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)