ClientPrefs-GoldKingZ.Shared
1.0.4
dotnet add package ClientPrefs-GoldKingZ.Shared --version 1.0.4
NuGet\Install-Package ClientPrefs-GoldKingZ.Shared -Version 1.0.4
<PackageReference Include="ClientPrefs-GoldKingZ.Shared" Version="1.0.4" />
<PackageVersion Include="ClientPrefs-GoldKingZ.Shared" Version="1.0.4" />
<PackageReference Include="ClientPrefs-GoldKingZ.Shared" />
paket add ClientPrefs-GoldKingZ.Shared --version 1.0.4
#r "nuget: ClientPrefs-GoldKingZ.Shared, 1.0.4"
#:package ClientPrefs-GoldKingZ.Shared@1.0.4
#addin nuget:?package=ClientPrefs-GoldKingZ.Shared&version=1.0.4
#tool nuget:?package=ClientPrefs-GoldKingZ.Shared&version=1.0.4
🚀 Quick Start
1. Define your data class
public sealed class ClientPrefs
{
public bool ChatMuted { get; set; } = false;
public int Volume { get; set; } = 50;
public float XAxis { get; set; } = 0f;
public string FavPack { get; set; } = "";
public int Mode { get; set; } = 0;
}
Supported types:
bool,int,long,ulong,float,double,string,DateTimeReserved names (do NOT use):
PlayerName,PlayerSteamID,DateAndTime— injected automatically by ClientPrefs
2. Register in your plugin
using ClientPrefs_GoldKingZ.Shared;
private IPrefsStore<ClientPrefs>? _prefs;
public override void OnAllPluginsLoaded(bool hotReload)
{
var api = ClientPrefsApi.Get();
if (api == null)
{
Logger.LogError("[MyPlugin] Missing cs2-ClientPrefs-GoldKingZ API !");
return;
}
_prefs = api.CreatePrefs<ClientPrefs>(this, new ClientPrefsOptions
{
PrefsAPI_CookiesEnable = PrefsAPI_SaveMode.OnPlayerDisconnect,
});
if (hotReload)
{
_prefs?.Refresh();
}
}
public override void Unload(bool hotReload)
{
_prefs?.Unload();
}
3. Use it
if (_prefs?.TryGetValue(player.Slot, out var data) != true) return;
data.ChatMuted = !data.ChatMuted;
data.Volume = 75;
That's it. Changes are tracked automatically and saved on disconnect or map end.
Note:
TryGetValuereturnsfalsewhile a player's data is still loading. The player automatically gets a chat message to wait, and another when everything is loaded. Just handle thefalsereturn and let the player retry.
🧩 Multiple Isolated Stores
One plugin can register more than one store — call CreatePrefs<T>() once per data class. Each store gets its own table and never shares rows or columns with the others.
private IPrefsStore<ClientPrefs>? _prefs;
private IPrefsStore<ClientPrefsHud>? _hud;
public override void OnAllPluginsLoaded(bool hotReload)
{
var api = ClientPrefsApi.Get();
if (api == null) return;
_prefs = api.CreatePrefs<ClientPrefs>(this, new ClientPrefsOptions { /* ... */ });
_hud = api.CreatePrefs<ClientPrefsHud>(this, new ClientPrefsOptions
{
PrefsAPI_TableName = "test_hud", // exact table name on SQLite AND MySQL
});
}
public override void Unload(bool hotReload)
{
_prefs?.Unload();
_hud?.Unload();
}
Without
PrefsAPI_TableName, each store auto-names its table<FolderName>_<ClassName>— so multiple stores never collide.
⚙️ Configuration Options
| Option | Values | Default |
|---|---|---|
PrefsAPI_CookiesEnable |
Disabled / OnPlayerDisconnect / OnMapEnd |
Disabled |
PrefsAPI_CookiesAutoRemoveInactivePlayersOlderThanDays |
0 = never delete, 1+ = days |
7 |
PrefsAPI_MySqlEnable |
Disabled / OnPlayerDisconnect / OnMapEnd |
Disabled |
PrefsAPI_MySqlAutoRemoveInactivePlayersOlderThanDays |
0 = never delete, 1+ = days |
7 |
PrefsAPI_MySqlConnectionTimeout |
seconds | 30 |
PrefsAPI_MySqlRetryAttempts |
any positive integer | 3 |
PrefsAPI_MySqlRetryDelay |
seconds between retries | 2 |
PrefsAPI_TableName |
string or null for auto. Applies to both SQLite and MySQL |
null → <FolderName>_<ClassName> |
PrefsAPI_MySqlConfig |
MySqlConfig { Server, Port, Database, Username, Password } or MySql_Servers list for failover |
empty |
PrefsAPI_ReloadOnReconnect |
true = reload from storage / false = keep memory |
false |
PrefsAPI_LoadDefaultAfterDrop |
true = give defaults after drop / false = empty until rejoin |
true |
PrefsAPI_DebugEnable |
true = show all logs / false = errors only |
false |
📖 API Methods
Read / Write Data (in-memory, instant)
| Method | Description |
|---|---|
TryGetValue(player, out data) |
Get player data by controller. Returns false if not loaded |
TryGetValue(slot, out data) |
Get player data by slot number |
TryGetValue(steamId, out data) |
Get player data by SteamID64 (must be in memory) |
TryGetValue(player, action) |
Run action if player is loaded (callback style) |
TryGetValue(slot, action) |
Run action if slot is loaded (callback style) |
TryGetValue(steamId, action) |
Run action if SteamID64 is in memory and loaded |
Player Loaded Event
| Method | Description |
|---|---|
OnPlayerLoaded(player, callback) |
Run callback ONCE when THIS store finishes loading the player |
OnPlayerLoaded(player, callback, All_Plugins: true) |
Run callback ONCE when EVERY plugin finished loading the player |
Call it anywhere (a connect event, etc). It fires once per call for the player you pass — it is not a registration. Call it twice = fires twice, you control it. Runs on the game thread.
DataBase (works for OFFLINE players)
| Method | Description |
|---|---|
FetchPlayer(steamId, callback) |
Get one player's stored data (offline OK) |
FetchPlayer<TResult>(steamId, callback, All_Plugins: true) |
Get one player from EVERY plugin into your own result class |
SearchByField(field, value, callback) |
Find all players where a field equals a value |
SearchByField<TResult>(field, value, callback, All_Plugins: true) |
Search EVERY plugin into your own result class |
ModifyAndSave(steamId, modify, done) |
Modify one player's stored data and save it (offline OK, this plugin) |
Reads cookies + MySQL per this store's config — newest data wins. In
<TResult>results,result.Pluginandresult.Tabletell you which plugin / table each row came from.
Force Save
| Method | Description |
|---|---|
ForceSave(player) / (slot) / (steamId) |
Save this player now — this plugin only |
ForceSave(..., All_Plugins: true) |
Save this player across ALL plugins using ClientPrefs |
ForceSave(..., done: saved => { }) |
Optional callback — true = saved OK |
Drop Player (wipe memory + cookies.db + MySQL)
| Method | Description |
|---|---|
DropPlayer(player) / (slot) / (steamId) |
Wipe this player — this plugin only |
DropPlayer(..., All_Plugins: true) |
Wipe this player from ALL plugins using ClientPrefs |
DropPlayer(..., done: dropped => { }) |
Optional callback — true = wiped |
DropPlayerbysteamIdworks even if the player is offline (deletes from storage). Wipes only the backends this store has enabled.
Lifecycle
| Method | Description |
|---|---|
Refresh() |
Save all changed data + reload all players from storage |
Unload() |
Save all changed data + close connections + clear memory |
🔄 Auto-Migration
You can freely edit your data class at any time. ClientPrefs automatically updates your cookies.db and MySQL table to match — no need to delete the database.
| Change | What happens |
|---|---|
| Add a new field | New column added, existing players keep their data |
| Remove a field | Column dropped, other columns stay untouched |
| Change field type | Column type updated (table rebuilt for cookies, MODIFY COLUMN for MySQL) |
No data loss when adding or removing fields. Changing a field's type or renaming it (drop old + add new) resets that one column to its default — other columns are unaffected. Just edit your data class, rebuild your plugin, and reload.
📂 Folder Structure
After installation:
csgo/
└── addons/counterstrikesharp/
├── plugins/
│ └── ClientPrefs-GoldKingZ/ ← Core plugin
│ ├── ClientPrefs-GoldKingZ.dll
│ ├── ClientPrefs-GoldKingZ.Shared.dll
│ ├── Microsoft.Data.Sqlite.dll
│ ├── MySqlConnector.dll
│ ├── SQLitePCLRaw.batteries_v2.dll
│ ├── SQLitePCLRaw.core.dll
│ ├── SQLitePCLRaw.provider.e_sqlite3.dll
│ ├── e_sqlite3.dll ← Native SQLite (Windows)
│ ├── libe_sqlite3.so ← Native SQLite (Linux)
│ └── lang/
│ └── en.json ← Chat messages
└── shared/
└── ClientPrefs-GoldKingZ.Shared/
└── ClientPrefs-GoldKingZ.Shared.dll ← API reference for developers
Each consumer plugin gets its own isolated storage inside the core folder:
plugins/
└── ClientPrefs-GoldKingZ/
├── YourPlugin/
│ └── cookies.db ← Created automatically
└── AnotherPlugin/
└── cookies.db
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- CounterStrikeSharp.API (>= 1.0.373)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.