diff --git a/[gameplay]/freeroam/fr_client.lua b/[gameplay]/freeroam/fr_client.lua
index 8add35a52..e7c5c0b01 100644
--- a/[gameplay]/freeroam/fr_client.lua
+++ b/[gameplay]/freeroam/fr_client.lua
@@ -290,7 +290,7 @@ function animCmd(command, lib, name)
errMsg('This animation may not be set by command')
return
end
- server.setPedAnimation(localPlayer, lib, name, true, true)
+ server.setPedAnimation(localPlayer, lib, name, -1, true, true)
end
addCommandHandler('anim', animCmd)
diff --git a/[gameplay]/freeroam/fr_server.lua b/[gameplay]/freeroam/fr_server.lua
index 8ab902fc3..15a6ddf45 100644
--- a/[gameplay]/freeroam/fr_server.lua
+++ b/[gameplay]/freeroam/fr_server.lua
@@ -37,6 +37,7 @@ g_RPCFunctions = {
removeVehicleUpgrade = { option = 'upgrades', descr = 'Adding/removing upgrades' },
setElementAlpha = { option = 'alpha', descr = 'Changing your alpha' },
setElementInterior = true,
+ setCameraInterior = true,
setMySkin = { option = 'setskin', descr = 'Setting skin' },
setPedAnimation = { option = 'anim', descr = 'Setting an animation' },
setPedFightingStyle = { option = 'setstyle', descr = 'Setting fighting style' },
@@ -123,10 +124,6 @@ function onLocalSettingChange(setting,value)
end
function joinHandler(player)
- if not player then
- player = source
- end
-
local r, g, b = math.random(50, 255), math.random(50, 255), math.random(50, 255)
setPlayerNametagColor(player, r, g, b)
g_PlayerData[player] = { vehicles = {}, settings={} }
@@ -137,7 +134,8 @@ function joinHandler(player)
outputChatBox('Press F1 to show/hide controls', player, 0, 255, 0)
end
end
-addEventHandler('onPlayerJoin', root, joinHandler)
+
+addEventHandler('onPlayerJoin', root, function() joinHandler(source) end)
local settingsToSend = {
"command_spam_protection",
@@ -269,7 +267,7 @@ function handleClothesInit()
end
end
addEvent('onClothesInit', true)
-addEventHandler('onClothesInit', resourceRoot, handleClothesInit)
+addEventHandler('onClothesInit', resourceRoot, handleClothesInit, false)
addEvent('onPlayerGravInit', true)
addEventHandler('onPlayerGravInit', root,
@@ -281,55 +279,58 @@ addEventHandler('onPlayerGravInit', root,
end
)
+------------------------------------------
+-- [START] Remote Player Call Functions --
+
+
function setMySkin(skinid)
- if not isElement(source) then return end
- if getElementModel(source) == skinid then return end
- if isPedDead(source) then
- local x, y, z = getElementPosition(source)
+ if not isElement(client) then return end
+ if getElementModel(client) == skinid then return end
+ if isPedDead(client) then
+ local x, y, z = getElementPosition(client)
- if isPedTerminated(source) then
+ if isPedTerminated(client) then
x = 0
y = 0
z = 3
end
- local r = getPedRotation(source)
- local interior = getElementInterior(source)
- spawnPlayer(source, x, y, z, r, skinid)
- setElementInterior(source, interior)
- setCameraInterior(source, interior)
+ local r = getPedRotation(client)
+ local interior = getElementInterior(client)
+ spawnPlayer(client, x, y, z, r, skinid)
+ setElementInterior(client, interior)
+ setCameraInterior(client, interior)
else
- setElementModel(source, skinid)
+ setElementModel(client, skinid)
end
- setCameraTarget(source, source)
- setCameraInterior(source, getElementInterior(source))
+ setCameraTarget(client, client)
+ setCameraInterior(client, getElementInterior(client))
end
function spawnMe(x, y, z)
if not x then
- x, y, z = getElementPosition(source)
+ x, y, z = getElementPosition(client)
end
- if isPedTerminated(source) then
- repeat until spawnPlayer(source, x, y, z, 0, math.random(9, 288))
+ if isPedTerminated(client) then
+ repeat until spawnPlayer(client, x, y, z, 0, math.random(9, 288))
else
- spawnPlayer(source, x, y, z, 0, getPedSkin(source))
+ spawnPlayer(client, x, y, z, 0, getPedSkin(client))
end
- setCameraTarget(source, source)
- setCameraInterior(source, getElementInterior(source))
+ setCameraTarget(client, client)
+ setCameraInterior(client, getElementInterior(client))
end
function warpMeIntoVehicle(vehicle)
-
if not isElement(vehicle) then return end
- if isPedDead(source) then
+ if isPedDead(client) then
spawnMe()
end
- if getPedOccupiedVehicle(source) then
- outputChatBox('Get out of your vehicle first.', source, 255,0,0)
+ if getPedOccupiedVehicle(client) then
+ outputChatBox('Get out of your vehicle first.', client, 255, 0, 0)
return
end
local interior = getElementInterior(vehicle)
@@ -337,66 +338,68 @@ function warpMeIntoVehicle(vehicle)
local driver = getVehicleController(vehicle)
for i=0,numseats do
if not getVehicleOccupant(vehicle, i) then
-
- if isPedDead(source) then
+ if isPedDead(client) then
local x, y, z = getElementPosition(vehicle)
spawnMe(x + 4, y, z + 1)
end
- setElementInterior(source, interior)
- setCameraInterior(source, interior)
- warpPedIntoVehicle(source, vehicle, i)
+ setElementInterior(client, interior)
+ setCameraInterior(client, interior)
+ warpPedIntoVehicle(client, vehicle, i)
return
end
end
if isElement(driver) then
- outputChatBox('No free seats left in ' .. getPlayerName(driver) .. '\'s vehicle.', source, 255, 0, 0)
+ outputChatBox('No free seats left in ' .. getPlayerName(driver) .. '\'s vehicle.', client, 255, 0, 0)
end
-
end
local sawnoffAntiAbuse = {}
+
function giveMeWeapon(weapon, amount)
+ local player = client
if table.find(getOption('weapons.disallowed'), weapon) then
- errMsg((getWeaponNameFromID(weapon) or tostring(weapon)) .. 's are not allowed', source)
+ errMsg((getWeaponNameFromID(weapon) or tostring(weapon)) .. 's are not allowed', player)
else
- giveWeapon(source, weapon, amount, true)
+ giveWeapon(player, weapon, amount, true)
if weapon == 26 then
- if not sawnoffAntiAbuse[source] then
- setControlState (source, "aim_weapon", false)
- setControlState (source, "fire", false)
- toggleControl (source, "fire", false)
- reloadPedWeapon (source)
- sawnoffAntiAbuse[source] = setTimer (function(source)
- if not source then return end
- toggleControl (source, "fire", true)
- sawnoffAntiAbuse[source] = nil
- end, 3000, 1, source)
+ if not sawnoffAntiAbuse[player] then
+ setControlState(player, "aim_weapon", false)
+ setControlState(player, "fire", false)
+ toggleControl(player, "fire", false)
+ reloadPedWeapon(player)
+ sawnoffAntiAbuse[player] = setTimer(function(player)
+ if not player then return end
+ toggleControl(player, "fire", true)
+ sawnoffAntiAbuse[player] = nil
+ end, 3000, 1, player)
end
- end
+ end
end
end
+
function giveMeVehicles(vehID)
- if not isElement(source) then return end
- local element = getPedOccupiedVehicle(source) or source
+ local player = client
+ if not isElement(player) then return end
+ local element = getPedOccupiedVehicle(player) or player
local px,py,pz = getElementPosition(element)
local _,_,prot = getElementRotation(element)
local posVector = Vector3(px,py,pz+2)
local rotVector = Vector3(0,0,prot)
local vehMatrix = Matrix(posVector,rotVector)
- local vehicleList = g_PlayerData[source].vehicles
+ local vehicleList = g_PlayerData[player].vehicles
if not vehID then return end
if not table.find(getOption('vehicles.disallowed'), vehID) then
if #vehicleList >= getOption('vehicles.maxperplayer') then unloadVehicle(vehicleList[1]) end
local vehPos = posVector+vehMatrix.right*3
local vehicle = Vehicle(vehID, vehPos, rotVector) or false
if vehicle then
- vehicle.interior = source.interior
- vehicle.dimension = source.dimension
+ vehicle.interior = player.interior
+ vehicle.dimension = player.dimension
if vehicle.vehicleType == "Bike" then vehicle.velocity = Vector3(0,0,-0.01) end
table.insert(vehicleList, vehicle)
- g_VehicleData[vehicle] = { creator = source, timers = {} }
+ g_VehicleData[vehicle] = { creator = player, timers = {} }
if g_Trailers[vehID] then
if getOption('vehicles.maxidletime') >= 0 then
if getOption('vehicles.idleexplode') then
@@ -407,10 +410,13 @@ function giveMeVehicles(vehID)
end
end
else
- errMsg(getVehicleNameFromModel(vehID):gsub('y$', 'ie') .. 's are not allowed', source)
+ errMsg(getVehicleNameFromModel(vehID):gsub('y$', 'ie') .. 's are not allowed', player)
end
end
+-- [END] Remote Player Call Functions --
+----------------------------------------
+
_setPlayerGravity = setPedGravity
function setPedGravity(player, grav)
if grav < getOption('gravity.min') then
@@ -602,8 +608,8 @@ addEventHandler('onServerCall', resourceRoot,
-- Custom check made to intercept the jetpack on custom gravity
if fnInfo and type(fnInfo) ~= "boolean" and tostring(fnInfo.option) == "jetpack" then
- if tonumber(("%.3f"):format(getPedGravity(source))) ~= 0.008 then
- errMsg("* You may use jetpack only if the gravity is set to 0.008", source)
+ if tonumber(("%.3f"):format(getPedGravity(client))) ~= 0.008 then
+ errMsg("* You may use jetpack only if the gravity is set to 0.008", client)
return
end
end
@@ -613,11 +619,24 @@ addEventHandler('onServerCall', resourceRoot,
for i,pathpart in ipairs(fnName:split('.')) do
fn = fn[pathpart]
end
+ if not g_RPCFunctionsValidation[fnName] then
+ outputDebugString('Function ' ..
+ tostring(fnName) ..
+ ' is missing from the validation list. Please add this one to g_RPCFunctionsValidation.', 1)
+ return
+ end
+ if not g_RPCFunctionsValidation[fnName](...) then
+ errMsg('Something went wrong.', client)
+ -- outputDebugString(
+ -- 'Invalid parameters has been provided for function `' ..
+ -- tostring(fnName) .. '` by user: ' .. getPlayerSerial(client) .. ' It can be a bug.', 1)
+ return
+ end
fn(...)
elseif type(fnInfo) == 'table' then
- errMsg(fnInfo.descr .. ' is not allowed', source)
+ errMsg(fnInfo.descr .. ' is not allowed', client)
end
- end
+ end, false
)
function clientCall(player, fnName, ...)
diff --git a/[gameplay]/freeroam/meta.xml b/[gameplay]/freeroam/meta.xml
index fc3db5a48..a7035f723 100644
--- a/[gameplay]/freeroam/meta.xml
+++ b/[gameplay]/freeroam/meta.xml
@@ -13,6 +13,7 @@
+
diff --git a/[gameplay]/freeroam/remote_player_call_validation_s.lua b/[gameplay]/freeroam/remote_player_call_validation_s.lua
new file mode 100644
index 000000000..88d529878
--- /dev/null
+++ b/[gameplay]/freeroam/remote_player_call_validation_s.lua
@@ -0,0 +1,147 @@
+g_RPCFunctionsValidation = {
+ addPedClothes = function(thePlayer, clothesTexture, clothesModel, clothesType, ...)
+ if client ~= thePlayer then return false end
+ if type(clothesTexture) ~= "string" then return false end
+ if type(clothesModel) ~= "string" then return false end
+ if type(clothesType) ~= "number" then return false end
+ if (#{ ... } > 0) then return false end
+ return true
+ end,
+ addVehicleUpgrade = function(theVehicle, upgrade, ...)
+ if getPedOccupiedVehicle(client) ~= theVehicle then return false end
+ if type(upgrade) ~= "number" and type(upgrade) ~= "string" then return false end
+ if (#{ ... } > 0) then return false end
+ return true
+ end,
+ fadeVehiclePassengersCamera = function(toggle, ...)
+ if type(toggle) ~= "boolean" then return false end
+ if (#{ ... } > 0) then return false end
+ return true
+ end,
+ fixVehicle = function(theVehicle, ...)
+ if getPedOccupiedVehicle(client) ~= theVehicle then return false end
+ if (#{ ... } > 0) then return false end
+ return true
+ end,
+ giveMeVehicles = function(vehicleId, ...)
+ if type(vehicleId) ~= "number" then return false end
+ if (#{ ... } > 0) then return false end
+ return true
+ end,
+ giveMeWeapon = function(weapon, amount, ...)
+ if type(weapon) ~= "number" and type(weapon) ~= "string" then return false end
+ if type(amount) ~= "number" then return false end
+ if (#{ ... } > 0) then return false end
+ return true
+ end,
+ removePedClothes = function(thePlayer, clothesType, ...)
+ if client ~= thePlayer then return false end
+ if type(clothesType) ~= "number" then return false end
+ if (#{ ... } > 0) then return false end
+ return true
+ end,
+ removePedFromVehicle = function(thePlayer, ...)
+ if client ~= thePlayer then return false end
+ if (#{ ... } > 0) then return false end
+ return true
+ end,
+ removeVehicleUpgrade = function(theVehicle, upgrade, ...)
+ if getPedOccupiedVehicle(client) ~= theVehicle then return false end
+ if type(upgrade) ~= "number" then return false end
+ if (#{ ... } > 0) then return false end
+ return true
+ end,
+ setElementAlpha = function(thePlayer, alpha, ...)
+ if client ~= thePlayer then return false end
+ if type(alpha) ~= "number" then return false end
+ if (#{ ... } > 0) then return false end
+ return true
+ end,
+ setElementInterior = function(thePlayerOrVehicle, interior, ...)
+ if client ~= thePlayerOrVehicle and thePlayerOrVehicle ~= getPedOccupiedVehicle(client) then return false end
+ if type(tonumber(interior)) ~= "number" then return false end
+ if (#{ ... } > 0) then return false end
+ return true
+ end,
+ setCameraInterior = function (thePlayer, interior, ...)
+ if client ~= thePlayer then return false end
+ if type(tonumber(interior)) ~= "number" then return false end
+ if (#{ ... } > 0) then return false end
+ return true
+ end,
+ setMySkin = function(skinId, ...)
+ if type(skinId) ~= "number" then return false end
+ if (#{ ... } > 0) then return false end
+ return true
+ end,
+ setPedAnimation = function(thePlayer, block, anim, time, loop, updatePosition, ...)
+ if client ~= thePlayer then return false end
+ if (block == false and #{ anim, time, loop, updatePosition, ... } == 0) then return true end
+ if block ~= nil and type(block) ~= "string" then return false end
+ if anim ~= nil and type(anim) ~= "string" then return false end
+ if time ~= nil and type(time) ~= "number" then return false end
+ if loop ~= nil and type(loop) ~= "boolean" then return false end
+ if updatePosition ~= nil and type(updatePosition) ~= "boolean" then return false end
+ if (#{ ... } > 0) then return false end
+ return true
+ end,
+ setPedFightingStyle = function(thePlayer, style, ...)
+ if client ~= thePlayer then return false end
+ if type(style) ~= "number" then return false end
+ if (#{ ... } > 0) then return false end
+ return true
+ end,
+ setPedGravity = function(thePlayer, gravity, ...)
+ if client ~= thePlayer then return false end
+ if type(gravity) ~= "number" then return false end
+ if (#{ ... } > 0) then return false end
+ return true
+ end,
+ setPedStat = function(thePlayer, stat, value, ...)
+ if client ~= thePlayer then return false end
+ if type(stat) ~= "number" then return false end
+ if type(value) ~= "number" then return false end
+ if (#{ ... } > 0) then return false end
+ return true
+ end,
+ setPedWearingJetpack = function(thePlayer, toggle, ...)
+ if client ~= thePlayer then return false end
+ if type(toggle) ~= "boolean" then return false end
+ if (#{ ... } > 0) then return false end
+ return true
+ end,
+ setVehicleColor = function(theVehicle, r1, g1, b1, r2, g2, b2, r3, g3, b3, r4, g4, b4, ...)
+ if getPedOccupiedVehicle(client) ~= theVehicle then return false end
+ if r1 and (type(r1) ~= "number" or type(g1) ~= "number" or type(b1) ~= "number") then return false end
+ -- Starting the next look up at g2, because for the Palette format which uses 4 arguments.
+ if g2 and (type(r2) ~= "number" or type(g2) ~= "number" or type(b2) ~= "number") then return false end
+ if r3 and (type(r3) ~= "number" or type(g3) ~= "number" or type(b3) ~= "number") then return false end
+ if r4 and (type(r4) ~= "number" or type(g4) ~= "number" or type(b4) ~= "number") then return false end
+ if (#{ ... } > 0) then return false end
+ return true
+ end,
+ setVehicleHeadLightColor = function(theVehicle, r, g, b, ...)
+ if getPedOccupiedVehicle(client) ~= theVehicle then return false end
+ if type(r) ~= "number" or type(g) ~= "number" or type(b) ~= "number" then return false end
+ if (#{ ... } > 0) then return false end
+ return true
+ end,
+ setVehicleOverrideLights = function(theVehicle, value, ...)
+ if getPedOccupiedVehicle(client) ~= theVehicle then return false end
+ if type(value) ~= "number" then return false end
+ if (#{ ... } > 0) then return false end
+ return true
+ end,
+ setVehiclePaintjob = function(theVehicle, value, ...)
+ if getPedOccupiedVehicle(client) ~= theVehicle then return false end
+ if type(value) ~= "number" then return false end
+ if (#{ ... } > 0) then return false end
+ return true
+ end,
+ warpMeIntoVehicle = function(theVehicle, ...)
+ if not isElement(theVehicle) then return false end
+ if getElementType(theVehicle) ~= "vehicle" then return false end
+ if (#{ ... } > 0) then return false end
+ return true
+ end
+}