ice_gametopREDIS.go 10.6 KB
/**********************************************
* Copyright(c) 2016-2017 IceSimba
* All rights reserved.
*
* FileName: ice_gametopREDIS.go
* Author:  cc
* Version: 1.0
* Date:  2017/07/28
* Description:
* Others:
* Function List:
    IceGametopRedisAddSortSet            将数据添加到有序集
    IceGametopRedisSort                  分数排序
    IceGametopRedisSubmitScore           用户提交分数
	IceGameTopRedisGetSingleUserRankInfo 获取单个用户的排名信息
	IceGameTopRedisCreateRank            创建排行榜
* History:
    1.Date:
      Author:
      Modification:
**********************************************/

package sdkredis

import (
	"client/sdkdb"
	"common"
	"errors"
	"log"
	"regexp"
	"strconv"
	"strings"
)

type IGT struct {
	RankIndex       int    `json:"rank_index"`
	UID             string `json:"user_id"`
	MyKey           string `json:"score"`
	NickName        string `json:"nick_name"`
	HeadPortraitURL string `json:"headportrait_url"`
}

/**
 *  将数据添加到有序集
 */
func IceGametopRedisAddSortSet() {
	// 连接redis
	redisConn := RedisClient.GetConn()
	defer RedisClose(redisConn)

	// 取出排行榜设置数据,并添加到有序集
	rankSetList, rsderr := RedisGetKeys(redisConn, "ice_gametopset:*gtname")
	if rsderr != nil {
		log.Printf("RedisGetKeys err[%v]\n", rsderr)
		return
	}
	for _, rs := range rankSetList {
		index0 := strings.Index(rs, ":gtid:")
		index1 := strings.Index(rs, ":gid:")
		index2 := strings.Index(rs, ":toptype:")
		index3 := strings.Index(rs, ":gtname")
		gtid := common.Substr2(rs, index0+6, index1)
		gid := common.Substr2(rs, index1+5, index2)
		toptype := common.Substr2(rs, index2+9, index3)

		keys, err := RedisGetKeys(redisConn, "ice_gametop:*gtid:"+gtid+"*gid:"+gid+"*toptype:"+toptype+"*")
		if err != nil {
			RedisClose(redisConn)
			log.Printf("RedisGetKeys keys[%s] err[%v]\n", keys, err)
			return
		}

		for _, key := range keys {
			value, _ := RedisGetKV(redisConn, key)
			value_float64, _ := strconv.ParseFloat(value, 64)
			RedisZAddSortSet(redisConn, "sortset:gtid:"+gtid+":gid:"+gid+":toptype:"+toptype, value_float64, key)
		}

	}
}

/**
 *  分数排序
 */
func IceGametopRedisSort(gtid string, gid string, toptype string, start int, stop int) (igts []*IGT) {
	// 连接redis
	redisConn := RedisClient.GetConn()
	defer RedisClose(redisConn)

	// 获取当前排行榜是正序还是反序
	var sorceorder string
	iceGameTopSet, _, err := sdkdb.IceGameTopSetQueryOne(gtid, gid, toptype)
	if err == nil {
		if iceGameTopSet != nil {
			sorceorder = iceGameTopSet.SORCEORDER
		} else {
			return
		}
	} else {
		log.Printf("IceGameTopSetQueryOne err[%v]", err)
		return
	}
	toptype = iceGameTopSet.TOPTYPE //不需要对传入的toptype做判断,根据gid和gtid就可以获得排行
	// 获得有序sort
	sortsetName := "sortset:gtid:" + gtid + ":gid:" + gid + ":toptype:" + toptype
	log.Printf("sortsetName[%s]", sortsetName)

	var (
		strList    []string
		sorterr    error
		valuecount = 2    //需要使用正则获取特定值的数目
		resultstr  string //redis查询结果字符串
	)

	log.Printf("sorceorder[%v]", sorceorder)
	if sorceorder == "0" {
		strList, sorterr = RedisSort(redisConn, sortsetName, start-1, stop-1) // 从小到大
	} else if sorceorder == "1" {
		strList, sorterr = RedisReverseSort(redisConn, sortsetName, start-1, stop-1) // 从大到小
	}

	if sorterr != nil {
		log.Println("RedisSort err[%v]", sorterr)
		return
	} else if len(strList) == 0 {
		log.Println("rank has no user")
		return []*IGT{}
	}

	igts = []*IGT{}
	index := start
	_, err = RedisDBSelect(redisConn, 4)
	if err != nil {
		log.Printf("select db err:", err)
	}

	for i := 0; i < len(strList); i += 2 {
		igt := new(IGT)

		igt.RankIndex = index

		startIndex := strings.Index(strList[i], "uid:") + 4
		endIndex := strings.Index(strList[i], ":gtid")
		igt.UID = common.Substr2(strList[i], startIndex, endIndex)

		//查询储存昵称以及头像url的redis
		var err error
		resultstr, err = RedisGetKV(redisConn, "GUID:"+igt.UID)
		if err != nil {
			log.Println("get redis err:", err)
		}
		r, err := regexp.Compile(`\|([^\|])*\|`)
		if err != nil {
			log.Println("err:", err)
		}
		// 使用正则匹配需要的值
		result := r.FindAllString(resultstr, valuecount)

		//去除用来匹配的特殊字符“|“
		if result != nil {
			for key, value := range result {
				value = value[1 : len(value)-1]
				log.Println(value)
				result[key] = value
			}
			//result 为切片,储存了所有匹配到的特定值
			igt.NickName = result[0]        //第一个为昵称
			igt.HeadPortraitURL = result[1] //第二个为头像url
		}

		igt.MyKey = strList[i+1]

		igts = append(igts, igt)
		index++
	}
	_, err = RedisDBSelect(redisConn, 2)
	if err != nil {
		log.Printf("select db err:", err)
	}

	return
}

/**
 *  用户提交分数
 */
func IceGametopRedisSubmitScore(uid string, gtid string, gid string, score string) error {
	// 连接redis
	redisConn := RedisClient.GetConn()
	defer RedisClose(redisConn)

	iceGameTopSets, err := sdkdb.IceGameTopSetQuery(gtid, gid)
	if iceGameTopSets == nil {
		err = errors.New("gametop name or game name not exist")
		return err
	}
	if len(iceGameTopSets) == 0 {
		return err
	}
	if err != nil {
		log.Println(err)
		return err
	}
	// update time 2017-09-07 14:59:54 update by  徐振浩
	// update start
	//提交的分数
	score_float64, _ := strconv.ParseFloat(score, 64)
	//提交的排行榜类型
	log.Println(iceGameTopSets)
	toptype := iceGameTopSets[0].TOPTYPE
	log.Printf("toptoptop[%v]", toptype)
	//redis键值
	ice_gametopK := "ice_gametop:uid:" + uid + ":gtid:" + gtid + ":gid:" + gid + ":toptype:" + toptype + ":mykey"
	//获取原有分数
	value, err := RedisGetKV(redisConn, ice_gametopK)
	log.Println(value)
	var value_float64 float64
	if value == "" {
		value_float64 = 0
	} else {
		if err != nil {
			return err
		}
		value_float64, _ = strconv.ParseFloat(value, 64)
	}
	//进行比较,比原先分数高才会更新
	log.Println(value_float64)
	sortType, err := sdkdb.IceGameTopSetQuerySortType(gtid, gid)
	if err != nil {
		return err
	}
	if sortType == "0" {
		if value_float64-score_float64 > 0.000001 || value == "" {
			if reply, err := RedisSetKV(redisConn, ice_gametopK, score); err != nil {
				RedisClose(redisConn)
				log.Printf("RedisSetKV reply[%v] err[%v]", reply, err)
				return err
			}
			// 更新有序集中的数据
			log.Println(score_float64)
			log.Println(ice_gametopK)
			res, err := RedisZAddSortSet(redisConn, "sortset:gtid:"+gtid+":gid:"+gid+":toptype:"+toptype, score_float64, ice_gametopK)
			if err != nil {
				log.Println(err)
			}
			log.Println(res)
		}
	} else {
		if score_float64-value_float64 > 0.000001 {
			if reply, err := RedisSetKV(redisConn, ice_gametopK, score); err != nil {
				RedisClose(redisConn)
				log.Printf("RedisSetKV reply[%v] err[%v]", reply, err)
				return err
			}
			// 更新有序集中的数据
			log.Println(score_float64)
			log.Println(ice_gametopK)
			res, err := RedisZAddSortSet(redisConn, "sortset:gtid:"+gtid+":gid:"+gid+":toptype:"+toptype, score_float64, ice_gametopK)
			if err != nil {
				log.Println(err)
			}
			log.Println(res)
		}
	}
	//update end
	return nil
}

/**
 *  获取单个用户的排名信息
 */
func IceGameTopRedisGetSingleUserRankInfo(uid string, gtid string, gid string, toptype string) (igt *IGT) {
	// 连接redis
	redisConn := RedisClient.GetConn()
	defer RedisClose(redisConn)

	// 获取当前排行榜是正序还是反序/

	var sorceorder string
	iceGameTopSet, _, err := sdkdb.IceGameTopSetQueryOne(gtid, gid, toptype)
	if err == nil {
		if iceGameTopSet != nil {
			sorceorder = iceGameTopSet.SORCEORDER
			toptype = iceGameTopSet.TOPTYPE //不需要对传入的toptype做判断,根据gid和gtid就可以获得排行
		} else {

			return
		}
	} else {
		return
	}

	// 排序
	var strList []string
	var sorterr error

	if sorceorder == "0" {
		strList, sorterr = RedisSort(redisConn, "sortset:gtid:"+gtid+":gid:"+gid+":toptype:"+toptype, 0, -1)
	} else if sorceorder == "1" {
		strList, sorterr = RedisReverseSort(redisConn, "sortset:gtid:"+gtid+":gid:"+gid+":toptype:"+toptype, 0, -1)
	}
	if sorterr != nil {
		log.Println("RedisSort err[%v]", sorterr)
		return
	} else if len(strList) == 0 {
		log.Println("rank has no data")
	}

	igt = new(IGT)
	index := 1
	var resultstr string
	var valuecount = 2
	_, err = RedisDBSelect(redisConn, 4)
	if err != nil {
		log.Printf("select db err:", err)
	}
	for i := 0; i < len(strList); i += 2 {
		startIndex := strings.Index(strList[i], "uid:") + 4
		endIndex := strings.Index(strList[i], ":gtid")
		currUID := common.Substr2(strList[i], startIndex, endIndex)

		if currUID == uid {
			igt.UID = uid
			igt.RankIndex = index
			igt.MyKey = strList[i+1]
			//查询储存昵称以及头像url的redis
			var err error
			resultstr, err = RedisGetKV(redisConn, "GUID:"+igt.UID)
			if err != nil {
				log.Println("get redis err:", err)
			}
			r, err := regexp.Compile(`\|([^\|])*\|`)
			if err != nil {
				log.Println("err:", err)
			}
			// 使用正则匹配需要的值
			result := r.FindAllString(resultstr, valuecount)

			//去除用来匹配的特殊字符“|“
			if result != nil {
				for key, value := range result {
					value = value[1 : len(value)-1]
					log.Println(value)
					result[key] = value
				}
				//result 为切片,储存了所有匹配到的特定值
				igt.NickName = result[0]        //第一个为昵称
				igt.HeadPortraitURL = result[1] //第二个为头像url
			}
		}

		index++
	}
	_, err = RedisDBSelect(redisConn, 2)
	if err != nil {
		log.Printf("select db err:", err)
	}

	return
}

func IceGameTopRedisCreateRank(gtid string, gid string, toptype string, gtname string, sorcetype string, sorcesub string, sorceorder string) error {
	// 连接redis
	redisConn := RedisClient.GetConn()
	defer RedisClose(redisConn)

	if reply, err := RedisSetKV(redisConn, "ice_gametopset:gtid:"+gtid+":gid:"+gid+":toptype:"+toptype+":gtname", gtname); err != nil {
		RedisClose(redisConn)
		log.Printf("RedisCommand replay[%v] err[%v]\n", reply, err)
		return err
	}

	if reply, err := RedisSetKV(redisConn, "ice_gametopset:gtid:"+gtid+":gid:"+gid+":toptype:"+toptype+":sorcetype", sorcetype); err != nil {
		RedisClose(redisConn)
		log.Printf("RedisCommand replay[%v] err[%v]\n", reply, err)
		return err
	}

	if reply, err := RedisSetKV(redisConn, "ice_gametopset:gtid:"+gtid+":gid:"+gid+":toptype:"+toptype+":sorcesub", sorcesub); err != nil {
		RedisClose(redisConn)
		log.Printf("RedisCommand replay[%v] err[%v]\n", reply, err)
		return err
	}

	if reply, err := RedisSetKV(redisConn, "ice_gametopset:gtid:"+gtid+":gid:"+gid+":toptype:"+toptype+":sorceorder", sorceorder); err != nil {
		RedisClose(redisConn)
		log.Printf("RedisCommand replay[%v] err[%v]\n", reply, err)
		return err
	}

	return nil
}