various thingies
This commit is contained in:
@@ -0,0 +1,162 @@
|
||||
using LabApi.Features;
|
||||
using LabApi.Loader.Features.Plugins;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Data.SQLite;
|
||||
using LabApi.Events.Arguments.PlayerEvents;
|
||||
using LabApi.Events.Handlers;
|
||||
using LabApi.Loader;
|
||||
|
||||
namespace StatsTracker
|
||||
{
|
||||
public class StatsTracker : Plugin
|
||||
{
|
||||
public override string Name => "StatsTracker";
|
||||
public override string Author => "Code002Lover";
|
||||
public override Version Version { get; } = new(1, 0, 0);
|
||||
public override string Description => "Tracks stats for players.";
|
||||
public override Version RequiredApiVersion { get; } = new(LabApiProperties.CompiledVersion);
|
||||
|
||||
private string _dbPath;
|
||||
private readonly ConcurrentDictionary<string, PlayerStats> _currentSessionStats = new();
|
||||
|
||||
private class PlayerStats
|
||||
{
|
||||
public int Kills { get; set; }
|
||||
public int Deaths { get; set; }
|
||||
public Dictionary<ItemType, int> ItemUsage { get; set; } = new();
|
||||
}
|
||||
|
||||
public override void Enable()
|
||||
{
|
||||
_dbPath = Path.Combine(this.GetConfigDirectory().FullName, "stats.db");
|
||||
InitializeDatabase();
|
||||
|
||||
PlayerEvents.Death += OnPlayerDied;
|
||||
PlayerEvents.UsedItem += OnItemUsed;
|
||||
PlayerEvents.Left += OnPlayerLeft;
|
||||
}
|
||||
|
||||
public override void Disable()
|
||||
{
|
||||
PlayerEvents.Death -= OnPlayerDied;
|
||||
PlayerEvents.UsedItem -= OnItemUsed;
|
||||
PlayerEvents.Left -= OnPlayerLeft;
|
||||
|
||||
// Save any remaining stats
|
||||
foreach (var player in _currentSessionStats)
|
||||
{
|
||||
SavePlayerStats(player.Key, player.Value);
|
||||
}
|
||||
_currentSessionStats.Clear();
|
||||
}
|
||||
|
||||
private void InitializeDatabase()
|
||||
{
|
||||
using var connection = new SQLiteConnection($"Data Source={_dbPath}");
|
||||
connection.Open();
|
||||
|
||||
using var command = connection.CreateCommand();
|
||||
command.CommandText = """
|
||||
|
||||
CREATE TABLE IF NOT EXISTS PlayerStats (
|
||||
UserId TEXT PRIMARY KEY,
|
||||
Kills INTEGER DEFAULT 0,
|
||||
Deaths INTEGER DEFAULT 0
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS ItemUsage (
|
||||
UserId TEXT,
|
||||
ItemType INTEGER,
|
||||
UsageCount INTEGER DEFAULT 0,
|
||||
PRIMARY KEY (UserId, ItemType)
|
||||
);
|
||||
""";
|
||||
command.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
private void OnPlayerDied(PlayerDeathEventArgs ev)
|
||||
{
|
||||
if (ev.Attacker != null)
|
||||
{
|
||||
var killerStats = _currentSessionStats.GetOrAdd(ev.Attacker.UserId, _ => new PlayerStats());
|
||||
killerStats.Kills++;
|
||||
}
|
||||
|
||||
var victimStats = _currentSessionStats.GetOrAdd(ev.Player.UserId, _ => new PlayerStats());
|
||||
victimStats.Deaths++;
|
||||
}
|
||||
|
||||
private void OnItemUsed(PlayerUsedItemEventArgs ev)
|
||||
{
|
||||
var stats = _currentSessionStats.GetOrAdd(ev.Player.UserId, _ => new PlayerStats());
|
||||
|
||||
if (!stats.ItemUsage.ContainsKey(ev.UsableItem.Type))
|
||||
stats.ItemUsage[ev.UsableItem.Type] = 0;
|
||||
|
||||
stats.ItemUsage[ev.UsableItem.Type]++;
|
||||
}
|
||||
|
||||
private void OnPlayerLeft(PlayerLeftEventArgs ev)
|
||||
{
|
||||
if (_currentSessionStats.TryRemove(ev.Player.UserId, out var stats))
|
||||
{
|
||||
SavePlayerStats(ev.Player.UserId, stats);
|
||||
}
|
||||
}
|
||||
|
||||
private void SavePlayerStats(string userId, PlayerStats stats)
|
||||
{
|
||||
using var connection = new SQLiteConnection($"Data Source={_dbPath}");
|
||||
connection.Open();
|
||||
using var transaction = connection.BeginTransaction();
|
||||
|
||||
try
|
||||
{
|
||||
// Update player stats
|
||||
using (var command = connection.CreateCommand())
|
||||
{
|
||||
command.CommandText = """
|
||||
|
||||
INSERT INTO PlayerStats (UserId, Kills, Deaths)
|
||||
VALUES (@userId, @kills, @deaths)
|
||||
ON CONFLICT(UserId) DO UPDATE SET
|
||||
Kills = Kills + @kills,
|
||||
Deaths = Deaths + @deaths;
|
||||
""";
|
||||
|
||||
command.Parameters.AddWithValue("@userId", userId);
|
||||
command.Parameters.AddWithValue("@kills", stats.Kills);
|
||||
command.Parameters.AddWithValue("@deaths", stats.Deaths);
|
||||
command.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
// Update item usage
|
||||
foreach (var itemInfoPair in stats.ItemUsage)
|
||||
{
|
||||
var itemType = itemInfoPair.Key;
|
||||
var count = itemInfoPair.Value;
|
||||
using var command = connection.CreateCommand();
|
||||
command.CommandText = """
|
||||
|
||||
INSERT INTO ItemUsage (UserId, ItemType, UsageCount)
|
||||
VALUES (@userId, @itemType, @count)
|
||||
ON CONFLICT(UserId, ItemType) DO UPDATE SET
|
||||
UsageCount = UsageCount + @count;
|
||||
""";
|
||||
|
||||
command.Parameters.AddWithValue("@userId", userId);
|
||||
command.Parameters.AddWithValue("@itemType", (int)itemType);
|
||||
command.Parameters.AddWithValue("@count", count);
|
||||
command.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
transaction.Commit();
|
||||
}
|
||||
catch
|
||||
{
|
||||
transaction.Rollback();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user