CHEATS GUIs SCRIPTS MAPS TUTORIALS SOUNDS EFFECTS TOOLS SERVERS SKINS TEXTURES MODELS PLUGINS MODS
 
Remove ads!
Rating
Based on GVME Community!
Rating:


Your rating: N/A
Total votes: 0

You cannot rating yet!
You can rate anything - when you add rating to a submission your vote determines its success or failure.

To vote on this submission
register or login

You cannot add to Favorites!
Total Favorites

You cannot say thanks!
You must register or login

Details
More informations about this submission!
Release: Final
Version: v2
Development Informations
1.0 & 2.0 versions

Statistics
Scores and popularity
Views: 8502
Downloads: 1593
Feedback: 0

vRP Framework Fivem

Share: F F F F F F F
FiveM RP addon/framework
  Added by: Tatu Eugen
Author(s):
ImagicTheCat
  Category: Grand Theft Auto: V > FiveM
  Tags: vrp fivem framework
Attached Image
This is vRP 2, the second major version of vRP. It aims to have less overhead and a more straightforward and structured approach using OOP. This will probably be the last major version, vRP based resources can be updated for vRP 2 using the extension system.

Download page:
  • v2.0 vRP_fivem.zip
  • v1.0 vRP_1.0_vrpex.zip

Features
  • basic admin tools (kick,ban,whitelist), groups/permissions, languages, identification system (persistent user id for database storage), user/character/server/global custom data key/value
  • player state (survival vitals, weapons, player appearance, position)
  • player identity/phone/aptitudes (education/exp), emotes, business system / money (wallet/bank), homes
  • cloakrooms (uniform for jobs), basic police (PC, check, I.D., handcuff, jails, seize weapons/items), basic emergency (coma, reanimate)
  • inventory (with custom item definition, parametric items), chests (vehicle trunks), transformer (harvest, process, produce) (illegal informer)
  • basic implementations: ATM, market, shops, skinshop, garage
  • GUI (dynamic menu, progress bars, prompt), map entities (blip, markers), areas (enter/leave callbacks)
  • database MySQL "driver" system to interface to any MySQL resources
  • OOP design, more structured code and less overhead
  • proxy for easy inter-resource developement, tunnel for easy server/clients communication


Documentation:
Concepts
OOP
vRP 2 Object-Oriented Programming uses the Luaoop library.

ℹ️
By using OOP, instead of loading resources communicating with vRP through Proxy, extensions can directly be loaded into the vRP resource context. Each extension keeps its data and is able to access other extensions data and methods, making extending vRP easier, more powerful (you can access stuff even if not exposed) and with less overhead.
Extension
An extension is a class extending vRP. Two versions of an extension (same name) can be loaded server-side and client-side.

local MyExt = class("MyExt", vRP.Extension)
Loaded extensions are accessibles through the vRP instance:

vRP.EXT.MyExt:test()
💡
You can see how an extension is made by looking at the code of vRP modules or https://github.com/ImagicTheCat/v...ic-mission.
User
Extensions can extend User properties/methods with a User class (constructor is called).

⚠️
To not conflict with other extensions, make sure the added properties and methods have a very specific name or prefix.
MyExt.User = class("User")
Event
Extensions can listen to global events by defining methods in the event table.

MyExt.event = {}

function MyExt.event:playerSpawn(user, first_spawn)
end
ℹ️
Events marked with (sync) in the documentation may be called using vRP:triggerEventSync which will wait for the listeners to complete, meaning that listeners must return (mostly in a short time frame) in order to let the execution continue normally.
Proxy and Tunnel
Extensions can listen to proxy/tunnel calls by defining methods in the proxy or tunnel table.

MyExt.proxy = {}
function MyExt.proxy:getInfo()
end

-- client-side
MyExt.tunnel = {}
function MyExt.tunnel:test()
end
The proxy interface generated will be accessible from other resources like this:

local my_ext = Proxy.getInterface("vRP.EXT.MyExt")
local info = my_ext.getInfo()
❗
Extensions don’t need/should not use proxy between them.
The tunnel is accessible (from the client-side or server-side extension) like this:

-- server-side
function MyExt.event:playerSpawn(user, first_spawn)
self.remote._test(user.source)
end

-- client-side
function MyExt.event:playerDeath()
self.remote._test()
end
DB driver
A DB driver is a class handling MySQL queries. When the vRP MySQL API is used, the DB driver methods are called to process the queries. If the DB driver is not loaded yet, queries will be cached until loaded.

Data
vRP provides basic methods to store custom binary data in the database. A string key is associated to a binary value (ex: a Lua string). The key is a VARCHAR(100) and the value a BLOB (probably 65535 bytes).

global
GData

per server
SData

per user
UData

per character
CData

🔥
vRP core tables, as core files, should not be modified for the same reasons. New tables and queries should be created if the data system is not powerful enough.
Multi-server and character
vRP 2 has multi-server and multi-character support. Each server has a string identifier.

⚠️
Players can use another character after spawned, so extensions should properly handle character load/unload events and check if the character is ready.
Proxy and Tunnel
The proxy library is used to call other resources functions through a proxy event.

The idea behind tunnel is to easily access any declared server function from any client resource, and to access any declared client function from any server resource.

💡
Good practice is to get the interface once and set it as a global, if you want to get multiple times the same interface from the same resource, you need to specify a unique identifier (the name of the resource + a unique id for each one).
ℹ️
Tunnel and Proxy are blocking calls in the current coroutine until the values are returned, to bypass this behaviour, especially for the Tunnel to optimize speed (ping latency of each call), use as prefix for the function name (Proxy/Tunnel interfaces should not have functions starting with ). This will discard the returned values, but if you still need them, you can make normal calls in a new Citizen thread with Citizen.CreateThreadNow or async to have non-blocking code.
⚠️
Also remember that Citizen event handlers (used by Proxy and Tunnel) may not work while loading the resource, to use the Proxy at loading time, you will need to delay it with Citizen.CreateThread or a SetTimeout.
Asynchronous
vRP 2 extensively uses asynchronous tasks in a transparent way using coroutines, some functions may not return immediately (or never).

Loading script
To use vRP 2, a script must be loaded in the vRP resource context of a specific side.

-- include `@vrp/lib/utils.lua` in `__resource.lua` (for the targeted side)

local Proxy = module("vrp", "lib/Proxy")
local vRP = Proxy.getInterface("vRP")

vRP.loadScript("my_resource", "vrp") -- load vrp.lua
The content of vrp.lua is now executed in the vRP context and can now use the API.

ℹ️
vRP.loadScript() has the same behavior as module(), but executed in the vRP context.
General API
utils
lib/utils.lua defines some useful globals.

-- side detection
SERVER -- boolean
CLIENT -- boolean

-- load a lua resource file as module (for a specific side)
-- rsc: resource name
-- path: lua file path without extension
module(rsc, path)

class -- Luaoop class

-- create an async returner or a thread (Citizen.CreateThreadNow)
-- func: if passed, will create a thread, otherwise will return an async returner
async(func)

-- convert Lua string to hexadecimal
tohex(str)

-- basic deep clone function (doesn't handle circular references)
clone(t)

parseInt(v)

parseDouble(v)

-- will remove chars not allowed/disabled by strchars
-- allow_policy: if true, will allow all strchars, if false, will allow everything except the strchars
sanitizeString(str, strchars, allow_policy)

splitString(str, sep)
Proxy and Tunnel
Proxy
-- add event handler to call interface functions
-- name: interface name
-- itable: table containing functions
Proxy.addInterface(name, itable)

-- get a proxy interface
-- name: interface name
-- identifier: (optional) unique string to identify this proxy interface access; if nil, will be the name of the resource
Proxy.getInterface(name, identifier)
Tunnel
-- set the base delay between Triggers for a destination
-- dest: player source
-- delay: milliseconds (0 for instant trigger)
Tunnel.setDestDelay(dest, delay)

-- bind an interface (listen to net requests)
-- name: interface name
-- interface: table containing functions
Tunnel.bindInterface(name,interface)

-- get a tunnel interface to send requests
-- name: interface name
-- identifier: (optional) unique string to identify this tunnel interface access; if nil, will be the name of the resource
Tunnel.getInterface(name,identifier)
Interface
interface defined function names should not start with an underscore (_)

the tunnel server-side call requires the player source as first parameter

the tunnel server-side called function can use the global source (correct until a TriggerEvent/yield/etc) as the remote player source

using an underscore to call a remote function interface ignores (no wait) the returned values

-- PROXY any side, TUNNEL client-side

-- call and wait for returned values
-- ...: arguments
-- return values
interface.func(...)

-- call without waiting
-- ...: arguments
interface._func(...)

-- TUNNEL server-side

-- call and wait for returned values
-- ...: arguments
-- return values
interface.func(player, ...) -- or _func to ignore returned values
DBDriver
-- called when the driver is initialized (connection), should return true on success
-- db_cfg: cfg/base.lua .db config
DBDriver:onInit(db_cfg)

-- should prepare the query (@param notation)
DBDriver:onPrepare(name, query)

-- should execute the prepared query
-- params: map of parameters
-- mode:
--- "query": should return rows, affected
--- "execute": should return affected
--- "scalar": should return a scalar
DBDriver:onQuery(name, params, mode)
Extension
self.remote -- tunnel interface to other network side

-- level: (optional) level, 0 by default
Extension:log(msg, level)

Extension:error(msg)
User
User inherits from all extensions sub-class User (if registered before the first user instantiation).

self.source
self.name -- FiveM name (may be steam name)
self.id
self.cid -- character id
self.endpoint -- FiveM endpoint
self.data -- user data
self.cdata -- character data
self.loading_character -- flag
self.use_character_action -- action delay
self.spawns -- spawn count

-- return true if the user character is ready (loaded, not loading)
User:isReady()

User:save()

-- return characters id list
User:getCharacters()

-- return created character id or nil if failed
User:createCharacter()

-- use character
-- return true or false, err_code
-- err_code:
--- 1: delay error, too soon
--- 2: already loading
--- 3: invalid character
User:useCharacter(id)

-- delete character
-- return true or false on failure
User:deleteCharacter(id)
vRP
Shared
self.EXT -- map of name => ext
self.modules -- cfg/modules

vRP.Extension

-- register an extension
-- extension: Extension class
vRP:registerExtension(extension)

-- trigger event (with async call for each listener)
vRP:triggerEvent(name, ...)

-- trigger event and wait for all listeners to complete
vRP:triggerEventSync(name, ...)

-- msg: log message
-- suffix: (optional) category, string
-- level: (optional) level, 0 by default
vRP:log(msg, suffix, level)

-- msg: error message
-- suffix: optional category, string
vRP:error(msg, suffix)
Events
extensionLoad(extension)
called when an extension is loaded, passing the extension instance (can be used to initialize with another extension when loaded before the latter)

Server
self.cfg -- cfg/base config
self.lang -- loaded lang (https://github.com/ImagicTheCat/Luang)
self.users -- map of id => User
self.pending_users -- pending user source update (first spawn), map of ids key => user
self.users_by_source -- map of source => user
self.users_by_cid -- map of character id => user

-- db/SQL API
self.db_drivers
self.db_driver
self.db_initialized

vRP.DBDriver

-- return identification string for a specific source
vRP.getSourceIdKey(source)

vRP.getPlayerEndpoint(player)

vRP.getPlayerName(player)

-- register a DB driver
-- db_driver: DBDriver class
vRP:registerDBDriver(db_driver)

-- prepare a query
--- name: unique name for the query
--- query: SQL string with @params notation
vRP:prepare(name, query)

-- execute a query
--- name: unique name of the query
--- params: map of parameters
--- mode: default is "query"
---- "query": should return rows (list of map of parameter => value), affected
---- "execute": should return affected
---- "scalar": should return a scalar
vRP:query(name, params, mode)

-- shortcut for vRP.query with "execute"
vRP:execute(name, params)

-- shortcut for vRP.query with "scalar"
vRP:scalar(name, params)

vRP:isBanned(user_id)

vRP:setBanned(user_id,banned)

vRP:isWhitelisted(user_id)

vRP:setWhitelisted(user_id,whitelisted)

-- user data
-- value: binary string
vRP:setUData(user_id,key,value)

vRP:getUData(user_id,key)

-- character data
-- value: binary string
vRP:setCData(character_id,key,value)

vRP:getCData(character_id,key)

-- server data
-- value: binary string
vRP:setSData(key,value,id)

vRP:getSData(key,id)

-- global data
-- value: binary string
vRP:setGData(key,value)

vRP:getGData(key)

vRP:ban(user,reason)

vRP:kick(user,reason)

vRP:save()
Events
(sync) characterLoad(user)
called right after the character loading

(sync) characterUnload(user)
called before character unloading

playerJoin(user)
called when a player joins (valid user)

playerRejoin(user)
called when a player re-joins (ex: after a crash)

playerDelay(user, state)
called when the player tunnel delay changes, state is true if delay is enabled

playerSpawn(user, first_spawn)
called when the player spawns

playerDeath(user)
called when the player dies

(sync) playerLeave(user)
called before user removal

save
called when vRP performs a save (can be used to sync the save of external extension data)

Client
self.cfg -- cfg/client config
Events
playerSpawn()
called when the player spawns

playerDeath()
called when the player dies
  Added: May 1 2020, 07:45 AM    Modified: Never edited!    Thanks List: [+]      
Add Feedback

You cannot post yet!
Get involved on GVME by posting your thoughts. Give authors your feedback to help them develop.

To post in this submission register or login
Feedback