Files
operationSystem-back/src/main/java/com/caliverse/admin/domain/service/BattleEventService.java

377 lines
16 KiB
Java

package com.caliverse.admin.domain.service;
import com.caliverse.admin.domain.dao.admin.BattleMapper;
import com.caliverse.admin.domain.datacomponent.MetaDataHandler;
import com.caliverse.admin.domain.entity.BattleEvent;
import com.caliverse.admin.domain.entity.HISTORYTYPE;
import com.caliverse.admin.domain.entity.metadata.MetaBattleConfigData;
import com.caliverse.admin.domain.entity.metadata.MetaBattleRewardData;
import com.caliverse.admin.domain.request.BattleEventRequest;
import com.caliverse.admin.domain.response.BattleEventResponse;
import com.caliverse.admin.dynamodb.service.DynamodbBattleEventService;
import com.caliverse.admin.global.common.code.CommonCode;
import com.caliverse.admin.global.common.code.ErrorCode;
import com.caliverse.admin.global.common.code.SuccessCode;
import com.caliverse.admin.global.common.constants.CommonConstants;
import com.caliverse.admin.global.common.constants.MysqlConstants;
import com.caliverse.admin.global.common.utils.CommonUtils;
import com.caliverse.admin.history.service.MysqlHistoryLogService;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestParam;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
@Service
@RequiredArgsConstructor
@Slf4j
public class BattleEventService {
private final DynamodbBattleEventService dynamodbBattleEventService;
private final BattleMapper battleMapper;
private final MetaDataHandler metaDataHandler;
private final HistoryService historyService;
private final ObjectMapper objectMapper;
private final MysqlHistoryLogService mysqlHistoryLogService;
//전투시스템 설정 데이터
public BattleEventResponse getBattleConfigList(){
List<MetaBattleConfigData> list = metaDataHandler.getMetaBattleConfigsListData();
return BattleEventResponse.builder()
.status(CommonCode.SUCCESS.getHttpStatus())
.result(CommonCode.SUCCESS.getResult())
.resultData(BattleEventResponse.ResultData.builder()
.battleConfigList(list)
.build()
)
.build();
}
//전투시스템 보상 데이터
public BattleEventResponse getBattleRewardList(){
List<MetaBattleRewardData> list = metaDataHandler.getMetaBattleRewardsListData();
return BattleEventResponse.builder()
.status(CommonCode.SUCCESS.getHttpStatus())
.result(CommonCode.SUCCESS.getResult())
.resultData(BattleEventResponse.ResultData.builder()
.battleRewardList(list)
.build()
)
.build();
}
// 전투시스템 이벤트 조회
public BattleEventResponse getBattleEventList(@RequestParam Map<String, String> requestParam){
requestParam = CommonUtils.pageSetting(requestParam);
List<BattleEvent> list = battleMapper.getBattleEventList(requestParam);
int allCnt = battleMapper.getAllCnt(requestParam);
return BattleEventResponse.builder()
.status(CommonCode.SUCCESS.getHttpStatus())
.result(CommonCode.SUCCESS.getResult())
.resultData(BattleEventResponse.ResultData.builder()
.battleEventList(list)
.total(battleMapper.getTotal())
.totalAll(allCnt)
.pageNo(requestParam.get("page_no")!=null?
Integer.parseInt(requestParam.get("page_no")):1)
.build()
)
.build();
}
// 전투시스템 이벤트 상세조회
public BattleEventResponse getBattleEventDetail(Long id){
BattleEvent battleEvent = battleMapper.getBattleEventDetail(id);
return BattleEventResponse.builder()
.status(CommonCode.SUCCESS.getHttpStatus())
.result(CommonCode.SUCCESS.getResult())
.resultData(BattleEventResponse.ResultData.builder()
.battleEvent(battleEvent)
.build())
.build();
}
@Transactional(transactionManager = "transactionManager")
public BattleEventResponse postBattleEvent(BattleEventRequest battleEventRequest){
if(battleEventRequest.getRepeatType().equals(BattleEvent.BATTLE_REPEAT_TYPE.NONE)){
LocalDateTime start_dt = battleEventRequest.getEventStartDt();
LocalDateTime end_dt = start_dt.plusHours(12);
battleEventRequest.setEventEndDt(end_dt);
}
battleEventRequest.setInstanceId(CommonConstants.BATTLE_INSTANCE_ID); //고정값으로 넣고 추후 맵정보가 늘어나면 선택하는 걸로
int operation_time = calcEndTime(battleEventRequest);
battleEventRequest.setEventOperationTime(operation_time);
// int is_time = battleMapper.chkTimeOver(battleEventRequest);
List<BattleEvent> existingList = battleMapper.getCheckBattleEventList(battleEventRequest);
boolean isTime = isTimeOverlapping(existingList, battleEventRequest);
if(isTime){
return BattleEventResponse.builder()
.status(CommonCode.ERROR.getHttpStatus())
.result(ErrorCode.ERROR_BATTLE_EVENT_TIME_OVER.toString())
.build();
}
// 일자만 필요해서 UTC시간으로 변경되다보니 한국시간(+9)을 더해서 마지막시간으로 설정
LocalDateTime end_dt_kst = battleEventRequest.getEventEndDt()
.plusHours(9)
.withHour(23)
.withMinute(59)
.withSecond(59)
.withNano(0);
battleEventRequest.setEventEndDt(end_dt_kst);
int next_event_id = dynamodbBattleEventService.getEventId() + 1;
battleEventRequest.setEventId(next_event_id);
int result = battleMapper.postBattleEvent(battleEventRequest);
log.info("AdminToolDB BattleEvent Save: {}", battleEventRequest);
long battle_event_id = battleEventRequest.getId();
HashMap<String,String> map = new HashMap<>();
map.put("id",String.valueOf(battle_event_id));
BattleEvent event_info = battleMapper.getBattleEventDetail(battle_event_id);
mysqlHistoryLogService.insertHistoryLog(
HISTORYTYPE.BATTLE_EVENT_ADD,
MysqlConstants.TABLE_NAME_BATTLE_EVENT,
HISTORYTYPE.BATTLE_EVENT_ADD.name(),
event_info,
CommonUtils.getAdmin().getEmail(),
CommonUtils.getClientIp()
);
dynamodbBattleEventService.insertBattleEvent(battleEventRequest);
return BattleEventResponse.builder()
.status(CommonCode.SUCCESS.getHttpStatus())
.result(CommonCode.SUCCESS.getResult())
.resultData(BattleEventResponse.ResultData.builder()
.message(SuccessCode.SAVE.getMessage())
.build())
.build();
}
@Transactional(transactionManager = "transactionManager")
public BattleEventResponse updateBattleEvent(Long id, BattleEventRequest battleEventRequest) {
battleEventRequest.setId(id);
battleEventRequest.setUpdateBy(CommonUtils.getAdmin().getId());
battleEventRequest.setUpdateDt(LocalDateTime.now());
BattleEvent before_info = battleMapper.getBattleEventDetail(id);
if(!before_info.getStatus().equals(BattleEvent.BATTLE_STATUS.STOP)){
return BattleEventResponse.builder()
.status(CommonCode.ERROR.getHttpStatus())
.result(ErrorCode.ERROR_BATTLE_EVENT_STATUS_IMPOSSIBLE.toString())
.build();
}
List<BattleEvent> existingList = battleMapper.getCheckBattleEventList(battleEventRequest);
boolean isTime = isTimeOverlapping(existingList, battleEventRequest);
if(isTime){
return BattleEventResponse.builder()
.status(CommonCode.ERROR.getHttpStatus())
.result(ErrorCode.ERROR_BATTLE_EVENT_TIME_OVER.toString())
.build();
}
int operation_time = calcEndTime(battleEventRequest);
battleEventRequest.setEventOperationTime(operation_time);
// 일자만 필요해서 UTC시간으로 변경되다보니 한국시간(+9)을 더해서 마지막시간으로 설정
LocalDateTime end_dt_kst = battleEventRequest.getEventEndDt()
.plusHours(9)
.withHour(23)
.withMinute(59)
.withSecond(59)
.withNano(0);
battleEventRequest.setEventEndDt(end_dt_kst);
int result = battleMapper.updateBattleEvent(battleEventRequest);
log.info("AdminToolDB BattleEvent Update Complete: {}", battleEventRequest);
Map<String, String> map = new HashMap<>();
map.put("id", String.valueOf(id));
BattleEvent after_info = battleMapper.getBattleEventDetail(id);
mysqlHistoryLogService.updateHistoryLog(
HISTORYTYPE.BATTLE_EVENT_UPDATE,
MysqlConstants.TABLE_NAME_BATTLE_EVENT,
HISTORYTYPE.BATTLE_EVENT_UPDATE.name(),
before_info,
after_info,
CommonUtils.getAdmin().getEmail(),
CommonUtils.getClientIp()
);
dynamodbBattleEventService.updateBattleEvent(battleEventRequest);
return BattleEventResponse.builder()
.resultData(BattleEventResponse.ResultData.builder()
.build())
.status(CommonCode.SUCCESS.getHttpStatus())
.result(CommonCode.SUCCESS.getResult())
.build();
}
@Transactional(transactionManager = "transactionManager")
public BattleEventResponse updateStopBattleEvent(Long id){
Map<String,Object> map = new HashMap<>();
BattleEvent info = battleMapper.getBattleEventDetail(id);
if(info.getStatus().equals(BattleEvent.BATTLE_STATUS.RUNNING)){
return BattleEventResponse.builder()
.status(CommonCode.ERROR.getHttpStatus())
.result(ErrorCode.ERROR_BATTLE_EVENT_STATUS_START_IMPOSSIBLE.toString())
.build();
}
map.put("id", id);
map.put("status", BattleEvent.BATTLE_STATUS.STOP);
map.put("updateBy", CommonUtils.getAdmin().getId());
int result = battleMapper.updateStatusBattleEvent(map);
try{
log.info("BattleEvent Stop Complete: {}", objectMapper.writeValueAsString(info));
}catch(Exception e){
log.error("BattleEvent Stop Failed: {}", e.getMessage());
}
mysqlHistoryLogService.updateHistoryLog(
HISTORYTYPE.BATTLE_EVENT_UPDATE,
MysqlConstants.TABLE_NAME_BATTLE_EVENT,
HISTORYTYPE.BATTLE_EVENT_UPDATE.name(),
info,
battleMapper.getBattleEventDetail(id),
CommonUtils.getAdmin().getEmail(),
CommonUtils.getClientIp()
);
dynamodbBattleEventService.updateStopBattleEvent(info);
return BattleEventResponse.builder()
.resultData(BattleEventResponse.ResultData.builder()
.build())
.status(CommonCode.SUCCESS.getHttpStatus())
.result(CommonCode.SUCCESS.getResult())
.build();
}
@Transactional(transactionManager = "transactionManager")
public BattleEventResponse deleteBattleEvent(BattleEventRequest battleEventRequest){
Map<String,Object> map = new HashMap<>();
AtomicBoolean is_falil = new AtomicBoolean(false);
battleEventRequest.getList().forEach(
item->{
Long id = item.getId();
BattleEvent info = battleMapper.getBattleEventDetail(id);
if(!info.getStatus().equals(BattleEvent.BATTLE_STATUS.STOP)){
is_falil.set(true);
return;
}
map.put("id", id);
map.put("updateBy", CommonUtils.getAdmin().getId());
int result = battleMapper.deleteBattleEvent(map);
log.info("BattleEvent Delete Complete: {}", item);
mysqlHistoryLogService.deleteHistoryLog(
HISTORYTYPE.BATTLE_EVENT_DELETE,
MysqlConstants.TABLE_NAME_BATTLE_EVENT,
HISTORYTYPE.BATTLE_EVENT_DELETE.name(),
info,
CommonUtils.getAdmin().getEmail(),
CommonUtils.getClientIp()
);
// dynamodbLandAuctionService.cancelLandAuction(auction_info);
}
);
if(is_falil.get()){
return BattleEventResponse.builder()
.status(CommonCode.ERROR.getHttpStatus())
.result(ErrorCode.ERROR_AUCTION_STATUS_IMPOSSIBLE.toString())
.build();
}
return BattleEventResponse.builder()
.resultData(BattleEventResponse.ResultData.builder()
.build())
.status(CommonCode.SUCCESS.getHttpStatus())
.result(CommonCode.SUCCESS.getResult())
.build();
}
public List<BattleEvent> getScheduleBattleEventList(){
return battleMapper.getScheduleBattleEventList();
}
@Transactional(transactionManager = "transactionManager")
public void updateBattleEventStatus(Map<String,Object> map){
try{
battleMapper.updateStatusBattleEvent(map);
log.info("BattleEvent status changed: {}", map.get("status"));
}catch(Exception e){
log.error("BattleEvent Status Update Fail map: {}", map);
}
}
// 이벤트 동작 시간 계산
private int calcEndTime(BattleEventRequest battleEventRequest){
MetaBattleConfigData config = metaDataHandler.getMetaBattleConfigsListData().stream()
.filter(data -> data.getId().equals(battleEventRequest.getConfigId()))
.findFirst()
.orElse(null);
if(config == null) return 0;
int round_time = battleEventRequest.getRoundTime();
int round_count = battleEventRequest.getRoundCount();
int round_wait_time = config.getNextRoundWaitTime();
int result_wait_time = config.getResultUIWaitTime();
int server_wait_time = CommonConstants.BATTLE_SERVER_WAIT_TIME;
int total_time = round_time + ((round_count - 1) * (round_time + round_wait_time)) + result_wait_time + server_wait_time;
return total_time; // 초
}
private boolean isTimeOverlapping(List<BattleEvent> existingList, BattleEventRequest battleEventRequest){
LocalTime newStartTime = battleEventRequest.getEventStartDt().toLocalTime();
LocalTime newEndTime = newStartTime.plusSeconds(battleEventRequest.getEventOperationTime());
return existingList.stream().anyMatch(schedule -> {
LocalTime existingStartTime = schedule.getEventStartDt().toLocalTime();
LocalTime existingEndTime = existingStartTime.plusSeconds(schedule.getEventOperationTime());
return !existingStartTime.isAfter(newEndTime) && !newStartTime.isAfter(existingEndTime);
});
}
}