OnlineAwardLogic.lua 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394
  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. local targetDay = getDiffDay(OnlineRewardData.haveTime)
  76. local targetCfg = onlineAardCfg[targetDay]
  77. --配置错误或者已经超过配置里的天数了都不显示
  78. if not targetCfg then
  79. return true
  80. end
  81. return false
  82. end
  83. --计算下一个未获得奖励需要的在线时间
  84. local function calcLeftTime(human)
  85. local OnlineRewardData = human.db.OnlineRewardData
  86. local targetDay = getDiffDay(OnlineRewardData.haveTime)
  87. local targetCfg = onlineAardCfg[targetDay]
  88. if not targetCfg then
  89. return
  90. end
  91. local leftTime = 0
  92. local totalNeedTime = 0
  93. local timeCfg = targetCfg.onlineTimeVec
  94. local totalOnlineTime = calcTotalOnlineTime(human)
  95. for _, needTime in ipairs(timeCfg) do
  96. totalNeedTime = totalNeedTime + needTime * TIMEBASE
  97. if totalNeedTime > totalOnlineTime then
  98. leftTime = totalNeedTime - totalOnlineTime
  99. break
  100. end
  101. end
  102. return leftTime
  103. end
  104. --返回可领取奖励的index Vec
  105. local function getCanReceiveAwardVec(human, isRed)
  106. local OnlineRewardData = human.db.OnlineRewardData
  107. local dailyData = OnlineRewardData.dailyData
  108. local targetDay = getDiffDay(OnlineRewardData.haveTime)
  109. local targetCfg = onlineAardCfg[targetDay]
  110. local todayRecordData = dailyData and dailyData[targetDay]
  111. if not targetCfg then
  112. if not isRed then
  113. Broadcast.sendErr(human, Lang.COMMON_COMFIG_ERROR)
  114. end
  115. return
  116. end
  117. --充值金额是否符合
  118. local topupAcountDaily = human.db.topupAcountDaily
  119. if not topupAcountDaily or topupAcountDaily < targetCfg.needRecharge then
  120. if not isRed then
  121. Broadcast.sendErr(human, Lang.COMMON_DAY_RECHARGE_NOT_ENOUGH)
  122. end
  123. return
  124. end
  125. local totalNeedTime = 0
  126. local cfgOnlineTimeVec = targetCfg.onlineTimeVec
  127. local totalOnlineTime = calcTotalOnlineTime(human)
  128. local len = 0
  129. local awardIdxVec = {}
  130. for idx, needTime in ipairs(cfgOnlineTimeVec) do
  131. totalNeedTime = totalNeedTime + needTime * TIMEBASE
  132. if totalOnlineTime >= totalNeedTime and (not todayRecordData or not todayRecordData[idx]) then
  133. len = len + 1
  134. awardIdxVec[len] = idx
  135. end
  136. end
  137. if len == 0 then
  138. return
  139. end
  140. return awardIdxVec
  141. end
  142. --定时器任务
  143. local function timeFunc(human)
  144. if not ObjHuman.onlineNewUniqueTag[human.db.newUniqueTag] then
  145. return
  146. end
  147. -- if not IsOnline then
  148. -- return
  149. -- end
  150. local leftTime = calcLeftTime(human)
  151. if leftTime and leftTime > 0 then
  152. local now = os.time()
  153. local todayStartTi = Util.getDayStartTime(now)
  154. local nextDayStartTi = todayStartTi + DAYSEC
  155. --只有需要挂机时间 + 当前时间 < 下一天0点, 那么才加定时器
  156. if leftTime + now < nextDayStartTi then
  157. Timer.addLater(leftTime, function ()
  158. Query(human)
  159. --红点更新
  160. YunYingLogic.updateIcon(YYInfo[ACTID], human, true)
  161. timeFunc(human)
  162. end)
  163. end
  164. end
  165. end
  166. --红点判断
  167. function isRed(human, YYInfo, funcConfig)
  168. if not isHaveAct(human) then
  169. return false
  170. end
  171. if not getCanReceiveAwardVec(human, true) then
  172. return false
  173. end
  174. return true
  175. end
  176. --是否开启(外部调用)
  177. function isOpen(human)
  178. if not isHaveAct(human) then
  179. return false
  180. end
  181. if isOver(human) then
  182. return false
  183. end
  184. return true
  185. end
  186. --登录
  187. function onLogin(human, actID)
  188. if not isHaveAct(human) then
  189. return
  190. end
  191. -- IsOnline = true
  192. checkHaveTime(human)
  193. timeFunc(human)
  194. end
  195. --下线
  196. -- function onLogout(human, funcID, parameter, parameter2)
  197. -- IsOnline = false
  198. -- end
  199. --跨天
  200. function updateDaily(human, funcID)
  201. checkHaveTime(human)
  202. end
  203. --新跨天函数,这里用新的跨天函数是因为ObjHuman.lua中 重置每日在线时间代码会晚于运营活动中的 updateDaily()执行
  204. --这个活动中,会用到每日在线时间,所以需要重新定义一个跨天函数,在重置每日在线时间后再执行
  205. function NewUpdateDaily(human)
  206. if not isHaveAct(human) then
  207. return
  208. end
  209. --if IsOnline then
  210. if isOver(human) then
  211. YunYingLogic.updateIcon(YYInfo[ACTID], human, true)
  212. return
  213. end
  214. --针对玩家在线跨天情况,下发一次最新数据
  215. Query(human)
  216. timeFunc(human)
  217. --end
  218. end
  219. --充值
  220. function onCharge(human, price)
  221. local OnlineRewardData = human.db.OnlineRewardData
  222. if not OnlineRewardData or not OnlineRewardData.haveTime then
  223. checkHaveTime(human)
  224. timeFunc(human)
  225. YunYingLogic.updateIcon(YYInfo[ACTID], human, true)
  226. end
  227. OnlineRewardData = human.db.OnlineRewardData
  228. local targetDay = getDiffDay(OnlineRewardData.haveTime)
  229. local targetCfg = onlineAardCfg[targetDay]
  230. --活动结束后玩家充值导致报错
  231. if not targetCfg then
  232. return
  233. end
  234. local topupAcountDaily = human.db.topupAcountDaily
  235. if topupAcountDaily and topupAcountDaily >= targetCfg.needRecharge then
  236. Query(human)
  237. end
  238. return true
  239. end
  240. --查询
  241. function Query(human)
  242. if not isHaveAct(human) then
  243. return Broadcast.sendErr(human, Lang.YUNYING_ERR_TIME)
  244. end
  245. local OnlineRewardData = human.db.OnlineRewardData
  246. local dailyData = OnlineRewardData.dailyData
  247. local targetDay = getDiffDay(OnlineRewardData.haveTime)
  248. local targetCfg = onlineAardCfg[targetDay]
  249. local todayData = dailyData and dailyData[targetDay]
  250. if not targetCfg then
  251. return Broadcast.sendErr(human, Lang.COMMON_COMFIG_ERROR)
  252. end
  253. local timeCfg = targetCfg.onlineTimeVec
  254. local awardCfg = targetCfg.awardVec
  255. if #timeCfg ~= #awardCfg then
  256. return Broadcast.sendErr(human, Lang.COMMON_COMFIG_ERROR)
  257. end
  258. local len = 0
  259. local totalNeedTime = 0
  260. local totalOnlineTime = calcTotalOnlineTime(human)
  261. local msgRet = Msg.gc.GC_ONLINEAWARD_QUERY
  262. msgRet.leftTime = 0
  263. msgRet.needRecharge = targetCfg.needRecharge
  264. msgRet.isReach = 0
  265. local topupAcountDaily = human.db.topupAcountDaily
  266. if topupAcountDaily and topupAcountDaily >= targetCfg.needRecharge then
  267. msgRet.isReach = 1
  268. end
  269. msgRet.remainingDays = math.max(#onlineAardCfg - targetDay, 0)
  270. local msgAwardVec = msgRet.awardVec
  271. msgAwardVec[0] = 0
  272. for idx, needTime in ipairs(timeCfg) do
  273. len = len + 1
  274. msgAwardVec[len].state = 0
  275. Grid.makeItem(msgAwardVec[len].itemInfo, awardCfg[idx][1], awardCfg[idx][2])
  276. totalNeedTime = totalNeedTime + needTime * TIMEBASE
  277. if totalOnlineTime >= totalNeedTime then
  278. msgAwardVec[len].state = 1
  279. if todayData and todayData[idx] then
  280. msgAwardVec[len].state = 2
  281. end
  282. else
  283. if msgRet.leftTime == 0 then
  284. msgRet.leftTime = totalNeedTime - totalOnlineTime
  285. end
  286. end
  287. end
  288. msgAwardVec[0] = len
  289. Msg.send(msgRet, human.fd)
  290. end
  291. --领奖
  292. function ClaimAward(human)
  293. if not isHaveAct(human) then
  294. return Broadcast.sendErr(human, Lang.YUNYING_ERR_TIME)
  295. end
  296. local awardIdxVec = getCanReceiveAwardVec(human)
  297. if not awardIdxVec then
  298. return
  299. end
  300. local OnlineRewardData = human.db.OnlineRewardData
  301. local targetDay = getDiffDay(OnlineRewardData.haveTime)
  302. OnlineRewardData.dailyData = OnlineRewardData.dailyData or {}
  303. OnlineRewardData.dailyData[targetDay] = OnlineRewardData.dailyData[targetDay] or {}
  304. local todayRecoedData = OnlineRewardData.dailyData[targetDay]
  305. local len = 0
  306. local awardVec = {}
  307. local targetCfg = onlineAardCfg[targetDay]
  308. local awardCfg = targetCfg.awardVec
  309. for _, idx in ipairs(awardIdxVec) do
  310. len = len + 1
  311. awardVec[len] = {awardCfg[idx][1], awardCfg[idx][2]}
  312. todayRecoedData[idx] = true
  313. end
  314. BagLogic.addItemList(human, awardVec, LOGTYPE)
  315. --下发数据更新
  316. Query(human)
  317. --红点更新
  318. YunYingLogic.updateIcon(YYInfo[ACTID], human, true)
  319. end