package com.fdkk.fdkkmeta.grpcService; import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.ObjectUtil; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.fdkk.fdkkmeta.config.MetaConfig; import com.fdkk.fdkkmeta.domain.dto.RouteDto; import com.fdkk.fdkkmeta.domain.entity.mysql.BreakpointsEntity; import com.fdkk.fdkkmeta.domain.entity.mysql.MoveFrameEntity; import com.fdkk.fdkkmeta.domain.entity.mysql.RotateFrameEntity; import com.fdkk.fdkkmeta.domain.entity.mysql.UserEntity; import com.fdkk.fdkkmeta.domain.po.*; import com.fdkk.fdkkmeta.grpc.*; import com.fdkk.fdkkmeta.redis.RedisCache; import com.fdkk.fdkkmeta.redis.RedisPublishService; import com.fdkk.fdkkmeta.service.BreakpointsService; import com.fdkk.fdkkmeta.service.MoveFrameService; import com.fdkk.fdkkmeta.service.RotateFrameService; import com.fdkk.fdkkmeta.service.UserService; import com.fdkk.fdkkmeta.util.ProtoJsonUtils; import com.fdkk.fdkkmeta.util.kesar.GetRoute; import constants.RedisQueueConstant; import io.grpc.stub.StreamObserver; import lombok.extern.slf4j.Slf4j; import net.devh.boot.grpc.server.service.GrpcService; import org.springframework.beans.factory.annotation.Autowired; import java.io.File; import java.util.Arrays; import java.util.List; /** * @author Xiewj * @date 2022/5/9 */ @GrpcService @Slf4j public class sceneGrpcServer extends SceneGrpcServiceGrpc.SceneGrpcServiceImplBase { @Autowired MetaConfig metaConfig; @Autowired UserService userService; @Autowired BreakpointsService breakpointsService; @Autowired RotateFrameService rotateFrameService; @Autowired MoveFrameService moveFrameService; @Autowired RedisCache redisCache; @Autowired SceneGrpcService sceneGrpcService; @Autowired private RedisPublishService redisPublishService; /*** * 回复 案例 * SceneReply res = SceneReply.newBuilder().setRes(id+","+name).build(); * responseObserver.onNext(res); */ /* @Override public void testMethod(SceneRequest request, StreamObserver responseObserver) { // grpc服务端获取调用端请求参数 String id = request.getId(); String name = request.getName(); // 这里可以有自己的业务代码,只需要按照porto中的返回类型返回参数即可 SceneReply res = SceneReply.newBuilder().setRes(id+","+name).build(); responseObserver.onNext(res); responseObserver.onCompleted(); log.info("回复{}",res); } */ @Override public void getRoute(RouteRequest request, StreamObserver responseObserver) { // grpc服务端获取调用端请求参数 String sceneCode = request.getSceneCode(); Point sLocation = request.getSLocation(); Point eLocation = request.getELocation(); RouteDto po=new RouteDto(); PointPO s=new PointPO(); s.setX(Double.parseDouble(sLocation.getX())); s.setY(Double.parseDouble(sLocation.getY())); s.setZ(Double.parseDouble(sLocation.getY())); PointPO e=new PointPO(); e.setX(Double.parseDouble(eLocation.getX())); e.setY(Double.parseDouble(eLocation.getY())); e.setZ(Double.parseDouble(eLocation.getY())); po.setE_location(e); po.setS_location(s); po.setSceneCode(sceneCode); JSONArray maps = GetRoute.getRoute(metaConfig.getFreespacePath()+ File.separator +"target_freespace.json", po); // 这里可以有自己的业务代码,只需要按照porto中的返回类型返回参数即可 RouteReply.Builder builder = RouteReply.newBuilder(); if (ArrayUtil.isNotEmpty(maps)) { for (int i = 0; i < maps.size(); i++) { RouteArray.Builder addInBuilder = builder.addInBuilder(); ProtoJsonUtils.toProtoBean(addInBuilder, maps.get(i).toString()); } } responseObserver.onNext(builder.build()); responseObserver.onCompleted(); } @Override public void init(InitRequest request, StreamObserver responseObserver) { try { log.info("开始初始化!"); String user_id = request.getUserId(); String nick_name = request.getNickName(); String skin_id = request.getSkinId(); String avatar_id = request.getAvatarId(); String room_id = request.getRoomId(); String app_id = request.getAppId(); Space player =request.getPlayer(); //保存user UserEntity userEntity=new UserEntity(); long firstFrameId = 1081L; long firstBreakPointId = 100L; userEntity.setAppId(app_id); userEntity.setUserId(user_id); userEntity.setAvatarId(avatar_id); userEntity.setNickName(nick_name); userEntity.setRoomId(room_id); userEntity.setSkinId(skin_id); userEntity.setFrameId(firstFrameId); userEntity.setBreakPointId(firstBreakPointId); userEntity.setOnline(true); //Point playerPoint = player.getPosition(); BreakpointsEntity breakpointsEntity = breakpointsService.findById(firstBreakPointId); AngleUe4 playerAngle = player.getAngle(); //初始化的时候可以写死 AnglePO player_angle = new AnglePO(); player_angle.setPitch(playerAngle.getPitch()); player_angle.setYaw(playerAngle.getYaw()); player_angle.setRoll(playerAngle.getRoll()); userEntity.setPlayerAngle(player_angle); PointPO player_position = new PointPO(); player_position.setX(breakpointsEntity.getPosition().getX()); player_position.setY(breakpointsEntity.getPosition().getY()); player_position.setZ(breakpointsEntity.getPosition().getZ()); userEntity.setPlayerPosition(player_position); //数据库user表中创建用户记录 userService.save(userEntity); JSONObject myState = new JSONObject(); myState.put("isMoving",0); myState.put("horizontalMove",0); myState.put("frameId",firstFrameId); myState.put("breakPointId",firstBreakPointId); myState.put("appId",app_id); //redis中写入用户状态信息 redisCache.setCacheObject("UserState:"+userEntity.getUserId(),myState); MetaDataFramePO metaDataFramePO = createDefaultFrameMetadata(userEntity); //返回 CommonReply.Builder builder = CommonReply.newBuilder(); //初始化的情况下,没有traceId // String[] traceIds = metaDataFramePO.getTraceIds(); // for(int i=0;i responseObserver) { try { redisPublishService.sendProtocolMessage(RedisQueueConstant.ROTATE_QUEUE,request.toBuilder()); ActionPO rotateRequestPO = new ActionPO(); int action_type = request.getActionType(); String trace_id = request.getTraceId(); String user_id = request.getUserId(); RotationAction rotationAction = request.getRotationAction(); JSONObject myState = redisCache.getCacheObject("UserState:"+user_id); //UserEntity user = userService.findUserId(user_id); RotateFrameEntity rotateFrameEntity = rotateFrameService.findById(myState.getLong("frameId")); rotateRequestPO.setAction_type(action_type); rotateRequestPO.setTrace_id(trace_id); rotateRequestPO.setUser_id(user_id); double horizontalMove = myState.getDouble("horizontalMove"); horizontalMove += rotationAction.getHorizontalMove(); double hAngle = horizontalMove * 90; log.info("旋转的角度:"+hAngle+",旋转距离:"+rotationAction.getHorizontalMove()+",积累的距离:"+horizontalMove); int offFrameIndex = (int)Math.ceil(hAngle); if(Math.abs(offFrameIndex)<1){ myState.put("horizontalMove",horizontalMove); //redis中写入用户状态信息 redisCache.setCacheObject("UserState:"+user_id,myState); log.info("没有旋转,更新了redis的UserState表"); NormalReply.Builder builder = NormalReply.newBuilder(); builder.setCode(200); responseObserver.onNext(builder.build()); responseObserver.onCompleted(); return; } else{ myState.put("horizontalMove",0); } int currentFrame = rotateFrameEntity.getFrameIndex(); //从数据库里读取 currentFrame +=offFrameIndex; if(currentFrame<0){ currentFrame+=360; } else{ currentFrame = currentFrame % 359; } rotateFrameEntity = rotateFrameService.findByAppIdAndBreakPointIdAndFrameIndex(myState.getString("appId"),myState.getLong("breakPointId"),currentFrame); rotateRequestPO.setFrameId(rotateFrameEntity.getId()); log.info("存储请求:"+rotateFrameEntity.getId()); //每次存一帧 redisCache.setCacheList("setCacheRequest:"+user_id, Arrays.asList(rotateRequestPO)); //redis中写入用户状态信息 myState.put("frameId",rotateFrameEntity.getId()); redisCache.setCacheObject("UserState:"+user_id,myState); NormalReply.Builder builder = NormalReply.newBuilder(); builder.setCode(200); responseObserver.onNext(builder.build()); responseObserver.onCompleted(); } catch(Exception e) { e.printStackTrace(); responseObserver.onNext(NormalReply.newBuilder().setCode(500).build()); responseObserver.onCompleted(); log.error("rotateException{}",e.getMessage()); } } @Override public void echo(EchoRequest request, StreamObserver responseObserver){ try{ int action_type = request.getActionType(); String trace_id = request.getTraceId(); EchoReply.Builder builder = EchoReply.newBuilder(); builder.setActionType(action_type); builder.setPointType(100); builder.setExtra(""); builder.setTraceId(trace_id); builder.setPacketId(""); //builder.setNps(nps); builder.setPeopleNum(0); builder.setZoneId(""); builder.setEchoMsg(""); builder.setReserveDetail(null); //builder.setUserWithAvatarList(); //builder.setNewUserStates(); builder.setCode(0); builder.setMsg(""); responseObserver.onNext(builder.build()); responseObserver.onCompleted(); } catch(Exception e) { e.printStackTrace(); log.error("echoException{}",e.getMessage()); } } @Override public void usersState(GetNewUserStateRequest request, StreamObserver responseObserver){ try{ int action_type = request.getActionType(); String trace_id = request.getTraceId(); String user_id = request.getUserId(); //从数据库中取全部在线的user表 List list = userService.findUserOnline(true); GetNewUserStateReply.Builder builder = GetNewUserStateReply.newBuilder(); builder.setActionType(action_type); builder.setPointType(100); builder.setExtra(""); builder.setTraceId(trace_id); builder.setPacketId(""); //builder.setNps(nps); builder.setPeopleNum(0); builder.setZoneId(""); builder.setEchoMsg(""); builder.setReserveDetail(null); //builder.setUserWithAvatarList(); if(list.size()>0){ for(int i=0;i responseObserver){ try{ //int action_type= request.getActionType(); ClickingAction clicking_action = request.getClickingAction(); //State clicking_state = request.getClickingState(); String trace_id = request.getTraceId(); String user_id = request.getUserId(); UserEntity user = userService.findUserId(user_id); String appId = user.getAppId(); Long breakPointId = user.getBreakPointId(); BreakpointsEntity currentBreakpointsEntity = breakpointsService.getById(breakPointId); Point end = clicking_action.getClickingPoint(); RotateFrameEntity rotateFrameEntity = rotateFrameService.findById(user.getFrameId()); //计算路径 RouteDto po=new RouteDto(); PointPO s= user.getPlayerPosition(); PointPO e=new PointPO(); e.setX(Double.parseDouble(end.getX())); e.setY(Double.parseDouble(end.getY())); e.setZ(Double.parseDouble(end.getZ())); po.setE_location(e); po.setS_location(s); po.setSceneCode(appId); JSONArray path = new JSONArray(); JSONArray maps = GetRoute.getRoute(metaConfig.getFreespacePath()+ File.separator +appId+"_target_freespace.json", po); ActionPO movePO = new ActionPO(); if (maps!=null&&maps.size()>=2){ for(int i=0;i< maps.size();++i){ Long _breakPointId = JSON.parseObject(JSONObject.toJSON(maps.get(i)).toString()).getLong("id"); path.add(_breakPointId); //旋转矫正 if(i == 1){ AnglePO cameraAnglePO = rotateFrameEntity.getCameraAngle(); //旋转矫正:不仅存入redis,而且返回矫正后的角度 cameraAnglePO = setRotateForMove( user, trace_id, cameraAnglePO); movePO.setCameraAngle(cameraAnglePO); } } movePO.setAction_type(1); movePO.setTrace_id(trace_id); movePO.setUser_id(user_id); movePO.setPath(path); Long lastBreakPointId = JSON.parseObject(JSONObject.toJSON(maps.get(maps.size() -1)).toString()).getLong("id"); BreakpointsEntity breakpointsEntity = breakpointsService.findByAppIdAndBreakPointId(appId,lastBreakPointId); int playerAngleYaw = sceneGrpcService.calAngleForBreakPointId(currentBreakpointsEntity,breakpointsEntity); AnglePO playerAngle = user.getPlayerAngle(); playerAngle.setYaw(playerAngleYaw); movePO.setPlayerAngle(playerAngle); int subFrameIndex = moveFrameService.getCountByAppIAndStartBreakPointIdAndEndBreakPointIdAndAngle( user.getAppId(),path.getLongValue(0),path.getLongValue(1), movePO.getCameraAngle().getYaw()%45); movePO.setSubFrameIndex(subFrameIndex); redisCache.setCacheList("setCacheRequest:"+user_id, Arrays.asList(movePO)); } NormalReply.Builder builder = NormalReply.newBuilder(); builder.setCode(200); } catch (Exception e){ e.printStackTrace(); //builder.setCode(0); responseObserver.onNext(NormalReply.newBuilder().setCode(500).build()); responseObserver.onCompleted(); log.error("moveException{}",e.getMessage()); } } private AnglePO setRotateForMove(UserEntity user,String trace_id,AnglePO cameraAngle){ int angle = cameraAngle.getYaw(); int offAngle = 0; offAngle = angle%45; //先简单来,就累加。后续要再调试 //存储矫正的一组帧 offAngle = Math.abs(45 - offAngle); RotateFrameEntity _rotateFrameEntity = null; for(int j=0;j responseObserver) { try { log.info("进入{}",request); int action_type = request.getActionType(); NeighborPointsAction get_neighbor_points_action = request.getGetNeighborPointsAction(); String trace_id = request.getTraceId(); String user_id = request.getUserId(); //从表breakpoints里获取所有的呼吸点,并且是数组 //TODO 根据查询所有 UserEntity userEntity = userService.findUserId(user_id); List allList = breakpointsService.findByAppId(userEntity.getAppId()); BreakPointReply.Builder res = BreakPointReply.newBuilder(); res.setActionType(action_type); res.setPointType(100); res.setExtra(""); res.setTraceId(trace_id); res.setPacketId(""); for(int i=0;i responseObserver) { try { log.info("进入{}",request); int actionType = request.getActionType(); DirAction dirAction = request.getDirAction(); String trace_id = request.getTraceId(); String user_id = request.getUserId(); String packet_id = request.getPacketId(); ActionPO joystickPO = new ActionPO(); joystickPO.setAction_type(actionType); joystickPO.setTrace_id(trace_id); joystickPO.setUser_id(user_id); joystickPO.setPacket_id(packet_id); AnglePO playerAngle = joystickPO.getPlayerAngle(); playerAngle.setYaw(dirAction.getMoveAngle()); joystickPO.setPlayerAngle(playerAngle); redisCache.setCacheList("setCacheRequest:"+user_id, Arrays.asList(joystickPO)); //速度不够,只是让人旋转 if(dirAction.getSpeedLevel()<7){ return; } UserEntity user = userService.findUserId(user_id); //邻居点里找角度最合适的点 BreakpointsEntity breakpointsEntity = breakpointsService.findByAppIdAndBreakPointId(user.getAppId(), user.getBreakPointId()); BreakpointsEntity targetBreakpointsEntity = null; List neighBreakPointIds = breakpointsEntity.getContact(); double offAngle = 1000; double moveAngle = dirAction.getMoveAngle(); int playerAngleYaw = 0; if(neighBreakPointIds.size()>0){ for(int j=0;j responseObserver){ try{ log.info("进入{}",request); //删除redis:"setCacheRequest:"+user_id redisCache.delete("setCacheRequest:"+request.getUserId()); //删除redis:"UserState:"+user.getUserId() redisCache.delete("UserState:"+request.getUserId()); //删除redis:"updateFrameMetadata:"+user.getUserId() redisCache.delete("updateFrameMetadata:"+request.getUserId()); //删除user表的记录 String user_id = request.getUserId(); userService.removeByUserId(user_id); NormalReply.Builder builder = NormalReply.newBuilder(); builder.setCode(200); responseObserver.onNext(builder.build()); responseObserver.onCompleted(); } catch(Exception e){ e.printStackTrace(); responseObserver.onNext(NormalReply.newBuilder().setCode(500).build()); responseObserver.onCompleted(); log.info("exitException{}",e.getMessage()); } } private MetaDataFramePO createDefaultFrameMetadata(UserEntity user){ String[] traceIds = new String[1]; traceIds[0] = ""; JSONArray actionResponses = new JSONArray(); RotateFrameEntity rotateFrameEntity = rotateFrameService.findById(user.getFrameId()); PointPO playerPosition = user.getPlayerPosition(); Point playerPt = Point.newBuilder().setX(String.valueOf(playerPosition.getX())).setY(String.valueOf(playerPosition.getY())).setZ(String.valueOf(playerPosition.getZ())).build(); AnglePO playerAngle = user.getPlayerAngle(); AngleUe4 playerAg =AngleUe4.newBuilder().setPitch(playerAngle.getPitch()).setYaw(playerAngle.getYaw()).setRoll(playerAngle.getRoll()).build(); Space player = sceneGrpcService.createSpace(playerPt,playerAg); PointPO cameraPoint = rotateFrameEntity.getCameraPosition(); Point cameraPosition = sceneGrpcService.createPoint(String.valueOf(cameraPoint.getX()),String.valueOf(cameraPoint.getY()),String.valueOf(cameraPoint.getZ())); AnglePO cameraAnglePO = rotateFrameEntity.getCameraAngle(); AngleUe4 cameraAngle = sceneGrpcService.createAngle(cameraAnglePO.getPitch(),cameraAnglePO.getYaw(),cameraAnglePO.getRoll()); Space camera = sceneGrpcService.createSpace(cameraPosition,cameraAngle); MetaDataFramePO metaDataFramePO = new MetaDataFramePO(); metaDataFramePO.setTraceIds(traceIds); metaDataFramePO.setVehicle(null); State playerState = sceneGrpcService.createPlayerState2(player,camera,playerPt); RenderInfo renderInfo = sceneGrpcService.createRenderInfo(); UserState userState = sceneGrpcService.createUserState( user.getUserId(), playerState, renderInfo, null); //newUserStates UserState[] newUserStates = new UserState[1]; //JSONArray newUserStates = new JSONArray(); newUserStates[0] = userState; metaDataFramePO.setNewUserStates(newUserStates); metaDataFramePO.setActionResponses(actionResponses); metaDataFramePO.setGetStateType(0); metaDataFramePO.setCode(0); metaDataFramePO.setMsg(""); return metaDataFramePO; //redisCache.setCacheObject("updateFrameMetadata:"+user.getUserId(),metaDataFramePO); } }