|
|
|
@ -25,6 +25,8 @@ import java.util.UUID; |
|
|
|
@Service |
|
|
|
public class PlanetAdventurePkServiceImpl implements PlanetAdventurePkService { |
|
|
|
|
|
|
|
private static final int AUTO_FAIL_REMAINING_CARDS = 999999; |
|
|
|
|
|
|
|
@Autowired |
|
|
|
private PlanetAdventurePkRoomMapper roomMapper; |
|
|
|
@Autowired |
|
|
|
@ -85,6 +87,23 @@ public class PlanetAdventurePkServiceImpl implements PlanetAdventurePkService { |
|
|
|
.orderByDesc(PlanetAdventurePkRoom::getCreateTime)); |
|
|
|
} |
|
|
|
|
|
|
|
@Override |
|
|
|
public PlanetAdventurePkPlayVo roomInfo(String userId, String regionId, String roomId) { |
|
|
|
if (StringUtils.isEmpty(userId)) throw new HiverException("用户id不能为空"); |
|
|
|
PlanetAdventurePkRoom room = mustRoom(roomId, regionId); |
|
|
|
PlanetAdventurePkPlayer player = playerMapper.selectOne(new LambdaQueryWrapper<PlanetAdventurePkPlayer>() |
|
|
|
.eq(PlanetAdventurePkPlayer::getRoomId, roomId) |
|
|
|
.eq(PlanetAdventurePkPlayer::getUserId, userId) |
|
|
|
.last("limit 1")); |
|
|
|
PlanetAdventurePkPlayVo vo = new PlanetAdventurePkPlayVo(); |
|
|
|
vo.setMode("pk"); |
|
|
|
vo.setRoomId(room.getId()); |
|
|
|
vo.setSeed(room.getRoomSeed()); |
|
|
|
vo.setRoom(room); |
|
|
|
vo.setPlayer(player); |
|
|
|
return vo; |
|
|
|
} |
|
|
|
|
|
|
|
@Override |
|
|
|
@Transactional(rollbackFor = Exception.class) |
|
|
|
public PlanetAdventurePkRoom createRoom(String userId, String regionId, String nickname, String avatar, |
|
|
|
@ -93,8 +112,11 @@ public class PlanetAdventurePkServiceImpl implements PlanetAdventurePkService { |
|
|
|
require(userId, regionId); |
|
|
|
int players = maxPlayers == null ? 2 : Math.max(2, Math.min(5, maxPlayers)); |
|
|
|
int tickets = entryTickets == null ? 1 : Math.max(1, entryTickets); |
|
|
|
String roomId = genId(); |
|
|
|
ticketService.deductTickets(userId, regionId, tickets, |
|
|
|
PlanetConstant.TICKET_TYPE_ADVENTURE_PK_ENTRY, roomId + "_" + userId, "星球擂台开房入场券"); |
|
|
|
PlanetAdventurePkRoom room = new PlanetAdventurePkRoom(); |
|
|
|
room.setId(genId()); |
|
|
|
room.setId(roomId); |
|
|
|
room.setRoomName(StringUtils.isEmpty(roomName) ? "星球擂台房间" : roomName.trim()); |
|
|
|
room.setRegionId(regionId); |
|
|
|
room.setOwnerUserId(userId); |
|
|
|
@ -106,11 +128,13 @@ public class PlanetAdventurePkServiceImpl implements PlanetAdventurePkService { |
|
|
|
room.setPassword(password); |
|
|
|
room.setEntryTickets(tickets); |
|
|
|
room.setStatus(PlanetConstant.ADVENTURE_PK_ROOM_WAITING); |
|
|
|
room.setPoolTickets(0); |
|
|
|
room.setPlayerCount(0); |
|
|
|
room.setPoolTickets(tickets); |
|
|
|
room.setPlayerCount(1); |
|
|
|
room.setCreateTime(new Date()); |
|
|
|
room.setUpdateTime(new Date()); |
|
|
|
roomMapper.insert(room); |
|
|
|
PlanetAdventurePkPlayer owner = newPkPlayer(roomId, regionId, userId, nickname, avatar, college, tickets); |
|
|
|
playerMapper.insert(owner); |
|
|
|
return room; |
|
|
|
} |
|
|
|
|
|
|
|
@ -141,22 +165,7 @@ public class PlanetAdventurePkServiceImpl implements PlanetAdventurePkService { |
|
|
|
if (count >= room.getMaxPlayers()) throw new HiverException("房间人数已满"); |
|
|
|
ticketService.deductTickets(userId, regionId, room.getEntryTickets(), |
|
|
|
PlanetConstant.TICKET_TYPE_ADVENTURE_PK_ENTRY, roomId + "_" + userId, "星球擂台入场券"); |
|
|
|
PlanetAdventurePkPlayer player = new PlanetAdventurePkPlayer(); |
|
|
|
player.setId(genId()); |
|
|
|
player.setRoomId(roomId); |
|
|
|
player.setRegionId(regionId); |
|
|
|
player.setUserId(userId); |
|
|
|
player.setNickname(nickname); |
|
|
|
player.setAvatar(avatar); |
|
|
|
player.setCollege(college); |
|
|
|
player.setEntryTickets(room.getEntryTickets()); |
|
|
|
player.setStatus(PlanetConstant.ADVENTURE_PK_PLAYER_PLAYING); |
|
|
|
player.setCleared(0); |
|
|
|
player.setRankNo(0); |
|
|
|
player.setRewardTickets(0); |
|
|
|
player.setStartTime(new Date()); |
|
|
|
player.setCreateTime(new Date()); |
|
|
|
player.setUpdateTime(new Date()); |
|
|
|
PlanetAdventurePkPlayer player = newPkPlayer(roomId, regionId, userId, nickname, avatar, college, room.getEntryTickets()); |
|
|
|
playerMapper.insert(player); |
|
|
|
room.setPlayerCount(count + 1); |
|
|
|
room.setPoolTickets(nz(room.getPoolTickets()) + room.getEntryTickets()); |
|
|
|
@ -172,6 +181,9 @@ public class PlanetAdventurePkServiceImpl implements PlanetAdventurePkService { |
|
|
|
Integer durationSeconds, Integer remainingSeconds, Integer remainingCards) { |
|
|
|
if (StringUtils.isEmpty(userId)) throw new HiverException("用户id不能为空"); |
|
|
|
PlanetAdventurePkRoom room = mustRoom(roomId, regionId); |
|
|
|
if (room.getStatus() == PlanetConstant.ADVENTURE_PK_ROOM_SETTLED) { |
|
|
|
throw new HiverException("房间已结算,无法提交成绩"); |
|
|
|
} |
|
|
|
PlanetAdventurePkPlayer player = mustPlayer(roomId, userId); |
|
|
|
if (terminal(player)) throw new HiverException("本房间成绩已提交"); |
|
|
|
player.setCleared(cleared != null && cleared == 1 ? 1 : 0); |
|
|
|
@ -192,6 +204,26 @@ public class PlanetAdventurePkServiceImpl implements PlanetAdventurePkService { |
|
|
|
return submitRoom(userId, regionId, roomId, 0, 0, 0, remainingCards); |
|
|
|
} |
|
|
|
|
|
|
|
@Override |
|
|
|
@Transactional(rollbackFor = Exception.class) |
|
|
|
public int autoSettleOverdueRooms() { |
|
|
|
Date deadline = new Date(System.currentTimeMillis() - 30L * 60 * 1000); |
|
|
|
List<PlanetAdventurePkRoom> rooms = roomMapper.selectList(new LambdaQueryWrapper<PlanetAdventurePkRoom>() |
|
|
|
.in(PlanetAdventurePkRoom::getStatus, PlanetConstant.ADVENTURE_PK_ROOM_WAITING, PlanetConstant.ADVENTURE_PK_ROOM_PLAYING) |
|
|
|
.lt(PlanetAdventurePkRoom::getCreateTime, deadline)); |
|
|
|
int settled = 0; |
|
|
|
for (PlanetAdventurePkRoom room : rooms) { |
|
|
|
try { |
|
|
|
if (settleOverdue(room)) { |
|
|
|
settled++; |
|
|
|
} |
|
|
|
} catch (Exception ignored) { |
|
|
|
// 单个房间异常不影响后续房间,外层任务会记录总量。
|
|
|
|
} |
|
|
|
} |
|
|
|
return settled; |
|
|
|
} |
|
|
|
|
|
|
|
@Override |
|
|
|
public PlanetAdventureChallenge createChallenge(String userId, String regionId, String nickname, String avatar, |
|
|
|
String college, Integer durationSeconds) { |
|
|
|
@ -262,16 +294,71 @@ public class PlanetAdventurePkServiceImpl implements PlanetAdventurePkService { |
|
|
|
.eq(PlanetAdventureSession::getStatus, PlanetConstant.ADVENTURE_SESSION_SUBMITTED) |
|
|
|
.eq(PlanetAdventureSession::getCheatFlag, "N") |
|
|
|
.orderByAsc(PlanetAdventureSession::getDurationSeconds) |
|
|
|
.last("limit 3")); |
|
|
|
.last("limit 5")); |
|
|
|
} |
|
|
|
|
|
|
|
private void settleIfReady(PlanetAdventurePkRoom room) { |
|
|
|
List<PlanetAdventurePkPlayer> players = playerMapper.selectList(new LambdaQueryWrapper<PlanetAdventurePkPlayer>() |
|
|
|
.eq(PlanetAdventurePkPlayer::getRoomId, room.getId())); |
|
|
|
if (players.size() < room.getMaxPlayers()) return; |
|
|
|
for (PlanetAdventurePkPlayer p : players) { |
|
|
|
if (!terminal(p)) return; |
|
|
|
} |
|
|
|
settleRoom(room, players, false); |
|
|
|
} |
|
|
|
|
|
|
|
private boolean settleOverdue(PlanetAdventurePkRoom room) { |
|
|
|
List<PlanetAdventurePkPlayer> players = playerMapper.selectList(new LambdaQueryWrapper<PlanetAdventurePkPlayer>() |
|
|
|
.eq(PlanetAdventurePkPlayer::getRoomId, room.getId())); |
|
|
|
if (players.isEmpty()) { |
|
|
|
room.setStatus(PlanetConstant.ADVENTURE_PK_ROOM_SETTLED); |
|
|
|
room.setSettleTime(new Date()); |
|
|
|
room.setUpdateTime(new Date()); |
|
|
|
roomMapper.updateById(room); |
|
|
|
return true; |
|
|
|
} |
|
|
|
boolean noSubmitted = players.stream().noneMatch(this::terminal); |
|
|
|
for (PlanetAdventurePkPlayer p : players) { |
|
|
|
if (!terminal(p)) { |
|
|
|
p.setStatus(PlanetConstant.ADVENTURE_PK_PLAYER_FAILED); |
|
|
|
p.setCleared(0); |
|
|
|
p.setDurationSeconds(0); |
|
|
|
p.setRemainingSeconds(0); |
|
|
|
p.setRemainingCards(AUTO_FAIL_REMAINING_CARDS); |
|
|
|
p.setFinishTime(new Date()); |
|
|
|
p.setUpdateTime(new Date()); |
|
|
|
playerMapper.updateById(p); |
|
|
|
} |
|
|
|
} |
|
|
|
List<PlanetAdventurePkPlayer> latestPlayers = playerMapper.selectList(new LambdaQueryWrapper<PlanetAdventurePkPlayer>() |
|
|
|
.eq(PlanetAdventurePkPlayer::getRoomId, room.getId())); |
|
|
|
settleRoom(room, latestPlayers, noSubmitted); |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
private void settleRoom(PlanetAdventurePkRoom room, List<PlanetAdventurePkPlayer> players, boolean refundAll) { |
|
|
|
if (players.size() == 1 && Objects.equals(players.get(0).getUserId(), room.getOwnerUserId())) { |
|
|
|
PlanetAdventurePkPlayer owner = players.get(0); |
|
|
|
ticketService.addTicketsWithoutBuff(owner.getUserId(), owner.getRegionId(), nz(owner.getEntryTickets()), |
|
|
|
PlanetConstant.TICKET_TYPE_ADVENTURE_PK_REFUND, room.getId() + "_" + owner.getUserId(), "星球擂台无人参加退回"); |
|
|
|
owner.setRewardTickets(nz(owner.getEntryTickets())); |
|
|
|
owner.setRankNo(0); |
|
|
|
owner.setUpdateTime(new Date()); |
|
|
|
playerMapper.updateById(owner); |
|
|
|
finishRoom(room, null); |
|
|
|
return; |
|
|
|
} |
|
|
|
if (refundAll) { |
|
|
|
for (PlanetAdventurePkPlayer p : players) { |
|
|
|
ticketService.addTicketsWithoutBuff(p.getUserId(), p.getRegionId(), nz(p.getEntryTickets()), |
|
|
|
PlanetConstant.TICKET_TYPE_ADVENTURE_PK_REFUND, room.getId() + "_" + p.getUserId(), "星球擂台无人提交退回"); |
|
|
|
p.setRewardTickets(nz(p.getEntryTickets())); |
|
|
|
p.setRankNo(0); |
|
|
|
p.setUpdateTime(new Date()); |
|
|
|
playerMapper.updateById(p); |
|
|
|
} |
|
|
|
finishRoom(room, null); |
|
|
|
return; |
|
|
|
} |
|
|
|
players.sort((a, b) -> { |
|
|
|
boolean ac = nz(a.getCleared()) == 1; |
|
|
|
boolean bc = nz(b.getCleared()) == 1; |
|
|
|
@ -281,35 +368,59 @@ public class PlanetAdventurePkServiceImpl implements PlanetAdventurePkService { |
|
|
|
if (d != 0) return d; |
|
|
|
return Integer.compare(nz(b.getRemainingSeconds()), nz(a.getRemainingSeconds())); |
|
|
|
} |
|
|
|
return Integer.compare(nz(a.getRemainingCards()), nz(b.getRemainingCards())); |
|
|
|
int remain = Integer.compare(nz(a.getRemainingCards()), nz(b.getRemainingCards())); |
|
|
|
if (remain != 0) return remain; |
|
|
|
return Integer.compare(durationForRank(a), durationForRank(b)); |
|
|
|
}); |
|
|
|
boolean hasClear = players.stream().anyMatch(p -> nz(p.getCleared()) == 1); |
|
|
|
if (!hasClear) { |
|
|
|
for (PlanetAdventurePkPlayer p : players) { |
|
|
|
ticketService.addTicketsWithoutBuff(p.getUserId(), p.getRegionId(), nz(p.getEntryTickets()), |
|
|
|
PlanetConstant.TICKET_TYPE_ADVENTURE_PK_REFUND, room.getId() + "_" + p.getUserId(), "星球擂台无人通关退回"); |
|
|
|
p.setRewardTickets(nz(p.getEntryTickets())); |
|
|
|
p.setRankNo(0); |
|
|
|
playerMapper.updateById(p); |
|
|
|
} |
|
|
|
} else { |
|
|
|
PlanetAdventurePkPlayer winner = players.get(0); |
|
|
|
ticketService.addTicketsWithoutBuff(winner.getUserId(), winner.getRegionId(), nz(room.getPoolTickets()), |
|
|
|
PlanetConstant.TICKET_TYPE_ADVENTURE_PK_REWARD, room.getId(), "星球擂台第一名通吃奖池"); |
|
|
|
for (int i = 0; i < players.size(); i++) { |
|
|
|
PlanetAdventurePkPlayer p = players.get(i); |
|
|
|
p.setRankNo(i + 1); |
|
|
|
p.setRewardTickets(p.getUserId().equals(winner.getUserId()) ? nz(room.getPoolTickets()) : 0); |
|
|
|
playerMapper.updateById(p); |
|
|
|
} |
|
|
|
room.setWinnerUserId(winner.getUserId()); |
|
|
|
PlanetAdventurePkPlayer winner = players.get(0); |
|
|
|
ticketService.addTicketsWithoutBuff(winner.getUserId(), winner.getRegionId(), nz(room.getPoolTickets()), |
|
|
|
PlanetConstant.TICKET_TYPE_ADVENTURE_PK_REWARD, room.getId(), hasClear ? "星球擂台第一名通吃奖池" : "星球擂台消除最多通吃奖池"); |
|
|
|
for (int i = 0; i < players.size(); i++) { |
|
|
|
PlanetAdventurePkPlayer p = players.get(i); |
|
|
|
p.setRankNo(i + 1); |
|
|
|
p.setRewardTickets(p.getUserId().equals(winner.getUserId()) ? nz(room.getPoolTickets()) : 0); |
|
|
|
p.setUpdateTime(new Date()); |
|
|
|
playerMapper.updateById(p); |
|
|
|
} |
|
|
|
finishRoom(room, winner.getUserId()); |
|
|
|
} |
|
|
|
|
|
|
|
private void finishRoom(PlanetAdventurePkRoom room, String winnerUserId) { |
|
|
|
room.setWinnerUserId(winnerUserId); |
|
|
|
room.setStatus(PlanetConstant.ADVENTURE_PK_ROOM_SETTLED); |
|
|
|
room.setSettleTime(new Date()); |
|
|
|
room.setUpdateTime(new Date()); |
|
|
|
roomMapper.updateById(room); |
|
|
|
} |
|
|
|
|
|
|
|
private PlanetAdventurePkPlayer newPkPlayer(String roomId, String regionId, String userId, String nickname, |
|
|
|
String avatar, String college, Integer entryTickets) { |
|
|
|
PlanetAdventurePkPlayer player = new PlanetAdventurePkPlayer(); |
|
|
|
player.setId(genId()); |
|
|
|
player.setRoomId(roomId); |
|
|
|
player.setRegionId(regionId); |
|
|
|
player.setUserId(userId); |
|
|
|
player.setNickname(nickname); |
|
|
|
player.setAvatar(avatar); |
|
|
|
player.setCollege(college); |
|
|
|
player.setEntryTickets(entryTickets); |
|
|
|
player.setStatus(PlanetConstant.ADVENTURE_PK_PLAYER_PLAYING); |
|
|
|
player.setCleared(0); |
|
|
|
player.setRankNo(0); |
|
|
|
player.setRewardTickets(0); |
|
|
|
player.setStartTime(new Date()); |
|
|
|
player.setCreateTime(new Date()); |
|
|
|
player.setUpdateTime(new Date()); |
|
|
|
return player; |
|
|
|
} |
|
|
|
|
|
|
|
private int durationForRank(PlanetAdventurePkPlayer player) { |
|
|
|
if (nz(player.getDurationSeconds()) > 0) return nz(player.getDurationSeconds()); |
|
|
|
if (nz(player.getRemainingSeconds()) > 0) return Math.max(0, 180 - nz(player.getRemainingSeconds())); |
|
|
|
return Integer.MAX_VALUE; |
|
|
|
} |
|
|
|
|
|
|
|
private PlanetAdventurePkPlayVo playVo(PlanetAdventurePkRoom room, PlanetAdventurePkPlayer player) { |
|
|
|
PlanetAdventurePkPlayVo vo = new PlanetAdventurePkPlayVo(); |
|
|
|
vo.setMode("pk"); |
|
|
|
|