From 6136eacad7d37a699e3994647f94751fa227421d Mon Sep 17 00:00:00 2001 From: liuzujun <307836273@qq.com> Date: Fri, 12 Mar 2021 16:35:59 +0800 Subject: [PATCH] 添加好友表 --- run.sh | 4 ++-- src/actions/ActivityAction.lua | 18 +++--------------- src/actions/EmailAction.lua | 6 +++--- src/actions/FriendAction.lua | 128 ++++++++++++++++++++++++++++++++++++++++++++++++++------------------------------------------------------------------------------ src/actions/RoleAction.lua | 18 ++++++++---------- src/models/Activity.lua | 8 +------- src/models/Diner.lua | 8 ++++---- src/models/Friend.lua | 15 +++++++++++++++ src/models/Role.lua | 1 + src/models/RoleCross.lua | 43 +++++++++++++++++++++++++++---------------- src/models/RolePlugin.lua | 35 +++++++++++++++++++++++++++++------ src/services/dbseed.lua | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- src/services/globald.lua | 2 ++ src/services/mysqld.lua | 2 ++ src/shared/ModelBaseMysql.lua | 111 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------- src/utils/MysqlUtil.lua | 38 ++++++++++++++++++++++++++++++++++++++ 16 files changed, 351 insertions(+), 163 deletions(-) create mode 100644 src/models/Friend.lua diff --git a/run.sh b/run.sh index 6388c3d..274d4f7 100755 --- a/run.sh +++ b/run.sh @@ -10,10 +10,10 @@ fi pid=`cat skynet.pid` run=`ps aux | grep skynet | grep -v grep | grep -c $pid` -if [ $run = 1 ]; then +if [[ $run = 1 ]]; then echo "服务端正在运行" exit 0 fi skynet/skynet config/${config}.lua -echo "服务端启动完毕" \ No newline at end of file +echo "服务端启动完毕" diff --git a/src/actions/ActivityAction.lua b/src/actions/ActivityAction.lua index 0fd631e..8384726 100644 --- a/src/actions/ActivityAction.lua +++ b/src/actions/ActivityAction.lua @@ -1006,16 +1006,6 @@ function _M.friendHelpRpc(agent, data) local actData = role.activity:getActData("FriendEnergy") or {} - local function getIds() - local ids = {} - local friends = redisproxy:hgetall(FRIEND_KEY:format(roleId)) - for i = 1, #friends , 2 do - local objId = tonumber(friends[i]) - ids[objId] = 1 - end - return ids - end - if oper == 1 then -- 赠送好友能量 local giveAE = actData.giveAE or {} local objId = msg.roleId @@ -1025,7 +1015,7 @@ function _M.friendHelpRpc(agent, data) if not objId then return 3 end - if not redisproxy:hexists(FRIEND_KEY:format(roleId), objId) then + if not role.friends[objId] then result = 2 end if giveAE[objId] then @@ -1071,7 +1061,6 @@ function _M.friendHelpRpc(agent, data) local gift2 = gifts[2] local limit = actData.limit or 0 local cmd1, cmd2 = 0, 0 - local ids = getIds() local members = {} local temp = redisproxy:smembers(FRIEND_ENERGY:format(roleId)) @@ -1080,7 +1069,7 @@ function _M.friendHelpRpc(agent, data) end redisproxy:pipelining(function(red) - for friendId, _ in pairs(ids) do + for friendId, _ in pairs(role.friends) do if not giveAE[friendId] then giveAE[friendId] = 1 award[gift1[1]] = (award[gift1[1]] or 0) + gift1[2] @@ -1146,13 +1135,12 @@ function _M.friendHelpRpc(agent, data) local ids = {} local members = {} - local friendIds = getIds() local temp = redisproxy:smembers(FRIEND_ENERGY:format(roleId)) for _, id in pairs(temp) do members[tonumber(id)] = 1 end - for id, _ in pairs(friendIds) do + for id, _ in pairs(role.friends) do if members[id] then ids[id] = 1 end diff --git a/src/actions/EmailAction.lua b/src/actions/EmailAction.lua index ada7613..262963e 100644 --- a/src/actions/EmailAction.lua +++ b/src/actions/EmailAction.lua @@ -111,7 +111,7 @@ function _M.drawAllAttachRpc(agent, data) for _, email in ipairs(emails) do local attachments = getEmailAttachments(email) if attachments ~= "" then - email:setProperty("status", 2) + email:setProperty("status", 2, true) email:log(role, 2) ids[email:getProperty("id")] = 1 for key, v in pairs(attachments:toNumMap()) do @@ -139,7 +139,7 @@ function _M.drawAttachRpc(agent, data) if attachments == "" then return end local reward, change = role:award(attachments, {log = {desc = "draw_attach", int1 = id}}) - email:setProperty("status", 2) + email:setProperty("status", 2, true) email:log(role, 2) SendPacket(actionCodes.Email_drawAttachRpc, MsgPack.pack({reward = reward, change = change})) role:mylog("mail_action", {desc = "draw_attach", int1 = id, key1 = email:getProperty("title"), key2 = attachments}) @@ -156,7 +156,7 @@ function _M.checkRpc(agent, data) local email = require("models.Email").new({key = string.format("%d", id), id = id}) if not email:load() then return end - email:setProperty("status", 1) + email:setProperty("status", 1, true) email:log(role, 1) role:mylog("mail_action", {desc = "check_mail", int1 = id}) diff --git a/src/actions/FriendAction.lua b/src/actions/FriendAction.lua index 9666706..deab659 100644 --- a/src/actions/FriendAction.lua +++ b/src/actions/FriendAction.lua @@ -11,6 +11,7 @@ local table_unpack = table.unpack local table_find = table.find local table_nums = table.nums local math_random = math.randomInt +require "utils.MysqlUtil" local _M = {} @@ -23,12 +24,6 @@ local function formatArray(tb) return t end -local function checkFriendLimit(roleId) - roleId = tonumber(roleId) - local count = redisproxy:hlen(FRIEND_KEY:format(roleId)) - return count < globalCsv.friendListLimit -end - local function addAndCheckApplyLimit(roleId, objId) roleId = tonumber(roleId) @@ -78,7 +73,7 @@ function _M.searchRpc(agent, data) local objIds = {} local tempId = tonumber(key) if tempId then - if redisproxy:exists(string_format("role:%d", tempId)) then + if roleExists(tempId) then objIds[tempId] = 1 end end @@ -92,13 +87,13 @@ function _M.searchRpc(agent, data) for objId, _ in pairs(objIds) do local online, info = getRoleInfo(objId) local redret = redisproxy:pipelining(function (red) - red:hexists(FRIEND_KEY:format(roleId), objId) red:zscore(FRIEND_APPLY_KEY:format(objId), roleId) red:sismember(FRIEND_BLACK_KEY:format(roleId), objId) end) - local isFriend = redret[1] == 1 and 1 or nil - local hadApply = redret[2] and 1 or nil - local inBlack = redret[3] == 1 and 1 or nil + + local isFriend = role.friends[objId] and 1 or nil + local hadApply = redret[1] and 1 or nil + local inBlack = redret[2] == 1 and 1 or nil table.insert(searchList, table_merge({ roleId = objId, @@ -123,6 +118,7 @@ function _M.applyRpc(agent, data) local msg = MsgPack.unpack(data) local objectId = msg.roleId + dump(msg) if objectId == roleId then return @@ -130,44 +126,41 @@ function _M.applyRpc(agent, data) local result = nil local redret = redisproxy:pipelining(function (red) - red:exists(string_format("role:%d", objectId)) - red:hexists(FRIEND_KEY:format(roleId), objectId) red:zscore(FRIEND_APPLY_KEY:format(objectId), roleId) red:sismember(FRIEND_BLACK_KEY:format(objectId), roleId) red:sismember(FRIEND_BLACK_KEY:format(roleId), objectId) - red:hlen(FRIEND_KEY:format(roleId)) - red:hlen(FRIEND_KEY:format(objectId)) end) + dump(redret) -- 玩家id不存在 - if not result and redret[1] ~= 1 then + if not result and not roleExists(objectId) then result = 1 end -- 已经有这个好友 - if not result and redret[2] == 1 then + if not result and role.friends[objectId] then result = 2 end -- 已经申请 - if not result and redret[3] then + if not result and redret[1] then result = 3 end -- 对方把你拉黑 - if not result and redret[4] == 1 then + if not result and redret[2] == 1 then result = 4 end -- 你把对方拉黑了 - if not result and redret[5] == 1 then + if not result and redret[3] == 1 then result = 5 end -- 自己好友已经满 - if not result and redret[6] >= globalCsv.friendListLimit then + if not result and table.numbers(role.friends) >= globalCsv.friendListLimit then result = 6 end -- 对方的好友已满 - if not result and redret[7] >= globalCsv.friendListLimit then + if not result and getFriendCount(objectId) >= globalCsv.friendListLimit then result = 7 end @@ -209,29 +202,28 @@ function _M.applyListRpc(agent, data) return true end -local function checkHandleApply(roleId, objectId, needAddNew) +local function checkHandleApply(role, objectId, needAddNew) needAddNew = needAddNew or 0 + local roleId = role:getProperty("id") local redret = redisproxy:pipelining(function (red) - red:hlen(FRIEND_KEY:format(roleId)) - red:hlen(FRIEND_KEY:format(objectId)) red:sismember(FRIEND_BLACK_KEY:format(objectId), roleId) red:sismember(FRIEND_BLACK_KEY:format(roleId), objectId) end) --自己好友满了 - if (redret[1] + needAddNew) >= globalCsv.friendListLimit then + if (table.numbers(role.friends) + needAddNew) >= globalCsv.friendListLimit then return 1 end -- 对方好友满了 - if redret[2] >= globalCsv.friendListLimit then + if getFriendCount(objectId) >= globalCsv.friendListLimit then return 2 end -- 对方把你拉黑 - if redret[3] == 1 then + if redret[1] == 1 then return 3 end -- 你把对方拉黑了 - if redret[4] == 1 then + if redret[2] == 1 then return 4 end @@ -255,14 +247,13 @@ function _M.handleApplyRpc(agent, data) return end local curCount - result, curCount = checkHandleApply(roleId, objectId) + result, curCount = checkHandleApply(role, objectId) if not result then redisproxy:pipelining(function (red) red:ZREM(FRIEND_APPLY_KEY:format(roleId), objectId) red:ZREM(FRIEND_APPLY_KEY:format(objectId), roleId) - red:hsetnx(FRIEND_KEY:format(roleId), objectId, newTag) - red:hsetnx(FRIEND_KEY:format(objectId), roleId, newTag)--告知对放有新好友 + addFriend(roleId, objectId) end) local myInfo = role:friendSInfo() myInfo.online = true @@ -310,7 +301,7 @@ function _M.handleApplyRpc(agent, data) local needAddInfo = {} for _, objId in ipairs(allIds) do objId = tonumber(objId) - local cr, curCount = checkHandleApply(roleId, objId, #needAdd) + local cr, curCount = checkHandleApply(role, objId, #needAdd) if not cr then table.insert(needAdd, objId) table.insert(needAddMy, objId) @@ -335,12 +326,9 @@ function _M.handleApplyRpc(agent, data) red:ZREM(FRIEND_APPLY_KEY:format(roleId), table_unpack(needAdd)) for _, objectId in pairs(needAdd) do red:ZREM(FRIEND_APPLY_KEY:format(objectId), roleId) - red:hsetnx(FRIEND_KEY:format(objectId), roleId, newTag)--告知对放有新好友 + addFriend(roleId, objectId) end end - if next(needAddMy) then - red:HMSET(FRIEND_KEY:format(roleId), table_unpack(needAddMy)) - end end) local myInfo = role:friendSInfo() myInfo.roleId = roleId @@ -373,27 +361,21 @@ function _M.listRpc(agent, data) local friendList = {} local redret = redisproxy:pipelining(function (red) - red:hgetall(FRIEND_KEY:format(roleId)) red:SMEMBERS(FRIEND_POINT:format(roleId)) end) - local friends = redret[1] - local fpoint = formatArray(redret[2]) + local fpoint = formatArray(redret[1]) local hadGet = role.dailyData:getProperty("getFP") local hadGive = role.dailyData:getProperty("giveFP") - local clearRed = {} - for i = 1, #friends, 2 do - local id = friends[i] - local data = friends[i + 1] - local friendInfo = MsgPack.unpack(data) - id = tonumber(id) + local addNew = false + for id, friend in pairs(role.friends) do local online, info = getRoleInfo(id) local roleInfo = { roleId = id, online = online, - addTime = friendInfo[1], - isNew = friendInfo[2], + addTime = friend:getProperty("addTime"), + isNew = friend:getProperty("isNew"), pGive = hadGive[id], pGet = hadGet[id] and -1 or (fpoint[id] and 1 or nil) } @@ -401,14 +383,12 @@ function _M.listRpc(agent, data) friendList[#friendList + 1] = roleInfo - if friendInfo[2] then - friendInfo[2] = nil --清除新好友标记 - clearRed[#clearRed + 1] = id - clearRed[#clearRed + 1] = MsgPack.pack(friendInfo) + if roleInfo.isNew then + friend:setProperty("isNew", 0) + addNew = true end end - if next(clearRed) then - redisproxy:hmset(FRIEND_KEY:format(roleId), table_unpack(clearRed)) --清除新好友标记 + if addNew then role:checkTaskEnter("AddFriend", {count = #friendList}) end @@ -421,14 +401,14 @@ function _M.deleteRpc(agent, data) local roleId = role:getProperty("id") local msg = MsgPack.unpack(data) local objectId = msg.roleId - if not redisproxy:exists(string_format("role:%d", objectId)) then + if not roleExists(objectId) then return end -- 是否在好友列表中 - if redisproxy:hexists(FRIEND_KEY:format(roleId), objectId) then + if role.friends[objectId] then + role.friends[objectId] = nil redisproxy:pipelining(function (red) - red:hdel(FRIEND_KEY:format(roleId), objectId) - red:hdel(FRIEND_KEY:format(objectId), roleId) + delFriend(roleId, objectId) red:ZREM(FRIEND_APPLY_KEY:format(roleId), objectId) red:ZREM(FRIEND_APPLY_KEY:format(objectId), roleId) end) @@ -450,7 +430,7 @@ function _M.blockRpc(agent, data) local msg = MsgPack.unpack(data) local cmd = msg.cmd local objectId = msg.roleId - if not redisproxy:exists(string_format("role:%d", objectId)) then + if not roleExists(objectId) then return end @@ -463,8 +443,7 @@ function _M.blockRpc(agent, data) -- 删除好友 if not result then redisproxy:pipelining(function (red) - red:hdel(FRIEND_KEY:format(roleId), objectId) - red:hdel(FRIEND_KEY:format(objectId), roleId) + delFriend(roleId, objectId) red:ZREM(FRIEND_APPLY_KEY:format(roleId), objectId) red:ZREM(FRIEND_APPLY_KEY:format(objectId), roleId) red:sadd(FRIEND_BLACK_KEY:format(roleId), objectId) @@ -511,19 +490,19 @@ function _M.infoRpc(agent, data) local roleId = role:getProperty("id") local msg = MsgPack.unpack(data) local objectId = msg.roleId - if not redisproxy:exists(string_format("role:%d", objectId)) then + + if not roleExists(objectId) then return end local online, info = getRoleAllInfo(objectId) local redret = redisproxy:pipelining(function (red) - red:hexists(FRIEND_KEY:format(roleId), objectId) red:zscore(FRIEND_APPLY_KEY:format(objectId), roleId) red:sismember(FRIEND_BLACK_KEY:format(roleId), objectId) end) - local isFriend = redret[1] == 1 and 1 or nil - local hadApply = redret[2] == 1 and 1 or nil - local inBlack = redret[3] == 1 and 1 or nil + local isFriend = role.friends[objectId] and 1 or nil + local hadApply = redret[1] == 1 and 1 or nil + local inBlack = redret[2] == 1 and 1 or nil local objInfo = table_merge({ roleId = objectId, @@ -551,7 +530,7 @@ function _M.pointRpc(agent, data) if not result and giveP[objId] then result = 1 end - if not result and not redisproxy:hexists(FRIEND_KEY:format(roleId), objId) then + if not result and not role.friends[objId] then result = 2 end if not result then @@ -586,11 +565,9 @@ function _M.pointRpc(agent, data) elseif cmd == 3 then -- 一键赠送领取 -- 赠送 local giveP = role.dailyData:getProperty("giveFP") - local friends = redisproxy:hgetall(FRIEND_KEY:format(roleId)) local change = 0 redisproxy:pipelining(function(red) - for i = 1, #friends , 2 do - local objId = tonumber(friends[i]) + for objId, friend in pairs(role.friends) do if not giveP[objId] then giveP[objId] = 1 change = change + 1 @@ -645,22 +622,17 @@ function _M.randomRpc(agent, data) local roleId = role:getProperty("id") local redret = redisproxy:pipelining(function (red) - red:hgetall(FRIEND_KEY:format(roleId)) red:zrevrange(FRIEND_RECOMMEND, 0, globalCsv.friendRecommendLimit + globalCsv.friendListLimit + 10) --扩充10个 red:SMEMBERS(FRIEND_BLACK_KEY:format(roleId)) end) - local friends = {} - for i = 1, #redret[1], 2 do - friends[tonumber(redret[1][i])] = redret[1][i + 1] - end - local newList = redret[2] - local hadBlack = formatArray(redret[3]) + local newList = redret[1] + local hadBlack = formatArray(redret[2]) local needRoleIds = {} for _, newId in pairs(newList) do local numNewId = tonumber(newId) - if numNewId ~= roleId and not friends[numNewId] and not hadBlack[numNewId] then + if numNewId ~= roleId and not role.friends[numNewId] and not hadBlack[numNewId] then table.insert(needRoleIds, numNewId) end end diff --git a/src/actions/RoleAction.lua b/src/actions/RoleAction.lua index c02baf6..ce7e437 100644 --- a/src/actions/RoleAction.lua +++ b/src/actions/RoleAction.lua @@ -87,11 +87,11 @@ function _M.loginRpc( agent, data ) -- 2 if not role then local roleKey = string_format("%d", roleId) - --if not redisproxy:exists(roleKey) then - -- response.result = "DB_ERROR" - -- SendPacket(actionCodes.Role_loginRpc, MsgPack.pack(response)) - -- return true - --end + if not roleExists(roleId) 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() @@ -156,7 +156,6 @@ function _M.loginRpc( agent, data ) end end - --SERV_OPEN = redisproxy:hget("autoincrement_set", "server_start") SERV_OPEN = getDbCfgVal("server_info", "server_start", "str_value") role:changeStructVersion() -- 数据结构 版本更新 @@ -1107,21 +1106,20 @@ function _M.chatRpc(agent, data) local objectId = msg.roleId response.objId = objectId local redret = redisproxy:pipelining(function(red) - red:exists(string.format("role:%d", objectId)) red:sismember(FRIEND_BLACK_KEY:format(roleId), objectId) red:sismember(FRIEND_BLACK_KEY:format(objectId), roleId) end) - if redret[1] ~= 1 then + if not roleExists(objectId) then result = 1 return end -- 你把对方拉黑拉黑 - if redret[2] == 1 then + if redret[1] == 1 then result = 2 return end -- 对方把你拉黑 - local isBlock = redret[3] == 1 + local isBlock = redret[2] == 1 local bin = MsgPack.pack(response) if not isBlock then diff --git a/src/models/Activity.lua b/src/models/Activity.lua index 185244f..46ff1f5 100644 --- a/src/models/Activity.lua +++ b/src/models/Activity.lua @@ -938,17 +938,11 @@ activityFunc[Activity.ActivityType.FriendEnergy] = { function Activity:getActFriendNew() local roleId = self.owner:getProperty("id") - local friendIds = {} - local friends = redisproxy:hgetall(FRIEND_KEY:format(roleId)) - for i = 1, #friends , 2 do - local objId = tonumber(friends[i]) - friendIds[objId] = 1 - end local ids = {} local members = redisproxy:smembers(FRIEND_ENERGY:format(roleId)) for _, id in pairs(members) do - if friendIds[tonumber(id)] then + if self.owner.friends[tonumber(id)] then ids[tonumber(id)] = 1 end end diff --git a/src/models/Diner.lua b/src/models/Diner.lua index 2bfdf05..dd20265 100644 --- a/src/models/Diner.lua +++ b/src/models/Diner.lua @@ -7,10 +7,10 @@ end Diner.schema = { id = {"number", 0, "pri"}, -- 角色id buildL = {"string", ""}, -- 家具等级 1=1 2=1 3=1 - order = {"string", "[]", 1024}, -- 特殊订单 - sells = {"string", "[]", "", 1024}, -- 贩卖位置 - dishTree = {"string", "1=1 101=1 201=1"}, -- 料理天赋 - skillTree = {"string", ""}, -- 支援天赋 + order = {"string", "[]", "blob"}, -- 特殊订单 + sells = {"string", "[]", "blob"}, -- 贩卖位置 + dishTree = {"string", "1=1 101=1 201=1", "blob"}, -- 料理天赋 + skillTree = {"string", "", "blob"}, -- 支援天赋 popular = {"number",0}, -- 累计人气 expedite = {"number",1}, --每日加速次数 gfood = {"table", {}}, -- 愿望食材 {{id = 123, st = 1232144},} diff --git a/src/models/Friend.lua b/src/models/Friend.lua new file mode 100644 index 0000000..1e908fe --- /dev/null +++ b/src/models/Friend.lua @@ -0,0 +1,15 @@ +local Friend = class("Friend", require("shared.ModelBaseMysql")) + +function Friend:ctor(properties) + Friend.super.ctor(self, properties) +end + +Friend.schema = { + id = {"number", 0, "pri_auto"}, + roleid = {"number", 0, "index"}, + fid = {"number", 0, "index"}, + isNew = {"number", 1}, + addTime = {"number", skynet.timex()}, +} + +return Friend \ No newline at end of file diff --git a/src/models/Role.lua b/src/models/Role.lua index f6ba41e..9061728 100644 --- a/src/models/Role.lua +++ b/src/models/Role.lua @@ -25,6 +25,7 @@ function Role:ctor( properties ) self.storeData = nil self.heros = {} self.runeBag = {} + self.friends = {} self.advData = nil self.activity = nil self._pushToken = nil diff --git a/src/models/RoleCross.lua b/src/models/RoleCross.lua index 183dbd0..4f3c2c4 100644 --- a/src/models/RoleCross.lua +++ b/src/models/RoleCross.lua @@ -24,6 +24,20 @@ RoleCross.bind = function (Role) return info end + function Role:addFriend(friendId) + local res = mysqlproxy:query(string.format("SELECT * FROM `Friend` WHERE `roleid` = %s AND `fid` = %s;", self:getProperty("id"), friendId)) + for _, data in ipairs(res) do + local friend = require("models.Friend").new({key = string.format("%d",data.id), id = data.id}) + if friend:load(data) then + self.friends[friend:getProperty("fid")] = friend + end + end + end + + function Role:delFriend(friendId) + self.friends[friendId] = nil + end + -- 好友队伍战斗信息 function Role:friendBattleInfo() return self:getProperty("pvpTBVC") ~= 0 and self:getProperty("pvpTBC") or self:getProperty("hangTB") @@ -231,33 +245,30 @@ local function getRoleKey(roleId) end function CMD.setProperty(roleId, field, value) - local value = packRoleField(field, value) - if not value then return end - return redisproxy:hset(getRoleKey(roleId), field, value) + local tb = {} + tb[field] = value + return CMD.setProperties(roleId, tb) end function CMD.setProperties(roleId, fields) - local result = {} - for k,v in pairs(fields) do - local value = packRoleField(k, v) - if value then - result[#result + 1] = k - result[#result + 1] = value - end - end - return redisproxy:hmset(getRoleKey(roleId), table.unpack(result)) + local role = require("models.Role").new({key = string.format("%s",roleId), id = roleId}) + return role:updateFields(fields) end function CMD.getProperty(roleId, field) - return unpackRoleField(field ,redisproxy:hget(getRoleKey(roleId), field)) + local ret = CMD.getProperties(roleId, {field}) + return ret[field] end function CMD.getProperties(roleId, fields) - local returnValue = redisproxy:hmget(getRoleKey(roleId), table.unpack(fields)) + local role = require("models.Role").new({key = string.format("%s",roleId), id = roleId}) local ret = {} - for index, key in ipairs(fields) do - ret[key] = unpackRoleField(key, returnValue[index]) + local datas = role:loadFields(fields) + if datas then + for index, key in ipairs(fields) do + ret[key] = unpackRoleField(key, datas[key]) + end end return ret end diff --git a/src/models/RolePlugin.lua b/src/models/RolePlugin.lua index 634b0fd..933330e 100644 --- a/src/models/RolePlugin.lua +++ b/src/models/RolePlugin.lua @@ -13,6 +13,7 @@ function RolePlugin.bind(Role) self:loadActivity() self:loadStoreInfo() self:loadRoleIncre() + self:loadFriends() end function Role:reloadWhenLogin() @@ -621,6 +622,17 @@ function RolePlugin.bind(Role) end end + function Role:loadFriends() + local roleId = self:getProperty("id") + local res = mysqlproxy:query(string.format("SELECT * FROM `Friend` WHERE `roleid` = %s", roleId)) + for _, data in ipairs(res) do + local friend = require("models.Friend").new({key = string.format("%d",data.id), id = data.id}) + if friend:load(data) then + self.friends[friend:getProperty("fid")] = friend + end + end + end + function Role:loadDaily() local roleId = self:getProperty("id") local dataKey = string.format("%d", roleId) @@ -834,12 +846,6 @@ function RolePlugin.bind(Role) end -- delete rune - --redisproxy:pipelining(function (red) - -- for _, runeId in pairs(bDel) do - -- red:del(string.format(R_RUNE, roleId, runeId)) - -- red:srem(string.format(R_RUNEIDS, roleId), runeId) - -- end - --end) mysqlproxy:query(string.format("DELETE FROM `Rune` WHERE `uid` in (%s)", table.concat(bDel, ","))) local response = {} @@ -1555,6 +1561,21 @@ function RolePlugin.bind(Role) function Role:onRecoverTimer(now) self:updateTimeReset(now, true) self:checkNewEvent(now) + self:saveRoleData() + end + + function Role:saveRoleData() + self:update() + local objs = {self.activity, self.dailyData, self.dinerData, self.storeData, self.roleIncre} + for _, info in ipairs(objs) do + info:update() + end + local tbObjs = {self.friends, self.heros, self.runeBag} + for _, tbObj in ipairs(tbObjs) do + for _, info in pairs(tbObj) do + tbObj:update() + end + end end local function breath(sec, name) @@ -1812,6 +1833,8 @@ function RolePlugin.bind(Role) redisproxy:hdel(string.format(R_ORDERS, roleId), rechargeId) end + orderObject:update() + if status ~= "unknow" then self:log("setOrder", { order_status = ({success = 100, finsh = 200, fail = 300})[status] or 1000, -- "订单状态:100 - 开始下单(玩家还未开始付费行为记录)200 - 支付完成并发货(SDK通知可以发货时记录),300 - 订单被取消,1000 - 其他" diff --git a/src/services/dbseed.lua b/src/services/dbseed.lua index 9d5592e..f4a6b6e 100644 --- a/src/services/dbseed.lua +++ b/src/services/dbseed.lua @@ -34,6 +34,8 @@ local function initRedisDb( ... ) initAutoIncrementUid("autoincrement_set", "email") initAutoIncrementUid("autoincrement_set", "emailTimestamp") initAutoIncrementUid("autoincrement_set", "delay_email") + initAutoIncrementUid("autoincrement_set", "stopcreate") + initAutoIncrementUid("autoincrement_set", "maintain") --redisproxy:hsetnx("adv_season", "idx", 0) --redisproxy:hsetnx("adv_season", "chapter", globalCsv.adv_endless_default_chapter) @@ -80,6 +82,8 @@ local function initAutoIncreUidTable() mysqlproxy:query(string.format(tpl, "email", 0)) mysqlproxy:query(string.format(tpl, "emailTimestamp", 0)) mysqlproxy:query(string.format(tpl, "delay_email", 0)) + mysqlproxy:query(string.format(tpl, "stopcreate", 0)) + mysqlproxy:query(string.format(tpl, "maintain", 0)) end end @@ -102,7 +106,7 @@ local function initAdvSeasonTable() end local function checkRoleTables() - local list = {"Role", "Daily", "Activity", "Diner", "Store", "Hero", "RoleIncre", "Rune", "Order", "Email"} + local list = {"Role", "Daily", "Activity", "Diner", "Store", "Hero", "RoleIncre", "Rune", "Order", "Email", "Friend"} for _, name in ipairs(list) do local obj = require("models."..name).new({key = "key"}) print("check table [" .. name .. "] begin.") @@ -111,6 +115,48 @@ local function checkRoleTables() end end +local function createMysqlSp() + mysqlproxy:query "DROP PROCEDURE IF EXISTS `add_friends`" + mysqlproxy:query [[ + CREATE PROCEDURE `add_friends`(IN role_id bigint, IN friend_id bigint, IN add_time int) + BEGIN + DECLARE t_error INTEGER DEFAULT 0; + DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET t_error=1; + + START TRANSACTION; + INSERT INTO `Friend`(`roleid`,`fid`,`addTime`) VALUES(role_id, friend_id, add_time); + INSERT INTO `Friend`(`roleid`,`fid`,`addTime`) VALUES(friend_id, role_id, add_time); + + IF t_error = 1 THEN + ROLLBACK; + ELSE + COMMIT; + END IF; + select t_error; + END + ]] + + mysqlproxy:query "DROP PROCEDURE IF EXISTS `del_friends`" + mysqlproxy:query [[ + CREATE PROCEDURE `del_friends`(IN role_id bigint, IN friend_id bigint) + BEGIN + DECLARE t_error INTEGER DEFAULT 0; + DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET t_error=1; + + START TRANSACTION; + DELETE FROM `Friend` WHERE `roleid` = role_id AND `fid` = friend_id; + DELETE FROM `Friend` WHERE `roleid` = friend_id AND `fid` = role_id; + + IF t_error = 1 THEN + ROLLBACK; + ELSE + COMMIT; + END IF; + select t_error; + END + ]] +end + local steps = { [1] = { handler = initServerDatabase, @@ -127,9 +173,35 @@ local steps = { [4] = { handler = checkRoleTables, desc = "check role tables " - } + }, + [5] = { + handler = createMysqlSp, + desc = "create mysql store procedure " + }, } +local function loadAllUserInfo() + local maxId = 0 + local sql = "SELECT `id`, `uid`, `name` FROM `Role` WHERE `id` > %d ORDER BY `id` LIMIT 1000;" + while true do + local res = mysqlproxy:query(string.format(sql, maxId)) + if not next(res) then + return + else + for _, info in ipairs(res) do + if info["id"] > maxId then + maxId = info["id"] + end + redisproxy:pipelining(function (red) + local dbName = string.upper(info["name"]) + red:set(string.format("user:%s", dbName), info["id"]) + red:set(string.format("uid:%s", info["uid"]), dbName) + end) + end + end + end +end + skynet.start(function () --local new = redisproxy:hsetnx("autoincrement_set", "server_start", os.date("%Y%m%d", skynet.timex())) == 1 --if not new then @@ -146,5 +218,6 @@ skynet.start(function () print(action.desc .. "finished ...") end initRedisDb() + loadAllUserInfo() skynet.exit() end) \ No newline at end of file diff --git a/src/services/globald.lua b/src/services/globald.lua index 39dc9b8..28fc236 100644 --- a/src/services/globald.lua +++ b/src/services/globald.lua @@ -171,6 +171,8 @@ local function save_autoincrement_timer() saveUidToMysql("autoincrement_set", "email") saveUidToMysql("autoincrement_set", "emailTimestamp") saveUidToMysql("autoincrement_set", "delay_email") + saveUidToMysql("autoincrement_set", "stopcreate") + saveUidToMysql("autoincrement_set", "maintain") skynet.timeout(SAVE_AUTOINCREMENT_SET_INTERVAL, save_autoincrement_timer) end diff --git a/src/services/mysqld.lua b/src/services/mysqld.lua index bbd6ebd..c83a3b4 100644 --- a/src/services/mysqld.lua +++ b/src/services/mysqld.lua @@ -31,6 +31,8 @@ skynet.start(function() if cmd == "open" then local f = command[string.lower(cmd)] skynet.ret(skynet.pack(f(...))) + elseif string.lower(cmd) == "quote_sql_str" then + skynet.ret(skynet.pack(db[string.lower(cmd)](...))) else skynet.ret(skynet.pack(db[string.lower(cmd)](db, ...))) end diff --git a/src/shared/ModelBaseMysql.lua b/src/shared/ModelBaseMysql.lua index d7cfc7f..c2255d1 100644 --- a/src/shared/ModelBaseMysql.lua +++ b/src/shared/ModelBaseMysql.lua @@ -141,6 +141,10 @@ function ModelBaseMysql:save() end sql = string_format(sql, tbName, key_list, value_list, update_list) local res = mysqlproxy:query(sql) + if res["errno"] then + skynet.error(sql) + skynet.error(res["error"]) + end end end @@ -228,7 +232,7 @@ function ModelBaseMysql:getProperty(property) return self:getProperties({property})[property] end -function ModelBaseMysql:setProperty(property, value) +function ModelBaseMysql:setProperty(property, value, forceSave) if not self.class.schema[property] then print(string_format("%s [%s:setProperty()] Invalid property : %s", tostring(self), self.class.__cname, property)) @@ -245,13 +249,21 @@ function ModelBaseMysql:setProperty(property, value) assert(type(value) == typ, string_format("%s [%s:setProperties()] Type mismatch, %s expected %s, actual is %s", tostring(self), self.class.__cname, property, typ, type(value))) - self[propname] = value - self:save() + if typ == "number" or typ == "string" then + if self[propname] == value then + return + end + end + self[propname] = value + --self:save() + self.cacheFields[property] = self[propname] + if forceSave then + self:update() + end end -function ModelBaseMysql:setProperties(fields) - local result = {} +function ModelBaseMysql:setProperties(fields, forceSave) for property, value in pairs(fields) do if not self.class.schema[property] then print(string_format("%s [%s:setProperty()] Invalid property : %s", @@ -266,20 +278,23 @@ function ModelBaseMysql:setProperties(fields) assert(type(value) == typ, string_format("%s [%s:setProperties()] Type mismatch, %s expected %s, actual is %s", tostring(self), self.class.__cname, property, typ, type(value))) - self[propname] = value - table_insert(result, property) - if typ == "table" then - table_insert(result, MsgPack.pack(self[propname])) - else - table_insert(result, self[propname]) + if typ == "number" or typ == "string" then + if self[propname] == value then + return + end end + self[propname] = value + self.cacheFields[property] = self[propname] end end - self:save() + if forceSave then + self:update() + end + --self:save() end -function ModelBaseMysql:incrProperty(property, value) +function ModelBaseMysql:incrProperty(property, value, forceSave) if not self.class.schema[property] then print(string_format("%s [%s:setProperty()] Invalid property : %s", tostring(self), self.class.__cname, property)) @@ -289,15 +304,10 @@ function ModelBaseMysql:incrProperty(property, value) local typ, def = table_unpack(self.class.schema[property]) local propname = property .. "_" - if typ == "table" then return end + if typ == "table" or typ == "string" then return end if typ == "number" then value = tonumber(value) end - assert(type(value) == typ, - string_format("%s [%s:setProperties()] Type mismatch, %s expected %s, actual is %s", - tostring(self), self.class.__cname, property, typ, type(value))) - self[propname] = self[propname] + value - - self:save() + self:setProperty(property, self[propname] + value, forceSave) end function ModelBaseMysql:onLoad() @@ -438,4 +448,65 @@ function ModelBaseMysql:checkTableSchema() end +function ModelBaseMysql:loadFields(fields) + if not self:isValidKey() then + print(string_format("%s [%s:id] should be set before load", tostring(self), self.class.__cname)) + return + end + if not next(fields) then + return + end + local final = {} + for _, v in ipairs(fields) do + table.insert(final, '`'..v..'`') + end + local field_list = table.concat(final, ",") + local res = mysqlproxy:query(string_format("SELECT %s from `%s` where `%s` = %s;", field_list, self.class.__cname, self.pri_key, self:getKey())) + if res["errno"] then + return + end + + return res[1] +end + +function ModelBaseMysql:update() + if next(self.cacheFields) then + self:updateFields(self.cacheFields) + self.cacheFields = {} + end +end + +function ModelBaseMysql:updateFields(fields) + local params = {} + for field, value in pairs(fields) do + if self.class.schema[field][1] == "table" then + if next(value) then + local result = mysqlproxy:quote_sql_str(MsgPack.pack(value)) + params[field] = result + end + elseif self.class.schema[field][1] == "string" then + local result = mysqlproxy:quote_sql_str(value) + params[field] = result + else + params[field] = value + end + end + if next(params) then + local sql = "UPDATE `%s` SET %s WHERE `%s` = %s;" + local tbName = self.class.__cname + local tmp = {} + for k, v in pairs(params) do + table.insert(tmp, '`' .. k .. '` = ' .. v) + end + sql = string_format(sql, tbName, table.concat(tmp, ","), self.pri_key, self:getKey()) + local res = mysqlproxy:query(sql) + if res["errno"] then + skynet.error(sql) + skynet.error(res["error"]) + return false + end + end + return true +end + return ModelBaseMysql \ No newline at end of file diff --git a/src/utils/MysqlUtil.lua b/src/utils/MysqlUtil.lua index dfdd5e8..160d488 100644 --- a/src/utils/MysqlUtil.lua +++ b/src/utils/MysqlUtil.lua @@ -16,4 +16,42 @@ function setDbCfgVal(tbName, keyName, fieldName, fieldVal) if type(fieldVal) == "string" then fieldVal = string.format("'%s'", fieldVal) end local sql = string.format("UPDATE `%s` SET `%s` = %s WHERE `key` = '%s';", tbName, fieldName, fieldVal, keyName) mysqlproxy:query(sql) +end + +function getFriendCount(roleId) + local res = mysqlproxy:query(string.format("SELECT `id` FROM `Friend` WHERE `roleid` = %s", roleId)) + if res["errno"] then + return globalCsv.friendListLimit + end + + return #res +end + +function addFriend(roleId, friendId) + local stmt_csp = mysqlproxy:prepare("call add_friends(?, ?, ?)") + local r = mysqlproxy:execute(stmt_csp, roleId, friendId, skynet.timex()) + if r[1][1]["t_error"] == 0 then + rpcRole(roleId, "addFriend", friendId) + rpcRole(friendId, "addFriend", roleId) + end + dump(r) +end + +function delFriend(roleId, friendId) + local stmt_csp = mysqlproxy:prepare("call del_friends(?, ?)") + local r = mysqlproxy:execute(stmt_csp, roleId, friendId) + if r[1][1]["t_error"] == 0 then + rpcRole(roleId, "delFriend", friendId) + rpcRole(friendId, "delFriend", roleId) + end + dump(r) +end + +function roleExists(roleId) + local res = mysqlproxy:query(string.format("SELECT `id` FROM `Role` WHERE `id` = %s", roleId)) + if res["errno"] or not next(res) then + return false + end + + return true end \ No newline at end of file -- libgit2 0.21.2