forked from Simnation/Main
ed
This commit is contained in:
parent
e283a1c311
commit
618987ca69
105 changed files with 1 additions and 1339 deletions
BIN
resources/[freizeit]/[rcore_tv]/rcore_television/.fxap
Normal file
BIN
resources/[freizeit]/[rcore_tv]/rcore_television/.fxap
Normal file
Binary file not shown.
BIN
resources/[freizeit]/[rcore_tv]/rcore_television/Debug.lua
Normal file
BIN
resources/[freizeit]/[rcore_tv]/rcore_television/Debug.lua
Normal file
Binary file not shown.
|
@ -0,0 +1,4 @@
|
|||
-- if you want this script for... lets say like only vip, edit this function.
|
||||
function YourSpecialPermission()
|
||||
return true
|
||||
end
|
Binary file not shown.
|
@ -0,0 +1,119 @@
|
|||
local cameras = {}
|
||||
|
||||
function CreateCamera(name, pos, rot, fov)
|
||||
fov = fov or 50.0
|
||||
rot = rot or vector3(0, 0, 0)
|
||||
local cam = CreateCamWithParams("DEFAULT_SCRIPTED_CAMERA", pos.x, pos.y, pos.z, rot.x, rot.y, rot.z, fov, false, 0)
|
||||
local try = 0
|
||||
while not DoesCamExist(cam) do
|
||||
Wait(33)
|
||||
end
|
||||
local self = {}
|
||||
self.cam = cam
|
||||
self.attachedEntity = nil
|
||||
self.position = pos
|
||||
self.rotation = rot
|
||||
self.fov = fov
|
||||
self.name = name
|
||||
self.lastPointTo = nil
|
||||
self.changingPos = false
|
||||
self.SetCoords = function(pos)
|
||||
self.position = pos
|
||||
SetCamCoord(self.cam, pos.x, pos.y, pos.z)
|
||||
end
|
||||
|
||||
self.GetCoords = function()
|
||||
return GetCamCoord(self.cam)
|
||||
end
|
||||
|
||||
self.AttachCameraToEntity = function(entity, offSet)
|
||||
if not offSet then
|
||||
offSet = vector3(0, 0, 0)
|
||||
end
|
||||
self.attachedEntity = entity
|
||||
AttachCamToEntity(self.cam, entity, offSet.x, offSet.y, offSet.z, true)
|
||||
end
|
||||
|
||||
self.DeattachCameraFromEntity = function()
|
||||
AttachCamToEntity(self.cam, 0, 0, 0, 0, true)
|
||||
end
|
||||
|
||||
self.FocusOnCoords = function(pos)
|
||||
self.lastPointTo = pos
|
||||
PointCamAtCoord(self.cam, pos.x, pos.y, pos.z)
|
||||
end
|
||||
|
||||
self.FocusOnEntity = function(entity, offSet)
|
||||
PointCamAtEntity(self.cam, entity, offSet.x, offSet.y, offSet.z, true)
|
||||
end
|
||||
|
||||
self.StopFocus = function()
|
||||
StopCamPointing(self.cam)
|
||||
end
|
||||
|
||||
self.SetRotation = function(rot)
|
||||
SetCamRot(self.cam, rot.x, rot.y, rot.z, 2)
|
||||
end
|
||||
|
||||
self.GetRotation = function()
|
||||
return GetCamRot(self.cam, 2)
|
||||
end
|
||||
|
||||
self.IsRendering = function()
|
||||
return IsCamRendering(self.cam or -1)
|
||||
end
|
||||
|
||||
self.SetCamFov = function(fov)
|
||||
SetCamFov(self.cam, fov)
|
||||
end
|
||||
|
||||
self.Render = function()
|
||||
SetCamActive(self.cam, true)
|
||||
RenderScriptCams(true, true, 1, true, true)
|
||||
end
|
||||
self.ChangeCam = function(newCam, duration)
|
||||
duration = duration or 3000
|
||||
SetCamActiveWithInterp(newCam, self.cam, duration, true, true)
|
||||
end
|
||||
self.Destroy = function()
|
||||
SetCamActive(self.cam, false)
|
||||
DestroyCam(self.cam)
|
||||
cameras[name] = nil
|
||||
end
|
||||
|
||||
self.GetCam = function()
|
||||
return self.cam
|
||||
end
|
||||
|
||||
self.IsChangingCamera = function()
|
||||
return self.changingPos
|
||||
end
|
||||
|
||||
self.ChangePosition = function(newPos, newPoint, newRot, duration)
|
||||
newRot = newRot or vector3(0, 0, 0)
|
||||
duration = duration or 4000
|
||||
|
||||
self.changingPos = true
|
||||
|
||||
local tempCam = CreateCamera(string.format('tempCam-%s', self.name), newPos, newRot, self.fov)
|
||||
tempCam.Render()
|
||||
|
||||
self.ChangeCam(tempCam.cam, duration)
|
||||
Citizen.Wait(duration)
|
||||
tempCam.Destroy()
|
||||
|
||||
SetCamActiveWithInterp(tempCam.cam, self.cam, 0, true, true)
|
||||
SetCamCoord(self.cam, newPoint.x, newPoint.y, newPoint.z)
|
||||
SetCamFov(self.cam, self.fov)
|
||||
SetCamRot(self.cam, newRot.x, newRot.y, newRot.z, 2)
|
||||
|
||||
self.changingPos = false
|
||||
end
|
||||
|
||||
cameras[name] = self
|
||||
return self
|
||||
end
|
||||
|
||||
function StopRendering()
|
||||
RenderScriptCams(false, false, 1, false, false)
|
||||
end
|
|
@ -0,0 +1,15 @@
|
|||
-- adding suggestions messages for commands
|
||||
CreateThread(function()
|
||||
TriggerEvent('chat:addSuggestion', "/" .. Config.volumeCommand, _U("volume_info") or 'Will set a new volume for TV', {
|
||||
{ name = _U("volume_argument") or "volume", help = "0-100" },
|
||||
})
|
||||
|
||||
TriggerEvent('chat:addSuggestion', "/" .. Config.playUrl, _U("playlink_info") or 'Will play a custom URL in the TV.', {
|
||||
{ name = "URL", help = _U("play_url_info") or "Your URL for website" },
|
||||
})
|
||||
end)
|
||||
|
||||
-- fetching cache
|
||||
CreateThread(function()
|
||||
TriggerServerEvent("rcore_television:fetchCache")
|
||||
end)
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
resources/[freizeit]/[rcore_tv]/rcore_television/client/init.lua
Normal file
BIN
resources/[freizeit]/[rcore_tv]/rcore_television/client/init.lua
Normal file
Binary file not shown.
BIN
resources/[freizeit]/[rcore_tv]/rcore_television/client/link.lua
Normal file
BIN
resources/[freizeit]/[rcore_tv]/rcore_television/client/link.lua
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,93 @@
|
|||
-- will return true / false if player is looking at TV
|
||||
function IsPlayerLookingAtTV()
|
||||
return IsLookingAtTV
|
||||
end
|
||||
|
||||
-- will return true / false if player is in TV menu
|
||||
function IsPlayerInTVMenu()
|
||||
return ViewingTvMenu
|
||||
end
|
||||
|
||||
-- will return type of redirect from URL
|
||||
--- @param URL string
|
||||
function GetRedirectFromURL(URL)
|
||||
for key, value in pairs(Config.CustomSupport) do
|
||||
if string.match(URL, key) then
|
||||
return value
|
||||
end
|
||||
end
|
||||
return RedirectType.OTHER
|
||||
end
|
||||
|
||||
-- will return true/false if hash is in config
|
||||
--- @param hash int
|
||||
function IsModelTelevision(hash)
|
||||
return Config.resolution[hash] ~= nil
|
||||
end
|
||||
|
||||
--- Will display help notification
|
||||
--- @param msg string
|
||||
--- @param thisFrame boolean
|
||||
--- @param beep boolean
|
||||
--- @param duration int
|
||||
function ShowHelpNotification(msg, thisFrame, beep, duration)
|
||||
AddTextEntry('rcore_Tv_help_msg', msg)
|
||||
|
||||
if thisFrame then
|
||||
DisplayHelpTextThisFrame('rcore_Tv_help_msg', false)
|
||||
else
|
||||
if beep == nil then
|
||||
beep = false
|
||||
end
|
||||
BeginTextCommandDisplayHelp('rcore_Tv_help_msg')
|
||||
EndTextCommandDisplayHelp(0, false, beep, duration)
|
||||
end
|
||||
end
|
||||
|
||||
--- Formated help text to prevent dup code anywhere i need to call it.
|
||||
--- @param time int
|
||||
function displayHelp(time)
|
||||
local text = _U("help")
|
||||
text = text .. _U("tv_help_line_2")
|
||||
text = text .. _U("tv_help_line_3")
|
||||
text = text .. _U("tv_help_line_4")
|
||||
text = text .. _U("tv_help_line_5")
|
||||
text = text .. _U("tv_help_line_6")
|
||||
if not Config.CustomNotification then
|
||||
ShowHelpNotification(text, false, false, time)
|
||||
else
|
||||
if type(Config.CustomNotification) == "function" then
|
||||
Config.CustomNotification(text)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- Will register key action
|
||||
--- @param fc function
|
||||
--- @param uniqid string
|
||||
--- @param description string
|
||||
--- @param key string
|
||||
--- @param inputDevice string
|
||||
function RegisterKey(fc, uniqid, description, key, inputDevice)
|
||||
if inputDevice == nil then
|
||||
inputDevice = "keyboard"
|
||||
end
|
||||
RegisterCommand(uniqid .. key, fc, false)
|
||||
RegisterKeyMapping(uniqid .. key, description, inputDevice, key)
|
||||
end
|
||||
|
||||
--- Will send a print when debug is enabled
|
||||
--- @param ... object
|
||||
function Debug(...)
|
||||
if Config.Debug then
|
||||
print(...)
|
||||
end
|
||||
end
|
||||
|
||||
--- Will send a print when debug is enabled
|
||||
--- @param ... object
|
||||
function MegaDebug(...)
|
||||
if Config.FunctionsDebug then
|
||||
print("[Mega Debug]", ...)
|
||||
end
|
||||
end
|
837
resources/[freizeit]/[rcore_tv]/rcore_television/config.lua
Normal file
837
resources/[freizeit]/[rcore_tv]/rcore_television/config.lua
Normal file
|
@ -0,0 +1,837 @@
|
|||
Config = {}
|
||||
|
||||
-- 0 standalone
|
||||
-- 1 ESX
|
||||
-- 2 QBCore
|
||||
Config.FrameWork = 2
|
||||
|
||||
-- 1 = raycast (whitedot in center of the screen)
|
||||
-- 2 = E click on keyboard only.
|
||||
Config.DetectorType = 2
|
||||
|
||||
-- Target type
|
||||
-- 0 = In build target system
|
||||
-- 1 = Q_Target
|
||||
-- 2 = BT Target
|
||||
-- 3 = QB Target
|
||||
-- 4 = OX Target
|
||||
Config.TargetZoneType = 3
|
||||
|
||||
-- i will leave this function open, just in case you had anticheat.
|
||||
Config.SetPlayerInvisible = function()
|
||||
--local ped = PlayerPedId()
|
||||
--SetEntityLocallyInvisible(ped)
|
||||
end
|
||||
|
||||
Config.QBCoreObject = "QBCore:GetObject"
|
||||
|
||||
-- is the script es_extended based?
|
||||
Config.ESX_Object = "esx:getSharedObject"
|
||||
|
||||
-- event for player loaded
|
||||
Config.EsxPlayerLoaded = "esx:playerLoaded"
|
||||
|
||||
-- event for setJob
|
||||
Config.EsxSetJob = "esx:setJob"
|
||||
|
||||
-- event for player loaded
|
||||
Config.OnPlayerLoaded = "QBCore:Client:OnPlayerLoaded"
|
||||
|
||||
-- event for setJob
|
||||
Config.OnJobUpdate = "QBCore:Client:OnJobUpdate"
|
||||
|
||||
-- will enable debug print and stuff
|
||||
Config.Debug = false
|
||||
|
||||
-- will type start and end of events + nui callbacks
|
||||
Config.FunctionsDebug = false
|
||||
|
||||
-- Will print in what type of thing error has happened.. Example CreateThread, RegisterNetEvent, RegisterCommand, etc.
|
||||
Config.GeneralDebug = false
|
||||
|
||||
-- a command to set volume for TV
|
||||
Config.volumeCommand = "tvvolume"
|
||||
|
||||
-- a command to change TV channel
|
||||
Config.playUrl = "playlink"
|
||||
|
||||
-- a key to open television
|
||||
Config.keyOpenTV = "E"
|
||||
|
||||
-- a key to select program in TV menu
|
||||
Config.keyToSelectProgram = "RETURN" -- is enter
|
||||
|
||||
-- a keys to leave TV menu
|
||||
Config.keyToLeaveMenu = "BACK"
|
||||
Config.secondKeyToLeaveMenu = "escape"
|
||||
|
||||
-- a keys to stop current TV program
|
||||
Config.keyToStopChannel = "SPACE"
|
||||
|
||||
-- Default youtube playing volume
|
||||
-- Only goes for youtube...
|
||||
Config.defaultVolume = 40
|
||||
|
||||
-- i dont recommend to change this number
|
||||
-- how far away TV can be visible
|
||||
Config.visibleDistance = 10
|
||||
|
||||
-- if you want have whitelist to prevent troll links keep this on true.
|
||||
-- i dont recommend turning this option off, people just can use
|
||||
-- shortcut url and the system wont know that it is on blacklist etc.
|
||||
Config.useWhitelist = true
|
||||
|
||||
-- Message list
|
||||
-- the command for this is /streamertelevision
|
||||
Config.Messages = {
|
||||
["streamer_on"] = "Streamer mode is on. From now you will not hear any music/sound from any TV.",
|
||||
["streamer_off"] = "Streamer mode is off. From now you will be able to watch any TV.",
|
||||
}
|
||||
|
||||
-- list of scaleform to use to televison
|
||||
-- the more there is = the more television can be active on single place
|
||||
-- the hard limit should be 15? i think?
|
||||
-- keep the value on false.
|
||||
Config.ScaleFormLists = {
|
||||
["television_scaleform_1"] = false,
|
||||
["television_scaleform_2"] = false,
|
||||
["television_scaleform_3"] = false,
|
||||
["television_scaleform_4"] = false,
|
||||
["television_scaleform_5"] = false,
|
||||
["television_scaleform_6"] = false,
|
||||
["television_scaleform_7"] = false,
|
||||
}
|
||||
|
||||
-- what website are allowed to put on tv ?
|
||||
Config.whitelisted = {
|
||||
"youtube",
|
||||
"youtu.be",
|
||||
"twitch",
|
||||
".mp3",
|
||||
"wav",
|
||||
"mp4",
|
||||
"webm",
|
||||
"ogg",
|
||||
"ogv",
|
||||
"kick",
|
||||
"douyin",
|
||||
"bilibili",
|
||||
}
|
||||
|
||||
-- Black list urls
|
||||
Config.blackListed = {
|
||||
"pornhub",
|
||||
"sex-slave",
|
||||
"cryzysek"
|
||||
}
|
||||
|
||||
function split(text, sep)
|
||||
local sep, fields = sep or ":", {}
|
||||
local pattern = string.format("([^%s]+)", sep)
|
||||
text:gsub(pattern, function(c)
|
||||
fields[#fields + 1] = c
|
||||
end)
|
||||
return fields
|
||||
end
|
||||
|
||||
-- if you need complet redirect for some reason then you can do it here
|
||||
Config.CompletRedirect = {
|
||||
-- i have not found other solution how to play twitch from this, so redirect is one option for me now.
|
||||
["twitch"] = function(url, time, volume)
|
||||
local newUrl = split(url, "/")
|
||||
newUrl = "https://player.twitch.tv/?channel=" .. newUrl[#newUrl] .. "&parent=localhost&volume=" .. ((volume or 30) / 100)
|
||||
return newUrl
|
||||
end,
|
||||
["kick"] = function(url, time, volume)
|
||||
return "https://proxy.rcore.cz/kick.html?url=" .. url .. "&volume=" .. ((volume or 30) / 100)
|
||||
end,
|
||||
["youtube"] = function(url, time, volume)
|
||||
return "https://rco.re/product/television/v2.html?url=" .. url .. "&volume=" .. (volume or 30) .. "&time=" .. (time or 0)
|
||||
end,
|
||||
["youtu.be"] = function(url, time, volume)
|
||||
return "https://rco.re/product/television/v2.html?url=" .. url .. "&volume=" .. (volume or 30) .. "&time=" .. (time or 0)
|
||||
end,
|
||||
}
|
||||
|
||||
-- will get called each second because I have not found better way.
|
||||
Config.ClickOnScreen = {
|
||||
["twitch"] = function(duiObj)
|
||||
-- will accept the "i am over 18 hell yeah"
|
||||
-- old position for the 18+ (leaving it here just in case it was added back)
|
||||
--SendDuiMouseMove(duiObj, 870, 605)
|
||||
--SendDuiMouseDown(duiObj, "left")
|
||||
--SendDuiMouseUp(duiObj, "left")
|
||||
|
||||
-- another old twitch
|
||||
--SendDuiMouseMove(duiObj, 784, 604)
|
||||
--SendDuiMouseDown(duiObj, "left")
|
||||
--SendDuiMouseUp(duiObj, "left")
|
||||
|
||||
SendDuiMouseMove(duiObj, 846, 630)
|
||||
SendDuiMouseDown(duiObj, "left")
|
||||
SendDuiMouseUp(duiObj, "left")
|
||||
end,
|
||||
}
|
||||
|
||||
-- if the pasted URL contains one of the words bellow it will redirect it to
|
||||
-- html/support/DEFINED VALUE/index.html so you can make your own support
|
||||
-- to another website.
|
||||
Config.CustomSupport = {
|
||||
-- youtube
|
||||
["youtube"] = "youtube",
|
||||
["youtu.be"] = "youtube",
|
||||
|
||||
-- sound
|
||||
-- i do not recommend using .ogg there atleast small amout of video format that can be played.
|
||||
-- also who uses ogg for music ? right ?
|
||||
[".mp3"] = "music",
|
||||
[".wav"] = "music",
|
||||
|
||||
-- videos
|
||||
[".mp4"] = "video",
|
||||
[".webm"] = "video",
|
||||
[".ogg"] = "video",
|
||||
[".ogv"] = "video",
|
||||
|
||||
-- douyin support
|
||||
["douyin"] = "douyin",
|
||||
|
||||
-- bilibili support
|
||||
["bilibili"] = "bilibili",
|
||||
}
|
||||
|
||||
-- you can blacklist here the SendDUIMessage about player position for example
|
||||
-- if you're streaming picture so there isnt any reason to send the DUI message about position right?
|
||||
Config.IgnorePositionUpdateCustomSupport = {
|
||||
["youtube"] = false,
|
||||
["menu"] = true,
|
||||
["other"] = true,
|
||||
}
|
||||
|
||||
-- this will disable forever poping the scaleform at some point fivem update broke this
|
||||
-- but to make sure I am leaving the option here just in case it wasnt working
|
||||
-- for now it will ne enabled
|
||||
-- false value = enabled poping
|
||||
-- true value = disabled
|
||||
Config.ScaleformPop = true
|
||||
|
||||
-- this will allow networked objects to be streamed on (possible that they can move)
|
||||
-- this feature is in work-in-progress it can have some unwanted bugs!
|
||||
Config.AllowNetworkedObjects = false
|
||||
|
||||
-- list of default videos for TV.. you have to manualy change it in html/menu.html aswell
|
||||
Config.listVideos = {
|
||||
[1] = {
|
||||
name = "Flute Tune",
|
||||
icon = "fa-solid fa-newspaper",
|
||||
url = "https://www.youtube.com/watch?v=X2cl6_DVpFI"
|
||||
},
|
||||
[2] = {
|
||||
name = "Video 2",
|
||||
icon = "fas fa-cat",
|
||||
url = ""
|
||||
},
|
||||
[3] = {
|
||||
name = "Video 3",
|
||||
icon = "fas fa-city",
|
||||
url = ""
|
||||
},
|
||||
[4] = {
|
||||
name = "Video 4",
|
||||
icon = "fas fa-hourglass-half",
|
||||
url = ""
|
||||
},
|
||||
[5] = {
|
||||
name = "Video 5",
|
||||
icon = "fas fa-grin-beam",
|
||||
url = ""
|
||||
},
|
||||
[6] = {
|
||||
name = "Video 6",
|
||||
icon = "fas fa-skull-crossbones",
|
||||
url = ""
|
||||
},
|
||||
}
|
||||
|
||||
function PlayWearAnimation()
|
||||
local ped = PlayerPedId()
|
||||
local dict, anim = "gestures@m@standing@casual", "gesture_damn"
|
||||
|
||||
RequestAnimDict(dict)
|
||||
while not HasAnimDictLoaded(dict) do
|
||||
Wait(33)
|
||||
end
|
||||
|
||||
TaskPlayAnim(ped, dict, anim, 8.0, 1.0, -1, 48, 0.0, false, false, false)
|
||||
end
|
||||
|
||||
-- this will create television at defined coords with default URL.
|
||||
Config.PlayingTelevisionOnLocation = {
|
||||
|
||||
}
|
||||
|
||||
Config.ReplaceObjects = {
|
||||
{
|
||||
pos = vector3(-54.47, -1087.27, 27.27),
|
||||
radius = 2.0,
|
||||
originalModelHash = 1036195894,
|
||||
newModelHash = GetHashKey("prop_tv_flat_01"),
|
||||
}
|
||||
}
|
||||
|
||||
-- this will create television on coords that can be used by other folks
|
||||
Config.CreateTelevisionModelOnCoords = {
|
||||
|
||||
}
|
||||
|
||||
-- if this is set to true it will preload one scaleform of television if some users experiencing bad loading
|
||||
Config.UsePreloaded = true
|
||||
|
||||
-- Do not switch to true use command /tveditor
|
||||
Config.Editor = false
|
||||
|
||||
-- default open distance from the model
|
||||
Config.DefaultOpenDistance = 1.5
|
||||
|
||||
-- i wouldn't recommend to change anything there unless you know what you're doing
|
||||
Config.resolution = {
|
||||
|
||||
[1522819744] = {
|
||||
--Job = { ["police"] = {"*"}, },
|
||||
--ItemToOpen = { "remote", "another item" },
|
||||
|
||||
ScreenOffSet = vector3(7.036000, 0.572270, 3.442090),
|
||||
ScreenSize = vector3(0.767885, 0.027010, 0.0),
|
||||
rotationOffset = vector3(0, 0, 0),
|
||||
|
||||
distanceToOpen = 10.0,
|
||||
distance = 30.0,
|
||||
CameraOffSet = {
|
||||
x = 0.0,
|
||||
y = 12.0,
|
||||
z = 0.2,
|
||||
rotationOffset = vector3(0, 0, 180),
|
||||
},
|
||||
},
|
||||
|
||||
[GetHashKey("ch_prop_ch_tv_rt_01a")] = {
|
||||
--Job = { ["police"] = {"*"}, },
|
||||
--ItemToOpen = { "remote", "another item" },
|
||||
|
||||
ScreenOffSet = vector3(-0.090645, 1.413200, 0.885070),
|
||||
ScreenSize = vector3(0.894370, 0.503975, 0.0),
|
||||
rotationOffset = vector3(0, 0, 90), -- rotation of scaleform
|
||||
|
||||
distanceToOpen = Config.DefaultOpenDistance,
|
||||
distance = Config.visibleDistance,
|
||||
CameraOffSet = {
|
||||
x = -3.0,
|
||||
y = 0.0,
|
||||
z = 0.2,
|
||||
rotationOffset = vector3(0, 0, 90), -- rotation of camera
|
||||
},
|
||||
},
|
||||
|
||||
[GetHashKey("prop_monitor_w_large")] = {
|
||||
--Job = { ["police"] = {"*"}, },
|
||||
--ItemToOpen = { "remote", "another item" },
|
||||
|
||||
ScreenOffSet = vector3(0.373000, -0.076500, 0.622000),
|
||||
ScreenSize = vector3(-0.000685, -0.001575, 0),
|
||||
distanceToOpen = Config.DefaultOpenDistance,
|
||||
distance = Config.visibleDistance,
|
||||
CameraOffSet = {
|
||||
x = 0.0,
|
||||
y = -1.0,
|
||||
z = 0.4,
|
||||
},
|
||||
},
|
||||
[GetHashKey("apa_mp_h_str_avunitl_04")] = {
|
||||
--Job = { ["police"] = {"*"}, },
|
||||
--ItemToOpen = { "remote", "another item" },
|
||||
|
||||
ScreenOffSet = vector3(-0.291720, -0.407225, 2.083020),
|
||||
ScreenSize = vector3(0.081970, 0.046270, 0.0),
|
||||
|
||||
--ScreenOffSet = vector3(-0.335, -0.409, 2.074),
|
||||
--ScreenSize = vector3(0.081, 0.047, 0.090),
|
||||
distanceToOpen = Config.DefaultOpenDistance,
|
||||
distance = Config.visibleDistance,
|
||||
CameraOffSet = {
|
||||
x = 0.6,
|
||||
y = -2.7,
|
||||
z = 1.2,
|
||||
},
|
||||
},
|
||||
[GetHashKey("prop_monitor_01b")] = {
|
||||
--Job = { ["police"] = {"*"}, },
|
||||
--ItemToOpen = { "remote", "another item" },
|
||||
|
||||
ScreenOffSet = vector3(-0.240, -0.084, 0.449),
|
||||
ScreenSize = vector3(0, 0, 0),
|
||||
distanceToOpen = Config.DefaultOpenDistance,
|
||||
distance = Config.visibleDistance,
|
||||
CameraOffSet = {
|
||||
x = 0.05,
|
||||
y = -1.0,
|
||||
z = 0.1,
|
||||
rotationOffset = vector3(0, 0, 0),
|
||||
},
|
||||
},
|
||||
|
||||
[GetHashKey("apa_mp_h_str_avunitl_01_b")] = {
|
||||
--Job = { ["police"] = {"*"}, },
|
||||
--ItemToOpen = { "remote", "another item" },
|
||||
|
||||
ScreenOffSet = vector3(-0.471, -0.130, 1.941),
|
||||
ScreenSize = vector3(0.075, 0.042, 0.038),
|
||||
distanceToOpen = 3.0,
|
||||
distance = Config.visibleDistance,
|
||||
CameraOffSet = {
|
||||
x = 0.5,
|
||||
y = -3.0,
|
||||
z = 1.20,
|
||||
},
|
||||
},
|
||||
[GetHashKey("ex_prop_ex_tv_flat_01")] = {
|
||||
--Job = { ["police"] = {"*"}, },
|
||||
--ItemToOpen = { "remote", "another item" },
|
||||
|
||||
ScreenOffSet = vector3(-1.049, -0.062, 1.072),
|
||||
ScreenSize = vector3(-0.0, -0.0, -0.025),
|
||||
distanceToOpen = Config.DefaultOpenDistance,
|
||||
distance = Config.visibleDistance,
|
||||
CameraOffSet = {
|
||||
x = 0.0,
|
||||
y = -2.0,
|
||||
z = 0.40,
|
||||
},
|
||||
},
|
||||
|
||||
[-240931727] = { ---- TV Norid Wohnzimmer
|
||||
['ItemToOpen'] = nil,
|
||||
['CameraOffSet'] = {
|
||||
['z'] = 0.35,
|
||||
['rotationOffset'] = vec3(0.000000, 0.000000, 0.000000),
|
||||
['x'] = 0.0,
|
||||
['y'] = -3.0
|
||||
},
|
||||
['Job'] = nil,
|
||||
['ScreenSize'] = vec3(0.005425, 0.003510, 0.000000),
|
||||
['distanceToOpen'] = 1.5,
|
||||
['distance'] = 10,
|
||||
['ScreenOffSet'] = vec3(-1.484340, -0.045045, 0.870735)
|
||||
},
|
||||
|
||||
[60046420] = { ----- TV Nordi Schlafzimmer
|
||||
['Job'] = nil,
|
||||
['distanceToOpen'] = 1.5,
|
||||
['ScreenOffSet'] = vec3(-1.126000, -0.095500, 1.149000),
|
||||
['distance'] = 10,
|
||||
['CameraOffSet'] = {
|
||||
['y'] = -3.0,
|
||||
['z'] = 0.35,
|
||||
['rotationOffset'] = vec3(0.000000, 0.000000, 0.000000),
|
||||
['x'] = 0.0
|
||||
},
|
||||
['ScreenSize'] = vec3(-0.021175, -0.012000, 0.000000),
|
||||
['ItemToOpen'] = nil
|
||||
},
|
||||
|
||||
|
||||
[-1331536247] = { ---- TV Coffe Cute
|
||||
['ScreenSize'] = vec3(0.000000, 0.000000, 0.000000),
|
||||
['distance'] = 20,
|
||||
['ScreenOffSet'] = vec3(0.000000, 0.000000, 0.000000),
|
||||
['Job'] = nil,
|
||||
['ItemToOpen'] = nil,
|
||||
['distanceToOpen'] = 1.5,
|
||||
['CameraOffSet'] = {
|
||||
['x'] = 0.0,
|
||||
['rotationOffset'] = vec3(0.000000, 0.000000, 0.000000),
|
||||
['z'] = 0.35,
|
||||
['y'] = -3.0
|
||||
}
|
||||
},
|
||||
|
||||
[125407437] = { ---- Nordi Kino
|
||||
['Job'] = nil,
|
||||
['ScreenOffSet'] = vec3(-7.803390, -0.969630, 3.752175),
|
||||
['distance'] = 60,
|
||||
['CameraOffSet'] = {
|
||||
['y'] = -3.0,
|
||||
['x'] = 0.0,
|
||||
['rotationOffset'] = vec3(0.000000, 0.000000, 0.000000),
|
||||
['z'] = 0.35
|
||||
},
|
||||
['ItemToOpen'] = nil,
|
||||
['distanceToOpen'] = 30,
|
||||
['ScreenSize'] = vec3(0.004720, 0.036720, 0.000000)
|
||||
},
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
[GetHashKey("prop_huge_display_01")] = {
|
||||
--Job = { ["police"] = {"*"}, },
|
||||
--ItemToOpen = { "remote", "another item" },
|
||||
|
||||
ScreenOffSet = vector3(-5.110, -0.105, 3.640),
|
||||
ScreenSize = vector3(0.04, 0.025, 0.0),
|
||||
distanceToOpen = 15.0,
|
||||
distance = 30.0,
|
||||
CameraOffSet = {
|
||||
x = -0.6,
|
||||
y = -15.9,
|
||||
z = 1.0,
|
||||
rotation = vector3(0, 0, 0),
|
||||
},
|
||||
},
|
||||
[GetHashKey("prop_cs_tv_stand")] = {
|
||||
--Job = { ["police"] = {"*"}, },
|
||||
--ItemToOpen = { "remote", "another item" },
|
||||
|
||||
ScreenOffSet = vector3(-0.552, -0.080, 1.553),
|
||||
ScreenSize = vector3(0.0045, 0.004, 0.001),
|
||||
distanceToOpen = Config.DefaultOpenDistance,
|
||||
distance = Config.visibleDistance,
|
||||
CameraOffSet = {
|
||||
x = 0.0,
|
||||
y = -1.0,
|
||||
z = 1.23,
|
||||
},
|
||||
},
|
||||
[GetHashKey("v_ilev_cin_screen")] = {
|
||||
--Job = { ["police"] = {"*"}, },
|
||||
--ItemToOpen = { "remote", "another item" },
|
||||
|
||||
ScreenOffSet = vector3(-6.967, -0.535, 2.821),
|
||||
ScreenSize = vector3(-0.009, 0.057, 0),
|
||||
distanceToOpen = 15.0,
|
||||
distance = 30.0,
|
||||
CameraOffSet = {
|
||||
x = 0.15,
|
||||
y = -10.7,
|
||||
z = 0.5,
|
||||
},
|
||||
},
|
||||
[GetHashKey("sm_prop_smug_tv_flat_01")] = {
|
||||
--Job = { ["police"] = {"*"}, },
|
||||
--ItemToOpen = { "remote", "another item" },
|
||||
|
||||
ScreenOffSet = vector3(-0.682, -0.043, 0.978),
|
||||
ScreenSize = vector3(-0.0045, -0.0025, -0.006),
|
||||
distanceToOpen = Config.DefaultOpenDistance,
|
||||
distance = Config.visibleDistance,
|
||||
CameraOffSet = {
|
||||
x = 0.15,
|
||||
y = -2.7,
|
||||
z = 0.5,
|
||||
},
|
||||
},
|
||||
[GetHashKey("prop_trev_tv_01")] = {
|
||||
--Job = { ["police"] = {"*"}, },
|
||||
--ItemToOpen = { "remote", "another item" },
|
||||
|
||||
ScreenOffSet = vector3(-0.26, -0.01, 0.28),
|
||||
ScreenSize = vector3(0.0035, 0.002, 0.0135),
|
||||
distanceToOpen = Config.DefaultOpenDistance,
|
||||
distance = Config.visibleDistance,
|
||||
CameraOffSet = {
|
||||
x = 0.0,
|
||||
y = -1.0,
|
||||
z = 0.1,
|
||||
},
|
||||
},
|
||||
[GetHashKey("prop_tv_02")] = {
|
||||
--Job = { ["police"] = {"*"}, },
|
||||
--ItemToOpen = { "remote", "another item" },
|
||||
|
||||
ScreenOffSet = vector3(-0.20, -0.10, 0.19),
|
||||
ScreenSize = vector3(0.005, 0.0, 0.0135),
|
||||
distanceToOpen = Config.DefaultOpenDistance,
|
||||
distance = Config.visibleDistance,
|
||||
CameraOffSet = {
|
||||
x = 0.05,
|
||||
y = -1.0,
|
||||
z = 0.0,
|
||||
},
|
||||
},
|
||||
[GetHashKey("prop_tv_03")] = {
|
||||
--Job = { ["police"] = {"*"}, },
|
||||
--ItemToOpen = { "remote", "another item" },
|
||||
|
||||
ScreenOffSet = vector3(-0.35, -0.11, 0.22),
|
||||
ScreenSize = vector3(0.008, 0.003, 0.0355),
|
||||
distanceToOpen = Config.DefaultOpenDistance,
|
||||
distance = Config.visibleDistance,
|
||||
CameraOffSet = {
|
||||
x = 0.05,
|
||||
y = -1.0,
|
||||
z = 0.0,
|
||||
},
|
||||
},
|
||||
[GetHashKey("prop_tv_03_overlay")] = {
|
||||
--Job = { ["police"] = {"*"}, },
|
||||
--ItemToOpen = { "remote", "another item" },
|
||||
|
||||
ScreenOffSet = vector3(-0.36, -0.11, 0.21),
|
||||
ScreenSize = vector3(0.0009, 0.0005, 0.036),
|
||||
distanceToOpen = Config.DefaultOpenDistance,
|
||||
distance = Config.visibleDistance,
|
||||
CameraOffSet = {
|
||||
x = 0.05,
|
||||
y = -1.0,
|
||||
z = 0.0,
|
||||
},
|
||||
},
|
||||
[GetHashKey("prop_tv_04")] = {
|
||||
--Job = { ["police"] = {"*"}, },
|
||||
--ItemToOpen = { "remote", "another item" },
|
||||
|
||||
ScreenOffSet = vector3(0, 0, 0),
|
||||
ScreenSize = vector3(0, 0, 0),
|
||||
distanceToOpen = Config.DefaultOpenDistance,
|
||||
distance = Config.visibleDistance,
|
||||
CameraOffSet = {
|
||||
x = 0.05,
|
||||
y = -1.0,
|
||||
z = 0.0,
|
||||
},
|
||||
},
|
||||
[GetHashKey("prop_tv_06")] = {
|
||||
--Job = { ["police"] = {"*"}, },
|
||||
--ItemToOpen = { "remote", "another item" },
|
||||
|
||||
ScreenOffSet = vector3(-0.34, -0.09, 0.25),
|
||||
ScreenSize = vector3(0.0055, 0.0025, 0.0385),
|
||||
distanceToOpen = Config.DefaultOpenDistance,
|
||||
distance = Config.visibleDistance,
|
||||
CameraOffSet = {
|
||||
x = 0.05,
|
||||
y = -1.0,
|
||||
z = 0.0,
|
||||
},
|
||||
},
|
||||
[GetHashKey("prop_tv_flat_01_screen")] = {
|
||||
--Job = { ["police"] = {"*"}, },
|
||||
--ItemToOpen = { "remote", "another item" },
|
||||
|
||||
ScreenOffSet = vector3(-1.04, -0.06, 1.06),
|
||||
ScreenSize = vector3(-0.0055, -0.0035, 0.0735),
|
||||
distanceToOpen = Config.DefaultOpenDistance,
|
||||
distance = Config.visibleDistance,
|
||||
CameraOffSet = {
|
||||
x = 0.15,
|
||||
y = -2.7,
|
||||
z = 0.5,
|
||||
},
|
||||
},
|
||||
[GetHashKey("prop_tv_flat_02")] = {
|
||||
--Job = { ["police"] = {"*"}, },
|
||||
--ItemToOpen = { "remote", "another item" },
|
||||
|
||||
ScreenOffSet = vector3(-0.55, -0.01, 0.57),
|
||||
ScreenSize = vector3(0.00049, -0.0005, 0.073),
|
||||
distanceToOpen = Config.DefaultOpenDistance,
|
||||
distance = Config.visibleDistance,
|
||||
CameraOffSet = {
|
||||
x = 0.05,
|
||||
y = -1.5,
|
||||
z = 0.25,
|
||||
},
|
||||
},
|
||||
[GetHashKey("prop_tv_flat_02b")] = {
|
||||
--Job = { ["police"] = {"*"}, },
|
||||
--ItemToOpen = { "remote", "another item" },
|
||||
|
||||
ScreenOffSet = vector3(-0.55, -0.01, 0.57),
|
||||
ScreenSize = vector3(0.00049, -0.0005, 0.073),
|
||||
distanceToOpen = Config.DefaultOpenDistance,
|
||||
distance = Config.visibleDistance,
|
||||
CameraOffSet = {
|
||||
x = 0.05,
|
||||
y = -1.5,
|
||||
z = 0.25,
|
||||
},
|
||||
},
|
||||
[GetHashKey("prop_tv_flat_03")] = {
|
||||
--Job = { ["police"] = {"*"}, },
|
||||
--ItemToOpen = { "remote", "another item" },
|
||||
|
||||
ScreenOffSet = vector3(-0.335, -0.008, 0.412),
|
||||
ScreenSize = vector3(-0.0005, 0.0, 0.0745),
|
||||
distanceToOpen = Config.DefaultOpenDistance,
|
||||
distance = Config.visibleDistance,
|
||||
CameraOffSet = {
|
||||
x = 0.05,
|
||||
y = -1.0,
|
||||
z = 0.2,
|
||||
},
|
||||
},
|
||||
[GetHashKey("prop_tv_flat_03b")] = {
|
||||
--Job = { ["police"] = {"*"}, },
|
||||
--ItemToOpen = { "remote", "another item" },
|
||||
|
||||
ScreenOffSet = vector3(-0.335, -0.065, 0.211),
|
||||
ScreenSize = vector3(0.003, 0.002, 0.002),
|
||||
distanceToOpen = Config.DefaultOpenDistance,
|
||||
distance = Config.visibleDistance,
|
||||
CameraOffSet = {
|
||||
x = 0.05,
|
||||
y = -1.0,
|
||||
z = 0.0,
|
||||
},
|
||||
},
|
||||
[GetHashKey("apa_mp_h_str_avunits_01")] = {
|
||||
--Job = { ["police"] = {"*"}, },
|
||||
--ItemToOpen = { "remote", "another item" },
|
||||
|
||||
ScreenOffSet = vector3(-1.012, -0.302, 2.085),
|
||||
ScreenSize = vector3(0.023, 0.014, 0.004),
|
||||
distanceToOpen = Config.DefaultOpenDistance,
|
||||
distance = Config.visibleDistance,
|
||||
CameraOffSet = {
|
||||
x = -0.1,
|
||||
y = -2.7,
|
||||
z = 1.2,
|
||||
},
|
||||
},
|
||||
[GetHashKey("hei_heist_str_avunitl_03")] = {
|
||||
--Job = { ["police"] = {"*"}, },
|
||||
--ItemToOpen = { "remote", "another item" },
|
||||
|
||||
ScreenOffSet = vector3(-1.197, -0.372, 2.089),
|
||||
ScreenSize = vector3(0.071, 0.037, 0.094),
|
||||
distanceToOpen = Config.DefaultOpenDistance + 1.0,
|
||||
distance = Config.visibleDistance,
|
||||
CameraOffSet = {
|
||||
x = -0.1,
|
||||
y = -2.7,
|
||||
z = 1.2,
|
||||
},
|
||||
},
|
||||
[GetHashKey("prop_tv_flat_michael")] = {
|
||||
--Job = { ["police"] = {"*"}, },
|
||||
--ItemToOpen = { "remote", "another item" },
|
||||
|
||||
ScreenOffSet = vector3(-0.711, -0.067, 0.441),
|
||||
ScreenSize = vector3(0.0056, 0.0036, 0.0),
|
||||
distanceToOpen = Config.DefaultOpenDistance,
|
||||
distance = Config.visibleDistance,
|
||||
CameraOffSet = {
|
||||
x = 0.15,
|
||||
y = -2.7,
|
||||
z = 0.1,
|
||||
},
|
||||
},
|
||||
[GetHashKey("prop_tv_test")] = {
|
||||
--Job = { ["police"] = {"*"}, },
|
||||
--ItemToOpen = { "remote", "another item" },
|
||||
|
||||
ScreenOffSet = vector3(0, 0, 0),
|
||||
ScreenSize = vector3(0, 0, 0),
|
||||
distanceToOpen = Config.DefaultOpenDistance,
|
||||
distance = Config.visibleDistance,
|
||||
CameraOffSet = {
|
||||
x = 0.05,
|
||||
y = -1.0,
|
||||
z = 0.1,
|
||||
},
|
||||
},
|
||||
|
||||
[GetHashKey("xm_prop_x17_tv_flat_02")] = {
|
||||
--Job = { ["police"] = {"*"}, },
|
||||
--ItemToOpen = { "remote", "another item" },
|
||||
|
||||
ScreenOffSet = vector3(-1.049, -0.049, 1.068),
|
||||
ScreenSize = vector3(0, 0, 0),
|
||||
distanceToOpen = Config.DefaultOpenDistance,
|
||||
distance = Config.visibleDistance,
|
||||
CameraOffSet = {
|
||||
x = 0.05,
|
||||
y = -3.0,
|
||||
z = 0.4,
|
||||
},
|
||||
},
|
||||
|
||||
-- i dont recommend using this.. i have no idea if this TV is on more location
|
||||
-- than Michael house.. if there is just one TV then go ahead enable it.
|
||||
[GetHashKey("des_tvsmash_start")] = {
|
||||
--Job = { ["police"] = {"*"}, },
|
||||
--ItemToOpen = { "remote", "another item" },
|
||||
|
||||
ScreenOffSet = vector3(0.096, -1.010, 0.940),
|
||||
ScreenSize = vector3(0.009, 0.004, 0.004),
|
||||
rotationOffset = vector3(0, 0, -90),
|
||||
|
||||
distanceToOpen = Config.DefaultOpenDistance,
|
||||
distance = Config.visibleDistance,
|
||||
CameraOffSet = {
|
||||
x = 2.7,
|
||||
y = 0.1,
|
||||
z = 0.4,
|
||||
rotationOffset = vector3(0, 0, -90),
|
||||
},
|
||||
},
|
||||
|
||||
-- i dont recommend to enable this.. you need to swap model to get this working.
|
||||
-- if you know what you're doing.. swap this model: v_ilev_mm_scre_off to this one v_ilev_mm_screen2
|
||||
-- with function "CreateModelSwap"
|
||||
[GetHashKey("v_ilev_mm_screen2")] = {
|
||||
--Job = { ["police"] = {"*"}, },
|
||||
--ItemToOpen = { "remote", "another item" },
|
||||
|
||||
ScreenOffSet = vector3(-1.544, 0.006, -0.098),
|
||||
ScreenSize = vector3(0.040, 0.023, 0.002),
|
||||
distanceToOpen = Config.DefaultOpenDistance,
|
||||
distance = Config.visibleDistance,
|
||||
CameraOffSet = {
|
||||
x = 0.15,
|
||||
y = -2.7,
|
||||
z = -1.0,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
-- Because many mappers like to resize television... There is the option for custom size...
|
||||
Config.CustomScreenSizes = {
|
||||
[GetHashKey("prop_tv_flat_01")] = {-- {
|
||||
-- pos = vector3(-54.51, -1087.36, 27.26),
|
||||
-- ScreenSize = vector3(0.10, 0.0, 0),
|
||||
-- distanceToOpen = Config.DefaultOpenDistance,
|
||||
-- },
|
||||
},
|
||||
[GetHashKey("prop_huge_display_01")] = {-- {
|
||||
-- pos = vector3(-54.51, -1087.36, 27.26),
|
||||
-- ScreenSize = vector3(0.0, 0.0, 0),
|
||||
-- }
|
||||
},
|
||||
}
|
||||
|
||||
-- permission map
|
||||
Config.PermissionGroup = {
|
||||
ESX = {
|
||||
-- group system that used to work on numbers only
|
||||
[1] = {
|
||||
1, 2, 3, 4, 5
|
||||
},
|
||||
-- group system that works on name
|
||||
[2] = {
|
||||
"helper", "mod", "admin", "superadmin",
|
||||
},
|
||||
},
|
||||
|
||||
QBCore = {
|
||||
-- group system that works on ACE
|
||||
[1] = {
|
||||
"god", "admin", "mod",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
Config.CommandPermissions = {
|
||||
["tveditor"] = { 3, 4, 5, "admin", "superadmin", "god" },
|
||||
}
|
15
resources/[freizeit]/[rcore_tv]/rcore_television/const.lua
Normal file
15
resources/[freizeit]/[rcore_tv]/rcore_television/const.lua
Normal file
|
@ -0,0 +1,15 @@
|
|||
TargetType = {
|
||||
NO_TARGET = 0,
|
||||
Q_TARGET = 1,
|
||||
BT_TARGET = 2,
|
||||
QB_TARGET = 3,
|
||||
OX_TARGET = 4
|
||||
}
|
||||
|
||||
TargetTypeResourceName = {
|
||||
[TargetType.NO_TARGET] = "none",
|
||||
[TargetType.Q_TARGET] = "qtarget",
|
||||
[TargetType.BT_TARGET] = "bt-target",
|
||||
[TargetType.QB_TARGET] = "qb-target",
|
||||
[TargetType.OX_TARGET] = "ox_target"
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
RegisterNUICallback("menuloaded", function(data_, cb)
|
||||
local data = TelevisionCache[data_.identifier]
|
||||
local items = Config.PlayingTelevisionOnLocation[data_.identifier].Items
|
||||
local duiObj = data.duiObj
|
||||
local active = true
|
||||
for k, v in pairs(items) do
|
||||
local itemData = Deepcopy(v)
|
||||
itemData.CallBack = nil
|
||||
itemData.identifier = k
|
||||
itemData.active = active
|
||||
active = false
|
||||
|
||||
DuiMessage(duiObj, {
|
||||
type = "menuItems",
|
||||
items = itemData,
|
||||
})
|
||||
end
|
||||
|
||||
if cb then cb('ok') end
|
||||
end)
|
||||
|
||||
RegisterNUICallback("itemSelected", function(data, cb)
|
||||
local dataItem = Config.PlayingTelevisionOnLocation[data.identifier]
|
||||
if dataItem then
|
||||
if dataItem.Items[data.item].CloseAfterUse then
|
||||
LeaveTelevisionMenu()
|
||||
end
|
||||
dataItem.Items[data.item].CallBack()
|
||||
end
|
||||
|
||||
if cb then cb('ok') end
|
||||
end)
|
|
@ -0,0 +1 @@
|
|||
INSERT INTO `items` (`name`, `label`, `weight`, `rare`, `can_remove`) VALUES ('remote', 'remote', '1', '0', '1')
|
|
@ -0,0 +1,97 @@
|
|||
fx_version 'cerulean'
|
||||
games { 'gta5' }
|
||||
|
||||
version "2.1.4"
|
||||
|
||||
client_scripts {
|
||||
"config.lua",
|
||||
"const.lua",
|
||||
"utils/shared.lua",
|
||||
"Debug.lua",
|
||||
"locales/*.lua",
|
||||
"utils/client.lua",
|
||||
"client/permission.lua",
|
||||
|
||||
"client/VIP.lua",
|
||||
|
||||
"client/init.lua",
|
||||
"client/utils.lua",
|
||||
"client/client_editable.lua",
|
||||
"client/utils_editable.lua",
|
||||
"client/create_television.lua",
|
||||
"client/editor.lua",
|
||||
|
||||
"client/television_utils/volume.lua",
|
||||
|
||||
"client/render_scaleform.lua",
|
||||
"client/link.lua",
|
||||
"client/television_utils/menu.lua",
|
||||
"client/camera.lua",
|
||||
"client/television_utils/program.lua",
|
||||
"client/events.lua",
|
||||
"client/cache_event.lua",
|
||||
"client/dui_events.lua",
|
||||
|
||||
"custom/client/*.lua"
|
||||
}
|
||||
|
||||
server_scripts {
|
||||
"config.lua",
|
||||
"const.lua",
|
||||
"utils/shared.lua",
|
||||
"Debug.lua",
|
||||
"locales/*.lua",
|
||||
"utils/server.lua",
|
||||
"server/*.lua",
|
||||
}
|
||||
|
||||
ui_page "html/off.html"
|
||||
|
||||
files {
|
||||
"html/*.mp4",
|
||||
"html/*.html",
|
||||
"html/*.js",
|
||||
"html/support/**/*.*",
|
||||
"html/js/*.js",
|
||||
"html/css/*.css",
|
||||
"html/css/img/*.png",
|
||||
"html/css/img/*.jpg",
|
||||
|
||||
"html/menu/*.html",
|
||||
"html/menu/*.js",
|
||||
|
||||
"html/menu/css/*.css",
|
||||
|
||||
"html/menu/css/img/*.jpg",
|
||||
"html/menu/css/img/*.png",
|
||||
|
||||
"html/custom/**/*.*",
|
||||
"html/custom/**/css/*.*",
|
||||
"html/custom/**/js/*.*",
|
||||
}
|
||||
|
||||
dependencies {
|
||||
"tv_scaleform",
|
||||
'/server:4752',
|
||||
}
|
||||
|
||||
lua54 'yes'
|
||||
|
||||
escrow_ignore {
|
||||
"config.lua",
|
||||
"locales/*.lua",
|
||||
"utils/*.lua",
|
||||
|
||||
"const.lua",
|
||||
|
||||
"custom/client/*.lua",
|
||||
"custom/server/*.lua",
|
||||
|
||||
"server/server.lua",
|
||||
|
||||
"client/camera.lua",
|
||||
"client/VIP.lua",
|
||||
"client/client_editable.lua",
|
||||
"client/utils_editable.lua",
|
||||
}
|
||||
dependency '/assetpacks'
|
7
resources/[freizeit]/[rcore_tv]/rcore_television/html/bootstrap.min.js
vendored
Normal file
7
resources/[freizeit]/[rcore_tv]/rcore_television/html/bootstrap.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
7
resources/[freizeit]/[rcore_tv]/rcore_television/html/css/bootstrap.min.css
vendored
Normal file
7
resources/[freizeit]/[rcore_tv]/rcore_television/html/css/bootstrap.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
Binary file not shown.
After Width: | Height: | Size: 632 KiB |
|
@ -0,0 +1,106 @@
|
|||
#blackscreen{
|
||||
background: black;
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 999999;
|
||||
}
|
||||
|
||||
.bounce-enter-active {
|
||||
animation: bounce-in 0.5s;
|
||||
}
|
||||
|
||||
@keyframes bounce-in {
|
||||
0% {
|
||||
transform: scale(0);
|
||||
}
|
||||
50% {
|
||||
transform: scale(1.10);
|
||||
}
|
||||
100% {
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
#offButton{
|
||||
font-size: 32px;
|
||||
position: absolute;
|
||||
top: 6px;
|
||||
right: 52px;
|
||||
}
|
||||
|
||||
#off{
|
||||
background: aliceblue;
|
||||
position: absolute;
|
||||
height: 50px;
|
||||
width: 70px;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
#circle{
|
||||
height: 75px;
|
||||
width: 75px;
|
||||
background-color: aliceblue;
|
||||
border-radius: 50%;
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
top: -25px;
|
||||
right: 32px;
|
||||
}
|
||||
|
||||
body {
|
||||
background-image: url(./img/bg.jpg);
|
||||
background-size: cover;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#icon-size{
|
||||
font-size: 47px;
|
||||
padding: unset;
|
||||
padding-bottom: 40px;
|
||||
padding-top: 22px;
|
||||
}
|
||||
|
||||
#menu{
|
||||
margin: auto;
|
||||
width: 89%;
|
||||
}
|
||||
|
||||
#container{
|
||||
height: 649px;
|
||||
width: 871px;
|
||||
margin: auto;
|
||||
position: fixed;
|
||||
top: 29%;
|
||||
left: 27%;
|
||||
}
|
||||
|
||||
.text{
|
||||
font-family: Montserrat, sans-serif;
|
||||
text-overflow: ellipsis;
|
||||
font-size: 39px;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
bottom: 17px;
|
||||
}
|
||||
|
||||
.box{
|
||||
transition-duration: 500ms;
|
||||
background: aliceblue;
|
||||
float: left;
|
||||
margin: 8px;
|
||||
text-align: center;
|
||||
height: 96px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.box.active {
|
||||
z-index: 999 !important;
|
||||
border-radius: 6px;
|
||||
background: #b8dbfb;
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
<!doctype html>
|
||||
<html lang="en-us">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<link rel="stylesheet" href="./css/tv-menu.css">
|
||||
<link href="https://fonts.googleapis.com/css?family=Montserrat:600" rel="stylesheet">
|
||||
<script src="./js/vue.min.js"></script>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id = "blackscreen"> </div>
|
||||
<div id = "container">
|
||||
<div id = "menu">
|
||||
<div class = "box" v-for="item, key in menuItems" v-bind:class="{ active: item.active }">
|
||||
<p class = 'text'>{{item.Label}}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<script src="./js/script.js" type="text/javascript"></script>
|
|
@ -0,0 +1,71 @@
|
|||
$("#blackscreen").fadeOut(1500);
|
||||
|
||||
var VueJS = new Vue({
|
||||
el: '#container',
|
||||
data:
|
||||
{
|
||||
menuItems: [],
|
||||
},
|
||||
})
|
||||
|
||||
function getQueryParams() {
|
||||
var qs = window.location.search;
|
||||
qs = qs.split('+').join(' ');
|
||||
|
||||
var params = {},
|
||||
tokens,
|
||||
re = /[?&]?([^=]+)=([^&]*)/g;
|
||||
|
||||
while (tokens = re.exec(qs)) {
|
||||
params[decodeURIComponent(tokens[1])] = decodeURIComponent(tokens[2]);
|
||||
}
|
||||
return params;
|
||||
}
|
||||
|
||||
var activeIndex = 0;
|
||||
|
||||
function ChangeNumber(result){
|
||||
if(result){
|
||||
if(activeIndex + 1 == VueJS.menuItems.length) {
|
||||
activeIndex = -1;
|
||||
}
|
||||
activeIndex ++;
|
||||
}else{
|
||||
if(activeIndex == 0){
|
||||
activeIndex = VueJS.menuItems.length;
|
||||
}
|
||||
activeIndex --;
|
||||
}
|
||||
}
|
||||
|
||||
$(document).ready(function(){
|
||||
var params = getQueryParams();
|
||||
$.post('http://rcore_television/menuloaded', JSON.stringify({
|
||||
identifier: params.identifier,
|
||||
}));
|
||||
window.addEventListener('message', function(event) {
|
||||
var data = event.data;
|
||||
if(data.type === "menuItems"){
|
||||
VueJS.menuItems.push(data.items)
|
||||
}
|
||||
|
||||
if(data.type === "enter"){
|
||||
$.post('http://rcore_television/itemSelected', JSON.stringify({
|
||||
identifier: params.identifier,
|
||||
item: activeIndex,
|
||||
}));
|
||||
}
|
||||
|
||||
if(data.type === "direction_bottom"){
|
||||
ChangeNumber(true)
|
||||
for(var i = 0; i < VueJS.menuItems.length; i ++) VueJS.menuItems[i].active = false
|
||||
VueJS.menuItems[activeIndex].active = true
|
||||
}
|
||||
|
||||
if(data.type === "direction_top"){
|
||||
ChangeNumber(false)
|
||||
for(var i = 0; i < VueJS.menuItems.length; i ++) VueJS.menuItems[i].active = false
|
||||
VueJS.menuItems[activeIndex].active = true
|
||||
}
|
||||
});
|
||||
});
|
6
resources/[freizeit]/[rcore_tv]/rcore_television/html/custom/menu/js/vue.min.js
vendored
Normal file
6
resources/[freizeit]/[rcore_tv]/rcore_television/html/custom/menu/js/vue.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,105 @@
|
|||
function getQueryParams() {
|
||||
var qs = window.location.search;
|
||||
qs = qs.split('+').join(' ');
|
||||
|
||||
var params = {},
|
||||
tokens,
|
||||
re = /[?&]?([^=]+)=([^&]*)/g;
|
||||
|
||||
while (tokens = re.exec(qs)) {
|
||||
params[decodeURIComponent(tokens[1])] = decodeURIComponent(tokens[2]);
|
||||
}
|
||||
return params;
|
||||
}
|
||||
|
||||
function updateFrame(){
|
||||
var result = getQueryParams();
|
||||
|
||||
$("#black").css(
|
||||
{
|
||||
"max-width": "1920px",
|
||||
"max-height": "1080px",
|
||||
"top": "0",
|
||||
"bottom": "0",
|
||||
"left": "0",
|
||||
"right": "0",
|
||||
});
|
||||
}
|
||||
|
||||
function editString(string){
|
||||
var str = string.toLowerCase();
|
||||
var res = str.split("/");
|
||||
var final = res[res.length - 1];
|
||||
final = final.replace(".mp3", " ");
|
||||
final = final.replace(".wav", " ");
|
||||
final = final.replace(".wma", " ");
|
||||
final = final.replace(".wmv", " ");
|
||||
|
||||
final = final.replace(".aac", " ");
|
||||
final = final.replace(".ac3", " ");
|
||||
final = final.replace(".aif", " ");
|
||||
final = final.replace(".ogg", " ");
|
||||
final = final.replace("%20", " ");
|
||||
final = final.replace("-", " ");
|
||||
|
||||
return final;
|
||||
}
|
||||
|
||||
var MaxDistance = 10;
|
||||
var max_volume = 0.5;
|
||||
var TelevisionPos = [0,0,0];
|
||||
var PlayerPos = [0,0,0];
|
||||
|
||||
$(document).ready(function(){
|
||||
var result = getQueryParams();
|
||||
$.post('http://rcore_television/loaded', JSON.stringify({
|
||||
isMenu: false,
|
||||
identifier: result.identifier,
|
||||
}));
|
||||
window.addEventListener('message', function(event) {
|
||||
var data = event.data;
|
||||
if(data.type === "rcore_tv_update_pos"){
|
||||
PlayerPos = [data.x,data.y,data.z];
|
||||
}
|
||||
if(data.type === "rcore_tv_update_tv_pos"){
|
||||
TelevisionPos = [data.x,data.y,data.z];
|
||||
MaxDistance = data.MaxDistance;
|
||||
max_volume = data.max_volume / 100;
|
||||
}
|
||||
if(data.type === "rcore_tv_update_tv_volume"){
|
||||
max_volume = data.max_volume / 100;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
//taken from xsound
|
||||
//https://github.com/Xogy/xsound
|
||||
|
||||
function GetNewVolume()
|
||||
{
|
||||
var d_max = MaxDistance;
|
||||
var d_now = BetweenCoords();
|
||||
|
||||
var vol = 0;
|
||||
|
||||
var distance = (d_now / d_max);
|
||||
|
||||
if (distance < 1)
|
||||
{
|
||||
distance = distance * 100;
|
||||
var far_away = 100 - distance;
|
||||
vol = (max_volume / 100) * far_away;
|
||||
}
|
||||
|
||||
return vol;
|
||||
}
|
||||
|
||||
function BetweenCoords()
|
||||
{
|
||||
var deltaX = PlayerPos[0] - TelevisionPos[0];
|
||||
var deltaY = PlayerPos[1] - TelevisionPos[1];
|
||||
var deltaZ = PlayerPos[2] - TelevisionPos[2];
|
||||
|
||||
var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ);
|
||||
return distance;
|
||||
}
|
4
resources/[freizeit]/[rcore_tv]/rcore_television/html/js/howler.min.js
vendored
Normal file
4
resources/[freizeit]/[rcore_tv]/rcore_television/html/js/howler.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
2
resources/[freizeit]/[rcore_tv]/rcore_television/html/js/jquery.min.js
vendored
Normal file
2
resources/[freizeit]/[rcore_tv]/rcore_television/html/js/jquery.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
5
resources/[freizeit]/[rcore_tv]/rcore_television/html/js/prefixfree.min.js
vendored
Normal file
5
resources/[freizeit]/[rcore_tv]/rcore_television/html/js/prefixfree.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,167 @@
|
|||
var w = c.width = window.innerWidth,
|
||||
h = c.height = window.innerHeight,
|
||||
ctx = c.getContext( '2d' ),
|
||||
|
||||
minDist = 10,
|
||||
maxDist = 30,
|
||||
initialWidth = 10,
|
||||
maxLines = 100,
|
||||
initialLines = 4,
|
||||
speed = 5,
|
||||
|
||||
lines = [],
|
||||
frame = 0,
|
||||
timeSinceLast = 0,
|
||||
|
||||
dirs = [
|
||||
// straight x, y velocity
|
||||
[ 0, 1 ],
|
||||
[ 1, 0 ],
|
||||
[ 0, -1 ],
|
||||
[ -1, 0 ],
|
||||
// diagonals, 0.7 = sin(PI/4) = cos(PI/4)
|
||||
[ .7, .7 ],
|
||||
[ .7, -.7 ],
|
||||
[ -.7, .7 ],
|
||||
[ -.7, -.7]
|
||||
],
|
||||
starter = { // starting parent line, just a pseudo line
|
||||
|
||||
x: w / 2,
|
||||
y: h / 2,
|
||||
vx: 0,
|
||||
vy: 0,
|
||||
width: initialWidth
|
||||
};
|
||||
|
||||
function init() {
|
||||
|
||||
lines.length = 0;
|
||||
|
||||
for( var i = 0; i < initialLines; ++i )
|
||||
lines.push( new Line( starter ) );
|
||||
|
||||
ctx.fillStyle = '#222';
|
||||
ctx.fillRect( 0, 0, w, h );
|
||||
|
||||
// if you want a cookie ;)
|
||||
// ctx.lineCap = 'round';
|
||||
}
|
||||
function getColor( x ) {
|
||||
|
||||
return 'hsl( hue, 80%, 50% )'.replace(
|
||||
'hue', x / w * 360 + frame
|
||||
);
|
||||
}
|
||||
function anim() {
|
||||
|
||||
window.requestAnimationFrame( anim );
|
||||
|
||||
++frame;
|
||||
|
||||
ctx.shadowBlur = 0;
|
||||
ctx.fillStyle = 'rgba(0,0,0,.02)';
|
||||
ctx.fillRect( 0, 0, w, h );
|
||||
ctx.shadowBlur = .5;
|
||||
|
||||
for( var i = 0; i < lines.length; ++i )
|
||||
|
||||
if( lines[ i ].step() ) { // if true it's dead
|
||||
|
||||
lines.splice( i, 1 );
|
||||
--i;
|
||||
|
||||
}
|
||||
|
||||
// spawn new
|
||||
|
||||
++timeSinceLast
|
||||
|
||||
if( lines.length < maxLines && timeSinceLast > 10 && Math.random() < .5 ) {
|
||||
|
||||
timeSinceLast = 0;
|
||||
|
||||
lines.push( new Line( starter ) );
|
||||
|
||||
// cover the middle;
|
||||
ctx.fillStyle = ctx.shadowColor = getColor( starter.x );
|
||||
ctx.beginPath();
|
||||
ctx.arc( starter.x, starter.y, initialWidth, 0, Math.PI * 2 );
|
||||
ctx.fill();
|
||||
}
|
||||
}
|
||||
|
||||
function Line( parent ) {
|
||||
|
||||
this.x = parent.x | 0;
|
||||
this.y = parent.y | 0;
|
||||
this.width = parent.width / 1.25;
|
||||
|
||||
do {
|
||||
|
||||
var dir = dirs[ ( Math.random() * dirs.length ) |0 ];
|
||||
this.vx = dir[ 0 ];
|
||||
this.vy = dir[ 1 ];
|
||||
|
||||
} while (
|
||||
( this.vx === -parent.vx && this.vy === -parent.vy ) || ( this.vx === parent.vx && this.vy === parent.vy) );
|
||||
|
||||
this.vx *= speed;
|
||||
this.vy *= speed;
|
||||
|
||||
this.dist = ( Math.random() * ( maxDist - minDist ) + minDist );
|
||||
|
||||
}
|
||||
Line.prototype.step = function() {
|
||||
|
||||
var dead = false;
|
||||
|
||||
var prevX = this.x,
|
||||
prevY = this.y;
|
||||
|
||||
this.x += this.vx;
|
||||
this.y += this.vy;
|
||||
|
||||
--this.dist;
|
||||
|
||||
// kill if out of screen
|
||||
if( this.x < 0 || this.x > w || this.y < 0 || this.y > h )
|
||||
dead = true;
|
||||
|
||||
// make children :D
|
||||
if( this.dist <= 0 && this.width > 1 ) {
|
||||
|
||||
// keep yo self, sometimes
|
||||
this.dist = Math.random() * ( maxDist - minDist ) + minDist;
|
||||
|
||||
// add 2 children
|
||||
if( lines.length < maxLines ) lines.push( new Line( this ) );
|
||||
if( lines.length < maxLines && Math.random() < .5 ) lines.push( new Line( this ) );
|
||||
|
||||
// kill the poor thing
|
||||
if( Math.random() < .2 ) dead = true;
|
||||
}
|
||||
|
||||
ctx.strokeStyle = ctx.shadowColor = getColor( this.x );
|
||||
ctx.beginPath();
|
||||
ctx.lineWidth = this.width;
|
||||
ctx.moveTo( this.x, this.y );
|
||||
ctx.lineTo( prevX, prevY );
|
||||
ctx.stroke();
|
||||
|
||||
if( dead ) return true
|
||||
}
|
||||
|
||||
init();
|
||||
anim();
|
||||
|
||||
window.addEventListener( 'resize', function() {
|
||||
|
||||
w = c.width = window.innerWidth;
|
||||
h = c.height = window.innerHeight;
|
||||
starter.x = w / 2;
|
||||
starter.y = h / 2;
|
||||
|
||||
init();
|
||||
} )
|
||||
|
6
resources/[freizeit]/[rcore_tv]/rcore_television/html/js/vue.min.js
vendored
Normal file
6
resources/[freizeit]/[rcore_tv]/rcore_television/html/js/vue.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,22 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<script src='./js/jquery.min.js'></script>
|
||||
<script src="./js/functions.js"></script>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title></title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
</body>
|
||||
|
||||
<script>
|
||||
var result = getQueryParams();
|
||||
|
||||
$.post('http://rcore_television/duiHasLoaded', JSON.stringify({
|
||||
identifier: result.identifier,
|
||||
url: window.location.search.split('&link=')[1],
|
||||
}));
|
||||
</script>
|
||||
|
||||
</html>
|
Binary file not shown.
After Width: | Height: | Size: 632 KiB |
|
@ -0,0 +1,161 @@
|
|||
#blackscreen{
|
||||
background: black;
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 999999;
|
||||
}
|
||||
|
||||
.bounce-enter-active {
|
||||
animation: bounce-in 0.5s;
|
||||
}
|
||||
|
||||
@keyframes bounce-in {
|
||||
0% {
|
||||
transform: scale(0);
|
||||
}
|
||||
50% {
|
||||
transform: scale(1.10);
|
||||
}
|
||||
100% {
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
#offButton{
|
||||
font-size: 32px;
|
||||
position: absolute;
|
||||
top: 6px;
|
||||
right: 52px;
|
||||
}
|
||||
|
||||
#off{
|
||||
background: aliceblue;
|
||||
position: absolute;
|
||||
height: 50px;
|
||||
width: 70px;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
#circle{
|
||||
height: 75px;
|
||||
width: 75px;
|
||||
background-color: aliceblue;
|
||||
border-radius: 50%;
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
top: -25px;
|
||||
right: 32px;
|
||||
}
|
||||
|
||||
body {
|
||||
background-image: url(./img/bg.jpg);
|
||||
background-size: cover;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#icon-size{
|
||||
font-size: 47px;
|
||||
padding: unset;
|
||||
padding-bottom: 40px;
|
||||
padding-top: 22px;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 768px) {
|
||||
#menu {
|
||||
max-height: 43vw;
|
||||
max-width: 60vw;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
margin: auto;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
@media screen and (min-width: 768px) {
|
||||
#menu{
|
||||
max-height: 43vw;
|
||||
max-width: 76vw;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
margin: auto;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 768px) {
|
||||
.text {
|
||||
font-family: Montserrat, sans-serif;
|
||||
text-overflow: ellipsis;
|
||||
position: relative;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: 25px;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 768px) {
|
||||
.text{
|
||||
font-family: Montserrat, sans-serif;
|
||||
height: 95px;
|
||||
text-overflow: ellipsis;
|
||||
font-size: 39px;
|
||||
position: relative;
|
||||
bottom: 83px;
|
||||
width: 419px;
|
||||
left: 26px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
.box.active {
|
||||
z-index: 999 !important;
|
||||
border-radius: 17px;
|
||||
background: #e0eefb;
|
||||
transform: scale(1.25);
|
||||
box-shadow: 1px 7px 63px 0px #000000;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 768px) {
|
||||
.box{
|
||||
transition-duration: 500ms;
|
||||
background: aliceblue;
|
||||
max-height: 160px;
|
||||
max-width: 467px;
|
||||
float: left;
|
||||
margin: 8px;
|
||||
text-align: center;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
z-index: 9 !imporant;
|
||||
}
|
||||
}
|
||||
@media screen and (max-width: 768px) {
|
||||
.box {
|
||||
transition-duration: 500ms;
|
||||
background: aliceblue;
|
||||
float: left;
|
||||
margin: 8px;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
z-index: 9 !imporant;
|
||||
}
|
||||
|
||||
#icon-size{
|
||||
display: none;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
<!doctype html>
|
||||
<html lang="en-us">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<link rel="stylesheet" href="./css/tv-menu.css">
|
||||
<link href="https://fonts.googleapis.com/css?family=Montserrat:800" rel="stylesheet">
|
||||
<script src="../js/vue.min.js"></script>
|
||||
|
||||
<link rel="stylesheet" href="https://rco.re/fa/css/all.css">
|
||||
<script src="https://rco.re/fa/js/all.js" crossorigin="anonymous"></script>
|
||||
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id = "blackscreen"> </div>
|
||||
<div id = "off"><i id ="offButton" class="fas fa-power-off"></i></div>
|
||||
<div id = "circle"></div>
|
||||
|
||||
<div id = "menu">
|
||||
<div v-for="item, index in menuItems" class = 'box bounce-enter-active' v-bind:class="{ active: item.active }">
|
||||
<i id = 'icon-size' v-bind:class='item.icon'></i>
|
||||
<p class = 'text'>{{item.title}}</p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
<script src="./script.js" type="text/javascript"></script>
|
|
@ -0,0 +1,51 @@
|
|||
$("#blackscreen").fadeOut(1500);
|
||||
|
||||
var VueJS = new Vue({
|
||||
el: '#menu',
|
||||
data:
|
||||
{
|
||||
menuItems: [],
|
||||
},
|
||||
})
|
||||
|
||||
$(document).ready(function(){
|
||||
$.post('http://rcore_television/loaded', JSON.stringify({
|
||||
isMenu: true,
|
||||
}));
|
||||
window.addEventListener('message', function(event) {
|
||||
var data = event.data;
|
||||
|
||||
if(data.type === "reset"){
|
||||
VueJS.menuItems = [];
|
||||
}
|
||||
|
||||
if(data.type === "rcore_tv_change"){
|
||||
for(var i = 0; i < VueJS.menuItems.length; i ++) VueJS.menuItems[i].active = false;
|
||||
for(var i = 0; i < VueJS.menuItems.length; i ++){
|
||||
var menuData = VueJS.menuItems[i]
|
||||
if(menuData.index == data.selected){
|
||||
VueJS.menuItems[i].active = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(data.type === "rcore_tv_add_tv"){
|
||||
VueJS.menuItems.push({
|
||||
active: false,
|
||||
icon: data.icon,
|
||||
title: data.title,
|
||||
index: data.index,
|
||||
});
|
||||
}
|
||||
|
||||
if(data.type === "active_first"){
|
||||
for(var i = 0; i < VueJS.menuItems.length; i ++){
|
||||
var menuData = VueJS.menuItems[i]
|
||||
if(menuData.index == 1){
|
||||
VueJS.menuItems[i].active = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
|
@ -0,0 +1,75 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en" dir="ltr">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<script src="./js/jquery.min.js"></script>
|
||||
<link rel="stylesheet" href="./css/bootstrap.min.css">
|
||||
<script src="./bootstrap.min.js" ></script>
|
||||
|
||||
<title>Welcome traveler, hope you like this file. :) Here, have a cookie to your journey!</title>
|
||||
<style>
|
||||
.dot{
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
width: 0.25vw;
|
||||
height: 0.25vw;
|
||||
background: white;
|
||||
border-radius: 100%;
|
||||
border-color: black;
|
||||
border-style: solid;
|
||||
box-sizing: unset !important;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body style="background: transparent !important;">
|
||||
<div class = "dot" style = "display:none;"></div>
|
||||
|
||||
<div class="modal fade" id="textboard" tabindex="-1" role="dialog" aria-hidden="true" data-keyboard="false"
|
||||
data-backdrop="static">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="textboard_header">Result</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close" onclick="Close()">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form onkeydown="return event.key != 'Enter';">
|
||||
<div class="form-group">
|
||||
<textarea class="textarea" style="min-height: 28vw;min-width: 100%;"></textarea>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-dismiss="modal" onclick="Close()">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
<script>
|
||||
function Close(){
|
||||
$("#textboard").modal("hide");
|
||||
$.post('https://rcore_television/declined', JSON.stringify({}));
|
||||
}
|
||||
|
||||
$(function(){
|
||||
window.addEventListener('message', function(event) {
|
||||
var item = event.data;
|
||||
if(item.type === "showdot"){
|
||||
$(".dot").show("slow");
|
||||
}
|
||||
if(item.type === "hidedot"){
|
||||
$(".dot").hide("slow");
|
||||
}
|
||||
|
||||
if(item.type === "display_for_copy"){
|
||||
$('#textboard').modal("show");
|
||||
$(".textarea").val(item.text);
|
||||
}
|
||||
})
|
||||
});
|
||||
</script>
|
||||
</html>
|
|
@ -0,0 +1,82 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en" dir="ltr">
|
||||
<script src="/html/js/jquery.min.js"></script>
|
||||
<link rel="stylesheet" href="./css.css">
|
||||
<script src="/html/js/functions.js"></script>
|
||||
<style>
|
||||
body, html {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
background: black;
|
||||
}
|
||||
iframe {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 1.5%;
|
||||
width: 96.79%;
|
||||
height: 100%;
|
||||
border: none;
|
||||
}
|
||||
</style>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>rcore_television douyin support</title>
|
||||
</head>
|
||||
<body>
|
||||
<iframe id ="frame" frameborder="0" referrerpolicy="unsafe-url" allowfullscreen></iframe>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<script>
|
||||
function getQueryParams() {
|
||||
var qs = window.location.search;
|
||||
qs = qs.split('+').join(' ');
|
||||
|
||||
var params = {},
|
||||
tokens,
|
||||
re = /[?&]?([^=]+)=([^&]*)/g;
|
||||
|
||||
while (tokens = re.exec(qs)) {
|
||||
params[decodeURIComponent(tokens[1])] = decodeURIComponent(tokens[2]);
|
||||
}
|
||||
return params;
|
||||
}
|
||||
function extractVideoID(url) {
|
||||
const regex = /\/(BV\w+)/;
|
||||
const match = url.match(regex);
|
||||
return match ? match[1] : null;
|
||||
}
|
||||
|
||||
var result = getQueryParams();
|
||||
|
||||
var vol = Number(result.volume);
|
||||
var time = Number(result.time);
|
||||
|
||||
$("#frame").attr("src", "https://player.bilibili.com/player.html?bvid=" + extractVideoID(result.url) + "&autoplay=1&high_quality=1&danmaku=0");
|
||||
|
||||
$('#frame').on("load", function() {
|
||||
const iframe = document.getElementById("frame");
|
||||
const iframeDocument = iframe.contentDocument || iframe.contentWindow.document;
|
||||
|
||||
const interval = setInterval(() => {
|
||||
const video = iframeDocument.querySelector("video");
|
||||
if (video !== null) {
|
||||
clearInterval(interval);
|
||||
setInterval(() => {
|
||||
video.volume = GetNewVolume();
|
||||
}, 100);
|
||||
|
||||
video.addEventListener("loadedmetadata", () => {
|
||||
video.play();
|
||||
video.currentTime = time;
|
||||
$.post('http://rcore_television/updatePos', JSON.stringify({
|
||||
identifier: result.identifier,
|
||||
}));
|
||||
});
|
||||
}
|
||||
}, 50);
|
||||
});
|
||||
</script>
|
|
@ -0,0 +1,77 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en" dir="ltr">
|
||||
<script src="/html/js/jquery.min.js"></script>
|
||||
<link rel="stylesheet" href="./css.css">
|
||||
<script src="/html/js/functions.js"></script>
|
||||
<style>
|
||||
body, html {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
background: black;
|
||||
}
|
||||
iframe {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 1.5%;
|
||||
width: 96.79%;
|
||||
height: 100%;
|
||||
border: none;
|
||||
}
|
||||
</style>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>rcore_television douyin support</title>
|
||||
</head>
|
||||
<body>
|
||||
<iframe id ="frame" frameborder="0" referrerpolicy="unsafe-url" allowfullscreen></iframe>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<script>
|
||||
function getQueryParams() {
|
||||
var qs = window.location.search;
|
||||
qs = qs.split('+').join(' ');
|
||||
|
||||
var params = {},
|
||||
tokens,
|
||||
re = /[?&]?([^=]+)=([^&]*)/g;
|
||||
|
||||
while (tokens = re.exec(qs)) {
|
||||
params[decodeURIComponent(tokens[1])] = decodeURIComponent(tokens[2]);
|
||||
}
|
||||
return params;
|
||||
}
|
||||
|
||||
var result = getQueryParams();
|
||||
|
||||
var vol = Number(result.volume);
|
||||
var time = Number(result.time);
|
||||
|
||||
$("#frame").attr("src", "https://open.douyin.com/player/video?vid="+ result.url.split("/").pop() +"&autoplay=1")
|
||||
|
||||
$('#frame').on("load", function() {
|
||||
const iframe = document.getElementById("frame");
|
||||
const iframeDocument = iframe.contentDocument || iframe.contentWindow.document;
|
||||
|
||||
const interval = setInterval(() => {
|
||||
const video = iframeDocument.querySelector("video");
|
||||
if (video !== null) {
|
||||
clearInterval(interval);
|
||||
setInterval(() => {
|
||||
video.volume = GetNewVolume();
|
||||
}, 100);
|
||||
|
||||
video.addEventListener("loadedmetadata", () => {
|
||||
video.play();
|
||||
video.currentTime = time;
|
||||
$.post('http://rcore_television/updatePos', JSON.stringify({
|
||||
identifier: result.identifier,
|
||||
}));
|
||||
});
|
||||
}
|
||||
}, 50);
|
||||
});
|
||||
</script>
|
|
@ -0,0 +1,26 @@
|
|||
.centered {
|
||||
position: absolute;
|
||||
top:275px;
|
||||
bottom: 0;
|
||||
left: 68px;
|
||||
right: 0;
|
||||
margin: auto;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
max-width: 950px;
|
||||
max-height: 370px;
|
||||
}
|
||||
|
||||
#black iframe{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
canvas {
|
||||
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
background-color: black;
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en" dir="ltr">
|
||||
<script src='/html/js/jquery.min.js'></script>
|
||||
<script src="/html/js/howler.min.js" type="text/javascript"></script>
|
||||
<script src="/html/js/prefixfree.min.js"></script>
|
||||
<script src="/html/js/functions.js"></script>
|
||||
<link rel="stylesheet" href="./css.css">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>rcore_television audio support</title>
|
||||
</head>
|
||||
<body style="background-color: black;">
|
||||
<div id = "black" class = "centered">
|
||||
<canvas id="c"></canvas>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
<script src="/html/js/visualizer.js"></script>
|
||||
<script>
|
||||
var result = getQueryParams();
|
||||
var howl = null;
|
||||
updateFrame();
|
||||
|
||||
$( document ).ready(function() {
|
||||
howl = new Howl({
|
||||
src: [result.url],
|
||||
loop: false,
|
||||
format: ['mp3'],
|
||||
volume: 0,
|
||||
autoplay: true,
|
||||
onplay: function() {
|
||||
$.post('http://rcore_television/updatePos', JSON.stringify({
|
||||
identifier: result.identifier,
|
||||
}));
|
||||
|
||||
this.seek(result.time);
|
||||
setTimeout(UpdatVolume, 70);
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
function UpdatVolume(){
|
||||
if(howl){
|
||||
howl.volume(GetNewVolume());
|
||||
}
|
||||
setTimeout(UpdatVolume, 70);
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,22 @@
|
|||
body {
|
||||
background: black;
|
||||
}
|
||||
|
||||
.centered {
|
||||
position: absolute;
|
||||
top:275px;
|
||||
bottom: 0;
|
||||
left: 68px;
|
||||
right: 0;
|
||||
margin: auto;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
max-width: 950px;
|
||||
max-height: 370px;
|
||||
}
|
||||
|
||||
#black iframe{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en" dir="ltr">
|
||||
<script src="/html/js/jquery.min.js"></script>
|
||||
<script src="/html/js/functions.js"></script>
|
||||
<link rel="stylesheet" href="./css.css">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>rcore_television other support</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id = "black" class = "centered">
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<script>
|
||||
var result = getQueryParams();
|
||||
|
||||
updateFrame();
|
||||
|
||||
$("#black").append("<iframe src='"+ result.url +"'></iframe>");
|
||||
</script>
|
|
@ -0,0 +1,23 @@
|
|||
### Function list
|
||||
|
||||
------------
|
||||
|
||||
- getQueryParams() will return array list
|
||||
```
|
||||
url
|
||||
volume
|
||||
time
|
||||
```
|
||||
|
||||
- Usage:
|
||||
|
||||
```javascript
|
||||
var result = getQueryParams();
|
||||
alert(result.url);
|
||||
```
|
||||
<br>
|
||||
|
||||
- updateFrame() <br> Will update the container to the resolution of TV from config<br>
|
||||
it is important to always call it or the TV might be too big to fit the screen.
|
||||
|
||||
------------
|
|
@ -0,0 +1,27 @@
|
|||
body{
|
||||
background-color: black;
|
||||
}
|
||||
|
||||
video{
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.centered {
|
||||
position: absolute;
|
||||
top:275px;
|
||||
bottom: 0;
|
||||
left: 68px;
|
||||
right: 0;
|
||||
margin: auto;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
max-width: 950px;
|
||||
max-height: 370px;
|
||||
}
|
||||
|
||||
#black iframe{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en" dir="ltr">
|
||||
<script src="/html/js/jquery.min.js"></script>
|
||||
<script src="https://embed.twitch.tv/embed/v1.js"></script>
|
||||
<script src="/html/js/functions.js"></script>
|
||||
<link rel="stylesheet" href="./css.css">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>rcore_television twitch support</title>
|
||||
</head>
|
||||
<body >
|
||||
<div id = "black" class = "centered">
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
<script>
|
||||
var result = getQueryParams();
|
||||
|
||||
updateFrame();
|
||||
|
||||
var player = new Twitch.Embed("black", {
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
channel: result.url.replace("https://www.twitch.tv/", ""),
|
||||
parent: ["localhost:13172"]
|
||||
});
|
||||
|
||||
player.setVolume(result.volume);
|
||||
</script>
|
|
@ -0,0 +1,59 @@
|
|||
body{
|
||||
background-color: black;
|
||||
}
|
||||
|
||||
#main-video {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
#blurred-video {
|
||||
left: 50%;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
filter: blur(15px);
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.centered {
|
||||
position: absolute;
|
||||
top:275px;
|
||||
bottom: 0;
|
||||
left: 68px;
|
||||
right: 0;
|
||||
margin: auto;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
max-width: 950px;
|
||||
max-height: 370px;
|
||||
}
|
||||
|
||||
#black iframe{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
video::-webkit-media-controls {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Could Use thise as well for Individual Controls */
|
||||
video::-webkit-media-controls-play-button {}
|
||||
|
||||
video::-webkit-media-controls-volume-slider {}
|
||||
|
||||
video::-webkit-media-controls-mute-button {}
|
||||
|
||||
video::-webkit-media-controls-timeline {}
|
||||
|
||||
video::-webkit-media-controls-current-time-display {}
|
|
@ -0,0 +1,65 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en" dir="ltr">
|
||||
<script src='/html/js/jquery.min.js'></script>
|
||||
<script src="/html/js/functions.js"></script>
|
||||
<link rel="stylesheet" href="./css.css">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>rcore_television video support</title>
|
||||
</head>
|
||||
<body>
|
||||
<div>
|
||||
<video id = "main-video" preload="none" onplay="updateTime(1)" controls autoplay>
|
||||
<source id = "main-video-source">
|
||||
</video>
|
||||
<video id = "blurred-video" preload="none" onplay="updateTime(2)" onloadstart="this.volume=0.0" controls autoplay>
|
||||
<source id = "blurred-video-source">
|
||||
</video>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
<script>
|
||||
var result = getQueryParams();
|
||||
|
||||
var vol = result.volume;
|
||||
var time = result.time;
|
||||
|
||||
updateFrame();
|
||||
|
||||
$( document ).ready(function() {
|
||||
$("#main-video-source").attr("src", result.url);
|
||||
$("#main-video")[0].load();
|
||||
$('#main-video').trigger('play');
|
||||
|
||||
$("#blurred-video-source").attr("src", result.url);
|
||||
$("#blurred-video")[0].load();
|
||||
$('#blurred-video').trigger('play');
|
||||
});
|
||||
|
||||
function updateTime(video){
|
||||
if(video == 1){
|
||||
var player = $("#main-video").get(0);
|
||||
|
||||
player.currentTime = time;
|
||||
player.volume = 0;
|
||||
setTimeout(UpdatVolume, 100);
|
||||
}
|
||||
if(video == 2){
|
||||
var blurredVideo = $("#blurred-video").get(0);
|
||||
|
||||
blurredVideo.currentTime = time;
|
||||
blurredVideo.volume = 0;
|
||||
}
|
||||
|
||||
$.post('http://rcore_television/updatePos', JSON.stringify({
|
||||
identifier: result.identifier,
|
||||
}));
|
||||
}
|
||||
|
||||
function UpdatVolume(){
|
||||
var player = $("#main-video").get(0);
|
||||
player.volume = GetNewVolume();
|
||||
|
||||
setTimeout(UpdatVolume, 100);
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,19 @@
|
|||
body{
|
||||
background-color: black;
|
||||
}
|
||||
|
||||
.centered {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
width: -webkit-fill-available;
|
||||
height: -webkit-fill-available;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#black iframe{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en" dir="ltr">
|
||||
<script src="/html/js/jquery.min.js"></script>
|
||||
<script src="https://s.ytimg.com/yts/jsbin/www-widgetapi-vflJJaNgk/www-widgetapi.js"></script>
|
||||
<script src="https://www.youtube.com/iframe_api"></script>
|
||||
<script src="/html/js/functions.js"></script>
|
||||
<script src="./yt-player.js"></script>
|
||||
<link rel="stylesheet" href="./css.css">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>rcore_television youtube support</title>
|
||||
</head>
|
||||
<body>
|
||||
<iframe id="frame" class="centered" frameborder="0"></iframe>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<script>
|
||||
var result = getQueryParams();
|
||||
|
||||
var vol = Number(result.volume);
|
||||
var time = Number(result.time);
|
||||
|
||||
$("#frame").attr("src", "https://proxy.rcore.cz/v2.html?url=" + result.url + "&volume=0.0");
|
||||
$('#frame').on("load", function() {
|
||||
const iframe = document.getElementById("frame");
|
||||
const iframeDocument = iframe.contentDocument || iframe.contentWindow.document;
|
||||
|
||||
if (iframeDocument) {
|
||||
const interval = setInterval(() => {
|
||||
const blackIframe = iframeDocument.getElementById("black");
|
||||
if (blackIframe) {
|
||||
const blackIframeDocument = blackIframe.contentDocument || blackIframe.contentWindow.document;
|
||||
const video = blackIframeDocument.querySelector("video");
|
||||
if (video !== null) {
|
||||
$.post('http://rcore_television/updatePos', JSON.stringify({
|
||||
identifier: result.identifier,
|
||||
}));
|
||||
clearInterval(interval);
|
||||
|
||||
setInterval(() => {
|
||||
video.volume = GetNewVolume();
|
||||
}, 100);
|
||||
|
||||
video.addEventListener("loadedmetadata", () => {
|
||||
video.currentTime = time;
|
||||
});
|
||||
}
|
||||
}
|
||||
}, 50);
|
||||
}
|
||||
});
|
||||
</script>
|
|
@ -0,0 +1,31 @@
|
|||
var yPlayer = null;
|
||||
|
||||
function callMe(vol, time){
|
||||
yPlayer.setVolume(vol);
|
||||
yPlayer.playVideo();
|
||||
yPlayer.seekTo(time);
|
||||
setTimeout(UpdatVolume, 100);
|
||||
yPlayer.setVolume(0);
|
||||
}
|
||||
|
||||
function getYoutubeUrlId(url)
|
||||
{
|
||||
var videoId = "";
|
||||
if( url.indexOf("youtube") !== -1 ){
|
||||
var urlParts = url.split("?v=");
|
||||
videoId = urlParts[1].substring(0,11);
|
||||
}
|
||||
|
||||
if( url.indexOf("youtu.be") !== -1 ){
|
||||
var urlParts = url.replace("//", "").split("/");
|
||||
videoId = urlParts[1].substring(0,11);
|
||||
}
|
||||
return videoId;
|
||||
}
|
||||
|
||||
function UpdatVolume(){
|
||||
if(yPlayer){
|
||||
yPlayer.setVolume(GetNewVolume() * 100);
|
||||
}
|
||||
setTimeout(UpdatVolume, 100);
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
Locales = {
|
||||
["help"] = "Television help\n",
|
||||
|
||||
["tv_help_line_2"] = "Use keys ~INPUT_CELLPHONE_UP~ ~INPUT_CELLPHONE_DOWN~ to switch default TV program\n",
|
||||
["tv_help_line_3"] = "To start selected program press ~INPUT_CELLPHONE_SELECT~\n",
|
||||
["tv_help_line_4"] = "To end current program press ~INPUT_DIVE~\n\n",
|
||||
["tv_help_line_5"] = "To play custom video use command ~g~/playlink~w~\n\n",
|
||||
["tv_help_line_6"] = "To change TV volume use command ~g~/tvvolume~w~\n",
|
||||
|
||||
["volume_changed"] = "You updated prefer TV volume to: %s",
|
||||
["tvstation_changed"] = "You changed TV station to: %s",
|
||||
|
||||
["volume_invalid"] = "The volume has to be between 0-100",
|
||||
["argument_has_to_be_number"] = "The volume has to be a number!",
|
||||
|
||||
["volume_info"] = "Will set a new volume for TV",
|
||||
["volume_argument"] = "volume",
|
||||
|
||||
["playlink_info"] = "Will play a custom URL in the TV.",
|
||||
["play_url_info"] = "Your URL for website",
|
||||
|
||||
["switch_to_menu"] = "Push ~INPUT_COVER~ button to open television menu",
|
||||
|
||||
["doesnt_have_remote"] = "You will need this/these item %s to open the TV!",
|
||||
|
||||
["cant_play_video"] = "You need to be in a TV menu to play video!",
|
||||
|
||||
["link_isnt_whitelisted"] = "You cant use this link ! It is not whitelisted!",
|
||||
["blacklisted_link"] = "This link is blacklisted! Use other one please.",
|
||||
|
||||
["stopped_program"] = "You stopped the current TV program",
|
||||
|
||||
["not_vip"] = "You're not VIP to use a television!",
|
||||
|
||||
["target_label"] = "Open the TV",
|
||||
["target_icon"] = "fas fa-gamepad",
|
||||
["target_targeticon"] = "fas fa-gamepad",
|
||||
}
|
|
@ -0,0 +1,279 @@
|
|||
ESX = nil
|
||||
QBCore = nil
|
||||
|
||||
if Config.FrameWork == 1 then
|
||||
ESX = GetEsxObject()
|
||||
end
|
||||
|
||||
if Config.FrameWork == 2 then
|
||||
QBCore = Config.GetQBCoreObject()
|
||||
end
|
||||
|
||||
--- Will send a print when debug is enabled
|
||||
--- @param ... object
|
||||
function Debug(...)
|
||||
if Config.Debug then
|
||||
print(...)
|
||||
end
|
||||
end
|
||||
|
||||
TelevisionCache = {}
|
||||
PlayerBucketCache = {}
|
||||
|
||||
RegisterNetEvent("rcore_television:stopTelevisionAtCoords", function(coords)
|
||||
if not source then
|
||||
print("Event: \"rcore_television:stopTelevisionAtCoords\" has to be called from client side only!")
|
||||
end
|
||||
|
||||
local playerBucket = GetPlayerRoutingBucket(source)
|
||||
|
||||
if not TelevisionCache[playerBucket] then
|
||||
TelevisionCache[playerBucket] = {}
|
||||
end
|
||||
|
||||
for k, v in pairs(TelevisionCache[playerBucket]) do
|
||||
if #(v.tvPos - coords) < 1.5 then
|
||||
table.remove(TelevisionCache[playerBucket], k)
|
||||
TriggerClientEvent("rcore_television:stopTelevisionAtCoords", -1, coords)
|
||||
break
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
RegisterNetEvent("rcore_television:fetchCache", function()
|
||||
local playerBucket = GetPlayerRoutingBucket(source)
|
||||
|
||||
if not TelevisionCache[playerBucket] then
|
||||
TelevisionCache[playerBucket] = {}
|
||||
end
|
||||
|
||||
TriggerClientEvent("rcore_television:fetchCache", source, TelevisionCache[playerBucket])
|
||||
end)
|
||||
|
||||
-- adding time thread
|
||||
CreateThread(function()
|
||||
while true do
|
||||
Wait(1000)
|
||||
for _, val in pairs(TelevisionCache) do
|
||||
for _, v in pairs(val) do
|
||||
if v.time then
|
||||
v.time = v.time + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
-- updating bucket thread
|
||||
CreateThread(function()
|
||||
while true do
|
||||
Wait(500)
|
||||
for k, v in pairs(GetPlayers()) do
|
||||
Wait(2)
|
||||
local bucketID = GetPlayerRoutingBucket(k)
|
||||
if PlayerBucketCache[k] ~= bucketID then
|
||||
PlayerBucketCache[k] = bucketID
|
||||
TriggerClientEvent(TriggerName("UpdatePlayerBucketID"), k, bucketID)
|
||||
Debug("Updating player bucket ID cache", bucketID, "player ID", k)
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
RegisterNetEvent("rcore_television:AddTelevisionToCache", function(data)
|
||||
if not source then
|
||||
print("Event: \"rcore_television:AddTelevisionToCache\" has to be called from client side only!")
|
||||
end
|
||||
|
||||
local found = false
|
||||
local key
|
||||
local playerBucket = GetPlayerRoutingBucket(source)
|
||||
|
||||
if not TelevisionCache[playerBucket] then
|
||||
TelevisionCache[playerBucket] = {}
|
||||
end
|
||||
|
||||
for k, v in pairs(TelevisionCache[playerBucket]) do
|
||||
if data.NetID then
|
||||
if v.NetID == data.NetID then
|
||||
found = true
|
||||
key = k
|
||||
break
|
||||
end
|
||||
end
|
||||
if #(v.tvPos - data.tvPos) < 1.5 then
|
||||
found = true
|
||||
key = k
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if not found then
|
||||
table.insert(TelevisionCache[playerBucket], data)
|
||||
TriggerClientEvent("rcore_television:AddTelevisionToCache", -1, data)
|
||||
else
|
||||
TelevisionCache[playerBucket][key].URL = data.URL
|
||||
TelevisionCache[playerBucket][key].time = 0
|
||||
|
||||
TriggerClientEvent("rcore_television:UpdateTelevisionCache", -1, key, TelevisionCache[playerBucket][key])
|
||||
end
|
||||
end)
|
||||
|
||||
registerCallback(TriggerName("DoesPlayerHaveCertain"), function(source, cb, items)
|
||||
if Config.FrameWork == 1 then
|
||||
local xPlayer = ESX.GetPlayerFromId(source)
|
||||
for k, v in pairs(items) do
|
||||
local item = xPlayer.getInventoryItem(v)
|
||||
if item then
|
||||
if item.count ~= 0 then
|
||||
cb(true)
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
cb(false)
|
||||
end
|
||||
if Config.FrameWork == 2 then
|
||||
local qbPlayer = QBCore.Functions.GetPlayer(source)
|
||||
for k, v in pairs(items) do
|
||||
if qbPlayer.Functions.GetItemByName(v) then
|
||||
cb(true)
|
||||
return
|
||||
end
|
||||
end
|
||||
cb(false)
|
||||
end
|
||||
end)
|
||||
|
||||
local SharedGroups = {}
|
||||
if Config.Framework ~= 2 then
|
||||
SharedGroups = {
|
||||
"user", "mod", "moderator", "help", "helper", "admin", "superadmin", "god",
|
||||
}
|
||||
else
|
||||
SharedGroups = QBCore.Config.Server.Permissions
|
||||
end
|
||||
|
||||
for k, v in pairs(SharedGroups) do
|
||||
ExecuteCommand(("add_ace qbcore.%s rcore_perm.%s allow"):format(v, v))
|
||||
ExecuteCommand(("add_ace group.%s rcore_perm.%s allow"):format(v, v))
|
||||
end
|
||||
|
||||
local grantedPermission = {}
|
||||
function IsPlayerInGroup(source, groups, acePermission)
|
||||
if grantedPermission[source] then
|
||||
return true
|
||||
end
|
||||
|
||||
if acePermission then
|
||||
if IsPlayerAceAllowed(source, acePermission) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
if Config.FrameWork == 2 then
|
||||
for k, v in pairs(groups) do
|
||||
if IsPlayerAceAllowed(source, "rcore_perm." .. v) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if Config.FrameWork == 1 then
|
||||
local xPlayer = ESX.GetPlayerFromId(source)
|
||||
if xPlayer then
|
||||
for k, v in pairs(groups) do
|
||||
if xPlayer.getPermissions then
|
||||
if Config.PermissionGroup.ESX[1][xPlayer.getPermissions()] then
|
||||
return true
|
||||
end
|
||||
end
|
||||
if xPlayer.getGroup then
|
||||
if Config.PermissionGroup.ESX[2][xPlayer.getGroup()] then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
registerCallback(TriggerName("hasPermission"), function(source, cb, groups, acePermission)
|
||||
cb(IsPlayerInGroup(source, groups, acePermission))
|
||||
end)
|
||||
|
||||
CreateThread(function()
|
||||
local deepCopy = function(object)
|
||||
local lookup_table = {}
|
||||
local function _copy(object)
|
||||
if type(object) ~= "table" then
|
||||
return object
|
||||
elseif lookup_table[object] then
|
||||
return lookup_table[object]
|
||||
end
|
||||
local new_table = {}
|
||||
lookup_table[object] = new_table
|
||||
for index, value in pairs(object) do
|
||||
new_table[_copy(index)] = _copy(value)
|
||||
end
|
||||
return setmetatable(new_table, getmetatable(object))
|
||||
end
|
||||
return _copy(object)
|
||||
end
|
||||
|
||||
local permissionGroup = deepCopy(Config.PermissionGroup)
|
||||
for framework, v in pairs(permissionGroup) do
|
||||
for index, _v in pairs(v) do
|
||||
for key, permissions in pairs(_v) do
|
||||
Config.PermissionGroup[framework][index][key] = nil
|
||||
Config.PermissionGroup[framework][index][permissions] = true
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
RegisterCommand('tvgrantpermission', function(source, args, user)
|
||||
if source ~= 0 then
|
||||
TriggerClientEvent('chat:addMessage', source, { args = { "This command can be used ONLY in console! The 'Live Console' in txadmin panel." } })
|
||||
return
|
||||
end
|
||||
|
||||
if args[1] == nil then
|
||||
print("Please use command: /tvgrantpermission [player ID] | Example: /tvgrantpermission 7")
|
||||
return
|
||||
end
|
||||
|
||||
local sourceNumber = tonumber(args[1])
|
||||
|
||||
if not sourceNumber then
|
||||
print("The player ID has to be number!")
|
||||
return
|
||||
end
|
||||
|
||||
if grantedPermission[sourceNumber] ~= nil then
|
||||
print("This player has already temporary permission!")
|
||||
return
|
||||
end
|
||||
|
||||
grantedPermission[sourceNumber] = true
|
||||
print("You granted temporary permission to the user with server ID: ", sourceNumber, "The permission last 30 minutes")
|
||||
Wait(1000 * 60 * 30)
|
||||
|
||||
grantedPermission[sourceNumber] = nil
|
||||
end)
|
||||
|
||||
RegisterCommand("televisionversion", function(source, args, rawCommand)
|
||||
local frameworks = { [0] = "standlone", [1] = "esx", [2] = "qb-core" }
|
||||
local detection = { [1] = "Raycast", [2] = "GetClosestObject" }
|
||||
|
||||
print("^3")
|
||||
print("rcore_television")
|
||||
|
||||
print(string.format("^7framework: ^3%s", frameworks[Config.FrameWork]))
|
||||
print(string.format("^7detection type: ^3%s", detection[Config.DetectorType]))
|
||||
print(string.format("^7version: ^3%s", GetResourceMetadata(GetCurrentResourceName(), "version")))
|
||||
|
||||
print("https://documentation.rcore.cz/paid-resources/rcore_television")
|
||||
print("^7")
|
||||
end, false)
|
|
@ -0,0 +1,150 @@
|
|||
------------------------------------------------------------------
|
||||
-- Need to be changed to your framework, for now default is ESX --
|
||||
------------------------------------------------------------------
|
||||
if Config.FrameWork == 1 then
|
||||
local PlayerData = {}
|
||||
ESX = GetEsxObject()
|
||||
|
||||
CreateThread(function()
|
||||
if ESX then
|
||||
if ESX.IsPlayerLoaded() then
|
||||
PlayerData = ESX.GetPlayerData()
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
RegisterNetEvent(Config.EsxPlayerLoaded or 'esx:playerLoaded', function(xPlayer)
|
||||
PlayerData = xPlayer
|
||||
end)
|
||||
|
||||
RegisterNetEvent(Config.EsxSetJob or 'esx:setJob', function(job)
|
||||
PlayerData.job = job
|
||||
end)
|
||||
|
||||
function IsAtJob(name, grade)
|
||||
if not PlayerData or not PlayerData.job then
|
||||
print("ERROR", "the job for ESX is nil value please check if your events are correct.")
|
||||
return true
|
||||
end
|
||||
|
||||
if grade and grade == "*" and PlayerData.job.name == name then
|
||||
return true
|
||||
end
|
||||
if grade then
|
||||
return PlayerData.job.name == name and PlayerData.job.grade_name == grade
|
||||
end
|
||||
return PlayerData.job.name == name
|
||||
end
|
||||
end
|
||||
|
||||
if Config.FrameWork == 2 then
|
||||
local PlayerData = {}
|
||||
local QBCore
|
||||
function UpdatePlayerDataForQBCore()
|
||||
local pData = QBCore.Functions.GetPlayerData()
|
||||
|
||||
local jobName = "none"
|
||||
local gradeName = "none"
|
||||
|
||||
if pData.job then
|
||||
jobName = pData.job.name or "none"
|
||||
|
||||
if pData.job.grade then
|
||||
gradeName = pData.job.grade.name
|
||||
end
|
||||
end
|
||||
|
||||
PlayerData = {
|
||||
job = {
|
||||
name = jobName,
|
||||
grade_name = gradeName,
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
CreateThread(function()
|
||||
QBCore = Config.GetQBCoreObject()
|
||||
|
||||
if QBCore and QBCore.Functions.GetPlayerData() then
|
||||
UpdatePlayerDataForQBCore()
|
||||
end
|
||||
end)
|
||||
|
||||
-- Will load player job + update markers
|
||||
RegisterNetEvent(Config.OnPlayerLoaded, function()
|
||||
UpdatePlayerDataForQBCore()
|
||||
end)
|
||||
|
||||
-- Will load player job + update markers
|
||||
RegisterNetEvent(Config.OnJobUpdate, function()
|
||||
UpdatePlayerDataForQBCore()
|
||||
end)
|
||||
|
||||
function IsAtJob(name, grade)
|
||||
if not PlayerData or not PlayerData.job then
|
||||
print("ERROR", "the job for QBcore is nil value please check if your events are correct.")
|
||||
return true
|
||||
end
|
||||
|
||||
if grade and grade == "*" and PlayerData.job.name == name then
|
||||
return true
|
||||
end
|
||||
if grade then
|
||||
return PlayerData.job.name == name and PlayerData.job.grade_name == grade
|
||||
end
|
||||
return PlayerData.job.name == name
|
||||
end
|
||||
end
|
||||
|
||||
if Config.FrameWork == 0 then
|
||||
function IsAtJob(name, grade)
|
||||
return true
|
||||
end
|
||||
end
|
||||
------------------------
|
||||
-- Optional to change --
|
||||
------------------------
|
||||
-- This will allow to open any TV if true, other players wont be able to interact but will albe to see
|
||||
-- what is playing on TVscreen
|
||||
function CustomPermission()
|
||||
return true
|
||||
end
|
||||
|
||||
function showNotification(text)
|
||||
SetNotificationTextEntry('STRING')
|
||||
AddTextComponentString(text)
|
||||
DrawNotification(0, 1)
|
||||
end
|
||||
|
||||
RegisterNetEvent('rcore_tv:notification')
|
||||
AddEventHandler('rcore_tv:notification', showNotification)
|
||||
|
||||
--- call callback
|
||||
|
||||
---TAKEN FROM rcore framework
|
||||
---https://githu.com/Isigar/relisoft_core
|
||||
---https://docs.rcore.cz
|
||||
|
||||
local clientCallbacks = {}
|
||||
local currentRequest = 0
|
||||
|
||||
function callCallback(name, cb, ...)
|
||||
clientCallbacks[currentRequest] = cb
|
||||
TriggerServerEvent(TriggerName('callCallback'), name, currentRequest, ...)
|
||||
|
||||
if currentRequest < 65535 then
|
||||
currentRequest = currentRequest + 1
|
||||
else
|
||||
currentRequest = 0
|
||||
end
|
||||
end
|
||||
|
||||
exports('callCallback', callCallback)
|
||||
|
||||
RegisterNetEvent(TriggerName('callback'))
|
||||
AddEventHandler(TriggerName('callback'), function(requestId, ...)
|
||||
if clientCallbacks[requestId] == nil then
|
||||
return
|
||||
end
|
||||
clientCallbacks[requestId](...)
|
||||
end)
|
|
@ -0,0 +1,65 @@
|
|||
------------------------------------------------------------------
|
||||
-- Need to be changed to your framework, for now default is ESX --
|
||||
------------------------------------------------------------------
|
||||
ESX = nil
|
||||
QBCore = nil
|
||||
|
||||
if Config.FrameWork == 1 then
|
||||
ESX = GetEsxObject()
|
||||
end
|
||||
|
||||
if Config.FrameWork == 2 then
|
||||
QBCore = Config.GetQBCoreObject()
|
||||
end
|
||||
|
||||
|
||||
function HavePlayerControler(source, itemName)
|
||||
if Config.FrameWork == 1 then
|
||||
local sourceItem = ESX.GetPlayerFromId(source).getInventoryItem(itemName)
|
||||
return (sourceItem ~= nil and sourceItem.count ~= 0)
|
||||
end
|
||||
if Config.FrameWork == 2 then
|
||||
local qbPlayer = QBCore.Functions.GetPlayer(source)
|
||||
local item = qbPlayer.Functions.GetItemByName(itemName) or {}
|
||||
local ItemInfo = {
|
||||
name = itemName,
|
||||
count = item.amount or 0,
|
||||
label = item.label or "none",
|
||||
weight = item.weight or 0,
|
||||
usable = item.useable or false,
|
||||
rare = false,
|
||||
canRemove = false,
|
||||
}
|
||||
|
||||
return ItemInfo.count ~= 0
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
--- call callback
|
||||
---TAKEN FROM rcore framework
|
||||
---https://githu.com/Isigar/relisoft_core
|
||||
---https://docs.rcore.cz
|
||||
local serverCallbacks = {}
|
||||
local callbacksRequestsHistory = {}
|
||||
|
||||
function registerCallback(cbName, callback)
|
||||
serverCallbacks[cbName] = callback
|
||||
end
|
||||
|
||||
RegisterNetEvent(TriggerName('callCallback'))
|
||||
AddEventHandler(TriggerName('callCallback'), function(name, requestId, ...)
|
||||
local source = source
|
||||
if serverCallbacks[name] == nil then
|
||||
return
|
||||
end
|
||||
callbacksRequestsHistory[requestId] = {
|
||||
name = name,
|
||||
source = source,
|
||||
}
|
||||
local call = serverCallbacks[name]
|
||||
call(source, function(...)
|
||||
TriggerClientEvent(TriggerName('callback'), source, requestId, ...)
|
||||
end, ...)
|
||||
end)
|
|
@ -0,0 +1,241 @@
|
|||
function GetEsxObject()
|
||||
local promise_ = promise:new()
|
||||
local obj
|
||||
xpcall(function()
|
||||
obj = exports['es_extended']['getSharedObject']()
|
||||
promise_:resolve(obj)
|
||||
end, function(error)
|
||||
TriggerEvent(Config.ESX_Object or "esx:getSharedObject", function(module)
|
||||
obj = module
|
||||
promise_:resolve(obj)
|
||||
end)
|
||||
end)
|
||||
|
||||
Citizen.Await(obj)
|
||||
return obj
|
||||
end
|
||||
|
||||
Config.GetQBCoreObject = function()
|
||||
local promise_ = promise:new()
|
||||
local obj
|
||||
xpcall(function()
|
||||
obj = exports['qb-core']['GetCoreObject']()
|
||||
promise_:resolve(obj)
|
||||
end, function(error)
|
||||
xpcall(function()
|
||||
obj = exports['qb-core']['GetSharedObject']()
|
||||
promise_:resolve(obj)
|
||||
end, function(error)
|
||||
|
||||
local QBCore = nil
|
||||
local tries = 10
|
||||
|
||||
LoadQBCore = function()
|
||||
if tries == 0 then
|
||||
print("The QBCORE couldnt load any object! You need to correct the event / resource name for export!")
|
||||
return
|
||||
end
|
||||
|
||||
tries = tries - 1
|
||||
|
||||
if QBCore == nil then
|
||||
SetTimeout(100, LoadQBCore)
|
||||
end
|
||||
|
||||
TriggerEvent(Config.QBCoreObject or "QBCore:GetObject", function(module)
|
||||
QBCore = module
|
||||
|
||||
obj = QBCore
|
||||
promise_:resolve(QBCore)
|
||||
end)
|
||||
end
|
||||
|
||||
LoadQBCore()
|
||||
|
||||
end)
|
||||
end)
|
||||
|
||||
Citizen.Await(obj)
|
||||
|
||||
return obj
|
||||
end
|
||||
|
||||
function DrawUIText(text, x, y)
|
||||
SetTextFont(0)
|
||||
SetTextScale(0.5, 0.5)
|
||||
SetTextColour(255, 255, 255, 255)
|
||||
SetTextOutline()
|
||||
SetTextCentre(true)
|
||||
|
||||
BeginTextCommandDisplayText("STRING")
|
||||
AddTextComponentSubstringPlayerName(text)
|
||||
EndTextCommandDisplayText(x, y)
|
||||
end
|
||||
|
||||
--- this is for translation
|
||||
--- @param str string
|
||||
--- @param ... parameters
|
||||
function _U(str, ...)
|
||||
if type(Locales) ~= "table" then
|
||||
return string.format("Locales table doesnt exists! There is probably syntax error in the translation or the file is missing completely!\n", GetCurrentResourceName())
|
||||
end
|
||||
if not Locales[str] then
|
||||
return string.format("[%s] There isnt such [%s] translation", GetCurrentResourceName(), str)
|
||||
end
|
||||
return string.format(Locales[str], ...)
|
||||
end
|
||||
|
||||
--- Will return true/false
|
||||
--- @param url string
|
||||
function isWhitelisted(url)
|
||||
url = string.lower(url)
|
||||
for k, v in pairs(Config.whitelisted) do
|
||||
if string.match(url, v) ~= nil then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
--- Will return true/false
|
||||
--- @param url string
|
||||
function isBlackListed(url)
|
||||
url = string.lower(url or "")
|
||||
for k, v in pairs(Config.blackListed) do
|
||||
if string.match(url, v) ~= nil then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
--- Will return timestamp from youtube URL
|
||||
--- @param url string
|
||||
function GetTimeFromUrl(url)
|
||||
local pattern = "t=([^#&\n\r]+)"
|
||||
|
||||
local _time = string.match(url, pattern)
|
||||
|
||||
if _time then
|
||||
_time = _time.gsub(_time, "%D+", "")
|
||||
_time = tonumber(_time)
|
||||
else
|
||||
_time = 0
|
||||
end
|
||||
|
||||
return _time
|
||||
end
|
||||
|
||||
--- trigger name
|
||||
--- @param name string
|
||||
function TriggerName(name)
|
||||
return string.format('%s:%s', GetCurrentResourceName(), name)
|
||||
end
|
||||
|
||||
-- Will deep copy table
|
||||
--- @param orig table
|
||||
function Deepcopy(orig)
|
||||
local orig_type = type(orig)
|
||||
local copy
|
||||
if orig_type == 'table' then
|
||||
copy = {}
|
||||
for orig_key, orig_value in next, orig, nil do
|
||||
copy[Deepcopy(orig_key)] = Deepcopy(orig_value)
|
||||
end
|
||||
setmetatable(copy, Deepcopy(getmetatable(orig)))
|
||||
else
|
||||
-- number, string, boolean, etc
|
||||
copy = orig
|
||||
end
|
||||
return copy
|
||||
end
|
||||
|
||||
-- will dump table
|
||||
--- @param node table
|
||||
--- @param printing boolean
|
||||
function Dump(node, printing)
|
||||
local cache, stack, output = {}, {}, {}
|
||||
local depth = 1
|
||||
local output_str = "{\n"
|
||||
|
||||
while true do
|
||||
local size = 0
|
||||
for k, v in pairs(node) do
|
||||
size = size + 1
|
||||
end
|
||||
|
||||
local cur_index = 1
|
||||
for k, v in pairs(node) do
|
||||
if (cache[node] == nil) or (cur_index >= cache[node]) then
|
||||
|
||||
if (string.find(output_str, "}", output_str:len())) then
|
||||
output_str = output_str .. ",\n"
|
||||
elseif not (string.find(output_str, "\n", output_str:len())) then
|
||||
output_str = output_str .. "\n"
|
||||
end
|
||||
|
||||
-- This is necessary for working with HUGE tables otherwise we run out of memory using concat on huge strings
|
||||
table.insert(output, output_str)
|
||||
output_str = ""
|
||||
|
||||
local key
|
||||
if (type(k) == "number" or type(k) == "boolean") then
|
||||
key = "[" .. tostring(k) .. "]"
|
||||
else
|
||||
key = "['" .. tostring(k) .. "']"
|
||||
end
|
||||
|
||||
local isWhitelisted = false
|
||||
|
||||
if type(v) == "string" then
|
||||
isWhitelisted = string.match(string.lower(v), "nil")
|
||||
end
|
||||
|
||||
if (type(v) == "number" or type(v) == "boolean" or type(v) == "vector3" or isWhitelisted) then
|
||||
output_str = output_str .. string.rep('\t', depth) .. key .. " = " .. tostring(v)
|
||||
elseif (type(v) == "table") then
|
||||
output_str = output_str .. string.rep('\t', depth) .. key .. " = {\n"
|
||||
table.insert(stack, node)
|
||||
table.insert(stack, v)
|
||||
cache[node] = cur_index + 1
|
||||
break
|
||||
else
|
||||
output_str = output_str .. string.rep('\t', depth) .. key .. " = '" .. tostring(v) .. "'"
|
||||
end
|
||||
|
||||
if (cur_index == size) then
|
||||
output_str = output_str .. "\n" .. string.rep('\t', depth - 1) .. "}"
|
||||
else
|
||||
output_str = output_str .. ","
|
||||
end
|
||||
else
|
||||
-- close the table
|
||||
if (cur_index == size) then
|
||||
output_str = output_str .. "\n" .. string.rep('\t', depth - 1) .. "}"
|
||||
end
|
||||
end
|
||||
|
||||
cur_index = cur_index + 1
|
||||
end
|
||||
|
||||
if (size == 0) then
|
||||
output_str = output_str .. "\n" .. string.rep('\t', depth - 1) .. "}"
|
||||
end
|
||||
|
||||
if (#stack > 0) then
|
||||
node = stack[#stack]
|
||||
stack[#stack] = nil
|
||||
depth = cache[node] == nil and depth + 1 or depth - 1
|
||||
else
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
-- This is necessary for working with HUGE tables otherwise we run out of memory using concat on huge strings
|
||||
table.insert(output, output_str)
|
||||
output_str = table.concat(output)
|
||||
if not printing then
|
||||
print(output_str)
|
||||
end
|
||||
return output_str
|
||||
end
|
17
resources/[freizeit]/[rcore_tv]/readme.md
Normal file
17
resources/[freizeit]/[rcore_tv]/readme.md
Normal file
|
@ -0,0 +1,17 @@
|
|||
# rcore_television
|
||||
|
||||
if you see error: Bad binary format or syntax error near </1>
|
||||
|
||||
Read this guide:
|
||||
https://documentation.rcore.cz/cfx-auth-system/error-syntax-error-near-less-than-1-greater-than
|
||||
|
||||
i see "you lack the entitelment to run this resource"
|
||||
Follow thid guide: https://documentation.rcore.cz/cfx-auth-system/you-lack-the-entitlement
|
||||
|
||||
### editor
|
||||
|
||||
Use: /tveditor
|
||||
|
||||
Permission needed: add_ace group.admin command.tveditor allow
|
||||
|
||||
if you're not sure how to grant someone else principal just please use command: tvgrantpermission
|
BIN
resources/[freizeit]/[rcore_tv]/tv_scaleform/.fxap
Normal file
BIN
resources/[freizeit]/[rcore_tv]/tv_scaleform/.fxap
Normal file
Binary file not shown.
|
@ -0,0 +1,9 @@
|
|||
fx_version "cerulean"
|
||||
games { "gta5" }
|
||||
|
||||
lua54 "yes"
|
||||
|
||||
escrow_ignore {
|
||||
"stream/*.*",
|
||||
}
|
||||
dependency '/assetpacks'
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue