package com.hivekion.scenario.service.impl; import cn.hutool.json.JSONObject; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.hivekion.Global; import com.hivekion.baseData.entity.Scenario; import com.hivekion.baseData.entity.WeatherResource; import com.hivekion.baseData.service.IWeatherResourceService; import com.hivekion.baseData.service.ScenarioService; import com.hivekion.common.entity.ResponseCmdInfo; import com.hivekion.common.redis.RedisUtil; import com.hivekion.environment.entity.SimtoolWeather; import com.hivekion.environment.service.SimtoolWeatherService; import com.hivekion.scenario.entity.ScenarioTask; import com.hivekion.scenario.mapper.ScenarioTaskMapper; import com.hivekion.scenario.service.ScenarioTaskService; import com.hivekion.scenario.service.TaskLogicService; import com.hivekion.statistic.service.StatisticService; import com.hivekion.thread.SpringGlobalTaskManager; import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.util.List; import javax.annotation.PostConstruct; import javax.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; /** *

* 服务实现类 *

* * @author liDongYu * @since 2025-09-13 */ @Service @Slf4j public class ScenarioTaskServiceImpl extends ServiceImpl implements ScenarioTaskService { @Resource private SpringGlobalTaskManager springGlobalTaskManager; @Resource private SimtoolWeatherService weatherService; @Resource private RedisUtil redisUtil; @Resource private ScenarioService scenarioService; @Resource private IWeatherResourceService weatherResourceService; @Resource private TaskLogicService taskLogicService; @PostConstruct public void initTest(){ this.start(2746,"1"); } @Override public void start(Integer scenarioId, String roomId) { log.info("scenarioId::{},roomId::{}",scenarioId,roomId); Scenario currentScenario = scenarioService.getScenarioById(scenarioId); //想定当前持续时间 redisUtil.hset(roomId + "_" + scenarioId, "duringTime", "0"); //想定当前状态 redisUtil.hset(roomId + "_" + scenarioId, "states", "running"); //查询天气数据 List weatherList = weatherResourceService.list(new QueryWrapper() .eq("scenario_id",id)); JSONArray jsonArray = new JSONArray(); for(WeatherResource weatherResource: weatherList) { String weaherStr = JSON.toJSONString(weatherResource); Long timeBegstamp = weatherResource.getLastBegTime().atZone(ZoneId.systemDefault()) .toInstant() .toEpochMilli(); Long timeEndstamp = weatherResource.getLastEndTime().atZone(ZoneId.systemDefault()) .toInstant() .toEpochMilli(); com.alibaba.fastjson.JSONObject weatherObj = JSON.parseObject(weaherStr); weatherObj.put("weatherBegTime",timeBegstamp); weatherObj.put("weatherEndTime",timeEndstamp); jsonArray.add(weatherObj); } //放入天气数据 redisUtil.hset(roomId + "_" + id, "weather", JSON.toJSONString(jsonArray)); //查询任务 ScenarioTask queryTask = new ScenarioTask(); queryTask.setScenarioId(scenarioId); redisUtil.hset(roomId + "_" + scenarioId, "taskList", JSON.toJSONString(queryTaskList(queryTask))); new Thread(() -> { springGlobalTaskManager.startPerSecondTask(roomId + "_" + scenarioId + "_task", () -> { //时间累计 increaseTime(currentScenario, roomId); //天气触发 weatherTrigger(currentScenario, roomId); //任务触发 taskTrigger(currentScenario, roomId); }); }).start(); } @Override public void stop(Integer id, String roomId) { } @Override public void sleepWhile(Integer id, String roomId) { redisUtil.hset(roomId + "_" + id, "states", "sleep"); } @Override public void wakeup(Integer id, String roomId) { redisUtil.hset(roomId + "_" + id, "states", "running"); } private void increaseTime(Scenario currentScenario, String roomId) { try{ log.info("currentScenario:;{}",currentScenario); int mag = Global.roomParamMap.get(currentScenario.getId() + "_" + roomId) == null ? 1 : Global.roomParamMap.get(currentScenario.getId() + "_" + roomId).getMag(); //获取当前状态 Object statusObj = redisUtil.hget(roomId + "_" + currentScenario.getId(), "status"); if (statusObj != null && statusObj.toString().equals("running")) { Object duringObj = redisUtil.hget(roomId + "_" + currentScenario.getId(), "duringTime"); if (duringObj != null) { int oldValue = duringObj instanceof Integer ? (Integer) duringObj : 0; oldValue = oldValue + mag; redisUtil.hset(roomId + "_" + currentScenario.getId(), "duringTime", oldValue); } } }catch (Exception e){ log.error("error::",e); } } /** * 天气触发 * * @param currentScenario 当前想定 * @param roomId 房间ID */ private void weatherTrigger(Scenario currentScenario, String roomId) { try { String weatherResources = (String) redisUtil.hget(roomId + "_" + currentScenario.getId(), "weather"); JSONArray weatherArray = JSONArray.parseArray(weatherResources); String weatherStatus = redisUtil.hget(roomId + "_" + currentScenario.getId(), "weather-status") !=null?(String) redisUtil.hget(roomId + "_" + currentScenario.getId(), "weather-status"):null; for(int i=0;i= timeBegstamp && StringUtils.isEmpty(weatherStatus)) { ResponseCmdInfo responseCmdInfo = new ResponseCmdInfo(); responseCmdInfo.setScenarioId(currentScenario.getId()); responseCmdInfo.setRoom(roomId); responseCmdInfo.setCmdType("start-" + weatherObj.getString("weatherType")); responseCmdInfo.setScenarioId(currentScenario.getId()); responseCmdInfo.setRoom(roomId); System.out.println(responseCmdInfo.toString()); redisUtil.hset(roomId + "_" + currentScenario.getId(), "weather-status","start"); Global.sendCmdInfoQueue.add(responseCmdInfo); } else if(timeBegstamp+duringTime >= timeEndstamp && StringUtils.isNotEmpty(weatherStatus)){ ResponseCmdInfo responseCmdInfo = new ResponseCmdInfo(); responseCmdInfo.setScenarioId(currentScenario.getId()); responseCmdInfo.setRoom(roomId); responseCmdInfo.setCmdType("end-" + weatherObj.getString("weatherType")); responseCmdInfo.setScenarioId(currentScenario.getId()); responseCmdInfo.setRoom(roomId); System.out.println(responseCmdInfo.toString()); redisUtil.hset(roomId + "_" + currentScenario.getId(), "weather-status","end"); Global.sendCmdInfoQueue.add(responseCmdInfo); }else{ ResponseCmdInfo responseCmdInfo = new ResponseCmdInfo(); responseCmdInfo.setScenarioId(currentScenario.getId()); responseCmdInfo.setRoom(roomId); responseCmdInfo.setCmdType("remain-" + weatherObj.getString("weatherType")); responseCmdInfo.setScenarioId(currentScenario.getId()); responseCmdInfo.setRoom(roomId); System.out.println(responseCmdInfo.toString()); Global.sendCmdInfoQueue.add(responseCmdInfo); } } } catch (Exception ex) { ex.printStackTrace(); log.error(ex.getMessage()); } } /** * 获取当前想定从开始到现在时间 * @param scenario * @param roomId * @return */ private int getCurrentDuringTime(Scenario scenario, String roomId) { Object duringTime = redisUtil.hget(roomId + "_" + scenario.getId(), "duringTime"); if (duringTime != null) { return (Integer) duringTime; } return 0; } private void taskTrigger(Scenario currentScenario, String roomId) { try{ log.info("{}",currentScenario); Object statusObj = redisUtil.hget(roomId + "_" + currentScenario.getId(), "status"); if (statusObj != null && statusObj.toString().equals("running")) { Object taskListObj = redisUtil.hget(roomId + "_" + currentScenario.getId(), "taskList"); if (taskListObj != null) { if (taskListObj instanceof List) { List taskList = (List) taskListObj; for (Object task : taskList) { ScenarioTask scenarioTask = (ScenarioTask) task; switch (scenarioTask.getTaskType()) { case "1": taskLogicService.handleMoveTask(scenarioTask, currentScenario, roomId,18.0,null); break; case "2": taskLogicService.handleBattleTask(scenarioTask, currentScenario, roomId); break; case "4": case "5": case "6": case "7": default: taskLogicService.supplierTask(scenarioTask, currentScenario, roomId); } } } } } }catch (Exception e){ log.error("error::",e); } } @Override public List queryTaskList(ScenarioTask task) { QueryWrapper queryWrapper = new QueryWrapper<>(); queryWrapper.eq("scenario_id", task.getScenarioId()); if (StringUtils.isNotBlank(task.getResourceId())) { queryWrapper.eq("resource_id", task.getResourceId()); } return this.list(queryWrapper); } }