pvpd.lua
7.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
skynet = require "skynet"
local json = require("shared.json")
redisproxy = require("shared.redisproxy")
local cluster = require "skynet.cluster"
local serverId = tonumber(skynet.getenv("servId"))
datacenter = require "skynet.datacenter"
csvdb = require "shared.csvdata"
require "shared.init"
require "utils.init"
require "RedisKeys"
require "skynet.manager"
require "GlobalVar"
local MatchCache = {} -- 比赛记录 缓存   { [roundIdx] = {{rolesId, rolesId, winId = roleId}, {rolesId, rolesId}}, ... }
local RoleInfo = {} -- 角色信息缓存 {[rolesId] = info}
local pvpInfo = nil
local ROBOT_SERV_ID = 999 
local function packRoleId(servId, roleId)
	return roleId * 1000 + servId
end
local function unpackRoleId(tempId)
	local servId = tempId % 1000
	local roleId = math.floor(tempId / 1000)
	return servId, roleId
end
skynet.register_protocol {
	name = "role",
	id = 101,
	pack = skynet.pack,
	unpack = skynet.unpack,
	dispatch = function(session, address, submethod, ...)
	end,
}
local function rpcRole(roleId, funcName, ...)
	local fields = ...
	local agent = datacenter.get("agent", roleId)
	if agent and agent.serv then
		if funcName == "getProperties" then
			return skynet.call(agent.serv, "role", funcName, fields)
		else
			return skynet.call(agent.serv, "role", funcName, ...)
		end
	else
		local roleCross = require("models.RoleCross")
		if funcName == "getProperties" then
			return roleCross.handle(funcName, roleId, fields)
		else
			return roleCross.handle(funcName, roleId, ...)
		end
	end
end
local function getDBKey()
	local resetData = csvdb["time_resetCsv"][TimeReset.PvpCross]
	local curRound = math.floor((skynet.timex() - START_RESET_TIME - resetData.start) / resetData.interval)
	local idx = 1
	if curRound % 2 == 1 then
		idx = 2 
	end
	return RANK_PVP_HIGHT_KEY[idx]
end
local function getStartTime()
	local resetData = csvdb["time_resetCsv"][TimeReset.PvpCross]
	local curRound = math.floor((skynet.timex() - START_RESET_TIME - resetData.start) / resetData.interval)
	local startTime = START_RESET_TIME + curRound * resetData.interval + resetData.start
	return startTime
end
local CMD = {}
------------------- 角色调用 --------------------------
function CMD.updateRoleInfo(change)
	CMD.refreshRoleInfo(change)
	local pvpd = cluster.query("center", "pvpd")
	if pvpd then
		pcall(cluster.call, "center", pvpd, "updateRoleInfo", change)
	end
end
local function getDayAndTime()
	local startTime = getStartTime()
	local now = skynet.timex()
	local crossTime = now - startTime
	local aday = 3600 * 24
	local day = math.ceil(crossTime / aday) -- 当前是第几个比赛日
	local ctime = crossTime % aday -- 当前在本天 经过多少时间
	return day, ctime
end
local function hideMatchInfo()
	local day, ctime = getDayAndTime()
	local tempMatchCache = {}
	for round, tempData in pairs(MatchCache) do
		if round == day and ctime < globalCsv.pvp_cross_server_show_result - 1 then
			tempMatchCache[round] = {}
			for idx, match in pairs(tempData) do
				tempMatchCache[round][idx] = {
					[1] = match[1],
					[2] = match[2],
				}
			end
		elseif round <= day then
			tempMatchCache[round] = {}
			for idx, match in pairs(tempData) do
				tempMatchCache[round][idx] = {
					[1] = match[1],
					[2] = match[2],
					win = match.win,
					battleV = {
						[match[1]] = (match.teams[match[1]] or {}).battleV,
						[match[2]] = (match.teams[match[2]] or {}).battleV,
					}
				}
			end
		end
	end
	return tempMatchCache
end
local function hideRoleInfo()
	local day, ctime = getDayAndTime()
	local needInfo = {}
	local tempRoleInfo = {}
	for pId, roleInfo in pairs(RoleInfo) do
		tempRoleInfo[pId] = {
			name = roleInfo.name,
			level = roleInfo.level,
			headId = roleInfo.headId,
		}
	end
	return tempRoleInfo
end
function CMD.getMatchInfo()
	if not next(MatchCache) then
		local pvpd = cluster.query("center", "pvpd")
		if pvpd then
			local status, result = pcall(cluster.call, "center", pvpd, "getMatchInfo", {serverId = serverId})
			MatchCache = result.matchInfo or {}
			RoleInfo = result.roleInfo or {}
		end
	end
	return {matchInfo = hideMatchInfo(), roleInfo = hideRoleInfo()}
end
function CMD.getRoleInfo()
	if not next(MatchCache) then
		CMD.getMatchInfo()
	end
	return hideRoleInfo()
end
function CMD.getRoleDetail(pIds)
	if not next(MatchCache) then
		CMD.getMatchInfo()
	end
	local result = {}
	for _, pId in ipairs(pIds) do
		result[pId] = RoleInfo[pId]
	end
	return result
end
function CMD.getMatchRecord(round, matchIdx)
	if not next(MatchCache) then
		CMD.getMatchInfo()
	end
	local day, ctime = getDayAndTime()
	if round > day or (round == day  and ctime < globalCsv.pvp_cross_server_show_result) then return end -- 还么结算
	if not (MatchCache[round] or {})[matchIdx] then return end
	return {
		videos = MatchCache[round][matchIdx].video,
		teams = MatchCache[round][matchIdx].teams,
	}
end
function CMD.getBetInfo()
	if not next(MatchCache) then
		CMD.getMatchInfo()
	end
	local day, ctime = getDayAndTime()
	local change = false
	local lastDay = math.min(day, globalCsv.pvp_cross_server_day)
	local betInfo = pvpInfo:getProperty("betInfo")
	local betNum = pvpInfo:getProperty("betNum")
	for cday = 1, lastDay do
		if not betInfo[cday] then
			change = true
			betInfo[cday] = math.randomInt(1, #(MatchCache[cday] or {1}))
			if cday == lastDay then
				betNum = {}
				redisproxy:del("cross:pvpInfo:bet:" .. cday)
			end
		end
	end
	if change then
		pvpInfo:setProperties({
			betInfo = betInfo,
			betNum = betNum
		})
	end
	return pvpInfo:getProperties({"betInfo", "betNum"})
end
function CMD.setBet(idx, roleId, costNum)
	local day, ctime = getDayAndTime()
	if day > globalCsv.pvp_cross_server_day or ctime >= globalCsv.pvp_cross_server_stop_stake then return end
	
	local betInfo = pvpInfo:getProperty("betInfo")
	if not betInfo[day] then return end
	local betNum = pvpInfo:getProperty("betNum")
	betNum[idx] = (betNum[idx] or 0) + 1
	pvpInfo:setProperty("betNum", betNum)
	redisproxy:hset("cross:pvpInfo:bet:" .. day, roleId, costNum * 10 + idx)
	return {betNum = betNum}
end
-------------------中心服务器 调用----------------------
function CMD.loadRoles(roleIds)
	roleIds = roleIds or {}
	local infos = {}
	RoleInfo[serverId] = RoleInfo[serverId] or {}
	for _, roleId in ipairs(roleIds) do
		infos[roleId] = rpcRole(roleId, "pvpHInfo")
		local temp = {}
		for _field, _v in pairs(infos[roleId]) do
			if _field ~= "battleInfo" then
				temp[_field] = _v
			end
		end
		RoleInfo[packRoleId(serverId, roleId)] = temp
	end
	return infos
end
-- 新赛季了 清掉缓存
function CMD.loadTeams()
	local dbKey = getDBKey()
	local redret = redisproxy:zrevrange(dbKey, 0, 15)
	local roleIds = {}
	for _, roleId in ipairs(redret) do
		table.insert(roleIds, tonumber(roleId))
	end
	MatchCache = {}
	RoleInfo = {}
	local infos = CMD.loadRoles(roleIds)
	pvpInfo:setProperties({
		betInfo = {},
		betNum = {},
	})
	return {roleIds = roleIds, infos = infos}
end
-- 刷新缓存
function CMD.refreshMatchCache(info)
	MatchCache = info.matchInfo
	RoleInfo = info.roleInfo
end
-- 刷新 玩家数据
function CMD.refreshRoleInfo(change)
	if not next(RoleInfo) then return end
	if RoleInfo[change.id] then
		for field, value in pairs(change) do
			if field ~= "id" then
				RoleInfo[change.id][field] = value
			end
		end
	end
end
------------------------------------------------------
function CMD.start()
	redisd = skynet.localname(".redis")
	globalCsv = csvdb["GlobalDefineCsv"]
	
	pvpInfo = require("models.Pvpd").new({key = "cross:pvpInfo"})
	pvpInfo:load()
end
---------------------------------------------------------
local function __init__()
	skynet.dispatch("lua", function(_, _, command, ...)
		local f = CMD[command]
		if f then
			skynet.ret(skynet.pack(f(...)))
		end
	end)
	
	skynet.register(".pvpcross")
end
skynet.start(__init__)