Commit e6f86769023b6fb207b09371516ef402f61b3b75

Authored by 熊润斐
2 parents cade953f daab809c

Merge branch 'tr/bugfix-qa' into tr/publish/qa-out

src/ProtocolCode.lua
... ... @@ -241,6 +241,13 @@ actionCodes = {
241 241 Radio_startQuestRpc = 700,
242 242 Radio_finishQuestRpc = 701,
243 243 Radio_cancelQuestRpc = 702,
  244 +
  245 + Seaport_getServerProcessRpc = 750,
  246 + Seaport_donateRpc = 751,
  247 + Seaport_donateRewardRpc = 752,
  248 + Seaport_taskRpc = 753,
  249 + Seaport_shopRpc = 754,
  250 + Seaport_resetRpc = 755,
244 251 }
245 252  
246 253 rpcResponseBegin = 10000
... ...
src/RedisKeys.lua
... ... @@ -49,8 +49,8 @@ RANK_PVP_HIGHT = "rank:pvph"
49 49 RANK_PVP_HIGHT_KEY = {"rank:pvph1", "rank:pvph2"}
50 50 RECORD_PVP_HIGH = "record:pvph:%d"
51 51  
52   -
53   -
  52 +SEAPORT_TRADE_TASK_1 = "seaport:task1"
  53 +SEAPORT_TRADE_TASK_2 = "seaport:task2"
54 54  
55 55 FRIEND_KEY = "role:%d:friend" --哈希表 好友
56 56 FRIEND_APPLY_KEY = "role:%d:apply" -- sort set 申请列表
... ...
src/actions/RoleAction.lua
... ... @@ -159,6 +159,7 @@ function _M.loginRpc( agent, data )
159 159 role:changeStructVersion() -- 数据结构 版本更新
160 160 role:getAdvData(true) -- 清掉不合格的数据
161 161 role:advEndlessSeasonCheck(true) -- 冒险赛季更新检查
  162 + role:checkSeaportTrade() -- 检查海港贸易季活动
162 163  
163 164 -- 跨天登陆事件
164 165 local resetMode = role:updateTimeReset(now)
... ...
src/actions/SeaportAction.lua 0 → 100644
... ... @@ -0,0 +1,296 @@
  1 +local ipairs = ipairs
  2 +local table = table
  3 +local math = math
  4 +local redisproxy = redisproxy
  5 +local MsgPack = MsgPack
  6 +
  7 +local _M = {}
  8 +
  9 +function _M.getServerProcessRpc(agent, data)
  10 + local role = agent.role
  11 + local result = role:getSeaportServerProgress()
  12 +
  13 + SendPacket(actionCodes.Seaport_getServerProcessRpc, MsgPack.pack(result))
  14 + return true
  15 +end
  16 +
  17 +function _M.donateRpc(agent, data)
  18 + local role = agent.role
  19 + local msg = MsgPack.unpack(data)
  20 +
  21 + local phase = msg.phase or 0
  22 + local id = msg.id or 0
  23 + local itemId = msg.itemId or 0
  24 + local itemCount = msg.count or 0
  25 +
  26 + if itemId == 0 or itemCount == 0 then return 0 end
  27 + if role:getItemCount(itemId) < itemCount then return 1 end
  28 + local DonateCsv = csvdb["seaport_purchaseCsv"]
  29 + if not DonateCsv[phase] or not DonateCsv[phase][id] then return 2 end
  30 +
  31 + local ddata = DonateCsv[phase][id]
  32 + local needs = ddata.need_item:toArray(true,"=")
  33 + if itemId ~= needs[1] then return 3 end
  34 + if itemCount % needs[2] ~= 0 then return 4 end
  35 +
  36 + local group = itemCount / needs[2]
  37 + local rewards = ddata.award:toNumMap()
  38 +
  39 + for id, value in pairs(rewards) do
  40 + rewards[id] = value * group
  41 + end
  42 +
  43 + if phase == 1 then
  44 + local old = tonumber(redisproxy:hget(SEAPORT_TRADE_TASK_1,id)) or 0
  45 + local need = ddata.need_num - old
  46 + if need >= itemCount then
  47 + redisproxy:hincrby(SEAPORT_TRADE_TASK_1,id,itemCount)
  48 + else
  49 + redisproxy:hincrby(SEAPORT_TRADE_TASK_1,id,need)
  50 + for _, temp in pairs(DonateCsv[2]) do
  51 + local items = temp.need_item:toArray(true,"=")
  52 + if items[1] == itemId then
  53 + redisproxy:hincrby(SEAPORT_TRADE_TASK_2,temp.id,itemCount - need)
  54 + break
  55 + end
  56 + end
  57 + end
  58 + else
  59 + redisproxy:hincrby(SEAPORT_TRADE_TASK_2,id,itemCount)
  60 + end
  61 +
  62 + role:costItems({[itemId] = itemCount}, {log = {desc = "seaportDonate", int1 = phase, int2 = id}})
  63 + local reward, change = role:award(rewards, {log = {desc = "seaportDonate", int1 = ddata.phase, int2 = ddata.id}})
  64 +
  65 + role:mylog("role_action", {desc = "seaportDonate", int1 = itemId, int2 = itemCount})
  66 +
  67 + SendPacket(actionCodes.Seaport_donateRpc, MsgPack.pack(role:packReward(reward, change)))
  68 + return true
  69 +end
  70 +
  71 +function _M.donateRewardRpc(agent, data)
  72 + local role = agent.role
  73 + local msg = MsgPack.unpack(data)
  74 +
  75 + local id = msg.id
  76 + local dataCsv = csvdb["seaport_purchaseCsv"]
  77 + if not dataCsv[id] then return 0 end
  78 +
  79 + local seaport = role:getProperty("seaport") or {}
  80 + local donate = seaport.donate or {}
  81 + if donate[id] then return 3 end
  82 +
  83 + local data = dataCsv[id][1]
  84 +
  85 + local result = role:getSeaportServerProgress()
  86 + if not result[id] then return 1 end
  87 +
  88 + for _, tempData in ipairs(dataCsv[id]) do
  89 + if tempData.need_num > (result[id][tempData.id] or 0) then
  90 + return 2
  91 + end
  92 + end
  93 +
  94 + donate[id] = 1
  95 + seaport.donate = donate
  96 +
  97 + local reward, change = role:award(data.phase_award, {log = {desc = "seaportReward", int1 = data.phase, int2 = data.id}})
  98 +
  99 + role:updateProperty({field = "seaport", value = seaport})
  100 + SendPacket(actionCodes.Seaport_donateRewardRpc, MsgPack.pack(role:packReward(reward, change)))
  101 + return true
  102 +end
  103 +
  104 +-- 获取英雄大成功率
  105 +local function getHeroCoef(hero, condition)
  106 + -- 基础概率
  107 + local rareMap = {[HeroQuality.N] = 10, [HeroQuality.R] = 10, [HeroQuality.SR] = 15, [HeroQuality.SSR] = 20}
  108 + local rare = hero:getRare()
  109 + local result = 0
  110 + for _, it in ipairs(condition:toTableArray(true)) do
  111 + local type = it[1]
  112 + local value = it[2]
  113 + local add = it[3]
  114 + if type == 1 then -- 种族加成
  115 + if hero:getCamp() == value then
  116 + result = result + add
  117 + end
  118 + elseif type == 2 then -- 定位加成
  119 + if hero:getPosition() == value then
  120 + result = result + add
  121 + end
  122 + end
  123 + end
  124 +
  125 + return result + (rareMap[rare] or 0)
  126 +end
  127 +
  128 +function _M.taskRpc(agent, data)
  129 + local role = agent.role
  130 + local msg = MsgPack.unpack(data)
  131 +
  132 + local oper = msg.oper or 0
  133 + local team = msg.team or ""
  134 + local taskId = msg.id or 0
  135 + local level = msg.level or 0
  136 +
  137 + if oper == 0 then return 0 end
  138 + local TaskCsv = csvdb["seaport_taskCsv"]
  139 + if not TaskCsv[taskId] or not TaskCsv[taskId][level] then return 1 end
  140 +
  141 + local reward, change = {}, {}
  142 + local seaport = role:getProperty("seaport")
  143 +
  144 + local data = TaskCsv[taskId][level]
  145 + if oper == 1 then -- 开始委托
  146 + if team == "" then return 3 end
  147 + local conditions = data.condition:toTableArray(true)
  148 + local heros = team:toArray(true,"=")
  149 + if not next(heros) then return 8 end
  150 + local UnitCsv = csvdb["unitCsv"]
  151 + for _, conds in pairs(conditions) do
  152 + local count = 0
  153 + for _, heroId in pairs(heros) do
  154 + local hero = role.heros[heroId]
  155 + if not hero then return 8 end
  156 +
  157 + if conds[1] == 1 then
  158 + if hero:getProperty("level") >= conds[2] then
  159 + count = count + 1
  160 + end
  161 + elseif conds[1] == 2 then
  162 + if UnitCsv[hero:getProperty("type")].rare >= conds[2] then
  163 + count = count + 1
  164 + end
  165 + elseif conds[1] == 3 then
  166 + count = count + 1
  167 + end
  168 + end
  169 + if count < conds[#conds] then
  170 + return 4
  171 + end
  172 + end
  173 +
  174 + local collect = seaport.collect or {}
  175 + collect[taskId] = {}
  176 + collect[taskId].time = skynet.timex()
  177 + collect[taskId].level = level
  178 + collect[taskId].team = team
  179 +
  180 + seaport.collect = collect
  181 + elseif oper == 2 then -- 领取委托奖励
  182 + local collects = seaport.collect or {}
  183 + local collect = collects[taskId] or {}
  184 + if not next(collects) or not next(collect) then
  185 + return 5
  186 + end
  187 + local quick = msg.quick
  188 + local endTime = data.time + collect.time
  189 + local remainT = endTime - skynet.timex()
  190 + if not quick and remainT > 0 then return 6 end
  191 +
  192 + if quick and remainT > 0 then
  193 + local cost = math.ceil(remainT / 3600) * globalCsv.seaport_task_quick
  194 + if not role:checkItemEnough({[ItemId.Diamond] = cost}) then return 8 end
  195 + role:costItems({[ItemId.Diamond] = cost}, {log = {desc = "seaportTask", int1 = taskId, int2 = level}})
  196 + end
  197 +
  198 + local carbonCsv = csvdb["idle_battleCsv"]
  199 + local expCarbonId = role:getProperty("hangInfo").expCarbonId
  200 + local coidCarbonId = role:getProperty("hangInfo").carbonId
  201 + if not carbonCsv[expCarbonId] or not carbonCsv[coidCarbonId] then return 7 end
  202 +
  203 + local totalCoef = 0
  204 + for _, heroId in ipairs(collect.team:toArray(true,"=")) do
  205 + local hero = role.heros[heroId]
  206 + if hero then
  207 + totalCoef = totalCoef + getHeroCoef(hero, data.success)
  208 + hero:addHeroFaith(data.trust)
  209 + end
  210 + end
  211 +
  212 + local bigSuccess = false
  213 + local result = math.randomInt(0, 100)
  214 + if result < totalCoef then
  215 + bigSuccess = true
  216 + end
  217 +
  218 + local money = math.ceil(carbonCsv[coidCarbonId].money / 5 * data.time * carbonCsv[coidCarbonId].money_clear)
  219 + local exp = math.ceil(carbonCsv[expCarbonId].exp / 5 * data.time * carbonCsv[expCarbonId].exp_clear)
  220 + local itemReward = data.item_clear_special:toNumMap()
  221 + itemReward[ItemId.Gold] = (itemReward[ItemId.Gold] or 0) + money
  222 + itemReward[ItemId.Exp] = (itemReward[ItemId.Exp] or 0) + exp
  223 +
  224 + if bigSuccess then
  225 + for key, value in pairs(itemReward) do
  226 + itemReward[key] = math.ceil(1.5 * value)
  227 + end
  228 + end
  229 +
  230 + reward, change = role:award(itemReward, {log = {desc = "seaportTask", int1 = taskId, int2 = level}})
  231 +
  232 + seaport.collect[taskId] = nil
  233 + else
  234 + return 0
  235 + end
  236 +
  237 + role:updateProperty({field = "seaport", value = seaport})
  238 +
  239 + SendPacket(actionCodes.Seaport_taskRpc, MsgPack.pack(role:packReward(reward, change)))
  240 + return true
  241 +end
  242 +
  243 +function _M.shopRpc(agent, data)
  244 + local role = agent.role
  245 + local msg = MsgPack.unpack(data)
  246 + local id = msg.id or 0
  247 + local count = msg.count or 1
  248 +
  249 + local shopCsv = {}
  250 + local dataSet = csvdb["shop_normalCsv"]
  251 + for _, datat in pairs(dataSet) do
  252 + if datat.shop == 5 then
  253 + shopCsv[datat.id] = datat
  254 + end
  255 + end
  256 + local sdata = shopCsv[id]
  257 +
  258 + if not sdata then return 2 end
  259 +
  260 + local seaport = role:getProperty("seaport")
  261 + local shop = seaport.shop or {}
  262 +
  263 + if (shop[id] or 0) >= sdata.limit then return 1 end
  264 +
  265 +
  266 +
  267 +
  268 +
  269 + if role:getItemCount(sdata.icon) < sdata.cost * count then return 3 end
  270 +
  271 + role:costItems({[sdata.icon] = sdata.cost * count}, {log = {desc = "seaportShop", int1 = id, int2 = count}})
  272 +
  273 + local itemReward = sdata.gift:toNumMap()
  274 + for itemId, value in pairs(itemReward) do
  275 + itemReward[itemId] = value * count
  276 + end
  277 +
  278 + local reward, change = role:award(itemReward, {log = {desc = "seaportShop", int1 = id, int2 = count}})
  279 +
  280 + shop[id] = (shop[id] or 0) + count
  281 + seaport.shop = shop
  282 +
  283 + role:updateProperty({field = "seaport", value = seaport})
  284 +
  285 + SendPacket(actionCodes.Seaport_shopRpc, MsgPack.pack(role:packReward(reward, change)))
  286 + return true
  287 +end
  288 +
  289 +function _M.resetRpc(agent, data)
  290 + local role = agent.role
  291 + role:checkSeaportTrade()
  292 + SendPacket(actionCodes.Seaport_resetRpc, MsgPack.pack(""))
  293 + return true
  294 +end
  295 +
  296 +return _M
... ...
src/models/Role.lua
... ... @@ -188,6 +188,8 @@ Role.schema = {
188 188 calTask = {"table", {}}, -- 英雄令活动 日历任务活动
189 189 bcTask = {"table", {}}, -- 英雄令活动 日历任务活动 临时使用
190 190 radioTask = {"table", {}}, -- 电台任务 {id = {time=end_ts,heros=heros}} 表crusadeCsv
  191 +
  192 + seaport = {"table", {}}, -- 海岛贸易季 {time = 1234567890, donate = {}, collect = {[1] = {team = "1=2=3", time = 1234567890}}, shop = {}}
191 193 }
192 194  
193 195  
... ... @@ -418,6 +420,8 @@ function Role:data()
418 420 calTask = self:getProperty("calTask"),
419 421 bcTask = self:getProperty("bcTask"),
420 422 radioTask = self:getProperty("radioTask"),
  423 +
  424 + seaport = self:getProperty("seaport"),
421 425 }
422 426 end
423 427  
... ...
src/models/RoleLog.lua
... ... @@ -135,6 +135,11 @@ local ItemReason = {
135 135 --adv
136 136 chooseEvent = 1351, -- 冒险选择
137 137 clickTrader = 1352, -- 冒险商店
  138 +
  139 + seaportDonate = 1400, -- 贸易港捐赠
  140 + seaportShop = 1401, -- 贸易港商店兑换
  141 + seaportReward = 1402, -- 贸易港阶段奖励
  142 + seaportTask = 1403, -- 贸易港任务奖励
138 143 }
139 144  
140 145  
... ...
src/models/RolePlugin.lua
... ... @@ -1208,6 +1208,157 @@ function RolePlugin.bind(Role)
1208 1208 end
1209 1209 end
1210 1210  
  1211 + -- 结算上期海港贸易季
  1212 + function Role:checkSeaportTrade()
  1213 + local openTime0 = tonum(redisproxy:hget("autoincrement_set", "seaportTime0") or 0)
  1214 + local openTime1 = tonum(redisproxy:hget("autoincrement_set", "seaportTime1") or 0)
  1215 + local openTime2 = tonum(redisproxy:hget("autoincrement_set", "seaportTime2") or 0)
  1216 + local seaport = self:getProperty("seaport") or {}
  1217 + local oldTime = seaport.time or 0
  1218 + local update = false
  1219 +
  1220 + local function getReward(reset)
  1221 + -- 全服捐赠奖励
  1222 + local donate = seaport.donate or {}
  1223 + if not reset and (not donate[1] or not donate[2]) then
  1224 + local result = self:getSeaportServerProgress()
  1225 + local seaportCsv = csvdb["seaport_purchaseCsv"]
  1226 + for idx, set in ipairs(seaportCsv) do
  1227 + local done = true
  1228 + for id, data in ipairs(set) do
  1229 + if donate[id] or not result[idx] or not result[idx][id] or result[idx][id] < data.need_num then
  1230 + done = false
  1231 + break
  1232 + end
  1233 + end
  1234 + if done then
  1235 + update = true
  1236 + self:award(data.phase_award, {log = {desc = "seaportReward", int1 = set[1].phase, int2 = set[1].id}})
  1237 + donate[id] = 1
  1238 + end
  1239 + end
  1240 + seaport.donate = donate
  1241 + end
  1242 +
  1243 + -- 委托任务的奖励
  1244 + local collect = seaport.collect or {}
  1245 + if next(collect) then
  1246 + local function getHeroCoef(hero, condition)
  1247 + -- 基础概率
  1248 + local rareMap = {[HeroQuality.N] = 10, [HeroQuality.R] = 10, [HeroQuality.SR] = 15, [HeroQuality.SSR] = 20}
  1249 + local rare = hero:getRare()
  1250 + local result = 0
  1251 + for _, it in ipairs(condition:toTableArray(true)) do
  1252 + local type = it[1]
  1253 + local value = it[2]
  1254 + local add = it[3]
  1255 + if type == 1 then -- 种族加成
  1256 + if hero:getCamp() == value then
  1257 + result = result + add
  1258 + end
  1259 + elseif type == 2 then -- 定位加成
  1260 + if hero:getPosition() == value then
  1261 + result = result + add
  1262 + end
  1263 + end
  1264 + end
  1265 +
  1266 + return result + (rareMap[rare] or 0)
  1267 + end
  1268 +
  1269 + local carbonCsv = csvdb["idle_battleCsv"]
  1270 + local expCarbonId = self:getProperty("hangInfo").expCarbonId
  1271 + local coidCarbonId = self:getProperty("hangInfo").carbonId
  1272 + local taskCsv = csvdb["seaport_taskCsv"]
  1273 + local endTime = openTime0 + 86400 * 2
  1274 + for slot, set in pairs(taskCsv) do
  1275 + if collect[slot] then
  1276 + update = true
  1277 + local level = collect[slot].level
  1278 + local data = set[level]
  1279 + local teams = collect[slot].team
  1280 + local time = collect[slot].time
  1281 + if time + data.time <= endTime then
  1282 + if not carbonCsv[expCarbonId] or not carbonCsv[coidCarbonId] then break end
  1283 +
  1284 + local totalCoef = 0
  1285 + for _, heroId in ipairs(teams:toArray(true,"=")) do
  1286 + local hero = self.heros[heroId]
  1287 + if hero then
  1288 + totalCoef = totalCoef + getHeroCoef(hero, data.success)
  1289 + hero:addHeroFaith(data.trust)
  1290 + end
  1291 + end
  1292 +
  1293 + local bigSuccess = false
  1294 + local result = math.randomInt(0, 100)
  1295 + if result < totalCoef then
  1296 + bigSuccess = true
  1297 + end
  1298 +
  1299 + local money = math.ceil(carbonCsv[coidCarbonId].money / 5 * data.time * carbonCsv[coidCarbonId].money_clear)
  1300 + local exp = math.ceil(carbonCsv[expCarbonId].exp / 5 * data.time * carbonCsv[expCarbonId].exp_clear)
  1301 + local itemReward = data.item_clear_special:toNumMap()
  1302 + itemReward[ItemId.Gold] = (itemReward[ItemId.Gold] or 0) + money
  1303 + itemReward[ItemId.Exp] = (itemReward[ItemId.Exp] or 0) + exp
  1304 +
  1305 + if bigSuccess then
  1306 + for key, value in pairs(itemReward) do
  1307 + itemReward[key] = math.ceil(1.5 * value)
  1308 + end
  1309 + end
  1310 + self:award(itemReward, {log = {desc = "seaportTask", int1 = slot, int2 = level}})
  1311 + end
  1312 + end
  1313 + end
  1314 + end
  1315 + seaport.collect = {}
  1316 +
  1317 + if update or reset then
  1318 + if reset then
  1319 + seaport = {
  1320 + time = openTime0,
  1321 + shop = {},
  1322 + collect = {},
  1323 + donate = {}
  1324 + }
  1325 + end
  1326 + self:setProperty("seaport",seaport)
  1327 + end
  1328 + end
  1329 +
  1330 + if oldTime == openTime0 then
  1331 + if openTime1 == 1 or openTime2 == 1 then
  1332 + return
  1333 + end
  1334 + getReward()
  1335 + else
  1336 + getReward(true)
  1337 + end
  1338 + end
  1339 +
  1340 + function Role:getSeaportServerProgress()
  1341 + local result = {}
  1342 +
  1343 + local dataCsv = csvdb["seaport_purchaseCsv"]
  1344 + local rediskey = {SEAPORT_TRADE_TASK_1,SEAPORT_TRADE_TASK_2}
  1345 + for idx, set in ipairs(dataCsv) do
  1346 + local temp = {}
  1347 + temp = redisproxy:pipelining(function (red)
  1348 + for id, data in ipairs(set) do
  1349 + red:hget(rediskey[idx], id)
  1350 + end
  1351 + end)
  1352 + result[idx] = {}
  1353 + for i,v in ipairs(temp) do
  1354 + if v then
  1355 + result[idx][i] = tonumber(v)
  1356 + end
  1357 + end
  1358 + end
  1359 + return result
  1360 + end
  1361 +
1211 1362 -- 获得激活的冒险效果
1212 1363 function Role:getAdvActiveSupportEffect()
1213 1364 local effect = {}
... ...
src/services/globald.lua
... ... @@ -153,7 +153,36 @@ local function check_battle_act_close()
153 153 skynet.timeout(CHECK_BATTLE_ACT_CLOSE_INTERVAL, check_battle_act_close)
154 154 end
155 155  
  156 +-- @desc: 检查海港贸易开启、关闭
  157 +local function check_trade_seaport_status()
  158 + local nowTime = skynet.timex()
  159 + local nextTime = dayLater(nowTime)
  160 + local interval = 100 * (nextTime - nowTime + 1)
  161 +
  162 + local curTm = os.date("*t", nowTime)
  163 + if curTm.wday == 7 and curTm.hour >= 4 then -- 周六
  164 + local oldTime = tonumber(redisproxy:hget("autoincrement_set", "seaportTime0")) or 0
  165 + local cur4Time = specTime({hour = 4},nowTime)
  166 + if cur4Time ~= oldTime then
  167 + redisproxy:hset("autoincrement_set", "seaportTime0", cur4Time)
  168 + redisproxy:hset("autoincrement_set", "seaportTime1", 1)
  169 + redisproxy:del(SEAPORT_TRADE_TASK_1)
  170 + redisproxy:del(SEAPORT_TRADE_TASK_2)
  171 + end
  172 + end
  173 + if curTm.wday == 1 and curTm.hour >= 4 then -- 周日
  174 + if (tonumber(redisproxy:hget("autoincrement_set", "seaportTime1")) or 0) == 1 then
  175 + redisproxy:hset("autoincrement_set", "seaportTime2", 1)
  176 + end
  177 + end
  178 + if curTm.wday == 2 and curTm.hour >= 4 then -- 周一
  179 + -- redisproxy:hset("autoincrement_set", "seaportTime0", 0)
  180 + redisproxy:hset("autoincrement_set", "seaportTime1", 0)
  181 + redisproxy:hset("autoincrement_set", "seaportTime2", 0)
  182 + end
156 183  
  184 + skynet.timeout(interval, check_trade_seaport_status)
  185 +end
157 186  
158 187 local CMD = {}
159 188  
... ... @@ -178,6 +207,7 @@ end
178 207 function CMD.start()
179 208 check_mail_queue()
180 209 --check_battle_act_close()
  210 + check_trade_seaport_status()
181 211 end
182 212  
183 213 local function __init__()
... ...