micaww 32 Posted June 3 For those who use React for their front-end, here are a couple super basic React Hooks that I use to help accept events in components. Enjoy! import rpc from 'rage-rpc'; /** * Register an RPC handler for the lifetime of the component. * @param procedure - The name of the procedure * @param callback - The callback to handle the procedure * @param deps - Hook dependencies. When changed, the hook will be reregistered */ export function useRPCHandler(procedure: string, callback: rpc.ProcedureListener, deps: any[]){ useEffect(() => { rpc.register(procedure, callback); return () => { rpc.unregister(procedure); }; }, deps); } /** * Register an event handler for the lifetime of the component. * @param event - The name of the event * @param callback - The callback to handle the event */ export function useEventHandler(event: string, callback: rpc.ProcedureListener){ useEffect(() => { rpc.on(event, callback); return () => { rpc.off(event, callback); }; }); } This is ready for TypeScript, but you can easily use it in a JavaScript environment by simply removing the types in the arguments. Here is an example component using both hooks: import React from 'react'; import ReactDOM from 'react-dom'; import { useRPCHandler, useEventHandler } from './hooks'; // wherever you just put those two hook functions // This is a basic HUD component that shows a money value function HUD(){ const [money, setMoney] = useState(0); const [visible, setVisible] = useState(false); useRPCHandler('isMoneyVisible', () => visible, [visible]); useEventHandler('setMoney', amount => setMoney(amount)); if(!visible) return null; return ( <h1>${money.toLocaleString()}</h1> ); } ReactDOM.render( <HUD/>, document.getElementById('root') ); With this being rendered in any CEF browser, you can now use those 2 hooks from anywhere on RAGE: import rpc from 'rage-rpc'; // SERVER-SIDE const player = mp.players.at(0); rpc.callBrowsers(player, 'isMoneyVisible').then(visible => { if(visible){ console.log(`${player.name}'s money is visible!`); }else{ console.log(`${player.name}'s money isn't visible!`); } }); rpc.callBrowsers(player, 'setMoney', 999999); // CLIENT-SIDE OR IN ANY BROWSER rpc.callBrowsers('setMoney', 5000); Note: Notice that useRPCHandler requires a dependency array and useEventHandler does not. This is because registering RPC handlers in the browser requires an event to be sent to the client to tell the client that this browser instance can accept RPC calls. It's best to provide as many dependencies as your handler uses so that it will be unhooked and rehooked the minimum amount of times. This also prevents your callback from capturing stale values. useEventHandler can re-register itself as many times without any performance drawback, as the client doesn't care if it has a handler or not, so it doesn't notify the client that it has a handler for events. 2 Share this post Link to post Share on other sites
buxx0 2 Posted June 23 I wondered if there would be situation, in which we made a serverside call to client, and returns a Promise, which resolves after some time. In the meanwhile client has crashed or left, and I made await on this Promise in a command at serverside. I guess not resolved promises are nothing wrong itself, but to make my sleep calm I have to ask it, if in your opinion would be there some consequences or better to avoid this situation? Obviously code after await won't be reached I guess. async function someCommandCall () { await rpc.callClient(player, 'waitForKeyInput') // resolves after time and client has crashed console.log('resolved') } Share this post Link to post Share on other sites