├── rw_draw ├── data.json ├── fxmanifest.lua ├── LICENSE ├── permistions.lua ├── server.lua └── client.lua ├── README.md └── LICENSE /rw_draw/data.json: -------------------------------------------------------------------------------- 1 | [] -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ![chrome](https://github.com/RoyaleWind/RW_DRAW/assets/61204500/5b281e82-2dd1-4669-9669-dd9172acf41f) 4 | 5 | ### Support 6 | Join discord https://discord.gg/B23yY3UMut to get support 7 | 8 | -------------------------------------------------------------------------------- /rw_draw/fxmanifest.lua: -------------------------------------------------------------------------------- 1 | fx_version 'cerulean' 2 | games { 'gta5' } 3 | 4 | author 'RoyaleWind' 5 | description 'RW DRAW' 6 | version '1.2.0' 7 | lua54 'on' 8 | 9 | client_scripts { 10 | 'client.lua', 11 | } 12 | 13 | server_scripts { 14 | 'server.lua', 15 | 'permistions.lua', 16 | } 17 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 RoyaleWind 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /rw_draw/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 RoyaleWind 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /rw_draw/permistions.lua: -------------------------------------------------------------------------------- 1 | PERMS = {} 2 | PERMS.type = "license" ---[PERMISION FILE] 3 | PERMS.data = { 4 | ['license'] = { 5 | ['dkslakfasdasd'] = true, 6 | ['1aaspujepikemfwer141e4dpo1'] = true, 7 | }, 8 | } 9 | --------------------------------------------------- 10 | ---[MAIN] 11 | --------------------------------------------------- 12 | function perms(id) ---[ADD YOUR PERMISION SYSTEM] 13 | if PERMS.type == "custom" then 14 | return perms_custom(id) 15 | elseif PERMS.type == "license" then 16 | return perms_license(id) 17 | else 18 | print('[RW DRAW] THIS PERMISTION TYPE DOES NOT EXIST') 19 | return false 20 | end 21 | end 22 | --------------------------------------------------- 23 | ---[PERMISIONS] 24 | --------------------------------------------------- 25 | ---[CUSTOM] 26 | function perms_custom(id) 27 | return true 28 | end 29 | ---[license] 30 | function perms_license(id) 31 | local perms = false 32 | local id = id 33 | local license = nil 34 | for k,v in pairs(GetPlayerIdentifiers(id))do 35 | if string.sub(v, 1, string.len("license:")) == "license:" then 36 | license = v 37 | license = string.sub(v, string.len("license:") + 1) 38 | end 39 | end 40 | if license ~= nil and PERMS.data['license'][license] then 41 | perms = true 42 | end 43 | return perms 44 | end -------------------------------------------------------------------------------- /rw_draw/server.lua: -------------------------------------------------------------------------------- 1 | --------------------------------------------------- 2 | ---[https://discord.gg/B23yY3UMut] -- SUPPROT 3 | ---[MIT License] 4 | ---[Copyright (c) 2023 RoyaleWind] 5 | --------------------------------------------------- 6 | local Table = {} 7 | local MASTER = {} 8 | local M_INT = 0 9 | --------------------------------------------------- 10 | ---[SETUP] 11 | --------------------------------------------------- 12 | Citizen.CreateThread(function() 13 | Table = load() 14 | if Table ~= nil then 15 | for i, v in pairs(Table) do 16 | M_INT = M_INT + 1 17 | MASTER[M_INT] = {} 18 | MASTER[M_INT] = Table[i] 19 | ---[FIXING VECTORS BECOUSE JSON BREAKS IT] 20 | MASTER[M_INT].tl = vector3(MASTER[M_INT].tl.x,MASTER[M_INT].tl.y,MASTER[M_INT].tl.z) 21 | MASTER[M_INT].tr = vector3(MASTER[M_INT].tr.x,MASTER[M_INT].tr.y,MASTER[M_INT].tr.z) 22 | MASTER[M_INT].bl = vector3(MASTER[M_INT].bl.x,MASTER[M_INT].bl.y,MASTER[M_INT].bl.z) 23 | MASTER[M_INT].br = vector3(MASTER[M_INT].br.x,MASTER[M_INT].br.y,MASTER[M_INT].br.z) 24 | MASTER[M_INT].pos = vector3(MASTER[M_INT].pos.x,MASTER[M_INT].pos.y,MASTER[M_INT].pos.z) 25 | 26 | end 27 | else 28 | save() 29 | end 30 | end) 31 | --------------------------------------------------- 32 | ---[PLAYER] 33 | --------------------------------------------------- 34 | RegisterNetEvent('rw_draw:GetData') 35 | AddEventHandler('rw_draw:GetData', function() 36 | local player = source 37 | local staff = false 38 | while MASTER == nil do 39 | Citizen.Wait(1000) 40 | end 41 | staff = perms(player) 42 | TriggerClientEvent('rw_draw:Initialize',player,MASTER,staff) 43 | end) 44 | 45 | RegisterNetEvent('rw_draw:UpdateImage') 46 | AddEventHandler('rw_draw:UpdateImage', function(texname,url) 47 | local player = source 48 | if perms(player) then 49 | for i, v in pairs(MASTER) do 50 | if texname == v.texname then 51 | MASTER[i].url = url 52 | UpdateImage(i) 53 | end 54 | end 55 | end 56 | end) 57 | 58 | RegisterNetEvent('rw_draw:Remove') 59 | AddEventHandler('rw_draw:Remove', function(texname) 60 | local player = source 61 | if perms(player) then 62 | for i, v in pairs(MASTER) do 63 | if texname == v.texname then 64 | Remove(i) 65 | end 66 | end 67 | end 68 | end) 69 | 70 | RegisterNetEvent('rw_draw:regnew') 71 | AddEventHandler('rw_draw:regnew', function(data) 72 | local player = source 73 | if perms(player) then 74 | M_INT = M_INT + 1 75 | MASTER[M_INT] = data 76 | update(M_INT) 77 | end 78 | end) 79 | 80 | RegisterCommand("draw_dev", function(source, args, rawCommand) 81 | if args[1] ~= nil then 82 | local send = false 83 | local tmp = args[1] 84 | if tmp == "on" then 85 | send = true 86 | else 87 | send = false 88 | end 89 | player = source 90 | if perms(player) and send ~= nil then 91 | TriggerClientEvent('rw_draw:DevMode',-1,send) 92 | end 93 | end 94 | end, false) 95 | --------------------------------------------------- 96 | ---[FUNCTIONS] 97 | --------------------------------------------------- 98 | function update(id) 99 | TriggerClientEvent('rw_draw:NewInit',-1,MASTER[id]) 100 | save() 101 | end 102 | 103 | function UpdateImage(id) 104 | TriggerClientEvent('rw_draw:UpdateImage',-1,MASTER[id].texname,MASTER[id].url) 105 | save() 106 | end 107 | 108 | function Remove(id) 109 | TriggerClientEvent('rw_draw:Remove',-1,MASTER[id].texname) 110 | MASTER[id] = nil 111 | save() 112 | end 113 | --------------------------------------------------- 114 | ---[UTILS] 115 | --------------------------------------------------- 116 | 117 | function playerloaded(id) 118 | DoesEntityExist(GetPlayerPed(id)) 119 | end 120 | 121 | function load() 122 | local loadFile= LoadResourceFile(GetCurrentResourceName(), "./data.json") 123 | return (json.decode(loadFile)) 124 | end 125 | 126 | function save() 127 | SaveResourceFile(GetCurrentResourceName(), "data.json", json.encode(MASTER), -1) 128 | end -------------------------------------------------------------------------------- /rw_draw/client.lua: -------------------------------------------------------------------------------- 1 | --------------------------------------------------- 2 | ---[https://discord.gg/B23yY3UMut] -- SUPPROT 3 | ---[MIT License] 4 | ---[Copyright (c) 2023 RoyaleWind] 5 | --------------------------------------------------- 6 | ---[SETTINGS] 7 | --------------------------------------------------- 8 | local debug = true ---[PRINTS] 9 | local RENDER = 500 ---[RENDER DISTANCE] 10 | local EDIT = 4 ---[EDIT DISTANCE] 11 | -- local Dialog = "rw_dialog" ---[IF YOU HAVE RW_DIALOG USE RW DIALOG] [https://forum.cfx.re/t/rw-dialog/5088577] 12 | local Dialog = "dialog" 13 | --------------------------------------------------- 14 | ---[LOCALS NEED IT FOR THE RW_DRAW] 15 | --------------------------------------------------- 16 | local REGISTRY = {} 17 | local R_INT = 0 18 | local tpm1 = {} 19 | local tpm2 = {} 20 | local draw = false 21 | local cache = {} 22 | local cache_int = 0 23 | local devmode = false 24 | local poster = false 25 | local staff = false 26 | --------------------------------------------------- 27 | ---[SETUP] 28 | --------------------------------------------------- 29 | Citizen.CreateThread(function() 30 | TriggerServerEvent('rw_draw:GetData') 31 | end) 32 | --------------------------------------------------- 33 | ---[CREATE A NEW CANVAS] 34 | --------------------------------------------------- 35 | RegisterCommand("poster", function(source, args, rawCommand) 36 | if not staff then clmsg("INSUFFICIENT PERMISSIONS") return end 37 | if poster then clmsg("ACTION CANCELLED") return end 38 | 39 | poster = true 40 | tpm1 = getray("[1] TOP LEFT") 41 | if tpm1 == nil then clmsg("ACTION CANCELLED") poster = false return end 42 | Citizen.Wait(1000) 43 | draw = true 44 | tpm2 = getray("[2] BOTTOM DOWN") 45 | draw = false 46 | if tpm2 == nil then clmsg("ACTION CANCELLED") poster = false return end 47 | 48 | local key = randomString(4) 49 | ---[STAFF INPOUT] 50 | local data = exports[Dialog]:Create("ENTER URL", 'HTPS') 51 | local url = data.value 52 | if url == nil then clmsg("ACTION CANCELLED") poster = false return end 53 | 54 | local data = exports[Dialog]:Create("TX NAME", 'not use the same name') 55 | local name = data.value 56 | if name == nil then clmsg("ACTION CANCELLED") poster = false return end 57 | 58 | local data = exports[Dialog]:Create("width of url", 'only numbers pls') 59 | local width = tonumber(data.value) 60 | if width == nil then clmsg("ACTION CANCELLED") poster = false return end 61 | 62 | local data = exports[Dialog]:Create("height of url", 'only numbers pls') 63 | local height = tonumber(data.value) 64 | if height == nil then clmsg("ACTION CANCELLED") poster = false return end 65 | --------------------------------------------------- 66 | name = key.."_"..name 67 | cache_int = R_INT + 1 68 | cache[cache_int] = {} 69 | cache[cache_int].url = url 70 | cache[cache_int].width = width 71 | cache[cache_int].height = height 72 | cache[cache_int].dtexname = name.."_d" 73 | cache[cache_int].texname = name 74 | 75 | local topLeft = tpm1 76 | local bottomRight = tpm2 77 | local bottomLeft = vector3(topLeft.x,topLeft.y,bottomRight.z) 78 | local topright = vector3(bottomRight.x,bottomRight.y,topLeft.z) 79 | cache[cache_int].pos = topLeft 80 | cache[cache_int].tl = topLeft 81 | cache[cache_int].tr = topright 82 | cache[cache_int].bl = bottomLeft 83 | cache[cache_int].br = bottomRight 84 | TriggerServerEvent("rw_draw:regnew",cache[cache_int]) 85 | clmsg("NEW POSTER CREATED") 86 | poster = false 87 | -- NewInit(cache[cache_int]) 88 | -- DevUi() 89 | end, false) 90 | --------------------------------------------------- 91 | ---[FILL REGISTRY] 92 | --------------------------------------------------- 93 | function Initialize(data,role) 94 | staff = role 95 | local data = data 96 | for i, v in pairs(data) do 97 | R_INT = R_INT + 1 98 | REGISTRY[R_INT] = {} 99 | REGISTRY[R_INT] = data[i] 100 | REG_CANVAS(R_INT) 101 | end 102 | end 103 | 104 | function NewInit(data) 105 | local data = data 106 | R_INT = R_INT + 1 107 | REGISTRY[R_INT] = {} 108 | REGISTRY[R_INT] = data 109 | REG_CANVAS(R_INT) 110 | end 111 | --------------------------------------------------- 112 | ---[REGISTER NEW CANVAS] 113 | --------------------------------------------------- 114 | function REG_CANVAS(key) 115 | local url = REGISTRY[key].url 116 | local width = REGISTRY[key].width 117 | local height = REGISTRY[key].height 118 | local texuredicname = REGISTRY[key].dtexname 119 | local textureName = REGISTRY[key].texname 120 | ---[LOCALS] 121 | local textureDict = CreateRuntimeTxd(texuredicname) 122 | local duiObj = CreateDui(url, width, height) 123 | REGISTRY[key].duiObj = duiObj 124 | local dui = GetDuiHandle(duiObj) 125 | local tx = CreateRuntimeTextureFromDuiHandle(textureDict, textureName, dui) 126 | 127 | ---[INITIALIZE] 128 | InitializePoster(key) 129 | end 130 | 131 | function InitializePoster(key) 132 | Citizen.CreateThread(function() 133 | clmsg("[PSOTER]:"..key..":INITIATED") 134 | local topLeft = REGISTRY[key].tl 135 | local topright = REGISTRY[key].tr 136 | local bottomLeft = REGISTRY[key].bl 137 | local bottomRight = REGISTRY[key].br 138 | local texuredicname = REGISTRY[key].dtexname 139 | local textureName = REGISTRY[key].texname 140 | ----- 141 | local time = 0 142 | while REGISTRY[key] ~= nil do 143 | local ped = GetPlayerPed(-1) 144 | local playerCoords = GetEntityCoords(ped) 145 | if IsPlayerNear(playerCoords,REGISTRY[key].pos,RENDER) then 146 | time = 0 147 | DrawSpritePoly(bottomRight.x, bottomRight.y, bottomRight.z, topright.x, topright.y, topright.z, topLeft.x, topLeft.y, topLeft.z, 255, 255, 255, 255, texuredicname, textureName, 148 | 1.0, 1.0, 1.0, 149 | 1.0, 0.0, 1.0, 150 | 0.0, 0.0, 1.0) 151 | DrawSpritePoly(topLeft.x, topLeft.y, topLeft.z, bottomLeft.x, bottomLeft.y, bottomLeft.z, bottomRight.x, bottomRight.y, bottomRight.z, 255, 255, 255, 255, texuredicname, textureName, 152 | 0.0, 0.0, 1.0, 153 | 0.0, 1.0, 1.0, 154 | 1.0, 1.0) 155 | else 156 | time = 1000 157 | end 158 | Citizen.Wait(time) 159 | end 160 | end) 161 | end 162 | --------------------------------------------------- 163 | ---[RESET-REMOVE-UPDATE] 164 | --------------------------------------------------- 165 | function UpdateImage(texname,url) 166 | for i, v in pairs(REGISTRY) do 167 | local name = texname 168 | if v.texname == name then 169 | local duiobj = v.duiObj 170 | REGISTRY[i].url = url 171 | SetDuiUrl(duiobj,url) 172 | clmsg("POSTER UPDATE ID:"..name) 173 | end 174 | end 175 | end 176 | 177 | function Remove(texname) 178 | for i, v in pairs(REGISTRY) do 179 | local name = v.texname 180 | if v.texname == name then 181 | local duiobj = v.duiObj 182 | DestroyDui(duiobj) 183 | REGISTRY[i] = nil 184 | clmsg("POSTER DELETED ID:"..name) 185 | end 186 | end 187 | end 188 | 189 | function RESET() 190 | for i, v in pairs(REGISTRY) do 191 | local duiobj = v.duiObj 192 | DestroyDui(duiobj) 193 | end 194 | end 195 | 196 | function DevMode(state) 197 | devmode = state 198 | if devmode then 199 | DevUi() 200 | end 201 | end 202 | --------------------------------------------------- 203 | ---[UTILS] 204 | --------------------------------------------------- 205 | function clmsg(data) 206 | if debug then 207 | print(data) 208 | end 209 | end 210 | 211 | function IsPlayerNear(playerCoords, vector, distance) 212 | -- print(json.encode( playerCoords)) 213 | -- print(json.encode( vector)) 214 | 215 | local playerDistance = GetDistanceBetweenCoords(playerCoords,vector,true) 216 | return playerDistance <= distance 217 | end 218 | 219 | function RotationToDirection(rotation) 220 | local adjustedRotation = 221 | { 222 | x = (math.pi / 180) * rotation.x, 223 | y = (math.pi / 180) * rotation.y, 224 | z = (math.pi / 180) * rotation.z 225 | } 226 | local direction = 227 | { 228 | x = -math.sin(adjustedRotation.z) * math.abs(math.cos(adjustedRotation.x)), 229 | y = math.cos(adjustedRotation.z) * math.abs(math.cos(adjustedRotation.x)), 230 | z = math.sin(adjustedRotation.x) 231 | } 232 | return direction 233 | end 234 | 235 | function RayCastGamePlayCamera(distance) 236 | local cameraRotation = GetGameplayCamRot() 237 | local cameraCoord = GetGameplayCamCoord() 238 | local direction = RotationToDirection(cameraRotation) 239 | local destination = 240 | { 241 | x = cameraCoord.x + direction.x * distance, 242 | y = cameraCoord.y + direction.y * distance, 243 | z = cameraCoord.z + direction.z * distance 244 | } 245 | local a, b, c, d, e = GetShapeTestResult(StartShapeTestRay(cameraCoord.x, cameraCoord.y, cameraCoord.z, destination.x, destination.y, destination.z, -1, PlayerPedId(), 0)) 246 | return b, c, e 247 | end 248 | 249 | function Draw2DText(content, font, colour, scale, x, y) 250 | SetTextFont(font) 251 | SetTextScale(scale, scale) 252 | SetTextColour(colour[1],colour[2],colour[3], 255) 253 | SetTextEntry("STRING") 254 | SetTextDropShadow(0, 0, 0, 0,255) 255 | SetTextDropShadow() 256 | SetTextEdge(4, 0, 0, 0, 255) 257 | SetTextOutline() 258 | AddTextComponentString(content) 259 | DrawText(x, y) 260 | end 261 | 262 | function getray(id) 263 | local run = true 264 | while run do 265 | local Wait = 5 266 | local color = {r = 0, g = 255, b = 0, a = 200} 267 | local position = GetEntityCoords(PlayerPedId()) 268 | local hit, coords, entity = RayCastGamePlayCamera(1000.0) 269 | Draw2DText('Raycast Coords: ' .. coords.x .. ' ' .. coords.y .. ' ' .. coords.z, 4, {255, 255, 255}, 0.4, 0.55, 0.650) 270 | Draw2DText('Press ~g~E ~w~to POSITION : '..id, 4, {255, 255, 255}, 0.4, 0.55, 0.650 + 0.025) 271 | Draw2DText('Press ~r~DEL ~w~to CANCEL ', 4, {255, 255, 255}, 0.4, 0.55, 0.650 + 0.050) 272 | DrawMarker(28, coords.x, coords.y, coords.z, 0.0, 0.0, 0.0, 0.0, 180.0, 0.0, 0.1, 0.1, 0.1, color.r, color.g, color.b, color.a, false, true, 2, nil, nil, false) 273 | if draw then 274 | local topLeft = tpm1 275 | local bottomRight = coords 276 | local bottomLeft = vector3(topLeft.x,topLeft.y,bottomRight.z) 277 | local topright = vector3(bottomRight.x,bottomRight.y,topLeft.z) 278 | 279 | DrawMarker(28, topLeft.x, topLeft.y, topLeft.z, 0.0, 0.0, 0.0, 0.0, 180.0, 0.0, 0.1, 0.1, 0.1, color.r, color.g, color.b, color.a, false, true, 2, nil, nil, false) 280 | 281 | DrawPoly(bottomRight,topright,topLeft,0,0,255,200) 282 | DrawPoly(topLeft,bottomLeft,bottomRight,0,0,255,200) 283 | end 284 | if IsControlJustReleased(0, 38) then 285 | run = false 286 | return(coords) 287 | end 288 | if IsControlJustReleased(0, 178) then ---[DEL CANCEL] 289 | run = false 290 | return(nil) 291 | end 292 | Citizen.Wait(Wait) 293 | end 294 | end 295 | 296 | function DevUi() 297 | Citizen.CreateThread(function() 298 | clmsg("DEVELOPMENT MODE: ENABLED") 299 | local time = 0 300 | local found = false 301 | while devmode do 302 | local ped = GetPlayerPed(-1) 303 | local playerCoords = GetEntityCoords(ped) 304 | for i, v in pairs(REGISTRY) do 305 | if IsPlayerNear(playerCoords,v.pos,EDIT) then 306 | DrawMarker(28, v.pos.x, v.pos.y, v.pos.z, 0.0, 0.0, 0.0, 0.0, 180.0, 0.0, 0.1, 0.1, 0.1, 0, 255, 0, 255, false, true, 2, nil, nil, false) 307 | Draw2DText('Press ~r~ DEL ~w~to DELETE : ', 4, {255, 255, 255}, 0.4, 0.55, 0.600) 308 | Draw2DText('Press ~g~ E ~w~to EDIT : ', 4, {255, 255, 255}, 0.4, 0.55, 0.620) 309 | if IsControlJustReleased(0, 51) then ---[E EDIT] 310 | local data = exports[Dialog]:Create("NEW URL", 'ENTER HTTPS') 311 | local amount = data.value 312 | if amount then 313 | TriggerServerEvent("rw_draw:UpdateImage",v.texname,amount) 314 | time = 1000 315 | end 316 | end 317 | if IsControlJustReleased(0, 178) then ---[DEL DELETE] 318 | if exports[Dialog]:Decision("ARE YOU SURE YOU WANT TO DELETE?", 'THIS CANVAS', '', 'YES', 'NO').action == 'submit' then 319 | TriggerServerEvent("rw_draw:Remove",v.texname) 320 | time = 1000 321 | else 322 | clmsg('[ACTION CANCELLATION NOTICE]') 323 | end 324 | end 325 | end 326 | end 327 | Citizen.Wait(time) 328 | if time ~= 0 then 329 | time = 0 330 | end 331 | end 332 | clmsg("DEVELOPMENT MODE: DISABLED") 333 | end) 334 | end 335 | 336 | function randomString(length) 337 | local chars = {} 338 | for i = 1, length do 339 | chars[i] = string.char(math.random(65, 90)) 340 | end 341 | return table.concat(chars) 342 | end 343 | --------------------------------------------------- 344 | ---[EVENTS] 345 | --------------------------------------------------- 346 | AddEventHandler('onResourceStop', function(resourceName) 347 | if (GetCurrentResourceName() ~= resourceName) then 348 | return 349 | end 350 | RESET() 351 | end) 352 | RegisterNetEvent('rw_draw:Initialize', Initialize) ---[data] 353 | RegisterNetEvent('rw_draw:NewInit', NewInit) ---[data] 354 | RegisterNetEvent('rw_draw:Remove', Remove) ---[texname] 355 | RegisterNetEvent('rw_draw:UpdateImage', UpdateImage) ---[texname,url] 356 | RegisterNetEvent('rw_draw:DevMode', DevMode) ---[state] --------------------------------------------------------------------------------