Compare commits
No commits in common. "dbcf5decb89832c3f1a764588a15cb07327cbfd7" and "9cb5f99c2ff98954dfa85fdc79ed29ffb1e82af6" have entirely different histories.
dbcf5decb8
...
9cb5f99c2f
5 changed files with 1 additions and 903 deletions
|
@ -2,9 +2,7 @@ Le backend du site Brawlset est codé en [GO](https://go.dev/) et utilise [Pocke
|
||||||
|
|
||||||
# TODO
|
# TODO
|
||||||
|
|
||||||
- [x] Feat : Créer le système d'ELO
|
- [ ] Feat : Créer le système d'ELO
|
||||||
- [x] Feat : Update les ELO quand il y a un changement
|
|
||||||
- [ ] Feat : Update les ELO quand il y a une suppression de match
|
|
||||||
- [x] Fix : Changer le recto / verso des cartes
|
- [x] Fix : Changer le recto / verso des cartes
|
||||||
- [ ] Feat : Système d'évènements à ajouter sur la page principale
|
- [ ] Feat : Système d'évènements à ajouter sur la page principale
|
||||||
- [ ] Fix : Refuse to create deck when cards are not found
|
- [ ] Fix : Refuse to create deck when cards are not found
|
||||||
|
|
297
backend/hooks.go
297
backend/hooks.go
|
@ -1,297 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"math"
|
|
||||||
"slices"
|
|
||||||
|
|
||||||
"github.com/pocketbase/dbx"
|
|
||||||
"github.com/pocketbase/pocketbase/core"
|
|
||||||
)
|
|
||||||
|
|
||||||
type DuelResult struct {
|
|
||||||
Player1_NewELO float64
|
|
||||||
Player2_NewELO float64
|
|
||||||
Commander1_NewELO float64
|
|
||||||
Commander2_NewELO float64
|
|
||||||
}
|
|
||||||
|
|
||||||
func (app *application) SetupHooks() {
|
|
||||||
default_ELO_value := 100.0
|
|
||||||
|
|
||||||
// Set default values after creation
|
|
||||||
app.pb.OnRecordAfterCreateSuccess("elo_player").BindFunc(func (e *core.RecordEvent) error {
|
|
||||||
e.Record.Set("elo_casual", default_ELO_value)
|
|
||||||
e.Record.Set("elo_tournament", default_ELO_value)
|
|
||||||
e.App.Save(e.Record)
|
|
||||||
|
|
||||||
log.Println("record created")
|
|
||||||
return e.Next()
|
|
||||||
})
|
|
||||||
|
|
||||||
app.pb.OnRecordUpdate("elo").BindFunc(func (e *core.RecordEvent) error {
|
|
||||||
// Check if any of these fields has been changed : Player1, Player2, Commandant1, Commandant2, Score1, Score2, Date, Official
|
|
||||||
if(e.Record.GetString("player_1") != e.Record.Original().GetString("player_1") || e.Record.GetString("player_2") != e.Record.Original().GetString("player_2") || e.Record.GetString("commandant_1") != e.Record.Original().GetString("commandant_1") || e.Record.GetString("commandant_2") != e.Record.Original().GetString("commandant_2") || e.Record.GetString("score_1") != e.Record.Original().GetString("score_1") || e.Record.GetString("score_2") != e.Record.Original().GetString("score_2") || e.Record.GetString("date") != e.Record.Original().GetString("date") || e.Record.GetString("official") != e.Record.Original().GetString("official")) {
|
|
||||||
UpdateRecordELO(e, default_ELO_value)
|
|
||||||
UpdateLastELO(e, e.Record.GetFloat("elo_player_1"), e.Record.GetFloat("elo_player_2"), e.Record.GetFloat("elo_commandant_1"), e.Record.GetFloat("elo_commandant_2"))
|
|
||||||
updateNextMatchs(e, DuelResult{
|
|
||||||
Player1_NewELO: e.Record.GetFloat("elo_player_1"),
|
|
||||||
Player2_NewELO: e.Record.GetFloat("elo_player_2"),
|
|
||||||
Commander1_NewELO: e.Record.GetFloat("elo_commandant_1"),
|
|
||||||
Commander2_NewELO: e.Record.GetFloat("elo_commandant_2"),
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return e.Next()
|
|
||||||
})
|
|
||||||
|
|
||||||
// When a ELO entry has been added
|
|
||||||
app.pb.OnRecordCreate("elo").BindFunc(func (e *core.RecordEvent) error {
|
|
||||||
UpdateRecordELO(e, default_ELO_value)
|
|
||||||
|
|
||||||
UpdateLastELO(e, e.Record.GetFloat("elo_player_1"), e.Record.GetFloat("elo_player_2"), e.Record.GetFloat("elo_commandant_1"), e.Record.GetFloat("elo_commandant_2"))
|
|
||||||
|
|
||||||
updateNextMatchs(e, DuelResult{
|
|
||||||
Player1_NewELO: e.Record.GetFloat("elo_player_1"),
|
|
||||||
Player2_NewELO: e.Record.GetFloat("elo_player_2"),
|
|
||||||
Commander1_NewELO: e.Record.GetFloat("elo_commandant_1"),
|
|
||||||
Commander2_NewELO: e.Record.GetFloat("elo_commandant_2"),
|
|
||||||
})
|
|
||||||
|
|
||||||
return e.Next()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func updateNextMatchs(e *core.RecordEvent, newData DuelResult) {
|
|
||||||
official := e.Record.GetBool("official")
|
|
||||||
needToRecalculateElo := false
|
|
||||||
|
|
||||||
nextMatchsCount, _ := e.App.CountRecords("elo", dbx.And(dbx.And(dbx.NewExp("date > {:date}", dbx.Params{"date": e.Record.GetString("date")}), dbx.NewExp("official = {:official}", dbx.Params{"official": official})),dbx.Or(dbx.NewExp("player_1 = {:id}", dbx.Params{"id": e.Record.GetString("player_1")}), dbx.NewExp("player_2 = {:id}", dbx.Params{"id": e.Record.GetString("player_1")}))))
|
|
||||||
if nextMatchsCount > 0 {
|
|
||||||
needToRecalculateElo = true
|
|
||||||
}
|
|
||||||
|
|
||||||
nextMatchsCount, _ = e.App.CountRecords("elo", dbx.And(dbx.And(dbx.NewExp("date > {:date}", dbx.Params{"date": e.Record.GetString("date")}), dbx.NewExp("official = {:official}", dbx.Params{"official": official})),dbx.Or(dbx.NewExp("player_1 = {:id}", dbx.Params{"id": e.Record.GetString("player_2")}), dbx.NewExp("player_2 = {:id}", dbx.Params{"id": e.Record.GetString("player_2")}))))
|
|
||||||
if nextMatchsCount > 0 {
|
|
||||||
needToRecalculateElo = true
|
|
||||||
}
|
|
||||||
|
|
||||||
nextMatchsCount, _ = e.App.CountRecords("elo", dbx.And(dbx.And(dbx.NewExp("date > {:date}", dbx.Params{"date": e.Record.GetString("date")}), dbx.NewExp("official = {:official}", dbx.Params{"official": official})),dbx.Or(dbx.NewExp("commandant_1 = {:id}", dbx.Params{"id": e.Record.GetString("commandant_1")}), dbx.NewExp("commandant_2 = {:id}", dbx.Params{"id": e.Record.GetString("commandant_1")}))))
|
|
||||||
if nextMatchsCount > 0 {
|
|
||||||
needToRecalculateElo = true
|
|
||||||
}
|
|
||||||
|
|
||||||
nextMatchsCount, _ = e.App.CountRecords("elo", dbx.And(dbx.And(dbx.NewExp("date > {:date}", dbx.Params{"date": e.Record.GetString("date")}), dbx.NewExp("official = {:official}", dbx.Params{"official": official})),dbx.Or(dbx.NewExp("commandant_1 = {:id}", dbx.Params{"id": e.Record.GetString("commandant_2")}), dbx.NewExp("commandant_2 = {:id}", dbx.Params{"id": e.Record.GetString("commandant_2")}))))
|
|
||||||
if nextMatchsCount > 0 {
|
|
||||||
needToRecalculateElo = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if needToRecalculateElo {
|
|
||||||
eloMatchs := []Elo{}
|
|
||||||
log.Println(fmt.Sprintf("Matchs found after %s", e.Record.GetString("id")))
|
|
||||||
|
|
||||||
playerIdChanged := []string{ e.Record.GetString("player_1"), e.Record.GetString("player_2") }
|
|
||||||
newPlayerData := map[string]float64{}
|
|
||||||
newPlayerData[e.Record.GetString("player_1")] = newData.Player1_NewELO
|
|
||||||
newPlayerData[e.Record.GetString("player_2")] = newData.Player2_NewELO
|
|
||||||
newCommanderData := map[string]float64{}
|
|
||||||
newCommanderData[e.Record.GetString("commandant_1")] = newData.Commander1_NewELO
|
|
||||||
newCommanderData[e.Record.GetString("commandant_2")] = newData.Commander2_NewELO
|
|
||||||
commanderIdChanged := []string{ e.Record.GetString("commandant_1"), e.Record.GetString("commandant_2") }
|
|
||||||
err := e.App.RecordQuery("elo").
|
|
||||||
Where(dbx.NewExp("date > {:date}", dbx.Params{"date":e.Record.GetString("date")})).
|
|
||||||
AndWhere(dbx.NewExp("official = {:official}",dbx.Params{"official": official})).
|
|
||||||
OrderBy("date ASC").
|
|
||||||
All(&eloMatchs)
|
|
||||||
if err != nil {
|
|
||||||
log.Println(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, v := range eloMatchs {
|
|
||||||
// Check if Match is concerned by the ELO recalculate
|
|
||||||
if slices.Contains(playerIdChanged, v.Player1) || slices.Contains(playerIdChanged, v.Player2) {
|
|
||||||
record, _ := e.App.FindRecordById("elo", v.ID)
|
|
||||||
// If Player1 is not in the ID changed, now it is
|
|
||||||
if !slices.Contains(playerIdChanged, v.Player1) {
|
|
||||||
playerIdChanged = append(playerIdChanged, v.Player1)
|
|
||||||
} else {
|
|
||||||
record.Set("last_elo_player_1", newPlayerData[v.Player1])
|
|
||||||
}
|
|
||||||
// If Player2 is not in the ID changed, now it is
|
|
||||||
if !slices.Contains(playerIdChanged, v.Player2) {
|
|
||||||
playerIdChanged = append(playerIdChanged, v.Player2)
|
|
||||||
} else {
|
|
||||||
record.Set("last_elo_player_2", newPlayerData[v.Player2])
|
|
||||||
}
|
|
||||||
|
|
||||||
tempEloData := CalculateELO(record.GetFloat("last_elo_player_1"), record.GetFloat("last_elo_player_2"), record.GetFloat("last_elo_commandant_1"), record.GetFloat("last_elo_commandant_2"), record.GetInt("score_1"), record.GetInt("score_2"))
|
|
||||||
record.Set("elo_player_1", tempEloData.Player1_NewELO)
|
|
||||||
record.Set("elo_player_2", tempEloData.Player2_NewELO)
|
|
||||||
|
|
||||||
newPlayerData[v.Player1] = tempEloData.Player1_NewELO
|
|
||||||
newPlayerData[v.Player2] = tempEloData.Player2_NewELO
|
|
||||||
|
|
||||||
e.App.Save(record)
|
|
||||||
}
|
|
||||||
|
|
||||||
if slices.Contains(commanderIdChanged, v.Commander1) || slices.Contains(commanderIdChanged, v.Commander2) {
|
|
||||||
record, _ := e.App.FindRecordById("elo", v.ID)
|
|
||||||
// If Player1 is not in the ID changed, now it is
|
|
||||||
if !slices.Contains(commanderIdChanged, v.Commander1) {
|
|
||||||
commanderIdChanged = append(commanderIdChanged, v.Commander1)
|
|
||||||
} else {
|
|
||||||
record.Set("last_elo_commandant_1", newCommanderData[v.Commander1])
|
|
||||||
}
|
|
||||||
// If Player2 is not in the ID changed, now it is
|
|
||||||
if !slices.Contains(commanderIdChanged, v.Commander2) {
|
|
||||||
commanderIdChanged = append(commanderIdChanged, v.Commander2)
|
|
||||||
} else {
|
|
||||||
record.Set("last_elo_commandant_2", newCommanderData[v.Commander2])
|
|
||||||
}
|
|
||||||
|
|
||||||
tempEloData := CalculateELO(record.GetFloat("last_elo_player_1"), record.GetFloat("last_elo_player_2"), record.GetFloat("last_elo_commandant_1"), record.GetFloat("last_elo_commandant_2"), record.GetInt("score_1"), record.GetInt("score_2"))
|
|
||||||
record.Set("elo_commandant_1", tempEloData.Commander1_NewELO)
|
|
||||||
record.Set("elo_commandant_2", tempEloData.Commander2_NewELO)
|
|
||||||
|
|
||||||
newCommanderData[v.Commander1] = tempEloData.Commander1_NewELO
|
|
||||||
newCommanderData[v.Commander2] = tempEloData.Commander2_NewELO
|
|
||||||
|
|
||||||
e.App.Save(record)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
UpdateLastELO(e, newPlayerData[e.Record.GetString("player_1")], newPlayerData[e.Record.GetString("player_2")], newCommanderData[e.Record.GetString("commandant_1")], newCommanderData[e.Record.GetString("commandant_2")])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func UpdateLastELO(e *core.RecordEvent, player1_ELO float64, player2_ELO float64, commander1_ELO float64, commander2_ELO float64) {
|
|
||||||
recordPlayer1, _ := e.App.FindRecordById("elo_player", e.Record.GetString("player_1"))
|
|
||||||
recordPlayer2, _ := e.App.FindRecordById("elo_player", e.Record.GetString("player_2"))
|
|
||||||
if e.Record.GetBool("official") {
|
|
||||||
recordPlayer1.Set("elo_tournament", player1_ELO)
|
|
||||||
recordPlayer2.Set("elo_tournament", player2_ELO)
|
|
||||||
} else {
|
|
||||||
recordPlayer1.Set("elo_casual", player1_ELO)
|
|
||||||
recordPlayer2.Set("elo_casual", player2_ELO)
|
|
||||||
}
|
|
||||||
|
|
||||||
recordCommander1, _ := e.App.FindRecordById("carte", e.Record.GetString("commandant_1"))
|
|
||||||
recordCommander2, _ := e.App.FindRecordById("carte", e.Record.GetString("commandant_2"))
|
|
||||||
if e.Record.GetBool("official") {
|
|
||||||
recordCommander1.Set("elo_tournament", commander1_ELO)
|
|
||||||
recordCommander2.Set("elo_tournament", commander2_ELO)
|
|
||||||
} else {
|
|
||||||
recordCommander1.Set("elo_casual", commander1_ELO)
|
|
||||||
recordCommander2.Set("elo_casual", commander2_ELO)
|
|
||||||
}
|
|
||||||
|
|
||||||
e.App.Save(recordPlayer1)
|
|
||||||
e.App.Save(recordPlayer2)
|
|
||||||
e.App.Save(recordCommander1)
|
|
||||||
e.App.Save(recordCommander2)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func UpdateRecordELO(e *core.RecordEvent, default_ELO_value float64) {
|
|
||||||
date := e.Record.GetString("date")
|
|
||||||
official := e.Record.GetBool("official")
|
|
||||||
player1Id := e.Record.GetString("player_1")
|
|
||||||
player2Id := e.Record.GetString("player_2")
|
|
||||||
commander1Id := e.Record.GetString("commandant_1")
|
|
||||||
commander2Id := e.Record.GetString("commandant_2")
|
|
||||||
score1 := e.Record.GetInt("score_1")
|
|
||||||
score2 := e.Record.GetInt("score_2")
|
|
||||||
|
|
||||||
// Base data in case it's the first match
|
|
||||||
player1_ELO := default_ELO_value
|
|
||||||
player2_ELO := default_ELO_value
|
|
||||||
commander1_ELO := default_ELO_value
|
|
||||||
commander2_ELO := default_ELO_value
|
|
||||||
|
|
||||||
// Update ELO With last match ELO (Tournament or Casual)
|
|
||||||
updateEloPlayerWithLastMatch(e, player1Id, date, &player1_ELO, official)
|
|
||||||
updateEloPlayerWithLastMatch(e, player2Id, date, &player2_ELO, official)
|
|
||||||
|
|
||||||
// Update ELO With last match ELO (Tournament or Casual)
|
|
||||||
updateEloCommanderWithLastMatch(e, commander1Id, date, &commander1_ELO, official)
|
|
||||||
updateEloCommanderWithLastMatch(e, commander2Id, date, &commander2_ELO, official)
|
|
||||||
|
|
||||||
newData := CalculateELO(player1_ELO, player2_ELO, commander1_ELO, commander2_ELO, score1, score2)
|
|
||||||
|
|
||||||
e.Record.Set("last_elo_player_1", player1_ELO)
|
|
||||||
e.Record.Set("elo_player_1", newData.Player1_NewELO)
|
|
||||||
e.Record.Set("last_elo_player_2", player2_ELO)
|
|
||||||
e.Record.Set("elo_player_2", newData.Player2_NewELO)
|
|
||||||
e.Record.Set("last_elo_commandant_1", commander1_ELO)
|
|
||||||
e.Record.Set("elo_commandant_1", newData.Commander1_NewELO)
|
|
||||||
e.Record.Set("last_elo_commandant_2", commander2_ELO)
|
|
||||||
e.Record.Set("elo_commandant_2", newData.Commander2_NewELO)
|
|
||||||
}
|
|
||||||
|
|
||||||
func updateEloPlayerWithLastMatch(e *core.RecordEvent, playerId string, date string, elo *float64, official bool) {
|
|
||||||
lastMatch := Elo{}
|
|
||||||
err := e.App.RecordQuery("elo").
|
|
||||||
Where(dbx.NewExp("date < {:date}", dbx.Params{"date": date})).
|
|
||||||
AndWhere(dbx.NewExp("official = {:official}", dbx.Params{"official": official})).
|
|
||||||
AndWhere(dbx.Or(dbx.NewExp("player_1 = {:id}", dbx.Params{"id": playerId}), dbx.NewExp("player_2 = {:id}", dbx.Params{"id": playerId}))).
|
|
||||||
OrderBy("date DESC").
|
|
||||||
One(&lastMatch)
|
|
||||||
if err == nil {
|
|
||||||
// If a match exists before this one update ELO
|
|
||||||
if lastMatch.Player1 == playerId {
|
|
||||||
*elo = lastMatch.EloPlayer1
|
|
||||||
} else {
|
|
||||||
*elo = lastMatch.EloPlayer2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func updateEloCommanderWithLastMatch(e *core.RecordEvent, commanderId string, date string, elo *float64, official bool) {
|
|
||||||
lastMatch := Elo{}
|
|
||||||
err := e.App.RecordQuery("elo").
|
|
||||||
Where(dbx.NewExp("date < {:date}", dbx.Params{"date": date})).
|
|
||||||
AndWhere(dbx.NewExp("official = {:official}", dbx.Params{"official": official})).
|
|
||||||
AndWhere(dbx.Or(dbx.NewExp("commandant_1 = {:id}", dbx.Params{"id": commanderId}), dbx.NewExp("commandant_2 = {:id}", dbx.Params{"id": commanderId}))).
|
|
||||||
OrderBy("date DESC").
|
|
||||||
One(&lastMatch)
|
|
||||||
if err == nil {
|
|
||||||
// If a match exists before this one update ELO
|
|
||||||
if lastMatch.Commander1 == commanderId {
|
|
||||||
*elo = lastMatch.EloCommander1
|
|
||||||
} else {
|
|
||||||
*elo = lastMatch.EloCommander2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func CalculateELO(player1_ELO float64, player2_ELO float64, commander1_ELO float64, commander2_ELO float64, score1 int, score2 int) DuelResult {
|
|
||||||
K_PLAYER := 30.0
|
|
||||||
K_COMMANDER := 20.0
|
|
||||||
|
|
||||||
won_player1 := 0.0
|
|
||||||
won_player2 := 0.0
|
|
||||||
|
|
||||||
if score1 < score2 {
|
|
||||||
won_player2 = 1.0
|
|
||||||
} else if score1 > score2 {
|
|
||||||
won_player1 = 1.0
|
|
||||||
} else if score1 == score2 {
|
|
||||||
won_player1 = 0.5
|
|
||||||
won_player2 = 0.5
|
|
||||||
}
|
|
||||||
|
|
||||||
eloModifier_player1 := won_player1 - 1.0 / (1 + math.Pow(10, (player2_ELO - player1_ELO) / 400.0))
|
|
||||||
eloModifier_player2 := won_player2 - 1.0 / (1 + math.Pow(10, (player1_ELO - player2_ELO) / 400.0))
|
|
||||||
|
|
||||||
eloModifier_commander1 := won_player1 - 1.0 / (1 + math.Pow(10, (commander2_ELO - commander1_ELO) / 400.0))
|
|
||||||
eloModifier_commander2 := won_player2 - 1.0 / (1 + math.Pow(10, (commander1_ELO - commander2_ELO) / 400.0))
|
|
||||||
|
|
||||||
return DuelResult{
|
|
||||||
Player1_NewELO: player1_ELO + K_PLAYER * eloModifier_player1,
|
|
||||||
Player2_NewELO: player2_ELO + K_PLAYER * eloModifier_player2,
|
|
||||||
Commander1_NewELO: commander1_ELO + K_COMMANDER * eloModifier_commander1,
|
|
||||||
Commander2_NewELO: commander2_ELO + K_COMMANDER * eloModifier_commander2,
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -44,7 +44,6 @@ func main() {
|
||||||
app.SetupCache()
|
app.SetupCache()
|
||||||
app.SetupCrons()
|
app.SetupCrons()
|
||||||
app.SetupRoutes()
|
app.SetupRoutes()
|
||||||
app.SetupHooks()
|
|
||||||
|
|
||||||
log.Fatal(app.pb.Start())
|
log.Fatal(app.pb.Start())
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,578 +0,0 @@
|
||||||
package migrations
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/pocketbase/pocketbase/core"
|
|
||||||
m "github.com/pocketbase/pocketbase/migrations"
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
m.Register(func(app core.App) error {
|
|
||||||
jsonData := `[
|
|
||||||
{
|
|
||||||
"id": "pbc_2856227530",
|
|
||||||
"listRule": null,
|
|
||||||
"viewRule": null,
|
|
||||||
"createRule": null,
|
|
||||||
"updateRule": null,
|
|
||||||
"deleteRule": null,
|
|
||||||
"name": "elo",
|
|
||||||
"type": "base",
|
|
||||||
"fields": [
|
|
||||||
{
|
|
||||||
"autogeneratePattern": "[a-z0-9]{15}",
|
|
||||||
"hidden": false,
|
|
||||||
"id": "text3208210256",
|
|
||||||
"max": 15,
|
|
||||||
"min": 15,
|
|
||||||
"name": "id",
|
|
||||||
"pattern": "^[a-z0-9]+$",
|
|
||||||
"presentable": false,
|
|
||||||
"primaryKey": true,
|
|
||||||
"required": true,
|
|
||||||
"system": true,
|
|
||||||
"type": "text"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"hidden": false,
|
|
||||||
"id": "date2862495610",
|
|
||||||
"max": "",
|
|
||||||
"min": "",
|
|
||||||
"name": "date",
|
|
||||||
"presentable": false,
|
|
||||||
"required": true,
|
|
||||||
"system": false,
|
|
||||||
"type": "date"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cascadeDelete": false,
|
|
||||||
"collectionId": "pbc_1697519085",
|
|
||||||
"hidden": false,
|
|
||||||
"id": "relation2239679623",
|
|
||||||
"maxSelect": 1,
|
|
||||||
"minSelect": 0,
|
|
||||||
"name": "player_1",
|
|
||||||
"presentable": false,
|
|
||||||
"required": true,
|
|
||||||
"system": false,
|
|
||||||
"type": "relation"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cascadeDelete": false,
|
|
||||||
"collectionId": "pbc_1905410326",
|
|
||||||
"hidden": false,
|
|
||||||
"id": "relation2047047275",
|
|
||||||
"maxSelect": 1,
|
|
||||||
"minSelect": 0,
|
|
||||||
"name": "commandant_1",
|
|
||||||
"presentable": false,
|
|
||||||
"required": true,
|
|
||||||
"system": false,
|
|
||||||
"type": "relation"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"hidden": false,
|
|
||||||
"id": "number909748445",
|
|
||||||
"max": null,
|
|
||||||
"min": null,
|
|
||||||
"name": "score_1",
|
|
||||||
"onlyInt": false,
|
|
||||||
"presentable": false,
|
|
||||||
"required": false,
|
|
||||||
"system": false,
|
|
||||||
"type": "number"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cascadeDelete": false,
|
|
||||||
"collectionId": "pbc_1697519085",
|
|
||||||
"hidden": false,
|
|
||||||
"id": "relation477601085",
|
|
||||||
"maxSelect": 1,
|
|
||||||
"minSelect": 0,
|
|
||||||
"name": "player_2",
|
|
||||||
"presentable": false,
|
|
||||||
"required": true,
|
|
||||||
"system": false,
|
|
||||||
"type": "relation"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cascadeDelete": false,
|
|
||||||
"collectionId": "pbc_1905410326",
|
|
||||||
"hidden": false,
|
|
||||||
"id": "relation3809093585",
|
|
||||||
"maxSelect": 1,
|
|
||||||
"minSelect": 0,
|
|
||||||
"name": "commandant_2",
|
|
||||||
"presentable": false,
|
|
||||||
"required": true,
|
|
||||||
"system": false,
|
|
||||||
"type": "relation"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"hidden": false,
|
|
||||||
"id": "number2939222375",
|
|
||||||
"max": null,
|
|
||||||
"min": null,
|
|
||||||
"name": "score_2",
|
|
||||||
"onlyInt": false,
|
|
||||||
"presentable": false,
|
|
||||||
"required": false,
|
|
||||||
"system": false,
|
|
||||||
"type": "number"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"hidden": false,
|
|
||||||
"id": "bool2557948429",
|
|
||||||
"name": "official",
|
|
||||||
"presentable": false,
|
|
||||||
"required": false,
|
|
||||||
"system": false,
|
|
||||||
"type": "bool"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"hidden": false,
|
|
||||||
"id": "number1561173596",
|
|
||||||
"max": null,
|
|
||||||
"min": null,
|
|
||||||
"name": "elo_commandant_1",
|
|
||||||
"onlyInt": false,
|
|
||||||
"presentable": false,
|
|
||||||
"required": false,
|
|
||||||
"system": false,
|
|
||||||
"type": "number"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"hidden": false,
|
|
||||||
"id": "number3288649702",
|
|
||||||
"max": null,
|
|
||||||
"min": null,
|
|
||||||
"name": "elo_commandant_2",
|
|
||||||
"onlyInt": false,
|
|
||||||
"presentable": false,
|
|
||||||
"required": false,
|
|
||||||
"system": false,
|
|
||||||
"type": "number"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"hidden": false,
|
|
||||||
"id": "number4239465276",
|
|
||||||
"max": null,
|
|
||||||
"min": null,
|
|
||||||
"name": "elo_player_1",
|
|
||||||
"onlyInt": false,
|
|
||||||
"presentable": false,
|
|
||||||
"required": false,
|
|
||||||
"system": false,
|
|
||||||
"type": "number"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"hidden": false,
|
|
||||||
"id": "number1706576518",
|
|
||||||
"max": null,
|
|
||||||
"min": null,
|
|
||||||
"name": "elo_player_2",
|
|
||||||
"onlyInt": false,
|
|
||||||
"presentable": false,
|
|
||||||
"required": false,
|
|
||||||
"system": false,
|
|
||||||
"type": "number"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"hidden": false,
|
|
||||||
"id": "number4115095912",
|
|
||||||
"max": null,
|
|
||||||
"min": null,
|
|
||||||
"name": "last_elo_player_1",
|
|
||||||
"onlyInt": false,
|
|
||||||
"presentable": false,
|
|
||||||
"required": false,
|
|
||||||
"system": false,
|
|
||||||
"type": "number"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"hidden": false,
|
|
||||||
"id": "number1817063634",
|
|
||||||
"max": null,
|
|
||||||
"min": null,
|
|
||||||
"name": "last_elo_player_2",
|
|
||||||
"onlyInt": false,
|
|
||||||
"presentable": false,
|
|
||||||
"required": false,
|
|
||||||
"system": false,
|
|
||||||
"type": "number"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"hidden": false,
|
|
||||||
"id": "number2067666352",
|
|
||||||
"max": null,
|
|
||||||
"min": null,
|
|
||||||
"name": "last_elo_commandant_1",
|
|
||||||
"onlyInt": false,
|
|
||||||
"presentable": false,
|
|
||||||
"required": false,
|
|
||||||
"system": false,
|
|
||||||
"type": "number"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"hidden": false,
|
|
||||||
"id": "number3795272714",
|
|
||||||
"max": null,
|
|
||||||
"min": null,
|
|
||||||
"name": "last_elo_commandant_2",
|
|
||||||
"onlyInt": false,
|
|
||||||
"presentable": false,
|
|
||||||
"required": false,
|
|
||||||
"system": false,
|
|
||||||
"type": "number"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"hidden": false,
|
|
||||||
"id": "autodate3332085495",
|
|
||||||
"name": "updated",
|
|
||||||
"onCreate": true,
|
|
||||||
"onUpdate": true,
|
|
||||||
"presentable": false,
|
|
||||||
"system": false,
|
|
||||||
"type": "autodate"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"indexes": [],
|
|
||||||
"system": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "pbc_1697519085",
|
|
||||||
"listRule": null,
|
|
||||||
"viewRule": null,
|
|
||||||
"createRule": null,
|
|
||||||
"updateRule": null,
|
|
||||||
"deleteRule": null,
|
|
||||||
"name": "elo_player",
|
|
||||||
"type": "base",
|
|
||||||
"fields": [
|
|
||||||
{
|
|
||||||
"autogeneratePattern": "[a-z0-9]{15}",
|
|
||||||
"hidden": false,
|
|
||||||
"id": "text3208210256",
|
|
||||||
"max": 15,
|
|
||||||
"min": 15,
|
|
||||||
"name": "id",
|
|
||||||
"pattern": "^[a-z0-9]+$",
|
|
||||||
"presentable": false,
|
|
||||||
"primaryKey": true,
|
|
||||||
"required": true,
|
|
||||||
"system": true,
|
|
||||||
"type": "text"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cascadeDelete": false,
|
|
||||||
"collectionId": "_pb_users_auth_",
|
|
||||||
"hidden": false,
|
|
||||||
"id": "relation2375276105",
|
|
||||||
"maxSelect": 1,
|
|
||||||
"minSelect": 0,
|
|
||||||
"name": "user",
|
|
||||||
"presentable": false,
|
|
||||||
"required": false,
|
|
||||||
"system": false,
|
|
||||||
"type": "relation"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"autogeneratePattern": "",
|
|
||||||
"hidden": false,
|
|
||||||
"id": "text4166911607",
|
|
||||||
"max": 0,
|
|
||||||
"min": 0,
|
|
||||||
"name": "username",
|
|
||||||
"pattern": "",
|
|
||||||
"presentable": false,
|
|
||||||
"primaryKey": false,
|
|
||||||
"required": false,
|
|
||||||
"system": false,
|
|
||||||
"type": "text"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"hidden": false,
|
|
||||||
"id": "number2334461934",
|
|
||||||
"max": null,
|
|
||||||
"min": null,
|
|
||||||
"name": "elo_casual",
|
|
||||||
"onlyInt": false,
|
|
||||||
"presentable": false,
|
|
||||||
"required": false,
|
|
||||||
"system": false,
|
|
||||||
"type": "number"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"hidden": false,
|
|
||||||
"id": "number2732192018",
|
|
||||||
"max": null,
|
|
||||||
"min": null,
|
|
||||||
"name": "elo_tournament",
|
|
||||||
"onlyInt": false,
|
|
||||||
"presentable": false,
|
|
||||||
"required": false,
|
|
||||||
"system": false,
|
|
||||||
"type": "number"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"indexes": [],
|
|
||||||
"system": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "pbc_1905410326",
|
|
||||||
"listRule": null,
|
|
||||||
"viewRule": null,
|
|
||||||
"createRule": null,
|
|
||||||
"updateRule": null,
|
|
||||||
"deleteRule": null,
|
|
||||||
"name": "carte",
|
|
||||||
"type": "base",
|
|
||||||
"fields": [
|
|
||||||
{
|
|
||||||
"autogeneratePattern": "[a-z0-9]{8}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{12}",
|
|
||||||
"hidden": false,
|
|
||||||
"id": "text3208210256",
|
|
||||||
"max": 36,
|
|
||||||
"min": 36,
|
|
||||||
"name": "id",
|
|
||||||
"pattern": "^[a-z0-9\\-]+$",
|
|
||||||
"presentable": false,
|
|
||||||
"primaryKey": true,
|
|
||||||
"required": true,
|
|
||||||
"system": true,
|
|
||||||
"type": "text"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"autogeneratePattern": "",
|
|
||||||
"hidden": false,
|
|
||||||
"id": "text1579384326",
|
|
||||||
"max": 0,
|
|
||||||
"min": 0,
|
|
||||||
"name": "name",
|
|
||||||
"pattern": "",
|
|
||||||
"presentable": true,
|
|
||||||
"primaryKey": false,
|
|
||||||
"required": false,
|
|
||||||
"system": false,
|
|
||||||
"type": "text"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"autogeneratePattern": "",
|
|
||||||
"hidden": false,
|
|
||||||
"id": "text3273110370",
|
|
||||||
"max": 0,
|
|
||||||
"min": 0,
|
|
||||||
"name": "sanitized_name",
|
|
||||||
"pattern": "",
|
|
||||||
"presentable": false,
|
|
||||||
"primaryKey": false,
|
|
||||||
"required": false,
|
|
||||||
"system": false,
|
|
||||||
"type": "text"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"autogeneratePattern": "",
|
|
||||||
"hidden": false,
|
|
||||||
"id": "text976907234",
|
|
||||||
"max": 0,
|
|
||||||
"min": 0,
|
|
||||||
"name": "layout",
|
|
||||||
"pattern": "",
|
|
||||||
"presentable": false,
|
|
||||||
"primaryKey": false,
|
|
||||||
"required": false,
|
|
||||||
"system": false,
|
|
||||||
"type": "text"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"exceptDomains": null,
|
|
||||||
"hidden": false,
|
|
||||||
"id": "url1456686396",
|
|
||||||
"name": "small_image",
|
|
||||||
"onlyDomains": null,
|
|
||||||
"presentable": false,
|
|
||||||
"required": false,
|
|
||||||
"system": false,
|
|
||||||
"type": "url"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"exceptDomains": null,
|
|
||||||
"hidden": false,
|
|
||||||
"id": "url2615033119",
|
|
||||||
"name": "small_image_back",
|
|
||||||
"onlyDomains": null,
|
|
||||||
"presentable": false,
|
|
||||||
"required": false,
|
|
||||||
"system": false,
|
|
||||||
"type": "url"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"exceptDomains": null,
|
|
||||||
"hidden": false,
|
|
||||||
"id": "url2291853061",
|
|
||||||
"name": "normal_image",
|
|
||||||
"onlyDomains": null,
|
|
||||||
"presentable": false,
|
|
||||||
"required": false,
|
|
||||||
"system": false,
|
|
||||||
"type": "url"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"exceptDomains": null,
|
|
||||||
"hidden": false,
|
|
||||||
"id": "url2961008824",
|
|
||||||
"name": "normal_image_back",
|
|
||||||
"onlyDomains": null,
|
|
||||||
"presentable": false,
|
|
||||||
"required": false,
|
|
||||||
"system": false,
|
|
||||||
"type": "url"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"autogeneratePattern": "",
|
|
||||||
"hidden": false,
|
|
||||||
"id": "text2363381545",
|
|
||||||
"max": 0,
|
|
||||||
"min": 0,
|
|
||||||
"name": "type",
|
|
||||||
"pattern": "",
|
|
||||||
"presentable": false,
|
|
||||||
"primaryKey": false,
|
|
||||||
"required": false,
|
|
||||||
"system": false,
|
|
||||||
"type": "text"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"hidden": false,
|
|
||||||
"id": "select3054531206",
|
|
||||||
"maxSelect": 5,
|
|
||||||
"name": "color_identity",
|
|
||||||
"presentable": false,
|
|
||||||
"required": false,
|
|
||||||
"system": false,
|
|
||||||
"type": "select",
|
|
||||||
"values": [
|
|
||||||
"B",
|
|
||||||
"W",
|
|
||||||
"R",
|
|
||||||
"G",
|
|
||||||
"U"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"hidden": false,
|
|
||||||
"id": "date3520360348",
|
|
||||||
"max": "",
|
|
||||||
"min": "",
|
|
||||||
"name": "released_at",
|
|
||||||
"presentable": false,
|
|
||||||
"required": false,
|
|
||||||
"system": false,
|
|
||||||
"type": "date"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cascadeDelete": false,
|
|
||||||
"collectionId": "pbc_3912384429",
|
|
||||||
"hidden": false,
|
|
||||||
"id": "relation3860080092",
|
|
||||||
"maxSelect": 1,
|
|
||||||
"minSelect": 0,
|
|
||||||
"name": "mtg_set",
|
|
||||||
"presentable": false,
|
|
||||||
"required": false,
|
|
||||||
"system": false,
|
|
||||||
"type": "relation"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"autogeneratePattern": "",
|
|
||||||
"hidden": false,
|
|
||||||
"id": "text3805467153",
|
|
||||||
"max": 0,
|
|
||||||
"min": 0,
|
|
||||||
"name": "set_code",
|
|
||||||
"pattern": "",
|
|
||||||
"presentable": true,
|
|
||||||
"primaryKey": false,
|
|
||||||
"required": false,
|
|
||||||
"system": false,
|
|
||||||
"type": "text"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"hidden": false,
|
|
||||||
"id": "number3402113753",
|
|
||||||
"max": null,
|
|
||||||
"min": null,
|
|
||||||
"name": "price",
|
|
||||||
"onlyInt": false,
|
|
||||||
"presentable": false,
|
|
||||||
"required": false,
|
|
||||||
"system": false,
|
|
||||||
"type": "number"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"exceptDomains": null,
|
|
||||||
"hidden": false,
|
|
||||||
"id": "url518645060",
|
|
||||||
"name": "cardmarket_url",
|
|
||||||
"onlyDomains": null,
|
|
||||||
"presentable": false,
|
|
||||||
"required": false,
|
|
||||||
"system": false,
|
|
||||||
"type": "url"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"hidden": false,
|
|
||||||
"id": "bool1734659578",
|
|
||||||
"name": "can_be_commander",
|
|
||||||
"presentable": false,
|
|
||||||
"required": false,
|
|
||||||
"system": false,
|
|
||||||
"type": "bool"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"hidden": false,
|
|
||||||
"id": "bool2605256118",
|
|
||||||
"name": "banned",
|
|
||||||
"presentable": false,
|
|
||||||
"required": false,
|
|
||||||
"system": false,
|
|
||||||
"type": "bool"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"hidden": false,
|
|
||||||
"id": "number2334461934",
|
|
||||||
"max": null,
|
|
||||||
"min": null,
|
|
||||||
"name": "elo_casual",
|
|
||||||
"onlyInt": false,
|
|
||||||
"presentable": false,
|
|
||||||
"required": false,
|
|
||||||
"system": false,
|
|
||||||
"type": "number"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"hidden": false,
|
|
||||||
"id": "number2732192018",
|
|
||||||
"max": null,
|
|
||||||
"min": null,
|
|
||||||
"name": "elo_tournament",
|
|
||||||
"onlyInt": false,
|
|
||||||
"presentable": false,
|
|
||||||
"required": false,
|
|
||||||
"system": false,
|
|
||||||
"type": "number"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"indexes": [],
|
|
||||||
"system": false
|
|
||||||
}
|
|
||||||
]`
|
|
||||||
|
|
||||||
// add up queries...
|
|
||||||
|
|
||||||
return app.ImportCollectionsByMarshaledJSON([]byte(jsonData), false)
|
|
||||||
}, func(app core.App) error {
|
|
||||||
// add down queries...
|
|
||||||
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -55,27 +55,3 @@ type Deck struct {
|
||||||
Brawlset string `db:"brawlset" json:"brawslet,omitempty"`
|
Brawlset string `db:"brawlset" json:"brawslet,omitempty"`
|
||||||
Cards types.JSONArray[DeckCard] `db:"cartes" json:"cartes,omitempty"`
|
Cards types.JSONArray[DeckCard] `db:"cartes" json:"cartes,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Elo struct {
|
|
||||||
ID string `db:"id" json:"id"`
|
|
||||||
Date string `db:"date" json:"date"`
|
|
||||||
Player1 string `db:"player_1" json:"player_1"`
|
|
||||||
Player2 string `db:"player_2" json:"player_2"`
|
|
||||||
Commander1 string `db:"commander_1" json:"commander_1"`
|
|
||||||
Commander2 string `db:"commander_2" json:"commander_2"`
|
|
||||||
Score1 int `db:"score_1" json:"score_1"`
|
|
||||||
Score2 int `db:"score_2" json:"score_2"`
|
|
||||||
Official bool `db:"official" json:"official"`
|
|
||||||
EloCommander1 float64 `db:"elo_commandant_1" json:"elo_commander_1"`
|
|
||||||
EloCommander2 float64 `db:"elo_commandant_2" json:"elo_commander_2"`
|
|
||||||
EloPlayer1 float64 `db:"elo_player_1" json:"elo_player_1"`
|
|
||||||
EloPlayer2 float64 `db:"elo_player_2" json:"elo_player_2"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type EloPlayer struct {
|
|
||||||
ID string `db:"id" json:"id"`
|
|
||||||
User string `db:"user" json:"user"`
|
|
||||||
Username string `db:"username" json:"username"`
|
|
||||||
EloCasual float64 `db:"elo_casual" json:"elo_casual"`
|
|
||||||
EloTournament float64 `db:"elo_tournament" json:"elo_tournament"`
|
|
||||||
}
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue