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.
441 lines
13 KiB
Lua
441 lines
13 KiB
Lua
local skynet = require "skynet"
|
|
local socket = require "skynet.socket"
|
|
local cjson = require "cjson"
|
|
local datacenter = require "skynet.datacenter"
|
|
local config = require "config"
|
|
local msgutils = require "msgutils"
|
|
local dateutils = require "dateutils"
|
|
local mc = require "skynet.multicast"
|
|
local netpack = require "websocketnetpack"
|
|
local usermodel = require "usermodel"
|
|
local bagmodel = require "bagmodel"
|
|
local heromodel = require "heromodel"
|
|
local coingetmodel = require "coingetmodel"
|
|
local dailydealmodel = require "dailydealmodel"
|
|
local fundmodel = require "fundmodel"
|
|
local fukamodel = require "fukamodel"
|
|
local daybuymodel = require "daybuymodel"
|
|
local huobamodel = require "huobamodel"
|
|
local signinmodel = require "signinmodel"
|
|
local limitshopmodel = require "limitshopmodel"
|
|
local friendmodel = require "friendmodel"
|
|
local achievementmodel = require "achievementmodel"
|
|
local baoxiangmodel = require "baoxiangmodel"
|
|
local zhaomumodel = require "zhaomumodel"
|
|
local duanwumodel = require "duanwumodel"
|
|
local clubmodel = require "clubmodel"
|
|
local msgmodel = require "msgmodel"
|
|
local arenamodel = require "arenamodel"
|
|
local mailmodel = require "mailmodel"
|
|
local guajimodel = require "guajimodel"
|
|
local shoplogic = require "shoplogic"
|
|
local fukalogic = require "fukalogic"
|
|
local shoplimitlogic = require "shoplimitlogic"
|
|
local guajilogic = require "guajilogic"
|
|
|
|
require "functions"
|
|
|
|
local myid = ...
|
|
|
|
DEBUG("agent myid = ", myid)
|
|
|
|
local WATCHDOG
|
|
local gate
|
|
local CMD = {}
|
|
local uid
|
|
local client_fd
|
|
|
|
local runfork = true
|
|
local idletime
|
|
local lastcgtime
|
|
|
|
local counter = 0
|
|
|
|
local channels = {}
|
|
|
|
local funcs={}
|
|
|
|
local func_checker = {}
|
|
|
|
local handlers = {
|
|
"game.cmd.user",
|
|
"game.cmd.eqp",
|
|
"game.cmd.activity",
|
|
"game.cmd.room",
|
|
"game.cmd.friend",
|
|
"game.cmd.club",
|
|
"game.cmd.tower",
|
|
"game.cmd.boss",
|
|
"game.cmd.shop",
|
|
"game.cmd.mail",
|
|
"game.cmd.arena",
|
|
}
|
|
|
|
|
|
|
|
local function send_package(pack)
|
|
|
|
if not client_fd then
|
|
return
|
|
end
|
|
|
|
local data = pack.data or {}
|
|
data.errcode = data.errcode or 0
|
|
if data and data.errcode and data.errcode>0 and not data.errmsg then
|
|
data.errmsg = config.get("errmsg",string.format("e%d",data.errcode))
|
|
end
|
|
data.curtime = os.time()
|
|
data.msec = skynet.time()*1000
|
|
local ok, pack = msgutils.encode(pack)
|
|
if not ok then
|
|
error("agent send_package encode fail")
|
|
end
|
|
DEBUG("<=========== agent发送消息 to client :", pack)
|
|
local ok = socket.write(client_fd,netpack.pack(pack))
|
|
-- DEBUG("socket write ok = ", ok)
|
|
end
|
|
|
|
local sendmsgpack = function(pkg)
|
|
local box = pkg.box
|
|
-- skynet.error("uid ---------->", UID, " box ---------->", cjson.encode(box))
|
|
if box ~= nil then
|
|
if box.c=="msg" then
|
|
if box.m=="clubmsg" then
|
|
msgmodel.clubindex = box.data.data.msg.id
|
|
send_package(box)
|
|
elseif box.m == "mailmsg" then
|
|
msgmodel.mailindex = box.data.data.msg.id
|
|
mailmodel:newmail(box.data.data.msg)
|
|
send_package(box)
|
|
elseif box.m == "recruitmsg" then
|
|
msgmodel.recruitindex = box.data.data.msg.id
|
|
send_package(box)
|
|
elseif box.m == "arenamsg" then
|
|
msgmodel.arenaindex = box.data.data.msg.id
|
|
send_package(box)
|
|
elseif box.m == "friendapply" then
|
|
send_package(box)
|
|
elseif box.m == "applyagree" then
|
|
friendmodel:inneraddfriend(box.data.data.user)
|
|
send_package(box)
|
|
elseif box.m == "givecoin" then
|
|
friendmodel:innergivecoin(box.data.data.msg.uid, box.data.data.msg.coin)
|
|
send_package(box)
|
|
elseif box.m == "friendmsg" then
|
|
msgmodel.friendindex = box.data.data.msg.id
|
|
send_package(box)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
local registerHandler = function ()
|
|
for _, v in ipairs(handlers) do
|
|
local handler = require(v)
|
|
if handler then
|
|
for k, func in pairs(handler) do
|
|
if type(func) == 'function' and not string.startwith(k, "_") then
|
|
local splits = string.split(v, ".")
|
|
local funname = string.format("on_%s_%s", splits[#splits], k)
|
|
funcs[funname] = func
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
skynet.register_protocol {
|
|
name = "client",
|
|
id = skynet.PTYPE_CLIENT,
|
|
unpack = function (msg, sz)
|
|
local a= skynet.tostring(msg,sz)
|
|
-- return funpack(a)
|
|
return a
|
|
end,
|
|
dispatch = function (fd, _, msg)
|
|
skynet.ignoreret()
|
|
local ok, cmd = msgutils.decode(msg)
|
|
skynet.error("agent recv new msg ===>", cjson.encode(cmd))
|
|
if ok then
|
|
idletime = os.time()
|
|
|
|
local c = cmd.c
|
|
local m = cmd.m
|
|
|
|
local fname = string.format("on_%s_%s",tostring(c),tostring(m))
|
|
local curmsec = skynet.time() * 1000
|
|
-- DEBUG("curmsec = ", curmsec)
|
|
-- DEBUG("func_checker fname = ", fname, " curmsec ", func_checker[fname], " uid = ", UID)
|
|
if func_checker[fname] and curmsec - func_checker[fname] < 200 then
|
|
local resp = {}
|
|
resp.c = c
|
|
resp.m = m
|
|
local data = {}
|
|
data.errcode = 10000
|
|
data.errmsg = "对不起! 太快了~~~"
|
|
data.data = {}
|
|
resp.data = data
|
|
-- WARN(" cmd result = ", cjson.encode(resp))
|
|
send_package(resp)
|
|
return
|
|
end
|
|
func_checker[fname] = curmsec
|
|
local f = funcs[fname]
|
|
if f then
|
|
if not cmd.data.curtime or os.time()+1 < cmd.data.curtime then
|
|
WARN("Timestamp verification failed")
|
|
counter = counter + 1
|
|
if counter >= 3 then
|
|
local resp = {}
|
|
resp.c = "user"
|
|
resp.m = "logout"
|
|
local data = {}
|
|
data.errcode = 10000
|
|
data.errmsg = "对不起! 检测到您的数据异常了~~~"
|
|
data.data = {}
|
|
resp.data = data
|
|
send_package(resp)
|
|
return
|
|
end
|
|
local resp = {}
|
|
resp.c = c
|
|
resp.m = m
|
|
local data = {}
|
|
data.errcode = 10000
|
|
data.errmsg = "对不起! 检测到您的数据异常了~~~"
|
|
data.data = {}
|
|
resp.data = data
|
|
-- WARN(" cmd result = ", cjson.encode(resp))
|
|
send_package(resp)
|
|
return
|
|
end
|
|
cmd.data.agent = skynet.self()
|
|
local result = f(cmd)
|
|
-- WARN(" cmd result = ", cjson.encode(result))
|
|
if result then
|
|
send_package(result)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
}
|
|
|
|
|
|
|
|
--加入消息中心
|
|
local function join_msg_center()
|
|
pcall(skynet.call, ".msgd", "lua", "come", UID)
|
|
-- 挂接钩子
|
|
skynet.fork(function()
|
|
while runfork do
|
|
local ok, resp = pcall(skynet.call, ".msgd", "lua", "get", UID, msgmodel:serialize(), clubmodel:getclubid() or 0, usermodel:getserverid(), arenamodel:calcurserverid(), usermodel:getBaiFuServer())
|
|
if ok then
|
|
sendmsgpack(resp)
|
|
end
|
|
skynet.sleep(100)
|
|
end
|
|
end)
|
|
JOIN_SUCCESS = true
|
|
end
|
|
|
|
local exit_msg_center = function()
|
|
if not UID then
|
|
return
|
|
end
|
|
pcall(skynet.call, ".msgd", "lua", "bye", UID)
|
|
end
|
|
|
|
local function init()
|
|
local ok = pcall(skynet.call, ".ordermqd", "lua", "online", UID, skynet.self())
|
|
end
|
|
|
|
local function login()
|
|
runfork = true
|
|
local ok, account_status, first_login = pcall(skynet.call, ".usercenterd", "lua", "login", UID)
|
|
assert(ok, "login fail")
|
|
assert(checkint(account_status) == 0, "该账号已冻结")
|
|
if first_login then
|
|
local ok = pcall(skynet.call, ".signind", "lua", "login", UID)
|
|
local ok = pcall(skynet.call, ".taskd", "lua", "login", UID)
|
|
end
|
|
if usermodel._init then
|
|
usermodel:login()
|
|
end
|
|
send_package({ c = "user", m = "login", data = { errcode = 0, data = {} } })
|
|
end
|
|
|
|
--领取每日福利
|
|
local function receiverdaywelfare()
|
|
local ok = pcall(skynet.call, ".maild", "lua", "newusermail", UID)
|
|
-- local ok = pcall(skynet.call, ".maild", "lua", "senddaywelfaremail", UID)
|
|
end
|
|
|
|
local function autokick(t)
|
|
skynet.fork(function()
|
|
while runfork do
|
|
DEBUG("autokick ", t)
|
|
if os.time() - idletime > 60 then
|
|
pcall(skynet.send,WATCHDOG,"lua","close",client_fd)
|
|
break
|
|
end
|
|
if not lastcgtime or os.time() - lastcgtime > 5*60 then
|
|
collectgarbage()
|
|
end
|
|
skynet.sleep(15*100)
|
|
end
|
|
end)
|
|
end
|
|
|
|
function CMD.start(conf)
|
|
|
|
DEBUG("agent start conf = ", cjson.encode(conf))
|
|
|
|
local fd = conf.client
|
|
gate = conf.gate
|
|
WATCHDOG = conf.watchdog
|
|
client_fd = fd
|
|
CLIENT_FD = client_fd
|
|
|
|
UID = math.floor(conf.uid)
|
|
skynet.call(gate, "lua", "forward", fd)
|
|
registerHandler()
|
|
init()
|
|
login()
|
|
receiverdaywelfare()
|
|
idletime = os.time()
|
|
--是否开启心跳检查
|
|
autokick("start")
|
|
counter = 0
|
|
return "ok"
|
|
end
|
|
|
|
--重连
|
|
function CMD.reconnect(fd)
|
|
-- skynet.error("agent reconnect fd ------>", fd)
|
|
client_fd = fd
|
|
CLIENT_FD = client_fd
|
|
skynet.error("server agent forward")
|
|
skynet.call(gate, "lua", "forward", fd)
|
|
login()
|
|
receiverdaywelfare()
|
|
idletime = os.time()
|
|
autokick("reconnect")
|
|
counter = 0
|
|
return "ok"
|
|
end
|
|
|
|
|
|
function CMD.join_msg_center()
|
|
join_msg_center()
|
|
return "ok"
|
|
end
|
|
|
|
function CMD.recharge_callback(order_no)
|
|
local ok, order = pcall(skynet.call, ".orderd", "lua", "get", order_no)
|
|
-- INFO("recharge_callback ok = ", ok ," order = ", inspect(order))
|
|
if order.pay_type == "goldshop" then
|
|
local conf = shoplogic.getconf(order.recharge_id)
|
|
bagmodel:incrBagA("gold", checkint(conf.gold) + checkint(conf.give_gold))
|
|
elseif order.pay_type == "buyguajitime" then ---购买挂机时长
|
|
local cfg = guajilogic.getguajishichangconf(order.recharge_id)
|
|
guajimodel:setbasetime(cfg.time)
|
|
elseif order.pay_type == "firstrecharge" then --首冲
|
|
elseif order.pay_type == "buydailydeal" then ---购买特惠礼包
|
|
dailydealmodel:buydailydeal(order.recharge_id)
|
|
elseif order.pay_type == "buyfund" then ---购买基金
|
|
fundmodel:buyfund(order.recharge_id)
|
|
elseif order.pay_type == "buyfuka" then ---购买福卡
|
|
fukamodel:buyfuka(order.recharge_id)
|
|
local cfg = fukalogic.getconfbyid(order.recharge_id)
|
|
local rewards = cfg.buy_reward
|
|
for i,v in ipairs(rewards) do
|
|
bagmodel:incrBagA(v.key, v.value)
|
|
end
|
|
elseif order.pay_type == "buylimitshop" then ---购买限购商品
|
|
local cfg = shoplimitlogic.getconfbyid(checkint(order.recharge_id))
|
|
local rewards = cfg.reward
|
|
for i,v in ipairs(rewards) do
|
|
bagmodel:incrBagA(v.key, v.value)
|
|
end
|
|
limitshopmodel:buy(order.recharge_id)
|
|
elseif order.pay_type == "buybaoxiang" then ---购买宝箱商城
|
|
baoxiangmodel:buy(order.recharge_id)
|
|
elseif order.pay_type == "buyzhaomu" then ---购买招募商城
|
|
zhaomumodel:buy(order.recharge_id)
|
|
elseif order.pay_type == "buyduanwu" then ---购买端午限购
|
|
if duanwumodel._init then
|
|
duanwumodel:buy(order.recharge_id)
|
|
duanwumodel:incrscore(checkint(order.payment))
|
|
end
|
|
end
|
|
--TODO: 获取积天好礼 累计充值天数
|
|
usermodel:incrrechargetotal(checkint(order.payment)) --vip 充值金额增加
|
|
achievementmodel:emit("recharge", achievementmodel)
|
|
daybuymodel:add(order.payment)
|
|
local ok, ret = pcall(skynet.call, ".orderd", "lua", "complete", order_no)
|
|
send_package({ c = "user", m = "recharge_callback", data = { errcode = 0, errmsg = "充值成功", data = {} } })
|
|
return "ok"
|
|
end
|
|
|
|
|
|
local function logout()
|
|
if huobamodel._init then
|
|
huobamodel:save()
|
|
end
|
|
usermodel:logout()
|
|
end
|
|
|
|
|
|
function CMD.disconnect()
|
|
skynet.error("disconnect close------>")
|
|
runfork=false
|
|
JOIN_SUCCESS=false
|
|
logout()
|
|
exit_msg_center()
|
|
skynet.call(WATCHDOG, "lua", "close", client_fd)
|
|
return "ok"
|
|
end
|
|
|
|
local function exit()
|
|
local ok = pcall(skynet.call, ".ordermqd", "lua", "offline", UID)
|
|
usermodel:saveall()
|
|
heromodel:saveall()
|
|
end
|
|
|
|
function CMD.exit()
|
|
skynet.error("agent exit------->")
|
|
runfork=false
|
|
JOIN_SUCCESS=false
|
|
exit()
|
|
skynet.exit()
|
|
return 'ok'
|
|
end
|
|
|
|
function CMD.nativesend(cmd)
|
|
--skynet.error('nativesend--------->', cjson.encode(cmd))
|
|
|
|
local c = cmd.c
|
|
local m = cmd.m
|
|
|
|
send_package(cmd)
|
|
|
|
return "ok"
|
|
end
|
|
|
|
|
|
skynet.start(function()
|
|
|
|
skynet.dispatch("lua", function(_,_, command, ...)
|
|
-- skynet.trace()
|
|
--skynet.error("game agent command = ", command)
|
|
local f = CMD[command]
|
|
|
|
local ret = f(...)
|
|
|
|
if ret then
|
|
skynet.ret(skynet.pack(ret))
|
|
end
|
|
end)
|
|
end)
|