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
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)
|