Hey aleladner
In all of my plugins that work with MySQL I use the following ThreadHelper class:
https://github.com/RestoreMonarchyPlugins/PlayerStats/blob/master/PlayerStats/Helpers/ThreadHelper.cs
The ThreadHelper.RunAsynchronously
runs the method (Action action
) on a separate thread instead of the main game thread which prevents lagging. Here you can see some usage examples from PlayerStats plugin:
https://github.com/search?q=repo%3ARestoreMonarchyPlugins%2FPlayerStats%20ThreadHelper&type=code
Remember that you cannot and should not run any game methods such as EffectManager.sendUIEffect
, PlayerInventory.tryAddItem
or any chat methods on a non-game thread. When you need to execute game method after querying a database on a separate thread, you should use the ThreadHelper.RunSynchronously
which enqueues and then executes the callback method on a main thread using Rocket TaskDispatcher.QueueOnMainThread
. Here’s an example:
UnturnedPlayer player = (UnturnedPlayer)caller;
ThreadHelper.RunAsynchronously(() =>
{
// Query the database on separate thread
IEnumerable<ushort> playerItems = database.GetPlayerItems(player.Id);
// Then make a callback to main thread to execute game methods
ThreadHelper.RunSynchronously(() =>
{
foreach (ushort itemId in playerItems)
{
Item item = new Item(itemId, EItemOrigin.ADMIN);
player.Player.inventory.tryAddItem(item, true);
}
UnturnedChat.Say(player, $"You were given {playerItems.Count()} loadout items.");
});
});