162 lines
6.5 KiB
C#
162 lines
6.5 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|
|
} |