Last active
November 5, 2019 21:39
-
-
Save TheDutchDev/de34e410f615adebbd6b6d27e8f60167 to your computer and use it in GitHub Desktop.
Rage RPC in C#, server-side only for now.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Small example, fetches the getInvincible from the client to see if the client is invincible or not. | |
// SERVER-SIDE | |
var response = await client.RequestDataFromClient( "IsPlayerInvincible" ); | |
if( response == null ) | |
Console.WriteLine( "Couldnt fetch" ); | |
else | |
Console.WriteLine( $"Player invincible: { response[ 0 ] }" ); | |
// CLIENT-SIDE(JS) | |
mp.events.add( "IsPlayerInvincible", ( reqId ) => { | |
let invincible = mp.game.invoke( '0xB721981B2B939E07', localPlayer ); | |
mp.events.callRemote( "OnPlayerCompleteRPCTask", reqId, invincible ); | |
} ); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public static class RageRPC | |
{ | |
private static readonly int TimeoutMs = 2000; // time in milliseconds before a request is timedout | |
private static uint RequestId = 0; | |
public static Dictionary<uint, TaskCompletionSource<Response>> RequestedTasks { get; set; } = new Dictionary<uint, TaskCompletionSource<Response>>( ); | |
/// <summary> | |
/// Calls a client-side event and waits for a return call, then returns the data. This call must be awaited. | |
/// </summary> | |
/// <param name="client">The client to submit the event to</param> | |
/// <param name="eventName">The event name to be called on the client</param> | |
/// <param name="data">The data to be submitted to the client-side event</param> | |
/// <returns></returns> | |
public static async Task<dynamic> RequestDataFromClient( this Client client, string eventName, params dynamic[] data ) | |
{ | |
try | |
{ | |
if( RequestId > 1000000 ) // reset the ID after 1 million requests | |
RequestId = 0; | |
TaskCompletionSource<Response> tcs = new TaskCompletionSource<Response>( ); | |
var reqId = RequestId; | |
RequestId++; | |
// store requested task so we can complete it later on when the data is recieved | |
RequestedTasks.Add( reqId, tcs ); | |
// call the client-side event with request ID and additional optional data | |
client.TriggerEvent( eventName, reqId, data ); | |
// wait for the task to complete or timeout | |
var completed = await Task.WhenAny( tcs.Task, DelayResult( default( Response ), TimeSpan.FromMilliseconds( TimeoutMs ) ) ); | |
// remove it from the list after we're done with it. | |
RequestedTasks.Remove( reqId ); | |
// if the task timedout | |
if( completed != tcs.Task ) | |
return null; | |
// return data | |
var response = await completed; | |
return response.Data; | |
} | |
catch( Exception ex ) | |
{ | |
throw ex; | |
return null; | |
} | |
} | |
public static async Task<T> DelayResult<T>( T result, TimeSpan delay ) | |
{ | |
try | |
{ | |
await Task.Delay( delay ); | |
return result; | |
} | |
catch( Exception ex ) | |
{ | |
throw ex; | |
return default( T ); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class RageRPCEventHandler : Script | |
{ | |
[RemoteEvent( "OnPlayerCompleteRPCTask" )] | |
public void OnPlayerCompleteRPCTask( Client client, params dynamic[] data ) | |
{ | |
try | |
{ | |
// if the request couldn't be found in the list with existing requests | |
if( !RageRPC.RequestedTasks.ContainsKey( Convert.ToUInt32( data[ 0 ] ) ) ) | |
throw new Exception( "The requested task could not be found." ); | |
// get the task and set it's result value to the data that was recieved. | |
var currentTask = RageRPC.RequestedTasks.FirstOrDefault( rt => rt.Key == Convert.ToUInt32( data[ 0 ] ) ); | |
currentTask.Value.TrySetResult( new Response { Id = data[ 0 ], Data = data.Skip( 1 ).ToArray( ) } ); | |
} | |
catch( Exception ex ) | |
{ | |
throw ex; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Response | |
{ | |
public int Id { get; set; } | |
public dynamic[] Data { get; set; } | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment