Jump to content

Libraries

59 files

  1. [C# Server-Side] Events+Commands at Runtime

    Github page: https://github.com/robertnisipeanu/ragemp-server-events
     
    ragemp-server-events
    OOP Implementation of the RAGEMP server events (so you don't have to use [Command] or [ServerEvent] annotations). It allows you to add event handlers and commands at runtime.
    How to use
    Copy /client_packages/cs_packages/CustomCommands.cs to your server client resources (server-files/client_packages/cs_packages).
    From folder 'server' import Delegates.cs and Events.cs into your server-side project.
    Add using robearded; at the top of the files where you want to use my API.
    Use Events.*EventName* += EventHandler; to add an event handler and Events.AddCommand("*commandName*", CommandHandler); to add a command handler.
    Added events
    OnPlayerReady(Client client) -> This event is not available by default on the C# API If any other events will be custom implemented they will be added here ^
    Example
    You can find an example inside the 'example' folder.
    Need help?
    Please do not contact me if you didn't followed the above steps, I'm not gonna tell you again the steps in private when you have them here.
    If you need any other help, feel free to contact me on Discord at @rumble06#4127 or on RAGE.MP Forums at https://rage.mp/profile/45121-robearded/

    90 downloads

       (2 reviews)

    0 comments

    Updated

  2. [C#]RAGE:MP Discord Integration

    RAGEMP-DiscordIntegration
    This wrapper allows you easily create an instance of a discord bot within your RAGE:MP server.
    Features:
    1. Send messages to discord from your RAGE:MP Server.
    2. Send messages to your RAGE:MP Server from your Discord server.
    3. Register specific channel for the bot to listen. (Can be changed during runtime).
    3. Remove specific channel for the bot to STOP listening. (Can be changed during runtime).
    4. Update bot status on setup and/or during runtime
     
    How to use the wrapper
    1. Add the RAGEMP-DiscordIntegration.dll as a reference to your project in visual studio.
    2. Make sure to place the three provided Discord.Net.xx.dll into your server/runtime folder.
    3. Enjoy))))
    How to set up
    1. Create a new application on Discord Developers
    2. Create a bot.
    3. Invite bot to discord server.
    4. Use the token from your bot to initialize the bot as shown in the example below.
    5. Register/Remove channels from where your bot sends to all players.
    Example script.
    using GTANetworkAPI; using System; using System.Collections.Generic; using System.Text; public class Yes : Script { public Yes() { NAPI.Util.ConsoleOutput("Loaded: yes"); } [ServerEvent(Event.ResourceStart)] public void OnResourceStart() { Integration.DiscordIntegration.SetUpBotInstance("TOKEN_HERE", "RAGE:MP", Discord.ActivityType.Playing, Discord.UserStatus.DoNotDisturb); } [ServerEvent(Event.ChatMessage)] public async void OnChatMessage(Player player, string strMessage) { string strFormatted = $"[RAGE:MP] {player.Name}: {strMessage}"; await Integration.DiscordIntegration.SendMessage(3897429387492374, strFormatted, true).ConfigureAwait(true); } [Command("registerchannel")] public void RegisterDiscord(Player player, ulong discordChannelID) { bool bSuccess = Integration.DiscordIntegration.RegisterChannelForListenting(discordChannelID); player.SendChatMessage(bSuccess ? "Success" : "No Success"); } [Command("removechannel")] public void RemoveDiscordChannel(Player player, ulong discordChannelID) { bool bSuccess = Integration.DiscordIntegration.RemoveChannelFromListening(discordChannelID); player.SendChatMessage(bSuccess ? "Success" : "No Success"); } [Command("botstatus")] public async void UpdateBotStatusCommand(Player player, string gameName, Discord.ActivityType eActivityType, Discord.UserStatus eUserStatus) { await Integration.DiscordIntegration.UpdateBotStatus(gameName, eActivityType, eUserStatus).ConfigureAwait(true); } } Source code can be found on my github: https://github.com/JeremyEspresso/RAGEMP-DiscordIntegration

    Bugs or feature requests and what not. Just open an issue on the github and I will take a look soon™️.

    613 downloads

       (11 reviews)

    1 comment

    Updated

  3. [C++] L5RP Framework

    I wish to share this framework for ragempcppsdk, that L5RP team has created while we were developing for ragemp. Using C++ for serverside
    This framework worth both on Windows and on Linux operating systems. (Haven't tested it on mac OS).
    This framework contains some additional util features which are not present in cppsdk by default:
    Callable system for parsing command/event/console input/socket input arguments. Script system, which helps developers to split the code into seperate scripts. Some utilities such as Player and Vehicle components to fully utilize script system. Threaded CURL support (Could be used to call api calls in website to load/save server data) Threaded TCP Socket support (Could be used to integrate server with 3rd party applications such as discord bot, live players map and a lot more) (Currently only works on linux) Has been designed with an possibility in mind that rage-mp could die and scripts code could be lifted to other modifications. (Of course integration layer would be needed to be developed, but the thing is that once that would be developed scripts code wouldn't need to change at all) Command and Event system. (Currently its done in a bit weird way, where each player has his own set of commands. But Its not really good time for me to go and refactor one of the core parts of the framework) A lot of small utilites that makes developer's life easier whilst developing on cppsdk. Some bugfixes which are not present in ragemp. Timer/Promise support. (Promise is the same thing as a timer, but only executes once) Threaded Console Input/Output. Console Output being done through spdlog, having different severity levels and being logged into file. Ideas for the future:
    Example gamemode utilizing functions from this framework. Support for multi-language scripts. Some kind of documentation for this framework. In order to download/review this framework please use git: https://gitlab.com/l5rp/l5rp-api
    If you have any suggestions or improvements for this framework feel free to contact me in ragemp discord or in comment section. I'll also be reviewing pull request section from time to time.

    450 downloads

       (3 reviews)

    0 comments

    Updated

  4. [DISCONTINUED] Ajcom

    This library is discontinued and lacks some features. I'm working on a new remote call library which is faster and more secure
    Asynchronous Javascript Communication is a module to allow easy communication between server, client and CEF/browser. This module lets you call server handlers from clients (and vice versa) without dealing with adding and managing custom event handlers.
    You can easily call a handler and get your callback called as soon as everything is returned from the handler in a promise like way! Let's see how it works in action:
    // server side const ajcom = require("./ajcom") ajcom.register("getServerName", hCtx => { return mp.config.name }) // client side const ajcom = require("./[package name]/ajcom.js") mp.events.add("guiReady", () => { ajcom.callServer("getServerName").then((ctx, serverName) => { mp.gui.chat.push(`Welcome to ${serverName} ragemp server!`) }) }) That's all! Not convinced yet? See how the above code is done without ajcom:
    // server side mp.events.add("getServerName", (player) => { player.call("gotServerName", [mp.config.name]) }) // client side mp.events.add("gotServerName", (serverName) => { mp.gui.chat.push(`Welcome to ${serverName} ragemp server!`) }) mp.events.add("guiReady", () => { mp.events.callRemote("getServerName") }) See? It eases the event handling mess. But there's a lot more to ajcom. You can easily handle errors happening on handler's side or any of the callbacks, set delays and other stuff. The full documentation is available here
    Please post your questions and issues to the forum post
    Github repo

    84 downloads

       (2 reviews)

    1 comment

    Updated

  5. [JS] Clientside Polygons API (Dynamic Colshapes!)

    I recently needed a polygons library like this for my gamemode to define some companies, houses, gangzones and other kind of establishments boundaries, so I decided to create this resource previously based on abmn's zone manager, but the code was terrible and I decided to rewrite my own from scratch and improving the functionality.

    Basically you'll be able to create any kind of colshape you want, without worring about combining colshapes to fit your needs, you can just define the points and the height of the shape and it'll be created easily!

    You can set boundaries for houses to move furnitures, for companies to accomplish the job, for mountains in hunting animals scripts and anything else your creativity takes you, just use it!

    Demos

    https://streamable.com/w7l4h6

    https://youtu.be/OxSPcVQrWrY

    Advantages

    The main advantages of using this resource instead of abmn's are:
    These polygons are dynamic, you can modify, move, rotate, basically do anything to the polygon vertices array in real time and it'll work instantaneously, updating the collisions with players. This script is way more optimized and lightweight than the other version. You can choose the color for the lines of the polygon and set them visible or not by just modifying the polygon `visible` property. This script supports different kind of heights for detecting collision (eg.: slopes), it's accurate (may not work as you think it should depending on the slope degree and the polygon height), and supports even colshapes for mountains. You can add more vertex at any time you want to existing polygons, by just pushing a new vector3 position to `polygon.vertices` array.
      API Functions
    /* Creates a new polygon and return it's instance */ mp.polygons.add(vertices: Vector3Mp[], height: number, options = { visible: false, lineColorRGBA: [255,255,255,255], dimension: 0 }): Polygon /* Removes a polygon */ mp.polygons.remove(polygon: Polygon): void /* Check if a polygon exists */ mp.polygons.exists(polygon: Polygon): boolean /* Check if a position is contained within a given polygon */ mp.polygons.isPositionWithinPolygon(position: Vector3Mp, polygon: Polygon): boolean /* Examples */ // Creating a new polygon const polygon = mp.polygons.add([new mp.Vector3(10, 10, 5), new mp.Vector3(15, 15, 5), new mp.vector3(5, 5, 5)], 10, { visible: false, lineColorRGBA: [255,255,255,255], dimension: 0 }); // Set the polygon lines visible polygon.visible = true; // Modifying a polygon height polygon.height = 100; // Modifying a polygon color (RGBA) polygon.lineColorRGBA = [255, 155, 0, 255]; // Modifying a polygon dimension polygon.dimension = 30; /* Events*/ // Event called when player enter a polygon (clientside) mp.events.add('playerEnterPolygon', (polygon) => mp.gui.chat.push(`You entered the polygon ${polygon.id}!`)); // Event called when the local player leaves a polygon (clientside) mp.events.add('playerLeavePolygon', (polygon) => mp.gui.chat.push(`You left the polygon ${polygon.id}.`)); How to install
    Download the zip folder Extract it on your clientside folder Require the index file from the polygons folder. Enjoy it!

    See you on the next release!

    - n0minal

    509 downloads

       (5 reviews)

    0 comments

    Updated

  6. [PHP][Discord] Show Player Count directly in Discord

    In this file I will get you started on how you can use Discord to show your current player count.
     
    First step is to create an application at:
    https://discord.com/developers/applications

    Once created click Bot on the left hand side.
    Click "Add Bot" and then "Yes, do it!"
    Change your Icon to something more pretty
    Click "COPY" underneath "Click to reveal token"
    Open the file in the ZIP.
    Install PHP composer if not already installed.
    Run composer require team-reflex/discord-php
    Edit the example_rage.php file and change the "Discord Token here" to the token you copied earlier
    Change line 17 IP:PORT to your Server IP and Port
    When ready run the file with php -q example_rage.php
    This script must always be running for it to appear on the Discord member section. Therefore I would recommend running Linux Screen and running the php -q command then detaching the screen to run it in the background.
    The script uses the Discord Heartbeat to keep it active within the list. It will also only poll the server after running the heartbeat 5 times which is every 42 seconds.
     
    To set it up with your Discord server you must do the following:
    Take the link you were at to setup your bot - it should look like: https://discord.com/developers/applications/IDHERE/bot
    Where it says IDHERE - take it and insert it here: https://discord.com/api/oauth2/authorize?client_id=IDHERE&scope=bot&permissions=1
    Once this page loads - select your discord server that you are an admin of. 
    This will authorize your bot to submit to your server.
     
    To make your bot appear at the top of the list, simply create a new permission role called Server
    Give it permission to send messages
    Set it a nice colour
    Drag it to the top of your list
    Go to the User that is now in your Member list showing player details and give the role of the server you just created
     
    Have fun!
     

    522 downloads

       (3 reviews)

    2 comments

    Updated

  7. [TypeScript] Client-Framerate library

    This TypeScript library allows you to request the current clientside FPS.
    Licensed under the MIT License (see README.md for more info).
    Sincerely,
    ~Vincent
     
    Used icon: https://www.shareicon.net/screen-monitor-93177

    295 downloads

       (1 review)

    0 comments

    Updated

  8. Attachment Sync (C#)

    Source code : https://github.com/J4YT/RAGE-Multiplayer-Attachment-Sync

    C# Attachment sync for RAGE Multiplayer Server and Client. 
    Equivalent for the Efficient Attachment System made by ragempdev and rootcause
    https://rage.mp/files/file/144-efficient-attachment-sync
    Credits to DasNiels for the server-side Efficient Attachment Sync C#
    https://github.com/DasNiels/EfficientAttachmentSyncCSharp
    It has only been tested on RAGE Multiplayer 1.1
     

    475 downloads

       (3 reviews)

    1 comment

    Updated

  9. Better Clientside Commands

    This resource extends clientside mp.events object to make clientside command handling easier, which means no more splitting strings to use with if/else if or switch/case in playerCommand event
     
    Installing
    Put mp-commands into your server's client_packages directory, then add require('mp-commands'); to client_packages/index.js.
     
    Clientside API
    /** * Adds a clientside command. * @param {string} name Name of the command. * @param {function} handlerFn Function that will run when the command is used. * @throws {TypeError} name argument must be a string. * @throws {TypeError} handlerFn argument must be a function. * @throws {Error} Command with the given name already exists. */ mp.events.addCommand(name, handlerFn); /** * Returns clientside command names. * @return {string[]} */ mp.events.getCommandNames(); /** * Removes a clientside command. * @param {string} name Name of the command to remove. * @return {boolean} */ mp.events.removeCommand(name); /** * Removes all clientside commands. */ mp.events.removeAllCommands(); /** * (v2.0.0) Adds a console command. * @param {string} name Name of the console command. * @param {function} handlerFn Function that will run when the console command is used. * @throws {TypeError} name argument must be a string. * @throws {TypeError} handlerFn argument must be a function. * @throws {Error} Console command with the given name already exists. */ mp.console.addCommand(name, handlerFn); /** * (v2.0.0) Returns console command names. * @return {string[]} */ mp.console.getCommandNames(); /** * (v2.0.0) Removes a console command. * @param {string} name Name of the console command to remove. * @return {boolean} */ mp.console.removeCommand(name); /** * (v2.0.0) Removes all console commands. */ mp.console.removeAllCommands();  
    Example
    /* Looks like it's serverside code but it's not, updates GTA V's cash display. Usage: /updmoney [amount] */ mp.events.addCommand("updmoney", function (amount) { amount = Number(amount); if (!Number.isInteger(amount)) { mp.gui.chat.push("Invalid amount."); return; } mp.game.stats.statSetInt(mp.game.joaat("SP0_TOTAL_CASH"), amount, false); }); mp.events.addCommand("cmds", function () { mp.gui.chat.push(`Commands: ${mp.events.getCommandNames().join(", ")}`); });  
    Example (Console)
    NOTE: Console is a RAGE Multiplayer 1.1 feature, which means code below won't work on stable/prerelease/0.3.7 branch.
    // Write "hat 123 0" to the console and press enter to give yourself a cool helmet. mp.console.addCommand("hat", function (drawable, texture = 0) { drawable = Number(drawable); texture = Number(texture); if (!Number.isInteger(drawable) || !Number.isInteger(texture)) { mp.console.logError("Invalid drawable/texture."); return; } if (drawable < 0) { mp.players.local.clearProp(0); } else { mp.players.local.setPropIndex(0, drawable, texture, true); } }); // Write "cmds" to the console to see available console commands. mp.console.addCommand("cmds", function() { mp.console.logInfo(`Console commands: ${mp.console.getCommandNames().join(", ")}`); });  
    Notes
    I recommend loading mp-commands as the first script in client_packages/index.js so the functions become available in other scripts. Command names are case sensitive.

    1194 downloads

       (4 reviews)

    0 comments

    Updated

  10. Blip Info API

    This resource adds the blip information feature that exists for (mainly) adversary modes in GTA Online.
     
    Installing
    Put the files you downloaded in their respective places Add require('blip-info') to client_packages/index.js All done  
    API (Clientside)
    This library extends the mp.Blip prototype so these functions are available for every blip created using mp.blips.new.
    /** * Attaches data to the blip. * It's recommended that you use the BlipInfoBuilder class that comes with the library to build the info object. */ blipMp.setInfo(infoObject); /** * Removes the data attached to the blip. */ blipMp.resetInfo(); BlipInfoBuilder isn't documented here but it has JSDoc comments, the example script shows how it can be used as well.
     
    Example Script
    const BlipInfoBuilder = require("./blip-info/BlipInfoBuilder"); // example blip data const garageData = [ { name: "Garage: 0120 Murrieta Heights", description: "With good access to the major roadways in and out of Los Santos, this spacious garage is perfect for the man or woman who might need to leave town in a hurry. Or is obsessed with cars.", position: new mp.Vector3(963.4199, -1022.1301, 39.8475), textureDict: "dyn_mp_24", textureName: "dyn_mp_24", slots: 10, price: 150000 }, { name: "Garage: Unit 14 Popular St", description: "If you're an individual who likes to keep their business private, look no further than this secluded garage in East Los Santos.", position: new mp.Vector3(895.9359, -888.7846, 26.2485), textureDict: "dyn_mp_25", textureName: "dyn_mp_25", slots: 6, price: 77500 }, { name: "Garage: Unit 2 Popular St", description: "Spacious garage in prime East Los Santos. Panoramic views of urban blight, walking distance to gang members.", position: new mp.Vector3(817.4532, -924.8551, 25.2430), textureDict: "dyn_mp_26", textureName: "dyn_mp_26", slots: 10, price: 142500 }, { name: "Garage: 331 Supply St", description: "Newly renovated garage with excellent square footage and direct road access. What better place to keep brand-new vehicles than the neighborhood with the highest crime rate in Los Santos?", position: new mp.Vector3(759.2387, -755.3151, 25.9151), textureDict: "dyn_mp_27", textureName: "dyn_mp_27", slots: 10, price: 135000 }, { name: "Garage: Unit 1 Olympic Fwy", description: "A good-sized garage in a quiet location within walking distance of the train for those days when you feel extra guilty about your 6-car carbon footprint.", position: new mp.Vector3(842.1298, -1165.0754, 24.3046), textureDict: "dyn_mp_28", textureName: "dyn_mp_28", slots: 6, price: 70000 }, { name: "Garage: 0754 Roy Lowenstein Blvd", description: "Located just a few brain-melting steps away from an electrical substation, you'll never have to worry losing power or reaching old age again at this garage in East Los Santos.", position: new mp.Vector3(528.8805, -1603.0293, 28.3225), textureDict: "dyn_mp_29", textureName: "dyn_mp_29", slots: 2, price: 29500 }, { name: "Garage: 12 Little Bighorn Ave", description: "Affluent on the inside, effluent on the outside! This garage offers panoramic views of the Los Santos waterways.", position: new mp.Vector3(569.9441, -1570.2930, 27.5777), textureDict: "dyn_mp_30", textureName: "dyn_mp_30", slots: 2, price: 32000 }, { name: "Garage: Unit 124 Popular St", description: "Calling all bargain hunters! In today's economy, it's all about desirable properties in undesirable areas. East Los Santos? We prefer to call it 'South of Vinewood'! Plus if the economy keeps tanking, you can go live in it!", position: new mp.Vector3(727.7570, -1189.8367, 23.2765), textureDict: "dyn_mp_31", textureName: "dyn_mp_31", slots: 2, price: 25000 } ]; const seaRaceData = [ { name: "Los Santos Port", position: new mp.Vector3(621.7491, -2136.7981, 0.0), textureDict: "spsearaces", textureName: "lossantos", recordTime: "01:23.456", recordHolder: "sea_racing_pro" }, { name: "El Gordo", position: new mp.Vector3(3447.7471, 5192.9956, 0.0), textureDict: "spsearaces", textureName: "southcoast", recordTime: "00:00.123", recordHolder: "speed0fl1ght" }, // lets say this one doesn't have a record yet { name: "Power Station", position: new mp.Vector3(3063.1135, 639.8550, 0.0), textureDict: "spsearaces", textureName: "northcoast" }, // this one doesn't have a record yet as well and has a cash bonus { name: "Lago Zancudo", position: new mp.Vector3(198.1107, 3620.3972, 27.3487), textureDict: "spsearaces", textureName: "canyon", cashMultiplier: 2.5 } ]; // event handlers function onLocalPlayerReady() { // example 1: garage blips for (const garage of garageData) { // request the texture dict mp.game.graphics.requestStreamedTextureDict(garage.textureDict, false); // create the blip garage.blip = mp.blips.new(369, garage.position, { shortRange: true }); // set garage info (using plain object) garage.blip.setInfo({ // header title: garage.name, textureDict: garage.textureDict, textureName: garage.textureName, // data components: [ { type: 0, title: "Capacity", value: `${garage.slots} vehicles` }, { type: 0, title: "Price", value: `~g~$${garage.price}` }, { type: 4 }, { type: 5, value: garage.description } ] }); // with BlipInfoBuilder it'd look like this: /* const info = new BlipInfoBuilder() .setTitle(garage.name) .setTexture(garage.textureDict, garage.textureName) .addComponent("Capacity", `${garage.slots} vehicles`) .addComponent("Price", `~g~$${garage.price}`) .addDividerComponent() .addDescriptionComponent(garage.description) .build(); garage.blip.setInfo(info); */ } // example 2: sea races mp.game.graphics.requestStreamedTextureDict("spsearaces", false); for (const race of seaRaceData) { // create the blip race.blip = mp.blips.new(316, race.position, { shortRange: true }); // set race info (using BlipInfoBuilder) const info = new BlipInfoBuilder() .setTitle(race.name) .setTexture(race.textureDict, race.textureName) .addComponentWithIcon("Type", "Sea Race", 13, 1, false); if (race.cashMultiplier) { info.setCashText(`${race.cashMultiplier}x`); } if (race.recordHolder && race.recordTime) { info.addComponentWithPlayerName("Record Holder", race.recordHolder); info.addComponent("Record Time", race.recordTime); } race.blip.setInfo(info.build()); } } function onLocalPlayerQuit(player) { if (player !== mp.players.local) { return; } // garage clean up for (const garage of garageData) { // unload the texture mp.game.graphics.setStreamedTextureDictAsNoLongerNeeded(garage.textureDict); // remove blip if (garage.blip) { garage.blip.resetInfo(); garage.blip.destroy(); } } // sea race clean up // unload the texture mp.game.graphics.setStreamedTextureDictAsNoLongerNeeded("spsearaces"); // remove blips for (const race of seaRaceData) { if (race.blip) { race.blip.resetInfo(); race.blip.destroy(); } } } // register event handlers mp.events.add({ "playerReady": onLocalPlayerReady, "playerQuit": onLocalPlayerQuit });  
    Credits
    glitchdetector - for their research  
    Source code is also available on GitHub: https://github.com/root-cause/ragemp-blip-info

    76 downloads

       (1 review)

    0 comments

    Submitted

  11. Blood VFX

    Requires RAGE Multiplayer 1.1.0 and above.
    If you ever played the missions "Grass Roots - Michael" and "Grass Roots - Trevor", you'll remember these missions had special particle effects. This resource allows you to use those particle effects on your server.
     
    Installing
    Put BloodVfx.js into your server's client_packages directory, then add require('BloodVfx'); to client_packages/index.js.
     
    API (Clientside)
    /* This resource adds "bloodVfxMode" property to the mp.game.graphics object. Blood VFX modes: - VFX_MODE_DEFAULT = 0 - VFX_MODE_ALIEN = 1 - VFX_MODE_CLOWN = 2 - Invalid modes will be treated as VFX_MODE_DEFAULT. */ mp.game.graphics.bloodVfxMode  
    Example
    const KEY_F2 = 0x71; const KEY_F3 = 0x72; const KEY_F4 = 0x73; const VFX_MODE_DEFAULT = 0; const VFX_MODE_ALIEN = 1; const VFX_MODE_CLOWN = 2; // Pressing F2 will enable alien blood VFX. mp.keys.bind(KEY_F2, false, () => { mp.game.graphics.bloodVfxMode = VFX_MODE_ALIEN; }); // Pressing F3 will enable clown blood VFX. mp.keys.bind(KEY_F3, false, () => { mp.game.graphics.bloodVfxMode = VFX_MODE_CLOWN; }); // Pressing F4 will disable active blood VFX. mp.keys.bind(KEY_F4, false, () => { mp.game.graphics.bloodVfxMode = VFX_MODE_DEFAULT; });  
    Notes
    RAGEMP does not disable alien/clown blood VFX between sessions. (might change in the future) Meaning if you're playing on serverA that has clown blood VFX enabled and connect to serverB using the F1 menu, you'll still have clown blood VFX.  
    Source code is available on GitHub Gist in case you don't want to download: https://gist.github.com/root-cause/49e7b1601d531bb4c8ba18489ff6731c

    119 downloads

       (2 reviews)

    1 comment

    Updated

  12. camerasManager

    This is a tool for using cameras.
    ONLY CLIENTSIDE;
    Using: 
    const camerasManager = require('./camerasManager.js'); //creating camera /** @param {String} - camera name @param {String} - type camera @param {Vector3} - position @param {Vector3} - rotation @param {Number} - fov */ const kemperrr_camera = camerasManager.createCamera('kemperrr_the_best?', 'default', new mp.Vector3(0, 0, 100), new mp.Vector3(), 50); //destroy camera /** @param {Camera} - destroyed camera */ camerasManager.destroyCamera(kemperrr_camera); //get camera by name /** @param {String} camera name */ const kemperrr_camera = camerasManager.getCamera('kemperrr_the_best?'); //activate camera /** @param {Camera} - camera to activate @param {Boolean} - toggle */ camerasManager.setActiveCamera(kemperrr_camera, true); //deactivate camera /** @param {Camera} - camera to activate @param {Boolean} - toggle */ camerasManager.setActiveCamera(kemperrr_camera, false); //activate with interpolation /** @param {Camera} - camera to activate @param {Vector3} - where the camera will fly @param {Vector3} - New camera rotation @param {Number} - The time for which the camera will fly by @param {Number} - hz @param {Number} - hz */ camerasManager.setActiveCameraWithInterp(kemperrr_camera, new mp.Vector3(100, 200, 100), new mp.Vector3(0, 0, 90), 5000, 0, 0); //get gameplay camera const gameplayCamera = camerasManager.gameplayCam; mp.game.notify(JSON.stringify(gameplayCamera.getDirection())); //get current active camera const activeCamera = camerasManager.activeCamera; mp.game.notify(JSON.stringify(activeCamera.getCoord())); //events //an event is triggered when any camera starts interpolating camerasManager.on('startInterp', (camera) => { mp.game.notify(JSON.stringify(camera.getCoord())); }); //the event is triggered when any camera has completed interpolation camerasManager.on('stopInterp', (camera) => { mp.game.notify(JSON.stringify(camera.getCoord())); });

    680 downloads

       (1 review)

    0 comments

    Updated

  13. cefManager

    A library to easier manage CEF windows.
    Creating a CEF Window
    Function is based on Promise because I need this in my own resources. Promise return a CEF window object.
    cef window name (string)
    url (string)
    parameters to exec (array) - take a look on Executing a function into a CEF Window for parameters
    cefManager.createCef(cef window name, url, parametersToExec).then(cef => {}) cefManager.createCef('hud', 'package://rage/browsers/hud/index.html').then(cef => {}) Executing a function into a CEF Window
    Again function is based on Promise but returns nothing.
    cef window name (string)
    [function name (string), args how much you need(number, string, boolean etc.)]
    cefManager.executeCef(cef window name, [function name, args]).then(() => {}) cefManager.executeCef('hud', ['console.log', mp.players.length]).then(() => {}) Checking if CEF with name exists
    cef window name (string)
    cefManager.existsCef(cef window name) const exists = cefManager.existsCef('hud') Get CEF window object
    cef window name (string)
    cefManager.getCef(cef window name) const cef = cefManager.getCef('hud') Get CEF window current URL
    cef window name (string)
    cefManager.getCurrentCefURL(cef window name) const url = cefManager.getCurrentCefURL('hud') Get CEF window URL which was set in creating CEF window
    cef window name (string)
    cefManager.getCefURL(cef window name) const url = cefManager.getCefURL('hud') Reload CEF window
    Again Promise
    cef window name (string)
    ignore cache (boolean) - true to ignore cache (Browser::reload)
    cefManager.reloadCef(cef window name, ignore cache) cefManager.reloadCef('hud', true).then(() => {})  
     
    ps. no support from me for this library, if something works bad fix it.

    137 downloads

       (0 reviews)

    0 comments

    Updated

  14. Colshape Handler

    Simple CommonJS singleton module to handle colshape entering and exiting.
    Copy the Colshapes folder inside packages inside your packages folder. See the Examples folder for an example.
    Simply create your colshape like this:
    const colshape = mp.colshapes.newSphere(34, 15, 69, 15, 0) colshape.name = 'example' and then pull in the colshapeHandler singleton to add it to the array the following:
    const colshapeHandler = require('../Colshapes/index').getInstance() colshapeHandler.addColshape('example') If a player enters the specified colshape, the colshape name will be pushed towards a colshapes array as a player property, like this. Definition of this is inside the "playerJoin" event in the Colshapes\index.js. The specified colshape name will then be removed from the array again if the player exits the colshape.
     
    player.colshapes = [];  

    83 downloads

       (0 reviews)

    0 comments

    Submitted

  15. Currency API

    This resource provides a currency API to server developers.
    This resource will not save anything on its own. I'd also recommend you to not have over 2 billion of any currency.
     
    Installing
    Put the files you downloaded in their respective places Check the documentation and examples All done  
    Currency API
    const currencyAPI = require("../currency-api");  
    /** * Adds a currency to the system. * @param {String} key Currency identifier. (such as vip_tokens) * @param {String} name Currency's human readable name. (such as VIP Tokens) * @param {Number} syncType Sharing type of the currency. (0 = not shared with clients, 1 = shared with everyone, 2 = shared with just the wallet owner) * @return {Object} The added currency object. * @fires currencyDefined */ currencyAPI.addCurrency(key, name, syncType); /** * Returns whether the specified key is a registered currency or not. * @param {String} key Currency identifier. * @return {Boolean} */ currencyAPI.hasCurrency(key); /** * Returns the specified currency's object. * @param {String} key Currency identifier. * @return {?Object} The currency object, will be undefined if the key isn't registered. */ currencyAPI.getCurrency(key); /** * Returns an iterator of all registered currency identifiers. * @return {Iterator.<String>} */ currencyAPI.getAllCurrencies(); /** * Returns the human readable name of the specified currency. * @param {String} key Currency identifier. * @return {String} Human readable name, will be "Invalid Currency" if the key isn't registered. */ currencyAPI.getCurrencyName(key); /** * Returns the sync type of the specified currency. * @param {String} key Currency identifier. * @return {Number} Sync type of the currency. (0 = not shared with clients, 1 = shared with everyone, 2 = shared with just the wallet owner) */ currencyAPI.getCurrencySyncType(key); /** * Returns the sync key of the specified currency. Sync key is used with player.setVariable() * @param {String} key Currency identifier. * @return {?String} Sync key of the currency, will be null if the key isn't registered. */ currencyAPI.getCurrencySyncKey(key);  
    Currency API Events
    /** * currencyDefined * This event is called when a currency is added to the system with currencyAPI.addCurrency * @param {String} key Currency identifier. * @param {String} name Human readable name of the currency. * @param {Number} syncType Sharing type of the currency. (0 = not shared with clients, 1 = shared with everyone, 2 = shared with just the wallet owner) * @param {String} syncKey If the currency is shared, this string will be used with player.setVariable() or player.setOwnVariable() to transfer data to clientside. */ currencyAPI.on("currencyDefined", (key, name, syncType, syncKey) => { // Your code here }); /** * walletReplaced * This event is called when a player's wallet object gets replaced by player.setWallet() * @param {Player} player The player who had a wallet change. * @param {Object} oldWallet Old wallet object of the player. * @param {Object} newWallet New wallet object of the player. */ currencyAPI.on("walletReplaced", (player, oldWallet, newWallet) => { // Your code here }); /** * currencyUpdated * This event is called when a player's wallet has a currency change. * @param {Player} player The player who had a currency change. * @param {String} currencyKey Currency identifier. * @param {Number} oldAmount The player's old amount of currency. * @param {Number} newAmount The player's new amount of currency. * @param {String} source Name of the function that triggered this update, will either be "setCurrency" or "changeCurrency". */ currencyAPI.on("currencyUpdated", (player, currencyKey, oldAmount, newAmount, source) => { // Your code here });  
    Player API
    /** * Returns the wallet object of the player. * @return {Object} */ player.getWallet(); /** * Replaces the wallet object of the player with the specified one. * @param {Object} newWallet * @return {Boolean} True if successful, false otherwise. * @fires walletReplaced */ player.setWallet(newWallet); /** * Returns the amount of specified currency the player has in their wallet. * @param {String} currencyKey Currency identifier. * @return {Number} */ player.getCurrency(currencyKey); /** * Sets the amount of specified currency the player has in their wallet. * @param {String} currencyKey Currency identifier. * @param {Number} newAmount New amount of specified currency. * @return {Boolean} True if successful, false otherwise. * @fires currencyUpdated */ player.setCurrency(currencyKey, newAmount); /** * Changes the amount of specified currency the player has in their wallet by specified amount. * @param {String} currencyKey Currency identifier. * @param {Number} amount * @return {Boolean} True if successful, false otherwise. */ player.changeCurrency(currencyKey, amount);  
    Examples
    Full Test Script, will update GTAV money hud if you give yourself "cash" currency. (Used during development)
    // SERVERSIDE CODE const currencyAPI = require("../currency-api"); const SYNC_TYPE_NONE = 0; const SYNC_TYPE_EVERYONE = 1; const SYNC_TYPE_PLAYER = 2; // Events currencyAPI.on("currencyDefined", (key, name, syncType, syncKey) => { const syncTypes = ["none", "everyone", "player"]; console.log(`Currency defined, key: ${key} | name: ${name} | syncType: ${syncTypes[syncType]} | syncKey: ${syncKey}`); }); currencyAPI.on("walletReplaced", (player, oldWallet, newWallet) => { console.log("=============================="); console.log(`${player.name} had their wallet replaced.`); console.log(`Old wallet currencies: ${Object.keys(oldWallet).join(",")}`); console.log(`New wallet currencies: ${Object.keys(newWallet).join(",")}`); console.log("=============================="); }); currencyAPI.on("currencyUpdated", (player, currencyKey, oldAmount, newAmount, source) => { const diff = newAmount - oldAmount; console.log(`${player.name} ${diff < 0 ? "lost" : "got"} ${Math.abs(diff)} ${currencyAPI.getCurrencyName(currencyKey)} (${currencyKey}). (caused by: ${source})`); }); // Register currencies currencyAPI.addCurrency("cash", "Money", SYNC_TYPE_PLAYER); // So that we can use currency_cash shared variable on clientside currencyAPI.addCurrency("vip_tokens", "VIP Currency", SYNC_TYPE_NONE); // Test commands const fs = require("fs"); const path = require("path"); // Do /savewallet to save your wallet to a JSON file. (file path will be printed to console) mp.events.addCommand("savewallet", (player) => { const saveDir = path.join(__dirname, "wallets"); if (!fs.existsSync(saveDir)) fs.mkdirSync(saveDir); const playerPath = path.join(saveDir, `${player.socialClub}.json`); fs.writeFileSync(playerPath, JSON.stringify(player.getWallet(), null, 2)); player.outputChatBox("Wallet saved."); console.log(`Player ${player.name} saved their wallet. (${playerPath})`); }); // Do /loadwallet to load your wallet from a JSON file. mp.events.addCommand("loadwallet", (player) => { const playerPath = path.join(__dirname, "wallets", `${player.socialClub}.json`); if (fs.existsSync(playerPath)) { player.setWallet(JSON.parse(fs.readFileSync(playerPath))); player.outputChatBox("Wallet loaded."); } else { player.outputChatBox("Wallet file not found."); } }); // Do /mytokens to see your VIP tokens currency amount. mp.events.addCommand("mytokens", (player) => { player.outputChatBox(`Your VIP tokens: ${player.getCurrency("vip_tokens")}`); }); // Do /wallet to list the currencies you have. mp.events.addCommand("wallet", (player) => { const wallet = player.getWallet(); player.outputChatBox("Your wallet:"); for (const [key, value] of Object.entries(wallet)) player.outputChatBox(`${currencyAPI.getCurrencyName(key)}: ${value}`); }); // Do /setcurrency [key] [amount] to set your currency amount. mp.events.addCommand("setcurrency", (player, _, currencyKey, amount) => { amount = Number(amount); if (player.setCurrency(currencyKey, amount)) { player.outputChatBox(`Set ${currencyAPI.getCurrencyName(currencyKey)} (${currencyKey}) to ${amount}.`); } else { player.outputChatBox("Failed to set currency."); } }); // Do /changecurrency [key] [amount] to change your currency amount by specified value. mp.events.addCommand("changecurrency", (player, _, currencyKey, amount) => { amount = Number(amount); if (player.changeCurrency(currencyKey, amount)) { player.outputChatBox(`${currencyAPI.getCurrencyName(currencyKey)} (${currencyKey}) changed by ${amount}.`); } else { player.outputChatBox("Failed to change currency."); } }); // Do /currencies to get all registered currency identifiers and their names. mp.events.addCommand("currencies", (player) => { for (const key of currencyAPI.getAllCurrencies()) { player.outputChatBox(`${key} - Name: ${currencyAPI.getCurrencyName(key)}`); } }); // CLIENTSIDE CODE mp.events.addDataHandler("currency_cash", (entity, value) => { if (entity.handle === mp.players.local.handle) { mp.game.stats.statSetInt(mp.game.joaat("SP0_TOTAL_CASH"), value, false); mp.gui.chat.push(`(clientside) currency_cash updated, new value: ${value}`); } }); Source code is available on GitHub in case you don't want to download: https://github.com/root-cause/ragemp-currency-api
    Thanks to Lorc for providing the resource icon: https://game-icons.net/1x1/lorc/cash.html

    1451 downloads

       (5 reviews)

    0 comments

    Updated

  16. Custom chat

    This is a simple example of using a custom chat in RAGE MP.
    You can set time of hide chat from chat.js:
    hide_chat: 15000 // in milliseconds  

    3649 downloads

       (4 reviews)

    0 comments

    Updated

  17. Custom Sound CEF

    Simple CEF to play custom mp3's in the background. The CEF autodestroys after the sound has finished to not use our beloved PC resources.
     
    Copy client_packages and packages content in their respective directory, then import them.
    You can put your mp3's inside client_packages/Sound/sounds/ and trigger them with their filename. Only mp3 is supported right now, although ogg works as well, it's easily exchangeable and/or extensible to allow for both.
    As of right now, you can play a sound with the "/playsound NAME" command. You can use this as you want, this is only a barebones example to show how it works.
    I have not experimented when it comes to max sound length / filesize. I'd like to know though

    760 downloads

       (1 review)

    3 comments

    Submitted

  18. DavWebCreator

    DavWebCreator
    DavWebCreator is a C# class 'library' which provides you the possibility to generate HTML structures with according styles and logic behind each element.
    There are already plenty of examples online here: https://DavWebCreator.com
    But anyway I will provide you here at least one example 🙂
    Compatible with 1.1.0.0
     
    If you want to report a bug or just want some help join my discord: https://discord.gg/JYNDrSh
     
    Preview

     
    Code behind:
    [Command("yesno")] public void YesNoDialogExample(Client player) { // Generate the Browser Browser browser = new Browser("YesNoDialog", BrowserType.Custom, BrowserContentAlign.Center, "520px", "100%"); // Create the dialog. (Most of the elements will get a default value) var yesNoDialog = browser.GetYesNoDialog("YES_NO_EXAMPLE", "Character Deletion", "WARNING", "Do you really want to delete your character?", "Yes", "No"); // Customize for example the font size and the margin. yesNoDialog.Card.ContentTitle.FontSize = "30px"; yesNoDialog.Card.Margin = "33% 0 0 0"; // Add to the browser browser.AddYesNoDialog(yesNoDialog); // Finally open the browser for the desire player. browser.OpenBrowser(player); } //This event will be called when a button was clicked. [RemoteEvent("YES_NO_EXAMPLE")] public void YesNoExample(Client player, params object[] args) { if (args == null) return; // This is just a list of reponses. (You can bind for example 3 textboxes to a button and when someone click on that button, all 3 binded textboxes will be in the response, with their hidden values. List<BrowserEventResponse> responses = JsonConvert.DeserializeObject<List<BrowserEventResponse>>(args[0].ToString()); // For some reason we know that a YesNoDialog only gives you one response, because only the clicked button will be returned. BrowserEventResponse buttonResponse = responses[0]; player.SendChatMessage(buttonResponse.Value + " Clicked"); player.SendChatMessage(buttonResponse.HiddenValue + " This is our secret hidden value. e.g. some id"); // Close the browser player.TriggerEvent("CLOSE_BROWSER"); // Do stuff }  
    Installation
    Download the .rar Open the "DavWebCreator_Installation.rar" and open the directory called "DavWebCreator_GetStarted". Open the directory "Server Resources" and Copy and paste the directory "DavWebCreator" in to your"Visual Studio" server project. Go back to the directory called "DavWebCreator_GetStarted". Now open the directory "Client Resources" and Copy and paste the directory "DavWebCreator" in to your "Visual Studio" client project. Your solution should now look like this.

          6. Go back to the directory called"DavWebCreator_GetStarted".
          7. Now open the directory "Client Frontend" and copy and paste the directory "DavWebCreator" in to your RageMp "client_packages" directory.
     
    This is how it should look now:

    Done. Lets start with some examples…
    The project stays under the MIT license, feel free to contribute: https://github.com/davidowiz/DavWebBrowser 🙂
    Maybe the installation procedure will be improved. But as you all now, time is limited.
    Best regards,
    Davidowiz

    226 downloads

       (3 reviews)

    0 comments

    Updated

  19. Death Screen with Loading | Only HTML / CSS Design

    This is a Death-Screen Loading-Screen, its only a design. maked with html and css,
    you must script it on your server.
     
    If your Server has more than 100 registered players, than you must make a link with my rage.mp profile on your website.

    854 downloads

       (2 reviews)

    0 comments

    Updated

  20. Efficient Attachment Sync

    Most of the server developers (ones that don't patiently wait for *something large*, though this resource is powerful enough) use their own server-side object attachments implementation that represents some large JSON with all the object and attachment information. This resource lets you cache "static attachments" in the client-side code so thanks to efficient utilization of the shared data it just uses a small shared variable to do the attachment processing without any need to create server-side objects nor send its data.
     
    For example, if you want to attach a specific object to specific ped bone with spefic bone offset and object rotation, this will only use a ~4-8 byte shared variable keeping it accurate. User-made implementations I have seen before usually take ~100 bytes per an object.
     
    API: Client-side
    mp.attachmentMngr.register(attachmentId, model, bone, offset, rotation) mp.attachmentMngr.addLocal(attachmentId) (synced!) mp.attachmentMngr.removeLocal(attachmentId) (synced!)  
    API: Server-side
    player.addAttachment(attachmentId, remove) player.hasAttachment(attachmentId)  
    Example Resource
    There's an example resource in /client-packages/epic-attachments folder. It lets you toggle attachments (there are like 30 attachments) using a NativeUI-based menu. Thanks to root for his contributions made to the example resource.
     
     
     

    4039 downloads

       (14 reviews)

    7 comments

    Updated

  21. Fake Pickups

    Requires RAGE Multiplayer 1.1.0 and above.
    This resource adds the ability to create classic GTA style pickups we all love.
     
    Installing
    Put the files you downloaded in their respective places Add require('fake-pickups') to client_packages/index.js All done  
    Serverside API
    Global mp object extension:
    // Properties /* Returns the amount of existing pickups. */ mp.fakePickups.length; // Functions /* Creates a pickup. * model - Model name or hash, such as prop_armour_pickup. * position - Position of the pickup, recommended: mp.Vector3 instance * pickupRange - Collection range of the pickup. * respawnTime - Respawn time of the pickup after collection, values less than 1 will disable respawning of the pickup. * dimension - Dimension of the pickup. */ mp.fakePickups.new(model, position, pickupRange, respawnTime, dimension = 0); /* Returns the pickup instance with specified ID. */ mp.fakePickups.at(id); /* Returns whether a pickup with specified ID exists. */ mp.fakePickups.exists(id); /* Returns an array of existing pickups. */ mp.fakePickups.toArray();  
    FakePickup class:
    // Properties /* ID of the pickup, read only. */ instance.id; /* Model hash of the pickup, read only. */ instance.model; /* Position of the pickup, read only. */ instance.position; /* Collection range of the pickup, read only. */ instance.pickupRange; /* Respawn time of the pickup, can be changed. */ instance.respawnTime; /* Light data of the pickup, read only. */ instance.lightData; /* Whether the pickup is collected, read only. */ instance.isCollected; /* Dimension of the pickup, can be changed. */ instance.dimension; // Functions /* Allows you to set light data of the pickup, argument names should be obvious. If you want to remove the pickup's light, use resetLightData instead of this function with weird values. */ instance.setLightData(red, green, blue, range, intensity, shadow); /* Resets light data of the pickup. */ instance.resetLightData(); /* Respawns the pickup. (if collected) */ instance.respawn(); /* Destroys the pickup. */ instance.destroy();  
    Events:
    /* fakePickupSpawn is called when a pickup's prop is created. (Basically when it's created and respawned) */ mp.events.add("fakePickupSpawn", (pickup) => { // code here }); /* playerCollectFakePickup is called when a player collects a pickup. This event is cancelable. (Check example script) */ mp.events.add("playerCollectFakePickup", (player, pickup, cancel) => { // code here });  
    Example Script
    // setLightData calls are optional and you don't have to use them, just makes the pickups stand out at night time. const moneyPickup = mp.fakePickups.new("ex_prop_exec_cashpile", new mp.Vector3(1571.681, 3163.909, 40.331), 1.0, 5000); moneyPickup.setLightData(114, 204, 114, 2.0, 2.5, 15.0); const healthPickup = mp.fakePickups.new("prop_ld_health_pack", new mp.Vector3(1568.648, 3166.397, 40.331), 1.0, 5000); healthPickup.setLightData(53, 154, 71, 2.0, 2.5, 15.0); const armorPickup = mp.fakePickups.new("prop_armour_pickup", new mp.Vector3(1567.359, 3169.639, 40.331), 1.0, 5000); armorPickup.setLightData(93, 182, 229, 2.0, 2.5, 15.0); const weaponPickup = mp.fakePickups.new("w_mg_combatmg", new mp.Vector3(1569.465, 3172.773, 40.331), 1.0, 5000); weaponPickup.setLightData(255, 133, 85, 2.0, 2.5, 15.0); // You're better off using custom properties with your pickup instance, this code is for testing purposes. mp.events.add("playerCollectFakePickup", (player, pickup, cancel) => { if (pickup === moneyPickup) { player.outputChatBox("You picked up some money."); } else if (pickup === healthPickup) { if (player.health >= 75) { player.outputChatBox("You're just fine, no need to waste a health pack."); // Doing cancel.cancel = true; prevents the pickup from being marked as collected. cancel.cancel = true; return; } player.health = 100; player.outputChatBox("Health refilled."); } else if (pickup === armorPickup) { if (player.armour > 0) { player.outputChatBox("You already have armor."); // Doing cancel.cancel = true; prevents the pickup from being marked as collected. cancel.cancel = true; return; } player.armour = 100; player.outputChatBox("You picked up some armor."); } else if (pickup === weaponPickup) { player.giveWeapon(mp.joaat("weapon_combatmg"), 9999); player.outputChatBox("You picked up Combat MG."); } }); mp.events.add("fakePickupSpawn", (pickup) => { switch (pickup.model) { case mp.joaat("ex_prop_exec_cashpile"): mp.players.broadcast("The money pickup has respawned."); break; case mp.joaat("prop_ld_health_pack"): mp.players.broadcast("The health pickup has respawned."); break; case mp.joaat("prop_armour_pickup"): mp.players.broadcast("The body armor pickup has respawned."); break; case mp.joaat("w_mg_combatmg"): mp.players.broadcast("The Combat MG pickup has respawned."); break; } });  
    Source code is available on GitHub in case you don't want to download: https://github.com/root-cause/ragemp-fake-pickups

    242 downloads

       (6 reviews)

    0 comments

    Updated

  22. Glowing Players

    Requires RAGE Multiplayer 1.1.0 and above.
    This resource allows you to apply a glowing effect to players.
     
    Installing
    Put the files you downloaded in their respective places Add require('playerglow') to client_packages/index.js All done  
    API (Serverside)
    /** * Sets the glow color of a player. * @param {Number} red * @param {Number} green * @param {Number} blue */ player.setGlowColor(red, green, blue); /** * Gets the glow color of a player. * @return {Object} Glow color, will be null if the player doesn't have one. */ player.getGlowColor(); /** * Disables the glowing effect of a player. */ player.resetGlowColor();  
    Example
    mp.events.addCommand("setglow", (player, _, red, green, blue) => { player.setGlowColor(Number(red), Number(green), Number(blue)); }); mp.events.addCommand("getglow", (player) => { player.outputChatBox(`Current glow color: ${JSON.stringify(player.getGlowColor())}`); }); mp.events.addCommand("resetglow", (player) => { player.resetGlowColor(); });  
    Notes
    The effect is not really noticeable during daytime. If you have glowing players in your stream range and reconnect via F1 menu, their particle effect(s) will stay there until GTAV is restarted. This is because of particle handles being lost during reconnection and since they aren't managed by RAGEMP, they won't get removed.  
    Source code is available on GitHub in case you don't want to download: https://github.com/root-cause/ragemp-player-glow

    160 downloads

       (5 reviews)

    0 comments

    Submitted

  23. GTA V: Web Fonts

    Here is the .woff version of the fonts of GTA 5 i could find on their website.

    220 downloads

       (1 review)

    0 comments

    Updated

  24. Headblend Palette Color Sync

    This resource adds serverside API to set head blend palette colors. Head blend palette colors are used for crew colored clothing in GTA Online. (example here)
     
    Installing
    Put the files you downloaded in their respective places Add require('palette-sync') to client_packages/index.js All done  
    API (Serverside)
    This resource adds 4 functions to the mp.Player prototype:
    /** * Sets the specified head blend palette color for the player. **Make sure `player.setCustomization` is called beforehand to avoid issues.** * @param {number} paletteIndex * @param {number} red * @param {number} green * @param {number} blue * @throws If `paletteIndex` is less than 0 or higher than 3. * @throws If `red`, `green` or `blue` is not an integer between 0 to 255. */ player.setHeadBlendPaletteColor(paletteIndex, red, green, blue); /** * Sets the head blend palette colors for the player. This function should be used to update multiple palette colors at once. **Make sure `player.setCustomization` is called beforehand to avoid issues.** * @param {Array<[number, number, number, number]>} colors 2-dimensional array where each element has palette index, red, green and blue color data such as `[[0, 255, 0, 0], [3, 0, 255, 0]]`. * @throws If `colors` is not an array. * @throws If any `paletteIndex` is less than 0 or higher than 3. * @throws If any `red`, `green` or `blue` is not an integer between 0 to 255. */ player.setHeadBlendPaletteColors(colors); /** * Returns the specified head blend palette color for the player. * @param {number} paletteIndex * @throws If `paletteIndex` is less than 0 or higher than 3. * @returns {Object} An object with `red`, `green` and `blue` properties, ranging from 0 to 255. */ player.getHeadBlendPaletteColor(paletteIndex); /** * Returns the head blend palette colors for the player. * @returns {Array<Object>} An array of objects where each element has `red`, `green` and `blue` properties, ranging from 0 to 255. */ player.getHeadBlendPaletteColors();  
    Example (Serverside)
    // EXAMPLE: Getting a specific color of the player mp.events.addCommand("mycolor", (player, _, index) => { index = Number(index); const paletteColor = player.getHeadBlendPaletteColor(index); player.outputChatBox(`paletteIndex #${index} - red: ${paletteColor.red}, green: ${paletteColor.green}, blue: ${paletteColor.blue}`); }); // EXAMPLE: Getting all colors of the player mp.events.addCommand("mycolors", (player) => { const paletteColors = player.getHeadBlendPaletteColors(); paletteColors.forEach((item, index) => { player.outputChatBox(`paletteIndex #${index} - red: ${item.red}, green: ${item.green}, blue: ${item.blue}`); }); }); // EXAMPLE: Setting one color mp.events.addCommand("setcolor", (player, _, index, r, g, b) => { index = Number(index); r = Number(r); g = Number(g); b = Number(b); player.setHeadBlendPaletteColor(index, r, g, b); }); // EXAMPLE: Setting multiple colors at once mp.events.addCommand("randomcolors", (player) => { let data = []; // the game has 4 palette colors for (let i = 0; i < 4; i++) { data.push([ i, // palette index Math.floor(Math.random() * 256), // random red Math.floor(Math.random() * 256), // random green Math.floor(Math.random() * 256), // random blue ]); } player.setHeadBlendPaletteColors(data); });  
    Notes
    The game doesn't seem to like it when you set palette color(s) of a ped that doesn't have headblend data, it's recommended that you do color changes after using Player::setCustomization Crew t-shirt palette indices: 0 - sleeve color, 1 - no difference, 2 - collar color, 3 - main color Crew jacket palette indices: 0, 1, 2 - no difference, 3 - main color  
    Source code is also available on GitHub: https://github.com/root-cause/ragemp-palette-sync

    19 downloads

       (1 review)

    0 comments

    Updated

  25. Improved Commands

    This resource adds a very flexible command handler for serverside JavaScript.
     
    Installing
    Drag and drop the improved-commands folder to your server-files/packages/ folder.
    NOTE: The archive also contains a folder named improved-commands-example, it's an example resource so don't install it along with the library.
     
    Features
    Command aliases Capture command requests (and cancel them if you want to) Somewhat customizable command not found message (like serverside C#) beforeRun property that lets you do final checks before a command actually runs (see example)  
    API
    Instead of extending the global mp object, I've decided to export CommandEvents and CommandRegistry objects. You can access to the library by doing:
    const { CommandEvents, CommandRegistry } = require("../improved-commands");  
    API Properties
    /** * This property is used to toggle the "command not found" message feature. * Default value: false */ CommandRegistry.notFoundMessageEnabled; // get CommandRegistry.notFoundMessageEnabled = bool; // set /** * This property is used to set the "command not found" message. * Default value: "SERVER: Command not found." */ CommandRegistry.notFoundMessage; // get CommandRegistry.notFoundMessage = string; // set  
    API Functions
    /** * Adds a command to the registry. * The command object must contain "name" (string) and "run" (function) properties at the very least. * Optionally, the command object can have "aliases" (array of strings) and "beforeRun" (function, needs to return true for further execution) properties. * Other properties will be collected into an "extra" (object) property, which is useful for storing data on commands. */ CommandRegistry.add(command); /** * Returns all command names, aliases not included. * @return {string[]} */ CommandRegistry.getNames(); /** * Returns all command names with aliases. * @return {string[]} */ CommandRegistry.getNamesWithAliases(); /** * Returns the command object for the specified command name/alias. * @param {string} commandName * @return {Object|undefined} Will be undefined if there is no command with the given name/alias. */ CommandRegistry.find(commandName);  
    Events
    /** * receive * This event is emitted when a player tries to run a command. * @param {mp.Player} player The player who is trying to use the command. * @param {Object} command The command object. * @param {string} fullText All arguments that will be passed to the command, as one string. * @param {string[]} commandArgs All arguments that will be passed to the command. * @param {Object} cancel Whether the execution should be cancelled. Set this object's cancel property to true to stop further processing of the command. */ CommandEvents.on("receive", function (player, command, fullText, commandArgs, cancel) { // your code }); /** * fail * This event is emitted when an error is thrown during command execution. * @param {mp.Player} player The player whose command execution failed. * @param {Object} command The command object. * @param {string} fullText All arguments that were be passed to the command, as one string. * @param {string[]} commandArgs All arguments that were be passed to the command. * @param {Error} error The error that was thrown during command execution. */ CommandEvents.on("fail", function (player, command, fullText, commandArgs, error) { // your code });  
    Example
    const { CommandEvents, CommandRegistry } = require("../improved-commands"); // Should we inform the player when they enter an invalid command? Probably... // Note that commands added with mp.events.addCommand aren't known by this resource so they'll trigger the not found message // This is disabled by default CommandRegistry.notFoundMessageEnabled = true; // Events // Example: Players can't use commands in a vehicle CommandEvents.on("receive", function (player, command, fullText, commandArgs, cancel) { if (player.vehicle) { player.outputChatBox("You cannot use commands in a vehicle."); cancel.cancel = true; } }); // Example: Send a message to the player and print the error to the console on execution failure CommandEvents.on("fail", function (player, command, fullText, commandArgs, error) { player.outputChatBox(`Failed to run command "${command.name}".`); console.error(error.stack || error); }); // Commands // Example: /argtest lorem ipsum dolor sit amet -> results in "You wrote: lorem ipsum dolor sit amet" CommandRegistry.add({ name: "argtest", aliases: ["echo", "combineargs"], beforeRun: function (player, fullText) { if (fullText.length === 0) { player.outputChatBox("No arguments provided."); return false; } return true; }, run: function (player, fullText) { player.outputChatBox(`You wrote: ${fullText}`); } }); // Example: /freemode_male_only -> will only work when player's model is mp_m_freemode_01 CommandRegistry.add({ name: "freemode_male_only", beforeRun: function (player) { return player.model === mp.joaat("mp_m_freemode_01"); }, run: function (player) { player.outputChatBox("Yes, only freemode male can run this command."); } }); // Example: /boom -> will emit "fail" event CommandRegistry.add({ name: "boom", run: function (player) { throw new Error("error thrown"); } }); // Properties that aren't named "name", "aliases", "beforeRun" or "run" will be collected into the "extra" property // Example: /getweapon weapon_carbinerifle 500 -> will only work when player's adminLevel property value is equal to or higher than cmdAdminLevel extra property CommandRegistry.add({ name: "getweapon", aliases: ["giveweapon"], // You can access this property in handlers by using "this.extra.cmdAdminLevel" if the handlers are regular functions (meaning it doesn't work with arrow functions!) cmdAdminLevel: 5, beforeRun: function (player) { return player.adminLevel >= this.extra.cmdAdminLevel; }, run: function (player, fullText, weaponName, ammo = 9999) { // You can do this in beforeRun as well (see argtest example) if (!weaponName || weaponName.length === 0) { player.outputChatBox("Syntax: /getweapon [name]"); return; } player.giveWeapon(mp.joaat(weaponName), Number(ammo)); player.outputChatBox(`Gave yourself ${weaponName} with ${ammo} ammo.`); } }); // Example: Extra property #2 CommandRegistry.add({ name: "count_runs", // You can access this property in handlers by using "this.extra.timesRan" if the handlers are regular functions (meaning it doesn't work with arrow functions!) timesRan: 0, beforeRun: function (player) { player.outputChatBox(`This command was used ${this.extra.timesRan} time(s).`); return true; }, run: function (player) { this.extra.timesRan++; player.outputChatBox(`Now it's used ${this.extra.timesRan} time(s).`); } }); // Example: List all commands CommandRegistry.add({ name: "commands", aliases: ["cmds"], run: function (player) { const commands = CommandRegistry.getNamesWithAliases(); commands.sort(); player.outputChatBox(`Commands: ${commands.join(", ")}`); } }); // Example: Async beforeRun (v1.1 and above) // Important: You should check if player object is still valid by mp.players.exists(player) after awaiting // sleep function can be found here: https://stackoverflow.com/a/39914235 CommandRegistry.add({ name: "async", beforeRun: async function (player) { // Getting data from slow API await sleep(5000); const result = Math.random() < 0.5; if (result) { player.outputChatBox("You're allowed..."); } else { player.outputChatBox("You're not allowed..."); } return result; }, run: async function (player) { // Getting data from slow API again await sleep(2000); if (Math.random() < 0.5) { player.outputChatBox("You waited for nothing!"); } else { throw new Error("Failed so bad it caused an error"); // should emit fail } } });  
    Notes
    This resource does not know about commands added with mp.events.addCommand or C# commands. Meaning if you're using the command not found message feature, addCommand and C# commands will also result in command not found message. Commands are case insensitive. Also on GitHub: https://github.com/root-cause/ragemp-improved-commands

    294 downloads

       (5 reviews)

    1 comment

    Updated


×
×
  • Create New...