neo преди 1 година
родител
ревизия
3a481ae757
променени са 7 файла, в които са добавени 290 реда и са изтрити 4 реда
  1. 2 1
      dev/const/gameConst.lua
  2. 30 0
      dev/modules/dream.lua
  3. 1 0
      dev/modules/order.lua
  4. 149 0
      dev/utils/util_box.lua
  5. 68 3
      nodes/game/interface/box.lua
  6. 2 0
      nodes/global/main.lua
  7. 38 0
      nodes/global/service/dreamSrv.lua

+ 2 - 1
dev/const/gameConst.lua

@@ -24,7 +24,8 @@ root.EVENT_ID = {
24 24
 -- 常用资源物品ID
25 25
 root.ITEM_ID = {
26 26
     GOLD = 101, -- 金币
27
-    DIAMOND = 102 -- 宝石
27
+    DIAMOND = 102, -- 宝石
28
+    N1 = 103 -- N1纪念布章
28 29
 }
29 30
 
30 31
 -- 战斗类型

+ 30 - 0
dev/modules/dream.lua

@@ -0,0 +1,30 @@
1
+--[[
2
+Descripttion:追梦记录
3
+version:
4
+Author: Neo,Huang
5
+Date: 2022-08-17 16:04:20
6
+LastEditors: Neo,Huang
7
+LastEditTime: 2022-08-19 20:12:34
8
+--]]
9
+local root = class("dream", require("base.baseModule"))
10
+
11
+function root:ctor(id)
12
+	root.super.ctor(self, id, "dream", "id", true, false)
13
+	self.id = id
14
+end
15
+
16
+function root:mysql_get_init_columns()
17
+	return {
18
+		id = "bigint(20) NOT NULL COMMENT '邮件ID'",
19
+		uid = "bigint(20) DEFAULT 0 COMMENT '抽奖玩家ID'",
20
+		itemId = "int(11) DEFAULT 0 COMMENT '掉落时价格'",
21
+		dropItem = "json COMMENT '掉落物品'",
22
+		price = "int(11) DEFAULT 0 COMMENT '掉落时价格'",
23
+		odds = "int(11) DEFAULT 0 COMMENT '使用概率'",
24
+		isWin = "int(11) DEFAULT 0 COMMENT '是否中奖 0:不中奖 1:中奖'",
25
+		dropTime = "int(11) DEFAULT 1 COMMENT '掉落时间戳'",
26
+		expireTime = "int(11) DEFAULT 0 COMMENT '过期时间'"
27
+	}
28
+end
29
+
30
+return root

+ 1 - 0
dev/modules/order.lua

@@ -10,6 +10,7 @@ local root = class("order", require("base.baseModule"))
10 10
 
11 11
 function root:ctor(id)
12 12
     root.super.ctor(self, id, "order", "id", true, false)
13
+    self.id = id
13 14
 end
14 15
 
15 16
 function root:mysql_get_init_columns()

+ 149 - 0
dev/utils/util_box.lua

@@ -9,6 +9,8 @@ LastEditTime: 2023-11-15 22:41:18
9 9
 local timeUtil = require("utils.timeUtil")
10 10
 local redisUtil = require("utils.redisUtil")
11 11
 local util_player = require("utils.util_player")
12
+local mysqlUtil = require("utils.mysqlUtil")
13
+local lib_game_redis = require("lib_game_redis")
12 14
 
13 15
 local baseAdapt = require("base.baseAdapt")
14 16
 local boxAdapt = require("adapt.boxAdapt")
@@ -18,6 +20,9 @@ local MODULE_NAME = "box"
18 20
 
19 21
 local root = {}
20 22
 
23
+----------------------------------------
24
+-- 盲盒
25
+----------------------------------------
21 26
 local function _get_box_key(boxId)
22 27
     return string.format("%s:%s", MODULE_NAME, tostring(boxId))
23 28
 end
@@ -92,5 +97,149 @@ function root:pack_box_info_list(boxId)
92 97
     end
93 98
     return boxInfoList
94 99
 end
100
+----------------------------------------
101
+-- 追梦
102
+----------------------------------------
103
+local function _get_dream_key()
104
+    return "box:dream"
105
+end
106
+local function _get_dream_odds_tims_key(ti)
107
+    return string.format("box:dream:odds-times:%s", timeUtil.toDate(ti))
108
+end
109
+-- 新增记录
110
+function root:dream_add_record(uid, itemId, odds, dropItem, isWin)
111
+    if is_empty(uid) or is_empty(itemId) or is_empty(odds) or is_empty(dropItem) then
112
+        return false
113
+    end
114
+    local price = resAdapt:get_item_price(itemId)
115
+    if is_empty(price) then
116
+        return false
117
+    end
118
+
119
+    local dropTime = timeUtil.now()
120
+    local expireTime = dropItem + timeUtil.SEC_PER_DAY * 365
121
+    local sql =
122
+        string.format(
123
+        "INSERT INTO `mdl_dream` (`uid`,`itemId`,`dropItem`,`price`,`odds`,`isWin`,`dropTime`,`expireTime`)" ..
124
+            " VALUES (%s,%s,'%s',%s,%s,%s,%s,%s); ",
125
+        tostring(uid),
126
+        tostring(itemId),
127
+        cjson_encode(dropItem),
128
+        tostring(price),
129
+        tostring(odds),
130
+        tostring(isWin and 1 or 0),
131
+        tostring(dropTime),
132
+        tostring(expireTime)
133
+    )
134
+
135
+    return mysqlUtil:insert(sql)
136
+end
137
+-- 新增概率次数
138
+function root:dream_add_odds_times(odds, isWin)
139
+    if is_empty(odds) then
140
+        return false
141
+    end
142
+    local key = _get_dream_odds_tims_key()
143
+    local subKey = string.format("odds:%s:%s", tostring(odds), tostring(isWin and 1 or 0))
144
+    local times = redisUtil.hget_int(key, subKey)
145
+    times = times + 1
146
+    redisUtil.hset(key, subKey, times)
147
+end
148
+
149
+-- 获取精彩瞬间记录
150
+function root:dream_get_brilliants()
151
+    local minPrice = 100000
152
+    local count = 20
153
+    local sql =
154
+        string.format(
155
+        "SELECT * FROM `mdl_dream` WHERE `price`>=%s AND `isWin`=1 ORDER BY dropTime DESC limit %s",
156
+        tostring(minPrice),
157
+        tostring(count)
158
+    )
159
+    local ok, ret = mysqlUtil:select(sql)
160
+    if not ok or is_empty(ret) then
161
+        return
162
+    end
163
+    local list = {}
164
+    for _, v in ipairs(ret) do
165
+        local uid = tonumber(v.uid)
166
+        local info = {
167
+            playerInfo = util_player:get_base_info(uid),
168
+            itemId = tonumber(v.itemId),
169
+            dropItem = cjson_decode(v.dropItem),
170
+            price = tonumber(v.price),
171
+            odds = tonumber(v.odds),
172
+            dropTime = tonumber(v.dropTime)
173
+        }
174
+        table.insert(list, info)
175
+    end
176
+    return list
177
+end
178
+
179
+-- 掉落记录
180
+function root:dream_get_records()
181
+    local count = 20
182
+    local sql = string.format("SELECT * FROM `mdl_dream` ORDER BY dropTime DESC limit %s", tostring(count))
183
+    local ok, ret = mysqlUtil:select(sql)
184
+    if not ok or is_empty(ret) then
185
+        return
186
+    end
187
+    local list = {}
188
+    for _, v in ipairs(ret) do
189
+        local uid = tonumber(v.uid)
190
+        local info = {
191
+            playerInfo = util_player:get_base_info(uid),
192
+            itemId = tonumber(v.itemId),
193
+            dropItem = cjson_decode(v.dropItem),
194
+            price = tonumber(v.price),
195
+            odds = tonumber(v.odds),
196
+            dropTime = tonumber(v.dropTime)
197
+        }
198
+        table.insert(list, info)
199
+    end
200
+    return list
201
+end
202
+
203
+-- 次数统计
204
+function root:dream_get_statement()
205
+    local days = 3
206
+    local mapOddsWinTims = {}
207
+    local mapOddsLoseTims = {}
208
+    local currTime = timeUtil.now()
209
+    for i = 0, days - 2 do
210
+        local ti = currTime - timeUtil.SEC_PER_DAY * i
211
+        local key = _get_dream_odds_tims_key(ti)
212
+        for odds = 5, 85 do
213
+            -- 中奖
214
+            local subKey = string.format("odds:%s:1", tostring(odds))
215
+            local times = redisUtil.hget_int(key, subKey)
216
+            mapOddsWinTims[odds] = (mapOddsWinTims[odds] or 0) + times
217
+            -- 不中奖
218
+            subKey = string.format("odds:%s:0", tostring(odds))
219
+            times = redisUtil.hget_int(key, subKey)
220
+            mapOddsLoseTims[odds] = (mapOddsLoseTims[odds] or 0) + times
221
+        end
222
+    end
223
+    local oddsTimesList = {}
224
+    for odds = 5, 85 do
225
+        if not is_empty(mapOddsWinTims[odds]) or not is_empty(mapOddsLoseTims[odds]) then
226
+            local info = {
227
+                odds = odds,
228
+                winTimes = mapOddsWinTims[odds] or 0,
229
+                loseTimes = mapOddsLoseTims[odds] or 0
230
+            }
231
+            table.insert(oddsTimesList, info)
232
+        end
233
+    end
234
+    return oddsTimesList
235
+end
236
+-- 删除天统计
237
+function root:dream_del_day_statement(ti)
238
+    if is_empty(ti) then
239
+        return
240
+    end
241
+    local key = _get_dream_odds_tims_key(ti)
242
+    lib_game_redis:del(key)
243
+end
95 244
 
96 245
 return root

+ 68 - 3
nodes/game/interface/box.lua

@@ -17,7 +17,10 @@ local bagData = require("data.bag")
17 17
 
18 18
 local root = {}
19 19
 
20
+----------------------------------------
21
+-- 盲盒
22
+----------------------------------------
23
+-- 模块信息
20 24
 function root:box_blind_get_info(role, msg)
21 25
     local id = msg.id
22 26
     local ret = {
@@ -26,7 +29,7 @@ function root:box_blind_get_info(role, msg)
26 29
     return code.OK, ret
27 30
 end
28 31
 
32
+-- 开盲盒
29 33
 function root:box_blind_open(role, msg)
30 34
     local id = msg.id
31 35
     local count = msg.count or 1
@@ -45,11 +48,11 @@ function root:box_blind_open(role, msg)
45 48
                 break
46 49
             end
47 50
             -- 消耗
48
-            local eventId = string.format("box-blind-%s", tostring(id))
49
-            bagData:consume_items(uid, costItems, eventId)
51
+            local keyEvent = string.format("box-blind-%s", tostring(id))
52
+            bagData:consume_items(uid, costItems, keyEvent)
50 53
             -- 获取物品
51 54
             local _items = {{id = itemId, count = itemCount}}
52
-            bagData:add_items(uid, _items, eventId)
55
+            bagData:add_items(uid, _items, keyEvent)
53 56
 
54 57
             items = itemUtil.items_merge(items, _items)
55 58
         end
@@ -64,4 +67,64 @@ function root:box_blind_open(role, msg)
64 67
     return code.OK, ret
65 68
 end
66 69
 
70
+----------------------------------------
71
+-- 追梦
72
+----------------------------------------
73
+-- 开奖
74
+function root:box_dream_open(role, msg)
75
+    local itemId = msg.itemId
76
+    local odds = msg.odds
77
+    if is_empty(itemId) or is_empty(odds) or odds < 5 or odds > 85 then
78
+        return code.PARAMTER_ERROR
79
+    end
80
+    local confItem = resAdapt:get_item_conf(itemId)
81
+    if is_empty(confItem) then
82
+        return code.BAG.ITEM_NOT_EXIST
83
+    end
84
+    local uid = role.uid
85
+    -- 消耗
86
+    local costItems = {
87
+        {id = gameConst.ITEM_ID.DIAMOND, count = math.floor(confItem.price / confItem.priceConst * odds)}
88
+    }
89
+    local ok, _costItems = bagData:is_enough(uid, costItems)
90
+    if not ok then
91
+        return code.BAG.ITEM_NOT_ENOUGH
92
+    end
93
+    -- 消耗
94
+    local keyEvent = string.format("box-dream-%s", tostring(itemId))
95
+    bagData:consume_items(uid, _costItems, keyEvent)
96
+    -- 随机道具
97
+    local awardList = {
98
+        {id = itemId, count = 1, weight = adds},
99
+        {id = gameConst.ITEM_ID.N1, count = 1, weight = 100 - odds}
100
+    }
101
+    local index = random_list_by_weight(awardList)
102
+    local dropItem = {id = awardList[index].id, count = awardList[index].count}
103
+    bagData:add_items(uid, {dropItem}, keyEvent)
104
+    -- 记录/统计
105
+    local isWin = dropItem.id == itemId
106
+    util_box:dream_add_record(uid, itemId, odds, dropItem, isWin)
107
+    util_box:dream_add_odds_times(odds, isWin)
108
+
109
+    return code.OK, {dropItem = dropItem}
110
+end
111
+
112
+-- 精彩瞬间
113
+function root:box_dream_brilliant(role, msg)
114
+    local list = util_box:dream_get_brilliants()
115
+    return code.OK, {list = list}
116
+end
117
+
118
+-- 掉落记录
119
+function root:box_dream_records(role, msg)
120
+    local list = util_box:dream_get_records()
121
+    return code.OK, {list = list}
122
+end
123
+
124
+-- 全局统计
125
+function root:box_dream_statement(role, msg)
126
+    local oddsTimesList = util_box:dream_get_statement()
127
+    return code.OK, {oddsTimesList = oddsTimesList}
128
+end
129
+
67 130
 return root

+ 2 - 0
nodes/global/main.lua

@@ -24,6 +24,8 @@ skynet.start(
24 24
         init_nodes:init_config()
25 25
 
26 26
         skynet.uniqueservice("backupSrv")
27
+        skynet.uniqueservice("mailSrv")
28
+        skynet.uniqueservice("dreamSrv")
27 29
 
28 30
         -- 集群
29 31
         init_nodes:init_cluster()

+ 38 - 0
nodes/global/service/dreamSrv.lua

@@ -0,0 +1,38 @@
1
+--[[
2
+Descripttion:追梦
3
+version:
4
+Author: Neo,Huang
5
+Date: 2022-08-17 16:04:20
6
+LastEditors: Neo,Huang
7
+LastEditTime: 2022-08-20 15:18:25
8
+--]]
9
+local timer = require("timer")
10
+local baseService = require("baseService")
11
+local lib_game_mysql = require("lib_game_mysql")
12
+local util_box = require("utils.util_box")
13
+
14
+local timerDelExpireMail = nil
15
+
16
+local CMD = {}
17
+
18
+-- 清理过期追梦记录
19
+local function l_del_expire_record()
20
+	local currTime = skynet_time()
21
+	local sql = string.format("delete from mdl_dream where expireTime >0 and expireTime < %s;", tostring(currTime))
22
+	local ret = lib_game_mysql:query(sql)
23
+	log.info("l_del_expire_record sql[%s] ret[%s]", tostring(sql), tostring(ret))
24
+	-- 统计 - 保留30
25
+	local ti = currTime - 86400 * 30
26
+	util_box:dream_del_day_statement(ti)
27
+end
28
+
29
+function CMD.onStart()
30
+	timerDelExpireMail = timer.timeOut(60, l_del_expire_mail)
31
+end
32
+
33
+function CMD.onStop()
34
+	-- 取消定时器
35
+	timerDelExpireMail.func = nil
36
+end
37
+
38
+baseService.start(CMD, ".dreamCenter", true)