3 Docs@0.2.0
rilaxik edited this page 2024-10-30 15:37:56 +00:00

Rage FW and it's documentation are still in early development and may contain come unclear explanations. It you find any of those please open an issue and describe you problem or any improvements you want to see

Rage Framework @ 0.2.0

RageFW distibutes under a list of packages:

These are setup as-should if you are using our CLI, if you still want to setup yourself, please refer to examples

Shared types

Core element of type-safety in our framework system. It allows you to manually type any custom events you have in your server system. There are three interfaces, which share between the system to apply types:

  • RageFW_ICustomClientEvent
  • RageFW_ICustomServerEvent
  • RageFW_ICustomBrowserEvent

To apply types for events we use the following system and below is a sample how it applies them your code

customEventName(arg1: string, arg2: number): boolean
register('customEventName', async (arg1 /*string*/, arg2 /*number*/) => {
  // your logic
return true /*Promise<boolean>*/
})

Server

Package used on a server-side of your Rage:MP Server

Usage

import { fw } from '@entityseven/rage-fw-server'

Only usable in server environment. For usage in Client and Browser refer to their sections

Declaration

fw = {
    event: Server,
    player: Player,
    system: {
        log: Logger
    },
    rpc: Rpc
}

Further documentation will describe the fields included in fw

Server

Server-side interactions

register

Registers a server event with an associated callback

fw.event.register("playerJoin", (player) => {
    // do something
})

// Registering an event with middlewares
fw.event.register("playerJoin", (player) => {
    // do something
}, {
    middlewares: [...] // <- your middlewares here
})

// or

fw.event.register("playerJoin", (player) => {
    // do something
}, {
    middlewares: {
        executables: [...], // <- your middlewares here
        onError: (msg) => void msg // <- error handling here
    }
})

unregister

Unregisters a server event, removing the associated callback

fw.event.unregister("playerJoin")

trigger

Triggers registered server event. Formerly known as call or emit

fw.event.trigger('serverEventName', ['arg1', 2])

Player

Handles event manipulations that require player to be present in context

triggerClient

Triggers a client event from the server with arguments from shared types. Formerly known as callClient or emitClient

// without args
fw.player.triggerClient("clientEventName")
// with args
fw.player.triggerClient("clientEventName", ["message to client"])

triggerBrowser

Triggers a browser event from the server with arguments from shared types. Formerly known as callBrowser or emitBrowser

// without args
fw.player.triggerBrowser("browserEventName")
// with args
fw.player.triggerBrowser("browserEventName", ["message to browser"])

System

Handles functions used to interact with system environment

Logger

Used to log to a client in-game console

info

Informational logs. Colored in white

fw.system.log.info('some information to be logged')

warn

Warning logs. Colored in yellow

fw.system.log.warn('warning message')

error

Error logs. Colored in red

fw.system.log.info('some error information')

Rpc

rage-fw-rpc instance used under the hood. It is highly recommended to use this one if you need it instead of creating a new instance

Client

Package used on a client-side of your Rage:MP Server

Usage

import { fw } from '@entityseven/rage-fw-client'

Only usable in client environment. For usage in Server and Browser refer to their docs

Declaration

fw = {
    event: Client,
    player: Player,
    system: {
        log: Logger,
    },
    rpc: Rpc,
}

Further documentation will describe the fields included in fw

Client

Client-side interactions

register

Registers a client event with an associated callback

fw.event.register("playerDeath", (player, reason, killer) => {
    // do something
})

// Registering an event with middlewares
fw.event.register("playerDeath", (player, reason, killer) => {
    // do something
}, {
    middlewares: [...] // <- your middlewares here
})

// or

fw.event.register("playerDeath", (player, reason, killer) => {
    // do something
}, {
    middlewares: {
        executables: [...], // <- your middlewares here
        onError: (msg) => void msg // <- error handling here
    }
})

unregister

Unregisters a client event, removing the associated callback

fw.event.unregister("playerDeath")

Player

Handles event manipulations that require player to be present in context

browser

Setter. Also shares browser with rage-fw-rpc

fw.player.browser = mp.browsers.new('package://index.html')

trigger

Triggers registered client event with passed arguments. Formerly known as call or emit

// without args
fw.player.trigger("clientEventName")
// with args
fw.player.trigger("clientEventName", ["message to me"])

triggerServer

Triggers a server event from the client with arguments from shared types. Formerly known as callServer or emitServer

// without args
fw.player.triggerServer("serverEventName")
// with args
fw.player.triggerServer("serverEventName", ["message to server"])

triggerBrowser

Triggers a browser event from the client with arguments from shared types. Formerly known as callBrowser or emitBrowser

// without args
fw.player.triggerBrowser("browserEventName")
// with args
fw.player.triggerBrowser("browserEventName", ["message to browser"])

System

Handles functions used to interact with the client environment

Logger

Used to log to a client in-game console

info

Informational logs. Colored in white

fw.system.log.info('some information to be logged')

warn

Warning logs. Colored in yellow

fw.system.log.warn('warning message')

error

Error logs. Colored in red

fw.system.log.info('some error information')

Rpc

rage-fw-rpc instance used under the hood. It is highly recommended to use this one if you need it instead of creating a new instance

Browser

Package used on a browser-side of your Rage:MP Server

Usage

import { fw } from '@entityseven/rage-fw-browser'

Only usable in Browser environment. For usage in Server and Client refer to their docs

Declaration

fw = {
    event: Browser,
    rpc: Rpc
}

Further documentation will describe the fields included in fw

Browser

Browser-side interactions

debugLogs

Setter. Enables console debug logs for events

fw.event.debugLogs = true

customLogger

Setter. Enables console debug logs for events

fw.event.customLogger = () => (method: string, eventName: string, ...args: unknown[]) => {
	// log with desired formatting
}

register

Registers a browser event with an associated callback

fw.event.register("showNotification", (message, color) => {
    // do something
})

unregister

Unregisters a browser event, removing the associated callback

fw.event.unregister("showNotification")

trigger

Triggers a browser event from the browser with arguments from shared types. Formerly known as call or emit

// without args
fw.event.trigger("browserEventName")
// with args
fw.event.trigger("browserEventName", ["message to me"])

triggerServer

Triggers a server event from the browser with arguments from shared types. Formerly known as callServer or emitServer

// without args
fw.event.triggerServer("serverEventName")
// with args
fw.event.triggerServer("serverEventName", ["message to server"])

triggerClient

Triggers a client event from the browser with arguments from shared types. Formerly known as callClient or emitClient

// without args
fw.event.triggerClient("clientEventName")
// with args
fw.event.triggerClient("clientEventName", ["message to client"])

Rpc

rage-fw-rpc instance used under the hood. It is highly recommended to use this one if you need it instead of creating a new instance

forceBrowserDevMode?

rage-fw-rpc has a setting which enables it to be ran in browser dev mode without MP context (see Wiki -> Rpc -> Rpc Config). As rage-fw-browser does not expose Rpc constructor, you can use .env with RageFW_forceBrowserDevMode=true to enable it

Features

Event Middlewares

Rage FW offers you to add middlewares when registering events in Client and Server environments, to check if callback should be executed or should not. Core class functionality is not exposed to user, but some types are for easier code managing. Here are some key points (in context of Server environment, but also applicable to Client)

Declaration

register(
    eventName,
    callback,
    options?: {
        middlewares?: RageFW_MiddlewareOptions
    },
)

type RageFW_MiddlewareOptions = 
    | RageFW_MiddlewareFunction[]
    | {
          executables: RageFW_MiddlewareFunction[]
          onError: (error: string) => unknown
      }

type RageFW_MiddlewareFunction = (...args: T.RageFW_ServerArgs) => 
    Promise<RageFW_MiddlewareResponse>

type RageFW_MiddlewareResponse =
    | {
          success: boolean
          message?: string
      }
    | boolean

Usage

RageFW_MiddlewareFunction can be imported to type your middlewares, eg.:

import {type RageFW_MiddlewareFunction} from '@entityseven/rage-fw-server'

const isPlayerAdmin: RageFW_MiddlewareFunction<'yourEventName'> = async (player, ...args) => {
    if (player.adminLvl >= 2) {
    	return true
    } else {
    	return {
			success: false,
            message: 'You must have administrator rights for this action'
        }
    }
}

// or function-like if you want to omit some argument types or hoisting is required

async function isPlayerAdmin(player: PlayerMp, ...args): ReturnType<RageFW_MiddlewareFunction<'yourEventName'>> {
    if (player.adminLvl >= 2) {
        return true
    } else {
        return {
            success: false,
            message: 'You must have administrator rights for this action',
        }
    }
}

fw.event.register(
    'yourEventName',
    async (player, ...args) => {
        // do an action which requires administrator rights
    },
    {
        middlewares: {
            executables: [isPlayerAdmin],
            onError: e => {}, // notify player about missing permissions
        },
    },
)

Implementation TL;DR (why no next()?)

Unfortunately in Client-side of Rage:MP every thrown Error or Promise.reject is not catchable, meaning a naughty error window will pop-up on player's screen. Due to this implementation variant we were forced to not throw Errors from middlewares and just return middleware result. Server-side can handle errors, but to keep everything consistent we stick up to this variant