Commit 18bf12f316ce38f2c89d2c51e7744798e5bdb0f8

Authored by chenyueqi
2 parents ce0149f4 2806380f

Merge branch 'cn/develop-mysql' into cn/develop

config/develop.lua
... ... @@ -16,3 +16,8 @@ redis_host = "127.0.0.1"
16 16 redis_port = 6100
17 17 redis_db = 1
18 18 redis_auth = nil
  19 +
  20 +mysql_host = "127.0.0.1"
  21 +mysql_port = 3306
  22 +mysql_user = "root"
  23 +mysql_password = "123456"
19 24 \ No newline at end of file
... ...
... ... @@ -10,10 +10,10 @@ fi
10 10 pid=`cat skynet.pid`
11 11 run=`ps aux | grep skynet | grep -v grep | grep -c $pid`
12 12  
13   -if [ $run = 1 ]; then
  13 +if [[ $run = 1 ]]; then
14 14 echo "服务端正在运行"
15 15 exit 0
16 16 fi
17 17  
18 18 skynet/skynet config/${config}.lua
19   -echo "服务端启动完毕"
20 19 \ No newline at end of file
  20 +echo "服务端启动完毕"
... ...
src/GlobalVar.lua
... ... @@ -27,7 +27,11 @@ STRUCT_VERSION = 3 -- 数据结构版本
27 27 IOS_SID = 4 -- 判断是不是ios设备
28 28 UO_SID = 6 -- 判断是不是联运渠道
29 29  
  30 +MAX_SVR_ID = 10000
30 31 MAX_ROLE_NUM = 1000000
  32 +MAX_HERO_NUM = 1000000 -- 英雄的id = roleId * MAX_HERO_NUM + index
  33 +MAX_RUNE_NUM = 1000000 -- 铭文的id = roleId * MAX_RUNE_NUM + index
  34 +MAX_SPARK_NUM = 1000000 -- 火花的id = roleId * MAX_SPARK_NUM + index
31 35 -- 属性枚举
32 36 AttsEnum = {
33 37 hp = 1, -- 血量
... ... @@ -130,9 +134,10 @@ ItemStartId = {
130 134 ItemId = {
131 135 Gold = 1, -- 金币
132 136 Exp = 2, -- 经验
133   - Diamond = 3, -- 钻石
  137 + Jade = 3, -- 虹光玉
134 138 PlayerExp = 4, -- 突破材料
135 139 FriendPoint = 5, -- 友情点
  140 + Diamond = 8, -- 钻石
136 141 BreakCost = 10, -- 突破材料
137 142 EquipUp = 11, -- 装备升级材料
138 143 DinerCoin = 12, --后勤物资
... ... @@ -144,6 +149,7 @@ ItemId = {
144 149 PvpKey = 22, -- pvp钥匙
145 150 LunchFragment = 23,
146 151 RuneFragment = 24,
  152 + RecruitmentCard = 70, -- 招募券
147 153 HeroFC = {700, 701, 702, 703}, --通用角色碎片
148 154 AdvKey = 80, -- 冒险钥匙
149 155 AdvPower = 4701, -- 拾荒体力
... ...
src/ProtocolCode.lua
... ... @@ -53,6 +53,8 @@ actionCodes = {
53 53 Role_accuseRpc = 137, -- 举报
54 54 Role_loadSparks = 138,
55 55 Role_updateSpark = 139, -- 更新火花
  56 + Role_diamondConvertRpc = 140, -- 钻石兑换成别的物品
  57 + Role_getTimeGiftRpc = 141,
56 58  
57 59 Adv_startAdvRpc = 151,
58 60 Adv_startHangRpc = 152,
... ... @@ -125,6 +127,7 @@ actionCodes = {
125 127 Hang_endWorkBattleRpc = 267,
126 128 Hang_workBattleInfoRpc = 268,
127 129 Hang_getWorkRewardRpc = 269,
  130 + Hang_unlockChapterRpc = 270,
128 131  
129 132 Diner_updateProperty = 300,
130 133 Diner_addSellRpc = 301,
... ...
src/actions/ActivityAction.lua
... ... @@ -1013,16 +1013,6 @@ function _M.friendHelpRpc(agent, data)
1013 1013  
1014 1014 local actData = role.activity:getActData("FriendEnergy") or {}
1015 1015  
1016   - local function getIds()
1017   - local ids = {}
1018   - local friends = redisproxy:hgetall(FRIEND_KEY:format(roleId))
1019   - for i = 1, #friends , 2 do
1020   - local objId = tonumber(friends[i])
1021   - ids[objId] = 1
1022   - end
1023   - return ids
1024   - end
1025   -
1026 1016 if oper == 1 then -- 赠送好友能量
1027 1017 local giveAE = actData.giveAE or {}
1028 1018 local objId = msg.roleId
... ... @@ -1032,7 +1022,7 @@ function _M.friendHelpRpc(agent, data)
1032 1022 if not objId then
1033 1023 return 3
1034 1024 end
1035   - if not redisproxy:hexists(FRIEND_KEY:format(roleId), objId) then
  1025 + if not role.friends[objId] then
1036 1026 result = 2
1037 1027 end
1038 1028 if giveAE[objId] then
... ... @@ -1078,7 +1068,6 @@ function _M.friendHelpRpc(agent, data)
1078 1068 local gift2 = gifts[2]
1079 1069 local limit = actData.limit or 0
1080 1070 local cmd1, cmd2 = 0, 0
1081   - local ids = getIds()
1082 1071  
1083 1072 local members = {}
1084 1073 local temp = redisproxy:smembers(FRIEND_ENERGY:format(roleId))
... ... @@ -1087,7 +1076,7 @@ function _M.friendHelpRpc(agent, data)
1087 1076 end
1088 1077  
1089 1078 redisproxy:pipelining(function(red)
1090   - for friendId, _ in pairs(ids) do
  1079 + for friendId, _ in pairs(role.friends) do
1091 1080 if not giveAE[friendId] then
1092 1081 giveAE[friendId] = 1
1093 1082 award[gift1[1]] = (award[gift1[1]] or 0) + gift1[2]
... ... @@ -1153,13 +1142,12 @@ function _M.friendHelpRpc(agent, data)
1153 1142  
1154 1143 local ids = {}
1155 1144 local members = {}
1156   - local friendIds = getIds()
1157 1145 local temp = redisproxy:smembers(FRIEND_ENERGY:format(roleId))
1158 1146 for _, id in pairs(temp) do
1159 1147 members[tonumber(id)] = 1
1160 1148 end
1161 1149  
1162   - for id, _ in pairs(friendIds) do
  1150 + for id, _ in pairs(role.friends) do
1163 1151 if members[id] then
1164 1152 ids[id] = 1
1165 1153 end
... ... @@ -1294,8 +1282,8 @@ function _M.buyBattleCommandLvlRpc(agent, data)
1294 1282 end
1295 1283 if cost == 0 then return 5 end
1296 1284  
1297   - if not role:checkItemEnough({[ItemId.Diamond] = cost}) then return 6 end
1298   - role:costItems({[ItemId.Diamond] = cost}, {log = {desc = "actBuyBpLevel", int1 = curLvl}})
  1285 + if not role:checkItemEnough({[ItemId.Jade] = cost}) then return 6 end
  1286 + role:costItems({[ItemId.Jade] = cost}, {log = {desc = "actBuyBpLevel", int1 = curLvl}})
1299 1287 actData["lvl"] = nextLvl
1300 1288 role.activity:updateActData("BattleCommand", actData)
1301 1289  
... ...
src/actions/AdvAction.lua
... ... @@ -381,8 +381,8 @@ function _M.quickHangRpc(agent, data)
381 381  
382 382 local cost = math.ceil((info.time - skynet.timex()) / 3600 * globalCsv.adv_idle_quicken)
383 383  
384   - if not role:checkItemEnough({[ItemId.Diamond] = cost}) then return end
385   - role:costItems({[ItemId.Diamond] = cost}, {log = {desc = "advQuickHang", int1 = chapterId}})
  384 + if not role:checkItemEnough({[ItemId.Jade] = cost}) then return end
  385 + role:costItems({[ItemId.Jade] = cost}, {log = {desc = "advQuickHang", int1 = chapterId}})
386 386 info.time = 0
387 387 role:changeUpdates({{type = "advHang", field = chapterId, value = info}})
388 388  
... ... @@ -508,10 +508,10 @@ function _M.buyAdvCountRpc(agent , data)
508 508 local cost
509 509 if isEl then
510 510 if math.illegalNum(count, 1, globalCsv.adv_endless_daily_buy_count - role.dailyData:getProperty("advElBC")) then return end
511   - cost = {[ItemId.Diamond] = count * globalCsv.adv_endless_daily_buy_cost}
  511 + cost = {[ItemId.Jade] = count * globalCsv.adv_endless_daily_buy_cost}
512 512 else
513 513 if math.illegalNum(count, 1, globalCsv.adv_daily_buy_count - role.dailyData:getProperty("advBC")) then return end
514   - cost = {[ItemId.Diamond] = count * globalCsv.adv_daily_buy_cost}
  514 + cost = {[ItemId.Jade] = count * globalCsv.adv_daily_buy_cost}
515 515 end
516 516  
517 517  
... ... @@ -1029,8 +1029,8 @@ function _M.refreshSupportRpc(agent, data)
1029 1029 if cr < al then --免费
1030 1030 role.dailyData:updateProperty({field = "advSupRe", delta = 1})
1031 1031 else -- 付费
1032   - if not role:checkItemEnough({[ItemId.Diamond] = globalCsv.adv_support_refresh_cost}) then return end
1033   - role:costItems({[ItemId.Diamond] = globalCsv.adv_support_refresh_cost}, {log = {desc = "advReSupport"}})
  1032 + if not role:checkItemEnough({[ItemId.Jade] = globalCsv.adv_support_refresh_cost}) then return end
  1033 + role:costItems({[ItemId.Jade] = globalCsv.adv_support_refresh_cost}, {log = {desc = "advReSupport"}})
1034 1034 end
1035 1035  
1036 1036 role:advRandomSupportEffect()
... ...
src/actions/CarAction.lua
... ... @@ -13,9 +13,28 @@ function _M.makePotionRpc( agent, data )
13 13 local count = msg.count
14 14 if count < 1 then return 0 end
15 15 local potionBag = role:getProperty("potionBag")
16   - local potionLv = role.dinerData:getProperty("dishTree"):getv(potionId, 1)
  16 + local dishTree = role.dinerData:getProperty("dishTree")
  17 + local potionLv = dishTree:getv(potionId, 1)
17 18 if potionLv < 1 then return 1 end
18 19  
  20 + local talentSet = csvdb["diner_talentCsv"][potionId]
  21 + if not talentSet then
  22 + return 10
  23 + end
  24 +
  25 + local talentData = talentSet[potionLv]
  26 + if not talentData then
  27 + return 11
  28 + end
  29 + local limit = talentData.pointFront:toNumMap()
  30 + for k,v in pairs(limit) do
  31 + local lv = dishTree:getv(k, 0)
  32 + if lv < v then
  33 + return 12
  34 + end
  35 + end
  36 +
  37 +
19 38 local potionSet = csvdb["adv_potionCsv"][potionId]
20 39 if not potionSet then return 2 end
21 40  
... ...
src/actions/DinerAction.lua
... ... @@ -253,7 +253,7 @@ function _M.expediteSellRpc( agent, data )
253 253 end
254 254 local diamond = globalCsv.diner_sell_quick_cost[count]
255 255 if diamond > 0 then
256   - local cost = {[ItemId.Diamond] = diamond}
  256 + local cost = {[ItemId.Jade] = diamond}
257 257 if not role:checkItemEnough(cost) then
258 258 return 2
259 259 end
... ... @@ -612,7 +612,7 @@ function _M.refreshTaskRpc( agent, data )
612 612 local role = agent.role
613 613 local msg = MsgPack.unpack(data)
614 614  
615   - --local cost = {[ItemId.Diamond] = 40}
  615 + --local cost = {[ItemId.Jade] = 40}
616 616 --if not role:checkItemEnough(cost) then
617 617 -- return 1
618 618 --end
... ... @@ -709,6 +709,20 @@ function _M.addWantFoodRpc(agent , data)
709 709 local foodData = csvdb["diner_materialCsv"][itemId]
710 710 if not foodData then return 3 end
711 711 if foodData.unlock ~= 0 then
  712 + -- 遍历adv_potion
  713 + for potionId, _ in pairs(csvdb["adv_potionCsv"]) do
  714 + local potionLv = role.dinerData:getProperty("dishTree"):getv(potionId, 0)
  715 + if potionLv < 1 then return 4 end
  716 +
  717 + local potionSet = csvdb["adv_potionCsv"][potionId]
  718 + if not potionSet then return 5 end
  719 +
  720 + local potionData = potionSet[potionLv]
  721 + if not potionData then return 6 end
  722 +
  723 + local cost = potionData.material:toNumMap()
  724 + if not cost[itemId] then return 7 end
  725 + end
712 726 if not role:checkHangPass(foodData.unlock) then
713 727 return 4
714 728 end
... ...
src/actions/EmailAction.lua
... ... @@ -3,22 +3,32 @@ local tarr2tab = table.array2Table
3 3  
4 4 local function loadEmails(roleId)
5 5 local emails = {}
6   - local rds = string.format(R_EMAIL, roleId)
7   - local ids = redisproxy:lrange(rds, 0, EMAIL_LIMIT - 1)
8   - local redret = redisproxy:pipelining(function (red)
9   - for _, id in ipairs(ids) do
10   - red:hgetall(string.format("email:%d:%s", roleId, id))
11   - end
12   - end)
13   - for index, id in ipairs(ids) do
14   - local email = require("models.Email").new({key = string.format("email:%d:%s", roleId, id)})
15   - if email:load(tarr2tab(redret[index])) then
  6 + local res = mysqlproxy:query(string.format("SELECT * FROM `Email` WHERE `roleId` = %s", roleId))
  7 + for _, data in ipairs(res) do
  8 + local email = require("models.Email").new({key = string.format("%d",data.id), id=data.id})
  9 + if email:load(data) then
16 10 table.insert(emails, email)
17 11 end
18 12 end
19 13 return emails
20 14 end
21 15  
  16 +local function delExpireEmails(roleId)
  17 + local sql = [[
  18 + DELETE FROM Email
  19 + WHERE id IN (
  20 + SELECT id FROM (
  21 + SELECT id
  22 + FROM Email WHERE roleId=%s
  23 + ORDER BY createtime DESC, id desc
  24 + LIMIT %s, 100000
  25 + ) a
  26 + );
  27 + ]]
  28 + sql = string.format(sql, roleId, EMAIL_LIMIT)
  29 + mysqlproxy:query(sql)
  30 +end
  31 +
22 32 function _M.listRpc(agent, data)
23 33 local role = agent.role
24 34 local roleId = role:getProperty("id")
... ... @@ -51,7 +61,7 @@ function _M.listRpc(agent, data)
51 61 if flag and ( not email.mid or tonum(email.mid) == mid )
52 62 and ( not email.endtime or tonum(email.endtime) > now )then
53 63 local time = math.max(tonum(email.timestamp, 0) , tonum(email.createtime))
54   - redisproxy:insertEmail({
  64 + mysqlproxy:insertEmail({
55 65 roleId = roleId,
56 66 emailId = 0,
57 67 createtime = time,
... ... @@ -64,6 +74,7 @@ function _M.listRpc(agent, data)
64 74 end
65 75 end
66 76 end
  77 + delExpireEmails(roleId)
67 78  
68 79 local emails = loadEmails(roleId)
69 80 for _, email in ipairs(emails) do
... ... @@ -100,7 +111,7 @@ function _M.drawAllAttachRpc(agent, data)
100 111 for _, email in ipairs(emails) do
101 112 local attachments = getEmailAttachments(email)
102 113 if attachments ~= "" then
103   - email:setProperty("status", 2)
  114 + email:setProperty("status", 2, true)
104 115 email:log(role, 2)
105 116 ids[email:getProperty("id")] = 1
106 117 for key, v in pairs(attachments:toNumMap()) do
... ... @@ -120,16 +131,15 @@ function _M.drawAttachRpc(agent, data)
120 131 local msg = MsgPack.unpack(data)
121 132 local id = msg.id
122 133  
123   - local rds = string.format(R_EMAIL_ITEM, roleId, id)
124 134  
125   - local email = require("models.Email").new({key = rds})
  135 + local email = require("models.Email").new({key = string.format("%d", id), id = id})
126 136 if not email:load() then return end
127 137  
128 138 local attachments = getEmailAttachments(email)
129 139 if attachments == "" then return end
130 140  
131 141 local reward, change = role:award(attachments, {log = {desc = "draw_attach", int1 = id}})
132   - email:setProperty("status", 2)
  142 + email:setProperty("status", 2, true)
133 143 email:log(role, 2)
134 144 SendPacket(actionCodes.Email_drawAttachRpc, MsgPack.pack({reward = reward, change = change}))
135 145 role:mylog("mail_action", {desc = "draw_attach", int1 = id, key1 = email:getProperty("title"), key2 = attachments})
... ... @@ -143,11 +153,10 @@ function _M.checkRpc(agent, data)
143 153 local msg = MsgPack.unpack(data)
144 154 local id = msg.id
145 155  
146   - local emailRds = string.format("email:%d:%s", roleId, id)
147   - local email = require("models.Email").new({key = emailRds})
  156 + local email = require("models.Email").new({key = string.format("%d", id), id = id})
148 157 if not email:load() then return end
149 158  
150   - email:setProperty("status", 1)
  159 + email:setProperty("status", 1, true)
151 160 email:log(role, 1)
152 161 role:mylog("mail_action", {desc = "check_mail", int1 = id})
153 162  
... ... @@ -158,33 +167,21 @@ end
158 167 function _M.delRpc(agent, data)
159 168 local role = agent.role
160 169 local roleId = role:getProperty("id")
161   -
162   - local rds = string.format(R_EMAIL, roleId)
163   - local ids = redisproxy:lrange(rds, 0, EMAIL_LIMIT - 1)
164   - local now = skynet.timex()
165 170 local result = {}
166   - local emailSet = csvdb["emailCsv"]
167   -
168   - redisproxy:pipelining(function (red)
169   - for _, id in ipairs(ids) do
170   - local emailRds = string.format("email:%d:%s", roleId, id)
171   - local email = require("models.Email").new({key = emailRds})
172   - if email:load() then
173   - local status = email:getProperty("status")
174   - local attachments = email:getProperty("attachments")
175   - local emailData = emailSet[email:getProperty("emailId")]
176   - if emailData and attachments:len() == 0 then
177   - attachments = emailData.attachment
178   - end
179   - if status == 2 or (status == 1 and attachments:len() == 0) then
180   - email:log(role, 3)
181   - red:lrem(rds, 0, id)
182   - red:del(emailRds)
183   - result[tonum(id)] = 1
184   - end
185   - end
  171 + local tmp = {}
  172 + local emails = loadEmails(roleId)
  173 + for _, email in ipairs(emails) do
  174 + local attachments = getEmailAttachments(email)
  175 +
  176 + if email:getProperty("status") == 2 or (attachments == "" and email:getProperty("status") == 1) then
  177 + result[email:getProperty("id")] = 1
  178 + email:log(role, 3)
  179 + table.insert(tmp, email:getProperty("id"))
186 180 end
187   - end)
  181 + end
  182 +
  183 + mysqlproxy:query(string.format("DELETE FROM `Email` WHERE `id` in (%s)", table.concat(tmp, ",")))
  184 +
188 185 for delId, _ in ipairs(result) do
189 186 role:mylog("mail_action", {desc = "del_mail", int1 = delId})
190 187 end
... ...
src/actions/FriendAction.lua
... ... @@ -11,6 +11,7 @@ local table_unpack = table.unpack
11 11 local table_find = table.find
12 12 local table_nums = table.nums
13 13 local math_random = math.randomInt
  14 +require "utils.MysqlUtil"
14 15  
15 16 local _M = {}
16 17  
... ... @@ -23,12 +24,6 @@ local function formatArray(tb)
23 24 return t
24 25 end
25 26  
26   -local function checkFriendLimit(roleId)
27   - roleId = tonumber(roleId)
28   - local count = redisproxy:hlen(FRIEND_KEY:format(roleId))
29   - return count < globalCsv.friendListLimit
30   -end
31   -
32 27  
33 28 local function addAndCheckApplyLimit(roleId, objId)
34 29 roleId = tonumber(roleId)
... ... @@ -78,7 +73,7 @@ function _M.searchRpc(agent, data)
78 73 local objIds = {}
79 74 local tempId = tonumber(key)
80 75 if tempId then
81   - if redisproxy:exists(string_format("role:%d", tempId)) then
  76 + if roleExists(tempId) then
82 77 objIds[tempId] = 1
83 78 end
84 79 end
... ... @@ -92,13 +87,13 @@ function _M.searchRpc(agent, data)
92 87 for objId, _ in pairs(objIds) do
93 88 local online, info = getRoleInfo(objId)
94 89 local redret = redisproxy:pipelining(function (red)
95   - red:hexists(FRIEND_KEY:format(roleId), objId)
96 90 red:zscore(FRIEND_APPLY_KEY:format(objId), roleId)
97 91 red:sismember(FRIEND_BLACK_KEY:format(roleId), objId)
98 92 end)
99   - local isFriend = redret[1] == 1 and 1 or nil
100   - local hadApply = redret[2] and 1 or nil
101   - local inBlack = redret[3] == 1 and 1 or nil
  93 +
  94 + local isFriend = role.friends[objId] and 1 or nil
  95 + local hadApply = redret[1] and 1 or nil
  96 + local inBlack = redret[2] == 1 and 1 or nil
102 97  
103 98 table.insert(searchList, table_merge({
104 99 roleId = objId,
... ... @@ -123,6 +118,7 @@ function _M.applyRpc(agent, data)
123 118  
124 119 local msg = MsgPack.unpack(data)
125 120 local objectId = msg.roleId
  121 + dump(msg)
126 122  
127 123 if objectId == roleId then
128 124 return
... ... @@ -130,44 +126,41 @@ function _M.applyRpc(agent, data)
130 126  
131 127 local result = nil
132 128 local redret = redisproxy:pipelining(function (red)
133   - red:exists(string_format("role:%d", objectId))
134   - red:hexists(FRIEND_KEY:format(roleId), objectId)
135 129 red:zscore(FRIEND_APPLY_KEY:format(objectId), roleId)
136 130 red:sismember(FRIEND_BLACK_KEY:format(objectId), roleId)
137 131 red:sismember(FRIEND_BLACK_KEY:format(roleId), objectId)
138   - red:hlen(FRIEND_KEY:format(roleId))
139   - red:hlen(FRIEND_KEY:format(objectId))
140 132 end)
  133 + dump(redret)
141 134  
142 135 -- 玩家id不存在
143   - if not result and redret[1] ~= 1 then
  136 + if not result and not roleExists(objectId) then
144 137 result = 1
145 138 end
146 139  
147 140 -- 已经有这个好友
148   - if not result and redret[2] == 1 then
  141 + if not result and role.friends[objectId] then
149 142 result = 2
150 143 end
151 144 -- 已经申请
152   - if not result and redret[3] then
  145 + if not result and redret[1] then
153 146 result = 3
154 147 end
155 148 -- 对方把你拉黑
156   - if not result and redret[4] == 1 then
  149 + if not result and redret[2] == 1 then
157 150 result = 4
158 151 end
159 152  
160 153 -- 你把对方拉黑了
161   - if not result and redret[5] == 1 then
  154 + if not result and redret[3] == 1 then
162 155 result = 5
163 156 end
164 157  
165 158 -- 自己好友已经满
166   - if not result and redret[6] >= globalCsv.friendListLimit then
  159 + if not result and table.numbers(role.friends) >= globalCsv.friendListLimit then
167 160 result = 6
168 161 end
169 162 -- 对方的好友已满
170   - if not result and redret[7] >= globalCsv.friendListLimit then
  163 + if not result and getFriendCount(objectId) >= globalCsv.friendListLimit then
171 164 result = 7
172 165 end
173 166  
... ... @@ -209,29 +202,28 @@ function _M.applyListRpc(agent, data)
209 202 return true
210 203 end
211 204  
212   -local function checkHandleApply(roleId, objectId, needAddNew)
  205 +local function checkHandleApply(role, objectId, needAddNew)
213 206 needAddNew = needAddNew or 0
  207 + local roleId = role:getProperty("id")
214 208 local redret = redisproxy:pipelining(function (red)
215   - red:hlen(FRIEND_KEY:format(roleId))
216   - red:hlen(FRIEND_KEY:format(objectId))
217 209 red:sismember(FRIEND_BLACK_KEY:format(objectId), roleId)
218 210 red:sismember(FRIEND_BLACK_KEY:format(roleId), objectId)
219 211 end)
220 212  
221 213 --自己好友满了
222   - if (redret[1] + needAddNew) >= globalCsv.friendListLimit then
  214 + if (table.numbers(role.friends) + needAddNew) >= globalCsv.friendListLimit then
223 215 return 1
224 216 end
225 217 -- 对方好友满了
226   - if redret[2] >= globalCsv.friendListLimit then
  218 + if getFriendCount(objectId) >= globalCsv.friendListLimit then
227 219 return 2
228 220 end
229 221 -- 对方把你拉黑
230   - if redret[3] == 1 then
  222 + if redret[1] == 1 then
231 223 return 3
232 224 end
233 225 -- 你把对方拉黑了
234   - if redret[4] == 1 then
  226 + if redret[2] == 1 then
235 227 return 4
236 228 end
237 229  
... ... @@ -255,14 +247,13 @@ function _M.handleApplyRpc(agent, data)
255 247 return
256 248 end
257 249 local curCount
258   - result, curCount = checkHandleApply(roleId, objectId)
  250 + result, curCount = checkHandleApply(role, objectId)
259 251  
260 252 if not result then
261 253 redisproxy:pipelining(function (red)
262 254 red:ZREM(FRIEND_APPLY_KEY:format(roleId), objectId)
263 255 red:ZREM(FRIEND_APPLY_KEY:format(objectId), roleId)
264   - red:hsetnx(FRIEND_KEY:format(roleId), objectId, newTag)
265   - red:hsetnx(FRIEND_KEY:format(objectId), roleId, newTag)--告知对放有新好友
  256 + addFriend(roleId, objectId)
266 257 end)
267 258 local myInfo = role:friendSInfo()
268 259 myInfo.online = true
... ... @@ -310,7 +301,7 @@ function _M.handleApplyRpc(agent, data)
310 301 local needAddInfo = {}
311 302 for _, objId in ipairs(allIds) do
312 303 objId = tonumber(objId)
313   - local cr, curCount = checkHandleApply(roleId, objId, #needAdd)
  304 + local cr, curCount = checkHandleApply(role, objId, #needAdd)
314 305 if not cr then
315 306 table.insert(needAdd, objId)
316 307 table.insert(needAddMy, objId)
... ... @@ -335,12 +326,9 @@ function _M.handleApplyRpc(agent, data)
335 326 red:ZREM(FRIEND_APPLY_KEY:format(roleId), table_unpack(needAdd))
336 327 for _, objectId in pairs(needAdd) do
337 328 red:ZREM(FRIEND_APPLY_KEY:format(objectId), roleId)
338   - red:hsetnx(FRIEND_KEY:format(objectId), roleId, newTag)--告知对放有新好友
  329 + addFriend(roleId, objectId)
339 330 end
340 331 end
341   - if next(needAddMy) then
342   - red:HMSET(FRIEND_KEY:format(roleId), table_unpack(needAddMy))
343   - end
344 332 end)
345 333 local myInfo = role:friendSInfo()
346 334 myInfo.roleId = roleId
... ... @@ -373,27 +361,21 @@ function _M.listRpc(agent, data)
373 361  
374 362 local friendList = {}
375 363 local redret = redisproxy:pipelining(function (red)
376   - red:hgetall(FRIEND_KEY:format(roleId))
377 364 red:SMEMBERS(FRIEND_POINT:format(roleId))
378 365 end)
379 366  
380   - local friends = redret[1]
381   - local fpoint = formatArray(redret[2])
  367 + local fpoint = formatArray(redret[1])
382 368 local hadGet = role.dailyData:getProperty("getFP")
383 369 local hadGive = role.dailyData:getProperty("giveFP")
384 370  
385   - local clearRed = {}
386   - for i = 1, #friends, 2 do
387   - local id = friends[i]
388   - local data = friends[i + 1]
389   - local friendInfo = MsgPack.unpack(data)
390   - id = tonumber(id)
  371 + local addNew = false
  372 + for id, friend in pairs(role.friends) do
391 373 local online, info = getRoleInfo(id)
392 374 local roleInfo = {
393 375 roleId = id,
394 376 online = online,
395   - addTime = friendInfo[1],
396   - isNew = friendInfo[2],
  377 + addTime = friend:getProperty("addTime"),
  378 + isNew = friend:getProperty("isNew"),
397 379 pGive = hadGive[id],
398 380 pGet = hadGet[id] and -1 or (fpoint[id] and 1 or nil)
399 381 }
... ... @@ -401,14 +383,12 @@ function _M.listRpc(agent, data)
401 383  
402 384 friendList[#friendList + 1] = roleInfo
403 385  
404   - if friendInfo[2] then
405   - friendInfo[2] = nil --清除新好友标记
406   - clearRed[#clearRed + 1] = id
407   - clearRed[#clearRed + 1] = MsgPack.pack(friendInfo)
  386 + if roleInfo.isNew then
  387 + friend:setProperty("isNew", 0)
  388 + addNew = true
408 389 end
409 390 end
410   - if next(clearRed) then
411   - redisproxy:hmset(FRIEND_KEY:format(roleId), table_unpack(clearRed)) --清除新好友标记
  391 + if addNew then
412 392 role:checkTaskEnter("AddFriend", {count = #friendList})
413 393 end
414 394  
... ... @@ -421,14 +401,14 @@ function _M.deleteRpc(agent, data)
421 401 local roleId = role:getProperty("id")
422 402 local msg = MsgPack.unpack(data)
423 403 local objectId = msg.roleId
424   - if not redisproxy:exists(string_format("role:%d", objectId)) then
  404 + if not roleExists(objectId) then
425 405 return
426 406 end
427 407 -- 是否在好友列表中
428   - if redisproxy:hexists(FRIEND_KEY:format(roleId), objectId) then
  408 + if role.friends[objectId] then
  409 + role.friends[objectId] = nil
429 410 redisproxy:pipelining(function (red)
430   - red:hdel(FRIEND_KEY:format(roleId), objectId)
431   - red:hdel(FRIEND_KEY:format(objectId), roleId)
  411 + delFriend(roleId, objectId)
432 412 red:ZREM(FRIEND_APPLY_KEY:format(roleId), objectId)
433 413 red:ZREM(FRIEND_APPLY_KEY:format(objectId), roleId)
434 414 end)
... ... @@ -450,7 +430,7 @@ function _M.blockRpc(agent, data)
450 430 local msg = MsgPack.unpack(data)
451 431 local cmd = msg.cmd
452 432 local objectId = msg.roleId
453   - if not redisproxy:exists(string_format("role:%d", objectId)) then
  433 + if not roleExists(objectId) then
454 434 return
455 435 end
456 436  
... ... @@ -463,8 +443,7 @@ function _M.blockRpc(agent, data)
463 443 -- 删除好友
464 444 if not result then
465 445 redisproxy:pipelining(function (red)
466   - red:hdel(FRIEND_KEY:format(roleId), objectId)
467   - red:hdel(FRIEND_KEY:format(objectId), roleId)
  446 + delFriend(roleId, objectId)
468 447 red:ZREM(FRIEND_APPLY_KEY:format(roleId), objectId)
469 448 red:ZREM(FRIEND_APPLY_KEY:format(objectId), roleId)
470 449 red:sadd(FRIEND_BLACK_KEY:format(roleId), objectId)
... ... @@ -511,19 +490,19 @@ function _M.infoRpc(agent, data)
511 490 local roleId = role:getProperty("id")
512 491 local msg = MsgPack.unpack(data)
513 492 local objectId = msg.roleId
514   - if not redisproxy:exists(string_format("role:%d", objectId)) then
  493 +
  494 + if not roleExists(objectId) then
515 495 return
516 496 end
517 497  
518 498 local online, info = getRoleAllInfo(objectId)
519 499 local redret = redisproxy:pipelining(function (red)
520   - red:hexists(FRIEND_KEY:format(roleId), objectId)
521 500 red:zscore(FRIEND_APPLY_KEY:format(objectId), roleId)
522 501 red:sismember(FRIEND_BLACK_KEY:format(roleId), objectId)
523 502 end)
524   - local isFriend = redret[1] == 1 and 1 or nil
525   - local hadApply = redret[2] == 1 and 1 or nil
526   - local inBlack = redret[3] == 1 and 1 or nil
  503 + local isFriend = role.friends[objectId] and 1 or nil
  504 + local hadApply = redret[1] == 1 and 1 or nil
  505 + local inBlack = redret[2] == 1 and 1 or nil
527 506  
528 507 local objInfo = table_merge({
529 508 roleId = objectId,
... ... @@ -551,7 +530,7 @@ function _M.pointRpc(agent, data)
551 530 if not result and giveP[objId] then
552 531 result = 1
553 532 end
554   - if not result and not redisproxy:hexists(FRIEND_KEY:format(roleId), objId) then
  533 + if not result and not role.friends[objId] then
555 534 result = 2
556 535 end
557 536 if not result then
... ... @@ -586,11 +565,9 @@ function _M.pointRpc(agent, data)
586 565 elseif cmd == 3 then -- 一键赠送领取
587 566 -- 赠送
588 567 local giveP = role.dailyData:getProperty("giveFP")
589   - local friends = redisproxy:hgetall(FRIEND_KEY:format(roleId))
590 568 local change = 0
591 569 redisproxy:pipelining(function(red)
592   - for i = 1, #friends , 2 do
593   - local objId = tonumber(friends[i])
  570 + for objId, friend in pairs(role.friends) do
594 571 if not giveP[objId] then
595 572 giveP[objId] = 1
596 573 change = change + 1
... ... @@ -645,22 +622,17 @@ function _M.randomRpc(agent, data)
645 622 local roleId = role:getProperty("id")
646 623  
647 624 local redret = redisproxy:pipelining(function (red)
648   - red:hgetall(FRIEND_KEY:format(roleId))
649 625 red:zrevrange(FRIEND_RECOMMEND, 0, globalCsv.friendRecommendLimit + globalCsv.friendListLimit + 10) --扩充10个
650 626 red:SMEMBERS(FRIEND_BLACK_KEY:format(roleId))
651 627 end)
652   - local friends = {}
653   - for i = 1, #redret[1], 2 do
654   - friends[tonumber(redret[1][i])] = redret[1][i + 1]
655   - end
656 628  
657   - local newList = redret[2]
658   - local hadBlack = formatArray(redret[3])
  629 + local newList = redret[1]
  630 + local hadBlack = formatArray(redret[2])
659 631  
660 632 local needRoleIds = {}
661 633 for _, newId in pairs(newList) do
662 634 local numNewId = tonumber(newId)
663   - if numNewId ~= roleId and not friends[numNewId] and not hadBlack[numNewId] then
  635 + if numNewId ~= roleId and not role.friends[numNewId] and not hadBlack[numNewId] then
664 636 table.insert(needRoleIds, numNewId)
665 637 end
666 638 end
... ...
src/actions/GmAction.lua
... ... @@ -519,7 +519,7 @@ table.insert(helpDes, {&quot;发送邮件&quot;, &quot;email&quot;, &quot;id&quot;, &quot;奖励&quot;})
519 519 function _M.email(role, pms)
520 520 local id = tonum(pms.pm1, 0)
521 521 local reward = pms.pm2
522   - redisproxy:insertEmail({
  522 + mysqlproxy:insertEmail({
523 523 roleId = role:getProperty("id"),
524 524 emailId = id,
525 525 createtime = skynet.timex(),
... ...
src/actions/HangAction.lua
... ... @@ -22,7 +22,8 @@ local function checkReward(role)
22 22 return false
23 23 end
24 24 local carbonData = csvdb["idle_battleCsv"][hangInfo.carbonId]
25   - local expCarbonData = csvdb["idle_battleCsv"][hangInfo.expCarbonId]
  25 + --local expCarbonData = csvdb["idle_battleCsv"][hangInfo.expCarbonId]
  26 + local expCarbonData = hangInfo.expData or {}
26 27 local nowCoinTime = math.min(skynet.timex(), hangInfo.endCoinTime or 0)
27 28 local nowItemTime = math.min(skynet.timex(), hangInfo.endItemTime or 0)
28 29  
... ... @@ -42,9 +43,9 @@ local function checkReward(role)
42 43  
43 44 local items = role:getProperty("hangBag")
44 45 coinCount = (coinCount + coinDoubleCount) * expCoef
45   - items[ItemId.Gold] = math.floor((items[ItemId.Gold] or 0) + coinCount * expCarbonData.money)
46   - items[ItemId.Exp] = math.floor((items[ItemId.Exp] or 0) + coinCount * expCarbonData.exp)
47   - items[ItemId.PlayerExp] = math.floor((items[ItemId.PlayerExp] or 0) + coinCount * expCarbonData.playerExp)
  46 + items[ItemId.Gold] = math.floor((items[ItemId.Gold] or 0) + coinCount * (expCarbonData.money or 0))
  47 + items[ItemId.Exp] = math.floor((items[ItemId.Exp] or 0) + coinCount * (expCarbonData.exp or 0))
  48 + items[ItemId.PlayerExp] = math.floor((items[ItemId.PlayerExp] or 0) + (coinCount * expCarbonData.playerExp or 0))
48 49  
49 50 local pool = {}
50 51 for _, temp in pairs(carbonData.item:toArray()) do
... ... @@ -137,6 +138,15 @@ function _M.startRpc( agent, data )
137 138 if not role:checkHangPass(preCarbonId) then return 2 end
138 139 end
139 140  
  141 + local carbonId = msg.carbonId -- 解锁章节id
  142 + local condition = globalCsv.idle_chapter_unlock[carbonId]
  143 + if condition then
  144 + local unlockChapter = role:getProperty("unlockChap")
  145 + if not unlockChapter[carbonId] then
  146 + return 3
  147 + end
  148 + end
  149 +
140 150 if checkReward(role) then
141 151 role:updateProperty({field = "hangBag", value = role:getProperty("hangBag")})
142 152 end
... ... @@ -144,7 +154,7 @@ function _M.startRpc( agent, data )
144 154 local hangInfo = role:getProperty("hangInfo")
145 155 local isNew = not hangInfo.carbonId
146 156 hangInfo.carbonId = carbonId
147   - hangInfo.expCarbonId = isNew and carbonId or hangInfo.expCarbonId
  157 + --hangInfo.expCarbonId = isNew and carbonId or hangInfo.expCarbonId
148 158 local nowTime = skynet.timex()
149 159 if isNew then
150 160 hangInfo.coinTime = nowTime
... ... @@ -279,15 +289,25 @@ function _M.endBattleRpc(agent, data)
279 289 local nextCarbonId = role:getNextCarbonId(carbonId)
280 290 -- 设置挂机关卡
281 291 if isWin then --and (hangInfo.carbonId or 0) < nextCarbonId then
282   - if not hangInfo.expCarbonId then
283   - hangInfo.expCarbonId = carbonId
284   - else
285   - local oldCarbonData = csvdb["idle_battleCsv"][hangInfo.expCarbonId]
286   - local newCarbonData = csvdb["idle_battleCsv"][carbonId]
287   - if oldCarbonData.money < newCarbonData.money then
288   - hangInfo.expCarbonId = carbonId
289   - end
  292 + local newCarbonData = csvdb["idle_battleCsv"][carbonId]
  293 + if newCarbonData then
  294 + local expData = hangInfo.expData or {}
  295 + expData.exp = (expData.exp or 0) + newCarbonData.exp
  296 + expData.money = (expData.money or 0) + newCarbonData.money
  297 + expData.playerExp = (expData.playerExp or 0) + newCarbonData.playerExp
  298 + hangInfo.expData = expData
290 299 end
  300 +
  301 + --if not hangInfo.expCarbonId then
  302 + -- hangInfo.expCarbonId = carbonId
  303 + --else
  304 + -- local oldCarbonData = csvdb["idle_battleCsv"][hangInfo.expCarbonId]
  305 + -- local newCarbonData = csvdb["idle_battleCsv"][carbonId]
  306 + -- if oldCarbonData.money < newCarbonData.money then
  307 + -- hangInfo.expCarbonId = carbonId
  308 + -- end
  309 + --end
  310 +
291 311 --local cfg = csvdb["idle_battleCsv"][nextCarbonId]
292 312 --if cfg then
293 313 -- hangInfo.bossTime = skynet.timex() + cfg.idle_time
... ... @@ -418,14 +438,15 @@ function _M.quickRpc(agent , data)
418 438 local hangInfo = role:getProperty("hangInfo")
419 439 if not hangInfo.carbonId then return end
420 440 local carbonData = csvdb["idle_battleCsv"][hangInfo.carbonId]
421   - local expCarbonData = csvdb["idle_battleCsv"][hangInfo.expCarbonId]
  441 + --local expCarbonData = csvdb["idle_battleCsv"][hangInfo.expCarbonId]
  442 + local expCarbonData = hangInfo.expData or {}
422 443  
423 444 local curCount = role.dailyData:getProperty("hangQC") + 1
424 445 local costs = globalCsv.idle_quickproduce_cost:toArray(true, "=")
425 446 if not costs[curCount] then return end
426 447 if costs[curCount] > 0 then
427   - if not role:checkItemEnough({[ItemId.Diamond] = costs[curCount]}) then return end
428   - role:costItems({[ItemId.Diamond] = costs[curCount]}, {log = {desc = "quickHang", int1 = hangInfo.carbonId}})
  448 + if not role:checkItemEnough({[ItemId.Jade] = costs[curCount]}) then return end
  449 + role:costItems({[ItemId.Jade] = costs[curCount]}, {log = {desc = "quickHang", int1 = hangInfo.carbonId}})
429 450 end
430 451  
431 452 role.dailyData:updateProperty({field = "hangQC", value = curCount})
... ... @@ -435,9 +456,9 @@ function _M.quickRpc(agent , data)
435 456  
436 457 local coinCount = math.floor(time / globalCsv.idle_money_produce_cd)
437 458 local itemCount = math.floor(time / globalCsv.idle_item_produce_cd)
438   - reward[ItemId.Gold] = math.floor((reward[ItemId.Gold] or 0) + coinCount * expCarbonData.money)
439   - reward[ItemId.Exp] = math.floor((reward[ItemId.Exp] or 0) + coinCount * expCarbonData.exp)
440   - reward[ItemId.PlayerExp] = math.floor((reward[ItemId.PlayerExp] or 0) + coinCount * expCarbonData.playerExp)
  459 + reward[ItemId.Gold] = math.floor((reward[ItemId.Gold] or 0) + coinCount * (expCarbonData.money or 0))
  460 + reward[ItemId.Exp] = math.floor((reward[ItemId.Exp] or 0) + coinCount * (expCarbonData.exp or 0))
  461 + reward[ItemId.PlayerExp] = math.floor((reward[ItemId.PlayerExp] or 0) + coinCount * (expCarbonData.playerExp or 0))
441 462  
442 463 local pool = {}
443 464 for _, temp in pairs(carbonData.item:toArray()) do
... ... @@ -502,9 +523,9 @@ function _M.buyBonusCountRpc(agent, data)
502 523 local lastCount = globalCsv.bonus_daily_buy_count * coef + extraCnt - bonusC[btype]["b"]
503 524 if math.illegalNum(count, 1, lastCount) then return 1 end
504 525  
505   - if not role:checkItemEnough({[ItemId.Diamond] = globalCsv.bonus_buy_cost * count}) then return 2 end
  526 + if not role:checkItemEnough({[ItemId.Jade] = globalCsv.bonus_buy_cost * count}) then return 2 end
506 527  
507   - role:costItems({[ItemId.Diamond] = globalCsv.bonus_buy_cost * count}, {log = {desc = "buyBonusCount", int1 = btype, int2 = count}})
  528 + role:costItems({[ItemId.Jade] = globalCsv.bonus_buy_cost * count}, {log = {desc = "buyBonusCount", int1 = btype, int2 = count}})
508 529 bonusC[btype]["b"] = bonusC[btype]["b"] + count
509 530 bonusC[btype]["c"] = bonusC[btype]["c"] - count
510 531  
... ... @@ -1022,11 +1043,11 @@ function _M.bagFieldRpc(agent, data)
1022 1043 if not costD then
1023 1044 return 1
1024 1045 end
1025   - if costD ~= 0 and not role:checkItemEnough({[ItemId.Diamond] = costD}) then
  1046 + if costD ~= 0 and not role:checkItemEnough({[ItemId.Jade] = costD}) then
1026 1047 return 2
1027 1048 end
1028 1049 role:updateProperty({field = "hangBagLimit", value = curBL + 1})
1029   - role:costItems({[ItemId.Diamond] = costD}, {log = {desc = "bagField"}})
  1050 + role:costItems({[ItemId.Jade] = costD}, {log = {desc = "bagField"}})
1030 1051 SendPacket(actionCodes.Hang_bagFieldRpc, '')
1031 1052 return true
1032 1053 end
... ... @@ -1080,4 +1101,28 @@ function _M.selectTeamRpc(agent, data)
1080 1101 return true
1081 1102 end
1082 1103  
  1104 +function _M.unlockChapterRpc(agent, data)
  1105 + local role = agent.role
  1106 + local msg = MsgPack.unpack(data)
  1107 + local carbonId = msg.carbonId -- 解锁章节id
  1108 + local condition = globalCsv.idle_chapter_unlock[carbonId]
  1109 + if not condition then return 1 end
  1110 + local conditionMap = condition:toArray(true, "=")
  1111 + local count, level = conditionMap[1],conditionMap[2]
  1112 + local cnt = 0
  1113 + for _, hero in pairs(role.heros) do
  1114 + if hero:getProperty("level") >= level then
  1115 + cnt = cnt + 1
  1116 + end
  1117 + end
  1118 + if cnt < count then return 2 end
  1119 +
  1120 + local unlockChapter = role:getProperty("unlockChap")
  1121 + unlockChapter[carbonId] = 1
  1122 + role:updateProperty({field="unlockChap", value = unlockChapter})
  1123 +
  1124 + SendPacket(actionCodes.Hang_unlockChapterRpc, '')
  1125 + return true
  1126 +end
  1127 +
1083 1128 return _M
... ...
src/actions/HeroAction.lua
... ... @@ -35,10 +35,18 @@ function _M.levelUpRpc( agent, data )
35 35 local hero = role.heros[msg.id]
36 36 if not hero then return 1 end
37 37  
38   - if hero:getProperty("level") >= hero:getMaxLevel() then return 2 end
39   - local curData = csvdb["unit_expCsv"][hero:getProperty("level")]
  38 + local level = hero:getProperty("level")
  39 + if level >= hero:getMaxLevel() then return 2 end
  40 + local curData = csvdb["unit_expCsv"][level]
40 41 local cost = {[ItemId.Exp] = curData.exp, [ItemId.Gold] = curData.gold}
41 42 if not role:checkItemEnough(cost) then return 3 end
  43 +
  44 + -- 通过指定关卡后才能升级英雄等级
  45 + local pass = globalCsv.unit_exp_level_pass[level + 1]
  46 + if pass then
  47 + if not role:checkHangPass(pass) then return 4 end
  48 + end
  49 +
42 50 role:costItems(cost, {log = {desc = "heroLevelUp", int1 = msg.id, int2 = hero:getProperty("type")}})
43 51  
44 52 local oldAttr = hero:getTotalAttrs()
... ... @@ -69,12 +77,20 @@ function _M.breakRpc( agent, data )
69 77 local hero = role.heros[msg.id]
70 78 if not hero then return 1 end
71 79  
  80 + local breakL = hero:getProperty("breakL")
72 81 if hero:getProperty("level") < hero:getMaxLevel() then return 2 end
73   - if hero:getProperty("breakL") >= #csvdb["unit_breakCsv"] then return 3 end
74   - local curData = csvdb["unit_breakCsv"][hero:getProperty("breakL")]
  82 + if breakL >= #csvdb["unit_breakCsv"] then return 3 end
  83 + local curData = csvdb["unit_breakCsv"][breakL]
75 84 if hero:getProperty("wakeL") < curData["starLimit"] then return 4 end
76 85 local cost = {[ItemId.BreakCost] = curData.cost, [ItemId.Gold] = curData.gold}
77 86 if not role:checkItemEnough(cost) then return 4 end
  87 +
  88 + -- 通过指定关卡后才能突破英雄
  89 + local pass = globalCsv.unit_break_level_pass[breakL + 1]
  90 + if pass then
  91 + if not role:checkHangPass(pass) then return 4 end
  92 + end
  93 +
78 94 role:costItems(cost, {log = {desc = "heroBreak", int1 = msg.id, int2 = hero:getProperty("type")}})
79 95 local oldAttr = hero:getTotalAttrs()
80 96 hero:updateProperty({field = "breakL", delta = 1})
... ... @@ -648,11 +664,11 @@ function _M.getResetRewardRpc(agent, data)
648 664 totalCost[costArr[1]] = costArr[2]
649 665 else
650 666 local diamond = (costArr[2] - itemCount) * costArr[3]
651   - if role:getItemCount(ItemId.Diamond) < diamond then
  667 + if role:getItemCount(ItemId.Jade) < diamond then
652 668 return 1
653 669 end
654 670 totalCost[costArr[1]] = itemCount
655   - totalCost[ItemId.Diamond] = diamond
  671 + totalCost[ItemId.Jade] = diamond
656 672 end
657 673  
658 674 --if pay and not role:costDiamond({count = globalCsv.unit_heroBack_cost or 200, log = {desc = "resetHero", int1 = msg.id}}) then
... ...
src/actions/HttpAction.lua
... ... @@ -134,7 +134,37 @@ function _M.gm_action(query)
134 134 return isOn
135 135 end
136 136 -- 离线操作
137   - local role = require("models.Role").new({key = string.format("role:%d", query.id)})
  137 + local role = require("models.Role").new({key = string.format("%d", query.id)})
  138 + local ret = role:load()
  139 + if not ret then
  140 + return "角色不存在"
  141 + end
  142 + role:loadAll()
  143 + role:startActionUcode()
  144 + local status = gmFuncs[query.cmd](role, query)
  145 + role:endActionUcode()
  146 +
  147 + return status
  148 +end
  149 +
  150 +function _M.pay_action(query)
  151 + local gmFuncs = require "actions.GmAction"
  152 + if not query.cmd or not query.order or not gmFuncs[query.cmd] then return "指令不存在" end
  153 + local mysqlproxy = require "shared.mysqlproxy"
  154 + local res = mysqlproxy:query(string.format("SELECT roleid FROM `Order` WHERE `id` = %s", query.order))
  155 + if res[1] then
  156 + query.id = res[1]["roleid"]
  157 + else
  158 + return "订单非法"
  159 + end
  160 + -- 在线操作
  161 + query.id = tonumber(query.id)
  162 + local isOn = proc_online(query.cmd, query.id, query)
  163 + if isOn ~= "not_online" then
  164 + return isOn
  165 + end
  166 + -- 离线操作
  167 + local role = require("models.Role").new({key = string.format("%d", query.id)})
138 168 local ret = role:load()
139 169 if not ret then
140 170 return "角色不存在"
... ...
src/actions/PvpAction.lua
... ... @@ -241,7 +241,7 @@ function _M.buyCountRpc(agent, data)
241 241 return 1
242 242 end
243 243  
244   - local cost = {[ItemId.Diamond] = globalCsv.pvp_buy_cost * count}
  244 + local cost = {[ItemId.Jade] = globalCsv.pvp_buy_cost * count}
245 245 if not role:checkItemEnough(cost) then return 2 end
246 246 role:costItems(cost, {log = {desc = "buyPvpKey"}})
247 247 role:award({[ItemId.PvpKey] = count}, {log = {desc = "buyPvpKey"}})
... ...
src/actions/RoleAction.lua
... ... @@ -14,6 +14,8 @@ local table_insert = table.insert
14 14 local tconcat = table.concat
15 15 local httpc = require("http.httpc")
16 16  
  17 +require "utils.MysqlUtil"
  18 +
17 19 local WAVE_HERO_NUMS = 150
18 20 local WAVE_RUNE_NUMS = 150
19 21 local WAVE_SPARK_NUMS = 150
... ... @@ -85,8 +87,8 @@ function _M.loginRpc( agent, data )
85 87 local role = agent.role
86 88 -- 2
87 89 if not role then
88   - local roleKey = string_format("role:%d", roleId)
89   - if not redisproxy:exists(roleKey) then
  90 + local roleKey = string_format("%d", roleId)
  91 + if not roleExists(roleId) then
90 92 response.result = "DB_ERROR"
91 93 SendPacket(actionCodes.Role_loginRpc, MsgPack.pack(response))
92 94 return true
... ... @@ -155,7 +157,7 @@ function _M.loginRpc( agent, data )
155 157 end
156 158 end
157 159  
158   - SERV_OPEN = redisproxy:hget("autoincrement_set", "server_start")
  160 + SERV_OPEN = getDbCfgVal("server_info", "server_start", "str_value")
159 161  
160 162 role:changeStructVersion() -- 数据结构 版本更新
161 163 role:getAdvData(true) -- 清掉不合格的数据
... ... @@ -344,7 +346,8 @@ function _M.createRpc(agent, data)
344 346  
345 347 -- 再次检查uid
346 348 local uid = tostring(msg.uid)
347   - local user = redisproxy:get(string_format("uid:%s", uid))
  349 + --local user = redisproxy:get(string_format("uid:%s", uid))
  350 + local res, user = roleUidExists(uid)
348 351 if user then
349 352 response.result = "SUCCESS"
350 353 response.roleName = user
... ... @@ -367,7 +370,7 @@ function _M.createRpc(agent, data)
367 370 end
368 371 local roleName = setRoleName(msg.uid, roleId)
369 372 local newRole = require("models.Role").new({
370   - key = string_format("role:%d", roleId),
  373 + key = string_format("%d", roleId),
371 374 id = roleId,
372 375 uid = tostring(msg.uid),
373 376 sid = msg.subId or 0,
... ... @@ -387,6 +390,7 @@ function _M.createRpc(agent, data)
387 390 SendPacket(actionCodes.Role_createRpc, MsgPack.pack(response))
388 391 return true
389 392 end
  393 + --newRole:loadRoleIncre()
390 394 newRole:startActionUcode()
391 395 newRole.sysVersion = msg.sysVersion
392 396 newRole.ip = agent.ip:toArray(false, ":")[1]
... ... @@ -395,7 +399,7 @@ function _M.createRpc(agent, data)
395 399  
396 400 newRole:award(globalCsv.birthItem, {log = {desc = "birth"}, notNotify = true})
397 401 -- 欢迎邮件
398   - redisproxy:insertEmail({roleId = roleId, emailId = 1})
  402 + mysqlproxy:insertEmail({roleId = roleId, emailId = 1})
399 403  
400 404 if msg.newuser then
401 405 newRole:log("onCreateAccount")
... ... @@ -405,6 +409,8 @@ function _M.createRpc(agent, data)
405 409 if msg.newdevice then
406 410 newRole:mylog("newdevice", {key1 = agent.ip:toArray(false, ":")[1]})
407 411 end
  412 + -- 整体保存一次
  413 + newRole:update()
408 414  
409 415 SendPacket(actionCodes.Role_createRpc, MsgPack.pack(response))
410 416  
... ... @@ -425,9 +431,9 @@ function _M.createRpc(agent, data)
425 431 reward = reward:setv(itemId, count)
426 432 end
427 433 if back.reward[70] then
428   - redisproxy:insertEmail({roleId = roleId, emailId = MailId.CBBackAward2, contentPms = {back.money}, createtime = skynet.timex(), attachments = reward})
  434 + mysqlproxy:insertEmail({roleId = roleId, emailId = MailId.CBBackAward2, contentPms = {back.money}, createtime = skynet.timex(), attachments = reward})
429 435 else
430   - redisproxy:insertEmail({roleId = roleId, emailId = MailId.CBBackAward, contentPms = {back.money}, createtime = skynet.timex(), attachments = reward})
  436 + mysqlproxy:insertEmail({roleId = roleId, emailId = MailId.CBBackAward, contentPms = {back.money}, createtime = skynet.timex(), attachments = reward})
431 437 end
432 438 newRole:mylog("cbback", {key1 = uid, int2 = roleId})
433 439 end
... ... @@ -487,6 +493,7 @@ function _M.changeNameRpc(agent, data)
487 493 })
488 494  
489 495 role:changeCrossServerPvpSelfInfo("name")
  496 + role:checkTaskEnter("Rename", {})
490 497 SendPacket(actionCodes.Role_changeNameRpc, MsgPack.pack({result = 0}))
491 498 return true
492 499 end
... ... @@ -525,14 +532,19 @@ function _M.saleItemRpc(agent, data)
525 532 local role = agent.role
526 533 local msg = MsgPack.unpack(data)
527 534 local backs = msg.backs
528   - if not backs then return end
  535 + if not backs or not next(backs) then return 0 end
  536 +
  537 + for itemId, count in pairs(backs) do
  538 + if math.illegalNum(count, 1, role:getItemCount(itemId)) then return 1 end
  539 + if globalCsv.unit_paster_ban[itemId] then return 2 end
  540 + local itemData = csvdb["itemCsv"][itemId]
  541 + if itemData.sell_effect == "" then return 3 end
  542 + end
529 543  
530 544 local reward = {}
531 545 local fragCount = 0
532 546 for itemId, count in pairs(backs) do
533   - if math.illegalNum(count, 1, role:getItemCount(itemId)) then return end
534 547 local itemData = csvdb["itemCsv"][itemId]
535   - if itemData.sell_effect == "" then return end
536 548 if itemData.type == ItemType.HeroFragment or itemData.type == ItemType.HeroFCommon then
537 549 fragCount = fragCount + count
538 550 end
... ... @@ -643,8 +655,8 @@ function _M.openTimeBoxRpc(agent, data)
643 655 stopTime = nowTime + quick
644 656 local cost_pre = globalCsv.box_timeOpen_diamond:toArray(true, "=")
645 657 local costKey = math.ceil(quick / (cost_pre[1] * 60)) * cost_pre[2]
646   - if not role:checkItemEnough({[ItemId.Diamond] = costKey}) then return 5 end
647   - role:costItems({[ItemId.Diamond] = costKey}, {log = {desc = "openTimeBox", int1 = slot, int2 = oper}})
  658 + if not role:checkItemEnough({[ItemId.Jade] = costKey}) then return 5 end
  659 + role:costItems({[ItemId.Jade] = costKey}, {log = {desc = "openTimeBox", int1 = slot, int2 = oper}})
648 660 else
649 661 stopTime = math.min(nowTime,time + globalCsv.box_productLine_time * 3600)
650 662 end
... ... @@ -753,18 +765,14 @@ function _M.openSpeedUpBoxRpc(agent, data)
753 765  
754 766 if useType == 1 then -- 挂机齿轮
755 767 local hangInfo = role:getProperty("hangInfo")
756   - if not hangInfo.expCarbonId then
757   - return 2
758   - end
759   - local carbonData = csvdb["idle_battleCsv"][hangInfo.expCarbonId]
760   - reward[ItemId.Gold] = (reward[ItemId.Gold] or 0) + math.floor(time / globalCsv.idle_money_produce_cd) * carbonData.money * count
  768 + local expData = hangInfo.expData or {}
  769 + --local carbonData = csvdb["idle_battleCsv"][hangInfo.expCarbonId]
  770 + reward[ItemId.Gold] = (reward[ItemId.Gold] or 0) + math.floor(time / globalCsv.idle_money_produce_cd) * (expData.money or 0) * count
761 771 elseif useType == 2 then -- 挂机经验
762 772 local hangInfo = role:getProperty("hangInfo")
763   - if not hangInfo.expCarbonId then
764   - return 3
765   - end
766   - local carbonData = csvdb["idle_battleCsv"][hangInfo.expCarbonId]
767   - reward[ItemId.Exp] = (reward[ItemId.Exp] or 0) + math.floor(time / globalCsv.idle_money_produce_cd) * carbonData.exp * count
  773 + local expData = hangInfo.expData or {}
  774 + --local carbonData = csvdb["idle_battleCsv"][hangInfo.expCarbonId]
  775 + reward[ItemId.Exp] = (reward[ItemId.Exp] or 0) + math.floor(time / globalCsv.idle_money_produce_cd) * (expData.exp or 0) * count
768 776 elseif useType == 3 then -- 食材商人收入
769 777 local buildType = 6
770 778 local level = role.dinerData:getProperty("buildL"):getv(buildType, 1)
... ... @@ -833,8 +841,8 @@ function _M.storyBookRewardRpc(agent, data)
833 841 role:log("carriage_video", {
834 842 carriage_video_type = storyBookData.type, --放映室类型,剧情CG:0, 角色CG:1, 主线剧情:2, 角色剧情:3, 活动剧情:4, 图鉴:5
835 843 carriage_video_id = storyId, --放映室片段ID
836   - carriage_video_coinid = reward[ItemId.Diamond] and ItemId.Diamond or 0, --放映奖励货币类型,无奖励则填写0
837   - carriage_video_coinnum = reward[ItemId.Diamond] or 0, --放映奖励货币数量,无奖励则填写0
  844 + carriage_video_coinid = reward[ItemId.Jade] and ItemId.Jade or 0, --放映奖励货币类型,无奖励则填写0
  845 + carriage_video_coinnum = reward[ItemId.Jade] or 0, --放映奖励货币数量,无奖励则填写0
838 846 carriage_video_item = reward, --放映奖励其他物品数量,json格式记录,{'itemid1':10,'itemid2':5,…………..},无奖励则填写0
839 847 })
840 848  
... ... @@ -1153,21 +1161,20 @@ function _M.chatRpc(agent, data)
1153 1161 local objectId = msg.roleId
1154 1162 response.objId = objectId
1155 1163 local redret = redisproxy:pipelining(function(red)
1156   - red:exists(string.format("role:%d", objectId))
1157 1164 red:sismember(FRIEND_BLACK_KEY:format(roleId), objectId)
1158 1165 red:sismember(FRIEND_BLACK_KEY:format(objectId), roleId)
1159 1166 end)
1160   - if redret[1] ~= 1 then
  1167 + if not roleExists(objectId) then
1161 1168 result = 1
1162 1169 return
1163 1170 end
1164 1171 -- 你把对方拉黑拉黑
1165   - if redret[2] == 1 then
  1172 + if redret[1] == 1 then
1166 1173 result = 2
1167 1174 return
1168 1175 end
1169 1176 -- 对方把你拉黑
1170   - local isBlock = redret[3] == 1
  1177 + local isBlock = redret[2] == 1
1171 1178  
1172 1179 local bin = MsgPack.pack(response)
1173 1180 if not isBlock then
... ... @@ -1402,6 +1409,48 @@ function _M.goldBuyRpc(agent, data)
1402 1409 return true
1403 1410 end
1404 1411  
  1412 +function _M.diamondConvertRpc(agent, data)
  1413 + local role = agent.role
  1414 + local msg = MsgPack.unpack(data)
  1415 +
  1416 + local oper = msg.oper
  1417 + if oper ~= 1 and oper ~= 2 then return 0 end
  1418 +
  1419 + local cost = math.ceil(msg.cost or 0)
  1420 + if cost <= 0 then return 1 end
  1421 + if role:getAllDiamond() < cost then return 2 end
  1422 +
  1423 + local get = globalCsv.legal_tender_cost * cost
  1424 + role:costDiamond({count = cost, log = {desc = "convert", int1 = oper, int2 = get}})
  1425 + local reward, change
  1426 + if oper == 1 then -- 钻石兑换成虹光玉
  1427 + reward, change = role:award({[ItemId.Jade] = get}, {log = {desc = "convert"}})
  1428 + elseif oper == 2 then -- 钻石兑换成虹光玉再兑换成招募券
  1429 + local old = role:getItemCount(ItemId.Jade)
  1430 + get = old + get
  1431 +
  1432 + local quan = math.floor(get/globalCsv.recruit_cost)
  1433 + local remain = get - quan * globalCsv.recruit_cost
  1434 +
  1435 + local allReward = {}
  1436 + if remain > old then
  1437 + allReward[ItemId.Jade] = remain - old
  1438 + elseif remain == old then
  1439 + else
  1440 + role:costItems({[ItemId.Jade] = old - remain}, {log = {desc = "convert"}})
  1441 + end
  1442 +
  1443 + if quan > 0 then
  1444 + allReward[ItemId.RecruitmentCard] = quan
  1445 + end
  1446 +
  1447 + reward, change = role:award(allReward, {log = {desc = "convert"}})
  1448 + end
  1449 +
  1450 + SendPacket(actionCodes.Role_diamondConvertRpc, MsgPack.pack(role:packReward(reward, change)))
  1451 + return true
  1452 +end
  1453 +
1405 1454 function _M.getDownloadCvRewardRpc(agent, data)
1406 1455 local role = agent.role
1407 1456 local flag = role:getProperty("downCvR") or 0
... ... @@ -1489,4 +1538,26 @@ function _M.accuseRpc(agent, data)
1489 1538 return true
1490 1539 end
1491 1540  
  1541 +function _M.getTimeGiftRpc(agent, data)
  1542 + local role = agent.role
  1543 +
  1544 + local GiftCsv = csvdb["time_giftCsv"]
  1545 + local timeGift = role:getProperty("timeGift")
  1546 + if timeGift >= #GiftCsv then return 0 end
  1547 +
  1548 + local nextL = timeGift + 1
  1549 + local gift = GiftCsv[nextL]
  1550 + if not gift then return 1 end
  1551 +
  1552 + local createtime = role:getProperty("ctime")
  1553 + if skynet.timex() - createtime < gift.time then return 2 end
  1554 +
  1555 + role:updateProperty({field = "timeGift", value = nextL})
  1556 + local reward, change = role:award(gift.gift, {log = {desc = "giftTime", int1 = nextL}})
  1557 + role:mylog("role_action", {desc = "giftTime", int1 = nextL})
  1558 +
  1559 + SendPacket(actionCodes.Role_getTimeGiftRpc, MsgPack.pack(role:packReward(reward, change)))
  1560 + return true
  1561 +end
  1562 +
1492 1563 return _M
1493 1564 \ No newline at end of file
... ...
src/actions/SeaportAction.lua
... ... @@ -198,13 +198,13 @@ function _M.taskRpc(agent, data)
198 198  
199 199 if quick and remainT > 0 then
200 200 local cost = math.ceil(remainT / 3600) * globalCsv.seaport_task_quick
201   - if not role:checkItemEnough({[ItemId.Diamond] = cost}) then return 8 end
202   - role:costItems({[ItemId.Diamond] = cost}, {log = {desc = "seaportTask", int1 = taskId, int2 = level}})
  201 + if not role:checkItemEnough({[ItemId.Jade] = cost}) then return 8 end
  202 + role:costItems({[ItemId.Jade] = cost}, {log = {desc = "seaportTask", int1 = taskId, int2 = level}})
203 203 end
204 204  
205 205 local carbonCsv = csvdb["idle_battleCsv"]
206   - local expCarbonId = role:getProperty("hangInfo").expCarbonId
207   - if not carbonCsv[expCarbonId] then return 7 end
  206 + local expData = role:getProperty("hangInfo").expData or {}
  207 + --if not carbonCsv[expCarbonId] then return 7 end
208 208  
209 209 local totalCoef = 0
210 210 for _, heroId in ipairs(collect.team:toArray(true,"=")) do
... ... @@ -222,8 +222,8 @@ function _M.taskRpc(agent, data)
222 222 bigSuccess = true
223 223 end
224 224  
225   - local money = math.ceil(carbonCsv[expCarbonId].money / 5 * data.time * data.money_clear)
226   - local exp = math.ceil(carbonCsv[expCarbonId].exp / 5 * data.time * data.exp_clear)
  225 + local money = math.ceil((expData.money or 0) / 5 * data.time * data.money_clear)
  226 + local exp = math.ceil((expData.exp or 0) / 5 * data.time * data.exp_clear)
227 227 local itemReward = data.item_clear_special:toNumMap()
228 228 itemReward[ItemId.Gold] = (itemReward[ItemId.Gold] or 0) + money
229 229 itemReward[ItemId.Exp] = (itemReward[ItemId.Exp] or 0) + exp
... ...
src/actions/StoreAction.lua
... ... @@ -19,7 +19,6 @@ function _M.rechargeRpc(agent , data)
19 19 end
20 20 SendPacket(actionCodes.Store_rechargeRpc, MsgPack.pack({ order = partnerOrderId }))
21 21  
22   -
23 22 -- 测试的 直接发奖励了
24 23 skynet.timeout(10, function ()
25 24 role:handlePurchase({
... ...
src/actions/TowerAction.lua
... ... @@ -107,8 +107,13 @@ function _M.endBattleRpc(agent, data)
107 107 --排行榜
108 108 role:setTowerRank(curLevel % 10000, towerType + 1)
109 109  
  110 + local rewardStr = curTower.reward
  111 + if curTower.special_award ~= "" then
  112 + rewardStr = rewardStr .. " " .. curTower.special_award
  113 + end
  114 +
110 115 curLevel = curLevel + 1
111   - reward, change = role:award(curTower.reward, {log = {desc = "towerBattle", int1 = id}})
  116 + reward, change = role:award(rewardStr, {log = {desc = "towerBattle", int1 = id}})
112 117 if towerType == 0 then
113 118 role:checkTaskEnter("TowerPass", {level = towerInfo.l})
114 119 end
... ...
src/agent.lua
... ... @@ -12,6 +12,7 @@ local xxtea = require &quot;xxtea&quot;
12 12  
13 13 skynet = require "skynet"
14 14 redisproxy = require "shared.redisproxy"
  15 +mysqlproxy = require "shared.mysqlproxy"
15 16 datacenter = require "skynet.datacenter"
16 17 mcast_util = require "services/mcast_util"
17 18 csvdb = require "shared.csvdata"
... ...
src/main.lua
... ... @@ -21,6 +21,17 @@ skynet.start(function()
21 21 })
22 22 end
23 23  
  24 + -- 启动mysql
  25 + for i = 1, work_count do
  26 + local redisd = skynet.newservice("services/mysqld", i)
  27 + skynet.call(redisd, "lua", "open", {
  28 + host = skynet.getenv("mysql_host"),
  29 + port = tonumber(skynet.getenv("mysql_port")),
  30 + user = skynet.getenv("mysql_user"),
  31 + pwd = skynet.getenv("mysql_password"),
  32 + })
  33 + end
  34 +
24 35 --启动log
25 36 if use_logd == 1 then
26 37 for i = 1, work_count * 2 do
... ...
src/models/Activity.lua
1   -local Activity = class("Activity", require("shared.ModelBase"))
  1 +local Activity = class("Activity", require("shared.ModelBaseMysql"))
2 2 local string_format = string.format
3 3  
4 4 -- activity_ctr showType
... ... @@ -64,6 +64,7 @@ end
64 64  
65 65  
66 66 Activity.schema = {
  67 + id = {"number", 0, "pri"}, -- 角色id
67 68 actime = {"table", {}}, -- 最近检查某项活动的开始时间 {id = time}
68 69 round = {"table", {}}, -- 记录活动到了第几轮 {id = roundnum}
69 70 act4 = {"table", {}}, -- {0 = day, 1= -1, 2 = -1} == 签到活动
... ... @@ -942,17 +943,11 @@ activityFunc[Activity.ActivityType.FriendEnergy] = {
942 943  
943 944 function Activity:getActFriendNew()
944 945 local roleId = self.owner:getProperty("id")
945   - local friendIds = {}
946   - local friends = redisproxy:hgetall(FRIEND_KEY:format(roleId))
947   - for i = 1, #friends , 2 do
948   - local objId = tonumber(friends[i])
949   - friendIds[objId] = 1
950   - end
951 946  
952 947 local ids = {}
953 948 local members = redisproxy:smembers(FRIEND_ENERGY:format(roleId))
954 949 for _, id in pairs(members) do
955   - if friendIds[tonumber(id)] then
  950 + if self.owner.friends[tonumber(id)] then
956 951 ids[tonumber(id)] = 1
957 952 end
958 953 end
... ...
src/models/Daily.lua
1 1 -- 日常数据
2 2  
3   -local Daily = class("Daily", require("shared.ModelBase"))
  3 +local Daily = class("Daily", require("shared.ModelBaseMysql"))
4 4  
5 5 function Daily:ctor(properties)
6 6 Daily.super.ctor(self, properties)
7 7 end
8 8  
9 9 Daily.schema = {
10   - commentHero = {"string", ""}, -- 单日评论食灵记录 type=1
  10 + id = {"number", 0, "pri"}, -- 角色id
  11 + commentHero = {"string", "", "blob"}, -- 单日评论食灵记录 type=1
11 12 hangQC = {"number", 0}, -- 挂机快速次数
12 13 dinerQC = {"number", 0}, -- 贩卖加速次数
13 14 advElC = {"number", 0}, -- 无尽次数(消耗体力)
... ...
src/models/Diner.lua
1   -local Diner = class("Diner", require("shared.ModelBase"))
  1 +local Diner = class("Diner", require("shared.ModelBaseMysql"))
2 2  
3 3 function Diner:ctor(properties)
4 4 Diner.super.ctor(self, properties)
5 5 end
6 6  
7 7 Diner.schema = {
  8 + id = {"number", 0, "pri"}, -- 角色id
8 9 buildL = {"string", ""}, -- 家具等级 1=1 2=1 3=1
9   - order = {"string", "[]"}, -- 特殊订单
10   - sells = {"string", "[]"}, -- 贩卖位置
11   - dishTree = {"string", "1=1 101=1 201=1"}, -- 料理天赋
12   - skillTree = {"string", ""}, -- 支援天赋
  10 + order = {"string", "[]", "blob"}, -- 特殊订单
  11 + sells = {"string", "[]", "blob"}, -- 贩卖位置
  12 + dishTree = {"string", "1=1 101=1 201=1", "blob"}, -- 料理天赋
  13 + skillTree = {"string", "", "blob"}, -- 支援天赋
13 14 popular = {"number",0}, -- 累计人气
14 15 expedite = {"number",1}, --每日加速次数
15 16 gfood = {"table", {}}, -- 愿望食材 {{id = 123, st = 1232144},}
... ...
src/models/Email.lua
1   -local Email = class("Email", require("shared.ModelBase"))
  1 +local Email = class("Email", require("shared.ModelBaseMysql"))
2 2  
3 3 function Email:ctor(properties)
4 4 Email.super.ctor(self, properties)
5 5 end
6 6  
7 7 Email.schema = {
8   - key = {"string"}, -- redis key
9   - id = {"number", 0}, -- 数据库ID
  8 + id = {"number", 0, "pri_auto"}, -- 数据库ID
  9 + roleId = {"number", 0, "index"}, -- 角色 ID
10 10 emailId = {"number", 0}, -- 邮件csv ID
11 11 title = {"string", ""}, -- 邮件标题
12 12 stitle = {"string", ""}, -- 小标题
13 13 content = {"string", ""}, -- 邮件正文
14   - attachments = {"string", ""},
  14 + attachments = {"string", "", 512},
15 15 status = {"number", 0}, -- 邮件状态: 未读, 已读, 已领取
16 16 createtime = {"number", skynet.timex()},
17 17 contentPms = {"table", {}},
... ...
src/models/Friend.lua 0 → 100644
... ... @@ -0,0 +1,15 @@
  1 +local Friend = class("Friend", require("shared.ModelBaseMysql"))
  2 +
  3 +function Friend:ctor(properties)
  4 + Friend.super.ctor(self, properties)
  5 +end
  6 +
  7 +Friend.schema = {
  8 + id = {"number", 0, "pri_auto"},
  9 + roleid = {"number", 0, "index"},
  10 + fid = {"number", 0, "index"},
  11 + isNew = {"number", 1},
  12 + addTime = {"number", skynet.timex()},
  13 +}
  14 +
  15 +return Friend
0 16 \ No newline at end of file
... ...
src/models/Hero.lua
1   -local Hero = class("Hero", require("shared.ModelBase"))
  1 +local Hero = class("Hero", require("shared.ModelBaseMysql"))
2 2  
3 3 local HeroPlugin = import(".HeroPlugin")
4 4 HeroPlugin.bind(Hero)
5 5  
6 6 Hero.schema = {
7   - id = {"number"},
  7 + id = {"number", 0, "pri"},
  8 + roleid = {"number", 0, "index"},
8 9 type = {"number", 0},
9 10 level = {"number", 1}, -- 等级
10 11 breakL = {"number", 0}, -- 突破等级
... ... @@ -37,9 +38,13 @@ function Hero:notifyUpdateProperty(field, newValue, oldValue)
37 38 self:notifyUpdateProperties(datas)
38 39 end
39 40  
  41 +function Hero:getSimpleHeroId()
  42 + return self:getProperty("id") % (self:getProperty("roleid") * MAX_HERO_NUM)
  43 +end
  44 +
40 45 function Hero:notifyUpdateProperties(params)
41 46 local updateData = {
42   - id = self:getProperty("id"),
  47 + id = self:getSimpleHeroId(),
43 48 datas = params
44 49 }
45 50 SendPacket(actionCodes.Hero_updateProperty, MsgPack.pack(updateData))
... ...
src/models/Order.lua
1   -local Order = class("Order", require("shared.ModelBase"))
  1 +local Order = class("Order", require("shared.ModelBaseMysql"))
2 2  
3 3 function Order:ctor(properties)
4   - Order.super.ctor(self, properties)
  4 + Order.super.ctor(self, properties)
5 5 end
6 6  
7 7 Order.schema = {
8   - key = {"string"}, -- redis key
9   - order = {"string"}, -- 自己订单号
  8 + id = {"number", 0, "pri"}, -- 自己的订单号
  9 + roleid = {"number", 0, "index"},
  10 + --order = {"string"}, -- 自己订单号
10 11 rechargeId = {"number", 0},
11 12 transactionId = {"string", ""},
12 13 createTime = {"number", skynet.timex()}, -- 订单创建时间
... ...
src/models/Role.lua
1   -local Role = class("Role", require("shared.ModelBase"))
  1 +local Role = class("Role", require("shared.ModelBaseMysql"))
2 2  
3 3 local RoleLog = import(".RoleLog") --日志相关
4 4 local RolePlugin = import(".RolePlugin") --基础功能
... ... @@ -25,6 +25,7 @@ function Role:ctor( properties )
25 25 self.storeData = nil
26 26 self.heros = {}
27 27 self.runeBag = {}
  28 + self.friends = {}
28 29 self.sparkBag = {}
29 30 self.advData = nil
30 31 self.activity = nil
... ... @@ -41,11 +42,12 @@ function Role:ctor( properties )
41 42 self.sendMailFlag = false --发送邮件标识
42 43 end
43 44  
  45 +-- type, default value, key type, length
44 46 Role.schema = {
45   - id = {"number"},
  47 + id = {"number", 0, "pri"},
46 48 uid = {"string", ""},
47 49 name = {"string", ""},
48   - intro = {"string", ""},
  50 + intro = {"string", "", "", 1024},
49 51 headId = {"number", globalCsv.defaultHead},
50 52 sid = {"number", 0},
51 53 device = {"string", ""},
... ... @@ -60,27 +62,29 @@ Role.schema = {
60 62 ignoreMt = {"number", 0}, -- 忽略维护拦截
61 63 sversion = {"number", STRUCT_VERSION or 0}, -- 重整数据版本
62 64 timeReset = {"table", {}}, --重置轮回记录
  65 + jade = {"number", 0}, -- 虹光玉
63 66 diamond = {"number", 0}, -- 免费钻
64 67 reDiamond = {"number", 0}, -- android充值钻
65 68 reDiamondIos = {"number", 0}, -- ios充值钻
66 69 setting = {"table", {}}, --设置
67   - codeStr = {"string", ""}, --已经领过的礼包码
  70 + codeStr = {"string", "", "blob"}, --已经领过的礼包码
68 71 -- roleInfo
69 72 level = {"number", 1},
70 73 exp = {"number", 0},
71   - items = {"string", ""},
  74 + items = {"string", "", "blob"},
72 75 expireItem = {"table", {}}, --物品过期检查
73 76 funcOpen = {"table", {}}, --功能是否开放
74 77 funcLv = {"table", {}}, --功能等级
75 78 -- loveStatus = {"string", ""}, --统计角色的最高 好感度等级 类型相关 -- type=loveL type=loveL
76 79 crown = {"number", 0}, -- 看伴娘
77 80 silent = {"number", 0}, --禁言解禁时间
  81 + timeGift = {"number", 0}, -- 创建角色时间礼包
78 82  
79 83 bagLimit = {"table", globalCsv.store_limit_max},
80 84  
81 85 --冒险相关
82 86 advPass = {"table", {}}, -- 通关记录 {chapterId = layer}
83   - advItems = {"string", ""}, -- 冒险临时背包
  87 + advItems = {"string", "", "blob"}, -- 冒险临时背包
84 88 advInfo = {"table", {}}, -- 冒险关卡信息
85 89 advTeam = {"table", {}}, -- 冒险玩家队伍信息
86 90 advHang = {"table", {}}, -- 挂机信息 -- {chapterId = {format = teaminfo, time = endtime}}
... ... @@ -124,8 +128,8 @@ Role.schema = {
124 128 workBattle = {"table", {}}, -- 夜间玩法记录 {[1] = 1, [2] = 1, [3] = 1, [4] = 1, round = 10} -- 第N天打了多少次 round 轮次
125 129  
126 130 --引导相关
127   - newerGuide = {"string","1=1"}, -- 新手引导 master=slave
128   - funcGuide = {"string",""}, -- 功能引导 0=0跳过次数(999永久跳过) 1=1功能1触发情况
  131 + newerGuide = {"string","1=1", "", 10}, -- 新手引导 master=slave
  132 + funcGuide = {"string","", "blob"}, -- 功能引导 0=0跳过次数(999永久跳过) 1=1功能1触发情况
129 133  
130 134 pvpTC = {"table", {}}, -- pvp 编队普通
131 135 pvpTSC = {"table", {}}, -- pvp 他人可读的队伍信息
... ... @@ -196,6 +200,10 @@ Role.schema = {
196 200 seaport = {"table", {}}, -- 海岛贸易季 {time = 1234567890, donate = {}, collect = {[1] = {team = "1=2=3", time = 1234567890}}, shop = {}}
197 201  
198 202 returner = {"table", {}}, -- 回归者 {time = 12334233423, [1] = 1, [2] = 2, status = {[1] = 1}}
  203 +
  204 + roleIncre = {"table", {}}, -- 角色英雄,铭文,火花自增序列 {heroId = 1, runeId = 1, sparkId = 1}
  205 +
  206 + unlockChap = {"table", {}}, -- 解锁的章节
199 207 }
200 208  
201 209  
... ... @@ -345,6 +353,7 @@ function Role:data()
345 353 diamond = self:getAllDiamond(),
346 354 bagLimit = self:getProperty("bagLimit"),
347 355 silent = self:getProperty("silent"),
  356 + timeGift = self:getProperty("timeGift"),
348 357  
349 358 advPass = self:getProperty("advPass"),
350 359 advInfo = self:getProperty("advInfo"),
... ... @@ -431,6 +440,8 @@ function Role:data()
431 440  
432 441 seaport = self:getProperty("seaport"),
433 442 returner = self:getProperty("returner"),
  443 +
  444 + unlockChap = self:getProperty("unlockChap"), -- 解锁的章节
434 445 }
435 446 end
436 447  
... ...
src/models/RoleCross.lua
... ... @@ -24,6 +24,20 @@ RoleCross.bind = function (Role)
24 24 return info
25 25 end
26 26  
  27 + function Role:addFriend(friendId)
  28 + local res = mysqlproxy:query(string.format("SELECT * FROM `Friend` WHERE `roleid` = %s AND `fid` = %s;", self:getProperty("id"), friendId))
  29 + for _, data in ipairs(res) do
  30 + local friend = require("models.Friend").new({key = string.format("%d",data.id), id = data.id})
  31 + if friend:load(data) then
  32 + self.friends[friend:getProperty("fid")] = friend
  33 + end
  34 + end
  35 + end
  36 +
  37 + function Role:delFriend(friendId)
  38 + self.friends[friendId] = nil
  39 + end
  40 +
27 41 -- 好友队伍战斗信息
28 42 function Role:friendBattleInfo()
29 43 return self:getProperty("pvpTBVC") ~= 0 and self:getProperty("pvpTBC") or self:getProperty("hangTB")
... ... @@ -231,33 +245,30 @@ local function getRoleKey(roleId)
231 245 end
232 246  
233 247 function CMD.setProperty(roleId, field, value)
234   - local value = packRoleField(field, value)
235   - if not value then return end
236   - return redisproxy:hset(getRoleKey(roleId), field, value)
  248 + local tb = {}
  249 + tb[field] = value
  250 + return CMD.setProperties(roleId, tb)
237 251 end
238 252  
239 253  
240 254 function CMD.setProperties(roleId, fields)
241   - local result = {}
242   - for k,v in pairs(fields) do
243   - local value = packRoleField(k, v)
244   - if value then
245   - result[#result + 1] = k
246   - result[#result + 1] = value
247   - end
248   - end
249   - return redisproxy:hmset(getRoleKey(roleId), table.unpack(result))
  255 + local role = require("models.Role").new({key = string.format("%s",roleId), id = roleId})
  256 + return role:updateFields(fields)
250 257 end
251 258  
252 259 function CMD.getProperty(roleId, field)
253   - return unpackRoleField(field ,redisproxy:hget(getRoleKey(roleId), field))
  260 + local ret = CMD.getProperties(roleId, {field})
  261 + return ret[field]
254 262 end
255 263  
256 264 function CMD.getProperties(roleId, fields)
257   - local returnValue = redisproxy:hmget(getRoleKey(roleId), table.unpack(fields))
  265 + local role = require("models.Role").new({key = string.format("%s",roleId), id = roleId})
258 266 local ret = {}
259   - for index, key in ipairs(fields) do
260   - ret[key] = unpackRoleField(key, returnValue[index])
  267 + local datas = role:loadFields(fields)
  268 + if datas then
  269 + for index, key in ipairs(fields) do
  270 + ret[key] = unpackRoleField(key, datas[key])
  271 + end
261 272 end
262 273 return ret
263 274 end
... ...
src/models/RoleIncre.lua 0 → 100644
... ... @@ -0,0 +1,21 @@
  1 +local RoleIncre = class("RoleIncre", require("shared.ModelBaseMysql"))
  2 +
  3 +function RoleIncre:ctor( properties )
  4 + RoleIncre.super.ctor(self, properties)
  5 +end
  6 +
  7 +
  8 +RoleIncre.schema = {
  9 + id = {"number", 0, "pri"},
  10 + heroId = {"number", 0},
  11 + runeId = {"number", 0},
  12 + sparkId = {"number", 0},
  13 +}
  14 +
  15 +function RoleIncre:increBy(keyName, val)
  16 + local curId = self:getProperty(keyName)
  17 + self:setProperty(keyName, curId + val)
  18 + return curId + val
  19 +end
  20 +
  21 +return RoleIncre
0 22 \ No newline at end of file
... ...
src/models/RoleLog.lua
... ... @@ -59,7 +59,8 @@ local ItemReason = {
59 59 advLevelStage = 143, -- 拾荒活动阶段奖励
60 60 towerBnous = 144, -- 爬塔到一定层数对某些功能的奖励
61 61 unknowShop = 145, -- 未知商店
62   -
  62 + convert = 146, -- 钻石兑换其他物品
  63 + giftTime = 147, -- 创角后的时间礼包
63 64  
64 65 advHang = 301, -- 拾荒挂机
65 66 hangBattle = 302, -- 挂机战斗
... ...
src/models/RolePlugin.lua
... ... @@ -15,6 +15,8 @@ function RolePlugin.bind(Role)
15 15 self:loadDiner()
16 16 self:loadActivity()
17 17 self:loadStoreInfo()
  18 + --self:loadRoleIncre()
  19 + self:loadFriends()
18 20 self:loadSparks()
19 21 end
20 22  
... ... @@ -250,7 +252,7 @@ function RolePlugin.bind(Role)
250 252 local headData = csvdb["player_iconCsv"][itemId]
251 253 -- pvp 跨服竞技场奖励
252 254 if headData and headData.path == 2 then
253   - redisproxy:insertEmail({roleId = self:getProperty("id"), emailId = 19})
  255 + mysqlproxy:insertEmail({roleId = self:getProperty("id"), emailId = 19})
254 256 end
255 257 end
256 258 end
... ... @@ -459,7 +461,8 @@ function RolePlugin.bind(Role)
459 461  
460 462 function Role:getAllDiamond()
461 463 local diamond = self:getProperty("sid") == IOS_SID and self:getProperty("reDiamondIos") or self:getProperty("reDiamond")
462   - return self:getProperty("diamond") + diamond
  464 + --return self:getProperty("diamond") + diamond
  465 + return diamond
463 466 end
464 467  
465 468 function Role:gainDiamond(params)
... ... @@ -468,18 +471,18 @@ function RolePlugin.bind(Role)
468 471 if isnan(count) then
469 472 return false
470 473 end
471   - local origind = self:getProperty("diamond")
  474 + local origind = 0 -- self:getProperty("diamond")
472 475 local originr = self:getProperty("sid") == IOS_SID and self:getProperty("reDiamondIos") or self:getProperty("reDiamond")
473 476 local origin = origind + originr
474   - if params.isRecharge then
  477 + --if params.isRecharge then
475 478 if params.sid == IOS_SID then
476 479 self:incrProperty("reDiamondIos", count)
477 480 else
478 481 self:incrProperty("reDiamond", count)
479 482 end
480   - else
481   - self:incrProperty("diamond", count)
482   - end
  483 + --else
  484 + --self:incrProperty("diamond", count)
  485 + --end
483 486  
484 487 self:logItems(ItemId.Diamond, origin, count, params.log)
485 488 if params.log then
... ... @@ -508,7 +511,7 @@ function RolePlugin.bind(Role)
508 511 return false
509 512 end
510 513 local isIos = self:getProperty("sid") == IOS_SID
511   - local origind = self:getProperty("diamond")
  514 + local origind = 0 -- self:getProperty("diamond")
512 515 local originr = isIos and self:getProperty("reDiamondIos") or self:getProperty("reDiamond")
513 516 local origin = origind + originr
514 517  
... ... @@ -518,18 +521,20 @@ function RolePlugin.bind(Role)
518 521 if origin < count then
519 522 return false
520 523 end
521   - local last = count
522   - local costFirst = isIos and {"diamond", "reDiamondIos"} or {"diamond", "reDiamond"}
523   - if params.isRecharge then
524   - costFirst = isIos and {"reDiamondIos", "diamond"} or {"reDiamond", "diamond"}
525   - end
526   - last = math.max(last - self:getProperty(costFirst[1]), 0)
527   - if last < count then
528   - self:incrProperty(costFirst[1], last - count)
529   - end
530   - if last > 0 then
531   - self:incrProperty(costFirst[2], -last)
532   - end
  524 + local diamondKey = isIos and "reDiamondIos" or "reDiamond"
  525 + self:incrProperty(diamondKey, -count)
  526 + --local last = count
  527 + --local costFirst = isIos and {"diamond", "reDiamondIos"} or {"diamond", "reDiamond"}
  528 + --if params.isRecharge then
  529 + -- costFirst = isIos and {"reDiamondIos", "diamond"} or {"reDiamond", "diamond"}
  530 + --end
  531 + --last = math.max(last - self:getProperty(costFirst[1]), 0)
  532 + --if last < count then
  533 + -- self:incrProperty(costFirst[1], last - count)
  534 + --end
  535 + --if last > 0 then
  536 + -- self:incrProperty(costFirst[2], -last)
  537 + --end
533 538  
534 539  
535 540 self:logItems(ItemId.Diamond, origin, count, params.log)
... ... @@ -551,6 +556,14 @@ function RolePlugin.bind(Role)
551 556 return true
552 557 end
553 558  
  559 + function Role:increBy(field, val)
  560 + local roleIncre = self:getProperty("roleIncre")
  561 + local curId = roleIncre[field] or 0
  562 + roleIncre[field] = curId + val
  563 + self:setProperty("roleIncre", roleIncre)
  564 + return curId + val
  565 + end
  566 +
554 567 function Role:addHero(params)
555 568 local roleId = self:getProperty("id")
556 569 local heroType = params.type
... ... @@ -558,13 +571,12 @@ function RolePlugin.bind(Role)
558 571 local unitData = csvdb["unitCsv"][heroType]
559 572 if not unitData then return false end
560 573  
561   - local heroId = tonum(redisproxy:hincrby(string.format(R_INCR, roleId), "hero", 1))
562   -
563   - redisproxy:sadd(string.format(R_HEROS, roleId), heroId)
  574 + local heroId = self:increBy("heroId" , 1)
564 575  
565 576 local heroInfo = {
566   - key = string.format(R_HERO, roleId, heroId),
567   - id = heroId,
  577 + key = string.format("%d",roleId * MAX_HERO_NUM + heroId),
  578 + id = roleId * MAX_HERO_NUM + heroId,
  579 + roleid = roleId,
568 580 type= heroType,
569 581 wakeL = globalCsv.unit_wake_initLevel[unitData.rare],
570 582 }
... ... @@ -627,27 +639,33 @@ function RolePlugin.bind(Role)
627 639  
628 640 function Role:loadHeros()
629 641 local roleId = self:getProperty("id")
630   - local heroIds = redisproxy:smembers(string.format(R_HEROS, roleId))
631   - local redret = redisproxy:pipelining(function (red)
632   - for _, heroId in ipairs(heroIds) do
633   - red:hgetall(string.format(R_HERO, roleId, heroId))
634   - end
635   - end)
636   - for index, heroId in ipairs(heroIds) do
637   - local hero = require("models.Hero").new({key = string.format(R_HERO, roleId, heroId)})
638   - if hero:load(table.array2Table(redret[index])) then
  642 + local res = mysqlproxy:query(string.format("SELECT * FROM `Hero` WHERE `roleid` = %s", roleId))
  643 + for _, data in ipairs(res) do
  644 + local hero = require("models.Hero").new({key = string.format("%d",data.id), id=data.id})
  645 + if hero:load(data) then
639 646 hero.owner = self
640   - self.heros[tonumber(heroId)] = hero
  647 + self.heros[hero:getSimpleHeroId()] = hero
  648 + end
  649 + end
  650 + end
  651 +
  652 + function Role:loadFriends()
  653 + local roleId = self:getProperty("id")
  654 + local res = mysqlproxy:query(string.format("SELECT * FROM `Friend` WHERE `roleid` = %s", roleId))
  655 + for _, data in ipairs(res) do
  656 + local friend = require("models.Friend").new({key = string.format("%d",data.id), id = data.id})
  657 + if friend:load(data) then
  658 + self.friends[friend:getProperty("fid")] = friend
641 659 end
642 660 end
643 661 end
644 662  
645 663 function Role:loadDaily()
646 664 local roleId = self:getProperty("id")
647   - local dataKey = string.format(R_DAILY, roleId)
648   - self.dailyData = require("models.Daily").new({key = dataKey})
  665 + local dataKey = string.format("%d", roleId)
  666 + self.dailyData = require("models.Daily").new({key = dataKey, id = roleId})
649 667 self.dailyData.owner = self
650   - if not redisproxy:exists(dataKey) then
  668 + if not self.dailyData:checkKeyExists(dataKey) then
651 669 self.dailyData:create()
652 670 else
653 671 self.dailyData:load()
... ... @@ -656,10 +674,10 @@ function RolePlugin.bind(Role)
656 674  
657 675 function Role:loadActivity()
658 676 local roleId = self:getProperty("id")
659   - local dataKey = string.format(R_ACTIVITY, roleId)
660   - self.activity = require("models.Activity").new({key = dataKey})
  677 + local dataKey = string.format("%d", roleId)
  678 + self.activity = require("models.Activity").new({key = dataKey, id = roleId})
661 679 self.activity.owner = self
662   - if not redisproxy:exists(dataKey) then
  680 + if not self.activity:checkKeyExists(dataKey) then
663 681 self.activity:create()
664 682 else
665 683 self.activity:load()
... ... @@ -668,10 +686,10 @@ function RolePlugin.bind(Role)
668 686  
669 687 function Role:loadDiner()
670 688 local roleId = self:getProperty("id")
671   - local dataKey = string.format(R_DINER, roleId)
672   - self.dinerData = require("models.Diner").new({key = dataKey})
  689 + local dataKey = string.format("%d", roleId)
  690 + self.dinerData = require("models.Diner").new({key = dataKey, id = roleId})
673 691 self.dinerData.owner = self
674   - if not redisproxy:exists(dataKey) then
  692 + if not self.dinerData:checkKeyExists(dataKey) then
675 693 self.dinerData:create()
676 694 else
677 695 self.dinerData:load()
... ... @@ -685,16 +703,28 @@ function RolePlugin.bind(Role)
685 703  
686 704 function Role:loadStoreInfo()
687 705 local roleId = self:getProperty("id")
688   - local dataKey = string.format(R_STORE, roleId)
689   - self.storeData = require("models.Store").new({key = dataKey})
  706 + local dataKey = string.format("%d", roleId)
  707 + self.storeData = require("models.Store").new({key = dataKey, id = roleId})
690 708 self.storeData.owner = self
691   - if not redisproxy:exists(dataKey) then
  709 + if not self.storeData:checkKeyExists(dataKey) then
692 710 self.storeData:create()
693 711 else
694 712 self.storeData:load()
695 713 end
696 714 end
697 715  
  716 + --function Role:loadRoleIncre()
  717 + -- local roleId = self:getProperty("id")
  718 + -- local dataKey = string.format("%d", roleId)
  719 + -- self.roleIncre = require("models.RoleIncre").new({key = dataKey, id = roleId})
  720 + -- self.roleIncre.owner = self
  721 + -- if not self.roleIncre:checkKeyExists(dataKey) then
  722 + -- self.roleIncre:create()
  723 + -- else
  724 + -- self.roleIncre:load()
  725 + -- end
  726 + --end
  727 +
698 728 function Role:addEquip(equipType, equipLv, count, pms)
699 729 pms = pms or {}
700 730 if count ~= count then return end
... ... @@ -750,34 +780,24 @@ function RolePlugin.bind(Role)
750 780  
751 781 function Role:loadRunes()
752 782 local roleId = self:getProperty("id")
753   - local runeIds = redisproxy:smembers(string.format(R_RUNEIDS, roleId))
754   - local redret = redisproxy:pipelining(function (red)
755   - for _, runeId in ipairs(runeIds) do
756   - red:hgetall(string.format(R_RUNE, roleId, runeId))
757   - end
758   - end)
759   - for index, runeId in ipairs(runeIds) do
760   - local rune = require("models.Rune").new({key = string.format(R_RUNE, roleId, runeId)})
761   - if rune:load(table.array2Table(redret[index])) then
  783 + local res = mysqlproxy:query(string.format("SELECT * FROM `Rune` WHERE `roleid` = %s", roleId))
  784 + for _, data in ipairs(res) do
  785 + local rune = require("models.Rune").new({key = string.format("%d",data.uid), uid=data.uid})
  786 + if rune:load(data) then
762 787 rune.owner = self
763   - self.runeBag[tonumber(runeId)] = rune
  788 + self.runeBag[data.uid] = rune
764 789 end
765 790 end
766 791 end
767 792  
768 793 function Role:loadSparks()
769 794 local roleId = self:getProperty("id")
770   - local sparkIds = redisproxy:smembers(string.format(R_SPARKIDS, roleId))
771   - local redret = redisproxy:pipelining(function (red)
772   - for _, sparkId in ipairs(sparkIds) do
773   - red:hgetall(string.format(R_SPARK, roleId, sparkId))
774   - end
775   - end)
776   - for index, sparkId in ipairs(sparkIds) do
777   - local spark = require("models.Spark").new({key = string.format(R_SPARK, roleId, sparkId)})
778   - if spark:load(table.array2Table(redret[index])) then
  795 + local res = mysqlproxy:query(string.format("SELECT * FROM `Spark` WHERE `roleid` = %s", roleId))
  796 + for _, data in ipairs(res) do
  797 + local spark = require("models.Spark").new({key = string.format("%d",data.id), id=data.id})
  798 + if spark:load(data) then
779 799 spark.owner = self
780   - self.sparkBag[tonumber(sparkId)] = spark
  800 + self.sparkBag[data.id] = spark
781 801 end
782 802 end
783 803 end
... ... @@ -791,18 +811,17 @@ function RolePlugin.bind(Role)
791 811 if not data then return 3 end
792 812  
793 813 local roleId = self:getProperty("id")
794   - local runeUid = tonum(redisproxy:hincrby(string.format(R_INCR, roleId), "rune", 1))
  814 + local runeUid = self:increBy("runeId" , 1)
795 815  
796   - redisproxy:sadd(string.format(R_RUNEIDS, roleId), runeUid)
797   -
798   - local heroInfo = {
799   - key = string.format(R_RUNE, roleId, runeUid),
800   - uid = runeUid,
  816 + local runeInfo = {
  817 + key = string.format("%d",roleId * MAX_RUNE_NUM + runeUid),
  818 + uid = roleId * MAX_RUNE_NUM + runeUid,
  819 + roleid = roleId,
801 820 type = params.type,
802 821 id = params.id,
803 822 }
804 823  
805   - local newRune = require("models.Rune").new(heroInfo)
  824 + local newRune = require("models.Rune").new(runeInfo)
806 825 newRune:create()
807 826 newRune:generateAttrs()
808 827 newRune.owner = self
... ... @@ -845,16 +864,14 @@ function RolePlugin.bind(Role)
845 864 if not data then return 3 end
846 865  
847 866 local roleId = self:getProperty("id")
848   - local sparkUid = tonum(redisproxy:hincrby(string.format(R_INCR, roleId), "spark", 1))
849   -
850   - redisproxy:sadd(string.format(R_SPARKIDS, roleId), sparkUid)
  867 + local sparkUid = self:increBy("sparkId" , 1)
851 868  
852 869 local sparkInfo = {
853   - key = string.format(R_SPARK, roleId, sparkUid),
854   - id = sparkUid,
  870 + key = string.format("%d",roleId * MAX_SPARK_NUM + sparkUid),
  871 + id = roleId * MAX_SPARK_NUM + sparkUid,
  872 + roleid = roleId,
855 873 cfg_id = params.id,
856 874 }
857   -
858 875 local newSpark = require("models.Spark").new(sparkInfo)
859 876 newSpark:create()
860 877 newSpark:addAttr(data.attr:toNumMap())
... ... @@ -865,13 +882,14 @@ function RolePlugin.bind(Role)
865 882 table.insert(response, newSpark:data())
866 883 SendPacket(actionCodes.Role_loadSparks, MsgPack.pack(response))
867 884 end
868   - --self:checkTaskEnter("AddRune", {id = params.id, type = params.type, rarity = data.rarity}, params.notNotify)
  885 +
  886 + --self:checkTaskEnter("AddSpark", {id = params.id, type = params.type, rarity = data.rarity}, params.notNotify)
869 887  
870 888 self:logItems(params.id, 0, 1, params.log)
871 889 if params.log then
872 890 local log = clone(params.log)
873 891 if log["cint1"] or log["cint2"] or log["cint3"] then
874   - print("addRune error log have cint1 or cint2 or cint3 ", debug.traceback())
  892 + print("addSpark error log have cint1 or cint2 or cint3 ", debug.traceback())
875 893 end
876 894  
877 895 log["cint1"] = sparkUid
... ... @@ -916,12 +934,9 @@ function RolePlugin.bind(Role)
916 934 end
917 935 end
918 936  
919   - redisproxy:pipelining(function (red)
920   - for _, sparkId in pairs(bDel) do
921   - red:del(string.format(R_SPARK, roleId, sparkId))
922   - red:srem(string.format(R_SPARKIDS, roleId), sparkId)
923   - end
924   - end)
  937 + -- delete spark
  938 + mysqlproxy:query(string.format("DELETE FROM `Spark` WHERE `id` in (%s)", table.concat(bDel, ",")))
  939 +
925 940 local response = {}
926 941 for _, sparkId in pairs(bDel) do
927 942 table.insert(response, {id = sparkId, bDel = true})
... ... @@ -959,12 +974,9 @@ function RolePlugin.bind(Role)
959 974 end
960 975 end
961 976  
962   - redisproxy:pipelining(function (red)
963   - for _, runeId in pairs(bDel) do
964   - red:del(string.format(R_RUNE, roleId, runeId))
965   - red:srem(string.format(R_RUNEIDS, roleId), runeId)
966   - end
967   - end)
  977 + -- delete rune
  978 + mysqlproxy:query(string.format("DELETE FROM `Rune` WHERE `uid` in (%s)", table.concat(bDel, ",")))
  979 +
968 980 local response = {}
969 981 for _, runeId in pairs(bDel) do
970 982 table.insert(response, {uid = runeId, bDel = true})
... ... @@ -1399,7 +1411,7 @@ function RolePlugin.bind(Role)
1399 1411 end
1400 1412  
1401 1413 local carbonCsv = csvdb["idle_battleCsv"]
1402   - local expCarbonId = self:getProperty("hangInfo").expCarbonId
  1414 + local expData = self:getProperty("hangInfo").expData or {}
1403 1415 local taskCsv = csvdb["seaport_taskCsv"]
1404 1416 local endTime = openTime0 + 86400 * 2
1405 1417 local reward = {}
... ... @@ -1412,7 +1424,7 @@ function RolePlugin.bind(Role)
1412 1424 local teams = collect[slot].team
1413 1425 local time = collect[slot].time
1414 1426 if time + data.time <= endTime then
1415   - if not carbonCsv[expCarbonId] then break end
  1427 + --if not carbonCsv[expCarbonId] then break end
1416 1428  
1417 1429 local totalCoef = 0
1418 1430 for _, heroId in ipairs(teams:toArray(true,"=")) do
... ... @@ -1429,8 +1441,8 @@ function RolePlugin.bind(Role)
1429 1441 bigSuccess = true
1430 1442 end
1431 1443  
1432   - local money = math.ceil(carbonCsv[expCarbonId].money / 5 * data.time * data.money_clear)
1433   - local exp = math.ceil(carbonCsv[expCarbonId].exp / 5 * data.time * data.exp_clear)
  1444 + local money = math.ceil((expData.money or 0) / 5 * data.time * data.money_clear)
  1445 + local exp = math.ceil((expData.exp or 0) / 5 * data.time * data.exp_clear)
1434 1446 local itemReward = data.item_clear_special:toNumMap()
1435 1447 itemReward[ItemId.Gold] = (itemReward[ItemId.Gold] or 0) + money
1436 1448 itemReward[ItemId.Exp] = (itemReward[ItemId.Exp] or 0) + exp
... ... @@ -1891,6 +1903,21 @@ function RolePlugin.bind(Role)
1891 1903 function Role:onRecoverTimer(now)
1892 1904 self:updateTimeReset(now, true)
1893 1905 self:checkNewEvent(now)
  1906 + self:saveRoleData()
  1907 + end
  1908 +
  1909 + function Role:saveRoleData()
  1910 + self:update()
  1911 + local objs = {self.activity, self.dailyData, self.dinerData, self.storeData, self.roleIncre}
  1912 + for _, info in ipairs(objs) do
  1913 + info:update()
  1914 + end
  1915 + local tbObjs = {self.friends, self.heros, self.runeBag, self.sparkBag}
  1916 + for _, tbObj in ipairs(tbObjs) do
  1917 + for _, info in pairs(tbObj) do
  1918 + info:update()
  1919 + end
  1920 + end
1894 1921 end
1895 1922  
1896 1923 local function breath(sec, name)
... ... @@ -1950,21 +1977,10 @@ function RolePlugin.bind(Role)
1950 1977 end
1951 1978  
1952 1979 local roleId = self:getProperty("id")
1953   - local email_rds = string.format(R_EMAIL, roleId)
1954   -
1955   - local emailIds = redisproxy:lrange(email_rds, 0, EMAIL_LIMIT - 1) or {}
1956   - local redret = redisproxy:pipelining(function (red)
1957   - for _, id in ipairs(emailIds) do
1958   - red:hget(string.format(R_EMAIL_ITEM, roleId, id), "status")
1959   - end
1960   - end)
  1980 + local res = mysqlproxy:query(string.format("SELECT `id` FROM `Email` WHERE `roleId` = %d AND `status` = 0;", roleId))
1961 1981  
1962 1982 self.SendMailFlag = false
1963   - for index, id in ipairs(emailIds) do
1964   - if tonumber(redret[index]) == 0 then
1965   - return true
1966   - end
1967   - end
  1983 + return next(res)
1968 1984 end
1969 1985  
1970 1986 checks["pvphg"] = function()
... ... @@ -2095,24 +2111,27 @@ function RolePlugin.bind(Role)
2095 2111 if not self.activity:isOpenById(rechargeData.activity_id, "ActShopGoods") then return "" end
2096 2112 end
2097 2113  
2098   - local orderId = redisproxy:hget(string.format(R_ORDERS, roleId), rechargeId)
2099   - if orderId then
2100   - local orderObject = require("models.Order").new({ key = string.format(R_ORDER, roleId, orderId) })
  2114 + local orderId = redisproxy:hget(string.format(R_ORDERS, roleId), rechargeId)
  2115 + if orderId then
  2116 + local uid = orderId * MAX_SVR_ID + serverId
  2117 + local orderObject = require("models.Order").new({ key = string.format("%d", uid), id = uid })
2101 2118 if orderObject:load() and orderObject:getProperty("rechargeId") == rechargeId and math.abs(skynet.timex() - orderObject:getProperty("createTime")) < 5 * 60 then
2102   - return string.format("%d_%d_%d", serverId, roleId, orderId)
  2119 + return string.format("%d", uid)
2103 2120 end
2104   - end
  2121 + end
2105 2122  
2106 2123 orderId = redisproxy:hincrby("autoincrement_set", "order", 1)
2107   - local partnerOrderId = string.format("%d_%d_%d", serverId, roleId, orderId)
  2124 + local uid = orderId * MAX_SVR_ID + serverId
  2125 + local partnerOrderId = string.format("%d", orderId * MAX_SVR_ID + serverId)
2108 2126 local orderKey = string.format(R_ORDER, roleId, orderId)
2109 2127 redisproxy:del(orderKey) -- 删掉可能有了
2110 2128 local order = require("models.Order").new({
2111   - key = orderKey,
2112   - order = partnerOrderId,
  2129 + key = partnerOrderId,
  2130 + id = tonum(partnerOrderId),
2113 2131 rechargeId = rechargeId,
2114 2132 createTime = skynet.timex(),
2115 2133 transactionId = transactionId,
  2134 + roleid = roleId,
2116 2135 sid = self:getProperty("sid"),
2117 2136 choose = choose or "",
2118 2137 })
... ... @@ -2135,10 +2154,8 @@ function RolePlugin.bind(Role)
2135 2154 --]]
2136 2155 function Role:updatePurchaseOrder(partnerOrderStr, platformOrder, status)
2137 2156 if not partnerOrderStr then return false end
2138   - local _, _, orderId = string.match(partnerOrderStr, "(.+)_(.+)_(.+)")
2139   -
2140 2157 local roleId = self:getProperty("id")
2141   - local orderObject = require("models.Order").new({ key = string.format(R_ORDER, roleId, orderId) })
  2158 + local orderObject = require("models.Order").new({ key = string.format("%d", partnerOrderStr), id = tonum(partnerOrderStr)})
2142 2159 if not orderObject:load() then
2143 2160 return false
2144 2161 end
... ... @@ -2147,6 +2164,14 @@ function RolePlugin.bind(Role)
2147 2164 local dataSet = csvdb["shop_rechargeCsv"][rechargeId]
2148 2165 local sid = orderObject:getProperty("sid")
2149 2166  
  2167 + if roleId ~= orderObject:getProperty("roleid") then
  2168 + skynet.error(string.format("[recharge] with a different role id, current roleId:%d, order role Id:%d, order cpOrder: %s, platformOrder : %s, hadPlatformOrder: %s, id: %s, overTime : %s",
  2169 + roleId, orderObject:getProperty("roleid"),
  2170 + partnerOrderStr, platformOrder, orderObject:getProperty("transactionId"), rechargeId, orderObject:getProperty("finishTime")
  2171 + ))
  2172 + return false, "unknow"
  2173 + end
  2174 +
2150 2175 if orderObject:getProperty("finishTime") > 0 then
2151 2176 skynet.error(string.format("[recharge] is a finish order cpOrder: %s, platformOrder : %s, hadPlatformOrder: %s, id: %s, overTime : %s",
2152 2177 partnerOrderStr, platformOrder, orderObject:getProperty("transactionId"), rechargeId, orderObject:getProperty("finishTime")
... ... @@ -2168,6 +2193,8 @@ function RolePlugin.bind(Role)
2168 2193 redisproxy:hdel(string.format(R_ORDERS, roleId), rechargeId)
2169 2194 end
2170 2195  
  2196 + orderObject:update()
  2197 +
2171 2198 if status ~= "unknow" then
2172 2199 self:log("setOrder", {
2173 2200 order_status = ({success = 100, finsh = 200, fail = 300})[status] or 1000, -- "订单状态:100 - 开始下单(玩家还未开始付费行为记录)200 - 支付完成并发货(SDK通知可以发货时记录),300 - 订单被取消,1000 - 其他"
... ... @@ -2313,7 +2340,7 @@ function RolePlugin.bind(Role)
2313 2340 for k, v in pairs(tgift) do
2314 2341 gift = gift .. k.."="..v.." "
2315 2342 end
2316   - redisproxy:insertEmail({roleId = self:getProperty("id"), emailId = mailId, createtime = createTime, attachments = gift, contentPms = contentPms})
  2343 + mysqlproxy:insertEmail({roleId = self:getProperty("id"), emailId = mailId, createtime = createTime, attachments = gift, contentPms = contentPms})
2317 2344 self.sendMailFlag = true
2318 2345 end
2319 2346  
... ...
src/models/RoleTask.lua
... ... @@ -110,6 +110,7 @@ local TaskType = {
110 110 WeekTask = 910, -- 完成每周活跃任务
111 111 ActBattlePass = 911, -- 活动关卡通关 -- chapterId
112 112 Appoint = 912, -- 触发限时礼包,指定id
  113 + Rename = 913, -- 重命名
113 114  
114 115 --功能未实现 todo
115 116 AdvShop = 1002, -- 冒险商城
... ... @@ -235,6 +236,7 @@ local SudokuListener = {
235 236 [TaskType.PvpWin] = {{15, 1}},
236 237 [TaskType.DinerTalentUp] = {{16, f("level"), f("type")}},
237 238 [TaskType.RuneUp] = {{17, 1}},
  239 + [TaskType.Rename] = {{20, 1}},
238 240 }
239 241 }
240 242  
... ...
src/models/Rune.lua
1   -local Rune = class("Rune", require("shared.ModelBase"))
  1 +local Rune = class("Rune", require("shared.ModelBaseMysql"))
2 2 Rune.schema = {
3   - uid = {"number"}, -- 唯一自增id
  3 + uid = {"number", 0, "pri"}, -- 唯一自增id
  4 + roleid = {"number", 0, "index"},
4 5 type = {"number"}, -- 装备位置
5 6 id = {"number"},
6 7 level = {"number", 0}, -- 等级
... ...
src/models/Spark.lua
1   -local Spark = class("Spark", require("shared.ModelBase"))
  1 +local Spark = class("Spark", require("shared.ModelBaseMysql"))
2 2 Spark.schema = {
3   - id = {"number"}, -- 唯一自增id
  3 + id = {"number", 0, "pri"}, -- 唯一自增id
  4 + roleid = {"number", 0, "index"}, -- 唯一自增id
4 5 cfg_id = {"number"},
5 6 level = {"number", 0}, -- 等级
6 7 attrs = {"table", {}} -- 基础属性值 id=value
... ...
src/models/Store.lua
1 1 -- 商店数据
2 2  
3   -local Store = class("Store", require("shared.ModelBase"))
  3 +local Store = class("Store", require("shared.ModelBaseMysql"))
4 4  
5 5 function Store:ctor(properties)
6 6 Store.super.ctor(self, properties)
... ... @@ -33,6 +33,7 @@ ActGoodsType = {
33 33 }
34 34  
35 35 Store.schema = {
  36 + id = {"number", 0, "pri"}, -- 角色id
36 37 buyR = {"table", {}}, -- 购买商品记录 {id=count}
37 38 payR = {"table", {}}, -- 充值记录 {id=count}
38 39 growFund = {"number", 0}, -- 成长基金
... ...
src/services/agent_ctrl.lua
... ... @@ -10,6 +10,7 @@ local logproxy = require &quot;shared.logproxy&quot;
10 10  
11 11 local pcall = pcall
12 12 local string_format = string.format
  13 +require "utils.MysqlUtil"
13 14  
14 15 local poold
15 16  
... ... @@ -236,8 +237,9 @@ function _M:query_agent(fd, uid, isQueue)
236 237  
237 238 local response = {}
238 239  
239   - local user = redisproxy:get(string_format("uid:%s", uid))
240   - if user then
  240 + --local user = redisproxy:get(string_format("uid:%s", uid))
  241 + local res, user = roleUidExists(uid)
  242 + if res then
241 243 response.ret = "RET_HAS_EXISTED"
242 244 response.name = user
243 245 else
... ...
src/services/dbseed.lua
... ... @@ -4,44 +4,250 @@ require &quot;GlobalVar&quot;
4 4 require "RedisKeys"
5 5 require "ProtocolCode"
6 6 require "skynet.manager"
  7 +require "utils.MysqlUtil"
7 8  
8 9 skynet = require "skynet"
9 10  
10 11 redisproxy = require("shared.redisproxy")
  12 +mysqlproxy = require "shared.mysqlproxy"
11 13  
12 14 SendPacket = function ( ... ) end
13 15  
  16 +local function initSeaportTask()
  17 + local keys = {[SEAPORT_TRADE_TASK_1] = "seaport_task_1", [SEAPORT_TRADE_TASK_2] = "seaport_task_2"}
  18 +
  19 + for key, tb_name in pairs(keys) do
  20 + local res = mysqlproxy:query(string.format("SELECT `id`,`value` FROM %s;", tb_name))
  21 + for _, v in pairs(res) do
  22 + redisproxy:hset(key, v.id, v.value)
  23 + end
  24 + end
  25 +end
  26 +
14 27 local function initRedisDb( ... )
  28 + local function initAutoIncrementUid(tbName, keyName, fieldName)
  29 + if not fieldName then fieldName = "value" end
  30 + local mysqlVal = getDbCfgVal(tbName, keyName, fieldName)
  31 + if not mysqlVal then
  32 + skynet.error(string.format("get db cfg fail, table %s, key %s, field %s", tbName, keyName, fieldName))
  33 + return
  34 + end
  35 + local redisVal = tonum(redisproxy:hget(tbName, keyName))
  36 + if redisVal < mysqlVal then
  37 + redisproxy:hset(tbName, keyName, mysqlVal)
  38 + end
  39 + end
  40 +
  41 + initAutoIncrementUid("autoincrement_set", "role")
  42 + initAutoIncrementUid("autoincrement_set", "union")
  43 + initAutoIncrementUid("autoincrement_set", "order")
  44 + initAutoIncrementUid("autoincrement_set", "email")
  45 + initAutoIncrementUid("autoincrement_set", "emailTimestamp")
  46 + initAutoIncrementUid("autoincrement_set", "delay_email")
  47 + initAutoIncrementUid("autoincrement_set", "stopcreate")
  48 + initAutoIncrementUid("autoincrement_set", "maintain")
  49 + initAutoIncrementUid("autoincrement_set", "seaportTime0")
  50 + initAutoIncrementUid("autoincrement_set", "seaportTime1")
  51 + initAutoIncrementUid("autoincrement_set", "seaportTime2")
  52 +
  53 + redisproxy:hsetnx("adv_season", "idx", 0)
  54 + redisproxy:hsetnx("adv_season", "chapter", globalCsv.adv_endless_default_chapter)
  55 + redisproxy:hsetnx("adv_season", "overTime", 0)
  56 +end
  57 +
  58 +-- 初始化服务器数据库以及服务器信息表
  59 +local function initServerDatabase()
  60 + local servId = skynet.getenv("servId")
  61 + mysqlproxy:query(string.format("CREATE DATABASE IF NOT EXISTS server_%s DEFAULT CHARSET = utf8mb4 COLLATE utf8mb4_general_ci;", servId))
  62 + mysqlproxy:query(string.format("use server_%s", servId))
  63 +
  64 + -- 服务器信息表 开服时间
  65 + mysqlproxy:query [[
  66 + CREATE TABLE IF NOT EXISTS `server_info` (
  67 + `key` varchar(45) NOT NULL,
  68 + `int_value` int(11) DEFAULT NULL,
  69 + `str_value` varchar(128) DEFAULT NULL,
  70 + PRIMARY KEY (`key`)
  71 + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
  72 + ]]
  73 +
  74 + local res = mysqlproxy:query("SELECT * FROM `server_info` where `key` = 'server_start';")
  75 + if not next(res) then
  76 + mysqlproxy:query(string.format("INSERT INTO `server_info`(`key`, `str_value`) VALUES('server_start', '%s');",
  77 + os.date("%Y%m%d", skynet.timex())))
  78 + end
  79 +end
  80 +
  81 +local function initAutoIncreUidTable()
  82 + mysqlproxy:query [[
  83 + CREATE TABLE IF NOT EXISTS `autoincrement_set` (
  84 + `key` varchar(45) NOT NULL,
  85 + `value` int(11) DEFAULT NULL,
  86 + PRIMARY KEY (`key`)
  87 + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
  88 + ]]
15 89 local servId = tonumber(skynet.getenv("servId"))
16 90 if servId then
17   - redisproxy:hsetnx("autoincrement_set", "role", servId * MAX_ROLE_NUM)
18   - redisproxy:hsetnx("autoincrement_set", "union", servId * MAX_ROLE_NUM)
19   - redisproxy:hsetnx("autoincrement_set", "trade", servId * MAX_ROLE_NUM * 100)
20   - redisproxy:hsetnx("autoincrement_set", "email", 0)
21   - redisproxy:hsetnx("autoincrement_set", "emailTimestamp", 0)
22   - redisproxy:hsetnx("autoincrement_set", "delay_email", 0)
23   - redisproxy:hsetnx("adv_season", "idx", 0)
24   - redisproxy:hsetnx("adv_season", "chapter", globalCsv.adv_endless_default_chapter)
25   - redisproxy:hsetnx("adv_season", "overTime", 0)
  91 + local tpl = "INSERT INTO `autoincrement_set`(`key`, `value`) values('%s', %d)"
  92 + mysqlproxy:query(string.format(tpl, "role", servId * MAX_ROLE_NUM))
  93 + mysqlproxy:query(string.format(tpl, "union", servId * MAX_ROLE_NUM))
  94 + mysqlproxy:query(string.format(tpl, "order", 0))
  95 + mysqlproxy:query(string.format(tpl, "email", 0))
  96 + mysqlproxy:query(string.format(tpl, "emailTimestamp", 0))
  97 + mysqlproxy:query(string.format(tpl, "delay_email", 0))
  98 + mysqlproxy:query(string.format(tpl, "stopcreate", 0))
  99 + mysqlproxy:query(string.format(tpl, "maintain", 0))
  100 + mysqlproxy:query(string.format(tpl, "seaportTime0", 0))
  101 + mysqlproxy:query(string.format(tpl, "seaportTime1", 0))
  102 + mysqlproxy:query(string.format(tpl, "seaportTime2", 0))
26 103 end
27 104 end
28 105  
  106 +local function initSeaportTable()
  107 + -- 海港贸易任务
  108 + mysqlproxy:query [[
  109 + CREATE TABLE IF NOT EXISTS `seaport_task_1` (
  110 + `id` int NOT NULL,
  111 + `value` int(11) DEFAULT 0,
  112 + PRIMARY KEY (`id`)
  113 + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
  114 + ]]
  115 + mysqlproxy:query [[
  116 + CREATE TABLE IF NOT EXISTS `seaport_task_2` (
  117 + `id` int NOT NULL,
  118 + `value` int(11) DEFAULT 0,
  119 + PRIMARY KEY (`id`)
  120 + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
  121 + ]]
  122 +end
  123 +
  124 +local function initAdvSeasonTable()
  125 + --mysqlproxy:query [[
  126 + -- CREATE TABLE IF NOT EXISTS `adv_season` (
  127 + -- `key` varchar(45) NOT NULL,
  128 + -- `value` int(11) DEFAULT NULL,
  129 + -- PRIMARY KEY (`key`)
  130 + -- ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
  131 + --]]
  132 + --local servId = tonumber(skynet.getenv("servId"))
  133 + --if servId then
  134 + -- local tpl = "INSERT INTO `adv_season`(`key`, `value`) values('%s', %d)"
  135 +
  136 + -- mysqlproxy:query(string.format(tpl, "idx", 0))
  137 + -- mysqlproxy:query(string.format(tpl, "chapter", globalCsv.adv_endless_default_chapter))
  138 + -- mysqlproxy:query(string.format(tpl, "overTime", 0))
  139 + --end
  140 +end
  141 +
  142 +local function checkRoleTables()
  143 + local list = {"Role", "Daily", "Activity", "Diner", "Store", "Hero", "Rune", "Order", "Email", "Friend", "Spark"}
  144 + for _, name in ipairs(list) do
  145 + local obj = require("models."..name).new({key = "key"})
  146 + print("check table [" .. name .. "] begin.")
  147 + obj:checkTableSchema()
  148 + print("check table [" .. name .. "] end.")
  149 + end
  150 +end
  151 +
  152 +local function createMysqlSp()
  153 + mysqlproxy:query "DROP PROCEDURE IF EXISTS `add_friends`"
  154 + mysqlproxy:query [[
  155 + CREATE PROCEDURE `add_friends`(IN role_id bigint, IN friend_id bigint, IN add_time int)
  156 + BEGIN
  157 + DECLARE t_error INTEGER DEFAULT 0;
  158 + DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET t_error=1;
  159 +
  160 + START TRANSACTION;
  161 + INSERT INTO `Friend`(`roleid`,`fid`,`addTime`) VALUES(role_id, friend_id, add_time);
  162 + INSERT INTO `Friend`(`roleid`,`fid`,`addTime`) VALUES(friend_id, role_id, add_time);
  163 +
  164 + IF t_error = 1 THEN
  165 + ROLLBACK;
  166 + ELSE
  167 + COMMIT;
  168 + END IF;
  169 + select t_error;
  170 + END
  171 + ]]
  172 +
  173 + mysqlproxy:query "DROP PROCEDURE IF EXISTS `del_friends`"
  174 + mysqlproxy:query [[
  175 + CREATE PROCEDURE `del_friends`(IN role_id bigint, IN friend_id bigint)
  176 + BEGIN
  177 + DECLARE t_error INTEGER DEFAULT 0;
  178 + DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET t_error=1;
  179 +
  180 + START TRANSACTION;
  181 + DELETE FROM `Friend` WHERE `roleid` = role_id AND `fid` = friend_id;
  182 + DELETE FROM `Friend` WHERE `roleid` = friend_id AND `fid` = role_id;
  183 +
  184 + IF t_error = 1 THEN
  185 + ROLLBACK;
  186 + ELSE
  187 + COMMIT;
  188 + END IF;
  189 + select t_error;
  190 + END
  191 + ]]
  192 +end
  193 +
  194 +
29 195 local steps = {
30 196 [1] = {
31   - handler = initRedisDb,
32   - desc = "initialize redis database "
33   - }
  197 + handler = initServerDatabase,
  198 + desc = "initialize server database "
  199 + },
  200 + [2] = {
  201 + handler = initAutoIncreUidTable,
  202 + desc = "initialize auto_increment_uid table "
  203 + },
  204 + [3] = {
  205 + handler = initAdvSeasonTable,
  206 + desc = "initialize adv_season table "
  207 + },
  208 + [4] = {
  209 + handler = checkRoleTables,
  210 + desc = "check role tables "
  211 + },
  212 + [5] = {
  213 + handler = createMysqlSp,
  214 + desc = "create mysql store procedure "
  215 + },
  216 + [6] = {
  217 + handler = initSeaportTable,
  218 + desc = "initialize seaport table "
  219 + },
34 220 }
35 221  
36   -skynet.start(function ()
37   - redisproxy = require("shared.redisproxy")
38   -
39   - local new = redisproxy:hsetnx("autoincrement_set", "server_start", os.date("%Y%m%d", skynet.timex())) == 1
40   - if not new then
41   - print("server has been initialized...")
42   - skynet.exit()
43   - return
  222 +local function loadAllUserInfo()
  223 + local maxId = 0
  224 + local sql = "SELECT `id`, `uid`, `name` FROM `Role` WHERE `id` > %d ORDER BY `id` LIMIT 1000;"
  225 + while true do
  226 + local res = mysqlproxy:query(string.format(sql, maxId))
  227 + if not next(res) then
  228 + return
  229 + else
  230 + for _, info in ipairs(res) do
  231 + if info["id"] > maxId then
  232 + maxId = info["id"]
  233 + end
  234 + redisproxy:pipelining(function (red)
  235 + local dbName = string.upper(info["name"])
  236 + red:set(string.format("user:%s", dbName), info["id"])
  237 + red:set(string.format("uid:%s", info["uid"]), dbName)
  238 + end)
  239 + end
  240 + end
44 241 end
  242 +end
  243 +
  244 +skynet.start(function ()
  245 + --local new = redisproxy:hsetnx("autoincrement_set", "server_start", os.date("%Y%m%d", skynet.timex())) == 1
  246 + --if not new then
  247 + -- print("server has been initialized...")
  248 + -- skynet.exit()
  249 + -- return
  250 + --end
45 251 csvdb = require "shared.csvdata"
46 252 globalCsv = csvdb["GlobalDefineCsv"]
47 253  
... ... @@ -50,5 +256,8 @@ skynet.start(function ()
50 256 action.handler()
51 257 print(action.desc .. "finished ...")
52 258 end
  259 + initRedisDb()
  260 + initSeaportTask() -- 海港任务数据初始化
  261 + loadAllUserInfo()
53 262 skynet.exit()
54 263 end)
55 264 \ No newline at end of file
... ...
src/services/globald.lua
... ... @@ -2,12 +2,14 @@ local skynet = require &quot;skynet&quot;
2 2 local harbor = require "skynet.harbor"
3 3 local json = require("shared.json")
4 4 local redisproxy = require("shared.redisproxy")
  5 +local mysqlproxy = require("shared.mysqlproxy")
5 6  
6 7 require "shared.init"
7 8 require "utils.init"
8 9 require "RedisKeys"
9 10 require "skynet.manager"
10 11 require "GlobalVar"
  12 +require "utils.MysqlUtil"
11 13  
12 14  
13 15 local ipairs = ipairs
... ... @@ -18,6 +20,7 @@ local string_format = string.format
18 20  
19 21 local CHECK_MAIL_STATUS_INTERVAL = 100 * 60
20 22 local CHECK_BATTLE_ACT_CLOSE_INTERVAL = 100 * 1
  23 +local SAVE_AUTOINCREMENT_SET_INTERVAL = 100 * 2
21 24 local function mailQuene()
22 25 local delayEmail = tonum(redisproxy:hget("autoincrement_set", "delay_email"))
23 26 if delayEmail == 0 then
... ... @@ -133,7 +136,7 @@ local function check_battle_act_close()
133 136 rankIndex = rankIndex + 1
134 137 for _, cfg in pairs(actData) do
135 138 if rankIndex <= cfg.rank then
136   - redisproxy:insertEmail({
  139 + mysqlproxy:insertEmail({
137 140 roleId = roleId,
138 141 emailId = cfg.email_1,
139 142 attachments = cfg.reward_1,
... ... @@ -153,6 +156,48 @@ local function check_battle_act_close()
153 156 skynet.timeout(CHECK_BATTLE_ACT_CLOSE_INTERVAL, check_battle_act_close)
154 157 end
155 158  
  159 +local function save_autoincrement_timer()
  160 + local function saveUidToMysql(tbName, keyName, fieldName, ignore)
  161 + if not fieldName then fieldName = "value" end
  162 + local mysqlVal = getDbCfgVal(tbName, keyName, fieldName) or 0
  163 + local redisVal = tonum(redisproxy:hget(tbName, keyName))
  164 + if (not ignore) and redisVal > mysqlVal then
  165 + setDbCfgVal(tbName, keyName, fieldName, redisVal)
  166 + end
  167 + end
  168 +
  169 + saveUidToMysql("autoincrement_set", "role")
  170 + saveUidToMysql("autoincrement_set", "union")
  171 + saveUidToMysql("autoincrement_set", "order")
  172 + saveUidToMysql("autoincrement_set", "email")
  173 + saveUidToMysql("autoincrement_set", "emailTimestamp")
  174 + saveUidToMysql("autoincrement_set", "delay_email")
  175 + saveUidToMysql("autoincrement_set", "stopcreate", true)
  176 + saveUidToMysql("autoincrement_set", "maintain", true)
  177 + saveUidToMysql("autoincrement_set", "seaportTime0", true)
  178 + saveUidToMysql("autoincrement_set", "seaportTime1", true)
  179 + saveUidToMysql("autoincrement_set", "seaportTime2", true)
  180 +
  181 + skynet.timeout(SAVE_AUTOINCREMENT_SET_INTERVAL, save_autoincrement_timer)
  182 +end
  183 +
  184 +local function save_seaport_task()
  185 + local keys = {[SEAPORT_TRADE_TASK_1] = "seaport_task_1", [SEAPORT_TRADE_TASK_2] = "seaport_task_2"}
  186 + local sql = "INSERT INTO `%s` VALUES (%d, %d) ON DUPLICATE KEY UPDATE `value` = %d;"
  187 + for k, tb_name in pairs(keys) do
  188 + local data = redisproxy:hgetall(k)
  189 + if not next(data) then
  190 + mysqlproxy:query(string_format("DELETE FROM %s;", tb_name))
  191 + end
  192 + local infos = tarr2tab(data)
  193 + for id, value in pairs(infos) do
  194 + mysqlproxy:query(string_format(sql, tb_name, id, value, value))
  195 + end
  196 + end
  197 +
  198 + skynet.timeout(SAVE_AUTOINCREMENT_SET_INTERVAL, save_seaport_task)
  199 +end
  200 +
156 201 -- @desc: 检查海港贸易开启、关闭
157 202 local function check_trade_seaport_status()
158 203 local nowTime = skynet.timex()
... ... @@ -286,7 +331,9 @@ function CMD.start()
286 331 math.randomInit(skynet.timex())
287 332 check_mail_queue()
288 333 --check_battle_act_close()
  334 + save_autoincrement_timer()
289 335 check_trade_seaport_status()
  336 + save_seaport_task()
290 337 check_trade_seaport_donate()
291 338 check_work_battle()
292 339 end
... ...
src/services/mysqld.lua 0 → 100644
... ... @@ -0,0 +1,45 @@
  1 +local skynet = require "skynet"
  2 +require "skynet.manager"
  3 +local mysql = require "skynet.db.mysql"
  4 +
  5 +local db
  6 +local idx = ...
  7 +local command = {}
  8 +
  9 +function command.open(conf)
  10 + local function on_connect(db)
  11 + local servId = skynet.getenv("servId")
  12 + db:query("set charset utf8mb4");
  13 + db:query(string.format("use server_%s", servId))
  14 + end
  15 + local servId = skynet.getenv("servId")
  16 + db=mysql.connect({
  17 + host=conf.host,
  18 + port=conf.port,
  19 + database= "mysql",
  20 + user=conf.user,
  21 + password=conf.pwd,
  22 + max_packet_size = 5 * 1024 * 1024,
  23 + on_connect = on_connect
  24 + })
  25 + if not db then
  26 + print("failed to connect")
  27 + end
  28 +end
  29 +
  30 +skynet.start(function()
  31 + skynet.dispatch("lua", function(session, address, cmd, ...)
  32 + if cmd == "open" then
  33 + local f = command[string.lower(cmd)]
  34 + skynet.ret(skynet.pack(f(...)))
  35 + elseif string.lower(cmd) == "quote_sql_str" then
  36 + skynet.ret(skynet.pack(db[string.lower(cmd)](...)))
  37 + else
  38 + skynet.ret(skynet.pack(db[string.lower(cmd)](db, ...)))
  39 + end
  40 + end)
  41 + skynet.info_func(function()
  42 + return skynet.stat("mqlen")
  43 + end)
  44 + skynet.register(".mysql" .. idx)
  45 +end)
0 46 \ No newline at end of file
... ...
src/shared/ModelBaseMysql.lua 0 → 100644
... ... @@ -0,0 +1,512 @@
  1 +local ModelBaseMysql = class("ModelBaseMysql")
  2 +ModelBaseMysql.key = "key"
  3 +ModelBaseMysql.schema = {}
  4 +
  5 +local string_format = string.format
  6 +local table_insert = table.insert
  7 +local table_unpack = table.unpack
  8 +local assert = assert
  9 +local next = next
  10 +local ipairs = ipairs
  11 +local pairs = pairs
  12 +local tostring = tostring
  13 +local tonumber = tonumber
  14 +local mysqlproxy = mysqlproxy
  15 +
  16 +local function filterProperties(properties, filter)
  17 + for i, field in ipairs(filter) do
  18 + properties[field] = nil
  19 + end
  20 +end
  21 +
  22 +function ModelBaseMysql:ctor(properties)
  23 + self.cacheFields = {} --缓存字段 不更新数据库的字段
  24 +
  25 + self[self.class.key .. "_"] = properties[self.class.key] --数据库key
  26 + properties[self.class.key] = nil
  27 +
  28 + if not self:isValidKey() then
  29 + print(string_format("%s [%s:key] should be give in new(ctor)", tostring(self), self.class.__cname))
  30 + return
  31 + end
  32 +
  33 + if type(properties) ~= "table" then properties = {} end
  34 + self:loadProperties(properties) --缺少的域将设置默认值
  35 + self:getPriKey()
  36 +end
  37 +
  38 +--[[--
  39 +
  40 +返回对象的 ID 值。
  41 +
  42 +**Returns:**
  43 +
  44 +- ID 值
  45 +
  46 +]]
  47 +function ModelBaseMysql:getKey()
  48 + local id = self[self.class.key .. "_"]
  49 + assert(id ~= nil, string_format("%s [%s:getKey()] Invalid key", tostring(self), self.class.__cname))
  50 + return id
  51 +end
  52 +
  53 +function ModelBaseMysql:getPriKey()
  54 + for k, v in pairs(self.class.schema) do
  55 + local objType, def, keyType, length = table_unpack(v)
  56 + if keyType == "pri" or keyType == "pri_auto" then
  57 + self.pri_key = k
  58 + break
  59 + end
  60 + end
  61 +end
  62 +
  63 +function ModelBaseMysql:load(properties)
  64 + if not self:isValidKey() then
  65 + print(string_format("%s [%s:id] should be set before load", tostring(self), self.class.__cname))
  66 + return false
  67 + end
  68 + local load = false
  69 + if not properties then
  70 + properties = mysqlproxy:query(string_format("SELECT * from `%s` where `%s` = %s;", self.class.__cname, self.pri_key, self:getKey()))
  71 + load = true
  72 + end
  73 + if not next(properties) then return false end
  74 +
  75 + local data = load and properties[1] or properties
  76 +
  77 + self:loadProperties(data)
  78 +
  79 + self:onLoad()
  80 +
  81 + return true
  82 +end
  83 +
  84 +--创建model对应的redis数据, 必须已经设置了ID
  85 +function ModelBaseMysql:create()
  86 + if not self:isValidKey() then
  87 + print(string_format("%s [%s:key] should be set before create", tostring(self), self.class.__cname))
  88 + return nil
  89 + end
  90 +
  91 + self:save()
  92 + self:onCreate()
  93 +
  94 + return self
  95 +end
  96 +
  97 +-- save 忽略 缓存配置
  98 +function ModelBaseMysql:save()
  99 + local redisProperties = self:getProperties()
  100 +
  101 + local params = {}
  102 + for fieldName, value in pairs(redisProperties) do
  103 + local propname = fieldName .. "_"
  104 + if self.class.schema[fieldName][1] == "table" then
  105 + if not next(self[propname]) then
  106 + params[fieldName] = "NULL"
  107 + else
  108 + local result = mysqlproxy:quote_sql_str(MsgPack.pack(self[propname]))
  109 + --params[fieldName] = "'" .. MsgPack.pack(self[propname]) .. "'"
  110 + params[fieldName] = result
  111 + end
  112 + elseif self.class.schema[fieldName][1] == "string" then
  113 + local result = mysqlproxy:quote_sql_str(self[propname])
  114 + --params[fieldName] = "'" .. self[propname] .. "'"
  115 + params[fieldName] = result
  116 + else
  117 + params[fieldName] = self[propname]
  118 + end
  119 + end
  120 + if next(params) then
  121 + -- insert update
  122 + local sql = "INSERT INTO `%s` (%s) VALUES (%s) ON DUPLICATE KEY UPDATE %s;"
  123 + local tbName = self.class.__cname
  124 + local key_list = ""
  125 + local value_list = ""
  126 + local update_list = ""
  127 + for k, v in pairs(params) do
  128 + if key_list ~= "" then
  129 + key_list = key_list .. ","
  130 + end
  131 + if value_list ~= "" then
  132 + value_list = value_list .. ","
  133 + end
  134 + if update_list ~= "" then
  135 + update_list = update_list .. ","
  136 + end
  137 +
  138 + key_list = key_list .. "`" .. k .. "`"
  139 + value_list = value_list .. v
  140 + update_list = update_list .. "`" .. k .. "`=" .. v
  141 + end
  142 + sql = string_format(sql, tbName, key_list, value_list, update_list)
  143 + local res = mysqlproxy:query(sql)
  144 + if res["errno"] then
  145 + skynet.error(sql)
  146 + skynet.error(res["err"])
  147 + end
  148 + end
  149 +end
  150 +
  151 +--[[--
  152 +
  153 +确定对象是否设置了有效的 key。
  154 +
  155 +]]
  156 +function ModelBaseMysql:isValidKey()
  157 + local propname = self.class.key .. "_"
  158 + local key = self[propname]
  159 + return type(key) == "string" and key ~= ""
  160 +end
  161 +
  162 +--[[--
  163 +
  164 +加载对象的属性进内存。
  165 +NOTE: 如果properties缺少schema中的域, 将用默认值来填充
  166 +
  167 +**Parameters:**
  168 +
  169 +- properties: 包含属性值的数组
  170 +
  171 +]]
  172 +function ModelBaseMysql:loadProperties(properties)
  173 + assert(type(properties) == "table", "Invalid properties")
  174 + for field, schema in pairs(self.class.schema) do
  175 + local typ, def = table_unpack(schema)
  176 + local propname = field .. "_"
  177 +
  178 + if typ == "table" and type(properties[field]) == "string" then
  179 + properties[field] = MsgPack.unpack(properties[field])
  180 + end
  181 +
  182 + local val = properties[field] or def
  183 + if val ~= nil then
  184 + if typ == "number" then val = tonumber(val) end
  185 + assert(type(val) == typ,
  186 + string_format("%s [%s:loadProperties()] Type mismatch, %s expected %s, actual is %s",
  187 + tostring(self), self.class.__cname, field, typ, type(val)))
  188 + self[propname] = val
  189 + end
  190 + end
  191 +end
  192 +
  193 +--[[--
  194 +
  195 +取得对象的属性值。
  196 +
  197 +**Parameters:**
  198 +
  199 +- fields: 要取得哪些属性的值,如果未指定该参数,则返回 fields 中设定的属性
  200 +- filter: 要从结果中过滤掉哪些属性,如果未指定则不过滤
  201 +
  202 +**Returns:**
  203 +
  204 +- 包含属性值的数组
  205 +
  206 +]]
  207 +function ModelBaseMysql:getProperties(fields, filter)
  208 + local schema = self.class.schema
  209 + if type(fields) ~= "table" then fields = table.keys(self.class.schema) end
  210 +
  211 + local properties = {}
  212 + for i, field in ipairs(fields) do
  213 + local propname = field .. "_"
  214 + local typ = schema[field][1]
  215 + local val = self[propname]
  216 + assert(type(val) == typ,
  217 + string_format("%s [%s:getProperties()] Type mismatch, %s expected %s, actual is %s",
  218 + tostring(self), self.class.__cname, field, typ, type(val)))
  219 + properties[field] = val
  220 + end
  221 +
  222 + if type(filter) == "table" then
  223 + filterProperties(properties, filter)
  224 + end
  225 +
  226 + return properties
  227 +end
  228 +
  229 +function ModelBaseMysql:getProperty(property)
  230 + if type(property) ~= "string" then return nil end
  231 + if not self.class.schema[property] then return nil end
  232 + return self:getProperties({property})[property]
  233 +end
  234 +
  235 +function ModelBaseMysql:setProperty(property, value, forceSave)
  236 + if not self.class.schema[property] then
  237 + print(string_format("%s [%s:setProperty()] Invalid property : %s",
  238 + tostring(self), self.class.__cname, property))
  239 + return
  240 + end
  241 +
  242 + local typ, def = table_unpack(self.class.schema[property])
  243 + local propname = property .. "_"
  244 +
  245 + if typ == "number" then value = tonumber(value) end
  246 + if typ == "table" and not value then
  247 + value = self[propname] -- table 可以用自己的缓冲
  248 + end
  249 + assert(type(value) == typ,
  250 + string_format("%s [%s:setProperties()] Type mismatch, %s expected %s, actual is %s",
  251 + tostring(self), self.class.__cname, property, typ, type(value)))
  252 +
  253 + if typ == "number" or typ == "string" then
  254 + if self[propname] == value then
  255 + return
  256 + end
  257 + end
  258 + self[propname] = value
  259 + --self:save()
  260 + self.cacheFields[property] = self[propname]
  261 + if forceSave then
  262 + self:update()
  263 + end
  264 +end
  265 +
  266 +function ModelBaseMysql:setProperties(fields, forceSave)
  267 + for property, value in pairs(fields) do
  268 + if not self.class.schema[property] then
  269 + print(string_format("%s [%s:setProperty()] Invalid property : %s",
  270 + tostring(self), self.class.__cname, property))
  271 + else
  272 + local typ, def = table_unpack(self.class.schema[property])
  273 + local propname = property .. "_"
  274 + if typ == "number" then value = tonumber(value) end
  275 + if typ == "table" and not value then
  276 + value = self[propname] -- table 可以用自己的缓冲
  277 + end
  278 + assert(type(value) == typ,
  279 + string_format("%s [%s:setProperties()] Type mismatch, %s expected %s, actual is %s",
  280 + tostring(self), self.class.__cname, property, typ, type(value)))
  281 +
  282 + if typ == "number" or typ == "string" then
  283 + if self[propname] == value then
  284 + return
  285 + end
  286 + end
  287 + self[propname] = value
  288 + self.cacheFields[property] = self[propname]
  289 + end
  290 + end
  291 + if forceSave then
  292 + self:update()
  293 + end
  294 + --self:save()
  295 +end
  296 +
  297 +function ModelBaseMysql:incrProperty(property, value, forceSave)
  298 + if not self.class.schema[property] then
  299 + print(string_format("%s [%s:setProperty()] Invalid property : %s",
  300 + tostring(self), self.class.__cname, property))
  301 + return
  302 + end
  303 +
  304 + local typ, def = table_unpack(self.class.schema[property])
  305 + local propname = property .. "_"
  306 +
  307 + if typ == "table" or typ == "string" then return end
  308 + if typ == "number" then value = tonumber(value) end
  309 +
  310 + self:setProperty(property, self[propname] + value, forceSave)
  311 +end
  312 +
  313 +function ModelBaseMysql:onLoad()
  314 +end
  315 +
  316 +function ModelBaseMysql:onCreate()
  317 +end
  318 +
  319 +function ModelBaseMysql:checkKeyExists(key)
  320 + local res = mysqlproxy:query(string_format("SELECT * FROM `%s` WHERE `%s` = %s", self.class.__cname, self.pri_key, key))
  321 + return next(res)
  322 +end
  323 +
  324 +function ModelBaseMysql:checkTableSchema()
  325 + -- 1.检测是否表存在
  326 + local typeMap = {
  327 + number = {"int", 0},
  328 + string = {"varchar", "", 128},
  329 + table = {"blob", "NULL"},
  330 + pri = {"bigint", 0},
  331 + }
  332 + local tbName = self.class.__cname
  333 + local create_sql = [[
  334 + CREATE TABLE IF NOT EXISTS `%s` (
  335 + %s
  336 + PRIMARY KEY (`%s`)%s
  337 + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
  338 + ]]
  339 + local index_tpl_str = [[,INDEX `%s_Index` (`%s`)]]
  340 +
  341 + local alter_sql = [[
  342 + ALTER TABLE `%s` ADD COLUMN (
  343 + %s
  344 + ) ;
  345 + ]]
  346 + local field_tpl_str = "`%s` %s%s DEFAULT %s"
  347 + local auto_increment_str = "`%s` %s NOT NULL AUTO_INCREMENT"
  348 + local field_str = ""
  349 +
  350 + local res = mysqlproxy:query("desc `".. tbName .. "`;")
  351 + local keyList = {}
  352 + if res["err"] then -- 表不存在
  353 + local schema = {}
  354 + for k, v in pairs(self.class.schema) do
  355 + local keyType = v[3]
  356 + if keyType == "pri" or keyType == "pri_auto" then
  357 + self.pri_key = k
  358 + table_insert(schema, 1, {k, v})
  359 + else
  360 + if keyType == "index" then
  361 + table_insert(keyList, k)
  362 + end
  363 + table_insert(schema, {k, v})
  364 + end
  365 + end
  366 + for _, tbl in ipairs(schema) do
  367 + local k, v = tbl[1], tbl[2]
  368 + local objType, def, keyType, length = table_unpack(v)
  369 + local isAutoPriKey = false
  370 + assert(typeMap[objType], string_format("schema invalid type, %s, %s", tbName, k))
  371 + -- 主键使用bigint存储
  372 + if keyType == "pri" then objType = "pri" end
  373 + if keyType == "pri" or keyType == "pri_auto" then
  374 + objType = "pri"
  375 + if keyType == "pri_auto" then
  376 + isAutoPriKey = true
  377 + end
  378 + end
  379 +
  380 + local info = typeMap[objType]
  381 + local suffix = ""
  382 + local fieldType = info[1]
  383 + if objType == "table" or not def or def == "" then def = info[2] end
  384 + if type(def) == "string" and def ~= "NULL" then def = "'" .. def .. "'" end
  385 + if info[3] and not length then length = info[3] end
  386 + -- 设置字段长度
  387 + if info[3] then suffix = string.format("(%d)", length) end
  388 + -- 很长的string使用blob
  389 + if keyType == "blob" then
  390 + fieldType = keyType
  391 + suffix = ""
  392 + def = "NULL"
  393 + end
  394 +
  395 + if not isAutoPriKey then
  396 + field_str = field_str .. string.format(field_tpl_str..",", k, fieldType, suffix, def)
  397 + else
  398 + field_str = field_str .. string.format(auto_increment_str..",", k, fieldType)
  399 + end
  400 + end
  401 +
  402 + assert(self.pri_key, string_format("table not include primary key, [%s]", tbName))
  403 + local index_key_str = ""
  404 + for _, k in ipairs(keyList) do
  405 + index_key_str = index_key_str .. string_format(index_tpl_str, k, k)
  406 + end
  407 + -- 创建表格
  408 + print(string_format(create_sql, tbName, field_str, self.pri_key, index_key_str))
  409 + mysqlproxy:query(string_format(create_sql, tbName, field_str, self.pri_key, index_key_str))
  410 + else -- 检测是否有添加新字段
  411 + local addCol = {}
  412 + local curCols = {}
  413 + for _, col in ipairs(res) do
  414 + curCols[col["Field"]] = 1
  415 + end
  416 + for k, v in pairs(self.class.schema) do
  417 + local objType, def, keyType, length = table_unpack(v)
  418 + if not curCols[k] then
  419 + print(string_format("table [%s] add new column [%s]", tbName, k))
  420 + assert(typeMap[objType], string_format("schema invalid type, [%s], [%s]", tbName, k))
  421 +
  422 + local info = typeMap[objType]
  423 + local suffix = ""
  424 + local fieldType = info[1]
  425 + if objType == "table" or not def or def == "" then def = info[2] end
  426 + if type(def) == "string" and def ~= "NULL" then def = "'" .. def .. "'" end
  427 + if info[3] and not length then length = info[3] end
  428 + -- 设置字段长度
  429 + if info[3] then suffix = string.format("(%d)", length) end
  430 + -- 很长的string使用blob
  431 + if keyType == "blob" then
  432 + fieldType = keyType
  433 + suffix = ""
  434 + def = "NULL"
  435 + end
  436 + local sep = ","
  437 + if field_str == "" then
  438 + sep = ""
  439 + end
  440 + field_str = field_str .. string.format(sep..field_tpl_str, k, fieldType, suffix, def)
  441 + end
  442 + end
  443 + -- 添加新列
  444 + if field_str ~= "" then
  445 + mysqlproxy:query(string_format(alter_sql, tbName, field_str))
  446 + end
  447 + end
  448 +
  449 +end
  450 +
  451 +function ModelBaseMysql:loadFields(fields)
  452 + if not self:isValidKey() then
  453 + print(string_format("%s [%s:id] should be set before load", tostring(self), self.class.__cname))
  454 + return
  455 + end
  456 + if not next(fields) then
  457 + return
  458 + end
  459 + local final = {}
  460 + for _, v in ipairs(fields) do
  461 + table.insert(final, '`'..v..'`')
  462 + end
  463 + local field_list = table.concat(final, ",")
  464 + local res = mysqlproxy:query(string_format("SELECT %s from `%s` where `%s` = %s;", field_list, self.class.__cname, self.pri_key, self:getKey()))
  465 + if res["errno"] then
  466 + return
  467 + end
  468 +
  469 + return res[1]
  470 +end
  471 +
  472 +function ModelBaseMysql:update()
  473 + if next(self.cacheFields) then
  474 + self:updateFields(self.cacheFields)
  475 + self.cacheFields = {}
  476 + end
  477 +end
  478 +
  479 +function ModelBaseMysql:updateFields(fields)
  480 + local params = {}
  481 + for field, value in pairs(fields) do
  482 + if self.class.schema[field][1] == "table" then
  483 + if next(value) then
  484 + local result = mysqlproxy:quote_sql_str(MsgPack.pack(value))
  485 + params[field] = result
  486 + end
  487 + elseif self.class.schema[field][1] == "string" then
  488 + local result = mysqlproxy:quote_sql_str(value)
  489 + params[field] = result
  490 + else
  491 + params[field] = value
  492 + end
  493 + end
  494 + if next(params) then
  495 + local sql = "UPDATE `%s` SET %s WHERE `%s` = %s;"
  496 + local tbName = self.class.__cname
  497 + local tmp = {}
  498 + for k, v in pairs(params) do
  499 + table.insert(tmp, '`' .. k .. '` = ' .. v)
  500 + end
  501 + sql = string_format(sql, tbName, table.concat(tmp, ","), self.pri_key, self:getKey())
  502 + local res = mysqlproxy:query(sql)
  503 + if res["errno"] then
  504 + skynet.error(sql)
  505 + skynet.error(res["err"])
  506 + return false
  507 + end
  508 + end
  509 + return true
  510 +end
  511 +
  512 +return ModelBaseMysql
0 513 \ No newline at end of file
... ...
src/shared/mysqlproxy.lua 0 → 100644
... ... @@ -0,0 +1,53 @@
  1 +local skynet = require "skynet"
  2 +require "utils.init"
  3 +
  4 +local mysqld_count = tonumber(skynet.getenv("thread"))
  5 +local mysqld
  6 +skynet.init(function()
  7 + local idx = math.randomInt(1, mysqld_count)
  8 + mysqld = skynet.localname(".mysql" .. idx)
  9 +
  10 +end)
  11 +
  12 +local table_insert = table.insert
  13 +
  14 +local mysqlproxy = {}
  15 +
  16 +
  17 +setmetatable(mysqlproxy, { __index = function(t, k)
  18 + local cmd = string.upper(k)
  19 + local f = function (self, ...)
  20 + if k == "query" then
  21 + --print(...)
  22 + end
  23 + local ok, result = pcall(skynet.call, mysqld, "lua", cmd, ...)
  24 + if not ok then
  25 + skynet.error(cmd, ..., "\n", debug.traceback(coroutine.running(), nil))
  26 + return
  27 + end
  28 + return result
  29 + end
  30 + t[k] = f
  31 + return f
  32 +end})
  33 +
  34 +function mysqlproxy:insertEmail(params)
  35 + local pms = {
  36 + key = string.format("%s", 0),
  37 + roleId = params.roleId,
  38 + emailId = params.emailId,
  39 + createtime = params.createtime or skynet.timex(),
  40 + contentPms = params.contentPms or {},
  41 + rewardPms = params.rewardPms or {},
  42 + title = params.title or "",
  43 + stitle = params.stitle or "",
  44 + content = params.content or "",
  45 + attachments = params.attachments or "",
  46 + }
  47 +
  48 + local email = require("models.Email").new(pms)
  49 + email:create()
  50 + return true
  51 +end
  52 +
  53 +return mysqlproxy
0 54 \ No newline at end of file
... ...
src/utils/MysqlUtil.lua 0 → 100644
... ... @@ -0,0 +1,66 @@
  1 +local skynet = require "skynet"
  2 +local mysqlproxy = require "shared.mysqlproxy"
  3 +
  4 +
  5 +function getDbCfgVal(tbName, keyName, fieldName)
  6 + local sql = string.format("SELECT * FROM `%s` WHERE `key` = '%s';", tbName, keyName)
  7 + local res = mysqlproxy:query(sql)
  8 + if not next(res) or res.errno then
  9 + return
  10 + end
  11 +
  12 + return res[1][fieldName]
  13 +end
  14 +
  15 +function setDbCfgVal(tbName, keyName, fieldName, fieldVal)
  16 + if type(fieldVal) == "string" then fieldVal = string.format("'%s'", fieldVal) end
  17 + local sql = string.format("UPDATE `%s` SET `%s` = %s WHERE `key` = '%s';", tbName, fieldName, fieldVal, keyName)
  18 + mysqlproxy:query(sql)
  19 +end
  20 +
  21 +function getFriendCount(roleId)
  22 + local res = mysqlproxy:query(string.format("SELECT `id` FROM `Friend` WHERE `roleid` = %s", roleId))
  23 + if res["errno"] then
  24 + return globalCsv.friendListLimit
  25 + end
  26 +
  27 + return #res
  28 +end
  29 +
  30 +function addFriend(roleId, friendId)
  31 + local stmt_csp = mysqlproxy:prepare("call add_friends(?, ?, ?)")
  32 + local r = mysqlproxy:execute(stmt_csp, roleId, friendId, skynet.timex())
  33 + if r[1][1]["t_error"] == 0 then
  34 + rpcRole(roleId, "addFriend", friendId)
  35 + rpcRole(friendId, "addFriend", roleId)
  36 + end
  37 + dump(r)
  38 +end
  39 +
  40 +function delFriend(roleId, friendId)
  41 + local stmt_csp = mysqlproxy:prepare("call del_friends(?, ?)")
  42 + local r = mysqlproxy:execute(stmt_csp, roleId, friendId)
  43 + if r[1][1]["t_error"] == 0 then
  44 + rpcRole(roleId, "delFriend", friendId)
  45 + rpcRole(friendId, "delFriend", roleId)
  46 + end
  47 + dump(r)
  48 +end
  49 +
  50 +function roleExists(roleId)
  51 + local res = mysqlproxy:query(string.format("SELECT `id` FROM `Role` WHERE `id` = %s", roleId))
  52 + if res["errno"] or not next(res) then
  53 + return false
  54 + end
  55 +
  56 + return true
  57 +end
  58 +
  59 +function roleUidExists(uid)
  60 + local res = mysqlproxy:query(string.format("SELECT `name` FROM `Role` WHERE `uid` = %s", uid))
  61 + if res["errno"] or not next(res) then
  62 + return false
  63 + end
  64 +
  65 + return true, res[1]["name"]
  66 +end
0 67 \ No newline at end of file
... ...