ludo-matchForAi
This commit is contained in:
@@ -227,7 +227,6 @@ public class RoomAdminController extends BaseController {
|
||||
try {
|
||||
int result = roomSearchAdminService.resetRoomTitleAndIntro(uid, title, roomDesc, introduction);
|
||||
if (result > 0) {
|
||||
usersService.updateUserTime(uid);
|
||||
return new BusiResult<>(BusiStatus.SUCCESS);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
@@ -1305,6 +1305,8 @@ public enum RedisKey {
|
||||
//游戏匹配锁
|
||||
mini_game_match_round_lock,
|
||||
|
||||
mini_game_match_ai_count,
|
||||
|
||||
//已使用
|
||||
chat_room,
|
||||
|
||||
|
@@ -44,9 +44,11 @@ public interface UsersMapperExpend {
|
||||
*/
|
||||
List<Users> getRobotUser(@Param("gender") Byte gender, @Param("limit") int limit);
|
||||
|
||||
int updateUserTime(@Param("uid") Long uid);
|
||||
|
||||
int updateUserTimeByErbanNo(@Param("erbanNo") Long erbanNo);
|
||||
/**
|
||||
* 获取机器人账号
|
||||
* @return
|
||||
*/
|
||||
List<Users> listGameMatchRobotUser(@Param("partitionId") Integer partitionId);
|
||||
|
||||
List<Long> getUidByPage(@Param("offset") int offset, @Param("limit") int limit);
|
||||
|
||||
|
@@ -95,25 +95,31 @@ public class ChatRoomForMiniGameService implements IChatRoom {
|
||||
public Map<String, Object> getExtraData(ChatRoom chatRoom) {
|
||||
Long chatRoomId = chatRoom.getChatRoomId();
|
||||
Long roomId = chatRoom.getRoomId();
|
||||
List<MiniGameMatch> miniGameMatches = miniGameMatchService.list(Wrappers.<MiniGameMatch>lambdaQuery()
|
||||
.eq(MiniGameMatch::getRoomId, roomId)
|
||||
.notIn(MiniGameMatch::getMatchStatus, NavGameMatchStatusEnum.FINISH.ordinal(), NavGameMatchStatusEnum.FAIL.ordinal())
|
||||
.orderByDesc(MiniGameMatch::getCreateTime));
|
||||
if (CollectionUtil.isEmpty(miniGameMatches)) {
|
||||
|
||||
RMap<Long, Long> matchRoundMap = miniGameMatchRoundService.getMatchRoundMap();
|
||||
Long toMatchId = matchRoundMap.get(roomId);
|
||||
if (null == toMatchId){
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
MiniGameMatch miniGameMatch = miniGameMatches.get(0);
|
||||
Long miniGameMatchId = miniGameMatch.getId();
|
||||
List<MiniGameMatchRound> miniGameMatchRounds = miniGameMatchRoundService.list(Wrappers.<MiniGameMatchRound>lambdaQuery()
|
||||
.and(w -> w.eq(MiniGameMatchRound::getFromMatchId, miniGameMatchId).or().eq(MiniGameMatchRound::getToMatchId, miniGameMatchId))
|
||||
.eq(MiniGameMatchRound::getRoundStatus, NavGameRoundStatusEnum.PROCESS.ordinal()));
|
||||
|
||||
MiniGameMatch miniGameMatch = miniGameMatchService.getById(toMatchId);
|
||||
if (null == miniGameMatch
|
||||
|| miniGameMatch.getMatchStatus().equals(NavGameMatchStatusEnum.FINISH.ordinal())
|
||||
|| miniGameMatch.getMatchStatus().equals(NavGameMatchStatusEnum.FAIL.ordinal())){
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
MiniGameMatchRound miniGameMatchRound = miniGameMatchRoundService.getOne(Wrappers.<MiniGameMatchRound>lambdaQuery()
|
||||
.eq(MiniGameMatchRound::getToMatchId, toMatchId)
|
||||
.eq(MiniGameMatchRound::getRoundStatus, NavGameRoundStatusEnum.PROCESS.ordinal()), false);
|
||||
if (null == miniGameMatchRound){
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
//匹配状态
|
||||
Integer gameMode = miniGameMatch.getGameMode();
|
||||
MiniGameForNavConfigDto config = sysConfService.getJsonValueById(Constant.SysConfId.MINI_GAME_FOR_NAV, MiniGameForNavConfigDto.class);
|
||||
if (config == null) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
String mgId = config.getMgId();
|
||||
MiniGameForNavConfigDto config = miniGameForNavService.getConfigDto();
|
||||
Integer gameMode = miniGameMatchRound.getGameMode();
|
||||
String mgId = miniGameMatch.getMgId();
|
||||
MiniGame miniGame = miniGameService.queryMiniGameByMgId(Long.valueOf(mgId));
|
||||
//游戏配置
|
||||
ChatRoomForMiniGameDto dto = new ChatRoomForMiniGameDto();
|
||||
@@ -124,19 +130,18 @@ public class ChatRoomForMiniGameService implements IChatRoom {
|
||||
dto.setGameRoomIcon(gameRoomIcon.get(locale.getLanguage()));
|
||||
}
|
||||
dto.setMatchStatus(miniGameMatch.getMatchStatus());
|
||||
if (CollectionUtil.isNotEmpty(miniGameMatchRounds)) {
|
||||
MiniGameMatchRound miniGameMatchRound = miniGameMatchRounds.get(0);
|
||||
dto.setMatchRoundId(miniGameMatchRound.getId());
|
||||
dto.setRoundStatus(miniGameMatchRound.getRoundStatus());
|
||||
Long fromUid = miniGameMatchRound.getFromUid();
|
||||
Long toUid = miniGameMatchRound.getToUid();
|
||||
if (fromUid != null) {
|
||||
SpringContextHolder.getBean(ChatRoomManageServiceImpl.class).upMic(chatRoomId, 0, fromUid);
|
||||
}
|
||||
if (toUid != null) {
|
||||
SpringContextHolder.getBean(ChatRoomManageServiceImpl.class).upMic(chatRoomId, 1, toUid);
|
||||
}
|
||||
dto.setMatchRoundId(miniGameMatchRound.getId());
|
||||
dto.setRoundStatus(miniGameMatchRound.getRoundStatus());
|
||||
|
||||
Long fromUid = miniGameMatchRound.getFromUid();
|
||||
Long toUid = miniGameMatchRound.getToUid();
|
||||
if (fromUid != null) {
|
||||
SpringContextHolder.getBean(ChatRoomManageServiceImpl.class).upMic(chatRoomId, 0, fromUid);
|
||||
}
|
||||
if (toUid != null) {
|
||||
SpringContextHolder.getBean(ChatRoomManageServiceImpl.class).upMic(chatRoomId, 1, toUid);
|
||||
}
|
||||
|
||||
Map<Integer, GameModeDto> gameModeMap = config.getGameModeMap();
|
||||
GameModeDto gameModeDto = gameModeMap.get(gameMode);
|
||||
String APP_COMMON_GAME_SETTING_SELECT_INFO = "app_common_game_setting_select_info";
|
||||
|
@@ -0,0 +1,102 @@
|
||||
package com.accompany.business.service.miniGame;
|
||||
|
||||
import com.accompany.business.enums.game.NavGameMatchStatusEnum;
|
||||
import com.accompany.business.model.miniGame.MiniGameMatch;
|
||||
import com.accompany.business.mybatismapper.UsersMapperExpend;
|
||||
import com.accompany.business.service.chat.ChatRoomManageService;
|
||||
import com.accompany.business.service.user.UsersService;
|
||||
import com.accompany.common.constant.Constant;
|
||||
import com.accompany.common.redis.RedisKey;
|
||||
import com.accompany.common.utils.AppVersionUtil;
|
||||
import com.accompany.core.model.Users;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
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.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
public class MiniGameMatchAiService {
|
||||
|
||||
@Autowired
|
||||
private RedissonClient redissonClient;
|
||||
@Autowired
|
||||
private UsersMapperExpend usersMapperExpend;
|
||||
@Autowired
|
||||
private UsersService usersService;
|
||||
@Autowired
|
||||
private MiniGameMatchService matchService;
|
||||
@Autowired
|
||||
@Lazy
|
||||
private MiniGameForNavService miniGameForNavService;
|
||||
@Autowired
|
||||
private ChatRoomManageService chatRoomManageService;
|
||||
|
||||
private final String AI_ANDROID_APP_VERSION_LIMIT = "1.0.25";
|
||||
private final String AI_IOS_APP_VERSION_LIMIT = "20.20.56";
|
||||
|
||||
public boolean matchForAi(MiniGameMatch fromMiniGameMatch) {
|
||||
// Users u = usersService.getNotNullUsersByUid(fromMiniGameMatch.getUid());
|
||||
// if (Constant.OsType.ANDROID.equalsIgnoreCase(u.getOs()) && AppVersionUtil.compareVersion(u.getAppVersion(), AI_ANDROID_APP_VERSION_LIMIT) <= 0){
|
||||
// return false;
|
||||
// } else if (Constant.OsType.IOS.equalsIgnoreCase(u.getOs()) && AppVersionUtil.compareVersion(u.getAppVersion(), AI_IOS_APP_VERSION_LIMIT) <= 0) {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
List<Users> robotUsers = usersMapperExpend.listGameMatchRobotUser(fromMiniGameMatch.getPartitionId());
|
||||
if (CollectionUtils.isEmpty(robotUsers)){
|
||||
log.error("[ludo] 匹配ai 当前分区 {} 没有可用的赛事机器人了", fromMiniGameMatch.getPartitionId());
|
||||
return false;
|
||||
}
|
||||
|
||||
Set<Long> robotUidSet = robotUsers.stream().map(Users::getUid).collect(Collectors.toSet());
|
||||
RMap<Long, Integer> matchAiCountMap = getMatchAiCountMap(fromMiniGameMatch.getUid());
|
||||
Map<Long, Integer> matchCountMap = matchAiCountMap.getAll(robotUidSet);
|
||||
|
||||
int minMatchCount = !CollectionUtils.isEmpty(matchCountMap) ? matchCountMap.values().stream().min(Integer::compareTo).get(): 0;
|
||||
Long robotUid = minMatchCount <= 0? robotUidSet.iterator().next():
|
||||
matchCountMap.entrySet().stream().filter(it -> it.getValue().equals(minMatchCount)).map(Map.Entry::getKey).findAny().get();
|
||||
|
||||
Date now = new Date();
|
||||
//保存匹配记录
|
||||
MiniGameMatch toMiniGameMatch = new MiniGameMatch();
|
||||
toMiniGameMatch.setUid(robotUid);
|
||||
toMiniGameMatch.setRoomId(fromMiniGameMatch.getRoomId());
|
||||
toMiniGameMatch.setMgId(fromMiniGameMatch.getMgId());
|
||||
toMiniGameMatch.setGameMode(fromMiniGameMatch.getGameMode());
|
||||
toMiniGameMatch.setMatchStatus(NavGameMatchStatusEnum.WAIT.ordinal());
|
||||
toMiniGameMatch.setTicket(0d);
|
||||
toMiniGameMatch.setPartitionId(fromMiniGameMatch.getPartitionId());
|
||||
toMiniGameMatch.setCreateTime(now);
|
||||
toMiniGameMatch.setUpdateTime(now);
|
||||
matchService.save(toMiniGameMatch);
|
||||
|
||||
//匹配
|
||||
miniGameForNavService.match(fromMiniGameMatch, toMiniGameMatch);
|
||||
|
||||
//手动触发进入聊天室
|
||||
chatRoomManageService.enter(fromMiniGameMatch.getRoomId(), robotUid);
|
||||
|
||||
Integer afterNum = matchAiCountMap.addAndGet(robotUid, 1);
|
||||
matchAiCountMap.expire(Instant.ofEpochSecond(now.getTime() + 60 * 60 * 24 * 7));
|
||||
|
||||
log.info("[ludo] 匹配ai 成功 fromMatch {} uid {} robotUid {} afterNum {}",
|
||||
JSON.toJSONString(fromMiniGameMatch), fromMiniGameMatch.getUid(), robotUid, afterNum);
|
||||
return true;
|
||||
}
|
||||
|
||||
private RMap<Long, Integer> getMatchAiCountMap(Long uid){
|
||||
return redissonClient.getMap(RedisKey.mini_game_match_ai_count.getKey(uid.toString()));
|
||||
}
|
||||
}
|
@@ -108,6 +108,9 @@ public class MiniGameForNavServiceImpl implements MiniGameForNavService {
|
||||
@Autowired
|
||||
private UserInRoomService userInRoomService;
|
||||
|
||||
@Autowired
|
||||
private MiniGameMatchAiService miniGameMatchAiService;
|
||||
|
||||
@Autowired
|
||||
private RedissonClient redissonClient;
|
||||
|
||||
@@ -237,6 +240,7 @@ public class MiniGameForNavServiceImpl implements MiniGameForNavService {
|
||||
//初始化
|
||||
if (null == roomId){
|
||||
ChatRoomServiceFactory.getServiceByType(ChatRoomTypeEnum.MINI_GAME.ordinal()).init(toChatRoom);
|
||||
roomId = toChatRoom.getRoomId();
|
||||
}
|
||||
|
||||
//保存匹配记录
|
||||
@@ -281,9 +285,10 @@ public class MiniGameForNavServiceImpl implements MiniGameForNavService {
|
||||
try {
|
||||
for (int i = 0; i < matchSeconds; i++) {
|
||||
log.info("fromMatchId : {}, roomId : {}, polling process match second : {}", toMiniGameMatch.getId(), toMiniGameMatch.getRoomId(), i);
|
||||
if (matchForPolling(toMiniGameMatch)) {
|
||||
if (matchForPolling(toMiniGameMatch, i)) {
|
||||
return;
|
||||
}
|
||||
|
||||
TimeUnit.SECONDS.sleep(1);
|
||||
}
|
||||
//匹配失败
|
||||
@@ -295,11 +300,11 @@ public class MiniGameForNavServiceImpl implements MiniGameForNavService {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean matchForPolling(MiniGameMatch fromMiniGameMatch) {
|
||||
private boolean matchForPolling(MiniGameMatch fromMiniGameMatch, int second) {
|
||||
RMap<Long, Long> matchRoundMap = miniGameMatchRoundService.getMatchRoundMap();
|
||||
Long roundId = matchRoundMap.get(fromMiniGameMatch.getRoomId());
|
||||
if (null == roundId){
|
||||
return false;
|
||||
return (second == 9 && matchForAi(fromMiniGameMatch));
|
||||
}
|
||||
|
||||
RMap<Long, MiniGameMatch> waitGameMatchMap = miniGameMatchService.getWaitMatchMap(fromMiniGameMatch.getMgId(), fromMiniGameMatch.getGameMode(), fromMiniGameMatch.getPartitionId());
|
||||
@@ -342,11 +347,17 @@ public class MiniGameForNavServiceImpl implements MiniGameForNavService {
|
||||
}
|
||||
|
||||
//释放资源
|
||||
chatRoomService.releaseByRoomId(toMiniGameMatch.getRoomId());
|
||||
if (!fromMiniGameMatch.getRoomId().equals(toMiniGameMatch.getRoomId())){
|
||||
chatRoomService.releaseByRoomId(toMiniGameMatch.getRoomId());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean matchForAi(MiniGameMatch fromMiniGameMatch) {
|
||||
return miniGameMatchAiService.matchForAi(fromMiniGameMatch);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void matchForFail(MiniGameMatch miniGameMatch) {
|
||||
if (null == miniGameMatch || null == miniGameMatch.getUid()) {
|
||||
@@ -462,6 +473,9 @@ public class MiniGameForNavServiceImpl implements MiniGameForNavService {
|
||||
}
|
||||
Long roomId = fromMiniGameMatch.getRoomId();
|
||||
|
||||
RMap<Long, MiniGameMatch> waitMatchMap = miniGameMatchService.getWaitMatchMap(fromMiniGameMatch.getMgId(), fromMiniGameMatch.getGameMode(), fromMiniGameMatch.getPartitionId());
|
||||
|
||||
boolean quitWait = false;
|
||||
boolean locked = false;
|
||||
String redisKey = RedisKey.mini_game_match_round_lock.getKey(String.valueOf(roomId));
|
||||
RLock lock = redissonClient.getLock(redisKey);
|
||||
@@ -472,12 +486,14 @@ public class MiniGameForNavServiceImpl implements MiniGameForNavService {
|
||||
throw new ServiceException(BusiStatus.SERVERERROR);
|
||||
}
|
||||
|
||||
RMap<Long, MiniGameMatch> waitMatchMap = miniGameMatchService.getWaitMatchMap(fromMiniGameMatch.getMgId(), fromMiniGameMatch.getGameMode(), fromMiniGameMatch.getPartitionId());
|
||||
if (!waitMatchMap.containsKey(fromMiniGameMatch.getId())){
|
||||
MiniGameMatch waitFromMiniGameMatch = waitMatchMap.remove(fromMiniGameMatch.getId());
|
||||
if (null == waitFromMiniGameMatch){
|
||||
log.error("[ludo] 匹配 waitMatchMap 没有 from Id");
|
||||
throw new ServiceException(BusiStatus.SERVERERROR);
|
||||
}
|
||||
|
||||
quitWait = true;
|
||||
|
||||
boolean updateFromSuccess = miniGameMatchService.lambdaUpdate()
|
||||
.set(MiniGameMatch::getMatchStatus, NavGameMatchStatusEnum.SUCCESS.ordinal())
|
||||
.eq(MiniGameMatch::getId, fromMiniGameMatch.getId())
|
||||
@@ -504,7 +520,6 @@ public class MiniGameForNavServiceImpl implements MiniGameForNavService {
|
||||
miniGameMatchRoundService.save(round);
|
||||
|
||||
//设置麦位信息
|
||||
Long fromUid = fromMiniGameMatch.getUid();
|
||||
Long toUid = toMiniGameMatch.getUid();
|
||||
//聊天室
|
||||
ChatRoom fromChatRoom = chatRoomService.getByRoomId(fromMiniGameMatch.getRoomId());
|
||||
@@ -512,20 +527,24 @@ public class MiniGameForNavServiceImpl implements MiniGameForNavService {
|
||||
//上麦
|
||||
chatRoomManageService.upMic(fromChatRoom.getChatRoomId(), toUid);
|
||||
//下麦
|
||||
chatRoomManageService.downMic(toChatRoom.getChatRoomId(), toUid);
|
||||
if (!toChatRoom.getChatRoomId().equals(fromChatRoom.getChatRoomId())){
|
||||
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();
|
||||
}
|
||||
|
||||
if (quitWait){
|
||||
waitMatchMap.fastPut(fromMiniGameMatch.getId(), fromMiniGameMatch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -86,8 +86,6 @@ public abstract class AbstractRoomService implements IRoom {
|
||||
room.setBackPic(room.getDefBackpic());
|
||||
}
|
||||
}
|
||||
//更新user的update time
|
||||
usersService.updateUserTime(roomUid);
|
||||
Room roomDb = roomService.getRoomByDB(roomUid);
|
||||
if (roomDb != null) {
|
||||
Byte roomType = room.getType();
|
||||
|
@@ -1055,7 +1055,6 @@ public class RoomService extends BaseService {
|
||||
}
|
||||
room.setAudioSdkType(getAudioSdkTypeInConfig());
|
||||
insertRoom(room);
|
||||
usersService.updateUserTime(room.getUid());
|
||||
return room;
|
||||
}
|
||||
|
||||
|
@@ -704,14 +704,6 @@ public class UsersService extends BaseService {
|
||||
return false;
|
||||
}
|
||||
|
||||
public int updateUserTime(Long uid) {
|
||||
return usersMapperExpend.updateUserTime(uid);
|
||||
}
|
||||
|
||||
public int updateUserTimeByErbanNo(Long erbanNo) {
|
||||
return usersMapperExpend.updateUserTimeByErbanNo(erbanNo);
|
||||
}
|
||||
|
||||
public Users getUserByErbanNo(Long erbanNo) {
|
||||
String userStr = this.jedisService.hget(RedisKey.user_erban_no.getKey(), erbanNo.toString());
|
||||
if (!StringUtils.isEmpty(userStr)) {
|
||||
|
@@ -107,13 +107,6 @@
|
||||
</foreach>
|
||||
</update>
|
||||
|
||||
<update id="updateUserTime">
|
||||
update users set update_time = now() where uid = #{uid}
|
||||
</update>
|
||||
<update id="updateUserTimeByErbanNo">
|
||||
update users set update_time = now() where erban_no = #{erbanNo}
|
||||
</update>
|
||||
|
||||
<select id="getRobotUser" resultType="com.accompany.core.model.Users">
|
||||
SELECT <include refid="Base_Column_List"/> FROM users
|
||||
<include refid="robot_user_condition"></include>
|
||||
@@ -359,4 +352,10 @@
|
||||
group by u.partition_id, u.region_id
|
||||
</select>
|
||||
|
||||
<select id="listGameMatchRobotUser" resultMap="BaseResultMap">
|
||||
select * from users u
|
||||
where u.def_user = 6
|
||||
and u.partition_id = #{partitionId}
|
||||
</select>
|
||||
|
||||
</mapper>
|
Reference in New Issue
Block a user