local Deque = class("Deque")
function Deque:ctor() end
function Deque:size() end
function Deque:isEmpty() end
function Deque:clear() end
function Deque:pushFront(item) end
function Deque:pushBack(item) end
function Deque:popFront() end
function Deque
根据参考代码中的网络通信和数据结构模式,可以基于双端队列实现一个服务器端的双人战斗匹配系统。匹配类需要管理等待队列、处理匹配逻辑,并与客户端进行消息通信。
```lua
-- BattleMatchService.lua
local Deque = require("Deque")
local BattleMatchService = class("BattleMatchService")
function BattleMatchService:ctor()
self._waitingQueue = Deque.new() -- 等待匹配队列
self._matchedPairs = {} -- 已匹配对
self._playerData = {} -- 玩家数据缓存
self._matchTimeout = 30 -- 匹配超时时间(秒)
end
-- 玩家进入匹配队列
function BattleMatchService:EnterMatch(playerId, playerData)
if self._playerData[playerId] then
return false, "已在匹配队列中"
end
-- 存储玩家数据
self._playerData[playerId] = {
id = playerId,
data = playerData,
enterTime = os.time(),
status = "waiting"
}
-- 加入等待队列
self._waitingQueue:pushBack(playerId)
-- 尝试立即匹配
self:_tryMatch()
-- 通知客户端匹配开始(参考资料12中的消息发送模式)
self:_sendToClient(playerId, 90020101, 1, 1, nil, "匹配开始")
return true
end
-- 玩家取消匹配
function BattleMatchService:CancelMatch(playerId)
if not self._playerData[playerId] then
return false, "不在匹配队列中"
end
-- 从等待队列中移除
local queue = self._waitingQueue:toArray()
for i, id in ipairs(queue) do
if id == playerId then
-- 需要实现Deque的删除功能,这里简化处理
self:_removeFromQueue(playerId)
break
end
end
-- 清理玩家数据
self._playerData[playerId] = nil
-- 通知客户端
self:_sendToClient(playerId, 90020101, 0, 0, nil, "匹配取消")
return true
end
-- 尝试匹配玩家
function BattleMatchService:_tryMatch()
while self._waitingQueue:size() >= 2 do
local player1 = self._waitingQueue:popFront()
local player2 = self._waitingQueue:popFront()
if player1 and player2 then
-- 创建匹配对
local matchId = self:_generateMatchId()
self._matchedPairs[matchId] = {
player1 = player1,
player2 = player2,
matchTime = os.time()
}
-- 更新玩家状态
self._playerData[player1].status = "matched"
self._playerData[player2].status = "matched"
-- 通知双方匹配成功(参考资料12的客户端消息模式)
self:_sendToClient(player1, 90020101, 2, matchId, nil, "匹配成功")
self:_sendToClient(player2, 90020101, 2, matchId, nil, "匹配成功")
-- 触发战斗开始逻辑
self:_startBattle(matchId, player1, player2)
end
end
end
-- 生成匹配ID
function BattleMatchService:_generateMatchId()
return "match_" .. tostring(os.time()) .. "_" .. tostring(math.random(1000, 9999))
end
-- 从队列中移除玩家
function BattleMatchService:_removeFromQueue(playerId)
local tempQueue = Deque.new()
while not self._waitingQueue:isEmpty() do
local id = self._waitingQueue:popFront()
if id ~= playerId then
tempQueue:pushBack(id)
end
end
-- 恢复队列
while not tempQueue:isEmpty() do
self._waitingQueue:pushBack(tempQueue:popFront())
end
end
-- 发送消息到客户端(参考资料12的服务端消息发送)
function BattleMatchService:_sendToClient(actor, msgID, param1, param2, param3, str)
-- 这里使用引擎提供的sendmymsg函数
-- sendmymsg(actor, msgID, param1, param2, param3, str)
-- 在实际实现中,这里会调用引擎的消息发送接口
-- 如:sendmymsg(actor, msgID, param1, param2, param3, str)
-- 示例日志
print(string.format("发送消息到玩家%s: msgID=%d, param1=%d, param2=%d, str=%s",
actor, msgID, param1, param2, str or ""))
end
-- 开始战斗
function BattleMatchService:_startBattle(matchId, player1, player2)
-- 这里实现战斗初始化逻辑
-- 可以设置战斗场景、初始化玩家状态等
-- 通知客户端进入战斗(参考资料9中的消息处理模式)
local battleData = {
matchId = matchId,
opponent1 = self._playerData[player1].data,
opponent2 = self._playerData[player2].data
}
-- 清理匹配数据
self._playerData[player1] = nil
self._playerData[player2] = nil
-- 这里可以添加战斗开始的业务逻辑
print(string.format("战斗开始: matchId=%s, player1=%s, player2=%s",
matchId, player1, player2))
end
-- 定时清理超时匹配
function BattleMatchService:CleanupTimeoutMatches()
local currentTime = os.time()
local timeoutPlayers = {}
-- 检查等待队列中的超时玩家
local queue = self._waitingQueue:toArray()
for _, playerId in ipairs(queue) do
local player = self._playerData[playerId]
if player and (currentTime - player.enterTime) > self._matchTimeout then
table.insert(timeoutPlayers, playerId)
end
end
-- 移除超时玩家并通知
for _, playerId in ipairs(timeoutPlayers) do
self:CancelMatch(playerId)
self:_sendToClient(playerId, 90020101, 0, 0, nil, "匹配超时")
end
return #timeoutPlayers
end
-- 获取匹配状态
function BattleMatchService:GetMatchStatus(playerId)
local player = self._playerData[playerId]
if not player then
return "not_in_queue"
end
return {
status = player.status,
waitTime = os.time() - player.enterTime,
queueSize = self._waitingQueue:size()
}
end
-- 获取等待队列大小
function BattleMatchService:GetQueueSize()
return self._waitingQueue:size()
end
-- 清空所有匹配数据
function BattleMatchService:ClearAll()
self._waitingQueue:clear()
self._matchedPairs = {}
self._playerData = {}
end
return BattleMatchService
```
这个匹配类实现了以下核心功能:
1. **队列管理**:使用双端队列管理等待匹配的玩家,支持FIFO匹配策略
2. **匹配逻辑**:当队列中有至少2名玩家时,自动进行匹配
3. **消息通信**:参考资料12中的客户端-服务端消息模式,通知玩家匹配状态
4. **超时处理**:自动清理超时未匹配的玩家
5. **状态管理**:跟踪每个玩家的匹配状态和等待时间
使用方式:
```lua
local BattleMatchService = require("BattleMatchService")
local matchService = BattleMatchService.new()
-- 玩家进入匹配
matchService:EnterMatch("player_001", {level=50, power=1000})
-- 定时清理(可在服务器定时器中调用)
matchService:CleanupTimeoutMatches()
-- 获取队列状态
local size = matchService:GetQueueSize()
```
这个实现参考了热血江湖项目中的网络通信模式和数据管理方式,可以集成到现有的游戏服务器架构中。