import sqlite3
|
|
import json
|
|
from pathlib import Path
|
|
from typing import Optional, Dict, List
|
|
|
|
class Database:
|
|
"""Handles all database operations"""
|
|
|
|
def __init__(self, db_path: str = "data/game.db"):
|
|
self.db_path = db_path
|
|
Path("data").mkdir(exist_ok=True)
|
|
|
|
def _get_connection(self):
|
|
"""Get database connection"""
|
|
conn = sqlite3.connect(self.db_path)
|
|
conn.row_factory = sqlite3.Row
|
|
return conn
|
|
|
|
def init_db(self):
|
|
"""Initialize database tables"""
|
|
with self._get_connection() as conn:
|
|
# Players table
|
|
conn.execute('''
|
|
CREATE TABLE IF NOT EXISTS players (
|
|
player_id TEXT PRIMARY KEY,
|
|
nickname TEXT UNIQUE NOT NULL,
|
|
money INTEGER NOT NULL,
|
|
population INTEGER NOT NULL,
|
|
color TEXT NOT NULL,
|
|
last_online REAL NOT NULL
|
|
)
|
|
''')
|
|
|
|
# Buildings table
|
|
conn.execute('''
|
|
CREATE TABLE IF NOT EXISTS buildings (
|
|
x INTEGER NOT NULL,
|
|
y INTEGER NOT NULL,
|
|
type TEXT NOT NULL,
|
|
owner_id TEXT NOT NULL,
|
|
name TEXT,
|
|
placed_at REAL NOT NULL,
|
|
PRIMARY KEY (x, y),
|
|
FOREIGN KEY (owner_id) REFERENCES players (player_id)
|
|
)
|
|
''')
|
|
|
|
conn.commit()
|
|
|
|
def save_game_state(self, game_state):
|
|
"""Save complete game state to database"""
|
|
with self._get_connection() as conn:
|
|
# Save players
|
|
conn.execute('DELETE FROM players')
|
|
|
|
for player in game_state.players.values():
|
|
conn.execute('''
|
|
INSERT INTO players (player_id, nickname, money, population, color, last_online)
|
|
VALUES (?, ?, ?, ?, ?, ?)
|
|
''', (
|
|
player.player_id,
|
|
player.nickname,
|
|
player.money,
|
|
player.population,
|
|
player.color,
|
|
player.last_online
|
|
))
|
|
|
|
# Save buildings
|
|
conn.execute('DELETE FROM buildings')
|
|
|
|
for building in game_state.buildings.values():
|
|
conn.execute('''
|
|
INSERT INTO buildings (x, y, type, owner_id, name, placed_at)
|
|
VALUES (?, ?, ?, ?, ?, ?)
|
|
''', (
|
|
building.x,
|
|
building.y,
|
|
building.building_type.value,
|
|
building.owner_id,
|
|
building.name,
|
|
building.placed_at
|
|
))
|
|
|
|
conn.commit()
|
|
|
|
def load_game_state(self) -> dict:
|
|
"""Load complete game state from database"""
|
|
try:
|
|
with self._get_connection() as conn:
|
|
# Load players
|
|
players = []
|
|
cursor = conn.execute('SELECT * FROM players')
|
|
for row in cursor:
|
|
players.append({
|
|
"player_id": row["player_id"],
|
|
"nickname": row["nickname"],
|
|
"money": row["money"],
|
|
"population": row["population"],
|
|
"color": row["color"],
|
|
"last_online": row["last_online"]
|
|
})
|
|
|
|
# Load buildings
|
|
buildings = []
|
|
cursor = conn.execute('SELECT * FROM buildings')
|
|
for row in cursor:
|
|
buildings.append({
|
|
"x": row["x"],
|
|
"y": row["y"],
|
|
"type": row["type"],
|
|
"owner_id": row["owner_id"],
|
|
"name": row["name"],
|
|
"placed_at": row["placed_at"]
|
|
})
|
|
|
|
return {
|
|
"players": players,
|
|
"buildings": buildings
|
|
}
|
|
except Exception as e:
|
|
print(f"Error loading game state: {e}")
|
|
return {"players": [], "buildings": []}
|