Blame view

src/services/pvpd.lua 7.76 KB
e3c5cc5e   zhouhaihai   跨服竞技场over
1
  skynet = require "skynet"
c779be0c   zhouhaihai   pvp 中心服务
2
  local json = require("shared.json")
e3c5cc5e   zhouhaihai   跨服竞技场over
3
  redisproxy = require("shared.redisproxy")
c779be0c   zhouhaihai   pvp 中心服务
4
  local cluster = require "skynet.cluster"
e3c5cc5e   zhouhaihai   跨服竞技场over
5
  local serverId = tonumber(skynet.getenv("servId"))
e3c5cc5e   zhouhaihai   跨服竞技场over
6
  datacenter = require "skynet.datacenter"
a5486ede   zhouhaihai   csvdata 修改为 share...
7
  csvdb = require "shared.csvdata"
c779be0c   zhouhaihai   pvp 中心服务
8
9
10
11
  require "shared.init"
  require "utils.init"
  require "RedisKeys"
  require "skynet.manager"
c779be0c   zhouhaihai   pvp 中心服务
12
13
14
  require "GlobalVar"
  
  
e3c5cc5e   zhouhaihai   跨服竞技场over
15
16
17
18
19
20
21
22
23
24
25
26
27
28
  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
c779be0c   zhouhaihai   pvp 中心服务
29
  
e3c5cc5e   zhouhaihai   跨服竞技场over
30
31
  skynet.register_protocol {
  	name = "role",
a5486ede   zhouhaihai   csvdata 修改为 share...
32
  	id = 101,
e3c5cc5e   zhouhaihai   跨服竞技场over
33
34
35
36
37
  	pack = skynet.pack,
  	unpack = skynet.unpack,
  	dispatch = function(session, address, submethod, ...)
  	end,
  }
c779be0c   zhouhaihai   pvp 中心服务
38
39
  
  
e3c5cc5e   zhouhaihai   跨服竞技场over
40
  local function rpcRole(roleId, funcName, ...)
c779be0c   zhouhaihai   pvp 中心服务
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
  	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
  
e3c5cc5e   zhouhaihai   跨服竞技场over
59
60
61
62
63
64
  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 
c779be0c   zhouhaihai   pvp 中心服务
65
  	end
e3c5cc5e   zhouhaihai   跨服竞技场over
66
67
68
69
70
71
72
73
74
  	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
c779be0c   zhouhaihai   pvp 中心服务
75
76
77
  end
  
  
e3c5cc5e   zhouhaihai   跨服竞技场over
78
79
80
81
  local CMD = {}
  
  ------------------- 角色调用 --------------------------
  
c779be0c   zhouhaihai   pvp 中心服务
82
  
e3c5cc5e   zhouhaihai   跨服竞技场over
83
84
85
86
87
88
89
  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
c779be0c   zhouhaihai   pvp 中心服务
90
  
e3c5cc5e   zhouhaihai   跨服竞技场over
91
92
  local function getDayAndTime()
  	local startTime = getStartTime()
c779be0c   zhouhaihai   pvp 中心服务
93
  	local now = skynet.timex()
e3c5cc5e   zhouhaihai   跨服竞技场over
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
  
  	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 = {}
  	if day > globalCsv.pvp_cross_server_day then
  		return MatchCache
  	else
  		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
c779be0c   zhouhaihai   pvp 中心服务
131
132
133
  			end
  		end
  	end
e3c5cc5e   zhouhaihai   跨服竞技场over
134
  	return tempMatchCache
c779be0c   zhouhaihai   pvp 中心服务
135
136
  end
  
e3c5cc5e   zhouhaihai   跨服竞技场over
137
138
139
140
141
142
143
144
145
146
147
148
149
  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
c779be0c   zhouhaihai   pvp 中心服务
150
  
e3c5cc5e   zhouhaihai   跨服竞技场over
151
152
153
154
155
156
157
158
159
  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
c779be0c   zhouhaihai   pvp 中心服务
160
  
e3c5cc5e   zhouhaihai   跨服竞技场over
161
  	return {matchInfo = hideMatchInfo(), roleInfo = hideRoleInfo()}
c779be0c   zhouhaihai   pvp 中心服务
162
163
  end
  
e3c5cc5e   zhouhaihai   跨服竞技场over
164
165
166
  function CMD.getRoleInfo()
  	if not next(MatchCache) then
  		CMD.getMatchInfo()
c779be0c   zhouhaihai   pvp 中心服务
167
  	end
e3c5cc5e   zhouhaihai   跨服竞技场over
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
  	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,
  	}
c779be0c   zhouhaihai   pvp 中心服务
193
194
  end
  
e3c5cc5e   zhouhaihai   跨服竞技场over
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
  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 = {}
c581c6e9   zhouhaihai   pvp 优化
210
  				redisproxy:del("cross:pvpInfo:bet:" .. cday)
e3c5cc5e   zhouhaihai   跨服竞技场over
211
212
213
214
215
216
217
218
219
220
221
222
223
  			end
  		end
  	end
  	if change then
  		pvpInfo:setProperties({
  			betInfo = betInfo,
  			betNum = betNum
  		})
  	end
  
  	return pvpInfo:getProperties({"betInfo", "betNum"})
  end
  
c581c6e9   zhouhaihai   pvp 优化
224
  function CMD.setBet(idx, roleId, costNum)
e3c5cc5e   zhouhaihai   跨服竞技场over
225
226
227
228
229
230
231
232
233
  	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)
c581c6e9   zhouhaihai   pvp 优化
234
235
  
  	redisproxy:hset("cross:pvpInfo:bet:" .. day, roleId, costNum * 10 + idx)
e3c5cc5e   zhouhaihai   跨服竞技场over
236
237
238
239
240
241
  	return {betNum = betNum}
  end
  
  
  -------------------中心服务器 调用----------------------
  function CMD.loadRoles(roleIds)
c779be0c   zhouhaihai   pvp 中心服务
242
243
  	roleIds = roleIds or {}
  	local infos = {}
e3c5cc5e   zhouhaihai   跨服竞技场over
244
  	RoleInfo[serverId] = RoleInfo[serverId] or {}
c779be0c   zhouhaihai   pvp 中心服务
245
246
  	for _, roleId in ipairs(roleIds) do
  		infos[roleId] = rpcRole(roleId, "pvpHInfo")
e3c5cc5e   zhouhaihai   跨服竞技场over
247
248
249
250
251
252
253
  		local temp = {}
  		for _field, _v in pairs(infos[roleId]) do
  			if _field ~= "battleInfo" then
  				temp[_field] = _v
  			end
  		end
  		RoleInfo[packRoleId(serverId, roleId)] = temp
c779be0c   zhouhaihai   pvp 中心服务
254
255
256
257
  	end
  	return infos
  end
  
e3c5cc5e   zhouhaihai   跨服竞技场over
258
  -- 新赛季了 清掉缓存
c779be0c   zhouhaihai   pvp 中心服务
259
260
261
262
263
264
265
  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
e3c5cc5e   zhouhaihai   跨服竞技场over
266
267
268
269
270
271
272
273
274
  	MatchCache = {}
  	RoleInfo = {}
  	local infos = CMD.loadRoles(roleIds)
  	pvpInfo:setProperties({
  		betInfo = {},
  		betNum = {},
  	})
  	return {roleIds = roleIds, infos = infos}
  end
c779be0c   zhouhaihai   pvp 中心服务
275
  
e3c5cc5e   zhouhaihai   跨服竞技场over
276
277
278
279
280
  -- 刷新缓存
  function CMD.refreshMatchCache(info)
  	MatchCache = info.matchInfo
  	RoleInfo = info.roleInfo
  end
c779be0c   zhouhaihai   pvp 中心服务
281
  
e3c5cc5e   zhouhaihai   跨服竞技场over
282
283
284
285
286
287
288
289
290
291
  -- 刷新 玩家数据
  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
c779be0c   zhouhaihai   pvp 中心服务
292
293
  end
  
e3c5cc5e   zhouhaihai   跨服竞技场over
294
295
  ------------------------------------------------------
  function CMD.start()
a5486ede   zhouhaihai   csvdata 修改为 share...
296
297
298
  	redisd = skynet.localname(".redis")
  	globalCsv = csvdb["GlobalDefineCsv"]
  	
e3c5cc5e   zhouhaihai   跨服竞技场over
299
300
301
302
303
304
  	pvpInfo = require("models.Pvpd").new({key = "cross:pvpInfo"})
  	pvpInfo:load()
  end
  
  ---------------------------------------------------------
  
c779be0c   zhouhaihai   pvp 中心服务
305
306
307
308
309
310
311
  local function __init__()
  	skynet.dispatch("lua", function(_, _, command, ...)
  		local f = CMD[command]
  		if f then
  			skynet.ret(skynet.pack(f(...)))
  		end
  	end)
e3c5cc5e   zhouhaihai   跨服竞技场over
312
  	
a5486ede   zhouhaihai   csvdata 修改为 share...
313
  	skynet.register(".pvpcross")
c779be0c   zhouhaihai   pvp 中心服务
314
315
316
  end
  
  skynet.start(__init__)