Timelock weiter gebastelt
This commit is contained in:
@@ -8,6 +8,8 @@ Verknüpfung der Spiele, wenn das Finish eines aus dem Bereich Chastity ist, wir
|
||||
|
||||
Wenn ein Lock für einen User existiert, wird er ohne entsprechend Penis/Vagina zu dem Spiel erstellt.
|
||||
|
||||
TODO: Im Time Lock, wenn im Spinning Wheel tasks drin sind, dürfen keine sonst keine Tasks gefordert sein und umgekehrt
|
||||
|
||||
Ich kann Spieler einladen zu spielen, dann kriegt die Person eine E-Mail und muss bestätigen, dass es diese PErson ist, sie wird dann ins spiel übernommen
|
||||
-- Falls fall mit Chastity auftritt wird die Spielpartnerin als Keyholder eingetragen, diese Person darf entscheiden, was für ein Lock das wird.
|
||||
|
||||
|
||||
@@ -138,8 +138,8 @@ public class BdsmGameService {
|
||||
newLock.setTestLock(false);
|
||||
newLock.setTaskCardMode(template.getTaskCardMode());
|
||||
|
||||
int codeLines = template.getUnlockCodeLines() != null ? template.getUnlockCodeLines() : 5;
|
||||
newLock.setUnlockCodeLines(codeLines);
|
||||
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));
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
package de.oaa.xxx.games.chastity;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import de.oaa.xxx.games.chastity.cardlock.CardEnum;
|
||||
import de.oaa.xxx.games.chastity.cardlock.CardLockEntity;
|
||||
import de.oaa.xxx.games.chastity.tasks.Task;
|
||||
|
||||
public class KeyholderCardLock {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(KeyholderCardLock.class);
|
||||
|
||||
private CardLockEntity lock;
|
||||
|
||||
public void addCards(List<CardEnum> cards) {
|
||||
lock.getAvailableCards().addAll(cards);
|
||||
}
|
||||
|
||||
public void freeze() {
|
||||
var multiplier = lock.getPickEveryMinute() * new Random().nextDouble(1.0, 4.0);
|
||||
LocalDateTime frozenTill = LocalDateTime.now().plus((long) multiplier, ChronoUnit.MINUTES);
|
||||
lock.setFrozenUntill(frozenTill);
|
||||
LOGGER.debug("Frozen by keyholder until {}", lock.getFrozenUntill());
|
||||
}
|
||||
|
||||
public void freeze(LocalDateTime until) {
|
||||
lock.setFrozenUntill(until);
|
||||
LOGGER.debug("Frozen by keyholder until {}", lock.getFrozenUntill());
|
||||
}
|
||||
|
||||
public void task() {
|
||||
}
|
||||
|
||||
public void task(Task task) {
|
||||
}
|
||||
|
||||
public void penalty() {
|
||||
}
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
package de.oaa.xxx.games.chastity;
|
||||
|
||||
public enum LockType {
|
||||
|
||||
CARD, TIMED;
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package de.oaa.xxx.games.chastity;
|
||||
|
||||
public class ProcessLock {
|
||||
|
||||
public void oeffnen() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
package de.oaa.xxx.games.chastity;
|
||||
|
||||
public class ProcessTimedLock extends ProcessLock {
|
||||
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
package de.oaa.xxx.games.chastity;
|
||||
|
||||
public class Timer {
|
||||
|
||||
}
|
||||
@@ -43,6 +43,21 @@ public enum CardEnum {
|
||||
public Card get() {
|
||||
return new DoubleUpCard();
|
||||
}
|
||||
},
|
||||
CUM {
|
||||
@Override
|
||||
public Card get() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
},
|
||||
CUM_IN_CAGE {
|
||||
@Override
|
||||
public Card get() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -36,18 +36,26 @@ import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import de.oaa.xxx.games.chastity.CodeCreator;
|
||||
import de.oaa.xxx.games.chastity.KeyholderInvitationEntity;
|
||||
import de.oaa.xxx.games.chastity.KeyholderInvitationRepository;
|
||||
import de.oaa.xxx.games.chastity.LockeeInvitationEntity;
|
||||
import de.oaa.xxx.games.chastity.LockeeInvitationRepository;
|
||||
import de.oaa.xxx.games.chastity.common.CodeCreator;
|
||||
import de.oaa.xxx.games.chastity.keyholder.KeyholderInvitationEntity;
|
||||
import de.oaa.xxx.games.chastity.keyholder.KeyholderInvitationRepository;
|
||||
import de.oaa.xxx.games.chastity.keyholder.KeyholderNotificationRepository;
|
||||
import de.oaa.xxx.games.chastity.keyholder.KeyholderTaskChoiceEntity;
|
||||
import de.oaa.xxx.games.chastity.keyholder.KeyholderTaskChoiceRepository;
|
||||
import de.oaa.xxx.games.chastity.lockee.LockeeInvitationEntity;
|
||||
import de.oaa.xxx.games.chastity.lockee.LockeeInvitationRepository;
|
||||
import de.oaa.xxx.games.chastity.tasks.AssignedTaskEntity;
|
||||
import de.oaa.xxx.games.chastity.tasks.AssignedTaskRepository;
|
||||
import de.oaa.xxx.games.chastity.tasks.Task;
|
||||
import de.oaa.xxx.games.chastity.unlock.TempOpeningReason;
|
||||
import de.oaa.xxx.games.chastity.unlock.UnlockCodeHistoryRepository;
|
||||
import de.oaa.xxx.games.chastity.unlock.UnlockCodeHistoryService;
|
||||
import de.oaa.xxx.games.chastity.verification.VerificationEntity;
|
||||
import de.oaa.xxx.games.chastity.verification.VerificationRepository;
|
||||
import de.oaa.xxx.games.chastity.verification.VerificationVoteEntity;
|
||||
import de.oaa.xxx.games.chastity.verification.VerificationVoteRepository;
|
||||
import de.oaa.xxx.games.chastity.vote.CommunityTaskVoteEntity;
|
||||
import de.oaa.xxx.games.chastity.vote.CommunityTaskVoteRepository;
|
||||
import de.oaa.xxx.social.SystemMessageService;
|
||||
import de.oaa.xxx.user.UserRepository;
|
||||
|
||||
@@ -60,7 +68,7 @@ public class CardLockController {
|
||||
private final KeyholderInvitationRepository invitationRepository;
|
||||
private final VerificationRepository verificationRepository;
|
||||
private final VerificationVoteRepository verificationVoteRepository;
|
||||
private final HygieneViolationRepository hygieneViolationRepository;
|
||||
private final KeyholderNotificationRepository keyholderNotificationRepository;
|
||||
private final LockeeInvitationRepository lockeeInvitationRepository;
|
||||
private final AssignedTaskRepository assignedTaskRepository;
|
||||
private final KeyholderTaskChoiceRepository keyholderTaskChoiceRepository;
|
||||
@@ -76,7 +84,7 @@ public class CardLockController {
|
||||
public CardLockController(CardlockRepository cardlockRepository, UserRepository userRepository,
|
||||
KeyholderInvitationRepository invitationRepository, VerificationRepository verificationRepository,
|
||||
VerificationVoteRepository verificationVoteRepository,
|
||||
HygieneViolationRepository hygieneViolationRepository,
|
||||
KeyholderNotificationRepository keyholderNotificationRepository,
|
||||
LockeeInvitationRepository lockeeInvitationRepository, AssignedTaskRepository assignedTaskRepository,
|
||||
KeyholderTaskChoiceRepository keyholderTaskChoiceRepository,
|
||||
CommunityTaskVoteRepository communityTaskVoteRepository,
|
||||
@@ -88,7 +96,7 @@ public class CardLockController {
|
||||
this.invitationRepository = invitationRepository;
|
||||
this.verificationRepository = verificationRepository;
|
||||
this.verificationVoteRepository = verificationVoteRepository;
|
||||
this.hygieneViolationRepository = hygieneViolationRepository;
|
||||
this.keyholderNotificationRepository = keyholderNotificationRepository;
|
||||
this.lockeeInvitationRepository = lockeeInvitationRepository;
|
||||
this.assignedTaskRepository = assignedTaskRepository;
|
||||
this.keyholderTaskChoiceRepository = keyholderTaskChoiceRepository;
|
||||
@@ -197,7 +205,7 @@ public class CardLockController {
|
||||
lock.setRequiresVerification(req.requiresVerification());
|
||||
lock.setTestLock(req.testLock());
|
||||
lock.setTaskCardMode(req.taskCardMode() != null ? req.taskCardMode() : "RANDOM");
|
||||
lock.setUnlockCodeLines(codeLines);
|
||||
lock.setUnlockCodeLength(codeLines);
|
||||
lock.setUnlockCode(unlockCode);
|
||||
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
@@ -322,11 +330,7 @@ public class CardLockController {
|
||||
if (!l.getLockee().equals(myId))
|
||||
return ResponseEntity.status(403).build();
|
||||
|
||||
l.setHygineOpeningtime(LocalDateTime.now());
|
||||
cardlockRepository.save(l);
|
||||
|
||||
unlockCodeHistoryService.save(myId, l.getLockId(), l.getName(), l.getUnlockCode(), "HYGIENE_OPEN");
|
||||
|
||||
cardLockServiceFactory.create(l).startHygieneOpening();
|
||||
return ResponseEntity.ok(Map.of("unlockCode", l.getUnlockCode(), "durationMinutes",
|
||||
l.getHygineOpeningDurationMinutes() != null ? l.getHygineOpeningDurationMinutes() : 30));
|
||||
}
|
||||
@@ -346,46 +350,8 @@ public class CardLockController {
|
||||
if (!l.getLockee().equals(myId))
|
||||
return ResponseEntity.status(403).build();
|
||||
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
|
||||
// Overtime berechnen
|
||||
if (l.getHygineOpeningtime() != null && l.getHygineOpeningDurationMinutes() != null) {
|
||||
LocalDateTime dueTime = l.getHygineOpeningtime().plusMinutes(l.getHygineOpeningDurationMinutes());
|
||||
if (now.isAfter(dueTime)) {
|
||||
long overtimeMinutes = ChronoUnit.MINUTES.between(dueTime, now);
|
||||
if (l.getKeyholder() == null) {
|
||||
// Self-Lock: 4-fache Überschreitungszeit einfrieren
|
||||
if (l.getFrozenUntill() != null) {
|
||||
l.setFrozenUntill(l.getFrozenUntill().plusMinutes(overtimeMinutes * 4));
|
||||
} else {
|
||||
l.setFrozenUntill(now.plusMinutes(overtimeMinutes * 4));
|
||||
}
|
||||
} else {
|
||||
// Keyholder vorhanden: Verletzung protokollieren
|
||||
HygieneViolationEntity violation = new HygieneViolationEntity();
|
||||
violation.setLockId(lockId);
|
||||
violation.setLockeeId(myId);
|
||||
violation.setKeyholderUserId(l.getKeyholder());
|
||||
violation.setViolationTime(now);
|
||||
violation.setOvertimeMinutes(overtimeMinutes);
|
||||
hygieneViolationRepository.save(violation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Nächsten Öffnungszeitpunkt setzen
|
||||
l.setLastHygineOpening(LocalDateTime.now());
|
||||
l.setHygineOpeningtime(null);
|
||||
|
||||
// Neuen Entsperrcode generieren
|
||||
int codeLines = l.getUnlockCodeLines() != null ? l.getUnlockCodeLines() : 5;
|
||||
String newCode = generateUnlockCode(codeLines);
|
||||
l.setUnlockCode(newCode);
|
||||
cardlockRepository.save(l);
|
||||
|
||||
unlockCodeHistoryService.save(myId, l.getLockId(), l.getName(), newCode, "HYGIENE_CLOSE");
|
||||
|
||||
return ResponseEntity.ok(Map.of("newUnlockCode", newCode));
|
||||
String code = cardLockServiceFactory.create(l).endHygieneOpening();
|
||||
return ResponseEntity.ok(Map.of("newUnlockCode", code));
|
||||
}
|
||||
|
||||
@PostMapping("/cardlock/{lockId}/task/complete")
|
||||
@@ -496,9 +462,9 @@ public class CardLockController {
|
||||
result.put("hygieneEnabled", hygieneEnabled);
|
||||
result.put("hygieneOpeningDue", hygieneOpeningDue);
|
||||
result.put("hygieneSecondsRemaining", hygieneSecondsRemaining);
|
||||
result.put("hygieneOpeningActive", l.getHygineOpeningtime() != null);
|
||||
result.put("hygieneOpeningActive", l.getTempOpeningTime() != null && TempOpeningReason.HYGIENE == l.getTempOpeningReason());
|
||||
result.put("hygieneOpeningStarted",
|
||||
l.getHygineOpeningtime() != null ? l.getHygineOpeningtime().toString() : null);
|
||||
l.getTempOpeningTime() != null ? l.getTempOpeningTime().toString() : null);
|
||||
result.put("hygieneDurationMinutes",
|
||||
l.getHygineOpeningDurationMinutes() != null ? l.getHygineOpeningDurationMinutes() : 0);
|
||||
result.put("hasKeyholder", l.getKeyholder() != null);
|
||||
@@ -973,7 +939,7 @@ public class CardLockController {
|
||||
}
|
||||
}
|
||||
|
||||
var recentViolations = hygieneViolationRepository.findByLockId(lockId).stream()
|
||||
var notification = keyholderNotificationRepository.findByLockId(lockId).stream()
|
||||
.sorted((a, b) -> b.getViolationTime().compareTo(a.getViolationTime())).limit(5)
|
||||
.map(v -> Map.of("time", v.getViolationTime().toString(), "overtimeMinutes", v.getOvertimeMinutes()))
|
||||
.toList();
|
||||
@@ -998,7 +964,7 @@ public class CardLockController {
|
||||
result.put("hygieneEnabled", hygieneEnabled);
|
||||
result.put("hygieneOpeningDue", hygieneOpeningDue);
|
||||
result.put("hygieneSecondsRemaining", hygieneSecondsRemaining);
|
||||
result.put("hygieneOpeningActive", l.getHygineOpeningtime() != null);
|
||||
result.put("hygieneOpeningActive", l.getTempOpeningTime() != null && TempOpeningReason.HYGIENE == l.getTempOpeningReason());
|
||||
result.put("requiresVerification", l.isRequiresVerification());
|
||||
result.put("verificationDue", verificationDue);
|
||||
result.put("verificationDoneToday", verificationDoneToday);
|
||||
@@ -1007,7 +973,7 @@ public class CardLockController {
|
||||
result.put("verificationImage", verificationImage);
|
||||
result.put("verificationUpvotes", verificationUpvotes);
|
||||
result.put("verificationDownvotes", verificationDownvotes);
|
||||
result.put("hygieneViolations", recentViolations);
|
||||
result.put("hygieneViolations", notification);
|
||||
result.put("hasTasks", l.getTasks() != null && !l.getTasks().isEmpty());
|
||||
if (l.getTasks() != null) {
|
||||
var taskList = l.getTasks().stream().map(t -> {
|
||||
@@ -1589,6 +1555,8 @@ public class CardLockController {
|
||||
case FREEZE -> "Freeze";
|
||||
case RESET -> "Reset";
|
||||
case DOUBLE_UP -> "Double Up";
|
||||
case CUM -> "Kommen";
|
||||
case CUM_IN_CAGE -> "Kommen im Käfig";
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import java.util.UUID;
|
||||
|
||||
import de.oaa.xxx.games.chastity.tasks.Task;
|
||||
import de.oaa.xxx.games.chastity.tasks.TaskListConverter;
|
||||
import de.oaa.xxx.games.chastity.unlock.TempOpeningReason;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Convert;
|
||||
import jakarta.persistence.Entity;
|
||||
@@ -60,7 +61,7 @@ public class CardLockEntity {
|
||||
@Column
|
||||
private boolean testLock;
|
||||
@Column
|
||||
private Integer unlockCodeLines;
|
||||
private Integer unlockCodeLength;
|
||||
|
||||
// State
|
||||
@Column
|
||||
@@ -75,7 +76,11 @@ public class CardLockEntity {
|
||||
@Column
|
||||
private LocalDateTime lastHygineOpening;
|
||||
@Column
|
||||
private LocalDateTime hygineOpeningtime; // If null, not while hygine opening
|
||||
private LocalDateTime tempOpeningTime; // If null, not while hygine opening
|
||||
@Column
|
||||
private Integer tempOpeningDuration;
|
||||
@Column
|
||||
private TempOpeningReason tempOpeningReason;
|
||||
@Column
|
||||
private LocalDateTime unlockTime;
|
||||
@Column
|
||||
|
||||
@@ -11,33 +11,41 @@ import java.util.stream.Collectors;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import de.oaa.xxx.games.chastity.ProcessLock;
|
||||
import de.oaa.xxx.games.chastity.common.AbstractLockService;
|
||||
import de.oaa.xxx.games.chastity.common.CodeCreator;
|
||||
import de.oaa.xxx.games.chastity.keyholder.KeyholderNotificationEntity;
|
||||
import de.oaa.xxx.games.chastity.keyholder.KeyholderNotificationRepository;
|
||||
import de.oaa.xxx.games.chastity.tasks.Task;
|
||||
import de.oaa.xxx.games.chastity.unlock.TempOpeningReason;
|
||||
import de.oaa.xxx.games.chastity.unlock.UnlockCodeHistoryService;
|
||||
import de.oaa.xxx.games.chastity.verification.VerificationRepository;
|
||||
import de.oaa.xxx.games.chastity.verification.VerificationVoteRepository;
|
||||
import de.oaa.xxx.games.history.GameHistoryEntity;
|
||||
import de.oaa.xxx.games.history.GameHistoryRepository;
|
||||
import de.oaa.xxx.games.chastity.tasks.Task;
|
||||
import de.oaa.xxx.games.chastity.verification.VerificationEntity;
|
||||
import de.oaa.xxx.games.chastity.verification.VerificationRepository;
|
||||
import de.oaa.xxx.games.chastity.verification.VerificationVoteEntity;
|
||||
import de.oaa.xxx.games.chastity.verification.VerificationVoteRepository;
|
||||
import de.oaa.xxx.user.UserRepository;
|
||||
|
||||
public class CardLockService extends ProcessLock {
|
||||
public class CardLockService extends AbstractLockService {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(CardLockService.class);
|
||||
private final CardLockEntity lock;
|
||||
private VerificationRepository verificationRepository;
|
||||
private VerificationVoteRepository verificationVoteRepository;
|
||||
private CardLockRepository cardLockRepository;
|
||||
private VerificationRepository verificationRepository;
|
||||
private GameHistoryRepository gameHistoryRepository;
|
||||
private UserRepository userRepository;
|
||||
private UnlockCodeHistoryService unlockCodeHistoryService;
|
||||
private KeyholderNotificationRepository keyholderNotificationRepository;
|
||||
|
||||
public CardLockService(CardLockEntity lock, VerificationRepository verificationRepository, VerificationVoteRepository verificationVoteRepository, CardLockRepository cardLockRepository, GameHistoryRepository gameHistoryRepository, UserRepository userRepository) {
|
||||
this.lock = lock;
|
||||
this.verificationRepository = verificationRepository;
|
||||
this.verificationVoteRepository = verificationVoteRepository;
|
||||
public CardLockService(CardLockEntity lock, VerificationRepository verificationRepository,
|
||||
VerificationVoteRepository verificationVoteRepository, CardLockRepository cardLockRepository,
|
||||
GameHistoryRepository gameHistoryRepository, UserRepository userRepository, KeyholderNotificationRepository keyholderNotificationRepository,UnlockCodeHistoryService unlockCodeHistoryService) {
|
||||
super(verificationVoteRepository);
|
||||
this.lock = lock;
|
||||
this.cardLockRepository = cardLockRepository;
|
||||
this.verificationRepository = verificationRepository;
|
||||
this.gameHistoryRepository = gameHistoryRepository;
|
||||
this.userRepository = userRepository;
|
||||
this.keyholderNotificationRepository = keyholderNotificationRepository;
|
||||
this.unlockCodeHistoryService = unlockCodeHistoryService;
|
||||
}
|
||||
|
||||
public CardDTO getNextCard() {
|
||||
@@ -165,19 +173,6 @@ public class CardLockService extends ProcessLock {
|
||||
lock.getAvailableCards().add(CardEnum.GREEN);
|
||||
cardLockRepository.save(lock);
|
||||
}
|
||||
|
||||
|
||||
private boolean isValid(VerificationEntity entity) {
|
||||
int count = 0;
|
||||
for (VerificationVoteEntity vote : verificationVoteRepository.findAllByVerificationId(entity.getVerficationId())) {
|
||||
if (vote.isUpvote()) {
|
||||
count++;
|
||||
} else {
|
||||
count--;
|
||||
}
|
||||
}
|
||||
return count >= 0;
|
||||
}
|
||||
|
||||
public String freeze() {
|
||||
var multiplier = lock.getPickEveryMinute() * new Random().nextDouble(1.0, 4.0);
|
||||
@@ -244,4 +239,94 @@ public class CardLockService extends ProcessLock {
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public void startHygieneOpening() {
|
||||
tempOperning(TempOpeningReason.HYGIENE, lock.getHygineOpeningDurationMinutes());
|
||||
}
|
||||
|
||||
private Long calcOvertime() {
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
Long overtime = null;
|
||||
if (lock.getTempOpeningTime() != null && lock.getTempOpeningDuration() != null) {
|
||||
LocalDateTime dueTime = lock.getTempOpeningTime().plusMinutes(lock.getTempOpeningDuration());
|
||||
if (LocalDateTime.now().isAfter(dueTime)) {
|
||||
overtime = ChronoUnit.MINUTES.between(dueTime, now);
|
||||
}
|
||||
}
|
||||
return overtime;
|
||||
}
|
||||
|
||||
public String endHygieneOpening() {
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
|
||||
Long overtime = calcOvertime();
|
||||
if (overtime != null) {
|
||||
if (lock.getKeyholder() != null) {
|
||||
reportKeyholder(overtime);
|
||||
}
|
||||
freezeForOvertime(overtime);
|
||||
|
||||
}
|
||||
lock.setLastHygineOpening(now);
|
||||
lock.setTempOpeningDuration(null);
|
||||
lock.setTempOpeningTime(null);
|
||||
|
||||
var code = CodeCreator.createAlphanumericCode(lock.getUnlockCodeLength());
|
||||
lock.setUnlockCode(code);
|
||||
cardLockRepository.save(lock);
|
||||
return code;
|
||||
}
|
||||
|
||||
private void reportKeyholder(Long overtime) {
|
||||
KeyholderNotificationEntity notification = new KeyholderNotificationEntity();
|
||||
notification.setLockId(lock.getLockId());
|
||||
notification.setLockeeId(lock.getLockee());
|
||||
notification.setKeyholderUserId(lock.getKeyholder());
|
||||
notification.setViolationTime(LocalDateTime.now());
|
||||
notification.setOvertimeMinutes(overtime);
|
||||
keyholderNotificationRepository.save(notification);
|
||||
}
|
||||
|
||||
private void freezeForOvertime(Long overtime) {
|
||||
if (lock.getFrozenUntill() != null) {
|
||||
lock.setFrozenUntill(lock.getFrozenUntill().plusMinutes(overtime * 4));
|
||||
} else {
|
||||
lock.setFrozenUntill(LocalDateTime.now().plusMinutes(overtime * 4));
|
||||
}
|
||||
}
|
||||
|
||||
private void tempOperning(TempOpeningReason reason, Integer duration) {
|
||||
assert duration != null;
|
||||
lock.setTempOpeningReason(reason);
|
||||
lock.setTempOpeningTime(LocalDateTime.now());;
|
||||
lock.setTempOpeningDuration(duration);
|
||||
cardLockRepository.save(lock);
|
||||
unlockCodeHistoryService.save(lock.getLockee(), lock.getLockId(), lock.getName(), lock.getUnlockCode(), reason.toString());
|
||||
}
|
||||
|
||||
public String cum(boolean tempUnlock) {
|
||||
if (tempUnlock) {
|
||||
tempOperning(TempOpeningReason.CARD, 0); // Je länger man braucht, desto länger wird gefreezed
|
||||
}
|
||||
return lock.getUnlockCode();
|
||||
}
|
||||
|
||||
public String endCumming() {
|
||||
Long overtime = calcOvertime();
|
||||
if (overtime != null) {
|
||||
if (lock.getKeyholder() == null) {
|
||||
freezeForOvertime(overtime);
|
||||
} else {
|
||||
reportKeyholder(overtime);
|
||||
}
|
||||
}
|
||||
lock.setTempOpeningDuration(null);
|
||||
lock.setTempOpeningTime(null);
|
||||
lock.setTempOpeningReason(null);
|
||||
|
||||
var code = CodeCreator.createAlphanumericCode(lock.getUnlockCodeLength());
|
||||
lock.setUnlockCode(code);
|
||||
cardLockRepository.save(lock);
|
||||
return code;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package de.oaa.xxx.games.chastity.cardlock;
|
||||
|
||||
import de.oaa.xxx.games.history.GameHistoryRepository;
|
||||
import de.oaa.xxx.games.chastity.keyholder.KeyholderNotificationRepository;
|
||||
import de.oaa.xxx.games.chastity.unlock.UnlockCodeHistoryService;
|
||||
import de.oaa.xxx.games.chastity.verification.VerificationRepository;
|
||||
import de.oaa.xxx.games.chastity.verification.VerificationVoteRepository;
|
||||
import de.oaa.xxx.user.UserRepository;
|
||||
@@ -20,18 +22,24 @@ public class CardLockServiceFactory {
|
||||
private final VerificationVoteRepository verificationVoteRepository;
|
||||
private final CardLockRepository cardLockRepository;
|
||||
private final GameHistoryRepository gameHistoryRepository;
|
||||
private final UserRepository userRepository;
|
||||
private final UserRepository userRepository;
|
||||
private KeyholderNotificationRepository keyholderNotificationRepository;
|
||||
private final UnlockCodeHistoryService unlockCodeHistoryService;
|
||||
|
||||
public CardLockServiceFactory(VerificationRepository verificationRepository,
|
||||
VerificationVoteRepository verificationVoteRepository,
|
||||
CardLockRepository cardLockRepository,
|
||||
GameHistoryRepository gameHistoryRepository,
|
||||
UserRepository userRepository) {
|
||||
UserRepository userRepository,
|
||||
KeyholderNotificationRepository keyholderNotificationRepository,
|
||||
UnlockCodeHistoryService unlockCodeHistoryService) {
|
||||
this.verificationRepository = verificationRepository;
|
||||
this.verificationVoteRepository = verificationVoteRepository;
|
||||
this.cardLockRepository = cardLockRepository;
|
||||
this.gameHistoryRepository = gameHistoryRepository;
|
||||
this.userRepository = userRepository;
|
||||
this.keyholderNotificationRepository = keyholderNotificationRepository;
|
||||
this.unlockCodeHistoryService = unlockCodeHistoryService;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -44,7 +52,9 @@ public class CardLockServiceFactory {
|
||||
verificationVoteRepository,
|
||||
cardLockRepository,
|
||||
gameHistoryRepository,
|
||||
userRepository
|
||||
userRepository,
|
||||
keyholderNotificationRepository,
|
||||
unlockCodeHistoryService
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
package de.oaa.xxx.games.chastity.cardlock;
|
||||
|
||||
public class CumCard implements Card {
|
||||
|
||||
@Override
|
||||
public CardDTO processCard(CardLockService lock) {
|
||||
return new CardDTO(CardEnum.CUM, lock.cum(true));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package de.oaa.xxx.games.chastity.cardlock;
|
||||
|
||||
public class CumInCageCard implements Card {
|
||||
|
||||
@Override
|
||||
public CardDTO processCard(CardLockService lock) {
|
||||
return new CardDTO(CardEnum.CUM_IN_CAGE, lock.cum(false));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
package de.oaa.xxx.games.chastity.cardlock;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public interface HygieneViolationRepository extends JpaRepository<HygieneViolationEntity, UUID> {
|
||||
List<HygieneViolationEntity> findByKeyholderUserIdAndNotifiedKeyholderFalse(UUID keyholderUserId);
|
||||
List<HygieneViolationEntity> findByLockId(UUID lockId);
|
||||
}
|
||||
@@ -1,8 +1,12 @@
|
||||
package de.oaa.xxx.games.chastity.cardlock;
|
||||
|
||||
import de.oaa.xxx.games.chastity.keyholder.KeyholderTaskChoiceRepository;
|
||||
import de.oaa.xxx.games.chastity.tasks.AssignedTaskEntity;
|
||||
import de.oaa.xxx.games.chastity.tasks.AssignedTaskRepository;
|
||||
import de.oaa.xxx.games.chastity.tasks.Task;
|
||||
import de.oaa.xxx.games.chastity.vote.CommunityTaskVoteEntryEntity;
|
||||
import de.oaa.xxx.games.chastity.vote.CommunityTaskVoteEntryRepository;
|
||||
import de.oaa.xxx.games.chastity.vote.CommunityTaskVoteRepository;
|
||||
import de.oaa.xxx.social.SystemMessageService;
|
||||
import de.oaa.xxx.user.UserRepository;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
|
||||
@@ -16,6 +16,8 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
import de.oaa.xxx.games.chastity.tasks.AssignedTaskEntity;
|
||||
import de.oaa.xxx.games.chastity.tasks.AssignedTaskRepository;
|
||||
import de.oaa.xxx.games.chastity.tasks.Task;
|
||||
import de.oaa.xxx.games.chastity.vote.CommunityTaskVoteEntryRepository;
|
||||
import de.oaa.xxx.games.chastity.vote.CommunityTaskVoteRepository;
|
||||
import de.oaa.xxx.social.SystemMessageService;
|
||||
|
||||
@Component
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
package de.oaa.xxx.games.chastity.common;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import de.oaa.xxx.games.chastity.verification.VerificationEntity;
|
||||
import de.oaa.xxx.games.chastity.verification.VerificationVoteEntity;
|
||||
import de.oaa.xxx.games.chastity.verification.VerificationVoteRepository;
|
||||
|
||||
public abstract class AbstractLockService {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractLockService.class);
|
||||
private final VerificationVoteRepository verificationVoteRepository;
|
||||
|
||||
public AbstractLockService(VerificationVoteRepository verificationVoteRepository) {
|
||||
this.verificationVoteRepository = verificationVoteRepository;
|
||||
}
|
||||
|
||||
protected boolean isValid(VerificationEntity entity) {
|
||||
LOGGER.trace("isValid");
|
||||
int count = 0;
|
||||
for (VerificationVoteEntity vote : verificationVoteRepository.findAllByVerificationId(entity.getVerficationId())) {
|
||||
if (vote.isUpvote()) {
|
||||
count++;
|
||||
} else {
|
||||
count--;
|
||||
}
|
||||
}
|
||||
return count >= 0;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package de.oaa.xxx.games.chastity;
|
||||
package de.oaa.xxx.games.chastity.common;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
package de.oaa.xxx.games.chastity.common;
|
||||
|
||||
public enum LockType {
|
||||
|
||||
CARD, TIMED;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package de.oaa.xxx.games.chastity.common;
|
||||
|
||||
public enum PenaltyType {
|
||||
|
||||
ADD, FREEZE, PILLORY;
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package de.oaa.xxx.games.chastity;
|
||||
package de.oaa.xxx.games.chastity.keyholder;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import lombok.Getter;
|
||||
@@ -1,4 +1,4 @@
|
||||
package de.oaa.xxx.games.chastity;
|
||||
package de.oaa.xxx.games.chastity.keyholder;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@@ -1,4 +1,4 @@
|
||||
package de.oaa.xxx.games.chastity.cardlock;
|
||||
package de.oaa.xxx.games.chastity.keyholder;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import lombok.Getter;
|
||||
@@ -7,11 +7,13 @@ import lombok.Setter;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.UUID;
|
||||
|
||||
import de.oaa.xxx.games.chastity.unlock.TempOpeningReason;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Entity
|
||||
@Table(name = "hygiene_violation")
|
||||
public class HygieneViolationEntity {
|
||||
@Table(name = "keyholder_notification")
|
||||
public class KeyholderNotificationEntity {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.UUID)
|
||||
@@ -34,4 +36,7 @@ public class HygieneViolationEntity {
|
||||
|
||||
@Column(nullable = false)
|
||||
private boolean notifiedKeyholder = false;
|
||||
|
||||
@Column(nullable = false)
|
||||
private TempOpeningReason openingReason;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package de.oaa.xxx.games.chastity.keyholder;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public interface KeyholderNotificationRepository extends JpaRepository<KeyholderNotificationEntity, UUID> {
|
||||
List<KeyholderNotificationEntity> findByKeyholderUserIdAndNotifiedKeyholderFalse(UUID keyholderUserId);
|
||||
List<KeyholderNotificationEntity> findByLockId(UUID lockId);
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package de.oaa.xxx.games.chastity.cardlock;
|
||||
package de.oaa.xxx.games.chastity.keyholder;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import lombok.Getter;
|
||||
@@ -1,4 +1,4 @@
|
||||
package de.oaa.xxx.games.chastity.cardlock;
|
||||
package de.oaa.xxx.games.chastity.keyholder;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import java.util.List;
|
||||
@@ -0,0 +1,16 @@
|
||||
package de.oaa.xxx.games.chastity.lockcontroll;
|
||||
|
||||
public abstract class LockControl {
|
||||
|
||||
protected final LockControlCallback callback;
|
||||
|
||||
public LockControl(LockControlCallback callback) {
|
||||
this.callback = callback;
|
||||
}
|
||||
|
||||
public abstract boolean init();
|
||||
|
||||
public abstract boolean unlock();
|
||||
|
||||
public abstract boolean lock();
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package de.oaa.xxx.games.chastity.lockcontroll;
|
||||
|
||||
public interface LockControlCallback {
|
||||
|
||||
void setUnlockCode(String code);
|
||||
|
||||
int getUnlockcodeLenght();
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package de.oaa.xxx.games.chastity.lockcontroll;
|
||||
|
||||
public enum LockControllType {
|
||||
|
||||
TTLOCK, UNLOCK_CODE, TRUST;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package de.oaa.xxx.games.chastity.lockcontroll;
|
||||
|
||||
class NoInteractionCallback implements LockControlCallback {
|
||||
|
||||
@Override
|
||||
public void setUnlockCode(String code) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getUnlockcodeLenght() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package de.oaa.xxx.games.chastity.lockcontroll;
|
||||
|
||||
public class TTLockControl extends LockControl {
|
||||
|
||||
public TTLockControl() {
|
||||
super(new NoInteractionCallback());
|
||||
}
|
||||
|
||||
private static final String BASE_URL = "https://euapi.ttlock.com/";
|
||||
|
||||
@Override
|
||||
public boolean init() {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean unlock() {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean lock() {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package de.oaa.xxx.games.chastity.lockcontroll;
|
||||
|
||||
public class TrustLockControl extends LockControl {
|
||||
|
||||
public TrustLockControl() {
|
||||
super(new NoInteractionCallback());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean init() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean unlock() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean lock() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package de.oaa.xxx.games.chastity.lockcontroll;
|
||||
|
||||
import de.oaa.xxx.games.chastity.common.CodeCreator;
|
||||
|
||||
public class UnlockcodeLockControl extends LockControl {
|
||||
|
||||
public UnlockcodeLockControl(LockControlCallback callback) {
|
||||
super(callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean init() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean unlock() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean lock() {
|
||||
var code = CodeCreator.createAlphanumericCode(callback.getUnlockcodeLenght());
|
||||
callback.setUnlockCode(code);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package de.oaa.xxx.games.chastity;
|
||||
package de.oaa.xxx.games.chastity.lockee;
|
||||
|
||||
import java.security.Principal;
|
||||
import java.security.SecureRandom;
|
||||
@@ -220,7 +220,7 @@ public class LockeeInvitationController {
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
lock.setStartTime(now);
|
||||
lock.setUnlockCode(unlockCode);
|
||||
lock.setUnlockCodeLines(codeLines);
|
||||
lock.setUnlockCodeLength(codeLines);
|
||||
lock.setAvailableCards(new ArrayList<>(lock.getInitialCards()));
|
||||
lock.setOpenPicks(0);
|
||||
lock.setNextCardIn(now.plusMinutes(lock.getPickEveryMinute()));
|
||||
@@ -1,4 +1,4 @@
|
||||
package de.oaa.xxx.games.chastity;
|
||||
package de.oaa.xxx.games.chastity.lockee;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import lombok.Getter;
|
||||
@@ -1,4 +1,4 @@
|
||||
package de.oaa.xxx.games.chastity;
|
||||
package de.oaa.xxx.games.chastity.lockee;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
package de.oaa.xxx.games.chastity.pillory;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.UUID;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Table;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Entity
|
||||
@Table(name = "pillory")
|
||||
public class PilloryEntity {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.UUID)
|
||||
@Column
|
||||
@Setter(lombok.AccessLevel.NONE)
|
||||
private UUID pilloryId;
|
||||
@Column(nullable = false)
|
||||
private UUID lockId;
|
||||
@Column(nullable = false)
|
||||
private UUID lockeeUserId;
|
||||
@Column(nullable = false)
|
||||
private LocalDateTime createdAt;
|
||||
@Column
|
||||
private PilloryReason reason;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package de.oaa.xxx.games.chastity.pillory;
|
||||
|
||||
public enum PilloryReason {
|
||||
|
||||
HYGIENE_OPENING_EXEEDED,
|
||||
KEYHOLDER_DESCESSION;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package de.oaa.xxx.games.chastity.pillory;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
public interface PilloryRepository extends JpaRepository<PilloryEntity, UUID> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package de.oaa.xxx.games.chastity.spinningwheel;
|
||||
|
||||
import de.oaa.xxx.games.chastity.timelock.TimeLockService;
|
||||
|
||||
public enum EntryType {
|
||||
|
||||
ADD_TIME {
|
||||
@Override
|
||||
public void apply(TimeLockService service, Integer intVal, String stringVal) {
|
||||
service.addTime(intVal);
|
||||
}
|
||||
},
|
||||
REMOVE_TIME {
|
||||
@Override
|
||||
public void apply(TimeLockService service, Integer intVal, String stringVal) {
|
||||
service.removeTime(intVal);
|
||||
}
|
||||
},
|
||||
FREEZE_TIME {
|
||||
@Override
|
||||
public void apply(TimeLockService service, Integer intVal, String stringVal) {
|
||||
service.freeze(intVal);
|
||||
}
|
||||
},
|
||||
FREEZE {
|
||||
@Override
|
||||
public void apply(TimeLockService service, Integer intVal, String stringVal) {
|
||||
service.freeze();
|
||||
}
|
||||
},
|
||||
UNFREEZE {
|
||||
@Override
|
||||
public void apply(TimeLockService service, Integer intVal, String stringVal) {
|
||||
service.unfreeze();
|
||||
}
|
||||
},
|
||||
TASK {
|
||||
@Override
|
||||
public void apply(TimeLockService service, Integer intVal, String stringVal) {
|
||||
service.task();
|
||||
}
|
||||
},
|
||||
TEXT {
|
||||
@Override
|
||||
public void apply(TimeLockService service, Integer intVal, String stringVal) {
|
||||
service.text(intVal, stringVal);
|
||||
}
|
||||
};
|
||||
|
||||
public abstract void apply(TimeLockService service, Integer intVal, String stringVal);
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package de.oaa.xxx.games.chastity.spinningwheel;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
import jakarta.persistence.AttributeConverter;
|
||||
import jakarta.persistence.Converter;
|
||||
|
||||
@Converter
|
||||
public class SpinningWheelConverter implements AttributeConverter<List<SpinningWheelEntry>, String> {
|
||||
|
||||
private static final ObjectMapper mapper = new ObjectMapper();
|
||||
|
||||
@Override
|
||||
public String convertToDatabaseColumn(List<SpinningWheelEntry> list) {
|
||||
if (list == null || list.isEmpty())
|
||||
return null;
|
||||
try {
|
||||
return mapper.writeValueAsString(list);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SpinningWheelEntry> convertToEntityAttribute(String json) {
|
||||
if (json == null || json.isBlank())
|
||||
return new ArrayList<>();
|
||||
try {
|
||||
return new ArrayList<>(mapper.readValue(json, new TypeReference<List<SpinningWheelEntry>>() {
|
||||
}));
|
||||
} catch (Exception e) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package de.oaa.xxx.games.chastity.spinningwheel;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class SpinningWheelEntity {
|
||||
|
||||
private UUID wheelId;
|
||||
private String name;
|
||||
private List<SpinningWheelEntity> entries;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package de.oaa.xxx.games.chastity.spinningwheel;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class SpinningWheelEntry {
|
||||
|
||||
private EntryType type;
|
||||
private Integer intVal;
|
||||
private String stringVal;
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package de.oaa.xxx.games.chastity.spinningwheel;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class SpinningWheelEntryEntity {
|
||||
|
||||
private UUID entryId;
|
||||
private EntryType type;
|
||||
private Integer intVal;
|
||||
private String stringVal;
|
||||
|
||||
public SpinningWheelEntry toSpinningWheelEntry() {
|
||||
return new SpinningWheelEntry(type, intVal, stringVal);
|
||||
}
|
||||
}
|
||||
@@ -45,6 +45,9 @@ public class AssignedTaskEntity {
|
||||
/** Wie viele rote Karten hinzufügen bei Ablehnung / Ablauf (null = keine). */
|
||||
@Column
|
||||
private Integer penaltyRedCards;
|
||||
|
||||
@Column
|
||||
private Integer penaltyAddTime;
|
||||
|
||||
/** PENDING | ACCEPTED | DECLINED | EXPIRED */
|
||||
@Column(nullable = false)
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
package de.oaa.xxx.games.chastity.tasks;
|
||||
|
||||
public enum TaskMode {
|
||||
RANDOM, KEYHOLDER, COMMUNITY;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package de.oaa.xxx.games.chastity.timelock;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import de.oaa.xxx.games.chastity.lockcontroll.LockControllType;
|
||||
|
||||
public record TimeLockAdditionalSettings(LockControllType controllType, UUID lockee, UUID keyholder, boolean testlock, Integer unlockCodeLength) {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
package de.oaa.xxx.games.chastity.timelock;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import de.oaa.xxx.games.chastity.common.PenaltyType;
|
||||
import de.oaa.xxx.games.chastity.spinningwheel.SpinningWheelConverter;
|
||||
import de.oaa.xxx.games.chastity.spinningwheel.SpinningWheelEntry;
|
||||
import de.oaa.xxx.games.chastity.tasks.Task;
|
||||
import de.oaa.xxx.games.chastity.tasks.TaskListConverter;
|
||||
import de.oaa.xxx.games.chastity.tasks.TaskMode;
|
||||
import de.oaa.xxx.games.chastity.unlock.TempOpeningReason;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Convert;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Table;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Entity
|
||||
@Table(name = "time_lock")
|
||||
public class TimeLockEntity {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.UUID)
|
||||
@Column
|
||||
private UUID lockId;
|
||||
@Column
|
||||
private String name;
|
||||
// Settings
|
||||
@Column(nullable = false)
|
||||
private UUID lockee;
|
||||
@Column
|
||||
private UUID keyholder;
|
||||
@Column
|
||||
private LocalDateTime startTime;
|
||||
@Column
|
||||
private LocalDateTime unlockTime;
|
||||
@Column
|
||||
private boolean endTimeVisible;
|
||||
@Convert(converter = TaskListConverter.class)
|
||||
@Column(columnDefinition = "TEXT")
|
||||
private List<Task> tasks;
|
||||
@Column
|
||||
private Integer taskEveryMinutes;
|
||||
@Column
|
||||
private Integer minTasksPerDay;
|
||||
@Convert(converter = SpinningWheelConverter.class)
|
||||
@Column(columnDefinition = "TEXT")
|
||||
private List<SpinningWheelEntry> spinningWheelEntries;
|
||||
@Column
|
||||
private Integer hygineOpeningDurationMinutes;
|
||||
@Column
|
||||
private Integer hygineOpeningEveryMinites;
|
||||
@Column
|
||||
private boolean requiresVerification;
|
||||
@Column
|
||||
private boolean testLock;
|
||||
@Column
|
||||
private Integer unlockCodeLength;
|
||||
@Column(nullable = false)
|
||||
private TaskMode taskMode = TaskMode.RANDOM;
|
||||
@Column
|
||||
private Integer spinsEveryMinutes;
|
||||
@Column
|
||||
private Integer minSpinsPerDay;
|
||||
@Column
|
||||
private PenaltyType penaltyType;
|
||||
@Column
|
||||
private Integer penaltyValue;
|
||||
|
||||
@Column
|
||||
private LocalDateTime lastHygineOpening;
|
||||
@Column
|
||||
private LocalDateTime tempOpeningTime; // If null, not while hygine opening
|
||||
@Column
|
||||
private Integer tempOpeningDuration;
|
||||
@Column
|
||||
private TempOpeningReason tempOpeningReason;
|
||||
@Column
|
||||
private LocalDateTime frozenFrom;
|
||||
@Column
|
||||
private LocalDateTime frozenUntil;
|
||||
@Column
|
||||
private String currentTask;
|
||||
@Column(columnDefinition = "TEXT")
|
||||
private String currentTaskDescription;
|
||||
@Column
|
||||
private LocalDateTime taskUntil;
|
||||
@Column
|
||||
private String unlockCode;
|
||||
/** Keyholder hat Unlock angefordert – nächste Aktion der Lockee zeigt grüne Karte */
|
||||
@Column(nullable = false)
|
||||
private boolean keyholderRequestedUnlock = false;
|
||||
/** Lockee hat Notfall-Entsperrung angefordert */
|
||||
@Column
|
||||
private java.time.LocalDateTime emergencyUnlockRequestedAt;
|
||||
/** true = System hat automatisch entsperrt (Keyholderin nicht reagiert) */
|
||||
@Column(nullable = false)
|
||||
private boolean emergencyAutoUnlocked = false;
|
||||
@Column
|
||||
private List<LocalDateTime> taskTimes;
|
||||
@Column
|
||||
private List<LocalDateTime> spinningWheelTimes;
|
||||
@Column
|
||||
private LocalDate lastCheck;
|
||||
|
||||
public TaskMode getTaskMode() { return taskMode != null ? taskMode : TaskMode.RANDOM; }
|
||||
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package de.oaa.xxx.games.chastity.timelock;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
public interface TimeLockRepository extends JpaRepository<TimeLockEntity, UUID> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,381 @@
|
||||
package de.oaa.xxx.games.chastity.timelock;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import de.oaa.xxx.games.chastity.common.AbstractLockService;
|
||||
import de.oaa.xxx.games.chastity.common.CodeCreator;
|
||||
import de.oaa.xxx.games.chastity.keyholder.KeyholderNotificationEntity;
|
||||
import de.oaa.xxx.games.chastity.keyholder.KeyholderNotificationRepository;
|
||||
import de.oaa.xxx.games.chastity.lockcontroll.LockControl;
|
||||
import de.oaa.xxx.games.chastity.lockcontroll.LockControlCallback;
|
||||
import de.oaa.xxx.games.chastity.lockcontroll.TTLockControl;
|
||||
import de.oaa.xxx.games.chastity.lockcontroll.TrustLockControl;
|
||||
import de.oaa.xxx.games.chastity.lockcontroll.UnlockcodeLockControl;
|
||||
import de.oaa.xxx.games.chastity.spinningwheel.SpinningWheelEntry;
|
||||
import de.oaa.xxx.games.chastity.tasks.Task;
|
||||
import de.oaa.xxx.games.chastity.tasks.TaskMode;
|
||||
import de.oaa.xxx.games.chastity.unlock.TempOpeningReason;
|
||||
import de.oaa.xxx.games.chastity.unlock.UnlockCodeHistoryService;
|
||||
import de.oaa.xxx.games.chastity.verification.VerificationRepository;
|
||||
import de.oaa.xxx.games.chastity.verification.VerificationVoteRepository;
|
||||
import de.oaa.xxx.games.history.GameHistoryEntity;
|
||||
import de.oaa.xxx.games.history.GameHistoryRepository;
|
||||
import de.oaa.xxx.user.UserRepository;
|
||||
|
||||
public class TimeLockService extends AbstractLockService implements LockControlCallback {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(TimeLockService.class);
|
||||
private final TimeLockEntity lock;
|
||||
private final TimeLockRepository timeLockRepository;
|
||||
private final VerificationRepository verificationRepository;
|
||||
private final GameHistoryRepository gameHistoryRepository;
|
||||
private final UserRepository userRepository;
|
||||
private final KeyholderNotificationRepository keyholderNotificationRepository;
|
||||
private final UnlockCodeHistoryService unlockCodeHistoryService;
|
||||
|
||||
private LockControl lockControl;
|
||||
|
||||
public TimeLockService(TimeLockEntity lock, VerificationRepository verificationRepository,
|
||||
VerificationVoteRepository verificationVoteRepository,
|
||||
TimeLockRepository timeLockRepository,
|
||||
GameHistoryRepository gameHistoryRepository,
|
||||
UserRepository userRepository,
|
||||
KeyholderNotificationRepository keyholderNotificationRepository,
|
||||
UnlockCodeHistoryService unlockCodeHistoryService) {
|
||||
super(verificationVoteRepository);
|
||||
this.lock = lock;
|
||||
this.timeLockRepository = timeLockRepository;
|
||||
this.verificationRepository = verificationRepository;
|
||||
this.gameHistoryRepository = gameHistoryRepository;
|
||||
this.userRepository = userRepository;
|
||||
this.keyholderNotificationRepository = keyholderNotificationRepository;
|
||||
this.unlockCodeHistoryService = unlockCodeHistoryService;
|
||||
}
|
||||
|
||||
public void init(TimeLockTemplate template, TimeLockAdditionalSettings settings) {
|
||||
switch (settings.controllType()) {
|
||||
case TTLOCK -> lockControl = new TTLockControl();
|
||||
case TRUST -> lockControl = new TrustLockControl();
|
||||
case UNLOCK_CODE -> lockControl = new UnlockcodeLockControl(this);
|
||||
}
|
||||
|
||||
lock.setLockee(UUID.randomUUID());
|
||||
lock.setName(template.name());
|
||||
lock.setLockee(settings.lockee());
|
||||
lock.setKeyholder(settings.keyholder());
|
||||
lock.setRequiresVerification(template.requiresVerification());
|
||||
lock.setTestLock(settings.testlock());
|
||||
lock.setUnlockCodeLength(settings.unlockCodeLength());
|
||||
|
||||
lock.setStartTime(LocalDateTime.now());
|
||||
Integer unlockTimeMinutes = template.maxTimeInMinutes();
|
||||
if (template.minTimeInMinutes() != null) {
|
||||
unlockTimeMinutes = new Random().nextInt(template.minTimeInMinutes(), template.maxTimeInMinutes());
|
||||
}
|
||||
lock.setUnlockTime(LocalDateTime.now().plusMinutes(unlockTimeMinutes));
|
||||
lock.setEndTimeVisible(template.endTimeVisible());
|
||||
|
||||
lock.setTasks(template.tasks());
|
||||
lock.setTaskEveryMinutes(template.taskEveryMinutes());
|
||||
lock.setMinTasksPerDay(template.minTasksPerDay());
|
||||
|
||||
lock.setSpinningWheelEntries(template.spinningWheelEntries());
|
||||
lock.setSpinsEveryMinutes(template.spinsEveryMinutes());
|
||||
lock.setMinSpinsPerDay(template.minSpinsPerDay());
|
||||
|
||||
lock.setHygineOpeningDurationMinutes(template.hygineOpeningDurationMinutes());
|
||||
lock.setHygineOpeningEveryMinites(template.hygineOpeningEveryMinites());
|
||||
|
||||
lock.setTaskMode(template.taskMode());
|
||||
|
||||
lockControl.lock();
|
||||
}
|
||||
|
||||
public SpinningWheelEntry spinWheel() {
|
||||
if (TempOpeningReason.HYGIENE != lock.getTempOpeningReason() ) {
|
||||
var entries = lock.getSpinningWheelEntries();
|
||||
var entry = entries.get(new Random().nextInt(entries.size()));
|
||||
entry.getType().apply(this, entry.getIntVal(), entry.getStringVal());
|
||||
return entry;
|
||||
}
|
||||
// Nicht während der Hyhiene Öffnung
|
||||
return null;
|
||||
}
|
||||
|
||||
public void addTime(Integer intVal) {
|
||||
LOGGER.debug("Lock addTime: %s minutes", intVal);
|
||||
lock.setUnlockTime(lock.getUnlockTime().plusMinutes(intVal));
|
||||
}
|
||||
|
||||
public void removeTime(Integer intVal) {
|
||||
LOGGER.debug("Lock removeTime: %s minutes", intVal);
|
||||
lock.setUnlockTime(lock.getUnlockTime().minusMinutes(intVal));
|
||||
}
|
||||
|
||||
public void freeze(Integer intVal) {
|
||||
LOGGER.debug("Lock frozen for %s minutes", intVal);
|
||||
lock.setFrozenFrom(LocalDateTime.now());
|
||||
lock.setFrozenUntil(LocalDateTime.now().plusMinutes(intVal));
|
||||
}
|
||||
|
||||
public void freeze() {
|
||||
LOGGER.debug("Lock frozen");
|
||||
lock.setFrozenFrom(LocalDateTime.now());
|
||||
}
|
||||
|
||||
public void unfreeze() {
|
||||
if (lock.getFrozenFrom() != null) {
|
||||
var unfreeTime = lock.getFrozenUntil() != null ? lock.getFrozenUntil() : LocalDateTime.now();
|
||||
var diff = ChronoUnit.MINUTES.between(lock.getFrozenFrom(), unfreeTime);
|
||||
LOGGER.debug("Lock unfrozen - adding %s minutes to the lock", diff);
|
||||
lock.setUnlockTime(lock.getUnlockTime().plusMinutes(diff));
|
||||
} else {
|
||||
LOGGER.debug("Lock not frozen - ignore Call");
|
||||
}
|
||||
}
|
||||
|
||||
public void task() {
|
||||
if (TempOpeningReason.HYGIENE != lock.getTempOpeningReason() ) {
|
||||
switch (lock.getTaskMode()) {
|
||||
case TaskMode.RANDOM -> applyRandomTask();
|
||||
case TaskMode.KEYHOLDER -> startKeyHolderVote();
|
||||
case TaskMode.COMMUNITY -> startCommunityVode();
|
||||
}
|
||||
}
|
||||
// Nicht während der Hyhiene Öffnung
|
||||
}
|
||||
|
||||
private void startKeyHolderVote() {
|
||||
// Keyholder Vote starten
|
||||
}
|
||||
|
||||
private void startCommunityVode() {
|
||||
// Community Vote starten
|
||||
}
|
||||
|
||||
public void applyRandomTask() {
|
||||
LOGGER.debug("Apply random task");
|
||||
var tasks = lock.getTasks();
|
||||
if (!tasks.isEmpty()) {
|
||||
task(tasks.get(new Random().nextInt(tasks.size())));
|
||||
}
|
||||
}
|
||||
|
||||
public void task(Task task) {
|
||||
LOGGER.debug("Apply task {}", task);
|
||||
lock.setCurrentTask(task.resolveTitle());
|
||||
lock.setCurrentTaskDescription(task.getDescription());
|
||||
if (task.getMinutes() != null && task.getMinutes() > 0) {
|
||||
lock.setTaskUntil(LocalDateTime.now().plusMinutes(task.getMinutes()));
|
||||
}
|
||||
}
|
||||
|
||||
public void text(Integer intVal, String stringVal) {
|
||||
LOGGER.debug("Apply text {}", stringVal);
|
||||
lock.setCurrentTask(stringVal);
|
||||
if (intVal != null && intVal > 0) {
|
||||
lock.setTaskUntil(LocalDateTime.now().plusMinutes(intVal));
|
||||
}
|
||||
}
|
||||
|
||||
public String clearTask() {
|
||||
LOGGER.debug("Clear task");
|
||||
lock.setCurrentTask(null);
|
||||
lock.setCurrentTaskDescription(null);
|
||||
lock.setTaskUntil(null);
|
||||
return "";
|
||||
}
|
||||
|
||||
public void testUnfreeze() {
|
||||
if (lock.getFrozenUntil().isAfter(LocalDateTime.now())) {
|
||||
unfreeze();
|
||||
}
|
||||
}
|
||||
|
||||
public void unlock(String unlockCode) {
|
||||
lockControl.unlock();
|
||||
this.lock.setUnlockTime(LocalDateTime.now());
|
||||
boolean valid = true;
|
||||
if (lock.isEmergencyAutoUnlocked()) {
|
||||
valid = false;
|
||||
LOGGER.debug("Lock invalid - Emergency Auto-Unlock (1h timer)");
|
||||
}
|
||||
if (lock.isTestLock()) {
|
||||
valid = false;
|
||||
} else if (Duration.between(lock.getStartTime(), lock.getUnlockTime()).toHours() > 24) {
|
||||
Set<LocalDate> verifications = verificationRepository.findByLockId(this.lock.getLockId()).stream()
|
||||
.filter(verification -> isValid(verification))
|
||||
.map(verification -> verification.getVerificationTime().toLocalDate()).collect(Collectors.toSet());
|
||||
|
||||
LocalDate current = this.lock.getStartTime().toLocalDate();
|
||||
LocalDate last = this.lock.getUnlockTime().toLocalDate().minusDays(1);
|
||||
|
||||
while (!current.isAfter(last)) {
|
||||
if (!verifications.contains(current)) {
|
||||
valid = false;
|
||||
LOGGER.debug("Lock invalid - no daily verification on %s", current.toString());
|
||||
break;
|
||||
}
|
||||
current = current.plusDays(1);
|
||||
}
|
||||
}
|
||||
|
||||
lock.setUnlockTime(LocalDateTime.now());
|
||||
LOGGER.debug("Unlocked at {}", lock.getUnlockTime());
|
||||
timeLockRepository.save(lock);
|
||||
|
||||
if (valid) {
|
||||
long durationMinutes = Duration.between(lock.getStartTime(), lock.getUnlockTime()).toMinutes();
|
||||
|
||||
// Gemeinsamer History-Eintrag mit Teilnehmerliste
|
||||
GameHistoryEntity entry = new GameHistoryEntity();
|
||||
entry.setGameType(de.oaa.xxx.games.history.GameType.CARDLOCK);
|
||||
entry.setGameName(lock.getName());
|
||||
entry.setStartTime(lock.getStartTime());
|
||||
entry.setEndTime(lock.getUnlockTime());
|
||||
entry.setDurationMinutes(durationMinutes);
|
||||
entry.addParticipant(lock.getLockee(), de.oaa.xxx.games.history.GameRole.LOCKEE);
|
||||
if (lock.getKeyholder() != null) {
|
||||
entry.addParticipant(lock.getKeyholder(), de.oaa.xxx.games.history.GameRole.KEYHOLDER);
|
||||
}
|
||||
gameHistoryRepository.save(entry);
|
||||
|
||||
int minutes = (int) durationMinutes;
|
||||
userRepository.findById(lock.getLockee()).ifPresent(u -> {
|
||||
u.setLockeeXp(u.getLockeeXp() + minutes);
|
||||
userRepository.save(u);
|
||||
});
|
||||
if (lock.getKeyholder() != null) {
|
||||
userRepository.findById(lock.getKeyholder()).ifPresent(u -> {
|
||||
u.setKeyholderXp(u.getKeyholderXp() + minutes);
|
||||
userRepository.save(u);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void applyPenalty() {
|
||||
if (lock.getPenaltyType() != null) {
|
||||
switch (lock.getPenaltyType()) {
|
||||
case ADD -> addTime(lock.getPenaltyValue());
|
||||
case FREEZE -> freeze();
|
||||
case PILLORY -> pillory();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void check() {
|
||||
LocalDate today = LocalDate.now();
|
||||
if (!lock.getStartTime().toLocalDate().equals(today)) {
|
||||
if (lock.getLastCheck() != null || today.isAfter(lock.getLastCheck())) {
|
||||
LOGGER.info("Check the day before for violations");
|
||||
LocalDate yesterday = today.minusDays(1);
|
||||
boolean violation = false;
|
||||
if (lock.getMinTasksPerDay() != null) {
|
||||
if (lock.getMinTasksPerDay() > lock.getTaskTimes().stream().map(LocalDateTime::toLocalDate)
|
||||
.filter(yesterday::equals).count()) {
|
||||
violation = true;
|
||||
}
|
||||
}
|
||||
if (lock.getMinSpinsPerDay() != null) {
|
||||
if (lock.getMinSpinsPerDay() > lock.getSpinningWheelTimes().stream().map(LocalDateTime::toLocalDate)
|
||||
.filter(yesterday::equals).count()) {
|
||||
violation = true;
|
||||
}
|
||||
}
|
||||
if (violation) {
|
||||
applyPenalty();
|
||||
}
|
||||
lock.setLastCheck(today);
|
||||
timeLockRepository.save(lock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void pillory() {
|
||||
// TODO an den Pranger stellen
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUnlockCode(String code) {
|
||||
lock.setUnlockCode(code);
|
||||
timeLockRepository.save(lock);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getUnlockcodeLenght() {
|
||||
return lock.getUnlockCodeLength();
|
||||
}
|
||||
|
||||
|
||||
public void startHygieneOpening() {
|
||||
tempOperning(TempOpeningReason.HYGIENE, lock.getHygineOpeningDurationMinutes());
|
||||
}
|
||||
|
||||
private Long calcOvertime() {
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
Long overtime = null;
|
||||
if (lock.getTempOpeningTime() != null && lock.getTempOpeningDuration() != null) {
|
||||
LocalDateTime dueTime = lock.getTempOpeningTime().plusMinutes(lock.getTempOpeningDuration());
|
||||
if (LocalDateTime.now().isAfter(dueTime)) {
|
||||
overtime = ChronoUnit.MINUTES.between(dueTime, now);
|
||||
}
|
||||
}
|
||||
return overtime;
|
||||
}
|
||||
|
||||
public String endHygieneOpening() {
|
||||
lockControl.lock();
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
|
||||
Long overtime = calcOvertime();
|
||||
if (overtime != null) {
|
||||
if (lock.getKeyholder() != null) {
|
||||
reportKeyholder(overtime);
|
||||
}
|
||||
addOvertime(overtime);
|
||||
}
|
||||
lock.setLastHygineOpening(now);
|
||||
lock.setTempOpeningDuration(null);
|
||||
lock.setTempOpeningTime(null);
|
||||
|
||||
var code = CodeCreator.createAlphanumericCode(lock.getUnlockCodeLength());
|
||||
lock.setUnlockCode(code);
|
||||
timeLockRepository.save(lock);
|
||||
return code;
|
||||
}
|
||||
|
||||
private void reportKeyholder(Long overtime) {
|
||||
KeyholderNotificationEntity notification = new KeyholderNotificationEntity();
|
||||
notification.setLockId(lock.getLockId());
|
||||
notification.setLockeeId(lock.getLockee());
|
||||
notification.setKeyholderUserId(lock.getKeyholder());
|
||||
notification.setViolationTime(LocalDateTime.now());
|
||||
notification.setOvertimeMinutes(overtime);
|
||||
keyholderNotificationRepository.save(notification);
|
||||
}
|
||||
|
||||
private void addOvertime(Long overtime) {
|
||||
lock.setUnlockTime(lock.getUnlockTime().plusMinutes(overtime * 4));
|
||||
}
|
||||
|
||||
private void tempOperning(TempOpeningReason reason, Integer duration) {
|
||||
assert duration != null;
|
||||
lockControl.unlock();
|
||||
lock.setTempOpeningReason(reason);
|
||||
lock.setTempOpeningTime(LocalDateTime.now());;
|
||||
lock.setTempOpeningDuration(duration);
|
||||
timeLockRepository.save(lock);
|
||||
unlockCodeHistoryService.save(lock.getLockee(), lock.getLockId(), lock.getName(), lock.getUnlockCode(), reason.toString());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package de.oaa.xxx.games.chastity.timelock;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import de.oaa.xxx.games.chastity.keyholder.KeyholderNotificationRepository;
|
||||
import de.oaa.xxx.games.chastity.unlock.UnlockCodeHistoryService;
|
||||
import de.oaa.xxx.games.chastity.verification.VerificationRepository;
|
||||
import de.oaa.xxx.games.chastity.verification.VerificationVoteRepository;
|
||||
import de.oaa.xxx.games.history.GameHistoryRepository;
|
||||
import de.oaa.xxx.user.UserRepository;
|
||||
@Service
|
||||
public class TimeLockServiceFactory {
|
||||
|
||||
|
||||
private final VerificationRepository verificationRepository;
|
||||
private final VerificationVoteRepository verificationVoteRepository;
|
||||
private final TimeLockRepository timeLockRepository;
|
||||
private final GameHistoryRepository gameHistoryRepository;
|
||||
private final UserRepository userRepository;
|
||||
private KeyholderNotificationRepository keyholderNotificationRepository;
|
||||
private final UnlockCodeHistoryService unlockCodeHistoryService;
|
||||
|
||||
public TimeLockServiceFactory(VerificationRepository verificationRepository,
|
||||
VerificationVoteRepository verificationVoteRepository,
|
||||
TimeLockRepository timeLockRepository,
|
||||
GameHistoryRepository gameHistoryRepository,
|
||||
UserRepository userRepository,
|
||||
KeyholderNotificationRepository keyholderNotificationRepository,
|
||||
UnlockCodeHistoryService unlockCodeHistoryService) {
|
||||
this.verificationRepository = verificationRepository;
|
||||
this.verificationVoteRepository = verificationVoteRepository;
|
||||
this.timeLockRepository = timeLockRepository;
|
||||
this.gameHistoryRepository = gameHistoryRepository;
|
||||
this.userRepository = userRepository;
|
||||
this.keyholderNotificationRepository = keyholderNotificationRepository;
|
||||
this.unlockCodeHistoryService = unlockCodeHistoryService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Erstellt eine neue CardLockService-Instanz für das gegebene Lock.
|
||||
*/
|
||||
public TimeLockService create(TimeLockEntity lock) {
|
||||
return new TimeLockService(
|
||||
lock,
|
||||
verificationRepository,
|
||||
verificationVoteRepository,
|
||||
timeLockRepository,
|
||||
gameHistoryRepository,
|
||||
userRepository,
|
||||
keyholderNotificationRepository,
|
||||
unlockCodeHistoryService
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package de.oaa.xxx.games.chastity.timelock;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import de.oaa.xxx.games.chastity.common.PenaltyType;
|
||||
import de.oaa.xxx.games.chastity.spinningwheel.SpinningWheelEntry;
|
||||
import de.oaa.xxx.games.chastity.tasks.Task;
|
||||
import de.oaa.xxx.games.chastity.tasks.TaskMode;
|
||||
|
||||
public record TimeLockTemplate(UUID templateId, UUID owner, String name, Integer minTimeInMinutes,
|
||||
Integer maxTimeInMinutes, boolean endTimeVisible, Integer hygineOpeningDurationMinutes,
|
||||
Integer hygineOpeningEveryMinites, List<Task> tasks, Integer taskEveryMinutes, Integer minTasksPerDay,
|
||||
List<SpinningWheelEntry> spinningWheelEntries, Integer spinsEveryMinutes, Integer minSpinsPerDay,
|
||||
boolean requiresVerification, TaskMode taskMode, PenaltyType penaltyType, Integer penaltyValue) {
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
package de.oaa.xxx.games.chastity.timelock;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import de.oaa.xxx.games.chastity.common.PenaltyType;
|
||||
import de.oaa.xxx.games.chastity.spinningwheel.SpinningWheelConverter;
|
||||
import de.oaa.xxx.games.chastity.spinningwheel.SpinningWheelEntry;
|
||||
import de.oaa.xxx.games.chastity.tasks.Task;
|
||||
import de.oaa.xxx.games.chastity.tasks.TaskListConverter;
|
||||
import de.oaa.xxx.games.chastity.tasks.TaskMode;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Convert;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Table;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Entity
|
||||
@Table(name = "timelock_template")
|
||||
public class TimeLockTemplateEntity {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.UUID)
|
||||
@Column
|
||||
private UUID templateId;
|
||||
@Column(nullable = false)
|
||||
private UUID owner;
|
||||
@Column
|
||||
private String name;
|
||||
@Column
|
||||
private Integer minTimeInMinutes;
|
||||
@Column
|
||||
private Integer maxTimeInMinutes;
|
||||
@Column
|
||||
private boolean endTimeVisible;
|
||||
@Column
|
||||
private Integer hygineOpeningDurationMinutes;
|
||||
@Column
|
||||
private Integer hygineOpeningEveryMinites;
|
||||
|
||||
@Convert(converter = TaskListConverter.class)
|
||||
@Column(columnDefinition = "TEXT")
|
||||
private List<Task> tasks;
|
||||
@Column
|
||||
private Integer taskEveryMinutes;
|
||||
@Column
|
||||
private Integer minTasksPerDay;
|
||||
|
||||
@Convert(converter = SpinningWheelConverter.class)
|
||||
@Column(columnDefinition = "TEXT")
|
||||
private List<SpinningWheelEntry> spinningWheelEntries;
|
||||
@Column
|
||||
private Integer spinsEveryMinutes;
|
||||
@Column
|
||||
private Integer minSpinsPerDay;
|
||||
|
||||
@Column
|
||||
private boolean requiresVerification;
|
||||
@Column(nullable = false)
|
||||
private TaskMode taskMode = TaskMode.RANDOM;
|
||||
@Column
|
||||
private PenaltyType penaltyType;
|
||||
@Column
|
||||
private Integer penaltyValue;
|
||||
|
||||
public TaskMode getTaskCardMode() {
|
||||
return taskMode != null ? taskMode : TaskMode.RANDOM;
|
||||
}
|
||||
|
||||
public TimeLockTemplate toTimeLockTemplate() {
|
||||
return new TimeLockTemplate(templateId, owner, name, minTimeInMinutes, maxTimeInMinutes, endTimeVisible,
|
||||
hygineOpeningDurationMinutes, hygineOpeningEveryMinites, tasks, taskEveryMinutes, minTasksPerDay,
|
||||
spinningWheelEntries, spinsEveryMinutes, minSpinsPerDay, requiresVerification, taskMode, penaltyType,
|
||||
penaltyValue);
|
||||
}
|
||||
|
||||
public static TimeLockTemplateEntity fromTemplate(TimeLockTemplate template) {
|
||||
if (template != null) {
|
||||
TimeLockTemplateEntity entity = new TimeLockTemplateEntity();
|
||||
entity.setOwner(template.owner());
|
||||
entity.setName(template.name());
|
||||
entity.setMinTimeInMinutes(template.minTimeInMinutes());
|
||||
entity.setMaxTimeInMinutes(template.maxTimeInMinutes());
|
||||
entity.setEndTimeVisible(template.endTimeVisible());
|
||||
entity.setHygineOpeningDurationMinutes(template.hygineOpeningDurationMinutes());
|
||||
entity.setHygineOpeningEveryMinites(template.hygineOpeningEveryMinites());
|
||||
entity.setTasks(template.tasks());
|
||||
entity.setTaskEveryMinutes(template.taskEveryMinutes());
|
||||
entity.setMinTasksPerDay(template.minTasksPerDay());
|
||||
entity.setSpinningWheelEntries(template.spinningWheelEntries());
|
||||
entity.setSpinsEveryMinutes(template.spinsEveryMinutes());
|
||||
entity.setMinSpinsPerDay(template.minSpinsPerDay());
|
||||
entity.setRequiresVerification(template.requiresVerification());
|
||||
entity.setTaskMode(template.taskMode() != null ? template.taskMode() : TaskMode.RANDOM);
|
||||
entity.setPenaltyType(template.penaltyType());
|
||||
entity.setPenaltyValue(template.penaltyValue());
|
||||
return entity;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
package de.oaa.xxx.games.chastity.timelock;
|
||||
|
||||
import static de.oaa.xxx.util.ValidationResult.ERROR;
|
||||
import static de.oaa.xxx.util.ValidationResult.OK;
|
||||
import static de.oaa.xxx.util.ValidationResult.WARNING;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import de.oaa.xxx.games.chastity.spinningwheel.EntryType;
|
||||
import de.oaa.xxx.games.chastity.tasks.TaskMode;
|
||||
import de.oaa.xxx.util.ValidationResult;
|
||||
|
||||
public class TimeLockTemplateService {
|
||||
|
||||
private TimelockTemplateRepository timelockTemplateRepository;
|
||||
|
||||
public TimeLockTemplateService(TimelockTemplateRepository timelockTemplateRepository) {
|
||||
this.timelockTemplateRepository = timelockTemplateRepository;
|
||||
}
|
||||
|
||||
public List<TimeLockTemplate> all(UUID ownderId) {
|
||||
return timelockTemplateRepository.findByOwner(ownderId).stream().map(template -> template.toTimeLockTemplate()).toList();
|
||||
}
|
||||
|
||||
public boolean safe(TimeLockTemplate template) {
|
||||
var result = validate(template);
|
||||
if (ValidationResult.OK == result || ValidationResult.WARNING == result) {
|
||||
timelockTemplateRepository.save(TimeLockTemplateEntity.fromTemplate(template));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public ValidationResult validate(TimeLockTemplate template) {
|
||||
if (template == null) {
|
||||
return ERROR;
|
||||
}
|
||||
if (template.owner() == null ||
|
||||
template.name() == null ||
|
||||
template.maxTimeInMinutes() == null) {
|
||||
return ERROR;
|
||||
}
|
||||
if (template.taskEveryMinutes() != null) {
|
||||
if (template.tasks() == null || template.tasks().isEmpty()) {
|
||||
return ERROR;
|
||||
}
|
||||
if (template.spinningWheelEntries() != null && !template.spinningWheelEntries().isEmpty()
|
||||
&& template.spinningWheelEntries().stream().anyMatch(entry -> EntryType.TASK == entry.getType())) {
|
||||
return ERROR;
|
||||
}
|
||||
if (template.minTasksPerDay() != null) {
|
||||
int minTime = getMinimumTime(template);
|
||||
if (minTime > (24*60)) {
|
||||
return ERROR;
|
||||
} else if (minTime > (12*60)) {
|
||||
return WARNING;
|
||||
}
|
||||
}
|
||||
} else if (template.minTasksPerDay() != null) {
|
||||
return ERROR;
|
||||
}
|
||||
if (template.spinsEveryMinutes() != null) {
|
||||
if (template.spinningWheelEntries() == null || template.spinningWheelEntries().isEmpty()) {
|
||||
return ERROR;
|
||||
}
|
||||
if (template.minSpinsPerDay() != null) {
|
||||
int minTime = template.spinsEveryMinutes() * template.minSpinsPerDay();
|
||||
if (minTime > (24*60)) {
|
||||
return ERROR;
|
||||
} else if (minTime > (12*60)) {
|
||||
return WARNING;
|
||||
}
|
||||
}
|
||||
} else if (template.minSpinsPerDay() != null) {
|
||||
return ERROR;
|
||||
}
|
||||
if (template.hygineOpeningEveryMinites() != null && template.hygineOpeningDurationMinutes() == null) {
|
||||
return ERROR;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
private Integer getMinimumTime(TimeLockTemplate template) {
|
||||
int votetime = 0;
|
||||
if (TaskMode.COMMUNITY == template.taskMode() || TaskMode.KEYHOLDER == template.taskMode()) {
|
||||
votetime = 60 * template.minTasksPerDay();
|
||||
}
|
||||
int waittime = template.taskEveryMinutes() * template.minTasksPerDay();
|
||||
return votetime + waittime;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package de.oaa.xxx.games.chastity.timelock;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public interface TimelockTemplateRepository extends JpaRepository<TimeLockTemplateEntity, UUID> {
|
||||
List<TimeLockTemplateEntity> findByOwner(UUID owner);
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package de.oaa.xxx.games.chastity.unlock;
|
||||
|
||||
public enum TempOpeningReason {
|
||||
HYGIENE, CARD, TASK;
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package de.oaa.xxx.games.chastity.cardlock;
|
||||
package de.oaa.xxx.games.chastity.unlock;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import lombok.Getter;
|
||||
@@ -1,4 +1,4 @@
|
||||
package de.oaa.xxx.games.chastity.cardlock;
|
||||
package de.oaa.xxx.games.chastity.unlock;
|
||||
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
@@ -1,4 +1,4 @@
|
||||
package de.oaa.xxx.games.chastity.cardlock;
|
||||
package de.oaa.xxx.games.chastity.unlock;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -23,7 +23,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import de.oaa.xxx.games.chastity.CodeCreator;
|
||||
import de.oaa.xxx.games.chastity.common.CodeCreator;
|
||||
import de.oaa.xxx.user.UserRepository;
|
||||
|
||||
@RestController
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package de.oaa.xxx.games.chastity.cardlock;
|
||||
package de.oaa.xxx.games.chastity.vote;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import lombok.Getter;
|
||||
@@ -1,4 +1,4 @@
|
||||
package de.oaa.xxx.games.chastity.cardlock;
|
||||
package de.oaa.xxx.games.chastity.vote;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import lombok.Getter;
|
||||
@@ -1,4 +1,4 @@
|
||||
package de.oaa.xxx.games.chastity.cardlock;
|
||||
package de.oaa.xxx.games.chastity.vote;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import java.util.List;
|
||||
@@ -1,4 +1,4 @@
|
||||
package de.oaa.xxx.games.chastity.cardlock;
|
||||
package de.oaa.xxx.games.chastity.vote;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import java.time.LocalDateTime;
|
||||
@@ -0,0 +1,5 @@
|
||||
package de.oaa.xxx.util;
|
||||
|
||||
public enum ValidationResult {
|
||||
OK, INFO, WARNING, ERROR;
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
package de.oaa.xxx.games.chastity.timelock;
|
||||
|
||||
import de.oaa.xxx.games.chastity.spinningwheel.EntryType;
|
||||
import de.oaa.xxx.games.chastity.spinningwheel.SpinningWheelEntry;
|
||||
import de.oaa.xxx.games.chastity.tasks.Task;
|
||||
import de.oaa.xxx.games.chastity.tasks.TaskMode;
|
||||
import de.oaa.xxx.util.ValidationResult;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class TimeLockTemplateServiceTest {
|
||||
|
||||
private final TimeLockTemplateService service = new TimeLockTemplateService(null);
|
||||
|
||||
/**
|
||||
* Zentrale Factory-Methode für den Test.
|
||||
* Erzeugt immer ein frisches Record-Objekt.
|
||||
*/
|
||||
private TimeLockTemplate createTemplate(
|
||||
UUID owner, String name, Integer maxTime,
|
||||
Integer taskEvery, Integer minTasks, List<Task> tasks,
|
||||
Integer spinsEvery, Integer minSpins, List<SpinningWheelEntry> entries,
|
||||
Integer hygEvery, Integer hygDuration) {
|
||||
return createTemplate(owner, name, maxTime, taskEvery, minTasks, tasks, spinsEvery, minSpins, entries, hygEvery, hygDuration, TaskMode.RANDOM);
|
||||
}
|
||||
|
||||
private TimeLockTemplate createTemplate(
|
||||
UUID owner, String name, Integer maxTime,
|
||||
Integer taskEvery, Integer minTasks, List<Task> tasks,
|
||||
Integer spinsEvery, Integer minSpins, List<SpinningWheelEntry> entries,
|
||||
Integer hygEvery, Integer hygDuration, TaskMode taskMode) {
|
||||
|
||||
return new TimeLockTemplate(null,
|
||||
owner,
|
||||
name,
|
||||
0, // minTimeInMinutes
|
||||
maxTime,
|
||||
true, // endTimeVisible
|
||||
hygDuration,
|
||||
hygEvery,
|
||||
tasks,
|
||||
taskEvery,
|
||||
minTasks,
|
||||
entries,
|
||||
spinsEvery,
|
||||
minSpins,
|
||||
false, // requiresVerification
|
||||
taskMode,
|
||||
null, // penaltyType
|
||||
null // penaltyValue
|
||||
);
|
||||
}
|
||||
|
||||
// Hilfsmethode für ein schnelles Standard-Template
|
||||
private TimeLockTemplate validBase() {
|
||||
return createTemplate(UUID.randomUUID(), "Standard", 60, null, null, null, null, null, null, null, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
void validate_OK_Minimal() {
|
||||
assertThat(service.validate(validBase())).isEqualTo(ValidationResult.OK);
|
||||
}
|
||||
|
||||
@Test
|
||||
void validate_ERROR_MissingMandatoryFields() {
|
||||
assertThat(service.validate(createTemplate(null, "Name", 10, null, null, null, null, null, null, null, null))).isEqualTo(ValidationResult.ERROR);
|
||||
assertThat(service.validate(createTemplate(UUID.randomUUID(), null, 10, null, null, null, null, null, null, null, null))).isEqualTo(ValidationResult.ERROR);
|
||||
assertThat(service.validate(createTemplate(UUID.randomUUID(), "Name", null, null, null, null, null, null, null, null, null))).isEqualTo(ValidationResult.ERROR);
|
||||
}
|
||||
|
||||
@Test
|
||||
void validate_ERROR_TasksButNoList() {
|
||||
// Intervall gesetzt, aber Liste ist null oder leer
|
||||
TimeLockTemplate tNull = createTemplate(UUID.randomUUID(), "T", 60, 10, null, null, null, null, null, null, null);
|
||||
TimeLockTemplate tEmpty = createTemplate(UUID.randomUUID(), "T", 60, 10, null, Collections.emptyList(), null, null, null, null, null);
|
||||
|
||||
assertThat(service.validate(tNull)).isEqualTo(ValidationResult.ERROR);
|
||||
assertThat(service.validate(tEmpty)).isEqualTo(ValidationResult.ERROR);
|
||||
}
|
||||
|
||||
@Test
|
||||
void validate_ERROR_SpinningWheelTaskConflict() {
|
||||
SpinningWheelEntry taskEntry = new SpinningWheelEntry();
|
||||
taskEntry.setType(EntryType.TASK);
|
||||
|
||||
TimeLockTemplate t = createTemplate(UUID.randomUUID(), "T", 60, 10, null, List.of(new Task()), null, null, List.of(taskEntry), null, null);
|
||||
|
||||
assertThat(service.validate(t)).isEqualTo(ValidationResult.ERROR);
|
||||
}
|
||||
|
||||
@Test
|
||||
void validate_WARNING_TaskTimeLimitReached() {
|
||||
// 120 Min Intervall * 7 Tasks = 840 Min (> 12h)
|
||||
TimeLockTemplate t = createTemplate(UUID.randomUUID(), "T", 60, 120, 7, List.of(new Task()), null, null, null, null, null);
|
||||
|
||||
assertThat(service.validate(t)).isEqualTo(ValidationResult.WARNING);
|
||||
}
|
||||
|
||||
@Test
|
||||
void validate_ERROR_MinTasksWithoutInterval() {
|
||||
TimeLockTemplate t = createTemplate(UUID.randomUUID(), "T", 60, null, 5, null, null, null, null, null, null);
|
||||
assertThat(service.validate(t)).isEqualTo(ValidationResult.ERROR);
|
||||
}
|
||||
|
||||
@Test
|
||||
void validate_ERROR_SpinsButNoEntries() {
|
||||
TimeLockTemplate t = createTemplate(UUID.randomUUID(), "T", 60, null, null, null, 30, 2, null, null, null);
|
||||
assertThat(service.validate(t)).isEqualTo(ValidationResult.ERROR);
|
||||
}
|
||||
|
||||
@Test
|
||||
void validate_WARNING_SpinTimeLimitReached() {
|
||||
// 200 Min Intervall * 4 Spins = 800 Min (> 12h)
|
||||
TimeLockTemplate t = createTemplate(UUID.randomUUID(), "T", 60, null, null, null, 200, 4, List.of(new SpinningWheelEntry()), null, null);
|
||||
|
||||
assertThat(service.validate(t)).isEqualTo(ValidationResult.WARNING);
|
||||
}
|
||||
|
||||
@Test
|
||||
void validate_ERROR_HygieneIncomplete() {
|
||||
// Intervall gesetzt, aber Dauer fehlt
|
||||
TimeLockTemplate t = createTemplate(UUID.randomUUID(), "T", 60, null, null, null, null, null, null, 60, null);
|
||||
assertThat(service.validate(t)).isEqualTo(ValidationResult.ERROR);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validate_communityVotes() {
|
||||
TimeLockTemplate t = createTemplate(UUID.randomUUID(), "T", 60, 60, 6, List.of(new Task()), null, null, null, null, null,TaskMode.RANDOM);
|
||||
assertThat(service.validate(t)).isEqualTo(ValidationResult.OK);
|
||||
|
||||
t = createTemplate(UUID.randomUUID(), "T", 60, 60, 7, List.of(new Task()), null, null, null, null, null,TaskMode.COMMUNITY);
|
||||
assertThat(service.validate(t)).isEqualTo(ValidationResult.WARNING);
|
||||
|
||||
t = createTemplate(UUID.randomUUID(), "T", 60, 60, 12, List.of(new Task()), null, null, null, null, null,TaskMode.COMMUNITY);
|
||||
assertThat(service.validate(t)).isEqualTo(ValidationResult.WARNING);
|
||||
}
|
||||
|
||||
public void testErrorOnTasksAndTaskInWheel() {
|
||||
SpinningWheelEntry entry = Mockito.mock(SpinningWheelEntry.class);
|
||||
Mockito.when(entry.getType()).thenReturn(EntryType.TASK);
|
||||
TimeLockTemplate t = createTemplate(UUID.randomUUID(), "T", 60, 60, 6, List.of(new Task()), null, null, List.of(), null, null);
|
||||
assertThat(service.validate(t)).isEqualTo(ValidationResult.ERROR);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user