You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

339 lines
11 KiB
Lua

local skynet = require "skynet"
local redishelper = require "redishelper"
local mongohelper = require "mongohelper"
local keysutils = require "keysutils"
local dateutils = require "dateutils"
local utils = require "utils"
local settings = require "settings"
local cjson = require "cjson"
local appname = settings.appname
local skynet_node_name = ...
require "skynet.manager"
local CMD = {}
local limit_cfg = {
[1]=50, --入门
[2]=50, --初级
[3]=100,--中级
[4]=100,--高级
[5]=200,--大师
[6]=999999999,--巅峰
}
local inc = 0
local workerId = settings.nodes[skynet_node_name].server_no
local function getint()
inc = inc + 1
local s = string.format("%d%06d",os.time(),inc)
return checkint(s)
end
local season = {}
--获取赛季配置
function CMD.getseasonconf()
if not season.end_time or season.end_time < os.time() then
season = mongohelper.findOne(settings.arena_season_key.tname, settings.arena_season_key.cname, {status=1})
end
return season
end
--获取赛季编号
function CMD.getseasonno()
local c = CMD.getseasonconf()
return chechint(c.version)
end
local user_group_scritps = [[
local id = redis.call('get', ARGV[1])
if not id then
id = redis.call('get', ARGV[2])
if not id then
id = redis.call('incr', ARGV[2])
redis.call('expire', ARGV[2], tonumber(ARGV[5]))
redis.call('set', ARGV[1], id, "ex", tonumber(ARGV[5]))
local k = ARGV[3]..":"..tostring(id)
redis.call('zadd', k, 0, ARGV[4])
else
local k = ARGV[3]..":"..tostring(id)
local n = redis.call('zcard', k) or 0
n = tonumber(n)
if n >= tonumber(ARGV[6]) then
id = redis.call('incr', ARGV[2])
redis.call('expire', ARGV[2], ARGV[5])
redis.call('set', ARGV[1], id, "ex", tonumber(ARGV[5]))
local k = ARGV[3]..":"..tostring(id)
redis.call('zadd', k, 0, ARGV[4])
redis.call('expire', k, ARGV[5])
else
redis.call('set', ARGV[1], id, "ex", ARGV[5])
local k = ARGV[3]..":"..tostring(id)
redis.call('zadd', k, 0, ARGV[4])
redis.call('expire', k, ARGV[5])
end
end
end
return id
]]
function CMD.getgroupid(uid)
local k = keysutils.arena_usergroup_key(appname, uid, dateutils.get_weekno())
return redishelper.exec("get", uid, k)
end
--进行分组
--用户ID 服 竞技场等级
function CMD.joingroup(uid, server, level, week)
week = week or dateutils.get_weekno()
local k1 = keysutils.arena_usergroup_key(appname, uid, week)
local k2 = keysutils.arena_groupid_key(appname, server, level, week)
local k3 = keysutils.arena_groupbase_key(appname, server, level, week)
local overtime = dateutils.oneweekend(os.time() + 7*86400)
local ex = overtime - os.time()
return redishelper.exec("eval", uid, user_group_scritps, 6, "k1", "k2", "k3", "uid", "ex", "limit", k1, k2, k3, uid, ex, limit_cfg[level])
end
local scritps = [[
local score = redis.call('zscore', ARGV[1], ARGV[2]) or 0
score = tonumber(score)
if score <= 0 or score < ARGV[3] then
redis.call('zincrby', ARGV[1], -score, ARGV[2])
else
redis.call('zincrby', ARGV[1], -ARGV[3], ARGV[2])
end
return "ok"
]]
local save_scritps = [[
local myscore = tonumber(ARGV[4])
if myscore > 0 then
redis.call("zincrby", ARGV[1], myscore, ARGV[2])
else
local score = redis.call('zscore', ARGV[1], ARGV[2]) or 0
score = tonumber(score)
if score > 0 then
if score <= 0 or score < -myscore then
redis.call('zincrby', ARGV[1], -score, ARGV[2])
else
redis.call('zincrby', ARGV[1], myscore, ARGV[2])
end
end
end
local youscore = tonumber(ARGV[5])
if youscore > 0 then
redis.call('zincrby', ARGV[1], youscore, ARGV[3])
else
local score = redis.call('zscore', ARGV[1], ARGV[3]) or 0
score = tonumber(score)
if score > 0 then
if score <= 0 or score < -youscore then
redis.call('zincrby', ARGV[1], -score, ARGV[3])
else
redis.call('zincrby', ARGV[1], youscore, ARGV[3])
end
end
end
return "ok"
]]
--保存积分
function CMD.savescore(uid, userid, server, level, myscore, youscore)
local groupid = CMD.joingroup(uid, server, level)
local k = keysutils.arena_group_key(appname, server, level, dateutils.get_weekno(), groupid)
local overtime = dateutils.oneweekend(os.time() + 7*86400)
local ex = overtime - os.time()
local ok = redishelper.exec("eval", uid, save_scritps, 5, "key", "my", "your", "myscore", "youscore", k, uid, userid, myscore, youscore)
return ok
end
local rank_scritps = [[
local score = redis.call('zscore', ARGV[1], ARGV[2])
local rank = redis.call('zrank', ARGV[1], ARGV[2])
return {score, rank}
]]
function CMD.loaduserscore(uid, server, level)
local groupid = CMD.joingroup(uid, server, level)
local k = keysutils.arena_group_key(appname, server, level, dateutils.get_weekno(), groupid)
return redishelper.exec("eval", uid, rank_scritps, 2, "key", "uid", k, uid)
end
function CMD.loadrank(uid, server, level)
local groupid = CMD.joingroup(uid, server, level)
if not groupid then
return nil
end
local k = keysutils.arena_group_key(appname, server, level, dateutils.get_weekno(), groupid)
local res = redishelper.exec("zrevrange", uid, k, 0, -1, "WITHSCORES")
return utils.redis_pack(res)
end
function CMD.loadlastweekrank(uid, server, level)
local groupid = CMD.joingroup(uid, server, level, dateutils.get_weekno() - 1)
if not groupid then
return {}
end
local k = keysutils.arena_group_key(appname, server, level, dateutils.get_weekno(), groupid)
local res = redishelper.exec("zrevrange", uid, k, 0, -1, "WITHSCORES")
return utils.redis_pack(res)
end
function CMD.loadrandmousers(uid, server, level, min, max, rank)
math.randomseed(tostring(os.time()):reverse():sub(1, 6))
local groupid = CMD.joingroup(uid, server, level)
local k = keysutils.arena_group_key(appname, server, level, dateutils.get_weekno(), groupid)
local res = redishelper.exec("zrevrangebyscore", uid, k, max, min, "WITHSCORES")
local list = utils.redis_pack(res)
local users = {}
for k,v in pairs(list) do
local userid = checkint(k)
if uid ~= userid then
table.insert(users, {uid=math.floor(k), score=math.floor(v)})
end
end
if #users > 0 then
for i=1, 7 do
users = table.shuffle(users)
end
end
if #users <= 0 then
if rank == 1 then
return users
end
local res = redishelper.exec("zrange", uid, k, rank-1, rank-1, "WITHSCORES")
local list = utils.redis_pack(res)
local users = {}
for k,v in pairs(list) do
local userid = checkint(k)
if uid ~= userid then
table.insert(users, {uid=math.floor(k), score=math.floor(v)})
end
end
return users
end
if #users <= 4 then
if #users > 0 then
local overtime = dateutils.oneweekend(os.time() + 7*86400)
local ex = overtime - os.time()
local k = keysutils.arena_match_backup_key(appname, uid)
redishelper.exec("set", uid, k, cjson.encode(users), "ex", ex)
end
return users
end
local s = math.random(1, #users - 4 + 1)
local users = table.slice(users, s, 4)
if #users > 0 then
local overtime = dateutils.oneweekend(os.time() + 7*86400)
local ex = overtime - os.time()
local k = keysutils.arena_match_backup_key(appname, uid)
redishelper.exec("set", uid, k, cjson.encode(users), "ex", ex)
end
return users
end
function CMD.loadbackupusers(uid, server, level, min, max, myrank)
local k = keysutils.arena_match_backup_key(appname, uid)
local result = redishelper.exec("get", uid, k)
local ok, users = pcall(cjson.decode, result)
if ok then
return users
end
return CMD.loadrandmousers(uid, server, level, min, max, myrank)
end
function CMD.getbattlenum(uid)
local k = keysutils.arena_battlenum_key(appname, uid, dateutils.getday())
return redishelper.exec("get", uid, k) or 0
end
local battlenum_scripts = [[
redis.call('incr', ARGV[1])
redis.call('expire', ARGV[1], tonumber(ARGV[2]))
return "ok"
]]
function CMD.incrbattlenum(uid)
local k = keysutils.arena_battlenum_key(appname, uid, dateutils.getday())
local overtime = dateutils.onedayover(os.time() + 86400)
local ex = overtime - os.time()
local ok = redishelper.exec("eval", uid, battlenum_scripts, 2, "key", "ex", k, ex)
return ok
end
--获取刷新次数
function CMD.getrefreshnum(uid)
local k = keysutils.arena_refreshnum_key(appname, uid)
return redishelper.exec("get", uid, k) or 0
end
function CMD.incrrefreshnum(uid)
local k = keysutils.arena_refreshnum_key(appname, uid)
return redishelper.exec("incr", uid, k)
end
function CMD.delrefreshnum(uid)
local k = keysutils.arena_refreshnum_key(appname, uid)
return redishelper.exec("del", uid, k)
end
function CMD.setdeflineup(uid, data)
local k = keysutils.arena_deflineup_key(appname, uid)
local overtime = dateutils.oneweekend(os.time() + 7*86400)
local ex = overtime - os.time()
return redishelper.exec("set", uid, k, data, "ex", ex)
end
function CMD.getdeflineup(uid)
local k = keysutils.arena_deflineup_key(appname, uid)
return redishelper.exec("get", uid, k) or {}
end
local score_scritps = [[
redis.call('hincrby', ARGV[1], KEYS[2], ARGV[2])
redis.call('expire', ARGV[1], ARGV[3])
return "ok"
]]
--获取赛季通行证购买是否购买
function CMD.getuserarenapass(uid)
return mongohelper.findOne(settings.user_arena_pass_key.tname, settings.user_arena_pass_key.cname, {uid=uid})
end
function CMD.buyarenapass(data)
return mongohelper.insert(settings.user_arena_pass_key.tname, settings.user_arena_pass_key.cname, data)
end
function CMD.incrarenapassscore(uid, score)
local sea = CMD.getseasonconf()
local ex = math.max(sea.end_time - os.time(), 0)
local k = keysutils.arena_pass_key(appname, sea.no, uid)
return redishelper.exec("eval", uid, score_scritps, 3, "key", "score", "ex", k, score, ex)
end
function CMD.getarenapass(uid)
local k = keysutils.arena_pass_key(appname, no, uid)
return redishelper.exec("hgetall", uid, k)
end
function CMD.saveearenapass(uid, data)
local k = keysutils.arena_pass_key(appname, no, uid)
return redishelper.exec("hmset", uid, k, data)
end
skynet.start(function()
skynet.dispatch("lua", function(_, _, command, ...)
DEBUG(" arenad cmd = ", command)
local f = assert(CMD[command])
skynet.retpack(f(...))
end)
skynet.register('.' .. SERVICE_NAME)
end)