123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189 |
- --排行榜服务
- local skynet = require "skynet"
- require "skynet.manager"
- local util = require "util"
- local logger = require "logger"
- local common_fun = require "model.common_fun"
- local stringify = require "stringify"
- local pipeline = require "pipeline"
- local redisdriver = require "skynet.db.redis"
- local redis
- local KEY_STR = "ranking:%d:list"
- local cjson = require "cjson"
- local cjson_decode = cjson.decode -- 解码
- local cjson_encode = cjson.encode -- 编码
- local MAX_RANK = 300
- local compare = function(a, b)
- if a.num > b.num then
- return true
- end
- if a.num == b.num and a.num2 and b.num2 then
- return a.num2 > b.num2
- end
- return false
- end
- local function inserting(t, n, f)
- assert(type(t) == "table")
- local f = f or compare
- local size = #t
- local n = n or size + 1
- for i = 2, size do
- local num = math.min(i, n)
- if i > n and f(t[i], t[num]) then
- t[i], t[num] = t[num], t[i]
- end
- local temp = t[num]
- local j = num -1
- while j >= 1 and f(temp, t[j]) do
- t[j+1] = t[j]
- j = j - 1
- end
- t[j+1] = temp
- end
- -- if n < size then
- -- t[n+1] = nil
- -- end
- for i = n + 1, size do
- t[i] = nil
- end
- return t
- end
- local CMD = {}
- local ranklist = {
- }
- local showlist = {
- }
- local function update()
- for rank_type, list in pairs(ranklist) do
- inserting(list, MAX_RANK)
- showlist[rank_type] = {}
- local key = string.format(KEY_STR, rank_type)
- redis:del(key)
- local batch = pipeline(100)
- for rank, data in ipairs(list) do
- batch.add("hset", key, data.role.uid, cjson_encode(data))
- showlist[rank_type][rank] = common_fun.scopy(data)
- end
- batch.execute(redis,{})
- end
- end
- local function init()
- local conf = assert(option.redis)
- redis = redisdriver.connect(conf)
- redis:select(12)
- for rank_type= RANKING_ADV, RANKING_POWER do
- ranklist[rank_type] = {}
- local key = string.format(KEY_STR, rank_type)
- local retnuma = redis:hgetall(key)
- for k = 1, #retnuma, 2 do
- local data = cjson_decode(retnuma[k+1])
- ranklist[rank_type][#ranklist[rank_type]+1] = data
- end
- end
- end
- local function watchtime()
- skynet.fork(function()
- local interval = 60*2 -- 更新间隔为2分钟
- local up_time = os.time()
- while(true) do
- local now = os.time()
- if now > up_time then
- up_time = now + interval
- update()
- end
- skynet.sleep(300)
- end
- end)
- end
- local function find_uid(list, uid)
- for k, info in ipairs(list or {})do
- if info.role.uid == uid then
- return k, info
- end
- end
- end
- function CMD.player_rename(uid, name)
- for _, list in pairs(ranklist) do
- local _, info = find_uid(list, uid)
- if info then
- info.role.nickname = name
- end
- end
- end
- function CMD.update(rank_type, data)
- local key = string.format(KEY_STR, rank_type)
- ranklist[rank_type] = ranklist[rank_type] or {}
- local list = ranklist[rank_type]
- local k = find_uid(list, data.role.uid)
- if k then
- list[k] = data
- redis:hset(key, data.role.uid, cjson_encode(data))
- return
- end
- local show = showlist[rank_type] or {}
- if show[MAX_RANK] and show[MAX_RANK].num > data.num then
- return
- end
- list[#list+1] = data
- redis:hset(key, data.role.uid, cjson_encode(data))
- end
- function CMD.get_ranking(rank_type)
- return showlist[rank_type] or {}
- end
- -- 从排行榜中删除玩家
- function CMD.del(uid)
- for _, list in pairs(showlist) do
- local k = find_uid(list, uid)
- if k then
- table.remove(list, k)
- end
- end
- for rank_type, list in pairs(ranklist) do
- local key = string.format(KEY_STR, rank_type)
- local k = find_uid(list, uid)
- if k then
- table.remove(list, k)
- redis:hdel(key, uid)
- end
- end
- end
- function CMD.start()
- init()
- watchtime()
- end
- skynet.init(function()
- skynet.register(".rankinglist")
- end)
- skynet.start(function()
- skynet.dispatch("lua", function(session, _, cmd, ...)
- local f = assert(CMD[cmd])
- if 0==session then
- f(...)
- else
- skynet.retpack(f(...))
- end
- end)
- end)
|