Commit 1279810cb1c7a52d93146a2bf8f38009a3e6a752

Authored by liuzujun
2 parents 9b69ca55 020d02ee

海港贸易任务新增表

src/GlobalVar.lua
... ... @@ -19,6 +19,7 @@ START_RESET_TIME = START_RESET_TIME_BASE - TIME_ZONE * 3600
19 19 STRUCT_VERSION = 3 -- 数据结构版本
20 20  
21 21 IOS_SID = 4 -- 判断是不是ios设备
  22 +UO_SID = 6 -- 判断是不是联运渠道
22 23  
23 24 MAX_SVR_ID = 10000
24 25 MAX_ROLE_NUM = 1000000
... ... @@ -85,6 +86,7 @@ ItemType = {
85 86 SpeedBox = 16, -- 加速箱子
86 87 SelectItemBox = 17, -- 自选箱子
87 88 CommonPaster = 18, -- 万能贴纸
  89 + BossTicket = 20, -- boss挑战门票
88 90 }
89 91  
90 92 --在这个里面的会记录的是功能开放 对应类型open 而不是 ID
... ... @@ -315,6 +317,8 @@ CardType = {
315 317 PaySignCard = 6, -- 付费签到卡
316 318 BattlePassCard = 7, -- 探索指令
317 319 ActBattleCommandCard = 8, -- 战令活动卡
  320 + NormalMonthCardLevelUp = 9, -- 月卡升级
  321 + SuperMonthCardLevelUp = 10, -- 超级月卡升级
318 322 }
319 323  
320 324 ShopPackType = {
... ... @@ -374,7 +378,20 @@ DrawCardType = {
374 378 TeamSystemType = {
375 379 Hang = 1,
376 380 BonusBattle = 2,
377   - Tower = 3,
378 381 Dinner = 4,
379 382 FriendBattle = 5,
380   -}
381 383 \ No newline at end of file
  384 +}
  385 +
  386 +-- 某个功能对其他系统功能的加成类型
  387 +SystemBnousType = {
  388 + TowerBuff = 1, -- 电波塔内战斗开始时获得buff
  389 + CrusadeTask = 2, -- 讨伐电台任务加速
  390 + DinerGet = 3, -- 食材供应商获取速度
  391 + DinerLimit = 4, -- 食材供应商上限
  392 + DinerSell = 5, -- 料理贩卖速度
  393 + DinerPrice = 6, -- 齿轮价格
  394 + Adv = 7, -- 代理拾荒获得额外道具
  395 + HangTime = 8, -- 挂机时间上限
  396 + PvpTicket = 9, -- 每周额外获得竞技场门票数量
  397 + SweepReward = 10, -- 奖励关卡每次扫荡额外获得道具
  398 +}
... ...
src/ProtocolCode.lua
... ... @@ -145,6 +145,7 @@ actionCodes = {
145 145 Tower_rankRpc = 353,
146 146 Tower_bugCountRpc = 354,
147 147 Tower_rankInfoRpc = 355,
  148 + Tower_activeTowerBonusRpc = 356,
148 149  
149 150 Car_makePotionRpc = 400,
150 151 Car_equipUpRpc = 401,
... ... @@ -206,6 +207,7 @@ actionCodes = {
206 207 Store_getExploreCommandRewardRpc = 563, --探索指令
207 208 Store_getTotalRechargeAwardRpc = 564, -- 累计充值
208 209  
  210 + Store_biliCloudRechargeRpc = 596,
209 211 Store_biliAndroidRechargeRpc = 597,
210 212 Store_biliCpsRechargeRpc = 598,
211 213 Store_biliUoRechargeRpc = 599,
... ... @@ -243,6 +245,13 @@ actionCodes = {
243 245 Radio_startQuestRpc = 700,
244 246 Radio_finishQuestRpc = 701,
245 247 Radio_cancelQuestRpc = 702,
  248 +
  249 + Seaport_getServerProcessRpc = 750,
  250 + Seaport_donateRpc = 751,
  251 + Seaport_donateRewardRpc = 752,
  252 + Seaport_taskRpc = 753,
  253 + Seaport_shopRpc = 754,
  254 + Seaport_resetRpc = 755,
246 255 }
247 256  
248 257 rpcResponseBegin = 10000
... ...
src/RedisKeys.lua
... ... @@ -26,6 +26,15 @@ RANK_TYPE = {
26 26 RANK_TOWER = "rank:tower"
27 27 RANK_TOWER_INFO = "rank:tower:info"
28 28  
  29 +RANK_TOWER1 = "rank:tower1"
  30 +RANK_TOWER1_INFO = "rank:tower1:info"
  31 +
  32 +RANK_TOWER2 = "rank:tower2"
  33 +RANK_TOWER2_INFO = "rank:tower2:info"
  34 +
  35 +RANK_TOWER3 = "rank:tower3"
  36 +RANK_TOWER3_INFO = "rank:tower3:info"
  37 +
29 38 -- adv
30 39 RANK_ADV = {"rank:adv1", "rank:adv2"}
31 40 RANK_ADV_INFO = "rank:adv:info"
... ... @@ -40,8 +49,8 @@ RANK_PVP_HIGHT = "rank:pvph"
40 49 RANK_PVP_HIGHT_KEY = {"rank:pvph1", "rank:pvph2"}
41 50 RECORD_PVP_HIGH = "record:pvph:%d"
42 51  
43   -
44   -
  52 +SEAPORT_TRADE_TASK_1 = "seaport:task1"
  53 +SEAPORT_TRADE_TASK_2 = "seaport:task2"
45 54  
46 55 FRIEND_KEY = "role:%d:friend" --哈希表 好友
47 56 FRIEND_APPLY_KEY = "role:%d:apply" -- sort set 申请列表
... ...
src/actions/AdvAction.lua
... ... @@ -278,6 +278,7 @@ function _M.startHangRpc(agent, data)
278 278 end
279 279 adv_idle_time = adv_idle_time * 60
280 280  
  281 +
281 282 local advHang = role:getProperty("advHang")
282 283 if advHang[chapterId] then return 3 end --正在挂机
283 284  
... ... @@ -463,6 +464,15 @@ function _M.endHangRpc(agent, data)
463 464 for itemId, count in pairs(idleReward) do
464 465 idleReward[itemId] = count * adv_idle_reward_coef
465 466 end
  467 +
  468 + local bnousReward = role:getBnousAdv()
  469 + for time, set in pairs(bnousReward) do
  470 + local delta = math.floor(adv_idle_time / time)
  471 + for key, value in pairs(set) do
  472 + idleReward[key] = (idleReward[key] or 0) + value * delta
  473 + end
  474 + end
  475 +
466 476 reward, change = role:award(idleReward, {log = {desc = "advHang", int1 = chapterId}})
467 477 else
468 478 if cancel then
... ...
src/actions/DinerAction.lua
... ... @@ -75,7 +75,8 @@ function _M.addSellRpc( agent, data )
75 75 sells[slot].count = count
76 76 sells[slot].time = skynet.timex() - calSell.deltaTime
77 77  
78   - local needTime = sells[slot].count * dishData.sell_time + sells[slot].time - skynet.timex()
  78 + local timeSub = role:getBnousDiner(3,dishData.sell_time)
  79 + local needTime = sells[slot].count * (dishData.sell_time + timeSub) + sells[slot].time - skynet.timex()
79 80 role:pushMsg({type = "food", slot = slot, time = needTime})
80 81  
81 82 -- 检查解锁的顾客
... ... @@ -742,11 +743,15 @@ function _M.getGreenhouseRpc( agent, data )
742 743 local now = skynet.timex()
743 744 local gfood = role.dinerData:getProperty("gfood")
744 745 if not next(gfood) then return end
  746 +
  747 + local timeAdd = role:getBnousDiner(2,globalCsv.diner_get_food_time_max)
  748 +
745 749 for k , v in pairs(gfood) do
746 750 local itemId = v.id
747 751 local st = v.st
748 752 local speed = globalCsv.diner_get_food_speed[csvdb["itemCsv"][itemId].quality] * buildingData.speed / 100
749   - local endTime = st + globalCsv.diner_get_food_time_max
  753 + speed = speed + role:getBnousDiner(1,speed)
  754 + local endTime = st + globalCsv.diner_get_food_time_max + timeAdd
750 755 local endTime2 = math.min(now, endTime)
751 756 reward[itemId] = math.floor((endTime2 - st) / speed)
752 757 if endTime2 == endTime then
... ...
src/actions/GmAction.lua
... ... @@ -483,13 +483,25 @@ function _M.advit(role, pms)
483 483 end
484 484  
485 485  
486   -table.insert(helpDes, {"爬塔到指定层", "tower", "层数"})
  486 +table.insert(helpDes, {"爬塔到指定层", "tower", "塔id", "层数"})
487 487 function _M.tower(role, pms)
488   - local level = tonum(pms.pm1, 1)
  488 + local tType = tonum(pms.pm1, 1)
  489 + local level = tonum(pms.pm2, 1)
  490 + local layer = (tType - 1) * 10000 + level
489 491 if not csvdb["tower_battleCsv"][level] then return "不存在" end
490   - role:updateProperty({field = "towerInfo", value = {c = globalCsv.tower_count_limit, l = level}})
491   -
492   - role:mylog("gm_action", {desc = "tower", int1 = level, key1 = pms.sender})
  492 + local values = role:getProperty("towerInfo")
  493 + if tType == 1 then
  494 + values.l = layer
  495 + elseif tType == 2 then
  496 + values.l1 = layer
  497 + elseif tType == 3 then
  498 + values.l2 = layer
  499 + elseif tType == 4 then
  500 + values.l3 = layer
  501 + end
  502 + role:updateProperty({field = "towerInfo", value = values})
  503 +
  504 + role:mylog("gm_action", {desc = "tower", int1 = tType, int2 = layer, key1 = pms.sender})
493 505  
494 506 return "成功"
495 507 end
... ...
src/actions/HangAction.lua
... ... @@ -326,6 +326,7 @@ function _M.roleFormatRpc(agent , data)
326 326 local index = msg.index -- 阵容索引
327 327 local title = msg.title -- 阵容名称
328 328 local tactics = msg.tactics -- 战术
  329 + local tower = msg.tower
329 330 local team = {}
330 331 for slot, heroId in pairs(msg.heros) do
331 332 if not role.heros[heroId] then
... ... @@ -361,7 +362,11 @@ function _M.roleFormatRpc(agent , data)
361 362 team.tactics = msg.tactics
362 363 end
363 364  
364   - role:setTeamFormat(index, team)
  365 + if tower then
  366 + role:setTowerTeamFormat(index, team)
  367 + else
  368 + role:setTeamFormat(index, team)
  369 + end
365 370  
366 371 SendPacket(actionCodes.Hang_roleFormatRpc, '')
367 372 return true
... ... @@ -376,8 +381,9 @@ function _M.getRewardRpc(agent , data)
376 381 table.clear(items)
377 382 local hangInfo = role:getProperty("hangInfo")
378 383 local nowTime = skynet.timex()
379   - hangInfo.endItemTime = nowTime + globalCsv.idle_producetime_max
380   - hangInfo.endCoinTime = nowTime + globalCsv.idle_producetime_max
  384 + local timeAdd = role:getBnousHangTime()
  385 + hangInfo.endItemTime = nowTime + globalCsv.idle_producetime_max + timeAdd
  386 + hangInfo.endCoinTime = nowTime + globalCsv.idle_producetime_max + timeAdd
381 387 hangInfo.coinTime = nowTime
382 388 hangInfo.itemTime = nowTime
383 389 role:updateProperty({field = "hangBag", value = items})
... ... @@ -508,7 +514,7 @@ function _M.buyBonusCountRpc(agent, data)
508 514 return true
509 515 end
510 516  
511   -local function bonusWinReward(role, bonusData, rewardType, count)
  517 +local function bonusWinReward(role, bonusData, rewardType, count, sweep)
512 518 count = count or 1
513 519  
514 520 local reward, change = {}
... ... @@ -548,6 +554,13 @@ local function bonusWinReward(role, bonusData, rewardType, count)
548 554 end
549 555 end
550 556  
  557 + if sweep then
  558 + local bnousReward = role:getBnousSweep()
  559 + for key, value in pairs(bnousReward) do
  560 + reward[key] = (reward[key] or 0) + value * count
  561 + end
  562 + end
  563 +
551 564 reward, change = role:award(reward, {log = {desc = "bonusBattle", int1 = bonusData.id}})
552 565 role:checkTaskEnter("BonusPass", {id = bonusData.id, count = count})
553 566 return reward, change
... ... @@ -589,7 +602,7 @@ function _M.startBonusBattleRpc(agent, data)
589 602 bonusC[bonusData.type]["c"] = bonusC[bonusData.type]["c"] + count
590 603 role.dailyData:updateProperty({field = "bonusC", value = bonusC})
591 604  
592   - local reward, change = bonusWinReward(role, bonusData, 3, count)
  605 + local reward, change = bonusWinReward(role, bonusData, 3, count, true)
593 606 SendPacket(actionCodes.Hang_startBonusBattleRpc, MsgPack.pack({reward = reward, change = change}))
594 607  
595 608 role:checkTaskEnter("BonusQuick", {count = count})
... ...
src/actions/RadioAction.lua
... ... @@ -95,8 +95,9 @@ function _M.startQuestRpc(agent, data)
95 95 return 5
96 96 end
97 97 -- start quest, set finish time
  98 + local timeSub = role:getBnousCrusade(config.time)
98 99 local taskData = {}
99   - taskData["time"] = skynet.timex() + config.time
  100 + taskData["time"] = skynet.timex() + config.time + timeSub
100 101 taskData["heros"] = heros
101 102 radioTask[id] = taskData
102 103 role:updateProperty({field="radioTask", value=radioTask, notNotify=true})
... ...
src/actions/RoleAction.lua
... ... @@ -161,6 +161,7 @@ function _M.loginRpc( agent, data )
161 161 role:changeStructVersion() -- 数据结构 版本更新
162 162 role:getAdvData(true) -- 清掉不合格的数据
163 163 role:advEndlessSeasonCheck(true) -- 冒险赛季更新检查
  164 + role:checkSeaportTrade() -- 检查海港贸易季活动
164 165  
165 166 -- 跨天登陆事件
166 167 local resetMode = role:updateTimeReset(now)
... ... @@ -748,6 +749,7 @@ function _M.openSpeedUpBoxRpc(agent, data)
748 749 for k , v in pairs(gfood) do
749 750 local itemId = v.id
750 751 local speed = globalCsv.diner_get_food_speed[csvdb["itemCsv"][itemId].quality] * buildingData.speed / 100
  752 + speed = speed + role:getBnousDiner(1,speed)
751 753 reward[itemId] = (reward[itemId] or 0) + math.floor((time / speed) * count)
752 754 end
753 755 else
... ... @@ -1023,8 +1025,6 @@ function _M.achiveRpc(agent, data)
1023 1025 return true
1024 1026 end
1025 1027  
1026   -
1027   -
1028 1028 function _M.chatRpc(agent, data)
1029 1029 local role = agent.role
1030 1030 local roleId = role:getProperty("id")
... ... @@ -1039,10 +1039,21 @@ function _M.chatRpc(agent, data)
1039 1039 -- 判断禁言
1040 1040 local result = nil
1041 1041  
1042   - local SERV = string_format(".chated%d", math.random(1, 5))
1043   - local legal, mod = skynet.call(SERV, "lua", "check", content)
1044   - if not legal then
1045   - content = mod or ""
  1042 + local sdkResult
  1043 + if role:getProperty("sid") == UO_SID then
  1044 + sdkResult = role:uoChatSDK(content)
  1045 + else
  1046 + sdkResult = role:biliChatSDK(content)
  1047 + end
  1048 +
  1049 + if sdkResult then
  1050 + content = sdkResult
  1051 + else
  1052 + local SERV = string_format(".chated%d", math.random(1, 5))
  1053 + local legal, mod = skynet.call(SERV, "lua", "check", content)
  1054 + if not legal then
  1055 + content = mod or ""
  1056 + end
1046 1057 end
1047 1058  
1048 1059 if content == "" then
... ...
src/actions/SeaportAction.lua 0 → 100644
... ... @@ -0,0 +1,306 @@
  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 heroFaithMap = {}
  143 + local seaport = role:getProperty("seaport")
  144 +
  145 + local data = TaskCsv[taskId][level]
  146 + if data.phase == 2 then
  147 + local openTime = tonumber(redisproxy:hget("autoincrement_set", "seaportTime0")) or 0
  148 + local nowTime = skynet.timex()
  149 + if nowTime < (openTime + 86400) or nowTime > (openTime + 172800) then return 9 end
  150 + end
  151 +
  152 + if oper == 1 then -- 开始委托
  153 + if team == "" then return 3 end
  154 + local conditions = data.condition:toTableArray(true)
  155 + local heros = team:toArray(true,"=")
  156 + if not next(heros) then return 8 end
  157 + local UnitCsv = csvdb["unitCsv"]
  158 + for _, conds in pairs(conditions) do
  159 + local count = 0
  160 + for _, heroId in pairs(heros) do
  161 + local hero = role.heros[heroId]
  162 + if not hero then return 8 end
  163 +
  164 + if conds[1] == 1 then
  165 + if hero:getProperty("level") >= conds[2] then
  166 + count = count + 1
  167 + end
  168 + elseif conds[1] == 2 then
  169 + if UnitCsv[hero:getProperty("type")].rare >= conds[2] then
  170 + count = count + 1
  171 + end
  172 + elseif conds[1] == 3 then
  173 + count = count + 1
  174 + end
  175 + end
  176 + if count < conds[#conds] then
  177 + return 4
  178 + end
  179 + end
  180 +
  181 + local collect = seaport.collect or {}
  182 + collect[taskId] = {}
  183 + collect[taskId].time = skynet.timex()
  184 + collect[taskId].level = level
  185 + collect[taskId].team = team
  186 +
  187 + seaport.collect = collect
  188 + elseif oper == 2 then -- 领取委托奖励
  189 + local collects = seaport.collect or {}
  190 + local collect = collects[taskId] or {}
  191 + if not next(collects) or not next(collect) then
  192 + return 5
  193 + end
  194 + local quick = msg.quick
  195 + local endTime = data.time + collect.time
  196 + local remainT = endTime - skynet.timex()
  197 + if not quick and remainT > 0 then return 6 end
  198 +
  199 + if quick and remainT > 0 then
  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}})
  203 + end
  204 +
  205 + local carbonCsv = csvdb["idle_battleCsv"]
  206 + local expCarbonId = role:getProperty("hangInfo").expCarbonId
  207 + if not carbonCsv[expCarbonId] then return 7 end
  208 +
  209 + local totalCoef = 0
  210 + for _, heroId in ipairs(collect.team:toArray(true,"=")) do
  211 + local hero = role.heros[heroId]
  212 + if hero then
  213 + totalCoef = totalCoef + getHeroCoef(hero, data.success)
  214 + hero:addHeroFaith(data.trust)
  215 + heroFaithMap[heroId] = hero:getProperty("faith")
  216 + end
  217 + end
  218 +
  219 + local bigSuccess = false
  220 + local result = math.randomInt(0, 100)
  221 + if result < totalCoef then
  222 + bigSuccess = true
  223 + end
  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)
  227 + local itemReward = data.item_clear_special:toNumMap()
  228 + itemReward[ItemId.Gold] = (itemReward[ItemId.Gold] or 0) + money
  229 + itemReward[ItemId.Exp] = (itemReward[ItemId.Exp] or 0) + exp
  230 +
  231 + if bigSuccess then
  232 + for key, value in pairs(itemReward) do
  233 + itemReward[key] = math.ceil(1.5 * value)
  234 + end
  235 + end
  236 +
  237 + reward, change = role:award(itemReward, {log = {desc = "seaportTask", int1 = taskId, int2 = level}})
  238 +
  239 + seaport.collect[taskId] = nil
  240 + else
  241 + return 0
  242 + end
  243 +
  244 + role:updateProperty({field = "seaport", value = seaport})
  245 +
  246 + local result = role:packReward(reward, change)
  247 + result["heroFaith"] = heroFaithMap
  248 +
  249 + SendPacket(actionCodes.Seaport_taskRpc, MsgPack.pack(result))
  250 + return true
  251 +end
  252 +
  253 +function _M.shopRpc(agent, data)
  254 + local role = agent.role
  255 + local msg = MsgPack.unpack(data)
  256 + local id = msg.id or 0
  257 + local count = msg.count or 1
  258 +
  259 + local shopCsv = {}
  260 + local dataSet = csvdb["shop_normalCsv"]
  261 + for _, datat in pairs(dataSet) do
  262 + if datat.shop == 5 then
  263 + shopCsv[datat.id] = datat
  264 + end
  265 + end
  266 + local sdata = shopCsv[id]
  267 +
  268 + if not sdata then return 2 end
  269 +
  270 + local seaport = role:getProperty("seaport")
  271 + local shop = seaport.shop or {}
  272 +
  273 + if (shop[id] or 0) >= sdata.limit then return 1 end
  274 +
  275 +
  276 +
  277 +
  278 +
  279 + if role:getItemCount(sdata.icon) < sdata.cost * count then return 3 end
  280 +
  281 + role:costItems({[sdata.icon] = sdata.cost * count}, {log = {desc = "seaportShop", int1 = id, int2 = count}})
  282 +
  283 + local itemReward = sdata.gift:toNumMap()
  284 + for itemId, value in pairs(itemReward) do
  285 + itemReward[itemId] = value * count
  286 + end
  287 +
  288 + local reward, change = role:award(itemReward, {log = {desc = "seaportShop", int1 = id, int2 = count}})
  289 +
  290 + shop[id] = (shop[id] or 0) + count
  291 + seaport.shop = shop
  292 +
  293 + role:updateProperty({field = "seaport", value = seaport})
  294 +
  295 + SendPacket(actionCodes.Seaport_shopRpc, MsgPack.pack(role:packReward(reward, change)))
  296 + return true
  297 +end
  298 +
  299 +function _M.resetRpc(agent, data)
  300 + local role = agent.role
  301 + role:checkSeaportTrade()
  302 + SendPacket(actionCodes.Seaport_resetRpc, MsgPack.pack(""))
  303 + return true
  304 +end
  305 +
  306 +return _M
... ...
src/actions/StoreAction.lua
... ... @@ -129,6 +129,32 @@ function _M.biliUoRechargeRpc(agent, data)
129 129 return true
130 130 end
131 131  
  132 +-- 云游戏sdk充值
  133 +function _M.biliCloudRechargeRpc(agent, data)
  134 + local role = agent.role
  135 + local msg = MsgPack.unpack(data)
  136 + local id = msg.id
  137 + local dataSet = csvdb["shop_rechargeCsv"][id]
  138 + if not dataSet then return end
  139 + local roleId = role:getProperty("id")
  140 +
  141 + role.ignoreHeartbeat = true
  142 + --创建订单号
  143 + local partnerOrderId = role:getPurchaseOrder(id)
  144 + -- 签名
  145 + local secret_key = "c97a19c2c00143d6b0f0da2bc52208e7"
  146 + local need = {
  147 + out_trade_no = partnerOrderId,
  148 + money = dataSet.rmb * 100,
  149 + game_money = dataSet.diamond,
  150 + notify_url = msg.notifyUrl
  151 + }
  152 + local sign = signPms(need, secret_key)
  153 +
  154 + SendPacket(actionCodes.Store_biliCloudRechargeRpc, MsgPack.pack({ order = partnerOrderId, sign = sign}))
  155 + return true
  156 +end
  157 +
132 158 -- google 充值 入口
133 159 function _M.googleRechargeRpc(agent, data)
134 160 local role = agent.role
... ...
src/actions/TowerAction.lua
... ... @@ -23,14 +23,32 @@ function _M.startBattleRpc(agent, data)
23 23 local role = agent.role
24 24 local msg = MsgPack.unpack(data)
25 25 local id = msg.id
26   -
27   - if not role:isFuncUnlock(FuncUnlock.Tower) then return end
  26 + local towerType = math.floor(id / 10000)
  27 +
  28 + if not id or towerType < 0 or towerType > 3 then return 0 end
  29 + if not role:isFuncUnlock(FuncUnlock.Tower) then return 1 end
28 30  
29 31 local towerInfo = role:getProperty("towerInfo")
30 32  
31   - if towerInfo.l ~= id then return end -- 层数不对
  33 + if towerType == 0 and (towerInfo.l or 1) ~= id then return 2 end -- 层数不对
  34 + if towerType == 1 and ((towerInfo.l1 or 10001) ~= id or (towerInfo.l or 1) <= globalCsv.tower_open[towerType]) then return 2 end -- 层数不对
  35 + if towerType == 2 and ((towerInfo.l2 or 20001) ~= id or (towerInfo.l or 1) <= globalCsv.tower_open[towerType]) then return 2 end -- 层数不对
  36 + if towerType == 3 and ((towerInfo.l3 or 30001) ~= id or (towerInfo.l or 1) <= globalCsv.tower_open[towerType]) then return 2 end -- 层数不对
  37 +
  38 + if not csvdb["tower_battleCsv"][id] then return 4 end
  39 +
  40 + local teams = role:getTowerTeamFormat(towerType + 1)
  41 + if not next(teams) then return 5 end
  42 +
  43 + if towerType ~= 0 then
  44 + for _, heroId in pairs(teams.heros) do
  45 + local hero = role.heros[heroId]
  46 + if not hero then return 6 end
  47 + local unit = csvdb["unitCsv"][hero:getProperty("type")]
  48 + if unit.camp ~= towerType then return 7 end
  49 + end
  50 + end
32 51  
33   - if not csvdb["tower_battleCsv"][id] then return end
34 52 local curCount, nextTime = getUpdateTime(towerInfo.c, towerInfo.t)
35 53 --if curCount < 1 then return end -- 没有次数返回
36 54  
... ... @@ -57,18 +75,24 @@ function _M.endBattleRpc(agent, data)
57 75 local key = msg.key
58 76 local passTime = msg.passTime
59 77  
  78 + local curTower = csvdb["tower_battleCsv"][id]
  79 + if not curTower then return 2 end
  80 +
60 81 local towerInfo = role:getProperty("towerInfo")
61   - if towerInfo.l ~= id or not towerInfo.k or towerInfo.k ~= key then
  82 + local towerType = math.floor(id / 10000)
  83 + local towerLevel = {[0] = (towerInfo.l or 1), [1] = (towerInfo.l1 or 10001), [2] = (towerInfo.l2 or 20001), [3] = (towerInfo.l3 or 30001)}
  84 + local curLevel = towerLevel[towerType]
  85 +
  86 + if curLevel ~= id or not towerInfo.k or towerInfo.k ~= key then
62 87 SendPacket(actionCodes.Tower_endBattleRpc, MsgPack.pack({errorCode = 1}))
63 88 return true
64 89 end
65   - local curTower = csvdb["tower_battleCsv"][id]
66   - if not curTower then return 2 end
67 90  
68 91 -- 防作弊
69 92 if not role:checkBattleCheat("tower", {
70 93 isWin = msg.starNum and msg.starNum > 0,
71   - info = msg.info
  94 + info = msg.info,
  95 + tower = towerType + 1
72 96 }) then
73 97 SendPacket(actionCodes.Tower_endBattleRpc, MsgPack.pack({errorCode = 1}))
74 98 return true
... ... @@ -81,11 +105,23 @@ function _M.endBattleRpc(agent, data)
81 105 if msg.starNum and msg.starNum > 0 then --win
82 106 curCount = math.min(curCount + 1, globalCsv.tower_count_limit) -- 返还次数
83 107 --排行榜
84   - role:setTowerRank(towerInfo.l)
  108 + role:setTowerRank(curLevel % 10000, towerType + 1)
85 109  
86   - towerInfo.l = towerInfo.l + 1
  110 + curLevel = curLevel + 1
87 111 reward, change = role:award(curTower.reward, {log = {desc = "towerBattle", int1 = id}})
88   - role:checkTaskEnter("TowerPass", {level = towerInfo.l - 1})
  112 + if towerType == 0 then
  113 + role:checkTaskEnter("TowerPass", {level = towerInfo.l})
  114 + end
  115 + end
  116 +
  117 + if towerType == 0 then
  118 + towerInfo.l = curLevel
  119 + elseif towerType == 1 then
  120 + towerInfo.l1 = curLevel
  121 + elseif towerType == 2 then
  122 + towerInfo.l2 = curLevel
  123 + elseif towerType == 3 then
  124 + towerInfo.l3 = curLevel
89 125 end
90 126  
91 127 towerInfo.c = curCount
... ... @@ -93,8 +129,9 @@ function _M.endBattleRpc(agent, data)
93 129 towerInfo.k = nil
94 130 role:updateProperty({field = "towerInfo", value = towerInfo})
95 131  
96   -
97   - local rank = redisproxy:ZREVRANK(RANK_TOWER, role:getProperty("id"))
  132 + local RankTower = {[0] = RANK_TOWER,[1] = RANK_TOWER1,[2] = RANK_TOWER2,[3] = RANK_TOWER3}
  133 + local rankName = RankTower[towerType]
  134 + local rank = redisproxy:ZREVRANK(rankName, role:getProperty("id"))
98 135 if not rank then
99 136 rank = -1
100 137 else
... ... @@ -106,6 +143,7 @@ function _M.endBattleRpc(agent, data)
106 143 info = msg.info,
107 144 reward = reward,
108 145 rank = rank,
  146 + tower = towerType + 1
109 147 })
110 148 role:mylog("tower_action", {desc = "endBattle", short1 = msg.starNum > 0 and 1 or 0, int1 = id})
111 149  
... ... @@ -143,7 +181,9 @@ end
143 181  
144 182 function _M.rankRpc(agent , data)
145 183 local role = agent.role
146   - SendPacket(actionCodes.Tower_rankRpc, MsgPack.pack(role:getTowerRank()))
  184 + local msg = MsgPack.unpack(data)
  185 + local towerType = msg.tower or 1
  186 + SendPacket(actionCodes.Tower_rankRpc, MsgPack.pack(role:getTowerRank(towerType)))
147 187 return true
148 188 end
149 189  
... ... @@ -151,7 +191,43 @@ function _M.rankInfoRpc(agent , data)
151 191 local role = agent.role
152 192 local msg = MsgPack.unpack(data)
153 193 local roleId = msg.roleId
154   - SendPacket(actionCodes.Tower_rankInfoRpc, MsgPack.pack({format = role:getTowerRankOneInfo(roleId)}))
  194 + local towerType = msg.tower or 1
  195 + SendPacket(actionCodes.Tower_rankInfoRpc, MsgPack.pack({format = role:getTowerRankOneInfo(roleId, towerType)}))
  196 + return true
  197 +end
  198 +
  199 +function _M.activeTowerBonusRpc(agent, data)
  200 + local role = agent.role
  201 + local msg = MsgPack.unpack(data)
  202 + local tType = msg.tower
  203 + local id = msg.id
  204 +
  205 + local bnousCsv = csvdb["tower_battle_additionCsv"]
  206 +
  207 + if not tType or not id or not bnousCsv[tType] then return 0 end
  208 + local bnousData = bnousCsv[tType][id]
  209 + if not bnousData then return 1 end
  210 +
  211 + local towerInfo = role:getProperty("towerInfo")
  212 + local towerBnous = role:getProperty("towerBnous")
  213 +
  214 + if towerBnous[tType] and towerBnous[tType][id] then return 2 end
  215 + local towerLevel = {[1] = (towerInfo.l or 1), [2] = (towerInfo.l1 or 10001), [3] = (towerInfo.l2 or 20001), [4] = (towerInfo.l3 or 30001)}
  216 + local curLevel = towerLevel[tType]
  217 +
  218 + if tType ~= 1 then
  219 + if curLevel <= globalCsv.tower_open[tType - 1] then return 4 end
  220 + end
  221 +
  222 + if (curLevel % 10000) <= bnousData.floor then return 3 end
  223 +
  224 + if not towerBnous[tType] then
  225 + towerBnous[tType] = {}
  226 + end
  227 + towerBnous[tType][id] = 1
  228 + role:updateProperty({field = "towerBnous", value = towerBnous})
  229 + role:getTowerBnousActive(true)
  230 + SendPacket(actionCodes.Tower_activeTowerBonusRpc, '')
155 231 return true
156 232 end
157 233  
... ...
src/adv/Adv.lua
... ... @@ -2127,6 +2127,32 @@ function Adv:doActive(activeId, target)
2127 2127 self.battle.player:addBaseAttr(attr, value, vtype)
2128 2128 return true
2129 2129 end
  2130 + -- 13=将目标移动至地图随机点,可以移动至未翻开的空格
  2131 + doActiveEffect[13] = function(_)
  2132 + for _, target in ipairs(targers) do
  2133 + end
  2134 + return true
  2135 + end
  2136 + -- 14=获得drop,在有坐标时需要道具飞入背包的展现。
  2137 + doActiveEffect[14] = function(_, dropId)
  2138 + local gift = nil
  2139 + local dropData = csvdb["event_dropCsv"][dropId]
  2140 + if dropData then
  2141 + local item = dropData["range"]:randWeight(true)
  2142 + if item[1] ~= 0 then
  2143 + gift = {}
  2144 + gift[item[1]] = (gift[item[1]] or 0) + item[2]
  2145 + end
  2146 + end
  2147 + local roomId, blockId
  2148 + if not target or not target.roomId or not target.blockId then
  2149 + roomId, blockId = target.roomId, target.blockId
  2150 + end
  2151 + if gift then
  2152 + self:award(gift, {log = {desc = "doActive", int1 = activeId}}, {roomId = roomId, blockId = blockId})
  2153 + end
  2154 + return true
  2155 + end
2130 2156  
2131 2157 for _, effect in ipairs(activeData.effect:toArray()) do
2132 2158 local cur = effect:toArray(true, "=")
... ...
src/adv/AdvBlock.lua
... ... @@ -215,7 +215,9 @@ function Block:randomEvent()
215 215 randomFunc[AdvEventType.Trap] = function()
216 216 local data = csvdb["event_trapCsv"][self.event.id]
217 217 -- 因为一些神器效果 提前触发被动
218   - adv.battle.player:triggerPassive(Passive.CLICK_TRAP)
  218 + if not data.classify:sismember(1, " ") then
  219 + adv.battle.player:triggerPassive(Passive.CLICK_TRAP)
  220 + end
219 221  
220 222 local buffs = data.effect:toArray(true, "=")
221 223  
... ...
src/adv/AdvBuff.lua
... ... @@ -704,11 +704,13 @@ function Buff:overlay(releaser, data, layer)
704 704  
705 705 self.release = releaser or self.release
706 706 -- 叠加层数
  707 + local oldLayer = self.layer
707 708 self.layer = self.layer + layer
708 709 if maxLayer ~= 0 then
709 710 self.layer = math.min(maxLayer, self.layer)
710 711 end
711   - if self._overlay then
  712 +
  713 + if oldLayer ~= self.layer and self._overlay then
712 714 self:_overlay()
713 715 end
714 716  
... ...
src/adv/AdvMap.lua
... ... @@ -97,23 +97,28 @@ function Map:checkOver()
97 97 end
98 98 end
99 99  
  100 +function Map:randEmptyBlock()
  101 + local pool = {}
  102 + for _, room_ in pairs(self.rooms) do
  103 + for _, block_ in pairs(room_.blocks) do
  104 + if block_.isOpen and not block_.event then
  105 + table.insert(pool, {room_, block_})
  106 + end
  107 + end
  108 + end
  109 + if not next(pool) then return end
  110 + local idx = math.randomInt(1, #pool)
  111 + return pool[idx][1], pool[idx][2]
  112 +end
  113 +
100 114 --随机一个空的位置生成怪, 如果没有就没有
101 115 function Map:addNewMonsterRand(monsterId, where)
102 116 local room, block
103 117 if where then
104 118 room, block = where[1], where[2]
105 119 else
106   - local pool = {}
107   - for _, room_ in pairs(self.rooms) do
108   - for _, block_ in pairs(room_.blocks) do
109   - if block_.isOpen and not block_.event then
110   - table.insert(pool, {room_, block_})
111   - end
112   - end
113   - end
114   - if not next(pool) then return end
115   - local idx = math.randomInt(1, #pool)
116   - room, block = pool[idx][1], pool[idx][2]
  120 + room, block = self:randEmptyBlock()
  121 + if not room then return end
117 122 end
118 123  
119 124 if not monsterId then
... ...
src/adv/AdvPassive.lua
... ... @@ -565,6 +565,16 @@ end
565 565  
566 566 -- 在指定地点召唤event项目
567 567 function Passive:effect12(eventType, triggerPms, eventId, count, stage)
  568 + if eventType == AdvEventType.Monster then
  569 + for _, buff in ipairs(self.owner.battle.player.buffs) do
  570 + if not buff.isDel and buff:getType() == buff.Buff_NO_PASSIVE_MONSTER then
  571 + local effect = buff:effect()
  572 + if effect == 0 or effect == eventId then
  573 + return
  574 + end
  575 + end
  576 + end
  577 + end
568 578 local change = self.owner.battle.adv:getCurMap():layEventToStage(eventType, eventId, count, stage)
569 579 for _, one in ipairs(change) do
570 580 self.owner.battle.adv:backBlockChange(one[1].roomId, one[2].blockId)
... ...
1   -Subproject commit f70c635c2f99d9800b629e41e13aa5115d5f69cd
  1 +Subproject commit 82e5e1f2e6dd2bbbd469d24f7a310c1210655be8
... ...
src/models/Activity.lua
... ... @@ -490,7 +490,7 @@ activityFunc[Activity.ActivityType.CalendaTask] = {
490 490 role:checkTaskEnter("RoleLevelUp", {level = rLevel})
491 491  
492 492 local towerInfo = role:getProperty("towerInfo")
493   - role:checkTaskEnter("TowerPass", {level = towerInfo.l})
  493 + role:checkTaskEnter("TowerPass", {count = towerInfo.l, type = 1})
494 494 --"PvpWin"
495 495 --role:checkTaskEnter("HangPass", {id = 0})
496 496 role:checkCalendaTask(true, 15, 3)
... ... @@ -558,7 +558,7 @@ activityFunc[Activity.ActivityType.BattleCommandTask] = {
558 558 role:checkTaskEnter("RoleLevelUp", {level = rLevel})
559 559  
560 560 local towerInfo = role:getProperty("towerInfo")
561   - role:checkTaskEnter("TowerPass", {level = towerInfo.l})
  561 + role:checkTaskEnter("TowerPass", {count = towerInfo.l, type = 1})
562 562 --"PvpWin"
563 563 --role:checkTaskEnter("HangPass", {id = 0})
564 564 role:checkCalendaTask(true, 15, 3)
... ... @@ -1034,6 +1034,14 @@ activityFunc[Activity.ActivityType.BattleCommand] = {
1034 1034 ["init"] = function (self, actType, isCrossDay, notify, actId)
1035 1035 local data = {unlock = 0, freeR = "", payR = "", lvl = 0, sum = 0, week = 0}
1036 1036 self:updateActData(actType, data, not notify)
  1037 +
  1038 + local rechargeRecord = self.owner.storeData:getProperty("payR")
  1039 + for id, cfg in pairs(csvdb["shop_rechargeCsv"]) do
  1040 + if cfg.shop == 2 and cfg.type == CardType.ActBattleCommandCard then
  1041 + rechargeRecord[id] = nil
  1042 + end
  1043 + end
  1044 + self.owner.storeData:updateProperty({field="payR", value=rechargeRecord})
1037 1045 end,
1038 1046 ["check"] = function(self, actType, notify, id, count) -- 检查 itemid, count
1039 1047 local isOpen, actId = self:isOpen(actType)
... ... @@ -1077,6 +1085,15 @@ activityFunc[Activity.ActivityType.BattleCommand] = {
1077 1085 actData["week"] = 0
1078 1086 self:updateActData(actType, actData, true)
1079 1087 end,
  1088 + ["close"] = function (self, actType, notify, actId)
  1089 + local rechargeRecord = self.owner.storeData:getProperty("payR")
  1090 + for id, cfg in pairs(csvdb["shop_rechargeCsv"]) do
  1091 + if cfg.shop == 2 and cfg.type == CardType.ActBattleCommandCard then
  1092 + rechargeRecord[id] = nil
  1093 + end
  1094 + end
  1095 + self.owner.storeData:updateProperty({field="payR", value=rechargeRecord})
  1096 + end,
1080 1097 }
1081 1098  
1082 1099  
... ...
src/models/Diner.lua
... ... @@ -180,8 +180,13 @@ function Diner:checkDinerTask(typ, count, param1, param2, notNotify)
180 180 return dirty
181 181 end
182 182  
183   -function Diner:calSellReward(sell, delta, dishData)
  183 +function Diner:calSellReward(sell, delta, dishData, isExpedite)
184 184 local reward = sell.reward or ""
  185 +
  186 + if isExpedite then
  187 + reward = ""
  188 + end
  189 +
185 190 local popular = 0
186 191 if delta <= 0 then
187 192 return reward, popular
... ... @@ -226,10 +231,16 @@ function Diner:calSellReward(sell, delta, dishData)
226 231 end
227 232 upValue[-1] = (upValue[-1] or 0) + collectAdd
228 233  
  234 + -- 电波塔加成
  235 + local goldCount = self.owner:getBnousDiner(4,addReward[ItemId.Gold])
  236 +
229 237 for id, count in pairs(addReward) do
230 238 addReward[id] = math.floor(count * (1 + (upValue[id] or 0) / 100))
231 239 reward = reward:incrv(id, addReward[id])
232 240 end
  241 +
  242 + reward = reward:incrv(ItemId.Gold, goldCount)
  243 +
233 244 popular = math.floor(popular * (1 + (upValue[-1] or 0) / 100))
234 245  
235 246 return reward, popular
... ... @@ -246,7 +257,7 @@ function Diner:updateSell(slot, calOnly)
246 257 local deltaTime = 0
247 258 local deltaCount = 0
248 259 local timePass = skynet.timex() - sell.time
249   - local sellTime = dishData.sell_time
  260 + local sellTime = dishData.sell_time + self.owner:getBnousDiner(3, dishData.sell_time)
250 261  
251 262 deltaCount = math.floor(timePass / sellTime)
252 263 if deltaCount < sell.count then
... ... @@ -285,11 +296,11 @@ function Diner:expediteSell(slot)
285 296 local dishData = csvdb["diner_dishCsv"][sell.dish][sell.level]
286 297 local expediteCount = 0
287 298 local expediteTime = globalCsv.diner_sell_expediteTime
288   - local sellTime = dishData.sell_time
  299 + local sellTime = dishData.sell_time + self.owner:getBnousDiner(3,dishData.sell_time)
289 300 expediteCount = math.floor(expediteTime / sellTime)
290 301 expediteCount = math.min(expediteCount, sell.count)
291 302 local lastCount = sell.count - expediteCount
292   - local reward, popular = self:calSellReward(sell, expediteCount, dishData)
  303 + local reward, popular = self:calSellReward(sell, expediteCount, dishData, true)
293 304 local deltaTime = math.floor(expediteTime - sellTime * expediteCount)
294 305 if expediteCount > 0 then
295 306 sells[slot].time = sell.time - deltaTime
... ...
src/models/Role.lua
... ... @@ -118,6 +118,7 @@ Role.schema = {
118 118 hangTeams = {"table", {}}, -- pve自选编队
119 119 teamIndex = {"table", {}}, -- 各个系统使用的编队索引 type->index 见TeamSystemType
120 120 advTeams = {"table", {}}, -- 拾荒自选编队
  121 + towerTeams = {"table", {}}, -- 四个电波塔的队伍
121 122  
122 123 bonusStar = {"table", {}}, -- 奖励关卡 通关星星 {[id] = 1} 三个二进制位 表示三个星 从低到高 (1 << 0) (1 << 1) (1 << 2) 满星 (1 << 3) - 1
123 124  
... ... @@ -149,7 +150,8 @@ Role.schema = {
149 150  
150 151 boxL = {"table", {}}, -- boxList 正开启的箱子 -- {[1] = {id = 1010, gem = 101, time = 1313}}
151 152  
152   - towerInfo = {"table", {c = globalCsv.tower_count_limit, l = 1}}, -- 当天爬塔消耗的次数 -- {t = time, c = count, l = layer, k = battleKey}
  153 + towerInfo = {"table", {c = globalCsv.tower_count_limit, l = 1, l1 = 10001, l2 = 20001, l3 = 30001}}, -- 当天爬塔消耗的次数 -- {t = time, c = count, l = layer, k = battleKey}
  154 + towerBnous = {"table", {}}, -- 电波塔加成 {[1] = {[1] = 1, [2] = 1}, [2] = {}, [3] = {}, [4] = {}}
153 155  
154 156 spTask = {"table", {}}, -- 特殊任务 -- {id = status}
155 157  
... ... @@ -189,6 +191,8 @@ Role.schema = {
189 191 calTask = {"table", {}}, -- 英雄令活动 日历任务活动
190 192 bcTask = {"table", {}}, -- 英雄令活动 日历任务活动 临时使用
191 193 radioTask = {"table", {}}, -- 电台任务 {id = {time=end_ts,heros=heros}} 表crusadeCsv
  194 +
  195 + seaport = {"table", {}}, -- 海岛贸易季 {time = 1234567890, donate = {}, collect = {[1] = {team = "1=2=3", time = 1234567890}}, shop = {}}
192 196 }
193 197  
194 198  
... ... @@ -371,6 +375,7 @@ function Role:data()
371 375 hangTeams = self:getProperty("hangTeams"),
372 376 teamIndex = self:getProperty("teamIndex"),
373 377 advTeams = self:getProperty("advTeams"),
  378 + towerTeams = self:getProperty("towerTeams"),
374 379  
375 380 bonusStar = self:getProperty("bonusStar"),
376 381  
... ... @@ -388,6 +393,7 @@ function Role:data()
388 393 equips = self:getProperty("equips"),
389 394 boxL = self:getProperty("boxL"),
390 395 towerInfo = self:getProperty("towerInfo"),
  396 + towerBnous = self:getProperty("towerBnous"),
391 397 spTask = self:getProperty("spTask"),
392 398 dTask = self:getProperty("dTask"),
393 399 wTask = self:getProperty("wTask"),
... ... @@ -417,6 +423,8 @@ function Role:data()
417 423 calTask = self:getProperty("calTask"),
418 424 bcTask = self:getProperty("bcTask"),
419 425 radioTask = self:getProperty("radioTask"),
  426 +
  427 + seaport = self:getProperty("seaport"),
420 428 }
421 429 end
422 430  
... ...
src/models/RoleBattle.lua
... ... @@ -104,7 +104,7 @@ function Role:checkBattleCheat(battleType, params)
104 104 -- enemyServer = packBattleEnemyCommon(carbonData)
105 105 end
106 106 cheat["tower"] = function()
107   - local team = self:getTeamBattleInfo(self:getTeamFormatByType(TeamSystemType.Tower))
  107 + local team = self:getTeamBattleInfo(self:getTowerTeamFormat(params.tower))
108 108 for slot, hero in pairs(team.heros) do
109 109 local temp = {}
110 110 for arr, _ in pairs(checkCheatAttrs) do
... ... @@ -198,7 +198,7 @@ function Role:checkBattle(battleType, params)
198 198 end
199 199 end,
200 200 tower = function()
201   - local towerF = self:getTeamFormatByType(TeamSystemType.Tower)
  201 + local towerF = self:getTowerTeamFormat(params.tower)
202 202 for slot, hero in pairs(self:getTeamHerosInfo(towerF).heros) do
203 203 selflist[slot] = hero.type
204 204 end
... ...
src/models/RoleLog.lua
... ... @@ -57,6 +57,7 @@ local ItemReason = {
57 57 actBuyBpLevel = 141, -- 购买活动战令等级
58 58 newSign = 142,-- 新的活动签到
59 59 advLevelStage = 143, -- 拾荒活动阶段奖励
  60 + towerBnous = 144, -- 爬塔到一定层数对某些功能的奖励
60 61  
61 62  
62 63 advHang = 301, -- 拾荒挂机
... ... @@ -134,6 +135,11 @@ local ItemReason = {
134 135 --adv
135 136 chooseEvent = 1351, -- 冒险选择
136 137 clickTrader = 1352, -- 冒险商店
  138 +
  139 + seaportDonate = 1400, -- 贸易港捐赠
  140 + seaportShop = 1401, -- 贸易港商店兑换
  141 + seaportReward = 1402, -- 贸易港阶段奖励
  142 + seaportTask = 1403, -- 贸易港任务奖励
137 143 }
138 144  
139 145  
... ...
src/models/RolePlugin.lua
  1 +local httpc = require("http.httpc")
  2 +local md5 = require "md5"
  3 +local cjson = require "shared.json"
1 4  
2 5 local serverId = tonumber(skynet.getenv("servId"))
3 6 local RolePlugin = {}
... ... @@ -136,6 +139,12 @@ function RolePlugin.bind(Role)
136 139 [ItemType.Potion] = function ()
137 140 self:addPotion({id = itemId, count = count, notNotify = pms.notNotify, log = pms.log})
138 141 end,
  142 + [ItemType.BossTicket] = function ()
  143 + if not self.activity:isOpen("ChallengeLevel") then return end
  144 + local actData = self.activity:getActData("ChallengeLevel")
  145 + actData["ticket"] = (actData["ticket"] or 0) + count
  146 + self.activity:updateActData("ChallengeLevel", actData)
  147 + end,
139 148 }
140 149  
141 150 if count > 0 then
... ... @@ -305,7 +314,6 @@ function RolePlugin.bind(Role)
305 314 end
306 315  
307 316 function Role:addPotion(params)
308   - dump(params)
309 317 local pId = globalCsv.adv_item_potion[params.id]
310 318 local potionBag = self:getProperty("potionBag")
311 319 local origin = potionBag[pId] or 0
... ... @@ -1219,6 +1227,156 @@ function RolePlugin.bind(Role)
1219 1227 end
1220 1228 end
1221 1229  
  1230 + -- 结算上期海港贸易季
  1231 + function Role:checkSeaportTrade()
  1232 + local openTime0 = tonum(redisproxy:hget("autoincrement_set", "seaportTime0") or 0)
  1233 + local openTime1 = tonum(redisproxy:hget("autoincrement_set", "seaportTime1") or 0)
  1234 + local openTime2 = tonum(redisproxy:hget("autoincrement_set", "seaportTime2") or 0)
  1235 + local seaport = self:getProperty("seaport") or {}
  1236 + local oldTime = seaport.time or 0
  1237 + local update = false
  1238 +
  1239 + local function getReward(reset)
  1240 + -- 全服捐赠奖励
  1241 + local donate = seaport.donate or {}
  1242 + if not reset and (not donate[1] or not donate[2]) then
  1243 + local result = self:getSeaportServerProgress()
  1244 + local seaportCsv = csvdb["seaport_purchaseCsv"]
  1245 + for idx, set in ipairs(seaportCsv) do
  1246 + local done = true
  1247 + for id, data in ipairs(set) do
  1248 + if donate[id] or not result[idx] or not result[idx][id] or result[idx][id] < data.need_num then
  1249 + done = false
  1250 + break
  1251 + end
  1252 + end
  1253 + if done then
  1254 + update = true
  1255 + self:award(set[1].phase_award, {log = {desc = "seaportReward", int1 = set[1].phase, int2 = set[1].id}})
  1256 + donate[idx] = 1
  1257 + end
  1258 + end
  1259 + seaport.donate = donate
  1260 + end
  1261 +
  1262 + -- 委托任务的奖励
  1263 + local collect = seaport.collect or {}
  1264 + if next(collect) then
  1265 + local function getHeroCoef(hero, condition)
  1266 + -- 基础概率
  1267 + local rareMap = {[HeroQuality.N] = 10, [HeroQuality.R] = 10, [HeroQuality.SR] = 15, [HeroQuality.SSR] = 20}
  1268 + local rare = hero:getRare()
  1269 + local result = 0
  1270 + for _, it in ipairs(condition:toTableArray(true)) do
  1271 + local type = it[1]
  1272 + local value = it[2]
  1273 + local add = it[3]
  1274 + if type == 1 then -- 种族加成
  1275 + if hero:getCamp() == value then
  1276 + result = result + add
  1277 + end
  1278 + elseif type == 2 then -- 定位加成
  1279 + if hero:getPosition() == value then
  1280 + result = result + add
  1281 + end
  1282 + end
  1283 + end
  1284 +
  1285 + return result + (rareMap[rare] or 0)
  1286 + end
  1287 +
  1288 + local carbonCsv = csvdb["idle_battleCsv"]
  1289 + local expCarbonId = self:getProperty("hangInfo").expCarbonId
  1290 + local taskCsv = csvdb["seaport_taskCsv"]
  1291 + local endTime = openTime0 + 86400 * 2
  1292 + for slot, set in pairs(taskCsv) do
  1293 + if collect[slot] then
  1294 + update = true
  1295 + local level = collect[slot].level
  1296 + local data = set[level]
  1297 + local teams = collect[slot].team
  1298 + local time = collect[slot].time
  1299 + if time + data.time <= endTime then
  1300 + if not carbonCsv[expCarbonId] then break end
  1301 +
  1302 + local totalCoef = 0
  1303 + for _, heroId in ipairs(teams:toArray(true,"=")) do
  1304 + local hero = self.heros[heroId]
  1305 + if hero then
  1306 + totalCoef = totalCoef + getHeroCoef(hero, data.success)
  1307 + hero:addHeroFaith(data.trust)
  1308 + end
  1309 + end
  1310 +
  1311 + local bigSuccess = false
  1312 + local result = math.randomInt(0, 100)
  1313 + if result < totalCoef then
  1314 + bigSuccess = true
  1315 + end
  1316 +
  1317 + local money = math.ceil(carbonCsv[expCarbonId].money / 5 * data.time * data.money_clear)
  1318 + local exp = math.ceil(carbonCsv[expCarbonId].exp / 5 * data.time * data.exp_clear)
  1319 + local itemReward = data.item_clear_special:toNumMap()
  1320 + itemReward[ItemId.Gold] = (itemReward[ItemId.Gold] or 0) + money
  1321 + itemReward[ItemId.Exp] = (itemReward[ItemId.Exp] or 0) + exp
  1322 +
  1323 + if bigSuccess then
  1324 + for key, value in pairs(itemReward) do
  1325 + itemReward[key] = math.ceil(1.5 * value)
  1326 + end
  1327 + end
  1328 + self:award(itemReward, {log = {desc = "seaportTask", int1 = slot, int2 = level}})
  1329 + end
  1330 + end
  1331 + end
  1332 + end
  1333 + seaport.collect = {}
  1334 +
  1335 + if update or reset then
  1336 + if reset then
  1337 + seaport = {
  1338 + time = openTime0,
  1339 + shop = {},
  1340 + collect = {},
  1341 + donate = {}
  1342 + }
  1343 + end
  1344 + self:updateProperty({field = "seaport", value = seaport})
  1345 + end
  1346 + end
  1347 +
  1348 + if oldTime == openTime0 then
  1349 + if openTime1 == 1 or openTime2 == 1 then
  1350 + return
  1351 + end
  1352 + getReward()
  1353 + else
  1354 + getReward(true)
  1355 + end
  1356 + end
  1357 +
  1358 + function Role:getSeaportServerProgress()
  1359 + local result = {}
  1360 +
  1361 + local dataCsv = csvdb["seaport_purchaseCsv"]
  1362 + local rediskey = {SEAPORT_TRADE_TASK_1,SEAPORT_TRADE_TASK_2}
  1363 + for idx, set in ipairs(dataCsv) do
  1364 + local temp = {}
  1365 + temp = redisproxy:pipelining(function (red)
  1366 + for id, data in ipairs(set) do
  1367 + red:hget(rediskey[idx], id)
  1368 + end
  1369 + end)
  1370 + result[idx] = {}
  1371 + for i,v in pairs(temp) do
  1372 + if v then
  1373 + result[idx][i] = tonumber(v)
  1374 + end
  1375 + end
  1376 + end
  1377 + return result
  1378 + end
  1379 +
1222 1380 -- 获得激活的冒险效果
1223 1381 function Role:getAdvActiveSupportEffect()
1224 1382 local effect = {}
... ... @@ -1286,11 +1444,21 @@ function RolePlugin.bind(Role)
1286 1444 end
1287 1445  
1288 1446 local StdTowerRankTime = toUnixtime("2019010100")
1289   - function Role:setTowerRank(level)
  1447 + local TowerRankInfo = {
  1448 + [1] = {rank = RANK_TOWER, rankInfo = RANK_TOWER_INFO},
  1449 + [2] = {rank = RANK_TOWER1, rankInfo = RANK_TOWER1_INFO},
  1450 + [3] = {rank = RANK_TOWER2, rankInfo = RANK_TOWER2_INFO},
  1451 + [4] = {rank = RANK_TOWER3, rankInfo = RANK_TOWER3_INFO},
  1452 + }
  1453 + function Role:setTowerRank(level,tType)
  1454 + tType = tType or 1
1290 1455 local now = skynet.timex()
1291 1456 local ct = math.ceil((now - StdTowerRankTime) / 86400) --按天计算 365 * 27 < 10000 可以维持 27 年
1292 1457 local ct = 10000 - ct -- 越早的排名越靠前
1293   - local towerTeam = self:getTeamFormatByType(TeamSystemType.Tower)
  1458 +
  1459 +
  1460 + local info = TowerRankInfo[tType]
  1461 + local towerTeam = self:getTowerTeamFormat(tostring(tType))
1294 1462 local battleV = self:getTeamBattleValue(towerTeam.heros)
1295 1463 local score = (level * 10000 + ct) * 10000000 + battleV
1296 1464  
... ... @@ -1304,21 +1472,23 @@ function RolePlugin.bind(Role)
1304 1472 }
1305 1473 local roleId = self:getProperty("id")
1306 1474 redisproxy:pipelining(function (red)
1307   - red:zadd(RANK_TOWER, score, roleId) --更新分数
1308   - red:hset(RANK_TOWER_INFO, roleId, MsgPack.pack(curInfo))
  1475 + red:zadd(info.rank, score, roleId) --更新分数
  1476 + red:hset(info.rankInfo, roleId, MsgPack.pack(curInfo))
1309 1477 end)
1310 1478 end
1311 1479  
1312   - function Role:getTowerRank()
  1480 + function Role:getTowerRank(tType)
  1481 + tType = tType or 1
  1482 + local info = TowerRankInfo[tType]
1313 1483 local list = {}
1314   - local ids = redisproxy:zrevrange(RANK_TOWER, 0 , 99)
  1484 + local ids = redisproxy:zrevrange(info.rank, 0 , 99)
1315 1485 local redret = {}
1316 1486 if ids and next(ids) then
1317 1487 redret = redisproxy:pipelining(function (red)
1318 1488 for i = 1, #ids do
1319 1489 local roleId = ids[i]
1320 1490 table.insert(list, {roleId = tonumber(roleId)})
1321   - red:hget(RANK_TOWER_INFO, roleId)
  1491 + red:hget(info.rankInfo, roleId)
1322 1492 end
1323 1493 end)
1324 1494 end
... ... @@ -1327,7 +1497,7 @@ function RolePlugin.bind(Role)
1327 1497 player.format = nil
1328 1498 list[i].player = player
1329 1499 end
1330   - local rank = redisproxy:ZREVRANK(RANK_TOWER, self:getProperty("id"))
  1500 + local rank = redisproxy:ZREVRANK(info.rank, self:getProperty("id"))
1331 1501 if not rank then
1332 1502 rank = -1
1333 1503 else
... ... @@ -1336,8 +1506,10 @@ function RolePlugin.bind(Role)
1336 1506 return {list = list, rank = rank}
1337 1507 end
1338 1508  
1339   - function Role:getTowerRankOneInfo(roleId)
1340   - local data = redisproxy:hget(RANK_TOWER_INFO, roleId)
  1509 + function Role:getTowerRankOneInfo(roleId,tType)
  1510 + tType = tType or 1
  1511 + local info = TowerRankInfo[tType]
  1512 + local data = redisproxy:hget(info.rankInfo, roleId)
1341 1513 if data then
1342 1514 local player = MsgPack.unpack(data)
1343 1515 return player.format
... ... @@ -1557,6 +1729,19 @@ function RolePlugin.bind(Role)
1557 1729 })
1558 1730 end
1559 1731  
  1732 + -- 设置电波塔阵容
  1733 + function Role:getTowerTeamFormat(teamIdx)
  1734 + local teams = self:getProperty("towerTeams") or {}
  1735 + local team = teams[tostring(teamIdx)] or {}
  1736 + return team
  1737 + end
  1738 +
  1739 + function Role:setTowerTeamFormat(teamIdx, team)
  1740 + local teams = self:getProperty("towerTeams") or {}
  1741 + teams[tostring(teamIdx)] = team
  1742 + self:updateProperty({field = "towerTeams", value = teams, notNotify = false})
  1743 + end
  1744 +
1560 1745 -- update
1561 1746 function Role:onRecoverTimer(now)
1562 1747 self:updateTimeReset(now, true)
... ... @@ -2180,6 +2365,211 @@ function RolePlugin.bind(Role)
2180 2365 return hero:getProperty("faith")
2181 2366 end
2182 2367  
  2368 + local function table_keys( t )
  2369 + local keys = {}
  2370 + for k, _ in pairs( t ) do
  2371 + keys[#keys + 1] = k
  2372 + end
  2373 + return keys
  2374 + end
  2375 +
  2376 + local function makeStr(params, key, urlsign)
  2377 + local keys = table_keys(params)
  2378 + table.sort(keys)
  2379 + local sign2Str, requestStr = "", ""
  2380 + for _, key in ipairs(keys) do
  2381 + sign2Str = sign2Str .. (urlsign and urlencode(params[key]) or params[key])
  2382 + requestStr = requestStr .. string.format("%s=%s&",key,urlencode(params[key]))
  2383 + end
  2384 + local sign = md5.sumhexa(sign2Str .. key):lower()
  2385 + requestStr = requestStr .. string.format("sign=%s",sign)
  2386 +
  2387 + return requestStr
  2388 + end
  2389 +
  2390 + function Role:biliChatSDK(content)
  2391 + if content == "" then return end
  2392 + local base64Content = base64.encode(content)
  2393 + local uids = self:getProperty("uid"):split2("_")
  2394 + local uid = uids[2] or self:getProperty("uid")
  2395 +
  2396 + local urls = {
  2397 + "http://pnew.biligame.net",
  2398 + "http://pserver.bilibiligame.net"
  2399 + }
  2400 + local secret = "8920e9dcf0cb4ebca87393ce48021ead"
  2401 +
  2402 + local headers = {
  2403 + ["User-Agent"] = 'Mozilla/5.0 GameServer',
  2404 + ["Content-Type"] = "application/x-www-form-urlencoded",
  2405 + }
  2406 +
  2407 + local send = {
  2408 + game_id = 4818,
  2409 + uid = uid,
  2410 + merchant_id = 1,
  2411 + server_id = 3957,
  2412 + version = "1",
  2413 + timestamp = math.floor(skynet.timex() * 1000),
  2414 + content = base64Content,
  2415 + }
  2416 +
  2417 + local params = makeStr(send, secret)
  2418 + httpc.timeout = 100
  2419 + local status, body = httpc.request("POST", urls[1], "/api/server/censor", {}, headers, params)
  2420 + if tonumber(status) ~= 200 then
  2421 + status, body = httpc.request("POST", urls[2], "/api/server/censor", {}, headers, params)
  2422 + end
  2423 + if tonumber(status) ~= 200 then
  2424 + return
  2425 + end
  2426 + local result = json.decode(body)
  2427 + if not result or result.code ~= 0 then
  2428 + return
  2429 + end
  2430 + return result.data.content
  2431 + end
  2432 +
  2433 + function Role:uoChatSDK(content)
  2434 + if content == "" then return end
  2435 + local base64Content = base64.encode(content)
  2436 + local uids = self:getProperty("uid"):split2("_")
  2437 + local uid = uids[2] or self:getProperty("uid")
  2438 +
  2439 + local urls = {
  2440 + "http://uosdk.biligame.com",
  2441 + }
  2442 + local secret = "4243b5fb44b64175a20a53dcfb1346eb"
  2443 +
  2444 + local headers = {
  2445 + ["User-Agent"] = 'Mozilla/5.0 CP-Game-Server',
  2446 + ["Content-Type"] = "application/x-www-form-urlencoded",
  2447 + }
  2448 +
  2449 + local send = {
  2450 + app_id = 4821,
  2451 + user_id = uid,
  2452 + timestamp = math.floor(skynet.timex() * 1000),
  2453 + content = base64Content,
  2454 + }
  2455 +
  2456 + local params = makeStr(send, secret, true)
  2457 + httpc.timeout = 100
  2458 + local status, body = httpc.request("POST", urls[1], "/api/server/censor", {}, headers, params)
  2459 + if tonumber(status) ~= 200 then
  2460 + return
  2461 + end
  2462 + local result = json.decode(body)
  2463 + if not result or result.code ~= 0 then
  2464 + return
  2465 + end
  2466 + return result.data.content
  2467 + end
  2468 +
  2469 + function Role:getTowerBnousActive(update)
  2470 + if not update and self.towerBnousActive then
  2471 + return self.towerBnousActive
  2472 + end
  2473 + local towerInfo = self:getProperty("towerInfo")
  2474 + local towerLevel = {towerInfo.l or 1, towerInfo.l1 or 10001, towerInfo.l2 or 20001, towerInfo.l3 or 30001}
  2475 + local towerBnous = self:getProperty("towerBnous")
  2476 + local bnousCsv = csvdb["tower_battle_additionCsv"]
  2477 + self.towerBnousActive = {}
  2478 +
  2479 + for towerIdx, Set in pairs(towerBnous) do
  2480 + for id, _ in pairs(Set) do
  2481 + local data = bnousCsv[towerIdx][id]
  2482 + if data then
  2483 + local effects = data.effect:toTableArraySec()
  2484 + for _, effect in pairs(effects) do
  2485 + local pm1, pm2, pm3, pm4 = tonumber(effect[1]), tonumber(effect[2]), tonumber(effect[3]), tonumber(effect[4])
  2486 + if not self.towerBnousActive[pm1] then
  2487 + self.towerBnousActive[pm1] = {}
  2488 + end
  2489 + if pm1 == SystemBnousType.TowerBuff then
  2490 + if not self.towerBnousActive[pm1][pm2] then
  2491 + self.towerBnousActive[pm1][pm2] = {}
  2492 + end
  2493 + table.insert(self.towerBnousActive[pm1][pm2],pm3)
  2494 + elseif pm1 == SystemBnousType.Adv then
  2495 + if not self.towerBnousActive[pm1][pm4] then
  2496 + self.towerBnousActive[pm1][pm4] = {}
  2497 + end
  2498 + self.towerBnousActive[pm1][pm4][pm2] = (self.towerBnousActive[pm1][pm4][pm2] or 0) + pm3
  2499 + elseif pm1 == SystemBnousType.HangTime then
  2500 + if type(self.towerBnousActive[pm1]) == "table" then
  2501 + self.towerBnousActive[pm1] = 0
  2502 + end
  2503 + self.towerBnousActive[pm1] = self.towerBnousActive[pm1] + pm2
  2504 + else
  2505 + self.towerBnousActive[pm1][pm2] = (self.towerBnousActive[pm1][pm2] or 0) + pm3
  2506 + end
  2507 + end
  2508 + end
  2509 + end
  2510 + end
  2511 +
  2512 + return self.towerBnousActive
  2513 + end
  2514 +
  2515 + function Role:getDeltaValue(result, value)
  2516 + if not result then return 0 end
  2517 + local delta = 0
  2518 + if result[1] and value then
  2519 + delta = math.floor(value * result[1] / 100)
  2520 + end
  2521 + if result[0] then
  2522 + delta = delta + result[0]
  2523 + end
  2524 + return delta
  2525 + end
  2526 +
  2527 + function Role:getBnousBattleBuff()
  2528 + local towerBnous = self:getTowerBnousActive()
  2529 + return towerBnous[SystemBnousType.TowerBuff]
  2530 + end
  2531 +
  2532 + function Role:getBnousCrusade(value)
  2533 + local towerBnous = self:getTowerBnousActive()
  2534 + return self:getDeltaValue(towerBnous[SystemBnousType.CrusadeTask], value)
  2535 + end
  2536 +
  2537 + function Role:getBnousDiner(type, value)
  2538 + local towerBnous = self:getTowerBnousActive()
  2539 + type = type or 1
  2540 + local result
  2541 + if type == 1 then
  2542 + result = towerBnous[SystemBnousType.DinerGet]
  2543 + elseif type == 2 then
  2544 + result = towerBnous[SystemBnousType.DinerLimit]
  2545 + elseif type == 3 then
  2546 + result = towerBnous[SystemBnousType.DinerSell]
  2547 + elseif type == 4 then
  2548 + result = towerBnous[SystemBnousType.DinerPrice]
  2549 + end
  2550 + return self:getDeltaValue(result, value)
  2551 + end
  2552 +
  2553 + function Role:getBnousAdv()
  2554 + local towerBnous = self:getTowerBnousActive()
  2555 + return towerBnous[SystemBnousType.Adv] or {}
  2556 + end
  2557 +
  2558 + function Role:getBnousHangTime()
  2559 + local towerBnous = self:getTowerBnousActive()
  2560 + return towerBnous[SystemBnousType.HangTime] or 0
  2561 + end
  2562 +
  2563 + function Role:getBnousPvpTicket()
  2564 + local towerBnous = self:getTowerBnousActive()
  2565 + return towerBnous[SystemBnousType.PvpTicket] or {}
  2566 + end
  2567 +
  2568 + function Role:getBnousSweep()
  2569 + local towerBnous = self:getTowerBnousActive()
  2570 + return towerBnous[SystemBnousType.SweepReward] or {}
  2571 + end
  2572 +
2183 2573 end
2184 2574  
2185 2575 return RolePlugin
2186 2576 \ No newline at end of file
... ...
src/models/RoleTask.lua
... ... @@ -249,6 +249,7 @@ local ActivityListener = {
249 249 [TaskType.Pay] = {{Activity.ActivityType.PayBack, f("twd")}},
250 250 [TaskType.AdvMineKill] = {{Activity.ActivityType.Crisis, 1}},
251 251 [TaskType.AdvMineLayer] = {{Activity.ActivityType.Crisis, 2}},
  252 + [TaskType.AdvCostPower] = {{Activity.ActivityType.Crisis, 3, f("count")}},
252 253 [TaskType.DailyTask] = {{Activity.ActivityType.CommonSignIn, f("pre"), f("cur")}},
253 254 [TaskType.AddItem] = {{Activity.ActivityType.BattleCommand, f("id"), f("count")}},
254 255 }
... ...
src/models/RoleTimeReset.lua
... ... @@ -48,6 +48,12 @@ ResetFunc[&quot;CrossWeek&quot;] = function(self, notify, response)
48 48 response.dinerS = {}
49 49  
50 50 self.activity:refreshWeekData(notify)
  51 +
  52 + -- 跨周送一些道具
  53 + local BnousReward = self:getBnousPvpTicket()
  54 + if next(BnousReward) then
  55 + local reward, change = self:award(BnousReward, {log = {desc = "towerBnous"}})
  56 + end
51 57 end
52 58  
53 59  
... ...
src/models/Store.lua
... ... @@ -3,7 +3,29 @@
3 3 local Store = class("Store", require("shared.ModelBaseMysql"))
4 4  
5 5 function Store:ctor(properties)
6   - Store.super.ctor(self, properties)
  6 + Store.super.ctor(self, properties)
  7 +end
  8 +
  9 +function Store:onLoad()
  10 + local monEx = self:getProperty("monthCardEx")
  11 + local smonEx = self:getProperty("smonthCardEx")
  12 + local monId = self:getProperty("monthCardId")
  13 + local smonId = self:getProperty("smonthCardId")
  14 + local timeNow = skynet.timex()
  15 + local flag = false
  16 + if monEx > timeNow and monId == 0 then
  17 + self:updateProperty({field = "monthCardId", value = 101})
  18 + self:updateProperty({field = "getMailT1", value = 0})
  19 + flag = true
  20 + end
  21 + if smonEx > timeNow and smonId == 0 then
  22 + self:updateProperty({field = "smonthCardId", value = 102})
  23 + self:updateProperty({field = "getMailT2", value = 0})
  24 + flag = true
  25 + end
  26 + if flag then
  27 + self:sendMonthCardEmail()
  28 + end
7 29 end
8 30  
9 31 ActGoodsType = {
... ... @@ -18,7 +40,9 @@ Store.schema = {
18 40 growFundR = {"string", ""}, -- 成长基金领取记录
19 41  
20 42 monthCardEx = {"number", 0}, -- 月卡过期时间戳
  43 + monthCardId = {"number", 0}, -- 月卡id
21 44 smonthCardEx = {"number", 0}, -- 超级月卡过期时间戳
  45 + smonthCardId = {"number", 0}, -- 超级月卡id
22 46  
23 47 battleCard = {"number", 0}, -- 赛季卡
24 48 battleFR = {"string", ""}, -- 免费赛季卡领取记录
... ... @@ -52,7 +76,7 @@ function Store:updateProperty(params)
52 76 return
53 77 end
54 78 local newValue = self:getProperty(params.field)
55   - if not params.notNotify then
  79 + if not params.notNotify then
56 80 self:notifyUpdateProperty(params.field, newValue, oldValue)
57 81 end
58 82 end
... ... @@ -78,13 +102,16 @@ end
78 102 -- 发送月卡邮件
79 103 function Store:sendMonthCardEmail()
80 104 local timeNow = skynet.timex()
81   - local tabs = {{ex="monthCardEx", t="getMailT1", mail=MailId.MonthCard, alert=MailId.MonthCardEx},
82   - {ex="smonthCardEx", t="getMailT2", mail=MailId.SuperMonthCard, alert=MailId.SuperMonthCardEx}}
  105 +
  106 + local tabs = {{ex="monthCardEx", t="getMailT1", id= self:getProperty("monthCardId")},
  107 + {ex="smonthCardEx", t="getMailT2", id=self:getProperty("smonthCardId")}}
83 108 for _, v in ipairs(tabs) do
84 109 local ex = self:getProperty(v.ex)
85 110 local ts = self:getProperty(v.t) or 0
86   - local mailId = v.mail
87   - local alertId = v.alert
  111 + local cfg = csvdb["shop_cardCsv"][v.id] or {}
  112 +
  113 + local mailId = cfg.email
  114 + local alertId = cfg.email_2
88 115 local alertTs = dayLater(ex) - DAY_SEC
89 116 if ex > timeNow then
90 117 local cnt = 0
... ... @@ -185,24 +212,66 @@ function Store:getHangDropCoef()
185 212 return (1 + globalCsv.hang_drop_exp_coef) or 1, (1 + globalCsv.hang_drop_item_coef) or 1
186 213 end
187 214  
  215 +function Store:getCurMonthCardLvl(isSuper)
  216 + local id = 0
  217 + if isSuper then
  218 + id = self:getProperty("smonthCardId") or 0
  219 + else
  220 + id = self:getProperty("monthCardId") or 0
  221 + end
  222 + local cfg = csvdb["shop_cardCsv"][id]
  223 + if not cfg then return 0 end
  224 +
  225 + return cfg.level or 0
  226 +end
188 227  
189 228 -- 购买通行证
190 229 function Store:onBuyCard(type, duration, id, actid)
191 230 local timeNow = skynet.timex()
192 231 if type == CardType.NormalMonthCard then
193 232 if self:isMonthCardExpire() then
  233 + self:updateProperty({field = "monthCardId", value = id})
194 234 self:updateProperty({field = "monthCardEx", value = timeNow + duration})
195 235 else
196 236 self:updateProperty({field = "monthCardEx", value = self:getProperty("monthCardEx") + duration})
197 237 end
198 238 self:sendMonthCardEmail()
  239 + elseif type == CardType.NormalMonthCardLevelUp then
  240 + if self:isMonthCardExpire() then
  241 + skynet.error(string.format("month card expired, can not level up,%d,%d",self.owner:getProperty("id"), id))
  242 + else
  243 + local cfg = csvdb["shop_cardCsv"][id]
  244 + if not cfg then return end
  245 + local dif = cfg.level - self:getCurMonthCardLvl(false)
  246 + if dif > 1 and dif < 0 then
  247 + return
  248 + end
  249 + self:updateProperty({field = "monthCardId", value = id})
  250 + self:updateProperty({field = "monthCardEx", value = self:getProperty("monthCardEx") + duration})
  251 + end
  252 + self:sendMonthCardEmail()
199 253 elseif type == CardType.SuperMonthCard then
200 254 if self:isSuperMonthCardExpire() then
  255 + self:updateProperty({field = "smonthCardId", value = id})
201 256 self:updateProperty({field = "smonthCardEx", value = timeNow + duration})
202 257 else
203 258 self:updateProperty({field = "smonthCardEx", value = self:getProperty("smonthCardEx") + duration})
204 259 end
205 260 self:sendMonthCardEmail()
  261 + elseif type == CardType.SuperMonthCardLevelUp then
  262 + if self:isSuperMonthCardExpire() then
  263 + skynet.error(string.format("super month card expired, can not level up,%d,%d",self.owner:getProperty("id"), id))
  264 + else
  265 + local cfg = csvdb["shop_cardCsv"][id]
  266 + if not cfg then return end
  267 + local dif = cfg.level - self:getCurMonthCardLvl(true)
  268 + if dif > 1 and dif < 0 then
  269 + return
  270 + end
  271 + self:updateProperty({field = "smonthCardId", value = id})
  272 + self:updateProperty({field = "smonthCardEx", value = self:getProperty("smonthCardEx") + duration})
  273 + end
  274 + self:sendMonthCardEmail()
206 275 elseif type == CardType.PrivilegeCard then
207 276 if self:isPrivCardExpire() then
208 277 self:updateProperty({field = "privCardEx", value = timeNow + duration})
... ... @@ -254,7 +323,7 @@ function Store:notifyUpdateProperty(field, newValue, oldValue)
254 323 key = field,
255 324 newValue = newValue,
256 325 oldValue = oldValue,
257   - }
  326 + }
258 327 SendPacket(actionCodes.Store_updateproperty, MsgPack.pack(datas))
259 328 end
260 329  
... ... @@ -495,6 +564,8 @@ function Store:data()
495 564 actGoodsFlag = self:getProperty("actGoodsFlag"),
496 565 bpInfo = self:getProperty("bpInfo"),
497 566 totalRR = self:getProperty("totalRR"),
  567 + monthCardId = self:getProperty("monthCardId"),
  568 + smonthCardId = self:getProperty("smonthCardId"),
498 569 }
499 570 end
500 571  
... ...
src/services/dbseed.lua
... ... @@ -13,6 +13,16 @@ mysqlproxy = require &quot;shared.mysqlproxy&quot;
13 13  
14 14 SendPacket = function ( ... ) end
15 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
16 26  
17 27 local function initRedisDb( ... )
18 28 local function initAutoIncrementUid(tbName, keyName, fieldName)
... ... @@ -36,10 +46,13 @@ local function initRedisDb( ... )
36 46 initAutoIncrementUid("autoincrement_set", "delay_email")
37 47 initAutoIncrementUid("autoincrement_set", "stopcreate")
38 48 initAutoIncrementUid("autoincrement_set", "maintain")
  49 + initAutoIncrementUid("autoincrement_set", "seaportTime0")
  50 + initAutoIncrementUid("autoincrement_set", "seaportTime1")
  51 + initAutoIncrementUid("autoincrement_set", "seaportTime2")
39 52  
40   - --redisproxy:hsetnx("adv_season", "idx", 0)
41   - --redisproxy:hsetnx("adv_season", "chapter", globalCsv.adv_endless_default_chapter)
42   - --redisproxy:hsetnx("adv_season", "overTime", 0)
  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)
43 56 end
44 57  
45 58 -- 初始化服务器数据库以及服务器信息表
... ... @@ -84,9 +97,30 @@ local function initAutoIncreUidTable()
84 97 mysqlproxy:query(string.format(tpl, "delay_email", 0))
85 98 mysqlproxy:query(string.format(tpl, "stopcreate", 0))
86 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))
87 103 end
88 104 end
89 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 +
90 124 local function initAdvSeasonTable()
91 125 mysqlproxy:query [[
92 126 CREATE TABLE IF NOT EXISTS `adv_season` (
... ... @@ -157,6 +191,7 @@ local function createMysqlSp()
157 191 ]]
158 192 end
159 193  
  194 +
160 195 local steps = {
161 196 [1] = {
162 197 handler = initServerDatabase,
... ... @@ -178,6 +213,10 @@ local steps = {
178 213 handler = createMysqlSp,
179 214 desc = "create mysql store procedure "
180 215 },
  216 + [6] = {
  217 + handler = initSeaportTable,
  218 + desc = "initialize seaport table "
  219 + },
181 220 }
182 221  
183 222 local function loadAllUserInfo()
... ... @@ -218,6 +257,7 @@ skynet.start(function ()
218 257 print(action.desc .. "finished ...")
219 258 end
220 259 initRedisDb()
  260 + initSeaportTask() -- 海港任务数据初始化
221 261 loadAllUserInfo()
222 262 skynet.exit()
223 263 end)
224 264 \ No newline at end of file
... ...
src/services/globald.lua
... ... @@ -2,6 +2,7 @@ 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"
... ... @@ -156,11 +157,11 @@ local function check_battle_act_close()
156 157 end
157 158  
158 159 local function save_autoincrement_timer()
159   - local function saveUidToMysql(tbName, keyName, fieldName)
  160 + local function saveUidToMysql(tbName, keyName, fieldName, ignore)
160 161 if not fieldName then fieldName = "value" end
161 162 local mysqlVal = getDbCfgVal(tbName, keyName, fieldName) or 0
162 163 local redisVal = tonum(redisproxy:hget(tbName, keyName))
163   - if redisVal > mysqlVal then
  164 + if (not ignore) and redisVal > mysqlVal then
164 165 setDbCfgVal(tbName, keyName, fieldName, redisVal)
165 166 end
166 167 end
... ... @@ -171,12 +172,63 @@ local function save_autoincrement_timer()
171 172 saveUidToMysql("autoincrement_set", "email")
172 173 saveUidToMysql("autoincrement_set", "emailTimestamp")
173 174 saveUidToMysql("autoincrement_set", "delay_email")
174   - saveUidToMysql("autoincrement_set", "stopcreate")
175   - saveUidToMysql("autoincrement_set", "maintain")
  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)
176 180  
177 181 skynet.timeout(SAVE_AUTOINCREMENT_SET_INTERVAL, save_autoincrement_timer)
178 182 end
179 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 +
  201 +-- @desc: 检查海港贸易开启、关闭
  202 +local function check_trade_seaport_status()
  203 + local nowTime = skynet.timex()
  204 + local nextTime = dayLater(nowTime)
  205 + local interval = 100 * (nextTime - nowTime + 1)
  206 +
  207 + local curTm = os.date("*t", nowTime)
  208 + if curTm.wday == 7 and curTm.hour >= 4 then -- 周六
  209 + local oldTime = tonumber(redisproxy:hget("autoincrement_set", "seaportTime0")) or 0
  210 + local cur4Time = specTime({hour = 4},nowTime)
  211 + if cur4Time ~= oldTime then
  212 + redisproxy:hset("autoincrement_set", "seaportTime0", cur4Time)
  213 + redisproxy:hset("autoincrement_set", "seaportTime1", 1)
  214 + redisproxy:del(SEAPORT_TRADE_TASK_1)
  215 + redisproxy:del(SEAPORT_TRADE_TASK_2)
  216 + end
  217 + end
  218 + if curTm.wday == 1 and curTm.hour >= 4 then -- 周日
  219 + if (tonumber(redisproxy:hget("autoincrement_set", "seaportTime1")) or 0) == 1 then
  220 + redisproxy:hset("autoincrement_set", "seaportTime2", 1)
  221 + end
  222 + end
  223 + if curTm.wday == 2 and curTm.hour >= 4 then -- 周一
  224 + -- redisproxy:hset("autoincrement_set", "seaportTime0", 0)
  225 + redisproxy:hset("autoincrement_set", "seaportTime1", 0)
  226 + redisproxy:hset("autoincrement_set", "seaportTime2", 0)
  227 + end
  228 +
  229 + skynet.timeout(interval, check_trade_seaport_status)
  230 +end
  231 +
180 232 local CMD = {}
181 233  
182 234  
... ... @@ -201,6 +253,8 @@ function CMD.start()
201 253 check_mail_queue()
202 254 --check_battle_act_close()
203 255 save_autoincrement_timer()
  256 + check_trade_seaport_status()
  257 + save_seaport_task()
204 258 end
205 259  
206 260 local function __init__()
... ...
src/shared/base64.lua 0 → 100644
... ... @@ -0,0 +1,155 @@
  1 +local base64 = {}
  2 +local string = string
  3 +
  4 +base64.__code = {
  5 + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
  6 + 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
  7 + 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
  8 + 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/',
  9 + };
  10 +base64.__decode = {}
  11 +for k,v in pairs(base64.__code) do
  12 + base64.__decode[string.byte(v,1)] = k - 1
  13 +end
  14 +
  15 +function base64.encode(text)
  16 + local len = string.len(text)
  17 + local left = len % 3
  18 + len = len - left
  19 + local res = {}
  20 + local index = 1
  21 + for i = 1, len, 3 do
  22 + local a = string.byte(text, i )
  23 + local b = string.byte(text, i + 1)
  24 + local c = string.byte(text, i + 2)
  25 + -- num = a<<16 + b<<8 + c
  26 + local num = a * 65536 + b * 256 + c
  27 + for j = 1, 4 do
  28 + --tmp = num >> ((4 -j) * 6)
  29 + local tmp = math.floor(num / (2 ^ ((4-j) * 6)))
  30 + --curPos = tmp&0x3f
  31 + local curPos = tmp % 64 + 1
  32 + res[index] = base64.__code[curPos]
  33 + index = index + 1
  34 + end
  35 + end
  36 +
  37 + if left == 1 then
  38 + base64.__left1(res, index, text, len)
  39 + elseif left == 2 then
  40 + base64.__left2(res, index, text, len)
  41 + end
  42 + return table.concat(res)
  43 +end
  44 +
  45 +function base64.__left2(res, index, text, len)
  46 + local num1 = string.byte(text, len + 1)
  47 + num1 = num1 * 1024 --lshift 10
  48 + local num2 = string.byte(text, len + 2)
  49 + num2 = num2 * 4 --lshift 2
  50 + local num = num1 + num2
  51 +
  52 + local tmp1 = math.floor(num / 4096) --rShift 12
  53 + local curPos = tmp1 % 64 + 1
  54 + res[index] = base64.__code[curPos]
  55 +
  56 + local tmp2 = math.floor(num / 64)
  57 + curPos = tmp2 % 64 + 1
  58 + res[index + 1] = base64.__code[curPos]
  59 +
  60 + curPos = num % 64 + 1
  61 + res[index + 2] = base64.__code[curPos]
  62 +
  63 + res[index + 3] = "="
  64 +end
  65 +
  66 +function base64.__left1(res, index,text, len)
  67 + local num = string.byte(text, len + 1)
  68 + num = num * 16
  69 +
  70 + tmp = math.floor(num / 64)
  71 + local curPos = tmp % 64 + 1
  72 + res[index ] = base64.__code[curPos]
  73 +
  74 + curPos = num % 64 + 1
  75 + res[index + 1] = base64.__code[curPos]
  76 +
  77 + res[index + 2] = "="
  78 + res[index + 3] = "="
  79 +end
  80 +
  81 +function base64.decode(text)
  82 + local len = string.len(text)
  83 + local left = 0
  84 + if string.sub(text, len - 1) == "==" then
  85 + left = 2
  86 + len = len - 4
  87 + elseif string.sub(text, len) == "=" then
  88 + left = 1
  89 + len = len - 4
  90 + end
  91 +
  92 + local res = {}
  93 + local index = 1
  94 + local decode = base64.__decode
  95 + for i =1, len, 4 do
  96 + local a = decode[string.byte(text,i )]
  97 + local b = decode[string.byte(text,i + 1)]
  98 + local c = decode[string.byte(text,i + 2)]
  99 + local d = decode[string.byte(text,i + 3)]
  100 +
  101 + --num = a<<18 + b<<12 + c<<6 + d
  102 + local num = a * 262144 + b * 4096 + c * 64 + d
  103 +
  104 + local e = string.char(num % 256)
  105 + num = math.floor(num / 256)
  106 + local f = string.char(num % 256)
  107 + num = math.floor(num / 256)
  108 + res[index ] = string.char(num % 256)
  109 + res[index + 1] = f
  110 + res[index + 2] = e
  111 + index = index + 3
  112 + end
  113 +
  114 + if left == 1 then
  115 + base64.__decodeLeft1(res, index, text, len)
  116 + elseif left == 2 then
  117 + base64.__decodeLeft2(res, index, text, len)
  118 + end
  119 + return table.concat(res)
  120 +end
  121 +
  122 +function base64.__decodeLeft1(res, index, text, len)
  123 + local decode = base64.__decode
  124 + local a = decode[string.byte(text, len + 1)]
  125 + local b = decode[string.byte(text, len + 2)]
  126 + local c = decode[string.byte(text, len + 3)]
  127 + local num = a * 4096 + b * 64 + c
  128 +
  129 + local num1 = math.floor(num / 1024) % 256
  130 + local num2 = math.floor(num / 4) % 256
  131 + res[index] = string.char(num1)
  132 + res[index + 1] = string.char(num2)
  133 +end
  134 +
  135 +function base64.__decodeLeft2(res, index, text, len)
  136 + local decode = base64.__decode
  137 + local a = decode[string.byte(text, len + 1)]
  138 + local b = decode[string.byte(text, len + 2)]
  139 + local num = a * 64 + b
  140 + num = math.floor(num / 16)
  141 + res[index] = string.char(num)
  142 +end
  143 +
  144 +function base64.test()
  145 + local data = "a\193\207="
  146 + local abc = base64.encode(data)
  147 + print(abc)
  148 +
  149 + def = base64.decode(abc)
  150 + if def == data then
  151 + print("yes")
  152 + end
  153 +end
  154 +
  155 +return base64
0 156 \ No newline at end of file
... ...
src/shared/init.lua
... ... @@ -2,4 +2,5 @@ require(&quot;shared.functions&quot;)
2 2 require("shared.debug")
3 3  
4 4 json = require("shared.json")
5   -MsgPack = require "cmsgpack"
6 5 \ No newline at end of file
  6 +MsgPack = require "cmsgpack"
  7 +base64 = require("shared.base64")
7 8 \ No newline at end of file
... ...