|
|
@@ -3,7 +3,7 @@ |
|
|
|
package main // leadercraft-server |
|
|
|
|
|
|
|
import ( |
|
|
|
"flag" |
|
|
|
"flag" |
|
|
|
"fmt" |
|
|
|
"os" |
|
|
|
"os/signal" |
|
|
@@ -17,7 +17,7 @@ const ( |
|
|
|
) |
|
|
|
|
|
|
|
var ( |
|
|
|
isClosing bool |
|
|
|
isClosing bool |
|
|
|
printVersionAndExit bool |
|
|
|
) |
|
|
|
|
|
|
@@ -41,24 +41,41 @@ func main() { |
|
|
|
isClosing = true |
|
|
|
sqlClose() |
|
|
|
}() |
|
|
|
// get new rankings |
|
|
|
rows, err := db.Query("SELECT * FROM Entries WHERE rank=-1 ORDER BY time ASC;") |
|
|
|
// get new rankings |
|
|
|
rows, err := db.Query("SELECT * FROM Entries WHERE rank=-1 ORDER BY time ASC;") |
|
|
|
var players []int64 |
|
|
|
if err == nil { |
|
|
|
var entries []*Entry |
|
|
|
// update rank for boards |
|
|
|
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) |
|
|
|
} |
|
|
|
} |
|
|
|
for rows.Next() { |
|
|
|
entries = append(entries, &Entry{}) |
|
|
|
scanErr := rows.Scan(entries[count].Intake()...) |
|
|
|
if scanErr == nil { |
|
|
|
//fmt.Printf("Updating rank for entry %d in board %d from player %d\n", entries[count].ID, entries[count].Board, entries[count].Player) |
|
|
|
if entries[count].Board > 2 { // ignore special boards |
|
|
|
players = append(players, entries[count].Player) |
|
|
|
} |
|
|
|
updateBoardEntries(entries[count]) |
|
|
|
count++ |
|
|
|
} else { |
|
|
|
fmt.Println(scanErr) |
|
|
|
} |
|
|
|
} |
|
|
|
// update special boards |
|
|
|
for _, elem := range players { |
|
|
|
p := &Player{ID: elem} |
|
|
|
err := p.Load() |
|
|
|
if err == nil { |
|
|
|
//fmt.Printf("Updating high score for player %d\n", p.ID) |
|
|
|
updateMainRank(p) |
|
|
|
} else { |
|
|
|
fmt.Println(err) |
|
|
|
} |
|
|
|
} |
|
|
|
} else { |
|
|
|
fmt.Println(err) |
|
|
|
} |
|
|
|
fmt.Println(err) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
func initArgs() { |
|
|
@@ -76,33 +93,84 @@ func parseArgs() { |
|
|
|
} |
|
|
|
|
|
|
|
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) |
|
|
|
} |
|
|
|
} |
|
|
|
// 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() |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
func updateMainRank(p *Player) { |
|
|
|
rows, err := db.Query("SELECT * FROM Entries WHERE player = $1 AND board > 2 ORDER BY score DESC LIMIT $2;", p.ID, 100) |
|
|
|
var count int64 = 0 |
|
|
|
var sum int64 = 0 |
|
|
|
if err == nil { |
|
|
|
for rows.Next() { |
|
|
|
entry := &Entry{} |
|
|
|
scanErr := rows.Scan(entry.Intake()...) |
|
|
|
if scanErr == nil { |
|
|
|
count++ |
|
|
|
sum += entry.Score |
|
|
|
} else { |
|
|
|
fmt.Println(scanErr) |
|
|
|
return |
|
|
|
} |
|
|
|
} |
|
|
|
if count > 0 && sum > 0 { |
|
|
|
mainEntry := &Entry{ |
|
|
|
Player: p.ID, |
|
|
|
Board: 1, |
|
|
|
} |
|
|
|
average := sum / count |
|
|
|
//fmt.Printf("Average of %d/%d is %d\n", sum, count, average) |
|
|
|
dne := db.QueryRow("SELECT * FROM Entries WHERE board=$1 AND player=$2", 1, p.ID).Scan(mainEntry.Intake()...) |
|
|
|
if dne == nil { |
|
|
|
tx, _ := db.Begin() |
|
|
|
stmt, _ := tx.Prepare("UPDATE Entries SET rank=rank-1 WHERE rank >$1 AND id!=$2 AND board=$3;") |
|
|
|
_, err := stmt.Exec(mainEntry.Rank, mainEntry.ID, 1) |
|
|
|
if err != nil { |
|
|
|
tx.Rollback() |
|
|
|
fmt.Println(err) |
|
|
|
return // abort |
|
|
|
} else { |
|
|
|
tx.Commit() |
|
|
|
} |
|
|
|
mainEntry.Score = average |
|
|
|
mainEntry.Rank = -1 |
|
|
|
mainEntry.Commit() |
|
|
|
} else { |
|
|
|
createErr := newEntrySql(average, p.ID, 1) |
|
|
|
if createErr == nil { |
|
|
|
fmt.Println(createErr) |
|
|
|
return |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} else { |
|
|
|
fmt.Println(err) |
|
|
|
return |
|
|
|
} |
|
|
|
} |