package com.fdkk.fdkkmeta.grpcService; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.util.ArrayUtil; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; 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.RotateFrameEntity; import com.fdkk.fdkkmeta.domain.entity.mysql.UserEntity; import com.fdkk.fdkkmeta.domain.po.PointPO; import com.fdkk.fdkkmeta.grpc.*; import com.fdkk.fdkkmeta.redis.RedisCache; 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 com.google.protobuf.Message; import com.googlecode.protobuf.format.JsonFormat; import io.grpc.stub.StreamObserver; import lombok.extern.slf4j.Slf4j; import net.devh.boot.grpc.server.service.GrpcService; import org.json.JSONObject; import org.springframework.beans.factory.annotation.Autowired; import java.io.File; import java.io.IOException; 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; /*** * 回复 案例 * 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 { 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(); //保存user UserEntity userEntity=new UserEntity(); userService.save(userEntity); //初始化的时候可以写死 //frame_id //break_point_id //player_angle //再写入user表 } catch(Exception e) { e.printStackTrace(); } } @Override public void rotate(RotateRequest request, StreamObserver responseObserver) { try { /* { "action_type":1014, "rotation_action": { "vertical_move":0, "horizontal_move":-0.020630372492836675 }, "trace_id":"b40a894e-cd59-4db5-8d75-a8466a0c9f15", "user_id":"0a3987974feb4" } */ int action_type = request.getActionType(); //request.getRotationAction() String trace_id = request.getTraceId(); String user_id = request.getUserId(); //这三个变量从user表和rotateframe表里取 UserEntity user = userService.findById(user_id); BreakpointsEntity breakpointsEntity = breakpointsService.findById(user.getBreakPointId()); RotateFrameEntity rotateFrameEntity = rotateFrameService.findById(user.getFrameId()); Space player = null; Space camera = null; Point cameraCenter = null; State playerState = createPlayerState( player, camera, cameraCenter); RenderInfo renderInfo = createRenderInfo(); Event event = createEvent(); UserState userState = createUserState( user_id, playerState, renderInfo, event); /// metaConfig.getVideoFramePath() log.info("VideoFramePath{}", metaConfig.getVideoFramePath()); NormalReply res = NormalReply.newBuilder() .setTraceIds(0, trace_id) .setVehicle(null) .setNewUserStates(0, userState) .setActionResponses(0, 0) //这个要查查 .setGetStateType(0) .setCode(0) .setMsg("OK") .setFrameSrc(null) //从数据库中获取对应的路径 .build(); responseObserver.onNext(res); responseObserver.onCompleted(); } catch(Exception e) { e.printStackTrace(); } } //返回的是角度矫正数据 @Override public void moveStart(StartMoveRequest request, StreamObserver responseObserver) { try { /* * 1.从user表里获得当前人物所在的breakPoint_id * 2.根据breakPoint_id,从breakpoints表里获得对应的起始坐标 * 3.根据request中的clicking_action里的clicking_point(目的地)以及当前起始坐标计算出路径 * 4.返回整个路径的一段 * * */ int action_type= request.getActionType(); ClickingAction clicking_action = request.getClickingAction(); Point end = clicking_action.getClickingPoint(); State clicking_state = request.getClickingState(); String trace_id = request.getTraceId(); String user_id = request.getUserId(); UserEntity userEntity = userService.findById(user_id); BreakpointsEntity breakpointsEntity = breakpointsService.findById(userEntity.getBreakPointId()); Point start = null; //从user表里取 //计算路径 String appId = userEntity.getAppId(); RouteDto po=new RouteDto(); PointPO s=new PointPO(); s.setX(Double.parseDouble(start.getX())); s.setY(Double.parseDouble(start.getY())); s.setZ(Double.parseDouble(start.getY())); PointPO e=new PointPO(); e.setX(Double.parseDouble(end.getX())); e.setY(Double.parseDouble(end.getY())); e.setZ(Double.parseDouble(end.getY())); po.setE_location(e); po.setS_location(s); po.setSceneCode(appId); JSONArray maps = GetRoute.getRoute(metaConfig.getFreespacePath()+ File.separator +appId+"_target_freespace.json", po); //处理路径数组,处理完成后放入缓存 redisCache.setCacheObject(trace_id,maps); //开始返回结果,一段一段的返回(每段是两个邻居点的过渡),第一段之前还要有角度的矫正 //矫正的结果: //moveFrameService.findById() //这三个变量从user表和rotateframe表里取。自己对应的都是空 Space player = null; Space camera = null; Point cameraCenter = null; State playerState = createPlayerState( player, camera, cameraCenter); RenderInfo renderInfo = createRenderInfo(); Event event = createEvent(); UserState userState = createUserState( user_id, playerState, renderInfo, event); MoveReply res = MoveReply.newBuilder() .setTraceIds(0, trace_id) .setVehicle(null) .setNewUserStates(0, userState) .setActionResponses(0, 0) //这个要查查 .setGetStateType(0) .setCode(0) .setMsg("OK") //.setPlayer(index, value) //.setCamera(index, value) //.setCameraCenter(index, value) //.setFrameSrc(index, value) .setIsEnd(false) .build(); } catch(Exception e) { e.printStackTrace(); } } @Override public void moveProcess(MoveNextNeighborRequest request, StreamObserver responseObserver) { try { /* * 1.从user表里获得当前人物所在的breakPoint_id * 2.根据breakPoint_id,从breakpoints表里获得对应的起始坐标 * 3.根据request中的clicking_action里的clicking_point(目的地)以及当前起始坐标计算出路径 * 4.返回整个路径的一段 * * */ String user_id = request.getUserId(); String trace_id = request.getTraceId(); boolean needNext = request.getNext(); //moveStart的结果参考moveStart } catch(Exception e) { e.printStackTrace(); } } @Override public void getBreakPoint(BreakPointRequest request, StreamObserver 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.findById(user_id); List allList = breakpointsService.findByAppId(userEntity.getAppId()); Point[] nps=null; BreakPointReply res = BreakPointReply.newBuilder() .setActionType(action_type) .setPointType(100) .setExtra("") .setTraceId(trace_id) .setPacketId("") //.setNps(nps) .setPeopleNum(0) .setZoneId("") .setEchoMsg("") .setReserveDetail(null) //.setUserWithAvatarList() //.setNewUserStates() .setCode(0) .setMsg("") .build(); responseObserver.onNext(res); responseObserver.onCompleted(); log.info("回复{}",res); } catch(Exception e) { e.printStackTrace(); } } //操作杆 @Override public void joystick(JoystickRequest request, StreamObserver responseObserver) { try { log.info("进入{}",request); // responseObserver.onNext(res); // responseObserver.onCompleted(); // log.info("回复{}",res); } catch(Exception e) { e.printStackTrace(); } } private UserState createUserState(String user_id,State state,RenderInfo renderInfo,Event event) { UserState userState = UserState.newBuilder() .setUserId(user_id) .setPlayerState(state) .setRenderInfo(renderInfo) .setEvent(event) .setRelation(1) .build(); return userState; } private State createPlayerState(Space player,Space camera,Point cameraCenter) { State playerState = State.newBuilder() .setRoomTypeId("") .setPerson(0) .setAvatarId("") .setSkinId("") .setRoomId("") .setIsHost(false) .setIsFollowHost(false) .setSkinDataVersion("") .setAvatarComponents("") .setNickName("") .setMovingMode(0) .setAttitude("") .setAreaName("") .setPathName("") .setPathId("") .setAvatarSize(1) .setExtra("") .setPrioritySync(false) .setPlayer(player) .setCamera(camera) .setCameraCenter(cameraCenter).build(); return playerState; } private RenderInfo createRenderInfo() { RenderInfo renderInfo = RenderInfo.newBuilder() .setRenderType(0) .setVideoFrame(null) .setCameraStateType(0) .setIsMoving(0) .setNeedIfr(0) .setIsVideo(0) .setStillFrame(0) .setIsRotating(0) .setIsFollowing(0) .setClientPanoTreceId("") .setPrefetchVideoId("") .setNoMedia(false).build(); return renderInfo; } private Event createEvent() { Event event = Event.newBuilder().setId("").setType(0).setRotateEvent(null).setRemoveVisitorEvent(null).build(); return event; } private Space createSpace(Point position,AngleUe4 angle) { Space space = Space.newBuilder().setPosition(position).setAngle(angle).build(); return space; } private Point createPoint(String x,String y,String z) { Point point = Point.newBuilder().setX(x).setY(y).setZ(z).build(); return point; } private AngleUe4 createAngle(int pitch,int yaw,int roll) { AngleUe4 angle = AngleUe4.newBuilder().setPitch(pitch).setYaw(yaw).setRoll(roll).build(); return angle; } }