MMOWebSocket.java 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454
  1. package com.izouma.meta.websocket;
  2. import com.alibaba.fastjson.JSON;
  3. import com.alibaba.fastjson.JSONObject;
  4. import com.izouma.meta.config.Constants;
  5. import com.izouma.meta.domain.MetaMMOLoginInfo;
  6. import com.izouma.meta.domain.MetaObjectMoveCoordinate;
  7. import com.izouma.meta.dto.MMOMessage;
  8. import com.izouma.meta.dto.MMOSingleMessage;
  9. import com.izouma.meta.dto.MetaRestResult;
  10. import com.izouma.meta.dto.MetaServiceResult;
  11. import com.izouma.meta.enums.MoveType;
  12. import com.izouma.meta.repo.MetaMMOLoginInfoRepo;
  13. import com.izouma.meta.utils.ApplicationContextUtil;
  14. import com.izouma.meta.utils.ObjUtils;
  15. import lombok.extern.slf4j.Slf4j;
  16. import org.apache.commons.collections.CollectionUtils;
  17. import org.apache.commons.lang.StringUtils;
  18. import org.springframework.data.redis.core.RedisTemplate;
  19. import org.springframework.stereotype.Service;
  20. import javax.websocket.*;
  21. import javax.websocket.server.PathParam;
  22. import javax.websocket.server.ServerEndpoint;
  23. import java.time.LocalDateTime;
  24. import java.util.ArrayList;
  25. import java.util.List;
  26. import java.util.Map;
  27. import java.util.Objects;
  28. import java.util.concurrent.ConcurrentHashMap;
  29. import java.util.stream.Collectors;
  30. @Service
  31. @ServerEndpoint(value = "/websocket/mmo/{nickName}/{userId}")
  32. @Slf4j
  33. public class MMOWebSocket {
  34. /**
  35. * 当前在线的客户端map
  36. */
  37. private static final Map<String, Session> clients = new ConcurrentHashMap();
  38. private RedisTemplate redisTemplate;
  39. private MetaMMOLoginInfoRepo metaMMOLoginInfoRepo;
  40. private WebsocketCommon websocketCommon;
  41. private void init() {
  42. if (Objects.isNull(redisTemplate)) {
  43. redisTemplate = (RedisTemplate) ApplicationContextUtil.getBean("redisTemplate");
  44. }
  45. if (Objects.isNull(metaMMOLoginInfoRepo)) {
  46. metaMMOLoginInfoRepo = (MetaMMOLoginInfoRepo) ApplicationContextUtil.getBean("metaMMOLoginInfoRepo");
  47. }
  48. if (Objects.isNull(websocketCommon)) {
  49. websocketCommon = (WebsocketCommon) ApplicationContextUtil.getBean("websocketCommon");
  50. }
  51. }
  52. @OnOpen
  53. public void onOpen(@PathParam("nickName") String nickName, @PathParam("userId") String userId, Session session) {
  54. init();
  55. // 判断当前玩家是否在其他地方登陆
  56. if (clients.containsKey(Constants.REDIS_PREFIX.concat(userId))) {
  57. log.info(String.format("当前玩家[%S]已经在别处登陆,sessionId为[%S]", userId, session.getId()));
  58. // 关闭连接
  59. MMOSingleMessage mmoSingleMessage = new MMOSingleMessage();
  60. mmoSingleMessage.setMessageType(6);
  61. mmoSingleMessage.setMessage("您已在其他地方登录,已为您关闭上次登陆信息");
  62. websocketCommon.sendMessageTo(clients, JSON.toJSONString(mmoSingleMessage), Constants.REDIS_PREFIX.concat(userId));
  63. try {
  64. log.info("关闭上次登陆的session连接");
  65. clients.get(Constants.REDIS_PREFIX.concat(userId)).close();
  66. } catch (Exception e) {
  67. log.error("session close throw exception:", e);
  68. }
  69. }
  70. log.info("现在来连接的sessionId:" + session.getId() + "玩家id:" + userId + "玩家昵称" + nickName);
  71. clients.put(Constants.REDIS_PREFIX.concat(userId), session);
  72. // 获取上次登录的信息
  73. MetaMMOLoginInfo dbMetaMMOLoginInfo = metaMMOLoginInfoRepo.findLastByUserId(Long.parseLong(userId));
  74. // 玩家登陆信息入库
  75. MetaMMOLoginInfo metaMMOLoginInfo = MetaMMOLoginInfo.initMetaMMOLoginInfo(dbMetaMMOLoginInfo);
  76. metaMMOLoginInfo.setNickname(nickName);
  77. metaMMOLoginInfo.setUserId(Long.parseLong(userId));
  78. metaMMOLoginInfo.setOnLineTime(LocalDateTime.now());
  79. metaMMOLoginInfo.setSessionId(session.getId());
  80. MetaMMOLoginInfo save = metaMMOLoginInfoRepo.save(metaMMOLoginInfo);
  81. MMOMessage mmoMessage = new MMOMessage();
  82. mmoMessage.setMessageType(5);
  83. mmoMessage.setMessage(save);
  84. log.info(String.format("通知玩家[%S],本次登陆信息[%S]", userId, JSON.toJSONString(mmoMessage)));
  85. websocketCommon.sendMessageTo(clients, JSON.toJSONString(mmoMessage), Constants.REDIS_PREFIX.concat(userId));
  86. }
  87. @OnError
  88. public void onError(Session session, Throwable error) {
  89. // 异常处理
  90. log.error(String.format("sessionId[%S]的服务端发生了错误:[%S]", session.getId(), error.getMessage()));
  91. }
  92. @OnClose
  93. public void onClose(@PathParam("userId") String userId) {
  94. init();
  95. // 查询地图中玩家信息
  96. MetaMMOLoginInfo metaMMOLoginInfo = (MetaMMOLoginInfo) redisTemplate.opsForValue().get(Constants.REDIS_PREFIX.concat(userId));
  97. if (Objects.isNull(metaMMOLoginInfo)) {
  98. // 如果缓存中玩家信息为空,根据userId和sessionId查询数据库
  99. MetaMMOLoginInfo dbMetaMMOLoginInfo = metaMMOLoginInfoRepo.findByUserIdAndSessionIdAndDel(Long.parseLong(userId), clients.get(Constants.REDIS_PREFIX.concat(userId)).getId(), false);
  100. dbMetaMMOLoginInfo.setOffLineTime(LocalDateTime.now());
  101. // 更新离线时间
  102. metaMMOLoginInfoRepo.save(dbMetaMMOLoginInfo);
  103. clients.remove(Constants.REDIS_PREFIX.concat(userId));
  104. return;
  105. }
  106. String key = String.valueOf(metaMMOLoginInfo.getCityId()).concat(":").concat(String.valueOf(metaMMOLoginInfo.getRegionId()));
  107. List<String> otherUserIds = remove(key, userId);
  108. if (CollectionUtils.isNotEmpty(otherUserIds)) {
  109. // 分发下线消息给区域内其他玩家
  110. buildMessageForSendingToAllOther(otherUserIds, 3, metaMMOLoginInfo);
  111. }
  112. MetaMMOLoginInfo dbMetaMMOLoginInfo = metaMMOLoginInfoRepo.findById(metaMMOLoginInfo.getId()).orElse(null);
  113. if (Objects.isNull(dbMetaMMOLoginInfo)) {
  114. log.error(String.format("数据库中不存在id[%S]的记录", metaMMOLoginInfo.getId()));
  115. return;
  116. }
  117. ObjUtils.merge(dbMetaMMOLoginInfo, metaMMOLoginInfo);
  118. dbMetaMMOLoginInfo.setOffLineTime(LocalDateTime.now());
  119. metaMMOLoginInfoRepo.save(dbMetaMMOLoginInfo);
  120. clients.remove(Constants.REDIS_PREFIX.concat(userId));
  121. // 删除redis中自己的信息
  122. redisTemplate.delete(Constants.REDIS_PREFIX.concat(userId));
  123. // 移除地图中自己的信息
  124. redisTemplate.opsForList().remove(Constants.REDIS_PREFIX.concat(key), 0, Constants.REDIS_PREFIX.concat(userId));
  125. }
  126. @OnMessage
  127. public void onMessage(@PathParam("nickName") String nickName, @PathParam("userId") String userId, String message, Session session) {
  128. init();
  129. if (StringUtils.isBlank(message)) {
  130. log.error("Illegal parameter : message can not be null");
  131. return;
  132. }
  133. if (Constants.HEART_RECEIVE.equals(message)) {
  134. log.info(String.format("sessionId:[%S] userId:[%S] 连接正常", session.getId(), userId));
  135. websocketCommon.sendMessageTo(clients, Constants.HEART_RETURN, Constants.REDIS_PREFIX.concat(userId));
  136. return;
  137. }
  138. JSONObject jsonObject = JSON.parseObject(message);
  139. MetaServiceResult result = checkParams(jsonObject);
  140. if (!result.isSuccess()) {
  141. log.error(result.getMessage());
  142. return;
  143. }
  144. log.info("来自客户端消息:" + message + "客户端的id是:" + session.getId());
  145. int type = Integer.parseInt(jsonObject.getString("type"));
  146. String cityId = jsonObject.getString("cityId");
  147. String regionId = jsonObject.getString("regionId");
  148. String key = cityId.concat(":").concat(regionId);
  149. List<String> otherUserIds = remove(key, userId);
  150. if (type == 9) {
  151. String objectId = jsonObject.getString("objectId");
  152. MetaObjectMoveCoordinate metaObjectMoveCoordinate = null;
  153. try {
  154. String str = websocketCommon.getRequest("/metaObjectMove/".concat(objectId).concat("/queryCoordinate"));
  155. metaObjectMoveCoordinate = JSONObject.parseObject(str, MetaObjectMoveCoordinate.class);
  156. } catch (Exception e) {
  157. String errMsg = String.format("MetaObjectMoveCoordinate JSON parse throw exception:[%S]", e);
  158. log.error(errMsg);
  159. }
  160. if (Objects.isNull(metaObjectMoveCoordinate)) {
  161. log.error(String.format("物体[%S]坐标不存在", objectId));
  162. return;
  163. }
  164. buildMessageForSendingToAllOther(otherUserIds, 9, metaObjectMoveCoordinate);
  165. return;
  166. }
  167. MetaMMOLoginInfo metaMMOLoginInfo;
  168. List<MetaMMOLoginInfo> metaMMOLoginInfos = redisTemplate.opsForValue().multiGet(otherUserIds);
  169. switch (type) {
  170. case 1:
  171. log.info("当前操作类型为1 -> 玩家进入地图");
  172. metaMMOLoginInfo = buildMetaMMOLoginInfo(jsonObject, Long.parseLong(cityId), Long.parseLong(regionId), nickName, userId);
  173. if (CollectionUtils.isNotEmpty(otherUserIds)) {
  174. if (CollectionUtils.isNotEmpty(metaMMOLoginInfos)) {
  175. // 分发区域内其他玩家信息给自己
  176. buildMessageForSendingToUser(Constants.REDIS_PREFIX.concat(userId), 1, metaMMOLoginInfos);
  177. // 分发自己信息给区域内其他玩家
  178. buildMessageForSendingToAllOther(otherUserIds, 4, metaMMOLoginInfo);
  179. }
  180. }
  181. // 将自己信息存到redis中
  182. redisTemplate.opsForValue().set(Constants.REDIS_PREFIX.concat(userId), metaMMOLoginInfo);
  183. redisTemplate.opsForList().leftPush(Constants.REDIS_PREFIX.concat(key), Constants.REDIS_PREFIX.concat(userId));
  184. break;
  185. case 2:
  186. log.info(String.format("当前操作类型为[%S] -> 玩家切换区域", type));
  187. metaMMOLoginInfo = buildMetaMMOLoginInfo(jsonObject, Long.parseLong(cityId), Long.parseLong(regionId), nickName, userId);
  188. if (CollectionUtils.isNotEmpty(otherUserIds)) {
  189. // 分发自己信息给区域内其他玩家
  190. buildMessageForSendingToAllOther(otherUserIds, 4, metaMMOLoginInfo);
  191. // 分发区域内其他玩家信息给自己
  192. buildMessageForSendingToUser(Constants.REDIS_PREFIX.concat(userId), 1, metaMMOLoginInfos);
  193. }
  194. MetaMMOLoginInfo oldMetaMMOLoginInfo = (MetaMMOLoginInfo) redisTemplate.opsForValue().get(Constants.REDIS_PREFIX.concat(userId));
  195. if (Objects.isNull(oldMetaMMOLoginInfo)) {
  196. log.error("缺失玩家上次区域的地图缓存信息");
  197. break;
  198. }
  199. String oldKey = String.valueOf(oldMetaMMOLoginInfo.getCityId()).concat(":").concat(String.valueOf(oldMetaMMOLoginInfo.getRegionId()));
  200. List<String> oldUserIds = redisTemplate.opsForList().range(Constants.REDIS_PREFIX.concat(oldKey), 0, -1);
  201. if (CollectionUtils.isEmpty(oldUserIds)) {
  202. log.error("查询不到上次所进入的区域的玩家信息");
  203. break;
  204. }
  205. // 分发消息给之前区域的玩家
  206. buildMessageForSendingToAllOther(oldUserIds, 3, oldMetaMMOLoginInfo);
  207. // 清除玩家上次缓存的地图信息
  208. redisTemplate.opsForList().remove(Constants.REDIS_PREFIX.concat(oldKey), 0, Constants.REDIS_PREFIX.concat(userId));
  209. // 缓存玩家新的地图信息
  210. redisTemplate.opsForValue().set(Constants.REDIS_PREFIX.concat(userId), metaMMOLoginInfo);
  211. redisTemplate.opsForList().leftPush(Constants.REDIS_PREFIX.concat(key), Constants.REDIS_PREFIX.concat(userId));
  212. break;
  213. case 3:
  214. log.info(String.format("当前操作类型为[%S] -> 玩家在地图内移动", type));
  215. metaMMOLoginInfo = (MetaMMOLoginInfo) redisTemplate.opsForValue().get(Constants.REDIS_PREFIX.concat(userId));
  216. if (Objects.isNull(metaMMOLoginInfo)) {
  217. log.error("缓存中不存在本玩家信息");
  218. break;
  219. }
  220. // 更新玩家位置信息
  221. buildCommonProperty(metaMMOLoginInfo, jsonObject);
  222. // 分发玩家信息给区域内其他玩家
  223. buildMessageForSendingToAllOther(otherUserIds, 2, metaMMOLoginInfo);
  224. redisTemplate.opsForValue().set(Constants.REDIS_PREFIX.concat(userId), metaMMOLoginInfo);
  225. break;
  226. case 4:
  227. log.info(String.format("当前操作类型为[%S] -> 玩家进入大厅", type));
  228. metaMMOLoginInfo = (MetaMMOLoginInfo) redisTemplate.opsForValue().get(Constants.REDIS_PREFIX.concat(userId));
  229. if (Objects.isNull(metaMMOLoginInfo)) {
  230. log.error("缓存中不存在本玩家信息");
  231. break;
  232. }
  233. // 分发玩家信息给区域内其他玩家
  234. buildMessageForSendingToAllOther(otherUserIds, 3, metaMMOLoginInfo);
  235. // 更新库中玩家位置信息
  236. MetaMMOLoginInfo dbMetaMMOLoginInfo = metaMMOLoginInfoRepo.findById(metaMMOLoginInfo.getId()).orElse(null);
  237. if (Objects.isNull(dbMetaMMOLoginInfo)) {
  238. log.error(String.format("数据库不存在id[%S]的记录", metaMMOLoginInfo.getId()));
  239. break;
  240. }
  241. dbMetaMMOLoginInfo.setAxisX(metaMMOLoginInfo.getAxisX());
  242. dbMetaMMOLoginInfo.setAxisY(metaMMOLoginInfo.getAxisY());
  243. dbMetaMMOLoginInfo.setAxisZ(metaMMOLoginInfo.getAxisZ());
  244. dbMetaMMOLoginInfo.setEulerX(metaMMOLoginInfo.getEulerX());
  245. dbMetaMMOLoginInfo.setEulerY(metaMMOLoginInfo.getEulerY());
  246. dbMetaMMOLoginInfo.setEulerZ(metaMMOLoginInfo.getEulerZ());
  247. dbMetaMMOLoginInfo.setCityId(metaMMOLoginInfo.getCityId());
  248. dbMetaMMOLoginInfo.setRegionId(metaMMOLoginInfo.getRegionId());
  249. dbMetaMMOLoginInfo.setTop(metaMMOLoginInfo.getTop());
  250. dbMetaMMOLoginInfo.setHat(metaMMOLoginInfo.getHat());
  251. dbMetaMMOLoginInfo.setShoes(metaMMOLoginInfo.getShoes());
  252. dbMetaMMOLoginInfo.setDown(metaMMOLoginInfo.getDown());
  253. dbMetaMMOLoginInfo.setEmoji(metaMMOLoginInfo.getEmoji());
  254. dbMetaMMOLoginInfo.setAnim(metaMMOLoginInfo.getAnim());
  255. dbMetaMMOLoginInfo.setRole(metaMMOLoginInfo.getRole());
  256. dbMetaMMOLoginInfo.setMoveType(metaMMOLoginInfo.getMoveType());
  257. dbMetaMMOLoginInfo.setTurnedId(metaMMOLoginInfo.getTurnedId());
  258. dbMetaMMOLoginInfo.setVehicleId(metaMMOLoginInfo.getVehicleId());
  259. metaMMOLoginInfoRepo.save(dbMetaMMOLoginInfo);
  260. break;
  261. default:
  262. log.error(String.format("不存在的操作类型[%S]", type));
  263. }
  264. }
  265. /**
  266. * 分发玩家信息给区域内其他玩家
  267. *
  268. * @param userIds 玩家id集合
  269. * @param messageType 消息类型
  270. * @param data 消息体
  271. */
  272. private void buildMessageForSendingToAllOther(List<String> userIds, int messageType, Object data) {
  273. MMOMessage mmoMessage = new MMOMessage();
  274. mmoMessage.setMessageType(messageType);
  275. mmoMessage.setMessage(data);
  276. // 进行类型转换和判断
  277. if (data instanceof MetaMMOLoginInfo) {
  278. MetaMMOLoginInfo metaMMOLoginInfo = (MetaMMOLoginInfo) data;
  279. if (!clients.containsKey(Constants.REDIS_PREFIX.concat(String.valueOf(metaMMOLoginInfo.getUserId())))) {
  280. log.error("session信息不存在");
  281. return;
  282. }
  283. }
  284. userIds.forEach(id -> {
  285. try {
  286. log.info(String.format("服务器给所有当前区域内在线用户发送消息,当前在线人员为[%S]。消息:[%S]", id, JSON.toJSONString(mmoMessage)));
  287. clients.get(id).getBasicRemote().sendText(JSON.toJSONString(mmoMessage));
  288. } catch (Exception e) {
  289. log.error(String.format("send message [%S] to [%S] throw exception [%S]:", JSON.toJSONString(mmoMessage), id, e));
  290. }
  291. });
  292. }
  293. /**
  294. * 分发区域内其他玩家信息给自己
  295. *
  296. * @param userId 玩家id
  297. * @param messageType 消息类型
  298. * @param metaMMOLoginInfos 消息体(其他玩家信息)
  299. */
  300. private void buildMessageForSendingToUser(String userId, int messageType, List<MetaMMOLoginInfo> metaMMOLoginInfos) {
  301. MMOMessage mmoMessage = new MMOMessage();
  302. mmoMessage.setMessageType(messageType);
  303. mmoMessage.setMap(metaMMOLoginInfos);
  304. websocketCommon.sendMessageTo(clients, JSON.toJSONString(mmoMessage), userId);
  305. }
  306. /**
  307. * 构建玩家登陆信息
  308. *
  309. * @param jsonObject 玩家位置等信息json对象
  310. * @param cityId 城市id
  311. * @param regionId 区域id
  312. * @return 玩家位置信息
  313. */
  314. private MetaMMOLoginInfo buildMetaMMOLoginInfo(JSONObject jsonObject, Long cityId, Long regionId, String nickName, String userId) {
  315. // 获取到进入地图时自己的信息
  316. MetaMMOLoginInfo metaMMOLoginInfo = new MetaMMOLoginInfo();
  317. buildCommonProperty(metaMMOLoginInfo, jsonObject);
  318. metaMMOLoginInfo.setCityId(cityId);
  319. metaMMOLoginInfo.setRegionId(regionId);
  320. metaMMOLoginInfo.setUserId(Long.parseLong(userId));
  321. metaMMOLoginInfo.setNickname(nickName);
  322. if (Objects.nonNull(jsonObject.getString("role"))) {
  323. metaMMOLoginInfo.setRole(jsonObject.getString("role"));
  324. }
  325. if (Objects.nonNull(jsonObject.getString("id"))) {
  326. metaMMOLoginInfo.setId(Long.parseLong(jsonObject.getString("id")));
  327. }
  328. metaMMOLoginInfo.setCityId(cityId);
  329. return metaMMOLoginInfo;
  330. }
  331. /**
  332. * 根据jsonObject构建玩家位置信息
  333. *
  334. * @param metaMMOLoginInfo 玩家登陆信息
  335. * @param jsonObject 玩家位置信息json对象
  336. */
  337. private void buildCommonProperty(MetaMMOLoginInfo metaMMOLoginInfo, JSONObject jsonObject) {
  338. if (Objects.nonNull(jsonObject.getString("axisX"))) {
  339. metaMMOLoginInfo.setAxisX(Float.parseFloat(jsonObject.getString("axisX")));
  340. }
  341. if (Objects.nonNull(jsonObject.getString("axisY"))) {
  342. metaMMOLoginInfo.setAxisY(Float.parseFloat(jsonObject.getString("axisY")));
  343. }
  344. if (Objects.nonNull(jsonObject.getString("axisZ"))) {
  345. metaMMOLoginInfo.setAxisZ(Float.parseFloat(jsonObject.getString("axisZ")));
  346. }
  347. if (Objects.nonNull(jsonObject.getString("eulerX"))) {
  348. metaMMOLoginInfo.setEulerX(Float.parseFloat(jsonObject.getString("eulerX")));
  349. }
  350. if (Objects.nonNull(jsonObject.getString("eulerY"))) {
  351. metaMMOLoginInfo.setEulerY(Float.parseFloat(jsonObject.getString("eulerY")));
  352. }
  353. if (Objects.nonNull(jsonObject.getString("eulerZ"))) {
  354. metaMMOLoginInfo.setEulerZ(Float.parseFloat(jsonObject.getString("eulerZ")));
  355. }
  356. if (Objects.nonNull(jsonObject.getString("top"))) {
  357. metaMMOLoginInfo.setTop(Integer.parseInt(jsonObject.getString("top")));
  358. }
  359. if (Objects.nonNull(jsonObject.getString("hat"))) {
  360. metaMMOLoginInfo.setHat(Integer.parseInt(jsonObject.getString("hat")));
  361. }
  362. if (Objects.nonNull(jsonObject.getString("down"))) {
  363. metaMMOLoginInfo.setDown(Integer.parseInt(jsonObject.getString("down")));
  364. }
  365. if (Objects.nonNull(jsonObject.getString("shoes"))) {
  366. metaMMOLoginInfo.setShoes(Integer.parseInt(jsonObject.getString("shoes")));
  367. }
  368. if (Objects.nonNull(jsonObject.getString("anim"))) {
  369. metaMMOLoginInfo.setAnim(Integer.parseInt(jsonObject.getString("anim")));
  370. }
  371. if (Objects.nonNull(jsonObject.getString("emoji"))) {
  372. metaMMOLoginInfo.setEmoji(Integer.parseInt(jsonObject.getString("emoji")));
  373. }
  374. if (Objects.nonNull(jsonObject.getString("moveType"))) {
  375. metaMMOLoginInfo.setMoveType(MoveType.valueOf(jsonObject.getString("moveType")));
  376. }
  377. if (Objects.nonNull(jsonObject.getString("vehicleId"))) {
  378. metaMMOLoginInfo.setVehicleId(Long.parseLong(jsonObject.getString("vehicleId")));
  379. }
  380. if (Objects.nonNull(jsonObject.getString("turnedId"))) {
  381. metaMMOLoginInfo.setTurnedId(Long.parseLong(jsonObject.getString("turnedId")));
  382. }
  383. }
  384. /**
  385. * 校验参数
  386. *
  387. * @param jsonObject 参数
  388. * @return 校验结果
  389. */
  390. private MetaServiceResult checkParams(JSONObject jsonObject) {
  391. if (Objects.isNull(jsonObject)) {
  392. return MetaServiceResult.returnError("Illegal parameter : jsonObject can not be null");
  393. }
  394. if (Objects.isNull(jsonObject.getString("type"))) {
  395. return MetaServiceResult.returnError("Illegal parameter : type can not be null");
  396. }
  397. if (Objects.isNull(jsonObject.getString("cityId"))) {
  398. return MetaServiceResult.returnError("Illegal parameter : cityId can not be null");
  399. }
  400. if (Objects.isNull(jsonObject.getString("regionId"))) {
  401. return MetaServiceResult.returnError("Illegal parameter : regionId can not be null");
  402. }
  403. int type = Integer.parseInt(jsonObject.getString("type"));
  404. if (type == 9) {
  405. if (Objects.isNull(jsonObject.getString("objectId"))) {
  406. return MetaServiceResult.returnError("Illegal parameter : objectId can not be null");
  407. }
  408. return MetaServiceResult.returnSuccess("check success");
  409. }
  410. if (Objects.isNull(jsonObject.getString("id"))) {
  411. return MetaServiceResult.returnError("Illegal parameter : id can not be null");
  412. }
  413. return MetaServiceResult.returnSuccess("check success");
  414. }
  415. private List<String> remove(String key, String userId) {
  416. List<String> userIds = redisTemplate.opsForList().range(Constants.REDIS_PREFIX.concat(key), 0, -1);
  417. // 去除当前玩家id
  418. List<String> otherUserIds = new ArrayList<>();
  419. if (CollectionUtils.isNotEmpty(userIds)) {
  420. otherUserIds = userIds.stream().filter(id -> !Objects.equals(id, Constants.REDIS_PREFIX.concat(userId))).collect(Collectors.toList());
  421. }
  422. return otherUserIds;
  423. }
  424. public MetaRestResult<Void> clearMMO(String userId, String regionId, String cityId) {
  425. init();
  426. if (clients.containsKey(Constants.REDIS_PREFIX.concat(userId))) {
  427. String errMsg = String.format("userId[%S]用户mmo连接正常,无法清除缓存!", userId);
  428. log.info(errMsg);
  429. return MetaRestResult.returnError(errMsg);
  430. }
  431. String key = cityId.concat(":").concat(regionId);
  432. redisTemplate.delete(Constants.REDIS_PREFIX.concat(userId));
  433. redisTemplate.opsForList().remove(Constants.REDIS_PREFIX.concat(key), 0, Constants.REDIS_PREFIX.concat(userId));
  434. return MetaRestResult.returnSuccess("清除成功");
  435. }
  436. }