Follow the leader with help from a server
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

198 lines
6.9KB

  1. // NGnius 2020-02-11
  2. package main
  3. import (
  4. "database/sql"
  5. "fmt"
  6. "time"
  7. _ "github.com/mattn/go-sqlite3"
  8. )
  9. const (
  10. sqlServerDefault = "sqlite3"
  11. sqlConnectionDefault = "test.sqlite"
  12. )
  13. var (
  14. // command line arguments
  15. sqlServer string
  16. sqlConnection string
  17. buildTables bool
  18. populateTables bool
  19. // internal variables
  20. db *sql.DB
  21. )
  22. func sqlInit() error {
  23. var dbOpenErr error
  24. db, dbOpenErr = sql.Open(sqlServer, sqlConnection)
  25. if dbOpenErr != nil {
  26. return dbOpenErr
  27. }
  28. if buildTables {
  29. fmt.Println("Building tables in database...")
  30. sqlBuildTables()
  31. }
  32. if populateTables {
  33. fmt.Println("Populating tables in database...")
  34. sqlPopulateTables()
  35. }
  36. return nil
  37. }
  38. func sqlClose() error {
  39. if db != nil {
  40. err := db.Close()
  41. if err != nil {
  42. return err
  43. }
  44. db = nil
  45. }
  46. return nil
  47. }
  48. func boardByName(name string) (*Board, error) {
  49. b := &Board{}
  50. return b, db.QueryRow("SELECT * FROM Boards WHERE name=? LIMIT 1;", name).Scan(b.Intake()...)
  51. }
  52. func playerByName(name string) (*Player, error) {
  53. p := &Player{}
  54. return p, db.QueryRow("SELECT * FROM Players WHERE name=? LIMTI 1;", name).Scan(p.Intake()...)
  55. }
  56. func newEntrySql(score, player, board int64) error {
  57. tx, _ := db.Begin()
  58. stmt, _ := tx.Prepare("INSERT INTO Entries(score, player, board, time) VALUES (?, ?, ?, ?);")
  59. _, err := stmt.Exec(score, player, board, time.Now().Unix())
  60. if err != nil {
  61. tx.Rollback()
  62. return err
  63. }
  64. tx.Commit()
  65. return nil
  66. }
  67. func newKeySql(player int64) (*Key, error) {
  68. tx, _ := db.Begin()
  69. newKey := &Key{Token: "new", Player: player, Time: time.Now().Unix()}
  70. stmt, _ := tx.Prepare("INSERT INTO Keys(token, player, time) VALUES (?, ?, ?);")
  71. _, err := stmt.Exec(newKey.Token, newKey.Player, newKey.Time)
  72. if err != nil {
  73. tx.Rollback()
  74. return nil, err
  75. }
  76. tx.Commit()
  77. db.QueryRow("SELECT * FROM Keys WHERE token=? AND player=? AND time=?", newKey.Token, newKey.Player, newKey.Time).Scan(newKey.Intake()...)
  78. tokenErr := newKey.GenerateToken()
  79. if tokenErr != nil {
  80. return nil, tokenErr
  81. }
  82. return newKey, newKey.Commit()
  83. }
  84. func keyByToken(token string) (*Key, error) {
  85. k := &Key{}
  86. return k, db.QueryRow("SELECT * FROM Keys WHERE token=? LIMIT 1;", token).Scan(k.Intake()...)
  87. }
  88. func keyByPlayer(player int64) (*Key, error) {
  89. k := &Key{}
  90. return k, db.QueryRow("SELECT * FROM Keys WHERE player=? LIMIT 1;", player).Scan(k.Intake()...)
  91. }
  92. // internal operations
  93. func sqlBuildTables() {
  94. transaction, txErr := db.Begin()
  95. if txErr != nil {
  96. return
  97. }
  98. // test table
  99. //transaction.Exec("CREATE TABLE IF NOT EXISTS Test (Sometext VARCHAR, Somenumber);")
  100. //transaction.Exec("INSERT INTO Test (Sometext, Somenumber) VALUES (?,?);", "Hello sqlite", 123)
  101. // build real tables
  102. transaction.Exec("CREATE TABLE IF NOT EXISTS Players (id INTEGER PRIMARY KEY, name TEXT NOT NULL);")
  103. transaction.Exec("CREATE TABLE IF NOT EXISTS Boards (id INTEGER PRIMARY KEY, name TEXT NOT NULL, description TEXT NOT NULL);")
  104. transaction.Exec("CREATE TABLE IF NOT EXISTS Entries (id INTEGER PRIMARY KEY, rank INTEGER NOT NULL DEFAULT -1, score INTEGER NOT NULL, player INTEGER NOT NULL, board INTEGER NOT NULL, time INTEGER NOT NULL, metadata BLOB NOT NULL DEFAULT x'FF', FOREIGN KEY(player) REFERENCES Players(id), FOREIGN KEY(board) REFERENCES Boards(id));")
  105. transaction.Exec("CREATE TABLE IF NOT EXISTS Keys (id INTEGER PRIMARY KEY, token TEXT NOT NULL, player INTEGER NOT NULL, time INTEGER NOT NULL, metadata BLOB NOT NULL DEFAULT x'FF', FOREIGN KEY(player) REFERENCES Players(id));")
  106. transaction.Commit()
  107. }
  108. func sqlPopulateTables() {
  109. boards := []*Board{
  110. &Board{ID: 1, Name: "main-test", Description: "Overall best (test data)"},
  111. &Board{ID: 2, Name: "coolest-test", Description: "Coolest score (test data)"},
  112. &Board{ID: 3, Name: "fastest-test", Description: "Fastest time (test data)"},
  113. }
  114. for _, b := range boards {
  115. err := b.Commit()
  116. if err != nil {
  117. fmt.Printf("Error creating board %d: %s\n", b.ID, err)
  118. }
  119. }
  120. players := []*Player{
  121. &Player{ID: 1, Name: "NGnius (test)"},
  122. &Player{ID: 2, Name: "Also NGnius (test)"},
  123. &Player{ID: 3, Name: ".xX||eDgY TeeNaGeR||Xx. (test)"},
  124. &Player{ID: 4, Name: "New username who dis? (test)"},
  125. &Player{ID: 5, Name: "Extremely Ridiculously Long Name to break things (test)"},
  126. &Player{ID: 6, Name: "P|P3 |o|z (test)"},
  127. &Player{ID: 7, Name: "Waldo (test)"},
  128. &Player{ID: 8, Name: "Zettagram.com (test)"},
  129. &Player{ID: 9, Name: "The Doctor (test)"},
  130. &Player{ID: 10, Name: "Marvin the Paranoid Android (test)"},
  131. &Player{ID: 11, Name: "IDK HOW (test)"},
  132. &Player{ID: 12, Name: "If you can read this your API may be wrong (test)"},
  133. &Player{ID: 13, Name: "Unlucky 7 (test)"},
  134. }
  135. for _, p := range players {
  136. err := p.Commit()
  137. if err != nil {
  138. fmt.Printf("Error creating player %d: %s\n", p.ID, err)
  139. }
  140. }
  141. now := time.Now().Unix()
  142. metadata := []byte{0x00, 0x00, 0x00, 0x00}
  143. entries := []*Entry{
  144. &Entry{ID: 1, Rank: 1, Score: 1000, Player: players[0].ID, Board: boards[0].ID, Time: now, Metadata: metadata},
  145. &Entry{ID: 2, Rank: 2, Score: 900, Player: players[1].ID, Board: boards[0].ID, Time: now, Metadata: metadata},
  146. &Entry{ID: 3, Rank: 3, Score: 400, Player: players[2].ID, Board: boards[0].ID, Time: now, Metadata: metadata},
  147. &Entry{ID: 4, Rank: 4, Score: 350, Player: players[3].ID, Board: boards[0].ID, Time: now, Metadata: metadata},
  148. &Entry{ID: 5, Rank: 5, Score: 350, Player: players[4].ID, Board: boards[0].ID, Time: now, Metadata: metadata},
  149. &Entry{ID: 6, Rank: 6, Score: 250, Player: players[5].ID, Board: boards[0].ID, Time: now, Metadata: metadata},
  150. &Entry{ID: 7, Rank: 7, Score: 200, Player: players[6].ID, Board: boards[0].ID, Time: now, Metadata: metadata},
  151. &Entry{ID: 8, Rank: 8, Score: 175, Player: players[7].ID, Board: boards[0].ID, Time: now, Metadata: metadata},
  152. &Entry{ID: 9, Rank: 9, Score: 150, Player: players[8].ID, Board: boards[0].ID, Time: now, Metadata: metadata},
  153. &Entry{ID: 10, Rank: 10, Score: 140, Player: players[9].ID, Board: boards[0].ID, Time: now, Metadata: metadata},
  154. &Entry{ID: 11, Rank: 11, Score: 10, Player: players[10].ID, Board: boards[0].ID, Time: now, Metadata: metadata},
  155. &Entry{ID: 12, Rank: 12, Score: 60, Player: players[11].ID, Board: boards[0].ID, Time: now, Metadata: metadata},
  156. &Entry{ID: 13, Rank: 13, Score: 13, Player: players[12].ID, Board: boards[0].ID, Time: now},
  157. }
  158. for _, e := range entries {
  159. err := e.Commit()
  160. if err != nil {
  161. fmt.Printf("Error creating entry %d: %s\n", e.ID, err)
  162. }
  163. }
  164. metadata = []byte{0x7E}
  165. keys := []*Key{
  166. &Key{ID: 1, Token: "", Player: players[0].ID, Time: now, Metadata: metadata},
  167. &Key{ID: 2, Token: "", Player: players[1].ID, Time: now, Metadata: metadata},
  168. }
  169. for _, k := range keys {
  170. genErr := k.GenerateToken()
  171. if genErr != nil {
  172. fmt.Printf("Error generating token for key %d, %s\n", k.ID, genErr)
  173. }
  174. //fmt.Printf("Key %d token: %s\n", k.ID, k.Token)
  175. err := k.Commit()
  176. if err != nil {
  177. fmt.Printf("Error creating key %d, %s\n", k.ID, err)
  178. }
  179. // bitwise op test
  180. //fmt.Printf("Key &d is superuser:%t, enabled:%t\n", k.ID, k.IsSuperuser(), k.IsEnabled())
  181. }
  182. }