mirror of
https://github.com/HexCardGames/HexDeck.git
synced 2025-09-05 11:18:38 +02:00
🎉 🚧 Start working on backend
This commit is contained in:
142
backend/types/types.go
Normal file
142
backend/types/types.go
Normal file
@ -0,0 +1,142 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"github.com/zishang520/socket.io/v2/socket"
|
||||
"go.mongodb.org/mongo-driver/v2/bson"
|
||||
)
|
||||
|
||||
type WebsocketConnection struct {
|
||||
IsConnected bool
|
||||
Socket *socket.Socket
|
||||
}
|
||||
|
||||
type Card interface {
|
||||
}
|
||||
|
||||
type CardDeck interface {
|
||||
Init(*Room)
|
||||
SetRoom(*Room)
|
||||
IsEmpty() bool
|
||||
DrawCard() Card
|
||||
CanPlay(Card) bool
|
||||
PlayCard(Card) bool
|
||||
GetTopCard() Card
|
||||
UpdatePlayedCard(interface{}) Card
|
||||
IsPlayerActive(*Player) bool
|
||||
}
|
||||
|
||||
type Player struct {
|
||||
PlayerId bson.ObjectID
|
||||
SessionToken string
|
||||
Username string
|
||||
Permissions int
|
||||
Cards []Card `json:"-"`
|
||||
Connection WebsocketConnection `bson:"-" json:"-"`
|
||||
InactivityTimeout int `bson:"-" json:"-"`
|
||||
}
|
||||
|
||||
func (player *Player) ResetInactivity() {
|
||||
player.InactivityTimeout = 20 * 1000
|
||||
}
|
||||
|
||||
func (player *Player) SetPermissionBit(bit RoomPermission) {
|
||||
player.Permissions |= (1 << bit)
|
||||
}
|
||||
|
||||
func (player *Player) ClearPermissionBit(bit RoomPermission) {
|
||||
player.Permissions &= ^(1 << bit)
|
||||
}
|
||||
|
||||
func (player *Player) HasPermissionBit(bit RoomPermission) bool {
|
||||
return player.Permissions&(1<<bit) > 0
|
||||
}
|
||||
|
||||
type GameState int
|
||||
|
||||
const (
|
||||
StateLobby GameState = iota
|
||||
StateRunning
|
||||
StateEnded
|
||||
)
|
||||
|
||||
type RoomPermission int
|
||||
|
||||
const (
|
||||
PermissionHost RoomPermission = 0
|
||||
)
|
||||
|
||||
type GameOptions struct {
|
||||
}
|
||||
|
||||
type Room struct {
|
||||
RoomId bson.ObjectID `bson:"_id"`
|
||||
JoinCode string
|
||||
GameState GameState
|
||||
GameOptions GameOptions
|
||||
CardDeckId int
|
||||
CardDeck CardDeck
|
||||
Players []*Player
|
||||
PlayersMutex *sync.Mutex `bson:"-"`
|
||||
OwnerId bson.ObjectID
|
||||
MoveTimeout int
|
||||
Winner *bson.ObjectID
|
||||
}
|
||||
|
||||
func (room *Room) AppendPlayer(player *Player) {
|
||||
room.PlayersMutex.Lock()
|
||||
defer room.PlayersMutex.Unlock()
|
||||
room.Players = append(room.Players, player)
|
||||
}
|
||||
|
||||
func (room *Room) RemovePlayer(target Player) bool {
|
||||
room.PlayersMutex.Lock()
|
||||
defer room.PlayersMutex.Unlock()
|
||||
return room.RemovePlayerUnsafe(target)
|
||||
}
|
||||
|
||||
func (room *Room) FindPlayer(playerId bson.ObjectID) *Player {
|
||||
room.PlayersMutex.Lock()
|
||||
defer room.PlayersMutex.Unlock()
|
||||
|
||||
for _, player := range room.Players {
|
||||
if player.PlayerId == playerId {
|
||||
return player
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (room *Room) RemovePlayerUnsafe(target Player) bool {
|
||||
foundHost := false
|
||||
foundPlayer := false
|
||||
for i := 0; i < len(room.Players); i++ {
|
||||
player := room.Players[i]
|
||||
if player.PlayerId == target.PlayerId {
|
||||
room.Players = append(room.Players[:i], room.Players[i+1:]...)
|
||||
foundPlayer = true
|
||||
i--
|
||||
continue
|
||||
}
|
||||
if player.HasPermissionBit(PermissionHost) {
|
||||
foundHost = true
|
||||
}
|
||||
}
|
||||
if !foundPlayer {
|
||||
return false
|
||||
}
|
||||
if !foundHost && len(room.Players) > 0 {
|
||||
room.Players[0].SetPermissionBit(PermissionHost)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (room *Room) IsUsernameAvailable(username string) bool {
|
||||
for _, player := range room.Players {
|
||||
if player.Username == username {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
113
backend/types/websocket_packets.go
Normal file
113
backend/types/websocket_packets.go
Normal file
@ -0,0 +1,113 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"go.mongodb.org/mongo-driver/v2/bson"
|
||||
)
|
||||
|
||||
type S2C_Status struct {
|
||||
IsError bool
|
||||
StatusCode string
|
||||
Message string
|
||||
}
|
||||
type S2C_PlayerInfo struct {
|
||||
PlayerId bson.ObjectID
|
||||
Username string
|
||||
Permissions int
|
||||
IsConnected bool
|
||||
}
|
||||
type S2C_RoomInfo struct {
|
||||
RoomId bson.ObjectID `bson:"_id"`
|
||||
JoinCode string
|
||||
GameState GameState
|
||||
GameOptions GameOptions
|
||||
TopCard Card
|
||||
CardDeckId int
|
||||
Winner *bson.ObjectID
|
||||
Players []S2C_PlayerInfo
|
||||
}
|
||||
type S2C_Card struct {
|
||||
CanPlay bool
|
||||
Card Card
|
||||
}
|
||||
type S2C_OwnCards struct {
|
||||
Cards []S2C_Card
|
||||
}
|
||||
type S2C_PlayerState struct {
|
||||
PlayerId bson.ObjectID
|
||||
NumCards int
|
||||
Active bool
|
||||
}
|
||||
type S2C_CardPlayed struct {
|
||||
Card Card
|
||||
CardIndex int
|
||||
PlayedBy bson.ObjectID
|
||||
}
|
||||
type S2C_PlayedCardUpdate struct {
|
||||
UpdatedBy bson.ObjectID
|
||||
Card Card
|
||||
}
|
||||
|
||||
type C2S_UpdatePlayer struct {
|
||||
PlayerId bson.ObjectID
|
||||
Username *string
|
||||
Permissions *int
|
||||
}
|
||||
type C2S_KickPlayer struct {
|
||||
PlayerId bson.ObjectID
|
||||
}
|
||||
type C2S_PlayCard struct {
|
||||
CardIndex *int
|
||||
CardData interface{}
|
||||
}
|
||||
type C2S_UpdatePlayedCard struct {
|
||||
CardData interface{}
|
||||
}
|
||||
|
||||
func BuildRoomInfoPacket(room *Room) S2C_RoomInfo {
|
||||
players := make([]S2C_PlayerInfo, len(room.Players))
|
||||
for i, player := range room.Players {
|
||||
players[i] = S2C_PlayerInfo{
|
||||
PlayerId: player.PlayerId,
|
||||
Username: player.Username,
|
||||
Permissions: player.Permissions,
|
||||
IsConnected: player.Connection.IsConnected,
|
||||
}
|
||||
}
|
||||
roomInfo := S2C_RoomInfo{
|
||||
RoomId: room.RoomId,
|
||||
JoinCode: room.JoinCode,
|
||||
GameState: room.GameState,
|
||||
CardDeckId: room.CardDeckId,
|
||||
GameOptions: room.GameOptions,
|
||||
Winner: room.Winner,
|
||||
Players: players,
|
||||
}
|
||||
|
||||
if room.CardDeck != nil {
|
||||
roomInfo.TopCard = room.CardDeck.GetTopCard()
|
||||
}
|
||||
return roomInfo
|
||||
}
|
||||
|
||||
func BuildOwnCardsPacket(room *Room, player *Player) S2C_OwnCards {
|
||||
cards := make([]S2C_Card, len(player.Cards))
|
||||
for i, card := range player.Cards {
|
||||
cards[i] = S2C_Card{
|
||||
Card: card,
|
||||
CanPlay: room.CardDeck.CanPlay(card),
|
||||
}
|
||||
}
|
||||
return S2C_OwnCards{
|
||||
Cards: cards,
|
||||
}
|
||||
}
|
||||
|
||||
func BuildPlayerStatePacket(room *Room, player *Player) S2C_PlayerState {
|
||||
return S2C_PlayerState{PlayerId: player.PlayerId, NumCards: len(player.Cards), Active: room.CardDeck.IsPlayerActive(player)}
|
||||
}
|
||||
func BuildCardPlayedPacket(player *Player, cardIndex int, card Card) S2C_CardPlayed {
|
||||
return S2C_CardPlayed{Card: card, CardIndex: cardIndex, PlayedBy: player.PlayerId}
|
||||
}
|
||||
func BuildPlayedCardUpdatePacket(player *Player, card Card) S2C_PlayedCardUpdate {
|
||||
return S2C_PlayedCardUpdate{UpdatedBy: player.PlayerId, Card: card}
|
||||
}
|
Reference in New Issue
Block a user