Blame view

src/actions/PvpAction.lua 9.03 KB
440aa055   zhouhaihai   聊天
1
2
3
4
5
  local ipairs = ipairs
  local table = table
  local math = math
  local redisproxy = redisproxy
  local MsgPack = MsgPack
4cf74232   zhouhaihai   pvp
6
7
  local httpc = require("http.httpc")
  local remoteUrl = skynet.getenv("codeurl")
440aa055   zhouhaihai   聊天
8
9
10
  
  
  local _M = {}
4cf74232   zhouhaihai   pvp
11
12
  local _pvpBattleInfoCacheC = {}  --查询列表 缓存pvp战斗相关数据缓存
  local _pvpStartBattleCache = nil -- 
440aa055   zhouhaihai   聊天
13
  
4cf74232   zhouhaihai   pvp
14
15
  local _pvpRecordInfoCache = {} -- 记录缓存
  local _pvpRecordBattleInfoCache = {} -- 记录战斗数据缓存
440aa055   zhouhaihai   聊天
16
17
18
  
  function _M.formatCommonRpc(agent , data)
  	local role = agent.role
fa565e0c   zhouhaihai   优化结构
19
  	local roleId = role:getProperty("id")
440aa055   zhouhaihai   聊天
20
  	local msg = MsgPack.unpack(data)
fa565e0c   zhouhaihai   优化结构
21
  	local pvpTC = role:getProperty("pvpTC")
440aa055   zhouhaihai   聊天
22
23
24
25
26
  	for slot, heroId in pairs(msg.heros) do
  		if not role.heros[heroId] then
  			return
  		end
  	end
fa565e0c   zhouhaihai   优化结构
27
28
  	if not next(msg.heros) then
  		return
440aa055   zhouhaihai   聊天
29
  	end
440aa055   zhouhaihai   聊天
30
  
fa565e0c   zhouhaihai   优化结构
31
32
33
34
35
36
37
38
  	table.clear(pvpTC)
  	pvpTC.heros = {}
  	for slot, heroId in pairs(msg.heros) do
  		pvpTC.heros[slot] = heroId
  	end
  	pvpTC.leader = msg.leader
  	
  	role:savePvpCTeam(pvpTC)
440aa055   zhouhaihai   聊天
39
40
41
42
  	SendPacket(actionCodes.Pvp_formatCommonRpc, '')
  	return true
  end
  
4cf74232   zhouhaihai   pvp
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
  
  local function getMatchInfo(pvpList, battleCache)
  	table.clear(battleCache)
  	local redret = redisproxy:pipelining(function(red)
  		for _, info in ipairs(pvpList) do
  			if info.t == 1 then
  				red:zscore(RANK_PVP_COMMON, info.id)
  			end
  		end
  	end)
  
  	local matches = {}
  	local curIdx = 1
  	for idx, info in ipairs(pvpList) do
  		local curInfo = {idx = idx}
  		if info.t == 1 then --玩家
  			curInfo.roleId = info.id
  			curInfo.score = tonumber(redret[curIdx] or 0)
  			curIdx = curIdx + 1
  			-- name, level, headId, battleV, heros
  			local online, roleInfo = rpcRole(curInfo.roleId, "pvpCInfo")
  			for k , v in pairs(roleInfo) do
  				if k == "battleInfo" then
  					battleCache[curInfo.roleId] = v
  				else
  					curInfo[k] = v
  				end
  			end
  		elseif info.t == 2 then  	-- robot
  			curInfo.robot = info.id
  		end
  		table.insert(matches, curInfo)
  	end
  	return matches
  end
  
  -- 获取pvp信息
  function _M.infoRpc(agent, data)
440aa055   zhouhaihai   聊天
81
  	local role = agent.role
4cf74232   zhouhaihai   pvp
82
  	local roleId = role:getProperty("id")
440aa055   zhouhaihai   聊天
83
  	local msg = MsgPack.unpack(data)
4cf74232   zhouhaihai   pvp
84
  	local ptype = msg.ptype or 1
440aa055   zhouhaihai   聊天
85
  
4cf74232   zhouhaihai   pvp
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
  	local response = {}
  	if ptype == 1 then -- 普通pvp
  		local redret = redisproxy:pipelining(function(red)
  			red:zscore(RANK_PVP_COMMON, roleId)
  			red:zrevrank(RANK_PVP_COMMON, roleId)
  		end)
  		local score = tonumber(redret[1] or 0)
  		local rank = tonumber(redret[2] or -2) + 1  --排名 1 - ...  -1 未上榜 没打过pvp
  		local pvpMC = role:getProperty("pvpMC")
  		if not next(pvpMC) then --没有分配过对手
  			role:refreshPvpMatchC(score)
  			pvpMC = role:getProperty("pvpMC")
  		end
  		if not next(pvpMC) then return end
  		
  		response.score = score
  		response.rank = rank
  		response.matches = getMatchInfo(pvpMC, _pvpBattleInfoCacheC)
440aa055   zhouhaihai   聊天
104
  
4cf74232   zhouhaihai   pvp
105
106
107
108
109
110
  	elseif ptype == 2 then -- 高级pvp
  		return
  	else
  		return
  	end
  	SendPacket(actionCodes.Pvp_infoRpc, MsgPack.pack(response))
440aa055   zhouhaihai   聊天
111
112
113
  	return true
  end
  
4cf74232   zhouhaihai   pvp
114
  function _M.refreshMatchCRpc(agent, data)
440aa055   zhouhaihai   聊天
115
116
  	local role = agent.role
  	local msg = MsgPack.unpack(data)
4cf74232   zhouhaihai   pvp
117
118
119
120
  	role:refreshPvpMatchC()
  
  	local pvpMC = role:getProperty("pvpMC")
  	local matches = getMatchInfo(pvpMC, _pvpBattleInfoCacheC)
440aa055   zhouhaihai   聊天
121
  
4cf74232   zhouhaihai   pvp
122
  	SendPacket(actionCodes.Pvp_refreshMatchCRpc, MsgPack.pack({matches = matches}))
440aa055   zhouhaihai   聊天
123
124
125
126
127
128
  	return true
  end
  
  function _M.buyCountRpc(agent, data)
  	local role = agent.role
  	local msg = MsgPack.unpack(data)
4cf74232   zhouhaihai   pvp
129
  	local count = msg.count
440aa055   zhouhaihai   聊天
130
  
4cf74232   zhouhaihai   pvp
131
132
133
134
135
136
137
138
  	if math.illegalNum(count, 1, math.huge) then
  		return 1
  	end
  
  	local cost = {[ItemId.Diamond] = globalCsv.pvp_buy_cost * count}
  	if not role:checkItemEnough(cost) then return 2 end
  	role:costItems(cost)
  	role:award({[ItemId.PvpKey] = count})
440aa055   zhouhaihai   聊天
139
140
141
142
143
144
  
  	SendPacket(actionCodes.Pvp_buyCountRpc, '')
  	return true
  end
  
  function _M.startBattleRpc(agent, data)
4cf74232   zhouhaihai   pvp
145
146
  	local role = agent.role
  	local msg = MsgPack.unpack(data)
440aa055   zhouhaihai   聊天
147
  
4cf74232   zhouhaihai   pvp
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
  	local idx = msg.idx
  	local revenge = msg.revenge
  
  	local matchInfo
  
  	if revenge then  --复仇
  		if not _pvpRecordInfoCache[idx] then return end
  		if _pvpRecordInfoCache[idx].t == 1 then
  			matchInfo = _pvpRecordBattleInfoCache[_pvpRecordInfoCache[idx].id]
  		elseif _pvpRecordInfoCache[idx].t == 2 then
  			matchInfo = {robot = _pvpRecordInfoCache[idx].id}
  		end
  	else  --打正常
  		local pvpMC = role:getProperty("pvpMC")
  		if not pvpMC[idx] then return end
  		if pvpMC[idx].t == 1 then
  			matchInfo = _pvpBattleInfoCacheC[pvpMC[idx].id]
  		elseif pvpMC[idx].t == 2 then
  			matchInfo = {robot = pvpMC[idx].id}
  		end
  	end
  
  	if not matchInfo then return end
  
  	-- 次数扣一波
  	local pvpFree = role.dailyData:getProperty("pvpFree")
  	if pvpFree >= globalCsv.pvp_battle_free_count then
  		local cost = {[ItemId.PvpKey] = 1}
  		if not role:checkItemEnough(cost) then return end
  		role:costItems(cost)
  	else
  		role.dailyData:updateProperty({field = "pvpFree", delta = 1})
  	end
  
  	local key = tostring(math.random())
  	_pvpStartBattleCache = {idx = idx, key = key, revenge = revenge}
  
  	SendPacket(actionCodes.Pvp_startBattleRpc, MsgPack.pack({matchInfo = matchInfo, key = key}))
  	return true
440aa055   zhouhaihai   聊天
187
188
189
  end
  
  function _M.endBattleRpc(agent, data)
4cf74232   zhouhaihai   pvp
190
191
192
  	local role = agent.role
  	local roleId = role:getProperty("id")
  	local msg = MsgPack.unpack(data)
440aa055   zhouhaihai   聊天
193
  
4cf74232   zhouhaihai   pvp
194
195
196
197
198
199
  	if not msg.key or not _pvpStartBattleCache or msg.key ~= _pvpStartBattleCache.key then 
  		return 1
  	end
  	if not msg.idx or not msg.idx ~= _pvpStartBattleCache.idx then
  		return 2
  	end
440aa055   zhouhaihai   聊天
200
  
4cf74232   zhouhaihai   pvp
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
  	local isWin = msg.starNum and msg.starNum > 0
  
  	local revenge = _pvpStartBattleCache.revenge
  	local match
  	if revenge then
  		match = _pvpRecordInfoCache[msg.idx]
  	else
  		local pvpMC = role:getProperty("pvpMC")
  		match = pvpMC[msg.idx]
  	end
  	
  	if not match then return end
  
  	local temp = string.randWeight(csvdb["player_expCsv"][role:getProperty("level")].pvpBonus, true)
  	local reward = role:award({[temp[1]] = temp[2]})
  	local myScore, matchScore, oldmyScore, oldMatchScore, myRank, oldMyRank = role:changePvpScoreCommon(match.t == 1 and match.id or -1, isWin)
  
  	_pvpBattleInfoCacheC = {}  --重新发阵容了 没毛病
  	_pvpRecordInfoCache = {} -- 记录刷新了
  	_pvpRecordBattleInfoCache = {} -- 取新纪录的时候搞
  	_pvpStartBattleCache = nil
  
  	-- 请求上传录像
  	local now = skynet.timex()
  	local params = {
  		["roleid"] = roleId,
  		["key"] = "zhaolugame20191016",
  		["time"] = now,
  	}
  	local status, body = httpc.get(remoteUrl, "/applyvideo?" .. httpGetFormatData(params), {}, {})
  	local video = nil
  	if tonumber(status) == 200 then
  		local result = json.decode(body)
  		video = result.name
  	else
  		skynet.error("applyvideo", "error", status, body, content)
  	end
  
  	-- 加入战斗记录
  	redisproxy:pipelining(function(red)
  		local dbKey = string.format(RECORD_PVP_COMMON, roleId)
  		red:lpush(dbKey, MsgPack.pack({
  			id = match.id,
  			t = match.t,
  			win = isWin,
  			time = now,
  			video = video,
  			sdelta = myScore - oldmyScore,
  		}))
  		red:trim(dbKey, 0, 9)
  		-- 对方加入战斗记录
  		if match.t == 1 then
  			dbKey = string.format(RECORD_PVP_COMMON, match.id)
  			red:lpush(dbKey, MsgPack.pack({
  				id = roleId,
  				t = 1,
  				win = not isWin,
  				time = now,
  				video = video,
  				sdelta = matchScore - oldMatchScore,
  			}))
  			red:trim(dbKey, 0, 9)
  		end
  	end)
440aa055   zhouhaihai   聊天
265
  	
4cf74232   zhouhaihai   pvp
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
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
  	SendPacket(actionCodes.Pvp_endBattleRpc, MsgPack.pack({
  		reward = reward,
  		myScore = myScore,
  		matchScore = matchScore,
  		oldmyScore = oldmyScore,
  		oldMatchScore = oldMatchScore,
  		myRank = myRank,
  		oldMyRank = oldMyRank,
  		video = video,
  	}))
  	return true
  end
  
  function _M.rankListRpc(agent, data)
  	local role = agent.role
  	local roleId = role:getProperty("id")
  	local ptype = msg.ptype or 1
  
  	local response = {}
  	if ptype == 1 then -- 普通pvp
  		local redret = redisproxy:pipelining(function(red)
  			red:zscore(RANK_PVP_COMMON, roleId)
  			red:zrevrank(RANK_PVP_COMMON, roleId)
  			red:zrevrange(RANK_PVP_COMMON, 0, 99, "WITHSCORES")
  		end)
  		local score = tonumber(redret[1] or 0)
  		local rank = tonumber(redret[2] or -2) + 1  --排名 1 - ...  -1 未上榜 没打过pvp
  
  		local rankList = {}
  		for i = 1, #redret[3], 2 do
  			local roleId = tonumber(redret[i])
  			local score = tonumber(redret[i + 1])
  			local online, curInfo = rpcRole(roleId, "friendSInfo")
  			curInfo.score = score
  			curInfo.roleId = roleId
  			table.insert(rankList, curInfo)
  		end
  		
  		response.score = score
  		response.rank = rank
  		response.rankList = rankList
  
  	elseif ptype == 2 then -- 高级pvp
  		return
  	else
  		return
  	end
  	SendPacket(actionCodes.Pvp_rankListRpc, MsgPack.pack(response))
  	return true
  end
  
  function _M.recordListRpc(agent, data)
  	local role = agent.role
  	local roleId = role:getProperty("id")
  	local ptype = msg.ptype or 1
  
  	local recordList = {}
  	local now = skynet.timex()
  	if ptype == 1 then -- 普通pvp
  		local rlist = redisproxy:lrange(string.format(RECORD_PVP_COMMON, roleId), 0 , 9)
  		local tempList = {}
  		for _, temp in ipairs(rlist) do
  			local one = MsgPack.unpack(temp)
  			if now - one.time <= 24 * 3600 then -- 大于一天的弃之
  				table.insert(tempList, one)
  			end
  		end
  		_pvpRecordInfoCache = tempList
  
  		recordList = getMatchInfo(tempList, _pvpRecordBattleInfoCache)
  		for idx, info in ipairs(recordList) do
  			local temp = tempList[idx]
  			info.win = temp.win
  			info.time = temp.time
  			info.video = temp.video
  			info.sdelta = temp.sdelta
  		end
  		
  	elseif ptype == 2 then -- 高级pvp
  		return
  	else
  		return
  	end
  	SendPacket(actionCodes.Pvp_recordListRpc, MsgPack.pack({list = recordList}))
  	return true
440aa055   zhouhaihai   聊天
351
352
353
  end
  
  return _M