/
game.go
111 lines (89 loc) · 2.46 KB
/
game.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
package model
import (
"gorm.io/gorm"
)
type Game struct {
gorm.Model
BaseContest BaseContest `gorm:"foreignKey:ID"`
Metadata Metadata `gorm:"embedded"`
// game assets
GameLogic GameLogic `gorm:"embedded;embeddedPrefix:game_logic_"`
MatchDetail MatchDetail `gorm:"embedded;embeddedPrefix:match_detail_"`
}
type GamePrivilege string
const (
GamePrivilegeAdmin GamePrivilege = "admin"
GamePrivilegeRegistered GamePrivilege = "registered"
)
type GameLogic struct {
Build DockerTask `gorm:"embedded;embeddedPrefix:build_"`
Run DockerTask `gorm:"embedded;embeddedPrefix:run_"`
Status TaskStatus `gorm:"embedded"`
}
type MatchDetail struct {
Template string
}
// CRUD: Create
// Optional fields: Metadata, GameLogic, MatchDetail, BaseContest.Script, BaseContest.States
func (g *Game) Create(adminIDs []uint) error {
// link a base contest or create a new one
if g.ID != 0 {
if err := db.First(&g.BaseContest, g.ID).Error; err != nil {
return err
}
} else {
if err := g.BaseContest.Create(adminIDs); err != nil {
return err
}
}
// create game
g.ID = g.BaseContest.ID
if err := db.Create(g).Error; err != nil {
return err
}
// update base contest's game_id
return db.Model(&g.BaseContest).Update("game_id", g.ID).Error
}
// CRUD: Read
func GetGames(fields ...string) (games []Game, err error) {
tx := db.Preload("BaseContest", func(db *gorm.DB) *gorm.DB {
return db.Select(baseContestBaseFields)
})
if len(fields) > 0 {
tx = tx.Select(fields)
}
err = tx.Find(&games).Error
return
}
func GetGameByID(id uint, fields ...string) (game Game, err error) {
err = db.Preload("BaseContest").First(&game, id).Error
return
}
// CRUD: Update
func UpdateGameByID(id uint, updates map[string]interface{}) error {
return db.Model(&Game{}).Where("id = ?", id).Updates(updates).Error
}
func (g *Game) Update(updates map[string]interface{}) error {
return db.Model(g).Updates(updates).Error
}
// CRUD: Delete
func DeleteGameByID(id uint) error {
return db.Delete(&Game{}, id).Error
}
func (g *Game) Delete() error {
return db.Delete(g).Error
}
// associations
// Note: Game doesn't need registration
func (g *Game) GetPrivilege(userID uint) (GamePrivilege, error) {
var count int64
err := db.Table("base_contest_admins").Where("base_contest_id = ? AND user_id = ?", g.ID, userID).Count(&count).Error
if err != nil {
return "", err
}
if count > 0 {
return GamePrivilegeAdmin, nil
}
return GamePrivilegeRegistered, nil
}
// TODO:game logic files