OnlineAwardLogic.lua 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  1. --在线奖励活动
  2. --db
  3. --[=[
  4. human.db.OnlineRewardData = {
  5. haveTime = nil, --活动获得时间, 即首充时间
  6. dailyData = { --每日数据,key为当前时间距离 haveTime 的天数
  7. [1] = {
  8. [1] = nil, --记录当天某个档位奖励的领取情况, key 为档位,有记录表示已经领取了(不可领取和可领取两种状态不存db)
  9. [2] = nil,
  10. },
  11. [2] = {
  12. [1] = nil,
  13. [2] = nil,
  14. },
  15. }
  16. }
  17. ]=]--
  18. local Msg = require("core.Msg")
  19. local Grid = require("bag.Grid")
  20. local Util = require("common.Util")
  21. local BagLogic = require("bag.BagLogic")
  22. local Broadcast = require("broadcast.Broadcast")
  23. local Lang = require("common.Lang")
  24. local onlineAardCfg = require("excel.onlineAward").onlineAward
  25. local YunYingLogic = require("yunying.YunYingLogic")
  26. local PanelDefine = require("broadcast.PanelDefine")
  27. local Timer = require("core.Timer")
  28. local ObjHuman = require("core.ObjHuman")
  29. --分钟转秒
  30. local TIMEBASE = 60
  31. --一天的秒数
  32. local DAYSEC = 86400
  33. --本活动日志标识
  34. local LOGTYPE = "OnlineAwardLogic"
  35. --是否在线
  36. -- IsOnline = false
  37. --活动ID
  38. local ACTID = 18001
  39. --检查活动获得时间, 如果没有初始化则初始化
  40. local function checkHaveTime(human)
  41. local OnlineRewardData = human.db.OnlineRewardData
  42. if not OnlineRewardData or not OnlineRewardData.haveTime then
  43. human.db.OnlineRewardData = human.db.OnlineRewardData or {}
  44. human.db.OnlineRewardData.haveTime = os.time()
  45. end
  46. end
  47. --计算当天到目前为止的总在线时长
  48. local function calcTotalOnlineTime(human)
  49. local lastOnlineTime = human.db.onlineTimeDay or 0
  50. local loginTime = human.db.lastLoginTime
  51. --可能存在玩家在线跨天情况,需要判断登录时间与当前时间是否属于同一天,如果不是, 那么在此活动中,当天的登录时间应该为当天0点
  52. local now = os.time()
  53. if not Util.isSameDay(loginTime) then
  54. loginTime = Util.getDayStartTime(now)
  55. end
  56. local totalOnlineTime = now - loginTime + lastOnlineTime
  57. return totalOnlineTime
  58. end
  59. --获取当前时间距离startTime相差多少天
  60. local function getDiffDay(startTime)
  61. local passDay = Util.diffDay(startTime) + 1
  62. return passDay
  63. end
  64. --是否获得该活动
  65. local function isHaveAct(human)
  66. local topupAcount = human.db.topupAcount
  67. if topupAcount and topupAcount > 0 then
  68. return true
  69. end
  70. return false
  71. end
  72. --是否结束
  73. local function isOver(human)
  74. local OnlineRewardData = human.db.OnlineRewardData
  75. if not OnlineRewardData then
  76. return false
  77. end
  78. local targetDay = getDiffDay(OnlineRewardData.haveTime)
  79. local targetCfg = onlineAardCfg[targetDay]
  80. --配置错误或者已经超过配置里的天数了都不显示
  81. if not targetCfg then
  82. return true
  83. end
  84. return false
  85. end
  86. --计算下一个未获得奖励需要的在线时间
  87. local function calcLeftTime(human)
  88. local OnlineRewardData = human.db.OnlineRewardData
  89. local targetDay = getDiffDay(OnlineRewardData.haveTime)
  90. local targetCfg = onlineAardCfg[targetDay]
  91. if not targetCfg then
  92. return
  93. end
  94. local leftTime = 0
  95. local totalNeedTime = 0
  96. local timeCfg = targetCfg.onlineTimeVec
  97. local totalOnlineTime = calcTotalOnlineTime(human)
  98. for _, needTime in ipairs(timeCfg) do
  99. totalNeedTime = totalNeedTime + needTime * TIMEBASE
  100. if totalNeedTime > totalOnlineTime then
  101. leftTime = totalNeedTime - totalOnlineTime
  102. break
  103. end
  104. end
  105. return leftTime
  106. end
  107. --返回可领取奖励的index Vec
  108. local function getCanReceiveAwardVec(human, isRed)
  109. local OnlineRewardData = human.db.OnlineRewardData
  110. local dailyData = OnlineRewardData.dailyData
  111. local targetDay = getDiffDay(OnlineRewardData.haveTime)
  112. local targetCfg = onlineAardCfg[targetDay]
  113. local todayRecordData = dailyData and dailyData[targetDay]
  114. if not targetCfg then
  115. if not isRed then
  116. Broadcast.sendErr(human, Lang.COMMON_COMFIG_ERROR)
  117. end
  118. return
  119. end
  120. --充值金额是否符合
  121. local topupAcountDaily = human.db.topupAcountDaily
  122. if not topupAcountDaily or topupAcountDaily < targetCfg.needRecharge then
  123. if not isRed then
  124. Broadcast.sendErr(human, Lang.COMMON_DAY_RECHARGE_NOT_ENOUGH)
  125. end
  126. return
  127. end
  128. local totalNeedTime = 0
  129. local cfgOnlineTimeVec = targetCfg.onlineTimeVec
  130. local totalOnlineTime = calcTotalOnlineTime(human)
  131. local len = 0
  132. local awardIdxVec = {}
  133. for idx, needTime in ipairs(cfgOnlineTimeVec) do
  134. totalNeedTime = totalNeedTime + needTime * TIMEBASE
  135. if totalOnlineTime >= totalNeedTime and (not todayRecordData or not todayRecordData[idx]) then
  136. len = len + 1
  137. awardIdxVec[len] = idx
  138. end
  139. end
  140. if len == 0 then
  141. return
  142. end
  143. return awardIdxVec
  144. end
  145. --定时器任务
  146. local function timeFunc(human)
  147. if not ObjHuman.onlineNewUniqueTag[human.db.newUniqueTag] then
  148. return
  149. end
  150. -- if not IsOnline then
  151. -- return
  152. -- end
  153. local leftTime = calcLeftTime(human)
  154. if leftTime and leftTime > 0 then
  155. local now = os.time()
  156. local todayStartTi = Util.getDayStartTime(now)
  157. local nextDayStartTi = todayStartTi + DAYSEC
  158. --只有需要挂机时间 + 当前时间 < 下一天0点, 那么才加定时器
  159. if leftTime + now < nextDayStartTi then
  160. Timer.addLater(leftTime, function ()
  161. Query(human)
  162. --红点更新
  163. YunYingLogic.updateIcon(YYInfo[ACTID], human, true)
  164. timeFunc(human)
  165. end)
  166. end
  167. end
  168. end
  169. --红点判断
  170. function isRed(human, YYInfo, funcConfig)
  171. if not isHaveAct(human) then
  172. return false
  173. end
  174. if not getCanReceiveAwardVec(human, true) then
  175. return false
  176. end
  177. return true
  178. end
  179. --是否开启(外部调用)
  180. function isOpen(human)
  181. if not isHaveAct(human) then
  182. return false
  183. end
  184. if isOver(human) then
  185. return false
  186. end
  187. return true
  188. end
  189. --登录
  190. function onLogin(human, actID)
  191. if not isHaveAct(human) then
  192. return
  193. end
  194. -- IsOnline = true
  195. checkHaveTime(human)
  196. timeFunc(human)
  197. end
  198. --下线
  199. -- function onLogout(human, funcID, parameter, parameter2)
  200. -- IsOnline = false
  201. -- end
  202. --跨天
  203. -- function updateDaily(human, funcID)
  204. -- checkHaveTime(human)
  205. -- end
  206. --新跨天函数,这里用新的跨天函数是因为ObjHuman.lua中 重置每日在线时间代码会晚于运营活动中的 updateDaily()执行
  207. --这个活动中,会用到每日在线时间,所以需要重新定义一个跨天函数,在重置每日在线时间后再执行
  208. function NewUpdateDaily(human)
  209. if not isHaveAct(human) then
  210. return
  211. end
  212. --if IsOnline then
  213. if isOver(human) then
  214. YunYingLogic.updateIcon(YYInfo[ACTID], human, true)
  215. return
  216. end
  217. --针对玩家在线跨天情况,下发一次最新数据
  218. Query(human)
  219. timeFunc(human)
  220. --end
  221. end
  222. --充值
  223. function onCharge(human, price)
  224. local OnlineRewardData = human.db.OnlineRewardData
  225. if not OnlineRewardData or not OnlineRewardData.haveTime then
  226. checkHaveTime(human)
  227. timeFunc(human)
  228. YunYingLogic.updateIcon(YYInfo[ACTID], human, true)
  229. end
  230. OnlineRewardData = human.db.OnlineRewardData
  231. local targetDay = getDiffDay(OnlineRewardData.haveTime)
  232. local targetCfg = onlineAardCfg[targetDay]
  233. --活动结束后玩家充值导致报错
  234. if not targetCfg then
  235. return
  236. end
  237. local topupAcountDaily = human.db.topupAcountDaily
  238. if topupAcountDaily and topupAcountDaily >= targetCfg.needRecharge then
  239. Query(human)
  240. end
  241. return true
  242. end
  243. --查询
  244. function Query(human)
  245. if not isHaveAct(human) then
  246. return Broadcast.sendErr(human, Lang.YUNYING_ERR_TIME)
  247. end
  248. local OnlineRewardData = human.db.OnlineRewardData
  249. local dailyData = OnlineRewardData.dailyData
  250. local targetDay = getDiffDay(OnlineRewardData.haveTime)
  251. local targetCfg = onlineAardCfg[targetDay]
  252. local todayData = dailyData and dailyData[targetDay]
  253. if not targetCfg then
  254. return Broadcast.sendErr(human, Lang.COMMON_COMFIG_ERROR)
  255. end
  256. local timeCfg = targetCfg.onlineTimeVec
  257. local awardCfg = targetCfg.awardVec
  258. if #timeCfg ~= #awardCfg then
  259. return Broadcast.sendErr(human, Lang.COMMON_COMFIG_ERROR)
  260. end
  261. local len = 0
  262. local totalNeedTime = 0
  263. local totalOnlineTime = calcTotalOnlineTime(human)
  264. local msgRet = Msg.gc.GC_ONLINEAWARD_QUERY
  265. msgRet.leftTime = 0
  266. msgRet.needRecharge = targetCfg.needRecharge
  267. msgRet.isReach = 0
  268. local topupAcountDaily = human.db.topupAcountDaily
  269. if topupAcountDaily and topupAcountDaily >= targetCfg.needRecharge then
  270. msgRet.isReach = 1
  271. end
  272. msgRet.remainingDays = math.max(#onlineAardCfg - targetDay, 0)
  273. local msgAwardVec = msgRet.awardVec
  274. msgAwardVec[0] = 0
  275. for idx, needTime in ipairs(timeCfg) do
  276. len = len + 1
  277. msgAwardVec[len].state = 0
  278. Grid.makeItem(msgAwardVec[len].itemInfo, awardCfg[idx][1], awardCfg[idx][2])
  279. totalNeedTime = totalNeedTime + needTime * TIMEBASE
  280. if totalOnlineTime >= totalNeedTime then
  281. msgAwardVec[len].state = 1
  282. if todayData and todayData[idx] then
  283. msgAwardVec[len].state = 2
  284. end
  285. else
  286. if msgRet.leftTime == 0 then
  287. msgRet.leftTime = totalNeedTime - totalOnlineTime
  288. end
  289. end
  290. end
  291. msgAwardVec[0] = len
  292. Msg.send(msgRet, human.fd)
  293. end
  294. --领奖
  295. function ClaimAward(human)
  296. if not isHaveAct(human) then
  297. return Broadcast.sendErr(human, Lang.YUNYING_ERR_TIME)
  298. end
  299. local awardIdxVec = getCanReceiveAwardVec(human)
  300. if not awardIdxVec then
  301. return
  302. end
  303. local OnlineRewardData = human.db.OnlineRewardData
  304. local targetDay = getDiffDay(OnlineRewardData.haveTime)
  305. OnlineRewardData.dailyData = OnlineRewardData.dailyData or {}
  306. OnlineRewardData.dailyData[targetDay] = OnlineRewardData.dailyData[targetDay] or {}
  307. local todayRecoedData = OnlineRewardData.dailyData[targetDay]
  308. local len = 0
  309. local awardVec = {}
  310. local targetCfg = onlineAardCfg[targetDay]
  311. local awardCfg = targetCfg.awardVec
  312. for _, idx in ipairs(awardIdxVec) do
  313. len = len + 1
  314. awardVec[len] = {awardCfg[idx][1], awardCfg[idx][2]}
  315. todayRecoedData[idx] = true
  316. end
  317. BagLogic.addItemList(human, awardVec, LOGTYPE)
  318. --下发数据更新
  319. Query(human)
  320. --红点更新
  321. YunYingLogic.updateIcon(YYInfo[ACTID], human, true)
  322. end