Browse Source

join game

master
6 years ago
parent
commit
32ba3acfe8
  1. 4
      game/src/main/java/com/ccsens/game/bean/dto/ClientDto.java
  2. 50
      game/src/main/java/com/ccsens/game/bean/vo/ClientVo.java
  3. 9
      game/src/main/java/com/ccsens/game/persist/dao/GameUserJoinDao.java
  4. 121
      game/src/main/java/com/ccsens/game/service/ClientService.java
  5. 9
      game/src/main/java/com/ccsens/game/util/GameConstant.java
  6. 16
      game/src/main/resources/mapper_dao/GameUserJoinDao.xml
  7. 65
      util/src/main/java/com/ccsens/util/RedisUtil.java

4
game/src/main/java/com/ccsens/game/bean/dto/ClientDto.java

@ -22,5 +22,9 @@ public class ClientDto {
@NotNull(message = "请选择的时间") @NotNull(message = "请选择的时间")
@ApiModelProperty("本地时间") @ApiModelProperty("本地时间")
private Long localTime; private Long localTime;
@ApiModelProperty
@NotNull(message = "请选择项目")
private Long projectId;
} }
} }

50
game/src/main/java/com/ccsens/game/bean/vo/ClientVo.java

@ -15,6 +15,56 @@ public class ClientVo {
public static class Join{ public static class Join{
@ApiModelProperty("游戏状态") @ApiModelProperty("游戏状态")
private Byte gameStatus; private Byte gameStatus;
@ApiModelProperty("游戏总人数")
private Long countMembers;
@ApiModelProperty("未开始")
private PendingData pendingData;
@ApiModelProperty("准备中")
private PreparingData preparingData;
@ApiModelProperty("进行中")
private ProcessingData processingData;
@ApiModelProperty("已结束")
private CompletedData completedData;
} }
/**
* 未开始
*/
@Data
@ApiModel("ClientVoPendingData")
public static class PendingData{
}
@Data
@ApiModel("ClientVoPreparingData")
public static class PreparingData{
@ApiModelProperty("客户端开始时间")
private Long startLocalTime;
@ApiModelProperty("客户端结束时间")
private Long endLocalTime;
}
@Data
@ApiModel("ClientVoProcessingData")
public static class ProcessingData{
@ApiModelProperty("客户端开始时间")
private Long startLocalTime;
@ApiModelProperty("客户端结束时间")
private Long endLocalTime;
}
@Data
@ApiModel("ClientVoCompletedData")
public static class CompletedData{
@ApiModelProperty("次数")
private Integer times;
@ApiModelProperty("分数")
private Integer score;
@ApiModelProperty("排名次序")
private Integer sort;
@ApiModelProperty("超过百分之多少人")
private Integer over;
}
} }

9
game/src/main/java/com/ccsens/game/persist/dao/GameUserJoinDao.java

@ -1,8 +1,17 @@
package com.ccsens.game.persist.dao; package com.ccsens.game.persist.dao;
import com.ccsens.game.persist.mapper.GameUserJoinMapper; import com.ccsens.game.persist.mapper.GameUserJoinMapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
@Repository @Repository
public interface GameUserJoinDao extends GameUserJoinMapper { public interface GameUserJoinDao extends GameUserJoinMapper {
/**
* 获取排名
* @param userId
* @param recordId
* @return
*/
int getRanking(@Param("userId") Long userId, @Param("recordId") Long recordId);
} }

121
game/src/main/java/com/ccsens/game/service/ClientService.java

@ -1,15 +1,17 @@
package com.ccsens.game.service; package com.ccsens.game.service;
import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Snowflake;
import com.ccsens.game.bean.dto.ClientDto; import com.ccsens.game.bean.dto.ClientDto;
import com.ccsens.game.bean.po.GameMemberJoin;
import com.ccsens.game.bean.po.GameMemberJoinExample;
import com.ccsens.game.bean.po.GameRecord; import com.ccsens.game.bean.po.GameRecord;
import com.ccsens.game.bean.po.GameUserJoin;
import com.ccsens.game.bean.po.GameUserJoinExample;
import com.ccsens.game.bean.vo.ClientVo; import com.ccsens.game.bean.vo.ClientVo;
import com.ccsens.game.persist.dao.GameMemberJoinDao;
import com.ccsens.game.persist.dao.GameRecordDao; import com.ccsens.game.persist.dao.GameRecordDao;
import com.ccsens.game.persist.dao.GameUserJoinDao;
import com.ccsens.game.util.GameConstant; import com.ccsens.game.util.GameConstant;
import com.ccsens.util.CodeEnum; import com.ccsens.util.CodeEnum;
import com.ccsens.util.RedisUtil;
import com.ccsens.util.exception.BaseException; import com.ccsens.util.exception.BaseException;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -19,6 +21,7 @@ import org.springframework.transaction.annotation.Transactional;
import java.util.List; import java.util.List;
/** /**
* @description: * @description:
* @author: wuHuiJuan * @author: wuHuiJuan
@ -30,24 +33,20 @@ import java.util.List;
public class ClientService implements IClientService { public class ClientService implements IClientService {
@Autowired @Autowired
private GameMemberJoinDao gameMemberJoinDao; private GameUserJoinDao gameUserJoinDao;
@Autowired @Autowired
private GameRecordDao gameRecordDao; private GameRecordDao gameRecordDao;
@Autowired
private Snowflake snowflake;
@Autowired
private RedisUtil redisUtil;
@Override @Override
public ClientVo.Join join(ClientDto.Join join, Long userId) { public ClientVo.Join join(ClientDto.Join join, Long userId) {
log.info("加入游戏:{}, userId:{}", join, userId); log.info("加入游戏:{}, userId:{}", join, userId);
ClientVo.Join joinVo = new ClientVo.Join();
//根据游戏ID和用户ID查询用户是否加入 int timeMore = (int)(join.getLocalTime() - System.currentTimeMillis());
GameMemberJoinExample example = new GameMemberJoinExample(); log.info("{}时间差:{}", userId, timeMore);
example.createCriteria().andRecordIdEqualTo(join.getUrlId()).andMemberIdEqualTo(userId);
List<GameMemberJoin> gameMemberJoins = gameMemberJoinDao.selectByExample(example);
if (CollectionUtil.isNotEmpty(gameMemberJoins)) {
Long localStartTime = gameMemberJoins.get(0).getLocalStartTime();
log.info("用户已加入该游戏,直接返回开始时间{}", localStartTime);
joinVo.setStartLocalTime(localStartTime);
return joinVo;
}
//获取游戏信息 //获取游戏信息
GameRecord gameRecord = gameRecordDao.selectByPrimaryKey(join.getUrlId()); GameRecord gameRecord = gameRecordDao.selectByPrimaryKey(join.getUrlId());
log.info("游戏信息:{}", gameRecord); log.info("游戏信息:{}", gameRecord);
@ -56,10 +55,98 @@ public class ClientService implements IClientService {
throw new BaseException(CodeEnum.PARAM_ERROR); throw new BaseException(CodeEnum.PARAM_ERROR);
} }
//判断游戏状态 //根据游戏ID和用户ID查询用户是否加入
gameRecord.getGameStatus().byteValue() == GameConstant.GAME_END GameUserJoinExample example = new GameUserJoinExample();
example.createCriteria().andRecordIdEqualTo(join.getUrlId()).andUserIdEqualTo(userId);
List<GameUserJoin> gameUserJoins = gameUserJoinDao.selectByExample(example);
// 已加入
if (CollectionUtil.isNotEmpty(gameUserJoins)) {
//查询结果,返回对应的信息
return joinResult(gameUserJoins.get(0), gameRecord);
}
//游戏已结束
if (gameRecord.getGameStatus().byteValue() == GameConstant.GAME_COMPLETED) {
ClientVo.Join joinVo = initStatusAndCount(gameRecord);
ClientVo.CompletedData completedData = new ClientVo.CompletedData();
completedData.setTimes(0);
completedData.setScore(0);
completedData.setSort(joinVo.getCountMembers().intValue() + 1);
completedData.setOver(0);
joinVo.setCompletedData(completedData);
return joinVo;
}
// 2.保存游戏路径用户表(设置游戏路径ID+用户ID组合为唯一索引 replace)
GameUserJoin userJoin = new GameUserJoin();
userJoin.setId(snowflake.nextId());
userJoin.setUserId(userId);
userJoin.setRecordId(join.getUrlId());
userJoin.setTimeDifference(timeMore);
boolean prepare = gameRecord.getGameStatus().byteValue() == GameConstant.GAME_PREPARATION;
boolean processing = gameRecord.getGameStatus().byteValue() == GameConstant.GAME_PROCESSING;
userJoin.setLocalStartTime(prepare || processing ? gameRecord.getStartTime() + timeMore : 0);
userJoin.setLocalStartTime(prepare || processing ? gameRecord.getEndTime() + timeMore : 0);
gameUserJoinDao.insertSelective(userJoin);
// 3.更新redis(sort set key:分数 value:头像,姓名)
//4.根据状态延时发送消息
//5.返回状态
return null; return null;
} }
private ClientVo.Join joinResult(GameUserJoin join, GameRecord gameRecord){
ClientVo.Join joinVo = initStatusAndCount(gameRecord);
switch (gameRecord.getGameStatus()) {
case GameConstant.GAME_PENDING :
// 未开始
joinVo.setPendingData(new ClientVo.PendingData());
break;
case GameConstant.GAME_PREPARATION :
// 准备中
ClientVo.PreparingData preparingData = new ClientVo.PreparingData();
preparingData.setStartLocalTime(join.getLocalStartTime());
preparingData.setEndLocalTime(join.getLocalEndTime());
joinVo.setPreparingData(preparingData);
break;
case GameConstant.GAME_PROCESSING :
// 进行中
ClientVo.ProcessingData processingData = new ClientVo.ProcessingData();
processingData.setStartLocalTime(join.getLocalStartTime());
processingData.setEndLocalTime(join.getLocalEndTime());
joinVo.setProcessingData(processingData);
break;
case GameConstant.GAME_COMPLETED :
//已结束
ClientVo.CompletedData completedData = new ClientVo.CompletedData();
completedData.setTimes(Integer.parseInt(join.getTimes()));
completedData.setScore(Integer.parseInt(join.getScore()));
completedData.setSort(gameUserJoinDao.getRanking(join.getUserId(), join.getUserId()));
// TODO 超过百分之几的用户
joinVo.setCompletedData(completedData);
break;
default: break;
}
log.info("参加游戏:{}", joinVo);
return joinVo;
}
/**
* 设置状态和总人数
* @param gameRecord
*/
private ClientVo.Join initStatusAndCount(GameRecord gameRecord) {
ClientVo.Join joinVo = new ClientVo.Join();
// 游戏状态
joinVo.setGameStatus(gameRecord.getGameStatus());
// 总人数
// GameUserJoinExample userJoinExample = new GameUserJoinExample();
// userJoinExample.createCriteria().andRecordIdEqualTo(gameRecord.getId());
// long count = gameUserJoinDao.countByExample(userJoinExample);
joinVo.setCountMembers(redisUtil.zsGetSize(gameRecord.getId() + GameConstant.GAME_KEY));
return joinVo;
}
} }

9
game/src/main/java/com/ccsens/game/util/GameConstant.java

@ -8,14 +8,15 @@ package com.ccsens.game.util;
public class GameConstant { public class GameConstant {
/**游戏状态:未开始*/ /**游戏状态:未开始*/
public static final byte GAME_NO_START = 0; public static final byte GAME_PENDING = 0;
/**游戏状态:准备中*/ /**游戏状态:准备中*/
public static final byte GAME_PREPARATION = 1; public static final byte GAME_PREPARATION = 1;
/**游戏状态:进行中*/ /**游戏状态:进行中*/
public static final byte GAME_STARTED = 2; public static final byte GAME_PROCESSING = 2;
/**游戏状态:已结束*/ /**游戏状态:已结束*/
public static final byte GAME_END = 3; public static final byte GAME_COMPLETED = 3;
/**游戏key*/
public static final String GAME_KEY = "_game";
} }

16
game/src/main/resources/mapper_dao/GameUserJoinDao.xml

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ccsens.game.persist.dao.GameUserJoinDao">
<select id="getRanking" resultType="int">
SELECT rowNo FROM
(
SELECT user_id,(@rowNum:=@rowNum+1) AS rowNo
FROM
(select user_id,score from t_game_user_join where rec_status = 0 and record_id = #{recordId,jdbcType=BIGINT}) a,
(SELECT(@rowNum:=0)) b
ORDER BY a.score DESC
) c
WHERE c.user_id= #{userId,jdbcType=BIGINT} limit 1
</select>
</mapper>

65
util/src/main/java/com/ccsens/util/RedisUtil.java

@ -560,4 +560,69 @@ public class RedisUtil {
} }
} }
/**
* 获取sort set缓存的内容
* @author whj
* @date 2019/8/1
* @param key
* @param start 开始 0:第一个元素
* @param end 结束 -1代表所有
* @return java.util.Set<java.lang.Object>
*/
public Set<Object> zsGet(String key, long start, long end) {
return redisTemplate.opsForZSet().range(key, start, end);
}
/**
* 添加zset
* @author whj
* @date 2019/8/1
* @param key
* @param value
* @param score
* @return boolean
*/
public boolean zsSet(String key, Object value, double score) {
return redisTemplate.opsForZSet().add(key, value, score);
}
/**
* 添加zset
* @author whj
* @date 2019/8/1
* @param key
* @param value
* @param score
* @return boolean
*/
public boolean zsSet(String key, Object value, double score, long time) {
redisTemplate.opsForZSet().add(key, value, score);
if (time > 0) {
expire(key, time);
} else {
zsDel(key, value);
}
return true;
}
/**
* 获取zset长度
* @author whj
* @date 2019/8/1
* @param key
* @return
*/
public long zsGetSize(String key) {
return redisTemplate.opsForZSet().size(key);
}
public long zsDel(String key, Object... values) {
return redisTemplate.opsForZSet().remove(key, values);
}
public Object zsGetScore(String key, Object value) {
return redisTemplate.opsForZSet().score(key, value);
}
} }

Loading…
Cancel
Save