/// <summary> /// Registers all callbacks in the specified target object. Instance methods with a <see cref="CallbackAttribute" /> /// attached will be loaded. /// </summary> /// <param name="gameModeClient">The game mode client.</param> /// <param name="target">The target.</param> public static void RegisterCallbacksInObject(this IGameModeClient gameModeClient, object target) { if (target == null) { throw new ArgumentNullException(nameof(target)); } foreach (var method in target.GetType().GetTypeInfo().GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) { var attribute = method.GetCustomAttribute <CallbackAttribute>(); if (attribute == null) { continue; } var name = attribute.Name; if (string.IsNullOrEmpty(name)) { name = method.Name; } gameModeClient.RegisterCallback(name, target, method); } }
/// <summary> /// Initializes a new instance of the <see cref="Callback" /> class. /// </summary> /// <param name="target">The target to invoke the method on.</param> /// <param name="methodInfo">The information about the method to invoke.</param> /// <param name="name">The name of the callback.</param> /// <param name="parameterTypes">The types of the parameters.</param> /// <param name="gameModeClient">The game mode client.</param> public Callback(object target, MethodInfo methodInfo, string name, Type[] parameterTypes, IGameModeClient gameModeClient) { _gameModeClient = gameModeClient ?? throw new ArgumentNullException(nameof(gameModeClient)); _target = target ?? throw new ArgumentNullException(nameof(target)); _methodInfo = methodInfo ?? throw new ArgumentNullException(nameof(methodInfo)); Name = name ?? throw new ArgumentNullException(nameof(name)); var parameterInfos = methodInfo.GetParameters(); _parameterValues = new object[parameterTypes.Length]; _parameterTypes = new ParameterType[parameterTypes.Length]; // Verify the parameters match the method info if (parameterInfos.Length == 1 && parameterInfos[0].ParameterType == typeof(object[])) { _parametersContainer = new object[1]; } else { if (parameterTypes.Where((t, i) => t != parameterInfos[i].ParameterType).Any()) { throw new CallbackRegistrationException( "The specified parameters does not match the parameters of the specified method."); } } for (var i = 0; i < parameterTypes.Length; i++) { _parameterTypes[i] = GetParameterType(parameterTypes[i]); } }
protected NativeObjectProxyFactoryBase(IGameModeClient gameModeClient, string assemblyName) { _gameModeClient = gameModeClient; var asmName = new AssemblyName(assemblyName); var asmBuilder = AssemblyBuilder.DefineDynamicAssembly(asmName, AssemblyBuilderAccess.Run); _moduleBuilder = asmBuilder.DefineDynamicModule(asmName.Name + ".dll"); }
/// <summary> /// Initializes a new instance of the <see cref="EventService" /> class. /// </summary> public EventService(IGameModeClient gameModeClient, IServiceProvider serviceProvider, IEntityManager entityManager) { _gameModeClient = gameModeClient; _serviceProvider = serviceProvider; _entityManager = entityManager; CreateEventsFromAssemblies(); }
/// <summary> /// Initializes the game mode with the specified game mode client. /// </summary> /// <param name="client">The game mode client which is loading this game mode.</param> void IGameModeProvider.Initialize(IGameModeClient client) { Client = client; client.RegisterCallbacksInObject(this); LoadExtensions(); LoadServicesAndControllers(); }
/// <summary> /// Initializes a new instance of the <see cref="NativeLoader" /> class. /// </summary> /// <param name="gameModeClient">The game mode client.</param> public NativeLoader(IGameModeClient gameModeClient) { _gameModeClient = gameModeClient ?? throw new ArgumentNullException(nameof(gameModeClient)); ProxyFactory = //gameModeClient is HostedGameModeClient //? (INativeObjectProxyFactory) new FastNativeBasedNativeObjectProxyFactory(gameModeClient) // : new NativeHandleBasedNativeObjectProxyFactory(gameModeClient, this); }
/// <summary> /// Initializes a new instance of the <see cref="Callback" /> class. /// </summary> /// <param name="target">The target to invoke the method on.</param> /// <param name="methodInfo">The information about the method to invoke.</param> /// <param name="name">The name of the callback.</param> /// <param name="parameters">The parameters of the callback.</param> /// <param name="gameModeClient">The game mode client.</param> public Callback(object target, MethodInfo methodInfo, string name, CallbackParameterInfo[] parameters, IGameModeClient gameModeClient) { _gameModeClient = gameModeClient ?? throw new ArgumentNullException(nameof(gameModeClient)); _target = target ?? throw new ArgumentNullException(nameof(target)); _methodInfo = methodInfo ?? throw new ArgumentNullException(nameof(methodInfo)); _parameters = parameters ?? throw new ArgumentNullException(nameof(parameters)); Name = name ?? throw new ArgumentNullException(nameof(name)); _parameterInfos = methodInfo.GetParameters(); _parameterValues = new object[parameters.Length]; // Verify the parameters match the method info if (parameters.Length != _parameterInfos.Length) { throw new CallbackRegistrationException("The specified parameters does not match the parameters of the specified method."); } for (var i = 0; i < parameters.Length; i++) { var par = parameters[i]; var info = _parameterInfos[i]; switch (par.Type) { case CallbackParameterType.Value: if (!new[] { typeof(int), typeof(float), typeof(bool) }.Contains(info.ParameterType)) { throw new CallbackRegistrationException( "The specified parameters does not match the parameters of the specified method."); } break; case CallbackParameterType.Array: if (!new[] { typeof(int[]), typeof(float[]), typeof(bool[]) }.Contains(info.ParameterType)) { throw new CallbackRegistrationException( "The specified parameters does not match the parameters of the specified method."); } break; case CallbackParameterType.String: if (typeof(string) != info.ParameterType) { throw new CallbackRegistrationException( "The specified parameters does not match the parameters of the specified method."); } break; default: throw new ArgumentOutOfRangeException(); } } }
/// <summary> /// Initializes a new instance of the <see cref="Callback" /> class. /// </summary> /// <param name="target">The target to invoke the method on.</param> /// <param name="methodInfo">The information about the method to invoke.</param> /// <param name="name">The name of the callback.</param> /// <param name="gameModeClient">The game mode client.</param> public Callback(object target, MethodInfo methodInfo, string name, IGameModeClient gameModeClient) { _gameModeClient = gameModeClient ?? throw new ArgumentNullException(nameof(gameModeClient)); _target = target ?? throw new ArgumentNullException(nameof(target)); _methodInfo = methodInfo ?? throw new ArgumentNullException(nameof(methodInfo)); Name = name ?? throw new ArgumentNullException(nameof(name)); var parameterInfos = methodInfo.GetParameters(); _parameterValues = new object[parameterInfos.Length]; _parameterTypes = new ParameterType[parameterInfos.Length]; for (var i = 0; i < parameterInfos.Length; i++) { _parameterTypes[i] = GetParameterType(parameterInfos[i].ParameterType); } }
/// <summary> /// Initializes a new instance of the <see cref="Native" /> class. /// </summary> /// <param name="gameModeClient">The game mode client.</param> /// <param name="name">The name.</param> /// <param name="handle">The handle.</param> /// <param name="parameters">The parameters.</param> public Native(IGameModeClient gameModeClient, string name, int handle, params NativeParameterInfo[] parameters) { if (handle < 0) { throw new ArgumentOutOfRangeException(nameof(handle)); } _gameModeClient = gameModeClient ?? throw new ArgumentNullException(nameof(gameModeClient)); Parameters = parameters ?? throw new ArgumentNullException(nameof(parameters)); Name = name ?? throw new ArgumentNullException(nameof(name)); Handle = handle; if (parameters.Any(info => info.RequiresLength && info.LengthIndex >= parameters.Length)) { throw new ArgumentOutOfRangeException(nameof(parameters), "Invalid parameter length index."); } }
/// <summary> /// Registers a callback with the specified <paramref name="name" />. When the callback is called, the specified /// <paramref name="methodInfo" /> will be invoked on the specified <paramref name="target" />. /// </summary> /// <param name="gameModeClient">The game mode client.</param> /// <param name="name">The name af the callback to register.</param> /// <param name="target">The target on which to invoke the method.</param> /// <param name="methodInfo">The method information of the method to invoke when the callback is called.</param> public static void RegisterCallback(this IGameModeClient gameModeClient, string name, object target, MethodInfo methodInfo) { if (name == null) { throw new ArgumentNullException(nameof(name)); } if (target == null) { throw new ArgumentNullException(nameof(target)); } if (methodInfo == null) { throw new ArgumentNullException(nameof(methodInfo)); } var parameterInfos = methodInfo.GetParameters(); var parameters = new CallbackParameterInfo[parameterInfos.Length]; for (var i = 0; i < parameters.Length; i++) { if (Callback.IsValidValueType(parameterInfos[i].ParameterType)) { parameters[i] = CallbackParameterInfo.Value; } else if (Callback.IsValidArrayType(parameterInfos[i].ParameterType)) { var attribute = parameterInfos[i].GetCustomAttribute <ParameterLengthAttribute>(); if (attribute == null) { throw new CallbackRegistrationException("Parameters of array types must have an attached ParameterLengthAttribute."); } parameters[i] = CallbackParameterInfo.Array(attribute.Index); } else if (Callback.IsValidStringType(parameterInfos[i].ParameterType)) { parameters[i] = CallbackParameterInfo.String; } else { throw new CallbackRegistrationException("The method contains unsupported parameter types"); } } gameModeClient.RegisterCallback(name, target, methodInfo, parameters); }
/// <summary> /// Registers a callback with the specified <paramref name="name" />. When the callback is called, the specified /// <paramref name="methodInfo" /> will be invoked on the specified <paramref name="target" />. /// </summary> /// <param name="gameModeClient">The game mode client.</param> /// <param name="name">The name af the callback to register.</param> /// <param name="target">The target on which to invoke the method.</param> /// <param name="methodInfo">The method information of the method to invoke when the callback is called.</param> /// <param name="parameterTypes">The types of the parameters of the callback.</param> public static void RegisterCallback(this IGameModeClient gameModeClient, string name, object target, MethodInfo methodInfo, Type[] parameterTypes) { if (name == null) { throw new ArgumentNullException(nameof(name)); } if (target == null) { throw new ArgumentNullException(nameof(target)); } if (methodInfo == null) { throw new ArgumentNullException(nameof(methodInfo)); } if (parameterTypes == null) { throw new ArgumentNullException(nameof(parameterTypes)); } var parameters = new CallbackParameterInfo[parameterTypes.Length]; for (var i = 0; i < parameters.Length; i++) { if (Callback.IsValidValueType(parameterTypes[i])) { parameters[i] = CallbackParameterInfo.Value; } else if (Callback.IsValidArrayType(parameterTypes[i])) { throw new CallbackRegistrationException( "Parameters of array types must specify a parameter length."); } else if (Callback.IsValidStringType(parameterTypes[i])) { parameters[i] = CallbackParameterInfo.String; } else { throw new CallbackRegistrationException("The method contains unsupported parameter types"); } } gameModeClient.RegisterCallback(name, target, methodInfo, parameters, parameterTypes); }
/// <inheritdoc /> public void Initialize(IGameModeClient client) { client.UnhandledException += (sender, args) => { CoreLog.Log(CoreLogLevel.Error, "Unhandled exception: " + args.Exception); }; var services = new ServiceCollection(); services.AddSingleton(client); services.AddSingleton(client.NativeLoader); Configure(services); _serviceProvider = services.BuildServiceProvider(); _systemRegistry = _serviceProvider.GetRequiredService <ISystemRegistry>(); Configure(); AddWrappedSystemTypes(); }
/// <summary> /// Converts the value to a collection of bytes according to this parameter. /// </summary> /// <param name="value">The value.</param> /// <param name="length">The length.</param> /// <param name="gameModeClient">The game mode client.</param> /// <returns>A collection of bytes.</returns> public IEnumerable <byte> GetBytes(object value, int length, IGameModeClient gameModeClient) { switch (Type) { case NativeParameterType.Int32: case NativeParameterType.Int32Reference: if (value is int v) { return(ValueConverter.GetBytes(v)); } else if (value == null) { return(ValueConverter.GetBytes(0)); } break; case NativeParameterType.Single: case NativeParameterType.SingleReference: if (value is float f) { return(ValueConverter.GetBytes(f)); } else if (value == null) { return(ValueConverter.GetBytes(0.0f)); } break; case NativeParameterType.Bool: case NativeParameterType.BoolReference: if (value is bool b) { return(ValueConverter.GetBytes(b)); } else if (value == null) { return(ValueConverter.GetBytes(false)); } break; case NativeParameterType.String: if (value is string s) { return(ValueConverter.GetBytes(s, gameModeClient.Encoding)); } else if (value == null) { return(ValueConverter.GetBytes("", gameModeClient.Encoding)); } break; case NativeParameterType.StringReference: case NativeParameterType.Int32ArrayReference: case NativeParameterType.SingleArrayReference: case NativeParameterType.BoolArrayReference: if (length < 1) { throw new ArgumentOutOfRangeException(nameof(length)); } return(ValueConverter.GetBytes(length)); case NativeParameterType.Int32Array: if (value is int[] ai) { if (length < 1) { throw new ArgumentOutOfRangeException(nameof(length)); } var array = new byte[length * 4 + 4]; ValueConverter.GetBytes(length).CopyTo(array, 0); for (var i = 0; i < length; i++) { ValueConverter.GetBytes(ai[i]).CopyTo(array, 4 + i * 4); } return(array); } break; case NativeParameterType.SingleArray: if (value is float[] af) { if (length < 1) { throw new ArgumentOutOfRangeException(nameof(length)); } var array = new byte[length * 4 + 4]; ValueConverter.GetBytes(length).CopyTo(array, 0); for (var i = 0; i < length; i++) { ValueConverter.GetBytes(af[i]).CopyTo(array, 4 + i * 4); } return(array); } break; case NativeParameterType.BoolArray: if (value is bool[] ab) { if (length < 1) { throw new ArgumentOutOfRangeException(nameof(length)); } var array = new byte[length * 4 + 4]; ValueConverter.GetBytes(length).CopyTo(array, 0); for (var i = 0; i < length; i++) { ValueConverter.GetBytes(ab[i]).CopyTo(array, 4 + i * 4); } return(array); } break; } throw new ArgumentException("Value is of invalid type", nameof(value)); }
/// <summary> /// Returns the referenced value returned by a native. /// </summary> /// <param name="response">The response to extract the value from.</param> /// <param name="index">The current top of the response.</param> /// <param name="length">The length of the argument.</param> /// <param name="nativeResult">The result of the invoked native</param> /// <param name="gameModeClient">The game mode client.</param> /// <returns>The referenced value.</returns> public object GetReferenceArgument(byte[] response, ref int index, int length, int nativeResult, IGameModeClient gameModeClient) { object result = null; switch (Type) { case NativeParameterType.Int32Reference: result = ValueConverter.ToInt32(response, index); index += 4; break; case NativeParameterType.SingleReference: result = ValueConverter.ToSingle(response, index); index += 4; break; case NativeParameterType.BoolReference: result = ValueConverter.ToBoolean(response, index); index += 4; break; case NativeParameterType.StringReference: var str = ValueConverter.ToString(response, index, gameModeClient.Encoding); result = str; index += str.Length + 1; if (nativeResult == 0) { result = string.Empty; } break; case NativeParameterType.Int32ArrayReference: { //var len = ValueConverter.ToInt32(response, index); //index += 4; var arr = new int[length]; for (var i = 0; i < length; i++) { arr[i] = ValueConverter.ToInt32(response, index); index += 4; } result = arr; break; } case NativeParameterType.SingleArrayReference: { //var len = ValueConverter.ToInt32(response, index); //index += 4; var arr = new float[length]; for (var i = 0; i < length; i++) { arr[i] = ValueConverter.ToSingle(response, index); index += 4; } result = arr; break; } case NativeParameterType.BoolArrayReference: { //var len = ValueConverter.ToInt32(response, index); //index += 4; var arr = new bool[length]; for (var i = 0; i < length; i++) { arr[i] = ValueConverter.ToBoolean(response, index); index += 4; } result = arr; break; } } return(result); }
public NativeHandleBasedNativeObjectProxyFactory(IGameModeClient gameModeClient, INativeLoader nativeLoader) : base(gameModeClient, "ProxyAssembly") { _nativeLoader = nativeLoader; }
/// <inheritdoc /> public FastNativeBasedNativeObjectProxyFactory(IGameModeClient gameModeClient) : base("ProxyAssemblyFast") { _gameModeClient = gameModeClient; }
public Issue365FastNatives(IGameModeClient client) { _client = client; }
/// <summary> /// Initializes a new instance of the <see cref="NativeLoader" /> class. /// </summary> /// <param name="gameModeClient">The game mode client.</param> public NativeLoader(IGameModeClient gameModeClient) { _gameModeClient = gameModeClient ?? throw new ArgumentNullException(nameof(gameModeClient)); }
/// <summary> /// Initializes a new instance of the <see cref="NativeLoader" /> class. /// </summary> /// <param name="gameModeClient">The game mode client.</param> public NativeLoader(IGameModeClient gameModeClient) { _gameModeClient = gameModeClient ?? throw new ArgumentNullException(nameof(gameModeClient)); ProxyFactory = new NativeHandleBasedNativeObjectProxyFactory(gameModeClient, this); }
/// <summary> /// Initializes a new instance of the <see cref="ServerLogWriter"/> class. /// </summary> /// <param name="gameModeClient">The game mode client.</param> /// <exception cref="System.ArgumentNullException">gameModeClient</exception> public ServerLogWriter(IGameModeClient gameModeClient) { _gameModeClient = gameModeClient ?? throw new ArgumentNullException(nameof(gameModeClient)); }