Skip to content

Commit 5c16021

Browse files
authored
internetradio: error fix & admin commands (#524)
1 parent cf669db commit 5c16021

File tree

5 files changed

+176
-41
lines changed

5 files changed

+176
-41
lines changed

[gameplay]/internetradio/config/CRadioConfig.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,4 @@ RADIO_SETTINGS_TEMPLATE = {
2121
["boolean"] = true,
2222
},
2323
},
24-
}
24+
}

[gameplay]/internetradio/config/SRadioConfig.lua

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,8 @@
66

77
RADIO_BOX_MODEL = 2229
88
RADIO_DESTROY_ON_VEHICLE_EXPLODE = false
9-
RADIO_DESTROY_ON_VEHICLE_DESTROY = false
9+
RADIO_DESTROY_ON_VEHICLE_DESTROY = false
10+
RADIO_DESTROY_SPEAKER_COMMAND = "destroyspeaker"
11+
RADIO_DESTROY_SPEAKER_ACCESS_RIGHT = "function.kickPlayer"
12+
RADIO_DESTROY_SPEAKERS_IN_RANGE_COMMAND = "destroyspeakers"
13+
RADIO_DESTROY_SPEAKERS_IN_RANGE_ACCESS_RIGHT = "function.kickPlayer"

[gameplay]/internetradio/handle_radio/CHandleRadio.lua

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -267,15 +267,24 @@ function clearPlayerSpeaker(playerOrSpeaker)
267267
end
268268

269269
function isObjectSpeaker(objectElement)
270+
local validElement = isElement(objectElement)
271+
272+
if (not validElement) then
273+
return false
274+
end
275+
270276
for playerElement, speakerData in pairs(playerSpeakers) do
271-
local speakerBox = speakerData.speakerBox
272-
local matchingElement = (speakerBox == objectElement)
273277

274-
if (matchingElement) then
275-
local speakerSound = speakerSounds[playerElement]
276-
local speakerDummy = speakerData.speakerDummy
278+
if (speakerData) then
279+
local speakerBox = speakerData.speakerBox
280+
local matchingElement = (speakerBox == objectElement)
277281

278-
return true, speakerSound, speakerDummy
282+
if (matchingElement) then
283+
local speakerSound = speakerSounds[playerElement]
284+
local speakerDummy = speakerData.speakerDummy
285+
286+
return true, speakerSound, speakerDummy
287+
end
279288
end
280289
end
281290

@@ -328,4 +337,4 @@ function clearSpeakersOnDestroyQuit()
328337
clearPlayerSpeaker(source)
329338
end
330339
addEventHandler("onClientPlayerQuit", root, clearSpeakersOnDestroyQuit)
331-
addEventHandler("onClientElementDestroy", resourceRoot, clearSpeakersOnDestroyQuit)
340+
addEventHandler("onClientElementDestroy", resourceRoot, clearSpeakersOnDestroyQuit)

[gameplay]/internetradio/handle_radio/SHandleRadio.lua

Lines changed: 125 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -31,16 +31,19 @@ function getPlayerSpeakerData(playerElement)
3131
return playerSpeakerData
3232
end
3333

34-
function clearPlayerSpeaker(playerOrSpeaker)
34+
function clearPlayerSpeaker(playerOrSpeaker, forceDestroy)
3535
for playerElement, speakerData in pairs(playerSpeakers) do
3636
local speakerBox = speakerData.speakerBox
3737
local matchingElement = (playerElement == playerOrSpeaker) or (speakerBox == playerOrSpeaker)
3838

3939
if (matchingElement) then
40-
local boxElement = isElement(speakerBox)
4140

42-
if (boxElement) then
43-
destroyElement(speakerBox)
41+
if (forceDestroy) then
42+
local boxElement = isElement(speakerBox)
43+
44+
if (boxElement) then
45+
destroyElement(speakerBox)
46+
end
4447
end
4548

4649
playerSpeakers[playerElement] = nil
@@ -52,6 +55,25 @@ function clearPlayerSpeaker(playerOrSpeaker)
5255
return false
5356
end
5457

58+
function isObjectSpeaker(objectElement)
59+
local validElement = isElement(objectElement)
60+
61+
if (not validElement) then
62+
return false
63+
end
64+
65+
for playerElement, speakerData in pairs(playerSpeakers) do
66+
local speakerBox = speakerData.speakerBox
67+
local matchingElement = (speakerBox == objectElement)
68+
69+
if (matchingElement) then
70+
return true
71+
end
72+
end
73+
74+
return false
75+
end
76+
5577
function onServerCreateSpeaker(streamURL)
5678
if (not client) then
5779
return false
@@ -69,16 +91,7 @@ function onServerCreateSpeaker(streamURL)
6991
return false
7092
end
7193

72-
local playerSpeakerData = getPlayerSpeakerData(client)
73-
74-
if (playerSpeakerData) then
75-
local speakerBox = playerSpeakerData.speakerBox
76-
local speakerElement = isElement(speakerBox)
77-
78-
if (speakerElement) then
79-
destroyElement(speakerBox)
80-
end
81-
end
94+
clearPlayerSpeaker(client, true)
8295

8396
local playerPosX, playerPosY, playerPosZ = getElementPosition(client)
8497
local playerInterior = getElementInterior(client)
@@ -148,18 +161,7 @@ function onServerDestroySpeaker()
148161
return false
149162
end
150163

151-
local playerSpeakerData = getPlayerSpeakerData(client)
152-
153-
if (not playerSpeakerData) then
154-
return false
155-
end
156-
157-
local speakerBox = playerSpeakerData.speakerBox
158-
local speakerElement = isElement(speakerBox)
159-
160-
if (speakerElement) then
161-
destroyElement(speakerBox)
162-
end
164+
clearPlayerSpeaker(client, true)
163165
end
164166
addEvent("onServerDestroySpeaker", true)
165167
addEventHandler("onServerDestroySpeaker", root, onServerDestroySpeaker)
@@ -175,11 +177,102 @@ function syncSpeakers(startedResource)
175177
end
176178
addEventHandler("onPlayerResourceStart", root, syncSpeakers)
177179

178-
function clearSpeakersOnDestroyQuit()
179-
clearPlayerSpeaker(source)
180+
function clearSpeakerOnPlayerQuit()
181+
clearPlayerSpeaker(source, true)
182+
end
183+
addEventHandler("onPlayerQuit", root, clearSpeakerOnPlayerQuit)
184+
185+
function clearSpeakerOnElementDestroy()
186+
clearPlayerSpeaker(source, false)
187+
end
188+
addEventHandler("onElementDestroy", resourceRoot, clearSpeakerOnElementDestroy)
189+
190+
function destroySpeakerAdminCommand(playerElement, _, targetPlayer)
191+
local hasPlayerRightToDestroySpeaker = hasObjectPermissionTo(playerElement, RADIO_DESTROY_SPEAKER_ACCESS_RIGHT, false)
192+
193+
if (not hasPlayerRightToDestroySpeaker) then
194+
outputChatBox("#ff8800[Speakers]: #ffffffYou have no access to #ff8800/"..RADIO_DESTROY_SPEAKER_COMMAND, playerElement, 255, 255, 255, true)
195+
196+
return false
197+
end
198+
199+
if (not targetPlayer) then
200+
outputChatBox("#ff8800[Speakers]: #ffffffSyntax: #ff8800/"..RADIO_DESTROY_SPEAKER_COMMAND.." <playerName>", playerElement, 255, 255, 255, true)
201+
202+
return false
203+
end
204+
205+
local playerFromName = getPlayerFromPartialName(targetPlayer)
206+
207+
if (not playerFromName) then
208+
outputChatBox("#ff8800[Speakers]: #ffffffPlayer #ff8800"..targetPlayer.." #ffffffnot found.", playerElement, 255, 255, 255, true)
209+
210+
return false
211+
end
212+
213+
local speakerFound = clearPlayerSpeaker(playerFromName, true)
214+
local speakerDestroyed = (speakerFound and "Successfully destroyed #ff8800"..targetPlayer.."#ffffff speaker." or "Player #ff8800"..targetPlayer.."#ffffff has no speaker.")
215+
local speakerDestroyedMessage = "#ff8800[Speakers]: #ffffff"..speakerDestroyed
216+
217+
outputChatBox(speakerDestroyedMessage, playerElement, 255, 255, 255, true)
218+
end
219+
addCommandHandler(RADIO_DESTROY_SPEAKER_COMMAND, destroySpeakerAdminCommand)
220+
221+
function destroySpeakersInRangeAdminCommand(playerElement, _, searchRange)
222+
local hasPlayerRightToDestroySpeaker = hasObjectPermissionTo(playerElement, RADIO_DESTROY_SPEAKERS_IN_RANGE_ACCESS_RIGHT, false)
223+
224+
if (not hasPlayerRightToDestroySpeaker) then
225+
outputChatBox("#ff8800[Speakers]: #ffffffYou have no access to #ff8800/"..RADIO_DESTROY_SPEAKERS_IN_RANGE_COMMAND, playerElement, 255, 255, 255, true)
226+
227+
return false
228+
end
229+
230+
local speakerSearchRange = tonumber(searchRange)
231+
local validSearchRange = (speakerSearchRange and speakerSearchRange > 0)
232+
233+
if (not speakerSearchRange or not validSearchRange) then
234+
outputChatBox("#ff8800[Speakers]: #ffffffSyntax: #ff8800/"..RADIO_DESTROY_SPEAKERS_IN_RANGE_COMMAND.." <searchRange>", playerElement, 255, 255, 255, true)
235+
236+
return false
237+
end
238+
239+
local objectsTable = getElementsByType("object", resourceRoot)
240+
local playerInterior = getElementInterior(playerElement)
241+
local playerDimension = getElementDimension(playerElement)
242+
local playerX, playerY, playerZ = getElementPosition(playerElement)
243+
local totalDestroyedSpeakers = 0
244+
245+
for objectID = 1, #objectsTable do
246+
local objectElement = objectsTable[objectID]
247+
local objectSpeaker = isObjectSpeaker(objectElement)
248+
249+
if (objectSpeaker) then
250+
local speakerInterior = getElementInterior(objectElement)
251+
local speakerDimension = getElementDimension(objectElement)
252+
local matchingInterior = (speakerInterior == playerInterior)
253+
local matchingDimension = (speakerDimension == playerDimension)
254+
255+
if (matchingInterior and matchingDimension) then
256+
local speakerX, speakerY, speakerZ = getElementPosition(objectElement)
257+
local distanceToSpeaker = getDistanceBetweenPoints3D(playerX, playerY, playerZ, speakerX, speakerY, speakerZ)
258+
local speakerInDistance = (distanceToSpeaker <= speakerSearchRange)
259+
260+
if (speakerInDistance) then
261+
local speakerDestroyed = clearPlayerSpeaker(objectElement, true)
262+
263+
if (speakerDestroyed) then
264+
local newCountOfDestroyedSpeakers = (totalDestroyedSpeakers + 1)
265+
266+
totalDestroyedSpeakers = newCountOfDestroyedSpeakers
267+
end
268+
end
269+
end
270+
end
271+
end
272+
273+
outputChatBox("#ff8800[Speakers]: #ffffffDestroyed #ff8800"..totalDestroyedSpeakers.."#ffffff total speakers in range of #ff8800"..speakerSearchRange, playerElement, 255, 255, 255, true)
180274
end
181-
addEventHandler("onPlayerQuit", root, clearSpeakersOnDestroyQuit)
182-
addEventHandler("onElementDestroy", resourceRoot, clearSpeakersOnDestroyQuit)
275+
addCommandHandler(RADIO_DESTROY_SPEAKERS_IN_RANGE_COMMAND, destroySpeakersInRangeAdminCommand)
183276

184277
function destroyAttachedRadioOnVehicleExplodeOrDestroy()
185278
local validElement = isElement(source)
@@ -203,9 +296,9 @@ function destroyAttachedRadioOnVehicleExplodeOrDestroy()
203296
local attachedElementObject = (attachedElementType == "object")
204297

205298
if (attachedElementObject) then
206-
local boxFound = clearPlayerSpeaker(attachedElement)
299+
local speakerFound = clearPlayerSpeaker(attachedElement, true)
207300

208-
if (boxFound) then
301+
if (speakerFound) then
209302
break
210303
end
211304
end

[gameplay]/internetradio/handle_radio/ShHandleRadio.lua

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,35 @@ function verifyRadioStreamURL(streamURL)
5050
return true
5151
end
5252

53+
function getPlayerFromPartialName(partialName)
54+
if (not partialName) then
55+
return false
56+
end
57+
58+
local playerFromName = getPlayerFromName(partialName)
59+
60+
if (playerFromName) then
61+
return playerFromName
62+
end
63+
64+
local playersTable = getElementsByType("player")
65+
local partialNameLower = string.lower(partialName)
66+
67+
for playerID = 1, #playersTable do
68+
local playerElement = playersTable[playerID]
69+
local playerName = getPlayerName(playerElement)
70+
local playerNameLower = string.lower(playerName)
71+
local playerNameWithoutColor = string.gsub(playerNameLower, "#%x%x%x%x%x%x", "")
72+
local playerFound = string.find(playerNameWithoutColor, partialNameLower, 1, true)
73+
74+
if (playerFound) then
75+
return playerElement
76+
end
77+
end
78+
79+
return false
80+
end
81+
5382
function getOrSetPlayerDelay(playerElement, delayID, delayTime)
5483
local validElement = isElement(playerElement)
5584

0 commit comments

Comments
 (0)