ludo-重构匹配逻辑

This commit is contained in:
2025-04-14 01:57:15 +08:00
committed by khalil
parent bf8f9a71f9
commit 653f88f9c4
19 changed files with 461 additions and 412 deletions

View File

@@ -1302,10 +1302,8 @@ public enum RedisKey {
//游戏匹配 //游戏匹配
mini_game_match_wait, mini_game_match_wait,
mini_game_match_round, mini_game_match_round,
//游戏匹配开始 //游戏匹配锁
mini_game_match_round_start_lock, mini_game_match_round_lock,
//游戏匹配关闭锁
mini_game_match_round_close_lock,
//已使用 //已使用
chat_room, chat_room,

View File

@@ -0,0 +1,11 @@
package com.accompany.business.message;
import com.accompany.business.model.miniGame.MiniGameMatchRound;
import lombok.Data;
@Data
public class MiniGameMatchRoundMessage extends BaseMessage {
private MiniGameMatchRound round;
}

View File

@@ -12,8 +12,8 @@ import com.accompany.business.event.MiniGameSettlementEvent;
import com.accompany.business.model.chat.ChatRoom; import com.accompany.business.model.chat.ChatRoom;
import com.accompany.business.model.miniGame.MiniGameMatch; import com.accompany.business.model.miniGame.MiniGameMatch;
import com.accompany.business.model.miniGame.MiniGameMatchRound; import com.accompany.business.model.miniGame.MiniGameMatchRound;
import com.accompany.business.service.SendSysMsgService;
import com.accompany.business.service.chat.ChatRoomService; import com.accompany.business.service.chat.ChatRoomService;
import com.accompany.business.service.miniGame.MiniGameForNavService;
import com.accompany.business.service.miniGame.MiniGameForSudService; import com.accompany.business.service.miniGame.MiniGameForSudService;
import com.accompany.business.service.miniGame.MiniGameMatchRoundService; import com.accompany.business.service.miniGame.MiniGameMatchRoundService;
import com.accompany.business.service.miniGame.MiniGameMatchService; import com.accompany.business.service.miniGame.MiniGameMatchService;
@@ -21,17 +21,14 @@ import com.accompany.business.service.purse.UserPurseService;
import com.accompany.business.service.rank.IRank; import com.accompany.business.service.rank.IRank;
import com.accompany.business.service.rank.RankServiceFactory; import com.accompany.business.service.rank.RankServiceFactory;
import com.accompany.business.service.record.BillRecordService; import com.accompany.business.service.record.BillRecordService;
import com.accompany.common.constant.Constant;
import com.accompany.common.netease.ErBanNetEaseService; import com.accompany.common.netease.ErBanNetEaseService;
import com.accompany.common.redis.RedisKey; import com.accompany.common.redis.RedisKey;
import com.accompany.common.utils.GsonUtil; import com.accompany.common.utils.GsonUtil;
import com.accompany.core.enumeration.BillObjTypeEnum; import com.accompany.core.enumeration.BillObjTypeEnum;
import com.accompany.core.model.Users; import com.accompany.core.model.Users;
import com.accompany.core.service.SysConfService;
import com.accompany.core.service.common.JedisService;
import com.accompany.core.service.user.UsersBaseService; import com.accompany.core.service.user.UsersBaseService;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RMap;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener; import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@@ -53,15 +50,15 @@ public class MiniGameForNavSettleListener implements ApplicationListener<MiniGam
private static final int WINNER_STATUS = 2; private static final int WINNER_STATUS = 2;
@Autowired
private MiniGameForNavService miniGameForNavService;
@Autowired @Autowired
private MiniGameMatchService miniGameMatchService; private MiniGameMatchService miniGameMatchService;
@Autowired @Autowired
private MiniGameMatchRoundService miniGameMatchRoundService; private MiniGameMatchRoundService miniGameMatchRoundService;
@Autowired
private SysConfService sysConfService;
@Autowired @Autowired
private UsersBaseService usersBaseService; private UsersBaseService usersBaseService;
@@ -74,18 +71,12 @@ public class MiniGameForNavSettleListener implements ApplicationListener<MiniGam
@Autowired @Autowired
private ChatRoomService chatRoomService; private ChatRoomService chatRoomService;
@Autowired
private SendSysMsgService sendSysMsgService;
@Autowired @Autowired
private ErBanNetEaseService erBanNetEaseService; private ErBanNetEaseService erBanNetEaseService;
@Autowired @Autowired
private MiniGameForSudService miniGameForSudService; private MiniGameForSudService miniGameForSudService;
@Autowired
private JedisService jedisService;
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
@Override @Override
public void onApplicationEvent(MiniGameSettlementEvent event) { public void onApplicationEvent(MiniGameSettlementEvent event) {
@@ -100,36 +91,19 @@ public class MiniGameForNavSettleListener implements ApplicationListener<MiniGam
return; return;
} }
Long roomId = Long.valueOf(roomIdStr); Long roomId = Long.valueOf(roomIdStr);
String roundStr = jedisService.get(RedisKey.mini_game_match_round.getKey(String.valueOf(roomId)));
if (StrUtil.isEmpty(roundStr)) { RMap<Long, Long> roundCacheMap = miniGameMatchRoundService.getMatchRoundMap();
Long roundId = roundCacheMap.remove(roomId);
if (null == roundId){
return; return;
} }
String[] roundArray = roundStr.split(StrUtil.UNDERLINE);
Long matchRoundId = Long.valueOf(roundArray[2]); MiniGameMatchRound miniGameMatchRound = miniGameMatchRoundService.getById(roundId);
List<MiniGameMatchRound> miniGameMatchRounds = miniGameMatchRoundService.list(Wrappers.<MiniGameMatchRound>lambdaQuery() if (null == miniGameMatchRound || miniGameMatchRound.getRoundStatus() != NavGameRoundStatusEnum.PROCESS.ordinal()){
.eq(MiniGameMatchRound::getId, matchRoundId)
.eq(MiniGameMatchRound::getRoundStatus, NavGameRoundStatusEnum.PROCESS.ordinal()));
if (CollectionUtil.isEmpty(miniGameMatchRounds)) {
return;
}
MiniGameMatchRound miniGameMatchRound = miniGameMatchRounds.get(0);
Long fromMatchId = miniGameMatchRound.getFromMatchId();
Long toMatchId = miniGameMatchRound.getToMatchId();
MiniGameMatch fromMiniGameMatch = miniGameMatchService.getById(fromMatchId);
if (fromMiniGameMatch == null) {
return;
}
MiniGameMatch toMiniGameMatch = miniGameMatchService.getById(toMatchId);
if (toMiniGameMatch == null) {
return;
}
if (fromMiniGameMatch.getMatchStatus() == NavGameMatchStatusEnum.FINISH.ordinal() || toMiniGameMatch.getMatchStatus() == NavGameMatchStatusEnum.FINISH.ordinal()) {
return;
}
MiniGameForNavConfigDto config = sysConfService.getJsonValueById(Constant.SysConfId.MINI_GAME_FOR_NAV, MiniGameForNavConfigDto.class);
if (config == null) {
return; return;
} }
MiniGameForNavConfigDto config = miniGameForNavService.getConfigDto();
String mgId = config.getMgId(); String mgId = config.getMgId();
if (!gameEndDto.getMg_id_str().equals(mgId)) { if (!gameEndDto.getMg_id_str().equals(mgId)) {
log.info("config mgId : {}, game end mgId : {}", mgId, gameEndDto.getMg_id_str()); log.info("config mgId : {}, game end mgId : {}", mgId, gameEndDto.getMg_id_str());
@@ -154,9 +128,11 @@ public class MiniGameForNavSettleListener implements ApplicationListener<MiniGam
miniGameMatchRound.setWinUid(winUid); miniGameMatchRound.setWinUid(winUid);
miniGameMatchRound.setWinNum(winner); miniGameMatchRound.setWinNum(winner);
miniGameMatchRound.setPlatformNum(platform); miniGameMatchRound.setPlatformNum(platform);
userPurseService.addDiamond(winUid, winner, BillObjTypeEnum.MINI_GAME_MATCH_WINNER_IN, userPurseService.addDiamond(winUid, winner, BillObjTypeEnum.MINI_GAME_MATCH_WINNER_IN,
(userPurse -> billRecordService.insertGeneralBillRecord(userPurse.getUid(), miniGameMatchRound.getId().toString(), (userPurse -> billRecordService.insertGeneralBillRecord(userPurse.getUid(), miniGameMatchRound.getId().toString(),
BillObjTypeEnum.MINI_GAME_MATCH_WINNER_IN, winner, userPurse))); BillObjTypeEnum.MINI_GAME_MATCH_WINNER_IN, winner, userPurse)));
//榜单 //榜单
Map<String, IRank> rankMap = RankServiceFactory.getServiceByType(RedisKey.mini_game_rank.name()); Map<String, IRank> rankMap = RankServiceFactory.getServiceByType(RedisKey.mini_game_rank.name());
if (CollectionUtil.isNotEmpty(rankMap)) { if (CollectionUtil.isNotEmpty(rankMap)) {
@@ -167,23 +143,30 @@ public class MiniGameForNavSettleListener implements ApplicationListener<MiniGam
} }
} }
} }
//更新匹配 //更新匹配
miniGameMatchRound.setRoundStatus(NavGameRoundStatusEnum.END.ordinal()); miniGameMatchRound.setRoundStatus(NavGameRoundStatusEnum.END.ordinal());
miniGameMatchRoundService.updateById(miniGameMatchRound); miniGameMatchRoundService.updateById(miniGameMatchRound);
fromMiniGameMatch.setMatchStatus(NavGameMatchStatusEnum.FINISH.ordinal());
miniGameMatchService.updateById(fromMiniGameMatch); Long fromMatchId = miniGameMatchRound.getFromMatchId();
toMiniGameMatch.setMatchStatus(NavGameMatchStatusEnum.FINISH.ordinal()); Long toMatchId = miniGameMatchRound.getToMatchId();
miniGameMatchService.updateById(toMiniGameMatch); miniGameMatchService.lambdaUpdate()
.set(MiniGameMatch::getMatchStatus, NavGameMatchStatusEnum.FINISH.ordinal())
.in(MiniGameMatch::getId, fromMatchId, toMatchId)
.eq(MiniGameMatch::getMatchStatus, NavGameMatchStatusEnum.SUCCESS.ordinal())
.update();
//释放房间 //释放房间
chatRoomService.releaseByRoomId(miniGameMatchRound.getRoomId()); chatRoomService.releaseByRoomId(miniGameMatchRound.getRoomId());
ChatRoom chatRoom = chatRoomService.getByRoomId(miniGameMatchRound.getRoomId()); ChatRoom chatRoom = chatRoomService.getByRoomId(miniGameMatchRound.getRoomId());
if (chatRoom != null) { if (chatRoom != null) {
jedisService.del(RedisKey.room_mic_list.getKey(String.valueOf(chatRoom.getChatRoomId())));
//房间踢人 //房间踢人
erBanNetEaseService.kickMember(String.valueOf(chatRoom.getRoomId()), String.valueOf(fromMiniGameMatch.getUid()), String.valueOf(chatRoom.getChatRoomId()), null); erBanNetEaseService.kickMember(String.valueOf(chatRoom.getRoomId()), String.valueOf(miniGameMatchRound.getFromUid()), String.valueOf(chatRoom.getChatRoomId()), null);
erBanNetEaseService.kickMember(String.valueOf(chatRoom.getRoomId()), String.valueOf(toMiniGameMatch.getUid()), String.valueOf(chatRoom.getChatRoomId()), null); erBanNetEaseService.kickMember(String.valueOf(chatRoom.getRoomId()), String.valueOf(miniGameMatchRound.getToUid()), String.valueOf(chatRoom.getChatRoomId()), null);
//房间清理 //房间清理
miniGameForSudService.pushRoomClearEvent(fromMiniGameMatch.getMgId(), chatRoom.getRoomId()); miniGameForSudService.pushRoomClearEvent(mgId, chatRoom.getRoomId());
} }
} }
} }

View File

@@ -1,17 +1,13 @@
package com.accompany.business.event.listener.miniGame; package com.accompany.business.event.listener.miniGame;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.accompany.business.dto.miniGame.GameStartDto; import com.accompany.business.dto.miniGame.GameStartDto;
import com.accompany.business.enums.game.NavGameRoundStatusEnum;
import com.accompany.business.event.MiniGameStartEvent; import com.accompany.business.event.MiniGameStartEvent;
import com.accompany.business.model.miniGame.MiniGameMatchRound; import com.accompany.business.model.miniGame.MiniGameMatchRound;
import com.accompany.business.service.miniGame.MiniGameMatchRoundService; import com.accompany.business.service.miniGame.MiniGameMatchRoundService;
import com.accompany.common.redis.RedisKey;
import com.accompany.common.utils.GsonUtil; import com.accompany.common.utils.GsonUtil;
import com.accompany.core.service.common.JedisService;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RMap;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener; import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@@ -30,10 +26,6 @@ public class MiniGameForNavStartListener implements ApplicationListener<MiniGame
@Autowired @Autowired
private MiniGameMatchRoundService miniGameMatchRoundService; private MiniGameMatchRoundService miniGameMatchRoundService;
@Autowired
private JedisService jedisService;
@Override @Override
public void onApplicationEvent(MiniGameStartEvent event) { public void onApplicationEvent(MiniGameStartEvent event) {
Object source = event.getSource(); Object source = event.getSource();
@@ -47,19 +39,14 @@ public class MiniGameForNavStartListener implements ApplicationListener<MiniGame
return; return;
} }
Long roomId = Long.valueOf(roomIdStr); Long roomId = Long.valueOf(roomIdStr);
String roundStr = jedisService.get(RedisKey.mini_game_match_round.getKey(String.valueOf(roomId)));
if (StrUtil.isEmpty(roundStr)) { RMap<Long, Long> roundCacheMap = miniGameMatchRoundService.getMatchRoundMap();
Long roundId = roundCacheMap.get(roomId);
if (null == roundId){
return; return;
} }
String[] roundArray = roundStr.split(StrUtil.UNDERLINE);
Long matchRoundId = Long.valueOf(roundArray[2]); MiniGameMatchRound miniGameMatchRound = miniGameMatchRoundService.getById(roundId);
List<MiniGameMatchRound> miniGameMatchRounds = miniGameMatchRoundService.list(Wrappers.<MiniGameMatchRound>lambdaQuery()
.eq(MiniGameMatchRound::getId, matchRoundId)
.eq(MiniGameMatchRound::getRoundStatus, NavGameRoundStatusEnum.PROCESS.ordinal()));
if (CollectionUtil.isEmpty(miniGameMatchRounds)) {
return;
}
MiniGameMatchRound miniGameMatchRound = miniGameMatchRounds.get(0);
miniGameMatchRound.setGameRoundId(gameStartDto.getGame_round_id()); miniGameMatchRound.setGameRoundId(gameStartDto.getGame_round_id());
miniGameMatchRoundService.updateById(miniGameMatchRound); miniGameMatchRoundService.updateById(miniGameMatchRound);
} }

View File

@@ -10,10 +10,6 @@ import com.baomidou.mybatisplus.extension.service.IService;
*/ */
public interface ChatRoomService extends IService<ChatRoom> { public interface ChatRoomService extends IService<ChatRoom> {
default ChatRoom getOrOpen(Long uid, Integer roomType) {
return getOrOpen(null, uid, roomType);
}
/** /**
* 获取/开启聊天室 * 获取/开启聊天室
* @param roomId * @param roomId
@@ -23,11 +19,7 @@ public interface ChatRoomService extends IService<ChatRoom> {
*/ */
ChatRoom getOrOpen(Long roomId, Long uid, Integer roomType); ChatRoom getOrOpen(Long roomId, Long uid, Integer roomType);
/** ChatRoom getRoomByUid(Long uid);
* 释放聊天室
* @param uid
*/
void releaseByUid(Long uid);
/** /**
* 释放聊天室 * 释放聊天室

View File

@@ -18,6 +18,8 @@ public interface IChatRoom {
*/ */
ChatRoomTypeEnum roomType(); ChatRoomTypeEnum roomType();
ChatRoom getRoomByUid(Long uid);
/** /**
* 获取扩展属性 * 获取扩展属性
* @param chatRoom * @param chatRoom
@@ -31,13 +33,6 @@ public interface IChatRoom {
*/ */
Integer[] wheatBit(); Integer[] wheatBit();
/**
* 获取房间ID
* @param uid
* @return
*/
Long getRoomIdByUid(Long uid);
/** /**
* 初始化 * 初始化
* @param chatRoom * @param chatRoom

View File

@@ -5,10 +5,10 @@ import cn.hutool.core.util.StrUtil;
import com.accompany.business.dto.chat.ChatRoomForMiniGameDto; import com.accompany.business.dto.chat.ChatRoomForMiniGameDto;
import com.accompany.business.dto.miniGame.GameModeDto; import com.accompany.business.dto.miniGame.GameModeDto;
import com.accompany.business.dto.miniGame.MiniGameForNavConfigDto; import com.accompany.business.dto.miniGame.MiniGameForNavConfigDto;
import com.accompany.business.dto.miniGame.MiniGameMatchRoundDto;
import com.accompany.business.enums.chat.ChatRoomTypeEnum; import com.accompany.business.enums.chat.ChatRoomTypeEnum;
import com.accompany.business.enums.game.NavGameMatchStatusEnum; import com.accompany.business.enums.game.NavGameMatchStatusEnum;
import com.accompany.business.enums.game.NavGameRoundStatusEnum; import com.accompany.business.enums.game.NavGameRoundStatusEnum;
import com.accompany.business.message.MiniGameMatchRoundMessage;
import com.accompany.business.model.chat.ChatRoom; import com.accompany.business.model.chat.ChatRoom;
import com.accompany.business.model.miniGame.MiniGame; import com.accompany.business.model.miniGame.MiniGame;
import com.accompany.business.model.miniGame.MiniGameMatch; import com.accompany.business.model.miniGame.MiniGameMatch;
@@ -20,6 +20,7 @@ import com.accompany.business.service.miniGame.MiniGameForNavService;
import com.accompany.business.service.miniGame.MiniGameMatchRoundService; import com.accompany.business.service.miniGame.MiniGameMatchRoundService;
import com.accompany.business.service.miniGame.MiniGameMatchService; import com.accompany.business.service.miniGame.MiniGameMatchService;
import com.accompany.business.service.miniGame.MiniGameService; import com.accompany.business.service.miniGame.MiniGameService;
import com.accompany.business.service.mq.RocketMQService;
import com.accompany.business.vo.chat.ChatRoomVo; import com.accompany.business.vo.chat.ChatRoomVo;
import com.accompany.common.constant.Constant; import com.accompany.common.constant.Constant;
import com.accompany.common.redis.RedisKey; import com.accompany.common.redis.RedisKey;
@@ -30,14 +31,12 @@ import com.accompany.core.service.common.JedisService;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RMap;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.*; import java.util.*;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/** /**
* @author: liaozetao * @author: liaozetao
@@ -72,14 +71,26 @@ public class ChatRoomForMiniGameService implements IChatRoom {
@Autowired @Autowired
private SendSysMsgService sendSysMsgService; private SendSysMsgService sendSysMsgService;
@Resource(name = "bizExecutor") @Autowired
private ThreadPoolExecutor bizExecutor; private RocketMQService rocketMQService;
@Override @Override
public ChatRoomTypeEnum roomType() { public ChatRoomTypeEnum roomType() {
return ChatRoomTypeEnum.MINI_GAME; return ChatRoomTypeEnum.MINI_GAME;
} }
@Override
public ChatRoom getRoomByUid(Long uid) {
MiniGameMatch miniGameMatch = miniGameMatchService.getOne(Wrappers.<MiniGameMatch>lambdaQuery()
.eq(MiniGameMatch::getUid, uid)
.notIn(MiniGameMatch::getMatchStatus, NavGameMatchStatusEnum.FINISH.ordinal(), NavGameMatchStatusEnum.FAIL.ordinal())
.orderByDesc(MiniGameMatch::getId), false);
if (null == miniGameMatch){
return null;
}
return chatRoomService.getRoomByUid(uid);
}
@Override @Override
public Map<String, Object> getExtraData(ChatRoom chatRoom) { public Map<String, Object> getExtraData(ChatRoom chatRoom) {
Long chatRoomId = chatRoom.getChatRoomId(); Long chatRoomId = chatRoom.getChatRoomId();
@@ -170,19 +181,6 @@ public class ChatRoomForMiniGameService implements IChatRoom {
return new Integer[]{0, 1}; return new Integer[]{0, 1};
} }
@Override
public Long getRoomIdByUid(Long uid) {
List<MiniGameMatch> miniGameMatches = miniGameMatchService.list(Wrappers.<MiniGameMatch>lambdaQuery()
.eq(MiniGameMatch::getUid, uid)
.notIn(MiniGameMatch::getMatchStatus, NavGameMatchStatusEnum.FINISH.ordinal(), NavGameMatchStatusEnum.FAIL.ordinal())
.orderByDesc(MiniGameMatch::getCreateTime));
if (CollectionUtil.isEmpty(miniGameMatches)) {
return null;
}
MiniGameMatch miniGameMatch = miniGameMatches.get(0);
return miniGameMatch.getRoomId();
}
@Override @Override
public void init(ChatRoom chatRoom) { public void init(ChatRoom chatRoom) {
jedisService.del(RedisKey.room_mic_list.getKey(String.valueOf(chatRoom.getChatRoomId()))); jedisService.del(RedisKey.room_mic_list.getKey(String.valueOf(chatRoom.getChatRoomId())));
@@ -190,7 +188,8 @@ public class ChatRoomForMiniGameService implements IChatRoom {
@Override @Override
public void close(Long roomId, Long uid) { public void close(Long roomId, Long uid) {
jedisService.del(RedisKey.mini_game_match_round.getKey(String.valueOf(uid))); RMap<Long, Long> roundCacheMap = miniGameMatchRoundService.getMatchRoundMap();
roundCacheMap.fastRemove(roomId);
List<MiniGameMatch> miniGameMatches = miniGameMatchService.list(Wrappers.<MiniGameMatch>lambdaQuery() List<MiniGameMatch> miniGameMatches = miniGameMatchService.list(Wrappers.<MiniGameMatch>lambdaQuery()
.eq(MiniGameMatch::getRoomId, roomId) .eq(MiniGameMatch::getRoomId, roomId)
@@ -199,56 +198,36 @@ public class ChatRoomForMiniGameService implements IChatRoom {
if (CollectionUtil.isNotEmpty(miniGameMatches)) { if (CollectionUtil.isNotEmpty(miniGameMatches)) {
//释放资源 //释放资源
for (MiniGameMatch miniGameMatch : miniGameMatches) { for (MiniGameMatch miniGameMatch : miniGameMatches) {
miniGameForNavService.matchForFail(miniGameMatch.getId()); miniGameForNavService.matchForFail(miniGameMatch);
} }
} }
miniGameForNavService.closeGame(roomId); miniGameForNavService.closeGame(roomId);
} }
@Override @Override
public void enter(Long roomId, Long uid) { public void enter(Long roomId, Long uid) {
if (!jedisService.exits(RedisKey.mini_game_match_round.getKey(String.valueOf(uid)))) { RMap<Long, Long> roundCacheMap = miniGameMatchRoundService.getMatchRoundMap();
jedisService.setex(RedisKey.mini_game_match_round.getKey(String.valueOf(uid)), 24 * 60 * 60, String.valueOf(roomId)); if (!roundCacheMap.containsKey(roomId)){
}
List<MiniGameMatchRound> miniGameMatchRounds = miniGameMatchRoundService.list(Wrappers.<MiniGameMatchRound>lambdaQuery()
.eq(MiniGameMatchRound::getRoomId, roomId)
.eq(MiniGameMatchRound::getRoundStatus, NavGameRoundStatusEnum.PROCESS.ordinal()));
if (CollectionUtil.isEmpty(miniGameMatchRounds)) {
return; return;
} }
MiniGameForNavConfigDto config = miniGameForNavService.getConfigDto();
MiniGameMatchRound miniGameMatchRound = miniGameMatchRounds.get(0);
Long matchRoundId = miniGameMatchRound.getId();
Long fromUid = miniGameMatchRound.getFromUid();
Long toUid = miniGameMatchRound.getToUid();
if (!jedisService.exits(RedisKey.mini_game_match_round.getKey(String.valueOf(roomId)))) {
return;
}
if (jedisService.exits(RedisKey.mini_game_match_round.getKey(String.valueOf(fromUid)))
&& jedisService.exits(RedisKey.mini_game_match_round.getKey(String.valueOf(toUid)))) {
//聊天室
ChatRoomVo chatRoomVo = SpringContextHolder.getBean(ChatRoomManageServiceImpl.class).getByRoomId(roomId);
//匹配成功
sendSysMsgService.sendSingleRoomMessage(roomId, chatRoomVo.getChatRoomId().toString(), Constant.DefMsgType.MINI_GAME_MATCH, Constant.DefMsgType.MINI_GAME_MATCH_FOR_CHANGE, chatRoomVo);
Integer successSeconds = config.getSuccessSeconds(); MiniGameMatchRound miniGameMatchRound = miniGameMatchRoundService.getOne(Wrappers.<MiniGameMatchRound>lambdaQuery()
bizExecutor.submit(() -> { .eq(MiniGameMatchRound::getRoomId, roomId)
try { .eq(MiniGameMatchRound::getRoundStatus, NavGameRoundStatusEnum.PROCESS.ordinal())
for (int i = 0; i < successSeconds; i++) { .orderByDesc(MiniGameMatchRound::getId), false);
log.info("roomId : {}, uid : {}, polling success match second : {}", roomId, uid, i); if (null == miniGameMatchRound) {
if (miniGameForNavService.matchForSuccess(matchRoundId)) { roundCacheMap.fastRemove(roomId);
return; return;
}
TimeUnit.SECONDS.sleep(1);
}
//平局
miniGameForNavService.matchForEqualize(matchRoundId);
//匹配失败
sendSysMsgService.sendSingleRoomMessage(roomId, chatRoomVo.getChatRoomId().toString(), Constant.DefMsgType.MINI_GAME_MATCH, Constant.DefMsgType.MINI_GAME_MATCH_FOR_FAIL, new MiniGameMatchRoundDto());
} catch (Exception e) {
log.error(e.getMessage(), e);
}
});
} }
//聊天室
ChatRoomVo chatRoomVo = SpringContextHolder.getBean(ChatRoomManageServiceImpl.class).getByRoomId(roomId);
//匹配成功
sendSysMsgService.sendSingleRoomMessage(roomId, chatRoomVo.getChatRoomId().toString(), Constant.DefMsgType.MINI_GAME_MATCH, Constant.DefMsgType.MINI_GAME_MATCH_FOR_CHANGE, chatRoomVo);
MiniGameMatchRoundMessage message = new MiniGameMatchRoundMessage();
message.setRound(miniGameMatchRound);
rocketMQService.sendMiniGameMatchRoundMsg(message);
} }
} }

View File

@@ -50,13 +50,19 @@ public class ChatRoomManageServiceImpl implements ChatRoomManageService {
ChatRoomVo vo = new ChatRoomVo(); ChatRoomVo vo = new ChatRoomVo();
vo.setRoomId(roomId); vo.setRoomId(roomId);
ChatRoom chatRoom = chatRoomService.getByRoomId(roomId); ChatRoom chatRoom = chatRoomService.getByRoomId(roomId);
if (chatRoom == null) { return getByRoom(chatRoom);
}
public ChatRoomVo getByRoom(ChatRoom chatRoom) {
if (null == chatRoom){
return null; return null;
} }
Long chatRoomId = chatRoom.getChatRoomId();
vo.setChatRoomId(chatRoomId); ChatRoomVo vo = new ChatRoomVo();
vo.setRoomId(chatRoom.getRoomId());
vo.setChatRoomId(chatRoom.getChatRoomId());
vo.setRoomType(chatRoom.getRoomType()); vo.setRoomType(chatRoom.getRoomType());
vo.setRoomMics(getRoomMics(chatRoomId)); vo.setRoomMics(getRoomMics(chatRoom.getChatRoomId()));
IChatRoom iChatRoom = ChatRoomServiceFactory.getServiceByType(chatRoom.getRoomType()); IChatRoom iChatRoom = ChatRoomServiceFactory.getServiceByType(chatRoom.getRoomType());
if (iChatRoom != null) { if (iChatRoom != null) {
vo.setData(iChatRoom.getExtraData(chatRoom)); vo.setData(iChatRoom.getExtraData(chatRoom));
@@ -66,16 +72,13 @@ public class ChatRoomManageServiceImpl implements ChatRoomManageService {
@Override @Override
public ChatRoomVo getByUidAndType(Long uid, Integer roomType) { public ChatRoomVo getByUidAndType(Long uid, Integer roomType) {
Long roomId = ChatRoomServiceFactory.getServiceByType(roomType).getRoomIdByUid(uid); ChatRoom chatRoom = ChatRoomServiceFactory.getServiceByType(roomType).getRoomByUid(uid);
if (roomId == null) { return getByRoom(chatRoom);
return null;
}
return getByRoomId(roomId);
} }
@Override @Override
public List<RoomMic> getRoomMics(Long chatRoomId) { public List<RoomMic> getRoomMics(Long chatRoomId) {
ChatRoom chatRoom = chatRoomService.getById(chatRoomId); ChatRoom chatRoom = chatRoomService.getByRoomId(chatRoomId);
if (chatRoom == null) { if (chatRoom == null) {
return Collections.emptyList(); return Collections.emptyList();
} }
@@ -165,8 +168,6 @@ public class ChatRoomManageServiceImpl implements ChatRoomManageService {
ChatRoomServiceFactory.getServiceByType(roomType).close(roomId, uid); ChatRoomServiceFactory.getServiceByType(roomType).close(roomId, uid);
//解除关联 //解除关联
chatRoomService.releaseByRoomId(roomId); chatRoomService.releaseByRoomId(roomId);
//清除缓存
jedisService.del(RedisKey.room_mic_list.getKey(String.valueOf(roomId)));
} }
@Override @Override

View File

@@ -15,6 +15,7 @@ import com.accompany.common.utils.BeanUtil;
import com.accompany.common.utils.UUIDUtil; import com.accompany.common.utils.UUIDUtil;
import com.accompany.core.exception.ServiceException; import com.accompany.core.exception.ServiceException;
import com.accompany.core.service.account.NetEaseService; import com.accompany.core.service.account.NetEaseService;
import com.accompany.core.service.common.JedisService;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.SneakyThrows; import lombok.SneakyThrows;
@@ -27,7 +28,6 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.Date; import java.util.Date;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@@ -41,6 +41,9 @@ import java.util.concurrent.TimeUnit;
@Service @Service
public class ChatRoomServiceImpl extends ServiceImpl<ChatRoomMapper, ChatRoom> implements ChatRoomService, InitializingBean { public class ChatRoomServiceImpl extends ServiceImpl<ChatRoomMapper, ChatRoom> implements ChatRoomService, InitializingBean {
@Autowired
private JedisService jedisService;
@Autowired @Autowired
private NetEaseService netEaseService; private NetEaseService netEaseService;
@@ -50,7 +53,7 @@ public class ChatRoomServiceImpl extends ServiceImpl<ChatRoomMapper, ChatRoom> i
@Autowired @Autowired
private RedissonClient redissonClient; private RedissonClient redissonClient;
private RMap<Long, ChatRoom> chatRoomCacheMap; private RMap<Long, ChatRoom> workingChatRoomCacheMap;
@SneakyThrows @SneakyThrows
@Override @Override
@@ -69,7 +72,7 @@ public class ChatRoomServiceImpl extends ServiceImpl<ChatRoomMapper, ChatRoom> i
throw new ServiceException(BusiStatus.SERVERBUSY); throw new ServiceException(BusiStatus.SERVERBUSY);
} }
Set<Long> roomIdSet = chatRoomCacheMap.keySet(); Set<Long> roomIdSet = workingChatRoomCacheMap.keySet();
ChatRoom chatRoom = getOne(Wrappers.<ChatRoom>lambdaQuery() ChatRoom chatRoom = getOne(Wrappers.<ChatRoom>lambdaQuery()
.isNull(ChatRoom::getRefUid) .isNull(ChatRoom::getRefUid)
.notIn(CollectionUtil.isNotEmpty(roomIdSet), ChatRoom::getRoomId, roomIdSet) .notIn(CollectionUtil.isNotEmpty(roomIdSet), ChatRoom::getRoomId, roomIdSet)
@@ -109,7 +112,7 @@ public class ChatRoomServiceImpl extends ServiceImpl<ChatRoomMapper, ChatRoom> i
log.info("chat room new : {}", chatRoom.getRoomId()); log.info("chat room new : {}", chatRoom.getRoomId());
} }
chatRoomCacheMap.put(chatRoom.getRoomId(), chatRoom); workingChatRoomCacheMap.fastPut(chatRoom.getRoomId(), chatRoom);
return chatRoom; return chatRoom;
@@ -121,14 +124,21 @@ public class ChatRoomServiceImpl extends ServiceImpl<ChatRoomMapper, ChatRoom> i
} }
@Override @Override
public void releaseByUid(Long uid) { public ChatRoom getRoomByUid(Long uid){
List<ChatRoom> chatRooms = list(Wrappers.<ChatRoom>lambdaQuery() Map<Long, ChatRoom> workingChatRoomMap = workingChatRoomCacheMap.readAllMap();
.eq(ChatRoom::getRefUid, uid)); if (CollectionUtil.isEmpty(workingChatRoomMap)){
release(chatRooms); return null;
}
return workingChatRoomMap.values().stream()
.filter(chatRoom -> uid.equals(chatRoom.getRefUid()))
.findFirst().orElse(null);
} }
@Override @Override
public void releaseByRoomId(Long roomId) { public void releaseByRoomId(Long roomId) {
workingChatRoomCacheMap.fastRemove(roomId);
ChatRoom chatRoom = getOne(Wrappers.<ChatRoom>lambdaQuery() ChatRoom chatRoom = getOne(Wrappers.<ChatRoom>lambdaQuery()
.eq(ChatRoom::getRoomId, roomId), false); .eq(ChatRoom::getRoomId, roomId), false);
if (null == chatRoom){ if (null == chatRoom){
@@ -138,27 +148,22 @@ public class ChatRoomServiceImpl extends ServiceImpl<ChatRoomMapper, ChatRoom> i
chatRoom.setUpdateTime(new Date()); chatRoom.setUpdateTime(new Date());
updateById(chatRoom); updateById(chatRoom);
chatRoomCacheMap.fastRemove(roomId); //清除缓存
} jedisService.del(RedisKey.room_mic_list.getKey(String.valueOf(roomId)));
private void release(List<ChatRoom> chatRooms) {
Date now = new Date();
for (ChatRoom chatRoom : chatRooms) {
chatRoom.setRefUid(null);
chatRoom.setUpdateTime(now);
}
updateBatchById(chatRooms);
chatRoomCacheMap.fastRemove(chatRooms.stream().map(ChatRoom::getRoomId).toArray(Long[]::new));
} }
@Override @Override
public ChatRoom getByRoomId(Long roomId) { public ChatRoom getByRoomId(Long roomId) {
ChatRoom woringChatRoom = workingChatRoomCacheMap.get(roomId);
if (null != woringChatRoom){
return woringChatRoom;
}
return getOne(Wrappers.<ChatRoom>lambdaQuery() return getOne(Wrappers.<ChatRoom>lambdaQuery()
.eq(ChatRoom::getRoomId, roomId), false); .eq(ChatRoom::getRoomId, roomId), false);
} }
@Override @Override
public void afterPropertiesSet() throws Exception { public void afterPropertiesSet() throws Exception {
chatRoomCacheMap = redissonClient.getMap(RedisKey.chat_room.getKey()); workingChatRoomCacheMap = redissonClient.getMap(RedisKey.chat_room.getKey());
} }
} }

View File

@@ -1,6 +1,7 @@
package com.accompany.business.service.miniGame; package com.accompany.business.service.miniGame;
import com.accompany.business.dto.miniGame.MiniGameForNavConfigDto; import com.accompany.business.dto.miniGame.MiniGameForNavConfigDto;
import com.accompany.business.model.miniGame.MiniGameMatch;
import com.accompany.business.vo.chat.ChatRoomVo; import com.accompany.business.vo.chat.ChatRoomVo;
import com.accompany.business.vo.miniGame.MiniGameVo; import com.accompany.business.vo.miniGame.MiniGameVo;
@@ -25,20 +26,7 @@ public interface MiniGameForNavService {
*/ */
void start(String mgId, Integer gameMode); void start(String mgId, Integer gameMode);
/** void matchForFail(MiniGameMatch miniGameMatch);
*
* @param roomId
* @param mgId
* @param gameMode
* @return
*/
boolean matchForPolling(Long roomId, String mgId, Integer gameMode);
/**
* 匹配失败
* @param miniGameMatchId
*/
void matchForFail(Long miniGameMatchId);
/** /**
* 匹配成功 * 匹配成功
@@ -54,10 +42,10 @@ public interface MiniGameForNavService {
/** /**
* 匹配 * 匹配
* @param fromMatchId * @param fromMiniGameMatch
* @param toMatchId * @param toMiniGameMatch
*/ */
void match(Long fromMatchId, Long toMatchId); void match(MiniGameMatch fromMiniGameMatch, MiniGameMatch toMiniGameMatch);
/** /**
* 关闭游戏 * 关闭游戏

View File

@@ -2,6 +2,7 @@ package com.accompany.business.service.miniGame;
import com.accompany.business.model.miniGame.MiniGameMatchRound; import com.accompany.business.model.miniGame.MiniGameMatchRound;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import org.redisson.api.RMap;
/** /**
* @author: liaozetao * @author: liaozetao
@@ -9,4 +10,5 @@ import com.baomidou.mybatisplus.extension.service.IService;
* @description: * @description:
*/ */
public interface MiniGameMatchRoundService extends IService<MiniGameMatchRound> { public interface MiniGameMatchRoundService extends IService<MiniGameMatchRound> {
RMap<Long, Long> getMatchRoundMap();
} }

View File

@@ -2,6 +2,7 @@ package com.accompany.business.service.miniGame;
import com.accompany.business.model.miniGame.MiniGameMatch; import com.accompany.business.model.miniGame.MiniGameMatch;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import org.redisson.api.RMap;
/** /**
* @author: liaozetao * @author: liaozetao
@@ -9,4 +10,7 @@ import com.baomidou.mybatisplus.extension.service.IService;
* @description: * @description:
*/ */
public interface MiniGameMatchService extends IService<MiniGameMatch> { public interface MiniGameMatchService extends IService<MiniGameMatch> {
RMap<Long, MiniGameMatch> getWaitMatchMap(String mgId, Integer gameMode, Integer partitionId);
} }

View File

@@ -38,11 +38,10 @@ import com.accompany.core.enumeration.BillObjTypeEnum;
import com.accompany.core.exception.ServiceException; import com.accompany.core.exception.ServiceException;
import com.accompany.core.model.Users; import com.accompany.core.model.Users;
import com.accompany.core.service.SysConfService; import com.accompany.core.service.SysConfService;
import com.accompany.core.service.common.JedisLockService;
import com.accompany.core.service.common.JedisService;
import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RMap; import org.redisson.api.RMap;
import org.redisson.api.RedissonClient; import org.redisson.api.RedissonClient;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
@@ -97,12 +96,6 @@ public class MiniGameForNavServiceImpl implements MiniGameForNavService {
@Autowired @Autowired
private SendSysMsgService sendSysMsgService; private SendSysMsgService sendSysMsgService;
@Autowired
private JedisService jedisService;
@Autowired
private JedisLockService jedisLockService;
@Resource(name = "bizExecutor") @Resource(name = "bizExecutor")
private ThreadPoolExecutor bizExecutor; private ThreadPoolExecutor bizExecutor;
@@ -114,6 +107,7 @@ public class MiniGameForNavServiceImpl implements MiniGameForNavService {
@Autowired @Autowired
private UserInRoomService userInRoomService; private UserInRoomService userInRoomService;
@Autowired @Autowired
private RedissonClient redissonClient; private RedissonClient redissonClient;
@@ -210,85 +204,90 @@ public class MiniGameForNavServiceImpl implements MiniGameForNavService {
//扣减钱包,创建完轮次后再插入账单 //扣减钱包,创建完轮次后再插入账单
UserPurse afterPurse = userPurseService.subDiamond(uid, diamondNum, BillObjTypeEnum.MINI_GAME_MATCH_ENTER_OUT, BusiStatus.DIAMONDNUMNOTENOUGH, UserPurse::getDiamonds); UserPurse afterPurse = userPurseService.subDiamond(uid, diamondNum, BillObjTypeEnum.MINI_GAME_MATCH_ENTER_OUT, BusiStatus.DIAMONDNUMNOTENOUGH, UserPurse::getDiamonds);
Long roomId = null; //别的玩家已经发起等待的房间
MiniGameMatch fromMiniGameMatch = null; MiniGameMatch fromMiniGameMatch = null;
RMap<Long, MiniGameMatch> waitMatchMap = getWaitMatchMap(mgId, gameMode, partitionId); Long roomId = null;
List<MiniGameMatch> waitMatchList = waitMatchMap.values().stream()
RMap<Long, MiniGameMatch> waitMatchMap = miniGameMatchService.getWaitMatchMap(mgId, gameMode, partitionId);
List<MiniGameMatch> otherWaitMatchList = waitMatchMap.values().stream()
.filter(miniGameMatch -> !miniGameMatch.getUid().equals(uid)) .filter(miniGameMatch -> !miniGameMatch.getUid().equals(uid))
.sorted(Comparator.comparing(MiniGameMatch::getCreateTime)) .sorted(Comparator.comparing(MiniGameMatch::getCreateTime))
.collect(Collectors.toList()); .collect(Collectors.toList());
if (CollectionUtil.isNotEmpty(waitMatchList)) { RMap<Long, Long> matchRoundMap = miniGameMatchRoundService.getMatchRoundMap();
if (CollectionUtil.isNotEmpty(otherWaitMatchList)) {
for (int i = 0, j = 0; j < 3 && (fromMiniGameMatch == null for (int i = 0, j = 0; j < 3 && (fromMiniGameMatch == null
|| jedisService.exits(RedisKey.mini_game_match_round.getKey(String.valueOf(fromMiniGameMatch.getUid())))); || matchRoundMap.containsKey(fromMiniGameMatch.getRoomId()));
i = RandomUtil.randomByRange(0, waitMatchList.size()), j++) { i = RandomUtil.randomByRange(0, otherWaitMatchList.size()), j++) {
fromMiniGameMatch = waitMatchList.get(i); fromMiniGameMatch = otherWaitMatchList.get(i);
} }
} }
if (fromMiniGameMatch != null) { if (fromMiniGameMatch != null) {
if (!jedisService.exits(RedisKey.mini_game_match_round.getKey(String.valueOf(fromMiniGameMatch.getRoomId())))) { if (!matchRoundMap.containsKey(fromMiniGameMatch.getRoomId())) {
roomId = fromMiniGameMatch.getRoomId(); roomId = fromMiniGameMatch.getRoomId();
} }
} }
boolean isInit = (roomId == null);
ChatRoom chatRoom = chatRoomService.getOrOpen(roomId, uid, ChatRoomTypeEnum.MINI_GAME.ordinal()); ChatRoom toChatRoom = chatRoomService.getOrOpen(roomId, uid, ChatRoomTypeEnum.MINI_GAME.ordinal());
if (chatRoom == null) { if (toChatRoom == null) {
throw new ServiceException(BusiStatus.SERVERERROR); throw new ServiceException(BusiStatus.SERVERERROR);
} }
roomId = chatRoom.getRoomId();
//初始化 //初始化
if (isInit) { if (null == roomId){
ChatRoomServiceFactory.getServiceByType(ChatRoomTypeEnum.MINI_GAME.ordinal()).init(chatRoom); ChatRoomServiceFactory.getServiceByType(ChatRoomTypeEnum.MINI_GAME.ordinal()).init(toChatRoom);
} }
MiniGameMatch miniGameMatch = new MiniGameMatch(); //保存匹配记录
miniGameMatch.setUid(uid); MiniGameMatch toMiniGameMatch = new MiniGameMatch();
miniGameMatch.setRoomId(roomId); toMiniGameMatch.setUid(uid);
miniGameMatch.setMgId(mgId); toMiniGameMatch.setRoomId(roomId);
miniGameMatch.setGameMode(gameMode); toMiniGameMatch.setMgId(mgId);
miniGameMatch.setMatchStatus(NavGameMatchStatusEnum.WAIT.ordinal()); toMiniGameMatch.setGameMode(gameMode);
miniGameMatch.setTicket(diamondNum); toMiniGameMatch.setMatchStatus(NavGameMatchStatusEnum.WAIT.ordinal());
miniGameMatch.setPartitionId(partitionId); toMiniGameMatch.setTicket(diamondNum);
miniGameMatch.setCreateTime(now); toMiniGameMatch.setPartitionId(partitionId);
miniGameMatch.setUpdateTime(now); toMiniGameMatch.setCreateTime(now);
toMiniGameMatch.setUpdateTime(now);
List<MiniGameMatch> matches = miniGameMatchService.list(Wrappers.<MiniGameMatch>lambdaQuery() MiniGameMatch dbMatch = miniGameMatchService.getOne(Wrappers.<MiniGameMatch>lambdaQuery()
.eq(MiniGameMatch::getUid, uid) .eq(MiniGameMatch::getUid, uid)
.eq(MiniGameMatch::getMgId, mgId) .eq(MiniGameMatch::getMgId, mgId)
.eq(MiniGameMatch::getGameMode, gameMode) .eq(MiniGameMatch::getGameMode, gameMode)
.eq(MiniGameMatch::getMatchStatus, NavGameMatchStatusEnum.WAIT.ordinal()) .eq(MiniGameMatch::getMatchStatus, NavGameMatchStatusEnum.WAIT.ordinal())
.eq(MiniGameMatch::getPartitionId, partitionId)); .eq(MiniGameMatch::getPartitionId, partitionId), false);
if (CollectionUtil.isNotEmpty(matches)) { if (null != dbMatch) {
MiniGameMatch match = matches.get(0); toMiniGameMatch.setId(dbMatch.getId());
miniGameMatch.setId(match.getId()); miniGameMatchService.updateById(toMiniGameMatch);
} else {
miniGameMatchService.save(toMiniGameMatch);
} }
miniGameMatchService.saveOrUpdate(miniGameMatch);
billRecordService.insertGeneralBillRecord(uid, miniGameMatch.getId().toString(), BillObjTypeEnum.MINI_GAME_MATCH_ENTER_OUT, diamondNum, afterPurse); billRecordService.insertGeneralBillRecord(uid, toMiniGameMatch.getId().toString(), BillObjTypeEnum.MINI_GAME_MATCH_ENTER_OUT, diamondNum, afterPurse);
if (fromMiniGameMatch != null) { if (fromMiniGameMatch != null) {
//匹配 //匹配
match(fromMiniGameMatch.getId(), miniGameMatch.getId()); match(fromMiniGameMatch, toMiniGameMatch);
} else { } else {
//发起人 //发起人
chatRoomManageService.upMic(chatRoom.getChatRoomId(), uid); chatRoomManageService.upMic(toChatRoom.getChatRoomId(), uid);
//放入缓存 //放入缓存
waitMatchMap.fastPut(miniGameMatch.getId(), miniGameMatch); waitMatchMap.fastPut(toMiniGameMatch.getId(), toMiniGameMatch);
//匹配时长 //匹配时长
Integer matchSeconds = config.getMatchSeconds(); Integer matchSeconds = config.getMatchSeconds();
Long finalRoomId = roomId;
bizExecutor.submit(() -> { bizExecutor.submit(() -> {
try { try {
for (int i = 0; i < matchSeconds; i++) { for (int i = 0; i < matchSeconds; i++) {
log.info("fromMatchId : {}, roomId : {}, polling process match second : {}", miniGameMatch.getId(), finalRoomId, i); log.info("fromMatchId : {}, roomId : {}, polling process match second : {}", toMiniGameMatch.getId(), toMiniGameMatch.getRoomId(), i);
if (matchForPolling(finalRoomId, mgId, gameMode)) { if (matchForPolling(toMiniGameMatch)) {
return; return;
} }
TimeUnit.SECONDS.sleep(1); TimeUnit.SECONDS.sleep(1);
} }
//匹配失败 //匹配失败
matchForFail(miniGameMatch.getId()); matchForFail(toMiniGameMatch);
} catch (Exception e) { } catch (Exception e) {
log.error(e.getMessage(), e); log.error(e.getMessage(), e);
} }
@@ -296,43 +295,98 @@ public class MiniGameForNavServiceImpl implements MiniGameForNavService {
} }
} }
private RMap<Long, MiniGameMatch> getWaitMatchMap(String mgId, Integer gameMode, Integer partitionId){ private boolean matchForPolling(MiniGameMatch fromMiniGameMatch) {
return redissonClient.getMap(RedisKey.mini_game_match_wait.getKey(mgId, String.valueOf(gameMode), String.valueOf(partitionId))); RMap<Long, Long> matchRoundMap = miniGameMatchRoundService.getMatchRoundMap();
Long roundId = matchRoundMap.get(fromMiniGameMatch.getRoomId());
if (null == roundId){
return false;
}
RMap<Long, MiniGameMatch> waitGameMatchMap = miniGameMatchService.getWaitMatchMap(fromMiniGameMatch.getMgId(), fromMiniGameMatch.getGameMode(), fromMiniGameMatch.getPartitionId());
if (waitGameMatchMap.containsKey(fromMiniGameMatch.getId())) {
return false;
}
MiniGameMatch dbFromMiniGameMatch = miniGameMatchService.getById(fromMiniGameMatch.getId());
if (null == dbFromMiniGameMatch
|| dbFromMiniGameMatch.getMatchStatus() == NavGameMatchStatusEnum.FINISH.ordinal()
|| dbFromMiniGameMatch.getMatchStatus() == NavGameMatchStatusEnum.FAIL.ordinal()){
throw new ServiceException(BusiStatus.SERVERERROR);
}
if (dbFromMiniGameMatch.getMatchStatus() == NavGameMatchStatusEnum.WAIT.ordinal()){
matchForFail(dbFromMiniGameMatch);
throw new ServiceException(BusiStatus.SERVERERROR);
}
MiniGameMatchRound round = miniGameMatchRoundService.getById(roundId);
if (null == round || round.getRoundStatus() != NavGameRoundStatusEnum.PROCESS.ordinal()){
matchForFail(dbFromMiniGameMatch);
throw new ServiceException(BusiStatus.SERVERERROR);
}
MiniGameMatch toMiniGameMatch = miniGameMatchService.getById(round.getToMatchId());
if (null == toMiniGameMatch || toMiniGameMatch.getMatchStatus() != NavGameMatchStatusEnum.WAIT.ordinal()){
matchForFail(dbFromMiniGameMatch);
throw new ServiceException(BusiStatus.SERVERERROR);
}
boolean updateSuccess = miniGameMatchService.lambdaUpdate()
.set(MiniGameMatch::getMatchStatus, NavGameMatchStatusEnum.SUCCESS.ordinal())
.eq(MiniGameMatch::getId, toMiniGameMatch.getId())
.eq(MiniGameMatch::getMatchStatus, NavGameMatchStatusEnum.WAIT.ordinal())
.update();
if (!updateSuccess){
matchForFail(dbFromMiniGameMatch);
throw new ServiceException(BusiStatus.SERVERERROR);
}
//释放资源
chatRoomService.releaseByRoomId(toMiniGameMatch.getRoomId());
return true;
} }
@Override @Override
public void matchForFail(Long miniGameMatchId) { public void matchForFail(MiniGameMatch miniGameMatch) {
MiniGameMatch miniGameMatch = miniGameMatchService.getById(miniGameMatchId); if (null == miniGameMatch || null == miniGameMatch.getUid()) {
if (miniGameMatch == null) {
return; return;
} }
Integer matchStatus = miniGameMatch.getMatchStatus();
if (NavGameMatchStatusEnum.WAIT.ordinal() != matchStatus) { //更新
boolean updateSuccess = miniGameMatchService.lambdaUpdate()
.set(MiniGameMatch::getMatchStatus, NavGameMatchStatusEnum.FAIL.ordinal())
.eq(MiniGameMatch::getId, miniGameMatch.getId())
.eq(MiniGameMatch::getMatchStatus, NavGameMatchStatusEnum.WAIT.ordinal())
.update();
if (!updateSuccess){
return; return;
} }
Long uid = miniGameMatch.getUid(); Long uid = miniGameMatch.getUid();
Long roomId = miniGameMatch.getRoomId(); Long roomId = miniGameMatch.getRoomId();
Integer gameMode = miniGameMatch.getGameMode();
MiniGameForNavConfigDto config = getConfigDto();
Map<Integer, GameModeDto> gameModeMap = config.getGameModeMap();
//入场费 //入场费
Double diamondNum = gameModeMap.get(gameMode).getTicket(); Double diamondNum = miniGameMatch.getTicket();
//聊天室 //聊天室
ChatRoom chatRoom = chatRoomService.getByRoomId(roomId); ChatRoom chatRoom = chatRoomService.getByRoomId(roomId);
//更新为失败 if (null == chatRoom){
miniGameMatch.setMatchStatus(NavGameMatchStatusEnum.FAIL.ordinal()); return;
miniGameMatchService.updateById(miniGameMatch); }
Long chatRoomUid = chatRoom.getChatRoomId();
//匹配失败 //匹配失败
sendSysMsgService.sendSingleRoomMessage(roomId, chatRoom.getChatRoomId().toString(), Constant.DefMsgType.MINI_GAME_MATCH, Constant.DefMsgType.MINI_GAME_MATCH_FOR_FAIL, new MiniGameMatchRoundDto()); sendSysMsgService.sendSingleRoomMessage(roomId, chatRoom.getChatRoomId().toString(), Constant.DefMsgType.MINI_GAME_MATCH, Constant.DefMsgType.MINI_GAME_MATCH_FOR_FAIL, new MiniGameMatchRoundDto());
//释放房间
chatRoomService.releaseByRoomId(roomId);
//增加钱包 //增加钱包
userPurseService.addDiamond(uid, diamondNum, BillObjTypeEnum.MINI_GAME_MATCH_REFUND_IN, userPurseService.addDiamond(uid, diamondNum, BillObjTypeEnum.MINI_GAME_MATCH_REFUND_IN,
(userPurse -> billRecordService.insertGeneralBillRecord(uid, miniGameMatch.getId().toString(), BillObjTypeEnum.MINI_GAME_MATCH_REFUND_IN, diamondNum, userPurse))); (userPurse -> billRecordService.insertGeneralBillRecord(uid, miniGameMatch.getId().toString(), BillObjTypeEnum.MINI_GAME_MATCH_REFUND_IN, diamondNum, userPurse)));
//释放房间
chatRoomService.releaseByRoomId(roomId);
//房间踢人 //房间踢人
erBanNetEaseService.kickMember(String.valueOf(roomId), String.valueOf(uid), String.valueOf(chatRoom.getChatRoomId()), null); erBanNetEaseService.kickMember(String.valueOf(roomId), String.valueOf(uid), String.valueOf(chatRoomUid), null);
//房间清理 //房间清理
miniGameForSudService.pushRoomClearEvent(miniGameMatch.getMgId(), miniGameMatch.getRoomId()); miniGameForSudService.pushRoomClearEvent(miniGameMatch.getMgId(), roomId);
} }
@Override @Override
@@ -361,6 +415,7 @@ public class MiniGameForNavServiceImpl implements MiniGameForNavService {
boolean isRefund = StrUtil.isEmpty(gameMatchRound.getGameRoundId()) && gameMatchRound.getWinUid() == null && gameMatchRound.getWinNum() == 0; boolean isRefund = StrUtil.isEmpty(gameMatchRound.getGameRoundId()) && gameMatchRound.getWinUid() == null && gameMatchRound.getWinNum() == 0;
gameMatchRound.setRoundStatus(NavGameRoundStatusEnum.END.ordinal()); gameMatchRound.setRoundStatus(NavGameRoundStatusEnum.END.ordinal());
miniGameMatchRoundService.updateById(gameMatchRound); miniGameMatchRoundService.updateById(gameMatchRound);
Long fromMatchId = gameMatchRound.getFromMatchId(); Long fromMatchId = gameMatchRound.getFromMatchId();
Long toMatchId = gameMatchRound.getToMatchId(); Long toMatchId = gameMatchRound.getToMatchId();
MiniGameMatch fromMatch = miniGameMatchService.getById(fromMatchId); MiniGameMatch fromMatch = miniGameMatchService.getById(fromMatchId);
@@ -393,118 +448,85 @@ public class MiniGameForNavServiceImpl implements MiniGameForNavService {
} }
@Override @Override
public boolean matchForPolling(Long roomId, String mgId, Integer gameMode) { public void match(MiniGameMatch fromMiniGameMatch, MiniGameMatch toMiniGameMatch) {
ChatRoom chatRoom = chatRoomService.getByRoomId(roomId); if (fromMiniGameMatch == null || toMiniGameMatch == null
if (chatRoom == null) { || !fromMiniGameMatch.getMgId().equals(toMiniGameMatch.getMgId())
return false; || !fromMiniGameMatch.getGameMode().equals(toMiniGameMatch.getGameMode())
|| !fromMiniGameMatch.getPartitionId().equals(toMiniGameMatch.getPartitionId())){
throw new ServiceException(BusiStatus.SERVERERROR);
} }
Long refUid = chatRoom.getRefUid();
List<MiniGameMatch> fromMiniGameMatches = miniGameMatchService.list(Wrappers.<MiniGameMatch>lambdaQuery() if (fromMiniGameMatch.getMatchStatus() == NavGameMatchStatusEnum.SUCCESS.ordinal()
.eq(MiniGameMatch::getUid, refUid) || toMiniGameMatch.getMatchStatus() == NavGameMatchStatusEnum.SUCCESS.ordinal()) {
.eq(MiniGameMatch::getRoomId, roomId) return;
.eq(MiniGameMatch::getMgId, mgId)
.eq(MiniGameMatch::getGameMode, gameMode)
.eq(MiniGameMatch::getMatchStatus, NavGameMatchStatusEnum.WAIT.ordinal())
.orderByDesc(MiniGameMatch::getCreateTime));
if (CollectionUtil.isEmpty(fromMiniGameMatches)) {
return false;
} }
MiniGameMatch fromMiniGameMatch = fromMiniGameMatches.get(0); Long roomId = fromMiniGameMatch.getRoomId();
Integer partitionId = fromMiniGameMatch.getPartitionId();
List<MiniGameMatch> toMiniGameMatches = miniGameMatchService.list(Wrappers.<MiniGameMatch>lambdaQuery() boolean locked = false;
.ne(MiniGameMatch::getUid, refUid) String redisKey = RedisKey.mini_game_match_round_lock.getKey(String.valueOf(roomId));
.eq(MiniGameMatch::getMgId, mgId) RLock lock = redissonClient.getLock(redisKey);
.eq(MiniGameMatch::getGameMode, gameMode) try {
.eq(MiniGameMatch::getPartitionId, partitionId) locked = lock.tryLock(3, TimeUnit.SECONDS);
.eq(MiniGameMatch::getMatchStatus, NavGameMatchStatusEnum.WAIT.ordinal()) if (!locked) {
.orderByDesc(MiniGameMatch::getCreateTime)); log.error("[ludo] 匹配 获取锁超时 {} {}", fromMiniGameMatch.getUid(), toMiniGameMatch.getUid());
if (CollectionUtil.isEmpty(toMiniGameMatches)) { throw new ServiceException(BusiStatus.SERVERERROR);
return false; }
RMap<Long, MiniGameMatch> waitMatchMap = miniGameMatchService.getWaitMatchMap(fromMiniGameMatch.getMgId(), fromMiniGameMatch.getGameMode(), fromMiniGameMatch.getPartitionId());
if (!waitMatchMap.containsKey(fromMiniGameMatch.getId())){
log.error("[ludo] 匹配 waitMatchMap 没有 from Id");
throw new ServiceException(BusiStatus.SERVERERROR);
}
boolean updateFromSuccess = miniGameMatchService.lambdaUpdate()
.set(MiniGameMatch::getMatchStatus, NavGameMatchStatusEnum.SUCCESS.ordinal())
.eq(MiniGameMatch::getId, fromMiniGameMatch.getId())
.eq(MiniGameMatch::getMatchStatus, NavGameMatchStatusEnum.WAIT.ordinal())
.update();
if (!updateFromSuccess){
log.error("[ludo] 匹配 修改 from db状态失败");
throw new ServiceException(BusiStatus.SERVERERROR);
}
Date now = new Date();
//创建匹配轮次
MiniGameMatchRound round = new MiniGameMatchRound();
round.setRoomId(fromMiniGameMatch.getRoomId());
round.setFromMatchId(fromMiniGameMatch.getId());
round.setFromUid(fromMiniGameMatch.getUid());
round.setToMatchId(toMiniGameMatch.getId());
round.setToUid(toMiniGameMatch.getUid());
round.setGameMode(fromMiniGameMatch.getGameMode());
round.setCreateTime(now);
round.setUpdateTime(now);
round.setRoundStatus(NavGameRoundStatusEnum.PROCESS.ordinal());
miniGameMatchRoundService.save(round);
//设置麦位信息
Long fromUid = fromMiniGameMatch.getUid();
Long toUid = toMiniGameMatch.getUid();
//聊天室
ChatRoom fromChatRoom = chatRoomService.getByRoomId(fromMiniGameMatch.getRoomId());
ChatRoom toChatRoom = chatRoomService.getByRoomId(toMiniGameMatch.getRoomId());
//上麦
chatRoomManageService.upMic(fromChatRoom.getChatRoomId(), toUid);
//下麦
chatRoomManageService.downMic(toChatRoom.getChatRoomId(), toUid);
//设置匹配标识
RMap<Long, Long> matchRoundMap = miniGameMatchRoundService.getMatchRoundMap();
matchRoundMap.put(fromMiniGameMatch.getRoomId(), toMiniGameMatch.getId());
waitMatchMap.fastRemove(fromUid);
} catch (Exception e) {
log.error("[ludo] 匹配 异常", e);
} finally {
if (locked){
lock.unlock();
}
} }
int index = RandomUtil.randomByRange(0, toMiniGameMatches.size());
MiniGameMatch toMiniGameMatch = toMiniGameMatches.get(index);
Integer fromMatchStatus = fromMiniGameMatch.getMatchStatus();
Integer toMatchStatus = toMiniGameMatch.getMatchStatus();
if (fromMatchStatus == NavGameMatchStatusEnum.SUCCESS.ordinal() || toMatchStatus == NavGameMatchStatusEnum.SUCCESS.ordinal()) {
return true;
}
//释放资源
chatRoomService.releaseByRoomId(roomId);
//匹配
match(fromMiniGameMatch.getId(), toMiniGameMatch.getId());
return true;
}
@Override
public void match(Long fromMatchId, Long toMatchId) {
bizExecutor.submit(() -> {
MiniGameMatch fromMiniGameMatch = miniGameMatchService.getById(fromMatchId);
MiniGameMatch toMiniGameMatch = miniGameMatchService.getById(toMatchId);
if (fromMiniGameMatch == null || toMiniGameMatch == null) {
return;
}
Integer fromMatchStatus = fromMiniGameMatch.getMatchStatus();
Integer toMatchStatus = toMiniGameMatch.getMatchStatus();
if (fromMatchStatus == NavGameMatchStatusEnum.SUCCESS.ordinal() || toMatchStatus == NavGameMatchStatusEnum.SUCCESS.ordinal()) {
return;
}
Long roomId = fromMiniGameMatch.getRoomId();
String redisKey = RedisKey.mini_game_match_round_start_lock.getKey(String.valueOf(roomId));
String lockVal = jedisLockService.lock(redisKey, 60 * 1000);
if (StrUtil.isEmpty(lockVal)) {
return;
}
try {
Date now = new Date();
Long fromRoomId = fromMiniGameMatch.getRoomId();
Integer gameMode = fromMiniGameMatch.getGameMode();
Long toRoomId = toMiniGameMatch.getRoomId();
//更新
fromMiniGameMatch.setMatchStatus(NavGameMatchStatusEnum.SUCCESS.ordinal());
miniGameMatchService.updateById(fromMiniGameMatch);
toMiniGameMatch.setRoomId(fromRoomId);
toMiniGameMatch.setMatchStatus(NavGameMatchStatusEnum.SUCCESS.ordinal());
miniGameMatchService.updateById(toMiniGameMatch);
//创建匹配轮次
MiniGameMatchRound round = new MiniGameMatchRound();
round.setRoomId(fromRoomId);
round.setFromMatchId(fromMiniGameMatch.getId());
round.setFromUid(fromMiniGameMatch.getUid());
round.setToMatchId(toMiniGameMatch.getId());
round.setToUid(toMiniGameMatch.getUid());
round.setGameMode(gameMode);
round.setCreateTime(now);
round.setUpdateTime(now);
round.setRoundStatus(NavGameRoundStatusEnum.PROCESS.ordinal());
miniGameMatchRoundService.save(round);
//设置麦位信息
Long fromUid = fromMiniGameMatch.getUid();
Long toUid = toMiniGameMatch.getUid();
//聊天室
ChatRoom fromChatRoom = chatRoomService.getByRoomId(fromRoomId);
ChatRoom toChatRoom = chatRoomService.getByRoomId(toRoomId);
//上麦
chatRoomManageService.upMic(fromChatRoom.getChatRoomId(), toUid);
//下麦
chatRoomManageService.downMic(toChatRoom.getChatRoomId(), toUid);
//设置匹配标识
Long matchRoundId = round.getId();
jedisService.setex(RedisKey.mini_game_match_round.getKey(String.valueOf(fromRoomId)), 24 * 60 * 60,
fromUid + StrUtil.UNDERLINE + toUid + StrUtil.UNDERLINE + matchRoundId);
RMap<Long, MiniGameMatch> waitMatchMap = getWaitMatchMap(fromMiniGameMatch.getMgId(), fromMiniGameMatch.getGameMode(), fromMiniGameMatch.getPartitionId());
waitMatchMap.fastRemove(fromMiniGameMatch.getId());
} catch (Exception e) {
log.error(e.getMessage(), e);
} finally {
if (StringUtils.hasText(lockVal)) {
jedisLockService.unlock(redisKey, lockVal);
}
}
});
} }
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
@@ -521,30 +543,34 @@ public class MiniGameForNavServiceImpl implements MiniGameForNavService {
} }
//下麦 //下麦
chatRoomManageService.downMic(chatRoomId, uid); chatRoomManageService.downMic(chatRoomId, uid);
List<MiniGameMatchRound> miniGameMatchRounds = miniGameMatchRoundService.list(Wrappers.<MiniGameMatchRound>lambdaQuery()
.eq(MiniGameMatchRound::getRoomId, roomId) RMap<Long, Long> roundCacheMap = miniGameMatchRoundService.getMatchRoundMap();
.eq(MiniGameMatchRound::getRoundStatus, NavGameRoundStatusEnum.PROCESS.ordinal()) Long roundId = roundCacheMap.remove(roomId);
.orderByDesc(MiniGameMatchRound::getCreateTime)); if (null == roundId){
if (CollectionUtil.isEmpty(miniGameMatchRounds)) {
return;
}
if (miniGameMatchRounds.stream().noneMatch(v -> v.getFromUid().equals(uid) || v.getToUid().equals(uid))) {
return; return;
} }
MiniGameForNavConfigDto config = getConfigDto(); MiniGameForNavConfigDto config = getConfigDto();
//通知结果 //通知结果
MiniGameMatchRound miniGameMatchRound = miniGameMatchRounds.get(0); MiniGameMatchRound miniGameMatchRound = miniGameMatchRoundService.getById(roundId);
String lockKey = RedisKey.mini_game_match_round_close_lock.getKey(String.valueOf(roomId)); if (null == miniGameMatchRound || miniGameMatchRound.getRoundStatus() != NavGameRoundStatusEnum.PROCESS.ordinal()){
String lockVal = jedisLockService.lock(lockKey, 5 * 10);
if (StrUtil.isEmpty(lockVal)) {
log.info("closeGame is error...");
return; return;
} }
boolean locked = false;
String lockKey = RedisKey.mini_game_match_round_lock.getKey(String.valueOf(roomId));
RLock lock = redissonClient.getLock(lockKey);
try { try {
locked = lock.tryLock(3L, TimeUnit.SECONDS);
if (!locked){
throw new ServiceException(BusiStatus.SERVERERROR);
}
Integer gameMode = miniGameMatchRound.getGameMode(); Integer gameMode = miniGameMatchRound.getGameMode();
GameModeDto gameModeDto = config.getGameModeMap().get(gameMode); GameModeDto gameModeDto = config.getGameModeMap().get(gameMode);
Double winner = gameModeDto.getWinner(); Double winner = gameModeDto.getWinner();
Double platform = gameModeDto.getPlatform(); Double platform = gameModeDto.getPlatform();
MiniGameMatch fromMiniGameMatch = miniGameMatchService.getById(miniGameMatchRound.getFromMatchId()); MiniGameMatch fromMiniGameMatch = miniGameMatchService.getById(miniGameMatchRound.getFromMatchId());
MiniGameMatch toMiniGameMatch = miniGameMatchService.getById(miniGameMatchRound.getToMatchId()); MiniGameMatch toMiniGameMatch = miniGameMatchService.getById(miniGameMatchRound.getToMatchId());
if (fromMiniGameMatch == null || toMiniGameMatch == null) { if (fromMiniGameMatch == null || toMiniGameMatch == null) {
@@ -554,13 +580,14 @@ public class MiniGameForNavServiceImpl implements MiniGameForNavService {
miniGameMatchService.updateById(fromMiniGameMatch); miniGameMatchService.updateById(fromMiniGameMatch);
toMiniGameMatch.setMatchStatus(NavGameMatchStatusEnum.FINISH.ordinal()); toMiniGameMatch.setMatchStatus(NavGameMatchStatusEnum.FINISH.ordinal());
miniGameMatchService.updateById(toMiniGameMatch); miniGameMatchService.updateById(toMiniGameMatch);
//游戏提前失败结果 //游戏提前失败结果
MiniGameMatchRoundDto roundDto = new MiniGameMatchRoundDto(); MiniGameMatchRoundDto roundDto = new MiniGameMatchRoundDto();
roundDto.setChatRoomId(chatRoomId); roundDto.setChatRoomId(chatRoomId);
roundDto.setRoomId(roomId); roundDto.setRoomId(roomId);
roundDto.setMatchStatus(NavGameMatchStatusEnum.FINISH.ordinal()); roundDto.setMatchStatus(NavGameMatchStatusEnum.FINISH.ordinal());
roundDto.setRoundStatus(NavGameRoundStatusEnum.END.ordinal()); roundDto.setRoundStatus(NavGameRoundStatusEnum.END.ordinal());
Long fromUid = fromMiniGameMatch.getUid(); Long fromUid = miniGameMatchRound.getFromUid();
Users fromUser = usersService.getUsersByUid(fromUid); Users fromUser = usersService.getUsersByUid(fromUid);
List<MiniGamePlayerResultDto> results = new ArrayList<>(); List<MiniGamePlayerResultDto> results = new ArrayList<>();
MiniGamePlayerResultDto fromResultDto = new MiniGamePlayerResultDto(); MiniGamePlayerResultDto fromResultDto = new MiniGamePlayerResultDto();
@@ -592,6 +619,7 @@ public class MiniGameForNavServiceImpl implements MiniGameForNavService {
fromResultDto.setRank(2); fromResultDto.setRank(2);
} }
results.add(fromResultDto); results.add(fromResultDto);
Long toUid = toMiniGameMatch.getUid(); Long toUid = toMiniGameMatch.getUid();
Users toUser = usersService.getUsersByUid(toUid); Users toUser = usersService.getUsersByUid(toUid);
MiniGamePlayerResultDto toResultDto = new MiniGamePlayerResultDto(); MiniGamePlayerResultDto toResultDto = new MiniGamePlayerResultDto();
@@ -624,42 +652,38 @@ public class MiniGameForNavServiceImpl implements MiniGameForNavService {
} }
miniGameMatchRound.setRoundStatus(NavGameRoundStatusEnum.END.ordinal()); miniGameMatchRound.setRoundStatus(NavGameRoundStatusEnum.END.ordinal());
miniGameMatchRoundService.updateById(miniGameMatchRound); miniGameMatchRoundService.updateById(miniGameMatchRound);
results.add(toResultDto); results.add(toResultDto);
roundDto.setResults(results.stream().sorted(Comparator.comparingInt(MiniGamePlayerResultDto::getRank)).collect(Collectors.toList())); roundDto.setResults(results.stream().sorted(Comparator.comparingInt(MiniGamePlayerResultDto::getRank)).collect(Collectors.toList()));
sendSysMsgService.sendSingleRoomMessage(roomId, chatRoomId.toString(), Constant.DefMsgType.MINI_GAME_MATCH, Constant.DefMsgType.MINI_GAME_MATCH_FOR_RESULT, roundDto); sendSysMsgService.sendSingleRoomMessage(roomId, chatRoomId.toString(), Constant.DefMsgType.MINI_GAME_MATCH, Constant.DefMsgType.MINI_GAME_MATCH_FOR_RESULT, roundDto);
//删除缓存
jedisService.del(RedisKey.mini_game_match_round.getKey(String.valueOf(fromUid)));
jedisService.del(RedisKey.mini_game_match_round.getKey(String.valueOf(toUid)));
jedisService.del(RedisKey.mini_game_match_round.getKey(String.valueOf(roomId)));
//房间踢人 //房间踢人
erBanNetEaseService.kickMember(String.valueOf(roomId), String.valueOf(fromUid), String.valueOf(chatRoomId), null); erBanNetEaseService.kickMember(String.valueOf(roomId), String.valueOf(fromUid), String.valueOf(chatRoomId), null);
erBanNetEaseService.kickMember(String.valueOf(roomId), String.valueOf(toUid), String.valueOf(chatRoomId), null); erBanNetEaseService.kickMember(String.valueOf(roomId), String.valueOf(toUid), String.valueOf(chatRoomId), null);
//房间清理 //房间清理
miniGameForSudService.pushRoomClearEvent(fromMiniGameMatch.getMgId(), fromMiniGameMatch.getRoomId()); miniGameForSudService.pushRoomClearEvent(fromMiniGameMatch.getMgId(), fromMiniGameMatch.getRoomId());
//清理旧的匹配
for (int i = 1, len = miniGameMatchRounds.size(); i < len; i++) {
MiniGameMatchRound gameMatchRound = miniGameMatchRounds.get(i);
matchForEqualize(gameMatchRound.getId());
}
} catch (Exception e) { } catch (Exception e) {
log.error(e.getMessage(), e); log.error(e.getMessage(), e);
} finally { } finally {
jedisLockService.unlock(lockKey, lockVal); if (locked){
lock.unlock();
}
} }
} }
@Override @Override
public ChatRoomVo resumeRoom(Long uid) { public ChatRoomVo resumeRoom(Long uid) {
List<MiniGameMatchRound> miniGameMatchRounds = miniGameMatchRoundService.list(Wrappers.<MiniGameMatchRound>lambdaQuery() MiniGameMatchRound miniGameMatchRound = miniGameMatchRoundService.getOne(Wrappers.<MiniGameMatchRound>lambdaQuery()
.and(w -> w.eq(MiniGameMatchRound::getFromUid, uid) .and(w -> w.eq(MiniGameMatchRound::getFromUid, uid)
.or() .or()
.eq(MiniGameMatchRound::getToUid, uid)) .eq(MiniGameMatchRound::getToUid, uid))
.eq(MiniGameMatchRound::getRoundStatus, NavGameRoundStatusEnum.PROCESS.ordinal()) .eq(MiniGameMatchRound::getRoundStatus, NavGameRoundStatusEnum.PROCESS.ordinal())
.orderByDesc(MiniGameMatchRound::getCreateTime)); .orderByDesc(MiniGameMatchRound::getId), false);
if (CollectionUtil.isEmpty(miniGameMatchRounds)) { if (null == miniGameMatchRound){
return null; return null;
} }
MiniGameMatchRound miniGameMatchRound = miniGameMatchRounds.get(0);
Long roomId = miniGameMatchRound.getRoomId(); Long roomId = miniGameMatchRound.getRoomId();
return chatRoomManageService.getByRoomId(roomId); return chatRoomManageService.getByRoomId(roomId);
} }

View File

@@ -3,8 +3,13 @@ package com.accompany.business.service.miniGame.impl;
import com.accompany.business.model.miniGame.MiniGameMatchRound; import com.accompany.business.model.miniGame.MiniGameMatchRound;
import com.accompany.business.mybatismapper.miniGame.MiniGameMatchRoundMapper; import com.accompany.business.mybatismapper.miniGame.MiniGameMatchRoundMapper;
import com.accompany.business.service.miniGame.MiniGameMatchRoundService; import com.accompany.business.service.miniGame.MiniGameMatchRoundService;
import com.accompany.common.redis.RedisKey;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RMap;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
/** /**
@@ -14,5 +19,20 @@ import org.springframework.stereotype.Service;
*/ */
@Slf4j @Slf4j
@Service @Service
public class MiniGameMatchRoundServiceImpl extends ServiceImpl<MiniGameMatchRoundMapper, MiniGameMatchRound> implements MiniGameMatchRoundService { public class MiniGameMatchRoundServiceImpl extends ServiceImpl<MiniGameMatchRoundMapper, MiniGameMatchRound> implements MiniGameMatchRoundService, InitializingBean {
@Autowired
private RedissonClient redissonClient;
private RMap<Long, Long> matchRoundMap;
@Override
public RMap<Long, Long> getMatchRoundMap(){
return matchRoundMap;
}
@Override
public void afterPropertiesSet() throws Exception {
matchRoundMap = redissonClient.getMap(RedisKey.mini_game_match_round.getKey());
}
} }

View File

@@ -3,16 +3,24 @@ package com.accompany.business.service.miniGame.impl;
import com.accompany.business.model.miniGame.MiniGameMatch; import com.accompany.business.model.miniGame.MiniGameMatch;
import com.accompany.business.mybatismapper.miniGame.MiniGameMatchMapper; import com.accompany.business.mybatismapper.miniGame.MiniGameMatchMapper;
import com.accompany.business.service.miniGame.MiniGameMatchService; import com.accompany.business.service.miniGame.MiniGameMatchService;
import com.accompany.common.redis.RedisKey;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RMap;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
/**
* @author: liaozetao
* @date: 2024/5/20 11:10
* @description:
*/
@Slf4j @Slf4j
@Service @Service
public class MiniGameMatchServiceImpl extends ServiceImpl<MiniGameMatchMapper, MiniGameMatch> implements MiniGameMatchService { public class MiniGameMatchServiceImpl extends ServiceImpl<MiniGameMatchMapper, MiniGameMatch> implements MiniGameMatchService {
@Autowired
private RedissonClient redissonClient;
@Override
public RMap<Long, MiniGameMatch> getWaitMatchMap(String mgId, Integer gameMode, Integer partitionId){
return redissonClient.getMap(RedisKey.mini_game_match_wait.getKey(mgId, String.valueOf(gameMode), String.valueOf(partitionId)));
}
} }

View File

@@ -2,6 +2,7 @@ package com.accompany.business.service.mq;
import com.accompany.business.message.*; import com.accompany.business.message.*;
import com.accompany.business.message.linearlypool.LinearlyPoolPrizeMessage; import com.accompany.business.message.linearlypool.LinearlyPoolPrizeMessage;
import com.accompany.business.model.miniGame.MiniGameMatchRound;
import com.accompany.mq.constant.MqConstant; import com.accompany.mq.constant.MqConstant;
import com.accompany.mq.producer.MQMessageProducer; import com.accompany.mq.producer.MQMessageProducer;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
@@ -133,4 +134,9 @@ public class RocketMQService {
}); });
} }
public void sendMiniGameMatchRoundMsg(MiniGameMatchRoundMessage msg) {
mqMessageProducer.send(MqConstant.MINI_GAME_MATCH_ROUND_TOPIC, msg, sendResult -> log.info("sendMiniGameMatchRoundMsg success message: {}", JSON.toJSONString(msg)), throwable ->
log.error("sendMiniGameMatchRoundMsg fail message: {}", JSON.toJSONString(msg), throwable), 4);
}
} }

View File

@@ -36,7 +36,7 @@ public class MiniGameForNavController {
* @return * @return
*/ */
@ApiOperation("游戏配置") @ApiOperation("游戏配置")
@GetMapping("config") @GetMapping("/config")
public BusiResult<MiniGameVo> config() { public BusiResult<MiniGameVo> config() {
return BusiResult.success(miniGameForNavService.getConfig()); return BusiResult.success(miniGameForNavService.getConfig());
} }
@@ -48,7 +48,7 @@ public class MiniGameForNavController {
* @return * @return
*/ */
@ApiOperation("开始游戏") @ApiOperation("开始游戏")
@PostMapping("start") @PostMapping("/start")
public BusiResult<Void> start(String mgId, Integer gameMode) { public BusiResult<Void> start(String mgId, Integer gameMode) {
miniGameForNavService.start(mgId, gameMode); miniGameForNavService.start(mgId, gameMode);
return BusiResult.success(); return BusiResult.success();
@@ -60,7 +60,7 @@ public class MiniGameForNavController {
* @return * @return
*/ */
@ApiOperation("关闭") @ApiOperation("关闭")
@GetMapping("close") @GetMapping("/close")
public BusiResult<Void> close(Long roomId) { public BusiResult<Void> close(Long roomId) {
chatRoomManageService.close(roomId, UidContextHolder.get()); chatRoomManageService.close(roomId, UidContextHolder.get());
return BusiResult.success(); return BusiResult.success();
@@ -72,7 +72,7 @@ public class MiniGameForNavController {
*/ */
@ApiOperation("恢复房间") @ApiOperation("恢复房间")
@ApiImplicitParam(name = "roomType", value = "房间类型 0 小游戏") @ApiImplicitParam(name = "roomType", value = "房间类型 0 小游戏")
@GetMapping("resumeRoom") @GetMapping("/resumeRoom")
public BusiResult<ChatRoomVo> resumeRoom() { public BusiResult<ChatRoomVo> resumeRoom() {
return BusiResult.success(miniGameForNavService.resumeRoom(UidContextHolder.get())); return BusiResult.success(miniGameForNavService.resumeRoom(UidContextHolder.get()));
} }

View File

@@ -21,15 +21,12 @@ public interface MqConstant {
String YI_DUN_TEXT_ANTI_CONSUME_GROUP = "yidun_text_anti_consume_group"; String YI_DUN_TEXT_ANTI_CONSUME_GROUP = "yidun_text_anti_consume_group";
String CHANGE_TOPIC = "charge_topic"; String CHANGE_TOPIC = "charge_topic";
String CHARGE_CONSUME_GROUP = "charge_consume_group"; String CHARGE_CONSUME_GROUP = "charge_consume_group";
String ACT_USER_TASK_TOPIC = "act_user_task_topic"; String ACT_USER_TASK_TOPIC = "act_user_task_topic";
String ACT_USER_TASK_CONSUME_GROUP = "act_user_task_consume_group"; String ACT_USER_TASK_CONSUME_GROUP = "act_user_task_consume_group";
String ACT_TASK_REWARD_TOPIC = "act_task_reward_topic"; String ACT_TASK_REWARD_TOPIC = "act_task_reward_topic";
String ACT_TASK_REWARD_CONSUME_GROUP = "act_task_reward_consume_group"; String ACT_TASK_REWARD_CONSUME_GROUP = "act_task_reward_consume_group";
String LUCKY_24_TOPIC = "lucky_24_topic"; String LUCKY_24_TOPIC = "lucky_24_topic";
@@ -41,4 +38,7 @@ public interface MqConstant {
String BRAVO_TOPIC = "bravo_topic"; String BRAVO_TOPIC = "bravo_topic";
String BRAVO_CONSUME_GROUP = "bravo_consume_group"; String BRAVO_CONSUME_GROUP = "bravo_consume_group";
String MINI_GAME_MATCH_ROUND_TOPIC = "mini_game_match_round_topic";
String MINI_GAME_MATCH_ROUND_CONSUME_GROUP = "mini_game_match_round_consume_group";
} }

View File

@@ -0,0 +1,46 @@
package com.accompany.mq.consumer;
import com.accompany.business.dto.miniGame.MiniGameMatchRoundDto;
import com.accompany.business.message.MiniGameMatchRoundMessage;
import com.accompany.business.model.miniGame.MiniGameMatchRound;
import com.accompany.business.service.SendSysMsgService;
import com.accompany.business.service.chat.ChatRoomManageService;
import com.accompany.business.service.miniGame.MiniGameForNavService;
import com.accompany.business.vo.chat.ChatRoomVo;
import com.accompany.common.constant.Constant;
import com.accompany.mq.constant.MqConstant;
import com.accompany.mq.listener.AbstractMessageListener;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;
@Slf4j
@Component
@ConditionalOnProperty(name = "spring.application.name", havingValue = "web")
@RocketMQMessageListener(topic = MqConstant.MINI_GAME_MATCH_ROUND_TOPIC, consumerGroup = MqConstant.MINI_GAME_MATCH_ROUND_CONSUME_GROUP)
public class MiniGameMatchRoundMessageConsumer extends AbstractMessageListener<MiniGameMatchRoundMessage> {
@Autowired
private MiniGameForNavService navService;
@Autowired
private ChatRoomManageService chatRoomManageService;
@Autowired
private SendSysMsgService sendSysMsgService;
@Override
protected void onMessage(MiniGameMatchRoundMessage message) {
log.info("onMessage miniGameMatchRoundMessage: {}", message.toString());
MiniGameMatchRound round = message.getRound();
if (navService.matchForSuccess(round.getId())){
return;
}
navService.matchForEqualize(round.getId());
//聊天室
ChatRoomVo chatRoomVo = chatRoomManageService.getByRoomId(round.getRoomId());
//匹配失败
sendSysMsgService.sendSingleRoomMessage(round.getRoomId(), chatRoomVo.getChatRoomId().toString(), Constant.DefMsgType.MINI_GAME_MATCH, Constant.DefMsgType.MINI_GAME_MATCH_FOR_FAIL, new MiniGameMatchRoundDto());
}
}