-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
unknown
committed
Dec 3, 2020
1 parent
21ef898
commit b147216
Showing
10 changed files
with
919 additions
and
1 deletion.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
Build | ||
*.sln | ||
.vs | ||
obj/ | ||
bin/ |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
# Vina-Framework | ||
Vina Framework is developed to help creating high quality C# FiveM resources. The framework handle & abstract basic stuff that most resource need. | ||
Vina Framework is developed to help creating high quality C# FiveM resources. | ||
The framework handle & abstract basic stuff that most resource need. |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,237 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Threading.Tasks; | ||
|
||
using CitizenFX.Core; | ||
using CitizenFX.Core.Native; | ||
|
||
namespace VinaFrameworkClient.Core | ||
{ | ||
/// <summary> | ||
/// Extend your Client script with this class and add modules to your constructor | ||
/// </summary> | ||
public abstract class BaseClient : BaseScript | ||
{ | ||
/// <summary> | ||
/// This current client resource name | ||
/// </summary> | ||
public static string Name { get; private set; } | ||
|
||
/// <summary> | ||
/// This current client resource name | ||
/// </summary> | ||
public string ResourceName { get { return Name; } } | ||
|
||
private List<Module> modules; | ||
|
||
/// <summary> | ||
/// Extend your Client script with this class and add modules to your constructor | ||
/// </summary> | ||
public BaseClient() | ||
{ | ||
Name = API.GetCurrentResourceName(); | ||
modules = new List<Module>(); | ||
|
||
Debug.WriteLine("============================================================"); | ||
Log($"Initializing..."); | ||
|
||
Tick += initialize; | ||
} | ||
|
||
#region Base Events | ||
|
||
private async Task initialize() | ||
{ | ||
Tick -= initialize; | ||
|
||
await Delay(0); | ||
|
||
Log($"Initialized!"); | ||
TriggerServerEvent($"internal:{Name}:onPlayerClientInitialized"); | ||
} | ||
|
||
#endregion | ||
|
||
#region Methods | ||
|
||
/// <summary> | ||
/// Verify if the module has been loaded. | ||
/// </summary> | ||
/// <param name="moduleType">The module class type. Ex: typeof(MyModule)</param> | ||
/// <returns></returns> | ||
public bool HasModule(Type moduleType) | ||
{ | ||
foreach (Module module in modules) | ||
{ | ||
if (module.GetType() == moduleType) | ||
{ | ||
return true; | ||
} | ||
} | ||
|
||
return false; | ||
} | ||
|
||
/// <summary> | ||
/// Add module by referencing the type of your module class. | ||
/// </summary> | ||
/// <param name="moduleType">The module class type. Ex: typeof(MyModule)</param> | ||
public void AddModule(Type moduleType) | ||
{ | ||
bool error = false; | ||
foreach (Module _module in modules) | ||
{ | ||
if (_module.GetType() == moduleType) | ||
{ | ||
error = true; | ||
LogError(new Exception($"Trying to add existing module {moduleType.Name}!")); | ||
} | ||
} | ||
|
||
if (error) return; | ||
|
||
try | ||
{ | ||
if (!moduleType.IsSubclassOf(typeof(Module))) | ||
throw new Exception($"Trying to add class {moduleType.Name} that is not a subclass of Module!"); | ||
|
||
Module module = (Module)Activator.CreateInstance(moduleType, this); | ||
modules.Add(module); | ||
} | ||
catch (Exception exception) | ||
{ | ||
LogError(exception, $" in {moduleType.Name} > Constructor"); | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// Get a module instance from anywhere, cannot be called inside a module constructor. | ||
/// </summary> | ||
/// <typeparam name="T">The module class type.</typeparam> | ||
/// <returns>Return the module or throw an exception if the module is not found.</returns> | ||
public T GetModule<T>() | ||
{ | ||
foreach (Module module in modules) | ||
{ | ||
if (module.GetType() == typeof(T)) | ||
{ | ||
return (T)Convert.ChangeType(module, typeof(T)); | ||
} | ||
} | ||
|
||
throw new Exception($"Module {typeof(T)} doesn't exist!"); | ||
} | ||
|
||
/// <summary> | ||
/// Register an event. | ||
/// </summary> | ||
/// <param name="eventName">The event name to register.</param> | ||
/// <param name="action">The event delegate to register.</param> | ||
public void RegisterEvent(string eventName, Delegate action) | ||
{ | ||
EventHandlers[eventName] += action; | ||
Log($"Event {eventName} registered!"); | ||
} | ||
|
||
/// <summary> | ||
/// Un-register an event. | ||
/// </summary> | ||
/// <param name="eventName">The event name to un-register.</param> | ||
/// <param name="action">The event delegate to un-register.</param> | ||
public void UnregisterEvent(string eventName, Delegate action) | ||
{ | ||
EventHandlers[eventName] -= action; | ||
Log($"Event {eventName} deregistered!"); | ||
} | ||
|
||
/// <summary> | ||
/// Add a tick to the resource. | ||
/// </summary> | ||
/// <param name="action">The tick delegate to add.</param> | ||
public void AddTick(Func<Task> action) | ||
{ | ||
Tick += action; | ||
Log($"{action.Method.DeclaringType.Name} added Tick {action.Method.Name}!"); | ||
} | ||
|
||
/// <summary> | ||
/// Remove a tick from the resource. | ||
/// </summary> | ||
/// <param name="action">The tick delegate to remove.</param> | ||
public void RemoveTick(Func<Task> action) | ||
{ | ||
Tick -= action; | ||
Log($"{action.Method.DeclaringType.Name} removed Tick {action.Method.Name}!"); | ||
} | ||
|
||
/// <summary> | ||
/// Un-register an event. | ||
/// </summary> | ||
/// <param name="eventName">The event name to un-register.</param> | ||
/// <param name="action">The event delegate to un-register.</param> | ||
internal void AddInternalTick(Func<Task> action) | ||
{ | ||
Tick += action; | ||
} | ||
|
||
/// <summary> | ||
/// Remove a tick from the resource. | ||
/// </summary> | ||
/// <param name="action">The tick delegate to remove.</param> | ||
internal void RemoveInternalTick(Func<Task> action) | ||
{ | ||
Tick -= action; | ||
} | ||
|
||
/// <summary> | ||
/// Get the ExportDictionary. | ||
/// </summary> | ||
/// <returns>Return the ExportDictionary.</returns> | ||
public ExportDictionary GetExports() | ||
{ | ||
return Exports; | ||
} | ||
|
||
/// <summary> | ||
/// Get a specific Export from a resource. | ||
/// </summary> | ||
/// <param name="resourceName"></param> | ||
/// <returns>Return the dynamic export.</returns> | ||
public dynamic GetExport(string resourceName) | ||
{ | ||
return Exports[resourceName]; | ||
} | ||
|
||
/// <summary> | ||
/// Set an Export from this resource. | ||
/// </summary> | ||
/// <param name="name">The name of the Exported method.</param> | ||
/// <param name="method">The delegate of the Exported method.</param> | ||
public void SetExport(string name, Delegate method) | ||
{ | ||
Exports.Add(name, method); | ||
} | ||
|
||
/// <summary> | ||
/// Log a message. | ||
/// </summary> | ||
/// <param name="message">The message to log.</param> | ||
public void Log(string message) | ||
{ | ||
Debug.WriteLine($"{DateTime.Now.ToLongTimeString()} [INFO] {ResourceName.ToUpper()}: {message}"); | ||
} | ||
|
||
/// <summary> | ||
/// Log an exception. | ||
/// </summary> | ||
/// <param name="exception">The Exception to log.</param> | ||
/// <param name="prefix">Some text to add before the log message.</param> | ||
public void LogError(Exception exception, string prefix = "") | ||
{ | ||
string pre = (prefix != "") ? $" {prefix}" : ""; | ||
Debug.WriteLine($"{DateTime.Now.ToLongTimeString()} [ERROR] {ResourceName.ToUpper()}{pre}: {exception.Message}\n{exception.StackTrace}"); | ||
} | ||
|
||
#endregion | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
using System; | ||
using System.Threading.Tasks; | ||
|
||
using CitizenFX.Core; | ||
|
||
namespace VinaFrameworkClient.Core | ||
{ | ||
/// <summary> | ||
/// Extend your module class with this class and add it to your client constructor. | ||
/// </summary> | ||
public abstract class Module | ||
{ | ||
/// <summary> | ||
/// This current module name. | ||
/// </summary> | ||
protected string Name { get; } | ||
|
||
/// <summary> | ||
/// Read-only reference to the client instance. | ||
/// </summary> | ||
protected BaseClient client { get; } | ||
|
||
/// <summary> | ||
/// Extend your module class with this class and add it to your client constructor. | ||
/// </summary> | ||
/// <param name="client"></param> | ||
public Module(BaseClient client) | ||
{ | ||
Name = this.GetType().Name; | ||
this.client = client; | ||
client.AddInternalTick(initialize); | ||
Log($"Instance created!"); | ||
} | ||
|
||
private async Task initialize() | ||
{ | ||
Log($"Initializing..."); | ||
|
||
client.RemoveInternalTick(initialize); | ||
|
||
await BaseClient.Delay(0); | ||
|
||
try | ||
{ | ||
OnModuleInitialized(); | ||
} | ||
catch (Exception exception) | ||
{ | ||
LogError(exception, " in OnModuleInitialized"); | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// Overridable method that run on first tick only. You can get other module from here. | ||
/// </summary> | ||
protected virtual void OnModuleInitialized() | ||
{ | ||
Log($"Initialized!"); | ||
} | ||
|
||
/// <summary> | ||
/// | ||
/// </summary> | ||
/// <param name="msecs"></param> | ||
public static Task Delay(int msecs) | ||
{ | ||
return BaseClient.Delay(msecs); | ||
} | ||
|
||
/// <summary> | ||
/// Log a message from this module. | ||
/// </summary> | ||
/// <param name="message">The message to log.</param> | ||
protected void Log(string message) | ||
{ | ||
Debug.WriteLine($"{DateTime.Now.ToLongTimeString()} [INFO] {client.ResourceName.ToUpper()} > {Name.ToUpper()}: {message}"); | ||
} | ||
|
||
/// <summary> | ||
/// Log an exception from this module. | ||
/// </summary> | ||
/// <param name="exception">The Exception to log.</param> | ||
/// <param name="prefix">Some text to add before the log message.</param> | ||
protected void LogError(Exception exception, string prefix = "") | ||
{ | ||
string pre = (prefix != "") ? $" {prefix}" : ""; | ||
Debug.WriteLine($"{DateTime.Now.ToLongTimeString()} [ERROR] {client.ResourceName.ToUpper()} > {Name.ToUpper()}{pre}: {exception.Message}\n{exception.StackTrace}"); | ||
} | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
using System.Reflection; | ||
using System.Runtime.CompilerServices; | ||
using System.Runtime.InteropServices; | ||
|
||
// General Information about an assembly is controlled through the following | ||
// set of attributes. Change these attribute values to modify the information | ||
// associated with an assembly. | ||
[assembly: AssemblyTitle("VinaFramework")] | ||
[assembly: AssemblyDescription("")] | ||
[assembly: AssemblyConfiguration("")] | ||
[assembly: AssemblyCompany("")] | ||
[assembly: AssemblyProduct("VinaFrameworkClient")] | ||
[assembly: AssemblyCopyright("Copyright © VinaStar 2020")] | ||
[assembly: AssemblyTrademark("")] | ||
[assembly: AssemblyCulture("")] | ||
|
||
// Setting ComVisible to false makes the types in this assembly not visible | ||
// to COM components. If you need to access a type in this assembly from | ||
// COM, set the ComVisible attribute to true on that type. | ||
[assembly: ComVisible(false)] | ||
|
||
// The following GUID is for the ID of the typelib if this project is exposed to COM | ||
[assembly: Guid("6b2efafa-b162-4b97-b837-6d8a8e5162cd")] | ||
|
||
// Version information for an assembly consists of the following four values: | ||
// | ||
// Major Version | ||
// Minor Version | ||
// Build Number | ||
// Revision | ||
// | ||
// You can specify all the values or you can default the Build and Revision Numbers | ||
// by using the '*' as shown below: | ||
// [assembly: AssemblyVersion("1.0.*")] | ||
[assembly: AssemblyVersion("1.0.0.0")] | ||
[assembly: AssemblyFileVersion("1.0.0.0")] |
Oops, something went wrong.