package com.hivekion.scenario.service.impl; 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.scenario.entity.ScenarioTask; import com.hivekion.scenario.mapper.ScenarioTaskMapper; import com.hivekion.scenario.service.ScenarioTaskService; import com.hivekion.scenario.service.TaskLogicService; import com.hivekion.thread.SpringGlobalTaskManager; import java.time.Duration; import java.util.ArrayList; import java.util.List; import java.util.Random; 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 RedisUtil redisUtil; @Resource private ScenarioService scenarioService; @Resource private IWeatherResourceService weatherResourceService; @Resource private TaskLogicService taskLogicService; @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, "status", "running"); //查询天气数据 List weatherList = weatherResourceService.list( new QueryWrapper() .eq("scenario_id", scenarioId)); //放入天气数据 redisUtil.hset(roomId + "_" + scenarioId, "weather", JSONArray.toJSONString(weatherList)); //查询任务 ScenarioTask queryTask = new ScenarioTask(); queryTask.setScenarioId(scenarioId); redisUtil.hset(roomId + "_" + scenarioId, "taskList", JSONArray.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) { if (Global.roomParamMap.get(id + "_" + roomId) != null) { Global.roomParamMap.get(id + "_" + roomId).setMag(1); } springGlobalTaskManager.cancelTask(roomId + "_" + id + "_task"); } @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 { 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"); log.info("scenario_id:{},status::{}", currentScenario.getId(), statusObj); if (statusObj != null && statusObj.toString().equals("running")) { int duringTime = getCurrentDuringTime(currentScenario, roomId); duringTime = duringTime + mag; log.info("duringTime::{}", duringTime); redisUtil.hset(roomId + "_" + currentScenario.getId(), "duringTime", duringTime + ""); } } 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"); List weatherList = JSONArray.parseArray(weatherResources, WeatherResource.class); int duringTime = getCurrentDuringTime(currentScenario, roomId); for (WeatherResource resource : weatherList) { if ("init".equals(resource.getStatus())) { if (currentScenario.getStartTime().plusSeconds(duringTime) .isAfter(resource.getLastBegTime())) { log.info("{}", "start_" + resource.getWeatherType()); resource.setStatus("running"); ResponseCmdInfo responseCmdInfo = new ResponseCmdInfo<>(); responseCmdInfo.setScenarioId(currentScenario.getId()); responseCmdInfo.setRoom(roomId); responseCmdInfo.setCmdType("start_" + resource.getWeatherType()); responseCmdInfo.setScenarioId(currentScenario.getId()); responseCmdInfo.setRoom(roomId); Global.sendCmdInfoQueue.add(responseCmdInfo); } } if ("running".equals(resource.getStatus())) { if (currentScenario.getStartTime().plusSeconds(duringTime) .isAfter(resource.getLastEndTime())) { log.info("{}", "stopped_" + resource.getWeatherType()); resource.setStatus("stopped"); ResponseCmdInfo responseCmdInfo = new ResponseCmdInfo<>(); responseCmdInfo.setScenarioId(currentScenario.getId()); responseCmdInfo.setRoom(roomId); responseCmdInfo.setCmdType("stop_" + resource.getWeatherType()); responseCmdInfo.setScenarioId(currentScenario.getId()); responseCmdInfo.setRoom(roomId); Global.sendCmdInfoQueue.add(responseCmdInfo); } } } redisUtil.hset(roomId + "_" + currentScenario.getId(), "weather", JSONArray.toJSONString(weatherList)); } catch (Exception ex) { 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.parseInt(duringTime.toString()); } return 0; } private void taskTrigger(Scenario currentScenario, String roomId) { try { Object statusObj = redisUtil.hget(roomId + "_" + currentScenario.getId(), "status"); if (statusObj != null && statusObj.toString().equals("running")) { Object taskListObj = redisUtil.hget(roomId + "_" + currentScenario.getId(), "taskList"); List taskList = JSONArray.parseArray(taskListObj.toString(), ScenarioTask.class); for (ScenarioTask scenarioTask : taskList) { int duringTime = getCurrentDuringTime(currentScenario, roomId); log.info("task duringTime::{},{},{}", duringTime, currentScenario.getStartTime().plusSeconds(duringTime), scenarioTask.getStartTime()); if (currentScenario.getStartTime().plusSeconds(duringTime) .isAfter(scenarioTask.getStartTime())) { switch (scenarioTask.getTaskType()) { case "1": taskLogicService.handleMoveTask(scenarioTask, currentScenario, roomId, 18.0, null); break; case "2": Random random = new Random(); List randomIntList = new ArrayList<>(); long continueSeconds = Duration.between(scenarioTask.getStartTime(), scenarioTask.getEndTime()) .toMinutes() * 60; for (int i = 0; i < 5; i++) { randomIntList.add(random.nextInt((int) continueSeconds) + 1); } taskLogicService.handleBattleTask(scenarioTask, currentScenario, roomId, randomIntList); break; case "4": case "5": case "6": case "7": default: log.info("start a type=7 task"); taskLogicService.supplierTask(scenarioTask, currentScenario, roomId); } } } redisUtil.hset(roomId + "_" + currentScenario.getId(), "taskList", JSONArray.toJSONString(taskList)); } } 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); } }