Browse Source

新增邮件系统

neo 1 year ago
parent
commit
fc5a456d41

+ 2 - 2
common/core/nodeMgr.lua

@@ -107,13 +107,13 @@ function root.snaxcall(node, name, address, reqType, func, ...)
107
 end
107
 end
108
 
108
 
109
 -- 向所有agent进行广播
109
 -- 向所有agent进行广播
110
-function root.broadcast_game_agent(interface, ...)
110
+function root.broadcast_game_agent(mdl, cmd, ...)
111
 	local nodeInfoList = root.get_type_node_list("game")
111
 	local nodeInfoList = root.get_type_node_list("game")
112
 	if is_empty(nodeInfoList) then
112
 	if is_empty(nodeInfoList) then
113
 		return
113
 		return
114
 	end
114
 	end
115
 	for _, v in ipairs(nodeInfoList) do
115
 	for _, v in ipairs(nodeInfoList) do
116
-		root.send(v, ".srvAgentMgr", "broadcast_agents", interface, ...)
116
+		root.send(v, ".srvAgentMgr", "broadcast_agents", mdl, cmd, ...)
117
 	end
117
 	end
118
 end
118
 end
119
 
119
 

+ 7 - 0
dev/data/user.lua

@@ -53,6 +53,13 @@ function root:user_is_match_password(uid, password)
53
     end
53
     end
54
     return password == moduleData:hget(uid, MODULE_NAME, "password")
54
     return password == moduleData:hget(uid, MODULE_NAME, "password")
55
 end
55
 end
56
+-- 渠道匹配
57
+function root:user_is_match_channel(uid, channel)
58
+    if uid == nil or channel == nil then
59
+        return false
60
+    end
61
+    return channel == moduleData:get_channel(uid)
62
+end
56
 
63
 
57
 -- 账号状态
64
 -- 账号状态
58
 function root:get_status(uid)
65
 function root:get_status(uid)

+ 31 - 0
dev/modules/mail.lua

@@ -0,0 +1,31 @@
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("moduleMail", require("base.baseModule"))
10
+
11
+function root:ctor(id)
12
+	root.super.ctor(self, "mail", "id", true, true)
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 '接收人'",
20
+		channel = "int(11) DEFAULT 0 COMMENT '渠道编号'",
21
+		title = "varchar(50) DEFAULT '系统通知' COMMENT '邮件标题'",
22
+		cnt = "varchar(400) DEFAULT 1 COMMENT '邮件内容'",
23
+		items = "json COMMENT '邮件物品列表'",
24
+		ty = "int(11) DEFAULT 1 COMMENT '邮件类型'",
25
+		createTime = "int(11) DEFAULT 0 COMMENT '发送时间'",
26
+		expireTime = "int(11) DEFAULT 0 COMMENT '过期时间 -1:常驻邮件'",
27
+		src = "varchar(50) DEFAULT 'sys' COMMENT '邮件来源'"
28
+	}
29
+end
30
+
31
+return root

+ 193 - 0
dev/modules/pmail.lua

@@ -0,0 +1,193 @@
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 code = require("code")
10
+local util_mail = require("utils.util_mail")
11
+local timeUtil = require("utils.timeUtil")
12
+local itemUtil = require("utils.itemUtil")
13
+
14
+local bagData = require("data.bag")
15
+
16
+local root = class("mailSelf", require("base.baseModule"))
17
+
18
+function root:ctor(uid)
19
+	root.super.ctor(self, "tb_mail_self", "uid", true, nil, nil)
20
+
21
+	self.uid = uid
22
+end
23
+
24
+function root:getInitColumnNameOptions()
25
+	return {
26
+		uid = "bigint(20) unsigned NOT NULL COMMENT '用户ID'",
27
+		readIdList = "JSON COMMENT '已读邮件ID列表'",
28
+		delIdList = "JSON COMMENT '已删邮件ID列表'",
29
+		awardIdList = "JSON COMMENT '已领取奖励邮件ID列表'"
30
+	}
31
+end
32
+
33
+-- 读邮件 - 新增
34
+function root:add_read_mail(id)
35
+	if is_empty(id) then
36
+		return false
37
+	end
38
+	local readIdList = self:redis_get_key_info("readIdList")
39
+	if table.include(readIdList, id) then
40
+		return false
41
+	end
42
+	table.insetr(readIdList, id)
43
+	self:redis_update_key_info("readIdList", readIdList)
44
+end
45
+-- 是否已读
46
+function root:is_read(id)
47
+	if is_empty(id) then
48
+		return false
49
+	end
50
+	local readIdList = self:redis_get_key_info("readIdList")
51
+	if table.include(readIdList, id) then
52
+		return true
53
+	end
54
+	return false
55
+end
56
+
57
+-- 读邮件 - 新增
58
+function root:add_del_mail(id)
59
+	if is_empty(id) then
60
+		return false
61
+	end
62
+	local delIdList = self:redis_get_key_info("delIdList")
63
+	if table.include(delIdList, id) then
64
+		return false
65
+	end
66
+	table.insetr(delIdList, id)
67
+	self:redis_update_key_info("delIdList", delIdList)
68
+end
69
+-- 是否已读
70
+function root:is_del(id)
71
+	if is_empty(id) then
72
+		return false
73
+	end
74
+	local delIdList = self:redis_get_key_info("delIdList")
75
+	if table.include(delIdList, id) then
76
+		return true
77
+	end
78
+	return false
79
+end
80
+
81
+-- 奖励 - 新增
82
+function root:add_award_mail(id)
83
+	if is_empty(id) then
84
+		return false
85
+	end
86
+	local awardIdList = self:redis_get_key_info("awardIdList")
87
+	if table.include(awardIdList, id) then
88
+		return false
89
+	end
90
+	table.insetr(awardIdList, id)
91
+	self:redis_update_key_info("awardIdList", awardIdList)
92
+	return true
93
+end
94
+-- 是否已读
95
+function root:is_awarded(id)
96
+	if is_empty(id) then
97
+		return false
98
+	end
99
+	local awardIdList = self:redis_get_key_info("awardIdList")
100
+	if table.include(awardIdList, id) then
101
+		return true
102
+	end
103
+	return false
104
+end
105
+
106
+----------------------------------------
107
+-- 接口
108
+----------------------------------------
109
+-- 模块信息
110
+function root:itf_get_info(msg)
111
+	local lastTime = msg.lastTime or 0
112
+	local list = util_mail:user_get_mail_info_list(self.uid, lastTime)
113
+	local mailList = {}
114
+	if not is_empty(list) then
115
+		for _, v in ipairs(list) do
116
+			if not self:is_del(v.id) then
117
+				local info = {
118
+					id = v.id,
119
+					title = v.title,
120
+					cnt = v.cnt,
121
+					ty = v.ty,
122
+					createTime = v.createTime,
123
+					expireTime = v.expireTime,
124
+					status = v.status,
125
+					statusItems = self:is_awarded(v.id) and 1 or 0
126
+				}
127
+				if not is_empty(v.items) then
128
+					info.items = cjson_decode(v.items)
129
+				end
130
+				info.status = self:is_read(v.id) and 1 or 0
131
+				table.insert(mailList, info)
132
+			end
133
+		end
134
+	end
135
+	local ret = {
136
+		mailList = mailList,
137
+		sysTime = timeUtil.now(self.uid)
138
+	}
139
+	return code.OK, ret
140
+end
141
+-- 读取
142
+function root:itf_read(msg)
143
+	local idList = msg.idList
144
+	if msg == nil or is_empty(idList) then
145
+		return code.PARAMTER_ERROR
146
+	end
147
+	for _, id in ipairs(idList) do
148
+		self:add_read_mail(id)
149
+	end
150
+	return code.OK
151
+end
152
+-- 删除
153
+function root:itf_del(msg)
154
+	local idList = msg.idList
155
+	if msg == nil or is_empty(idList) then
156
+		return code.PARAMTER_ERROR
157
+	end
158
+	for _, id in ipairs(idList) do
159
+		self:add_del_mail(id)
160
+	end
161
+	return code.OK
162
+end
163
+-- 获取邮件奖励
164
+function root:itf_get_award(msg)
165
+	local idList = msg.idList
166
+	if msg == nil or is_empty(idList) then
167
+		return code.PARAMTER_ERROR
168
+	end
169
+
170
+	local awardIdList = self:redis_get_key_info("awardIdList")
171
+	local mailItems = nil
172
+	for _, id in ipairs(idList) do
173
+		-- 是否已领取
174
+		if not self:is_awarded(id) then
175
+			local errCode, items = util_mail:user_get_mail_award(self.uid, id)
176
+			if not code.is_not_ok(errCode) then
177
+				table.insert(awardIdList, id)
178
+				if not is_empty(items) then
179
+					-- 发放邮件物品
180
+					local keyEvent = string.format("mail-award-%s", tostring(id))
181
+					bagData:add_items(self.uid, items, keyEvent)
182
+				end
183
+
184
+				mailItems = itemUtil.items_merge(mailItems, items)
185
+			end
186
+		end
187
+	end
188
+	self:redis_update_key_info("awardIdList", awardIdList)
189
+
190
+	return code.OK, {items = mailItems}
191
+end
192
+
193
+return root

+ 33 - 0
dev/utils/util_global.lua

@@ -0,0 +1,33 @@
1
+--[[
2
+Descripttion:玩家事件
3
+version:
4
+Author: Neo,Huang
5
+Date: 2022-07-05 19:59:16
6
+LastEditors: Neo,Huang
7
+LastEditTime: 2022-07-05 20:08:31
8
+--]]
9
+local lib_game_redis = require("lib_game_redis")
10
+
11
+local MODULE_NAME = "global"
12
+
13
+local root = {}
14
+
15
+-- 创建玩家id
16
+function root:gen_user_id()
17
+    local uid = lib_game_redis:hincrby(MODULE_NAME, "user:max:id", 1)
18
+    if uid < 1000000 then
19
+        uid = uid + 1000000
20
+        lib_game_redis:set("user:max:id", uid)
21
+    end
22
+
23
+    return uid
24
+end
25
+
26
+-- 创建邮件id
27
+function root:gen_mail_id()
28
+    local id = lib_game_redis:hincrby(MODULE_NAME, "mail:max:id", 1)
29
+
30
+    return id
31
+end
32
+
33
+return root

+ 145 - 0
dev/utils/util_mail.lua

@@ -0,0 +1,145 @@
1
+--[[
2
+Descripttion:邮件
3
+version:
4
+Author: Neo,Huang
5
+Date: 2022-08-19 20:10:44
6
+LastEditors: Neo,Huang
7
+LastEditTime: 2022-08-19 20:10:56
8
+--]]
9
+local code = require("code")
10
+local util_user = require("utils.util_user")
11
+local nodeMgr = require("nodeMgr")
12
+local lib_game_mysql = require("lib_game_mysql")
13
+local util_global = require("utils.util_global")
14
+
15
+local mailAdapt = require("adapt.mailAdapt")
16
+
17
+local globalData = require("data.global")
18
+local moduleData = require("data.module")
19
+
20
+local root = {}
21
+
22
+-- 新增邮件
23
+-- uid:0为全服邮件 >1000000玩家邮件 -1:渠道邮件
24
+-- status: 邮件状态 个位:0:新增 1:已读 2:删除 十位:奖励状态 0:未领取 1:已领取
25
+function root:add_mail(uid, channel, title, cnt, items, ty, createTime, expireTime, src)
26
+    if uid == nil or title == nil or is_empty(cnt) then
27
+        return false
28
+    end
29
+    local id = util_global:gen_mail_id()
30
+
31
+    channel = channel or 0
32
+    ty = ty or 1
33
+    createTime = createTime or skynet_time()
34
+    expireTime = expireTime or (createTime + 7 * 24 * 60 * 60)
35
+    src = src or "sys"
36
+    -- 邮件物品
37
+    if is_empty(items) then
38
+        items = {}
39
+    end
40
+    items = cjson_encode(items)
41
+
42
+    -- 插入数据库
43
+    local values =
44
+        string.format(
45
+        "id=%s, uid=%s, channel=%s, title='%s', cnt='%s', items='%s', ty=%s, createTime=%s, expireTime=%s, src='%s'",
46
+        tostring(id),
47
+        tostring(uid),
48
+        tostring(channel),
49
+        tostring(title),
50
+        tostring(cnt),
51
+        tostring(items),
52
+        tostring(ty),
53
+        tostring(createTime),
54
+        tostring(expireTime),
55
+        tostring(src)
56
+    )
57
+    local sql = string.format("insert into mdl_mail set %s;", tostring(values))
58
+    local ret = lib_game_mysql:query(sql)
59
+    if ret.errno and ret.errno > 0 then
60
+        log.error("add_mail 新增邮件失败 ret[%s] sql[%s]", tostring(ret), tostring(sql))
61
+        return false
62
+    end
63
+    -- 通知新邮件
64
+    if uid == 0 then
65
+        -- 全服
66
+        nodeMgr.broadcast_game_agent("mail", "add_new_mail", {id = id})
67
+    elseif uid == -1 then
68
+        -- 渠道
69
+        nodeMgr.broadcast_game_agent("mail", "add_new_mail", {id = id, channel = channel})
70
+    elseif not is_robot(uid) then
71
+        -- 通知玩家 - 新增个人邮件
72
+        self:on_new_mail(uid, id)
73
+    end
74
+
75
+    return true
76
+end
77
+
78
+-- 获取玩家邮件
79
+function root:user_get_mail_info_list(uid, lastTime)
80
+    if uid == nil then
81
+        return
82
+    end
83
+    local currTime = skynet_time()
84
+    local channel = moduleData:get_channel(uid)
85
+    lastTime = lastTime or 0
86
+    -- 全局邮件,个人邮件
87
+    local sectionUser =
88
+        string.format("((`uid`=%s or `uid`=0) and `expireTime` >= %s)", tostring(uid), tostring(currTime))
89
+    -- 渠道邮件
90
+    local sectionChannel =
91
+        string.format("(`uid`=-1 and `channel` = %s and `expireTime` >= %s)", tostring(channel), tostring(currTime))
92
+
93
+    local sql =
94
+        string.format(
95
+        "SELECT * FROM `mdl_mail` WHERE createTime >= %s and (%s or %s);",
96
+        lastTime,
97
+        sectionUser,
98
+        sectionChannel
99
+    )
100
+    -- log.info("user_get_mail_info_list uid[%s] sql[%s]", tostring(uid), tostring(sql))
101
+
102
+    local ret = lib_game_mysql:query(sql)
103
+    if ret.errno and ret.errno > 0 then
104
+        log.error("user_get_mail_info_list 获取玩家邮件列表失败 ret[%s] sql[%s]", tostring(ret), tostring(sql))
105
+        return
106
+    end
107
+    return ret
108
+end
109
+-- 玩家获取邮件物品
110
+function root:user_get_mail_award(uid, id)
111
+    if uid == nil or id == nil then
112
+        return code.PARAMTER_ERROR
113
+    end
114
+
115
+    -- 获取邮件信息
116
+    local sql = string.format("SELECT * FROM `mdl_mail` WHERE id=%s;", tostring(id))
117
+    log.info("user_get_mail_award uid[%s] sql[%s]", tostring(uid), tostring(sql))
118
+
119
+    local ret = lib_game_mysql:query(sql)
120
+    if is_empty(ret) or (ret.errno and ret.errno > 0) then
121
+        log.error("user_get_mail_award 邮件不存在 ret[%s] sql[%s]", tostring(ret), tostring(sql))
122
+        return code.MAIL.NOT_FOUND
123
+    end
124
+    -- 邮件没有物品
125
+    if is_empty(ret[1].items) then
126
+        log.error("user_get_mail_award 邮件物品不存在 ret[%s] sql[%s]", tostring(ret), tostring(sql))
127
+        return code.MAIL.NOT_MORE_ITEMS
128
+    end
129
+
130
+    local items = cjson_decode(ret[1].items)
131
+
132
+    return code.OK, items
133
+end
134
+
135
+-- 通知玩家 - 新增邮件
136
+function root:on_new_mail(uid, id)
137
+    if uid == nil or is_robot(uid) or id == nil then
138
+        return false
139
+    end
140
+    local pack = {id = id}
141
+    util_user:user_proto_notify(uid, "on_new_mail", pack)
142
+    return true
143
+end
144
+
145
+return root

+ 53 - 0
nodes/game/interface/mail.lua

@@ -0,0 +1,53 @@
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 09:42:54
8
+--]]
9
+local code = require "code"
10
+local util_mail = require("utils.util_mail")
11
+
12
+local userData = require("data.user")
13
+
14
+local root = {}
15
+
16
+-- 获取邮件信息列表
17
+function root.mail_get_info(role, msg)
18
+    return role.pmail:itf_get_info(msg)
19
+end
20
+
21
+-- 读取邮件
22
+function root.mail_read(role, msg)
23
+    return role.pmail:itf_read(msg)
24
+end
25
+
26
+-- 删除邮件
27
+function root.mail_del(role, msg)
28
+    return role.pmail:itf_del(msg)
29
+end
30
+
31
+-- 获取邮件奖励
32
+function root.mail_get_award(role, msg)
33
+    return role.pmail:itf_get_award(msg)
34
+end
35
+
36
+-- 新邮件通知
37
+function root.add_new_mail(role, msg)
38
+    local uid = role.uid
39
+    local id = msg.id
40
+    local channel = msg.channel
41
+    if id == nil then
42
+        return code.PARAMTER_ERROR
43
+    end
44
+
45
+    if channel == nil or userData:user_is_match_channel(uid, channel) then
46
+        -- 玩家新增邮件
47
+        util_mail:on_new_mail(uid, id)
48
+    end
49
+
50
+    return code.OK
51
+end
52
+
53
+return root

+ 2 - 2
nodes/game/service/srvAgentMgr.lua

@@ -93,9 +93,9 @@ function root.print_uid_list()
93
 end
93
 end
94
 
94
 
95
 -- 在线玩家广播消息
95
 -- 在线玩家广播消息
96
-function root.broadcast_agents(cmd, ...)
96
+function root.broadcast_agents(mdl, cmd, ...)
97
 	for uid, handle in pairs(mapUid2Agent) do
97
 	for uid, handle in pairs(mapUid2Agent) do
98
-		pcall(skynet.send, handle, "lua", "doCmd", uid, cmd, ...)
98
+		pcall(skynet.send, handle, "lua", "doCmd", uid, mdl, cmd, ...)
99
 	end
99
 	end
100
 end
100
 end
101
 
101
 

+ 3 - 12
nodes/login/controllers/usr.lua

@@ -3,6 +3,7 @@ local tokenUtil = require "utils.tokenUtil"
3
 local serverLogUtil = require("utils.serverLogUtil")
3
 local serverLogUtil = require("utils.serverLogUtil")
4
 local util_user = require("utils.util_user")
4
 local util_user = require("utils.util_user")
5
 local accountModule = require("modules.accountModule")
5
 local accountModule = require("modules.accountModule")
6
+local util_global = require("utils.util_global")
6
 
7
 
7
 local lib_game_mysql = require("lib_game_mysql")
8
 local lib_game_mysql = require("lib_game_mysql")
8
 local lib_game_redis = require("lib_game_redis")
9
 local lib_game_redis = require("lib_game_redis")
@@ -50,17 +51,6 @@ local function l_uuid_register(msg)
50
     return errCode, ret
51
     return errCode, ret
51
 end
52
 end
52
 
53
 
53
-local function l_get_register_uid()
54
-    local uid = lib_game_redis:incrby("user:max:id", 1)
55
-    if uid < 1000000 then
56
-        uid = uid + 1000000
57
-        lib_game_redis:set("user:max:id", uid)
58
-    end
59
-
60
-    return uid
61
-end
62
-
63
 -- 快速注册
54
 -- 快速注册
64
 function root.register(msg)
55
 function root.register(msg)
65
     local errCode, ret = l_uuid_register(msg)
56
     local errCode, ret = l_uuid_register(msg)
@@ -69,7 +59,7 @@ function root.register(msg)
69
     end
59
     end
70
 
60
 
71
     -- 正常注册
61
     -- 正常注册
72
-    local uid = l_get_register_uid()
62
+    local uid = util_global:gen_user_id()
73
 
63
 
74
     userData:user_init_register_info(uid, msg)
64
     userData:user_init_register_info(uid, msg)
75
     -- 注册埋点
65
     -- 注册埋点
@@ -162,7 +152,7 @@ function root.registerByPhone(msg)
162
         -- return code.USR.ALREADY_REGISTER
152
         -- return code.USR.ALREADY_REGISTER
163
         return root.loginByPhone(msg)
153
         return root.loginByPhone(msg)
164
     end
154
     end
165
-    local uid = l_get_register_uid()
155
+    local uid = util_global:gen_user_id()
166
     -- 注册账号
156
     -- 注册账号
167
     moduleData:hset(account, "account", "account", account)
157
     moduleData:hset(account, "account", "account", account)
168
     moduleData:hset(account, "account", "password", password)
158
     moduleData:hset(account, "account", "password", password)