func newGame(w http.ResponseWriter, r *http.Request) { lwutil.CheckMathod(r, "POST") rc := redisPool.Get() defer rc.Close() session, err := findSession(w, r, rc) lwutil.CheckError(err, "err_auth") checkAdmin(session) appid := session.Appid if appid == 0 { lwutil.SendError("err_auth", "Please login with app secret") } // input input := struct { Id uint32 Name string Sort string }{} err = lwutil.DecodeRequestBody(r, &input) lwutil.CheckError(err, "err_decode_body") if input.Id == 0 || input.Name == "" { lwutil.SendError("err_input", "Missing Id or Name") } if input.Sort != SORT_ASC && input.Sort != SORT_DESC { lwutil.SendError("err_input", "Invalid Sort, must be ASC or DESC") } // game := Game{ input.Id, input.Name, input.Sort, } gameJson, err := json.Marshal(game) lwutil.CheckError(err, "") key := fmt.Sprintf("games/%d", appid) _, err = rc.Do("hset", key, input.Id, gameJson) lwutil.CheckError(err, "") // reply lwutil.WriteResponse(w, game) }
func authNewApp(w http.ResponseWriter, r *http.Request) { lwutil.CheckMathod(r, "POST") session, err := findSession(w, r, nil) lwutil.CheckError(err, "err_auth") checkAdmin(session) // input var input struct { Name string } err = lwutil.DecodeRequestBody(r, &input) lwutil.CheckError(err, "err_decode_body") if input.Name == "" { lwutil.SendError("err_input", "input.Name empty") } // db stmt, err := authDB.Prepare("INSERT INTO apps (name, secret) VALUES (?, ?)") lwutil.CheckError(err, "") secret := lwutil.GenUUID() _, err = stmt.Exec(input.Name, secret) lwutil.CheckError(err, "err_name_exists") // reply reply := struct { Name string Secret string }{input.Name, secret} lwutil.WriteResponse(w, reply) }
func authRegister(w http.ResponseWriter, r *http.Request) { lwutil.CheckMathod(r, "POST") // in var in struct { Username string Password string CountryAlpha2 string SignCode uint32 } err := lwutil.DecodeRequestBody(r, &in) lwutil.CheckError(err, "err_decode_body") if in.Username == "" || in.Password == "" { lwutil.SendError("err_input", "") } pwsha := lwutil.Sha224(in.Password + passwordSalt) // insert into db res, err := authDB.Exec("INSERT INTO user_accounts (username, password, countryAlpha2, signCode) VALUES (?, ?, ?, ?)", in.Username, pwsha, in.CountryAlpha2, in.SignCode) lwutil.CheckError(err, "err_account_exists") id, err := res.LastInsertId() lwutil.CheckError(err, "") // reply reply := struct { Userid int64 }{id} lwutil.WriteResponse(w, reply) }
func authSetInfo(w http.ResponseWriter, r *http.Request) { lwutil.CheckMathod(r, "POST") session, err := findSession(w, r, nil) lwutil.CheckError(err, "err_auth") // in var in struct { CountryCode uint32 SignCode uint32 } err = lwutil.DecodeRequestBody(r, &in) lwutil.CheckError(err, "err_decode_body") if in.CountryCode == 0 || in.SignCode == 0 { lwutil.SendError("err_input", "") } // insert into db _, err = authDB.Exec("UPDATE user_accounts SET countryCode=?, signCode=? WHERE id=?", in.CountryCode, in.SignCode, session.Userid) lwutil.CheckError(err, "") //new session newSession(w, session.Userid, session.Username, session.Appid, in.CountryCode, in.SignCode, nil) // out lwutil.WriteResponse(w, in) }
func dig(w http.ResponseWriter, r *http.Request) { lwutil.CheckMathod(r, "POST") rc := redisPool.Get() defer rc.Close() session, err := findSession(w, r, rc) lwutil.CheckError(err, "err_auth") appid := session.Appid if appid == 0 { lwutil.SendError("err_auth", "Please login with app secret") } // in var in struct { MatchId uint32 } err = lwutil.DecodeRequestBody(r, &in) lwutil.CheckError(err, "err_decode_body") // out out := struct { Rank int64 Score int64 }{1, 2} lwutil.WriteResponse(w, out) }
func delGame(w http.ResponseWriter, r *http.Request) { lwutil.CheckMathod(r, "POST") rc := redisPool.Get() defer rc.Close() session, err := findSession(w, r, rc) lwutil.CheckError(err, "err_auth") checkAdmin(session) appid := session.Appid if appid == 0 { lwutil.SendError("err_auth", "Please login with app secret") } // input gameIds := make([]int, 0, 8) err = lwutil.DecodeRequestBody(r, &gameIds) lwutil.CheckError(err, "err_decode_body") // redis args := make([]interface{}, 1, 8) args[0] = fmt.Sprintf("games/%d", appid) for _, gameId := range gameIds { args = append(args, gameId) } delNum, err := redis.Int(rc.Do("hdel", args...)) lwutil.CheckError(err, "") // reply lwutil.WriteResponse(w, delNum) }
func listGame(w http.ResponseWriter, r *http.Request) { lwutil.CheckMathod(r, "POST") rc := redisPool.Get() defer rc.Close() session, err := findSession(w, r, rc) lwutil.CheckError(err, "err_auth") appid := session.Appid if appid == 0 { lwutil.SendError("err_auth", "Please login with app secret") } // get game data gameValues, err := redis.Values(rc.Do("hgetall", fmt.Sprintf("games/%d", appid))) lwutil.CheckError(err, "") games := make([]interface{}, 0, len(gameValues)/2) for i, v := range gameValues { if i%2 == 0 { continue } var game interface{} err = json.Unmarshal(v.([]byte), &game) lwutil.CheckError(err, "") games = append(games, game) } //reply lwutil.WriteResponse(w, games) }
func delMatch(w http.ResponseWriter, r *http.Request) { lwutil.CheckMathod(r, "POST") rc := redisPool.Get() defer rc.Close() session, err := findSession(w, r, rc) lwutil.CheckError(err, "err_auth") checkAdmin(session) appid := session.Appid if appid == 0 { lwutil.SendError("err_auth", "Please login with app secret") } //input matchIds := make([]int, 0, 8) err = lwutil.DecodeRequestBody(r, &matchIds) lwutil.CheckError(err, "err_decode_body") //redis key := fmt.Sprintf("matchesInApp/%d", appid) params := make([]interface{}, 0, 8) params = append(params, key) matchIdsItf := make([]interface{}, len(matchIds)) for i, v := range matchIds { matchIdsItf[i] = v } params = append(params, matchIdsItf...) rc.Send("zrem", params...) args := make([]interface{}, len(matchIds)+1) args[0] = "matches" for i, matchId := range matchIds { key = fmt.Sprintf("%d+%d", appid, matchId) args[i+1] = key } rc.Send("hdel", args...) rc.Flush() _, err = rc.Receive() lwutil.CheckError(err, "") delNum, err := rc.Receive() lwutil.CheckError(err, "") //reply lwutil.WriteResponse(w, delNum) }
func benchLogin(w http.ResponseWriter, r *http.Request) { lwutil.CheckMathod(r, "GET") // input in := struct { Username string Password string Appsecret string }{Username: "******", Password: "******"} if in.Username == "" || in.Password == "" { lwutil.SendError("err_input", "") } pwsha := lwutil.Sha224(in.Password + passwordSalt) // get userid row := authDB.QueryRow("SELECT id, countryCode, signCode FROM user_accounts WHERE username=? AND password=?", in.Username, pwsha) var userid uint64 var countryCode, signCode uint32 err := row.Scan(&userid, &countryCode, &signCode) lwutil.CheckError(err, "") // get appid appid := uint32(0) if in.Appsecret != "" { row = authDB.QueryRow("SELECT id FROM apps WHERE secret=?", in.Appsecret) err = row.Scan(&appid) lwutil.CheckError(err, "") } // new session rc := redisPool.Get() defer rc.Close() usertoken, err := newSession(w, userid, in.Username, appid, 0, 0, rc) lwutil.CheckError(err, "") // reply reply := struct { Usertoken string Appid uint32 }{usertoken, appid} lwutil.WriteResponse(w, reply) }
func getMyRank(w http.ResponseWriter, r *http.Request) { lwutil.CheckMathod(r, "POST") rc := redisPool.Get() defer rc.Close() session, err := findSession(w, r, rc) lwutil.CheckError(err, "err_auth") appid := session.Appid if appid == 0 { lwutil.SendError("err_auth", "Please login with app secret") } // in var in struct { MatchId uint32 } err = lwutil.DecodeRequestBody(r, &in) lwutil.CheckError(err, "err_decode_body") keyLeaderboard := makeLeaderboardKey(in.MatchId) rc.Send("zrank", keyLeaderboard, session.Userid) rc.Send("zscore", keyLeaderboard, session.Userid) rc.Flush() rank, err := redis.Int64(rc.Receive()) score := int64(0) if err == redis.ErrNil { rank = 0 } else { lwutil.CheckError(err, "") if err == nil { rank += 1 } score, err = redis.Int64(rc.Receive()) lwutil.CheckError(err, "") } // out out := struct { Rank int64 Score int64 }{rank, score} lwutil.WriteResponse(w, out) }
func authLogin(w http.ResponseWriter, r *http.Request) { lwutil.CheckMathod(r, "POST") // input var input struct { Username string Password string Appsecret string } err := lwutil.DecodeRequestBody(r, &input) lwutil.CheckError(err, "err_decode_body") if input.Username == "" || input.Password == "" { lwutil.SendError("err_input", "") } pwsha := lwutil.Sha224(input.Password + passwordSalt) // get userid row := authDB.QueryRow("SELECT id, countryAlpha2, signCode FROM user_accounts WHERE username=? AND password=?", input.Username, pwsha) var userid uint64 var countryAlpha2 string var signCode uint32 err = row.Scan(&userid, &countryAlpha2, &signCode) lwutil.CheckError(err, "err_not_match") // get appid appid := uint32(0) if input.Appsecret != "" { row = authDB.QueryRow("SELECT id FROM apps WHERE secret=?", input.Appsecret) err = row.Scan(&appid) lwutil.CheckError(err, "err_app_secret") } // new session rc := redisPool.Get() defer rc.Close() usertoken, err := newSession(w, userid, input.Username, appid, rc) lwutil.CheckError(err, "") // reply lwutil.WriteResponse(w, usertoken) }
func checkAdmin(session *Session) { if session.Username != "admin" { lwutil.SendError("err_denied", "") } }
func addScore(w http.ResponseWriter, r *http.Request) { lwutil.CheckMathod(r, "POST") rc := redisPool.Get() defer rc.Close() session, err := findSession(w, r, rc) lwutil.CheckError(err, "err_auth") appid := session.Appid if appid == 0 { lwutil.SendError("err_auth", "Please login with app secret") } //input var in struct { TrySecret string Score int64 } err = lwutil.DecodeRequestBody(r, &in) lwutil.CheckError(err, "err_decode_body") //use secret to get matchId matchIdRaw, err := rc.Do("get", fmt.Sprintf("trySecrets/%s", in.TrySecret)) lwutil.CheckError(err, "") if matchIdRaw == nil { lwutil.SendError("err_secret", "") } matchId64, err := redis.Int64(matchIdRaw, err) lwutil.CheckError(err, "") matchId := uint32(matchId64) //get match info and prev score keyLeaderboard := makeLeaderboardKey(matchId) matchKey := fmt.Sprintf("%d+%d", appid, matchId) rc.Send("hget", "matches", matchKey) rc.Send("zscore", keyLeaderboard, session.Userid) rc.Flush() matchJs, err := redis.Bytes(rc.Receive()) lwutil.CheckError(err, "") var match Match err = json.Unmarshal(matchJs, &match) lwutil.CheckError(err, "") prevScore, err := redis.Int64(rc.Receive()) needOverwrite := false if err == redis.ErrNil { needOverwrite = true } else { lwutil.CheckError(err, "") if match.Sort == SORT_ASC { if in.Score < prevScore { needOverwrite = true } } else if match.Sort == SORT_DESC { if in.Score > prevScore { needOverwrite = true } } else { lwutil.SendError("", "invalid match.Sort: "+match.Sort) } } //del from failboard and add to leaderboard and delete secret if needOverwrite { rc.Send("zadd", keyLeaderboard, in.Score, session.Userid) } rc.Send("zrank", keyLeaderboard, session.Userid) rc.Send("del", fmt.Sprintf("trySecrets/%s", in.TrySecret)) err = rc.Flush() lwutil.CheckError(err, "") if needOverwrite { _, err := rc.Receive() lwutil.CheckError(err, "") } rank, err := redis.Int(rc.Receive()) lwutil.CheckError(err, "") rank++ //reply lwutil.WriteResponse(w, rank) }
func startMatch(w http.ResponseWriter, r *http.Request) { lwutil.CheckMathod(r, "POST") rc := redisPool.Get() defer rc.Close() session, err := findSession(w, r, rc) lwutil.CheckError(err, "err_auth") appid := session.Appid if appid == 0 { lwutil.SendError("err_auth", "Please login with app secret") } //input var in struct { MatchId uint32 } err = lwutil.DecodeRequestBody(r, &in) lwutil.CheckError(err, "err_decode_body") //get match info key := fmt.Sprintf("%d+%d", appid, in.MatchId) matchJson, err := redis.Bytes(rc.Do("hget", "matches", key)) lwutil.CheckError(err, "err_not_found") var match Match err = json.Unmarshal(matchJson, &match) lwutil.CheckError(err, "") //check time now := time.Now().Unix() if now < match.Begin || now >= match.End-MATCH_TRY_DURATION_SEC { lwutil.SendError("err_time", "now < match.Begin || now >= match.End-MATCH_TRY_DURATION_SEC") } //incr and check try number tryNumKey := makeTryNumKey(in.MatchId) tryNum, err := redis.Int(rc.Do("hget", tryNumKey, session.Userid)) if err != nil && err != redis.ErrNil { lwutil.CheckError(err, "") } if uint32(tryNum) >= match.TryMax { lwutil.SendError("err_no_try", "no try left") } _, err = rc.Do("hincrby", tryNumKey, session.Userid, 1) lwutil.CheckError(err, "") tryNum++ //new try secret trySecret := lwutil.GenUUID() _, err = rc.Do("setex", fmt.Sprintf("trySecrets/%s", trySecret), MATCH_TRY_DURATION_SEC, in.MatchId) lwutil.CheckError(err, "") //out out := struct { Secret string TryNum uint32 }{trySecret, uint32(tryNum)} lwutil.WriteResponse(w, out) }
func newMatch(w http.ResponseWriter, r *http.Request) { lwutil.CheckMathod(r, "POST") rc := redisPool.Get() defer rc.Close() session, err := findSession(w, r, rc) lwutil.CheckError(err, "err_auth") checkAdmin(session) appid := session.Appid if appid == 0 { lwutil.SendError("err_auth", "Please login with app secret") } //input var in struct { Name string GameId uint32 Begin string End string TryMax uint32 TryPrice uint32 } err = lwutil.DecodeRequestBody(r, &in) lwutil.CheckError(err, "err_decode_body") if in.Name == "" || in.Begin == "" || in.End == "" || in.GameId == 0 { lwutil.SendError("err_input", "Missing Name || Begin || End || Gameid") } if in.TryMax == 0 { in.TryMax = 1 } //game info game, err := findGame(in.GameId, appid) lwutil.CheckError(err, "err_game") //times const timeform = "2006-01-02 15:04:05" begin, err := time.ParseInLocation(timeform, in.Begin, time.Local) lwutil.CheckError(err, "") end, err := time.ParseInLocation(timeform, in.End, time.Local) lwutil.CheckError(err, "") beginUnix := begin.Unix() endUnix := end.Unix() if endUnix-beginUnix <= 60 { lwutil.SendError("err_input", "endUnix - beginUnix must > 60 seconds") } if time.Now().Unix() > endUnix { lwutil.SendError("err_input", "end time before now") } // matchId, err := redis.Int(rc.Do("incr", "idGen/match")) lwutil.CheckError(err, "") match := Match{ uint32(matchId), in.Name, in.GameId, beginUnix, endUnix, game.Sort, in.TryMax, in.TryPrice, } matchJson, err := json.Marshal(match) lwutil.CheckError(err, "") key := fmt.Sprintf("%d+%d", appid, matchId) rc.Send("hset", "matches", key, matchJson) key = fmt.Sprintf("matchesInApp/%d", appid) rc.Send("zadd", key, endUnix, matchId) rc.Flush() for i := 0; i < 2; i++ { _, err = rc.Receive() lwutil.CheckError(err, "") } //reply lwutil.WriteResponse(w, match) }
func listMatch(w http.ResponseWriter, r *http.Request) { lwutil.CheckMathod(r, "POST") rc := redisPool.Get() defer rc.Close() session, err := findSession(w, r, rc) lwutil.CheckError(err, "err_auth") appid := session.Appid if appid == 0 { lwutil.SendError("err_auth", "Please login with app secret") } nowUnix := time.Now().Unix() //get matchIds key := fmt.Sprintf("matchesInApp/%d", appid) matchIdValues, err := redis.Values(rc.Do("zrangebyscore", key, nowUnix, "+inf")) lwutil.CheckError(err, "") args := make([]interface{}, len(matchIdValues)+1) args[0] = "matches" for i, v := range matchIdValues { var id int id, err := redis.Int(v, err) lwutil.CheckError(err, "") matchkey := fmt.Sprintf("%d+%d", appid, id) args[i+1] = matchkey } //get match data matchesValues, err := redis.Values(rc.Do("hmget", args...)) matches := make([]Match, len(matchesValues)) for i, v := range matchesValues { var match Match err = json.Unmarshal(v.([]byte), &match) lwutil.CheckError(err, "") matches[i] = match } //out type OutMatch struct { Id uint32 Name string GameId uint32 Begin int64 End int64 Sort string TryMax uint32 TryPrice uint32 TryNum uint32 } outMatches := make([]OutMatch, len(matches)) // get try number for _, match := range matches { tryNumKey := makeTryNumKey(match.Id) rc.Send("hget", tryNumKey, session.Userid) } err = rc.Flush() lwutil.CheckError(err, "") for i, match := range matches { tryNum, err := redis.Int(rc.Receive()) if err != nil && err != redis.ErrNil { lwutil.CheckError(err, "") } outMatches[i] = OutMatch{ Id: match.Id, Name: match.Name, GameId: match.GameId, Begin: match.Begin, End: match.End, Sort: match.Sort, TryMax: match.TryMax, TryPrice: match.TryPrice, TryNum: uint32(tryNum), } } lwutil.WriteResponse(w, outMatches) }