Neues Spiel Vanilla Game hinzugefügt

This commit is contained in:
2026-03-27 12:06:29 +01:00
parent 0baf667ee7
commit e262a1b46b
96 changed files with 8132 additions and 3584 deletions

View File

@@ -52,7 +52,14 @@
"Bash(head -5 echo \"---\" grep -n \"⬆\\\\|⬇\\\\|sort\\\\|up\\\\|down\" /home/mario/Workspaces/xxx-thegame/xxxthegame/src/main/resources/static/admin.html)",
"Bash(head -8 echo \"---\" grep -n \"⭐\\\\|star\\\\|premium\\\\|abo\" /home/mario/Workspaces/xxx-thegame/xxxthegame/src/main/resources/static/abonnements.html)",
"Bash(head -8 echo \"---\" grep -n \"👁\\\\|view\\\\|sichtbar\\\\|Ansicht\" /home/mario/Workspaces/xxx-thegame/xxxthegame/src/main/resources/static/einladungen.html)",
"Bash(/dev/null echo:*)"
"Bash(/dev/null echo:*)",
"Read(//home/mario/Workspaces/xxx-thegame/**)",
"Bash(done)",
"Bash(mkdir -p /home/mario/Workspaces/xxx-thegame/xxxthegame/src/main/java/de/oaa/xxx/games/common/entity)",
"Bash(mkdir -p /home/mario/Workspaces/xxx-thegame/xxxthegame/src/main/java/de/oaa/xxx/games/common/repository)",
"Bash(mkdir -p /home/mario/Workspaces/xxx-thegame/xxxthegame/src/main/java/de/oaa/xxx/games/common/aufgaben)",
"Bash(mkdir -p /home/mario/Workspaces/xxx-thegame/xxxthegame/src/main/java/de/oaa/xxx/games/vanilla/entity)",
"Bash(mkdir -p /home/mario/Workspaces/xxx-thegame/xxxthegame/src/main/java/de/oaa/xxx/games/vanilla/repository)"
]
}
}

View File

@@ -1,5 +1,5 @@
#Thu Mar 26 16:50:07 CET 2026
#Fri Mar 27 07:46:21 CET 2026
display=\:0
host=mario-mint
process-id=121337
process-id=5726
user=mario

View File

@@ -1103,3 +1103,72 @@ java.lang.NullPointerException: Cannot invoke "org.eclipse.debug.core.ILaunchCon
at org.eclipse.debug.core.DebugPlugin$EventNotifier.dispatch(DebugPlugin.java:1456)
at org.eclipse.debug.core.DebugPlugin$EventDispatchJob.run(DebugPlugin.java:521)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:63)
!ENTRY org.springframework.tooling.boot.ls 1 0 2026-03-26 23:30:06.930
!MESSAGE DelegatingStreamConnectionProvider - Stopping Boot LS
!SESSION 2026-03-27 07:46:14.949 -----------------------------------------------
eclipse.buildId=4.39.0.20260305-0817
java.version=21.0.6
java.vendor=Eclipse Adoptium
BootLoader constants: OS=linux, ARCH=x86_64, WS=gtk, NL=de_DE
Framework arguments: -product org.eclipse.epp.package.java.product
Command-line arguments: -os linux -ws gtk -arch x86_64 -clean -product org.eclipse.epp.package.java.product
!ENTRY ch.qos.logback.classic 1 0 2026-03-27 07:46:16.465
!MESSAGE Activated before the state location was initialized. Retry after the state location is initialized.
!ENTRY ch.qos.logback.classic 1 0 2026-03-27 07:46:21.681
!MESSAGE Logback config file: /home/mario/Workspaces/xxx-thegame/.metadata/.plugins/org.eclipse.m2e.logback/logback.2.7.101.20251017-1242.xml
!ENTRY org.eclipse.ui 2 0 2026-03-27 07:46:21.840
!MESSAGE Warnings while parsing the commands from the 'org.eclipse.ui.commands' and 'org.eclipse.ui.actionDefinitions' extension points.
!SUBENTRY 1 org.eclipse.ui 2 0 2026-03-27 07:46:21.840
!MESSAGE Commands should really have a category: plug-in='org.springframework.tooling.boot.ls', id='spring.initializr.addStarters', categoryId='org.eclipse.lsp4e.commandCategory'
!ENTRY org.eclipse.ui 2 0 2026-03-27 07:46:21.978
!MESSAGE Warnings while parsing the commands from the 'org.eclipse.ui.commands' and 'org.eclipse.ui.actionDefinitions' extension points.
!SUBENTRY 1 org.eclipse.ui 2 0 2026-03-27 07:46:21.978
!MESSAGE Commands should really have a category: plug-in='org.springframework.tooling.boot.ls', id='spring.initializr.addStarters', categoryId='org.eclipse.lsp4e.commandCategory'
!ENTRY org.eclipse.jdt.ui 4 0 2026-03-27 07:55:15.883
!MESSAGE NullPointerException computing hover information in BdsmGameDurchfuehren.java at offset 8641
!STACK 0
java.lang.NullPointerException: Cannot invoke "org.eclipse.jdt.internal.compiler.lookup.TypeBinding.signableName()" because "binding.type" is null
at org.eclipse.jdt.internal.core.SelectionRequestor.acceptLocalVariable(SelectionRequestor.java:422)
at org.eclipse.jdt.internal.codeassist.SelectionEngine.selectFrom(SelectionEngine.java:1353)
at org.eclipse.jdt.internal.codeassist.SelectionEngine.select(SelectionEngine.java:1043)
at org.eclipse.jdt.internal.core.Openable.codeSelect(Openable.java:171)
at org.eclipse.jdt.internal.core.CompilationUnit.codeSelect(CompilationUnit.java:476)
at org.eclipse.jdt.internal.core.CompilationUnit.codeSelect(CompilationUnit.java:466)
at org.eclipse.jdt.internal.ui.text.java.hover.AbstractJavaEditorTextHover.getJavaElementsAt(AbstractJavaEditorTextHover.java:122)
at org.eclipse.jdt.internal.ui.text.java.hover.JavadocHover.lambda$0(JavadocHover.java:708)
at org.eclipse.jdt.internal.core.JavaModelManager.cacheZipFiles(JavaModelManager.java:5709)
at org.eclipse.jdt.internal.core.JavaModelManager.callReadOnly(JavaModelManager.java:5698)
at org.eclipse.jdt.core.JavaCore.callReadOnly(JavaCore.java:6211)
at org.eclipse.jdt.internal.ui.text.java.hover.JavadocHover.internalGetHoverInfo(JavadocHover.java:708)
at org.eclipse.jdt.internal.ui.text.java.hover.JavadocHover.getHoverInfo2(JavadocHover.java:704)
at org.eclipse.lsp4e.jdt.LSJavaHoverProvider.lambda$0(LSJavaHoverProvider.java:64)
at java.base/java.util.concurrent.CompletableFuture$AsyncRun.run(CompletableFuture.java:1804)
at java.base/java.util.concurrent.CompletableFuture$AsyncRun.exec(CompletableFuture.java:1796)
at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:387)
at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1312)
at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1843)
at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1808)
at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:188)
Suppressed: java.lang.Throwable: Source line 178 :
-----
}
return findeSperre();
}
private AufgabeAnzeige findeAufgabe() {
Mitspieler aktiv = findeMitspielerMitRolle(RolleEnum.AUFGABE_AKTIV);
if (aktiv != null) {
Mitspieler passiv = findeMitspielerMitRolle(RolleEnum.AUFGABE_PASSIV, aktiv);
if (passiv != null) {
List<Aufgabe> list = aufgabenList.getAufgaben().stream()
.filter(|aufgabe -> aufgabe.isAufgabePassend(level, aktiv, passiv))
-----
at org.eclipse.jdt.internal.ui.util.SelectionUtil.logException(SelectionUtil.java:157)
at org.eclipse.jdt.internal.ui.text.java.hover.AbstractJavaEditorTextHover.getJavaElementsAt(AbstractJavaEditorTextHover.java:124)
... 14 more

File diff suppressed because one or more lines are too long

View File

@@ -2,16 +2,19 @@
<typeInfoHistroy>
<typeInfo handle="=xxxthegame/src\/main\/java=/gradle_scope=/main=/=/gradle_used_by_scope=/main,test=/&lt;de.oaa.xxx.aufgaben{DefaultFiller.java[DefaultFiller" modifiers="1" timestamp="1772437686926"/>
<typeInfo handle="=xxxthegame/src\/main\/java=/gradle_scope=/main=/=/gradle_used_by_scope=/main,test=/&lt;de.oaa.xxx.aufgaben.controller{FillerController.java[FillerController" modifiers="1" timestamp="1772385528555"/>
<typeInfo handle="=xxxthegame/src\/main\/java=/gradle_scope=/main=/=/gradle_used_by_scope=/main,test=/&lt;de.oaa.xxx.games.chastity.ttlock{TTLockService.java[TTLockService" modifiers="1" timestamp="1774375173709"/>
<typeInfo handle="=xxxthegame/src\/main\/java=/gradle_scope=/main=/=/gradle_used_by_scope=/main,test=/&lt;de.oaa.xxx.user{UserRepository.java[UserRepository" modifiers="513" timestamp="1774016609131"/>
<typeInfo handle="=xxxthegame/src\/main\/java=/gradle_scope=/main=/=/gradle_used_by_scope=/main,test=/&lt;de.oaa.xxx.games.chastity.ttlock{TTLockUserConfigEntity.java[TTLockUserConfigEntity" modifiers="1" timestamp="1774425822887"/>
<typeInfo handle="=xxxthegame/src\/main\/java=/gradle_scope=/main=/=/gradle_used_by_scope=/main,test=/&lt;de.oaa.xxx.games.chastity.keyholder{KeyholderNotificationEntity.java[KeyholderNotificationEntity" modifiers="1" timestamp="1774386563354"/>
<typeInfo handle="=xxxthegame/src\/main\/java=/gradle_scope=/main=/=/gradle_used_by_scope=/main,test=/&lt;de.oaa.xxx.games.chastity.ttlock{TTLockCallback.java[TTLockCallback" modifiers="1" timestamp="1774387007874"/>
<typeInfo handle="=xxxthegame/src\/main\/java=/gradle_scope=/main=/=/gradle_used_by_scope=/main,test=/&lt;de.oaa.xxx.games.chastity.cardlock{CardLockController.java[CardLockController" modifiers="1" timestamp="1774508936868"/>
<typeInfo handle="=xxxthegame/src\/main\/java=/gradle_scope=/main=/=/gradle_used_by_scope=/main,test=/&lt;de.oaa.xxx.games.chastity.cardlock{CardLockEntity.java[CardLockEntity" modifiers="1" timestamp="1774171624571"/>
<typeInfo handle="=xxxthegame/src\/main\/java=/gradle_scope=/main=/=/gradle_used_by_scope=/main,test=/&lt;de.oaa.xxx.games.chastity.timelock{TimeLockController.java[TimeLockController" modifiers="1" timestamp="1774511010754"/>
<typeInfo handle="=xxxthegame/src\/main\/java=/gradle_scope=/main=/=/gradle_used_by_scope=/main,test=/&lt;de.oaa.xxx.user{UserController.java[UserController" modifiers="1" timestamp="1774425860838"/>
<typeInfo handle="=xxxthegame/src\/main\/java=/gradle_scope=/main=/=/gradle_used_by_scope=/main,test=/&lt;de.oaa.xxx.user{UserController.java[UserController" modifiers="1" timestamp="1774551025161"/>
<typeInfo handle="=xxxthegame/src\/main\/java=/gradle_scope=/main=/=/gradle_used_by_scope=/main,test=/&lt;de.oaa.xxx.games.chastity.ttlock{TTLockService.java[TTLockService" modifiers="1" timestamp="1774375173709"/>
<typeInfo handle="=xxxthegame/src\/main\/java=/gradle_scope=/main=/=/gradle_used_by_scope=/main,test=/&lt;de.oaa.xxx.games.chastity.timelock{TimeLockController.java[TimeLockController" modifiers="1" timestamp="1774558039992"/>
<typeInfo handle="=xxxthegame/src\/main\/java=/gradle_scope=/main=/=/gradle_used_by_scope=/main,test=/&lt;de.oaa.xxx.games.chastity.common{BaseLockService.java[BaseLockService" modifiers="1025" timestamp="1774551269600"/>
<typeInfo handle="=xxxthegame/src\/main\/java=/gradle_scope=/main=/=/gradle_used_by_scope=/main,test=/&lt;de.oaa.xxx.games.chastity.ttlock{TTLockCallback.java[TTLockCallback" modifiers="1" timestamp="1774387007874"/>
<typeInfo handle="=xxxthegame/src\/main\/java=/gradle_scope=/main=/=/gradle_used_by_scope=/main,test=/&lt;de.oaa.xxx.games.chastity.lockcontroll{TTLockControl.java[TTLockControl" modifiers="1" timestamp="1774383035013"/>
<typeInfo handle="=xxxthegame/src\/main\/java=/gradle_scope=/main=/=/gradle_used_by_scope=/main,test=/&lt;de.oaa.xxx.games.chastity.cardlock{CardLockController.java[CardLockController" modifiers="1" timestamp="1774550581083"/>
<typeInfo handle="=xxxthegame/src\/main\/java=/gradle_scope=/main=/=/gradle_used_by_scope=/main,test=/&lt;de.oaa.xxx.games.chastity.common{BaseLockEntity.java[BaseLockEntity" modifiers="1" timestamp="1774476260239"/>
<typeInfo handle="=xxxthegame/src\/main\/java=/gradle_scope=/main=/=/gradle_used_by_scope=/main,test=/&lt;de.oaa.xxx.games.chastity.timelock{TimeLockService.java[TimeLockService" modifiers="1" timestamp="1774510681823"/>
<typeInfo handle="=xxxthegame/src\/main\/java=/gradle_scope=/main=/=/gradle_used_by_scope=/main,test=/&lt;de.oaa.xxx.games.chastity.common{BaseLockService.java[BaseLockService" modifiers="1025" timestamp="1774508825104"/>
<typeInfo handle="=xxxthegame/src\/main\/java=/gradle_scope=/main=/=/gradle_used_by_scope=/main,test=/&lt;de.oaa.xxx.games.chastity.cardlock{CardLockService.java[CardLockService" modifiers="1" timestamp="1774551407143"/>
<typeInfo handle="=xxxthegame/src\/main\/java=/gradle_scope=/main=/=/gradle_used_by_scope=/main,test=/&lt;de.oaa.xxx.games.chastity.timelock{TimeLockService.java[TimeLockService" modifiers="1" timestamp="1774551447849"/>
<typeInfo handle="=xxxthegame/src\/main\/java=/gradle_scope=/main=/=/gradle_used_by_scope=/main,test=/&lt;de.oaa.xxx.aufgaben.controller{AboController.java[AboController" modifiers="1" timestamp="1773400404000"/>
</typeInfoHistroy>

View File

@@ -29,4 +29,7 @@
<fullyQualifiedTypeName name="de.oaa.xxx.games.chastity.ttlock.TTLockUserConfigRepository"/>
<fullyQualifiedTypeName name="de.oaa.xxx.games.chastity.ttlock.TTLockCallback"/>
<fullyQualifiedTypeName name="de.oaa.xxx.games.chastity.cardlock.CardLockService"/>
<fullyQualifiedTypeName name="de.oaa.xxx.games.chastity.cardlock.CumCard"/>
<fullyQualifiedTypeName name="de.oaa.xxx.games.chastity.cardlock.CumInCageCard"/>
<fullyQualifiedTypeName name="de.oaa.xxx.games.chastity.unlock.TempOpeningReason"/>
</qualifiedTypeNameHistroy>

View File

@@ -13,3 +13,4 @@
2026-03-26 10:32:24,614 [Worker-1: Loading available Gradle versions] INFO o.e.b.c.i.u.g.PublishedGradleVersions - Gradle version information cache is up-to-date. Trying to read.
2026-03-26 11:31:40,355 [Worker-8: Loading available Gradle versions] INFO o.e.b.c.i.u.g.PublishedGradleVersions - Gradle version information cache is up-to-date. Trying to read.
2026-03-26 16:50:11,098 [Worker-7: Loading available Gradle versions] INFO o.e.b.c.i.u.g.PublishedGradleVersions - Gradle version information cache is up-to-date. Trying to read.
2026-03-27 07:46:24,300 [Worker-7: Loading available Gradle versions] INFO o.e.b.c.i.u.g.PublishedGradleVersions - Gradle version information cache is up-to-date. Trying to read.

View File

@@ -1,3 +1,3 @@
#Thu Mar 26 16:50:07 CET 2026
#Fri Mar 27 07:46:21 CET 2026
org.eclipse.core.runtime=2
org.eclipse.platform=4.39.0.v20260226-0420

View File

@@ -20,21 +20,22 @@ 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.AufgabenGruppe;
import de.oaa.xxx.aufgaben.Toy;
import de.oaa.xxx.aufgaben.entity.AufgabenGruppeEntity;
import de.oaa.xxx.aufgaben.entity.ToyEntity;
import de.oaa.xxx.aufgaben.repository.AufgabeRepository;
import de.oaa.xxx.aufgaben.repository.AufgabenGruppeRepository;
import de.oaa.xxx.aufgaben.repository.FinisherRepository;
import de.oaa.xxx.aufgaben.repository.GruppenAboRepository;
import de.oaa.xxx.aufgaben.repository.SperreRepository;
import de.oaa.xxx.aufgaben.repository.StrafeRepository;
import de.oaa.xxx.aufgaben.repository.ToyRepository;
import de.oaa.xxx.feedback.FeedbackEntity;
import de.oaa.xxx.feedback.FeedbackRepository;
import de.oaa.xxx.feedback.FeedbackStatus;
import de.oaa.xxx.support.SupportUserService;
import de.oaa.xxx.games.common.aufgaben.AufgabenGruppe;
import de.oaa.xxx.games.common.aufgaben.AufgabenGruppeDisplay;
import de.oaa.xxx.games.common.aufgaben.Toy;
import de.oaa.xxx.games.common.entity.AufgabenGruppeEntity;
import de.oaa.xxx.games.common.entity.ToyEntity;
import de.oaa.xxx.games.common.repository.AufgabeRepository;
import de.oaa.xxx.games.common.repository.AufgabenGruppeRepository;
import de.oaa.xxx.games.common.repository.FinisherRepository;
import de.oaa.xxx.games.common.repository.GruppenAboRepository;
import de.oaa.xxx.games.common.repository.SperreRepository;
import de.oaa.xxx.games.common.repository.StrafeRepository;
import de.oaa.xxx.games.common.repository.ToyRepository;
import de.oaa.xxx.games.chastity.ttlock.TTLockConfigEntity;
import de.oaa.xxx.games.chastity.ttlock.TTLockConfigRepository;
import de.oaa.xxx.meldung.MeldungEntity;
@@ -197,7 +198,7 @@ public class AdminController {
// ── Aufgabengruppen ──────────────────────────────────────────────────────
@GetMapping("/aufgabengruppen")
public ResponseEntity<List<de.oaa.xxx.aufgaben.AufgabenGruppe>> getAufgabengruppen(Principal principal) {
public ResponseEntity<List<AufgabenGruppe>> getAufgabengruppen(Principal principal) {
requireAdmin(principal);
List<AufgabenGruppeEntity> list = aufgabenGruppeRepository
.findByUserIdIsNull(PageRequest.of(0, 1000)).getContent();
@@ -205,7 +206,7 @@ public class AdminController {
}
@PostMapping("/aufgabengruppen")
public ResponseEntity<de.oaa.xxx.aufgaben.AufgabenGruppeDisplay> createAufgabengruppe(
public ResponseEntity<AufgabenGruppeDisplay> createAufgabengruppe(
@RequestBody AufgabenGruppe gruppe, Principal principal) {
requireAdmin(principal);
gruppe.setUserId(null);

View File

@@ -1,23 +0,0 @@
package de.oaa.xxx.aufgaben;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
import java.util.UUID;
@Getter
@Setter
public class Aufgabe {
private UUID aufgabeId;
private String kurzText;
private String text;
private Integer level;
private Integer sekundenVon;
private Integer sekundenBis;
private UUID gruppeId;
private List<Werkzeug> benoetigtAktiv;
private List<Werkzeug> benoetigtPassiv;
private List<Toy> benoetigteToys;
}

View File

@@ -1,27 +0,0 @@
package de.oaa.xxx.aufgaben;
import de.oaa.xxx.games.bdsm.GeschlechtEnum;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
import java.util.UUID;
@Getter
@Setter
public class Finisher {
private UUID finisherId;
private String kurzText;
private String text;
private GeschlechtEnum geschlecht;
private List<Werkzeug> benoetigtAktiv;
private List<Werkzeug> benoetigtPassiv;
private List<Toy> benoetigteToys;
private UUID gruppeId;
@Override
public String toString() {
return "Finisher[id=" + finisherId + ", kurzText=" + kurzText + ", geschlecht=" + geschlecht + ", gruppeId=" + gruppeId + "]";
}
}

View File

@@ -1,22 +0,0 @@
package de.oaa.xxx.aufgaben;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
import java.util.UUID;
@Getter
@Setter
public class Sperre {
private UUID sperreId;
private String kurzText;
private String text;
private String releaseText;
private UUID gruppeId;
private List<Werkzeug> sperreFuer;
private Integer minutenVon;
private Integer minutenBis;
private List<Toy> benoetigteToys;
}

View File

@@ -1,23 +0,0 @@
package de.oaa.xxx.aufgaben;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
import java.util.UUID;
@Getter
@Setter
public class Strafe {
private UUID strafeId;
private Integer level;
private String text;
private String kurzText;
private Integer sekundenVon;
private Integer sekundenBis;
private UUID gruppeId;
private List<Werkzeug> benoetigtAktiv;
private List<Werkzeug> benoetigtPassiv;
private List<Toy> benoetigteToys;
}

View File

@@ -1,117 +0,0 @@
package de.oaa.xxx.aufgaben.controller;
import de.oaa.xxx.aufgaben.Sperre;
import de.oaa.xxx.aufgaben.Toy;
import de.oaa.xxx.aufgaben.entity.AufgabenGruppeEntity;
import de.oaa.xxx.aufgaben.entity.SperreEntity;
import de.oaa.xxx.aufgaben.entity.ToyEntity;
import de.oaa.xxx.aufgaben.repository.AufgabenGruppeRepository;
import de.oaa.xxx.aufgaben.repository.SperreRepository;
import de.oaa.xxx.aufgaben.repository.ToyRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.DeleteMapping;
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.RestController;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
@RestController("aufgabenSperreController")
@RequestMapping("/sperre")
@Transactional
public class SperreController {
private static final Logger LOGGER = LoggerFactory.getLogger(SperreController.class);
private final SperreRepository sperreRepository;
private final AufgabenGruppeRepository gruppeRepository;
private final ToyRepository toyRepository;
public SperreController(SperreRepository sperreRepository,
AufgabenGruppeRepository gruppeRepository,
ToyRepository toyRepository) {
this.sperreRepository = sperreRepository;
this.gruppeRepository = gruppeRepository;
this.toyRepository = toyRepository;
}
@GetMapping("/{sperreId}")
public ResponseEntity<Sperre> get(@PathVariable UUID sperreId) {
return sperreRepository.findById(sperreId)
.map(entity -> ResponseEntity.ok(entity.toSperre()))
.orElse(ResponseEntity.noContent().build());
}
@PostMapping
public ResponseEntity<Void> create(@RequestBody Sperre sperre) {
if (sperre.getKurzText() == null || sperre.getText() == null || sperre.getMinutenVon() == null
|| sperre.getGruppeId() == null || sperre.getSperreFuer() == null || sperre.getSperreFuer().isEmpty()) {
return ResponseEntity.badRequest().build();
}
AufgabenGruppeEntity gruppeEntity = gruppeRepository.findById(sperre.getGruppeId()).orElse(null);
if (gruppeEntity == null) {
return ResponseEntity.badRequest().build();
}
if (gruppeEntity.getSperren().size() >= 100) {
return ResponseEntity.status(409).build();
}
List<ToyEntity> toys = resolveToys(sperre.getBenoetigteToys());
SperreEntity entity = SperreEntity.create(sperre, gruppeEntity, toys);
sperreRepository.save(entity);
LOGGER.debug("Sperre {} '{}' in Gruppe {} erstellt", entity.getSperreId(), entity.getKurzText(), sperre.getGruppeId());
return ResponseEntity.created(
ServletUriComponentsBuilder.fromCurrentRequest().path("/{id}").buildAndExpand(entity.getSperreId()).toUri()
).build();
}
@PutMapping("/{sperreId}")
public ResponseEntity<Void> update(@PathVariable UUID sperreId, @RequestBody Sperre sperre) {
if (sperre.getKurzText() == null || sperre.getText() == null || sperre.getMinutenVon() == null
|| sperre.getSperreFuer() == null || sperre.getSperreFuer().isEmpty()) {
return ResponseEntity.badRequest().build();
}
SperreEntity entity = sperreRepository.findById(sperreId).orElse(null);
if (entity == null) return ResponseEntity.notFound().build();
entity.setKurzText(sperre.getKurzText());
entity.setText(sperre.getText());
entity.setReleaseText(sperre.getReleaseText());
entity.setMinutenVon(sperre.getMinutenVon());
entity.setMinutenBis(sperre.getMinutenBis());
entity.setSperreFuer(sperre.getSperreFuer());
entity.setBenoetigteToys(resolveToys(sperre.getBenoetigteToys()));
sperreRepository.save(entity);
LOGGER.debug("Sperre {} aktualisiert", sperreId);
return ResponseEntity.ok().build();
}
@DeleteMapping
public ResponseEntity<Void> delete(@RequestBody Sperre sperre) {
try {
sperreRepository.findById(sperre.getSperreId()).ifPresent(sperreRepository::delete);
return ResponseEntity.accepted().build();
} catch (Exception exception) {
LOGGER.error(exception.getMessage(), exception);
return ResponseEntity.internalServerError().build();
}
}
private List<ToyEntity> resolveToys(List<Toy> toys) {
if (toys == null || toys.isEmpty()) return new ArrayList<>();
List<UUID> ids = toys.stream()
.filter(t -> t.getToyId() != null)
.map(Toy::getToyId)
.toList();
if (ids.isEmpty()) return new ArrayList<>();
return toyRepository.findAllById(ids);
}
}

View File

@@ -1,12 +1,13 @@
package de.oaa.xxx.games.bdsm;
import lombok.Getter;
import lombok.Setter;
import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;
import de.oaa.xxx.games.common.aufgaben.Werkzeug;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class AktiveSperre {

View File

@@ -8,10 +8,10 @@ import java.util.stream.Collectors;
import com.fasterxml.jackson.databind.ObjectMapper;
import de.oaa.xxx.games.bdsm.aufgaben.Aufgabe;
import de.oaa.xxx.games.bdsm.aufgaben.AufgabenList;
import de.oaa.xxx.games.bdsm.aufgaben.Sperre;
import de.oaa.xxx.games.bdsm.aufgaben.Strafe;
import de.oaa.xxx.games.common.aufgaben.Aufgabe;
import de.oaa.xxx.games.common.aufgaben.AufgabenList;
import de.oaa.xxx.games.common.aufgaben.Sperre;
import de.oaa.xxx.games.common.aufgaben.Strafe;
import de.oaa.xxx.games.bdsm.entity.BdsmGameEntity;
import de.oaa.xxx.games.bdsm.sperre.SperreCallback;
import de.oaa.xxx.games.bdsm.sperre.SperrenVerlaengernCallback;

View File

@@ -1,11 +1,12 @@
package de.oaa.xxx.games.bdsm;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
import java.util.UUID;
import de.oaa.xxx.games.common.aufgaben.Werkzeug;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class Mitspieler {

View File

@@ -1,26 +0,0 @@
package de.oaa.xxx.games.bdsm;
public enum Werkzeug {
MUND("Mund", "Ob die Person gewillt ist den Mund einzusetzen."),
VAGINA("Vagina", "Ob die Person über eine Vagina verfügt und gewillt ist diese einzusetzen."),
PENIS("Penis", "Ob die Person über einen Penis verfügt und gewillt ist diesen einzusetzen."),
ANUS("Anus", "Ob die Person gewillt ist den Anus einzusetzen."),
UMSCHNALLDILDO("Umschnall-Dildo", "Ob die Person über einen Umschnall-Dildo verfügt und gewillt ist diesen einzusetzen.");
private final String anzeige;
private final String beschreibung;
Werkzeug(String anzeige, String beschreibung) {
this.anzeige = anzeige;
this.beschreibung = beschreibung;
}
public String beschreibungsText() {
return beschreibung;
}
public String anzeigeText() {
return anzeige;
}
}

View File

@@ -1,11 +1,11 @@
package de.oaa.xxx.aufgaben.controller;
package de.oaa.xxx.games.bdsm.controller;
import de.oaa.xxx.aufgaben.AufgabenGruppe;
import de.oaa.xxx.aufgaben.AufgabenGruppePage;
import de.oaa.xxx.aufgaben.entity.AufgabenGruppeEntity;
import de.oaa.xxx.aufgaben.entity.GruppenAboEntity;
import de.oaa.xxx.aufgaben.repository.AufgabenGruppeRepository;
import de.oaa.xxx.aufgaben.repository.GruppenAboRepository;
import de.oaa.xxx.games.common.aufgaben.AufgabenGruppe;
import de.oaa.xxx.games.common.aufgaben.AufgabenGruppePage;
import de.oaa.xxx.games.common.entity.AufgabenGruppeEntity;
import de.oaa.xxx.games.common.entity.GruppenAboEntity;
import de.oaa.xxx.games.common.repository.AufgabenGruppeRepository;
import de.oaa.xxx.games.common.repository.GruppenAboRepository;
import de.oaa.xxx.user.UserEntity;
import de.oaa.xxx.user.UserRepository;
import org.springframework.http.ResponseEntity;

View File

@@ -1,13 +1,13 @@
package de.oaa.xxx.aufgaben.controller;
package de.oaa.xxx.games.bdsm.controller;
import de.oaa.xxx.aufgaben.Aufgabe;
import de.oaa.xxx.aufgaben.Toy;
import de.oaa.xxx.aufgaben.entity.AufgabeEntity;
import de.oaa.xxx.aufgaben.entity.AufgabenGruppeEntity;
import de.oaa.xxx.aufgaben.entity.ToyEntity;
import de.oaa.xxx.aufgaben.repository.AufgabeRepository;
import de.oaa.xxx.aufgaben.repository.AufgabenGruppeRepository;
import de.oaa.xxx.aufgaben.repository.ToyRepository;
import de.oaa.xxx.games.common.aufgaben.Aufgabe;
import de.oaa.xxx.games.common.aufgaben.Toy;
import de.oaa.xxx.games.common.entity.AufgabeEntity;
import de.oaa.xxx.games.common.entity.AufgabenGruppeEntity;
import de.oaa.xxx.games.common.entity.ToyEntity;
import de.oaa.xxx.games.common.repository.AufgabeRepository;
import de.oaa.xxx.games.common.repository.AufgabenGruppeRepository;
import de.oaa.xxx.games.common.repository.ToyRepository;
import de.oaa.xxx.subscription.SubscriptionLimitService;
import de.oaa.xxx.user.UserRepository;
import org.slf4j.Logger;

View File

@@ -1,4 +1,4 @@
package de.oaa.xxx.aufgaben.controller;
package de.oaa.xxx.games.bdsm.controller;
import java.security.Principal;
import java.util.Base64;
@@ -23,17 +23,17 @@ import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
import de.oaa.xxx.aufgaben.AufgabenGruppe;
import de.oaa.xxx.aufgaben.AufgabenGruppeList;
import de.oaa.xxx.aufgaben.AufgabenGruppePage;
import de.oaa.xxx.aufgaben.AufgabenGruppeService;
import de.oaa.xxx.aufgaben.entity.AufgabenGruppeEntity;
import de.oaa.xxx.aufgaben.repository.AufgabeRepository;
import de.oaa.xxx.aufgaben.repository.AufgabenGruppeRepository;
import de.oaa.xxx.aufgaben.repository.FinisherRepository;
import de.oaa.xxx.aufgaben.repository.GruppenAboRepository;
import de.oaa.xxx.aufgaben.repository.SperreRepository;
import de.oaa.xxx.aufgaben.repository.StrafeRepository;
import de.oaa.xxx.games.common.aufgaben.AufgabenGruppe;
import de.oaa.xxx.games.common.aufgaben.AufgabenGruppeList;
import de.oaa.xxx.games.common.aufgaben.AufgabenGruppePage;
import de.oaa.xxx.games.common.aufgaben.AufgabenGruppeService;
import de.oaa.xxx.games.common.entity.AufgabenGruppeEntity;
import de.oaa.xxx.games.common.repository.AufgabeRepository;
import de.oaa.xxx.games.common.repository.AufgabenGruppeRepository;
import de.oaa.xxx.games.common.repository.FinisherRepository;
import de.oaa.xxx.games.common.repository.GruppenAboRepository;
import de.oaa.xxx.games.common.repository.SperreRepository;
import de.oaa.xxx.games.common.repository.StrafeRepository;
import de.oaa.xxx.subscription.SubscriptionLimitService;
import de.oaa.xxx.user.UserEntity;
import de.oaa.xxx.user.UserRepository;

View File

@@ -37,8 +37,8 @@ import de.oaa.xxx.games.bdsm.BdsmGameDurchfuehren;
import de.oaa.xxx.games.bdsm.BdsmGameService;
import de.oaa.xxx.games.bdsm.GeschlechtEnum;
import de.oaa.xxx.games.bdsm.Mitspieler;
import de.oaa.xxx.games.bdsm.Werkzeug;
import de.oaa.xxx.games.bdsm.aufgaben.AufgabenList;
import de.oaa.xxx.games.common.aufgaben.AufgabenList;
import de.oaa.xxx.games.common.aufgaben.Werkzeug;
import de.oaa.xxx.games.bdsm.entity.AktiveSperreEntity;
import de.oaa.xxx.games.bdsm.entity.BdsmEinladungEntity;
import de.oaa.xxx.games.bdsm.entity.BdsmGameEntity;

View File

@@ -1,9 +1,10 @@
package de.oaa.xxx.aufgaben.controller;
package de.oaa.xxx.games.bdsm.controller;
import de.oaa.xxx.games.common.aufgaben.Favorit;
import de.oaa.xxx.games.common.aufgaben.FavoritList;
import de.oaa.xxx.games.common.entity.FavoritEntity;
import de.oaa.xxx.games.common.repository.FavoritRepository;
import de.oaa.xxx.aufgaben.Favorit;
import de.oaa.xxx.aufgaben.FavoritList;
import de.oaa.xxx.aufgaben.entity.FavoritEntity;
import de.oaa.xxx.aufgaben.repository.FavoritRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;

View File

@@ -1,6 +1,5 @@
package de.oaa.xxx.aufgaben.controller;
package de.oaa.xxx.games.bdsm.controller;
import de.oaa.xxx.aufgaben.DefaultFiller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;
@@ -8,6 +7,8 @@ import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import de.oaa.xxx.games.common.aufgaben.DefaultFiller;
@RestController
@RequestMapping("/filler")
public class FillerController {

View File

@@ -1,13 +1,14 @@
package de.oaa.xxx.aufgaben.controller;
package de.oaa.xxx.games.bdsm.controller;
import de.oaa.xxx.games.common.aufgaben.Finisher;
import de.oaa.xxx.games.common.aufgaben.Toy;
import de.oaa.xxx.games.common.entity.AufgabenGruppeEntity;
import de.oaa.xxx.games.common.entity.FinisherEntity;
import de.oaa.xxx.games.common.entity.ToyEntity;
import de.oaa.xxx.games.common.repository.AufgabenGruppeRepository;
import de.oaa.xxx.games.common.repository.FinisherRepository;
import de.oaa.xxx.games.common.repository.ToyRepository;
import de.oaa.xxx.aufgaben.Finisher;
import de.oaa.xxx.aufgaben.Toy;
import de.oaa.xxx.aufgaben.entity.AufgabenGruppeEntity;
import de.oaa.xxx.aufgaben.entity.FinisherEntity;
import de.oaa.xxx.aufgaben.entity.ToyEntity;
import de.oaa.xxx.aufgaben.repository.AufgabenGruppeRepository;
import de.oaa.xxx.aufgaben.repository.FinisherRepository;
import de.oaa.xxx.aufgaben.repository.ToyRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;

View File

@@ -1,112 +1,118 @@
package de.oaa.xxx.games.bdsm.controller;
import de.oaa.xxx.games.bdsm.AktiveSperre;
import de.oaa.xxx.games.bdsm.Mitspieler;
import de.oaa.xxx.games.bdsm.entity.AktiveSperreEntity;
import de.oaa.xxx.games.bdsm.entity.BdsmGameEntity;
import de.oaa.xxx.games.bdsm.repository.AktiveSperreRepository;
import de.oaa.xxx.games.bdsm.repository.MitspielerRepository;
import de.oaa.xxx.games.bdsm.repository.BdsmGameRepository;
import de.oaa.xxx.games.bdsm.sperre.SperreCallback;
import de.oaa.xxx.games.bdsm.sperre.SperreVerarbeiten;
import de.oaa.xxx.games.bdsm.sperre.SperrenVerlaengernCallback;
import de.oaa.xxx.games.common.aufgaben.Sperre;
import de.oaa.xxx.games.common.aufgaben.Toy;
import de.oaa.xxx.games.common.entity.AufgabenGruppeEntity;
import de.oaa.xxx.games.common.entity.SperreEntity;
import de.oaa.xxx.games.common.entity.ToyEntity;
import de.oaa.xxx.games.common.repository.AufgabenGruppeRepository;
import de.oaa.xxx.games.common.repository.SperreRepository;
import de.oaa.xxx.games.common.repository.ToyRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.DeleteMapping;
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 org.springframework.web.servlet.support.ServletUriComponentsBuilder;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
@RestController("bdsmSperreController")
@RequestMapping("/bdsm/sperre")
@RestController("aufgabenSperreController")
@RequestMapping("/sperre")
@Transactional
public class SperreController {
private static final Logger LOGGER = LoggerFactory.getLogger(SperreController.class);
private final BdsmGameRepository sessionRepository;
private final MitspielerRepository mitspielerRepository;
private final AktiveSperreRepository aktiveSperreRepository;
private final SperreRepository sperreRepository;
private final AufgabenGruppeRepository gruppeRepository;
private final ToyRepository toyRepository;
public SperreController(BdsmGameRepository sessionRepository, MitspielerRepository mitspielerRepository,
AktiveSperreRepository aktiveSperreRepository) {
this.sessionRepository = sessionRepository;
this.mitspielerRepository = mitspielerRepository;
this.aktiveSperreRepository = aktiveSperreRepository;
public SperreController(SperreRepository sperreRepository,
AufgabenGruppeRepository gruppeRepository,
ToyRepository toyRepository) {
this.sperreRepository = sperreRepository;
this.gruppeRepository = gruppeRepository;
this.toyRepository = toyRepository;
}
@GetMapping("/{sperreId}")
public ResponseEntity<Sperre> get(@PathVariable UUID sperreId) {
return sperreRepository.findById(sperreId)
.map(entity -> ResponseEntity.ok(entity.toSperre()))
.orElse(ResponseEntity.noContent().build());
}
@PostMapping
public ResponseEntity<Void> sperren(@RequestBody SperreCallback callback) {
try {
new SperreVerarbeiten().sperreAnwenden(callback, sessionRepository, mitspielerRepository, aktiveSperreRepository);
LOGGER.info("Sperre angewandt für Session {}", callback.getSessionId());
return ResponseEntity.status(201).build();
} catch (Exception exception) {
LOGGER.error(exception.getMessage(), exception);
return ResponseEntity.internalServerError().build();
}
}
@GetMapping("/abgelaufene")
public ResponseEntity<String> getAbgelaufeneSperren(@RequestParam UUID sessionId) {
try {
List<AktiveSperreEntity> abgelaufene = aktiveSperreRepository.findAbgelaufene(sessionId, LocalDateTime.now());
StringBuilder builder = new StringBuilder();
SperreVerarbeiten verarbeiten = new SperreVerarbeiten();
if (!abgelaufene.isEmpty()) {
for (AktiveSperreEntity abgelaufen : abgelaufene) {
builder.append(verarbeiten.sperreAufheben(abgelaufen, aktiveSperreRepository, mitspielerRepository));
builder.append(";");
}
}
return ResponseEntity.ok(builder.toString());
} catch (Exception exception) {
LOGGER.error(exception.getMessage(), exception);
return ResponseEntity.internalServerError().build();
}
}
@GetMapping("/aktive")
public ResponseEntity<List<AktiveSperre>> getAktiveSperren(@RequestParam UUID sessionId) {
try {
BdsmGameEntity session = sessionRepository.findById(sessionId).orElse(null);
if (session == null) return ResponseEntity.noContent().build();
List<Mitspieler> mitspielerList = session.getMitspieler().stream()
.map(m -> m.toMitspieler())
.collect(Collectors.toList());
List<AktiveSperre> sperren = session.getAktiveSperren().stream()
.map(e -> e.toSperre(mitspielerList))
.collect(Collectors.toList());
return ResponseEntity.ok(sperren);
} catch (Exception exception) {
LOGGER.error(exception.getMessage(), exception);
return ResponseEntity.internalServerError().build();
}
}
@PostMapping("/verlaengern")
public ResponseEntity<Void> aktiveVerlaengern(@RequestBody SperrenVerlaengernCallback callback) {
if (callback == null || callback.getSpielerId() == null || callback.getFaktor() == null) {
public ResponseEntity<Void> create(@RequestBody Sperre sperre) {
if (sperre.getKurzText() == null || sperre.getText() == null || sperre.getMinutenVon() == null
|| sperre.getGruppeId() == null || sperre.getSperreFuer() == null || sperre.getSperreFuer().isEmpty()) {
return ResponseEntity.badRequest().build();
}
AufgabenGruppeEntity gruppeEntity = gruppeRepository.findById(sperre.getGruppeId()).orElse(null);
if (gruppeEntity == null) {
return ResponseEntity.badRequest().build();
}
if (gruppeEntity.getSperren().size() >= 100) {
return ResponseEntity.status(409).build();
}
List<ToyEntity> toys = resolveToys(sperre.getBenoetigteToys());
SperreEntity entity = SperreEntity.create(sperre, gruppeEntity, toys);
sperreRepository.save(entity);
LOGGER.debug("Sperre {} '{}' in Gruppe {} erstellt", entity.getSperreId(), entity.getKurzText(), sperre.getGruppeId());
return ResponseEntity.created(
ServletUriComponentsBuilder.fromCurrentRequest().path("/{id}").buildAndExpand(entity.getSperreId()).toUri()
).build();
}
@PutMapping("/{sperreId}")
public ResponseEntity<Void> update(@PathVariable UUID sperreId, @RequestBody Sperre sperre) {
if (sperre.getKurzText() == null || sperre.getText() == null || sperre.getMinutenVon() == null
|| sperre.getSperreFuer() == null || sperre.getSperreFuer().isEmpty()) {
return ResponseEntity.badRequest().build();
}
SperreEntity entity = sperreRepository.findById(sperreId).orElse(null);
if (entity == null) return ResponseEntity.notFound().build();
entity.setKurzText(sperre.getKurzText());
entity.setText(sperre.getText());
entity.setReleaseText(sperre.getReleaseText());
entity.setMinutenVon(sperre.getMinutenVon());
entity.setMinutenBis(sperre.getMinutenBis());
entity.setSperreFuer(sperre.getSperreFuer());
entity.setBenoetigteToys(resolveToys(sperre.getBenoetigteToys()));
sperreRepository.save(entity);
LOGGER.debug("Sperre {} aktualisiert", sperreId);
return ResponseEntity.ok().build();
}
@DeleteMapping
public ResponseEntity<Void> delete(@RequestBody Sperre sperre) {
try {
List<AktiveSperreEntity> aktiveLocks = aktiveSperreRepository.findAktiveLocks(callback.getSpielerId());
SperreVerarbeiten verarbeiten = new SperreVerarbeiten();
aktiveLocks.forEach(lock -> verarbeiten.sperreVerlaengern(lock, callback.getFaktor(), aktiveSperreRepository));
LOGGER.debug("Sperren für Spieler {} um Faktor {} verlängert ({} Sperren)", callback.getSpielerId(), callback.getFaktor(), aktiveLocks.size());
sperreRepository.findById(sperre.getSperreId()).ifPresent(sperreRepository::delete);
return ResponseEntity.accepted().build();
} catch (Exception exception) {
LOGGER.error(exception.getMessage(), exception);
return ResponseEntity.internalServerError().build();
}
}
private List<ToyEntity> resolveToys(List<Toy> toys) {
if (toys == null || toys.isEmpty()) return new ArrayList<>();
List<UUID> ids = toys.stream()
.filter(t -> t.getToyId() != null)
.map(Toy::getToyId)
.toList();
if (ids.isEmpty()) return new ArrayList<>();
return toyRepository.findAllById(ids);
}
}

View File

@@ -1,13 +1,14 @@
package de.oaa.xxx.aufgaben.controller;
package de.oaa.xxx.games.bdsm.controller;
import de.oaa.xxx.games.common.aufgaben.Strafe;
import de.oaa.xxx.games.common.aufgaben.Toy;
import de.oaa.xxx.games.common.entity.AufgabenGruppeEntity;
import de.oaa.xxx.games.common.entity.StrafeEntity;
import de.oaa.xxx.games.common.entity.ToyEntity;
import de.oaa.xxx.games.common.repository.AufgabenGruppeRepository;
import de.oaa.xxx.games.common.repository.StrafeRepository;
import de.oaa.xxx.games.common.repository.ToyRepository;
import de.oaa.xxx.aufgaben.Strafe;
import de.oaa.xxx.aufgaben.Toy;
import de.oaa.xxx.aufgaben.entity.AufgabenGruppeEntity;
import de.oaa.xxx.aufgaben.entity.StrafeEntity;
import de.oaa.xxx.aufgaben.entity.ToyEntity;
import de.oaa.xxx.aufgaben.repository.AufgabenGruppeRepository;
import de.oaa.xxx.aufgaben.repository.StrafeRepository;
import de.oaa.xxx.aufgaben.repository.ToyRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;

View File

@@ -1,11 +1,11 @@
package de.oaa.xxx.aufgaben.controller;
package de.oaa.xxx.games.bdsm.controller;
import de.oaa.xxx.aufgaben.Toy;
import de.oaa.xxx.aufgaben.ToyPage;
import de.oaa.xxx.aufgaben.entity.AufgabenGruppeEntity;
import de.oaa.xxx.aufgaben.entity.ToyEntity;
import de.oaa.xxx.aufgaben.repository.GruppenAboRepository;
import de.oaa.xxx.aufgaben.repository.ToyRepository;
import de.oaa.xxx.games.common.aufgaben.Toy;
import de.oaa.xxx.games.common.aufgaben.ToyPage;
import de.oaa.xxx.games.common.entity.AufgabenGruppeEntity;
import de.oaa.xxx.games.common.entity.ToyEntity;
import de.oaa.xxx.games.common.repository.GruppenAboRepository;
import de.oaa.xxx.games.common.repository.ToyRepository;
import de.oaa.xxx.subscription.SubscriptionLimitService;
import de.oaa.xxx.user.UserEntity;
import de.oaa.xxx.user.UserRepository;

View File

@@ -1,8 +1,14 @@
package de.oaa.xxx.games.bdsm.entity;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import de.oaa.xxx.games.bdsm.AktiveSperre;
import de.oaa.xxx.games.bdsm.Mitspieler;
import de.oaa.xxx.games.bdsm.Werkzeug;
import de.oaa.xxx.games.common.aufgaben.Werkzeug;
import jakarta.persistence.CollectionTable;
import jakarta.persistence.Column;
import jakarta.persistence.ElementCollection;
@@ -17,12 +23,6 @@ import jakarta.persistence.Table;
import lombok.Getter;
import lombok.Setter;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
@Getter
@Setter
@Entity

View File

@@ -1,9 +1,13 @@
package de.oaa.xxx.games.bdsm.entity;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import de.oaa.xxx.games.bdsm.GeschlechtEnum;
import de.oaa.xxx.games.bdsm.Mitspieler;
import de.oaa.xxx.games.bdsm.RolleEnum;
import de.oaa.xxx.games.bdsm.Werkzeug;
import de.oaa.xxx.games.common.aufgaben.Werkzeug;
import jakarta.persistence.CollectionTable;
import jakarta.persistence.Column;
import jakarta.persistence.ElementCollection;
@@ -19,10 +23,6 @@ import jakarta.persistence.Table;
import lombok.Getter;
import lombok.Setter;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
@Getter
@Setter
@Entity

View File

@@ -1,20 +1,21 @@
package de.oaa.xxx.games.bdsm.sperre;
import com.fasterxml.jackson.databind.ObjectMapper;
import de.oaa.xxx.games.bdsm.aufgaben.AufgabenList;
import de.oaa.xxx.games.bdsm.aufgaben.Sperre;
import de.oaa.xxx.games.bdsm.entity.AktiveSperreEntity;
import de.oaa.xxx.games.bdsm.entity.MitspielerEntity;
import de.oaa.xxx.games.bdsm.entity.BdsmGameEntity;
import de.oaa.xxx.games.bdsm.repository.AktiveSperreRepository;
import de.oaa.xxx.games.bdsm.repository.MitspielerRepository;
import de.oaa.xxx.games.bdsm.repository.BdsmGameRepository;
import java.time.LocalDateTime;
import java.util.Optional;
import java.util.Random;
import java.util.UUID;
import com.fasterxml.jackson.databind.ObjectMapper;
import de.oaa.xxx.games.common.aufgaben.AufgabenList;
import de.oaa.xxx.games.common.aufgaben.Sperre;
import de.oaa.xxx.games.bdsm.entity.AktiveSperreEntity;
import de.oaa.xxx.games.bdsm.entity.BdsmGameEntity;
import de.oaa.xxx.games.bdsm.entity.MitspielerEntity;
import de.oaa.xxx.games.bdsm.repository.AktiveSperreRepository;
import de.oaa.xxx.games.bdsm.repository.BdsmGameRepository;
import de.oaa.xxx.games.bdsm.repository.MitspielerRepository;
public class SperreVerarbeiten {
private final ObjectMapper objectMapper = new ObjectMapper();

View File

@@ -1,22 +1,45 @@
package de.oaa.xxx.games.chastity.keyholder;
import de.oaa.xxx.games.chastity.cardlock.*;
import de.oaa.xxx.games.chastity.common.*;
import de.oaa.xxx.games.chastity.lockcontroll.LockControllType;
import de.oaa.xxx.games.chastity.tasks.TaskMode;
import de.oaa.xxx.games.chastity.timelock.*;
import de.oaa.xxx.social.SystemMessageService;
import de.oaa.xxx.social.entity.MessageCause;
import de.oaa.xxx.subscription.SubscriptionLimitService;
import de.oaa.xxx.user.Geschlecht;
import de.oaa.xxx.user.UserRepository;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import java.security.Principal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import de.oaa.xxx.games.chastity.cardlock.CardEnum;
import de.oaa.xxx.games.chastity.cardlock.CardLockEntity;
import de.oaa.xxx.games.chastity.cardlock.CardLockService;
import de.oaa.xxx.games.chastity.cardlock.CardLockServiceFactory;
import de.oaa.xxx.games.chastity.cardlock.CardlockRepository;
import de.oaa.xxx.games.chastity.cardlock.CardlockTemplateEntity;
import de.oaa.xxx.games.chastity.common.BaseLockTemplateRepository;
import de.oaa.xxx.games.chastity.common.CodeCreator;
import de.oaa.xxx.games.chastity.common.TemplateSubscriptionRepository;
import de.oaa.xxx.games.chastity.lockcontroll.LockControllType;
import de.oaa.xxx.games.chastity.tasks.TaskMode;
import de.oaa.xxx.games.chastity.timelock.TimeLockAdditionalSettings;
import de.oaa.xxx.games.chastity.timelock.TimeLockEntity;
import de.oaa.xxx.games.chastity.timelock.TimeLockRepository;
import de.oaa.xxx.games.chastity.timelock.TimeLockServiceFactory;
import de.oaa.xxx.games.chastity.timelock.TimeLockTemplateEntity;
import de.oaa.xxx.social.SystemMessageService;
import de.oaa.xxx.social.entity.MessageCause;
import de.oaa.xxx.subscription.SubscriptionLimitService;
import de.oaa.xxx.user.UserRepository;
@RestController
@RequestMapping("/keyholder-offers")

View File

@@ -1,53 +1,53 @@
package de.oaa.xxx.games.bdsm.aufgaben;
import de.oaa.xxx.games.bdsm.Mitspieler;
import de.oaa.xxx.games.bdsm.Werkzeug;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
import java.util.UUID;
@Getter
@Setter
public class Aufgabe {
private UUID aufgabeId;
private String kurzText;
private String text;
private Integer level;
private Integer sekundenVon;
private Integer sekundenBis;
private UUID gruppeId;
private List<Werkzeug> benoetigtAktiv;
private List<Werkzeug> benoetigtPassiv;
@Override
public String toString() {
return "Aufgabe[id=" + aufgabeId + ", kurzText=" + kurzText + ", level=" + level
+ ", sekunden=" + sekundenVon + "-" + sekundenBis + ", gruppeId=" + gruppeId + "]";
}
public boolean isAufgabePassend(int level, Mitspieler aktiv, Mitspieler passiv) {
if (level != this.level && level - 1 != this.level) {
return false;
}
if (benoetigtPassiv != null) {
for (Werkzeug werkzeug : benoetigtPassiv) {
if (!passiv.isVerfuegbar(werkzeug)) {
return false;
}
}
}
if (benoetigtAktiv == null || benoetigtAktiv.isEmpty()) {
return true;
} else {
for (Werkzeug werkzeug : benoetigtAktiv) {
if (aktiv.isVerfuegbar(werkzeug)) {
return true;
}
}
return false;
}
}
}
package de.oaa.xxx.games.common.aufgaben;
import java.util.List;
import java.util.UUID;
import de.oaa.xxx.games.bdsm.Mitspieler;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class Aufgabe {
private UUID aufgabeId;
private String kurzText;
private String text;
private Integer level;
private Integer sekundenVon;
private Integer sekundenBis;
private UUID gruppeId;
private List<Werkzeug> benoetigtAktiv;
private List<Werkzeug> benoetigtPassiv;
private List<Toy> benoetigteToys;
@Override
public String toString() {
return "Aufgabe[id=" + aufgabeId + ", kurzText=" + kurzText + ", level=" + level
+ ", sekunden=" + sekundenVon + "-" + sekundenBis + ", gruppeId=" + gruppeId + "]";
}
public boolean isAufgabePassend(int level, Mitspieler aktiv, Mitspieler passiv) {
if (level != this.level && level - 1 != this.level) {
return false;
}
if (benoetigtPassiv != null) {
for (Werkzeug werkzeug : benoetigtPassiv) {
if (!passiv.isVerfuegbar(werkzeug)) {
return false;
}
}
}
if (benoetigtAktiv == null || benoetigtAktiv.isEmpty()) {
return true;
} else {
for (Werkzeug werkzeug : benoetigtAktiv) {
if (aktiv.isVerfuegbar(werkzeug)) {
return true;
}
}
return false;
}
}
}

View File

@@ -1,26 +1,26 @@
package de.oaa.xxx.aufgaben;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
import java.util.UUID;
@Getter
@Setter
public class AufgabenGruppe {
private UUID gruppenId;
private String name;
private String beschreibung;
private String von;
private UUID userId;
private boolean privateGruppe;
private List<Aufgabe> aufgaben;
private List<Strafe> strafen;
private List<Sperre> sperren;
private List<Finisher> finisher;
private String bild;
private long subscriberCount;
private boolean subscribed;
}
package de.oaa.xxx.games.common.aufgaben;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
import java.util.UUID;
@Getter
@Setter
public class AufgabenGruppe {
private UUID gruppenId;
private String name;
private String beschreibung;
private String von;
private UUID userId;
private boolean privateGruppe;
private List<Aufgabe> aufgaben;
private List<Strafe> strafen;
private List<Sperre> sperren;
private List<Finisher> finisher;
private String bild;
private long subscriberCount;
private boolean subscribed;
}

View File

@@ -1,19 +1,19 @@
package de.oaa.xxx.aufgaben;
import lombok.Getter;
import lombok.Setter;
import java.util.UUID;
@Getter
@Setter
public class AufgabenGruppeDisplay {
private UUID gruppenId;
private String name;
private String beschreibung;
private UUID userId;
private boolean privateGruppe;
private String bild;
private String von;
}
package de.oaa.xxx.games.common.aufgaben;
import lombok.Getter;
import lombok.Setter;
import java.util.UUID;
@Getter
@Setter
public class AufgabenGruppeDisplay {
private UUID gruppenId;
private String name;
private String beschreibung;
private UUID userId;
private boolean privateGruppe;
private String bild;
private String von;
}

View File

@@ -1,13 +1,13 @@
package de.oaa.xxx.aufgaben;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
@Getter
@Setter
public class AufgabenGruppeList {
private List<AufgabenGruppeDisplay> gruppen;
}
package de.oaa.xxx.games.common.aufgaben;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
@Getter
@Setter
public class AufgabenGruppeList {
private List<AufgabenGruppeDisplay> gruppen;
}

View File

@@ -1,16 +1,16 @@
package de.oaa.xxx.aufgaben;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
@Getter
@Setter
public class AufgabenGruppePage {
private List<AufgabenGruppe> content;
private int currentPage;
private int totalPages;
private long totalElements;
}
package de.oaa.xxx.games.common.aufgaben;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
@Getter
@Setter
public class AufgabenGruppePage {
private List<AufgabenGruppe> content;
private int currentPage;
private int totalPages;
private long totalElements;
}

View File

@@ -1,17 +1,18 @@
package de.oaa.xxx.aufgaben;
package de.oaa.xxx.games.common.aufgaben;
import de.oaa.xxx.games.common.entity.AufgabeEntity;
import de.oaa.xxx.games.common.entity.AufgabenGruppeEntity;
import de.oaa.xxx.games.common.entity.FinisherEntity;
import de.oaa.xxx.games.common.entity.SperreEntity;
import de.oaa.xxx.games.common.entity.StrafeEntity;
import de.oaa.xxx.games.common.entity.ToyEntity;
import de.oaa.xxx.games.common.repository.AufgabeRepository;
import de.oaa.xxx.games.common.repository.AufgabenGruppeRepository;
import de.oaa.xxx.games.common.repository.FinisherRepository;
import de.oaa.xxx.games.common.repository.SperreRepository;
import de.oaa.xxx.games.common.repository.StrafeRepository;
import de.oaa.xxx.games.common.repository.ToyRepository;
import de.oaa.xxx.aufgaben.entity.AufgabeEntity;
import de.oaa.xxx.aufgaben.entity.AufgabenGruppeEntity;
import de.oaa.xxx.aufgaben.entity.FinisherEntity;
import de.oaa.xxx.aufgaben.entity.SperreEntity;
import de.oaa.xxx.aufgaben.entity.StrafeEntity;
import de.oaa.xxx.aufgaben.entity.ToyEntity;
import de.oaa.xxx.aufgaben.repository.AufgabeRepository;
import de.oaa.xxx.aufgaben.repository.AufgabenGruppeRepository;
import de.oaa.xxx.aufgaben.repository.FinisherRepository;
import de.oaa.xxx.aufgaben.repository.SperreRepository;
import de.oaa.xxx.aufgaben.repository.StrafeRepository;
import de.oaa.xxx.aufgaben.repository.ToyRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

View File

@@ -1,25 +1,25 @@
package de.oaa.xxx.games.bdsm.aufgaben;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
@Getter
@Setter
public class AufgabenList {
private List<Aufgabe> aufgaben;
private List<Sperre> sperren;
private List<Strafe> strafen;
private List<Finisher> finisher;
public int size() {
int size = 0;
if (aufgaben != null) size += aufgaben.size();
if (sperren != null) size += sperren.size();
if (strafen != null) size += strafen.size();
if (getFinisher() != null) size += getFinisher().size();
return size;
}
}
package de.oaa.xxx.games.common.aufgaben;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
@Getter
@Setter
public class AufgabenList {
private List<Aufgabe> aufgaben;
private List<Sperre> sperren;
private List<Strafe> strafen;
private List<Finisher> finisher;
public int size() {
int size = 0;
if (aufgaben != null) size += aufgaben.size();
if (sperren != null) size += sperren.size();
if (strafen != null) size += strafen.size();
if (getFinisher() != null) size += getFinisher().size();
return size;
}
}

View File

@@ -1,18 +1,25 @@
package de.oaa.xxx.aufgaben;
package de.oaa.xxx.games.common.aufgaben;
import de.oaa.xxx.games.common.entity.AufgabeEntity;
import de.oaa.xxx.games.common.entity.AufgabenGruppeEntity;
import de.oaa.xxx.games.common.entity.SperreEntity;
import de.oaa.xxx.games.common.entity.StrafeEntity;
import de.oaa.xxx.games.common.entity.ToyEntity;
import de.oaa.xxx.games.common.repository.AufgabeRepository;
import de.oaa.xxx.games.common.repository.AufgabenGruppeRepository;
import de.oaa.xxx.games.common.repository.SperreRepository;
import de.oaa.xxx.games.common.repository.StrafeRepository;
import de.oaa.xxx.games.common.repository.ToyRepository;
import de.oaa.xxx.aufgaben.entity.AufgabeEntity;
import de.oaa.xxx.aufgaben.entity.AufgabenGruppeEntity;
import de.oaa.xxx.aufgaben.entity.SperreEntity;
import de.oaa.xxx.aufgaben.entity.StrafeEntity;
import de.oaa.xxx.aufgaben.entity.ToyEntity;
import de.oaa.xxx.aufgaben.repository.AufgabeRepository;
import de.oaa.xxx.aufgaben.repository.AufgabenGruppeRepository;
import de.oaa.xxx.aufgaben.repository.SperreRepository;
import de.oaa.xxx.aufgaben.repository.StrafeRepository;
import de.oaa.xxx.aufgaben.repository.ToyRepository;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import static de.oaa.xxx.games.common.aufgaben.Werkzeug.ANUS;
import static de.oaa.xxx.games.common.aufgaben.Werkzeug.MUND;
import static de.oaa.xxx.games.common.aufgaben.Werkzeug.PENIS;
import static de.oaa.xxx.games.common.aufgaben.Werkzeug.UMSCHNALLDILDO;
import static de.oaa.xxx.games.common.aufgaben.Werkzeug.VAGINA;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
@@ -20,12 +27,6 @@ import java.util.Collections;
import java.util.List;
import java.util.UUID;
import static de.oaa.xxx.aufgaben.Werkzeug.ANUS;
import static de.oaa.xxx.aufgaben.Werkzeug.MUND;
import static de.oaa.xxx.aufgaben.Werkzeug.PENIS;
import static de.oaa.xxx.aufgaben.Werkzeug.UMSCHNALLDILDO;
import static de.oaa.xxx.aufgaben.Werkzeug.VAGINA;
@Component
public class DefaultFiller {

View File

@@ -1,15 +1,15 @@
package de.oaa.xxx.aufgaben;
import lombok.Getter;
import lombok.Setter;
import java.util.UUID;
@Getter
@Setter
public class Favorit {
private UUID favoritId;
private UUID userId;
private UUID aufgabenGruppeId;
}
package de.oaa.xxx.games.common.aufgaben;
import lombok.Getter;
import lombok.Setter;
import java.util.UUID;
@Getter
@Setter
public class Favorit {
private UUID favoritId;
private UUID userId;
private UUID aufgabenGruppeId;
}

View File

@@ -1,13 +1,13 @@
package de.oaa.xxx.aufgaben;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
@Getter
@Setter
public class FavoritList {
private List<Favorit> favoriten;
}
package de.oaa.xxx.games.common.aufgaben;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
@Getter
@Setter
public class FavoritList {
private List<Favorit> favoriten;
}

View File

@@ -1,14 +1,13 @@
package de.oaa.xxx.games.bdsm.aufgaben;
import de.oaa.xxx.games.bdsm.GeschlechtEnum;
import de.oaa.xxx.games.bdsm.Mitspieler;
import de.oaa.xxx.games.bdsm.Werkzeug;
import lombok.Getter;
import lombok.Setter;
package de.oaa.xxx.games.common.aufgaben;
import java.util.List;
import java.util.UUID;
import de.oaa.xxx.games.bdsm.GeschlechtEnum;
import de.oaa.xxx.games.bdsm.Mitspieler;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class Finisher {
@@ -19,13 +18,15 @@ public class Finisher {
private GeschlechtEnum geschlecht;
private List<Werkzeug> benoetigtAktiv;
private List<Werkzeug> benoetigtPassiv;
private List<Toy> benoetigteToys;
private UUID gruppeId;
@Override
public String toString() {
return "Finisher[id=" + finisherId + ", kurzText=" + kurzText + ", geschlecht=" + geschlecht + "]";
return "Finisher[id=" + finisherId + ", kurzText=" + kurzText + ", geschlecht=" + geschlecht + ", gruppeId=" + gruppeId + "]";
}
public boolean isAufgabePassend(Mitspieler aktiv, Mitspieler passiv) {
public boolean isAufgabePassend(Mitspieler aktiv, Mitspieler passiv) {
if (benoetigtPassiv != null) {
for (Werkzeug werkzeug : benoetigtPassiv) {
if (!passiv.isVerfuegbar(werkzeug)) {

View File

@@ -1,58 +1,58 @@
package de.oaa.xxx.aufgaben;
import org.slf4j.LoggerFactory;
import javax.imageio.ImageIO;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
public class ImageScaler {
private static final int MAX_SIZE = 128;
public byte[] scale(byte[] origBytes) {
try (ByteArrayInputStream bais = new ByteArrayInputStream(origBytes)) {
BufferedImage orig = ImageIO.read(bais);
if (orig == null) {
return origBytes;
}
int origWidth = orig.getWidth();
int origHeight = orig.getHeight();
// Bereits klein genug unverändern zurückgeben
if (origWidth <= MAX_SIZE && origHeight <= MAX_SIZE) {
return origBytes;
}
// Seitenverhältnis beibehalten: längste Seite auf MAX_SIZE
int newWidth, newHeight;
if (origWidth >= origHeight) {
newWidth = MAX_SIZE;
newHeight = Math.max(1, Math.round((float) MAX_SIZE * origHeight / origWidth));
} else {
newHeight = MAX_SIZE;
newWidth = Math.max(1, Math.round((float) MAX_SIZE * origWidth / origHeight));
}
BufferedImage scaled = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = scaled.createGraphics();
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g.drawImage(orig, 0, 0, newWidth, newHeight, null);
g.dispose();
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
ImageIO.write(scaled, "png", baos);
return baos.toByteArray();
}
} catch (IOException e) {
LoggerFactory.getLogger(ImageScaler.class).error("Fehler beim Skalieren des Bildes", e);
return origBytes;
}
}
}
package de.oaa.xxx.games.common.aufgaben;
import org.slf4j.LoggerFactory;
import javax.imageio.ImageIO;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
public class ImageScaler {
private static final int MAX_SIZE = 128;
public byte[] scale(byte[] origBytes) {
try (ByteArrayInputStream bais = new ByteArrayInputStream(origBytes)) {
BufferedImage orig = ImageIO.read(bais);
if (orig == null) {
return origBytes;
}
int origWidth = orig.getWidth();
int origHeight = orig.getHeight();
// Bereits klein genug unverändern zurückgeben
if (origWidth <= MAX_SIZE && origHeight <= MAX_SIZE) {
return origBytes;
}
// Seitenverhältnis beibehalten: längste Seite auf MAX_SIZE
int newWidth, newHeight;
if (origWidth >= origHeight) {
newWidth = MAX_SIZE;
newHeight = Math.max(1, Math.round((float) MAX_SIZE * origHeight / origWidth));
} else {
newHeight = MAX_SIZE;
newWidth = Math.max(1, Math.round((float) MAX_SIZE * origWidth / origHeight));
}
BufferedImage scaled = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = scaled.createGraphics();
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g.drawImage(orig, 0, 0, newWidth, newHeight, null);
g.dispose();
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
ImageIO.write(scaled, "png", baos);
return baos.toByteArray();
}
} catch (IOException e) {
LoggerFactory.getLogger(ImageScaler.class).error("Fehler beim Skalieren des Bildes", e);
return origBytes;
}
}
}

View File

@@ -1,38 +1,38 @@
package de.oaa.xxx.games.bdsm.aufgaben;
import de.oaa.xxx.games.bdsm.Mitspieler;
import de.oaa.xxx.games.bdsm.Werkzeug;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
import java.util.UUID;
@Getter
@Setter
public class Sperre {
private UUID sperreId;
private String kurzText;
private String text;
private String releaseText;
private UUID gruppeId;
private List<Werkzeug> sperreFuer;
private Integer minutenVon;
private Integer minutenBis;
@Override
public String toString() {
return "Sperre[id=" + sperreId + ", kurzText=" + kurzText
+ ", minuten=" + minutenVon + "-" + minutenBis + ", fuer=" + sperreFuer + ", gruppeId=" + gruppeId + "]";
}
public boolean isAufgabePassend(Mitspieler passiv) {
for (Werkzeug werkzeug : sperreFuer) {
if (!passiv.isVerfuegbar(werkzeug)) {
return false;
}
}
return true;
}
}
package de.oaa.xxx.games.common.aufgaben;
import java.util.List;
import java.util.UUID;
import de.oaa.xxx.games.bdsm.Mitspieler;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class Sperre {
private UUID sperreId;
private String kurzText;
private String text;
private String releaseText;
private UUID gruppeId;
private List<Werkzeug> sperreFuer;
private Integer minutenVon;
private Integer minutenBis;
private List<Toy> benoetigteToys;
@Override
public String toString() {
return "Sperre[id=" + sperreId + ", kurzText=" + kurzText
+ ", minuten=" + minutenVon + "-" + minutenBis + ", fuer=" + sperreFuer + ", gruppeId=" + gruppeId + "]";
}
public boolean isAufgabePassend(Mitspieler passiv) {
for (Werkzeug werkzeug : sperreFuer) {
if (!passiv.isVerfuegbar(werkzeug)) {
return false;
}
}
return true;
}
}

View File

@@ -1,47 +1,47 @@
package de.oaa.xxx.games.bdsm.aufgaben;
import de.oaa.xxx.games.bdsm.Mitspieler;
import de.oaa.xxx.games.bdsm.Werkzeug;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
import java.util.UUID;
@Getter
@Setter
public class Strafe {
private UUID strafeId;
private Integer level;
private String text;
private String kurzText;
private Integer sekundenVon;
private Integer sekundenBis;
private UUID gruppeId;
private List<Werkzeug> benoetigtAktiv;
private List<Werkzeug> benoetigtPassiv;
public boolean isAufgabePassend(int level, Mitspieler aktiv, Mitspieler passiv) {
if (level != this.level && level - 1 != this.level) {
return false;
}
if (benoetigtPassiv != null) {
for (Werkzeug werkzeug : benoetigtPassiv) {
if (!passiv.isVerfuegbar(werkzeug)) {
return false;
}
}
}
if (benoetigtAktiv == null || benoetigtAktiv.isEmpty()) {
return true;
} else {
for (Werkzeug werkzeug : benoetigtAktiv) {
if (aktiv.isVerfuegbar(werkzeug)) {
return true;
}
}
return false;
}
}
}
package de.oaa.xxx.games.common.aufgaben;
import java.util.List;
import java.util.UUID;
import de.oaa.xxx.games.bdsm.Mitspieler;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class Strafe {
private UUID strafeId;
private Integer level;
private String text;
private String kurzText;
private Integer sekundenVon;
private Integer sekundenBis;
private UUID gruppeId;
private List<Werkzeug> benoetigtAktiv;
private List<Werkzeug> benoetigtPassiv;
private List<Toy> benoetigteToys;
public boolean isAufgabePassend(int level, Mitspieler aktiv, Mitspieler passiv) {
if (level != this.level && level - 1 != this.level) {
return false;
}
if (benoetigtPassiv != null) {
for (Werkzeug werkzeug : benoetigtPassiv) {
if (!passiv.isVerfuegbar(werkzeug)) {
return false;
}
}
}
if (benoetigtAktiv == null || benoetigtAktiv.isEmpty()) {
return true;
} else {
for (Werkzeug werkzeug : benoetigtAktiv) {
if (aktiv.isVerfuegbar(werkzeug)) {
return true;
}
}
return false;
}
}
}

View File

@@ -1,17 +1,17 @@
package de.oaa.xxx.aufgaben;
import lombok.Getter;
import lombok.Setter;
import java.util.UUID;
@Getter
@Setter
public class Toy {
private UUID toyId;
private String name;
private String beschreibung;
private UUID userId;
private String bild;
}
package de.oaa.xxx.games.common.aufgaben;
import lombok.Getter;
import lombok.Setter;
import java.util.UUID;
@Getter
@Setter
public class Toy {
private UUID toyId;
private String name;
private String beschreibung;
private UUID userId;
private String bild;
}

View File

@@ -1,14 +1,14 @@
package de.oaa.xxx.aufgaben;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
@Getter
@Setter
public class ToyList {
private List<Toy> systemToys;
private List<Toy> userToys;
}
package de.oaa.xxx.games.common.aufgaben;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
@Getter
@Setter
public class ToyList {
private List<Toy> systemToys;
private List<Toy> userToys;
}

View File

@@ -1,16 +1,16 @@
package de.oaa.xxx.aufgaben;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
@Getter
@Setter
public class ToyPage {
private List<Toy> content;
private int currentPage;
private int totalPages;
private long totalElements;
}
package de.oaa.xxx.games.common.aufgaben;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
@Getter
@Setter
public class ToyPage {
private List<Toy> content;
private int currentPage;
private int totalPages;
private long totalElements;
}

View File

@@ -1,21 +1,21 @@
package de.oaa.xxx.aufgaben;
public enum Werkzeug {
MUND("Mund", "Ob die Person gewillt ist den Mund einzusetzen."),
VAGINA("Vagina", "Ob die Person über eine Vagina verfügt und gewillt ist diese einzusetzen."),
PENIS("Penis", "Ob die Person über einen Penis verfügt und gewillt ist diesen einzusetzen."),
ANUS("Anus", "Ob die Person gewillt ist den Anus einzusetzen."),
UMSCHNALLDILDO("Umschnall-Dildo", "Ob die Person über einen Umschnall-Dildo verfügt und gewillt ist diesen einzusetzen.");
private final String anzeige;
private final String beschreibung;
Werkzeug(String anzeige, String beschreibung) {
this.anzeige = anzeige;
this.beschreibung = beschreibung;
}
public String beschreibungsText() { return beschreibung; }
public String anzeigeText() { return anzeige; }
}
package de.oaa.xxx.games.common.aufgaben;
public enum Werkzeug {
MUND("Mund", "Ob die Person gewillt ist den Mund einzusetzen."),
VAGINA("Vagina", "Ob die Person über eine Vagina verfügt und gewillt ist diese einzusetzen."),
PENIS("Penis", "Ob die Person über einen Penis verfügt und gewillt ist diesen einzusetzen."),
ANUS("Anus", "Ob die Person gewillt ist den Anus einzusetzen."),
UMSCHNALLDILDO("Umschnall-Dildo", "Ob die Person über einen Umschnall-Dildo verfügt und gewillt ist diesen einzusetzen.");
private final String anzeige;
private final String beschreibung;
Werkzeug(String anzeige, String beschreibung) {
this.anzeige = anzeige;
this.beschreibung = beschreibung;
}
public String beschreibungsText() { return beschreibung; }
public String anzeigeText() { return anzeige; }
}

View File

@@ -1,96 +1,97 @@
package de.oaa.xxx.aufgaben.entity;
import de.oaa.xxx.aufgaben.Aufgabe;
import de.oaa.xxx.aufgaben.Werkzeug;
import jakarta.persistence.CascadeType;
import jakarta.persistence.CollectionTable;
import jakarta.persistence.Column;
import jakarta.persistence.ElementCollection;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.JoinTable;
import jakarta.persistence.ManyToMany;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import lombok.Getter;
import lombok.Setter;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
@Getter
@Setter
@Entity
@Table(name = "aufgabe")
public class AufgabeEntity {
@Id
@Column
private UUID aufgabeId;
@Column
private String kurzText;
@Column(columnDefinition = "TEXT")
private String text;
@Column
private Integer level;
@Column
private Integer sekundenVon;
@Column
private Integer sekundenBis;
@ManyToOne
@JoinColumn(name = "gruppeId")
private AufgabenGruppeEntity aufgabenGruppe;
@Enumerated(EnumType.STRING)
@ElementCollection(targetClass = Werkzeug.class)
@CollectionTable(name = "aufgabe_benoetigtAktiv", joinColumns = @JoinColumn(name = "aufgabeId"))
@Column(name = "werkzeug")
private List<Werkzeug> benoetigtAktiv;
@Enumerated(EnumType.STRING)
@ElementCollection(targetClass = Werkzeug.class)
@CollectionTable(name = "aufgabe_benoetigtPassiv", joinColumns = @JoinColumn(name = "aufgabeId"))
@Column(name = "werkzeug")
private List<Werkzeug> benoetigtPassiv;
@ManyToMany(cascade = CascadeType.DETACH)
@JoinTable(name = "aufgabeToy", joinColumns = {@JoinColumn(name = "aufgabeId")}, inverseJoinColumns = {@JoinColumn(name = "toyId")})
private List<ToyEntity> benoetigteToys;
@Override
public String toString() {
return "AufgabeEntity[id=" + aufgabeId + ", kurzText=" + kurzText + ", level=" + level
+ ", sekunden=" + sekundenVon + "-" + sekundenBis + "]";
}
public Aufgabe toAufgabe() {
Aufgabe aufgabe = new Aufgabe();
aufgabe.setAufgabeId(aufgabeId);
aufgabe.setBenoetigtAktiv(benoetigtAktiv != null ? new ArrayList<>(benoetigtAktiv) : new ArrayList<>());
aufgabe.setBenoetigteToys(benoetigteToys != null ? benoetigteToys.stream().map(ToyEntity::toToy).toList() : new ArrayList<>());
aufgabe.setBenoetigtPassiv(benoetigtPassiv != null ? new ArrayList<>(benoetigtPassiv) : new ArrayList<>());
aufgabe.setGruppeId(aufgabenGruppe.getGruppenId());
aufgabe.setKurzText(kurzText);
aufgabe.setLevel(level);
aufgabe.setSekundenBis(sekundenBis);
aufgabe.setSekundenVon(sekundenVon);
aufgabe.setText(text);
return aufgabe;
}
public static AufgabeEntity create(Aufgabe aufgabe, AufgabenGruppeEntity aufgabenGruppeEntity, List<ToyEntity> toys) {
AufgabeEntity entity = new AufgabeEntity();
entity.setAufgabeId(UUID.randomUUID());
entity.setAufgabenGruppe(aufgabenGruppeEntity);
entity.setBenoetigtAktiv(aufgabe.getBenoetigtAktiv());
entity.setBenoetigteToys(toys != null ? toys : new ArrayList<>());
entity.setBenoetigtPassiv(aufgabe.getBenoetigtPassiv());
entity.setKurzText(aufgabe.getKurzText());
entity.setLevel(aufgabe.getLevel());
entity.setSekundenBis(aufgabe.getSekundenBis());
entity.setSekundenVon(aufgabe.getSekundenVon());
entity.setText(aufgabe.getText());
return entity;
}
}
package de.oaa.xxx.games.common.entity;
import jakarta.persistence.CascadeType;
import jakarta.persistence.CollectionTable;
import jakarta.persistence.Column;
import jakarta.persistence.ElementCollection;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.JoinTable;
import jakarta.persistence.ManyToMany;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import lombok.Getter;
import lombok.Setter;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import de.oaa.xxx.games.common.aufgaben.Aufgabe;
import de.oaa.xxx.games.common.aufgaben.Werkzeug;
@Getter
@Setter
@Entity
@Table(name = "aufgabe")
public class AufgabeEntity {
@Id
@Column
private UUID aufgabeId;
@Column
private String kurzText;
@Column(columnDefinition = "TEXT")
private String text;
@Column
private Integer level;
@Column
private Integer sekundenVon;
@Column
private Integer sekundenBis;
@ManyToOne
@JoinColumn(name = "gruppeId")
private AufgabenGruppeEntity aufgabenGruppe;
@Enumerated(EnumType.STRING)
@ElementCollection(targetClass = Werkzeug.class)
@CollectionTable(name = "aufgabe_benoetigtAktiv", joinColumns = @JoinColumn(name = "aufgabeId"))
@Column(name = "werkzeug")
private List<Werkzeug> benoetigtAktiv;
@Enumerated(EnumType.STRING)
@ElementCollection(targetClass = Werkzeug.class)
@CollectionTable(name = "aufgabe_benoetigtPassiv", joinColumns = @JoinColumn(name = "aufgabeId"))
@Column(name = "werkzeug")
private List<Werkzeug> benoetigtPassiv;
@ManyToMany(cascade = CascadeType.DETACH)
@JoinTable(name = "aufgabeToy", joinColumns = {@JoinColumn(name = "aufgabeId")}, inverseJoinColumns = {@JoinColumn(name = "toyId")})
private List<ToyEntity> benoetigteToys;
@Override
public String toString() {
return "AufgabeEntity[id=" + aufgabeId + ", kurzText=" + kurzText + ", level=" + level
+ ", sekunden=" + sekundenVon + "-" + sekundenBis + "]";
}
public Aufgabe toAufgabe() {
Aufgabe aufgabe = new Aufgabe();
aufgabe.setAufgabeId(aufgabeId);
aufgabe.setBenoetigtAktiv(benoetigtAktiv != null ? new ArrayList<>(benoetigtAktiv) : new ArrayList<>());
aufgabe.setBenoetigteToys(benoetigteToys != null ? benoetigteToys.stream().map(ToyEntity::toToy).toList() : new ArrayList<>());
aufgabe.setBenoetigtPassiv(benoetigtPassiv != null ? new ArrayList<>(benoetigtPassiv) : new ArrayList<>());
aufgabe.setGruppeId(aufgabenGruppe.getGruppenId());
aufgabe.setKurzText(kurzText);
aufgabe.setLevel(level);
aufgabe.setSekundenBis(sekundenBis);
aufgabe.setSekundenVon(sekundenVon);
aufgabe.setText(text);
return aufgabe;
}
public static AufgabeEntity create(Aufgabe aufgabe, AufgabenGruppeEntity aufgabenGruppeEntity, List<ToyEntity> toys) {
AufgabeEntity entity = new AufgabeEntity();
entity.setAufgabeId(UUID.randomUUID());
entity.setAufgabenGruppe(aufgabenGruppeEntity);
entity.setBenoetigtAktiv(aufgabe.getBenoetigtAktiv());
entity.setBenoetigteToys(toys != null ? toys : new ArrayList<>());
entity.setBenoetigtPassiv(aufgabe.getBenoetigtPassiv());
entity.setKurzText(aufgabe.getKurzText());
entity.setLevel(aufgabe.getLevel());
entity.setSekundenBis(aufgabe.getSekundenBis());
entity.setSekundenVon(aufgabe.getSekundenVon());
entity.setText(aufgabe.getText());
return entity;
}
}

View File

@@ -1,94 +1,95 @@
package de.oaa.xxx.aufgaben.entity;
import de.oaa.xxx.aufgaben.AufgabenGruppe;
import de.oaa.xxx.aufgaben.AufgabenGruppeDisplay;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Lob;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
import lombok.Getter;
import lombok.Setter;
import java.util.Base64;
import java.util.List;
import java.util.UUID;
@Getter
@Setter
@Entity
@Table(name = "aufgaben_gruppe")
public class AufgabenGruppeEntity {
@Id
@Column
private UUID gruppenId;
@Column
private String name;
@Column
private String beschreibung;
@Column
private UUID userId;
@Column
private boolean privateGruppe;
@Lob
@Column(columnDefinition = "BLOB")
private byte[] bild;
@Column
private String von;
@OneToMany(mappedBy = "aufgabenGruppe")
private List<AufgabeEntity> aufgaben;
@OneToMany(mappedBy = "aufgabenGruppe")
private List<StrafeEntity> strafen;
@OneToMany(mappedBy = "aufgabenGruppe")
private List<SperreEntity> sperren;
@OneToMany(mappedBy = "aufgabenGruppe")
private List<FinisherEntity> finisher;
@Override
public String toString() {
return "AufgabenGruppeEntity[gruppenId=" + gruppenId + ", name=" + name + ", userId=" + userId
+ ", privat=" + privateGruppe + ", von=" + von + "]";
}
public AufgabenGruppe toAufgabenGruppe() {
AufgabenGruppe gruppe = new AufgabenGruppe();
gruppe.setGruppenId(gruppenId);
gruppe.setUserId(userId);
gruppe.setName(name);
gruppe.setBeschreibung(beschreibung);
gruppe.setPrivateGruppe(privateGruppe);
gruppe.setBild(bild != null ? Base64.getEncoder().encodeToString(bild) : null);
gruppe.setVon(von);
gruppe.setAufgaben(aufgaben.stream().map(AufgabeEntity::toAufgabe).toList());
gruppe.setStrafen(strafen.stream().map(StrafeEntity::toStrafe).toList());
gruppe.setSperren(sperren.stream().map(SperreEntity::toSperre).toList());
gruppe.setFinisher(finisher.stream().map(FinisherEntity::toFinisher).toList());
return gruppe;
}
public static AufgabenGruppeEntity create(AufgabenGruppe gruppe) {
AufgabenGruppeEntity entity = new AufgabenGruppeEntity();
entity.setGruppenId(UUID.randomUUID());
entity.setName(gruppe.getName());
entity.setBeschreibung(gruppe.getBeschreibung());
entity.setUserId(gruppe.getUserId());
entity.setPrivateGruppe(gruppe.isPrivateGruppe());
entity.setBild(gruppe.getBild() != null ? Base64.getDecoder().decode(gruppe.getBild()) : null);
entity.setVon(gruppe.getVon());
return entity;
}
public AufgabenGruppeDisplay toAufgabenGruppeDisplay() {
AufgabenGruppeDisplay display = new AufgabenGruppeDisplay();
display.setGruppenId(gruppenId);
display.setUserId(userId);
display.setName(name);
display.setBeschreibung(beschreibung);
display.setPrivateGruppe(privateGruppe);
display.setBild(bild != null ? Base64.getEncoder().encodeToString(bild) : null);
display.setVon(von);
return display;
}
}
package de.oaa.xxx.games.common.entity;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Lob;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
import lombok.Getter;
import lombok.Setter;
import java.util.Base64;
import java.util.List;
import java.util.UUID;
import de.oaa.xxx.games.common.aufgaben.AufgabenGruppe;
import de.oaa.xxx.games.common.aufgaben.AufgabenGruppeDisplay;
@Getter
@Setter
@Entity
@Table(name = "aufgaben_gruppe")
public class AufgabenGruppeEntity {
@Id
@Column
private UUID gruppenId;
@Column
private String name;
@Column
private String beschreibung;
@Column
private UUID userId;
@Column
private boolean privateGruppe;
@Lob
@Column(columnDefinition = "BLOB")
private byte[] bild;
@Column
private String von;
@OneToMany(mappedBy = "aufgabenGruppe")
private List<AufgabeEntity> aufgaben;
@OneToMany(mappedBy = "aufgabenGruppe")
private List<StrafeEntity> strafen;
@OneToMany(mappedBy = "aufgabenGruppe")
private List<SperreEntity> sperren;
@OneToMany(mappedBy = "aufgabenGruppe")
private List<FinisherEntity> finisher;
@Override
public String toString() {
return "AufgabenGruppeEntity[gruppenId=" + gruppenId + ", name=" + name + ", userId=" + userId
+ ", privat=" + privateGruppe + ", von=" + von + "]";
}
public AufgabenGruppe toAufgabenGruppe() {
AufgabenGruppe gruppe = new AufgabenGruppe();
gruppe.setGruppenId(gruppenId);
gruppe.setUserId(userId);
gruppe.setName(name);
gruppe.setBeschreibung(beschreibung);
gruppe.setPrivateGruppe(privateGruppe);
gruppe.setBild(bild != null ? Base64.getEncoder().encodeToString(bild) : null);
gruppe.setVon(von);
gruppe.setAufgaben(aufgaben.stream().map(AufgabeEntity::toAufgabe).toList());
gruppe.setStrafen(strafen.stream().map(StrafeEntity::toStrafe).toList());
gruppe.setSperren(sperren.stream().map(SperreEntity::toSperre).toList());
gruppe.setFinisher(finisher.stream().map(FinisherEntity::toFinisher).toList());
return gruppe;
}
public static AufgabenGruppeEntity create(AufgabenGruppe gruppe) {
AufgabenGruppeEntity entity = new AufgabenGruppeEntity();
entity.setGruppenId(UUID.randomUUID());
entity.setName(gruppe.getName());
entity.setBeschreibung(gruppe.getBeschreibung());
entity.setUserId(gruppe.getUserId());
entity.setPrivateGruppe(gruppe.isPrivateGruppe());
entity.setBild(gruppe.getBild() != null ? Base64.getDecoder().decode(gruppe.getBild()) : null);
entity.setVon(gruppe.getVon());
return entity;
}
public AufgabenGruppeDisplay toAufgabenGruppeDisplay() {
AufgabenGruppeDisplay display = new AufgabenGruppeDisplay();
display.setGruppenId(gruppenId);
display.setUserId(userId);
display.setName(name);
display.setBeschreibung(beschreibung);
display.setPrivateGruppe(privateGruppe);
display.setBild(bild != null ? Base64.getEncoder().encodeToString(bild) : null);
display.setVon(von);
return display;
}
}

View File

@@ -1,47 +1,48 @@
package de.oaa.xxx.aufgaben.entity;
import de.oaa.xxx.aufgaben.Favorit;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.Getter;
import lombok.Setter;
import java.util.UUID;
@Getter
@Setter
@Entity
@Table(name = "favorit")
public class FavoritEntity {
@Id
@Column
private UUID favoritId;
@Column
private UUID userId;
@Column
private UUID aufgabenGruppeId;
@Override
public String toString() {
return "FavoritEntity[favoritId=" + favoritId + ", userId=" + userId + ", gruppeId=" + aufgabenGruppeId + "]";
}
public Favorit toFavorit() {
Favorit favorit = new Favorit();
favorit.setAufgabenGruppeId(aufgabenGruppeId);
favorit.setFavoritId(favoritId);
favorit.setUserId(userId);
return favorit;
}
public static FavoritEntity fromFavorit(Favorit favorit, UUID userId) {
FavoritEntity entity = new FavoritEntity();
entity.setFavoritId(UUID.randomUUID());
entity.setAufgabenGruppeId(favorit.getAufgabenGruppeId());
entity.setUserId(userId);
return entity;
}
}
package de.oaa.xxx.games.common.entity;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.Getter;
import lombok.Setter;
import java.util.UUID;
import de.oaa.xxx.games.common.aufgaben.Favorit;
@Getter
@Setter
@Entity
@Table(name = "favorit")
public class FavoritEntity {
@Id
@Column
private UUID favoritId;
@Column
private UUID userId;
@Column
private UUID aufgabenGruppeId;
@Override
public String toString() {
return "FavoritEntity[favoritId=" + favoritId + ", userId=" + userId + ", gruppeId=" + aufgabenGruppeId + "]";
}
public Favorit toFavorit() {
Favorit favorit = new Favorit();
favorit.setAufgabenGruppeId(aufgabenGruppeId);
favorit.setFavoritId(favoritId);
favorit.setUserId(userId);
return favorit;
}
public static FavoritEntity fromFavorit(Favorit favorit, UUID userId) {
FavoritEntity entity = new FavoritEntity();
entity.setFavoritId(UUID.randomUUID());
entity.setAufgabenGruppeId(favorit.getAufgabenGruppeId());
entity.setUserId(userId);
return entity;
}
}

View File

@@ -1,89 +1,89 @@
package de.oaa.xxx.aufgaben.entity;
import de.oaa.xxx.aufgaben.Finisher;
import de.oaa.xxx.aufgaben.Werkzeug;
import de.oaa.xxx.games.bdsm.GeschlechtEnum;
import jakarta.persistence.CascadeType;
import jakarta.persistence.CollectionTable;
import jakarta.persistence.Column;
import jakarta.persistence.ElementCollection;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.JoinTable;
import jakarta.persistence.ManyToMany;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import lombok.Getter;
import lombok.Setter;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
@Getter
@Setter
@Entity
@Table(name = "finisher")
public class FinisherEntity {
@Id
@Column
private UUID finisherId;
@Column
private String kurzText;
@Column(columnDefinition = "TEXT")
private String text;
@Enumerated(EnumType.STRING)
@Column
private GeschlechtEnum geschlecht;
@ManyToOne
@JoinColumn(name = "gruppeId")
private AufgabenGruppeEntity aufgabenGruppe;
@Enumerated(EnumType.STRING)
@ElementCollection(targetClass = Werkzeug.class)
@CollectionTable(name = "finisher_benoetigtAktiv", joinColumns = @JoinColumn(name = "finisherId"))
@Column(name = "werkzeug")
private List<Werkzeug> benoetigtAktiv;
@Enumerated(EnumType.STRING)
@ElementCollection(targetClass = Werkzeug.class)
@CollectionTable(name = "finisher_benoetigtPassiv", joinColumns = @JoinColumn(name = "finisherId"))
@Column(name = "werkzeug")
private List<Werkzeug> benoetigtPassiv;
@ManyToMany(cascade = CascadeType.DETACH)
@JoinTable(name = "finisherToy", joinColumns = {@JoinColumn(name = "finisherId")}, inverseJoinColumns = {@JoinColumn(name = "toyId")})
private List<ToyEntity> benoetigteToys;
@Override
public String toString() {
return "FinisherEntity[id=" + finisherId + ", kurzText=" + kurzText + ", geschlecht=" + geschlecht + "]";
}
public Finisher toFinisher() {
Finisher finisher = new Finisher();
finisher.setFinisherId(finisherId);
finisher.setKurzText(kurzText);
finisher.setText(text);
finisher.setGeschlecht(geschlecht);
finisher.setBenoetigtAktiv(benoetigtAktiv != null ? new ArrayList<>(benoetigtAktiv) : new ArrayList<>());
finisher.setBenoetigtPassiv(benoetigtPassiv != null ? new ArrayList<>(benoetigtPassiv) : new ArrayList<>());
finisher.setBenoetigteToys(benoetigteToys != null ? benoetigteToys.stream().map(ToyEntity::toToy).toList() : new ArrayList<>());
finisher.setGruppeId(aufgabenGruppe.getGruppenId());
return finisher;
}
public static FinisherEntity create(Finisher finisher, AufgabenGruppeEntity aufgabenGruppeEntity, List<ToyEntity> toys) {
FinisherEntity entity = new FinisherEntity();
entity.setFinisherId(UUID.randomUUID());
entity.setAufgabenGruppe(aufgabenGruppeEntity);
entity.setKurzText(finisher.getKurzText());
entity.setText(finisher.getText());
entity.setGeschlecht(finisher.getGeschlecht());
entity.setBenoetigtAktiv(finisher.getBenoetigtAktiv());
entity.setBenoetigtPassiv(finisher.getBenoetigtPassiv());
entity.setBenoetigteToys(toys != null ? toys : new ArrayList<>());
return entity;
}
}
package de.oaa.xxx.games.common.entity;
import de.oaa.xxx.games.bdsm.GeschlechtEnum;
import de.oaa.xxx.games.common.aufgaben.Finisher;
import de.oaa.xxx.games.common.aufgaben.Werkzeug;
import jakarta.persistence.CascadeType;
import jakarta.persistence.CollectionTable;
import jakarta.persistence.Column;
import jakarta.persistence.ElementCollection;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.JoinTable;
import jakarta.persistence.ManyToMany;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import lombok.Getter;
import lombok.Setter;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
@Getter
@Setter
@Entity
@Table(name = "finisher")
public class FinisherEntity {
@Id
@Column
private UUID finisherId;
@Column
private String kurzText;
@Column(columnDefinition = "TEXT")
private String text;
@Enumerated(EnumType.STRING)
@Column
private GeschlechtEnum geschlecht;
@ManyToOne
@JoinColumn(name = "gruppeId")
private AufgabenGruppeEntity aufgabenGruppe;
@Enumerated(EnumType.STRING)
@ElementCollection(targetClass = Werkzeug.class)
@CollectionTable(name = "finisher_benoetigtAktiv", joinColumns = @JoinColumn(name = "finisherId"))
@Column(name = "werkzeug")
private List<Werkzeug> benoetigtAktiv;
@Enumerated(EnumType.STRING)
@ElementCollection(targetClass = Werkzeug.class)
@CollectionTable(name = "finisher_benoetigtPassiv", joinColumns = @JoinColumn(name = "finisherId"))
@Column(name = "werkzeug")
private List<Werkzeug> benoetigtPassiv;
@ManyToMany(cascade = CascadeType.DETACH)
@JoinTable(name = "finisherToy", joinColumns = {@JoinColumn(name = "finisherId")}, inverseJoinColumns = {@JoinColumn(name = "toyId")})
private List<ToyEntity> benoetigteToys;
@Override
public String toString() {
return "FinisherEntity[id=" + finisherId + ", kurzText=" + kurzText + ", geschlecht=" + geschlecht + "]";
}
public Finisher toFinisher() {
Finisher finisher = new Finisher();
finisher.setFinisherId(finisherId);
finisher.setKurzText(kurzText);
finisher.setText(text);
finisher.setGeschlecht(geschlecht);
finisher.setBenoetigtAktiv(benoetigtAktiv != null ? new ArrayList<>(benoetigtAktiv) : new ArrayList<>());
finisher.setBenoetigtPassiv(benoetigtPassiv != null ? new ArrayList<>(benoetigtPassiv) : new ArrayList<>());
finisher.setBenoetigteToys(benoetigteToys != null ? benoetigteToys.stream().map(ToyEntity::toToy).toList() : new ArrayList<>());
finisher.setGruppeId(aufgabenGruppe.getGruppenId());
return finisher;
}
public static FinisherEntity create(Finisher finisher, AufgabenGruppeEntity aufgabenGruppeEntity, List<ToyEntity> toys) {
FinisherEntity entity = new FinisherEntity();
entity.setFinisherId(UUID.randomUUID());
entity.setAufgabenGruppe(aufgabenGruppeEntity);
entity.setKurzText(finisher.getKurzText());
entity.setText(finisher.getText());
entity.setGeschlecht(finisher.getGeschlecht());
entity.setBenoetigtAktiv(finisher.getBenoetigtAktiv());
entity.setBenoetigtPassiv(finisher.getBenoetigtPassiv());
entity.setBenoetigteToys(toys != null ? toys : new ArrayList<>());
return entity;
}
}

View File

@@ -1,36 +1,36 @@
package de.oaa.xxx.aufgaben.entity;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import lombok.Getter;
import lombok.Setter;
import java.util.UUID;
@Getter
@Setter
@Entity
@Table(name = "gruppen_abo")
public class GruppenAboEntity {
@Id
@Column
private UUID aboId;
@Column
private UUID userId;
@ManyToOne
@JoinColumn(name = "gruppenId")
private AufgabenGruppeEntity aufgabenGruppe;
@Override
public String toString() {
return "GruppenAboEntity[aboId=" + aboId + ", userId=" + userId
+ ", gruppe=" + (aufgabenGruppe != null ? aufgabenGruppe.getName() : null) + "]";
}
}
package de.oaa.xxx.games.common.entity;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import lombok.Getter;
import lombok.Setter;
import java.util.UUID;
@Getter
@Setter
@Entity
@Table(name = "gruppen_abo")
public class GruppenAboEntity {
@Id
@Column
private UUID aboId;
@Column
private UUID userId;
@ManyToOne
@JoinColumn(name = "gruppenId")
private AufgabenGruppeEntity aufgabenGruppe;
@Override
public String toString() {
return "GruppenAboEntity[aboId=" + aboId + ", userId=" + userId
+ ", gruppe=" + (aufgabenGruppe != null ? aufgabenGruppe.getName() : null) + "]";
}
}

View File

@@ -1,89 +1,90 @@
package de.oaa.xxx.aufgaben.entity;
import de.oaa.xxx.aufgaben.Sperre;
import de.oaa.xxx.aufgaben.Werkzeug;
import jakarta.persistence.CascadeType;
import jakarta.persistence.CollectionTable;
import jakarta.persistence.Column;
import jakarta.persistence.ElementCollection;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.JoinTable;
import jakarta.persistence.ManyToMany;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import lombok.Getter;
import lombok.Setter;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
@Getter
@Setter
@Entity
@Table(name = "sperre")
public class SperreEntity {
@Id
@Column
private UUID sperreId;
@Column
private String kurzText;
@Column(columnDefinition = "TEXT")
private String text;
@Column(columnDefinition = "TEXT")
private String releaseText;
@ManyToOne
@JoinColumn(name = "gruppeId")
private AufgabenGruppeEntity aufgabenGruppe;
@Enumerated(EnumType.STRING)
@ElementCollection(targetClass = Werkzeug.class)
@CollectionTable(name = "sperre_sperreFuer", joinColumns = @JoinColumn(name = "sperreId"))
@Column(name = "werkzeug")
private List<Werkzeug> sperreFuer;
@Column
private Integer minutenVon;
@Column
private Integer minutenBis;
@ManyToMany(cascade = CascadeType.DETACH)
@JoinTable(name = "sperreToy", joinColumns = {@JoinColumn(name = "sperreId")}, inverseJoinColumns = {@JoinColumn(name = "toyId")})
private List<ToyEntity> benoetigteToys;
@Override
public String toString() {
return "SperreEntity[id=" + sperreId + ", kurzText=" + kurzText
+ ", minuten=" + minutenVon + "-" + minutenBis + ", fuer=" + sperreFuer + "]";
}
public Sperre toSperre() {
Sperre sperre = new Sperre();
sperre.setSperreId(sperreId);
sperre.setGruppeId(aufgabenGruppe.getGruppenId());
sperre.setKurzText(kurzText);
sperre.setMinutenBis(minutenBis);
sperre.setMinutenVon(minutenVon);
sperre.setReleaseText(releaseText);
sperre.setSperreFuer(sperreFuer != null ? new ArrayList<>(sperreFuer) : new ArrayList<>());
sperre.setText(text);
sperre.setBenoetigteToys(benoetigteToys != null ? benoetigteToys.stream().map(ToyEntity::toToy).toList() : new ArrayList<>());
return sperre;
}
public static SperreEntity create(Sperre sperre, AufgabenGruppeEntity aufgabenGruppeEntity, List<ToyEntity> toys) {
SperreEntity entity = new SperreEntity();
entity.setSperreId(UUID.randomUUID());
entity.setAufgabenGruppe(aufgabenGruppeEntity);
entity.setBenoetigteToys(toys != null ? toys : new ArrayList<>());
entity.setKurzText(sperre.getKurzText());
entity.setMinutenBis(sperre.getMinutenBis());
entity.setMinutenVon(sperre.getMinutenVon());
entity.setReleaseText(sperre.getReleaseText());
entity.setSperreFuer(sperre.getSperreFuer());
entity.setText(sperre.getText());
return entity;
}
}
package de.oaa.xxx.games.common.entity;
import jakarta.persistence.CascadeType;
import jakarta.persistence.CollectionTable;
import jakarta.persistence.Column;
import jakarta.persistence.ElementCollection;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.JoinTable;
import jakarta.persistence.ManyToMany;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import lombok.Getter;
import lombok.Setter;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import de.oaa.xxx.games.common.aufgaben.Sperre;
import de.oaa.xxx.games.common.aufgaben.Werkzeug;
@Getter
@Setter
@Entity
@Table(name = "sperre")
public class SperreEntity {
@Id
@Column
private UUID sperreId;
@Column
private String kurzText;
@Column(columnDefinition = "TEXT")
private String text;
@Column(columnDefinition = "TEXT")
private String releaseText;
@ManyToOne
@JoinColumn(name = "gruppeId")
private AufgabenGruppeEntity aufgabenGruppe;
@Enumerated(EnumType.STRING)
@ElementCollection(targetClass = Werkzeug.class)
@CollectionTable(name = "sperre_sperreFuer", joinColumns = @JoinColumn(name = "sperreId"))
@Column(name = "werkzeug")
private List<Werkzeug> sperreFuer;
@Column
private Integer minutenVon;
@Column
private Integer minutenBis;
@ManyToMany(cascade = CascadeType.DETACH)
@JoinTable(name = "sperreToy", joinColumns = {@JoinColumn(name = "sperreId")}, inverseJoinColumns = {@JoinColumn(name = "toyId")})
private List<ToyEntity> benoetigteToys;
@Override
public String toString() {
return "SperreEntity[id=" + sperreId + ", kurzText=" + kurzText
+ ", minuten=" + minutenVon + "-" + minutenBis + ", fuer=" + sperreFuer + "]";
}
public Sperre toSperre() {
Sperre sperre = new Sperre();
sperre.setSperreId(sperreId);
sperre.setGruppeId(aufgabenGruppe.getGruppenId());
sperre.setKurzText(kurzText);
sperre.setMinutenBis(minutenBis);
sperre.setMinutenVon(minutenVon);
sperre.setReleaseText(releaseText);
sperre.setSperreFuer(sperreFuer != null ? new ArrayList<>(sperreFuer) : new ArrayList<>());
sperre.setText(text);
sperre.setBenoetigteToys(benoetigteToys != null ? benoetigteToys.stream().map(ToyEntity::toToy).toList() : new ArrayList<>());
return sperre;
}
public static SperreEntity create(Sperre sperre, AufgabenGruppeEntity aufgabenGruppeEntity, List<ToyEntity> toys) {
SperreEntity entity = new SperreEntity();
entity.setSperreId(UUID.randomUUID());
entity.setAufgabenGruppe(aufgabenGruppeEntity);
entity.setBenoetigteToys(toys != null ? toys : new ArrayList<>());
entity.setKurzText(sperre.getKurzText());
entity.setMinutenBis(sperre.getMinutenBis());
entity.setMinutenVon(sperre.getMinutenVon());
entity.setReleaseText(sperre.getReleaseText());
entity.setSperreFuer(sperre.getSperreFuer());
entity.setText(sperre.getText());
return entity;
}
}

View File

@@ -1,96 +1,97 @@
package de.oaa.xxx.aufgaben.entity;
import de.oaa.xxx.aufgaben.Strafe;
import de.oaa.xxx.aufgaben.Werkzeug;
import jakarta.persistence.CascadeType;
import jakarta.persistence.CollectionTable;
import jakarta.persistence.Column;
import jakarta.persistence.ElementCollection;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.JoinTable;
import jakarta.persistence.ManyToMany;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import lombok.Getter;
import lombok.Setter;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
@Getter
@Setter
@Entity
@Table(name = "strafe")
public class StrafeEntity {
@Id
@Column
private UUID strafeId;
@Column
private String kurzText;
@Column
private Integer level;
@Column(columnDefinition = "TEXT")
private String text;
@Column
private Integer sekundenVon;
@Column
private Integer sekundenBis;
@ManyToOne
@JoinColumn(name = "gruppeId")
private AufgabenGruppeEntity aufgabenGruppe;
@Enumerated(EnumType.STRING)
@ElementCollection(targetClass = Werkzeug.class)
@CollectionTable(name = "strafe_benoetigtAktiv", joinColumns = @JoinColumn(name = "strafeId"))
@Column(name = "werkzeug")
private List<Werkzeug> benoetigtAktiv;
@Enumerated(EnumType.STRING)
@ElementCollection(targetClass = Werkzeug.class)
@CollectionTable(name = "strafe_benoetigtPassiv", joinColumns = @JoinColumn(name = "strafeId"))
@Column(name = "werkzeug")
private List<Werkzeug> benoetigtPassiv;
@ManyToMany(cascade = CascadeType.DETACH)
@JoinTable(name = "strafeToy", joinColumns = {@JoinColumn(name = "strafeId")}, inverseJoinColumns = {@JoinColumn(name = "toyId")})
private List<ToyEntity> benoetigteToys;
@Override
public String toString() {
return "StrafeEntity[id=" + strafeId + ", kurzText=" + kurzText + ", level=" + level
+ ", sekunden=" + sekundenVon + "-" + sekundenBis + "]";
}
public Strafe toStrafe() {
Strafe strafe = new Strafe();
strafe.setStrafeId(strafeId);
strafe.setBenoetigtAktiv(benoetigtAktiv != null ? new ArrayList<>(benoetigtAktiv) : new ArrayList<>());
strafe.setBenoetigteToys(benoetigteToys != null ? benoetigteToys.stream().map(ToyEntity::toToy).toList() : new ArrayList<>());
strafe.setBenoetigtPassiv(benoetigtPassiv != null ? new ArrayList<>(benoetigtPassiv) : new ArrayList<>());
strafe.setGruppeId(aufgabenGruppe.getGruppenId());
strafe.setKurzText(kurzText);
strafe.setLevel(level);
strafe.setSekundenBis(sekundenBis);
strafe.setSekundenVon(sekundenVon);
strafe.setText(text);
return strafe;
}
public static StrafeEntity create(Strafe strafe, AufgabenGruppeEntity aufgabenGruppeEntity, List<ToyEntity> toys) {
StrafeEntity entity = new StrafeEntity();
entity.setStrafeId(UUID.randomUUID());
entity.setAufgabenGruppe(aufgabenGruppeEntity);
entity.setBenoetigtAktiv(strafe.getBenoetigtAktiv());
entity.setBenoetigteToys(toys != null ? toys : new ArrayList<>());
entity.setBenoetigtPassiv(strafe.getBenoetigtPassiv());
entity.setKurzText(strafe.getKurzText());
entity.setLevel(strafe.getLevel());
entity.setSekundenBis(strafe.getSekundenBis());
entity.setSekundenVon(strafe.getSekundenVon());
entity.setText(strafe.getText());
return entity;
}
}
package de.oaa.xxx.games.common.entity;
import jakarta.persistence.CascadeType;
import jakarta.persistence.CollectionTable;
import jakarta.persistence.Column;
import jakarta.persistence.ElementCollection;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.JoinTable;
import jakarta.persistence.ManyToMany;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import lombok.Getter;
import lombok.Setter;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import de.oaa.xxx.games.common.aufgaben.Strafe;
import de.oaa.xxx.games.common.aufgaben.Werkzeug;
@Getter
@Setter
@Entity
@Table(name = "strafe")
public class StrafeEntity {
@Id
@Column
private UUID strafeId;
@Column
private String kurzText;
@Column
private Integer level;
@Column(columnDefinition = "TEXT")
private String text;
@Column
private Integer sekundenVon;
@Column
private Integer sekundenBis;
@ManyToOne
@JoinColumn(name = "gruppeId")
private AufgabenGruppeEntity aufgabenGruppe;
@Enumerated(EnumType.STRING)
@ElementCollection(targetClass = Werkzeug.class)
@CollectionTable(name = "strafe_benoetigtAktiv", joinColumns = @JoinColumn(name = "strafeId"))
@Column(name = "werkzeug")
private List<Werkzeug> benoetigtAktiv;
@Enumerated(EnumType.STRING)
@ElementCollection(targetClass = Werkzeug.class)
@CollectionTable(name = "strafe_benoetigtPassiv", joinColumns = @JoinColumn(name = "strafeId"))
@Column(name = "werkzeug")
private List<Werkzeug> benoetigtPassiv;
@ManyToMany(cascade = CascadeType.DETACH)
@JoinTable(name = "strafeToy", joinColumns = {@JoinColumn(name = "strafeId")}, inverseJoinColumns = {@JoinColumn(name = "toyId")})
private List<ToyEntity> benoetigteToys;
@Override
public String toString() {
return "StrafeEntity[id=" + strafeId + ", kurzText=" + kurzText + ", level=" + level
+ ", sekunden=" + sekundenVon + "-" + sekundenBis + "]";
}
public Strafe toStrafe() {
Strafe strafe = new Strafe();
strafe.setStrafeId(strafeId);
strafe.setBenoetigtAktiv(benoetigtAktiv != null ? new ArrayList<>(benoetigtAktiv) : new ArrayList<>());
strafe.setBenoetigteToys(benoetigteToys != null ? benoetigteToys.stream().map(ToyEntity::toToy).toList() : new ArrayList<>());
strafe.setBenoetigtPassiv(benoetigtPassiv != null ? new ArrayList<>(benoetigtPassiv) : new ArrayList<>());
strafe.setGruppeId(aufgabenGruppe.getGruppenId());
strafe.setKurzText(kurzText);
strafe.setLevel(level);
strafe.setSekundenBis(sekundenBis);
strafe.setSekundenVon(sekundenVon);
strafe.setText(text);
return strafe;
}
public static StrafeEntity create(Strafe strafe, AufgabenGruppeEntity aufgabenGruppeEntity, List<ToyEntity> toys) {
StrafeEntity entity = new StrafeEntity();
entity.setStrafeId(UUID.randomUUID());
entity.setAufgabenGruppe(aufgabenGruppeEntity);
entity.setBenoetigtAktiv(strafe.getBenoetigtAktiv());
entity.setBenoetigteToys(toys != null ? toys : new ArrayList<>());
entity.setBenoetigtPassiv(strafe.getBenoetigtPassiv());
entity.setKurzText(strafe.getKurzText());
entity.setLevel(strafe.getLevel());
entity.setSekundenBis(strafe.getSekundenBis());
entity.setSekundenVon(strafe.getSekundenVon());
entity.setText(strafe.getText());
return entity;
}
}

View File

@@ -1,58 +1,59 @@
package de.oaa.xxx.aufgaben.entity;
import de.oaa.xxx.aufgaben.Toy;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Lob;
import jakarta.persistence.Table;
import lombok.Getter;
import lombok.Setter;
import java.util.Base64;
import java.util.UUID;
@Getter
@Setter
@Entity
@Table(name = "toy")
public class ToyEntity {
@Id
@Column
private UUID toyId;
@Column
private String name;
@Column
private String beschreibung;
@Column
private UUID userId;
@Lob
@Column(columnDefinition = "BLOB")
private byte[] bild;
@Override
public String toString() {
return "ToyEntity[toyId=" + toyId + ", name=" + name + ", userId=" + userId + "]";
}
public Toy toToy() {
Toy toy = new Toy();
toy.setToyId(toyId);
toy.setName(name);
toy.setBeschreibung(beschreibung);
toy.setUserId(userId);
toy.setBild(bild != null ? Base64.getEncoder().encodeToString(bild) : null);
return toy;
}
public static ToyEntity create(Toy toy) {
ToyEntity entity = new ToyEntity();
entity.setToyId(UUID.randomUUID());
entity.setName(toy.getName());
entity.setBeschreibung(toy.getBeschreibung());
entity.setUserId(toy.getUserId());
entity.setBild(toy.getBild() != null ? Base64.getDecoder().decode(toy.getBild()) : null);
return entity;
}
}
package de.oaa.xxx.games.common.entity;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Lob;
import jakarta.persistence.Table;
import lombok.Getter;
import lombok.Setter;
import java.util.Base64;
import java.util.UUID;
import de.oaa.xxx.games.common.aufgaben.Toy;
@Getter
@Setter
@Entity
@Table(name = "toy")
public class ToyEntity {
@Id
@Column
private UUID toyId;
@Column
private String name;
@Column
private String beschreibung;
@Column
private UUID userId;
@Lob
@Column(columnDefinition = "BLOB")
private byte[] bild;
@Override
public String toString() {
return "ToyEntity[toyId=" + toyId + ", name=" + name + ", userId=" + userId + "]";
}
public Toy toToy() {
Toy toy = new Toy();
toy.setToyId(toyId);
toy.setName(name);
toy.setBeschreibung(beschreibung);
toy.setUserId(userId);
toy.setBild(bild != null ? Base64.getEncoder().encodeToString(bild) : null);
return toy;
}
public static ToyEntity create(Toy toy) {
ToyEntity entity = new ToyEntity();
entity.setToyId(UUID.randomUUID());
entity.setName(toy.getName());
entity.setBeschreibung(toy.getBeschreibung());
entity.setUserId(toy.getUserId());
entity.setBild(toy.getBild() != null ? Base64.getDecoder().decode(toy.getBild()) : null);
return entity;
}
}

View File

@@ -1,13 +1,14 @@
package de.oaa.xxx.aufgaben.repository;
import de.oaa.xxx.aufgaben.entity.AufgabeEntity;
import de.oaa.xxx.aufgaben.entity.AufgabenGruppeEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
import java.util.UUID;
public interface AufgabeRepository extends JpaRepository<AufgabeEntity, UUID> {
List<AufgabeEntity> findByAufgabenGruppeIn(List<AufgabenGruppeEntity> gruppen);
}
package de.oaa.xxx.games.common.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import de.oaa.xxx.games.common.entity.AufgabeEntity;
import de.oaa.xxx.games.common.entity.AufgabenGruppeEntity;
import java.util.List;
import java.util.UUID;
public interface AufgabeRepository extends JpaRepository<AufgabeEntity, UUID> {
List<AufgabeEntity> findByAufgabenGruppeIn(List<AufgabenGruppeEntity> gruppen);
}

View File

@@ -1,33 +1,40 @@
package de.oaa.xxx.aufgaben.repository;
import de.oaa.xxx.aufgaben.entity.AufgabenGruppeEntity;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import java.util.List;
import java.util.UUID;
public interface AufgabenGruppeRepository extends JpaRepository<AufgabenGruppeEntity, UUID> {
@Query("select age from AufgabenGruppeEntity age where age.userId = :userId")
List<AufgabenGruppeEntity> findByUserId(@Param("userId") UUID userId);
long countByUserId(UUID userId);
Page<AufgabenGruppeEntity> findByUserIdIsNull(Pageable pageable);
Page<AufgabenGruppeEntity> findByUserId(UUID userId, Pageable pageable);
@Query("select age from AufgabenGruppeEntity age where (age.privateGruppe = false or age.userId = :userId) and (:search is null or age.name like :search)")
List<AufgabenGruppeEntity> listWithUserAndSearch(@Param("userId") UUID userId, @Param("search") String search, PageRequest pageable);
@Query("select age from AufgabenGruppeEntity age where age.privateGruppe = false and (:search is null or age.name like :search)")
List<AufgabenGruppeEntity> listPublicWithSearch(@Param("search") String search, PageRequest pageable);
@Query("select age from AufgabenGruppeEntity age where age.privateGruppe = false and age.userId is not null and age.userId <> :userId and (:name is null or lower(age.name) like lower(:name))")
List<AufgabenGruppeEntity> findPublicFromOthers(@Param("userId") UUID userId, @Param("name") String name);
}
package de.oaa.xxx.games.common.repository;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import de.oaa.xxx.games.common.entity.AufgabenGruppeEntity;
import java.util.List;
import java.util.UUID;
public interface AufgabenGruppeRepository extends JpaRepository<AufgabenGruppeEntity, UUID> {
@Query("select age from AufgabenGruppeEntity age where age.userId = :userId")
List<AufgabenGruppeEntity> findByUserId(@Param("userId") UUID userId);
long countByUserId(UUID userId);
Page<AufgabenGruppeEntity> findByUserIdIsNull(Pageable pageable);
Page<AufgabenGruppeEntity> findByUserId(UUID userId, Pageable pageable);
@Query("select age from AufgabenGruppeEntity age where (age.privateGruppe = false or age.userId = :userId) and (:search is null or age.name like :search)")
List<AufgabenGruppeEntity> listWithUserAndSearch(@Param("userId") UUID userId, @Param("search") String search, PageRequest pageable);
@Query("select age from AufgabenGruppeEntity age where age.privateGruppe = false and (:search is null or age.name like :search)")
List<AufgabenGruppeEntity> listPublicWithSearch(@Param("search") String search, PageRequest pageable);
@Query("select age from AufgabenGruppeEntity age where age.privateGruppe = false and age.userId is not null and age.userId <> :userId and (:name is null or lower(age.name) like lower(:name))")
List<AufgabenGruppeEntity> findPublicFromOthers(@Param("userId") UUID userId, @Param("name") String name);
@Query("SELECT g FROM AufgabenGruppeEntity g WHERE (g.privateGruppe = false OR g.userId = :userId) AND g.strafen IS EMPTY AND g.sperren IS EMPTY AND (:search IS NULL OR g.name LIKE :search)")
List<AufgabenGruppeEntity> listVanillaSafeWithUserAndSearch(@Param("userId") UUID userId, @Param("search") String search, PageRequest pageable);
@Query("SELECT g FROM AufgabenGruppeEntity g WHERE g.privateGruppe = false AND g.userId IS NOT NULL AND g.userId <> :userId AND g.strafen IS EMPTY AND g.sperren IS EMPTY AND (:name IS NULL OR LOWER(g.name) LIKE LOWER(:name))")
List<AufgabenGruppeEntity> findVanillaSafePublicFromOthers(@Param("userId") UUID userId, @Param("name") String name);
}

View File

@@ -1,16 +1,17 @@
package de.oaa.xxx.aufgaben.repository;
import de.oaa.xxx.aufgaben.entity.FavoritEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
import java.util.UUID;
public interface FavoritRepository extends JpaRepository<FavoritEntity, UUID> {
List<FavoritEntity> findByUserId(UUID userId);
List<FavoritEntity> findByUserIdAndAufgabenGruppeId(UUID userId, UUID aufgabenGruppeId);
void deleteByAufgabenGruppeId(UUID aufgabenGruppeId);
}
package de.oaa.xxx.games.common.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import de.oaa.xxx.games.common.entity.FavoritEntity;
import java.util.List;
import java.util.UUID;
public interface FavoritRepository extends JpaRepository<FavoritEntity, UUID> {
List<FavoritEntity> findByUserId(UUID userId);
List<FavoritEntity> findByUserIdAndAufgabenGruppeId(UUID userId, UUID aufgabenGruppeId);
void deleteByAufgabenGruppeId(UUID aufgabenGruppeId);
}

View File

@@ -1,9 +1,10 @@
package de.oaa.xxx.aufgaben.repository;
import de.oaa.xxx.aufgaben.entity.FinisherEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.UUID;
public interface FinisherRepository extends JpaRepository<FinisherEntity, UUID> {
}
package de.oaa.xxx.games.common.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import de.oaa.xxx.games.common.entity.FinisherEntity;
import java.util.UUID;
public interface FinisherRepository extends JpaRepository<FinisherEntity, UUID> {
}

View File

@@ -1,21 +1,22 @@
package de.oaa.xxx.aufgaben.repository;
import de.oaa.xxx.aufgaben.entity.AufgabenGruppeEntity;
import de.oaa.xxx.aufgaben.entity.GruppenAboEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
import java.util.UUID;
public interface GruppenAboRepository extends JpaRepository<GruppenAboEntity, UUID> {
List<GruppenAboEntity> findByUserId(UUID userId);
boolean existsByUserIdAndAufgabenGruppe(UUID userId, AufgabenGruppeEntity gruppe);
void deleteByUserIdAndAufgabenGruppe(UUID userId, AufgabenGruppeEntity gruppe);
long countByAufgabenGruppe(AufgabenGruppeEntity gruppe);
void deleteByAufgabenGruppe(AufgabenGruppeEntity gruppe);
}
package de.oaa.xxx.games.common.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import de.oaa.xxx.games.common.entity.AufgabenGruppeEntity;
import de.oaa.xxx.games.common.entity.GruppenAboEntity;
import java.util.List;
import java.util.UUID;
public interface GruppenAboRepository extends JpaRepository<GruppenAboEntity, UUID> {
List<GruppenAboEntity> findByUserId(UUID userId);
boolean existsByUserIdAndAufgabenGruppe(UUID userId, AufgabenGruppeEntity gruppe);
void deleteByUserIdAndAufgabenGruppe(UUID userId, AufgabenGruppeEntity gruppe);
long countByAufgabenGruppe(AufgabenGruppeEntity gruppe);
void deleteByAufgabenGruppe(AufgabenGruppeEntity gruppe);
}

View File

@@ -1,13 +1,14 @@
package de.oaa.xxx.aufgaben.repository;
import de.oaa.xxx.aufgaben.entity.AufgabenGruppeEntity;
import de.oaa.xxx.aufgaben.entity.SperreEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
import java.util.UUID;
public interface SperreRepository extends JpaRepository<SperreEntity, UUID> {
List<SperreEntity> findByAufgabenGruppeIn(List<AufgabenGruppeEntity> gruppen);
}
package de.oaa.xxx.games.common.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import de.oaa.xxx.games.common.entity.AufgabenGruppeEntity;
import de.oaa.xxx.games.common.entity.SperreEntity;
import java.util.List;
import java.util.UUID;
public interface SperreRepository extends JpaRepository<SperreEntity, UUID> {
List<SperreEntity> findByAufgabenGruppeIn(List<AufgabenGruppeEntity> gruppen);
}

View File

@@ -1,13 +1,14 @@
package de.oaa.xxx.aufgaben.repository;
import de.oaa.xxx.aufgaben.entity.AufgabenGruppeEntity;
import de.oaa.xxx.aufgaben.entity.StrafeEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
import java.util.UUID;
public interface StrafeRepository extends JpaRepository<StrafeEntity, UUID> {
List<StrafeEntity> findByAufgabenGruppeIn(List<AufgabenGruppeEntity> gruppen);
}
package de.oaa.xxx.games.common.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import de.oaa.xxx.games.common.entity.AufgabenGruppeEntity;
import de.oaa.xxx.games.common.entity.StrafeEntity;
import java.util.List;
import java.util.UUID;
public interface StrafeRepository extends JpaRepository<StrafeEntity, UUID> {
List<StrafeEntity> findByAufgabenGruppeIn(List<AufgabenGruppeEntity> gruppen);
}

View File

@@ -1,41 +1,42 @@
package de.oaa.xxx.aufgaben.repository;
import de.oaa.xxx.aufgaben.entity.ToyEntity;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
public interface ToyRepository extends JpaRepository<ToyEntity, UUID> {
Page<ToyEntity> findByUserIdIsNull(Pageable pageable);
Page<ToyEntity> findByUserId(UUID userId, Pageable pageable);
long countByUserId(UUID userId);
List<ToyEntity> findByUserId(UUID userId);
boolean existsByNameIgnoreCaseAndUserIdIsNull(String name);
boolean existsByNameIgnoreCaseAndUserId(String name, UUID userId);
boolean existsByNameIgnoreCaseAndUserIdIsNullAndToyIdNot(String name, UUID toyId);
boolean existsByNameIgnoreCaseAndUserIdAndToyIdNot(String name, UUID userId, UUID toyId);
Optional<ToyEntity> findByNameIgnoreCaseAndUserId(String name, UUID userId);
@Query("SELECT COUNT(a) FROM AufgabeEntity a JOIN a.benoetigteToys t WHERE t.toyId = :toyId")
long countAufgabeUsage(@Param("toyId") UUID toyId);
@Query("SELECT COUNT(s) FROM StrafeEntity s JOIN s.benoetigteToys t WHERE t.toyId = :toyId")
long countStrafeUsage(@Param("toyId") UUID toyId);
@Query("SELECT COUNT(sp) FROM SperreEntity sp JOIN sp.benoetigteToys t WHERE t.toyId = :toyId")
long countSperreUsage(@Param("toyId") UUID toyId);
}
package de.oaa.xxx.games.common.repository;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import de.oaa.xxx.games.common.entity.ToyEntity;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
public interface ToyRepository extends JpaRepository<ToyEntity, UUID> {
Page<ToyEntity> findByUserIdIsNull(Pageable pageable);
Page<ToyEntity> findByUserId(UUID userId, Pageable pageable);
long countByUserId(UUID userId);
List<ToyEntity> findByUserId(UUID userId);
boolean existsByNameIgnoreCaseAndUserIdIsNull(String name);
boolean existsByNameIgnoreCaseAndUserId(String name, UUID userId);
boolean existsByNameIgnoreCaseAndUserIdIsNullAndToyIdNot(String name, UUID toyId);
boolean existsByNameIgnoreCaseAndUserIdAndToyIdNot(String name, UUID userId, UUID toyId);
Optional<ToyEntity> findByNameIgnoreCaseAndUserId(String name, UUID userId);
@Query("SELECT COUNT(a) FROM AufgabeEntity a JOIN a.benoetigteToys t WHERE t.toyId = :toyId")
long countAufgabeUsage(@Param("toyId") UUID toyId);
@Query("SELECT COUNT(s) FROM StrafeEntity s JOIN s.benoetigteToys t WHERE t.toyId = :toyId")
long countStrafeUsage(@Param("toyId") UUID toyId);
@Query("SELECT COUNT(sp) FROM SperreEntity sp JOIN sp.benoetigteToys t WHERE t.toyId = :toyId")
long countSperreUsage(@Param("toyId") UUID toyId);
}

View File

@@ -0,0 +1,23 @@
package de.oaa.xxx.games.vanilla;
import lombok.Getter;
import lombok.Setter;
import java.util.UUID;
@Getter
@Setter
public class VanillaAufgabeAnzeige {
private String nameAktiverMitspieler;
private String aufgabeText;
private Integer timer;
private Integer level;
private UUID mitspielerId;
private boolean eigenesGeraet;
@Override
public String toString() {
return "VanillaAufgabeAnzeige[mitspieler=" + nameAktiverMitspieler + ", level=" + level + ", timer=" + timer + "]";
}
}

View File

@@ -0,0 +1,17 @@
package de.oaa.xxx.games.vanilla;
import lombok.Getter;
import lombok.Setter;
import java.time.LocalDateTime;
import java.util.UUID;
@Getter @Setter
public class VanillaGame {
private UUID sessionId;
private UUID userId;
private UUID setupId;
private Integer aufgabenProLevel;
private Integer level;
private Integer aufgabenAufAktuellemLevel;
private LocalDateTime startZeit;
private LocalDateTime letzteAktivitaet;
}

View File

@@ -0,0 +1,128 @@
package de.oaa.xxx.games.vanilla;
import com.fasterxml.jackson.databind.ObjectMapper;
import de.oaa.xxx.games.common.aufgaben.Aufgabe;
import de.oaa.xxx.games.common.aufgaben.AufgabenList;
import de.oaa.xxx.games.bdsm.GeschlechtEnum;
import de.oaa.xxx.games.bdsm.RolleEnum;
import de.oaa.xxx.games.vanilla.entity.VanillaGameEntity;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class VanillaGameDurchfuehren {
private final AufgabenList aufgabenList;
private final List<VanillaMitspieler> mitspieler = new ArrayList<>();
private int aufgabenProLevel;
private int level;
private int aufgabenAufAktuellemLevel;
public VanillaGameDurchfuehren(VanillaGameEntity entity) throws Exception {
ObjectMapper objectMapper = new ObjectMapper();
aufgabenList = objectMapper.readValue(entity.getAufgaben(), AufgabenList.class);
entity.getMitspieler().forEach(m -> mitspieler.add(m.toMitspieler()));
this.aufgabenProLevel = entity.getAufgabenProLevel() != null ? entity.getAufgabenProLevel() : 5;
this.level = entity.getLevel() != null ? entity.getLevel() : 1;
this.aufgabenAufAktuellemLevel = entity.getAufgabenAufAktuellemLevel() != null ? entity.getAufgabenAufAktuellemLevel() : 0;
}
public int getLevel() { return level; }
public int getAufgabenAufAktuellemLevel() { return aufgabenAufAktuellemLevel; }
public VanillaAufgabeAnzeige getNext() {
checkLevel();
if (level == 6) return null;
VanillaAufgabeAnzeige anzeige = findeAufgabe();
if (anzeige != null) return anzeige;
// Fallback
VanillaMitspieler aktiv = findeMitspielerMitRolle(RolleEnum.AUFGABE_AKTIV);
VanillaMitspieler passiv = findeMitspielerMitRolle(RolleEnum.AUFGABE_PASSIV, aktiv);
VanillaAufgabeAnzeige fallback = new VanillaAufgabeAnzeige();
fallback.setNameAktiverMitspieler(aktiv != null ? aktiv.getName() : "");
if (aktiv != null) { fallback.setMitspielerId(aktiv.getId()); fallback.setEigenesGeraet(aktiv.isEigenesGeraet()); }
fallback.setAufgabeText("Keine passende Aufgabe gefunden. Überbrückt die Zeit mit Kuscheln.");
fallback.setTimer(120);
return fallback;
}
public void backToLvl5() { this.level = 5; this.aufgabenAufAktuellemLevel = 0; }
public List<VanillaAufgabeAnzeige> getFinisher() {
var list = new ArrayList<VanillaAufgabeAnzeige>();
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);
var finishers = aufgabenList.getFinisher().stream()
.filter(f -> geschlecht == f.getGeschlecht() && f.isAufgabePassend(partner != null ? toMitspielerBdsm(partner) : null, toMitspielerBdsm(cumming)))
.toList();
VanillaAufgabeAnzeige anzeige = new VanillaAufgabeAnzeige();
anzeige.setNameAktiverMitspieler(cumming.getName());
anzeige.setMitspielerId(cumming.getId());
anzeige.setEigenesGeraet(cumming.isEigenesGeraet());
if (!finishers.isEmpty()) {
var f = finishers.get(new Random().nextInt(finishers.size()));
anzeige.setAufgabeText(getAnzeigeText(f.getText(), cumming.getName(), partner != null ? partner.getName() : ""));
} else {
anzeige.setAufgabeText(cumming.getName() + " geht heute leider leer aus...");
}
list.add(anzeige);
});
});
return list;
}
private void checkLevel() {
if (++aufgabenAufAktuellemLevel >= 1 + aufgabenProLevel) {
aufgabenAufAktuellemLevel = 0;
level++;
}
}
private VanillaAufgabeAnzeige findeAufgabe() {
VanillaMitspieler aktiv = findeMitspielerMitRolle(RolleEnum.AUFGABE_AKTIV);
if (aktiv == null) return null;
VanillaMitspieler passiv = findeMitspielerMitRolle(RolleEnum.AUFGABE_PASSIV, aktiv);
de.oaa.xxx.games.bdsm.Mitspieler aktivBdsm = toMitspielerBdsm(aktiv);
de.oaa.xxx.games.bdsm.Mitspieler passivBdsm = passiv != null ? toMitspielerBdsm(passiv) : null;
List<Aufgabe> passende = aufgabenList.getAufgaben().stream()
.filter(a -> a.isAufgabePassend(level, aktivBdsm, passivBdsm != null ? passivBdsm : aktivBdsm))
.toList();
if (passende.isEmpty()) return null;
Aufgabe aufgabe = passende.get(new Random().nextInt(passende.size()));
VanillaAufgabeAnzeige anzeige = new VanillaAufgabeAnzeige();
anzeige.setNameAktiverMitspieler(aktiv.getName());
anzeige.setMitspielerId(aktiv.getId());
anzeige.setEigenesGeraet(aktiv.isEigenesGeraet());
anzeige.setAufgabeText(getAnzeigeText(aufgabe.getText(), aktiv.getName(), passiv != null ? passiv.getName() : ""));
if (aufgabe.getSekundenVon() != null && aufgabe.getSekundenBis() != null && aufgabe.getSekundenBis() > 0) {
anzeige.setTimer(new Random().nextInt(aufgabe.getSekundenVon(), aufgabe.getSekundenBis() + 1));
}
return anzeige;
}
private VanillaMitspieler findeMitspielerMitRolle(RolleEnum rolle) { return findeMitspielerMitRolle(rolle, null); }
private VanillaMitspieler findeMitspielerMitRolle(RolleEnum rolle, VanillaMitspieler ausschliessen) {
List<VanillaMitspieler> kandidaten = mitspieler.stream()
.filter(m -> m.getRollen().contains(rolle) && !m.equals(ausschliessen))
.toList();
if (kandidaten.isEmpty()) return null;
return kandidaten.get(new Random().nextInt(kandidaten.size()));
}
private de.oaa.xxx.games.bdsm.Mitspieler toMitspielerBdsm(VanillaMitspieler vm) {
de.oaa.xxx.games.bdsm.Mitspieler m = new de.oaa.xxx.games.bdsm.Mitspieler();
m.setId(vm.getId()); m.setName(vm.getName()); m.setGeschlecht(vm.getGeschlecht());
m.setRollen(vm.getRollen()); m.setSpieltMit(vm.getSpieltMit());
m.setVerfuegbareWerkzeuge(vm.getVerfuegbareWerkzeuge()); m.setEigenesGeraet(vm.isEigenesGeraet());
return m;
}
private String getAnzeigeText(String text, String aktiv, String passiv) {
if (text == null) return "";
return text.replace("{AKTIV}", aktiv != null ? aktiv : "").replace("{PASSIV}", passiv != null ? passiv : "");
}
}

View File

@@ -0,0 +1,24 @@
package de.oaa.xxx.games.vanilla;
import de.oaa.xxx.games.bdsm.GeschlechtEnum;
import de.oaa.xxx.games.bdsm.RolleEnum;
import de.oaa.xxx.games.common.aufgaben.Werkzeug;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
import java.util.UUID;
@Getter @Setter
public class VanillaMitspieler {
private UUID id;
private UUID userId;
private String name;
private GeschlechtEnum geschlecht;
private List<RolleEnum> rollen;
private List<GeschlechtEnum> spieltMit;
private List<Werkzeug> verfuegbareWerkzeuge;
private boolean eigenesGeraet;
public boolean isVerfuegbar(Werkzeug werkzeug) {
return verfuegbareWerkzeuge != null && verfuegbareWerkzeuge.contains(werkzeug);
}
}

View File

@@ -0,0 +1,160 @@
package de.oaa.xxx.games.vanilla.controller;
import de.oaa.xxx.games.common.aufgaben.AufgabenGruppe;
import de.oaa.xxx.games.common.aufgaben.AufgabenGruppePage;
import de.oaa.xxx.games.common.entity.AufgabenGruppeEntity;
import de.oaa.xxx.games.common.entity.GruppenAboEntity;
import de.oaa.xxx.games.common.repository.AufgabenGruppeRepository;
import de.oaa.xxx.games.common.repository.GruppenAboRepository;
import de.oaa.xxx.user.UserEntity;
import de.oaa.xxx.user.UserRepository;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.DeleteMapping;
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.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.security.Principal;
import java.util.Comparator;
import java.util.List;
import java.util.UUID;
@RestController
@RequestMapping("/vanilla/abo")
@Transactional
public class VanillaAboController {
private static final Logger LOGGER = LoggerFactory.getLogger(VanillaAboController.class);
private static final int DEFAULT_PAGE_SIZE = 5;
private static final int DISCOVER_PAGE_SIZE = 10;
private final GruppenAboRepository aboRepository;
private final AufgabenGruppeRepository gruppeRepository;
private final UserRepository userRepository;
public VanillaAboController(GruppenAboRepository aboRepository,
AufgabenGruppeRepository gruppeRepository,
UserRepository userRepository) {
this.aboRepository = aboRepository;
this.gruppeRepository = gruppeRepository;
this.userRepository = userRepository;
}
// ── Abonnierte Gruppen laden (nur vanilla-safe) ──
@GetMapping("/list")
public ResponseEntity<AufgabenGruppePage> listSubscribed(
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "" + DEFAULT_PAGE_SIZE) int size,
Principal principal) {
UserEntity user = resolveUser(principal);
if (user == null) return ResponseEntity.status(401).build();
List<AufgabenGruppe> dtos = aboRepository.findByUserId(user.getUserId()).stream()
.map(GruppenAboEntity::getAufgabenGruppe)
.filter(g -> !g.isPrivateGruppe())
.filter(g -> g.getStrafen().isEmpty() && g.getSperren().isEmpty())
.map(g -> enrich(g, user.getUserId(), true))
.sorted(Comparator.comparing(AufgabenGruppe::getName, String.CASE_INSENSITIVE_ORDER))
.toList();
return ResponseEntity.ok(manualPage(dtos, page, size));
}
// ── Entdecken (nur vanilla-safe Gruppen von anderen) ──
@GetMapping("/discover")
public ResponseEntity<AufgabenGruppePage> discover(
@RequestParam(required = false) String name,
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "" + DISCOVER_PAGE_SIZE) int size,
Principal principal) {
UserEntity user = resolveUser(principal);
if (user == null) return ResponseEntity.status(401).build();
String namePattern = name != null && !name.isBlank() ? "%" + name.trim() + "%" : null;
List<AufgabenGruppe> dtos = gruppeRepository
.findVanillaSafePublicFromOthers(user.getUserId(), namePattern).stream()
.map(g -> enrich(g, user.getUserId(), aboRepository.existsByUserIdAndAufgabenGruppe(user.getUserId(), g)))
.sorted(Comparator.comparingLong(AufgabenGruppe::getSubscriberCount).reversed()
.thenComparing(AufgabenGruppe::getName, String.CASE_INSENSITIVE_ORDER))
.toList();
return ResponseEntity.ok(manualPage(dtos, page, size));
}
// ── Abonnieren (nur vanilla-safe) ──
@PostMapping("/{gruppenId}")
public ResponseEntity<Void> subscribe(@PathVariable UUID gruppenId, Principal principal) {
UserEntity user = resolveUser(principal);
if (user == null) return ResponseEntity.status(401).build();
AufgabenGruppeEntity gruppe = gruppeRepository.findById(gruppenId).orElse(null);
if (gruppe == null || gruppe.isPrivateGruppe() || user.getUserId().equals(gruppe.getUserId())) {
return ResponseEntity.badRequest().build();
}
// Vanilla-safe validation
if (!gruppe.getStrafen().isEmpty() || !gruppe.getSperren().isEmpty()) {
return ResponseEntity.status(403).build();
}
if (aboRepository.existsByUserIdAndAufgabenGruppe(user.getUserId(), gruppe)) {
return ResponseEntity.ok().build();
}
GruppenAboEntity abo = new GruppenAboEntity();
abo.setAboId(UUID.randomUUID());
abo.setUserId(user.getUserId());
abo.setAufgabenGruppe(gruppe);
aboRepository.save(abo);
LOGGER.info("User {} hat Vanilla-Gruppe {} abonniert", user.getUserId(), gruppenId);
return ResponseEntity.status(201).build();
}
// ── Abonnement kündigen ──
@DeleteMapping("/{gruppenId}")
public ResponseEntity<Void> unsubscribe(@PathVariable UUID gruppenId, Principal principal) {
UserEntity user = resolveUser(principal);
if (user == null) return ResponseEntity.status(401).build();
AufgabenGruppeEntity gruppe = gruppeRepository.findById(gruppenId).orElse(null);
if (gruppe == null) return ResponseEntity.noContent().build();
aboRepository.deleteByUserIdAndAufgabenGruppe(user.getUserId(), gruppe);
LOGGER.info("User {} hat Vanilla-Abo auf Gruppe {} beendet", user.getUserId(), gruppenId);
return ResponseEntity.accepted().build();
}
// ── Hilfsmethoden ──
private AufgabenGruppe enrich(AufgabenGruppeEntity entity, UUID userId, boolean subscribed) {
AufgabenGruppe g = entity.toAufgabenGruppe();
g.setSubscriberCount(aboRepository.countByAufgabenGruppe(entity));
g.setSubscribed(subscribed);
return g;
}
private AufgabenGruppePage manualPage(List<AufgabenGruppe> all, int page, int size) {
int total = all.size();
int start = page * size;
List<AufgabenGruppe> content = start >= total ? List.of() : all.subList(start, Math.min(start + size, total));
AufgabenGruppePage result = new AufgabenGruppePage();
result.setContent(content);
result.setCurrentPage(page);
result.setTotalPages(total == 0 ? 1 : (int) Math.ceil((double) total / size));
result.setTotalElements(total);
return result;
}
private UserEntity resolveUser(Principal principal) {
return userRepository.findByEmail(principal.getName()).orElse(null);
}
}

View File

@@ -0,0 +1,128 @@
package de.oaa.xxx.games.vanilla.controller;
import de.oaa.xxx.games.common.aufgaben.Aufgabe;
import de.oaa.xxx.games.common.aufgaben.Toy;
import de.oaa.xxx.games.common.entity.AufgabeEntity;
import de.oaa.xxx.games.common.entity.AufgabenGruppeEntity;
import de.oaa.xxx.games.common.entity.ToyEntity;
import de.oaa.xxx.games.common.repository.AufgabeRepository;
import de.oaa.xxx.games.common.repository.AufgabenGruppeRepository;
import de.oaa.xxx.games.common.repository.ToyRepository;
import de.oaa.xxx.subscription.SubscriptionLimitService;
import de.oaa.xxx.user.UserRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.DeleteMapping;
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.RestController;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
import java.security.Principal;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
@RestController
@RequestMapping("/vanilla/aufgabe")
@Transactional
public class VanillaAufgabeController {
private static final Logger LOGGER = LoggerFactory.getLogger(VanillaAufgabeController.class);
private final AufgabeRepository aufgabeRepository;
private final AufgabenGruppeRepository gruppeRepository;
private final ToyRepository toyRepository;
private final UserRepository userRepository;
private final SubscriptionLimitService limitService;
public VanillaAufgabeController(AufgabeRepository aufgabeRepository,
AufgabenGruppeRepository gruppeRepository,
ToyRepository toyRepository,
UserRepository userRepository,
SubscriptionLimitService limitService) {
this.aufgabeRepository = aufgabeRepository;
this.gruppeRepository = gruppeRepository;
this.toyRepository = toyRepository;
this.userRepository = userRepository;
this.limitService = limitService;
}
@GetMapping("/{aufgabeId}")
public ResponseEntity<Aufgabe> get(@PathVariable UUID aufgabeId) {
return aufgabeRepository.findById(aufgabeId)
.map(entity -> ResponseEntity.ok(entity.toAufgabe()))
.orElse(ResponseEntity.noContent().build());
}
@PostMapping
public ResponseEntity<Void> create(@RequestBody Aufgabe aufgabe, Principal principal) {
if (aufgabe.getKurzText() == null || aufgabe.getText() == null || aufgabe.getLevel() == null || aufgabe.getGruppeId() == null) {
return ResponseEntity.badRequest().build();
}
AufgabenGruppeEntity gruppeEntity = gruppeRepository.findById(aufgabe.getGruppeId()).orElse(null);
if (gruppeEntity == null) {
return ResponseEntity.badRequest().build();
}
var ownerOpt = userRepository.findByEmail(principal.getName());
int limit = ownerOpt.map(u -> limitService.maxTasksPerGroup(u.getUserId()))
.orElse(SubscriptionLimitService.STANDARD_MAX_TASKS_PER_GROUP);
if (gruppeEntity.getAufgaben().size() >= limit) {
return ResponseEntity.status(409).build();
}
List<ToyEntity> toys = resolveToys(aufgabe.getBenoetigteToys());
AufgabeEntity entity = AufgabeEntity.create(aufgabe, gruppeEntity, toys);
aufgabeRepository.save(entity);
LOGGER.debug("Vanilla-Aufgabe {} '{}' in Gruppe {} erstellt", entity.getAufgabeId(), entity.getKurzText(), aufgabe.getGruppeId());
return ResponseEntity.created(
ServletUriComponentsBuilder.fromCurrentRequest().path("/{id}").buildAndExpand(entity.getAufgabeId()).toUri()
).build();
}
@PutMapping("/{aufgabeId}")
public ResponseEntity<Void> update(@PathVariable UUID aufgabeId, @RequestBody Aufgabe aufgabe) {
if (aufgabe.getKurzText() == null || aufgabe.getText() == null || aufgabe.getLevel() == null) {
return ResponseEntity.badRequest().build();
}
AufgabeEntity entity = aufgabeRepository.findById(aufgabeId).orElse(null);
if (entity == null) return ResponseEntity.notFound().build();
entity.setKurzText(aufgabe.getKurzText());
entity.setText(aufgabe.getText());
entity.setLevel(aufgabe.getLevel());
entity.setSekundenVon(aufgabe.getSekundenVon());
entity.setSekundenBis(aufgabe.getSekundenBis());
entity.setBenoetigtAktiv(aufgabe.getBenoetigtAktiv());
entity.setBenoetigtPassiv(aufgabe.getBenoetigtPassiv());
entity.setBenoetigteToys(resolveToys(aufgabe.getBenoetigteToys()));
aufgabeRepository.save(entity);
LOGGER.debug("Vanilla-Aufgabe {} aktualisiert", aufgabeId);
return ResponseEntity.ok().build();
}
@DeleteMapping
public ResponseEntity<Void> delete(@RequestBody Aufgabe aufgabe) {
try {
aufgabeRepository.findById(aufgabe.getAufgabeId()).ifPresent(aufgabeRepository::delete);
return ResponseEntity.accepted().build();
} catch (Exception exception) {
LOGGER.error(exception.getMessage(), exception);
return ResponseEntity.internalServerError().build();
}
}
private List<ToyEntity> resolveToys(List<Toy> toys) {
if (toys == null || toys.isEmpty()) return new ArrayList<>();
List<UUID> ids = toys.stream()
.filter(t -> t.getToyId() != null)
.map(Toy::getToyId)
.toList();
if (ids.isEmpty()) return new ArrayList<>();
return toyRepository.findAllById(ids);
}
}

View File

@@ -0,0 +1,284 @@
package de.oaa.xxx.games.vanilla.controller;
import java.security.Principal;
import java.util.Base64;
import java.util.UUID;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.DeleteMapping;
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 org.springframework.web.servlet.support.ServletUriComponentsBuilder;
import de.oaa.xxx.games.common.aufgaben.AufgabenGruppe;
import de.oaa.xxx.games.common.aufgaben.AufgabenGruppeList;
import de.oaa.xxx.games.common.aufgaben.AufgabenGruppePage;
import de.oaa.xxx.games.common.aufgaben.AufgabenGruppeService;
import de.oaa.xxx.games.common.entity.AufgabenGruppeEntity;
import de.oaa.xxx.games.common.repository.AufgabeRepository;
import de.oaa.xxx.games.common.repository.AufgabenGruppeRepository;
import de.oaa.xxx.games.common.repository.FinisherRepository;
import de.oaa.xxx.games.common.repository.GruppenAboRepository;
import de.oaa.xxx.games.common.repository.SperreRepository;
import de.oaa.xxx.games.common.repository.StrafeRepository;
import de.oaa.xxx.subscription.SubscriptionLimitService;
import de.oaa.xxx.user.UserEntity;
import de.oaa.xxx.user.UserRepository;
@RestController
@RequestMapping("/vanilla/gruppe")
@Transactional
public class VanillaAufgabenGruppeController {
private static final Logger LOGGER = LoggerFactory.getLogger(VanillaAufgabenGruppeController.class);
private static final int DEFAULT_PAGE_SIZE = 5;
private final AufgabenGruppeRepository gruppeRepository;
private final AufgabeRepository aufgabeRepository;
private final StrafeRepository strafeRepository;
private final SperreRepository sperreRepository;
private final FinisherRepository finisherRepository;
private final UserRepository userRepository;
private final GruppenAboRepository aboRepository;
private final AufgabenGruppeService aufgabenGruppeService;
private final SubscriptionLimitService limitService;
public VanillaAufgabenGruppeController(AufgabenGruppeRepository gruppeRepository,
AufgabeRepository aufgabeRepository,
StrafeRepository strafeRepository,
SperreRepository sperreRepository,
FinisherRepository finisherRepository,
UserRepository userRepository,
GruppenAboRepository aboRepository,
AufgabenGruppeService aufgabenGruppeService,
SubscriptionLimitService limitService) {
this.gruppeRepository = gruppeRepository;
this.aufgabeRepository = aufgabeRepository;
this.strafeRepository = strafeRepository;
this.sperreRepository = sperreRepository;
this.finisherRepository = finisherRepository;
this.userRepository = userRepository;
this.aboRepository = aboRepository;
this.aufgabenGruppeService = aufgabenGruppeService;
this.limitService = limitService;
}
// ── Paginierte Listen ──
@GetMapping("/list/user")
public ResponseEntity<AufgabenGruppePage> listUser(
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "" + DEFAULT_PAGE_SIZE) int size,
Principal principal) {
UserEntity user = resolveUser(principal);
if (user == null) return ResponseEntity.status(401).build();
// Only vanilla-safe user groups (no Strafen, no Sperren)
UUID userId = user.getUserId();
String searchPattern = null;
java.util.List<AufgabenGruppeEntity> all = gruppeRepository.listVanillaSafeWithUserAndSearch(
userId, searchPattern, PageRequest.of(0, 500, Sort.by("name")));
java.util.List<AufgabenGruppeEntity> ownOnly = all.stream()
.filter(g -> userId.equals(g.getUserId())).toList();
AufgabenGruppePage result = manualPage(ownOnly.stream().map(entity -> {
AufgabenGruppe g = entity.toAufgabenGruppe();
g.setSubscriberCount(aboRepository.countByAufgabenGruppe(entity));
return g;
}).toList(), page, DEFAULT_PAGE_SIZE);
return ResponseEntity.ok(result);
}
@GetMapping("/list/system")
public ResponseEntity<AufgabenGruppePage> listSystem(
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "" + DEFAULT_PAGE_SIZE) int size) {
// Only vanilla-safe system groups (userId IS NULL → no strafen/sperren anyway, but filter for safety)
Page<AufgabenGruppeEntity> result = gruppeRepository.findByUserIdIsNull(
PageRequest.of(page, size, Sort.by("name")));
AufgabenGruppePage r = new AufgabenGruppePage();
r.setContent(result.getContent().stream()
.filter(g -> g.getStrafen().isEmpty() && g.getSperren().isEmpty())
.map(AufgabenGruppeEntity::toAufgabenGruppe).toList());
r.setCurrentPage(result.getNumber());
r.setTotalPages(result.getTotalPages());
r.setTotalElements(result.getTotalElements());
return ResponseEntity.ok(r);
}
// ── Bestehende Endpunkte ──
@GetMapping("/all")
public ResponseEntity<AufgabenGruppeList> getAll(@RequestParam(required = false) String search) {
UUID userId = (UUID) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
String searchPattern = search != null ? "%" + search + "%" : null;
AufgabenGruppeList list = new AufgabenGruppeList();
list.setGruppen(gruppeRepository.listVanillaSafeWithUserAndSearch(userId, searchPattern, PageRequest.of(0, 500))
.stream().map(AufgabenGruppeEntity::toAufgabenGruppeDisplay).toList());
return ResponseEntity.ok(list);
}
@GetMapping("/own")
public ResponseEntity<AufgabenGruppeList> getOwn(@RequestParam UUID userId) {
AufgabenGruppeList list = new AufgabenGruppeList();
list.setGruppen(gruppeRepository.findByUserId(userId).stream()
.filter(g -> g.getStrafen().isEmpty() && g.getSperren().isEmpty())
.map(AufgabenGruppeEntity::toAufgabenGruppeDisplay).toList());
return ResponseEntity.ok(list);
}
@GetMapping("/{gruppeId}")
public ResponseEntity<AufgabenGruppe> get(@PathVariable UUID gruppeId) {
return gruppeRepository.findById(gruppeId)
.filter(g -> g.getStrafen().isEmpty() && g.getSperren().isEmpty())
.map(entity -> ResponseEntity.ok(entity.toAufgabenGruppe()))
.orElse(ResponseEntity.status(403).build());
}
// ── Anlegen ──
@PostMapping
public ResponseEntity<Void> create(@RequestBody AufgabenGruppe gruppe, Principal principal) {
if (gruppe.getName() == null || gruppe.getName().isBlank()) {
return ResponseEntity.badRequest().build();
}
UserEntity user = resolveUser(principal);
if (user == null) return ResponseEntity.status(401).build();
if (gruppeRepository.countByUserId(user.getUserId()) >= limitService.maxTaskGroups(user.getUserId())) {
return ResponseEntity.status(409).build();
}
AufgabenGruppeEntity entity = AufgabenGruppeEntity.create(gruppe);
entity.setUserId(user.getUserId());
entity.setPrivateGruppe(true);
gruppeRepository.save(entity);
LOGGER.debug("User {} hat Vanilla-AufgabenGruppe '{}' ({}) erstellt", user.getUserId(), entity.getName(), entity.getGruppenId());
return ResponseEntity.created(
ServletUriComponentsBuilder.fromCurrentRequest().path("/{id}").buildAndExpand(entity.getGruppenId()).toUri()
).build();
}
// ── Bearbeiten ──
@PutMapping("/{gruppeId}")
public ResponseEntity<Void> update(@PathVariable UUID gruppeId,
@RequestBody AufgabenGruppe gruppe,
Principal principal) {
if (gruppe.getName() == null || gruppe.getName().isBlank()) {
return ResponseEntity.badRequest().build();
}
UserEntity user = resolveUser(principal);
if (user == null) return ResponseEntity.status(401).build();
AufgabenGruppeEntity entity = gruppeRepository.findById(gruppeId).orElse(null);
if (entity == null) return ResponseEntity.notFound().build();
if (!user.getUserId().equals(entity.getUserId())) return ResponseEntity.status(403).build();
// Vanilla-safe check: cannot edit a non-vanilla-safe group
if (!entity.getStrafen().isEmpty() || !entity.getSperren().isEmpty()) return ResponseEntity.status(403).build();
entity.setName(gruppe.getName().trim());
entity.setBeschreibung(gruppe.getBeschreibung());
entity.setVon(gruppe.getVon());
entity.setPrivateGruppe(gruppe.isPrivateGruppe());
if (gruppe.getBild() != null) {
entity.setBild(Base64.getDecoder().decode(gruppe.getBild()));
}
gruppeRepository.save(entity);
LOGGER.debug("User {} hat Vanilla-AufgabenGruppe {} aktualisiert", user.getUserId(), gruppeId);
return ResponseEntity.ok().build();
}
// ── Kopieren (Systemgruppe → eigene) ──
@PostMapping("/copy/{gruppeId}")
public ResponseEntity<Void> copy(@PathVariable UUID gruppeId, Principal principal) {
UserEntity user = resolveUser(principal);
if (user == null) return ResponseEntity.status(401).build();
// Only allow copying vanilla-safe groups
AufgabenGruppeEntity source = gruppeRepository.findById(gruppeId).orElse(null);
if (source == null) return ResponseEntity.notFound().build();
if (!source.getStrafen().isEmpty() || !source.getSperren().isEmpty()) return ResponseEntity.status(403).build();
try {
aufgabenGruppeService.copyGruppe(gruppeId, user.getUserId());
return ResponseEntity.status(201).build();
} catch (IllegalStateException e) {
return ResponseEntity.status(409).build();
} catch (IllegalArgumentException e) {
String msg = e.getMessage();
if (msg != null && msg.contains("nicht gefunden")) return ResponseEntity.notFound().build();
return ResponseEntity.status(403).build();
}
}
// ── Löschen ──
@DeleteMapping("/{gruppeId}")
public ResponseEntity<Void> deleteById(@PathVariable UUID gruppeId, Principal principal) {
UserEntity user = resolveUser(principal);
if (user == null) return ResponseEntity.status(401).build();
AufgabenGruppeEntity entity = gruppeRepository.findById(gruppeId).orElse(null);
if (entity == null) return ResponseEntity.noContent().build();
if (!user.getUserId().equals(entity.getUserId())) return ResponseEntity.status(403).build();
// Only allow deletion of vanilla-safe groups
if (!entity.getStrafen().isEmpty() || !entity.getSperren().isEmpty()) return ResponseEntity.status(403).build();
try {
aboRepository.deleteByAufgabenGruppe(entity);
aufgabeRepository.deleteAll(entity.getAufgaben());
strafeRepository.deleteAll(entity.getStrafen());
sperreRepository.deleteAll(entity.getSperren());
finisherRepository.deleteAll(entity.getFinisher());
gruppeRepository.delete(entity);
return ResponseEntity.accepted().build();
} catch (Exception e) {
LOGGER.error(e.getMessage(), e);
return ResponseEntity.internalServerError().build();
}
}
@DeleteMapping
public ResponseEntity<Void> delete(@RequestBody AufgabenGruppe gruppe) {
try {
gruppeRepository.findById(gruppe.getGruppenId()).ifPresent(entity -> {
if (entity.getStrafen().isEmpty() && entity.getSperren().isEmpty()) {
gruppeRepository.delete(entity);
}
});
return ResponseEntity.accepted().build();
} catch (Exception exception) {
LOGGER.error(exception.getMessage(), exception);
return ResponseEntity.internalServerError().build();
}
}
// ── Hilfsmethoden ──
private UserEntity resolveUser(Principal principal) {
return userRepository.findByEmail(principal.getName()).orElse(null);
}
private AufgabenGruppePage manualPage(java.util.List<AufgabenGruppe> all, int page, int size) {
int total = all.size();
int start = page * size;
java.util.List<AufgabenGruppe> content = start >= total ? java.util.List.of() : all.subList(start, Math.min(start + size, total));
AufgabenGruppePage result = new AufgabenGruppePage();
result.setContent(content);
result.setCurrentPage(page);
result.setTotalPages(total == 0 ? 1 : (int) Math.ceil((double) total / size));
result.setTotalElements(total);
return result;
}
}

View File

@@ -0,0 +1,247 @@
package de.oaa.xxx.games.vanilla.controller;
import java.security.Principal;
import java.time.LocalDateTime;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.DeleteMapping;
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.games.vanilla.entity.VanillaEinladungEntity;
import de.oaa.xxx.games.vanilla.entity.VanillaEinladungEntity.Status;
import de.oaa.xxx.games.vanilla.repository.VanillaEinladungRepository;
import de.oaa.xxx.social.SystemMessageService;
import de.oaa.xxx.social.entity.MessageCause;
import de.oaa.xxx.social.repository.FriendshipRepository;
import de.oaa.xxx.user.UserRepository;
@RestController
@RequestMapping("/vanilla/einladung")
@Transactional
public class VanillaEinladungController {
private final VanillaEinladungRepository einladungRepository;
private final UserRepository userRepository;
private final FriendshipRepository friendshipRepository;
private final SystemMessageService systemMessageService;
public VanillaEinladungController(VanillaEinladungRepository einladungRepository,
UserRepository userRepository,
FriendshipRepository friendshipRepository,
SystemMessageService systemMessageService) {
this.einladungRepository = einladungRepository;
this.userRepository = userRepository;
this.friendshipRepository = friendshipRepository;
this.systemMessageService = systemMessageService;
}
record EinladungRequest(UUID setupId, int slotIndex, UUID inviteeId) {}
record AntwortRequest(boolean accepted, String mode) {} // mode: OWN_DEVICE | HOST_DEVICE
record SpielerDatenRequest(String spielerDatenJson) {}
private UUID currentUserId(Principal principal) {
return userRepository.findByEmail(principal.getName())
.map(u -> u.getUserId()).orElse(null);
}
@PostMapping
public ResponseEntity<Map<String, Object>> sendEinladung(@RequestBody EinladungRequest req, Principal principal) {
UUID inviterId = currentUserId(principal);
if (inviterId == null) return ResponseEntity.status(401).build();
// Freundschaft prüfen
var friendship = friendshipRepository.findExisting(inviterId, req.inviteeId());
if (friendship.isEmpty() || friendship.get().getStatus() != de.oaa.xxx.social.entity.FriendshipEntity.Status.ACCEPTED) {
return ResponseEntity.status(403).build();
}
if (req.setupId() == null) return ResponseEntity.badRequest().build();
// Vanilla: max 1 Gast-Slot prüfen ob bereits eine aktive Einladung für dieses Setup existiert
boolean slotOccupied = einladungRepository.findBySetupId(req.setupId()).stream()
.anyMatch(e -> e.getStatus() == Status.PENDING
|| e.getStatus() == Status.ACCEPTED_OWN
|| e.getStatus() == Status.ACCEPTED_HOST);
if (slotOccupied) {
return ResponseEntity.status(409).build();
}
// Prüfen ob Person bereits aktiv eingeladen
boolean alreadyInvited = einladungRepository.findBySetupId(req.setupId()).stream()
.anyMatch(e -> req.inviteeId().equals(e.getInviteeId())
&& (e.getStatus() == Status.PENDING
|| e.getStatus() == Status.ACCEPTED_OWN
|| e.getStatus() == Status.ACCEPTED_HOST));
if (alreadyInvited) {
return ResponseEntity.status(409).build();
}
// Alte Einladung für diesen Slot canceln
einladungRepository.findBySetupId(req.setupId()).stream()
.filter(e -> e.getSlotIndex() == req.slotIndex() && e.getStatus() == Status.PENDING)
.forEach(e -> e.setStatus(Status.CANCELLED));
VanillaEinladungEntity entity = new VanillaEinladungEntity();
entity.setEinladungId(UUID.randomUUID());
entity.setSetupId(req.setupId());
entity.setInviterId(inviterId);
entity.setInviteeId(req.inviteeId());
entity.setSlotIndex(req.slotIndex());
entity.setStatus(Status.PENDING);
entity.setCreatedAt(LocalDateTime.now());
einladungRepository.save(entity);
String inviterName = userRepository.findById(inviterId).map(u -> u.getName()).orElse("Jemand");
systemMessageService.send(
inviterId, req.inviteeId(),
inviterName + " hat dich zum Vanilla Game eingeladen.",
"/einladungen.html",
MessageCause.INVITATION
);
Map<String, Object> result = new LinkedHashMap<>();
result.put("einladungId", entity.getEinladungId());
return ResponseEntity.ok(result);
}
@DeleteMapping("/{id}")
public ResponseEntity<Void> cancelEinladung(@PathVariable UUID id, Principal principal) {
UUID userId = currentUserId(principal);
if (userId == null) return ResponseEntity.status(401).build();
VanillaEinladungEntity e = einladungRepository.findById(id).orElse(null);
if (e == null) return ResponseEntity.notFound().build();
if (!e.getInviterId().equals(userId)) return ResponseEntity.status(403).build();
e.setStatus(Status.CANCELLED);
String inviterName = userRepository.findById(userId).map(u -> u.getName()).orElse("Jemand");
systemMessageService.send(userId, e.getInviteeId(),
inviterName + " hat die Vanilla-Spieleinladung zurückgezogen.",
"/einladungen.html", MessageCause.INVITATION);
return ResponseEntity.accepted().build();
}
@GetMapping
public ResponseEntity<List<Map<String, Object>>> getBySetupId(@RequestParam UUID setupId, Principal principal) {
UUID userId = currentUserId(principal);
if (userId == null) return ResponseEntity.status(401).build();
List<Map<String, Object>> list = einladungRepository.findBySetupId(setupId).stream()
.map(this::toMap).toList();
return ResponseEntity.ok(list);
}
@GetMapping("/meine-aktive")
public ResponseEntity<Map<String, Object>> getAktive(Principal principal) {
UUID userId = currentUserId(principal);
if (userId == null) return ResponseEntity.status(401).build();
return einladungRepository.findByInviteeIdAndStatus(userId, Status.ACCEPTED_OWN)
.stream().findFirst()
.map(e -> ResponseEntity.ok(toMap(e)))
.orElse(ResponseEntity.noContent().build());
}
@GetMapping("/pending")
public ResponseEntity<List<Map<String, Object>>> getPending(Principal principal) {
UUID userId = currentUserId(principal);
if (userId == null) return ResponseEntity.status(401).build();
List<Map<String, Object>> list = einladungRepository.findByInviteeIdAndStatus(userId, Status.PENDING)
.stream().map(e -> {
Map<String, Object> m = toMap(e);
userRepository.findById(e.getInviterId()).ifPresent(u -> {
m.put("inviterName", u.getName());
m.put("inviterAvatar", u.getProfilePicture() != null ? u.getProfilePicture() : "");
});
return m;
}).toList();
return ResponseEntity.ok(list);
}
@GetMapping("/sent")
public ResponseEntity<List<Map<String, Object>>> getSent(Principal principal) {
UUID userId = currentUserId(principal);
if (userId == null) return ResponseEntity.status(401).build();
List<Map<String, Object>> list = einladungRepository.findByInviterIdAndStatus(userId, Status.PENDING)
.stream().map(e -> {
Map<String, Object> m = toMap(e);
userRepository.findById(e.getInviteeId()).ifPresent(u -> {
m.put("inviteeName", u.getName());
m.put("inviteeAvatar", u.getProfilePicture() != null ? u.getProfilePicture() : "");
});
return m;
}).toList();
return ResponseEntity.ok(list);
}
@GetMapping("/{id}")
public ResponseEntity<Map<String, Object>> getById(@PathVariable("id") UUID id, Principal principal) {
UUID userId = currentUserId(principal);
if (userId == null) return ResponseEntity.status(401).build();
VanillaEinladungEntity e = einladungRepository.findById(id).orElse(null);
if (e == null) return ResponseEntity.notFound().build();
if (!e.getInviteeId().equals(userId) && !e.getInviterId().equals(userId)) {
return ResponseEntity.status(403).build();
}
Map<String, Object> m = toMap(e);
userRepository.findById(e.getInviterId()).ifPresent(u -> {
m.put("inviterName", u.getName());
m.put("inviterAvatar", u.getProfilePicture() != null ? u.getProfilePicture() : "");
});
return ResponseEntity.ok(m);
}
@PutMapping("/{id}/spielerdaten")
public ResponseEntity<Void> spielerDatenEinreichen(@PathVariable UUID id, @RequestBody SpielerDatenRequest req, Principal principal) {
UUID userId = currentUserId(principal);
if (userId == null) return ResponseEntity.status(401).build();
VanillaEinladungEntity e = einladungRepository.findById(id).orElse(null);
if (e == null) return ResponseEntity.notFound().build();
if (!e.getInviteeId().equals(userId)) return ResponseEntity.status(403).build();
if (e.getStatus() != Status.ACCEPTED_OWN) return ResponseEntity.badRequest().build();
e.setSpielerDatenJson(req.spielerDatenJson());
e.setBereit(true);
return ResponseEntity.accepted().build();
}
@PutMapping("/{id}/antwort")
public ResponseEntity<Void> antwort(@PathVariable UUID id, @RequestBody AntwortRequest req, Principal principal) {
UUID userId = currentUserId(principal);
if (userId == null) return ResponseEntity.status(401).build();
VanillaEinladungEntity e = einladungRepository.findById(id).orElse(null);
if (e == null) return ResponseEntity.notFound().build();
if (!e.getInviteeId().equals(userId)) return ResponseEntity.status(403).build();
if (e.getStatus() != Status.PENDING) return ResponseEntity.badRequest().build();
if (!req.accepted()) {
e.setStatus(Status.DECLINED);
} else if ("OWN_DEVICE".equals(req.mode())) {
e.setStatus(Status.ACCEPTED_OWN);
} else {
e.setStatus(Status.ACCEPTED_HOST);
}
return ResponseEntity.accepted().build();
}
private Map<String, Object> toMap(VanillaEinladungEntity e) {
Map<String, Object> m = new LinkedHashMap<>();
m.put("einladungId", e.getEinladungId());
m.put("setupId", e.getSetupId());
m.put("slotIndex", e.getSlotIndex());
m.put("inviteeId", e.getInviteeId());
m.put("inviterId", e.getInviterId());
m.put("status", e.getStatus().name());
m.put("sessionId", e.getSessionId());
m.put("bereit", e.isBereit());
m.put("spielerDatenJson", e.getSpielerDatenJson());
userRepository.findById(e.getInviteeId()).ifPresent(u -> m.put("inviteeName", u.getName()));
return m;
}
}

View File

@@ -0,0 +1,101 @@
package de.oaa.xxx.games.vanilla.controller;
import de.oaa.xxx.games.common.aufgaben.Favorit;
import de.oaa.xxx.games.common.aufgaben.FavoritList;
import de.oaa.xxx.games.common.entity.FavoritEntity;
import de.oaa.xxx.games.common.repository.AufgabenGruppeRepository;
import de.oaa.xxx.games.common.repository.FavoritRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.DeleteMapping;
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.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
import java.util.List;
import java.util.UUID;
@RestController
@RequestMapping("/vanilla/favorit")
@Transactional
public class VanillaFavoritController {
private static final Logger LOGGER = LoggerFactory.getLogger(VanillaFavoritController.class);
private final FavoritRepository favoritRepository;
private final AufgabenGruppeRepository gruppeRepository;
public VanillaFavoritController(FavoritRepository favoritRepository,
AufgabenGruppeRepository gruppeRepository) {
this.favoritRepository = favoritRepository;
this.gruppeRepository = gruppeRepository;
}
@GetMapping("/{favoritId}")
public ResponseEntity<Favorit> get(@PathVariable UUID favoritId) {
return favoritRepository.findById(favoritId)
.map(entity -> ResponseEntity.ok(entity.toFavorit()))
.orElse(ResponseEntity.noContent().build());
}
@GetMapping
public ResponseEntity<FavoritList> all() {
UUID userId = (UUID) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
List<FavoritEntity> entities = favoritRepository.findByUserId(userId);
FavoritList result = new FavoritList();
// Only return favorites pointing to vanilla-safe groups
result.setFavoriten(entities.stream()
.filter(f -> {
var gruppe = gruppeRepository.findById(f.getAufgabenGruppeId()).orElse(null);
return gruppe != null && gruppe.getStrafen().isEmpty() && gruppe.getSperren().isEmpty();
})
.map(FavoritEntity::toFavorit).toList());
return ResponseEntity.ok(result);
}
@PostMapping
public ResponseEntity<Void> create(@RequestBody Favorit favorit) {
UUID userId = (UUID) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
if (favorit.getAufgabenGruppeId() == null) {
return ResponseEntity.badRequest().build();
}
// Validate vanilla-safe
var gruppe = gruppeRepository.findById(favorit.getAufgabenGruppeId()).orElse(null);
if (gruppe == null || !gruppe.getStrafen().isEmpty() || !gruppe.getSperren().isEmpty()) {
return ResponseEntity.status(403).build();
}
List<FavoritEntity> existing = favoritRepository.findByUserIdAndAufgabenGruppeId(userId, favorit.getAufgabenGruppeId());
FavoritEntity entity;
if (existing.isEmpty()) {
entity = FavoritEntity.fromFavorit(favorit, userId);
favoritRepository.save(entity);
LOGGER.debug("User {} hat Vanilla-AufgabenGruppe {} als Favorit gespeichert", userId, favorit.getAufgabenGruppeId());
} else {
entity = existing.get(0);
}
return ResponseEntity.created(
ServletUriComponentsBuilder.fromCurrentRequest().path("/{id}").buildAndExpand(entity.getFavoritId()).toUri()
).build();
}
@DeleteMapping
public ResponseEntity<Void> delete(@RequestBody Favorit favorit) {
try {
UUID userId = (UUID) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
favoritRepository.findByUserIdAndAufgabenGruppeId(userId, favorit.getAufgabenGruppeId())
.forEach(favoritRepository::delete);
return ResponseEntity.accepted().build();
} catch (Exception exception) {
LOGGER.error(exception.getMessage(), exception);
return ResponseEntity.internalServerError().build();
}
}
}

View File

@@ -0,0 +1,34 @@
package de.oaa.xxx.games.vanilla.controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import de.oaa.xxx.games.common.aufgaben.DefaultFiller;
@RestController
@RequestMapping("/vanilla/filler")
public class VanillaFillerController {
private static final Logger LOGGER = LoggerFactory.getLogger(VanillaFillerController.class);
private final DefaultFiller defaultFiller;
public VanillaFillerController(DefaultFiller defaultFiller) {
this.defaultFiller = defaultFiller;
}
@PostMapping
public ResponseEntity<Void> fill() {
try {
defaultFiller.fill();
return ResponseEntity.ok().build();
} catch (Exception exception) {
LOGGER.error(exception.getMessage(), exception);
return ResponseEntity.internalServerError().build();
}
}
}

View File

@@ -0,0 +1,116 @@
package de.oaa.xxx.games.vanilla.controller;
import de.oaa.xxx.games.common.aufgaben.Finisher;
import de.oaa.xxx.games.common.aufgaben.Toy;
import de.oaa.xxx.games.common.entity.AufgabenGruppeEntity;
import de.oaa.xxx.games.common.entity.FinisherEntity;
import de.oaa.xxx.games.common.entity.ToyEntity;
import de.oaa.xxx.games.common.repository.AufgabenGruppeRepository;
import de.oaa.xxx.games.common.repository.FinisherRepository;
import de.oaa.xxx.games.common.repository.ToyRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.DeleteMapping;
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.RestController;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
@RestController
@RequestMapping("/vanilla/finisher")
@Transactional
public class VanillaFinisherController {
private static final Logger LOGGER = LoggerFactory.getLogger(VanillaFinisherController.class);
private final FinisherRepository finisherRepository;
private final AufgabenGruppeRepository gruppeRepository;
private final ToyRepository toyRepository;
public VanillaFinisherController(FinisherRepository finisherRepository,
AufgabenGruppeRepository gruppeRepository,
ToyRepository toyRepository) {
this.finisherRepository = finisherRepository;
this.gruppeRepository = gruppeRepository;
this.toyRepository = toyRepository;
}
@GetMapping("/{finisherId}")
public ResponseEntity<Finisher> get(@PathVariable UUID finisherId) {
return finisherRepository.findById(finisherId)
.map(entity -> ResponseEntity.ok(entity.toFinisher()))
.orElse(ResponseEntity.noContent().build());
}
@PostMapping
public ResponseEntity<Void> create(@RequestBody Finisher finisher) {
if (finisher.getKurzText() == null || finisher.getText() == null
|| finisher.getGeschlecht() == null || finisher.getGruppeId() == null) {
return ResponseEntity.badRequest().build();
}
AufgabenGruppeEntity gruppeEntity = gruppeRepository.findById(finisher.getGruppeId()).orElse(null);
if (gruppeEntity == null) {
return ResponseEntity.badRequest().build();
}
if (gruppeEntity.getFinisher().size() >= 100) {
return ResponseEntity.status(409).build();
}
List<ToyEntity> toys = resolveToys(finisher.getBenoetigteToys());
FinisherEntity entity = FinisherEntity.create(finisher, gruppeEntity, toys);
finisherRepository.save(entity);
LOGGER.debug("Vanilla-Finisher {} '{}' in Gruppe {} erstellt", entity.getFinisherId(), entity.getKurzText(), finisher.getGruppeId());
return ResponseEntity.created(
ServletUriComponentsBuilder.fromCurrentRequest().path("/{id}").buildAndExpand(entity.getFinisherId()).toUri()
).build();
}
@PutMapping("/{finisherId}")
public ResponseEntity<Void> update(@PathVariable UUID finisherId, @RequestBody Finisher finisher) {
if (finisher.getKurzText() == null || finisher.getText() == null || finisher.getGeschlecht() == null) {
return ResponseEntity.badRequest().build();
}
FinisherEntity entity = finisherRepository.findById(finisherId).orElse(null);
if (entity == null) return ResponseEntity.notFound().build();
entity.setKurzText(finisher.getKurzText());
entity.setText(finisher.getText());
entity.setGeschlecht(finisher.getGeschlecht());
entity.setBenoetigtAktiv(finisher.getBenoetigtAktiv());
entity.setBenoetigtPassiv(finisher.getBenoetigtPassiv());
entity.setBenoetigteToys(resolveToys(finisher.getBenoetigteToys()));
finisherRepository.save(entity);
LOGGER.debug("Vanilla-Finisher {} aktualisiert", finisherId);
return ResponseEntity.ok().build();
}
@DeleteMapping
public ResponseEntity<Void> delete(@RequestBody Finisher finisher) {
try {
finisherRepository.findById(finisher.getFinisherId()).ifPresent(finisherRepository::delete);
return ResponseEntity.accepted().build();
} catch (Exception exception) {
LOGGER.error(exception.getMessage(), exception);
return ResponseEntity.internalServerError().build();
}
}
private List<ToyEntity> resolveToys(List<Toy> toys) {
if (toys == null || toys.isEmpty()) return new ArrayList<>();
List<UUID> ids = toys.stream()
.filter(t -> t.getToyId() != null)
.map(Toy::getToyId)
.toList();
if (ids.isEmpty()) return new ArrayList<>();
return toyRepository.findAllById(ids);
}
}

View File

@@ -0,0 +1,410 @@
package de.oaa.xxx.games.vanilla.controller;
import java.security.Principal;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.DeleteMapping;
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.RestController;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
import com.fasterxml.jackson.databind.ObjectMapper;
import de.oaa.xxx.games.common.aufgaben.AufgabenList;
import de.oaa.xxx.games.vanilla.VanillaAufgabeAnzeige;
import de.oaa.xxx.games.vanilla.VanillaGame;
import de.oaa.xxx.games.vanilla.VanillaGameDurchfuehren;
import de.oaa.xxx.games.vanilla.VanillaMitspieler;
import de.oaa.xxx.games.vanilla.entity.VanillaEinladungEntity;
import de.oaa.xxx.games.vanilla.entity.VanillaGameEntity;
import de.oaa.xxx.games.vanilla.entity.VanillaMitspielerEntity;
import de.oaa.xxx.games.vanilla.repository.VanillaEinladungRepository;
import de.oaa.xxx.games.vanilla.repository.VanillaGameRepository;
import de.oaa.xxx.games.vanilla.repository.VanillaMitspielerRepository;
import de.oaa.xxx.social.SystemMessageService;
import de.oaa.xxx.social.entity.MessageCause;
import de.oaa.xxx.user.UserRepository;
@RestController
@RequestMapping("/vanilla")
@Transactional
public class VanillaGameController {
private static final Logger LOGGER = LoggerFactory.getLogger(VanillaGameController.class);
/**
* Kurzlebiger In-Memory-Marker: Sessions die ordentlich über spielAbgeschlossen
* beendet wurden.
*/
private static final Set<UUID> ORDENTLICH_BEENDET = Collections.synchronizedSet(new HashSet<>());
private final VanillaGameRepository sessionRepository;
private final VanillaMitspielerRepository mitspielerRepository;
private final VanillaEinladungRepository einladungRepository;
private final UserRepository userRepository;
private final ObjectMapper objectMapper;
private final SystemMessageService systemMessageService;
public VanillaGameController(VanillaGameRepository sessionRepository,
VanillaMitspielerRepository mitspielerRepository,
VanillaEinladungRepository einladungRepository,
UserRepository userRepository,
ObjectMapper objectMapper,
SystemMessageService systemMessageService) {
this.sessionRepository = sessionRepository;
this.mitspielerRepository = mitspielerRepository;
this.einladungRepository = einladungRepository;
this.userRepository = userRepository;
this.objectMapper = objectMapper;
this.systemMessageService = systemMessageService;
}
@GetMapping("/{sessionId}")
public ResponseEntity<VanillaGame> getBySessionId(@PathVariable UUID sessionId) {
return sessionRepository.findById(sessionId)
.map(entity -> ResponseEntity.ok(toSession(entity)))
.orElse(ResponseEntity.noContent().build());
}
@GetMapping
public ResponseEntity<VanillaGame> getByUserId(@org.springframework.web.bind.annotation.RequestParam UUID userId) {
return sessionRepository.findByUserId(userId)
.map(entity -> ResponseEntity.ok(toSession(entity)))
.orElse(ResponseEntity.noContent().build());
}
@PostMapping
public ResponseEntity<Void> create(@RequestBody VanillaGame session) {
String email = (String) org.springframework.security.core.context.SecurityContextHolder.getContext().getAuthentication().getPrincipal();
UUID userId = userRepository.findByEmail(email).map(u -> u.getUserId()).orElse(null);
if (userId == null) return ResponseEntity.status(401).build();
var existingOpt = sessionRepository.findByUserId(userId);
if (existingOpt.isPresent()) {
VanillaGameEntity existing = existingOpt.get();
if (existing.getAufgaben() != null) return ResponseEntity.status(409).build();
// Unvollständige Session (aufgaben=null) bereinigen
mitspielerRepository.deleteAll(existing.getMitspieler());
sessionRepository.delete(existing);
}
VanillaGameEntity entity = new VanillaGameEntity();
entity.setSessionId(UUID.randomUUID());
entity.setUserId(userId);
entity.setAufgabenAufAktuellemLevel(0);
entity.setAufgabenProLevel(session.getAufgabenProLevel() != null ? session.getAufgabenProLevel() : 5);
LocalDateTime now = LocalDateTime.now();
entity.setLetzteAktivitaet(now);
entity.setStartZeit(now);
entity.setLevel(1);
entity.setSetupId(session.getSetupId());
sessionRepository.save(entity);
LOGGER.debug("VanillaGame gestartet [sessionId={}, userId={}, aufgabenProLevel={}]",
entity.getSessionId(), entity.getUserId(), entity.getAufgabenProLevel());
return ResponseEntity.created(
ServletUriComponentsBuilder.fromCurrentRequest().path("/{id}").buildAndExpand(entity.getSessionId()).toUri()
).build();
}
@DeleteMapping
public ResponseEntity<Void> deleteSession(@RequestBody VanillaGame session) {
return sessionRepository.findById(session.getSessionId())
.map(entity -> {
mitspielerRepository.deleteAll(entity.getMitspieler());
sessionRepository.delete(entity);
return ResponseEntity.accepted().<Void>build();
})
.orElse(ResponseEntity.noContent().build());
}
@PostMapping("/{sessionId}/abgeschlossen")
public ResponseEntity<Void> spielAbgeschlossen(@PathVariable UUID sessionId) {
VanillaGameEntity entity = sessionRepository.findById(sessionId).orElse(null);
if (entity == null) return ResponseEntity.notFound().build();
ORDENTLICH_BEENDET.add(sessionId);
mitspielerRepository.deleteAll(entity.getMitspieler());
sessionRepository.delete(entity);
return ResponseEntity.accepted().build();
}
/** Prüft ob eine Session ordentlich (nicht abgebrochen) beendet wurde. */
@GetMapping("/{sessionId}/beendet")
public ResponseEntity<Void> istBeendet(@PathVariable UUID sessionId) {
if (ORDENTLICH_BEENDET.remove(sessionId)) return ResponseEntity.ok().build();
return ResponseEntity.notFound().build();
}
@DeleteMapping("/{sessionId}/verlassen")
public ResponseEntity<Void> verlasseSpiel(@PathVariable UUID sessionId, Principal principal) {
UUID userId = userRepository.findByEmail(principal.getName()).map(u -> u.getUserId()).orElse(null);
if (userId == null) return ResponseEntity.status(401).build();
VanillaGameEntity session = sessionRepository.findById(sessionId).orElse(null);
if (session == null) return ResponseEntity.notFound().build();
VanillaMitspielerEntity self = session.getMitspieler().stream()
.filter(m -> userId.equals(m.getUserId()))
.findFirst().orElse(null);
if (self == null) return ResponseEntity.status(403).build();
String name = self.getName();
String nachricht = name + " hat das Vanilla-Spiel verlassen. Das Spiel wurde abgebrochen.";
systemMessageService.send(userId, session.getUserId(), nachricht, "/userhome.html", MessageCause.GAME_STATE);
session.getMitspieler().stream()
.filter(m -> m.isEigenesGeraet() && m.getUserId() != null && !userId.equals(m.getUserId()))
.forEach(m -> systemMessageService.send(userId, m.getUserId(), nachricht, "/userhome.html", MessageCause.GAME_STATE));
mitspielerRepository.deleteAll(session.getMitspieler());
sessionRepository.delete(session);
return ResponseEntity.accepted().build();
}
@PostMapping("/{sessionId}/aufgaben")
public ResponseEntity<Void> setAufgaben(@RequestBody AufgabenList list, @PathVariable UUID sessionId) {
try {
if (list.size() > 1000) {
return ResponseEntity.badRequest().build();
}
String aufgaben = objectMapper.writeValueAsString(list);
VanillaGameEntity session = sessionRepository.findById(sessionId).orElse(null);
if (session == null) {
return ResponseEntity.badRequest().build();
}
session.setAufgaben(aufgaben);
sessionRepository.save(session);
// Erst jetzt Einladungen mit der Session verknüpfen Gäste werden nur weitergeleitet wenn aufgaben bereit sind
if (session.getSetupId() != null) {
einladungRepository.findBySetupId(session.getSetupId()).stream()
.filter(e -> e.getStatus() == VanillaEinladungEntity.Status.ACCEPTED_OWN
|| e.getStatus() == VanillaEinladungEntity.Status.ACCEPTED_HOST)
.forEach(e -> e.setSessionId(session.getSessionId()));
}
return ResponseEntity.accepted().build();
} catch (Exception exception) {
LOGGER.error(exception.getMessage(), exception);
return ResponseEntity.internalServerError().build();
}
}
@GetMapping("/{sessionId}/aufgaben/next")
public ResponseEntity<VanillaAufgabeAnzeige> getNextAufgabe(@PathVariable UUID sessionId) {
try {
VanillaGameEntity session = sessionRepository.findById(sessionId).orElse(null);
if (session == null || session.getAufgaben() == null) {
return ResponseEntity.badRequest().build();
}
session.setLetzteAktivitaet(LocalDateTime.now());
VanillaGameDurchfuehren durchfuehren = new VanillaGameDurchfuehren(session);
VanillaAufgabeAnzeige next = durchfuehren.getNext();
session.setLevel(durchfuehren.getLevel());
session.setAufgabenAufAktuellemLevel(durchfuehren.getAufgabenAufAktuellemLevel());
if (next == null) {
return ResponseEntity.noContent().build();
}
next.setLevel(durchfuehren.getLevel());
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Neue Vanilla-Aufgabe [sessionId={}, level={}, aufgaben={}/{}]",
sessionId, session.getLevel(), session.getAufgabenAufAktuellemLevel(),
session.getAufgabenProLevel());
}
return ResponseEntity.ok(next);
} catch (Exception exception) {
LOGGER.error(exception.getMessage(), exception);
return ResponseEntity.internalServerError().build();
}
}
@PostMapping("/{sessionId}/mitspieler")
public ResponseEntity<Void> addMitspieler(@RequestBody VanillaMitspieler mitspieler, @PathVariable UUID sessionId) {
if (mitspieler.getName() == null || mitspieler.getGeschlecht() == null || mitspieler.getRollen() == null
|| mitspieler.getRollen().isEmpty() || mitspieler.getSpieltMit() == null || mitspieler.getSpieltMit().isEmpty()
|| mitspieler.getVerfuegbareWerkzeuge() == null || mitspieler.getVerfuegbareWerkzeuge().isEmpty()) {
return ResponseEntity.badRequest().build();
}
VanillaGameEntity session = sessionRepository.findById(sessionId).orElse(null);
if (session == null) {
return ResponseEntity.badRequest().build();
}
// Max 2 Mitspieler (1 Host + max 1 Gast)
if (session.getMitspieler().size() >= 1) {
return ResponseEntity.status(409).build();
}
VanillaMitspielerEntity entity = new VanillaMitspielerEntity();
entity.setMitspielerId(UUID.randomUUID());
entity.setGeschlecht(mitspieler.getGeschlecht());
entity.setName(mitspieler.getName());
entity.setRollen(mitspieler.getRollen());
entity.setSpieltMit(mitspieler.getSpieltMit());
entity.setWerkzeuge(new ArrayList<>(mitspieler.getVerfuegbareWerkzeuge()));
entity.setUserId(mitspieler.getUserId());
entity.setEigenesGeraet(mitspieler.isEigenesGeraet());
entity.setSession(session);
mitspielerRepository.save(entity);
return ResponseEntity.accepted().build();
}
@GetMapping("/{sessionId}/finisher")
public ResponseEntity<List<VanillaAufgabeAnzeige>> getFinisher(@PathVariable UUID sessionId) {
try {
VanillaGameEntity session = sessionRepository.findById(sessionId).orElse(null);
if (session == null) return ResponseEntity.badRequest().build();
VanillaGameDurchfuehren durchfuehren = new VanillaGameDurchfuehren(session);
return ResponseEntity.ok(durchfuehren.getFinisher());
} catch (Exception exception) {
LOGGER.error(exception.getMessage(), exception);
return ResponseEntity.internalServerError().build();
}
}
@PostMapping("/{sessionId}/backToLevel5")
public ResponseEntity<Void> backToLevel5(@PathVariable UUID sessionId) {
try {
VanillaGameEntity session = sessionRepository.findById(sessionId).orElse(null);
if (session == null) return ResponseEntity.badRequest().build();
VanillaGameDurchfuehren durchfuehren = new VanillaGameDurchfuehren(session);
durchfuehren.backToLvl5();
session.setLevel(durchfuehren.getLevel());
session.setAufgabenAufAktuellemLevel(durchfuehren.getAufgabenAufAktuellemLevel());
sessionRepository.save(session);
return ResponseEntity.accepted().build();
} catch (Exception exception) {
LOGGER.error(exception.getMessage(), exception);
return ResponseEntity.internalServerError().build();
}
}
@GetMapping("/{sessionId}/mitspieler/me")
public ResponseEntity<Map<String, Object>> getMeinMitspieler(@PathVariable UUID sessionId, Principal principal) {
UUID userId = userRepository.findByEmail(principal.getName()).map(u -> u.getUserId()).orElse(null);
if (userId == null) return ResponseEntity.status(401).build();
VanillaGameEntity session = sessionRepository.findById(sessionId).orElse(null);
if (session == null) return ResponseEntity.notFound().build();
return session.getMitspieler().stream()
.filter(m -> userId.equals(m.getUserId()))
.findFirst()
.map(m -> {
Map<String, Object> result = new LinkedHashMap<>();
result.put("mitspielerId", m.getMitspielerId());
result.put("name", m.getName());
result.put("eigenesGeraet", m.isEigenesGeraet());
return ResponseEntity.ok(result);
})
.orElse(ResponseEntity.noContent().build());
}
record AbschliessenRequest(boolean sperreAnwenden) {}
record AbschliessenResponse(List<Object> abgelaufeneSperren) {}
@PostMapping("/{sessionId}/active-task/abschliessen")
public ResponseEntity<AbschliessenResponse> activeTaskAbschliessen(
@PathVariable UUID sessionId, @RequestBody AbschliessenRequest req) {
VanillaGameEntity session = sessionRepository.findById(sessionId).orElse(null);
if (session == null) return ResponseEntity.notFound().build();
// Vanilla: keine Sperren/Strafen einfach activeTask löschen
session.setActiveTaskJson(null);
session.setTaskStartedAt(null);
sessionRepository.save(session);
return ResponseEntity.ok(new AbschliessenResponse(List.of()));
}
record ActiveTaskRequest(String taskJson, LocalDateTime timerStartedAt) {}
record ActiveTaskResponse(String taskJson, Long elapsedSeconds) {}
@PutMapping("/{sessionId}/active-task")
public ResponseEntity<Void> setActiveTask(@PathVariable UUID sessionId, @RequestBody ActiveTaskRequest req) {
VanillaGameEntity session = sessionRepository.findById(sessionId).orElse(null);
if (session == null) return ResponseEntity.notFound().build();
session.setActiveTaskJson(req.taskJson());
session.setTaskStartedAt(req.timerStartedAt());
sessionRepository.save(session);
return ResponseEntity.accepted().build();
}
@DeleteMapping("/{sessionId}/active-task")
public ResponseEntity<Void> clearActiveTask(@PathVariable UUID sessionId) {
VanillaGameEntity session = sessionRepository.findById(sessionId).orElse(null);
if (session == null) return ResponseEntity.notFound().build();
session.setActiveTaskJson(null);
session.setTaskStartedAt(null);
sessionRepository.save(session);
return ResponseEntity.accepted().build();
}
@GetMapping("/{sessionId}/active-task")
public ResponseEntity<ActiveTaskResponse> getActiveTask(@PathVariable UUID sessionId) {
VanillaGameEntity session = sessionRepository.findById(sessionId).orElse(null);
if (session == null) return ResponseEntity.notFound().build();
if (session.getActiveTaskJson() == null) return ResponseEntity.noContent().build();
Long elapsed = null;
if (session.getTaskStartedAt() != null) {
elapsed = Duration.between(session.getTaskStartedAt(), LocalDateTime.now()).getSeconds();
}
return ResponseEntity.ok(new ActiveTaskResponse(session.getActiveTaskJson(), elapsed));
}
// ── Debug-Endpoint: vollständiger Entity-Zustand ──
@GetMapping("/{sessionId}/debug")
public ResponseEntity<Map<String, Object>> debug(@PathVariable UUID sessionId) {
VanillaGameEntity entity = sessionRepository.findById(sessionId).orElse(null);
if (entity == null) return ResponseEntity.notFound().build();
Map<String, Object> session = new LinkedHashMap<>();
session.put("sessionId", entity.getSessionId());
session.put("userId", entity.getUserId());
session.put("setupId", entity.getSetupId());
session.put("startZeit", entity.getStartZeit());
session.put("letzteAktivitaet", entity.getLetzteAktivitaet());
session.put("level", entity.getLevel());
session.put("aufgabenAufAktuellemLevel", entity.getAufgabenAufAktuellemLevel());
session.put("aufgabenProLevel", entity.getAufgabenProLevel());
session.put("taskStartedAt", entity.getTaskStartedAt());
session.put("hatAufgaben", entity.getAufgaben() != null);
session.put("hatActiveTask", entity.getActiveTaskJson() != null);
List<Map<String, Object>> mitspielerList = entity.getMitspieler().stream().map(m -> {
Map<String, Object> mp = new LinkedHashMap<>();
mp.put("mitspielerId", m.getMitspielerId());
mp.put("name", m.getName());
mp.put("userId", m.getUserId());
mp.put("geschlecht", m.getGeschlecht());
mp.put("rollen", m.getRollen());
mp.put("werkzeuge", m.getWerkzeuge());
mp.put("spieltMit", m.getSpieltMit());
mp.put("eigenesGeraet", m.isEigenesGeraet());
return mp;
}).toList();
Map<String, Object> result = new LinkedHashMap<>();
result.put("session", session);
result.put("mitspieler", mitspielerList);
return ResponseEntity.ok(result);
}
private VanillaGame toSession(VanillaGameEntity entity) {
VanillaGame session = new VanillaGame();
session.setSessionId(entity.getSessionId());
session.setUserId(entity.getUserId());
session.setAufgabenProLevel(entity.getAufgabenProLevel());
session.setLevel(entity.getLevel());
session.setAufgabenAufAktuellemLevel(entity.getAufgabenAufAktuellemLevel());
session.setStartZeit(entity.getStartZeit());
session.setLetzteAktivitaet(entity.getLetzteAktivitaet());
return session;
}
}

View File

@@ -0,0 +1,78 @@
package de.oaa.xxx.games.vanilla.controller;
import de.oaa.xxx.games.vanilla.entity.VanillaSetupDraftEntity;
import de.oaa.xxx.games.vanilla.repository.VanillaSetupDraftRepository;
import de.oaa.xxx.user.UserRepository;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import java.security.Principal;
import java.time.LocalDateTime;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.UUID;
@RestController
@RequestMapping("/vanilla/setup")
@Transactional
public class VanillaSetupDraftController {
private final VanillaSetupDraftRepository draftRepository;
private final UserRepository userRepository;
public VanillaSetupDraftController(VanillaSetupDraftRepository draftRepository, UserRepository userRepository) {
this.draftRepository = draftRepository;
this.userRepository = userRepository;
}
record DraftRequest(String setupId, String settingsJson, String setupJson, String gruppenJson) {}
private UUID currentUserId(Principal principal) {
return userRepository.findByEmail(principal.getName()).map(u -> u.getUserId()).orElse(null);
}
@GetMapping
public ResponseEntity<Map<String, Object>> getDraft(
@RequestParam(required = false) String setupId,
Principal principal) {
UUID userId = currentUserId(principal);
if (userId == null) return ResponseEntity.status(401).build();
var lookup = (setupId != null && !setupId.isBlank())
? draftRepository.findBySetupId(setupId)
: draftRepository.findByUserId(userId);
return lookup
.map(d -> {
Map<String, Object> m = new LinkedHashMap<>();
m.put("setupId", d.getSetupId());
m.put("settingsJson", d.getSettingsJson());
m.put("setupJson", d.getSetupJson());
m.put("gruppenJson", d.getGruppenJson());
return ResponseEntity.ok(m);
})
.orElse(ResponseEntity.noContent().build());
}
@PutMapping
public ResponseEntity<Void> saveDraft(@RequestBody DraftRequest req, Principal principal) {
UUID userId = currentUserId(principal);
if (userId == null) return ResponseEntity.status(401).build();
VanillaSetupDraftEntity d = draftRepository.findByUserId(userId)
.orElseGet(() -> { VanillaSetupDraftEntity n = new VanillaSetupDraftEntity(); n.setUserId(userId); return n; });
if (req.setupId() != null) d.setSetupId(req.setupId());
if (req.settingsJson() != null) d.setSettingsJson(req.settingsJson());
if (req.setupJson() != null) d.setSetupJson(req.setupJson());
if (req.gruppenJson() != null) d.setGruppenJson(req.gruppenJson());
d.setUpdatedAt(LocalDateTime.now());
draftRepository.save(d);
return ResponseEntity.accepted().build();
}
@DeleteMapping
public ResponseEntity<Void> deleteDraft(Principal principal) {
UUID userId = currentUserId(principal);
if (userId == null) return ResponseEntity.status(401).build();
draftRepository.findByUserId(userId).ifPresent(draftRepository::delete);
return ResponseEntity.accepted().build();
}
}

View File

@@ -0,0 +1,253 @@
package de.oaa.xxx.games.vanilla.controller;
import de.oaa.xxx.games.common.aufgaben.Toy;
import de.oaa.xxx.games.common.aufgaben.ToyPage;
import de.oaa.xxx.games.common.entity.AufgabenGruppeEntity;
import de.oaa.xxx.games.common.entity.ToyEntity;
import de.oaa.xxx.games.common.repository.GruppenAboRepository;
import de.oaa.xxx.games.common.repository.ToyRepository;
import de.oaa.xxx.subscription.SubscriptionLimitService;
import de.oaa.xxx.user.UserEntity;
import de.oaa.xxx.user.UserRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.DeleteMapping;
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 org.springframework.web.servlet.support.ServletUriComponentsBuilder;
import java.security.Principal;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
@RestController
@RequestMapping("/vanilla/toy")
@Transactional
public class VanillaToyController {
private static final Logger LOGGER = LoggerFactory.getLogger(VanillaToyController.class);
private static final int DEFAULT_PAGE_SIZE = 12;
private final ToyRepository toyRepository;
private final UserRepository userRepository;
private final GruppenAboRepository aboRepository;
private final SubscriptionLimitService limitService;
public VanillaToyController(ToyRepository toyRepository,
UserRepository userRepository,
GruppenAboRepository aboRepository,
SubscriptionLimitService limitService) {
this.toyRepository = toyRepository;
this.userRepository = userRepository;
this.aboRepository = aboRepository;
this.limitService = limitService;
}
@GetMapping("/list/user")
public ResponseEntity<ToyPage> listUser(
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "" + DEFAULT_PAGE_SIZE) int size,
Principal principal) {
UserEntity user = userRepository.findByEmail(principal.getName()).orElse(null);
if (user == null) {
return ResponseEntity.status(401).build();
}
Page<ToyEntity> result = toyRepository.findByUserId(
user.getUserId(), PageRequest.of(page, size, Sort.by("name")));
return ResponseEntity.ok(toToyPage(result));
}
@GetMapping("/list/system")
public ResponseEntity<ToyPage> listSystem(
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "" + DEFAULT_PAGE_SIZE) int size) {
Page<ToyEntity> result = toyRepository.findByUserIdIsNull(
PageRequest.of(page, size, Sort.by("name")));
return ResponseEntity.ok(toToyPage(result));
}
/**
* Returns all toys available to the current user for assignment to items:
* own toys + system toys + toys referenced in subscribed vanilla-safe groups' items.
*/
@GetMapping("/available")
public ResponseEntity<List<Toy>> available(Principal principal) {
UserEntity user = userRepository.findByEmail(principal.getName()).orElse(null);
if (user == null) return ResponseEntity.status(401).build();
List<ToyEntity> own = toyRepository.findByUserId(user.getUserId(), PageRequest.of(0, 500, Sort.by("name"))).getContent();
List<ToyEntity> system = toyRepository.findByUserIdIsNull(PageRequest.of(0, 500, Sort.by("name"))).getContent();
Set<UUID> knownIds = new HashSet<>();
own.forEach(t -> knownIds.add(t.getToyId()));
system.forEach(t -> knownIds.add(t.getToyId()));
Set<ToyEntity> fromAbos = new HashSet<>();
aboRepository.findByUserId(user.getUserId()).forEach(abo -> {
AufgabenGruppeEntity gruppe = abo.getAufgabenGruppe();
// Only include toys from vanilla-safe groups (no Strafen, no Sperren)
if (!gruppe.getStrafen().isEmpty() || !gruppe.getSperren().isEmpty()) return;
gruppe.getAufgaben().forEach(a -> {
if (a.getBenoetigteToys() != null)
a.getBenoetigteToys().stream().filter(t -> !knownIds.contains(t.getToyId())).forEach(fromAbos::add);
});
});
List<Toy> result = new ArrayList<>();
result.addAll(own.stream().map(ToyEntity::toToy).toList());
result.addAll(system.stream().map(ToyEntity::toToy).toList());
result.addAll(fromAbos.stream()
.sorted(Comparator.comparing(ToyEntity::getName, String.CASE_INSENSITIVE_ORDER))
.map(ToyEntity::toToy).toList());
return ResponseEntity.ok(result);
}
@GetMapping("/{toyId}")
public ResponseEntity<Toy> get(@PathVariable UUID toyId) {
return toyRepository.findById(toyId)
.map(entity -> ResponseEntity.ok(entity.toToy()))
.orElse(ResponseEntity.noContent().build());
}
@PostMapping
public ResponseEntity<Void> create(@RequestBody Toy toy, Principal principal) {
if (toy.getName() == null || toy.getName().isBlank()) {
return ResponseEntity.badRequest().build();
}
UserEntity user = userRepository.findByEmail(principal.getName()).orElse(null);
if (user == null) {
return ResponseEntity.status(401).build();
}
if (toyRepository.existsByNameIgnoreCaseAndUserIdIsNull(toy.getName())
|| toyRepository.existsByNameIgnoreCaseAndUserId(toy.getName(), user.getUserId())) {
return ResponseEntity.status(409)
.header("X-Error", "duplicate-name")
.build();
}
if (toyRepository.countByUserId(user.getUserId()) >= limitService.maxToys(user.getUserId())) {
return ResponseEntity.status(409)
.header("X-Error", "limit-reached")
.build();
}
ToyEntity entity = ToyEntity.create(toy);
entity.setUserId(user.getUserId());
toyRepository.save(entity);
LOGGER.debug("User {} hat Vanilla-Toy {} '{}' erstellt", user.getUserId(), entity.getToyId(), entity.getName());
return ResponseEntity.created(
ServletUriComponentsBuilder.fromCurrentRequest().path("/{id}").buildAndExpand(entity.getToyId()).toUri()
).build();
}
@PostMapping("/copy/{toyId}")
public ResponseEntity<Void> copy(@PathVariable UUID toyId, Principal principal) {
UserEntity user = userRepository.findByEmail(principal.getName()).orElse(null);
if (user == null) {
return ResponseEntity.status(401).build();
}
ToyEntity source = toyRepository.findById(toyId).orElse(null);
if (source == null) {
return ResponseEntity.notFound().build();
}
if (source.getUserId() != null) {
return ResponseEntity.status(403).build();
}
if (toyRepository.existsByNameIgnoreCaseAndUserId(source.getName(), user.getUserId())) {
return ResponseEntity.status(409)
.header("X-Error", "duplicate-name")
.build();
}
ToyEntity copy = new ToyEntity();
copy.setToyId(UUID.randomUUID());
copy.setName(source.getName());
copy.setBeschreibung(source.getBeschreibung());
copy.setUserId(user.getUserId());
copy.setBild(source.getBild());
toyRepository.save(copy);
LOGGER.debug("User {} hat System-Toy {} kopiert für Vanilla (Kopie: {})", user.getUserId(), toyId, copy.getToyId());
return ResponseEntity.status(201).build();
}
@PutMapping("/{toyId}")
public ResponseEntity<Void> update(@PathVariable UUID toyId, @RequestBody Toy toy, Principal principal) {
if (toy.getName() == null || toy.getName().isBlank()) {
return ResponseEntity.badRequest().build();
}
UserEntity user = userRepository.findByEmail(principal.getName()).orElse(null);
if (user == null) {
return ResponseEntity.status(401).build();
}
ToyEntity entity = toyRepository.findById(toyId).orElse(null);
if (entity == null) {
return ResponseEntity.notFound().build();
}
if (!user.getUserId().equals(entity.getUserId())) {
return ResponseEntity.status(403).build();
}
if (toyRepository.existsByNameIgnoreCaseAndUserIdIsNullAndToyIdNot(toy.getName(), toyId)
|| toyRepository.existsByNameIgnoreCaseAndUserIdAndToyIdNot(toy.getName(), user.getUserId(), toyId)) {
return ResponseEntity.status(409)
.header("X-Error", "duplicate-name")
.build();
}
entity.setName(toy.getName().trim());
entity.setBeschreibung(toy.getBeschreibung());
if (toy.getBild() != null) {
entity.setBild(Base64.getDecoder().decode(toy.getBild()));
}
toyRepository.save(entity);
LOGGER.debug("User {} hat Vanilla-Toy {} aktualisiert", user.getUserId(), toyId);
return ResponseEntity.ok().build();
}
@DeleteMapping("/{toyId}")
public ResponseEntity<Void> delete(@PathVariable UUID toyId, Principal principal) {
UserEntity user = userRepository.findByEmail(principal.getName()).orElse(null);
if (user == null) {
return ResponseEntity.status(401).build();
}
ToyEntity toy = toyRepository.findById(toyId).orElse(null);
if (toy == null) {
return ResponseEntity.noContent().build();
}
if (!user.getUserId().equals(toy.getUserId())) {
return ResponseEntity.status(403).build();
}
if (toyRepository.countAufgabeUsage(toyId) > 0
|| toyRepository.countStrafeUsage(toyId) > 0
|| toyRepository.countSperreUsage(toyId) > 0) {
return ResponseEntity.status(409).build();
}
try {
toyRepository.delete(toy);
return ResponseEntity.accepted().build();
} catch (Exception e) {
LOGGER.error(e.getMessage(), e);
return ResponseEntity.internalServerError().build();
}
}
private ToyPage toToyPage(Page<ToyEntity> page) {
ToyPage toyPage = new ToyPage();
toyPage.setContent(page.getContent().stream().map(ToyEntity::toToy).toList());
toyPage.setCurrentPage(page.getNumber());
toyPage.setTotalPages(page.getTotalPages());
toyPage.setTotalElements(page.getTotalElements());
return toyPage;
}
}

View File

@@ -0,0 +1,22 @@
package de.oaa.xxx.games.vanilla.entity;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import java.time.LocalDateTime;
import java.util.UUID;
@Getter @Setter @Entity @Table(name = "vanilla_einladung")
public class VanillaEinladungEntity {
public enum Status { PENDING, ACCEPTED_OWN, ACCEPTED_HOST, DECLINED, CANCELLED }
@Id @Column private UUID einladungId;
@Column(nullable = false) private UUID setupId;
@Column private UUID sessionId;
@Column(nullable = false) private UUID inviterId;
@Column(nullable = false) private UUID inviteeId;
@Column(nullable = false) private int slotIndex;
@Enumerated(EnumType.STRING) @Column(nullable = false, length = 20) private Status status;
@Column(nullable = false) private LocalDateTime createdAt;
@Column(columnDefinition = "TEXT") private String spielerDatenJson;
@Column(nullable = false, columnDefinition = "BOOLEAN DEFAULT false") private boolean bereit;
}

View File

@@ -0,0 +1,26 @@
package de.oaa.xxx.games.vanilla.entity;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
@Getter @Setter @Entity @Table(name = "vanilla_game")
public class VanillaGameEntity {
@Id @Column private UUID sessionId;
@Column(unique = true) private UUID userId;
@Column private LocalDateTime startZeit;
@Column private LocalDateTime letzteAktivitaet;
@OneToMany(mappedBy = "session", fetch = FetchType.EAGER)
private List<VanillaMitspielerEntity> mitspieler = new ArrayList<>();
@Column private Integer aufgabenProLevel;
@Column private Integer level;
@Column private Integer aufgabenAufAktuellemLevel;
@Column(columnDefinition = "TEXT") private String aufgaben;
@Column(columnDefinition = "TEXT") private String activeTaskJson;
@Column private LocalDateTime taskStartedAt;
@Column private UUID setupId;
}

View File

@@ -0,0 +1,41 @@
package de.oaa.xxx.games.vanilla.entity;
import de.oaa.xxx.games.bdsm.GeschlechtEnum;
import de.oaa.xxx.games.bdsm.RolleEnum;
import de.oaa.xxx.games.common.aufgaben.Werkzeug;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
@Getter @Setter @Entity @Table(name = "vanilla_mitspieler")
public class VanillaMitspielerEntity {
@Id @Column private UUID mitspielerId;
@Column private UUID userId;
@Column private boolean eigenesGeraet;
@Column private String name;
@Enumerated(EnumType.STRING) @Column private GeschlechtEnum geschlecht;
@Enumerated(EnumType.STRING)
@ElementCollection(targetClass = Werkzeug.class, fetch = FetchType.EAGER)
@CollectionTable(name = "vanilla_mitspieler_werkzeuge", joinColumns = @JoinColumn(name = "mitspielerId"))
@Column(name = "werkzeug") private List<Werkzeug> werkzeuge = new ArrayList<>();
@Enumerated(EnumType.STRING)
@ElementCollection(targetClass = GeschlechtEnum.class, fetch = FetchType.EAGER)
@CollectionTable(name = "vanilla_mitspieler_spieltMit", joinColumns = @JoinColumn(name = "mitspielerId"))
@Column(name = "geschlecht") private List<GeschlechtEnum> spieltMit = new ArrayList<>();
@Enumerated(EnumType.STRING)
@ElementCollection(targetClass = RolleEnum.class, fetch = FetchType.EAGER)
@CollectionTable(name = "vanilla_mitspieler_rollen", joinColumns = @JoinColumn(name = "mitspielerId"))
@Column(name = "rolle") private List<RolleEnum> rollen = new ArrayList<>();
@ManyToOne @JoinColumn(name = "sessionId", nullable = false) private VanillaGameEntity session;
public de.oaa.xxx.games.vanilla.VanillaMitspieler toMitspieler() {
de.oaa.xxx.games.vanilla.VanillaMitspieler m = new de.oaa.xxx.games.vanilla.VanillaMitspieler();
m.setGeschlecht(geschlecht); m.setId(mitspielerId); m.setUserId(userId);
m.setEigenesGeraet(eigenesGeraet); m.setName(name); m.setRollen(rollen);
m.setSpieltMit(spieltMit); m.setVerfuegbareWerkzeuge(new ArrayList<>(werkzeuge));
return m;
}
}

View File

@@ -0,0 +1,17 @@
package de.oaa.xxx.games.vanilla.entity;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import java.time.LocalDateTime;
import java.util.UUID;
@Getter @Setter @Entity @Table(name = "vanilla_setup_draft")
public class VanillaSetupDraftEntity {
@Id @Column(name = "user_id") private UUID userId;
@Column(length = 36) private String setupId;
@Column(columnDefinition = "TEXT") private String settingsJson;
@Column(columnDefinition = "TEXT") private String setupJson;
@Column(columnDefinition = "TEXT") private String gruppenJson;
@Column private LocalDateTime updatedAt;
}

View File

@@ -0,0 +1,11 @@
package de.oaa.xxx.games.vanilla.repository;
import de.oaa.xxx.games.vanilla.entity.VanillaEinladungEntity;
import de.oaa.xxx.games.vanilla.entity.VanillaEinladungEntity.Status;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
import java.util.UUID;
public interface VanillaEinladungRepository extends JpaRepository<VanillaEinladungEntity, UUID> {
List<VanillaEinladungEntity> findBySetupId(UUID setupId);
List<VanillaEinladungEntity> findByInviteeIdAndStatus(UUID inviteeId, Status status);
List<VanillaEinladungEntity> findByInviterIdAndStatus(UUID inviterId, Status status);
}

View File

@@ -0,0 +1,8 @@
package de.oaa.xxx.games.vanilla.repository;
import de.oaa.xxx.games.vanilla.entity.VanillaGameEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.Optional;
import java.util.UUID;
public interface VanillaGameRepository extends JpaRepository<VanillaGameEntity, UUID> {
Optional<VanillaGameEntity> findByUserId(UUID userId);
}

View File

@@ -0,0 +1,5 @@
package de.oaa.xxx.games.vanilla.repository;
import de.oaa.xxx.games.vanilla.entity.VanillaMitspielerEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.UUID;
public interface VanillaMitspielerRepository extends JpaRepository<VanillaMitspielerEntity, UUID> {}

View File

@@ -0,0 +1,9 @@
package de.oaa.xxx.games.vanilla.repository;
import de.oaa.xxx.games.vanilla.entity.VanillaSetupDraftEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.Optional;
import java.util.UUID;
public interface VanillaSetupDraftRepository extends JpaRepository<VanillaSetupDraftEntity, UUID> {
Optional<VanillaSetupDraftEntity> findByUserId(UUID userId);
Optional<VanillaSetupDraftEntity> findBySetupId(String setupId);
}

View File

@@ -1,18 +1,18 @@
package de.oaa.xxx.user;
import de.oaa.xxx.aufgaben.repository.AufgabeRepository;
import de.oaa.xxx.aufgaben.repository.AufgabenGruppeRepository;
import de.oaa.xxx.aufgaben.repository.FavoritRepository;
import de.oaa.xxx.aufgaben.repository.GruppenAboRepository;
import de.oaa.xxx.aufgaben.repository.SperreRepository;
import de.oaa.xxx.aufgaben.repository.StrafeRepository;
import de.oaa.xxx.aufgaben.repository.ToyRepository;
import de.oaa.xxx.emailchange.EmailChangeRepository;
import de.oaa.xxx.games.bdsm.entity.AktiveSperreEntity;
import de.oaa.xxx.games.bdsm.entity.MitspielerEntity;
import de.oaa.xxx.games.bdsm.repository.AktiveSperreRepository;
import de.oaa.xxx.games.common.repository.AufgabeRepository;
import de.oaa.xxx.games.common.repository.AufgabenGruppeRepository;
import de.oaa.xxx.games.bdsm.repository.BdsmGameRepository;
import de.oaa.xxx.games.common.repository.FavoritRepository;
import de.oaa.xxx.games.common.repository.GruppenAboRepository;
import de.oaa.xxx.games.bdsm.repository.MitspielerRepository;
import de.oaa.xxx.games.common.repository.SperreRepository;
import de.oaa.xxx.games.common.repository.StrafeRepository;
import de.oaa.xxx.games.common.repository.ToyRepository;
import de.oaa.xxx.passwordreset.PasswordResetRepository;
import de.oaa.xxx.registration.Registration;
import de.oaa.xxx.social.entity.MessageCause;

View File

@@ -4,7 +4,7 @@
<meta charset="UTF-8">
<link rel="icon" href="/img/icon.png" type="image/png">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Aufgaben xXx Sphere</title>
<title id="pageTitle">Aufgaben xXx Sphere</title>
<link rel="stylesheet" href="/css/variables.css">
<link rel="stylesheet" href="/css/style.css">
<style>
@@ -599,6 +599,21 @@
</div>
<script>
// ── Mode detection ──
const urlParams = new URLSearchParams(window.location.search);
const IS_BDSM_MODE = urlParams.get('mode') === 'bdsm';
// ── API-URL-Hilfsfunktion ──
function apiUrl(path) {
if (IS_BDSM_MODE) return path;
return '/vanilla' + path;
}
// ── Seitenüberschrift ──
document.getElementById('pageTitle').textContent = IS_BDSM_MODE
? 'Aufgaben BDSM xXx Sphere'
: 'Aufgaben Vanilla xXx Sphere';
const PAGE_SIZE = 5;
let userPage = 0, userTotalPages = 1;
let aboPage = 0, aboTotalPages = 1;
@@ -618,7 +633,7 @@
function loadUserGruppen() {
resetSelection();
document.getElementById('userLoading').style.display = 'block';
fetch(`/gruppe/list/user?page=${userPage}&size=${PAGE_SIZE}`)
fetch(apiUrl(`/gruppe/list/user`) + `?page=${userPage}&size=${PAGE_SIZE}`)
.then(r => { if (!r.ok) throw new Error(`HTTP ${r.status}`); return r.json(); })
.then(data => {
console.log('[aufgaben] user gruppen:', data);
@@ -634,7 +649,7 @@
function loadSystemGruppen() {
resetSelection();
document.getElementById('systemLoading').style.display = 'block';
fetch(`/gruppe/list/system?page=${systemPage}&size=${PAGE_SIZE}`)
fetch(apiUrl(`/gruppe/list/system`) + `?page=${systemPage}&size=${PAGE_SIZE}`)
.then(r => { if (!r.ok) throw new Error(`HTTP ${r.status}`); return r.json(); })
.then(data => {
console.log('[aufgaben] system gruppen:', data);
@@ -649,7 +664,7 @@
function loadAboGruppen() {
document.getElementById('aboLoading').style.display = 'block';
fetch(`/abo/list?page=${aboPage}&size=${PAGE_SIZE}`)
fetch(apiUrl(`/abo/list`) + `?page=${aboPage}&size=${PAGE_SIZE}`)
.then(r => { if (!r.ok) throw new Error(`HTTP ${r.status}`); return r.json(); })
.then(data => {
console.log('[aufgaben] abo gruppen:', data);
@@ -690,8 +705,8 @@
const finisherCount = (g.finisher || []).length;
const counts = [
aufgabenCount ? `${aufgabenCount} Aufgabe${aufgabenCount !== 1 ? 'n' : ''}` : '',
strafeCount ? `${strafeCount} Strafe${strafeCount !== 1 ? 'n' : ''}` : '',
sperreCount ? `${sperreCount} Zeitstrafe${sperreCount !== 1 ? 'n' : ''}` : '',
IS_BDSM_MODE && strafeCount ? `${strafeCount} Strafe${strafeCount !== 1 ? 'n' : ''}` : '',
IS_BDSM_MODE && sperreCount ? `${sperreCount} Zeitstrafe${sperreCount !== 1 ? 'n' : ''}` : '',
finisherCount ? `${finisherCount} Finisher` : ''
].filter(Boolean).join(' · ');
@@ -717,8 +732,8 @@
<div class="gruppe-body" id="body-${esc(g.gruppenId)}" style="display:none;">
${g.beschreibung ? `<div class="gruppe-desc">${esc(g.beschreibung)}</div>` : ''}
${renderSubSection('Aufgaben', sortByLevelThenName(g.aufgaben || []), 'aufgabe', renderAufgabe, g.gruppenId, type)}
${renderSubSection('Strafen', sortByLevelThenName(g.strafen || []), 'strafe', renderStrafe, g.gruppenId, type)}
${renderSubSection('Zeitstrafen',sortByName(g.sperren || []), 'zeitstrafe',renderZeitstrafe, g.gruppenId, type)}
${IS_BDSM_MODE ? renderSubSection('Strafen', sortByLevelThenName(g.strafen || []), 'strafe', renderStrafe, g.gruppenId, type) : ''}
${IS_BDSM_MODE ? renderSubSection('Zeitstrafen',sortByName(g.sperren || []), 'zeitstrafe',renderZeitstrafe, g.gruppenId, type) : ''}
${renderSubSection('Finisher', sortByName(g.finisher || []), 'finisher', renderFinisher, g.gruppenId, type)}
</div>
</div>`;
@@ -730,7 +745,8 @@
// ── Sub-sections ──
function renderSubSection(title, items, kind, renderFn, gruppenId, type) {
const addBtn = type === 'user'
const showAdd = type === 'user' && (IS_BDSM_MODE || (kind !== 'strafe' && kind !== 'zeitstrafe'));
const addBtn = showAdd
? `<button class="btn-sub-add" onclick="openItemModal('${esc(gruppenId)}','${kind}')">+ ${title.replace('en','').replace('fen','fe')}</button>`
: '';
return `<div class="sub-section">
@@ -889,14 +905,21 @@
}
// ── Item löschen ──
const ITEM_DELETE_URL = { aufgabe: '/aufgabe', strafe: '/strafe', zeitstrafe: '/sperre', finisher: '/finisher' };
const ITEM_DELETE_URL = {
aufgabe: apiUrl('/aufgabe'),
strafe: IS_BDSM_MODE ? '/strafe' : null,
zeitstrafe: IS_BDSM_MODE ? '/sperre' : null,
finisher: apiUrl('/finisher')
};
const ITEM_DELETE_FIELD = { aufgabe: 'aufgabeId', strafe: 'strafeId', zeitstrafe: 'sperreId', finisher: 'finisherId' };
function deleteItem(kind, itemId, gruppenId, event) {
event.stopPropagation();
if (!confirm('Eintrag wirklich löschen?')) return;
const deleteUrl = ITEM_DELETE_URL[kind];
if (!deleteUrl) return;
const body = { [ITEM_DELETE_FIELD[kind]]: itemId };
fetch(ITEM_DELETE_URL[kind], {
fetch(deleteUrl, {
method: 'DELETE',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body)
@@ -1027,7 +1050,7 @@
document.getElementById('gBild').value = '';
if (currentEditId) {
fetch(`/gruppe/${currentEditId}`)
fetch(apiUrl(`/gruppe/${currentEditId}`))
.then(r => r.ok ? r.json() : null)
.then(g => {
if (!g) return;
@@ -1091,7 +1114,7 @@
bild: bildBase64
};
fetch(isEdit ? `/gruppe/${currentEditId}` : '/gruppe', {
fetch(isEdit ? apiUrl(`/gruppe/${currentEditId}`) : apiUrl('/gruppe'), {
method: isEdit ? 'PUT' : 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
@@ -1126,7 +1149,7 @@
openConfirmModal('Aufgabengruppe und alle enthaltenen Aufgaben, Strafen und Zeitstrafen wirklich löschen?', () => {
const btn = document.getElementById('deleteBtn');
btn.disabled = true;
fetch(`/gruppe/${selectedGruppeId}`, { method: 'DELETE' })
fetch(apiUrl(`/gruppe/${selectedGruppeId}`), { method: 'DELETE' })
.then(r => {
if (r.ok || r.status === 202) {
userPage = 0;
@@ -1148,7 +1171,7 @@
if (!selectedGruppeId || selectedGruppeType !== 'system') return;
const btn = document.getElementById('copyBtn');
btn.disabled = true;
fetch(`/gruppe/copy/${selectedGruppeId}`, { method: 'POST' })
fetch(apiUrl(`/gruppe/copy/${selectedGruppeId}`), { method: 'POST' })
.then(r => {
if (r.ok || r.status === 201) {
userPage = 0;
@@ -1167,7 +1190,7 @@
if (!selectedGruppeId || selectedGruppeType !== 'abo') return;
const btn = document.getElementById('aboCopyBtn');
btn.disabled = true;
fetch(`/gruppe/copy/${selectedGruppeId}`, { method: 'POST' })
fetch(apiUrl(`/gruppe/copy/${selectedGruppeId}`), { method: 'POST' })
.then(r => {
if (r.ok || r.status === 201) {
userPage = 0;
@@ -1190,7 +1213,7 @@
if (!confirm('Abonnement dieser Gruppe wirklich kündigen?')) return;
const btn = document.getElementById('unsubBtn');
btn.disabled = true;
fetch(`/abo/${selectedGruppeId}`, { method: 'DELETE' })
fetch(apiUrl(`/abo/${selectedGruppeId}`), { method: 'DELETE' })
.then(r => {
if (r.ok || r.status === 202) {
resetSelection();
@@ -1210,7 +1233,7 @@
function _loadAvailableToys() {
if (_allAvailableToys !== null) return Promise.resolve(_allAvailableToys);
return fetch('/toy/available')
return fetch(apiUrl('/toy/available'))
.then(r => r.json())
.then(toys => { _allAvailableToys = toys || []; return _allAvailableToys; });
}
@@ -1442,7 +1465,7 @@
benoetigtPassiv: checkedValues('iWerkzeugPassiv'),
benoetigteToys: _selectedToys.map(t => ({ toyId: t.toyId }))
};
const base = kind === 'aufgabe' ? '/aufgabe' : '/strafe';
const base = kind === 'aufgabe' ? apiUrl('/aufgabe') : '/strafe';
url = isEdit ? `${base}/${currentItemEditId}` : base;
method = isEdit ? 'PUT' : 'POST';
@@ -1456,7 +1479,7 @@
benoetigtPassiv: checkedValues('iWerkzeugFinisherPassiv'),
benoetigteToys: _selectedToys.map(t => ({ toyId: t.toyId }))
};
url = isEdit ? `/finisher/${currentItemEditId}` : '/finisher';
url = isEdit ? apiUrl(`/finisher/${currentItemEditId}`) : apiUrl('/finisher');
method = isEdit ? 'PUT' : 'POST';
} else {
@@ -1475,7 +1498,7 @@
sperreFuer,
benoetigteToys: _selectedToys.map(t => ({ toyId: t.toyId }))
};
url = isEdit ? `/sperre/${currentItemEditId}` : '/sperre';
url = isEdit ? `/sperre/${currentItemEditId}` : '/sperre'; // BDSM-only
method = isEdit ? 'PUT' : 'POST';
}
@@ -1573,7 +1596,7 @@
publishConfirmBtn.disabled = true;
publishConfirmBtn.textContent = 'Wird veröffentlicht…';
fetch(`/gruppe/${selectedGruppeId}`, {
fetch(apiUrl(`/gruppe/${selectedGruppeId}`), {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({

View File

@@ -7,7 +7,12 @@
label: 'Vanilla Game',
icon: I('VANILLA'),
items: [
{ href: '/sessionvanilla.html', icon: I('PLAY_NEW'), label: 'Neue Session' },
{ href: '/neuvanilla.html', icon: I('PLAY_NEW'), label: 'Neue Session', id: 'navVanillaNeu' },
{ href: '#', icon: I('WAITING'), label: 'Aktive Session', id: 'navVanillaAktiv' },
{ href: '/vanillaingame.html', icon: I('PLAY_ACTIVE'), label: 'Im Spiel', id: 'navVanillaImSpiel' },
{ href: '/aufgaben.html', icon: I('CHECK'), label: 'Aufgaben' },
{ href: '/toys.html', icon: I('TOYS'), label: 'Toys' },
{ href: '/entdecken.html', icon: I('DISCOVER'), label: 'Entdecken' },
]
},
{
@@ -17,9 +22,9 @@
{ href: '/neubdsm.html', icon: I('PLAY_NEW'), label: 'Neue Session', id: 'navBdsmNeu' },
{ href: '#', icon: I('WAITING'), label: 'Aktive Session', id: 'navBdsmAktiv' },
{ href: '/bdsmingame.html', icon: I('PLAY_ACTIVE'), label: 'Im Spiel', id: 'navBdsmImSpiel' },
{ href: '/aufgaben.html', icon: I('CHECK'), label: 'Aufgaben' },
{ href: '/toys.html', icon: I('TOYS'), label: 'Toys' },
{ href: '/entdecken.html', icon: I('DISCOVER'), label: 'Entdecken' },
{ href: '/aufgaben.html?mode=bdsm', icon: I('CHECK'), label: 'Aufgaben' },
{ href: '/toys.html', icon: I('TOYS'), label: 'Toys' },
{ href: '/entdecken.html', icon: I('DISCOVER'), label: 'Entdecken' },
]
},
{
@@ -59,11 +64,12 @@
return `<li><a href="${href}"${cls}><span class="icon">${icon}</span> ${label}${badge}</a></li>`;
}).join('');
const fullHref = path + window.location.search;
const nav = groups.map(({ label, icon, items }) => {
const isOpen = items.some(item => item.href === path);
const isOpen = items.some(item => item.href === path || item.href === fullHref);
const openCls = isOpen ? ' open' : '';
const subItems = items.map(({ href, icon: iIcon, label: iLabel, id: iId }) => {
const cls = path === href ? ' class="active"' : '';
const cls = (href === path || href === fullHref) ? ' class="active"' : '';
const idAt = iId ? ` id="${iId}"` : '';
return `<li${idAt}><a href="${href}"${cls}><span class="icon">${iIcon}</span> ${iLabel}</a></li>`;
}).join('');
@@ -133,9 +139,14 @@
const navAktiv = document.getElementById('navBdsmAktiv');
const navImSpiel = document.getElementById('navBdsmImSpiel');
const navCAktiv = document.getElementById('navChastityAktiv');
const navVNeu = document.getElementById('navVanillaNeu');
const navVAktiv = document.getElementById('navVanillaAktiv');
const navVImSpiel = document.getElementById('navVanillaImSpiel');
if (navAktiv) navAktiv.style.display = 'none';
if (navImSpiel) navImSpiel.style.display = 'none';
if (navCAktiv) navCAktiv.style.display = 'none';
if (navVAktiv) navVAktiv.style.display = 'none';
if (navVImSpiel) navVImSpiel.style.display = 'none';
// Session-Status prüfen
fetch('/login/me')
@@ -162,6 +173,25 @@
}
} catch (_) {}
// Vanilla Session-Status
try {
const vAktivRes = await fetch('/vanilla/einladung/meine-aktive');
if (vAktivRes.ok) {
const vAktiv = await vAktivRes.json();
if (navVNeu) navVNeu.style.display = 'none';
if (navVImSpiel) navVImSpiel.style.display = 'none';
if (navVAktiv) {
navVAktiv.style.display = '';
navVAktiv.querySelector('a').href = vAktiv.sessionId ? '/vanillaingame.html' : '/neuvanilla.html';
}
} else {
const vSessionRes = await fetch(`/vanilla?userId=${user.userId}`);
const vHasSession = vSessionRes.status === 200;
if (navVNeu) navVNeu.style.display = vHasSession ? 'none' : '';
if (navVImSpiel) navVImSpiel.style.display = vHasSession ? '' : 'none';
}
} catch (_) {}
// Chastity Lock-Status
try {
const lockRes = await fetch('/keyholder/mylock');

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,11 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta http-equiv="refresh" content="0;url=/neuvanilla.html">
<title>Vanilla Game xXx Sphere</title>
</head>
<body>
<script>window.location.replace('/neuvanilla.html');</script>
</body>
</html>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,11 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta http-equiv="refresh" content="0;url=/neuvanilla.html">
<title>Vanilla Game xXx Sphere</title>
</head>
<body>
<script>window.location.replace('/neuvanilla.html');</script>
</body>
</html>