This commit is contained in:
abdelaziz
2026-03-30 07:49:37 +02:00
parent 9440351bc0
commit bc4118704e
21 changed files with 1785 additions and 124 deletions
+209
View File
@@ -0,0 +1,209 @@
using System.IO;
using Microsoft.Data.Sqlite;
namespace CheckersSpielBot
{
public class DatabaseService
{
private readonly string _connectionString;
public DatabaseService()
{
string dbPath = Path.Combine(
AppDomain.CurrentDomain.BaseDirectory, "checkers.db");
_connectionString = $"Data Source={dbPath}";
InitializeSchema();
}
private void InitializeSchema()
{
using var conn = new SqliteConnection(_connectionString);
conn.Open();
var cmd = conn.CreateCommand();
cmd.CommandText = @"
CREATE TABLE IF NOT EXISTS players (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT NOT NULL UNIQUE,
password TEXT NOT NULL,
created_at TEXT NOT NULL DEFAULT (datetime('now'))
);
CREATE TABLE IF NOT EXISTS gameHistory (
id INTEGER PRIMARY KEY AUTOINCREMENT,
playerId INTEGER NOT NULL,
startedAt TEXT NOT NULL DEFAULT (datetime('now')),
endedAt TEXT NULL,
winner TEXT NULL,
wentFirst TEXT NOT NULL DEFAULT 'player',
FOREIGN KEY (playerId) REFERENCES players(id)
);";
cmd.ExecuteNonQuery();
}
public bool RegisterPlayer(string username, string password, out string error)
{
error = string.Empty;
try
{
using var conn = new SqliteConnection(_connectionString);
conn.Open();
var check = conn.CreateCommand();
check.CommandText = "SELECT COUNT(*) FROM players WHERE username = @u";
check.Parameters.AddWithValue("@u", username);
long exists = (long)check.ExecuteScalar()!;
if (exists > 0)
{
error = "Username already exists.";
return false;
}
string hashed = BCrypt.Net.BCrypt.HashPassword(password);
var cmd = conn.CreateCommand();
cmd.CommandText = "INSERT INTO players (username, password) VALUES (@u, @p)";
cmd.Parameters.AddWithValue("@u", username);
cmd.Parameters.AddWithValue("@p", hashed);
cmd.ExecuteNonQuery();
return true;
}
catch (Exception ex)
{
error = ex.Message;
return false;
}
}
public bool LoginPlayer(string username, string password,
out int playerId, out string error)
{
playerId = -1;
error = string.Empty;
try
{
using var conn = new SqliteConnection(_connectionString);
conn.Open();
var cmd = conn.CreateCommand();
cmd.CommandText = "SELECT id, password FROM players WHERE username = @u";
cmd.Parameters.AddWithValue("@u", username);
using var reader = cmd.ExecuteReader();
if (!reader.Read())
{
error = "Username not found.";
return false;
}
int id = reader.GetInt32(0);
string stored = reader.GetString(1);
if (!BCrypt.Net.BCrypt.Verify(password, stored))
{
error = "Incorrect password.";
return false;
}
playerId = id;
return true;
}
catch (Exception ex)
{
error = ex.Message;
return false;
}
}
public int StartGame(int playerId, string wentFirst)
{
try
{
using var conn = new SqliteConnection(_connectionString);
conn.Open();
var cmd = conn.CreateCommand();
cmd.CommandText = @"
INSERT INTO gameHistory (playerId, startedAt, wentFirst)
VALUES (@pid, datetime('now'), @wf);
SELECT last_insert_rowid();";
cmd.Parameters.AddWithValue("@pid", playerId);
cmd.Parameters.AddWithValue("@wf", wentFirst);
return Convert.ToInt32(cmd.ExecuteScalar());
}
catch { return -1; }
}
public void EndGame(int gameId, string winner)
{
try
{
using var conn = new SqliteConnection(_connectionString);
conn.Open();
var cmd = conn.CreateCommand();
cmd.CommandText = @"
UPDATE gameHistory
SET endedAt = datetime('now'), winner = @w
WHERE id = @id";
cmd.Parameters.AddWithValue("@w", winner);
cmd.Parameters.AddWithValue("@id", gameId);
cmd.ExecuteNonQuery();
}
catch { }
}
public List<GameHistoryEntry> GetHistory(int playerId)
{
var list = new List<GameHistoryEntry>();
try
{
using var conn = new SqliteConnection(_connectionString);
conn.Open();
var cmd = conn.CreateCommand();
cmd.CommandText = @"
SELECT id, startedAt, endedAt, winner, wentFirst
FROM gameHistory
WHERE playerId = @pid
ORDER BY startedAt DESC";
cmd.Parameters.AddWithValue("@pid", playerId);
using var reader = cmd.ExecuteReader();
while (reader.Read())
{
var entry = new GameHistoryEntry
{
Id = reader.GetInt32(0),
StartedAt = DateTime.Parse(reader.GetString(1)),
EndedAt = reader.IsDBNull(2)
? null
: DateTime.Parse(reader.GetString(2)),
Winner = reader.IsDBNull(3) ? "—" : reader.GetString(3),
WentFirst = reader.GetString(4)
};
list.Add(entry);
}
}
catch { }
return list;
}
}
public class GameHistoryEntry
{
public int Id { get; set; }
public DateTime StartedAt { get; set; }
public DateTime? EndedAt { get; set; }
public string Winner { get; set; } = "—";
public string WentFirst { get; set; } = "—";
public string Duration => EndedAt.HasValue
? $"{(EndedAt.Value - StartedAt).TotalMinutes:F0} min"
: "In progress";
}
}