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 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 authListApp(w http.ResponseWriter, r *http.Request) { lwutil.CheckMathod(r, "POST") session, err := findSession(w, r, nil) lwutil.CheckError(err, "err_auth") checkAdmin(session) // db rows, err := authDB.Query("SELECT name, secret FROM apps") lwutil.CheckError(err, "") type App struct { Name string Secret string } apps := make([]App, 0, 16) var app App for rows.Next() { err = rows.Scan(&app.Name, &app.Secret) lwutil.CheckError(err, "") apps = append(apps, app) } lwutil.WriteResponse(w, apps) }
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 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 benchJson(w http.ResponseWriter, r *http.Request) { lwutil.CheckMathod(r, "GET") str := []byte(` { "Name": "aa", "Gameid": 885, "Begin": "2013/04/06 23:43:24", "End": "2013/05/06 23:43:24", "Sort": 0 } `) in := struct { Name string Gameid uint32 Begin string End string Sort uint8 }{} err := json.Unmarshal(str, &in) lwutil.CheckError(err, "") lwutil.WriteResponse(w, in) }
func findSession(w http.ResponseWriter, r *http.Request, rc redis.Conn) (*Session, error) { session := new(Session) usertokenCookie, err := r.Cookie("usertoken") if err != nil { return session, lwutil.NewErr(err) } usertoken := usertokenCookie.Value //redis if rc == nil { rc = redisPool.Get() defer rc.Close() } sessionBytes, err := redis.Bytes(rc.Do("get", fmt.Sprintf("sessions/%s", usertoken))) if err != nil { return session, lwutil.NewErr(err) } err = json.Unmarshal(sessionBytes, session) lwutil.CheckError(err, "") //update session dt := time.Now().Sub(session.Born) if dt > sessionUpdateSecond*time.Second { newSession(w, session.Userid, session.Username, session.Appid, rc) } return session, nil }
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 benchDBInsert(w http.ResponseWriter, r *http.Request) { lwutil.CheckMathod(r, "GET") //db stmt, err := matchDB.Prepare("INSERT INTO insertTest (a, b, c, d) VALUES (?, ?, ?, ?)") lwutil.CheckError(err, "") ids := make([]int64, insertCount) for i := 0; i < insertCount; i++ { res, err := stmt.Exec(1, 2, 3, 4) lwutil.CheckError(err, "err_account_exists") ids[i], err = res.LastInsertId() lwutil.CheckError(err, "") } lwutil.WriteResponse(w, ids) }
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 benchDBSingleSelect(w http.ResponseWriter, r *http.Request) { lwutil.CheckMathod(r, "GET") row := authDB.QueryRow("SELECT id FROM user_accounts WHERE username=?", "admin") var userid uint32 err := row.Scan(&userid) lwutil.CheckError(err, "") lwutil.WriteResponse(w, userid) }
func authLogout(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_already_logout") usertokenCookie, err := r.Cookie("usertoken") lwutil.CheckError(err, "err_already_logout") usertoken := usertokenCookie.Value rc.Send("del", fmt.Sprintf("sessions/%s", usertoken)) rc.Send("del", fmt.Sprintf("usertokens/%d+%d", session.Userid, session.Appid)) rc.Flush() for i := 0; i < 2; i++ { _, err = rc.Receive() lwutil.CheckError(err, "") } // reply lwutil.WriteResponse(w, "logout") }
func benchJson2(w http.ResponseWriter, r *http.Request) { lwutil.CheckMathod(r, "GET") str := []byte(` { "Name": "aa" } `) in := struct { Name string }{} err := json.Unmarshal(str, &in) lwutil.CheckError(err, "") lwutil.WriteResponse(w, in) }
func authLoginInfo(w http.ResponseWriter, r *http.Request) { lwutil.CheckMathod(r, "POST") session, err := findSession(w, r, nil) lwutil.CheckError(err, "err_auth") // usertokenCookie, err := r.Cookie("usertoken") usertoken := usertokenCookie.Value // reply := struct { Session *Session UserToken string }{session, usertoken} lwutil.WriteResponse(w, reply) }
func benchRedisGet(w http.ResponseWriter, r *http.Request) { lwutil.CheckMathod(r, "GET") rc := redisPool.Get() defer rc.Close() rc.Send("set", "foo", "yes") rc.Send("get", "foo") rc.Flush() rc.Receive() foo, err := redis.String(rc.Receive()) lwutil.CheckError(err, "") // foo, err := redis.String(rc.Do("get", "foo")) // lwutil.CheckError(err, "") lwutil.WriteResponse(w, foo) }
func newSession(w http.ResponseWriter, userid uint64, username string, appid uint32, rc redis.Conn) (usertoken string, err error) { if rc == nil { rc = redisPool.Get() defer rc.Close() } usertoken = "" usertokenRaw, err := rc.Do("get", fmt.Sprintf("usertokens/%d+%d", userid, appid)) lwutil.CheckError(err, "") if usertokenRaw != nil { if usertoken, err := redis.String(usertokenRaw, err); err != nil { return usertoken, lwutil.NewErr(err) } rc.Do("del", fmt.Sprintf("sessions/%s", usertoken)) } usertoken = lwutil.GenUUID() session := Session{userid, username, time.Now(), appid} jsonSession, err := json.Marshal(session) if err != nil { return usertoken, lwutil.NewErr(err) } rc.Send("setex", fmt.Sprintf("sessions/%s", usertoken), sessionLifeSecond, jsonSession) rc.Send("setex", fmt.Sprintf("usertokens/%d+%d", userid, appid), sessionLifeSecond, usertoken) rc.Flush() for i := 0; i < 2; i++ { if _, err = rc.Receive(); err != nil { return usertoken, lwutil.NewErr(err) } } // cookie http.SetCookie(w, &http.Cookie{Name: "usertoken", Value: usertoken, MaxAge: sessionLifeSecond, Path: "/"}) return usertoken, err }
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) }
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) }