robot.lua 4.85 KB
require "ProtocolCode"
require "shared.init"
require "utils.init"
skynet = require "skynet"
local socketdriver = require "skynet.socketdriver"
local netpack = require "skynet.netpack"
local xxtea = require "xxtea"
local httpc = require("http.httpc")
local config = require "robot_config"

local XXTEA_KEY = "699D448D6D24f7F941E9F6E99F823E18"

local CMD = {}
local client = {}
local eventListener = {}

local ignoreListener = {
	["Role.updateProperty"] = function(data)
		if not client.role then return end
		local msg = MsgPack.unpack(data)
		for _, one in pairs(msg) do
			client.role[one.key] = one.newValue
		end
	end,
	["Role.updateProperties"] = function(data)
		local msg = MsgPack.unpack(data)
		for field, value in pairs(msg) do
			client.role[field] = value
		end
	end,
	["Role.notifyNewEvent"] = true,
	["Role.chat"] = true,
	["Role.updateItems"] = true,
	["Gm.receiveResponse"] = true,
	["Role.changeUpdate"] = true,
	["Role.loadRunes"] = true,
	["Hero.loadInfos"] = true,
	["Store.updateproperty"] = true,
	["Sys.maintainNotice"] = true,
	["Hero.drawHeroExtraRewardNtf"] = true,
	["Sys.innerErrorMsg"] = function(data)
		local msg = MsgPack.unpack(data)
		log("innerErrorMsg: " .. msg.id)
	end,
}

function addListener(actionCode, callback, isKeep)
	callback = callback or function() end
	local handlerName = actionHandlers[actionCode]
	if string.sub(handlerName, -3, -1) == "Rpc" then
		actionCode = actionCode + rpcResponseBegin
	end
	if eventListener[actionHandlers[actionCode]] then
		log(handlerName .. " had listener")
	end
	local trueCall = callback
	if not isKeep then
		trueCall = function(data)
			removeListener(actionCode)
			callback(data)
		end
	end
	eventListener[actionHandlers[actionCode]] = trueCall
end

function removeListener(actionCode)
	local handlerName = actionHandlers[actionCode]
	if string.sub(handlerName, -3, -1) == "Rpc" then
		actionCode = actionCode + rpcResponseBegin
	end
	eventListener[actionHandlers[actionCode]] = nil
end

function triggerListener(listener, data)
	if eventListener[listener] then
		if #data > 0 then data = xxtea.decrypt(data, XXTEA_KEY) end
		eventListener[listener](data)
	elseif ignoreListener[listener] then
		if type(ignoreListener[listener]) == "function" then
			if #data > 0 then data = xxtea.decrypt(data, XXTEA_KEY) end
			ignoreListener[listener](data)
		end
	else
		-- log(listener .. " no handle!!!")
	end
end

function sendServer(actionCode, bin)
	local session = 0
	local handlerName = actionHandlers[actionCode]
	if actionCode == actionCodes.Role_queryLoginRpc or string.sub(handlerName, -3, -1) ~= "Rpc" then
		session = nil
	end
	
	local data = string.pack("H", actionCode)
	if session then
		data = data .. string.pack("H", session)
	end

	if #bin > 0 then bin = xxtea.encrypt(bin, XXTEA_KEY) end
	data = data .. bin

	socketdriver.send(client.fd, netpack.pack(data))
end

function requestServer(actionCode, bin, callback, isKeep)
	addListener(actionCode, callback, isKeep)
	sendServer(actionCode, bin)
end

local function heartBeat()
	sendServer(actionCodes.Sys_heartBeat, "")
	skynet.timeout(500, heartBeat)
end

local function startUnit(unit)
	if unit == "login" then
	else
		unit = math.randWeight(config.units, "weight")
	end

	local ok, unitTest = pcall(require, "unitTest." .. unit)
	if not ok then
		log("unitTest load error : " .. unitTest)
	end

	unitTest.new(client):startTest()
end


-- 登录成功开始任务
function CMD.task()
	heartBeat()
	-- 20 秒后开始执行任务 错开登录
	skynet.sleep(math.randomInt(2000, 3000))
	startUnit()
end

-- 开始登录
function CMD.start(fd, id)
	client.fd = fd
	client.clientId = id

	local uname = config.uname_prefix .. id
	client.uname = uname
	local status, body = httpc.get(config.http, "/login?" .. httpGetFormatData({token = uname, device = "test", channel = "develop"}))
	if tonumber(status) ~= 200 then
		log("http get error", uname, body)
		return
	end
	local servInfo = json.decode(body)
	client.uid = servInfo.userid
	
	startUnit("login")
end

-- 退出
function CMD.exit()
	sendServer(actionCodes.Gm_clientRequest,  MsgPack.pack({cmd = "gmmsg", pm1 = "123"}))
	skynet.sleep(50)
	skynet.ret(skynet.pack())
	skynet.exit()
end

skynet.register_protocol {
	name = "client",
	id = skynet.PTYPE_CLIENT,
	unpack = function (msg, sz)
		local data = skynet.tostring(msg, sz)
		local cmd = string.unpack("H", string.sub(data, 1, 2))
		return cmd, string.sub(data, 3)
	end,
	dispatch = function(session, address, cmd, data)
		local actionName = actionHandlers[cmd]
		if not actionName then
			log("actionName not exist", actionName)
			return
		end

		if cmd > rpcResponseBegin and actionName ~= "Role.queryLoginRpcResponse" then
			-- 回复 有session
			session = string.unpack("H", string.sub(data, 1, 2))
			data = string.sub(data, 3)
		end

		triggerListener(actionName, data)
	end,
}

skynet.start(function ()
	skynet.dispatch("lua", function (_,_,cmd,...)
		skynet.ret(skynet.pack(CMD[cmd](...)))
	end)
end)