109 lines
2.8 KiB
Go
109 lines
2.8 KiB
Go
|
// NGnius 2020-01-30
|
||
|
|
||
|
package main // leadercraft-server
|
||
|
|
||
|
import (
|
||
|
"flag"
|
||
|
"fmt"
|
||
|
"os"
|
||
|
"os/signal"
|
||
|
)
|
||
|
|
||
|
const (
|
||
|
// Version the current version
|
||
|
Version = "0.1"
|
||
|
// Name the program name
|
||
|
Name = "leadercraft-s"
|
||
|
)
|
||
|
|
||
|
var (
|
||
|
isClosing bool
|
||
|
printVersionAndExit bool
|
||
|
)
|
||
|
|
||
|
func init() {
|
||
|
initArgs()
|
||
|
}
|
||
|
|
||
|
func main() {
|
||
|
parseArgs()
|
||
|
sqlInitErr := sqlInit()
|
||
|
if sqlInitErr != nil {
|
||
|
fmt.Printf("Failed to initialise SQL connection: %s\n", sqlInitErr)
|
||
|
os.Exit(1)
|
||
|
}
|
||
|
// handle interrupt (terminate) signal
|
||
|
signalChan := make(chan os.Signal)
|
||
|
signal.Notify(signalChan, os.Interrupt)
|
||
|
go func() {
|
||
|
s := <-signalChan
|
||
|
fmt.Println("Received terminate signal " + s.String())
|
||
|
isClosing = true
|
||
|
sqlClose()
|
||
|
}()
|
||
|
// get new rankings
|
||
|
rows, err := db.Query("SELECT * FROM Entries WHERE rank=-1 ORDER BY time ASC;")
|
||
|
if err == nil {
|
||
|
var entries []*Entry
|
||
|
count := 0
|
||
|
for rows.Next() {
|
||
|
entries = append(entries, &Entry{})
|
||
|
scanErr := rows.Scan(entries[count].Intake()...)
|
||
|
if scanErr == nil {
|
||
|
updateBoardEntries(entries[count])
|
||
|
count++
|
||
|
} else {
|
||
|
fmt.Println(scanErr)
|
||
|
}
|
||
|
}
|
||
|
} else {
|
||
|
fmt.Println(err)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func initArgs() {
|
||
|
flag.BoolVar(&printVersionAndExit, "version", false, "Print version and exit")
|
||
|
flag.StringVar(&sqlConnection, "conn", sqlConnectionDefault, "Database connection string")
|
||
|
flag.StringVar(&sqlServer, "sql", sqlServerDefault, "SQL Database type")
|
||
|
}
|
||
|
|
||
|
func parseArgs() {
|
||
|
flag.Parse()
|
||
|
if printVersionAndExit {
|
||
|
fmt.Println(Name + " v" + Version)
|
||
|
os.Exit(0)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func updateBoardEntries(entry *Entry) {
|
||
|
// get nearest entry that's lower and steal it's rank
|
||
|
nearestEntry := &Entry{}
|
||
|
scanErr := db.QueryRow("SELECT * FROM Entries WHERE score < $1 AND rank!= -1 AND board=$2 ORDER BY score DESC LIMIT 1;", entry.Score, entry.Board).Scan(nearestEntry.Intake()...)
|
||
|
if (scanErr == nil) {
|
||
|
entry.Rank = nearestEntry.Rank
|
||
|
entry.Commit()
|
||
|
// update all ranks lower than itself
|
||
|
tx, _ := db.Begin()
|
||
|
stmt, _ := tx.Prepare("UPDATE Entries SET rank=rank+1 WHERE rank >=$1 AND id!=$2 AND board=$3;")
|
||
|
_, err := stmt.Exec(entry.Rank, entry.ID, entry.Board)
|
||
|
if err != nil {
|
||
|
tx.Rollback()
|
||
|
fmt.Println(err)
|
||
|
} else {
|
||
|
tx.Commit()
|
||
|
}
|
||
|
} else {
|
||
|
// nothing to beat
|
||
|
scanErr = db.QueryRow("SELECT * FROM Entries WHERE score >= $1 AND rank!= -1 AND board=$2 ORDER BY score ASC LIMIT 1;", entry.Score, entry.Board).Scan(nearestEntry.Intake()...)
|
||
|
if (scanErr == nil) {
|
||
|
entry.Rank = nearestEntry.Rank + 1
|
||
|
entry.Commit()
|
||
|
} else {
|
||
|
// no other entries
|
||
|
entry.Rank = 1
|
||
|
entry.Commit()
|
||
|
//fmt.Println(scanErr)
|
||
|
}
|
||
|
}
|
||
|
}
|