Advertisement
Guest User

Untitled

a guest
Jul 19th, 2017
1,428
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 32.68 KB | None | 0 0
  1. `/!\ THIS IS THE FXSERVER VERSION /!\`
  2. ```
  3. Lot of things change in this version, moving to FXServer and MySQL full async requests.
  4. Many functions based on MySQL queries are now async too.
  5. A lot of those changes are not yet documented.
  6. ```
  7.  
  8. # vRP
  9. FiveM RP addon/framework
  10.  
  11. The project aim to create a generic and simple RP framework to prevent everyone from reinventing the wheel.
  12.  
  13. Contributions are welcomed.
  14.  
  15. If you want to try the framework somewhere, here is a list of servers using vRP, without whitelist and managed by me.
  16.  
  17. vRP test server availables:
  18. * 93.115.96.185 (FR) [(config)](http://93.115.96.185/fivem/servers/FR_cfg.zip) [(discord)](https://discord.gg/ZAdE3eu)
  19.  
  20. Support me on Patreon to keep this project alive:
  21.  
  22. [![Support me and the project on Patreon](http://i.imgur.com/dyePK6Q.png)](https://www.patreon.com/ImagicTheCat)
  23.  
  24. [(old pledgie, thank you to the donors)](https://pledgie.com/campaigns/34016)
  25.  
  26.  
  27. See also (and use it as a basis to understand how to develop extensions for vRP) :
  28. * https://github.com/ImagicTheCat/vRP-basic-mission (repair/delivery missions extension)
  29.  
  30. ## Features
  31. * basic admin tools (kick,ban,whitelist)
  32. * groups/permissions
  33. * language config file
  34. * player state auto saved to database (hunger,thirst,weapons,player apparence,position)
  35. * player identity
  36. * business system
  37. * aptitudes (education/exp)
  38. * homes (experimental, if a visitor leave in any other way than using the green circle, like crashing, flying or disconnecting, it will require an eject all)
  39. * phone
  40. * cloakrooms (uniform for jobs)
  41. * basic police (PC, check, I.D., handcuff, jails, seize weapons/items)
  42. * basic emergency (coma, reanimate)
  43. * emotes
  44. * money (wallet/bank)
  45. * inventory (with custom item definition, parametric items), chests (vehicle trunks)
  46. * basic implementations: ATM, market, gunshop, skinshop, garage
  47. * item transformer (harvest, process, produce) (illegal informer)
  48. * identification system (persistant user id for database storage)
  49. * user custom data key/value
  50. * gui (dynamic menu, progress bars, prompt) API
  51. * blip, markers (colored circles), areas (enter/leave callbacks) API
  52. * MySQL lua bindings (prepared statements)
  53. * proxy for easy server-side inter-resource developement
  54. * tunnel for easy server/clients communication
  55.  
  56. ## TODO LIST
  57. * home stuff (home garage,etc)
  58. * vehicle customization
  59. * static chests
  60. * drop weapon/save weapon components
  61. * police pc: add custom police records
  62. * admin: tp to marker
  63. * police research per veh type
  64. * display some permission/group count
  65.  
  66. ## NOTES
  67. ### Homes
  68.  
  69. The home system is experimental, don't expect too much from it at this point. But it's a good basis for some RP interactions, and further developments.
  70.  
  71. #### How it works
  72.  
  73. Homes are closed interiors allocated to players when they want to go inside their home, it means that if no slots are availables, you can't enter to your home. Slots are freed when everyone moves out, however if a player dies, crashes or disconnects inside, the slot will not close itself, only "eject all" will close the slot. So it's possible that all slots are locked after a while, restarting the server will fix the issue.
  74.  
  75. Also, player addresses are bound to the home cluster name, it means that if you change the cluster configuration name, players will not be able to enter/sell their home anymore. So choose the name well and don't change it, if you don't want to deal with this.
  76.  
  77. ## Tutorials
  78.  
  79. * [Deployment](#deployment)
  80. * [Installation](#installation)
  81. * [Configuration](#configuration)
  82. * [Update](#update)
  83. * [Issues / Features / Help](#issues--features--help)
  84. * [Events](#events)
  85. * [Base](#base)
  86. * [API](#api)
  87. * [Base](#base-1)
  88. * [Group/permission](#grouppermission)
  89. * [Survival](#survival)
  90. * [Police](#police)
  91. * [Player state](#player-state)
  92. * [Identity](#identity)
  93. * [Money](#money)
  94. * [Inventory](#inventory)
  95. * [Item transformer](#item-transformer)
  96. * [Home](#home)
  97. * [Mission](#mission)
  98. * [GUI](#gui)
  99. * [Registering choices to the main menu](#registering-choices-to-the-main-menu)
  100. * [Map](#map)
  101. * [Libs](#libs)
  102. * [Proxy](#proxy)
  103. * [Tunnel](#tunnel)
  104. * [MySQL](#mysql)
  105.  
  106. [(gh-md-toc)](https://github.com/ekalinin/github-markdown-toc)
  107.  
  108. ### Deployment
  109. #### Installation
  110.  
  111. vRP has been tested under Windows and GNU/Linux with Mono 4.8.
  112.  
  113. First, make sure you don't have other resources loaded (especially resources using MySQL, add them later and see if they break vRP).
  114. vRP use a new version of MySql.Data.dll, the 4.5, since only one version can be loaded at a time, if another resource load an older version, things will get crazy.
  115.  
  116. Then clone the repository or download the master [archive](https://github.com/ImagicTheCat/vRP/archive/master.zip) and copy the `vrp/` directory to your resource folder. Add `vrp_mysql` then `vrp` to the loading resource list (first after the basic FiveM resources is better).
  117.  
  118. #### Configuration
  119.  
  120. Only the files in the `cfg/` directory should be modified. Modifying the vRP core files is highly discouraged (don't open an issue if it's about modified core files).
  121.  
  122. There is only one required file to configure before launching the server, `cfg/base.lua`, to setup the MySQL database credentials.
  123.  
  124. There is a lot to configure in vRP, nothing comes preconfigured so everyone can make his unique server.
  125. Everything you need to know is in the configuration files, but if you have troubles configuring, look at the configuration of the vRP LaTest servers above.
  126.  
  127. #### Update
  128.  
  129. vRP will warn you at server launch if a new version is available. You can also update while I commit things, but do that only if you like to beta test, because you will need to update a lot.
  130.  
  131. A way to update:
  132. * save your `cfg/` folder somewhere
  133. * copy all new files in `vrp/`
  134. * compare your old `cfg/` folder with the new one, fill the gaps (one mistake will break everything, take your time)
  135. * replace the new `cfg/` folder with the old modified `cfg/` folder
  136.  
  137. #### Issues / Features / Help
  138.  
  139. The issue section is only for bug reports and feature requests. I will close (and ban) issues not related to the core of vRP, to keep the github clean.
  140. Don't submit issues about your own modifications, I will close them without warning.
  141.  
  142. When submitting an issue, add any information you can find, with all details. Saying that something doesn't work is useless and will not solve the issue.
  143. If you have errors in your console BEFORE the issue happen, everything could be corrupted, so the issue is irrelevant, you should solve all unrelated errors before submitting issues.
  144.  
  145. For questions, help, discussions around the project, please go instead on the vRP thread of the FiveM forum here: https://forum.fivem.net/t/release-vrp-framework/22894
  146.  
  147. ### Events
  148. #### Base
  149.  
  150. ```lua
  151.  
  152. -- (server) called after identification
  153. AddEventHandler("vRP:playerJoin",function(user_id,source,name,last_login) end)
  154.  
  155. -- (server) called when the player join again without triggering the vRP:playerLeave event before
  156. -- (used after a client crash for example)
  157. AddEventHandler("vRP:playerRejoin",function(user_id,source,name) end)
  158.  
  159. -- (server) called when a logged player spawn
  160. AddEventHandler("vRP:playerSpawn", function(user_id, source, first_spawn) end)
  161.  
  162. -- (server) called when a player leave
  163. AddEventHandler("vRP:playerLeave",function(user_id, source) end)
  164.  
  165. -- (server) called when a player join a group
  166. -- gtype can be nil
  167. AddEventHandler("vRP:playerJoinGroup", function(user_id, group, gtype) end)
  168.  
  169. -- (server) called when a player leave a group
  170. -- gtype can be nil
  171. AddEventHandler("vRP:playerLeaveGroup", function(user_id, group, gtype) end)
  172.  
  173. ```
  174.  
  175. ### API
  176.  
  177. To call the server-side API functions, get the vRP interface.
  178.  
  179. ```lua
  180. local Proxy = require("resources/vRP/lib/Proxy")
  181.  
  182. vRP = Proxy.getInterface("vRP")
  183.  
  184. -- ex:
  185. vRP.getUserId({source},function(user_id)
  186. print("user_id = "..user_id)
  187. end)
  188. ```
  189.  
  190. You can also do it client-side, the API is the same as the TUNNEL CLIENT APIs (copy and add the `vrp/client/Proxy.lua` to your resources, first).
  191.  
  192. ```lua
  193. vRP = Proxy.getInterface("vRP")
  194.  
  195. -- ex:
  196. vRP.notify({"A notification."}) -- notify the player
  197. ```
  198.  
  199. For the client/server tunnel API, the interface is also "vRP", see the Tunnel library below.
  200.  
  201. In the config files callbacks, you can use directly vRP and vRPclient (the tunnel to the clients).
  202.  
  203. #### Base
  204.  
  205. ```lua
  206. -- PROXY API
  207.  
  208. -- return map of user_id -> player source
  209. vRP.getUsers()
  210.  
  211. -- return user id or nil if the source is invalid
  212. vRP.getUserId(source)
  213.  
  214. -- return source of the user or nil if not connected
  215. vRP.getUserSource(user_id)
  216.  
  217. -- set user data (textual data)
  218. vRP.setUData(user_id,key,value)
  219.  
  220. -- get user data (textual data)
  221. -- return nil if data not found
  222. vRP.getUData(user_id,key)
  223.  
  224. -- set server data (textual data)
  225. vRP.setSData(key,value)
  226.  
  227. -- get server data (textual data)
  228. -- return nil if data not found
  229. vRP.getSData(key)
  230.  
  231. -- TUNNEL SERVER API
  232.  
  233. -- TUNNEL CLIENT API
  234.  
  235. -- teleport the player to the specified coordinates
  236. vRP.teleport(x,y,z)
  237.  
  238. -- get the player position
  239. -- return x,y,z
  240. vRP.getPosition()
  241.  
  242. -- get the player speed
  243. -- return speed
  244. vRP.getSpeed()
  245.  
  246. -- return false if in exterior, true if inside a building
  247. vRP.isInside()
  248.  
  249. -- notify the player
  250. vRP.notify(message)
  251.  
  252. -- play a screen effect
  253. -- name, see https://wiki.fivem.net/wiki/Screen_Effects
  254. -- duration: in seconds, if -1, will play until stopScreenEffect is called
  255. vRP.playScreenEffect(name, duration)
  256.  
  257. -- stop a screen effect
  258. -- name, see https://wiki.fivem.net/wiki/Screen_Effects
  259. vRP.stopScreenEffect(name)
  260.  
  261.  
  262.  
  263. -- FUNCTIONS BELOW ARE EXPERIMENTALS
  264.  
  265. -- get nearest players (inside the radius)
  266. -- return map of player => distance in meters
  267. vRP.getNearestPlayers(radius)
  268.  
  269. -- get nearest player (inside the radius)
  270. -- return player or nil
  271. vRP.getNearestPlayer(radius)
  272.  
  273.  
  274. -- animations dict/name: see http://docs.ragepluginhook.net/html/62951c37-a440-478c-b389-c471230ddfc5.htm
  275.  
  276. -- play animation (new version)
  277. -- upper: true, only upper body, false, full animation
  278. -- seq: list of animations as {dict,anim_name,loops} (loops is the number of loops, default 1)
  279. -- looping: if true, will infinitely loop the first element of the sequence until stopAnim is called
  280. vRP.playAnim(upper, seq, looping)
  281.  
  282. -- stop animation (new version)
  283. -- upper: true, stop the upper animation, false, stop full animations
  284. vRP.stopAnim(upper)
  285.  
  286. -- SOUND
  287. -- some lists:
  288. -- pastebin.com/A8Ny8AHZ
  289. -- https://wiki.gtanet.work/index.php?title=FrontEndSoundlist
  290.  
  291. -- play sound at a specific position
  292. vRP.playSpatializedSound(dict,name,x,y,z,range)
  293.  
  294. -- play sound
  295. vRP.playSound(dict,name)
  296. ```
  297.  
  298. #### Group/permission
  299.  
  300. Group and permissions are a way to limit features to specific players.
  301. Each group have a set of permissions defined in `cfg/groups.lua`.
  302. Permissions can be used with most of the vRP modules, giving the ability to create specific garages, item transformers, etc.
  303.  
  304. ##### Regular permissions
  305.  
  306. Regular permissions are plain text permissions, they can be added to groups. You can add a `-` before the permission to negate (even if other groups add the permission, they will be ignored).
  307.  
  308. ##### Special item permission
  309.  
  310. You can use a special permission to check for items.
  311. Form: `#idname.operator`, operators to check the amount are greater `>`, less `<`, equal ` `. Ex:
  312. * `#tacos.>0` -> one or more tacos
  313. * `#weed.1` -> exactly one weed
  314.  
  315. ##### Special aptitude permission
  316.  
  317. You can use a special permission to check for aptitudes.
  318. Form: `@group.aptitude.operator`, operators to check the level are greater `>`, less `<`, equal ` `. Ex:
  319. * `@physical.strength.3` -> strength level equal to 3
  320. * `@science.chemicals.>4` -> chemicals science level greater or equal to 5
  321.  
  322. ##### API
  323.  
  324. ```lua
  325. -- PROXY API
  326.  
  327. -- add a group to a connected user
  328. vRP.addUserGroup(user_id,group)
  329.  
  330. -- remove a group from a connected user
  331. vRP.removeUserGroup(user_id,group)
  332.  
  333. -- check if the user has a specific group
  334. vRP.hasGroup(user_id,group)
  335.  
  336. -- check if the user has a specific permission
  337. vRP.hasPermission(user_id, perm)
  338.  
  339. -- check if the user has a specific list of permissions (all of them)
  340. vRP.hasPermissions(user_id, perms)
  341.  
  342. -- get user group by group type
  343. -- return group name or an empty string
  344. vRP.getUserGroupByType(user_id,gtype)
  345.  
  346. -- return list of connected users by group
  347. vRP.getUsersByGroup(group)
  348.  
  349. -- return list of connected users by permission
  350. vRP.getUsersByPermission(perm)
  351. ```
  352.  
  353. #### Survival
  354.  
  355. Running, walking, being hurt/injured, and just living add hunger and thirst. When the hunger and the thirst are at their maximum level (100%), next hunger/thirst overflow will damage the character by the same amount (ex: when thirsty, don't run, take a car).
  356. This module disable the basic health regen.
  357.  
  358. The survival module implement also a coma system, if the health of the player is below the coma threshold, the player is in coma for a specific duration before dying. The health (thus coma) is recorded in the player state.
  359. If a player disconnect and reconnect while in coma, he will fall in coma again and die in a few seconds.
  360.  
  361. ```lua
  362. -- PROXY API
  363.  
  364. -- return hunger (0-100)
  365. vRP.getHunger(user_id)
  366.  
  367. -- return thirst (0-100)
  368. vRP.getThirst(user_id)
  369.  
  370. vRP.setHunger(user_id,value)
  371.  
  372. vRP.setThirst(user_id,value)
  373.  
  374. -- vary hunger value by variation amount (+ to add hunger, - to remove hunger)
  375. vRP.varyHunger(user_id,variation)
  376.  
  377. -- same as vary hunger
  378. vRP.varyThirst(user_id,variation)
  379.  
  380. -- TUNNEL SERVER API
  381.  
  382. -- TUNNEL CLIENT API
  383.  
  384. -- player health variation (+ to heal, - to deal damage)
  385. vRP.varyHealth(variation)
  386.  
  387. -- get player health
  388. vRP.getHealth()
  389.  
  390. -- set player health
  391. vRP.setHealth(health)
  392.  
  393. -- check if the player is in coma
  394. vRP.isInComa()
  395.  
  396. -- enable/disable spawned player ability to hurt friendly
  397. -- flag: boolean
  398. vRP.setFriendlyFire(flag)
  399.  
  400. -- enable/disable spawned player ability to be chased/arrested by cops
  401. -- flag: boolean
  402. vRP.setPolice(flag)
  403. ```
  404.  
  405. #### Police
  406.  
  407. ```lua
  408. -- PROXY API
  409.  
  410. -- insert a police record for a specific user
  411. --- line: text for one line (can be html)
  412. vRP.insertPoliceRecord(user_id, line)
  413.  
  414. -- TUNNEL SERVER API
  415.  
  416. -- TUNNEL CLIENT API
  417.  
  418. -- apply wanted level
  419. -- stars 1-5
  420. vRP.applyWantedLevel(stars)
  421.  
  422. -- true to enable, false to disable
  423. -- if enabled, will prevent NPC cops to fire at the player
  424. vRP.setCop(flag)
  425. ```
  426.  
  427. #### Player state
  428. ```lua
  429. -- PROXY API
  430.  
  431. -- TUNNEL SERVER API
  432.  
  433. -- TUNNEL CLIENT API
  434.  
  435. -- get player weapons data
  436. -- return table with weapons data, use print(json.encode(result)) to understand the structure
  437. vRP.getWeapons()
  438.  
  439. -- give weapons
  440. -- weapons: same structure as returned by getWeapons()
  441. -- (optional) clear_before: if true, will remove all the weapons before adding the new ones
  442. vRP.giveWeapons(weapons,clear_before)
  443.  
  444. -- get player apparence customization data
  445. -- return table with customization data, use print(json.encode(result)) to understand the structure
  446. -- .model or .modelhash define the player model, the indexes define each component as [drawable_id,texture_id,palette_id] array
  447. -- props are referenced using the prefix "p" for the key (p0,p1,p2,p...), -1 = no prop
  448. vRP.getCustomization()
  449.  
  450. -- set player apparence
  451. -- customization_data: same structure as returned by getCustomization()
  452. vRP.setCustomization(customization_data)
  453. ```
  454.  
  455. #### Identity
  456.  
  457. The identity module add identity cards with a car registration number (one per identity, all vehicles will have the same registration number).
  458.  
  459. ```lua
  460. -- PROXY API
  461.  
  462. -- get user identity
  463. -- return nil if not found
  464. -- identity keys are the database fields: user_id, name, firstname, age, registration
  465. vRP.getUserIdentity(user_id)
  466. ```
  467.  
  468. #### Money
  469.  
  470. The money is managed with direct SQL queries to prevent most potential value corruptions.
  471. The wallet empties itself when respawning (after death).
  472.  
  473. ```lua
  474. -- PROXY API
  475.  
  476. -- get money in wallet
  477. vRP.getMoney(user_id)
  478.  
  479. -- set money in wallet
  480. vRP.setMoney(user_id,value)
  481.  
  482. -- try a payment (wallet only)
  483. -- return true or false (debited if true)
  484. vRP.tryPayment(user_id,amount)
  485.  
  486. -- try full payment (wallet + bank to complete payment)
  487. -- return true or false (debited if true)
  488. vRP.tryFullPayment(user_id,amount)
  489.  
  490. -- give money to wallet
  491. vRP.giveMoney(user_id,amount)
  492.  
  493. -- get bank money
  494. vRP.getBankMoney(user_id)
  495.  
  496. -- set bank money
  497. vRP.setBankMoney(user_id,value)
  498.  
  499. -- try a withdraw
  500. -- return true or false (withdrawn if true)
  501. vRP.tryWithdraw(user_id,amount)
  502.  
  503. -- try a deposit
  504. -- return true or false (deposited if true)
  505. vRP.tryDeposit(user_id,amount)
  506.  
  507. -- TUNNEL SERVER API
  508.  
  509. -- TUNNEL CLIENT API
  510. ```
  511.  
  512. #### Inventory
  513.  
  514. The inventory is autosaved and, as the wallet, gets empty upon death.
  515.  
  516. ##### Items
  517.  
  518. Items are simple identifiers associated with a quantity in an inventory. But they can also be parametrics.
  519.  
  520. Parametrics items are identified like other items in the inventory but also have arguments as: `weapon|pistol` instead of just an ID. Parametric items don't contain any data, they are generic item definitions that will be specialized by the arguments.
  521.  
  522. ```lua
  523. -- PROXY API
  524.  
  525. -- define an inventory item (call this at server start) (parametric or plain text data)
  526. -- idname: unique item name
  527. -- name: display name or genfunction
  528. -- description: item description (html) or genfunction
  529. -- choices: menudata choices (see gui api) only as genfunction or nil
  530. -- weight: weight or genfunction
  531. --
  532. -- genfunction are functions returning a correct value as: function(args) return value end
  533. -- where args is a list of {base_idname,arg,arg,arg,...}
  534.  
  535. vRP.defInventoryItem(idname,name,description,choices,weight)
  536.  
  537. -- return name, description, weight
  538. vRP.getItemDefinition(idname)
  539.  
  540. vRP.getItemName(idname)
  541.  
  542. vRP.getItemDescription(idname)
  543.  
  544. vRP.getItemChoices(idname)
  545.  
  546. vRP.getItemWeight(idname)
  547.  
  548. -- add item to a connected user inventory
  549. vRP.giveInventoryItem(user_id,idname,amount,notify)
  550.  
  551. -- try to get item from a connected user inventory
  552. -- return true if the item has been found and the quantity removed
  553. vRP.tryGetInventoryItem(user_id,idname,amount,notify)
  554.  
  555. -- clear connected user inventory
  556. vRP.clearInventory(user_id)
  557.  
  558. -- compute weight of a list of items (in inventory/chest format)
  559. vRP.computeItemsWeight(items)
  560.  
  561. -- return user inventory total weight
  562. vRP.getInventoryWeight(user_id)
  563.  
  564. -- return user inventory max weight
  565. vRP.getInventoryMaxWeight(user_id)
  566.  
  567. -- open a chest by name
  568. -- cb_close(): called when the chest is closed
  569. vRP.openChest(source, name, max_weight, cb_close)
  570.  
  571. -- TUNNEL SERVER API
  572.  
  573. -- TUNNEL CLIENT API
  574. ```
  575.  
  576. Full example of a resource defining a water bottle item.
  577. Once defined, items can be used by any resources (ex: they can be added to shops).
  578.  
  579. ```lua
  580. local Proxy = require("resources/vRP/lib/Proxy")
  581. local Tunnel = require("resources/vRP/lib/Tunnel")
  582.  
  583. vRP = Proxy.getInterface("vRP")
  584. vRPclient = Tunnel.getInterface("vRP","vrp_waterbottle")
  585.  
  586. -- create Water bottle item (the callback hell begins)
  587. local wb_choices = {} -- (see gui API for menudata choices structure)
  588.  
  589. wb_choices["Drink"] = {function(player,choice) -- add drink action
  590. local user_id = vRP.getUserId({player}) -- get user_id
  591. if user_id ~= nil then
  592. if vRP.tryGetInventoryItem({user_id,"water_bottle",1}) -- try to remove one bottle
  593. vRP.varyThirst({user_id,-35}) -- decrease thirst
  594. vRPclient.notify(player,{"~b~ Drinking."}) -- notify
  595. vRP.closeMenu({player}) -- the water bottle is consumed by the action, close the menu
  596. end
  597. end
  598. end,"Do it."}
  599.  
  600. -- add item definition
  601. vRP.defInventoryItem({"water_bottle","Water bottle","Drink this my friend.",function() return wb_choices end,0.5})
  602.  
  603. -- (at any time later) give 2 water bottles to a connected user
  604. vRP.giveInventoryItem({user_id,"water_bottle",2})
  605.  
  606. ```
  607.  
  608. #### Item transformer
  609.  
  610. The item transformer is a very generic way to create harvest and processing areas.
  611. The concept is simple:
  612. * you can use the action of the item transformer when entering the area
  613. * the item transformer has a number of work units, regenerated at a specific rate
  614. * the item transformer takes reagents (money, items or none) to produce products (money or items) and it consumes a work unit
  615.  
  616. This way, processing and harvesting are limited by the work units.
  617. Item transformers can be dynamically set and removed, if you want to build random harvest points.
  618.  
  619. ```lua
  620. -- add an item transformer
  621. -- name: transformer id name
  622. -- itemtr: item transformer definition table
  623. --- name
  624. --- permissions (optional)
  625. --- max_units
  626. --- units_per_minute
  627. --- x,y,z,radius,height (area properties)
  628. --- r,g,b (color)
  629. --- recipes, map of action =>
  630. ---- description
  631. ---- in_money
  632. ---- out_money
  633. ---- reagents: items as idname => amount
  634. ---- products: items as idname => amount
  635. ---- aptitudes: list as "group.aptitude" => exp amount generated
  636. --- onstart(player,recipe): optional callback
  637. --- onstep(player,recipe): optional callback
  638. --- onstop(player,recipe): optional callback
  639. vRP.setItemTransformer(name,itemtr)
  640.  
  641. -- remove an item transformer
  642. vRP.removeItemTransformer(name)
  643.  
  644.  
  645. -- Example from another resource using proxy
  646.  
  647. local itemtr = {
  648. name="Water bottles tree", -- menu name
  649. r=0,g=125,b=255, -- color
  650. max_units=10,
  651. units_per_minute=5,
  652. x=1858,y=3687.5,z=34.26, -- pos
  653. radius=5, height=1.5, -- area
  654. recipes = {
  655. ["Harvest"] = { -- action name
  656. description="Harvest some water bottles.", -- action description
  657. in_money=0, -- money taken per unit
  658. out_money=0, -- money earned per unit
  659. reagents={}, -- items taken per unit
  660. products={ -- items given per unit
  661. ["water_bottle"] = 1
  662. }
  663. }
  664. }
  665. }
  666.  
  667. vRP.setItemTransformer({"my_unique_transformer",itemtr})
  668. ```
  669.  
  670. For static areas, configure the file `cfg/item_transformers.lua`, the transformers will be automatically added.
  671.  
  672. #### Home
  673.  
  674. ```lua
  675. -- PROXY API
  676.  
  677. -- define home component
  678. -- name: unique component id
  679. -- oncreate(owner_id, slot_type, slot_id, cid, config, x, y, z, player)
  680. -- ondestroy(owner_id, slot_type, slot_id, cid, config, x, y, z, player)
  681. vRP.defHomeComponent(name, oncreate, ondestroy)
  682.  
  683. -- user access a home by address (without asking)
  684. -- return true on success
  685. vRP.accessHome(user_id, home, number)
  686. ```
  687.  
  688. ##### Basic components
  689.  
  690. ###### Chest
  691.  
  692. `chest`
  693. A home chest.
  694.  
  695. ```lua
  696. _config = {
  697. weight = 200
  698. }
  699. ```
  700.  
  701. ###### Wardrobe
  702.  
  703. `wardrobe`
  704. Save your character customization in the wardrobe, so you don't need to customize/pay clothes in skinshop again.
  705.  
  706. ###### Game table
  707.  
  708. `gametable`
  709. * Bet with other peoples.
  710.  
  711. ###### Item transformer
  712.  
  713. `itemtr`
  714. Set the config as any item transformer structure configuration.
  715.  
  716.  
  717. #### Mission
  718.  
  719. ```lua
  720. -- PROXY API
  721.  
  722. -- start a mission for a player
  723. --- mission_data:
  724. ---- name: Mission name
  725. ---- steps: ordered list of
  726. ----- text
  727. ----- position: {x,y,z}
  728. ----- onenter(player,area)
  729. ----- onleave(player,area) (optional)
  730. ----- blipid, blipcolor (optional)
  731. vRP.startMission(player, mission_data)
  732.  
  733. -- end the current player mission step
  734. vRP.nextMissionStep(player)
  735.  
  736. -- stop the player mission
  737. vRP.stopMission(player)
  738.  
  739. -- check if the player has a mission
  740. vRP.hasMission(player)
  741. ```
  742.  
  743. #### GUI
  744.  
  745. Controls for the menu generated by the API are the cellphone controls (LEFT,RIGHT,UP,DOWN,CANCEL,SELECT and OPEN to open the main menu).
  746. Don't forget to change the key to open the phone for something different than UP. You can also use the middle mouse button by default.
  747.  
  748. You can customize the GUI css in `cfg/gui.lua`.
  749.  
  750.  
  751. ```lua
  752. -- PROXY API
  753.  
  754. -- HOW TO: building a dynamic menu
  755. local menudata = {}
  756. menudata.name = "My Menu"
  757.  
  758. -- shift menu from the top by 75px and set the menu header to green
  759. menudata.css = {top = "75px", header_color = "rgba(0,255,0,0.75)"} -- exhaustive list
  760.  
  761. menudata.onclose = function(player)
  762. print("menu closed")
  763. end
  764.  
  765. local onchoose = function(player,choice,mod)
  766. -- mod will be input modulation -1,0,1 (left,(c)enter,right)
  767. print("player choose "..choice)
  768. vRP.closeMenu({source}) -- ({} because proxy call) close the menu after the first choice (an action menu for example)
  769. end
  770.  
  771. -- add options and callbacks
  772. menudata["Option1"] = {onchoose, "this <b>option</b> is amazing"} -- callaback and description
  773. menudata["Option two"] = {onchoose} -- no description
  774. menudata["Another option"] = {function(choice) print("another option choice") end,"this<br />one<br />is<br />better"}
  775. -- END HOW TO
  776.  
  777. -- open a dynamic menu to the client (will close previously opened menus)
  778. vRP.openMenu(source, menudata)
  779.  
  780. -- close client active menu
  781. vRP.closeMenu(source)
  782.  
  783. -- prompt textual (and multiline) information from player
  784. -- cb_result: function(player,result)
  785. vRP.prompt(source,title,default_text,cb_result)
  786.  
  787. -- ask something to a player with a limited amount of time to answer (yes|no request)
  788. -- time: request duration in seconds
  789. -- cb_ok: function(player,ok)
  790. vRP.request(source,text,time,cb_ok)
  791.  
  792. -- STATIC MENUS
  793.  
  794. -- define choices to a static menu by name (needs to be called like inventory item definition, at initialization)
  795. vRP.addStaticMenuChoices(name, choices)
  796.  
  797. -- TUNNEL SERVER API
  798.  
  799. -- TUNNEL CLIENT API
  800.  
  801.  
  802. -- progress bar
  803.  
  804.  
  805. -- create/update a progress bar
  806. -- anchor: the anchor string type (multiple progress bars can be set for the same anchor)
  807. ---- "minimap" => above minimap (will divide that horizontal space)
  808. ---- "center" => center of the screen, at the bottom
  809. ---- "botright" => bottom right of the screen
  810. vRP.setProgressBar(name,anchor,text,r,g,b,value)
  811.  
  812. -- set progress bar value in percent
  813. vRP.setProgressBarValue(name,value)
  814.  
  815. -- set progress bar text
  816. vRP.setProgressBarText(name,text)
  817.  
  818. -- remove progress bar
  819. vRP.removeProgressBar(name)
  820.  
  821.  
  822. -- div
  823.  
  824. -- dynamic div are used to display formatted data
  825. -- if only some part of the div changes, use JS pre-defined functions to hide/show the div and change the data
  826.  
  827. -- set a div
  828. -- css: plain global css, the div class is ".div_nameofthediv"
  829. -- content: html content of the div
  830. vRP.setDiv(name,css,content)
  831.  
  832. -- set the div css
  833. vRP.setDivCss(name,css)
  834.  
  835. -- set the div content
  836. vRP.setDivContent(name,content)
  837.  
  838. -- execute js for the div in a simple sandbox
  839. -- you can attach objects or functions to the div element for later calls
  840. -- use div.querySelector to find the div children elements
  841. -- js context: div (the div element)
  842. vRP.divExecuteJS(name,js)
  843.  
  844. -- remove the div
  845. vRP.removeDiv(name)
  846.  
  847. -- announce
  848.  
  849. -- add an announce to the queue
  850. -- background: image url (800x150)
  851. -- content: announce html content
  852. vRP.announce(background,content)
  853.  
  854. ```
  855.  
  856. ##### Registering choices to the main menu
  857.  
  858. The main menu is generated using an event, this is useful to add special choices if needed.
  859.  
  860. ```lua
  861. -- in another resource using the proxy interface
  862.  
  863. AddEventHandler("vRP:buildMainMenu",function(player)
  864. local choices = {}
  865.  
  866. local fchoice = function(player,choice)
  867. print("player "..player.." choose "..choice)
  868. end
  869.  
  870. choices["My Choice"] = {fchoice,"My choice description."}
  871. choices["My Choice 2"] = {fchoice,"My choice 2 description."}
  872.  
  873. vRP.buildMainMenu({player,choices}) -- add choices to the player main menu
  874. end)
  875. ```
  876.  
  877. #### Map
  878.  
  879. ```lua
  880. -- PROXY API
  881.  
  882. -- create/update a player area (will trigger enter and leave callbacks)
  883. -- cb_enter, cb_leave: function(player,area_name)
  884. vRP.setArea(source,name,x,y,z,radius,height,cb_enter,cb_leave)
  885.  
  886. -- remove a player area
  887. vRP.removeArea(source,name)
  888.  
  889. -- TUNNEL SERVER API
  890.  
  891. -- TUNNEL CLIENT API
  892.  
  893. -- set the GPS destination marker coordinates
  894. vRP.setGPS(x,y)
  895.  
  896. -- set route to native blip id
  897. vRP.setBlipRoute(id)
  898.  
  899. -- create new blip, return native id
  900. vRP.addBlip(x,y,z,idtype,idcolor,text)
  901.  
  902. -- remove blip by native id
  903. vRP.removeBlip(id)
  904.  
  905. -- set a named blip (same as addBlip but for a unique name, add or update)
  906. -- return native id
  907. vRP.setNamedBlip(name,x,y,z,idtype,idcolor,text)
  908.  
  909. -- remove a named blip
  910. vRP.removeNamedBlip(name)
  911.  
  912. -- add a circular marker to the game map
  913. -- return marker id
  914. vRP.addMarker(x,y,z,sx,sy,sz,r,g,b,a,visible_distance)
  915.  
  916. -- remove marker
  917. vRP.removeMarker(id)
  918.  
  919. -- set a named marker (same as addMarker but for a unique name, add or update)
  920. -- return id
  921. vRP.setNamedMarker(name,x,y,z,sx,sy,sz,r,g,b,a,visible_distance)
  922.  
  923. -- remove a named marker
  924. vRP.removeNamedMarker(name)
  925.  
  926. ```
  927.  
  928. ### Libs
  929.  
  930. #### Proxy
  931.  
  932. The proxy lib is used to call other resources functions through a proxy event.
  933.  
  934. Ex:
  935.  
  936. resource1.lua
  937. ```lua
  938. local Proxy = require("resources/vRP/lib/Proxy")
  939.  
  940. Resource1 = {}
  941. Proxy.addInterface("resource1",Resource1) -- add functions to resource1 interface (can be called multiple times if multiple files declare different functions for the same interface)
  942.  
  943. function Resource1.test(a,b)
  944. print("resource1 TEST "..a..","..b)
  945. return a+b,a*b -- return two values
  946. end
  947. ```
  948. resource2.lua
  949. ```lua
  950. local Proxy = require("resources/vRP/lib/Proxy")
  951.  
  952. Resource1 = Proxy.getInterface("resource1")
  953.  
  954. local rvalue1, rvalue2 = Resource1.test({13,42})
  955. print("resource2 TEST rvalues = "..rvalue1..","..rvalue2)
  956. ```
  957.  
  958. The notation is **Interface.function({arguments})**.
  959.  
  960. #### Tunnel
  961.  
  962. The idea behind tunnels is to easily access any declared server function from any client resource, and to access any declared client function from any server resource.
  963.  
  964. Example of two-way resource communication:
  965.  
  966. Server-side myrsc
  967. ```lua
  968. local Tunnel = require("resources/vRP/lib/Tunnel")
  969.  
  970. -- build the server-side interface
  971. serverdef = {} -- you can add function to serverdef later in other server scripts
  972. Tunnel.bindInterface("myrsc",serverdef)
  973.  
  974. function serverdef.test(msg)
  975. print("msg "..msg.." received from "..source)
  976. return 42
  977. end
  978.  
  979. -- get the client-side access
  980. clientaccess = Tunnel.getInterface("myrsc","myrsc") -- the second argument is a unique id for this tunnel access, the current resource name is a good choice
  981.  
  982. -- (later, in a player spawn event) teleport the player to 0,0,0
  983. clientaccess.teleport(source,{0,0,0})
  984. ```
  985.  
  986. Client-side myrsc (copy the resources/vRP/client/Tunnel.lua and add it first to the client scripts of your resource)
  987. ```lua
  988.  
  989. -- build the client-side interface
  990. clientdef = {} -- you can add function to clientdef later in other client scripts
  991. Tunnel.bindInterface("myrsc",clientdef)
  992.  
  993. function clientdef.teleport(x,y,z)
  994. SetEntityCoords(GetPlayerPed(-1), x, y, z, 1,0,0,0)
  995. end
  996.  
  997. -- sometimes, you would want to return the tunnel call asynchronously
  998. -- ex:
  999. function clientdef.setModel(hash)
  1000. local exit = TUNNEL_DELAYED() -- get the delayed return function
  1001.  
  1002. Citizen.CreateThread(function()
  1003. -- do the asynchronous model loading
  1004. Citizen.Wait(1000)
  1005.  
  1006. exit({true}) -- return a boolean to confirm loading (calling exit will not really exit the function, but just send back the array as the tunnel call return values, so call it wisely)
  1007. end)
  1008. end
  1009.  
  1010. -- get the server-side access
  1011. serveraccess = Tunnel.getInterface("myrsc","myrsc") -- the second argument is a unique id for this tunnel access, the current resource name is a good choice
  1012.  
  1013. -- call test on server and print the returned value
  1014. serveraccess.test({"my client message"},function(r)
  1015. print(r)
  1016. end)
  1017.  
  1018. ```
  1019.  
  1020. Now if we want to use the same teleport function in another resource:
  1021.  
  1022. ```lua
  1023. local Tunnel = require("resources/vRP/lib/Tunnel")
  1024.  
  1025. -- get the client-side access of myrsc
  1026. myrsc_access = Tunnel.getInterface("myrsc","myotherrsc")
  1027.  
  1028. -- (later, in a player spawn event) teleport the player to 0,0,0
  1029. myrsc_access.teleport(source,{0,0,0})
  1030. ```
  1031.  
  1032. This way resources can easily use other resources client/server API.
  1033.  
  1034. A magic trick with the tunnel system (which is based on the TriggerEvent), imagine we want to teleport all players to the same position:
  1035.  
  1036. ```lua
  1037. clientaccess.teleport(-1,{0,0,0},function()
  1038. print("player "..source.." teleported") -- will be displayed for each teleported player
  1039. end)
  1040. ```
  1041.  
  1042. #### MySQL
  1043.  
  1044. ```lua
  1045. local MySQL = require("resources/vRP/lib/MySQL/MySQL")
  1046.  
  1047. -- host can be "host" or "host:port"
  1048. local sql = MySQL.open("127.0.0.1","user","password","database") -- add ,true) to enable debug for the connection
  1049. local q_init = sql:prepare([[
  1050. CREATE IF NOT EXISTS list(
  1051. name VARCHAR(255),
  1052. value INTEGER,
  1053. CONSTRAINT pk_list PRIMARY KEY(name)
  1054. );
  1055. ]])
  1056. q_init:execute()
  1057.  
  1058. local q_insert = sql:prepare("INSERT INTO list(name,value) VALUES(@name,@value)")
  1059.  
  1060. for i=0,100 do
  1061. q_insert:bind("@name","entry"..i)
  1062. q_insert:bind("@value",i*5)
  1063. q_insert:execute()
  1064.  
  1065. print("inserted id = "..q_insert:last_insert_id())
  1066. end
  1067.  
  1068. local q_select = sql:prepare("SELECT * FROM list")
  1069. local r = q_select:query()
  1070. print("NAME VALUE")
  1071. while r:fetch() do
  1072. print(r:getValue("name").." "..r:getValue("value"))
  1073. -- or print(r:getValue(0).." "..r:getValue(1))
  1074. -- or local row = r:getRow()
  1075. end
  1076.  
  1077. r:close() -- don't forget to close the result
  1078.  
  1079. -- or
  1080. local r = q_select:query()
  1081. local list = r:toTable() -- result is autoclosed
  1082. ```
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement