|
@@ -10,20 +10,16 @@ import com.zanxiang.game.module.mybatis.entity.User;
|
|
|
import com.zanxiang.game.module.mybatis.mapper.GameUserRoleMapper;
|
|
|
import com.zanxiang.game.module.sdk.constant.RedisKeyConstant;
|
|
|
import com.zanxiang.game.module.sdk.enums.DataTypeEnum;
|
|
|
+import com.zanxiang.game.module.sdk.enums.KafkaEventTrackEnum;
|
|
|
import com.zanxiang.game.module.sdk.enums.LoginTypeEnum;
|
|
|
import com.zanxiang.game.module.sdk.pojo.param.GameRoleActiveCallParam;
|
|
|
import com.zanxiang.game.module.sdk.pojo.param.GameUserRoleUpdateParam;
|
|
|
import com.zanxiang.game.module.sdk.pojo.param.UserData;
|
|
|
import com.zanxiang.game.module.sdk.service.*;
|
|
|
import com.zanxiang.module.redis.service.IDistributedLockComponent;
|
|
|
-import com.zanxiang.module.util.DateUtil;
|
|
|
import com.zanxiang.module.util.JsonUtil;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
-import org.apache.kafka.clients.producer.Producer;
|
|
|
-import org.apache.kafka.clients.producer.ProducerRecord;
|
|
|
-import org.apache.logging.log4j.util.Strings;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
-import org.springframework.beans.factory.annotation.Qualifier;
|
|
|
import org.springframework.beans.factory.annotation.Value;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
@@ -41,36 +37,32 @@ import java.util.concurrent.TimeUnit;
|
|
|
@Service
|
|
|
public class GameUserRoleServiceImpl extends ServiceImpl<GameUserRoleMapper, GameUserRole> implements IGameUserRoleService {
|
|
|
|
|
|
- @Autowired
|
|
|
- private RestTemplate restTemplate;
|
|
|
-
|
|
|
- @Autowired
|
|
|
- private IGameUserService gameUserService;
|
|
|
+ @Value("${server.domain}")
|
|
|
+ private String serverUrl;
|
|
|
|
|
|
@Autowired
|
|
|
private IUserService userService;
|
|
|
|
|
|
@Autowired
|
|
|
- private IUserLoginLogService userLoginLogService;
|
|
|
+ private IKafkaService kafkaService;
|
|
|
|
|
|
@Autowired
|
|
|
- private IDistributedLockComponent distributedLockComponent;
|
|
|
+ private RestTemplate restTemplate;
|
|
|
|
|
|
@Autowired
|
|
|
- private IUserTokenService userTokenService;
|
|
|
+ private IGameUserService gameUserService;
|
|
|
|
|
|
@Autowired
|
|
|
private ICallBackService callBackService;
|
|
|
|
|
|
- @Value("${spring.kafka.game-sdk.gameRoleActiveTopic}")
|
|
|
- private String gameRoleActiveTopic;
|
|
|
+ @Autowired
|
|
|
+ private IUserTokenService userTokenService;
|
|
|
|
|
|
- @Value("${server.domain}")
|
|
|
- private String serverUrl;
|
|
|
+ @Autowired
|
|
|
+ private IUserLoginLogService userLoginLogService;
|
|
|
|
|
|
@Autowired
|
|
|
- @Qualifier("gameSdkKafkaProducer")
|
|
|
- private Producer<String, String> kafkaProducer;
|
|
|
+ private IDistributedLockComponent distributedLockComponent;
|
|
|
|
|
|
@Override
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
@@ -84,7 +76,7 @@ public class GameUserRoleServiceImpl extends ServiceImpl<GameUserRoleMapper, Gam
|
|
|
//创建角色
|
|
|
if (Objects.equals(dataType, DataTypeEnum.TYPE_CREATE_ROLE.getDateType())) {
|
|
|
//新建游戏角色
|
|
|
- this.createRoleUpdate(param, userData);
|
|
|
+ this.gameRoleCreate(param, userData);
|
|
|
//插入用户登录记录
|
|
|
return userLoginLogService.createRoleLoginLog(userData, param.getRoleId(), param.getRoleName(), LoginTypeEnum.LOGIN_IN.getLoginType());
|
|
|
}
|
|
@@ -96,7 +88,11 @@ public class GameUserRoleServiceImpl extends ServiceImpl<GameUserRoleMapper, Gam
|
|
|
//逻辑兜底, 万一角色未创建成功, 补充创建
|
|
|
if (gameUserRole == null) {
|
|
|
//新建游戏角色
|
|
|
- this.createRoleUpdate(param, userData);
|
|
|
+ this.gameRoleCreate(param, userData);
|
|
|
+ //刚创建的角色, 如果是更新请求, 则不需要执行
|
|
|
+ if (Objects.equals(dataType, DataTypeEnum.TYPE_LEVEL_UP.getDateType())) {
|
|
|
+ return Boolean.TRUE;
|
|
|
+ }
|
|
|
}
|
|
|
//进入游戏
|
|
|
if (Objects.equals(dataType, DataTypeEnum.TYPE_ENTER_GAME.getDateType())) {
|
|
@@ -105,22 +101,7 @@ public class GameUserRoleServiceImpl extends ServiceImpl<GameUserRoleMapper, Gam
|
|
|
}
|
|
|
//等级提升更新
|
|
|
if (Objects.equals(dataType, DataTypeEnum.TYPE_LEVEL_UP.getDateType())) {
|
|
|
- //更新频率限制, 20秒更新一次, 避免游戏实时战力高频上报
|
|
|
- if (!distributedLockComponent.doLock(RedisKeyConstant.ROLE_LEVEL_UP + userData.getUserId(), 0L, 20L, TimeUnit.SECONDS)) {
|
|
|
- return Boolean.TRUE;
|
|
|
- }
|
|
|
- return super.update(new LambdaUpdateWrapper<GameUserRole>()
|
|
|
- .set(GameUserRole::getRoleName, param.getRoleName())
|
|
|
- .set(GameUserRole::getRoleLevel, param.getRoleLevel())
|
|
|
- .set(gameUserRole == null || Strings.isBlank(gameUserRole.getServerId()), GameUserRole::getServerId, param.getServerId())
|
|
|
- .set(GameUserRole::getServerName, param.getServerName())
|
|
|
- .set(param.getRoleVipLevel() != null, GameUserRole::getRoleVipLevel, param.getRoleVipLevel())
|
|
|
- .set(param.getRolePower() != null, GameUserRole::getRolePower, param.getRolePower())
|
|
|
- .set(GameUserRole::getUpdateTime, param.getRoleGradeUpdateTime() == null || param.getRoleGradeUpdateTime() <= 0 ? LocalDateTime.now() : DateUtil.secondToLocalDateTime(param.getRoleGradeUpdateTime()))
|
|
|
- .set(param.getExtra() != null, GameUserRole::getExtra, JsonUtil.toString(param.getExtra()))
|
|
|
- .eq(GameUserRole::getUserId, userData.getUserId())
|
|
|
- .eq(GameUserRole::getGameId, userData.getGameId())
|
|
|
- .eq(GameUserRole::getRoleId, param.getRoleId()));
|
|
|
+ return this.gameRoleUpdate(param, gameUserRole, userData);
|
|
|
}
|
|
|
//退出游戏
|
|
|
if (Objects.equals(dataType, DataTypeEnum.TYPE_EXIT_GAME.getDateType())) {
|
|
@@ -130,7 +111,35 @@ public class GameUserRoleServiceImpl extends ServiceImpl<GameUserRoleMapper, Gam
|
|
|
return Boolean.FALSE;
|
|
|
}
|
|
|
|
|
|
- private void createRoleUpdate(GameUserRoleUpdateParam param, UserData userData) {
|
|
|
+ private boolean gameRoleUpdate(GameUserRoleUpdateParam param, GameUserRole gameUserRole, UserData userData) {
|
|
|
+ //更新频率限制, 20秒更新一次, 避免游戏实时战力高频上报
|
|
|
+ if (!distributedLockComponent.doLock(RedisKeyConstant.ROLE_LEVEL_UP + userData.getUserId(), 0L, 20L, TimeUnit.SECONDS)) {
|
|
|
+ return Boolean.TRUE;
|
|
|
+ }
|
|
|
+ //玩家角色信息更新
|
|
|
+ if (gameUserRole.getServerId() == null) {
|
|
|
+ gameUserRole.setServerId(param.getServerId());
|
|
|
+ }
|
|
|
+ if (param.getRoleVipLevel() != null) {
|
|
|
+ gameUserRole.setRoleVipLevel(param.getRoleVipLevel());
|
|
|
+ }
|
|
|
+ if (param.getRolePower() != null) {
|
|
|
+ gameUserRole.setRolePower(param.getRolePower());
|
|
|
+ }
|
|
|
+ if (param.getExtra() != null) {
|
|
|
+ gameUserRole.setExtra(JsonUtil.toString(param.getExtra()));
|
|
|
+ }
|
|
|
+ gameUserRole.setRoleName(param.getRoleName());
|
|
|
+ gameUserRole.setRoleLevel(param.getRoleLevel());
|
|
|
+ gameUserRole.setServerName(param.getServerName());
|
|
|
+ gameUserRole.setUpdateTime(LocalDateTime.now());
|
|
|
+ boolean result = super.updateById(gameUserRole);
|
|
|
+ //角色更新数据埋点发送到卡夫卡
|
|
|
+ kafkaService.eventTrack(KafkaEventTrackEnum.KAFKA_EVENT_TRACK_ROLE_UPDATE, JsonUtil.toString(gameUserRole));
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void gameRoleCreate(GameUserRoleUpdateParam param, UserData userData) {
|
|
|
//上锁
|
|
|
if (!distributedLockComponent.doLock(RedisKeyConstant.ROLE_UPDATE_KEY + "_" + userData.getUserId(), 0L, 1L, TimeUnit.MINUTES)) {
|
|
|
return;
|
|
@@ -148,7 +157,28 @@ public class GameUserRoleServiceImpl extends ServiceImpl<GameUserRoleMapper, Gam
|
|
|
return;
|
|
|
}
|
|
|
User user = userService.getById(userData.getUserId());
|
|
|
- userRole = GameUserRole.builder()
|
|
|
+ userRole = this.transform(param, userData, gameUser, user);
|
|
|
+ super.save(userRole);
|
|
|
+ //更新玩家创角数
|
|
|
+ gameUserService.update(new LambdaUpdateWrapper<GameUser>()
|
|
|
+ .setSql("role_count=role_count+" + 1)
|
|
|
+ .set(GameUser::getUpdateTime, LocalDateTime.now())
|
|
|
+ .eq(GameUser::getId, gameUser.getId()));
|
|
|
+ //更新用户创角数
|
|
|
+ userService.update(new LambdaUpdateWrapper<User>()
|
|
|
+ .setSql("role_count=role_count+" + 1)
|
|
|
+ .set(User::getUpdateTime, LocalDateTime.now())
|
|
|
+ .eq(User::getId, gameUser.getUserId()));
|
|
|
+ //用户创角回传
|
|
|
+ callBackService.roleCallBack(userRole, userData);
|
|
|
+ //用户创角埋点数据发送到卡夫卡
|
|
|
+ kafkaService.eventTrack(KafkaEventTrackEnum.KAFKA_EVENT_TRACK_ROLE_CREATE, JsonUtil.toString(userRole));
|
|
|
+ //释放锁
|
|
|
+ distributedLockComponent.unlock(RedisKeyConstant.ROLE_UPDATE_KEY + "_" + userData.getUserId());
|
|
|
+ }
|
|
|
+
|
|
|
+ private GameUserRole transform(GameUserRoleUpdateParam param, UserData userData, GameUser gameUser, User user) {
|
|
|
+ return GameUserRole.builder()
|
|
|
.userId(userData.getUserId())
|
|
|
.gameUserId(gameUser.getId())
|
|
|
.gameId(userData.getGameId())
|
|
@@ -161,26 +191,11 @@ public class GameUserRoleServiceImpl extends ServiceImpl<GameUserRoleMapper, Gam
|
|
|
.rolePower(param.getRolePower())
|
|
|
.os(userData.getDeviceSystem())
|
|
|
.regTime(user == null ? null : user.getCreateTime())
|
|
|
- .createTime(param.getRoleGradeUpdateTime() == null || param.getRoleGradeUpdateTime() <= 0 ? LocalDateTime.now() : DateUtil.secondToLocalDateTime(param.getRoleGradeUpdateTime()))
|
|
|
+ .createTime(LocalDateTime.now())
|
|
|
.updateTime(LocalDateTime.now())
|
|
|
.lastLoginTime(LocalDateTime.now())
|
|
|
.extra(param.getExtra() == null ? null : JsonUtil.toString(param.getExtra()))
|
|
|
.build();
|
|
|
- super.save(userRole);
|
|
|
- //更新玩家创角数
|
|
|
- gameUserService.update(new LambdaUpdateWrapper<GameUser>()
|
|
|
- .setSql("role_count=role_count+" + 1)
|
|
|
- .set(GameUser::getUpdateTime, LocalDateTime.now())
|
|
|
- .eq(GameUser::getId, gameUser.getId()));
|
|
|
- //更新用户创角数
|
|
|
- userService.update(new LambdaUpdateWrapper<User>()
|
|
|
- .setSql("role_count=role_count+" + 1)
|
|
|
- .set(User::getUpdateTime, LocalDateTime.now())
|
|
|
- .eq(User::getId, gameUser.getUserId()));
|
|
|
- //用户创角回传
|
|
|
- callBackService.roleCallBack(userRole, userData);
|
|
|
- //释放锁
|
|
|
- distributedLockComponent.unlock(RedisKeyConstant.ROLE_UPDATE_KEY + "_" + userData.getUserId());
|
|
|
}
|
|
|
|
|
|
@Override
|
|
@@ -255,29 +270,17 @@ public class GameUserRoleServiceImpl extends ServiceImpl<GameUserRoleMapper, Gam
|
|
|
|
|
|
@Override
|
|
|
public boolean gameRoleActiveCall(UserData userData, GameRoleActiveCallParam param) {
|
|
|
- //token临期失效判断
|
|
|
- try {
|
|
|
- userTokenService.userTokenUpdateCheck(userData);
|
|
|
- } catch (Exception ignored) {
|
|
|
- }
|
|
|
- //测试环境不使用kafka
|
|
|
+ //测试不执行
|
|
|
if (this.serverUrl.contains("test")) {
|
|
|
return Boolean.TRUE;
|
|
|
}
|
|
|
- //活跃提交
|
|
|
- Map<String, Object> activeParamMap = new HashMap<>(6);
|
|
|
- activeParamMap.put("userId", userData.getUserId());
|
|
|
- activeParamMap.put("gameId", userData.getGameId());
|
|
|
- activeParamMap.put("serverId", param.getServerId());
|
|
|
- activeParamMap.put("roleId", param.getRoleId());
|
|
|
- activeParamMap.put("roleLevel", param.getRoleLevel());
|
|
|
- activeParamMap.put("activeTime", System.currentTimeMillis());
|
|
|
+ //token临期失效判断
|
|
|
try {
|
|
|
- kafkaProducer.send(new ProducerRecord<>(gameRoleActiveTopic, userData.getUserId().toString(), JsonUtil.toString(activeParamMap)));
|
|
|
- } catch (Exception e) {
|
|
|
- log.error("用户角色活跃信息发送到 Kafka 异常!, activeParamMap : {}, e : {}", JsonUtil.toString(activeParamMap), e.getMessage());
|
|
|
- return Boolean.FALSE;
|
|
|
+ userTokenService.userTokenUpdateCheck(userData);
|
|
|
+ } catch (Exception ignored) {
|
|
|
}
|
|
|
+ //活跃信息发送到卡夫卡
|
|
|
+ kafkaService.roleActiveTrack(userData, param);
|
|
|
return Boolean.TRUE;
|
|
|
}
|
|
|
}
|