From e39e612baf40ad002ba8df36f86e00c0c644ecd6 Mon Sep 17 00:00:00 2001
From: srslyyyy <51768772+srslyyyy@users.noreply.github.com>
Date: Sun, 30 Jun 2024 08:59:56 +0200
Subject: [PATCH 01/15] Refactor internet radio
---
[gameplay]/internetradio/client.lua | 353 ------------------
.../internetradio/config/CRadioConfig.lua | 14 +
.../internetradio/config/SRadioConfig.lua | 7 +
.../internetradio/config/ShRadioConfig.lua | 95 +++++
[gameplay]/internetradio/gui/CRadioGUI.lua | 57 +++
.../handle_radio/CHandleRadio.lua | 301 +++++++++++++++
.../handle_radio/SHandleRadio.lua | 152 ++++++++
.../handle_radio/ShHandleRadio.lua | 29 ++
[gameplay]/internetradio/meta.xml | 20 +-
[gameplay]/internetradio/server.lua | 145 -------
.../internetradio/settings/CRadioSettings.lua | 71 ++++
.../track_name/CRadioTrackName.lua | 114 ++++++
12 files changed, 857 insertions(+), 501 deletions(-)
delete mode 100644 [gameplay]/internetradio/client.lua
create mode 100644 [gameplay]/internetradio/config/CRadioConfig.lua
create mode 100644 [gameplay]/internetradio/config/SRadioConfig.lua
create mode 100644 [gameplay]/internetradio/config/ShRadioConfig.lua
create mode 100644 [gameplay]/internetradio/gui/CRadioGUI.lua
create mode 100644 [gameplay]/internetradio/handle_radio/CHandleRadio.lua
create mode 100644 [gameplay]/internetradio/handle_radio/SHandleRadio.lua
create mode 100644 [gameplay]/internetradio/handle_radio/ShHandleRadio.lua
delete mode 100644 [gameplay]/internetradio/server.lua
create mode 100644 [gameplay]/internetradio/settings/CRadioSettings.lua
create mode 100644 [gameplay]/internetradio/track_name/CRadioTrackName.lua
diff --git a/[gameplay]/internetradio/client.lua b/[gameplay]/internetradio/client.lua
deleted file mode 100644
index 7ee0c8dd5..000000000
--- a/[gameplay]/internetradio/client.lua
+++ /dev/null
@@ -1,353 +0,0 @@
-local radioSpeakers = {}
-local blackColor = tocolor(0, 0, 0, 255)
-local textColor = tocolor(150, 50, 150, 255)
-local radioTable = {
- {"[Top 40 Mix] BAYERN Radio - Top40", "http://stream.antenne.de:80/top-40"},
- {"[Top 40 Mix] 1.FM - Absolute Top 40", "http://185.33.21.111:80/top40_32a"},
- {"[Top 40 Pop] Power 181", "http://listen.181fm.com/181-power_128k.mp3"},
- {"[80s] BAYERN Radio - 80ers", "http://stream.antenne.de:80/80er-kulthits"},
- {"[90s] BAYERN Radio - 90ers", "http://stream.antenne.de:80/90er-hits"},
- {"[RAP] RadioRecord RapClassics", "https://radiorecord.hostingradio.ru/rapclassics96.aacp"},
- {"[RAP] 1001 The Heat", "http://149.56.157.81:8569/listen.pls"},
- {"[HipHop] HOT 108 JAMZ", "https://live.powerhitz.com/hot108"},
- {"[Mix] Antena1 94.7", "http://51.254.29.40:80/stream2"},
- {"[Mix] Mix96", "https://radiorecord.hostingradio.ru/mix96.aacp"},
- {"[Mix] Radio SA", "https://y0b.net/radiosa.m3u"},
- {"[Mix] 181 The Mix", "http://listen.livestreamingservice.com/181-themix_64k.aac"},
- {"[DANCE] Dance One", "http://185.33.21.112:80/dance_128"},
- {"[DANCE] Dance Wave", "https://dancewave.online/dance.aac"},
- {"[DANCE] Dance Wave Retro", "https://retro.dancewave.online/retrodance.aac"},
- {"[DANCE] 1.FM - Deep House", "http://185.33.21.111:80/deephouse_64a"},
- {"[POP] Antenne Bayern", "http://stream.antenne.de:80/antenne"},
- {"[Roadman] UK DRILL RAP", "https://stream.zeno.fm/bmqy8pp9am8uv"},
- {"[Roadman] UK DRILL FM", "https://stream.zeno.fm/zbhn3mx74bhvv"},
- {"[Ghetto] Alabama's Finest", "http://66.85.47.227:8000/stream"},
- {"[HardBass] Russian HardBASS", "https://radiorecord.hostingradio.ru/hbass96.aacp"},
- {"[Trap] RadioRecord Trap96", "https://radiorecord.hostingradio.ru/trap96.aacp"},
- {"[Drift] Phonk Radio", "https://s2.radio.co/s2b2b68744/listen"},
- {"[Drift] Phonk Radio #2", "https://radiorecord.hostingradio.ru/phonk96.aacp"},
- {"[Drift] Phonk Radio #3", "https://stream.zeno.fm/lfrqotftczpuv"},
- {"[Drift] Phonk Radio #4", "https://stream.zeno.fm/ym4ywb2ezs8uv"},
- {"[Drift] Phonk Radio #5", "https://stream.zeno.fm/aeoju66zrnfuv"},
- {"[Drift] Phonk Radio #6", "https://stream.zeno.fm/71ntub27u18uv"},
- {"[Dubstep] Dub96", "https://radiorecord.hostingradio.ru/dub96.aacp"},
- {"[Random] 105.3 Easy POP and 90s", "http://157.90.133.87:8076/stream"},
- {"[House] True House Chill", "http://stream.truehouse.net:8000/chill"},
- {"[RnB Hits] PowerHitz", "http://66.85.88.174/realrnb"},
- {"[ROCK] BAYERN Radio - 90er Rock", "http://stream.antenne.de:80/90er-rock"},
- {"[ROCK] BAYERN Radio - Classic Rock", "http://stream.antenne.de:80/classic-rock-live"},
- {"[ROCK] 1.FM Classic Rock", "http://185.33.21.111:80/crock_64a"},
- {"[PT Radio & International] Antena1", "https://www.antena1.com.br/stream/"},
- {"[PT Radio] AlienWare", "https://sonic.paulatina.co:10995"}, -- http://elhuecodelasalsa.com/
- {"[Random] 100 Hit Radio", "https://radio1.streamserver.link/radio/8010/100hit-aac"},
- {"[Office] Office Hitz", "http://66.85.88.174/officemix"},
- {"[Pop] Antena1 - 94.7fm", "http://5.135.83.159:80/stream2"},
- {"[Blues] XRDS Blues", "http://198.58.106.133:8321/stream"},
- {"[RU] RussianMix", "https://radiorecord.hostingradio.ru/rus96.aacp"},
- {"[Jazz] Bay Smooth Jazz", "http://185.33.21.111:80/smoothjazz_64a"},
- {"[Trance] Amsterdam Trance", "http://185.33.21.111:80/atr_128"},
- {"[Trance] Absolute Trance Euro", "http://185.33.21.112:80/trance_128"},
- {"[Lovesongs] 100Hits Love", "https://194.97.151.139/lovesongs"},
- {"[ARAB] Arab HitsRadio", "https://icecast.omroep.nl/funx-arab-bb-mp3"},
- {"[ARAB] Arabesk FM", "https://yayin.arabeskfm.biz:8042/"},
- {"[90's] Star 90's", "http://listen.181fm.com/181-star90s_128k.mp3"},
- {"[Random] Hitradio OE3", "https://orf-live.ors-shoutcast.at/oe3-q1a.m3u"},
- {"[Jewish Radio] Jewish Music Stream", "https://stream.jewishmusicstream.com:8000/stream"},
- {"[Thailand Radio] COOLFahrenheit93", "http://103.253.132.7:5004"},
- {"[India] Bollywood Hits Radio", "https://stream.zeno.fm/rqqps6cbe3quv"},
- {"[Russia Radio 1] TatarRadiosi", "https://tatarradio.hostingradio.ru/tatarradio320.mp3"},
- {"[Russia Radio 2] Shanson", "https://chanson.hostingradio.ru:8041/chanson256.mp3"},
- {"[Russia Radio 3] EuropaRussia", "https://europarussia.ru:8006/live"},
- {"[Russia Radio 4] Blatnyachok", "http://89.188.115.214:8000"},
- {"[80s] Russian & International 80s", "https://radiorecord.hostingradio.ru/198096.aacp"},
- {"[90s] Russian & International 90s", "https://radiorecord.hostingradio.ru/sd9096.aacp"},
- {"[Top] 1.FM Hits 2000-s", "http://185.33.21.111:80/hits2000_128"},
- {"[2000s] BAYERN Radio - 2000-s", "http://stream.antenne.de:80/2000er-hits"},
- {"[2010s] BAYERN Radio - 2010-s", "http://stream.antenne.de:80/2010er-hits"},
- {"[70s] SomaFM Seventies", "https://ice1.somafm.com/seventies-128-aac"},
- {"[80s] BAYERN Radio - 80ers", "http://stream.antenne.de:80/80er-kulthits"},
- {"[90s] BAYERN Radio - 90ers", "http://stream.antenne.de:80/90er-hits"}, -- Alternative: http://s1-webradio.antenne.de/90er-hits
- {"[Top] BAYERN Radio - Top 1000", "http://stream.antenne.de:80/top-1000"},
- {"[Random] BAYERN Radio - Chillout", "http://stream.antenne.de:80/chillout"},
- {"[Random] BAYERN Radio - Relax", "http://stream.antenne.de:80/relax"},
- {"[Random] BAYERN Radio - Lounge", "http://stream.antenne.de:80/lounge"},
- {"[Random] BAYERN Radio - In The Mix", "http://stream.antenne.de:80/in-the-mix"},
- {"[Random] BAYERN Radio - Spring Hits", "http://stream.antenne.de:80/fruehlings-hits"},
- {"[Random] BAYERN Radio - Happy Hits", "http://stream.antenne.de:80/happy-hits"},
- {"[Random] BAYERN Radio - Greatest Hits", "http://stream.antenne.de:80/greatest-hits"},
- {"[Random] BAYERN Radio - Party Hits", "http://stream.antenne.de:80/party-hits"},
- {"[Random] BAYERN Radio - Pop XXL", "http://stream.antenne.de:80/pop-xxl"},
- {"[Dance / RU] RadioRecord", "https://radiorecord.hostingradio.ru/rr_main96.aacp"},
- {"[Deep96] RadioRecord", "https://radiorecord.hostingradio.ru/deep96.aacp"},
- {"[Mix96] RadioRecord", "https://radiorecord.hostingradio.ru/mix96.aacp"},
- {"[Uplift96] RadioRecord", "https://radiorecord.hostingradio.ru/uplift96.aacp"},
- {"[Ambient96] RadioRecord", "https://radiorecord.hostingradio.ru/ambient96.aacp"},
- {"[Darkside96] RadioRecord", "https://radiorecord.hostingradio.ru/darkside96.aacp"},
- {"[Summer96] RadioRecord", "https://radiorecord.hostingradio.ru/summerparty96.aacp"},
- {"[Dance] BAYERN Radio - Dance XXL", "http://stream.antenne.de:80/dance-xxl"},
- {"[Dance] FunX Dance", "https://icecast.omroep.nl/funx-dance-bb-mp3"},
-}
-
-function speakersysGUI()
- if (speakersys) then
- return true
- end
-
- local screenX, screenY = guiGetScreenSize()
-
- speakersys = guiCreateWindow((screenX - 325) / 1.1, (screenY - 380) / 1.4, 325, 380, "SPEAKER MUSIC (RADIO/MP3)", false)
- guiSetAlpha(speakersys, 1)
- guiWindowSetSizable(speakersys, false)
- urlGrid = guiCreateGridList(10, 54, 304, 139, false, speakersys)
- urlEdit = guiCreateEdit(10, 25, 304, 26, "http://stream.antenne.de:80/80er-kulthits", false, speakersys)
- setBtn = guiCreateButton(10, 200, 150, 30, "CREATE SPEAKER", false, speakersys)
- destroyBox = guiCreateButton(162, 200, 150, 30, "DESTROY SPEAKER", false, speakersys)
- pauseBtn = guiCreateButton(10, 235, 150, 30, "Play - Pause", false, speakersys)
- close = guiCreateButton(162, 235, 150, 30, "Close", false, speakersys)
-
- xmlSetting = guiCreateCheckBox(15, 345, 160, 17, "Toggle other boxes", false, false, speakersys)
- enableLabel = guiCreateLabel(167, 345, 150, 17, "", false, speakersys)
- urlColumn = guiGridListAddColumn(urlGrid, "Internet Radio Station", 0.8)
- guiSetVisible(speakersys, false)
-
- if (not getSetting("box") or getSetting("box") == "ENABLED") then
- enable = true
- guiCheckBoxSetSelected(xmlSetting, true)
- setSetting("box", "ENABLED")
- guiSetText(enableLabel, "You hear all speakers")
- guiLabelSetColor(enableLabel, 0, 255, 0)
- elseif getSetting("box") == "DISABLED" then
- enable = nil
- guiCheckBoxSetSelected(xmlSetting, false)
- guiSetText(enableLabel, "You only hear your speaker")
- guiLabelSetColor(enableLabel, 255, 0, 0)
- end
-
- addEventHandler("onClientGUIClick", urlGrid, updateUrlEdit, false)
-
- for key, ent in pairs(radioTable) do
- local row = guiGridListAddRow(urlGrid)
- guiGridListSetItemText(urlGrid, row, urlColumn, ent[1], false, false)
- end
- setTimer(getRadioInfo, 10000, 0)
-end
-addEventHandler("onClientResourceStart", resourceRoot, speakersysGUI)
-
-function updateUrlEdit()
- if (guiGridListGetItemText(urlGrid, guiGridListGetSelectedItem(urlGrid), 1) ~= "") then
- for key, ent in pairs(radioTable) do
- if (guiGridListGetItemText(urlGrid, guiGridListGetSelectedItem(urlGrid), 1) == ent[1]) then
- guiSetText(urlEdit, ent[2])
- end
- end
- end
-end
-
-function openGUI()
- if (guiGetVisible(speakersys)) then
- guiSetVisible(speakersys, false)
- showCursor(false)
- else
- guiSetVisible(speakersys, true)
- showCursor(true)
- end
-end
-addEvent("Speaker.openInterface", true)
-addEventHandler("Speaker.openInterface", root, openGUI)
-bindKey("F3", "down", openGUI)
-
-function clickEvent()
- if (source == setBtn) then
- local vol = 1.0
- local url = guiGetText(urlEdit)
-
- if not (url) or (url == "") or (string.len(url) > 550) or not string.find(url, "http") then
- return outputChatBox("SPEAKER: Invalid URL, please check your input!", 255, 0, 0)
- end
-
- triggerServerEvent("speaker.startStream", localPlayer, url, vol)
-
- elseif (source == close) then
- openGUI()
- elseif (source == pauseBtn) then
- triggerServerEvent("speaker.pause", localPlayer)
- elseif (source == destroyBox) then
- triggerServerEvent("speaker.destroy", localPlayer)
- elseif (source == xmlSetting) then
- enable = not enable
-
- if (enable) then
- outputChatBox("NOTE: Reconnect to listen to deactivated songs again", 0, 255, 0)
- setSetting("box", "ENABLED")
- guiCheckBoxSetSelected(xmlSetting, true)
- guiSetText(enableLabel, "You hear all speakers")
- guiLabelSetColor(enableLabel, 0, 255, 0)
- else
- setSetting("box", "DISABLED")
- guiCheckBoxSetSelected(xmlSetting, false)
- guiSetText(enableLabel, "You only hear your music")
- guiLabelSetColor(enableLabel, 255, 0, 0)
- end
- end
-end
-addEventHandler("onClientGUIClick", resourceRoot, clickEvent)
-
-function setData(value, theType, serial)
- if (not radioSpeakers[serial]) then
- return
- end
-
- if (not isElement(radioSpeakers[serial][1])) then
- return
- end
-
- if (theType == "vol") then
- setSoundVolume(radioSpeakers[serial][1], value)
- elseif (theType == "dist") then
- setSoundMaxDistance(radioSpeakers[serial][1], 65)
- elseif (theType == "destroy") then
- stopSound(radioSpeakers[serial][1])
- destroyElement(radioSpeakers[serial][2])
- radioSpeakers[serial] = nil
- end
-end
-addEvent("speaker.setData", true)
-addEventHandler("speaker.setData", root, setData)
-
-function setPaused(serial)
- if (not radioSpeakers[serial]) then
- return
- end
-
- if (not isElement(radioSpeakers[serial][1])) then
- return
- end
- setSoundPaused(radioSpeakers[serial][1], not isSoundPaused(radioSpeakers[serial][1]))
-end
-addEvent("speaker.ps", true)
-addEventHandler("speaker.ps", root, setPaused)
-
-function setBox(str)
- if (not str) then
- return
- end
-
- for serial, ent in pairs(str) do
-
- if (radioSpeakers[serial] and isElement(radioSpeakers[serial][1])) then
- destroyElement(radioSpeakers[serial][1])
- destroyElement(radioSpeakers[serial][2])
- end
-
- if (isElement(ent[1])) then
- if (ent[11] == getPlayerName(localPlayer) or enable) then
- local radio = playSound3D(ent[2], ent[3], ent[4], ent[5], true, false)
- setElementData(radio, "ob", ent[11])
- local dumm = createObject(1337, ent[3], ent[4], ent[5])
- setElementAlpha(dumm, 0)
- setElementCollisionsEnabled(dumm, false)
- attachElements(dumm, ent[1], -0.32, -0.22, 0.8)
- radioSpeakers[serial] = {radio, dumm}
-
- if (ent[6] and isElement(ent[6])) then
- attachElements(radio, ent[6])
- end
-
- setElementInterior(radio, ent[7])
- setElementDimension(radio, ent[8])
- setSoundVolume(radio, ent[9])
- setSoundMaxDistance(radio, ent[10])
- setInteriorSoundsEnabled(false)
- end
- end
- end
-end
-addEvent("speaker.setBox", true)
-addEventHandler("speaker.setBox", root, setBox)
-
-function getRadioInfo()
- for key, radio in pairs(radioSpeakers) do
- if (radio[1] and isElement(radio[1])) then
- radioSpeakers[key][3] = nil
- table.insert(radioSpeakers[key], getSoundMetaTags(radio[1]).stream_title or getSoundMetaTags(radio[1]).title)
- end
- end
-end
-
-function drawData()
- for key, radio in pairs(radioSpeakers) do
- if (radio[2] and isElement(radio[2] and radio[1])) then
- local eX, eY, eZ = getElementPosition(radio[2])
- eZ = (eZ + 1)
- local sx, sy = getScreenFromWorldPosition(eX, eY, eZ)
- local cameraX, cameraY, cameraZ = getCameraMatrix()
-
- if (sx and sy) then
- if (not enable and getElementData(radio[1], "ob") ~= getPlayerName(localPlayer)) then
- stopSound(radio[1])
- destroyElement(radio[2])
- radioSpeakers[key] = nil
- return false
- end
-
- local distance = getDistanceBetweenPoints3D(cameraX, cameraY, cameraZ, eX, eY, eZ)
-
- if (distance <= 65 and isLineOfSightClear(cameraX, cameraY, cameraZ, eX, eY, eZ, true, false, false, false, false, false) and radio[3]) then
- local height = dxGetFontHeight(1, "default-bold")
- local owner = getElementData(radio[1], "ob")
- text = radio[3]
-
- if toggle then
- text = "Owner: " .. owner .. " - " .. text .. ""
- end
-
- local width = dxGetTextWidth(text, 1, "default-bold")
-
- dxDrawRectangle(sx - width / 2 - 5, sy, width + 8, height, blackColor, false)
- dxDrawText(text, sx - width / 2, sy, sx - width / 2, sy, textColor, 1, "default-bold")
- end
- end
- end
- end
-end
-addEventHandler("onClientRender", root, drawData)
-
-function toggleCursor(key, state)
- toggle = not toggle
-end
-bindKey("lalt", "both", toggleCursor)
-
-settingsXMLFile = nil
-
-function onStartup()
- triggerServerEvent("getSpeakers", localPlayer)
-
- settingsXMLFile = xmlLoadFile("settings.xml")
- if not settingsXMLFile then
- settingsXMLFile = xmlCreateFile("settings.xml", "settings")
- end
-end
-addEventHandler("onClientResourceStart", resourceRoot, onStartup)
-
-onStartup()
-
-function setSetting(setting, value)
- if value then
- value = tostring(value)
- xmlNodeSetAttribute(settingsXMLFile, setting, value)
- end
- xmlSaveFile(settingsXMLFile)
-end
-
-function getSetting(setting)
- if setting then
- local val = xmlNodeGetAttribute(settingsXMLFile, setting)
- if val then
- return val
- else
- return false
- end
- else
- return false
- end
-end
diff --git a/[gameplay]/internetradio/config/CRadioConfig.lua b/[gameplay]/internetradio/config/CRadioConfig.lua
new file mode 100644
index 000000000..6da7d1680
--- /dev/null
+++ b/[gameplay]/internetradio/config/CRadioConfig.lua
@@ -0,0 +1,14 @@
+-- #######################################
+-- ## Project: Internet radio ##
+-- ## Authors: MTA contributors ##
+-- ## Version: 1.0 ##
+-- #######################################
+
+RADIO_TRACK_SCALE = 1
+RADIO_TRACK_FONT = "default-bold"
+RADIO_TRACK_COLOR = tocolor(150, 50, 150, 255)
+RADIO_TRACK_BACKGROUND_COLOR = tocolor(0, 0, 0, 255)
+
+RADIO_TOGGLE_KEY = "F9"
+RADIO_COMMANDS = {"sound", "music", "musica", "song", "radio", "speaker"}
+RADIO_SETTINGS_PATH = "settings.json"
\ No newline at end of file
diff --git a/[gameplay]/internetradio/config/SRadioConfig.lua b/[gameplay]/internetradio/config/SRadioConfig.lua
new file mode 100644
index 000000000..4bfae1e9c
--- /dev/null
+++ b/[gameplay]/internetradio/config/SRadioConfig.lua
@@ -0,0 +1,7 @@
+-- #######################################
+-- ## Project: Internet radio ##
+-- ## Authors: MTA contributors ##
+-- ## Version: 1.0 ##
+-- #######################################
+
+RADIO_BOX_MODEL = 2229
\ No newline at end of file
diff --git a/[gameplay]/internetradio/config/ShRadioConfig.lua b/[gameplay]/internetradio/config/ShRadioConfig.lua
new file mode 100644
index 000000000..5d3b5b65c
--- /dev/null
+++ b/[gameplay]/internetradio/config/ShRadioConfig.lua
@@ -0,0 +1,95 @@
+-- #######################################
+-- ## Project: Internet radio ##
+-- ## Authors: MTA contributors ##
+-- ## Version: 1.0 ##
+-- #######################################
+
+RADIO_ALLOW_CUSTOM_URLS = false
+RADIO_STREAM_URL_MAX_LENGTH = 512
+RADIO_MAX_SOUND_DISTANCE = 65
+RADIO_STATIONS = {
+ {"[Top 40 Mix] BAYERN Radio - Top40", "http://stream.antenne.de:80/top-40"},
+ {"[Top 40 Mix] 1.FM - Absolute Top 40", "http://185.33.21.111:80/top40_32a"},
+ {"[Top 40 Pop] Power 181", "http://listen.181fm.com/181-power_128k.mp3"},
+ {"[80s] BAYERN Radio - 80ers", "http://stream.antenne.de:80/80er-kulthits"},
+ {"[90s] BAYERN Radio - 90ers", "http://stream.antenne.de:80/90er-hits"},
+ {"[RAP] RadioRecord RapClassics", "https://radiorecord.hostingradio.ru/rapclassics96.aacp"},
+ {"[RAP] 1001 The Heat", "http://149.56.157.81:8569/listen.pls"},
+ {"[HipHop] HOT 108 JAMZ", "https://live.powerhitz.com/hot108"},
+ {"[Mix] Antena1 94.7", "http://51.254.29.40:80/stream2"},
+ {"[Mix] Mix96", "https://radiorecord.hostingradio.ru/mix96.aacp"},
+ {"[Mix] Radio SA", "https://y0b.net/radiosa.m3u"},
+ {"[Mix] 181 The Mix", "http://listen.livestreamingservice.com/181-themix_64k.aac"},
+ {"[DANCE] Dance One", "http://185.33.21.112:80/dance_128"},
+ {"[DANCE] Dance Wave", "https://dancewave.online/dance.aac"},
+ {"[DANCE] Dance Wave Retro", "https://retro.dancewave.online/retrodance.aac"},
+ {"[DANCE] 1.FM - Deep House", "http://185.33.21.111:80/deephouse_64a"},
+ {"[POP] Antenne Bayern", "http://stream.antenne.de:80/antenne"},
+ {"[Roadman] UK DRILL RAP", "https://stream.zeno.fm/bmqy8pp9am8uv"},
+ {"[Roadman] UK DRILL FM", "https://stream.zeno.fm/zbhn3mx74bhvv"},
+ {"[Ghetto] Alabama's Finest", "http://66.85.47.227:8000/stream"},
+ {"[HardBass] Russian HardBASS", "https://radiorecord.hostingradio.ru/hbass96.aacp"},
+ {"[Trap] RadioRecord Trap96", "https://radiorecord.hostingradio.ru/trap96.aacp"},
+ {"[Drift] Phonk Radio", "https://s2.radio.co/s2b2b68744/listen"},
+ {"[Drift] Phonk Radio #2", "https://radiorecord.hostingradio.ru/phonk96.aacp"},
+ {"[Drift] Phonk Radio #3", "https://stream.zeno.fm/lfrqotftczpuv"},
+ {"[Drift] Phonk Radio #4", "https://stream.zeno.fm/ym4ywb2ezs8uv"},
+ {"[Drift] Phonk Radio #5", "https://stream.zeno.fm/aeoju66zrnfuv"},
+ {"[Drift] Phonk Radio #6", "https://stream.zeno.fm/71ntub27u18uv"},
+ {"[Dubstep] Dub96", "https://radiorecord.hostingradio.ru/dub96.aacp"},
+ {"[Random] 105.3 Easy POP and 90s", "http://157.90.133.87:8076/stream"},
+ {"[House] True House Chill", "http://stream.truehouse.net:8000/chill"},
+ {"[RnB Hits] PowerHitz", "http://66.85.88.174/realrnb"},
+ {"[ROCK] BAYERN Radio - 90er Rock", "http://stream.antenne.de:80/90er-rock"},
+ {"[ROCK] BAYERN Radio - Classic Rock", "http://stream.antenne.de:80/classic-rock-live"},
+ {"[ROCK] 1.FM Classic Rock", "http://185.33.21.111:80/crock_64a"},
+ {"[PT Radio & International] Antena1", "https://www.antena1.com.br/stream/"},
+ {"[PT Radio] AlienWare", "https://sonic.paulatina.co:10995"}, -- http://elhuecodelasalsa.com/
+ {"[Random] 100 Hit Radio", "https://radio1.streamserver.link/radio/8010/100hit-aac"},
+ {"[Office] Office Hitz", "http://66.85.88.174/officemix"},
+ {"[Pop] Antena1 - 94.7fm", "http://5.135.83.159:80/stream2"},
+ {"[Blues] XRDS Blues", "http://198.58.106.133:8321/stream"},
+ {"[RU] RussianMix", "https://radiorecord.hostingradio.ru/rus96.aacp"},
+ {"[Jazz] Bay Smooth Jazz", "http://185.33.21.111:80/smoothjazz_64a"},
+ {"[Trance] Amsterdam Trance", "http://185.33.21.111:80/atr_128"},
+ {"[Trance] Absolute Trance Euro", "http://185.33.21.112:80/trance_128"},
+ {"[Lovesongs] 100Hits Love", "https://194.97.151.139/lovesongs"},
+ {"[ARAB] Arab HitsRadio", "https://icecast.omroep.nl/funx-arab-bb-mp3"},
+ {"[ARAB] Arabesk FM", "https://yayin.arabeskfm.biz:8042/"},
+ {"[90's] Star 90's", "http://listen.181fm.com/181-star90s_128k.mp3"},
+ {"[Random] Hitradio OE3", "https://orf-live.ors-shoutcast.at/oe3-q1a.m3u"},
+ {"[Jewish Radio] Jewish Music Stream", "https://stream.jewishmusicstream.com:8000/stream"},
+ {"[Thailand Radio] COOLFahrenheit93", "http://103.253.132.7:5004"},
+ {"[India] Bollywood Hits Radio", "https://stream.zeno.fm/rqqps6cbe3quv"},
+ {"[Russia Radio 1] TatarRadiosi", "https://tatarradio.hostingradio.ru/tatarradio320.mp3"},
+ {"[Russia Radio 2] Shanson", "https://chanson.hostingradio.ru:8041/chanson256.mp3"},
+ {"[Russia Radio 3] EuropaRussia", "https://europarussia.ru:8006/live"},
+ {"[Russia Radio 4] Blatnyachok", "http://89.188.115.214:8000"},
+ {"[80s] Russian & International 80s", "https://radiorecord.hostingradio.ru/198096.aacp"},
+ {"[90s] Russian & International 90s", "https://radiorecord.hostingradio.ru/sd9096.aacp"},
+ {"[Top] 1.FM Hits 2000-s", "http://185.33.21.111:80/hits2000_128"},
+ {"[2000s] BAYERN Radio - 2000-s", "http://stream.antenne.de:80/2000er-hits"},
+ {"[2010s] BAYERN Radio - 2010-s", "http://stream.antenne.de:80/2010er-hits"},
+ {"[70s] SomaFM Seventies", "https://ice1.somafm.com/seventies-128-aac"},
+ {"[80s] BAYERN Radio - 80ers", "http://stream.antenne.de:80/80er-kulthits"},
+ {"[90s] BAYERN Radio - 90ers", "http://stream.antenne.de:80/90er-hits"}, -- Alternative: http://s1-webradio.antenne.de/90er-hits
+ {"[Top] BAYERN Radio - Top 1000", "http://stream.antenne.de:80/top-1000"},
+ {"[Random] BAYERN Radio - Chillout", "http://stream.antenne.de:80/chillout"},
+ {"[Random] BAYERN Radio - Relax", "http://stream.antenne.de:80/relax"},
+ {"[Random] BAYERN Radio - Lounge", "http://stream.antenne.de:80/lounge"},
+ {"[Random] BAYERN Radio - In The Mix", "http://stream.antenne.de:80/in-the-mix"},
+ {"[Random] BAYERN Radio - Spring Hits", "http://stream.antenne.de:80/fruehlings-hits"},
+ {"[Random] BAYERN Radio - Happy Hits", "http://stream.antenne.de:80/happy-hits"},
+ {"[Random] BAYERN Radio - Greatest Hits", "http://stream.antenne.de:80/greatest-hits"},
+ {"[Random] BAYERN Radio - Party Hits", "http://stream.antenne.de:80/party-hits"},
+ {"[Random] BAYERN Radio - Pop XXL", "http://stream.antenne.de:80/pop-xxl"},
+ {"[Dance / RU] RadioRecord", "https://radiorecord.hostingradio.ru/rr_main96.aacp"},
+ {"[Deep96] RadioRecord", "https://radiorecord.hostingradio.ru/deep96.aacp"},
+ {"[Mix96] RadioRecord", "https://radiorecord.hostingradio.ru/mix96.aacp"},
+ {"[Uplift96] RadioRecord", "https://radiorecord.hostingradio.ru/uplift96.aacp"},
+ {"[Ambient96] RadioRecord", "https://radiorecord.hostingradio.ru/ambient96.aacp"},
+ {"[Darkside96] RadioRecord", "https://radiorecord.hostingradio.ru/darkside96.aacp"},
+ {"[Summer96] RadioRecord", "https://radiorecord.hostingradio.ru/summerparty96.aacp"},
+ {"[Dance] BAYERN Radio - Dance XXL", "http://stream.antenne.de:80/dance-xxl"},
+ {"[Dance] FunX Dance", "https://icecast.omroep.nl/funx-dance-bb-mp3"},
+}
\ No newline at end of file
diff --git a/[gameplay]/internetradio/gui/CRadioGUI.lua b/[gameplay]/internetradio/gui/CRadioGUI.lua
new file mode 100644
index 000000000..6ff3bf7f4
--- /dev/null
+++ b/[gameplay]/internetradio/gui/CRadioGUI.lua
@@ -0,0 +1,57 @@
+-- #######################################
+-- ## Project: Internet radio ##
+-- ## Authors: MTA contributors ##
+-- ## Version: 1.0 ##
+-- #######################################
+
+RADIO_GUI = false
+
+local function initializeRadioGUI()
+ if (RADIO_GUI) then
+ return false
+ end
+
+ local screenX, screenY = guiGetScreenSize()
+ local radioWindowSizeX, radioWindowSizeY = 325, 380
+ local radioWindowPosX, radioWindowPosY = (screenX - 325)/1.1, (screenY - 380)/1.4
+
+ RADIO_GUI = {}
+ RADIO_GUI["Radio window"] = guiCreateWindow(radioWindowPosX, radioWindowPosY, radioWindowSizeX, radioWindowSizeY, "SPEAKER MUSIC (RADIO/MP3)", false)
+ RADIO_GUI["Stream URLs gridlist"] = guiCreateGridList(10, 54, 304, 139, false, RADIO_GUI["Radio window"])
+ RADIO_GUI["Stream URL edit"] = guiCreateEdit(10, 25, 304, 26, "http://stream.antenne.de:80/80er-kulthits", false, RADIO_GUI["Radio window"])
+ RADIO_GUI["Create speaker button"] = guiCreateButton(10, 200, 150, 30, "CREATE SPEAKER", false, RADIO_GUI["Radio window"])
+ RADIO_GUI["Destroy speaker button"] = guiCreateButton(162, 200, 150, 30, "DESTROY SPEAKER", false, RADIO_GUI["Radio window"])
+ RADIO_GUI["Play/pause button"] = guiCreateButton(10, 235, 150, 30, "Play - Pause", false, RADIO_GUI["Radio window"])
+ RADIO_GUI["Close button"] = guiCreateButton(162, 235, 150, 30, "Close", false, RADIO_GUI["Radio window"])
+
+ RADIO_GUI["Toggle remote speakers checkbox"] = guiCreateCheckBox(15, 345, 160, 17, "Toggle other speakers", false, false, RADIO_GUI["Radio window"])
+ RADIO_GUI["Toggle remote speakers label"] = guiCreateLabel(167, 345, 150, 17, "", false, RADIO_GUI["Radio window"])
+ RADIO_GUI["Radio station URL column"] = guiGridListAddColumn(RADIO_GUI["Stream URLs gridlist"], "Radio station", 0.8)
+
+ guiSetVisible(RADIO_GUI["Radio window"], false)
+ guiEditSetMaxLength(RADIO_GUI["Stream URL edit"], RADIO_STREAM_URL_MAX_LENGTH)
+ guiWindowSetSizable(RADIO_GUI["Radio window"], false)
+ guiGridListSetSortingEnabled(RADIO_GUI["Stream URLs gridlist"], false)
+
+ loadRadioStations()
+
+ addEventHandler("onClientGUIClick", RADIO_GUI["Stream URLs gridlist"], onClientGUIClickLoadStationStreamURL, false)
+ addEventHandler("onClientGUIClick", RADIO_GUI["Create speaker button"], onClientGUIClickCreateSpeaker, false)
+ addEventHandler("onClientGUIClick", RADIO_GUI["Play/pause button"], onClientGUIClickToggleSpeaker, false)
+ addEventHandler("onClientGUIClick", RADIO_GUI["Destroy speaker button"], onClientGUIClickDestroySpeaker, false)
+ addEventHandler("onClientGUIClick", RADIO_GUI["Close button"], onClientGUIClickCloseRadioGUI, false)
+
+ return true
+end
+
+function toggleRadioGUI()
+ initializeRadioGUI()
+
+ local guiState = guiGetVisible(RADIO_GUI["Radio window"])
+ local guiNewState = (not guiState)
+
+ guiSetVisible(RADIO_GUI["Radio window"], guiNewState)
+ showCursor(guiNewState)
+end
+bindKey(RADIO_TOGGLE_KEY, "down", toggleRadioGUI)
+addEventHandler("onClientResourceStart", resourceRoot, toggleRadioGUI)
\ No newline at end of file
diff --git a/[gameplay]/internetradio/handle_radio/CHandleRadio.lua b/[gameplay]/internetradio/handle_radio/CHandleRadio.lua
new file mode 100644
index 000000000..edc318e6a
--- /dev/null
+++ b/[gameplay]/internetradio/handle_radio/CHandleRadio.lua
@@ -0,0 +1,301 @@
+-- #######################################
+-- ## Project: Internet radio ##
+-- ## Authors: MTA contributors ##
+-- ## Version: 1.0 ##
+-- #######################################
+
+local speakerSounds = {}
+local playerSpeakers = {}
+
+local function getStreamURLFromEdit()
+ local streamURL = guiGetText(RADIO_GUI["Stream URL edit"])
+ local validStreamURL = verifyRadioStreamURL(streamURL)
+
+ if (not validStreamURL) then
+ return false
+ end
+
+ return streamURL
+end
+
+local function handleSpeakerOnStreamInOut(speakerElement, toggleOn)
+ local validElement = isElement(speakerElement)
+
+ if (not validElement) then
+ return false
+ end
+
+ local elementType = getElementType(speakerElement)
+ local objectType = (elementType == "object")
+
+ if (not objectType) then
+ return false
+ end
+
+ for playerElement, speakerData in pairs(playerSpeakers) do
+ local speakerBox = speakerData.speakerBox
+ local matchingElement = (speakerBox == speakerElement)
+
+ if (matchingElement) then
+ toggleSpeakerSounds(playerElement, toggleOn)
+
+ return true
+ end
+ end
+
+ return false
+end
+
+function loadRadioStations()
+ for stationID = 1, #RADIO_STATIONS do
+ local radioStationData = RADIO_STATIONS[stationID]
+ local radioStation = radioStationData[1]
+ local radioStationURL = radioStationData[2]
+ local radioStationRow = guiGridListAddRow(RADIO_GUI["Stream URLs gridlist"])
+
+ guiGridListSetItemText(RADIO_GUI["Stream URLs gridlist"], radioStationRow, RADIO_GUI["Radio station URL column"], radioStation, false, false)
+ guiGridListSetItemData(RADIO_GUI["Stream URLs gridlist"], radioStationRow, RADIO_GUI["Radio station URL column"], radioStationURL)
+ end
+
+ return true
+end
+
+function toggleSpeakerSounds(playerElement, toggleOn)
+ local speakerSound = speakerSounds[playerElement]
+ local speakerSoundElement = isElement(speakerSound)
+
+ if (speakerSoundElement) then
+ destroyElement(speakerSound)
+ end
+
+ if (toggleOn) then
+ local speakerData = getPlayerSpeakerData(playerElement)
+
+ if (not speakerData) then
+ return false
+ end
+
+ local speakerBox = speakerData.speakerBox
+ local speakerBoxPosX, speakerBoxPosY, speakerBoxPosZ = getElementPosition(speakerBox)
+ local speakerInterior = getElementInterior(speakerBox)
+ local speakerDimension = getElementDimension(speakerBox)
+ local speakerSoundMaxDistance = speakerData.speakerSoundMaxDistance
+ local speakerStreamURL = speakerData.speakerStreamURL
+ local speakerNewSound = playSound3D(speakerStreamURL, speakerBoxPosX, speakerBoxPosY, speakerBoxPosZ, false, false)
+
+ if (not speakerNewSound) then
+ return false
+ end
+
+ local speakerPaused = speakerData.speakerPaused
+
+ speakerSounds[playerElement] = speakerNewSound
+
+ setElementInterior(speakerNewSound, speakerInterior)
+ setElementInterior(speakerNewSound, speakerDimension)
+
+ setSoundPaused(speakerNewSound, speakerPaused)
+ setSoundMaxDistance(speakerNewSound, speakerSoundMaxDistance)
+ setSoundVolume(speakerNewSound, 0.02)
+ attachElements(speakerNewSound, speakerBox)
+ end
+
+ if (not toggleOn) then
+ speakerSounds[playerElement] = nil
+ end
+
+ return true
+end
+
+function onClientGUIClickLoadStationStreamURL()
+ local selectedRow, selectedColumn = guiGridListGetSelectedItem(source)
+ local stationStreamURL = guiGridListGetItemData(source, selectedRow, selectedColumn)
+
+ if (not stationStreamURL) then
+ return false
+ end
+
+ guiSetText(RADIO_GUI["Stream URL edit"], stationStreamURL)
+end
+
+function onClientGUIClickCreateSpeaker()
+ local streamURL = getStreamURLFromEdit()
+
+ if (not streamURL) then
+ outputChatBox("SPEAKER: Invalid URL, please check your input!", 255, 0, 0)
+
+ return false
+ end
+
+ triggerServerEvent("onServerCreateSpeaker", localPlayer, streamURL)
+end
+
+function onClientGUIClickToggleSpeaker()
+ local playerSpeaker = getPlayerSpeakerData(localPlayer)
+
+ if (not playerSpeaker) then
+ return false
+ end
+
+ triggerServerEvent("onServerToggleSpeaker", localPlayer)
+end
+
+function onClientGUIClickDestroySpeaker()
+ local playerSpeaker = getPlayerSpeakerData(localPlayer)
+
+ if (not playerSpeaker) then
+ return false
+ end
+
+ triggerServerEvent("onServerDestroySpeaker", localPlayer)
+end
+
+function onClientGUIClickCloseRadioGUI()
+ toggleRadioGUI()
+end
+
+function setPlayerSpeakerData(playerElement, speakerData)
+ local validElement = isElement(playerElement)
+
+ if (not validElement) then
+ return false
+ end
+
+ local speakerBox = speakerData.speakerBox
+ local speakerDummy = createObject(1337, 0, 0, 3)
+
+ speakerData.speakerDummy = speakerDummy
+ playerSpeakers[playerElement] = speakerData
+
+ toggleSpeakerSounds(playerElement, true)
+
+ setElementAlpha(speakerDummy, 0)
+ setElementCollisionsEnabled(speakerDummy, false)
+ attachElements(speakerDummy, speakerBox, -0.32, -0.22, 0.8)
+
+ return true
+end
+
+function setPlayerSpeakerPaused(playerElement, pauseState)
+ local playerSpeakerData = getPlayerSpeakerData(playerElement)
+
+ if (not playerSpeakerData) then
+ return false
+ end
+
+ local speakerSound = speakerSounds[playerElement]
+
+ playerSpeakerData.speakerPaused = pauseState
+
+ if (speakerSound) then
+ local speakerPaused = isSoundPaused(speakerSound)
+ local updatePauseState = (speakerPaused ~= pauseState)
+
+ if (updatePauseState) then
+ setSoundPaused(speakerSound, pauseState)
+ end
+ end
+
+ return true
+end
+
+function getPlayerSpeakerData(playerElement)
+ local validElement = isElement(playerElement)
+
+ if (not validElement) then
+ return false
+ end
+
+ local playerSpeakerData = playerSpeakers[playerElement]
+
+ return playerSpeakerData
+end
+
+function clearPlayerSpeaker(playerOrSpeaker)
+ for playerElement, speakerData in pairs(playerSpeakers) do
+ local speakerBox = speakerData.speakerBox
+ local matchingElement = (playerElement == playerOrSpeaker) or (speakerBox == playerOrSpeaker)
+
+ if (matchingElement) then
+ local speakerDummy = speakerData.speakerDummy
+ local speakerDummyElement = isElement(speakerDummy)
+
+ NEARBY_SPEAKERS[speakerDummyElement] = nil
+
+ if (speakerDummyElement) then
+ destroyElement(speakerDummy)
+ end
+
+ toggleSpeakerSounds(playerElement, false)
+ playerSpeakers[playerElement] = nil
+
+ return true
+ end
+ end
+
+ return false
+end
+
+function isObjectSpeaker(objectElement)
+ for playerElement, speakerData in pairs(playerSpeakers) do
+ local speakerBox = speakerData.speakerBox
+ local matchingElement = (speakerBox == objectElement)
+
+ if (matchingElement) then
+ local speakerSound = speakerSounds[playerElement]
+ local speakerDummy = speakerData.speakerDummy
+
+ return true, speakerSound, speakerDummy
+ end
+ end
+
+ return false
+end
+
+function onClientSyncSpeakers(activeSpeakers)
+ playerSpeakers = activeSpeakers
+
+ for playerElement, speakerData in pairs(playerSpeakers) do
+ local speakerBox = speakerData.speakerBox
+ local speakerBoxStreamedIn = isElementStreamedIn(speakerBox)
+
+ if (speakerBoxStreamedIn) then
+ toggleSpeakerSounds(playerElement, true)
+ end
+ end
+end
+addEvent("onClientSyncSpeakers", true)
+addEventHandler("onClientSyncSpeakers", root, onClientSyncSpeakers)
+
+function onClientCreateSpeaker(speakerData)
+ setPlayerSpeakerData(source, speakerData)
+end
+addEvent("onClientCreateSpeaker", true)
+addEventHandler("onClientCreateSpeaker", root, onClientCreateSpeaker)
+
+function onClientToggleSpeaker(pauseState)
+ setPlayerSpeakerPaused(source, pauseState)
+end
+addEvent("onClientToggleSpeaker", true)
+addEventHandler("onClientToggleSpeaker", root, onClientToggleSpeaker)
+
+function toggleSpeakerOnStreamIn()
+ handleSpeakerOnStreamInOut(source, true)
+end
+addEventHandler("onClientElementStreamIn", resourceRoot, toggleSpeakerOnStreamIn)
+
+function toggleSpeakerOnStreamOut()
+ handleSpeakerOnStreamInOut(source, false)
+end
+addEventHandler("onClientElementStreamOut", resourceRoot, toggleSpeakerOnStreamOut)
+
+function clearSpeakersOnDestroyQuit()
+ clearPlayerSpeaker(source)
+end
+addEventHandler("onClientPlayerQuit", root, clearSpeakersOnDestroyQuit)
+addEventHandler("onClientElementDestroy", resourceRoot, clearSpeakersOnDestroyQuit)
+
+function onClientRenderDebugRadio()
+ dxDrawText(inspect(playerSpeakers).."\n"..inspect(speakerSounds), 100, 100)
+end
+addEventHandler("onClientRender", root, onClientRenderDebugRadio)
\ No newline at end of file
diff --git a/[gameplay]/internetradio/handle_radio/SHandleRadio.lua b/[gameplay]/internetradio/handle_radio/SHandleRadio.lua
new file mode 100644
index 000000000..4a899b84a
--- /dev/null
+++ b/[gameplay]/internetradio/handle_radio/SHandleRadio.lua
@@ -0,0 +1,152 @@
+-- #######################################
+-- ## Project: Internet radio ##
+-- ## Authors: MTA contributors ##
+-- ## Version: 1.0 ##
+-- #######################################
+
+local playerSpeakers = {}
+
+function setPlayerSpeakerData(playerElement, speakerData)
+ local validElement = isElement(playerElement)
+
+ if (not validElement) then
+ return false
+ end
+
+ playerSpeakers[playerElement] = speakerData
+ triggerClientEvent(root, "onClientCreateSpeaker", playerElement, speakerData)
+
+ return true
+end
+
+function getPlayerSpeakerData(playerElement)
+ local validElement = isElement(playerElement)
+
+ if (not validElement) then
+ return false
+ end
+
+ local playerSpeakerData = playerSpeakers[playerElement]
+
+ return playerSpeakerData
+end
+
+function clearPlayerSpeaker(playerOrSpeaker)
+ for playerElement, speakerData in pairs(playerSpeakers) do
+ local speakerBox = speakerData.speakerBox
+ local matchingElement = (playerElement == playerOrSpeaker) or (speakerBox == playerOrSpeaker)
+
+ if (matchingElement) then
+ playerSpeakers[playerElement] = nil
+
+ return true
+ end
+ end
+
+ return false
+end
+
+function onServerCreateSpeaker(streamURL)
+ if (not client) then
+ return false
+ end
+
+ local validStreamURL = verifyRadioStreamURL(streamURL)
+
+ if (not validStreamURL) then
+ return false
+ end
+
+ local playerSpeakerData = getPlayerSpeakerData(client)
+
+ if (playerSpeakerData) then
+ local speakerBox = playerSpeakerData.speakerBox
+ local speakerElement = isElement(speakerBox)
+
+ if (speakerElement) then
+ destroyElement(speakerBox)
+ end
+ end
+
+ local playerPosX, playerPosY, playerPosZ = getElementPosition(client)
+ local playerInterior = getElementInterior(client)
+ local playerDimension = getElementDimension(client)
+
+ local boxPosX, boxPosY, boxPosZ = (playerPosX - 0.5), (playerPosY + 0.5), (playerPosZ - 1)
+ local boxRotX, boxRotY, boxRotZ = 0, 0, 0
+ local boxLowLOD = false
+ local boxElement = createObject(RADIO_BOX_MODEL, boxPosX, boxPosY, boxPosZ, boxRotX, boxRotY, boxRotZ, boxLowLOD)
+
+ setElementInterior(boxElement, playerInterior)
+ setElementDimension(boxElement, playerDimension)
+ setElementCollisionsEnabled(boxElement, false)
+
+ local speakerData = {
+ speakerBox = boxElement,
+ speakerStreamURL = streamURL,
+ speakerSoundMaxDistance = RADIO_MAX_SOUND_DISTANCE,
+ speakerPaused = false,
+ }
+
+ setPlayerSpeakerData(client, speakerData)
+end
+addEvent("onServerCreateSpeaker", true)
+addEventHandler("onServerCreateSpeaker", root, onServerCreateSpeaker)
+
+function onServerDestroySpeaker()
+ if (not client) then
+ return false
+ end
+
+ local playerSpeakerData = getPlayerSpeakerData(client)
+
+ if (not playerSpeakerData) then
+ return false
+ end
+
+ local speakerBox = playerSpeakerData.speakerBox
+ local speakerElement = isElement(speakerBox)
+
+ if (speakerElement) then
+ destroyElement(speakerBox)
+ end
+end
+addEvent("onServerDestroySpeaker", true)
+addEventHandler("onServerDestroySpeaker", root, onServerDestroySpeaker)
+
+function onServerToggleSpeaker()
+ if (not client) then
+ return false
+ end
+
+ local playerSpeakerData = getPlayerSpeakerData(client)
+
+ if (not playerSpeakerData) then
+ return false
+ end
+
+ local speakerPaused = playerSpeakerData.speakerPaused
+ local pauseNewState = (not speakerPaused)
+
+ playerSpeakerData.speakerPaused = pauseNewState
+ triggerClientEvent(root, "onClientToggleSpeaker", client, pauseNewState)
+end
+addEvent("onServerToggleSpeaker", true)
+addEventHandler("onServerToggleSpeaker", root, onServerToggleSpeaker)
+
+function syncSpeakers(startedResource)
+ local matchingResource = (startedResource == resource)
+
+ if (not matchingResource) then
+ return false
+ end
+
+ triggerClientEvent(source, "onClientSyncSpeakers", source, playerSpeakers)
+end
+addEventHandler("onPlayerResourceStart", root, syncSpeakers)
+
+function clearSpeakersOnDestroyQuit()
+ clearPlayerSpeaker(source)
+end
+addEventHandler("onPlayerQuit", root, clearSpeakersOnDestroyQuit)
+addEventHandler("onElementDestroy", resourceRoot, clearSpeakersOnDestroyQuit)
\ No newline at end of file
diff --git a/[gameplay]/internetradio/handle_radio/ShHandleRadio.lua b/[gameplay]/internetradio/handle_radio/ShHandleRadio.lua
new file mode 100644
index 000000000..b3a633ac7
--- /dev/null
+++ b/[gameplay]/internetradio/handle_radio/ShHandleRadio.lua
@@ -0,0 +1,29 @@
+-- #######################################
+-- ## Project: Internet radio ##
+-- ## Authors: MTA contributors ##
+-- ## Version: 1.0 ##
+-- #######################################
+
+function verifyRadioStreamURL(streamURL)
+ local urlType = type(streamURL)
+ local urlString = (urlType == "string")
+
+ if (not urlString) then
+ return false
+ end
+
+ local urlLength = utf8.len(streamURL)
+ local urlValidLength = (urlLength <= RADIO_STREAM_URL_MAX_LENGTH)
+
+ if (not urlValidLength) then
+ return false
+ end
+
+ local urlHttp = utf8.find(streamURL, "http")
+
+ if (not urlHttp) then
+ return false
+ end
+
+ return true
+end
\ No newline at end of file
diff --git a/[gameplay]/internetradio/meta.xml b/[gameplay]/internetradio/meta.xml
index b48c6b30a..13cedd335 100644
--- a/[gameplay]/internetradio/meta.xml
+++ b/[gameplay]/internetradio/meta.xml
@@ -1,6 +1,20 @@
-
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/[gameplay]/internetradio/server.lua b/[gameplay]/internetradio/server.lua
deleted file mode 100644
index 4f0a452e1..000000000
--- a/[gameplay]/internetradio/server.lua
+++ /dev/null
@@ -1,145 +0,0 @@
-local sounds, antiSpam = {}, {}
-
-function startStream(url, vol)
-
- if (not antiSpam[client]) then
- antiSpam[client] = 0
- setTimer(function(plr)
- antiSpam[plr] = nil end, 10000, 1, client)
- end
-
- antiSpam[client] = ((antiSpam[client] or 0) + 1)
-
- if (antiSpam[client] > 5) then -- More than 5 boxes in 10 seconds
- return false
- end
-
- local dist = 65
- local serial = getPlayerSerial(client)
-
- if (not sounds[client]) then
- sounds[client] = {}
- end
-
- if (sounds[client][serial] and isElement(sounds[client][serial][1])) then
- destroyElement(sounds[client][serial][1])
- end
-
- local x, y, z = getElementPosition(client)
- local interior = getElementInterior(client)
- local dimension = getElementDimension(client)
-
- local box = createObject(2229, x - 0.5, y + 0.5, z - 1, 0, 0, rx)
- setElementDimension(box, dimension)
- setElementInterior(box, interior)
-
- local vehicle = getPedOccupiedVehicle(client)
-
- if (isPedInVehicle(client) and vehicle and isElement(vehicle)) then
- sounds[client][serial] = {box, url, x, y, z + 2, vehicle, interior, dimension, vol, dist, getPlayerName(client)}
- setElementCollisionsEnabled(box, false)
- attachElements(box, vehicle, -0.7, -1.5, -0.1, 0, 90, 0)
- else
- sounds[client][serial] = {box, url, x, y, z, false, interior, dimension, vol, dist, getPlayerName(client)}
- setElementCollisionsEnabled(box, false)
- end
-
- outputServerLog("[SPEAKER] "..getPlayerName(client):gsub("#%x%x%x%x%x%x", "").." created speaker with URL: "..url)
- triggerClientEvent(root, "speaker.setBox", client, sounds[client])
-end
-addEvent("speaker.startStream", true)
-addEventHandler("speaker.startStream", root, startStream)
-
-function setting(vol, dist)
- local serial = getPlayerSerial(client)
-
- if (sounds[client]) then
- if (vol) then
- triggerClientEvent(root, "speaker.setData", client, vol, "vol", serial)
- return true
- end
-
- if (dist) then
- triggerClientEvent(root, "speaker.setData", client, dist, "dist", serial)
- return true
- end
- end
-end
-addEvent("speaker.change", true)
-addEventHandler("speaker.change", root, setting)
-
-function openGUI(player)
- triggerClientEvent(player, "Speaker.openInterface", player)
-end
-addCommandHandler("sound", openGUI, false, false)
-addCommandHandler("music", openGUI, false, false)
-addCommandHandler("musica", openGUI, false, false)
-addCommandHandler("song", openGUI, false, false)
-addCommandHandler("radio", openGUI, false, false)
-addCommandHandler("speaker", openGUI, false, false)
-
-function delAdmin(player, cmd, ID)
- if (hasObjectPermissionTo(player, "function.kickPlayer", false)) then
- local s2 = getPlayerFromName(ID)
-
- if (ID and s2 and sounds[s2]) then
- local serial = getPlayerSerial(s2)
- destroyElement(sounds[s2][serial][1])
- triggerClientEvent(root, "speaker.setData", player, false, "destroy", serial)
- outputChatBox("Speaker removed!", player, 0, 255, 0)
- sounds[s2] = nil
- else
- outputChatBox("Error, the player does not exist or does not have a speaker.", player, 255, 0, 0)
- end
- end
-end
-addCommandHandler("delbox", delAdmin)
-
-function destroySpeaker()
- local serial = getPlayerSerial(client)
- if (sounds[client]) then
- destroyElement(sounds[client][serial][1])
- triggerClientEvent(root, "speaker.setData", client, false, "destroy", serial)
- sounds[client] = nil
- end
-end
-addEvent("speaker.destroy", true)
-addEventHandler("speaker.destroy", root, destroySpeaker)
-
-function pauseSpeaker()
- if (sounds[client]) then
- local serial = getPlayerSerial(client)
- triggerClientEvent(root, "speaker.ps", client, serial)
- end
-end
-addEvent("speaker.pause", true)
-addEventHandler("speaker.pause", root, pauseSpeaker)
-
-function getSpeakers()
- local ltable = {}
- local speakers = 0
-
- for k, v in pairs(sounds) do
- for k2, v2 in pairs(v) do
- ltable[k2] = sounds[k][k2]
- speakers = speakers + 1
- end
- end
-
- if (speakers > 0) then
- triggerClientEvent(client, "speaker.setBox", client, ltable)
- end
-end
-addEvent("getSpeakers", true)
-addEventHandler("getSpeakers", root, getSpeakers)
-
-function onPlayerQuit()
- local serial = getPlayerSerial(source)
-
- if (sounds[source]) then
- destroyElement(sounds[source][serial][1])
- triggerClientEvent(root, "speaker.setData", source, false, "destroy", serial)
- sounds[source] = nil
- end
-end
-addEventHandler("onPlayerQuit", root, onPlayerQuit)
\ No newline at end of file
diff --git a/[gameplay]/internetradio/settings/CRadioSettings.lua b/[gameplay]/internetradio/settings/CRadioSettings.lua
new file mode 100644
index 000000000..713cb11da
--- /dev/null
+++ b/[gameplay]/internetradio/settings/CRadioSettings.lua
@@ -0,0 +1,71 @@
+-- #######################################
+-- ## Project: Internet radio ##
+-- ## Authors: MTA contributors ##
+-- ## Version: 1.0 ##
+-- #######################################
+
+local radioSettings = {}
+local settingsConfig = {
+ ["allowRemoteSpeakers"] = {
+ defaultValue = true,
+ getValueFrom = nil,
+ },
+}
+
+local function verifyRadioSettings(pRadioSettings)
+ local settingsType = type(pRadioSettings)
+ local settingsTable = (settingsType == "table")
+
+ if (not settingsTable) then
+ return false
+ end
+
+ radioSettings = pRadioSettings
+
+ return true
+end
+
+function onClientResourceStartLoadSettings()
+ local settingsFileExists = fileExists(RADIO_SETTINGS_PATH)
+
+ if (not settingsFileExists) then
+ return false
+ end
+
+ local settingsFileReadOnly = true
+ local settingsFileHandler = fileOpen(RADIO_SETTINGS_PATH, settingsFileReadOnly)
+
+ if (not settingsFileHandler) then
+ return false
+ end
+
+ local settingsFileSize = fileGetSize(settingsFileHandler)
+ local settingsFileData = fileRead(settingsFileHandler, settingsFileSize)
+ local settingsJson = fromJSON(settingsFileData)
+
+ fileClose(settingsFileHandler)
+ verifyRadioSettings(settingsJson)
+end
+addEventHandler("onClientResourceStart", resourceRoot, onClientResourceStartLoadSettings)
+
+function onClientResourceStopSaveSettings()
+ local settingsFileExists = fileExists(RADIO_SETTINGS_PATH)
+
+ if (settingsFileExists) then
+ fileDelete(RADIO_SETTINGS_PATH)
+ end
+
+ local newSettingsFile = fileCreate(RADIO_SETTINGS_PATH)
+
+ if (not newSettingsFile) then
+ return false
+ end
+
+ local jsonCompact = false
+ local jsonPrettyType = "tabs"
+ local jsonData = toJSON(radioSettings, jsonCompact, jsonPrettyType)
+
+ fileWrite(newSettingsFile, jsonData)
+ fileClose(newSettingsFile)
+end
+addEventHandler("onClientResourceStop", resourceRoot, onClientResourceStopSaveSettings)
\ No newline at end of file
diff --git a/[gameplay]/internetradio/track_name/CRadioTrackName.lua b/[gameplay]/internetradio/track_name/CRadioTrackName.lua
new file mode 100644
index 000000000..5282cde3d
--- /dev/null
+++ b/[gameplay]/internetradio/track_name/CRadioTrackName.lua
@@ -0,0 +1,114 @@
+-- #######################################
+-- ## Project: Internet radio ##
+-- ## Authors: MTA contributors ##
+-- ## Version: 1.0 ##
+-- #######################################
+
+local trackNameColorCoded = false
+local speakerTrackRender = false
+local fontHeight = dxGetFontHeight(RADIO_TRACK_SCALE, RADIO_TRACK_FONT)
+
+NEARBY_SPEAKERS = {}
+
+local function toggleSpeakerTrackRender()
+ local toggleOn = next(NEARBY_SPEAKERS)
+
+ if (toggleOn) then
+
+ if (speakerTrackRender) then
+ return false
+ end
+
+ addEventHandler("onClientRender", root, onClientRenderRadioTrackName)
+ speakerTrackRender = true
+
+ return true
+ end
+
+ if (not toggleOn) then
+
+ if (not speakerTrackRender) then
+ return false
+ end
+
+ removeEventHandler("onClientRender", root, onClientRenderRadioTrackName)
+ speakerTrackRender = false
+
+ return true
+ end
+end
+
+local function getSpeakerTrackName(streamSound)
+ local validElement = isElement(streamSound)
+
+ if (not validElement) then
+ return false
+ end
+
+ local elementType = getElementType(streamSound)
+ local soundType = (elementType == "sound")
+
+ if (not soundType) then
+ return false
+ end
+
+ local streamMetaTags = getSoundMetaTags(streamSound)
+
+ if (not streamMetaTags) then
+ return false
+ end
+
+ local streamTitle = streamMetaTags.stream_title
+ local streamTrackTitle = streamMetaTags.title
+ local trackName = (streamTitle or streamTrackTitle)
+
+ return trackName
+end
+
+function checkForNearbySpeakers()
+ local playerX, playerY, playerZ = getElementPosition(localPlayer)
+ local playerInterior = getElementInterior(localPlayer)
+ local playerDimension = getElementDimension(localPlayer)
+ local searchRange = RADIO_MAX_SOUND_DISTANCE
+ local nearbyObjects = getElementsWithinRange(playerX, playerY, playerZ, searchRange, "object", playerInterior, playerDimension)
+
+ NEARBY_SPEAKERS = {}
+
+ for objectID = 1, #nearbyObjects do
+ local nearbyObject = nearbyObjects[objectID]
+ local _, speakerSound, speakerDummy = isObjectSpeaker(nearbyObject)
+ local trackName = getSpeakerTrackName(speakerSound)
+
+ if (speakerDummy and trackName) then
+
+ NEARBY_SPEAKERS[speakerDummy] = trackName
+ end
+ end
+
+ toggleSpeakerTrackRender()
+end
+setTimer(checkForNearbySpeakers, 1000, 0)
+
+function onClientRenderRadioTrackName()
+ for nearbySpeaker, trackName in pairs(NEARBY_SPEAKERS) do
+ local speakerX, speakerY, speakerZ = getElementPosition(nearbySpeaker)
+ local cameraX, cameraY, cameraZ = getCameraMatrix()
+ local distanceToSpeaker = getDistanceBetweenPoints3D(speakerX, speakerY, speakerZ, cameraX, cameraY, cameraZ)
+ local closeToSpeaker = (distanceToSpeaker <= RADIO_MAX_SOUND_DISTANCE)
+
+ if (closeToSpeaker) then
+ local speakerOffsetZ = (speakerZ + 1)
+ local screenX, screenY = getScreenFromWorldPosition(speakerX, speakerY, speakerOffsetZ, 0, false)
+
+ if (screenX and screenY) then
+ local textWidth = dxGetTextWidth(trackName, RADIO_TRACK_SCALE, RADIO_TRACK_FONT, trackNameColorCoded)
+ local textPosX = (screenX - textWidth/2)
+ local textBackgroundPosX = (textPosX - 5)
+ local textBackgroundPosY = (textWidth + 8)
+
+ dxDrawRectangle(textBackgroundPosX, screenY, textBackgroundPosY, fontHeight, RADIO_TRACK_BACKGROUND_COLOR, false)
+ dxDrawText(trackName, textPosX, screenY, textPosX, screenY, RADIO_TRACK_COLOR, RADIO_TRACK_SCALE, "default-bold")
+ end
+ end
+ end
+end
\ No newline at end of file
From bc83542ac1fd784546853a423c3c755e8a8723d5 Mon Sep 17 00:00:00 2001
From: srslyyyy <51768772+srslyyyy@users.noreply.github.com>
Date: Sun, 30 Jun 2024 09:07:38 +0200
Subject: [PATCH 02/15] Fix error on track name.
---
[gameplay]/internetradio/handle_radio/CHandleRadio.lua | 2 +-
[gameplay]/internetradio/track_name/CRadioTrackName.lua | 1 -
2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/[gameplay]/internetradio/handle_radio/CHandleRadio.lua b/[gameplay]/internetradio/handle_radio/CHandleRadio.lua
index edc318e6a..22ad9a13d 100644
--- a/[gameplay]/internetradio/handle_radio/CHandleRadio.lua
+++ b/[gameplay]/internetradio/handle_radio/CHandleRadio.lua
@@ -220,7 +220,7 @@ function clearPlayerSpeaker(playerOrSpeaker)
local speakerDummy = speakerData.speakerDummy
local speakerDummyElement = isElement(speakerDummy)
- NEARBY_SPEAKERS[speakerDummyElement] = nil
+ NEARBY_SPEAKERS[speakerDummy] = nil
if (speakerDummyElement) then
destroyElement(speakerDummy)
diff --git a/[gameplay]/internetradio/track_name/CRadioTrackName.lua b/[gameplay]/internetradio/track_name/CRadioTrackName.lua
index 5282cde3d..17aac495f 100644
--- a/[gameplay]/internetradio/track_name/CRadioTrackName.lua
+++ b/[gameplay]/internetradio/track_name/CRadioTrackName.lua
@@ -80,7 +80,6 @@ function checkForNearbySpeakers()
local trackName = getSpeakerTrackName(speakerSound)
if (speakerDummy and trackName) then
-
NEARBY_SPEAKERS[speakerDummy] = trackName
end
end
From 039fcd82c7282261446df3d765e93c25adb617b9 Mon Sep 17 00:00:00 2001
From: srslyyyy <51768772+srslyyyy@users.noreply.github.com>
Date: Sun, 30 Jun 2024 09:16:15 +0200
Subject: [PATCH 03/15] Get camera position once
---
[gameplay]/internetradio/track_name/CRadioTrackName.lua | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/[gameplay]/internetradio/track_name/CRadioTrackName.lua b/[gameplay]/internetradio/track_name/CRadioTrackName.lua
index 17aac495f..d58476076 100644
--- a/[gameplay]/internetradio/track_name/CRadioTrackName.lua
+++ b/[gameplay]/internetradio/track_name/CRadioTrackName.lua
@@ -89,9 +89,10 @@ end
setTimer(checkForNearbySpeakers, 1000, 0)
function onClientRenderRadioTrackName()
+ local cameraX, cameraY, cameraZ = getCameraMatrix()
+
for nearbySpeaker, trackName in pairs(NEARBY_SPEAKERS) do
local speakerX, speakerY, speakerZ = getElementPosition(nearbySpeaker)
- local cameraX, cameraY, cameraZ = getCameraMatrix()
local distanceToSpeaker = getDistanceBetweenPoints3D(speakerX, speakerY, speakerZ, cameraX, cameraY, cameraZ)
local closeToSpeaker = (distanceToSpeaker <= RADIO_MAX_SOUND_DISTANCE)
From 3b6fba9996129d85dadb3b434cd7fb95a31a867b Mon Sep 17 00:00:00 2001
From: srslyyyy <51768772+srslyyyy@users.noreply.github.com>
Date: Sun, 30 Jun 2024 19:57:53 +0200
Subject: [PATCH 04/15] Add delays for player actions.
---
.../internetradio/config/ShRadioConfig.lua | 3 ++
.../handle_radio/CHandleRadio.lua | 20 +++++++-
.../handle_radio/SHandleRadio.lua | 48 ++++++++++++------
.../handle_radio/ShHandleRadio.lua | 49 ++++++++++++++++++-
4 files changed, 103 insertions(+), 17 deletions(-)
diff --git a/[gameplay]/internetradio/config/ShRadioConfig.lua b/[gameplay]/internetradio/config/ShRadioConfig.lua
index 5d3b5b65c..9034d70ad 100644
--- a/[gameplay]/internetradio/config/ShRadioConfig.lua
+++ b/[gameplay]/internetradio/config/ShRadioConfig.lua
@@ -4,6 +4,9 @@
-- ## Version: 1.0 ##
-- #######################################
+RADIO_CREATE_SPEAKER_DELAY = 3000
+RADIO_TOGGLE_SPEAKER_DELAY = 1500
+RADIO_DESTROY_SPEAKER_DELAY = 1500
RADIO_ALLOW_CUSTOM_URLS = false
RADIO_STREAM_URL_MAX_LENGTH = 512
RADIO_MAX_SOUND_DISTANCE = 65
diff --git a/[gameplay]/internetradio/handle_radio/CHandleRadio.lua b/[gameplay]/internetradio/handle_radio/CHandleRadio.lua
index 22ad9a13d..37bf73a40 100644
--- a/[gameplay]/internetradio/handle_radio/CHandleRadio.lua
+++ b/[gameplay]/internetradio/handle_radio/CHandleRadio.lua
@@ -96,7 +96,7 @@ function toggleSpeakerSounds(playerElement, toggleOn)
setSoundPaused(speakerNewSound, speakerPaused)
setSoundMaxDistance(speakerNewSound, speakerSoundMaxDistance)
- setSoundVolume(speakerNewSound, 0.02)
+ setSoundVolume(speakerNewSound, 0.30)
attachElements(speakerNewSound, speakerBox)
end
@@ -127,6 +127,12 @@ function onClientGUIClickCreateSpeaker()
return false
end
+ local createDelayPassed = getOrSetPlayerDelay(localPlayer, "create_speaker", RADIO_CREATE_SPEAKER_DELAY)
+
+ if (not createDelayPassed) then
+ return false
+ end
+
triggerServerEvent("onServerCreateSpeaker", localPlayer, streamURL)
end
@@ -137,6 +143,12 @@ function onClientGUIClickToggleSpeaker()
return false
end
+ local toggleDelayPassed = getOrSetPlayerDelay(localPlayer, "toggle_speaker", RADIO_TOGGLE_SPEAKER_DELAY)
+
+ if (not toggleDelayPassed) then
+ return false
+ end
+
triggerServerEvent("onServerToggleSpeaker", localPlayer)
end
@@ -147,6 +159,12 @@ function onClientGUIClickDestroySpeaker()
return false
end
+ local destroyDelayPassed = getOrSetPlayerDelay(localPlayer, "destroy_speaker", RADIO_DESTROY_SPEAKER_DELAY)
+
+ if (not destroyDelayPassed) then
+ return false
+ end
+
triggerServerEvent("onServerDestroySpeaker", localPlayer)
end
diff --git a/[gameplay]/internetradio/handle_radio/SHandleRadio.lua b/[gameplay]/internetradio/handle_radio/SHandleRadio.lua
index 4a899b84a..5bb618fe4 100644
--- a/[gameplay]/internetradio/handle_radio/SHandleRadio.lua
+++ b/[gameplay]/internetradio/handle_radio/SHandleRadio.lua
@@ -51,6 +51,12 @@ function onServerCreateSpeaker(streamURL)
return false
end
+ local createDelayPassed = getOrSetPlayerDelay(client, "create_speaker", RADIO_CREATE_SPEAKER_DELAY)
+
+ if (not createDelayPassed) then
+ return false
+ end
+
local validStreamURL = verifyRadioStreamURL(streamURL)
if (not validStreamURL) then
@@ -93,46 +99,58 @@ end
addEvent("onServerCreateSpeaker", true)
addEventHandler("onServerCreateSpeaker", root, onServerCreateSpeaker)
-function onServerDestroySpeaker()
+function onServerToggleSpeaker()
if (not client) then
return false
end
+ local toggleDelayPassed = getOrSetPlayerDelay(client, "toggle_speaker", RADIO_TOGGLE_SPEAKER_DELAY)
+
+ if (not toggleDelayPassed) then
+ return false
+ end
+
local playerSpeakerData = getPlayerSpeakerData(client)
if (not playerSpeakerData) then
return false
end
- local speakerBox = playerSpeakerData.speakerBox
- local speakerElement = isElement(speakerBox)
+ local speakerPaused = playerSpeakerData.speakerPaused
+ local pauseNewState = (not speakerPaused)
- if (speakerElement) then
- destroyElement(speakerBox)
- end
+ playerSpeakerData.speakerPaused = pauseNewState
+ triggerClientEvent(root, "onClientToggleSpeaker", client, pauseNewState)
end
-addEvent("onServerDestroySpeaker", true)
-addEventHandler("onServerDestroySpeaker", root, onServerDestroySpeaker)
+addEvent("onServerToggleSpeaker", true)
+addEventHandler("onServerToggleSpeaker", root, onServerToggleSpeaker)
-function onServerToggleSpeaker()
+function onServerDestroySpeaker()
if (not client) then
return false
end
+ local destroyDelayPassed = getOrSetPlayerDelay(client, "destroy_speaker", RADIO_DESTROY_SPEAKER_DELAY)
+
+ if (not destroyDelayPassed) then
+ return false
+ end
+
local playerSpeakerData = getPlayerSpeakerData(client)
if (not playerSpeakerData) then
return false
end
- local speakerPaused = playerSpeakerData.speakerPaused
- local pauseNewState = (not speakerPaused)
+ local speakerBox = playerSpeakerData.speakerBox
+ local speakerElement = isElement(speakerBox)
- playerSpeakerData.speakerPaused = pauseNewState
- triggerClientEvent(root, "onClientToggleSpeaker", client, pauseNewState)
+ if (speakerElement) then
+ destroyElement(speakerBox)
+ end
end
-addEvent("onServerToggleSpeaker", true)
-addEventHandler("onServerToggleSpeaker", root, onServerToggleSpeaker)
+addEvent("onServerDestroySpeaker", true)
+addEventHandler("onServerDestroySpeaker", root, onServerDestroySpeaker)
function syncSpeakers(startedResource)
local matchingResource = (startedResource == resource)
diff --git a/[gameplay]/internetradio/handle_radio/ShHandleRadio.lua b/[gameplay]/internetradio/handle_radio/ShHandleRadio.lua
index b3a633ac7..19c556c77 100644
--- a/[gameplay]/internetradio/handle_radio/ShHandleRadio.lua
+++ b/[gameplay]/internetradio/handle_radio/ShHandleRadio.lua
@@ -4,6 +4,9 @@
-- ## Version: 1.0 ##
-- #######################################
+local isServer = (not triggerServerEvent)
+local playerDelays = {}
+
function verifyRadioStreamURL(streamURL)
local urlType = type(streamURL)
local urlString = (urlType == "string")
@@ -26,4 +29,48 @@ function verifyRadioStreamURL(streamURL)
end
return true
-end
\ No newline at end of file
+end
+
+function getOrSetPlayerDelay(playerElement, delayID, delayTime)
+ local validElement = isElement(playerElement)
+
+ if (not validElement) then
+ return false
+ end
+
+ local elementType = getElementType(playerElement)
+ local playerType = (elementType == "player")
+
+ if (not playerType) then
+ return false
+ end
+
+ local playerDelayData = playerDelays[playerElement]
+
+ if (not playerDelayData) then
+ playerDelays[playerElement] = {}
+ playerDelayData = playerDelays[playerElement]
+ end
+
+ local activeDelay = playerDelayData[delayID]
+ local timeNow = getTickCount()
+
+ if (activeDelay) then
+ local delayPassed = (timeNow > activeDelay)
+
+ if (not delayPassed) then
+ return false
+ end
+ end
+
+ local delayEndTime = (timeNow + delayTime)
+
+ playerDelayData[delayID] = delayEndTime
+
+ return true
+end
+
+function clearPlayersDelay()
+ playerDelays[source] = nil
+end
+addEventHandler(isServer and "onPlayerQuit" or "onClientPlayerQuit", root, clearPlayersDelay)
\ No newline at end of file
From 0f9adf438aa1d5b98f7815ac585cadd89268a21c Mon Sep 17 00:00:00 2001
From: srslyyyy <51768772+srslyyyy@users.noreply.github.com>
Date: Sun, 30 Jun 2024 20:08:07 +0200
Subject: [PATCH 05/15] Check whether custom URL is allowed.
---
.../handle_radio/CHandleRadio.lua | 10 ++++++----
.../handle_radio/ShHandleRadio.lua | 19 +++++++++++++++++++
2 files changed, 25 insertions(+), 4 deletions(-)
diff --git a/[gameplay]/internetradio/handle_radio/CHandleRadio.lua b/[gameplay]/internetradio/handle_radio/CHandleRadio.lua
index 37bf73a40..965dc95a6 100644
--- a/[gameplay]/internetradio/handle_radio/CHandleRadio.lua
+++ b/[gameplay]/internetradio/handle_radio/CHandleRadio.lua
@@ -9,10 +9,10 @@ local playerSpeakers = {}
local function getStreamURLFromEdit()
local streamURL = guiGetText(RADIO_GUI["Stream URL edit"])
- local validStreamURL = verifyRadioStreamURL(streamURL)
+ local validStreamURL, errorCode = verifyRadioStreamURL(streamURL)
if (not validStreamURL) then
- return false
+ return false, errorCode
end
return streamURL
@@ -119,10 +119,12 @@ function onClientGUIClickLoadStationStreamURL()
end
function onClientGUIClickCreateSpeaker()
- local streamURL = getStreamURLFromEdit()
+ local streamURL, errorCode = getStreamURLFromEdit()
if (not streamURL) then
- outputChatBox("SPEAKER: Invalid URL, please check your input!", 255, 0, 0)
+ local textToDisplay = errorCode or "SPEAKER: Invalid URL, please check your input!"
+
+ outputChatBox(textToDisplay, 255, 0, 0)
return false
end
diff --git a/[gameplay]/internetradio/handle_radio/ShHandleRadio.lua b/[gameplay]/internetradio/handle_radio/ShHandleRadio.lua
index 19c556c77..4bfbba092 100644
--- a/[gameplay]/internetradio/handle_radio/ShHandleRadio.lua
+++ b/[gameplay]/internetradio/handle_radio/ShHandleRadio.lua
@@ -28,6 +28,25 @@ function verifyRadioStreamURL(streamURL)
return false
end
+ if (not RADIO_ALLOW_CUSTOM_URLS) then
+ local allowedStreamURL = false
+
+ for stationID = 1, #RADIO_STATIONS do
+ local stationData = RADIO_STATIONS[stationID]
+ local stationStreamURL = stationData[2]
+ local matchingStreamURL = (stationStreamURL == streamURL)
+
+ if (matchingStreamURL) then
+ allowedStreamURL = true
+ break
+ end
+ end
+
+ if (not allowedStreamURL) then
+ return false, "SPEAKER: Custom URLs are not allowed."
+ end
+ end
+
return true
end
From 4a8e6e4d5d2fcc1f132e72eeb9e82f4431145e77 Mon Sep 17 00:00:00 2001
From: srslyyyy <51768772+srslyyyy@users.noreply.github.com>
Date: Sun, 30 Jun 2024 21:31:08 +0200
Subject: [PATCH 06/15] Add radio settings.
---
.../internetradio/config/CRadioConfig.lua | 11 ++-
[gameplay]/internetradio/gui/CRadioGUI.lua | 10 ++-
.../internetradio/settings/CRadioSettings.lua | 68 ++++++++++++++++---
3 files changed, 76 insertions(+), 13 deletions(-)
diff --git a/[gameplay]/internetradio/config/CRadioConfig.lua b/[gameplay]/internetradio/config/CRadioConfig.lua
index 6da7d1680..72aecd801 100644
--- a/[gameplay]/internetradio/config/CRadioConfig.lua
+++ b/[gameplay]/internetradio/config/CRadioConfig.lua
@@ -11,4 +11,13 @@ RADIO_TRACK_BACKGROUND_COLOR = tocolor(0, 0, 0, 255)
RADIO_TOGGLE_KEY = "F9"
RADIO_COMMANDS = {"sound", "music", "musica", "song", "radio", "speaker"}
-RADIO_SETTINGS_PATH = "settings.json"
\ No newline at end of file
+RADIO_SETTINGS_PATH = "settings.json"
+
+RADIO_SETTINGS_TEMPLATE = {
+ ["allowRemoteSpeakers"] = {
+ defaultsTo = true,
+ dataType = {
+ ["boolean"] = true,
+ },
+ },
+}
\ No newline at end of file
diff --git a/[gameplay]/internetradio/gui/CRadioGUI.lua b/[gameplay]/internetradio/gui/CRadioGUI.lua
index 6ff3bf7f4..7765a170a 100644
--- a/[gameplay]/internetradio/gui/CRadioGUI.lua
+++ b/[gameplay]/internetradio/gui/CRadioGUI.lua
@@ -14,6 +14,7 @@ local function initializeRadioGUI()
local screenX, screenY = guiGetScreenSize()
local radioWindowSizeX, radioWindowSizeY = 325, 380
local radioWindowPosX, radioWindowPosY = (screenX - 325)/1.1, (screenY - 380)/1.4
+ local allowRemoteSpeakers = getRadioSetting("allowRemoteSpeakers")
RADIO_GUI = {}
RADIO_GUI["Radio window"] = guiCreateWindow(radioWindowPosX, radioWindowPosY, radioWindowSizeX, radioWindowSizeY, "SPEAKER MUSIC (RADIO/MP3)", false)
@@ -24,7 +25,7 @@ local function initializeRadioGUI()
RADIO_GUI["Play/pause button"] = guiCreateButton(10, 235, 150, 30, "Play - Pause", false, RADIO_GUI["Radio window"])
RADIO_GUI["Close button"] = guiCreateButton(162, 235, 150, 30, "Close", false, RADIO_GUI["Radio window"])
- RADIO_GUI["Toggle remote speakers checkbox"] = guiCreateCheckBox(15, 345, 160, 17, "Toggle other speakers", false, false, RADIO_GUI["Radio window"])
+ RADIO_GUI["Toggle remote speakers checkbox"] = guiCreateCheckBox(15, 345, 160, 17, "Toggle other speakers", allowRemoteSpeakers, false, RADIO_GUI["Radio window"])
RADIO_GUI["Toggle remote speakers label"] = guiCreateLabel(167, 345, 150, 17, "", false, RADIO_GUI["Radio window"])
RADIO_GUI["Radio station URL column"] = guiGridListAddColumn(RADIO_GUI["Stream URLs gridlist"], "Radio station", 0.8)
@@ -40,10 +41,17 @@ local function initializeRadioGUI()
addEventHandler("onClientGUIClick", RADIO_GUI["Play/pause button"], onClientGUIClickToggleSpeaker, false)
addEventHandler("onClientGUIClick", RADIO_GUI["Destroy speaker button"], onClientGUIClickDestroySpeaker, false)
addEventHandler("onClientGUIClick", RADIO_GUI["Close button"], onClientGUIClickCloseRadioGUI, false)
+ addEventHandler("onClientGUIClick", RADIO_GUI["Toggle remote speakers checkbox"], onClientGUIClickToggleRemoteSpeakers, false)
return true
end
+function onClientGUIClickToggleRemoteSpeakers()
+ local allowRemoteSpeakers = guiCheckBoxGetSelected(source)
+
+ setRadioSetting("allowRemoteSpeakers", allowRemoteSpeakers)
+end
+
function toggleRadioGUI()
initializeRadioGUI()
diff --git a/[gameplay]/internetradio/settings/CRadioSettings.lua b/[gameplay]/internetradio/settings/CRadioSettings.lua
index 713cb11da..78a072728 100644
--- a/[gameplay]/internetradio/settings/CRadioSettings.lua
+++ b/[gameplay]/internetradio/settings/CRadioSettings.lua
@@ -4,13 +4,7 @@
-- ## Version: 1.0 ##
-- #######################################
-local radioSettings = {}
-local settingsConfig = {
- ["allowRemoteSpeakers"] = {
- defaultValue = true,
- getValueFrom = nil,
- },
-}
+local savedRadioSettings = {}
local function verifyRadioSettings(pRadioSettings)
local settingsType = type(pRadioSettings)
@@ -20,15 +14,67 @@ local function verifyRadioSettings(pRadioSettings)
return false
end
- radioSettings = pRadioSettings
+ local settingsToLoad = {}
+
+ for settingKey, settingValue in pairs(pRadioSettings) do
+ local settingKeyType = type(settingKey)
+ local settingKeyString = (settingKeyType == "string")
+
+ if (settingKeyString) then
+ settingsToLoad[settingKey] = settingValue
+ end
+ end
+
+ for settingKey, settingValue in pairs(settingsToLoad) do
+ local settingData = RADIO_SETTINGS_TEMPLATE[settingKey]
+ local settingExists = (settingData ~= nil)
+
+ if (settingExists) then
+ local settingValueType = type(settingValue)
+ local settingAllowedType = settingData.dataType
+ local settingMatchingDataType = settingAllowedType[settingValueType]
+
+ if (not settingMatchingDataType) then
+ local settingDefault = settingData.defaultsTo
+
+ settingsToLoad[settingKey] = settingDefault
+ end
+ else
+ settingsToLoad[settingKey] = nil
+ end
+ end
+
+ savedRadioSettings = settingsToLoad
return true
end
+local function loadDefaultRadioSettings()
+ for settingKey, settingData in pairs(RADIO_SETTINGS_TEMPLATE) do
+ local settingValue = settingData.defaultsTo
+
+ savedRadioSettings[settingKey] = settingValue
+ end
+end
+
+function setRadioSetting(pKey, pValue)
+ savedRadioSettings[pKey] = pValue
+
+ return true
+end
+
+function getRadioSetting(pKey)
+ local radioSetting = savedRadioSettings[pKey]
+
+ return radioSetting
+end
+
function onClientResourceStartLoadSettings()
local settingsFileExists = fileExists(RADIO_SETTINGS_PATH)
if (not settingsFileExists) then
+ loadDefaultRadioSettings()
+
return false
end
@@ -46,7 +92,7 @@ function onClientResourceStartLoadSettings()
fileClose(settingsFileHandler)
verifyRadioSettings(settingsJson)
end
-addEventHandler("onClientResourceStart", resourceRoot, onClientResourceStartLoadSettings)
+addEventHandler("onClientResourceStart", resourceRoot, onClientResourceStartLoadSettings, false, "high")
function onClientResourceStopSaveSettings()
local settingsFileExists = fileExists(RADIO_SETTINGS_PATH)
@@ -63,9 +109,9 @@ function onClientResourceStopSaveSettings()
local jsonCompact = false
local jsonPrettyType = "tabs"
- local jsonData = toJSON(radioSettings, jsonCompact, jsonPrettyType)
+ local jsonData = toJSON(savedRadioSettings, jsonCompact, jsonPrettyType)
fileWrite(newSettingsFile, jsonData)
fileClose(newSettingsFile)
end
-addEventHandler("onClientResourceStop", resourceRoot, onClientResourceStopSaveSettings)
\ No newline at end of file
+addEventHandler("onClientResourceStop", resourceRoot, onClientResourceStopSaveSettings, false, "high")
\ No newline at end of file
From 1da3d3886575499c7680ae8c1e67fe2c7f2f3183 Mon Sep 17 00:00:00 2001
From: srslyyyy <51768772+srslyyyy@users.noreply.github.com>
Date: Sun, 30 Jun 2024 21:45:26 +0200
Subject: [PATCH 07/15] Handle remote speakers.
---
[gameplay]/internetradio/gui/CRadioGUI.lua | 3 ++-
.../handle_radio/CHandleRadio.lua | 21 ++++++++++++++++---
2 files changed, 20 insertions(+), 4 deletions(-)
diff --git a/[gameplay]/internetradio/gui/CRadioGUI.lua b/[gameplay]/internetradio/gui/CRadioGUI.lua
index 7765a170a..4ce20c89b 100644
--- a/[gameplay]/internetradio/gui/CRadioGUI.lua
+++ b/[gameplay]/internetradio/gui/CRadioGUI.lua
@@ -25,7 +25,7 @@ local function initializeRadioGUI()
RADIO_GUI["Play/pause button"] = guiCreateButton(10, 235, 150, 30, "Play - Pause", false, RADIO_GUI["Radio window"])
RADIO_GUI["Close button"] = guiCreateButton(162, 235, 150, 30, "Close", false, RADIO_GUI["Radio window"])
- RADIO_GUI["Toggle remote speakers checkbox"] = guiCreateCheckBox(15, 345, 160, 17, "Toggle other speakers", allowRemoteSpeakers, false, RADIO_GUI["Radio window"])
+ RADIO_GUI["Toggle remote speakers checkbox"] = guiCreateCheckBox(15, 345, 160, 17, "Allow other players speakers", allowRemoteSpeakers, false, RADIO_GUI["Radio window"])
RADIO_GUI["Toggle remote speakers label"] = guiCreateLabel(167, 345, 150, 17, "", false, RADIO_GUI["Radio window"])
RADIO_GUI["Radio station URL column"] = guiGridListAddColumn(RADIO_GUI["Stream URLs gridlist"], "Radio station", 0.8)
@@ -50,6 +50,7 @@ function onClientGUIClickToggleRemoteSpeakers()
local allowRemoteSpeakers = guiCheckBoxGetSelected(source)
setRadioSetting("allowRemoteSpeakers", allowRemoteSpeakers)
+ handleAllSpeakers()
end
function toggleRadioGUI()
diff --git a/[gameplay]/internetradio/handle_radio/CHandleRadio.lua b/[gameplay]/internetradio/handle_radio/CHandleRadio.lua
index 965dc95a6..590d3d9d6 100644
--- a/[gameplay]/internetradio/handle_radio/CHandleRadio.lua
+++ b/[gameplay]/internetradio/handle_radio/CHandleRadio.lua
@@ -68,6 +68,16 @@ function toggleSpeakerSounds(playerElement, toggleOn)
destroyElement(speakerSound)
end
+ local allowRemoteSpeakers = getRadioSetting("allowRemoteSpeakers")
+
+ if (not allowRemoteSpeakers) then
+ local remoteSpeaker = (playerElement ~= localPlayer)
+
+ if (remoteSpeaker) then
+ toggleOn = false
+ end
+ end
+
if (toggleOn) then
local speakerData = getPlayerSpeakerData(playerElement)
@@ -272,9 +282,7 @@ function isObjectSpeaker(objectElement)
return false
end
-function onClientSyncSpeakers(activeSpeakers)
- playerSpeakers = activeSpeakers
-
+function handleAllSpeakers()
for playerElement, speakerData in pairs(playerSpeakers) do
local speakerBox = speakerData.speakerBox
local speakerBoxStreamedIn = isElementStreamedIn(speakerBox)
@@ -283,6 +291,13 @@ function onClientSyncSpeakers(activeSpeakers)
toggleSpeakerSounds(playerElement, true)
end
end
+
+ return true
+end
+
+function onClientSyncSpeakers(activeSpeakers)
+ playerSpeakers = activeSpeakers
+ handleAllSpeakers()
end
addEvent("onClientSyncSpeakers", true)
addEventHandler("onClientSyncSpeakers", root, onClientSyncSpeakers)
From e1f50847bd0fa5bd347a355827ecdeef2cccfb84 Mon Sep 17 00:00:00 2001
From: srslyyyy <51768772+srslyyyy@users.noreply.github.com>
Date: Sun, 30 Jun 2024 21:49:25 +0200
Subject: [PATCH 08/15] Remove debug stuff.
---
[gameplay]/internetradio/gui/CRadioGUI.lua | 2 +-
[gameplay]/internetradio/handle_radio/CHandleRadio.lua | 9 ++-------
2 files changed, 3 insertions(+), 8 deletions(-)
diff --git a/[gameplay]/internetradio/gui/CRadioGUI.lua b/[gameplay]/internetradio/gui/CRadioGUI.lua
index 4ce20c89b..72595f06c 100644
--- a/[gameplay]/internetradio/gui/CRadioGUI.lua
+++ b/[gameplay]/internetradio/gui/CRadioGUI.lua
@@ -25,7 +25,7 @@ local function initializeRadioGUI()
RADIO_GUI["Play/pause button"] = guiCreateButton(10, 235, 150, 30, "Play - Pause", false, RADIO_GUI["Radio window"])
RADIO_GUI["Close button"] = guiCreateButton(162, 235, 150, 30, "Close", false, RADIO_GUI["Radio window"])
- RADIO_GUI["Toggle remote speakers checkbox"] = guiCreateCheckBox(15, 345, 160, 17, "Allow other players speakers", allowRemoteSpeakers, false, RADIO_GUI["Radio window"])
+ RADIO_GUI["Toggle remote speakers checkbox"] = guiCreateCheckBox(15, 345, 180, 17, "Allow other players speakers", allowRemoteSpeakers, false, RADIO_GUI["Radio window"])
RADIO_GUI["Toggle remote speakers label"] = guiCreateLabel(167, 345, 150, 17, "", false, RADIO_GUI["Radio window"])
RADIO_GUI["Radio station URL column"] = guiGridListAddColumn(RADIO_GUI["Stream URLs gridlist"], "Radio station", 0.8)
diff --git a/[gameplay]/internetradio/handle_radio/CHandleRadio.lua b/[gameplay]/internetradio/handle_radio/CHandleRadio.lua
index 590d3d9d6..0b1d593b2 100644
--- a/[gameplay]/internetradio/handle_radio/CHandleRadio.lua
+++ b/[gameplay]/internetradio/handle_radio/CHandleRadio.lua
@@ -106,7 +106,7 @@ function toggleSpeakerSounds(playerElement, toggleOn)
setSoundPaused(speakerNewSound, speakerPaused)
setSoundMaxDistance(speakerNewSound, speakerSoundMaxDistance)
- setSoundVolume(speakerNewSound, 0.30)
+ setSoundVolume(speakerNewSound, 1)
attachElements(speakerNewSound, speakerBox)
end
@@ -328,9 +328,4 @@ function clearSpeakersOnDestroyQuit()
clearPlayerSpeaker(source)
end
addEventHandler("onClientPlayerQuit", root, clearSpeakersOnDestroyQuit)
-addEventHandler("onClientElementDestroy", resourceRoot, clearSpeakersOnDestroyQuit)
-
-function onClientRenderDebugRadio()
- dxDrawText(inspect(playerSpeakers).."\n"..inspect(speakerSounds), 100, 100)
-end
-addEventHandler("onClientRender", root, onClientRenderDebugRadio)
\ No newline at end of file
+addEventHandler("onClientElementDestroy", resourceRoot, clearSpeakersOnDestroyQuit)
\ No newline at end of file
From 2b5e3a5a4a1ec178d4ed2d819467d87c7a6abb88 Mon Sep 17 00:00:00 2001
From: srslyyyy <51768772+srslyyyy@users.noreply.github.com>
Date: Sun, 30 Jun 2024 21:57:02 +0200
Subject: [PATCH 09/15] Use patterns for meta.xml
---
[gameplay]/internetradio/meta.xml | 12 ------------
1 file changed, 12 deletions(-)
diff --git a/[gameplay]/internetradio/meta.xml b/[gameplay]/internetradio/meta.xml
index 13cedd335..48852f699 100644
--- a/[gameplay]/internetradio/meta.xml
+++ b/[gameplay]/internetradio/meta.xml
@@ -2,19 +2,7 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
From 77e06423cafad497021dab7d6ed8bf46cd67f6a9 Mon Sep 17 00:00:00 2001
From: srslyyyy <51768772+srslyyyy@users.noreply.github.com>
Date: Sun, 30 Jun 2024 22:00:42 +0200
Subject: [PATCH 10/15] Bump server version in meta
---
[gameplay]/internetradio/meta.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/[gameplay]/internetradio/meta.xml b/[gameplay]/internetradio/meta.xml
index 48852f699..32115f928 100644
--- a/[gameplay]/internetradio/meta.xml
+++ b/[gameplay]/internetradio/meta.xml
@@ -1,6 +1,6 @@
-
+
From a7a02daf169c437701e1f895e81ea42b3eb18c36 Mon Sep 17 00:00:00 2001
From: srslyyyy <51768772+srslyyyy@users.noreply.github.com>
Date: Sun, 30 Jun 2024 22:10:23 +0200
Subject: [PATCH 11/15] Adjust script/pattern names.
---
.../config/{CRadioConfig.lua => C_RadioConfig.lua} | 0
.../config/{SRadioConfig.lua => S_RadioConfig.lua} | 0
.../config/{ShRadioConfig.lua => Sh_RadioConfig.lua} | 0
.../internetradio/gui/{CRadioGUI.lua => C_RadioGUI.lua} | 0
.../handle_radio/{CHandleRadio.lua => C_HandleRadio.lua} | 0
.../handle_radio/{SHandleRadio.lua => S_HandleRadio.lua} | 0
.../handle_radio/{ShHandleRadio.lua => Sh_HandleRadio.lua} | 0
[gameplay]/internetradio/meta.xml | 6 +++---
.../settings/{CRadioSettings.lua => C_RadioSettings.lua} | 0
.../{CRadioTrackName.lua => C_RadioTrackName.lua} | 0
10 files changed, 3 insertions(+), 3 deletions(-)
rename [gameplay]/internetradio/config/{CRadioConfig.lua => C_RadioConfig.lua} (100%)
rename [gameplay]/internetradio/config/{SRadioConfig.lua => S_RadioConfig.lua} (100%)
rename [gameplay]/internetradio/config/{ShRadioConfig.lua => Sh_RadioConfig.lua} (100%)
rename [gameplay]/internetradio/gui/{CRadioGUI.lua => C_RadioGUI.lua} (100%)
rename [gameplay]/internetradio/handle_radio/{CHandleRadio.lua => C_HandleRadio.lua} (100%)
rename [gameplay]/internetradio/handle_radio/{SHandleRadio.lua => S_HandleRadio.lua} (100%)
rename [gameplay]/internetradio/handle_radio/{ShHandleRadio.lua => Sh_HandleRadio.lua} (100%)
rename [gameplay]/internetradio/settings/{CRadioSettings.lua => C_RadioSettings.lua} (100%)
rename [gameplay]/internetradio/track_name/{CRadioTrackName.lua => C_RadioTrackName.lua} (100%)
diff --git a/[gameplay]/internetradio/config/CRadioConfig.lua b/[gameplay]/internetradio/config/C_RadioConfig.lua
similarity index 100%
rename from [gameplay]/internetradio/config/CRadioConfig.lua
rename to [gameplay]/internetradio/config/C_RadioConfig.lua
diff --git a/[gameplay]/internetradio/config/SRadioConfig.lua b/[gameplay]/internetradio/config/S_RadioConfig.lua
similarity index 100%
rename from [gameplay]/internetradio/config/SRadioConfig.lua
rename to [gameplay]/internetradio/config/S_RadioConfig.lua
diff --git a/[gameplay]/internetradio/config/ShRadioConfig.lua b/[gameplay]/internetradio/config/Sh_RadioConfig.lua
similarity index 100%
rename from [gameplay]/internetradio/config/ShRadioConfig.lua
rename to [gameplay]/internetradio/config/Sh_RadioConfig.lua
diff --git a/[gameplay]/internetradio/gui/CRadioGUI.lua b/[gameplay]/internetradio/gui/C_RadioGUI.lua
similarity index 100%
rename from [gameplay]/internetradio/gui/CRadioGUI.lua
rename to [gameplay]/internetradio/gui/C_RadioGUI.lua
diff --git a/[gameplay]/internetradio/handle_radio/CHandleRadio.lua b/[gameplay]/internetradio/handle_radio/C_HandleRadio.lua
similarity index 100%
rename from [gameplay]/internetradio/handle_radio/CHandleRadio.lua
rename to [gameplay]/internetradio/handle_radio/C_HandleRadio.lua
diff --git a/[gameplay]/internetradio/handle_radio/SHandleRadio.lua b/[gameplay]/internetradio/handle_radio/S_HandleRadio.lua
similarity index 100%
rename from [gameplay]/internetradio/handle_radio/SHandleRadio.lua
rename to [gameplay]/internetradio/handle_radio/S_HandleRadio.lua
diff --git a/[gameplay]/internetradio/handle_radio/ShHandleRadio.lua b/[gameplay]/internetradio/handle_radio/Sh_HandleRadio.lua
similarity index 100%
rename from [gameplay]/internetradio/handle_radio/ShHandleRadio.lua
rename to [gameplay]/internetradio/handle_radio/Sh_HandleRadio.lua
diff --git a/[gameplay]/internetradio/meta.xml b/[gameplay]/internetradio/meta.xml
index 32115f928..7460d996f 100644
--- a/[gameplay]/internetradio/meta.xml
+++ b/[gameplay]/internetradio/meta.xml
@@ -2,7 +2,7 @@
-
-
-
+
+
+
\ No newline at end of file
diff --git a/[gameplay]/internetradio/settings/CRadioSettings.lua b/[gameplay]/internetradio/settings/C_RadioSettings.lua
similarity index 100%
rename from [gameplay]/internetradio/settings/CRadioSettings.lua
rename to [gameplay]/internetradio/settings/C_RadioSettings.lua
diff --git a/[gameplay]/internetradio/track_name/CRadioTrackName.lua b/[gameplay]/internetradio/track_name/C_RadioTrackName.lua
similarity index 100%
rename from [gameplay]/internetradio/track_name/CRadioTrackName.lua
rename to [gameplay]/internetradio/track_name/C_RadioTrackName.lua
From cb706b39f0e91c98b5965dbb1ade7f890e75c71a Mon Sep 17 00:00:00 2001
From: srslyyyy <51768772+srslyyyy@users.noreply.github.com>
Date: Sun, 30 Jun 2024 22:45:15 +0200
Subject: [PATCH 12/15] Revert to old script names.
---
.../config/{C_RadioConfig.lua => CRadioConfig.lua} | 0
.../config/{S_RadioConfig.lua => SRadioConfig.lua} | 0
.../config/{Sh_RadioConfig.lua => ShRadioConfig.lua} | 0
.../internetradio/gui/{C_RadioGUI.lua => CRadioGUI.lua} | 0
.../handle_radio/{C_HandleRadio.lua => CHandleRadio.lua} | 0
.../handle_radio/{S_HandleRadio.lua => SHandleRadio.lua} | 0
.../handle_radio/{Sh_HandleRadio.lua => ShHandleRadio.lua} | 0
[gameplay]/internetradio/meta.xml | 6 +++---
.../settings/{C_RadioSettings.lua => CRadioSettings.lua} | 0
.../{C_RadioTrackName.lua => CRadioTrackName.lua} | 0
10 files changed, 3 insertions(+), 3 deletions(-)
rename [gameplay]/internetradio/config/{C_RadioConfig.lua => CRadioConfig.lua} (100%)
rename [gameplay]/internetradio/config/{S_RadioConfig.lua => SRadioConfig.lua} (100%)
rename [gameplay]/internetradio/config/{Sh_RadioConfig.lua => ShRadioConfig.lua} (100%)
rename [gameplay]/internetradio/gui/{C_RadioGUI.lua => CRadioGUI.lua} (100%)
rename [gameplay]/internetradio/handle_radio/{C_HandleRadio.lua => CHandleRadio.lua} (100%)
rename [gameplay]/internetradio/handle_radio/{S_HandleRadio.lua => SHandleRadio.lua} (100%)
rename [gameplay]/internetradio/handle_radio/{Sh_HandleRadio.lua => ShHandleRadio.lua} (100%)
rename [gameplay]/internetradio/settings/{C_RadioSettings.lua => CRadioSettings.lua} (100%)
rename [gameplay]/internetradio/track_name/{C_RadioTrackName.lua => CRadioTrackName.lua} (100%)
diff --git a/[gameplay]/internetradio/config/C_RadioConfig.lua b/[gameplay]/internetradio/config/CRadioConfig.lua
similarity index 100%
rename from [gameplay]/internetradio/config/C_RadioConfig.lua
rename to [gameplay]/internetradio/config/CRadioConfig.lua
diff --git a/[gameplay]/internetradio/config/S_RadioConfig.lua b/[gameplay]/internetradio/config/SRadioConfig.lua
similarity index 100%
rename from [gameplay]/internetradio/config/S_RadioConfig.lua
rename to [gameplay]/internetradio/config/SRadioConfig.lua
diff --git a/[gameplay]/internetradio/config/Sh_RadioConfig.lua b/[gameplay]/internetradio/config/ShRadioConfig.lua
similarity index 100%
rename from [gameplay]/internetradio/config/Sh_RadioConfig.lua
rename to [gameplay]/internetradio/config/ShRadioConfig.lua
diff --git a/[gameplay]/internetradio/gui/C_RadioGUI.lua b/[gameplay]/internetradio/gui/CRadioGUI.lua
similarity index 100%
rename from [gameplay]/internetradio/gui/C_RadioGUI.lua
rename to [gameplay]/internetradio/gui/CRadioGUI.lua
diff --git a/[gameplay]/internetradio/handle_radio/C_HandleRadio.lua b/[gameplay]/internetradio/handle_radio/CHandleRadio.lua
similarity index 100%
rename from [gameplay]/internetradio/handle_radio/C_HandleRadio.lua
rename to [gameplay]/internetradio/handle_radio/CHandleRadio.lua
diff --git a/[gameplay]/internetradio/handle_radio/S_HandleRadio.lua b/[gameplay]/internetradio/handle_radio/SHandleRadio.lua
similarity index 100%
rename from [gameplay]/internetradio/handle_radio/S_HandleRadio.lua
rename to [gameplay]/internetradio/handle_radio/SHandleRadio.lua
diff --git a/[gameplay]/internetradio/handle_radio/Sh_HandleRadio.lua b/[gameplay]/internetradio/handle_radio/ShHandleRadio.lua
similarity index 100%
rename from [gameplay]/internetradio/handle_radio/Sh_HandleRadio.lua
rename to [gameplay]/internetradio/handle_radio/ShHandleRadio.lua
diff --git a/[gameplay]/internetradio/meta.xml b/[gameplay]/internetradio/meta.xml
index 7460d996f..8ada107c7 100644
--- a/[gameplay]/internetradio/meta.xml
+++ b/[gameplay]/internetradio/meta.xml
@@ -2,7 +2,7 @@
-
-
-
+
+
+
\ No newline at end of file
diff --git a/[gameplay]/internetradio/settings/C_RadioSettings.lua b/[gameplay]/internetradio/settings/CRadioSettings.lua
similarity index 100%
rename from [gameplay]/internetradio/settings/C_RadioSettings.lua
rename to [gameplay]/internetradio/settings/CRadioSettings.lua
diff --git a/[gameplay]/internetradio/track_name/C_RadioTrackName.lua b/[gameplay]/internetradio/track_name/CRadioTrackName.lua
similarity index 100%
rename from [gameplay]/internetradio/track_name/C_RadioTrackName.lua
rename to [gameplay]/internetradio/track_name/CRadioTrackName.lua
From 2e48db9daf2cc2a98b80025d58bea305268f8ef0 Mon Sep 17 00:00:00 2001
From: srslyyyy <51768772+srslyyyy@users.noreply.github.com>
Date: Mon, 1 Jul 2024 00:09:16 +0200
Subject: [PATCH 13/15] Change default key. Add option to show on start.
And make use of previously unused commands.
---
[gameplay]/internetradio/config/CRadioConfig.lua | 3 ++-
[gameplay]/internetradio/gui/CRadioGUI.lua | 16 +++++++++++++++-
2 files changed, 17 insertions(+), 2 deletions(-)
diff --git a/[gameplay]/internetradio/config/CRadioConfig.lua b/[gameplay]/internetradio/config/CRadioConfig.lua
index 72aecd801..074933b58 100644
--- a/[gameplay]/internetradio/config/CRadioConfig.lua
+++ b/[gameplay]/internetradio/config/CRadioConfig.lua
@@ -9,7 +9,8 @@ RADIO_TRACK_FONT = "default-bold"
RADIO_TRACK_COLOR = tocolor(150, 50, 150, 255)
RADIO_TRACK_BACKGROUND_COLOR = tocolor(0, 0, 0, 255)
-RADIO_TOGGLE_KEY = "F9"
+RADIO_TOGGLE_KEY = "F3"
+RADIO_SHOW_ON_START = true
RADIO_COMMANDS = {"sound", "music", "musica", "song", "radio", "speaker"}
RADIO_SETTINGS_PATH = "settings.json"
diff --git a/[gameplay]/internetradio/gui/CRadioGUI.lua b/[gameplay]/internetradio/gui/CRadioGUI.lua
index 72595f06c..41a7b2952 100644
--- a/[gameplay]/internetradio/gui/CRadioGUI.lua
+++ b/[gameplay]/internetradio/gui/CRadioGUI.lua
@@ -43,6 +43,12 @@ local function initializeRadioGUI()
addEventHandler("onClientGUIClick", RADIO_GUI["Close button"], onClientGUIClickCloseRadioGUI, false)
addEventHandler("onClientGUIClick", RADIO_GUI["Toggle remote speakers checkbox"], onClientGUIClickToggleRemoteSpeakers, false)
+ for commandID = 1, #RADIO_COMMANDS do
+ local commandName = RADIO_COMMANDS[commandID]
+
+ addCommandHandler(commandName, toggleRadioGUI)
+ end
+
return true
end
@@ -63,4 +69,12 @@ function toggleRadioGUI()
showCursor(guiNewState)
end
bindKey(RADIO_TOGGLE_KEY, "down", toggleRadioGUI)
-addEventHandler("onClientResourceStart", resourceRoot, toggleRadioGUI)
\ No newline at end of file
+
+function onClientResourceStartRadioGUI()
+ if (not RADIO_SHOW_ON_START) then
+ return false
+ end
+
+ toggleRadioGUI()
+end
+addEventHandler("onClientResourceStart", resourceRoot, onClientResourceStartRadioGUI)
\ No newline at end of file
From 7e89c499a566c3008ce74afe1339048c0286ff41 Mon Sep 17 00:00:00 2001
From: srslyyyy <51768772+srslyyyy@users.noreply.github.com>
Date: Mon, 1 Jul 2024 00:47:34 +0200
Subject: [PATCH 14/15] Ensure default settings on start.
---
[gameplay]/internetradio/settings/CRadioSettings.lua | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/[gameplay]/internetradio/settings/CRadioSettings.lua b/[gameplay]/internetradio/settings/CRadioSettings.lua
index 78a072728..e8c2a2f0c 100644
--- a/[gameplay]/internetradio/settings/CRadioSettings.lua
+++ b/[gameplay]/internetradio/settings/CRadioSettings.lua
@@ -72,9 +72,9 @@ end
function onClientResourceStartLoadSettings()
local settingsFileExists = fileExists(RADIO_SETTINGS_PATH)
- if (not settingsFileExists) then
- loadDefaultRadioSettings()
+ loadDefaultRadioSettings()
+ if (not settingsFileExists) then
return false
end
From b52aa8d8205e6be812b29ceb1929dc0470888b1e Mon Sep 17 00:00:00 2001
From: srslyyyy <51768772+srslyyyy@users.noreply.github.com>
Date: Sat, 13 Jul 2024 07:49:49 +0200
Subject: [PATCH 15/15] Update CRadioSettings.lua
---
[gameplay]/internetradio/settings/CRadioSettings.lua | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/[gameplay]/internetradio/settings/CRadioSettings.lua b/[gameplay]/internetradio/settings/CRadioSettings.lua
index e8c2a2f0c..23c6a4f2e 100644
--- a/[gameplay]/internetradio/settings/CRadioSettings.lua
+++ b/[gameplay]/internetradio/settings/CRadioSettings.lua
@@ -6,8 +6,8 @@
local savedRadioSettings = {}
-local function verifyRadioSettings(pRadioSettings)
- local settingsType = type(pRadioSettings)
+local function verifyRadioSettings(radioSettings)
+ local settingsType = type(radioSettings)
local settingsTable = (settingsType == "table")
if (not settingsTable) then
@@ -16,7 +16,7 @@ local function verifyRadioSettings(pRadioSettings)
local settingsToLoad = {}
- for settingKey, settingValue in pairs(pRadioSettings) do
+ for settingKey, settingValue in pairs(radioSettings) do
local settingKeyType = type(settingKey)
local settingKeyString = (settingKeyType == "string")