武汉8号线列车位置显示功能
This commit is contained in:
parent
753c314292
commit
41fe8bba1c
@ -0,0 +1,133 @@
|
|||||||
|
package club.joylink.rtss.simulation.cbtc.ATS.service;
|
||||||
|
|
||||||
|
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
|
||||||
|
import club.joylink.rtss.simulation.cbtc.ATP.ground.MaService;
|
||||||
|
import club.joylink.rtss.simulation.cbtc.ATS.service.ars.AtsRouteSelectService;
|
||||||
|
import club.joylink.rtss.simulation.cbtc.CI.CiApiService;
|
||||||
|
import club.joylink.rtss.simulation.cbtc.CI.CiLogic;
|
||||||
|
import club.joylink.rtss.simulation.cbtc.Simulation;
|
||||||
|
import club.joylink.rtss.simulation.cbtc.SimulationLifeCycleService;
|
||||||
|
import club.joylink.rtss.simulation.cbtc.constant.RunLevel;
|
||||||
|
import club.joylink.rtss.simulation.cbtc.constant.SimulationConstants;
|
||||||
|
import club.joylink.rtss.simulation.cbtc.data.CalculateService;
|
||||||
|
import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository;
|
||||||
|
import club.joylink.rtss.simulation.cbtc.data.map.MapConfig;
|
||||||
|
import club.joylink.rtss.simulation.cbtc.data.map.Route;
|
||||||
|
import club.joylink.rtss.simulation.cbtc.data.map.Section;
|
||||||
|
import club.joylink.rtss.simulation.cbtc.data.plan.StationPlan;
|
||||||
|
import club.joylink.rtss.simulation.cbtc.data.plan.TripPlan;
|
||||||
|
import club.joylink.rtss.simulation.cbtc.data.support.RoutePath;
|
||||||
|
import club.joylink.rtss.simulation.cbtc.data.support.SectionPosition;
|
||||||
|
import club.joylink.rtss.simulation.cbtc.data.support.TrainLoadParam2;
|
||||||
|
import club.joylink.rtss.simulation.cbtc.data.vo.TrainInfo;
|
||||||
|
import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityTrain;
|
||||||
|
import club.joylink.rtss.simulation.cbtc.device.virtual.VRDeviceLogicLoop;
|
||||||
|
import club.joylink.rtss.simulation.cbtc.device.virtual.VRTrainRunningService;
|
||||||
|
import club.joylink.rtss.simulation.cbtc.event.SimulationRunAsPlanEvent;
|
||||||
|
import club.joylink.rtss.simulation.cbtc.exception.SimulationException;
|
||||||
|
import club.joylink.rtss.simulation.cbtc.exception.SimulationExceptionType;
|
||||||
|
import club.joylink.rtss.simulation.cbtc.onboard.ATP.ATPService;
|
||||||
|
import club.joylink.rtss.simulation.cbtc.tool.DeviceStatusModifyTool;
|
||||||
|
import club.joylink.rtss.vo.ws.TrainPosition;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.LocalTime;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
public class NewAtsTrainLoadService extends AtsTrainLoadService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private VRTrainRunningService vrTrainRunningService;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public void loadTripNumberTrain(Simulation simulation, TrainPosition tp,Section section) {
|
||||||
|
SimulationDataRepository repository = simulation.getRepository();
|
||||||
|
String tripNumber = tp.getTrainTripNum();
|
||||||
|
TrainInfo trainInfo = repository.getTrainInfoMap().values().stream().filter(train -> tripNumber.equals(train.getTripNumber())).findFirst().orElse(null);
|
||||||
|
|
||||||
|
// List<VirtualRealityTrain> allVrTrain = repository.getAllVrTrain();
|
||||||
|
|
||||||
|
if(Objects.nonNull(trainInfo)){
|
||||||
|
//存在列车需要更新位置
|
||||||
|
Optional<VirtualRealityTrain> virtualRealityTrainOptional = repository.getAllVrTrain().stream().filter(d->Objects.equals(d.getTripNumber(),tripNumber)).findFirst();
|
||||||
|
VirtualRealityTrain virtualRealityTrain = virtualRealityTrainOptional.get();
|
||||||
|
trainOnline(simulation, section, tp, virtualRealityTrain);
|
||||||
|
// virtualRealityTrain.initManualTrain(headPosition, tp.isRight());
|
||||||
|
}else{
|
||||||
|
|
||||||
|
Optional<VirtualRealityTrain> virtualRealityTrainOptional = repository.getAllVrTrain().stream()
|
||||||
|
.filter(vrTrain -> !repository.isVrTrainOnline(vrTrain.getGroupNumber()))
|
||||||
|
.findFirst();
|
||||||
|
VirtualRealityTrain virtualRealityTrain = virtualRealityTrainOptional.get();
|
||||||
|
// 设置列车车次
|
||||||
|
virtualRealityTrain.setTripNumber(tripNumber);
|
||||||
|
trainOnline(simulation, section, tp, virtualRealityTrain);
|
||||||
|
// SectionPosition headPosition = new SectionPosition(section, tp.getLocation() - section.getKmMin());
|
||||||
|
// virtualRealityTrain.initManualTrain(headPosition, tp.isRight());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 列车上线并构建ATS监控列车信息
|
||||||
|
* @param simulation
|
||||||
|
* @param section
|
||||||
|
* @param tp
|
||||||
|
* @param train
|
||||||
|
*/
|
||||||
|
private void trainOnline(Simulation simulation, Section section, TrainPosition tp, VirtualRealityTrain train) {
|
||||||
|
boolean right = tp.isRight();
|
||||||
|
if (!section.isPhysical()) {
|
||||||
|
section = section.getParent();
|
||||||
|
}
|
||||||
|
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertNotNull(section.isPhysical(), "列车需加载到物理区段上");
|
||||||
|
//重叠检测
|
||||||
|
SectionPosition headPosition = new SectionPosition(section, tp.getLocation() - section.getKmMin());
|
||||||
|
// SectionPosition headPosition = new SectionPosition(section, section.getStopPointByDirection(right));
|
||||||
|
SectionPosition tailPosition = CalculateService.calculateNextPositionByStartAndLen(headPosition, !right, train.getLen(), false);
|
||||||
|
boolean willOverlap = vrTrainRunningService.willOverlap(simulation, headPosition, tailPosition);
|
||||||
|
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertNotTrue(willOverlap, "列车重叠");
|
||||||
|
// 列车上线并构建ATS监控列车信息
|
||||||
|
manualTrainOnlineAndSupervise(simulation, train, headPosition, right);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 人工车上线并监控
|
||||||
|
*/
|
||||||
|
private void manualTrainOnlineAndSupervise(Simulation simulation, VirtualRealityTrain train, SectionPosition headPosition, boolean right) {
|
||||||
|
train.initManualTrain(headPosition, right);
|
||||||
|
SimulationDataRepository repository = simulation.getRepository();
|
||||||
|
//设置列车预选模式、驾驶模式、运行级别
|
||||||
|
if (!headPosition.getSection().anyZcWorking()) {
|
||||||
|
train.initAsRM();
|
||||||
|
} else {
|
||||||
|
MapConfig config = repository.getConfig();
|
||||||
|
if (RunLevel.ITC.equals(config.getRunMode())) {
|
||||||
|
train.initAsAM_I();
|
||||||
|
} else if (RunLevel.IL.equals(config.getRunMode())) {
|
||||||
|
train.initAsRM();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!repository.getConfig().isHandleDepot()) {
|
||||||
|
TrainInfo trainInfo = TrainInfo.constructManualTrain(train);
|
||||||
|
trainInfo.tracking(train);
|
||||||
|
repository.addOnlineTrain(train);
|
||||||
|
repository.addTrainInfo(trainInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -6,71 +6,110 @@ import club.joylink.rtss.simulation.SimulationManager;
|
|||||||
import club.joylink.rtss.simulation.cbtc.Simulation;
|
import club.joylink.rtss.simulation.cbtc.Simulation;
|
||||||
import club.joylink.rtss.simulation.cbtc.build.SimulationBuildParams;
|
import club.joylink.rtss.simulation.cbtc.build.SimulationBuildParams;
|
||||||
import club.joylink.rtss.simulation.cbtc.data.map.Section;
|
import club.joylink.rtss.simulation.cbtc.data.map.Section;
|
||||||
|
import club.joylink.rtss.util.JsonUtils;
|
||||||
import club.joylink.rtss.vo.ws.TrainPosition;
|
import club.joylink.rtss.vo.ws.TrainPosition;
|
||||||
import com.google.common.cache.Cache;
|
import com.google.common.cache.Cache;
|
||||||
import com.google.common.cache.CacheBuilder;
|
import com.google.common.cache.CacheBuilder;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
import org.springframework.util.StringUtils;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.util.*;
|
import java.util.Comparator;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class TrainPositionService {
|
public class TrainPositionService {
|
||||||
@Resource
|
@Resource
|
||||||
AtsTrainLoadService atsTrainLoadService;
|
private NewAtsTrainLoadService newAtsTrainLoadService;
|
||||||
@Resource
|
@Resource
|
||||||
SimulationManager simulationManager;
|
private SimulationManager simulationManager;
|
||||||
private final static Cache<Section.SectionRoadType,List<Section>> ROAD_TYPE_CACHE = CacheBuilder.newBuilder().build();
|
/**
|
||||||
|
* 数据过期时间
|
||||||
public void initTrainOrUpdate(String mapName,TrainPosition tp){
|
*/
|
||||||
|
private final static long EXPIRE_SECTION_TIME_MIN = 10;
|
||||||
|
/**
|
||||||
|
* 区段的缓存
|
||||||
|
* key 对应的方向类型
|
||||||
|
* EXPIRE_SECTION_TIME_MIN 数据过期时间
|
||||||
|
*/
|
||||||
|
private final static Cache<Section.SectionRoadType,List<Section>> ROAD_TYPE_CACHE = CacheBuilder.newBuilder().expireAfterWrite(EXPIRE_SECTION_TIME_MIN, TimeUnit.MINUTES).build();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化或更新列车的位置
|
||||||
|
* @param mapName
|
||||||
|
* @param json
|
||||||
|
*/
|
||||||
|
public void initTrainOrUpdate(String mapName,String json){
|
||||||
|
TrainPosition tp = JsonUtils.read(json, TrainPosition.class);
|
||||||
List<Simulation> simulationList = this.findSimulationList(mapName);
|
List<Simulation> simulationList = this.findSimulationList(mapName);
|
||||||
if(Objects.equals(true, CollectionUtils.isEmpty(simulationList))){
|
if(Objects.equals(true, CollectionUtils.isEmpty(simulationList))){
|
||||||
log.error("");
|
log.error("未找到对应的类型的仿真,无法渲染列车位置 param:{}",json);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Section> sectionList = findDirectionAllSection(simulationList.get(0),tp.getRoadType());
|
List<Section> sectionList = findDirectionAllSection(simulationList.get(0),tp.getRoadType());
|
||||||
|
Section section = this.findSecion(sectionList,tp);
|
||||||
|
if(Objects.isNull(section)){
|
||||||
|
log.error("未找到对应的区段 param:{}",json);
|
||||||
|
return;
|
||||||
|
}
|
||||||
for (Simulation sim : simulationList) {
|
for (Simulation sim : simulationList) {
|
||||||
|
this.newAtsTrainLoadService.loadTripNumberTrain(sim,tp,section);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void findSecion(List<Section> sectionList,TrainPosition tp){
|
/**
|
||||||
|
* 根据传入的参数 定位对应的所在的区段
|
||||||
|
* @param sectionList
|
||||||
|
* @param tp
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private Section findSecion(List<Section> sectionList,TrainPosition tp){
|
||||||
int i = 0;
|
int i = 0;
|
||||||
Section findSection;
|
// Section findSection;
|
||||||
for (Section section : sectionList) {
|
for (Section section : sectionList) {
|
||||||
if(tp.isRight()){
|
if(tp.isRight()){
|
||||||
if(tp.getLocation() <= section.getKmMax()){
|
if(tp.getLocation() <= section.getKmMax()){
|
||||||
findSection = section;
|
return section;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
|
if(tp.getLocation() <= section.getKmMax() && tp.getLocation() >= section.getKmMin()){
|
||||||
|
return section;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据车辆方向获取对应的区段并升序排序
|
||||||
|
* @param sim
|
||||||
|
* @param roadType
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
private static synchronized List<Section> findDirectionAllSection(Simulation sim,Section.SectionRoadType roadType){
|
private static synchronized List<Section> findDirectionAllSection(Simulation sim,Section.SectionRoadType roadType){
|
||||||
List<Section> list = ROAD_TYPE_CACHE.getIfPresent(roadType);
|
List<Section> list = ROAD_TYPE_CACHE.getIfPresent(roadType);
|
||||||
if(Objects.equals(true,CollectionUtils.isEmpty(list))){
|
if(Objects.equals(true,CollectionUtils.isEmpty(list))){
|
||||||
list = sim.getRepository().getSectionList();
|
list = sim.getRepository().getSectionList();
|
||||||
list = list.stream().filter(d->d.getRoadType() == roadType)
|
list = list.stream().filter(d->d.getRoadType() == roadType)
|
||||||
.sorted(Comparator.comparing(Section::getKmMin)/*.reversed()*/).collect(Collectors.toList());
|
.sorted(Comparator.comparing(Section::getKmMin)).collect(Collectors.toList());
|
||||||
ROAD_TYPE_CACHE.put(roadType,list);
|
ROAD_TYPE_CACHE.put(roadType,list);
|
||||||
}
|
}
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取对应线路的仿真,并且地图类型为 MapPrdTypeEnum.BIG_SCREEN_TRAIN_POSITION
|
||||||
|
* @param mapName
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
private List<Simulation> findSimulationList(String mapName){
|
private List<Simulation> findSimulationList(String mapName){
|
||||||
return this.simulationManager.getSimulationList().stream().filter(d->{
|
return this.simulationManager.getSimulationList().stream().filter(d->{
|
||||||
if(d instanceof Simulation){
|
if(d instanceof Simulation){
|
||||||
|
@ -1,15 +1,20 @@
|
|||||||
package club.joylink.rtss.websocket;
|
package club.joylink.rtss.websocket;
|
||||||
|
|
||||||
|
import club.joylink.rtss.simulation.cbtc.ATS.service.TrainPositionService;
|
||||||
import club.joylink.rtss.simulation.cbtc.GroupSimulationCache;
|
import club.joylink.rtss.simulation.cbtc.GroupSimulationCache;
|
||||||
import club.joylink.rtss.simulation.cbtc.Simulation;
|
import club.joylink.rtss.simulation.cbtc.Simulation;
|
||||||
|
|
||||||
|
import club.joylink.rtss.util.JsonUtils;
|
||||||
import club.joylink.rtss.vo.client.SocketMessageVO;
|
import club.joylink.rtss.vo.client.SocketMessageVO;
|
||||||
import club.joylink.rtss.vo.client.factory.SocketMessageFactory;
|
import club.joylink.rtss.vo.client.factory.SocketMessageFactory;
|
||||||
|
import club.joylink.rtss.vo.ws.TrainPosition;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.messaging.handler.annotation.DestinationVariable;
|
import org.springframework.messaging.handler.annotation.DestinationVariable;
|
||||||
import org.springframework.messaging.handler.annotation.MessageMapping;
|
import org.springframework.messaging.handler.annotation.MessageMapping;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
import java.security.Principal;
|
import java.security.Principal;
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
@ -21,7 +26,8 @@ public class WebSocketController {
|
|||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private GroupSimulationCache groupSimulationCache;
|
private GroupSimulationCache groupSimulationCache;
|
||||||
|
@Resource
|
||||||
|
private TrainPositionService trainPositionService;
|
||||||
@MessageMapping("/simulation/{group}/vr")
|
@MessageMapping("/simulation/{group}/vr")
|
||||||
public void routingData(Principal user, String json, @DestinationVariable String group) {
|
public void routingData(Principal user, String json, @DestinationVariable String group) {
|
||||||
Simulation simulation = groupSimulationCache.getSimulationByGroup(group);
|
Simulation simulation = groupSimulationCache.getSimulationByGroup(group);
|
||||||
@ -29,11 +35,8 @@ public class WebSocketController {
|
|||||||
stompMessageService.sendToUser(simulation.getSimulationUserIds(), message);
|
stompMessageService.sendToUser(simulation.getSimulationUserIds(), message);
|
||||||
}
|
}
|
||||||
|
|
||||||
@MessageMapping("/{mapId}/trainPosition")
|
@MessageMapping("/{mapName}/trainPosition")
|
||||||
public void mlbs( String json,@DestinationVariable String mapId) {
|
public void mlbs( String json,@DestinationVariable String mapName) {
|
||||||
// Simulation simulation = groupSimulationCache.getSimulationByGroup(group);
|
this.trainPositionService.initTrainOrUpdate(mapName,json);
|
||||||
// SocketMessageVO<String> message = SocketMessageFactory.buildVrMessage(group, json);
|
|
||||||
// stompMessageService.sendToUser(simulation.getSimulationUserIds(), message);
|
|
||||||
System.out.println("aaaaaaaaaaaaa");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ import java.nio.charset.StandardCharsets;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class StompClientManager {
|
public class StompClientManager {
|
||||||
@ -26,14 +27,50 @@ public class StompClientManager {
|
|||||||
.connect("ws://127.0.0.1:9000/joylink-tbi-websocket",handler, "null");
|
.connect("ws://127.0.0.1:9000/joylink-tbi-websocket",handler, "null");
|
||||||
StompSession stompSession = future.get();
|
StompSession stompSession = future.get();
|
||||||
|
|
||||||
Map<String,Object> dataMap = new HashMap<>();
|
runToLeft(stompSession,"train001");
|
||||||
dataMap.put("trainTripNum","train001");
|
// runToRight(stompSession,"train002");
|
||||||
dataMap.put("direction",1);
|
|
||||||
dataMap.put("location",19.99);
|
}
|
||||||
ObjectMapper om = new ObjectMapper();
|
|
||||||
String val = JsonUtils.writeValueNullableFieldAsString(dataMap);
|
public static void runToLeft(StompSession stompSession,String tripNum){
|
||||||
System.out.println(val);
|
int step = 80;
|
||||||
stompSession.send("/app/测试中文/trainPosition",val.getBytes(StandardCharsets.UTF_8));
|
int location = 40000;
|
||||||
|
while(true){
|
||||||
|
location -= step;
|
||||||
|
Map<String,Object> dataMap = new HashMap<>();
|
||||||
|
dataMap.put("trainTripNum",tripNum);
|
||||||
|
// dataMap.put("direction",1);
|
||||||
|
dataMap.put("direction",0);
|
||||||
|
dataMap.put("location",location);
|
||||||
|
String val = JsonUtils.writeValueNullableFieldAsString(dataMap);
|
||||||
|
System.out.println(val);
|
||||||
|
stompSession.send("/app/武汉8号线/trainPosition",val.getBytes(StandardCharsets.UTF_8));
|
||||||
|
try {
|
||||||
|
TimeUnit.MILLISECONDS.sleep(500);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static void runToRight(StompSession stompSession,String tripNum){
|
||||||
|
int step = 20;
|
||||||
|
int location = 0;
|
||||||
|
while(true){
|
||||||
|
location += step;
|
||||||
|
Map<String,Object> dataMap = new HashMap<>();
|
||||||
|
dataMap.put("trainTripNum",tripNum);
|
||||||
|
dataMap.put("direction",1);
|
||||||
|
// dataMap.put("direction",0);
|
||||||
|
dataMap.put("location",location);
|
||||||
|
String val = JsonUtils.writeValueNullableFieldAsString(dataMap);
|
||||||
|
System.out.println(val);
|
||||||
|
stompSession.send("/app/武汉8号线/trainPosition",val.getBytes(StandardCharsets.UTF_8));
|
||||||
|
try {
|
||||||
|
TimeUnit.MILLISECONDS.sleep(500);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user