[Release] SS-RunCode - Run Code Locally or Server-Side Via Chat!

Since I hail from the good old days of Multi Theft Auto: San Andreas, there was this one particular resource that was very useful to me whilst developing resources. And that resource was called runcode.

This release is more or less that, except ported over to FiveM. So majority of the credit goes to the MTA development team for making the original resource.

What Is SS-RunCode?

SS-RunCode is a resource that lets you execute code directly via the chat, this is particularly useful for quickly testing functions and running short snippets of code without having to use a resource (well, other than this one heh).

It is strongly recommended you either tweak the default chat resource or use your own custom one, as the default one is an absolute bother to write longer messages with.

I Can Has Screenshots?

No, but you can has a video showcasing it in action. Showing usage of both commands crun and srun, along with an unintentional typo showing that it’s capable of outputting errors.

https://streamable.com/gc8ip

Usage

There are 2 commands that you need to be aware of, those are as follows:

/crun - This will run the code on the client, see it as a short version of clientrun.
/srun - This will run the code on the server, see it as a short version of serverrun.

Examples

These are examples I have included in the code, but I will post them here for you convenience and at my inconvenience;

Client-Side
/crun SetVehicleCustomPrimaryColour(GetVehiclePedIsUsing(GetPlayerPed(-1)), 255, 70, 0)
/crun SetVehicleFixed(GetVehiclePedIsUsing(GetPlayerPed(-1)))
/crun GetEntityCoords(GetPlayerPed(-1))

Server-Side
/srun TriggerClientEvent(“chatMessage”, -1, “[SS-RunCode]”, {0, 187, 0}, “Hello this was sent to everyone via SRun!”)
/srun TriggerClientEvent(“chatMessage”, 1, “[SS-RunCode]”, {0, 187, 0}, “Hello this was sent to you via SRun!”)

Planned Features

As of now I don’t really have any planned features. One I did have in mind, though, was to implement my own custom chat that is bound to a separate keybind and that isn’t an absolute headache to work with.

I doubt I will go through the effort to add some permission system to this, I will leave that up to you.

So please, do use this with caution as anyone can use these commands.

Known Issues

None as of now, but please do let me know if you find any.

Download

11 Likes

This is a very very very powerful release! Thank you!

Thank you man, this is very usefull to test things before codding. But I will try to modify the code to do a version without the chat and send you the result if you want :wink:

Here is the modified version. There are new features :slight_smile:

  1. Press “F6” and type your code.
  2. Choose your target (Client, All clients, Server, Server + Client, Server + All clients) and the press ENTER.
  3. It will execute the code on the designated target.

Please do not send empty script.

sys_runcode.rar (4.0 KB) The author of this post can re-upload my modified version if he want.

From Belgium with :heart:

2 Likes

this is a small modification of thegamerrespow’s version.

This edit allows the script to use essentialsmode permission levels.
The current setup in the code requires the user to be permission level 4.

client.lua

function startCodding()
    DisplayOnscreenKeyboard(1, "", "", "", "", "", "", 255)
    while (UpdateOnscreenKeyboard() == 0) do
        DisableAllControlActions(0);
        Wait(0);
    end
    if (GetOnscreenKeyboardResult()) then
        script = GetOnscreenKeyboardResult()
        OpenMenu()
    end
end
RegisterNetEvent("crun:startcoding")
AddEventHandler("crun:startcoding", function()

startCodding()

end)
Citizen.CreateThread(function()

	while true do
		Citizen.Wait(0)
        if IsControlJustPressed(1,167) then
            TriggerServerEvent("crun:admincheck")
        end
	end
end)

runcode_menu = {
	opened = false,
	title = "",
	currentmenu = "main",
	lastmenu = nil,
	currentpos = nil,
	selectedbutton = 0,
	marker = { r = 0, g = 155, b = 255, a = 200, type = 1 }, -- ???
	menu = {
		x = 0.11,
		y = 0.25,
		width = 0.2,
		height = 0.04,
		buttons = 10,
		from = 1,
		to = 10,
		scale = 0.4,
		font = 0,
		["main"] = {
			title = "SEND TO",
			name = "main",
			buttons = {
				{name = "Client"},
				{name = "All clients"},
                {name = "Server"},
                {name = "Server + Client"},
                {name = "Server + All clients"},
			}
		},
	}
}

function LocalPed()
    return GetPlayerPed(-1)
end
-------------------------------------------------
----------------CONFIG SELECTION----------------
-------------------------------------------------
function drawNotification(text)
	SetNotificationTextEntry("STRING")
	AddTextComponentString(text)
	DrawNotification(false, false)
end

function ButtonSelected(button)
	local ped = GetPlayerPed(-1)
	local this = runcode_menu.currentmenu
	if this == "main" then
        if button.name == "Client" then
            TriggerServerEvent("runcode:execute", 1, script) -- CLIENT
            drawNotification("Code sent to you !")
            CloseMenu()
        elseif button.name == "All clients" then
            TriggerServerEvent("runcode:execute", 2, script) -- ALL CLIENTS
            drawNotification("Code sent to everybody !")
            CloseMenu()
        elseif button.name == "Server" then
            TriggerServerEvent("runcode:execute", 3, script) -- SERVER
            drawNotification("Code sent to the server !")
            CloseMenu()
        elseif button.name == "Server + Client" then
            TriggerServerEvent("runcode:execute", 4, script) -- SERVER + CLIENT
            drawNotification("Code sent to the server and you !")
            CloseMenu()
        elseif button.name == "Server + All clients" then
            TriggerServerEvent("runcode:execute", 5, script) -- SERVER + ALL CLIENTS
            drawNotification("Code sent everywhere !")
            CloseMenu()
        end
		
	end
end
-------------------------------------------------
------------------DRAW NOTIFY--------------------
-------------------------------------------------
function drawNotification(text)
	SetNotificationTextEntry("STRING")
	AddTextComponentString(text)
	DrawNotification(false, false)
end
-------------------------------------------------
------------------DRAW TITLE MENU----------------
-------------------------------------------------
function drawMenuTitle(txt,x,y)
local menu = runcode_menu.menu
	SetTextFont(2)
	SetTextProportional(0)
	SetTextScale(0.5, 0.5)
	SetTextColour(255, 255, 255, 255)
	SetTextEntry("STRING")
	AddTextComponentString(txt)
	DrawRect(x,y,menu.width,menu.height,244,122,66,150)
	DrawText(x - menu.width/2 + 0.005, y - menu.height/2 + 0.0028)
end
-------------------------------------------------
------------------DRAW MENU BOUTON---------------
-------------------------------------------------
function drawMenuButton(button,x,y,selected)
	local menu = runcode_menu.menu
	SetTextFont(menu.font)
	SetTextProportional(0)
	SetTextScale(menu.scale, menu.scale)
	if selected then
		SetTextColour(0, 0, 0, 255)
	else
		SetTextColour(255, 255, 255, 255)
	end
	SetTextCentre(0)
	SetTextEntry("STRING")
	AddTextComponentString(button.name)
	if selected then
		DrawRect(x,y,menu.width,menu.height,255,255,255,255)
	else
		DrawRect(x,y,menu.width,menu.height,0,0,0,150)
	end
	DrawText(x - menu.width/2 + 0.005, y - menu.height/2 + 0.0028)
end
-------------------------------------------------
------------------DRAW MENU INFO-----------------
-------------------------------------------------
function drawMenuInfo(text)
	local menu = runcode_menu.menu
	SetTextFont(menu.font)
	SetTextProportional(0)
	SetTextScale(0.45, 0.45)
	SetTextColour(255, 255, 255, 255)
	SetTextCentre(0)
	SetTextEntry("STRING")
	AddTextComponentString(text)
	DrawRect(0.675, 0.95,0.65,0.050,0,0,0,150)
	DrawText(0.365, 0.934)
end
-------------------------------------------------
----------------DRAW MENU DROIT------------------
-------------------------------------------------
function drawMenuRight(txt,x,y,selected)
	local menu = runcode_menu.menu
	SetTextFont(menu.font)
	SetTextProportional(0)
	SetTextScale(menu.scale, menu.scale)
	if selected then
		SetTextColour(0, 0, 0, 255)
	else
		SetTextColour(255, 255, 255, 255)
	end
	SetTextCentre(0)
	SetTextEntry("STRING")
	AddTextComponentString(txt)
	DrawText(x + menu.width/2 - 0.03, y - menu.height/2 + 0.0028)
end
-------------------------------------------------
-------------------DRAW TEXT---------------------
-------------------------------------------------
function drawTxt(text,font,centre,x,y,scale,r,g,b,a)
	SetTextFont(font)
	SetTextProportional(0)
	SetTextScale(scale, scale)
	SetTextColour(r, g, b, a)
	SetTextDropShadow(0, 0, 0, 0,255)
	SetTextEdge(1, 0, 0, 0, 255)
	SetTextDropShadow()
	SetTextOutline()
	SetTextCentre(centre)
	SetTextEntry("STRING")
	AddTextComponentString(text)
	DrawText(x , y)
end
-------------------------------------------------
----------------CONFIG BACK MENU-----------------
-------------------------------------------------
function Back()
	if backlock then
		return
	end
	backlock = true
	if runcode_menu.currentmenu == "main" then
		CloseMenu()
	end
end
-------------------------------------------------
----------------FONCTION ???????-----------------
-------------------------------------------------
function f(n)
return n + 0.0001
end

function LocalPed()
return GetPlayerPed(-1)
end

function try(f, catch_f)
local status, exception = pcall(f)
if not status then
catch_f(exception)
end
end
function firstToUpper(str)
    return (str:gsub("^%l", string.upper))
end

function tablelength(T)
  local count = 0
  for _ in pairs(T) do count = count + 1 end
  return count
end

function round(num, idp)
  if idp and idp>0 then
    local mult = 10^idp
    return math.floor(num * mult + 0.5) / mult
  end
  return math.floor(num + 0.5)
end

function stringstarts(String,Start)
   return string.sub(String,1,string.len(Start))==Start
end
-------------------------------------------------
----------------FONCTION OPEN--------------------
-------------------------------------------------
function OpenMenu() --OpenCreator
	boughtcar = false
	runcode_menu.currentmenu = "main"
	runcode_menu.opened = true
	runcode_menu.selectedbutton = 0
end
-------------------------------------------------
----------------FONCTION CLOSE-------------------
-------------------------------------------------
function CloseMenu() -- Close Creator
	Citizen.CreateThread(function()
        runcode_menu.opened = false
		runcode_menu.menu.from = 1
		runcode_menu.menu.to = 10
	end)
end
-------------------------------------------------
----------------FONCTION OPEN MENU---------------
-------------------------------------------------
function DisplayHelpText(str)
	SetTextComponentFormat("STRING")
	AddTextComponentString(str)
	DisplayHelpTextFromStringLabel(0, 0, 1, -1)
end

local backlock = false
Citizen.CreateThread(function()
	local x = 406.281
	local y = -1644.16
	local z = 29.2919

	while true do
		Citizen.Wait(0)
		if runcode_menu.opened then
			local ped = LocalPed()
			local menu = runcode_menu.menu[runcode_menu.currentmenu]
			drawTxt(runcode_menu.title,1,1,runcode_menu.menu.x,runcode_menu.menu.y,1.0, 255,255,255,255)
			drawMenuTitle(menu.title, runcode_menu.menu.x,runcode_menu.menu.y + 0.08)
			drawTxt(runcode_menu.selectedbutton.."/"..tablelength(menu.buttons),0,0,runcode_menu.menu.x + runcode_menu.menu.width/2 - 0.0385,runcode_menu.menu.y + 0.067,0.4, 255,255,255,255)
			local y = runcode_menu.menu.y + 0.12
			buttoncount = tablelength(menu.buttons)
			local selected = false

			for i,button in pairs(menu.buttons) do
				if i >= runcode_menu.menu.from and i <= runcode_menu.menu.to then

					if i == runcode_menu.selectedbutton then
						selected = true
					else
						selected = false
					end
					drawMenuButton(button,runcode_menu.menu.x,y,selected)
					y = y + 0.04
					if selected and IsControlJustPressed(1,201) then
						ButtonSelected(button)
					end
				end
			end
		end
		if runcode_menu.opened then
			if IsControlJustPressed(1,202) then
				Back()
			end
			if IsControlJustReleased(1,202) then
				backlock = false
			end
			if IsControlJustPressed(1,188) then
				if runcode_menu.selectedbutton > 1 then
					runcode_menu.selectedbutton = runcode_menu.selectedbutton -1
					if buttoncount > 10 and runcode_menu.selectedbutton < runcode_menu.menu.from then
						runcode_menu.menu.from = runcode_menu.menu.from -1
						runcode_menu.menu.to = runcode_menu.menu.to - 1
					end
				end
			end
			if IsControlJustPressed(1,187)then
				if runcode_menu.selectedbutton < buttoncount then
					runcode_menu.selectedbutton = runcode_menu.selectedbutton +1
					if buttoncount > 10 and runcode_menu.selectedbutton > runcode_menu.menu.to then
						runcode_menu.menu.to = runcode_menu.menu.to + 1
						runcode_menu.menu.from = runcode_menu.menu.from + 1
					end
				end
			end
		end

	end
end)

server.lua

RegisterServerEvent("runcode:execute")
AddEventHandler('runcode:execute', function(mode,script)
	if mode == 1 then
		TriggerClientEvent("RunCode:RunStringLocally", source, script)
	elseif	mode == 2 then
		TriggerEvent('es:getPlayers', function(pl)
			for k,v in pairs(pl) do
				TriggerClientEvent("RunCode:RunStringLocally", k, script)
			end
		end)
	elseif	mode == 3 then
		RunString(script, source)
	elseif	mode == 4 then
		TriggerClientEvent("RunCode:RunStringLocally", source, script)
		RunString(script, source)
	elseif	mode == 5 then
		TriggerEvent('es:getPlayers', function(pl)
			for k,v in pairs(pl) do
				TriggerClientEvent("RunCode:RunStringLocally", k, script)
			end
		end)
		RunString(script, source)
	end	
end)
RegisterServerEvent("crun:admincheck")
AddEventHandler('crun:admincheck', function()
	TriggerEvent("es:getPlayerFromId", source, function(user)
		if user.permission_level == 4 then
			TriggerClientEvent("crun:startcoding", source)
		end
	end)
end)
1 Like

How do you disable this? It’s the number one cause of people getting their VPS hijacked, as everyone runs as admin. It’s a HUGE security hole :smiley:

By not adding it in the first place. ‘People’ are clearly adding this resource themselves…

What’s a “powerful” release?