فهرست منبع

Merge branch 'dev' of sunkean/raex_mmo into master

sunkean 2 سال پیش
والد
کامیت
a9e55849b3

+ 2 - 0
src/main/java/com/izouma/meta/config/Constants.java

@@ -43,6 +43,8 @@ public interface Constants {
 
     String PRIVATE_CHAT = "PRIVATE_CHAT";
 
+    String REDIS_PREFIX = "meta:";
+
     interface MetaRestCode {
 
         int success = 200;

+ 50 - 0
src/main/java/com/izouma/meta/domain/MetaObjectMoveCoordinate.java

@@ -0,0 +1,50 @@
+package com.izouma.meta.domain;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.Entity;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@Entity
+@ApiModel("元宇宙物体移动坐标")
+public class MetaObjectMoveCoordinate extends BaseEntity {
+
+    @ApiModelProperty("物体id")
+    @ExcelProperty("物体id")
+    private Long objectId;
+
+    @ApiModelProperty("坐标下标")
+    @ExcelProperty("坐标下标")
+    private int coordinateIndex;
+
+    @ApiModelProperty("axisX")
+    @ExcelProperty("axisX")
+    private float axisX;
+
+    @ApiModelProperty("axisY")
+    @ExcelProperty("axisY")
+    private float axisY;
+
+    @ApiModelProperty("axisZ")
+    @ExcelProperty("axisZ")
+    private float axisZ;
+
+    @ApiModelProperty("eulerX")
+    @ExcelProperty("eulerX")
+    private float eulerX;
+
+    @ApiModelProperty("eulerY")
+    @ExcelProperty("eulerY")
+    private float eulerY;
+
+    @ApiModelProperty("eulerZ")
+    @ExcelProperty("eulerZ")
+    private float eulerZ;
+}

+ 1 - 1
src/main/java/com/izouma/meta/dto/MMOMessage.java

@@ -21,7 +21,7 @@ public class MMOMessage {
      */
     private Integer messageType;
 
-    private MetaMMOLoginInfo message;
+    private Object message;
 
     private List<MetaMMOLoginInfo> map;
 }

+ 68 - 43
src/main/java/com/izouma/meta/websocket/MMOWebSocket.java

@@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
 import com.izouma.meta.config.Constants;
 import com.izouma.meta.domain.MetaMMOLoginInfo;
+import com.izouma.meta.domain.MetaObjectMoveCoordinate;
 import com.izouma.meta.dto.MMOMessage;
 import com.izouma.meta.dto.MMOSingleMessage;
 import com.izouma.meta.dto.MetaRestResult;
@@ -39,13 +40,9 @@ public class MMOWebSocket {
      */
     private static final Map<String, Session> clients = new ConcurrentHashMap();
 
-    private final String REDIS_PREFIX = "meta:";
-
-    private RedisTemplate redisTemplate;
-
+    private RedisTemplate        redisTemplate;
     private MetaMMOLoginInfoRepo metaMMOLoginInfoRepo;
-
-    private WebsocketCommon websocketCommon;
+    private WebsocketCommon      websocketCommon;
 
     private void init() {
         if (Objects.isNull(redisTemplate)) {
@@ -63,22 +60,22 @@ public class MMOWebSocket {
     public void onOpen(@PathParam("nickName") String nickName, @PathParam("userId") String userId, Session session) {
         init();
         // 判断当前玩家是否在其他地方登陆
-        if (clients.containsKey(REDIS_PREFIX.concat(userId))) {
+        if (clients.containsKey(Constants.REDIS_PREFIX.concat(userId))) {
             log.info(String.format("当前玩家[%S]已经在别处登陆,sessionId为[%S]", userId, session.getId()));
             // 关闭连接
             MMOSingleMessage mmoSingleMessage = new MMOSingleMessage();
             mmoSingleMessage.setMessageType(6);
             mmoSingleMessage.setMessage("您已在其他地方登录,已为您关闭上次登陆信息");
-            websocketCommon.sendMessageTo(clients, JSON.toJSONString(mmoSingleMessage), REDIS_PREFIX.concat(userId));
+            websocketCommon.sendMessageTo(clients, JSON.toJSONString(mmoSingleMessage), Constants.REDIS_PREFIX.concat(userId));
             try {
                 log.info("关闭上次登陆的session连接");
-                clients.get(REDIS_PREFIX.concat(userId)).close();
+                clients.get(Constants.REDIS_PREFIX.concat(userId)).close();
             } catch (Exception e) {
                 log.error("session close throw exception:", e);
             }
         }
         log.info("现在来连接的sessionId:" + session.getId() + "玩家id:" + userId + "玩家昵称" + nickName);
-        clients.put(REDIS_PREFIX.concat(userId), session);
+        clients.put(Constants.REDIS_PREFIX.concat(userId), session);
         // 获取上次登录的信息
         MetaMMOLoginInfo dbMetaMMOLoginInfo = metaMMOLoginInfoRepo.findLastByUserId(Long.parseLong(userId));
         // 玩家登陆信息入库
@@ -92,7 +89,7 @@ public class MMOWebSocket {
         mmoMessage.setMessageType(5);
         mmoMessage.setMessage(save);
         log.info(String.format("通知玩家[%S],本次登陆信息[%S]", userId, JSON.toJSONString(mmoMessage)));
-        websocketCommon.sendMessageTo(clients, JSON.toJSONString(mmoMessage), REDIS_PREFIX.concat(userId));
+        websocketCommon.sendMessageTo(clients, JSON.toJSONString(mmoMessage), Constants.REDIS_PREFIX.concat(userId));
     }
 
     @OnError
@@ -105,14 +102,14 @@ public class MMOWebSocket {
     public void onClose(@PathParam("userId") String userId) {
         init();
         // 查询地图中玩家信息
-        MetaMMOLoginInfo metaMMOLoginInfo = (MetaMMOLoginInfo) redisTemplate.opsForValue().get(REDIS_PREFIX.concat(userId));
+        MetaMMOLoginInfo metaMMOLoginInfo = (MetaMMOLoginInfo) redisTemplate.opsForValue().get(Constants.REDIS_PREFIX.concat(userId));
         if (Objects.isNull(metaMMOLoginInfo)) {
             // 如果缓存中玩家信息为空,根据userId和sessionId查询数据库
-            MetaMMOLoginInfo dbMetaMMOLoginInfo = metaMMOLoginInfoRepo.findByUserIdAndSessionIdAndDel(Long.parseLong(userId), clients.get(REDIS_PREFIX.concat(userId)).getId(), false);
+            MetaMMOLoginInfo dbMetaMMOLoginInfo = metaMMOLoginInfoRepo.findByUserIdAndSessionIdAndDel(Long.parseLong(userId), clients.get(Constants.REDIS_PREFIX.concat(userId)).getId(), false);
             dbMetaMMOLoginInfo.setOffLineTime(LocalDateTime.now());
             // 更新离线时间
             metaMMOLoginInfoRepo.save(dbMetaMMOLoginInfo);
-            clients.remove(REDIS_PREFIX.concat(userId));
+            clients.remove(Constants.REDIS_PREFIX.concat(userId));
             return;
         }
         String key = String.valueOf(metaMMOLoginInfo.getCityId()).concat(":").concat(String.valueOf(metaMMOLoginInfo.getRegionId()));
@@ -129,11 +126,11 @@ public class MMOWebSocket {
         ObjUtils.merge(dbMetaMMOLoginInfo, metaMMOLoginInfo);
         dbMetaMMOLoginInfo.setOffLineTime(LocalDateTime.now());
         metaMMOLoginInfoRepo.save(dbMetaMMOLoginInfo);
-        clients.remove(REDIS_PREFIX.concat(userId));
+        clients.remove(Constants.REDIS_PREFIX.concat(userId));
         // 删除redis中自己的信息
-        redisTemplate.delete(REDIS_PREFIX.concat(userId));
+        redisTemplate.delete(Constants.REDIS_PREFIX.concat(userId));
         // 移除地图中自己的信息
-        redisTemplate.opsForList().remove(REDIS_PREFIX.concat(key), 0, REDIS_PREFIX.concat(userId));
+        redisTemplate.opsForList().remove(Constants.REDIS_PREFIX.concat(key), 0, Constants.REDIS_PREFIX.concat(userId));
     }
 
     @OnMessage
@@ -145,7 +142,7 @@ public class MMOWebSocket {
         }
         if (Constants.HEART_RECEIVE.equals(message)) {
             log.info(String.format("sessionId:[%S] userId:[%S] 连接正常", session.getId(), userId));
-            websocketCommon.sendMessageTo(clients, Constants.HEART_RETURN, REDIS_PREFIX.concat(userId));
+            websocketCommon.sendMessageTo(clients, Constants.HEART_RETURN, Constants.REDIS_PREFIX.concat(userId));
             return;
         }
         JSONObject jsonObject = JSON.parseObject(message);
@@ -160,6 +157,23 @@ public class MMOWebSocket {
         String regionId = jsonObject.getString("regionId");
         String key = cityId.concat(":").concat(regionId);
         List<String> otherUserIds = remove(key, userId);
+        if (type == 9) {
+            String objectId = jsonObject.getString("objectId");
+            MetaObjectMoveCoordinate metaObjectMoveCoordinate = null;
+            try {
+                String str = websocketCommon.getRequest("/metaObjectMove/".concat(objectId).concat("/queryCoordinate"));
+                metaObjectMoveCoordinate = JSONObject.parseObject(str, MetaObjectMoveCoordinate.class);
+            } catch (Exception e) {
+                String errMsg = String.format("MetaObjectMoveCoordinate JSON parse throw exception:[%S]", e);
+                log.error(errMsg);
+            }
+            if (Objects.isNull(metaObjectMoveCoordinate)) {
+                log.error(String.format("物体[%S]坐标不存在", objectId));
+                return;
+            }
+            buildMessageForSendingToAllOther(otherUserIds, 9, metaObjectMoveCoordinate);
+            return;
+        }
         MetaMMOLoginInfo metaMMOLoginInfo;
         List<MetaMMOLoginInfo> metaMMOLoginInfos = redisTemplate.opsForValue().multiGet(otherUserIds);
         switch (type) {
@@ -169,14 +183,14 @@ public class MMOWebSocket {
                 if (CollectionUtils.isNotEmpty(otherUserIds)) {
                     if (CollectionUtils.isNotEmpty(metaMMOLoginInfos)) {
                         // 分发区域内其他玩家信息给自己
-                        buildMessageForSendingToUser(REDIS_PREFIX.concat(userId), 1, metaMMOLoginInfos);
+                        buildMessageForSendingToUser(Constants.REDIS_PREFIX.concat(userId), 1, metaMMOLoginInfos);
                         // 分发自己信息给区域内其他玩家
                         buildMessageForSendingToAllOther(otherUserIds, 4, metaMMOLoginInfo);
                     }
                 }
                 // 将自己信息存到redis中
-                redisTemplate.opsForValue().set(REDIS_PREFIX.concat(userId), metaMMOLoginInfo);
-                redisTemplate.opsForList().leftPush(REDIS_PREFIX.concat(key), REDIS_PREFIX.concat(userId));
+                redisTemplate.opsForValue().set(Constants.REDIS_PREFIX.concat(userId), metaMMOLoginInfo);
+                redisTemplate.opsForList().leftPush(Constants.REDIS_PREFIX.concat(key), Constants.REDIS_PREFIX.concat(userId));
                 break;
             case 2:
                 log.info(String.format("当前操作类型为[%S] -> 玩家切换区域", type));
@@ -185,15 +199,15 @@ public class MMOWebSocket {
                     // 分发自己信息给区域内其他玩家
                     buildMessageForSendingToAllOther(otherUserIds, 4, metaMMOLoginInfo);
                     // 分发区域内其他玩家信息给自己
-                    buildMessageForSendingToUser(REDIS_PREFIX.concat(userId), 1, metaMMOLoginInfos);
+                    buildMessageForSendingToUser(Constants.REDIS_PREFIX.concat(userId), 1, metaMMOLoginInfos);
                 }
-                MetaMMOLoginInfo oldMetaMMOLoginInfo = (MetaMMOLoginInfo) redisTemplate.opsForValue().get(REDIS_PREFIX.concat(userId));
+                MetaMMOLoginInfo oldMetaMMOLoginInfo = (MetaMMOLoginInfo) redisTemplate.opsForValue().get(Constants.REDIS_PREFIX.concat(userId));
                 if (Objects.isNull(oldMetaMMOLoginInfo)) {
                     log.error("缺失玩家上次区域的地图缓存信息");
                     break;
                 }
                 String oldKey = String.valueOf(oldMetaMMOLoginInfo.getCityId()).concat(":").concat(String.valueOf(oldMetaMMOLoginInfo.getRegionId()));
-                List<String> oldUserIds = redisTemplate.opsForList().range(REDIS_PREFIX.concat(oldKey), 0, -1);
+                List<String> oldUserIds = redisTemplate.opsForList().range(Constants.REDIS_PREFIX.concat(oldKey), 0, -1);
                 if (CollectionUtils.isEmpty(oldUserIds)) {
                     log.error("查询不到上次所进入的区域的玩家信息");
                     break;
@@ -201,14 +215,14 @@ public class MMOWebSocket {
                 // 分发消息给之前区域的玩家
                 buildMessageForSendingToAllOther(oldUserIds, 3, oldMetaMMOLoginInfo);
                 // 清除玩家上次缓存的地图信息
-                redisTemplate.opsForList().remove(REDIS_PREFIX.concat(oldKey), 0, REDIS_PREFIX.concat(userId));
+                redisTemplate.opsForList().remove(Constants.REDIS_PREFIX.concat(oldKey), 0, Constants.REDIS_PREFIX.concat(userId));
                 // 缓存玩家新的地图信息
-                redisTemplate.opsForValue().set(REDIS_PREFIX.concat(userId), metaMMOLoginInfo);
-                redisTemplate.opsForList().leftPush(REDIS_PREFIX.concat(key), REDIS_PREFIX.concat(userId));
+                redisTemplate.opsForValue().set(Constants.REDIS_PREFIX.concat(userId), metaMMOLoginInfo);
+                redisTemplate.opsForList().leftPush(Constants.REDIS_PREFIX.concat(key), Constants.REDIS_PREFIX.concat(userId));
                 break;
             case 3:
                 log.info(String.format("当前操作类型为[%S] -> 玩家在地图内移动", type));
-                metaMMOLoginInfo = (MetaMMOLoginInfo) redisTemplate.opsForValue().get(REDIS_PREFIX.concat(userId));
+                metaMMOLoginInfo = (MetaMMOLoginInfo) redisTemplate.opsForValue().get(Constants.REDIS_PREFIX.concat(userId));
                 if (Objects.isNull(metaMMOLoginInfo)) {
                     log.error("缓存中不存在本玩家信息");
                     break;
@@ -217,11 +231,11 @@ public class MMOWebSocket {
                 buildCommonProperty(metaMMOLoginInfo, jsonObject);
                 // 分发玩家信息给区域内其他玩家
                 buildMessageForSendingToAllOther(otherUserIds, 2, metaMMOLoginInfo);
-                redisTemplate.opsForValue().set(REDIS_PREFIX.concat(userId), metaMMOLoginInfo);
+                redisTemplate.opsForValue().set(Constants.REDIS_PREFIX.concat(userId), metaMMOLoginInfo);
                 break;
             case 4:
                 log.info(String.format("当前操作类型为[%S] -> 玩家进入大厅", type));
-                metaMMOLoginInfo = (MetaMMOLoginInfo) redisTemplate.opsForValue().get(REDIS_PREFIX.concat(userId));
+                metaMMOLoginInfo = (MetaMMOLoginInfo) redisTemplate.opsForValue().get(Constants.REDIS_PREFIX.concat(userId));
                 if (Objects.isNull(metaMMOLoginInfo)) {
                     log.error("缓存中不存在本玩家信息");
                     break;
@@ -263,17 +277,21 @@ public class MMOWebSocket {
     /**
      * 分发玩家信息给区域内其他玩家
      *
-     * @param userIds          玩家id集合
-     * @param messageType      消息类型
-     * @param metaMMOLoginInfo 消息体
+     * @param userIds     玩家id集合
+     * @param messageType 消息类型
+     * @param data        消息体
      */
-    private void buildMessageForSendingToAllOther(List<String> userIds, int messageType, MetaMMOLoginInfo metaMMOLoginInfo) {
+    private void buildMessageForSendingToAllOther(List<String> userIds, int messageType, Object data) {
         MMOMessage mmoMessage = new MMOMessage();
         mmoMessage.setMessageType(messageType);
-        mmoMessage.setMessage(metaMMOLoginInfo);
-        if (!clients.containsKey(REDIS_PREFIX.concat(String.valueOf(metaMMOLoginInfo.getUserId())))) {
-            log.error("session信息不存在");
-            return;
+        mmoMessage.setMessage(data);
+        // 进行类型转换和判断
+        if (data instanceof MetaMMOLoginInfo) {
+            MetaMMOLoginInfo metaMMOLoginInfo = (MetaMMOLoginInfo) data;
+            if (!clients.containsKey(Constants.REDIS_PREFIX.concat(String.valueOf(metaMMOLoginInfo.getUserId())))) {
+                log.error("session信息不存在");
+                return;
+            }
         }
         userIds.forEach(id -> {
             try {
@@ -398,6 +416,13 @@ public class MMOWebSocket {
         if (Objects.isNull(jsonObject.getString("regionId"))) {
             return MetaServiceResult.returnError("Illegal parameter : regionId can not be null");
         }
+        int type = Integer.parseInt(jsonObject.getString("type"));
+        if (type == 9) {
+            if (Objects.isNull(jsonObject.getString("objectId"))) {
+                return MetaServiceResult.returnError("Illegal parameter : objectId can not be null");
+            }
+            return MetaServiceResult.returnSuccess("check success");
+        }
         if (Objects.isNull(jsonObject.getString("id"))) {
             return MetaServiceResult.returnError("Illegal parameter : id can not be null");
         }
@@ -405,25 +430,25 @@ public class MMOWebSocket {
     }
 
     private List<String> remove(String key, String userId) {
-        List<String> userIds = redisTemplate.opsForList().range(REDIS_PREFIX.concat(key), 0, -1);
+        List<String> userIds = redisTemplate.opsForList().range(Constants.REDIS_PREFIX.concat(key), 0, -1);
         //  去除当前玩家id
         List<String> otherUserIds = new ArrayList<>();
         if (CollectionUtils.isNotEmpty(userIds)) {
-            otherUserIds = userIds.stream().filter(id -> !Objects.equals(id, REDIS_PREFIX.concat(userId))).collect(Collectors.toList());
+            otherUserIds = userIds.stream().filter(id -> !Objects.equals(id, Constants.REDIS_PREFIX.concat(userId))).collect(Collectors.toList());
         }
         return otherUserIds;
     }
 
     public MetaRestResult<Void> clearMMO(String userId, String regionId, String cityId) {
         init();
-        if (clients.containsKey(REDIS_PREFIX.concat(userId))) {
+        if (clients.containsKey(Constants.REDIS_PREFIX.concat(userId))) {
             String errMsg = String.format("userId[%S]用户mmo连接正常,无法清除缓存!", userId);
             log.info(errMsg);
             return MetaRestResult.returnError(errMsg);
         }
         String key = cityId.concat(":").concat(regionId);
-        redisTemplate.delete(REDIS_PREFIX.concat(userId));
-        redisTemplate.opsForList().remove(REDIS_PREFIX.concat(key), 0, REDIS_PREFIX.concat(userId));
+        redisTemplate.delete(Constants.REDIS_PREFIX.concat(userId));
+        redisTemplate.opsForList().remove(Constants.REDIS_PREFIX.concat(key), 0, Constants.REDIS_PREFIX.concat(userId));
         return MetaRestResult.returnSuccess("清除成功");
     }
 }

+ 11 - 13
src/main/java/com/izouma/meta/websocket/WebsocketCommon.java

@@ -4,9 +4,9 @@ package com.izouma.meta.websocket;
 import com.izouma.meta.config.GeneralProperties;
 import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
-import org.apache.http.HttpResponse;
 import org.apache.http.HttpStatus;
 import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.CloseableHttpResponse;
 import org.apache.http.client.methods.HttpGet;
 import org.apache.http.impl.client.HttpClients;
 import org.apache.http.util.EntityUtils;
@@ -20,6 +20,8 @@ import java.util.Set;
 @Slf4j
 @AllArgsConstructor
 public class WebsocketCommon {
+
+    private final HttpClient client = HttpClients.createDefault();
     private GeneralProperties generalProperties;
 
     /**
@@ -64,25 +66,21 @@ public class WebsocketCommon {
 
     public String getRequest(String url) {
         String requestUrl = generalProperties.getUrlPrefix().concat(url);
-        HttpClient client = HttpClients.createDefault();
         HttpGet get = new HttpGet(requestUrl);
-        String obj;
-        try {
-            log.info(String.format("execute get request url : %S ", requestUrl));
-            HttpResponse res = client.execute(get);
+        try (CloseableHttpResponse res = (CloseableHttpResponse) client.execute(get)) {
+            log.info(String.format("execute get request url : %s ", requestUrl));
             if (res.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
-                obj = EntityUtils.toString(res.getEntity());
+                return EntityUtils.toString(res.getEntity());
             } else {
-                String errMsg = String.format(" request [%S] returned error ", requestUrl);
-                log.info(errMsg);
+                String errMsg = String.format("request [%s] returned error", requestUrl);
+                log.error(errMsg);
                 throw new RuntimeException(errMsg);
             }
         } catch (Exception e) {
-            String errMsg = String.format(" client failed to execute request for url: %S ", requestUrl);
-            log.info(errMsg);
-            throw new RuntimeException(errMsg);
+            String errMsg = String.format("client failed to execute request for url: %s", requestUrl);
+            log.error(errMsg, e);
+            throw new RuntimeException(errMsg, e);
         }
-        return obj;
     }
 
 }