rage-framework-rpc/src/index.js

163 lines
4.8 KiB
JavaScript
Raw Normal View History

2018-11-01 13:31:53 +00:00
const util = require('./util.js');
2018-11-01 19:05:48 +00:00
const environment = util.getEnvironment();
if(!environment) throw 'Unknown RAGE environment';
const PROCESS_EVENT = '__rpc:process';
const rpc = {};
2018-11-01 13:31:53 +00:00
const listeners = {};
2018-11-01 19:05:48 +00:00
const pending = {};
2018-11-01 13:31:53 +00:00
2018-11-01 19:05:48 +00:00
async function callProcedure(name, args, info){
if(!listeners[name]) throw 'PROCEDURE_NOT_FOUND';
return listeners[name](args, info);
}
2018-11-01 13:31:53 +00:00
2018-11-01 19:05:48 +00:00
const processEvent = (...args) => {
let data = args[0];
if(environment === "server") data = args[1];
data = util.parseData(data);
if(data.req){ // someone is trying to remotely call a procedure
const info = {
id: data.id,
environment: data.env
};
if(environment === "server") info.player = args[0];
const promise = callProcedure(data.name, data.args, info);
switch(environment){
case "server": {
promise.then(res => {
info.player.call(PROCESS_EVENT, [util.stringifyData({
ret: 1,
id: data.id,
res
})]);
}).catch(err => {
info.player.call(PROCESS_EVENT, [util.stringifyData({
ret: 1,
id: data.id,
err
})]);
});
break;
}
case "client": {
promise.then(res => {
mp.events.callRemote(PROCESS_EVENT, util.stringifyData({
ret: 1,
id: data.id,
res
}));
}).catch(err => {
mp.events.callRemote(PROCESS_EVENT, util.stringifyData({
ret: 1,
id: data.id,
err
}));
});
break;
}
}
}else if(data.ret){ // a previously called remote procedure has returned
const info = pending[data.id];
if(info){
if(data.err) info.reject(data.err);
else info.resolve(data.res);
pending[data.id] = undefined;
}
}
};
2018-11-01 13:31:53 +00:00
2018-11-01 19:05:48 +00:00
mp.events.add(PROCESS_EVENT, processEvent);
2018-11-01 13:31:53 +00:00
/**
2018-11-01 19:05:48 +00:00
* Register a procedure.
* @param {string} name - The name of the procedure.
* @param {function} cb - The procedure's callback. The return value will be sent back to the caller.
2018-11-01 13:31:53 +00:00
*/
2018-11-01 19:05:48 +00:00
rpc.register = (name, cb) => {
listeners[name] = cb;
2018-11-01 13:31:53 +00:00
};
/**
2018-11-01 19:05:48 +00:00
* Unregister a procedure.
* @param {string} name - The name of the procedure.
2018-11-01 13:31:53 +00:00
*/
2018-11-01 19:05:48 +00:00
rpc.unregister = (name) => {
listeners[name] = undefined;
2018-11-01 13:31:53 +00:00
};
/**
2018-11-01 19:05:48 +00:00
* Calls a local procedure.
* @param {string} name - The name of the locally registered procedure.
* @param args - Any parameters for the procedure.
* @returns {Promise} - The result from the procedure.
2018-11-01 13:31:53 +00:00
*/
2018-11-01 19:05:48 +00:00
rpc.call = (name, args) => callProcedure(name, args, { environment });
2018-11-01 13:31:53 +00:00
/**
2018-11-01 19:05:48 +00:00
* Calls a remote procedure registered on the server.
* @param {string} name - The name of the registered procedure.
* @param args - Any parameters for the procedure.
* @returns {Promise} - The result from the procedure.
2018-11-01 13:31:53 +00:00
*/
2018-11-01 19:05:48 +00:00
rpc.callServer = (name, args) => {
switch(environment){
case "server": {
return rpc.call(name, args);
}
case "client": {
const id = util.uid();
return new Promise((resolve, reject) => {
pending[id] = {
resolve,
reject
};
mp.events.callRemote(PROCESS_EVENT, util.stringifyData({
req: 1,
id,
name,
env: environment,
args
}));
});
}
}
2018-11-01 13:31:53 +00:00
};
/**
2018-11-01 19:05:48 +00:00
* Calls a remote procedure registered on the client.
* @param player - The player to call the procedure on.
* @param {string} name - The name of the registered procedure.
* @param args - Any parameters for the procedure.
* @returns {Promise} - The result from the procedure.
2018-11-01 13:31:53 +00:00
*/
2018-11-01 19:05:48 +00:00
rpc.callClient = (player, name, args) => {
switch(environment){
case "client": {
if(player === mp.players.local) return rpc.call(name, args);
else return Promise.reject('Only the server can RPC to other clients.');
}
case "server": {
const id = util.uid();
return new Promise((resolve, reject) => {
pending[id] = {
resolve,
reject
};
player.call(PROCESS_EVENT, [util.stringifyData({
req: 1,
id,
name,
env: environment,
args
})]);
});
}
}
2018-11-01 13:31:53 +00:00
};
2018-11-01 19:05:48 +00:00
module.exports = rpc;