local ipairs = ipairs local table = table local math = math local next = next local string = string local redisproxy = redisproxy local MsgPack = MsgPack local getRandomName = getRandomName local mcast_util = mcast_util local string_format = string.format local tonumber = tonumber local require = require local table_insert = table.insert local tconcat = table.concat local httpc = require("http.httpc") local WAVE_HERO_NUMS = 150 local WAVE_RUNE_NUMS = 150 local function validName(name) name = string.upper(name) local exist = redisproxy:exists(string_format("user:%s", name)) if exist then return "existed" end local SERV = string_format("NAMED%d", math.random(1, 5)) local legal = skynet.call(SERV, "lua", "check", name) return legal and "ok" or "illegal" end -- 随机玩家名 local function randomRoleName() -- 过滤已经存在的名字 local name repeat name = getRandomName() until validName(name) == "ok" return name end local function setRoleName(uid, roleId) local result local name local dbName repeat name = randomRoleName() dbName = string.upper(name) result = redisproxy:setnx(string_format("user:%s", dbName), roleId) until result == 1 redisproxy:set(string_format("uid:%s", uid), dbName) return name end local _M = {} function _M.loginRpc( agent, data ) local msg = MsgPack.unpack(data) local response = {} -- if msg.version ~= globalCsv.version then -- response.result = "UPDATE_TIP" -- SendPacket(actionCodes.Role_loginRpc, MsgPack.pack(response)) -- return true -- end -- 1. local roleId = redisproxy:get(string_format("user:%s", string.upper(msg.name))) if not roleId then response.result = "NOT_EXIST" SendPacket(actionCodes.Role_loginRpc, MsgPack.pack(response)) return true end roleId = tonumber(roleId) --维护不能登录 local maintain = tonumber(redisproxy:hget("autoincrement_set", "maintain")) if maintain and maintain > 0 then if tonumber(redisproxy:hget(string_format("role:%d", roleId), "ignoreMt")) ~= 1 then response.result = "MAINTAIN_TIP" SendPacket(actionCodes.Role_loginRpc, MsgPack.pack(response)) return true end end local now = skynet.timex() local role = agent.role -- 2 if not role then local roleKey = string_format("role:%d", roleId) if not redisproxy:exists(roleKey) then response.result = "DB_ERROR" SendPacket(actionCodes.Role_loginRpc, MsgPack.pack(response)) return true end -- 2a role = require("models.Role").new({key = roleKey}) role:load() role:loadAll() else role:reloadWhenLogin() end if not msg.isGMlogin then local banTime = role:getProperty("banTime") if banTime > now then response.result = "BAN_TIP" response.banTime = banTime response.banType = role:getProperty("banType") response.roleId = roleId SendPacket(actionCodes.Role_loginRpc, MsgPack.pack(response)) return true end if banTime ~= 0 then -- 清除封号状态 role:setBan(0) end end SERV_OPEN = redisproxy:hget("autoincrement_set", "server_start") role:changeStructVersion() -- 数据结构 版本更新 -- 跨天登陆事件 role:onCrossDay(now) role:setProperty("ltime", now) for _, name in ipairs({"dailyData", "dinerData"}) do response[name] = role[name]:data() end response.role = role:data() response.result = "SUCCESS" response.serverTime = now local modules = {} local heroIds = {} for heroId, _ in pairs(role.heros) do table.insert(heroIds, heroId) end local heroWave = math.ceil(#heroIds / WAVE_HERO_NUMS) if #heroIds <= 50 then heroWave = 0 table_insert(modules, "heros") end local runeIds = {} for id ,_ in pairs(role.runeBag) do table.insert(runeIds, id) end local runeWave = math.ceil(#runeIds / WAVE_RUNE_NUMS) if #runeIds <= 50 then runeWave = 0 table_insert(modules, "runeBag") end for _, name in ipairs(modules) do response[name] = {} for id, unit in pairs(role[name]) do response[name][id] = unit:data() end end response.wave = 1 + heroWave + runeWave SendPacket(actionCodes.Role_loginRpc, MsgPack.pack(response)) local curWave = 1 local runeIndex = 1 for index = curWave + 1, curWave + runeWave do local runeResponse = {runeBag = {}} for i = runeIndex, runeIndex + WAVE_RUNE_NUMS do local runeId = runeIds[i] if not runeId then break end local rune = role.runeBag[runeId] table.insert(runeResponse.runeBag, rune:data()) runeIndex = runeIndex + 1 end runeResponse.runeWave = index SendPacket(actionCodes.Role_loginRpc, MsgPack.pack(runeResponse)) end curWave = curWave + runeWave local heroIndex = 1 for index = curWave + 1, curWave + heroWave do local heroResponse = {heros = {}} for i = heroIndex, heroIndex + WAVE_HERO_NUMS do local heroId = heroIds[i] if not heroId then break end local hero = role.heros[heroId] table_insert(heroResponse.heros, hero:data()) heroIndex = heroIndex + 1 end heroResponse.heroWave = index SendPacket(actionCodes.Role_loginRpc, MsgPack.pack(heroResponse)) end curWave = curWave + heroWave -- role:log("login", { ip = agent.ip, diamond = role:getProperty("diamond"), reDiamond = role:getProperty("reDiamond")}) datacenter.set("agent", roleId, { serv = skynet.self(), fd = agent.client_fd, gate_serv = agent.gate_serv, }) agent.role = role start_agent_timer() -- 注册全服广播 local channel = math.randomInt(1, 1) local w_channel = datacenter.get( ("MC_W_CHANNEL" .. channel) ) if w_channel then mcast_util.sub_world(w_channel) end return true end function _M.createRpc(agent, data) local msg = MsgPack.unpack(data) local response = {} -- 再次检查uid local uid = tostring(msg.uid) local user = redisproxy:get(string_format("uid:%s", uid)) if user then response.result = "SUCCESS" response.roleName = user SendPacket(actionCodes.Role_createRpc, MsgPack.pack(response)) return true end local roleId = getNextRoleId() if not roleId then response.result = "DB_FULL" SendPacket(actionCodes.Role_createRpc, MsgPack.pack(response)) return true end local roleName = setRoleName(msg.uid, roleId) local newRole = require("models.Role").new({ key = string_format("role:%d", roleId), id = roleId, uid = tostring(msg.uid), subId = msg.subId or 0, name = roleName, uname = msg.uname or "", device = tostring(msg.device) }) if newRole:create() then --更新USER表 response.result = "SUCCESS" response.roleId = roleId response.roleName = string.upper(roleName) else response.result = "DB_ERROR" SendPacket(actionCodes.Role_createRpc, MsgPack.pack(response)) return true end -- 欢迎邮件 -- redisproxy:insertEmail({roleId = roleId, emailId = 1}) -- redisproxy:insertEmail({roleId = roleId, emailId = 2}) newRole:log("create", { ip = agent.ip, ucode = ucode}) SendPacket(actionCodes.Role_createRpc, MsgPack.pack(response)) return true end function _M.syncTimeRpc(agent, data) SendPacket(actionCodes.Role_syncTimeRpc, MsgPack.pack({nowTime = skynet.timex()})) return true end function _M.saleItemRpc(agent, data) local role = agent.role local msg = MsgPack.unpack(data) local backs = msg.backs if not backs then return end local reward = {} for itemId, count in pairs(backs) do if math.illegalNum(count, 1, role:getItemCount(itemId)) then return end local itemData = csvdb["itemCsv"][itemId] if itemData.sell_effect == "" then return end local sellEffect = itemData.sell_effect:toArray(true, "=") reward[sellEffect[1]] = (reward[sellEffect[1]] or 0) + sellEffect[2] * count end role:costItems(backs) local reward = role:award(reward) SendPacket(actionCodes.Role_saleItemRpc, MsgPack.pack({reward = reward})) return true end function _M.openItemRpc(agent, data) local role = agent.role local msg = MsgPack.unpack(data) local itemId = msg.itemId local count = msg.count if math.illegalNum(count, 1, role:getItemCount(itemId)) then return end local itemData = csvdb["itemCsv"][itemId] if itemData.use_type ~= 2 then return end local randomData = csvdb["item_randomCsv"][tonumber(itemData.use_effect)] if not randomData then return end local reward = randomData.gift:toNumMap() for _id, _count in pairs(reward) do reward[_id] = _count * count end if randomData.random_num > 0 and randomData.random_gift ~= "" then for i = 1, count do local pool = {} for _, temp in ipairs(randomData.random_gift:toArray()) do table.insert(pool, temp:toArray(true, "=")) end local needCount = math.min(#pool, randomData.random_num) for j = 1, needCount do local idx = math.randWeight(pool, 3) reward[pool[idx][1]] = (reward[pool[idx][1]] or 0) + pool[idx][2] table.remove(pool, idx) end end end role:costItems({[itemId] = count}) reward = role:award(reward) SendPacket(actionCodes.Role_openItemRpc, MsgPack.pack({reward = reward})) return true end function _M.storyBookRewardRpc(agent, data) local role = agent.role local msg = MsgPack.unpack(data) local storyId = msg.id local storyBookData = csvdb["story_bookCsv"][storyId] if not storyBookData then return end local storyStatus = role:getProperty("storyB") if not storyStatus[storyId] or not storyStatus[storyId].s or storyStatus[storyId].s ~= 1 then return end -- 获取奖励 storyStatus[storyId].s = -1 role:changeUpdates({{ type = "storyB", field = storyId, value = storyStatus[storyId] }}) local reward = role:award(storyBookData.gift) SendPacket(actionCodes.Role_storyBookRewardRpc, MsgPack.pack({reward = reward})) return true end function _M.unLockStoryBookRpc(agent, data) local role = agent.role local msg = MsgPack.unpack(data) local storyId = msg.id local storyBookData = csvdb["story_bookCsv"][storyId] if not storyBookData or storyBookData.lockItem == "" then return end -- 不能解锁 local storyStatus = role:getProperty("storyB") if storyStatus[storyId] and storyStatus[storyId].s then return end --不需要解锁 local cost = storyBookData.lockItem:toNumMap() if not cost or not next(cost) then return end if not role:checkItemEnough(cost) then return end -- 消耗品不足 role:costItems(cost) -- 解锁 storyStatus[storyId] = storyStatus[storyId] or {} table.clear(storyStatus[storyId]) storyStatus[storyId].s = 1 role:changeUpdates({{ type = "storyB", field = storyId, value = storyStatus[storyId] }}) SendPacket(actionCodes.Role_unLockStoryBookRpc, '') return true end return _M