Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
121 changes: 76 additions & 45 deletions PlayerSettings/CPlayerSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,28 @@

namespace PlayerSettings
{
internal class CPlayerSettings
{
private int userid;
private CCSPlayerController player;
private Dictionary<string, string> cached_values;

public CPlayerSettings(CCSPlayerController _player)
{
player = _player;
userid = -1;
Storage.GetUserIdAsync(player, (userid) => this.userid = userid);
cached_values = new Dictionary<string, string>();
}
internal class CPlayerSettings
{
private int userid;
private CCSPlayerController player;
private Dictionary<string, string> cached_values;
private readonly Dictionary<string, string> pending_updates;
private readonly TaskCompletionSource<int> userIdReady;

public CPlayerSettings(CCSPlayerController _player)
{
player = _player;
userid = -1;
cached_values = new Dictionary<string, string>();
pending_updates = new Dictionary<string, string>();
userIdReady = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
Storage.GetUserIdAsync(player, (userid) =>
{
this.userid = userid;
userIdReady.TrySetResult(userid);
FlushPendingUpdates();
});
}

public string GetValue(string param, string default_value)
{
Expand All @@ -34,36 +43,58 @@ public string GetValue(string param, string default_value)
return value;
}

public void SetValue(string param, string value)
{
cached_values[param] = value;
Storage.SetUserSettingValue(userid, param, value);
}

public int UserId()
{
return userid;
}

public bool EqualPlayer(CCSPlayerController _player)
{
return player == _player;
}

internal void ParseLoadedSettings(List<List<string>> rows, List<Action<CCSPlayerController>> actions)
{
Task.Run(() =>
{
foreach (var row in rows)
{
cached_values[row[0]] = row[1];
}
}).ContinueWith((_) =>
{
foreach (var action in actions)
Server.NextFrameAsync(() => action(player));
});
}
public void SetValue(string param, string value)
{
cached_values[param] = value;
if (userid == -1)
{
pending_updates[param] = value;
return;
}

Storage.SetUserSettingValue(userid, param, value);
}

}
}
public int UserId()
{
return userid;
}

public Task<int> WaitForUserIdAsync()
{
if (userid != -1)
return Task.FromResult(userid);

return userIdReady.Task;
}

public bool EqualPlayer(CCSPlayerController _player)
{
return player == _player;
}

internal void ParseLoadedSettings(List<List<string>> rows, List<Action<CCSPlayerController>> actions)
{
foreach (var row in rows)
{
cached_values[row[0]] = row[1];
}

var actionsSnapshot = actions.ToArray();
foreach (var action in actionsSnapshot)
Server.NextFrameAsync(() => action(player));
}

private void FlushPendingUpdates()
{
if (pending_updates.Count == 0)
return;

foreach (var entry in pending_updates)
Storage.SetUserSettingValue(userid, entry.Key, entry.Value);

pending_updates.Clear();
}

}
}
38 changes: 22 additions & 16 deletions PlayerSettings/Main.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,27 +35,33 @@ public void OnConfigParsed(PluginConfig config)

private ISettingsApi? _api;
private readonly PluginCapability<ISettingsApi?> _pluginCapability = new("settings:nfcore");
public override void Load(bool hotReload)
{
_api = new SettingsApi();
Capabilities.RegisterPluginCapability(_pluginCapability, () => _api);
RegisterListener<Listeners.OnClientAuthorized>(OnClientAuthorized);

if (hotReload)
foreach (var player in Utilities.GetPlayers())
OnClientAuthorized(player.Slot, player.AuthorizedSteamID);
}
public override void Load(bool hotReload)
{
_api = new SettingsApi();
Capabilities.RegisterPluginCapability(_pluginCapability, () => _api);
RegisterListener<Listeners.OnClientAuthorized>(OnClientAuthorized);
RegisterListener<Listeners.OnClientDisconnect>(OnClientDisconnect);

if (hotReload)
foreach (var player in Utilities.GetPlayers())
OnClientAuthorized(player.Slot, player.AuthorizedSteamID);
}

public override void Unload(bool hotReload)
{
Storage.Close();
}

private void OnClientAuthorized(int slot, SteamID steamID)
{
((SettingsApi)_api).LoadOnConnect(Utilities.GetPlayerFromSlot(slot));
}
}
private void OnClientAuthorized(int slot, SteamID steamID)
{
((SettingsApi)_api).LoadOnConnect(Utilities.GetPlayerFromSlot(slot));
}

private void OnClientDisconnect(int slot)
{
((SettingsApi)_api).RemovePlayer(slot);
}
}

public struct DatabaseParams
{
Expand All @@ -78,4 +84,4 @@ public bool IsLocal()
{
return (Host == "127.0.0.1:3306" && Name == "" && User == "" && Password == "") || Host == "";
}
}
}
83 changes: 41 additions & 42 deletions PlayerSettings/SettingsApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,19 @@
namespace PlayerSettings
{

internal class SettingsApi : ISettingsApi
{
private CPlayerSettings[] settings;
internal List<Action<CCSPlayerController>> actions = new List<Action<CCSPlayerController>>();
public SettingsApi()
{
settings = Array.Empty<CPlayerSettings>();
if (actions == null)
actions = new List<Action<CCSPlayerController>>();
else
actions.Clear();
}
internal class SettingsApi : ISettingsApi
{
private readonly Dictionary<int, CPlayerSettings> settingsBySlot;
internal List<Action<CCSPlayerController>> actions = new List<Action<CCSPlayerController>>();
public SettingsApi()
{
settingsBySlot = new Dictionary<int, CPlayerSettings>();
if (actions == null)
actions = new List<Action<CCSPlayerController>>();
else
actions.Clear();
SettingItems.Init();
}

public void AddHook(Action<CCSPlayerController> action)
{
Expand All @@ -32,28 +33,23 @@ public void RemHook(Action<CCSPlayerController> action)
actions.RemoveAll(x => x == action);
}

private CPlayerSettings FindUser(CCSPlayerController player)
{
foreach (var item in this.settings)
{
if (item.EqualPlayer(player))
{
//Console.WriteLine($"Returned found: {item.UserId()}");
return item;
}
}

var newInst = new CPlayerSettings(player);
AddPlayerInst(newInst);
return newInst;
}

private void AddPlayerInst(CPlayerSettings inst)
{
Array.Resize(ref settings, settings.Length + 1);
settings[settings.Length - 1] = inst;
}

private CPlayerSettings FindUser(CCSPlayerController player)
{
if (settingsBySlot.TryGetValue(player.Slot, out var existing))
{
if (existing.EqualPlayer(player))
return existing;
}

var newInst = new CPlayerSettings(player);
settingsBySlot[player.Slot] = newInst;
return newInst;
}

internal void RemovePlayer(int slot)
{
settingsBySlot.Remove(slot);
}

public string GetPlayerSettingsValue(CCSPlayerController player, string param, string default_value)
{
Expand All @@ -66,14 +62,17 @@ public void SetPlayerSettingsValue(CCSPlayerController player, string param, str
FindUser(player).SetValue(param, value);
}

internal void LoadOnConnect(CCSPlayerController player)
{
var user = FindUser(player);

Task.Run(() => { while (user.UserId() == -1) Task.Delay(50).Wait(); }).ContinueWith((_) =>
Storage.LoadSettings(user.UserId(), (vars) => user.ParseLoadedSettings(vars, actions))
);
}
internal void LoadOnConnect(CCSPlayerController player)
{
var user = FindUser(player);
_ = LoadOnConnectAsync(user);
}

private async Task LoadOnConnectAsync(CPlayerSettings user)
{
await user.WaitForUserIdAsync().ConfigureAwait(false);
Storage.LoadSettings(user.UserId(), (vars) => user.ParseLoadedSettings(vars, actions));
}

public void RegisterTogglableSetting(string name, string viewName)
{
Expand Down