예제 #1
0
파일: auth.go 프로젝트: henyouqian/grid
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)
}
예제 #2
0
파일: auth.go 프로젝트: henyouqian/grid
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)
}
예제 #3
0
파일: dig.go 프로젝트: henyouqian/grid
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)
}
예제 #4
0
파일: auth.go 프로젝트: henyouqian/matches
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)
}
예제 #5
0
파일: game.go 프로젝트: henyouqian/matches
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)
}
예제 #6
0
파일: match.go 프로젝트: henyouqian/matches
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)
}
예제 #7
0
파일: game.go 프로젝트: henyouqian/matches
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)
}
예제 #8
0
파일: rank.go 프로젝트: henyouqian/matches
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)
}
예제 #9
0
파일: auth.go 프로젝트: henyouqian/grid
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)
}
예제 #10
0
파일: match.go 프로젝트: henyouqian/matches
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)
}
예제 #11
0
파일: match.go 프로젝트: henyouqian/matches
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)
}
예제 #12
0
파일: match.go 프로젝트: henyouqian/matches
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)
}