🎉 🚧 Start working on backend

This commit is contained in:
2025-03-06 10:14:21 +01:00
parent 3217b2c4c3
commit c4b9f9287f
17 changed files with 1591 additions and 0 deletions

82
backend/db/db.go Normal file
View File

@ -0,0 +1,82 @@
package db
import (
"context"
"fmt"
"log/slog"
"github.com/HexCardGames/HexDeck/types"
"go.mongodb.org/mongo-driver/v2/bson"
"go.mongodb.org/mongo-driver/v2/mongo"
"go.mongodb.org/mongo-driver/v2/mongo/options"
)
type DatabaseConnection struct {
client *mongo.Client
}
type GlobalStatsCollection struct {
GamesPlayed int `bson:"games_played"`
}
func (conn *DatabaseConnection) QueryRunningRooms() []*types.Room {
res, err := conn.client.Database("hexdeck").Collection("games").Find(context.TODO(), bson.D{{Key: "gamestate", Value: bson.D{{Key: "$ne", Value: types.StateEnded}}}})
if err != nil {
slog.Error("Loading rooms from database failed", "error", err)
return make([]*types.Room, 0)
}
var serializableRooms []SerializableRoom
err = res.All(context.TODO(), &serializableRooms)
if err != nil {
slog.Error("Decoding rooms from database failed", "error", err)
return make([]*types.Room, 0)
}
var rooms []*types.Room = make([]*types.Room, len(serializableRooms))
for i, serializableRoom := range serializableRooms {
room := serializableRoom.ToRoom()
rooms[i] = room
}
return rooms
}
func (conn *DatabaseConnection) InsertRoom(room *types.Room) {
_, err := conn.client.Database("hexdeck").Collection("games").InsertOne(context.TODO(), room)
if err != nil {
slog.Error("Error while inserting room into database", "error", err)
}
}
func (conn *DatabaseConnection) UpdateRoom(room *types.Room) {
result, err := conn.client.Database("hexdeck").Collection("games").UpdateByID(context.TODO(), room.RoomId, bson.D{{Key: "$set", Value: room}})
if err != nil {
slog.Error("Error while updating room in database", "error", err)
}
if result.MatchedCount < 1 {
slog.Warn(fmt.Sprintf("No collections were found while trying to update room data for room '%s'", room.RoomId))
}
}
func (conn *DatabaseConnection) IncrementGamesPlayed() {
conn.client.Database("hexdeck").Collection("global_stats").UpdateOne(context.TODO(), bson.D{}, bson.D{
{Key: "$inc", Value: bson.D{{Key: "games_played", Value: 1}}},
}, options.UpdateOne().SetUpsert(true))
}
func (conn *DatabaseConnection) QueryGlobalStats() GlobalStatsCollection {
res := conn.client.Database("hexdeck").Collection("global_stats").FindOne(context.TODO(), bson.D{})
var stats GlobalStatsCollection
res.Decode(&stats)
return stats
}
func CreateDBConnection(uri string) DatabaseConnection {
client, _ := mongo.Connect(options.Client().ApplyURI(uri))
return DatabaseConnection{client}
}
var Conn DatabaseConnection
func InitDB(uri string) {
Conn = CreateDBConnection(uri)
}

View File

@ -0,0 +1,71 @@
package db
import (
"sync"
"github.com/HexCardGames/HexDeck/decks"
"github.com/HexCardGames/HexDeck/types"
"go.mongodb.org/mongo-driver/v2/bson"
)
type SerializablePlayer struct {
PlayerId bson.ObjectID
SessionToken string
Username string
Permissions int
Cards []bson.D
}
func (serializable *SerializablePlayer) ToPlayer(cardDeckId int) types.Player {
cards := make([]types.Card, len(serializable.Cards))
for i, card := range serializable.Cards {
cards[i] = decks.CardFromInterface(cardDeckId, card)
}
player := types.Player{
PlayerId: serializable.PlayerId,
SessionToken: serializable.SessionToken,
Username: serializable.Username,
Permissions: serializable.Permissions,
Connection: types.WebsocketConnection{IsConnected: false},
Cards: cards,
}
player.ResetInactivity()
return player
}
type SerializableRoom struct {
RoomId bson.ObjectID `bson:"_id"`
JoinCode string
GameState types.GameState
GameOptions types.GameOptions
CardDeckId int
CardDeck bson.D
Players []SerializablePlayer
OwnerId bson.ObjectID
MoveTimeout int
Winner *bson.ObjectID
}
func (serializable SerializableRoom) ToRoom() *types.Room {
players := make([]*types.Player, len(serializable.Players))
for i, serializablePlayer := range serializable.Players {
player := serializablePlayer.ToPlayer(serializable.CardDeckId)
players[i] = &player
}
cardDeck := decks.DeckFromInterface(serializable.CardDeckId, serializable.CardDeck)
room := &types.Room{
RoomId: serializable.RoomId,
JoinCode: serializable.JoinCode,
GameState: serializable.GameState,
GameOptions: serializable.GameOptions,
CardDeckId: serializable.CardDeckId,
CardDeck: cardDeck,
Players: players,
PlayersMutex: &sync.Mutex{},
OwnerId: serializable.OwnerId,
MoveTimeout: serializable.MoveTimeout,
Winner: serializable.Winner,
}
cardDeck.SetRoom(room)
return room
}