diff --git a/bilder/card vorlage.xcf b/bilder/card vorlage.xcf new file mode 100644 index 0000000..259b6e3 Binary files /dev/null and b/bilder/card vorlage.xcf differ diff --git a/bilder/card.png b/bilder/card.png new file mode 100644 index 0000000..8bf5d1d Binary files /dev/null and b/bilder/card.png differ diff --git a/bilder/card_green.png b/bilder/card_green.png new file mode 100644 index 0000000..d4f980a Binary files /dev/null and b/bilder/card_green.png differ diff --git a/xxxthegame/src/main/java/Ideen.txt b/xxxthegame/src/main/java/Ideen.txt new file mode 100644 index 0000000..5b81403 --- /dev/null +++ b/xxxthegame/src/main/java/Ideen.txt @@ -0,0 +1,12 @@ +Anzeige der Locks und Lockees im Profil, Anzeige der Locked time, falls verifiziert, die verification muss einmal am tag statt finden + +Historie für die Spiele + +Sammeln von Erfahrung + +Verknüpfung der Spiele, wenn das Finish eines aus dem Bereich Chastity ist, wird daraus sofort ein Lock erstellt + +Wenn ein Lock für einen User existiert, wird er ohne entsprechend Penis/Vagina zu dem Spiel erstellt. + +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. \ No newline at end of file diff --git a/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/KeyholdeCardLock.java b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/KeyholdeCardLock.java new file mode 100644 index 0000000..ed154e6 --- /dev/null +++ b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/KeyholdeCardLock.java @@ -0,0 +1,49 @@ +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 KeyholdeCardLock { + + private static final Logger LOGGER = LoggerFactory.getLogger(KeyholdeCardLock.class); + + private CardLockEntity lock; + + + public void addCards(List 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 untill %s", lock.getFrozenUntill()); + } + + public void freeze(LocalDateTime untill) { + lock.setFrozenUntill(untill); + LOGGER.debug("Frozen by keyholder untill %s", lock.getFrozenUntill()); + } + + public void task() { + + } + + public void task(Task task) { + + } + + public void penalty() { + + } +} diff --git a/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/KeyholderController.java b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/KeyholderController.java new file mode 100644 index 0000000..545c195 --- /dev/null +++ b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/KeyholderController.java @@ -0,0 +1,8 @@ +package de.oaa.xxx.games.chastity; + +public class KeyholderController { + + + + +} diff --git a/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/LockType.java b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/LockType.java new file mode 100644 index 0000000..22fd395 --- /dev/null +++ b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/LockType.java @@ -0,0 +1,6 @@ +package de.oaa.xxx.games.chastity; + +public enum LockType { + + CARD, TIMED; +} diff --git a/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/PrcoessTimedLock.java b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/PrcoessTimedLock.java new file mode 100644 index 0000000..b341e31 --- /dev/null +++ b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/PrcoessTimedLock.java @@ -0,0 +1,5 @@ +package de.oaa.xxx.games.chastity; + +public class PrcoessTimedLock { + +} diff --git a/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/ProcessCardLock.java b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/ProcessCardLock.java new file mode 100644 index 0000000..f8d1c4e --- /dev/null +++ b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/ProcessCardLock.java @@ -0,0 +1,104 @@ +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 ProcessCardLock extends ProcessLock { + + private static final Logger LOGGER = LoggerFactory.getLogger(ProcessCardLock.class); + private final CardLockEntity lock; + + public ProcessCardLock(CardLockEntity lock) { + this.lock = lock; + } + + public String getNextCard() { + LOGGER.debug("New Card requested by user %s", lock.getLockee().toString()); + if (lock.getAvailableCards().size() > 0) { + var card = lock.getAvailableCards().get(new Random().nextInt(lock.getAvailableCards().size())); + LOGGER.debug("Card drafted: %s", card.toString()); + card.get().processCard(this); + } + return ""; + } + + public String doubleUp() { + List cards = lock.getAvailableCards(); + LOGGER.debug("Double up %i cards", cards.size()); + lock.getAvailableCards().addAll(cards); + LOGGER.debug("Now %i cards", cards.size()); + return ""; + } + + public String reset() { + LOGGER.debug("Reset to initial cards"); + lock.setAvailableCards(lock.getInitialCards()); + return ""; + } + + public String unlock() { + // Verifications prüfen + // Historie eintragen + // XP berechnen + // Lock löschen + + lock.setUnlockTime(LocalDateTime.now()); + LOGGER.debug("Unlocked at " + lock.getUnlockTime()); + return ""; + } + + public String freeze() { + var multiplier = lock.getPickEveryMinute() * new Random().nextDouble(1.0, 4.0); + freeze(multiplier); + return ""; + } + + private String freeze(double multiplier) { + LocalDateTime frozenTill = LocalDateTime.now().plus((long) multiplier, ChronoUnit.MINUTES); + lock.setFrozenUntill(frozenTill); + LOGGER.debug("Frozen untill %s", lock.getFrozenUntill()); + return ""; + } + + public String task() { + LOGGER.debug("Apply random task"); + if (lock.getTasks().size() > 0) { + task(lock.getTasks().get(new Random().nextInt(lock.getTasks().size()))); + } + return ""; + } + + public String task(Task task) { + LOGGER.debug("Apply task %s", task); + lock.setCurrentTask(task.getText()); + if (task.getMinutes() != null) { + freeze(task.getMinutes()); + } + return ""; + } + + public String clearTask() { + LOGGER.debug("Clear task"); + lock.setFrozenUntill(null); + lock.setCurrentTask(null); + return ""; + } + + public String redCard() { + return ""; + } + + public String yellowCard() { + + return ""; + } +} diff --git a/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/ProcessLock.java b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/ProcessLock.java new file mode 100644 index 0000000..96cf871 --- /dev/null +++ b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/ProcessLock.java @@ -0,0 +1,9 @@ +package de.oaa.xxx.games.chastity; + +public class ProcessLock { + + public void oeffnen() { + // TODO Auto-generated method stub + + } +} diff --git a/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/Timer.java b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/Timer.java new file mode 100644 index 0000000..b1ecd8c --- /dev/null +++ b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/Timer.java @@ -0,0 +1,5 @@ +package de.oaa.xxx.games.chastity; + +public class Timer { + +} diff --git a/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/cardlock/Card.java b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/cardlock/Card.java new file mode 100644 index 0000000..c8c04ef --- /dev/null +++ b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/cardlock/Card.java @@ -0,0 +1,8 @@ +package de.oaa.xxx.games.chastity.cardlock; + +import de.oaa.xxx.games.chastity.ProcessCardLock; + +public interface Card { + + public CardDTO processCard(ProcessCardLock lock); +} diff --git a/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/cardlock/CardDTO.java b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/cardlock/CardDTO.java new file mode 100644 index 0000000..67fc492 --- /dev/null +++ b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/cardlock/CardDTO.java @@ -0,0 +1,5 @@ +package de.oaa.xxx.games.chastity.cardlock; + +public record CardDTO (String text, String urlImage){ + +} diff --git a/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/cardlock/CardEnum.java b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/cardlock/CardEnum.java new file mode 100644 index 0000000..8dfd8c4 --- /dev/null +++ b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/cardlock/CardEnum.java @@ -0,0 +1,30 @@ +package de.oaa.xxx.games.chastity.cardlock; + +public enum CardEnum { + + ROT { + @Override + public Card get() { + return new RedCard(); + } + }, + GRUEN { + @Override + public Card get() { + return new GreenCard(); + } + }, + GELB { + @Override + public Card get() { + return new YellowCard(); + } + }, + AUFGABE { + @Override + public Card get() { + return new TaskCard(); + } + }; + public abstract Card get(); +} diff --git a/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/cardlock/CardLockEntity.java b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/cardlock/CardLockEntity.java new file mode 100644 index 0000000..4d4a7f6 --- /dev/null +++ b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/cardlock/CardLockEntity.java @@ -0,0 +1,191 @@ +package de.oaa.xxx.games.chastity.cardlock; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.UUID; + +import de.oaa.xxx.games.chastity.tasks.Task; + +public class CardLockEntity { + + private UUID lockId; + private String name; + // Settings + private UUID lockee; + private List initialCards; + private Integer pickEveryMinute; + private boolean accumulatePicks; + private boolean showRemainingCards; + private LocalDateTime latestOpeningtime; + private LocalDateTime frozenUntill; + private Integer hygineOpeningDurationMinutes; + private Integer hygineOpeningEveryMinites; + private List tasks; + private boolean requiresVerification; + + // State + private LocalDateTime startTime; + private LocalDateTime nextCardIn; + private Integer openPicks; + private List availableCards; + private LocalDateTime lastHygineOpening; + private LocalDateTime hygineOpeningtime; // If null, not while hygine opening + private LocalDateTime unlockTime; + private String currentTask; + + private List tasksInQueue; + + + public UUID getLockee() { + return lockee; + } + + public void setLockee(UUID lockee) { + this.lockee = lockee; + } + + public List getInitialCards() { + return initialCards; + } + + public void setInitialCards(List initialCards) { + this.initialCards = initialCards; + } + + public Integer getPickEveryMinute() { + return pickEveryMinute; + } + + public void setPickEveryMinute(Integer pickEveryMinute) { + this.pickEveryMinute = pickEveryMinute; + } + + public boolean isAccumulatePicks() { + return accumulatePicks; + } + + public void setAccumulatePicks(boolean accumulatePicks) { + this.accumulatePicks = accumulatePicks; + } + + public boolean isShowRemainingCards() { + return showRemainingCards; + } + + public void setShowRemainingCards(boolean showRemainingCards) { + this.showRemainingCards = showRemainingCards; + } + + public LocalDateTime getLatestOpeningtime() { + return latestOpeningtime; + } + + public void setLatestOpeningtime(LocalDateTime latestOpeningtime) { + this.latestOpeningtime = latestOpeningtime; + } + + public LocalDateTime getFrozenUntill() { + return frozenUntill; + } + + public void setFrozenUntill(LocalDateTime frozenUntill) { + this.frozenUntill = frozenUntill; + } + + public Integer getHygineOpeningDurationMinutes() { + return hygineOpeningDurationMinutes; + } + + public void setHygineOpeningDurationMinutes(Integer hygineOpeningDurationMinutes) { + this.hygineOpeningDurationMinutes = hygineOpeningDurationMinutes; + } + + public Integer getHygineOpeningEveryMinites() { + return hygineOpeningEveryMinites; + } + + public void setHygineOpeningEveryMinites(Integer hygineOpeningEveryMinites) { + this.hygineOpeningEveryMinites = hygineOpeningEveryMinites; + } + + public LocalDateTime getStartTime() { + return startTime; + } + + public void setStartTime(LocalDateTime startTime) { + this.startTime = startTime; + } + + public LocalDateTime getNextCardIn() { + return nextCardIn; + } + + public void setNextCardIn(LocalDateTime nextCardIn) { + this.nextCardIn = nextCardIn; + } + + public Integer getOpenPicks() { + return openPicks; + } + + public void setOpenPicks(Integer openPicks) { + this.openPicks = openPicks; + } + + public List getAvailableCards() { + return availableCards; + } + + public void setAvailableCards(List availableCards) { + this.availableCards = availableCards; + } + + public LocalDateTime getLastHygineOpening() { + return lastHygineOpening; + } + + public void setLastHygineOpening(LocalDateTime lastHygineOpening) { + this.lastHygineOpening = lastHygineOpening; + } + + public LocalDateTime getHygineOpeningtime() { + return hygineOpeningtime; + } + + public void setHygineOpeningtime(LocalDateTime hygineOpeningtime) { + this.hygineOpeningtime = hygineOpeningtime; + } + + public LocalDateTime getUnlockTime() { + return unlockTime; + } + + public void setUnlockTime(LocalDateTime unlockTime) { + this.unlockTime = unlockTime; + } + + public List getTasks() { + return tasks; + } + + public void setTasks(List tasks) { + this.tasks = tasks; + } + + public String getCurrentTask() { + return currentTask; + } + + public void setCurrentTask(String currentTask) { + this.currentTask = currentTask; + } + + public List getTasksInQueue() { + return tasksInQueue; + } + + public void setTasksInQueue(List tasksInQueue) { + this.tasksInQueue = tasksInQueue; + } + +} diff --git a/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/cardlock/CardlockRepository.java b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/cardlock/CardlockRepository.java new file mode 100644 index 0000000..a4e5626 --- /dev/null +++ b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/cardlock/CardlockRepository.java @@ -0,0 +1,5 @@ +package de.oaa.xxx.games.chastity.cardlock; + +public class CardlockRepository { + +} diff --git a/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/cardlock/DoubleUpCard.java b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/cardlock/DoubleUpCard.java new file mode 100644 index 0000000..0dcfaaf --- /dev/null +++ b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/cardlock/DoubleUpCard.java @@ -0,0 +1,11 @@ +package de.oaa.xxx.games.chastity.cardlock; + +import de.oaa.xxx.games.chastity.ProcessCardLock; + +public class DoubleUpCard implements Card { + + @Override + public CardDTO processCard(ProcessCardLock lock) { + return new CardDTO(lock.doubleUp(), "img/card_red.png"); + } +} diff --git a/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/cardlock/FreezeCard.java b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/cardlock/FreezeCard.java new file mode 100644 index 0000000..16f1189 --- /dev/null +++ b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/cardlock/FreezeCard.java @@ -0,0 +1,12 @@ +package de.oaa.xxx.games.chastity.cardlock; + +import de.oaa.xxx.games.chastity.ProcessCardLock; + +public class FreezeCard implements Card { + + @Override + public CardDTO processCard(ProcessCardLock lock) { + return new CardDTO(lock.freeze(), "img/card_freeze.png"); + } + +} diff --git a/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/cardlock/GreenCard.java b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/cardlock/GreenCard.java new file mode 100644 index 0000000..4d98928 --- /dev/null +++ b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/cardlock/GreenCard.java @@ -0,0 +1,11 @@ +package de.oaa.xxx.games.chastity.cardlock; + +import de.oaa.xxx.games.chastity.ProcessCardLock; + +public class GreenCard implements Card { + + @Override + public CardDTO processCard(ProcessCardLock lock) { + return new CardDTO(lock.unlock(), "img/card_green.png"); + } +} diff --git a/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/cardlock/RedCard.java b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/cardlock/RedCard.java new file mode 100644 index 0000000..7af049f --- /dev/null +++ b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/cardlock/RedCard.java @@ -0,0 +1,12 @@ +package de.oaa.xxx.games.chastity.cardlock; + +import de.oaa.xxx.games.chastity.ProcessCardLock; + +public class RedCard implements Card { + + @Override + public CardDTO processCard(ProcessCardLock lock) { + return new CardDTO(lock.redCard(), "img/card_red.png"); + } + +} diff --git a/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/cardlock/ResetCard.java b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/cardlock/ResetCard.java new file mode 100644 index 0000000..37b33f0 --- /dev/null +++ b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/cardlock/ResetCard.java @@ -0,0 +1,12 @@ +package de.oaa.xxx.games.chastity.cardlock; + +import de.oaa.xxx.games.chastity.ProcessCardLock; + +public class ResetCard implements Card { + + @Override + public CardDTO processCard(ProcessCardLock lock) { + return new CardDTO(lock.reset(), "img/card_reset.png"); + } + +} diff --git a/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/cardlock/TaskCard.java b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/cardlock/TaskCard.java new file mode 100644 index 0000000..b234c90 --- /dev/null +++ b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/cardlock/TaskCard.java @@ -0,0 +1,12 @@ +package de.oaa.xxx.games.chastity.cardlock; + +import de.oaa.xxx.games.chastity.ProcessCardLock; + +public class TaskCard implements Card { + + @Override + public CardDTO processCard(ProcessCardLock lock) { + return new CardDTO(lock.task(), "img/card_task.png"); + } + +} diff --git a/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/cardlock/YellowCard.java b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/cardlock/YellowCard.java new file mode 100644 index 0000000..b26d127 --- /dev/null +++ b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/cardlock/YellowCard.java @@ -0,0 +1,11 @@ +package de.oaa.xxx.games.chastity.cardlock; + +import de.oaa.xxx.games.chastity.ProcessCardLock; + +public class YellowCard implements Card { + + @Override + public CardDTO processCard(ProcessCardLock lock) { + return new CardDTO(lock.yellowCard(), "img/card_yellow.png"); + } +} diff --git a/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/history/LockHistoryController.java b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/history/LockHistoryController.java new file mode 100644 index 0000000..d34fa3e --- /dev/null +++ b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/history/LockHistoryController.java @@ -0,0 +1,35 @@ +package de.oaa.xxx.games.chastity.history; + +import java.security.Principal; +import java.util.List; +import java.util.UUID; + +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +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.user.UserRepository; + +@RestController +@RequestMapping("/lockhistory") +public class LockHistoryController { + + private UserRepository userRepository; + private LockHistoryRepository lockHistoryRepository; + + public LockHistoryController(UserRepository userRepository, LockHistoryRepository lockHistoryRepository) { + this.userRepository = userRepository; + this.lockHistoryRepository = lockHistoryRepository; + } + + @GetMapping + public ResponseEntity> get(@RequestParam UUID userId, Principal principal) { + var meOpt = userRepository.findByEmail(principal.getName()); + if (meOpt.isEmpty()) + return ResponseEntity.status(401).build(); + return ResponseEntity.ok(lockHistoryRepository.findByUserIdOrderByEndTimeDesc(userId).stream() + .map(entity -> entity.toLockHistory()).toList()); + } +} diff --git a/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/history/LockHistoryDTO.java b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/history/LockHistoryDTO.java new file mode 100644 index 0000000..8bbeee6 --- /dev/null +++ b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/history/LockHistoryDTO.java @@ -0,0 +1,11 @@ +package de.oaa.xxx.games.chastity.history; + +import java.time.LocalDateTime; +import java.util.UUID; + +import de.oaa.xxx.games.chastity.LockType; + +public record LockHistoryDTO (UUID historyId, UUID userId, LocalDateTime startTime, LocalDateTime endTime, LockType type, UUID lockedBy) { + +} + diff --git a/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/history/LockHistoryEntity.java b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/history/LockHistoryEntity.java new file mode 100644 index 0000000..7460d3e --- /dev/null +++ b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/history/LockHistoryEntity.java @@ -0,0 +1,81 @@ +package de.oaa.xxx.games.chastity.history; + +import java.time.LocalDateTime; +import java.util.UUID; + +import de.oaa.xxx.games.chastity.LockType; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; + +@Entity +@Table(name = "lock_history") +public class LockHistoryEntity { + + @Id + @Column + private UUID historyId; + @Column(nullable = false) + private UUID userId; + @Column(nullable = false) + private LocalDateTime startTime; + @Column(nullable = false) + private LocalDateTime endTime; + @Column(nullable = false) + private LockType type; + @Column + private UUID lockedBy; + + public UUID getHistoryId() { + return historyId; + } + + public void setHistoryId(UUID historyId) { + this.historyId = historyId; + } + + public UUID getUserId() { + return userId; + } + + public void setUserId(UUID userId) { + this.userId = userId; + } + + public LocalDateTime getStartTime() { + return startTime; + } + + public void setStartTime(LocalDateTime startTime) { + this.startTime = startTime; + } + + public LocalDateTime getEndTime() { + return endTime; + } + + public void setEndTime(LocalDateTime endTime) { + this.endTime = endTime; + } + + public LockType getType() { + return type; + } + + public void setType(LockType type) { + this.type = type; + } + + public UUID getLockedBy() { + return lockedBy; + } + + public void setLockedBy(UUID lockedBy) { + this.lockedBy = lockedBy; + } + + public LockHistoryDTO toLockHistory() { + return new LockHistoryDTO(historyId, userId, startTime, endTime, type, lockedBy); + } +} diff --git a/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/history/LockHistoryRepository.java b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/history/LockHistoryRepository.java new file mode 100644 index 0000000..4b35ab8 --- /dev/null +++ b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/history/LockHistoryRepository.java @@ -0,0 +1,12 @@ +package de.oaa.xxx.games.chastity.history; + +import java.util.List; +import java.util.UUID; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface LockHistoryRepository extends JpaRepository { + + List findByUserIdOrderByEndTimeDesc(UUID userId); + +} diff --git a/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/tasks/Task.java b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/tasks/Task.java new file mode 100644 index 0000000..932d2dc --- /dev/null +++ b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/tasks/Task.java @@ -0,0 +1,30 @@ +package de.oaa.xxx.games.chastity.tasks; + +public class Task { + + private String text; + private Integer minutes; + + public String getText() { + return text; + } + + public void setText(String text) { + this.text = text; + } + + public Integer getMinutes() { + return minutes; + } + + public void setMinutes(Integer minutes) { + this.minutes = minutes; + } + + @Override + public String toString() { + return "Task [text=" + text + ", minutes=" + minutes + "]"; + } + + +} diff --git a/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/verification/VerificationController.java b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/verification/VerificationController.java new file mode 100644 index 0000000..6e6a4ea --- /dev/null +++ b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/verification/VerificationController.java @@ -0,0 +1,134 @@ +package de.oaa.xxx.games.chastity.verification; + +import java.security.Principal; +import java.time.LocalDateTime; +import java.util.Base64; +import java.util.List; +import java.util.Optional; +import java.util.Random; +import java.util.UUID; +import java.util.stream.Collectors; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Sort; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +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.aufgaben.controller.AboController; +import de.oaa.xxx.user.UserRepository; + +@RestController +@RequestMapping("/verification") +@Transactional +public class VerificationController { + + private static final String CHARS = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789"; + + private final VerificationRepository verificationRepository; + private final VerificationVoteRepository verificationVoteRepository; + private final UserRepository userRepository; + + public VerificationController(VerificationRepository verificationRepository, + VerificationVoteRepository verificationVoteRepository, UserRepository userRepository, + AboController aboController) { + this.verificationRepository = verificationRepository; + this.verificationVoteRepository = verificationVoteRepository; + this.userRepository = userRepository; + } + + @GetMapping("/{verificationId}") + public ResponseEntity get(@PathVariable UUID verificationId) { + return verificationRepository.findById(verificationId).map(entity -> ResponseEntity.ok(entity.toVerification())) + .orElse(ResponseEntity.noContent().build()); + } + + @GetMapping("/") + public ResponseEntity> getAll(@RequestParam(value = "page", defaultValue = "1") int page, + @RequestParam(value = "size", defaultValue = "10") int size) { + var paging = PageRequest.of(page, size, Sort.by("verificationTime").descending()); + Page result = verificationRepository.findAllByImageIsNotNull(paging); + return ResponseEntity.ok(result.stream().map(entity -> entity.toVerification()).toList()); + } + + @GetMapping("/new") + public ResponseEntity createVerification() { + VerificationEntity verification = new VerificationEntity(); + verification.setVerficationId(UUID.randomUUID()); + verification.setCode(createCode()); + verification.setVerificationTime(LocalDateTime.now()); + verificationRepository.save(verification); + return ResponseEntity.ok(verification.toVerification()); + } + + @GetMapping("/{verificationId}") + public ResponseEntity getVerification(@PathVariable UUID verificationId) { + Optional optional = verificationRepository.findById(verificationId); + if (optional.isEmpty()) { + return ResponseEntity.noContent().build(); + } + var dto = optional.get().toVerification(); + dto.votes().addAll(verificationVoteRepository.findAllByVerificationId(verificationId).stream() + .map(entity -> entity.toVerificationVote()).collect(Collectors.toList())); + return ResponseEntity.ok(dto); + } + + @PutMapping("/{verificationId}") + public ResponseEntity update(@PathVariable UUID verificationId, @RequestBody VerificationDTO dto, + Principal principal) { + var user = userRepository.findByEmail(principal.getName()).orElse(null); + if (user == null) { + return ResponseEntity.status(401).build(); + } + var entity = verificationRepository.findById(verificationId).orElse(null); + if (entity == null) { + return ResponseEntity.notFound().build(); + } + var codeErstelltAm = entity.getVerificationTime(); + var vorEinerStunde = LocalDateTime.now().minusHours(1); + if (codeErstelltAm.isBefore(vorEinerStunde)) { + return ResponseEntity.status(HttpStatus.GONE).build(); + } + if (dto.image() != null) { + entity.setImage(Base64.getDecoder().decode(dto.image())); + } + verificationRepository.save(entity); + return ResponseEntity.ok().build(); + } + + @PostMapping("/{verificationId}/vote/") + public ResponseEntity addVote(@PathVariable UUID verificationId, @RequestBody VerificationVoteDTO dto, + Principal principal) { + var user = userRepository.findByEmail(principal.getName()).orElse(null); + if (user == null) { + return ResponseEntity.status(401).build(); + } + var verification = verificationRepository.findById(verificationId).orElse(null); + if (verification == null) { + return ResponseEntity.notFound().build(); + } + var vote = new VerificationVoteEntity(); + vote.setVoteId(UUID.randomUUID()); + vote.setUserId(dto.userId()); + vote.setUpvote(dto.upvote()); + verificationVoteRepository.save(vote); + return ResponseEntity.accepted().build(); + } + + private String createCode() { + StringBuilder sb = new StringBuilder(6); + for (int i = 0; i < 6; i++) { + sb.append(CHARS.charAt(new Random().nextInt(CHARS.length()))); + } + return sb.toString(); + } +} diff --git a/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/verification/VerificationDTO.java b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/verification/VerificationDTO.java new file mode 100644 index 0000000..1b9491c --- /dev/null +++ b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/verification/VerificationDTO.java @@ -0,0 +1,7 @@ +package de.oaa.xxx.games.chastity.verification; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.UUID; + +public record VerificationDTO(UUID verficationId, String code, LocalDateTime verificationTime, byte[] image, List votes) {} diff --git a/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/verification/VerificationEntity.java b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/verification/VerificationEntity.java new file mode 100644 index 0000000..30bb92f --- /dev/null +++ b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/verification/VerificationEntity.java @@ -0,0 +1,53 @@ +package de.oaa.xxx.games.chastity.verification; + +import java.time.LocalDateTime; +import java.util.UUID; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; + +@Entity +@Table(name = "verification") +public class VerificationEntity { + + @Id + @Column + private UUID verficationId; + @Column(nullable = false) + private String code; + @Column(nullable = false) + private LocalDateTime verificationTime; + @Column(columnDefinition = "BLOB") + private byte[] image; + + public UUID getVerficationId() { + return verficationId; + } + public void setVerficationId(UUID verficationId) { + this.verficationId = verficationId; + } + public String getCode() { + return code; + } + public void setCode(String code) { + this.code = code; + } + public LocalDateTime getVerificationTime() { + return verificationTime; + } + public void setVerificationTime(LocalDateTime verificationTime) { + this.verificationTime = verificationTime; + } + public byte[] getImage() { + return image; + } + public void setImage(byte[] image) { + this.image = image; + } + public VerificationDTO toVerification() { + return new VerificationDTO(verficationId, code, verificationTime,image, null); + } + +} diff --git a/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/verification/VerificationRepository.java b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/verification/VerificationRepository.java new file mode 100644 index 0000000..7496e1f --- /dev/null +++ b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/verification/VerificationRepository.java @@ -0,0 +1,11 @@ +package de.oaa.xxx.games.chastity.verification; + +import java.util.UUID; + +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface VerificationRepository extends JpaRepository { + + org.springframework.data.domain.Page findAllByImageIsNotNull(Pageable pageable); +} diff --git a/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/verification/VerificationVoteDTO.java b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/verification/VerificationVoteDTO.java new file mode 100644 index 0000000..cd3979a --- /dev/null +++ b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/verification/VerificationVoteDTO.java @@ -0,0 +1,5 @@ +package de.oaa.xxx.games.chastity.verification; + +import java.util.UUID; + +public record VerificationVoteDTO (UUID voteId, UUID userId, boolean upvote) {} diff --git a/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/verification/VerificationVoteEntity.java b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/verification/VerificationVoteEntity.java new file mode 100644 index 0000000..8a9c012 --- /dev/null +++ b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/verification/VerificationVoteEntity.java @@ -0,0 +1,44 @@ +package de.oaa.xxx.games.chastity.verification; + +import java.util.UUID; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; + +@Entity +@Table(name="verification_vote") +public class VerificationVoteEntity { + + @Id + @Column + private UUID voteId; + @Column(nullable = false) + private UUID userId; + @Column(nullable = false) + private boolean upvote; + + public UUID getVoteId() { + return voteId; + } + public void setVoteId(UUID voteId) { + this.voteId = voteId; + } + public UUID getUserId() { + return userId; + } + public void setUserId(UUID userId) { + this.userId = userId; + } + public boolean isUpvote() { + return upvote; + } + public void setUpvote(boolean upvote) { + this.upvote = upvote; + } + + public VerificationVoteDTO toVerificationVote() { + return new VerificationVoteDTO(voteId, userId, upvote); + } +} diff --git a/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/verification/VerificationVoteRepository.java b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/verification/VerificationVoteRepository.java new file mode 100644 index 0000000..a05330f --- /dev/null +++ b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/verification/VerificationVoteRepository.java @@ -0,0 +1,15 @@ +package de.oaa.xxx.games.chastity.verification; + +import java.util.List; +import java.util.UUID; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface VerificationVoteRepository extends JpaRepository { + + List findAllByVerificationId(UUID verificationId); + + void deleteAllByVerificationId(UUID verificationId); +} + + diff --git a/xxxthegame/src/main/java/de/oaa/xxx/session/SessionDurchfuehren.java b/xxxthegame/src/main/java/de/oaa/xxx/session/SessionDurchfuehren.java index 28bdeb6..5704f94 100644 --- a/xxxthegame/src/main/java/de/oaa/xxx/session/SessionDurchfuehren.java +++ b/xxxthegame/src/main/java/de/oaa/xxx/session/SessionDurchfuehren.java @@ -82,16 +82,17 @@ public class SessionDurchfuehren { List.of(GeschlechtEnum.WEIBLICH, GeschlechtEnum.DIVERS, GeschlechtEnum.MAENNLICH).forEach(geschlecht -> { mitspieler.stream().filter(m -> geschlecht == m.getGeschlecht()).toList().forEach(cumming -> { var partner = findeMitspielerMitRolle(RolleEnum.AUFGABE_PASSIV, cumming); - aufgabenList.getFinisher().stream() + var finishers = aufgabenList.getFinisher().stream() .filter(finisher -> geschlecht == finisher.getGeschlecht()) - .findAny() - .ifPresent(aufgabe -> { - AufgabeAnzeige anzeige = new AufgabeAnzeige(); - anzeige.setNameAktiverMitspieler(cumming.getName()); - anzeige.setAufgabeText(getAnzeigeText(aufgabe.getText(), - cumming.getName(), partner != null ? partner.getName() : "")); - list.add(anzeige); - }); + .toList(); + if (!finishers.isEmpty()) { + var aufgabe = finishers.get(new Random().nextInt(list.size())); + AufgabeAnzeige anzeige = new AufgabeAnzeige(); + anzeige.setNameAktiverMitspieler(cumming.getName()); + anzeige.setAufgabeText(getAnzeigeText(aufgabe.getText(), + cumming.getName(), partner != null ? partner.getName() : "")); + list.add(anzeige); + } }); }); return list; diff --git a/xxxthegame/src/main/java/de/oaa/xxx/social/dto/KommentarDto.java b/xxxthegame/src/main/java/de/oaa/xxx/social/dto/KommentarDto.java index 3dbf8c5..ed9e9ea 100644 --- a/xxxthegame/src/main/java/de/oaa/xxx/social/dto/KommentarDto.java +++ b/xxxthegame/src/main/java/de/oaa/xxx/social/dto/KommentarDto.java @@ -1,7 +1,6 @@ package de.oaa.xxx.social.dto; import java.time.LocalDateTime; -import java.util.List; import java.util.UUID; public record KommentarDto( diff --git a/xxxthegame/src/main/resources/static/img/card.png b/xxxthegame/src/main/resources/static/img/card.png new file mode 100644 index 0000000..8bf5d1d Binary files /dev/null and b/xxxthegame/src/main/resources/static/img/card.png differ diff --git a/xxxthegame/src/main/resources/static/img/card_green.png b/xxxthegame/src/main/resources/static/img/card_green.png new file mode 100644 index 0000000..d4f980a Binary files /dev/null and b/xxxthegame/src/main/resources/static/img/card_green.png differ diff --git a/xxxthegame/src/main/resources/static/img/card_old.png b/xxxthegame/src/main/resources/static/img/card_old.png new file mode 100644 index 0000000..b3e1068 Binary files /dev/null and b/xxxthegame/src/main/resources/static/img/card_old.png differ