logic.go 8.48 KB
package logic

import (
	"HttpServer/jsonconf"
	"HttpServer/redishandler"
	"common/logger"
	"common/redis"
	"encoding/json"
	"fmt"
	"net/http"
	"strconv"
	"sync"
	"time"
)

var (
	//m_userInfo *beegomap.BeeMap //make(map[int32]*UserData
	Maplock *sync.RWMutex
)

func init() {
	//m_userInfo = beegomap.NewBeeMap()
	Maplock = new(sync.RWMutex)
}

func SetHeader(w http.ResponseWriter) {
	w.Header().Set("Access-Control-Allow-Origin", "*") //允许访问所有域
	w.Header().Set("Content-Type", "application/json")
	w.Header().Set("Access-Control-Allow-Headers", "Content-Type,Uuid")
}

func HandlerLogin(w http.ResponseWriter, data string, uuid int, token string) {
	SetHeader(w)
	var resp UserLoginResp
	resp.Code = 0
	resp.Message = "success"
	var rdata UserLoginReq
	err := json.Unmarshal([]byte(data), &rdata)
	if err != nil {
		logger.Info("json decode HandlerLogin data failed:%v,for:%v", err, data)
		resp.Message = "json unmarshal failed"
		resp.Code = 1
		respstr, _ := json.Marshal(&resp)
		logger.Info("###HandlerLogin###rdata:%v", string(respstr))
		fmt.Fprint(w, string(respstr))
		return
	}

	//首先判断一下是否是首次登陆
	isexist, _ := redishandler.GetRedisClient().HExists(redis.USER_INFO__KEY, strconv.Itoa(rdata.UserId))
	if !isexist {
		//不存在
		//属于新登录的玩家数据
		InitUserInfo(&rdata, &resp, rdata.UserId)

	} else {
		uinfo, err := GetUserInfo(strconv.Itoa(rdata.UserId))
		if err != nil {
			logger.Info("GetUserInfo HandlerLogin data failed:%v,for:%v", err, data)
			resp.Message = "GetUserInfo failed"
			resp.Code = 2
			respstr, _ := json.Marshal(&resp)
			fmt.Fprint(w, string(respstr))
			return
		}

		resp.Data.Nickname = uinfo.NickName
		resp.Data.UserId = strconv.Itoa(rdata.UserId)
		resp.Data.AccessToken = token
		resp.Data.HeadImg = uinfo.Head
		resp.Data.LoginType = rdata.Lype

	}

	//回包
	respstr, _ := json.Marshal(&resp)
	fmt.Fprint(w, string(respstr))

	logger.Info("###HandlerLogin###rdata:%v", string(respstr))
}

func HandlerDoBuyCat(w http.ResponseWriter, data string, uuid int) {
	SetHeader(w)
	var resp DoBuyCatResp
	resp.Code = 0
	resp.Message = "success"
	var rdata DoBuyCatReq
	err := json.Unmarshal([]byte(data), &rdata)
	for {
		if err != nil {
			logger.Error("HandlerDoBuyCat json unmarshal failed=%v", err)
			resp.Code = 1
			resp.Message = "json failed"
			break
		}
		uinfo, err := GetUserInfo(strconv.Itoa(uuid))
		if err != nil || uinfo == nil {
			logger.Error("HandlerDoBuyCat getuserinfo failed=%v", err)
			resp.Code = 1
			resp.Message = "get userinfo failed"
			break
		}

		maxlv := uinfo.Highestlv - 5
		if maxlv < 1 {
			//最小1j
			maxlv = 1
		}
		if rdata.CatId > maxlv || rdata.CatId < 1 || rdata.CatId > len(uinfo.BuyCatInfo) {
			logger.Error("HandlerDoBuyCat buy lv  failed=%v", err)
			resp.Code = 1
			resp.Message = "buy lv invalid"
			break
		}

		curprice := uinfo.BuyCatInfo[rdata.CatId-1].CurPrice
		if uinfo.Gold < curprice {
			logger.Error("HandlerDoBuyCat gold not enough  failed=%v", err)
			resp.Code = 1
			resp.Message = "gold not enough"
			break
		}

		//获取配置
		catcfg := jsonconf.GetCatConfig(rdata.CatId)
		if catcfg == nil {
			logger.Error("HandlerDoBuyCat get cat cfg  failed=%v,lv=%v", err, rdata.CatId)
			resp.Code = 1
			resp.Message = "get cat cfg failed"
			break
		}

		//需要找到一个位置
		catpos := getCatPutPos(uinfo, rdata.CatId)
		if catpos < 0 {
			logger.Error("HandlerDoBuyCat not enough place  failed=%v", err)
			resp.Code = 1
			resp.Message = "not enough place"
			break
		}
		//扣钱
		uinfo.Gold -= curprice

		//重新计算价格
		if uinfo.BuyCatInfo[rdata.CatId-1].IsMaxBuytime == 0 {
			uinfo.BuyCatInfo[rdata.CatId-1].CurPrice = int64(float64(uinfo.BuyCatInfo[rdata.CatId-1].CurPrice) * float64(catcfg.Ratio))
			uinfo.BuyCatInfo[rdata.CatId-1].Buytime++
			if uinfo.BuyCatInfo[rdata.CatId-1].Buytime >= catcfg.Increse_limit {
				uinfo.BuyCatInfo[rdata.CatId-1].IsMaxBuytime = 1
			}
		}

		//需要重新计算速率
		uinfo.CalcGoldRate()

		resp.Data.Price = strconv.FormatInt(uinfo.BuyCatInfo[rdata.CatId-1].CurPrice, 10)
		resp.Data.Position = catpos
		resp.Data.Coin.UserId = uuid
		resp.Data.Coin.Coin = strconv.FormatInt(uinfo.Gold, 10)
		resp.Data.Coin.IcomeRate = strconv.FormatInt(uinfo.Goldrate, 10)
		resp.Data.Coin.UpdateTime = int(time.Now().Unix())

		resp.Code = 0

		//保存
		SaveUserInfo(uinfo, strconv.Itoa(uuid))

		break

	}
	//回包
	respstr, _ := json.Marshal(&resp)
	fmt.Fprint(w, string(respstr))
}

func HandlerGetUserData(w http.ResponseWriter, data string, uuid int) {
	SetHeader(w)
	var resp GetUserDataResp
	resp.Code = 0
	resp.Message = "success"

	for {
		v, err := redishandler.GetRedisClient().HGet(redis.USER_LAST_CALC_TIME, strconv.Itoa(uuid))
		if err != nil {
			logger.Info("CalcOfflineData get USER_LAST_CALC_TIME failed=%v", err)
			resp.Message = "redishandler failed"
			resp.Code = 1
			break
		}

		lasttime, _ := strconv.Atoi(v)
		nowtime := time.Now().Unix()
		if nowtime-int64(lasttime) < 0 {
			logger.Error("HandlerGetUserData nowtime=%v lasttime=%v", nowtime, lasttime)
			resp.Message = "request time small than zero"
			resp.Code = 1
			break
		}
		uinfo, err := GetUserInfo(strconv.Itoa(uuid))
		if err != nil || uinfo == nil {
			logger.Error("HandlerGetUserData getuserinfo failed=%v", err)
			resp.Code = 1
			resp.Message = "get userinfo failed"
			break
		}

		if nowtime-int64(lasttime) > 5*60 {
			//算离线收益
			resp.Data.TimingReward = false
			offsec := nowtime - int64(lasttime)
			if offsec > 2*3600 {
				offsec = 2 * 3600
			}

			uinfo.OfflineGold = offsec * uinfo.Goldrate
			resp.Data.Coin = strconv.FormatInt(uinfo.Gold, 10)
			resp.Data.Now = int(time.Now().Unix())
			resp.Data.Output = "0"
			resp.Data.OfflineReward.OfflineTime = int(offsec)
			resp.Data.OfflineReward.Income = strconv.FormatInt(uinfo.OfflineGold, 10)
		} else {
			//按费离线收益计算
			offsec := nowtime - int64(lasttime)
			resp.Data.TimingReward = true
			resp.Data.Now = int(time.Now().Unix())
			addgold := uinfo.Goldrate * offsec
			uinfo.Gold = addgold
			uinfo.GoldSum += addgold
			uinfo.AddToRank()
			resp.Data.Output = strconv.FormatInt(addgold, 10)
			resp.Data.Coin = strconv.FormatInt(uinfo.Gold, 10)
		}

		//保存此次计算时间
		nowtimestr := strconv.FormatInt(nowtime, 10)
		redishandler.GetRedisClient().HSet(redis.USER_LAST_CALC_TIME, strconv.Itoa(uuid), nowtimestr)
		logger.Info("HandlerGetUserData save USER_LAST_CALC_TIME time=%v", nowtimestr)

		break
	}

	//回包
	respstr, _ := json.Marshal(&resp)
	fmt.Fprint(w, string(respstr))
}

func HandlerGetOfflineReward(w http.ResponseWriter, data string, uuid int) {
	SetHeader(w)
	var resp GetOfflineRewardResp
	resp.Code = 0
	resp.Message = "success"
	var rdata GetOfflineRewardReq

	err := json.Unmarshal([]byte(data), &rdata)
	for {
		if err != nil {
			logger.Error("HandlerGetOfflineReward json unmarshal failed=%v", err)
			resp.Code = 1
			resp.Message = "json failed"
			break
		}

		uinfo, err := GetUserInfo(strconv.Itoa(uuid))
		if err != nil || uinfo == nil {
			logger.Error("HandlerGetUserData getuserinfo failed=%v", err)
			resp.Code = 1
			resp.Message = "get userinfo failed"
			break
		}

		addgold := uinfo.OfflineGold

		if rdata.Optype == 2 {
			addgold *= 2

		}
		uinfo.Gold += addgold
		uinfo.GoldSum += addgold
		uinfo.AddToRank()

		//此处todo 记录离线领取的次数

		//领取过后将离线金币清零
		uinfo.OfflineGold = 0

		//保存
		SaveUserInfo(uinfo, strconv.Itoa(uuid))

		resp.Code = 0
		break
	}

	//回包
	respstr, _ := json.Marshal(&resp)
	fmt.Fprint(w, string(respstr))
}

func HandlerQueryPlayerRank(w http.ResponseWriter, data string, uuid int) {
	SetHeader(w)
	var resp QueryPlayerRankResp
	resp.Code = 0
	resp.Message = "success"
	for {
		//取100名
		vv, err := redishandler.GetRedisClient().ZRevRangewithIndex(redis.USER_GOLD_RANK, 0, 99)
		if err == nil {
			rank := 0
			for _, v := range vv {
				rank++
				//logger.Info("TestMyredis k=%v,v=%v", k, v)
				rinfobyte, _ := v.(string)
				ruid, _ := strconv.Atoi(rinfobyte)
				rindo, err := GetUserInfo(rinfobyte)
				if err == nil && rindo != nil {
					var tmp RankInfoDesc
					tmp.UserId = ruid
					tmp.Income = rindo.GoldSum
					tmp.Nickname = rindo.NickName
					tmp.Headurl = rindo.Head
					tmp.Rank = rank
					tmp.CatName = rindo.CalcHigestCatName()
					resp.Data = append(resp.Data, tmp)
				}
			}
		} else {
			logger.Error("HandlerUpdateUserInfo redisfailed ")
			resp.Code = 1
			resp.Message = "redisfailed"
			break
		}
		resp.Code = 0
		break
	}

	//回包
	respstr, _ := json.Marshal(&resp)
	fmt.Fprint(w, string(respstr))
}