Some checks failed
Host-Based Deploy (Java 21 Fix) / build-and-run (push) Has been cancelled
209 lines
9.6 KiB
Java
209 lines
9.6 KiB
Java
package de.oaa.xxx.games.bdsm;
|
|
|
|
import java.time.Duration;
|
|
import java.time.LocalDateTime;
|
|
import java.util.ArrayList;
|
|
import java.util.UUID;
|
|
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.LoggerFactory;
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
|
import de.oaa.xxx.games.bdsm.entity.BdsmGameEntity;
|
|
import de.oaa.xxx.games.bdsm.repository.AktiveSperreRepository;
|
|
import de.oaa.xxx.games.bdsm.repository.BdsmGameRepository;
|
|
import de.oaa.xxx.games.bdsm.repository.MitspielerRepository;
|
|
import de.oaa.xxx.games.chastity.cardlock.CardLockEntity;
|
|
import de.oaa.xxx.games.chastity.cardlock.CardlockRepository;
|
|
import de.oaa.xxx.games.history.GameHistoryEntity;
|
|
import de.oaa.xxx.games.history.GameHistoryRepository;
|
|
import de.oaa.xxx.games.history.GameRole;
|
|
import de.oaa.xxx.games.history.GameType;
|
|
import de.oaa.xxx.social.SystemMessageService;
|
|
import de.oaa.xxx.social.entity.MessageCause;
|
|
import de.oaa.xxx.user.UserRepository;
|
|
|
|
/**
|
|
* Service für komplexe BDSM-Game-Operationen.
|
|
* Kapselt Spielabschluss-Logik (XP-Vergabe, History) und den BDSM→Chastity-Übergang.
|
|
*/
|
|
@Service
|
|
public class BdsmGameService {
|
|
|
|
private static final Logger LOGGER = LoggerFactory.getLogger(BdsmGameService.class);
|
|
|
|
private final BdsmGameRepository sessionRepository;
|
|
private final MitspielerRepository mitspielerRepository;
|
|
private final AktiveSperreRepository aktiveSperreRepository;
|
|
private final UserRepository userRepository;
|
|
private final GameHistoryRepository gameHistoryRepository;
|
|
private final CardlockRepository cardlockRepository;
|
|
private final SystemMessageService systemMessageService;
|
|
|
|
public BdsmGameService(BdsmGameRepository sessionRepository,
|
|
MitspielerRepository mitspielerRepository,
|
|
AktiveSperreRepository aktiveSperreRepository,
|
|
UserRepository userRepository,
|
|
GameHistoryRepository gameHistoryRepository,
|
|
CardlockRepository cardlockRepository,
|
|
SystemMessageService systemMessageService) {
|
|
this.sessionRepository = sessionRepository;
|
|
this.mitspielerRepository = mitspielerRepository;
|
|
this.aktiveSperreRepository = aktiveSperreRepository;
|
|
this.userRepository = userRepository;
|
|
this.gameHistoryRepository = gameHistoryRepository;
|
|
this.cardlockRepository = cardlockRepository;
|
|
this.systemMessageService = systemMessageService;
|
|
}
|
|
|
|
/**
|
|
* Beendet eine BDSM-Session ordentlich: History speichern, XP vergeben,
|
|
* Gäste auf eigenem Gerät benachrichtigen, Daten aufräumen.
|
|
*/
|
|
@Transactional
|
|
public void spielAbschliessen(BdsmGameEntity entity) {
|
|
LocalDateTime endTime = LocalDateTime.now();
|
|
long durationMinutes = Duration.between(entity.getStartZeit(), endTime).toMinutes();
|
|
|
|
GameHistoryEntity entry = new GameHistoryEntity();
|
|
entry.setGameName("BDSM Game");
|
|
entry.setGameType(GameType.BDSM);
|
|
entry.setStartTime(entity.getStartZeit());
|
|
entry.setEndTime(endTime);
|
|
entry.setDurationMinutes(durationMinutes);
|
|
entry.addParticipant(entity.getUserId(), GameRole.PLAYER);
|
|
entity.getMitspieler().stream()
|
|
.filter(m -> m.getUserId() != null)
|
|
.forEach(m -> entry.addParticipant(m.getUserId(), GameRole.PLAYER));
|
|
gameHistoryRepository.save(entry);
|
|
|
|
int xp = (int) durationMinutes;
|
|
userRepository.findById(entity.getUserId()).ifPresent(u -> {
|
|
u.setBdsmXp(u.getBdsmXp() + xp);
|
|
userRepository.save(u);
|
|
});
|
|
entity.getMitspieler().stream()
|
|
.filter(m -> m.getUserId() != null)
|
|
.forEach(m -> userRepository.findById(m.getUserId()).ifPresent(u -> {
|
|
u.setBdsmXp(u.getBdsmXp() + xp);
|
|
userRepository.save(u);
|
|
}));
|
|
|
|
// Gäste auf eigenem Gerät benachrichtigen
|
|
String endNachricht = "Das BDSM-Spiel wurde erfolgreich beendet. Danke fürs Mitspielen! 🎉";
|
|
entity.getMitspieler().stream()
|
|
.filter(m -> m.isEigenesGeraet() && m.getUserId() != null)
|
|
.forEach(m -> systemMessageService.send(entity.getUserId(), m.getUserId(),
|
|
endNachricht, "/userhome.html", MessageCause.GAME_STATE));
|
|
|
|
bereinige(entity);
|
|
}
|
|
|
|
/**
|
|
* Überführt eine BDSM-Session in ein neues Chastity-Lock (BDSM→Chastity-Transition).
|
|
* History + XP werden wie beim normalen Spielabschluss vergeben.
|
|
*
|
|
* @return Das neu angelegte CardLockEntity
|
|
* @throws IllegalArgumentException wenn Session oder Template nicht gefunden
|
|
* @throws IllegalStateException wenn Lockee bereits ein aktives Lock hat
|
|
*/
|
|
@Transactional
|
|
public CardLockEntity zuChastity(UUID sessionId, UUID templateLockId, UUID lockeeUserId, UUID keyholderUserId) {
|
|
BdsmGameEntity entity = sessionRepository.findById(sessionId)
|
|
.orElseThrow(() -> new IllegalArgumentException("Session nicht gefunden: " + sessionId));
|
|
|
|
CardLockEntity template = cardlockRepository.findById(templateLockId)
|
|
.orElseThrow(() -> new IllegalArgumentException("Template-Lock nicht gefunden: " + templateLockId));
|
|
|
|
if (lockeeUserId != null
|
|
&& cardlockRepository.existsByLockeeAndStartTimeIsNotNullAndUnlockTimeIsNull(lockeeUserId)) {
|
|
throw new IllegalStateException("Lockee hat bereits ein aktives Chastity-Lock");
|
|
}
|
|
|
|
LocalDateTime now = LocalDateTime.now();
|
|
CardLockEntity newLock = new CardLockEntity();
|
|
newLock.setName(template.getName());
|
|
newLock.setLockee(lockeeUserId);
|
|
newLock.setKeyholder(keyholderUserId);
|
|
newLock.setInitialCards(template.getInitialCards());
|
|
newLock.setPickEverySeconds(template.getPickEverySeconds());
|
|
newLock.setAccumulatePicks(template.isAccumulatePicks());
|
|
newLock.setShowRemainingCards(template.isShowRemainingCards());
|
|
newLock.setLatestOpeningtime(template.getLatestOpeningtime());
|
|
newLock.setHygineOpeningDurationSeconds(template.getHygineOpeningDurationSeconds());
|
|
newLock.setHygineOpeningEverySeconds(template.getHygineOpeningEverySeconds());
|
|
newLock.setTasks(template.getTasks());
|
|
newLock.setRequiresVerification(template.isRequiresVerification());
|
|
newLock.setTestLock(false);
|
|
newLock.setTaskMode(template.getTaskMode());
|
|
|
|
int codeLines = template.getUnlockCodeLength() != null ? template.getUnlockCodeLength() : 5;
|
|
newLock.setUnlockCodeLength(codeLines);
|
|
StringBuilder codeBuilder = new StringBuilder();
|
|
java.util.Random rng = new java.util.Random();
|
|
for (int i = 0; i < codeLines; i++) codeBuilder.append(rng.nextInt(10));
|
|
newLock.setUnlockCode(codeBuilder.toString());
|
|
|
|
newLock.setStartTime(now);
|
|
newLock.setAvailableCards(template.getInitialCards() != null
|
|
? new ArrayList<>(template.getInitialCards()) : new ArrayList<>());
|
|
newLock.setOpenPicks(0);
|
|
if (template.getPickEverySeconds() != null) {
|
|
newLock.setNextCardIn(now.plusSeconds(template.getPickEverySeconds()));
|
|
}
|
|
if (template.getHygineOpeningEverySeconds() != null) {
|
|
newLock.setLastHygineOpening(now);
|
|
}
|
|
cardlockRepository.save(newLock);
|
|
|
|
// Lockee benachrichtigen
|
|
if (lockeeUserId != null) {
|
|
userRepository.findById(keyholderUserId).ifPresent(keyholder ->
|
|
systemMessageService.send(keyholderUserId, lockeeUserId,
|
|
keyholder.getName() + " hat nach dem BDSM Game ein Chastity Lock auf dich gesetzt.",
|
|
"/games/chastity/activelock.html", MessageCause.GAME_STATE));
|
|
}
|
|
|
|
// Spielabschluss-Logik (History + XP + Cleanup)
|
|
LocalDateTime endTime = LocalDateTime.now();
|
|
long durationMinutes = Duration.between(entity.getStartZeit(), endTime).toMinutes();
|
|
GameHistoryEntity entry = new GameHistoryEntity();
|
|
entry.setGameName("BDSM Game");
|
|
entry.setGameType(GameType.BDSM);
|
|
entry.setStartTime(entity.getStartZeit());
|
|
entry.setEndTime(endTime);
|
|
entry.setDurationMinutes(durationMinutes);
|
|
entry.addParticipant(entity.getUserId(), GameRole.PLAYER);
|
|
entity.getMitspieler().stream()
|
|
.filter(m -> m.getUserId() != null)
|
|
.forEach(m -> entry.addParticipant(m.getUserId(), GameRole.PLAYER));
|
|
gameHistoryRepository.save(entry);
|
|
|
|
int xp = (int) durationMinutes;
|
|
userRepository.findById(entity.getUserId()).ifPresent(u -> {
|
|
u.setBdsmXp(u.getBdsmXp() + xp);
|
|
userRepository.save(u);
|
|
});
|
|
entity.getMitspieler().stream()
|
|
.filter(m -> m.getUserId() != null)
|
|
.forEach(m -> userRepository.findById(m.getUserId()).ifPresent(u -> {
|
|
u.setBdsmXp(u.getBdsmXp() + xp);
|
|
userRepository.save(u);
|
|
}));
|
|
|
|
bereinige(entity);
|
|
|
|
LOGGER.info("BDSM-Session {} in Chastity-Lock {} überführt (Lockee: {}, Keyholder: {})",
|
|
sessionId, newLock.getLockId(), lockeeUserId, keyholderUserId);
|
|
return newLock;
|
|
}
|
|
|
|
/** Löscht alle Session-Daten (Sperren, Mitspieler, Session selbst). */
|
|
private void bereinige(BdsmGameEntity entity) {
|
|
aktiveSperreRepository.deleteAll(entity.getAktiveSperren());
|
|
mitspielerRepository.deleteAll(entity.getMitspieler());
|
|
sessionRepository.delete(entity);
|
|
}
|
|
}
|