Initialer Commit

This commit is contained in:
2026-03-01 19:40:49 +01:00
commit 5dc408add8
255 changed files with 16104 additions and 0 deletions

View File

@@ -0,0 +1,12 @@
package de.oaa.xxx;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class XxxThegameApplication {
public static void main(String[] args) {
SpringApplication.run(XxxThegameApplication.class, args);
}
}

View File

@@ -0,0 +1,48 @@
package de.oaa.xxx.aufgaben;
import java.util.List;
import java.util.UUID;
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;
public UUID getAufgabeId() { return aufgabeId; }
public void setAufgabeId(UUID aufgabeId) { this.aufgabeId = aufgabeId; }
public String getKurzText() { return kurzText; }
public void setKurzText(String kurzText) { this.kurzText = kurzText; }
public String getText() { return text; }
public void setText(String text) { this.text = text; }
public Integer getLevel() { return level; }
public void setLevel(Integer level) { this.level = level; }
public Integer getSekundenVon() { return sekundenVon; }
public void setSekundenVon(Integer sekundenVon) { this.sekundenVon = sekundenVon; }
public Integer getSekundenBis() { return sekundenBis; }
public void setSekundenBis(Integer sekundenBis) { this.sekundenBis = sekundenBis; }
public UUID getGruppeId() { return gruppeId; }
public void setGruppeId(UUID gruppeId) { this.gruppeId = gruppeId; }
public List<Werkzeug> getBenoetigtAktiv() { return benoetigtAktiv; }
public void setBenoetigtAktiv(List<Werkzeug> benoetigtAktiv) { this.benoetigtAktiv = benoetigtAktiv; }
public List<Werkzeug> getBenoetigtPassiv() { return benoetigtPassiv; }
public void setBenoetigtPassiv(List<Werkzeug> benoetigtPassiv) { this.benoetigtPassiv = benoetigtPassiv; }
public List<Toy> getBenoetigteToys() { return benoetigteToys; }
public void setBenoetigteToys(List<Toy> benoetigteToys) { this.benoetigteToys = benoetigteToys; }
}

View File

@@ -0,0 +1,52 @@
package de.oaa.xxx.aufgaben;
import java.util.List;
import java.util.UUID;
public class AufgabenGruppe {
private UUID gruppenId;
private String name;
private String beschreibung;
private String von;
private UUID userId;
private boolean privateGruppe;
private List<Toy> toys;
private List<Aufgabe> aufgaben;
private List<Strafe> strafen;
private List<Sperre> sperren;
private String bild;
public UUID getGruppenId() { return gruppenId; }
public void setGruppenId(UUID gruppenId) { this.gruppenId = gruppenId; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getBeschreibung() { return beschreibung; }
public void setBeschreibung(String beschreibung) { this.beschreibung = beschreibung; }
public String getVon() { return von; }
public void setVon(String von) { this.von = von; }
public UUID getUserId() { return userId; }
public void setUserId(UUID userId) { this.userId = userId; }
public boolean isPrivateGruppe() { return privateGruppe; }
public void setPrivateGruppe(boolean privateGruppe) { this.privateGruppe = privateGruppe; }
public List<Toy> getToys() { return toys; }
public void setToys(List<Toy> toys) { this.toys = toys; }
public List<Aufgabe> getAufgaben() { return aufgaben; }
public void setAufgaben(List<Aufgabe> aufgaben) { this.aufgaben = aufgaben; }
public List<Strafe> getStrafen() { return strafen; }
public void setStrafen(List<Strafe> strafen) { this.strafen = strafen; }
public List<Sperre> getSperren() { return sperren; }
public void setSperren(List<Sperre> sperren) { this.sperren = sperren; }
public String getBild() { return bild; }
public void setBild(String bild) { this.bild = bild; }
}

View File

@@ -0,0 +1,35 @@
package de.oaa.xxx.aufgaben;
import java.util.UUID;
public class AufgabenGruppeDisplay {
private UUID gruppenId;
private String name;
private String beschreibung;
private UUID userId;
private boolean privateGruppe;
private String bild;
private String von;
public UUID getGruppenId() { return gruppenId; }
public void setGruppenId(UUID gruppenId) { this.gruppenId = gruppenId; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getBeschreibung() { return beschreibung; }
public void setBeschreibung(String beschreibung) { this.beschreibung = beschreibung; }
public UUID getUserId() { return userId; }
public void setUserId(UUID userId) { this.userId = userId; }
public boolean isPrivateGruppe() { return privateGruppe; }
public void setPrivateGruppe(boolean privateGruppe) { this.privateGruppe = privateGruppe; }
public String getBild() { return bild; }
public void setBild(String bild) { this.bild = bild; }
public String getVon() { return von; }
public void setVon(String von) { this.von = von; }
}

View File

@@ -0,0 +1,11 @@
package de.oaa.xxx.aufgaben;
import java.util.List;
public class AufgabenGruppeList {
private List<AufgabenGruppeDisplay> gruppen;
public List<AufgabenGruppeDisplay> getGruppen() { return gruppen; }
public void setGruppen(List<AufgabenGruppeDisplay> gruppen) { this.gruppen = gruppen; }
}

View File

@@ -0,0 +1,379 @@
package de.oaa.xxx.aufgaben;
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 java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
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 {
private final AufgabeRepository aufgabeRepository;
private final AufgabenGruppeRepository gruppeRepository;
private final SperreRepository sperreRepository;
private final StrafeRepository strafeRepository;
private final ToyRepository toyRepository;
public DefaultFiller(AufgabeRepository aufgabeRepository, AufgabenGruppeRepository gruppeRepository,
SperreRepository sperreRepository, StrafeRepository strafeRepository,
ToyRepository toyRepository) {
this.aufgabeRepository = aufgabeRepository;
this.gruppeRepository = gruppeRepository;
this.sperreRepository = sperreRepository;
this.strafeRepository = strafeRepository;
this.toyRepository = toyRepository;
}
@Transactional
public void fill() {
chastityFemale();
chastityMale();
plugs();
knebel();
stafen();
aufgaben();
}
void chastityFemale() {
AufgabenGruppeEntity keuschWiebl = createAufgGruppe("Keuschhaltung weiblich", "Enthält verschiedene Aufgaben für Keuschhaltung von weiblichen Spielpartnern", getClass().getClassLoader().getResourceAsStream("femaleCB.png"));
ToyEntity kg = createToy("KG weiblich", "Ein Voll-Keuschheitsgürtel für die Frau", keuschWiebl);
ToyEntity kgVaginal = createToy("KG weiblich, Vaginaldildo", "Ein Voll-Keuschheitsgürtel für die Frau inkl. eines Vaginaldildos", keuschWiebl);
ToyEntity kgAnal = createToy("KG weiblich, Analdildo", "Ein Voll-Keuschheitsgürtel für die Frau inkl. eines Analdildos", keuschWiebl);
ToyEntity kgDouble = createToy("KG weiblich, Vaginal- u. Analdildo", "Ein Voll-Keuschheitsgürtel für die Frau inkl. eines Vaginal- und Analdildos", keuschWiebl);
createSperre("Voll-KG", "{PASSIV} trägt fortan einen Voll-KG, {AKTIV} ist der Keyholder", "{AKTIV}, es ist ab der Zeit {PASSIV} von ihrem KG zu befreien", 10, 30, Arrays.asList(kg), Arrays.asList(VAGINA), keuschWiebl);
createSperre("Voll-KG + Vaginaldildo", "{PASSIV} trägt fortan einen Voll-KG mit Vaginaldildo, {AKTIV} ist der Keyholder", "{AKTIV}, es ist ab der Zeit {PASSIV} von ihrem KG zu befreien", 10, 30, Arrays.asList(kgVaginal), Arrays.asList(VAGINA), keuschWiebl);
createSperre("Voll-KG + Analdildo", "{PASSIV} trägt fortan einen Voll-KG mit Analdildo, {AKTIV} ist der Keyholder", "{AKTIV}, es ist ab der Zeit {PASSIV} von ihrem KG zu befreien", 10, 30, Arrays.asList(kgAnal), Arrays.asList(VAGINA, ANUS), keuschWiebl);
createSperre("Voll-KG + Doubleplugged", "{PASSIV} trägt fortan einen Voll-KG mit Vaginal- und Analdildo, {AKTIV} ist der Keyholder", "{AKTIV}, es ist ab der Zeit {PASSIV} von ihrem KG zu befreien", 10, 30, Arrays.asList(kgDouble), Arrays.asList(VAGINA, ANUS), keuschWiebl);
}
void chastityMale() {
AufgabenGruppeEntity keuschMaennl = createAufgGruppe("Keuschhaltung männlich", "Enthält verschiedene Aufgaben für Keuschhaltung von männlichen Spielpartnern", getClass().getClassLoader().getResourceAsStream("maleCB.png"));
ToyEntity kaefig = createToy("Peniskäfig", "Ein gewöhnlicher Peniskäfig", keuschMaennl);
ToyEntity kgMaennl = createToy("KG männlich", "Ein Voll-Keuschheitsgürtel für den Mann", keuschMaennl);
ToyEntity knMaennlAnal = createToy("KG männlich, Analdildo", "Ein Voll-Keuschheitsgürtel für den Mann inkl. eines Analdildos oder -plugs", keuschMaennl);
createSperre("Peniskäfig", "{PASSIV} trägt fortan einen Peniskäfig, {AKTIV} ist der Keyholder", "{AKTIV}, es ist ab der Zeit {PASSIV} von seinem Peniskäfig zu befreien", 10, 30, Arrays.asList(kaefig), Arrays.asList(PENIS), keuschMaennl);
createSperre("Voll-KG", "{PASSIV} trägt fortan einen Voll-KG, {AKTIV} ist der Keyholder", "{AKTIV}, es ist ab der Zeit {PASSIV} von seinem KG zu befreien", 10, 30, Arrays.asList(kgMaennl), Arrays.asList(PENIS), keuschMaennl);
createSperre("Voll-KG + Analdildo", "{PASSIV} trägt fortan einen Voll-KG mit Analdildo, {AKTIV} ist der Keyholder", "{AKTIV}, es ist ab der Zeit {PASSIV} von seinem KG zu befreien", 10, 30, Arrays.asList(knMaennlAnal), Arrays.asList(PENIS, ANUS), keuschMaennl);
}
void plugs() {
AufgabenGruppeEntity gruppe = createAufgGruppe("Plugs", "Enthält verschiedene Aufgaben für das Tragen von Buttplugs über einen gewissen Zeitraum.", getClass().getClassLoader().getResourceAsStream("plugs.png"));
ToyEntity plugKlein = createToy("Plug klein", "Ein kleiner Buttplug", gruppe);
ToyEntity plugMittel = createToy("Plug mittel", "Ein mittelgroßer Buttplug", gruppe);
ToyEntity plugGross = createToy("Plug groß", "Ein großer Buttplug", gruppe);
ToyEntity plugElektro = createToy("Elektro-Plug", "Ein Elektroplug, der Stromstöße verpasst", gruppe);
createSperre("Plug klein", "{AKTIV} führt {PASSIV} einen kleinen Buttplug in anal ein, dieser ist bis auf weiteres zu tragen.", "{AKTIV}, es ist Zeit {PASSIV} von seinem Plug zu befreien", 10, 30, Arrays.asList(plugKlein), Arrays.asList(ANUS), gruppe);
createSperre("Plug mittel", "{AKTIV} führt {PASSIV} einen mittelgroßen Buttplug anal ein, dieser ist bis auf weiteres zu tragen.", "{AKTIV}, es ist Zeit {PASSIV} von seinem Plug zu befreien", 10, 30, Arrays.asList(plugMittel), Arrays.asList(ANUS), gruppe);
createSperre("Plug groß", "{AKTIV} führt {PASSIV} einen großen Buttplug anal ein, dieser ist bis auf weiteres zu tragen.", "{AKTIV}, es ist Zeit {PASSIV} von seinem Plug zu befreien", 10, 30, Arrays.asList(plugGross), Arrays.asList(ANUS), gruppe);
createSperre("Elektro-Plug anal", "{AKTIV} führt {PASSIV} einen Elekro-Plug anal ein, dieser ist bis auf weiteres zu tragen. {AKTIV} darf {PASSIV} leichte Stromstöße verpassen", "{AKTIV}, es ist Zeit {PASSIV} von seinem Plug zu befreien", 10, 30, Arrays.asList(plugElektro), Arrays.asList(ANUS), gruppe);
createSperre("Elektro-Plug vaginal", "{AKTIV} führt {PASSIV} einen Elekto-Plug vaginal ein, dieser ist bis auf weiteres zu tragen. {AKTIV} darf {PASSIV} leichte Stromstöße verpassen", "{AKTIV}, es ist Zeit {PASSIV} von seinem Plug zu befreien", 10, 30, Arrays.asList(plugElektro), Arrays.asList(VAGINA), gruppe);
}
void knebel() {
AufgabenGruppeEntity gruppe = createAufgGruppe("Knebel", "Enthält verschiedene Aufgaben für das Tragen von Knebeln über einen gewissen Zeitraum.", getClass().getClassLoader().getResourceAsStream("knebel.png"));
ToyEntity ballKnebel = createToy("Ballknebel", "Ein Ballknebel", gruppe);
ToyEntity penisKnebel = createToy("Penisknebel", "Ein Penisknebel", gruppe);
ToyEntity aufblKnebel = createToy("Aufblasbarer Knebel", "Ein aufblasbarer Knebel", gruppe);
ToyEntity isolationsmaske = createToy("Isolationsmaske", "Eine Isolationsmaske", gruppe);
createSperre("Ballknebel", "{AKTIV}, lege {PASSIV} einen Ballknebel an, dieser ist bis auf weiteres zu tragen.", "{AKTIV}, es ist Zeit {PASSIV} von seinem Knebel zu befreien.", 10, 30, Arrays.asList(ballKnebel), Arrays.asList(MUND), gruppe);
createSperre("Penisknebel", "{AKTIV}, lege {PASSIV} einen Dildoknebel an, dieser ist bis auf weiteres zu tragen.", "{AKTIV}, es ist Zeit {PASSIV} von seinem Knebel zu befreien.", 10, 30, Arrays.asList(penisKnebel), Arrays.asList(MUND), gruppe);
createSperre("Aufblasbarer Knebel", "{AKTIV}, lege {PASSIV} einen aufblasbaren Knebel an und pumpe diesen soweit auf, dass {PASSIV} noch halbwegs gut atmen kann, dieser ist bis auf weiteres zu tragen.", "{AKTIV}, es ist Zeit {PASSIV} von seinem Knebel zu befreien.", 5, 15, Arrays.asList(aufblKnebel), Arrays.asList(MUND), gruppe);
createSperre("Isolationsmaske", "{AKTIV}, lege {PASSIV} eine Isolationsmaske an, diese ist bis auf weiteres zu tragen.", "{AKTIV}, es ist Zeit {PASSIV} von seinem Knebel zu befreien.", 5, 15, Arrays.asList(isolationsmaske), Arrays.asList(MUND), gruppe);
}
void stafen() {
AufgabenGruppeEntity strafen = createAufgGruppe("Strafen", "Enthält verschiedene Bestrafungen", getClass().getClassLoader().getResourceAsStream("peitsche.png"));
ToyEntity gerte = createToy("Gerte", "Eine gewöhnliche Gerte", strafen);
ToyEntity paddel = createToy("Paddel", "Eine gewöhnliches Paddel", strafen);
ToyEntity peitsche = createToy("Peitsche", "Eine gewöhnliche Peitsche", strafen);
ToyEntity penisKnebel = createToy("Doppel-Penisknebel", "Ein Doppel-Penisknebel", strafen);
ToyEntity handfesseln = createToy("Handfesseln", "Fesseln zum Binden der Hände, z.B. Handschellen", strafen);
ToyEntity plugGross = createToy("Plug groß", "Ein großer Buttplug", strafen);
ToyEntity plugElektro = createToy("Elektro-Plug", "Ein Elektroplug, der Stromstöße verpasst", strafen);
ToyEntity plugPump = createToy("Pump-Plug", "Ein aufblasbarer Plug", strafen);
ToyEntity nippelklemmen = createToy("Nippelklemmen", "Nippelklemmen", strafen);
ToyEntity augenbinde = createToy("Augenbinde", "Eine Augenbinde", strafen);
ToyEntity ballKnebel = createToy("Ballknebel", "Ein Ballknebel", strafen);
ToyEntity strapon = createToy("Strapon", "Ein Umschnalldildo", strafen);
ToyEntity kgMann = createToy("KG Mann", "Ein Voll-KG oder Peniskäfig für den Mann", strafen);
ToyEntity kgFrau = createToy("KG Frau", "Ein Voll-KG die Frau", strafen);
ToyEntity dildoKlein = createToy("Dildo klein", "Ein kleiner Dildo", strafen);
ToyEntity dildoGross = createToy("Dildo groß", "Ein großer Dildo", strafen);
createStrafe("5 Schläge mit flachen Hand", "{PASSIV} stellt sich mit dem Gesicht zur Wand, Hände hinterm Kopf, Beine schulterbreit, {AKTIV} verpasst {PASSIV} 5 Schläge mit der flachen Hand auf das Gesäß.",
1, null, null, Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), strafen);
createStrafe("15 Schläge mit flachen Hand", "{PASSIV} stellt sich mit dem Gesicht zur Wand, Hände hinterm Kopf, Beine schulterbreit, {AKTIV} verpasst {PASSIV} 15 beherzte Schläge mit der flachen Hand auf das Gesäß, {PASSIV} zählt laut mit",
3, null, null, Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), strafen);
createStrafe("5 Schläge mit Gerte", "{PASSIV} stellt sich mit dem Gesicht zur Wand, Hände hinterm Kopf, Beine schulterbreit, {AKTIV} verpasst {PASSIV} 5 Schläge mit der Gerte auf das Gesäß.",
2, null, null, Collections.emptyList(), Collections.emptyList(), Arrays.asList(gerte), strafen);
createStrafe("15 Schläge mit Gerte", "{PASSIV} stellt sich mit dem Gesicht zur Wand, Hände hinterm Kopf, Beine schulterbreit, {AKTIV} verpasst {PASSIV} 15 beherzte Schläge mit der Gerte auf das Gesäß, {PASSIV} zählt laut mit",
4, null, null, Collections.emptyList(), Collections.emptyList(), Arrays.asList(gerte), strafen);
createStrafe("5 Schläge mit Paddel", "{PASSIV} stellt sich mit dem Gesicht zur Wand, Hände hinterm Kopf, Beine schulterbreit, {AKTIV} verpasst {PASSIV} 5 Schläge mit dem Paddel auf das Gesäß.",
2, null, null, Collections.emptyList(), Collections.emptyList(), Arrays.asList(paddel), strafen);
createStrafe("15 Schläge mit Paddel", "{PASSIV} stellt sich mit dem Gesicht zur Wand, Hände hinterm Kopf, Beine schulterbreit, {AKTIV} verpasst {PASSIV} 15 beherzte Schläge mit dem Paddel auf das Gesäß, {PASSIV} zählt laut mit",
4, null, null, Collections.emptyList(), Collections.emptyList(), Arrays.asList(paddel), strafen);
createStrafe("5 Schläge mit Peitsche", "{PASSIV} stellt sich mit dem Gesicht zur Wand, Hände hinterm Kopf, Beine schulterbreit, {AKTIV} verpasst {PASSIV} 5 Schläge mit der Peitsche auf das Gesäß.",
3, null, null, Collections.emptyList(), Collections.emptyList(), Arrays.asList(peitsche), strafen);
createStrafe("15 Schläge mit Peitsche", "{PASSIV} stellt sich mit dem Gesicht zur Wand, Hände hinterm Kopf, Beine schulterbreit, {AKTIV} verpasst {PASSIV} 15 beherzte Schläge mit der Peitsche auf das Gesäß, {PASSIV} zählt laut mit",
5, null, null, Collections.emptyList(), Collections.emptyList(), Arrays.asList(peitsche), strafen);
createStrafe("Schläge auf Klitoris mit Hand", "{PASSIV} liegt auf dem Rücken mit breiten Beinen, {AKTIV} verpasst {PASSIV} 5 Schläge mit der Hand auf die Klitoris, {PASSIV} zählt laut mit",
4, null, null, Collections.emptyList(), Arrays.asList(VAGINA), Collections.emptyList(), strafen);
createStrafe("Schläge auf Klitoris mit Peitsche", "{PASSIV} liegt auf dem Rücken mit breiten Beinen, {AKTIV} verpasst {PASSIV} 5 Schläge mit der Peitsche auf die Klitoris, {PASSIV} zählt laut mit",
5, null, null, Collections.emptyList(), Arrays.asList(VAGINA), Arrays.asList(peitsche), strafen);
createStrafe("Schläge auf Klitoris mit Paddel", "{PASSIV} liegt auf dem Rücken mit breiten Beinen, {AKTIV} verpasst {PASSIV} 5 Schläge mit dem Paddel auf die Klitoris, {PASSIV} zählt laut mit",
5, null, null, Collections.emptyList(), Arrays.asList(VAGINA), Arrays.asList(paddel), strafen);
createStrafe("Schläge auf Klitoris mit Gerte", "{PASSIV} liegt auf dem Rücken mit breiten Beinen, {AKTIV} verpasst {PASSIV} 5 Schläge mit der Gerte auf die Klitoris, {PASSIV} zählt laut mit",
5, null, null, Collections.emptyList(), Arrays.asList(VAGINA), Arrays.asList(gerte), strafen);
createStrafe("5 Ohrfeigen", "{PASSIV} stellt sich mit dem Rücken zur Wand, Hände hinterm Kopf, Beine schulterbreit, {AKTIV} verpasst {PASSIV} 5 Ohrfeigen, {PASSIV} zählt laut mit",
5, null, null, Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), strafen);
createStrafe("Elektroplug anal", "{AKTIV} führt {PASSIV} anal einen Elektro-Plug ein. {AKTIV} erhöht ganz langsam die Intensität bis {PASSIV} 'STOP' sagt, dann fängt {AKTIV} wieder bei null an",
5, 30, 90, Collections.emptyList(), Arrays.asList(ANUS), Arrays.asList(plugElektro), strafen);
createStrafe("Elektroplug vaginal", "{AKTIV} führt {PASSIV} vaginal einen Elektro-Plug ein. {AKTIV} erhöht ganz langsam die Intensität bis {PASSIV} 'STOP' sagt, dann fängt {AKTIV} wieder bei null an",
5, 30, 90, Collections.emptyList(), Arrays.asList(VAGINA), Arrays.asList(plugElektro), strafen);
createStrafe("Pumpplug anal", "{AKTIV} führt {PASSIV} anal einen Pump-Plug ein. {AKTIV} pumpt ganz langsam auf bis {PASSIV} 'STOP' sagt, dann fängt {AKTIV} wieder bei null an",
5, 30, 90, Collections.emptyList(), Arrays.asList(ANUS), Arrays.asList(plugPump), strafen);
createStrafe("Pumpplug vaginal", "{AKTIV} führt {PASSIV} vaginal einen Pump-Plug ein. {AKTIV} pumpt ganz langsam auf bis {PASSIV} 'STOP' sagt, dann fängt {AKTIV} wieder bei null an",
5, 30, 90, Collections.emptyList(), Arrays.asList(VAGINA), Arrays.asList(plugPump), strafen);
createStrafe("Facesitting (Vagina)", "{PASSIV} liegt auf dem Rücken, {AKTIV} setzt sich auf das Gesicht von {PASSIV} und lässt sich den Vaginal und/oder Analbereich verwöhnen",
2, 90, 180, Arrays.asList(VAGINA, ANUS), Arrays.asList(MUND), Collections.emptyList(), strafen);
createStrafe("Facesitting gefesselt (Vagina)", "{PASSIV} liegt mit auf den Rücken gefesselten Händen auf dem Rücken, {AKTIV} setzt sich auf das Gesicht von {PASSIV} und lässt sich den Vaginal und/oder Analbereich verwöhnen",
4, 90, 180, Arrays.asList(VAGINA, ANUS), Arrays.asList(MUND), Arrays.asList(handfesseln), strafen);
createStrafe("Facesitting (Penis)", "{PASSIV} liegt auf dem Rücken, {AKTIV} setzt sich auf das Gesicht von {PASSIV} und lässt sich den Penis und/oder Analbereich verwöhnen",
2, 90, 180, Arrays.asList(PENIS, ANUS), Arrays.asList(MUND), Collections.emptyList(), strafen);
createStrafe("Facesitting gefesselt (Penis)", "{PASSIV} liegt mit auf den Rücken gefesselten Händen auf dem Rücken, {AKTIV} setzt sich auf das Gesicht von {PASSIV} und lässt sich den Penis und/oder Analbereich verwöhnen",
4, 90, 180, Arrays.asList(VAGINA, PENIS), Arrays.asList(MUND), Arrays.asList(handfesseln), strafen);
createStrafe("Facesitting Doppelpenisknebel", "{PASSIV} liegt auf dem Rücken, {AKTIV} legt {PASSIV} einen Doppel-Penisknebel an und reitet diesen vaginal oder anal",
3, 60, 120, Arrays.asList(VAGINA), Arrays.asList(MUND), Arrays.asList(penisKnebel), strafen);
createStrafe("Facesitting Doppelpenisknebel gefesselt", "{PASSIV} liegt mit auf den Rücken gefesselten Händen auf dem Rücken, {AKTIV} legt {PASSIV} einen Doppel-Penisknebel an und reitet diesen vaginal oder anal",
3, 60, 120, Arrays.asList(VAGINA), Arrays.asList(MUND), Arrays.asList(penisKnebel, handfesseln), strafen);
createStrafe("Nippelklemmen", "{AKTIV} legt {PASSIV} Nippelklemmen an, {AKTIV} zieht an der Kette und erhöht ganz langsam die Intensität bis {PASSIV} 'STOP' sagt, dann fängt {AKTIV} wieder bei null an",
3, 30, 90, Collections.emptyList(), Collections.emptyList(), Arrays.asList(nippelklemmen), strafen);
createStrafe("Nippelbehandlung", "{AKTIV} nimmt die Nippel von {PASSIV} zwischen die Finger und erhöht langsam den Druck bis {PASSIV} 'STOP' sagt",
2, null, null, Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), strafen);
createStrafe("Hilflos liegen lassen", "{AKTIV} fesselt, knebelt und verbindet die Augen von {PASSIV}. {AKTIV} lässt {PASSIV} wehrlos liegen, bei Ablauf der Zeit erlöst {AKTIV} {PASSIV} mit einem beherzten Platsch auf den Po",
4, 300, 600, Collections.emptyList(), Collections.emptyList(), Arrays.asList(handfesseln, ballKnebel, augenbinde), strafen);
createStrafe("Strapon reiten", "{PASSIV} liegt auf dem Rücken und trägt dabei einen Umschnalldildo. {AKTIV} reitet den Umschnalldildo von {PASSIV}",
3, 60, 180, Arrays.asList(VAGINA, ANUS), Collections.emptyList(), Arrays.asList(strapon), strafen);
createStrafe("Strapon reiten gefesselt", "{AKTIV} fesselt und knebelt {PASSIV}. {PASSIV} trägt dabei einen Umschnalldildo. {AKTIV} reitet den Umschnalldildo von {PASSIV}",
4, 60, 180, Arrays.asList(VAGINA, ANUS), Collections.emptyList(), Arrays.asList(strapon, handfesseln), strafen);
createStrafe("Teaseblowjob mit dem Strapon", "{AKTIV} fesselt und knebelt {PASSIV}. {PASSIV} trägt dabei einen Umschnalldildo, KG und einen großen Buttplug. {AKTIV} gibt dem Umschnalldildo einen Blowjob in 69er Position und präsentiert {PASSIV} dabei den Intimbereich",
5, 180, 300, Arrays.asList(VAGINA), Collections.emptyList(), Arrays.asList(kgMann, plugGross, handfesseln, strapon), strafen);
createStrafe("Teasereiten mit Strapon", "{AKTIV} fesselt und knebelt {PASSIV}. {PASSIV} trägt dabei einen Umschnalldildo, KG und einen großen Buttplug. {AKTIV} reitet den Umschnalldildo von {PASSIV}.",
5, 180, 300, Arrays.asList(VAGINA), Collections.emptyList(), Arrays.asList(kgMann, plugGross, handfesseln, strapon), strafen);
createStrafe("Tease mit Selbstbefriedigung (Mann KG)", "{AKTIV} knebelt und fesselt {PASSIV} an einen Stuhl. {PASSIV} trägt dabei einen KG und einen großen Buttplug. {AKTIV} befriedigt sich dann vor den Augen von {PASSIV} selber",
4, 240, 360, Arrays.asList(VAGINA), Collections.emptyList(), Arrays.asList(kgMann, plugGross, ballKnebel, handfesseln), strafen);
createStrafe("Tease mit Selbstbefriedigung (Frau KG)", "{AKTIV} knebelt und fesselt {PASSIV} an einen Stuhl. {PASSIV} trägt dabei einen KG und einen großen Buttplug. {AKTIV} befriedigt sich dann vor den Augen von {PASSIV} selber",
4, 240, 360, Arrays.asList(PENIS), Collections.emptyList(), Arrays.asList(kgFrau, plugGross, ballKnebel, handfesseln), strafen);
createStrafe("Blowjob auf allen vieren", "{AKTIV}, zwinge {PASSIV} vor dir auf die Knie, führe dein Glied (oder Strap on) in den Mund von {PASSIV} ein und zeig mit einem Deepthroat, wer das sagen hat",
5, 30, 90, Arrays.asList(PENIS, UMSCHNALLDILDO), Arrays.asList(MUND), Collections.emptyList(), strafen);
createStrafe("Oralsex mit kleinem Dildo in der Vagina", "{PASSIV}, geh auf die Knie und reite vaginal einen kleinen Dildo, befriedige dabei {AKTIV} oral.",
2, 60, 120, Arrays.asList(VAGINA, PENIS), Arrays.asList(VAGINA), Arrays.asList(dildoKlein), strafen);
createStrafe("Oralsex mit großen Dildo in der Vagina", "{PASSIV}, geh auf die Knie und reite vaginal einen großen Dildo, befriedige dabei {AKTIV} oral.",
4, 60, 120, Arrays.asList(VAGINA, PENIS), Arrays.asList(VAGINA), Arrays.asList(dildoGross), strafen);
createStrafe("Oralsex mit kleinem Dildo im Anus", "{PASSIV}, geh auf die Knie und reite anal einen kleinen Dildo, befriedige dabei {AKTIV} oral.",
3, 60, 120, Arrays.asList(VAGINA, PENIS), Arrays.asList(ANUS), Arrays.asList(dildoKlein), strafen);
createStrafe("Oralsex mit großen Dildo im Anus", "{PASSIV}, geh auf die Knie und reite anal einen großen Dildo, befriedige dabei {AKTIV} oral.",
4, 60, 120, Arrays.asList(VAGINA, PENIS), Arrays.asList(ANUS), Arrays.asList(dildoGross), strafen);
createStrafe("Vagina dehnen", "{PASSIV} geht auf alle viere und streckt den Hintern schön in die Luft, {AKTIV} führe langsam nach und nach mehr Finger in die Vagina von {PASSIV} ein, bis {PASSIV} 'STOP' sagt",
2, null, null, Collections.emptyList(), Arrays.asList(VAGINA), Collections.emptyList(), strafen);
createStrafe("Anus dehnen", "{PASSIV} geht auf alle viere und streckt den Hintern schön in die Luft, {AKTIV} führe langsam nach und nach mehr Finger in die Anus von {PASSIV} ein, bis {PASSIV} 'STOP' sagt",
2, null, null, Collections.emptyList(), Arrays.asList(ANUS), Collections.emptyList(), strafen);
createStrafe("Vaginalsex in Missionarstellung und Breathplay", "{AKTIV} dringt in Missionarsstellung in {PASSIV} und gibt vollgas, dabei packt {AKTIV} {PASSIV} am Hals und drückt beherzt zu",
4, 30, 60, Arrays.asList(PENIS, UMSCHNALLDILDO), Arrays.asList(VAGINA), Collections.emptyList(), strafen);
createStrafe("Analsex in Missionarstellung und Breathplay", "{AKTIV} dringt in Missionarsstellung anal in {PASSIV} und gibt vollgas, dabei packt {AKTIV} {PASSIV} am Hals und drückt beherzt zu",
4, 30, 60, Arrays.asList(PENIS, UMSCHNALLDILDO), Arrays.asList(ANUS), Collections.emptyList(), strafen);
}
void aufgaben() {
AufgabenGruppeEntity aufgaben = createAufgGruppe("Aufgaben", "Enthält verschiedene Sex-Aufgaben.", getClass().getClassLoader().getResourceAsStream("sex.png"));
ToyEntity vibrator = createToy("Vibrator", "Ein herkömmlicher Vibrator.", aufgaben);
ToyEntity dildoKlein = createToy("Dildo klein", "Ein kleiner Dildo", aufgaben);
ToyEntity dildoGross = createToy("Dildo groß", "Ein großer Dildo", aufgaben);
createAufgabe("Hintern präsentieren", "{AKTIV}, zeig {PASSIV} deinen Hintern, gib dir selber dabei ein oder zwei Klappse auf den Po",
1, null, null, Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), aufgaben);
createAufgabe("Hals küssen", "{AKTIV}, küsse den Hals von {PASSIV} leidenschaftlich",
1, 30, 60, Arrays.asList(MUND), Collections.emptyList(), Collections.emptyList(), aufgaben);
createAufgabe("Bauchnabel küssen", "{AKTIV}, zeichne mit Küssen den Bauchnabel von {PASSIV} nach",
1, 30, 60, Arrays.asList(MUND), Collections.emptyList(), Collections.emptyList(), aufgaben);
createAufgabe("Ohren knabbern", "{AKTIV}, knabber leidenschaftlich an den Ohrläppchen von {PASSIV}",
1, 30, 60, Arrays.asList(MUND), Collections.emptyList(), Collections.emptyList(), aufgaben);
createAufgabe("Berühren ohne anfassen", "{AKTIV}, berühre den gesamten Körper von {PASSIV} ohne die Hände zu verwenden",
2, 60, 120, Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), aufgaben);
createAufgabe("Nacken küssen", "{PASSIV} sitzt vor {AKTIV}, {AKTIV} küsste leidenschaftlich den Nacken von {PASSIV}",
1, 60, 120, Arrays.asList(MUND), Collections.emptyList(), Collections.emptyList(), aufgaben);
createAufgabe("Brust küssen", "{AKTIV}, küsse die Brust von {PASSIV} ohne die Nippel zu berühren",
1, 60, 120, Arrays.asList(MUND), Collections.emptyList(), Collections.emptyList(), aufgaben);
createAufgabe("Nippel verwöhnen", "{AKTIV}, verwöhne die Nippel von {PASSIV} mit Küssen",
2, 60, 120, Arrays.asList(MUND), Collections.emptyList(), Collections.emptyList(), aufgaben);
createAufgabe("Hintern küssen", "{AKTIV}, küsse den Hintern von {PASSIV} ohne den Anus zu berühren",
1, 60, 120, Arrays.asList(MUND), Collections.emptyList(), Collections.emptyList(), aufgaben);
createAufgabe("Intimkuss durch Unterwäsche", "{AKTIV}, küsse den Intimbereich von {PASSIV} durch die Unterwäsche",
2, 60, 120, Arrays.asList(MUND), Collections.emptyList(), Collections.emptyList(), aufgaben);
createAufgabe("Brustmassage", "{AKTIV}, massiere die Brust von {PASSIV} leidenschaftlich",
1, 60, 120, Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), aufgaben);
createAufgabe("Hinternmassage", "{AKTIV}, massiere den Hintern von {PASSIV} leidenschaftlich",
1, 60, 120, Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), aufgaben);
createAufgabe("Rückenmassage", "{AKTIV}, massiere den Rücken von {PASSIV} leidenschaftlich",
1, 60, 120, Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), aufgaben);
createAufgabe("Oberschenkelmassage", "{AKTIV}, massiere die Oberschenkel von {PASSIV} leidenschaftlich",
1, 60, 120, Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), aufgaben);
createAufgabe("Klitoris mit Vibrator verwöhnen", "{AKTIV}, verwöhne die Klitoris von {PASSIV} mit einem Vibrator",
3, 30, 180, Collections.emptyList(), Arrays.asList(VAGINA), Arrays.asList(vibrator), aufgaben);
createAufgabe("Cunnilingus und Finger in Vagina", "{AKTIV}, verwöhne die Klitoris von {PASSIV} mit dem Mund, führe dabei einen bis zwei Finger in die Vagina von {PASSIV} ein",
3, 30, 180, Arrays.asList(MUND), Arrays.asList(VAGINA), Collections.emptyList(), aufgaben);
createAufgabe("Klitoris mit Fingern verwöhnen und Finger in Vagina", "{AKTIV}, verwöhne die Klitoris von {PASSIV} mit der Hand, führe dabei einen bis zwei Finger in die Vagina von {PASSIV} ein",
4, 30, 180, Collections.emptyList(), Arrays.asList(VAGINA), Collections.emptyList(), aufgaben);
createAufgabe("Eichel mit Vibrator verwöhnen", "{AKTIV}, verwöhne die Eichel von {PASSIV} mit einem Vibrator",
3, 30, 180, Collections.emptyList(), Arrays.asList(PENIS), Arrays.asList(vibrator), aufgaben);
createAufgabe("Felatio", "{AKTIV}, verwöhne die Eichel von {PASSIV} mit dem Mund",
3, 30, 180, Arrays.asList(MUND), Arrays.asList(PENIS), Collections.emptyList(), aufgaben);
createAufgabe("Handjob", "{AKTIV}, verwöhne die Eichel von {PASSIV} mit der Hand",
3, 30, 180, Collections.emptyList(), Arrays.asList(PENIS), Collections.emptyList(), aufgaben);
createAufgabe("Facesitting", "{AKTIV} liegt auf dem Rücken, {PASSIV} sitzt auf seinem Gesicht. {AKTIV}, verwöhne die Vagina von {PASSIV} mit dem Mund",
4, 60, 180, Arrays.asList(MUND), Arrays.asList(VAGINA), Collections.emptyList(), aufgaben);
createAufgabe("69er-Position", "69er-Zeit: {AKTIV} liegt oben. {PASSIV}, falls du verschlossen bist, ziehe einen Strap on an, damit {AKTIV} auch was zu tun hat.",
4, 60, 180, Arrays.asList(VAGINA, MUND), Arrays.asList(MUND), Collections.emptyList(), aufgaben);
createAufgabe("Kleiner Dildo vaginal", "{AKTIV}, führe {PASSIV} einen kleinen Dildo vaginal ein und verwöhne {PASSIV} durch langsame Bewegungen mit selbigem",
3, 30, 180, Collections.emptyList(), Arrays.asList(VAGINA), Arrays.asList(dildoKlein), aufgaben);
createAufgabe("Großer Dildo vaginal", "{AKTIV}, führe {PASSIV} einen großen Dildo vaginal ein und verwöhne {PASSIV} durch langsame Bewegungen mit selbigem",
4, 30, 180, Collections.emptyList(), Arrays.asList(VAGINA), Arrays.asList(dildoGross), aufgaben);
createAufgabe("Großer Dildo vaginal schnell", "{AKTIV}, führe {PASSIV} einen großen Dildo vaginal ein und bewege selbigen möglichst schnell rein und raus",
5, 30, 60, Collections.emptyList(), Arrays.asList(VAGINA), Arrays.asList(dildoGross), aufgaben);
createAufgabe("Missionarstellung langsam", "{AKTIV} dringt in Missionarstellung in {PASSIV} ein und verwöhnt {PASSIV} mit langsamen Bewegungen",
3, 60, 180, Arrays.asList(PENIS, UMSCHNALLDILDO), Arrays.asList(VAGINA), Collections.emptyList(), aufgaben);
createAufgabe("Missionarstellung schnell", "{AKTIV} dringt in Missionarstellung in {PASSIV} ein und verwöhnt {PASSIV} mit schnellen Bewegungen",
4, 30, 90, Arrays.asList(PENIS, UMSCHNALLDILDO), Arrays.asList(VAGINA), Collections.emptyList(), aufgaben);
createAufgabe("Missionarstellung Vollgas", "{AKTIV} dringt in Missionarstellung in {PASSIV} ein und gibt vollgas",
5, 30, 60, Arrays.asList(PENIS, UMSCHNALLDILDO), Arrays.asList(VAGINA), Collections.emptyList(), aufgaben);
createAufgabe("Reiterstellung langsam", "{PASSIV} setzt sich in Reiterstellung auf {AKTIV}. {PASSIV} bestimmt das Tempo",
3, 60, 180, Arrays.asList(PENIS, UMSCHNALLDILDO), Arrays.asList(VAGINA), Collections.emptyList(), aufgaben);
createAufgabe("Reiterstellung schnell", "{PASSIV} setzt sich in Reiterstellung auf {AKTIV}. {PASSIV} versucht das Tempo hoch zu halten",
4, 60, 120, Arrays.asList(PENIS, UMSCHNALLDILDO), Arrays.asList(VAGINA), Collections.emptyList(), aufgaben);
createAufgabe("Reiterstellung vollgas", "{PASSIV} setzt sich in Reiterstellung auf {AKTIV} und gibt vollgas",
5, 30, 60, Arrays.asList(PENIS, UMSCHNALLDILDO), Arrays.asList(VAGINA), Collections.emptyList(), aufgaben);
createAufgabe("Doggystyle langsam", "{AKTIV} dringt in Hundestellung in {PASSIV} ein und verwöhnt {PASSIV} mit langsamen Bewegungen",
3, 60, 180, Arrays.asList(PENIS, UMSCHNALLDILDO), Arrays.asList(VAGINA), Collections.emptyList(), aufgaben);
createAufgabe("Doggystyle schnell", "{AKTIV} dringt in Hundestellung in {PASSIV} ein und verwöhnt {PASSIV} mit schnellen Bewegungen",
4, 60, 120, Arrays.asList(PENIS, UMSCHNALLDILDO), Arrays.asList(VAGINA), Collections.emptyList(), aufgaben);
createAufgabe("Doggystyle vollgas", "{AKTIV} dringt in Hundestellung in {PASSIV} ein und gibt vollgas",
5, 30, 60, Arrays.asList(PENIS, UMSCHNALLDILDO), Arrays.asList(VAGINA), Collections.emptyList(), aufgaben);
createAufgabe("Doggystyle vollgas keinen Mucks", "{AKTIV} dringt in Hundestellung in {PASSIV} ein und gibt vollgas. {PASSIV} darf dabei keinen Laut von sich geben.",
5, 30, 60, Arrays.asList(PENIS, UMSCHNALLDILDO), Arrays.asList(VAGINA), Collections.emptyList(), aufgaben);
createAufgabe("Doggystyle Tempo bestimmt die 'gefickte' Person", "{AKTIV} dringt in Hundestellung in {PASSIV} ein. {AKTIV} hält still und {PASSIV} gibt das Tempo vor",
3, 60, 180, Arrays.asList(PENIS, UMSCHNALLDILDO), Arrays.asList(VAGINA), Collections.emptyList(), aufgaben);
createAufgabe("Löffelchen langsam", "{AKTIV} dringt in Löffelchenstellung in {PASSIV} ein und verwöhnt {PASSIV} mit langsamen Bewegungen",
3, 60, 180, Arrays.asList(PENIS, UMSCHNALLDILDO), Arrays.asList(VAGINA), Collections.emptyList(), aufgaben);
createAufgabe("Löffelchen schnell", "{AKTIV} dringt in Löffelchenstellung in {PASSIV} ein und verwöhnt {PASSIV} mit schnellen Bewegungen",
4, 60, 120, Arrays.asList(PENIS, UMSCHNALLDILDO), Arrays.asList(VAGINA), Collections.emptyList(), aufgaben);
createAufgabe("Löffelchen vollgas", "{AKTIV} dringt in Löffelchenstellung in {PASSIV} ein und gibt vollgas",
5, 30, 60, Arrays.asList(PENIS, UMSCHNALLDILDO), Arrays.asList(VAGINA), Collections.emptyList(), aufgaben);
}
private AufgabeEntity createAufgabe(String kurzText, String text, Integer level, Integer sekundenVon, Integer sekundenBis,
List<Werkzeug> benoetigtAktiv, List<Werkzeug> benoetigtPassiv, List<ToyEntity> benoetigteToys,
AufgabenGruppeEntity gruppe) {
AufgabeEntity entity = new AufgabeEntity();
entity.setAufgabeId(UUID.randomUUID());
entity.setKurzText(kurzText);
entity.setText(text);
entity.setLevel(level);
entity.setSekundenVon(sekundenVon);
entity.setSekundenBis(sekundenBis);
entity.setBenoetigtAktiv(benoetigtAktiv);
entity.setBenoetigtPassiv(benoetigtPassiv);
entity.setBenoetigteToys(benoetigteToys);
entity.setAufgabenGruppe(gruppe);
aufgabeRepository.save(entity);
return entity;
}
private StrafeEntity createStrafe(String kurzText, String text, Integer level, Integer sekundenVon, Integer sekundenBis,
List<Werkzeug> benoetigtAktiv, List<Werkzeug> benoetigtPassiv, List<ToyEntity> benoetigteToys,
AufgabenGruppeEntity gruppe) {
StrafeEntity entity = new StrafeEntity();
entity.setStrafeId(UUID.randomUUID());
entity.setKurzText(kurzText);
entity.setText(text);
entity.setLevel(level);
entity.setSekundenVon(sekundenVon);
entity.setSekundenBis(sekundenBis);
entity.setBenoetigtAktiv(benoetigtAktiv);
entity.setBenoetigtPassiv(benoetigtPassiv);
entity.setBenoetigteToys(benoetigteToys);
entity.setAufgabenGruppe(gruppe);
strafeRepository.save(entity);
return entity;
}
private SperreEntity createSperre(String kurzText, String text, String releaseText, Integer von, Integer bis,
List<ToyEntity> toys, List<Werkzeug> sperreFuer, AufgabenGruppeEntity gruppe) {
SperreEntity entity = new SperreEntity();
entity.setSperreId(UUID.randomUUID());
entity.setKurzText(kurzText);
entity.setText(text);
entity.setReleaseText(releaseText);
entity.setMinutenVon(von);
entity.setMinutenBis(bis);
entity.setBenoetigteToys(toys);
entity.setSperreFuer(sperreFuer);
entity.setAufgabenGruppe(gruppe);
sperreRepository.save(entity);
return entity;
}
private AufgabenGruppeEntity createAufgGruppe(String name, String beschreibung, InputStream stream) {
AufgabenGruppeEntity entity = new AufgabenGruppeEntity();
entity.setGruppenId(UUID.randomUUID());
entity.setUserId(null);
entity.setName(name);
entity.setBeschreibung(beschreibung);
entity.setPrivateGruppe(false);
try {
if (stream != null) {
entity.setBild(stream.readAllBytes());
}
} catch (IOException e) {
e.printStackTrace();
}
gruppeRepository.save(entity);
return entity;
}
private ToyEntity createToy(String name, String beschreibung, AufgabenGruppeEntity gruppe) {
ToyEntity toy = new ToyEntity();
toy.setToyId(UUID.randomUUID());
toy.setName(name);
toy.setBeschreibung(beschreibung);
toy.setAufgabenGruppe(gruppe);
toyRepository.save(toy);
return toy;
}
}

View File

@@ -0,0 +1,19 @@
package de.oaa.xxx.aufgaben;
import java.util.UUID;
public class Favorit {
private UUID favoritId;
private UUID userId;
private UUID aufgabenGruppeId;
public UUID getFavoritId() { return favoritId; }
public void setFavoritId(UUID favoritId) { this.favoritId = favoritId; }
public UUID getUserId() { return userId; }
public void setUserId(UUID userId) { this.userId = userId; }
public UUID getAufgabenGruppeId() { return aufgabenGruppeId; }
public void setAufgabenGruppeId(UUID aufgabenGruppeId) { this.aufgabenGruppeId = aufgabenGruppeId; }
}

View File

@@ -0,0 +1,11 @@
package de.oaa.xxx.aufgaben;
import java.util.List;
public class FavoritList {
private List<Favorit> favoriten;
public List<Favorit> getFavoriten() { return favoriten; }
public void setFavoriten(List<Favorit> favoriten) { this.favoriten = favoriten; }
}

View File

@@ -0,0 +1,29 @@
package de.oaa.xxx.aufgaben;
import org.slf4j.LoggerFactory;
import javax.imageio.ImageIO;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
public class ImageScaler {
public byte[] scale(byte[] origByte) {
try (ByteArrayInputStream bais = new ByteArrayInputStream(origByte)) {
BufferedImage orig = ImageIO.read(bais);
BufferedImage scaled = (BufferedImage) orig.getScaledInstance(128, 128, Image.SCALE_DEFAULT);
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
ImageIO.write(scaled, "png", baos);
return baos.toByteArray();
} catch (IOException exception) {
LoggerFactory.getLogger(getClass()).error("Fehler beim Skalieren des Bildes", exception);
}
} catch (IOException exception) {
LoggerFactory.getLogger(getClass()).error("Fehler beim Skalieren des Bildes", exception);
}
return new byte[0];
}
}

View File

@@ -0,0 +1,44 @@
package de.oaa.xxx.aufgaben;
import java.util.List;
import java.util.UUID;
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;
public UUID getSperreId() { return sperreId; }
public void setSperreId(UUID sperreId) { this.sperreId = sperreId; }
public String getKurzText() { return kurzText; }
public void setKurzText(String kurzText) { this.kurzText = kurzText; }
public String getText() { return text; }
public void setText(String text) { this.text = text; }
public String getReleaseText() { return releaseText; }
public void setReleaseText(String releaseText) { this.releaseText = releaseText; }
public UUID getGruppeId() { return gruppeId; }
public void setGruppeId(UUID gruppeId) { this.gruppeId = gruppeId; }
public List<Werkzeug> getSperreFuer() { return sperreFuer; }
public void setSperreFuer(List<Werkzeug> sperreFuer) { this.sperreFuer = sperreFuer; }
public Integer getMinutenVon() { return minutenVon; }
public void setMinutenVon(Integer minutenVon) { this.minutenVon = minutenVon; }
public Integer getMinutenBis() { return minutenBis; }
public void setMinutenBis(Integer minutenBis) { this.minutenBis = minutenBis; }
public List<Toy> getBenoetigteToys() { return benoetigteToys; }
public void setBenoetigteToys(List<Toy> benoetigteToys) { this.benoetigteToys = benoetigteToys; }
}

View File

@@ -0,0 +1,48 @@
package de.oaa.xxx.aufgaben;
import java.util.List;
import java.util.UUID;
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 UUID getStrafeId() { return strafeId; }
public void setStrafeId(UUID strafeId) { this.strafeId = strafeId; }
public Integer getLevel() { return level; }
public void setLevel(Integer level) { this.level = level; }
public String getText() { return text; }
public void setText(String text) { this.text = text; }
public String getKurzText() { return kurzText; }
public void setKurzText(String kurzText) { this.kurzText = kurzText; }
public Integer getSekundenVon() { return sekundenVon; }
public void setSekundenVon(Integer sekundenVon) { this.sekundenVon = sekundenVon; }
public Integer getSekundenBis() { return sekundenBis; }
public void setSekundenBis(Integer sekundenBis) { this.sekundenBis = sekundenBis; }
public UUID getGruppeId() { return gruppeId; }
public void setGruppeId(UUID gruppeId) { this.gruppeId = gruppeId; }
public List<Werkzeug> getBenoetigtAktiv() { return benoetigtAktiv; }
public void setBenoetigtAktiv(List<Werkzeug> benoetigtAktiv) { this.benoetigtAktiv = benoetigtAktiv; }
public List<Werkzeug> getBenoetigtPassiv() { return benoetigtPassiv; }
public void setBenoetigtPassiv(List<Werkzeug> benoetigtPassiv) { this.benoetigtPassiv = benoetigtPassiv; }
public List<Toy> getBenoetigteToys() { return benoetigteToys; }
public void setBenoetigteToys(List<Toy> benoetigteToys) { this.benoetigteToys = benoetigteToys; }
}

View File

@@ -0,0 +1,23 @@
package de.oaa.xxx.aufgaben;
import java.util.UUID;
public class Toy {
private UUID toyId;
private String name;
private String beschreibung;
private UUID gruppeId;
public UUID getToyId() { return toyId; }
public void setToyId(UUID toyId) { this.toyId = toyId; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getBeschreibung() { return beschreibung; }
public void setBeschreibung(String beschreibung) { this.beschreibung = beschreibung; }
public UUID getGruppeId() { return gruppeId; }
public void setGruppeId(UUID gruppeId) { this.gruppeId = gruppeId; }
}

View File

@@ -0,0 +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; }
}

View File

@@ -0,0 +1,71 @@
package de.oaa.xxx.aufgaben.controller;
import de.oaa.xxx.aufgaben.Aufgabe;
import de.oaa.xxx.aufgaben.entity.AufgabeEntity;
import de.oaa.xxx.aufgaben.entity.AufgabenGruppeEntity;
import de.oaa.xxx.aufgaben.repository.AufgabeRepository;
import de.oaa.xxx.aufgaben.repository.AufgabenGruppeRepository;
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.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.UUID;
@RestController
@RequestMapping("/aufgabe")
@Transactional
public class AufgabeController {
private static final Logger LOGGER = LoggerFactory.getLogger(AufgabeController.class);
private final AufgabeRepository aufgabeRepository;
private final AufgabenGruppeRepository gruppeRepository;
public AufgabeController(AufgabeRepository aufgabeRepository, AufgabenGruppeRepository gruppeRepository) {
this.aufgabeRepository = aufgabeRepository;
this.gruppeRepository = gruppeRepository;
}
@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) {
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 || gruppeEntity.getAufgaben().size() > 50) {
return ResponseEntity.badRequest().build();
}
AufgabeEntity entity = AufgabeEntity.create(aufgabe, gruppeEntity);
aufgabeRepository.save(entity);
return ResponseEntity.created(
ServletUriComponentsBuilder.fromCurrentRequest().path("/{id}").buildAndExpand(entity.getAufgabeId()).toUri()
).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();
}
}
}

View File

@@ -0,0 +1,82 @@
package de.oaa.xxx.aufgaben.controller;
import de.oaa.xxx.aufgaben.AufgabenGruppe;
import de.oaa.xxx.aufgaben.AufgabenGruppeList;
import de.oaa.xxx.aufgaben.entity.AufgabenGruppeEntity;
import de.oaa.xxx.aufgaben.repository.AufgabenGruppeRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.PageRequest;
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.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
import java.util.UUID;
@RestController
@RequestMapping("/gruppe")
@Transactional
public class AufgabenGruppeController {
private static final Logger LOGGER = LoggerFactory.getLogger(AufgabenGruppeController.class);
private final AufgabenGruppeRepository gruppeRepository;
public AufgabenGruppeController(AufgabenGruppeRepository gruppeRepository) {
this.gruppeRepository = gruppeRepository;
}
@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.listWithUserAndSearch(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().map(AufgabenGruppeEntity::toAufgabenGruppeDisplay).toList());
return ResponseEntity.ok(list);
}
@GetMapping("/{gruppeId}")
public ResponseEntity<AufgabenGruppe> get(@PathVariable UUID gruppeId) {
return gruppeRepository.findById(gruppeId)
.map(entity -> ResponseEntity.ok(entity.toAufgabenGruppe()))
.orElse(ResponseEntity.noContent().build());
}
@PostMapping
public ResponseEntity<Void> create(@RequestBody AufgabenGruppe gruppe) {
AufgabenGruppeEntity entity = AufgabenGruppeEntity.create(gruppe);
gruppeRepository.save(entity);
return ResponseEntity.created(
ServletUriComponentsBuilder.fromCurrentRequest().path("/{id}").buildAndExpand(entity.getGruppenId()).toUri()
).build();
}
@DeleteMapping
public ResponseEntity<Void> delete(@RequestBody AufgabenGruppe gruppe) {
try {
gruppeRepository.findById(gruppe.getGruppenId()).ifPresent(gruppeRepository::delete);
return ResponseEntity.accepted().build();
} catch (Exception exception) {
LOGGER.error(exception.getMessage(), exception);
return ResponseEntity.internalServerError().build();
}
}
}

View File

@@ -0,0 +1,84 @@
package de.oaa.xxx.aufgaben.controller;
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;
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("/favorit")
@Transactional
public class FavoritController {
private static final Logger LOGGER = LoggerFactory.getLogger(FavoritController.class);
private final FavoritRepository favoritRepository;
public FavoritController(FavoritRepository favoritRepository) {
this.favoritRepository = favoritRepository;
}
@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();
result.setFavoriten(entities.stream().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();
}
List<FavoritEntity> existing = favoritRepository.findByUserIdAndAufgabenGruppeId(userId, favorit.getAufgabenGruppeId());
FavoritEntity entity;
if (existing.isEmpty()) {
entity = FavoritEntity.fromFavorit(favorit, userId);
favoritRepository.save(entity);
} 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,33 @@
package de.oaa.xxx.aufgaben.controller;
import de.oaa.xxx.aufgaben.DefaultFiller;
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;
@RestController
@RequestMapping("/filler")
public class FillerController {
private static final Logger LOGGER = LoggerFactory.getLogger(FillerController.class);
private final DefaultFiller defaultFiller;
public FillerController(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,72 @@
package de.oaa.xxx.aufgaben.controller;
import de.oaa.xxx.aufgaben.Sperre;
import de.oaa.xxx.aufgaben.entity.AufgabenGruppeEntity;
import de.oaa.xxx.aufgaben.entity.SperreEntity;
import de.oaa.xxx.aufgaben.repository.AufgabenGruppeRepository;
import de.oaa.xxx.aufgaben.repository.SperreRepository;
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.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.UUID;
@RestController
@RequestMapping("/sperre")
@Transactional
public class SperreController {
private static final Logger LOGGER = LoggerFactory.getLogger(SperreController.class);
private final SperreRepository sperreRepository;
private final AufgabenGruppeRepository gruppeRepository;
public SperreController(SperreRepository sperreRepository, AufgabenGruppeRepository gruppeRepository) {
this.sperreRepository = sperreRepository;
this.gruppeRepository = gruppeRepository;
}
@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 || gruppeEntity.getAufgaben().size() > 50) {
return ResponseEntity.badRequest().build();
}
SperreEntity entity = SperreEntity.create(sperre, gruppeEntity);
sperreRepository.save(entity);
return ResponseEntity.created(
ServletUriComponentsBuilder.fromCurrentRequest().path("/{id}").buildAndExpand(entity.getSperreId()).toUri()
).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();
}
}
}

View File

@@ -0,0 +1,71 @@
package de.oaa.xxx.aufgaben.controller;
import de.oaa.xxx.aufgaben.Strafe;
import de.oaa.xxx.aufgaben.entity.AufgabenGruppeEntity;
import de.oaa.xxx.aufgaben.entity.StrafeEntity;
import de.oaa.xxx.aufgaben.repository.AufgabenGruppeRepository;
import de.oaa.xxx.aufgaben.repository.StrafeRepository;
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.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.UUID;
@RestController
@RequestMapping("/strafe")
@Transactional
public class StrafeController {
private static final Logger LOGGER = LoggerFactory.getLogger(StrafeController.class);
private final StrafeRepository strafeRepository;
private final AufgabenGruppeRepository gruppeRepository;
public StrafeController(StrafeRepository strafeRepository, AufgabenGruppeRepository gruppeRepository) {
this.strafeRepository = strafeRepository;
this.gruppeRepository = gruppeRepository;
}
@GetMapping("/{strafeId}")
public ResponseEntity<Strafe> get(@PathVariable UUID strafeId) {
return strafeRepository.findById(strafeId)
.map(entity -> ResponseEntity.ok(entity.toStrafe()))
.orElse(ResponseEntity.noContent().build());
}
@PostMapping
public ResponseEntity<Void> create(@RequestBody Strafe strafe) {
if (strafe.getKurzText() == null || strafe.getText() == null || strafe.getLevel() == null || strafe.getGruppeId() == null) {
return ResponseEntity.badRequest().build();
}
AufgabenGruppeEntity gruppeEntity = gruppeRepository.findById(strafe.getGruppeId()).orElse(null);
if (gruppeEntity == null || gruppeEntity.getAufgaben().size() > 50) {
return ResponseEntity.badRequest().build();
}
StrafeEntity entity = StrafeEntity.create(strafe, gruppeEntity);
strafeRepository.save(entity);
return ResponseEntity.created(
ServletUriComponentsBuilder.fromCurrentRequest().path("/{id}").buildAndExpand(entity.getStrafeId()).toUri()
).build();
}
@DeleteMapping
public ResponseEntity<Void> delete(@RequestBody Strafe strafe) {
try {
strafeRepository.findById(strafe.getStrafeId()).ifPresent(strafeRepository::delete);
return ResponseEntity.accepted().build();
} catch (Exception exception) {
LOGGER.error(exception.getMessage(), exception);
return ResponseEntity.internalServerError().build();
}
}
}

View File

@@ -0,0 +1,73 @@
package de.oaa.xxx.aufgaben.controller;
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.AufgabenGruppeRepository;
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.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.UUID;
@RestController
@RequestMapping("/toy")
@Transactional
public class ToyController {
private static final Logger LOGGER = LoggerFactory.getLogger(ToyController.class);
private final ToyRepository toyRepository;
private final AufgabenGruppeRepository gruppeRepository;
public ToyController(ToyRepository toyRepository, AufgabenGruppeRepository gruppeRepository) {
this.toyRepository = toyRepository;
this.gruppeRepository = gruppeRepository;
}
@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) {
if (toy.getName() == null || toy.getGruppeId() == null) {
return ResponseEntity.badRequest().build();
}
AufgabenGruppeEntity gruppeEntity = gruppeRepository.findById(toy.getGruppeId()).orElse(null);
if (gruppeEntity == null || gruppeEntity.getAufgaben().size() > 50) {
return ResponseEntity.badRequest().build();
}
ToyEntity entity = ToyEntity.create(toy, gruppeEntity);
toyRepository.save(entity);
return ResponseEntity.created(
ServletUriComponentsBuilder.fromCurrentRequest().path("/{id}").buildAndExpand(entity.getToyId()).toUri()
).build();
}
@DeleteMapping
@Transactional
public ResponseEntity<Void> delete(@RequestBody Toy toy) {
// Bug fix: original code had transaction.rollback() here - now correctly uses @Transactional
try {
toyRepository.findById(toy.getToyId()).ifPresent(toyRepository::delete);
return ResponseEntity.accepted().build();
} catch (Exception exception) {
LOGGER.error(exception.getMessage(), exception);
return ResponseEntity.internalServerError().build();
}
}
}

View File

@@ -0,0 +1,115 @@
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 java.util.List;
import java.util.UUID;
@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;
public UUID getAufgabeId() { return aufgabeId; }
public void setAufgabeId(UUID aufgabeId) { this.aufgabeId = aufgabeId; }
public String getKurzText() { return kurzText; }
public void setKurzText(String kurzText) { this.kurzText = kurzText; }
public String getText() { return text; }
public void setText(String text) { this.text = text; }
public Integer getLevel() { return level; }
public void setLevel(Integer level) { this.level = level; }
public Integer getSekundenVon() { return sekundenVon; }
public void setSekundenVon(Integer sekundenVon) { this.sekundenVon = sekundenVon; }
public Integer getSekundenBis() { return sekundenBis; }
public void setSekundenBis(Integer sekundenBis) { this.sekundenBis = sekundenBis; }
public AufgabenGruppeEntity getAufgabenGruppe() { return aufgabenGruppe; }
public void setAufgabenGruppe(AufgabenGruppeEntity aufgabenGruppe) { this.aufgabenGruppe = aufgabenGruppe; }
public List<Werkzeug> getBenoetigtAktiv() { return benoetigtAktiv; }
public void setBenoetigtAktiv(List<Werkzeug> benoetigtAktiv) { this.benoetigtAktiv = benoetigtAktiv; }
public List<Werkzeug> getBenoetigtPassiv() { return benoetigtPassiv; }
public void setBenoetigtPassiv(List<Werkzeug> benoetigtPassiv) { this.benoetigtPassiv = benoetigtPassiv; }
public List<ToyEntity> getBenoetigteToys() { return benoetigteToys; }
public void setBenoetigteToys(List<ToyEntity> benoetigteToys) { this.benoetigteToys = benoetigteToys; }
public Aufgabe toAufgabe() {
Aufgabe aufgabe = new Aufgabe();
aufgabe.setAufgabeId(aufgabeId);
aufgabe.setBenoetigtAktiv(benoetigtAktiv);
aufgabe.setBenoetigteToys(benoetigteToys.stream().map(ToyEntity::toToy).toList());
aufgabe.setBenoetigtPassiv(benoetigtPassiv);
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) {
AufgabeEntity entity = new AufgabeEntity();
entity.setAufgabeId(UUID.randomUUID());
entity.setAufgabenGruppe(aufgabenGruppeEntity);
entity.setBenoetigtAktiv(aufgabe.getBenoetigtAktiv());
entity.setBenoetigteToys(aufgabe.getBenoetigteToys().stream().map(toy -> ToyEntity.create(toy, aufgabenGruppeEntity)).toList());
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

@@ -0,0 +1,122 @@
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 java.util.Base64;
import java.util.List;
import java.util.UUID;
@Entity
@Table(name = "aufgabenGruppe")
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;
@Column
private Integer relevanz;
@OneToMany(mappedBy = "aufgabenGruppe")
private List<ToyEntity> toys;
@OneToMany(mappedBy = "aufgabenGruppe")
private List<AufgabeEntity> aufgaben;
@OneToMany(mappedBy = "aufgabenGruppe")
private List<StrafeEntity> strafen;
@OneToMany(mappedBy = "aufgabenGruppe")
private List<SperreEntity> sperren;
public UUID getGruppenId() { return gruppenId; }
public void setGruppenId(UUID gruppenId) { this.gruppenId = gruppenId; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getBeschreibung() { return beschreibung; }
public void setBeschreibung(String beschreibung) { this.beschreibung = beschreibung; }
public UUID getUserId() { return userId; }
public void setUserId(UUID userId) { this.userId = userId; }
public boolean isPrivateGruppe() { return privateGruppe; }
public void setPrivateGruppe(boolean privateGruppe) { this.privateGruppe = privateGruppe; }
public byte[] getBild() { return bild; }
public void setBild(byte[] bild) { this.bild = bild; }
public String getVon() { return von; }
public void setVon(String von) { this.von = von; }
public Integer getRelevanz() { return relevanz; }
public void setRelevanz(Integer relevanz) { this.relevanz = relevanz; }
public List<ToyEntity> getToys() { return toys; }
public void setToys(List<ToyEntity> toys) { this.toys = toys; }
public List<AufgabeEntity> getAufgaben() { return aufgaben; }
public void setAufgaben(List<AufgabeEntity> aufgaben) { this.aufgaben = aufgaben; }
public List<StrafeEntity> getStrafen() { return strafen; }
public void setStrafen(List<StrafeEntity> strafen) { this.strafen = strafen; }
public List<SperreEntity> getSperren() { return sperren; }
public void setSperren(List<SperreEntity> sperren) { this.sperren = sperren; }
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.setToys(toys.stream().map(ToyEntity::toToy).toList());
gruppe.setAufgaben(aufgaben.stream().map(AufgabeEntity::toAufgabe).toList());
gruppe.setStrafen(strafen.stream().map(StrafeEntity::toStrafe).toList());
gruppe.setSperren(sperren.stream().map(SperreEntity::toSperre).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

@@ -0,0 +1,47 @@
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 java.util.UUID;
@Entity
@Table(name = "favorit")
public class FavoritEntity {
@Id
@Column
private UUID favoritId;
@Column
private UUID userId;
@Column
private UUID aufgabenGruppeId;
public UUID getFavoritId() { return favoritId; }
public void setFavoritId(UUID favoritId) { this.favoritId = favoritId; }
public UUID getUserId() { return userId; }
public void setUserId(UUID userId) { this.userId = userId; }
public UUID getAufgabenGruppeId() { return aufgabenGruppeId; }
public void setAufgabenGruppeId(UUID aufgabenGruppeId) { this.aufgabenGruppeId = 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

@@ -0,0 +1,104 @@
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 java.util.List;
import java.util.UUID;
@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;
public UUID getSperreId() { return sperreId; }
public void setSperreId(UUID sperreId) { this.sperreId = sperreId; }
public String getKurzText() { return kurzText; }
public void setKurzText(String kurzText) { this.kurzText = kurzText; }
public String getText() { return text; }
public void setText(String text) { this.text = text; }
public String getReleaseText() { return releaseText; }
public void setReleaseText(String releaseText) { this.releaseText = releaseText; }
public AufgabenGruppeEntity getAufgabenGruppe() { return aufgabenGruppe; }
public void setAufgabenGruppe(AufgabenGruppeEntity aufgabenGruppe) { this.aufgabenGruppe = aufgabenGruppe; }
public List<Werkzeug> getSperreFuer() { return sperreFuer; }
public void setSperreFuer(List<Werkzeug> sperreFuer) { this.sperreFuer = sperreFuer; }
public Integer getMinutenVon() { return minutenVon; }
public void setMinutenVon(Integer minutenVon) { this.minutenVon = minutenVon; }
public Integer getMinutenBis() { return minutenBis; }
public void setMinutenBis(Integer minutenBis) { this.minutenBis = minutenBis; }
public List<ToyEntity> getBenoetigteToys() { return benoetigteToys; }
public void setBenoetigteToys(List<ToyEntity> benoetigteToys) { this.benoetigteToys = benoetigteToys; }
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);
sperre.setText(text);
return sperre;
}
public static SperreEntity create(Sperre sperre, AufgabenGruppeEntity aufgabenGruppeEntity) {
SperreEntity entity = new SperreEntity();
entity.setSperreId(UUID.randomUUID());
entity.setAufgabenGruppe(aufgabenGruppeEntity);
entity.setBenoetigteToys(sperre.getBenoetigteToys().stream().map(toy -> ToyEntity.create(toy, aufgabenGruppeEntity)).toList());
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

@@ -0,0 +1,115 @@
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 java.util.List;
import java.util.UUID;
@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;
public UUID getStrafeId() { return strafeId; }
public void setStrafeId(UUID strafeId) { this.strafeId = strafeId; }
public String getKurzText() { return kurzText; }
public void setKurzText(String kurzText) { this.kurzText = kurzText; }
public Integer getLevel() { return level; }
public void setLevel(Integer level) { this.level = level; }
public String getText() { return text; }
public void setText(String text) { this.text = text; }
public Integer getSekundenVon() { return sekundenVon; }
public void setSekundenVon(Integer sekundenVon) { this.sekundenVon = sekundenVon; }
public Integer getSekundenBis() { return sekundenBis; }
public void setSekundenBis(Integer sekundenBis) { this.sekundenBis = sekundenBis; }
public AufgabenGruppeEntity getAufgabenGruppe() { return aufgabenGruppe; }
public void setAufgabenGruppe(AufgabenGruppeEntity aufgabenGruppe) { this.aufgabenGruppe = aufgabenGruppe; }
public List<Werkzeug> getBenoetigtAktiv() { return benoetigtAktiv; }
public void setBenoetigtAktiv(List<Werkzeug> benoetigtAktiv) { this.benoetigtAktiv = benoetigtAktiv; }
public List<Werkzeug> getBenoetigtPassiv() { return benoetigtPassiv; }
public void setBenoetigtPassiv(List<Werkzeug> benoetigtPassiv) { this.benoetigtPassiv = benoetigtPassiv; }
public List<ToyEntity> getBenoetigteToys() { return benoetigteToys; }
public void setBenoetigteToys(List<ToyEntity> benoetigteToys) { this.benoetigteToys = benoetigteToys; }
public Strafe toStrafe() {
Strafe strafe = new Strafe();
strafe.setStrafeId(strafeId);
strafe.setBenoetigtAktiv(benoetigtAktiv);
strafe.setBenoetigteToys(benoetigteToys.stream().map(ToyEntity::toToy).toList());
strafe.setBenoetigtPassiv(benoetigtPassiv);
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) {
StrafeEntity entity = new StrafeEntity();
entity.setStrafeId(UUID.randomUUID());
entity.setAufgabenGruppe(aufgabenGruppeEntity);
entity.setBenoetigtAktiv(strafe.getBenoetigtAktiv());
entity.setBenoetigteToys(strafe.getBenoetigteToys().stream().map(toy -> ToyEntity.create(toy, aufgabenGruppeEntity)).toList());
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

@@ -0,0 +1,57 @@
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.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import java.util.UUID;
@Entity
@Table(name = "toy")
public class ToyEntity {
@Id
@Column
private UUID toyId;
@Column
private String name;
@Column
private String beschreibung;
@ManyToOne
@JoinColumn(name = "gruppeId")
private AufgabenGruppeEntity aufgabenGruppe;
public UUID getToyId() { return toyId; }
public void setToyId(UUID toyId) { this.toyId = toyId; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getBeschreibung() { return beschreibung; }
public void setBeschreibung(String beschreibung) { this.beschreibung = beschreibung; }
public AufgabenGruppeEntity getAufgabenGruppe() { return aufgabenGruppe; }
public void setAufgabenGruppe(AufgabenGruppeEntity aufgabenGruppe) { this.aufgabenGruppe = aufgabenGruppe; }
public Toy toToy() {
Toy toy = new Toy();
toy.setBeschreibung(beschreibung);
toy.setName(name);
toy.setGruppeId(aufgabenGruppe.getGruppenId());
toy.setToyId(toyId);
return toy;
}
public static ToyEntity create(Toy toy, AufgabenGruppeEntity aufgabenGruppeEntity) {
ToyEntity entity = new ToyEntity();
entity.setAufgabenGruppe(aufgabenGruppeEntity);
entity.setBeschreibung(toy.getBeschreibung());
entity.setName(toy.getName());
entity.setToyId(UUID.randomUUID());
return entity;
}
}

View File

@@ -0,0 +1,9 @@
package de.oaa.xxx.aufgaben.repository;
import de.oaa.xxx.aufgaben.entity.AufgabeEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.UUID;
public interface AufgabeRepository extends JpaRepository<AufgabeEntity, UUID> {
}

View File

@@ -0,0 +1,22 @@
package de.oaa.xxx.aufgaben.repository;
import de.oaa.xxx.aufgaben.entity.AufgabenGruppeEntity;
import org.springframework.data.domain.PageRequest;
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);
@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);
}

View File

@@ -0,0 +1,14 @@
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);
}

View File

@@ -0,0 +1,9 @@
package de.oaa.xxx.aufgaben.repository;
import de.oaa.xxx.aufgaben.entity.SperreEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.UUID;
public interface SperreRepository extends JpaRepository<SperreEntity, UUID> {
}

View File

@@ -0,0 +1,9 @@
package de.oaa.xxx.aufgaben.repository;
import de.oaa.xxx.aufgaben.entity.StrafeEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.UUID;
public interface StrafeRepository extends JpaRepository<StrafeEntity, UUID> {
}

View File

@@ -0,0 +1,9 @@
package de.oaa.xxx.aufgaben.repository;
import de.oaa.xxx.aufgaben.entity.ToyEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.UUID;
public interface ToyRepository extends JpaRepository<ToyEntity, UUID> {
}

View File

@@ -0,0 +1,41 @@
package de.oaa.xxx.config;
import io.jsonwebtoken.Claims;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.filter.OncePerRequestFilter;
import java.io.IOException;
import java.util.Collections;
import java.util.UUID;
public class JwtAuthenticationFilter extends OncePerRequestFilter {
private final JwtService jwtService;
public JwtAuthenticationFilter(JwtService jwtService) {
this.jwtService = jwtService;
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
String token = request.getHeader("token");
if (token != null && !token.isBlank()) {
String clientIp = request.getRemoteAddr();
Claims claims = jwtService.validateToken(token, clientIp);
if (claims != null) {
String userIdStr = claims.get("userId", String.class);
UUID userId = UUID.fromString(userIdStr);
UsernamePasswordAuthenticationToken authentication =
new UsernamePasswordAuthenticationToken(userId, null, Collections.emptyList());
SecurityContextHolder.getContext().setAuthentication(authentication);
}
}
filterChain.doFilter(request, response);
}
}

View File

@@ -0,0 +1,90 @@
package de.oaa.xxx.config;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.security.Key;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.util.Base64;
import java.util.Date;
import java.util.UUID;
@Service
public class JwtService {
private static final Logger LOGGER = LoggerFactory.getLogger(JwtService.class);
@Value("${jwt.keystore.password}")
private String keyPass;
@Value("${jwt.keystore.alias}")
private String alias;
private KeyStore getKeystore() throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException {
KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
keystore.load(getClass().getClassLoader().getResourceAsStream("xxx.jks"), keyPass.toCharArray());
return keystore;
}
public String createToken(String email, UUID userId, String clientIp) {
try {
KeyStore keystore = getKeystore();
Key key = keystore.getKey(alias, keyPass.toCharArray());
String token = Jwts.builder()
.issuer("OAA Games")
.issuedAt(new Date())
.claim("email", email)
.claim("client", clientIp)
.claim("userId", userId.toString())
.signWith(key)
.compact();
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Erstellter token: {}", token);
}
return token;
} catch (Exception e) {
LOGGER.error("Fehler beim Erstellen des Tokens", e);
throw new RuntimeException("Token-Erstellung fehlgeschlagen", e);
}
}
public Claims validateToken(String token, String clientIp) {
try {
KeyStore keystore = getKeystore();
Key key = keystore.getKey(alias, keyPass.toCharArray());
Jws<Claims> claimsJws = Jwts.parser().verifyWith((java.security.PublicKey) keystore.getCertificate(alias).getPublicKey()).build().parseSignedClaims(token);
Claims claims = claimsJws.getPayload();
String tokenClient = claims.get("client", String.class);
if (!clientIp.equals(tokenClient)) {
LOGGER.warn("IP-Adresse stimmt nicht überein: Token={}, Request={}", tokenClient, clientIp);
return null;
}
return claims;
} catch (Exception e) {
LOGGER.debug("Token-Validierung fehlgeschlagen: {}", e.getMessage());
return null;
}
}
public String getPublicKeyBase64() {
try {
KeyStore keystore = getKeystore();
PublicKey publicKey = keystore.getCertificate(alias).getPublicKey();
return Base64.getEncoder().encodeToString(publicKey.getEncoded());
} catch (Exception e) {
LOGGER.error("Fehler beim Laden des Public Keys", e);
throw new RuntimeException("Public-Key-Laden fehlgeschlagen", e);
}
}
}

View File

@@ -0,0 +1,39 @@
package de.oaa.xxx.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
@Configuration
@EnableWebSecurity
public class SecurityConfig {
private final JwtService jwtService;
public SecurityConfig(JwtService jwtService) {
this.jwtService = jwtService;
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf(AbstractHttpConfigurer::disable)
.sessionManagement(sm -> sm.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.authorizeHttpRequests(auth -> auth
.requestMatchers(HttpMethod.GET, "/login", "/login/publickey").permitAll()
.requestMatchers(HttpMethod.POST, "/user").permitAll()
.requestMatchers(HttpMethod.POST, "/registration").permitAll()
.requestMatchers(HttpMethod.GET, "/registration/activation/**").permitAll()
.requestMatchers(HttpMethod.POST, "/filler").permitAll()
.anyRequest().authenticated()
)
.addFilterBefore(new JwtAuthenticationFilter(jwtService), UsernamePasswordAuthenticationFilter.class);
return http.build();
}
}

View File

@@ -0,0 +1,17 @@
package de.oaa.xxx.mail;
public class Email {
private String emailAdresse;
private String titel;
private String text;
public String getEmailAdresse() { return emailAdresse; }
public void setEmailAdresse(String emailAdresse) { this.emailAdresse = emailAdresse; }
public String getTitel() { return titel; }
public void setTitel(String titel) { this.titel = titel; }
public String getText() { return text; }
public void setText(String text) { this.text = text; }
}

View File

@@ -0,0 +1,37 @@
package de.oaa.xxx.mail;
import jakarta.mail.Message;
import jakarta.mail.MessagingException;
import jakarta.mail.internet.InternetAddress;
import jakarta.mail.internet.MimeMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;
@Service
public class MailService {
private static final Logger LOGGER = LoggerFactory.getLogger(MailService.class);
private final JavaMailSender mailSender;
public MailService(JavaMailSender mailSender) {
this.mailSender = mailSender;
}
public boolean send(Email email) {
try {
MimeMessage message = mailSender.createMimeMessage();
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(email.getEmailAdresse()));
message.setSubject(email.getTitel());
message.setFrom(InternetAddress.parse("noreply@xxx-bdsmgame.de")[0]);
message.setContent(email.getText(), "text/html; charset=utf-8");
mailSender.send(message);
return true;
} catch (MessagingException e) {
LOGGER.error(e.getLocalizedMessage(), e);
return false;
}
}
}

View File

@@ -0,0 +1,47 @@
package de.oaa.xxx.registration;
import de.oaa.xxx.user.Registration;
import de.oaa.xxx.user.UserController;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.net.URI;
import java.util.UUID;
@RestController
@RequestMapping("/registration/activation")
public class ActivationController {
private final RegistrationRepository registrationRepository;
private final UserController userController;
public ActivationController(RegistrationRepository registrationRepository, UserController userController) {
this.registrationRepository = registrationRepository;
this.userController = userController;
}
@GetMapping("/{uuid}")
public ResponseEntity<Void> activate(@PathVariable String uuid) {
RegistrationEntity registration = registrationRepository.findById(UUID.fromString(uuid)).orElse(null);
if (registration != null && !Boolean.TRUE.equals(registration.getActivated())) {
Registration reg = new Registration();
reg.setEmail(registration.getEmail());
reg.setName(registration.getName());
reg.setPasswordHash(registration.getPassword());
ResponseEntity<Void> response = userController.userAnlegen(reg);
if (response.getStatusCode().is2xxSuccessful()) {
registration.setActivated(Boolean.TRUE);
registrationRepository.save(registration);
return ResponseEntity.status(302).location(URI.create("/activation.html")).build();
} else {
return ResponseEntity.internalServerError().build();
}
} else {
return ResponseEntity.noContent().build();
}
}
}

View File

@@ -0,0 +1,28 @@
package de.oaa.xxx.registration;
import java.util.UUID;
public class Registration {
private UUID id;
private String name;
private String email;
private String passwordHash;
public UUID getId() { return id; }
public void setId(UUID id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
public String getPasswordHash() { return passwordHash; }
public void setPasswordHash(String passwordHash) { this.passwordHash = passwordHash; }
@Override
public String toString() {
return "Registration [id=" + id + ", name=" + name + ", email=" + email + "]";
}
}

View File

@@ -0,0 +1,59 @@
package de.oaa.xxx.registration;
import de.oaa.xxx.mail.Email;
import de.oaa.xxx.mail.MailService;
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.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/registration")
public class RegistrationController {
private static final Logger LOGGER = LoggerFactory.getLogger(RegistrationController.class);
private final RegistrationRepository registrationRepository;
private final MailService mailService;
public RegistrationController(RegistrationRepository registrationRepository, MailService mailService) {
this.registrationRepository = registrationRepository;
this.mailService = mailService;
}
@PostMapping
public ResponseEntity<Void> create(@RequestBody Registration registration) {
LOGGER.info("POST {}: {}", getClass().getName(), registration);
if (!registrationRepository.findByEmail(registration.getEmail()).isEmpty()) {
LOGGER.warn("User mit E-Mail {} bereits vorhanden", registration.getEmail());
return ResponseEntity.badRequest().build();
}
RegistrationEntity entity = RegistrationEntity.create(registration);
registrationRepository.save(entity);
registration.setId(entity.getRegistrationId());
Email email = new Email();
email.setTitel("Bitte bestätige deine E-Mail Adresse");
email.setEmailAdresse(registration.getEmail());
email.setText(getMailText(registration));
if (!mailService.send(email)) {
registrationRepository.delete(entity);
return ResponseEntity.internalServerError().build();
}
return ResponseEntity.accepted().build();
}
private String getMailText(Registration registration) {
return """
<html>
<h1>Moin %s</h1>
<p>Vielen Dank für deine Anmeldung bei XXX-BDSM Game!</p>
<p>Klicke <a href="http://localhost:8080/registration/activation/%s">hier</a> um deine E-Mail-Adresse zu bestätigen.</p>
<p>Und nun viel Spass beim Spiel!</p>
</html>""".formatted(registration.getName(), registration.getId().toString());
}
}

View File

@@ -0,0 +1,64 @@
package de.oaa.xxx.registration;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import java.util.UUID;
@Entity
@Table(name = "registration")
public class RegistrationEntity {
@Id
@Column
private UUID registrationId;
@Column
private String name;
@Column(unique = true)
private String email;
@Column
private String password;
@Column
private Boolean activated;
public UUID getRegistrationId() { return registrationId; }
public void setRegistrationId(UUID registrationId) { this.registrationId = registrationId; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
public Boolean getActivated() { return activated; }
public void setActivated(Boolean activated) { this.activated = activated; }
public String getPassword() { return password; }
public void setPassword(String password) { this.password = password; }
@Override
public String toString() {
return "RegistrationEntity [registrationId=" + registrationId + ", name=" + name + ", email=" + email + "]";
}
public Registration toRegistration() {
Registration registration = new Registration();
registration.setId(registrationId);
registration.setEmail(email);
registration.setName(name);
registration.setPasswordHash(password);
return registration;
}
public static RegistrationEntity create(Registration registration) {
RegistrationEntity entity = new RegistrationEntity();
entity.setRegistrationId(UUID.randomUUID());
entity.setEmail(registration.getEmail());
entity.setActivated(Boolean.FALSE);
entity.setName(registration.getName());
entity.setPassword(registration.getPasswordHash());
return entity;
}
}

View File

@@ -0,0 +1,11 @@
package de.oaa.xxx.registration;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
import java.util.UUID;
public interface RegistrationRepository extends JpaRepository<RegistrationEntity, UUID> {
List<RegistrationEntity> findByEmail(String email);
}

View File

@@ -0,0 +1,37 @@
package de.oaa.xxx.session;
import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;
public class AktiveSperre {
private UUID aktiveSperreId;
private Mitspieler mitspieler;
private Integer minuten;
private LocalDateTime startzeit;
private LocalDateTime endzeit;
private List<Werkzeug> fuer;
private String releaseText;
public UUID getAktiveSperreId() { return aktiveSperreId; }
public void setAktiveSperreId(UUID aktiveSperreId) { this.aktiveSperreId = aktiveSperreId; }
public Mitspieler getMitspieler() { return mitspieler; }
public void setMitspieler(Mitspieler mitspieler) { this.mitspieler = mitspieler; }
public Integer getMinuten() { return minuten; }
public void setMinuten(Integer minuten) { this.minuten = minuten; }
public LocalDateTime getStartzeit() { return startzeit; }
public void setStartzeit(LocalDateTime startzeit) { this.startzeit = startzeit; }
public LocalDateTime getEndzeit() { return endzeit; }
public void setEndzeit(LocalDateTime endzeit) { this.endzeit = endzeit; }
public List<Werkzeug> getFuer() { return fuer; }
public void setFuer(List<Werkzeug> fuer) { this.fuer = fuer; }
public String getReleaseText() { return releaseText; }
public void setReleaseText(String releaseText) { this.releaseText = releaseText; }
}

View File

@@ -0,0 +1,21 @@
package de.oaa.xxx.session;
public class AufgabeAnzeige {
private String nameAktiverMitspieler;
private String aufgabeText;
private Integer timer;
private Callback callback;
public String getNameAktiverMitspieler() { return nameAktiverMitspieler; }
public void setNameAktiverMitspieler(String nameAktiverMitspieler) { this.nameAktiverMitspieler = nameAktiverMitspieler; }
public String getAufgabeText() { return aufgabeText; }
public void setAufgabeText(String aufgabeText) { this.aufgabeText = aufgabeText; }
public Integer getTimer() { return timer; }
public void setTimer(Integer timer) { this.timer = timer; }
public Callback getCallback() { return callback; }
public void setCallback(Callback callback) { this.callback = callback; }
}

View File

@@ -0,0 +1,7 @@
package de.oaa.xxx.session;
public enum AufgabeArt {
AUFGABE,
STRAFE,
SPERRE;
}

View File

@@ -0,0 +1,11 @@
package de.oaa.xxx.session;
import java.util.UUID;
public abstract class Callback {
private UUID sessionId;
public UUID getSessionId() { return sessionId; }
public void setSessionId(UUID sessionId) { this.sessionId = sessionId; }
}

View File

@@ -0,0 +1,7 @@
package de.oaa.xxx.session;
public enum GeschlechtEnum {
WEIBLICH,
DIVERS,
MAENNLICH;
}

View File

@@ -0,0 +1,46 @@
package de.oaa.xxx.session;
import java.util.List;
import java.util.UUID;
public class Mitspieler {
private UUID id;
private String name;
private GeschlechtEnum geschlecht;
private List<GeschlechtEnum> spieltMit;
private List<RolleEnum> rollen;
private List<Werkzeug> verfuegbareWerkzeuge;
public UUID getId() { return id; }
public void setId(UUID id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public GeschlechtEnum getGeschlecht() { return geschlecht; }
public void setGeschlecht(GeschlechtEnum geschlecht) { this.geschlecht = geschlecht; }
public List<GeschlechtEnum> getSpieltMit() { return spieltMit; }
public void setSpieltMit(List<GeschlechtEnum> spieltMit) { this.spieltMit = spieltMit; }
public List<RolleEnum> getRollen() { return rollen; }
public void setRollen(List<RolleEnum> rollen) { this.rollen = rollen; }
public List<Werkzeug> getVerfuegbareWerkzeuge() { return verfuegbareWerkzeuge; }
public void setVerfuegbareWerkzeuge(List<Werkzeug> verfuegbareWerkzeuge) { this.verfuegbareWerkzeuge = verfuegbareWerkzeuge; }
public boolean isVerfuegbar(Werkzeug werkzeug) {
return verfuegbareWerkzeuge.contains(werkzeug);
}
public boolean isPassenderSpielpartner(Mitspieler other) {
if (!spieltMit.contains(other.getGeschlecht())) {
return false;
}
if (!other.spieltMit.contains(geschlecht)) {
return false;
}
return true;
}
}

View File

@@ -0,0 +1,8 @@
package de.oaa.xxx.session;
public enum RolleEnum {
BESTRAFUNG_AKTIV,
BESTRAFUNG_PASSIV,
AUFGABE_AKTIV,
AUFGABE_PASSIV;
}

View File

@@ -0,0 +1,31 @@
package de.oaa.xxx.session;
import java.util.UUID;
public class Session {
private UUID sessionId;
private UUID userId;
private Integer wahrscheinlichkeitSperre;
private Integer wahrscheinlichkeitStrafe;
private Integer aufgabenProLevel;
private Double zeitfaktorZeitstrafen;
public UUID getSessionId() { return sessionId; }
public void setSessionId(UUID sessionId) { this.sessionId = sessionId; }
public UUID getUserId() { return userId; }
public void setUserId(UUID userId) { this.userId = userId; }
public Integer getWahrscheinlichkeitSperre() { return wahrscheinlichkeitSperre; }
public void setWahrscheinlichkeitSperre(Integer wahrscheinlichkeitSperre) { this.wahrscheinlichkeitSperre = wahrscheinlichkeitSperre; }
public Integer getWahrscheinlichkeitStrafe() { return wahrscheinlichkeitStrafe; }
public void setWahrscheinlichkeitStrafe(Integer wahrscheinlichkeitStrafe) { this.wahrscheinlichkeitStrafe = wahrscheinlichkeitStrafe; }
public Integer getAufgabenProLevel() { return aufgabenProLevel; }
public void setAufgabenProLevel(Integer aufgabenProLevel) { this.aufgabenProLevel = aufgabenProLevel; }
public Double getZeitfaktorZeitstrafen() { return zeitfaktorZeitstrafen; }
public void setZeitfaktorZeitstrafen(Double zeitfaktorZeitstrafen) { this.zeitfaktorZeitstrafen = zeitfaktorZeitstrafen; }
}

View File

@@ -0,0 +1,213 @@
package de.oaa.xxx.session;
import com.fasterxml.jackson.databind.ObjectMapper;
import de.oaa.xxx.session.aufgaben.Aufgabe;
import de.oaa.xxx.session.aufgaben.AufgabenList;
import de.oaa.xxx.session.aufgaben.Sperre;
import de.oaa.xxx.session.aufgaben.Strafe;
import de.oaa.xxx.session.entity.SessionEntity;
import de.oaa.xxx.session.sperre.SperreCallback;
import de.oaa.xxx.session.sperre.SperrenVerlaengernCallback;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;
public class SessionDurchfuehren {
private final AufgabenList aufgabenList;
private final List<Mitspieler> mitspieler = new ArrayList<>();
private final List<AktiveSperre> aktiveSperren = new ArrayList<>();
private final Integer wahrscheinlichkeitSperre;
private final Integer wahrscheinlichkeitStrafe;
private final Integer aufgabenProLevel;
private Integer level;
private Integer aufgabenAufAktuellemLevel;
public SessionDurchfuehren(SessionEntity entity) throws Exception {
ObjectMapper objectMapper = new ObjectMapper();
aufgabenList = objectMapper.readValue(entity.getAufgaben(), AufgabenList.class);
entity.getMitspieler().forEach(mitspielerEntity -> mitspieler.add(mitspielerEntity.toMitspieler()));
entity.getAktiveSperren().forEach(sperreEntity -> aktiveSperren.add(sperreEntity.toSperre(mitspieler)));
wahrscheinlichkeitSperre = entity.getWahrscheinlichkeitSperre();
wahrscheinlichkeitStrafe = entity.getWahrscheinlichkeitStrafe();
aufgabenProLevel = entity.getAufgabenProLevel() != null ? entity.getAufgabenProLevel() : 5;
level = entity.getLevel() != null ? entity.getLevel() : 1;
aufgabenAufAktuellemLevel = entity.getAufgabenAufAktuellemLevel() != null ? entity.getAufgabenAufAktuellemLevel() : 0;
}
public AufgabeAnzeige getNext() {
checkLevel();
AufgabeAnzeige anzeige = null;
int nextInt = new Random().nextInt(1, 100);
if (nextInt == 1) {
anzeige = findUltimativeStrafe();
} else if (nextInt == 2) {
anzeige = findSperreVerlaengern();
} else if (nextInt > wahrscheinlichkeitSperre + wahrscheinlichkeitStrafe + 2) {
anzeige = findeAufgabe();
} else if (nextInt > wahrscheinlichkeitSperre + 2) {
anzeige = findeStrafe();
} else {
anzeige = findeSperre();
}
if (anzeige == null) {
Mitspieler aktiv = findeMitspielerMitRolle(RolleEnum.AUFGABE_AKTIV);
Mitspieler passiv = findeMitspielerMitRolle(RolleEnum.AUFGABE_PASSIV, aktiv);
String text = "Ups, da ist etwas schief gelaufen. Keine potenzielle Aufgabe gefunden. Entweder seid ihr inzwischen so gut weggesperrt, dass wirklich keine Aufgaben mehr zur Verfügung stehen, oder uns ist ein Fehler unterlaufen. {AKTIV} und {PASSIV} überbrücken die Zeit mit ein wenig Petting.";
anzeige = new AufgabeAnzeige();
anzeige.setNameAktiverMitspieler(aktiv != null ? aktiv.getName() : "");
anzeige.setAufgabeText(getAnzeigeText(text, aktiv != null ? aktiv.getName() : "?", passiv != null ? passiv.getName() : "?"));
anzeige.setTimer(120);
}
return anzeige;
}
private void checkLevel() {
if (++aufgabenAufAktuellemLevel >= aufgabenProLevel && level < 5) {
aufgabenAufAktuellemLevel = 0;
level++;
}
}
private AufgabeAnzeige findUltimativeStrafe() {
Mitspieler aktiv = findeMitspielerMitRolle(RolleEnum.BESTRAFUNG_AKTIV);
if (aktiv != null) {
Mitspieler passiv = findeMitspielerMitRolle(RolleEnum.BESTRAFUNG_PASSIV, aktiv);
if (passiv != null) {
String text = "{AKTIV}, verschnüre {PASSIV} fachmännisch inkl. KG, Plugs, Knebel, Augenbinde und was dir sonst einfällt. Nutze die Ruhe für was auch immer du möchtest.";
AufgabeAnzeige anzeige = new AufgabeAnzeige();
anzeige.setNameAktiverMitspieler(aktiv.getName());
anzeige.setAufgabeText(getAnzeigeText(text, aktiv.getName(), passiv.getName()));
anzeige.setTimer(new Random().nextInt(1800, 7200));
return anzeige;
}
}
return findeStrafe();
}
private AufgabeAnzeige findSperreVerlaengern() {
if (!aktiveSperren.isEmpty()) {
AktiveSperre sperre = aktiveSperren.get(new Random().nextInt(aktiveSperren.size()));
Mitspieler passiv = sperre.getMitspieler();
Mitspieler aktiv = findeMitspielerMitRolle(RolleEnum.BESTRAFUNG_AKTIV, passiv);
if (aktiv != null) {
String text = "{AKTIV}, du entscheidest. Sollen alle bestehenden Zeitstrafen von {PASSIV} verlängert werden...?";
AufgabeAnzeige anzeige = new AufgabeAnzeige();
anzeige.setAufgabeText(getAnzeigeText(text, aktiv.getName(), passiv.getName()));
anzeige.setNameAktiverMitspieler(aktiv.getName());
SperrenVerlaengernCallback callback = new SperrenVerlaengernCallback();
callback.setFaktor(new Random().nextInt(2, 4));
callback.setSpielerId(passiv.getId());
anzeige.setCallback(callback);
return anzeige;
}
}
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))
.collect(Collectors.toList());
if (!list.isEmpty()) {
Aufgabe aufgabe = list.get(new Random().nextInt(list.size()));
AufgabeAnzeige anzeige = new AufgabeAnzeige();
anzeige.setNameAktiverMitspieler(aktiv.getName());
anzeige.setAufgabeText(getAnzeigeText(aufgabe.getText(), aktiv.getName(), passiv.getName()));
if (aufgabe.getSekundenVon() != null) {
if (aufgabe.getSekundenBis() != null) {
anzeige.setTimer(new Random().nextInt(aufgabe.getSekundenVon(), aufgabe.getSekundenBis()));
} else {
anzeige.setTimer(aufgabe.getSekundenVon());
}
}
return anzeige;
}
}
}
return findeStrafe();
}
private AufgabeAnzeige findeStrafe() {
Mitspieler aktiv = findeMitspielerMitRolle(RolleEnum.BESTRAFUNG_AKTIV);
if (aktiv != null) {
Mitspieler passiv = findeMitspielerMitRolle(RolleEnum.BESTRAFUNG_PASSIV, aktiv);
if (passiv != null) {
List<Strafe> list = aufgabenList.getStrafen().stream()
.filter(strafe -> strafe.isAufgabePassend(level, aktiv, passiv))
.collect(Collectors.toList());
if (!list.isEmpty()) {
Strafe strafe = list.get(new Random().nextInt(list.size()));
AufgabeAnzeige anzeige = new AufgabeAnzeige();
anzeige.setNameAktiverMitspieler(aktiv.getName());
anzeige.setAufgabeText(getAnzeigeText(strafe.getText(), aktiv.getName(), passiv.getName()));
if (strafe.getSekundenVon() != null) {
if (strafe.getSekundenBis() != null) {
anzeige.setTimer(new Random().nextInt(strafe.getSekundenVon(), strafe.getSekundenBis()));
} else {
anzeige.setTimer(strafe.getSekundenVon());
}
}
return anzeige;
}
}
}
return findeSperre();
}
private AufgabeAnzeige findeSperre() {
Mitspieler aktiv = findeMitspielerMitRolle(RolleEnum.BESTRAFUNG_AKTIV);
if (aktiv != null) {
Mitspieler passiv = findeMitspielerMitRolle(RolleEnum.BESTRAFUNG_PASSIV, aktiv);
if (passiv != null) {
List<Sperre> list = aufgabenList.getSperren().stream()
.filter(sperre -> sperre.isAufgabePassend(passiv))
.collect(Collectors.toList());
if (!list.isEmpty()) {
Sperre sperre = list.get(new Random().nextInt(list.size()));
AufgabeAnzeige anzeige = new AufgabeAnzeige();
anzeige.setNameAktiverMitspieler(aktiv.getName());
anzeige.setAufgabeText(getAnzeigeText(sperre.getText(), aktiv.getName(), passiv.getName()));
SperreCallback callback = new SperreCallback();
callback.setSperreId(sperre.getSperreId());
callback.setSpielerId(passiv.getId());
callback.setReleaseText(getAnzeigeText(sperre.getReleaseText(), aktiv.getName(), passiv.getName()));
anzeige.setCallback(callback);
return anzeige;
}
}
}
return null;
}
private String getAnzeigeText(String textMitPlatzhaltern, String nameAktiv, String namePassiv) {
return textMitPlatzhaltern.replace("{AKTIV}", nameAktiv).replace("{PASSIV}", namePassiv);
}
private Mitspieler findeMitspielerMitRolle(RolleEnum rolle) {
List<Mitspieler> list = mitspieler.stream()
.filter(m -> m.getRollen().contains(rolle))
.toList();
return list.isEmpty() ? null : list.get(new Random().nextInt(list.size()));
}
private Mitspieler findeMitspielerMitRolle(RolleEnum rolle, Mitspieler gegenspieler) {
if (gegenspieler == null) return findeMitspielerMitRolle(rolle);
List<Mitspieler> list = mitspieler.stream()
.filter(m -> m != gegenspieler)
.filter(m -> m.isPassenderSpielpartner(gegenspieler))
.filter(m -> m.getRollen().contains(rolle))
.toList();
return list.isEmpty() ? null : list.get(new Random().nextInt(list.size()));
}
}

View File

@@ -0,0 +1,26 @@
package de.oaa.xxx.session;
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

@@ -0,0 +1,70 @@
package de.oaa.xxx.session.aufgaben;
import de.oaa.xxx.session.Mitspieler;
import de.oaa.xxx.session.Werkzeug;
import java.util.List;
import java.util.UUID;
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;
public UUID getAufgabeId() { return aufgabeId; }
public void setAufgabeId(UUID aufgabeId) { this.aufgabeId = aufgabeId; }
public String getKurzText() { return kurzText; }
public void setKurzText(String kurzText) { this.kurzText = kurzText; }
public String getText() { return text; }
public void setText(String text) { this.text = text; }
public Integer getLevel() { return level; }
public void setLevel(Integer level) { this.level = level; }
public Integer getSekundenVon() { return sekundenVon; }
public void setSekundenVon(Integer sekundenVon) { this.sekundenVon = sekundenVon; }
public Integer getSekundenBis() { return sekundenBis; }
public void setSekundenBis(Integer sekundenBis) { this.sekundenBis = sekundenBis; }
public UUID getGruppeId() { return gruppeId; }
public void setGruppeId(UUID gruppeId) { this.gruppeId = gruppeId; }
public List<Werkzeug> getBenoetigtAktiv() { return benoetigtAktiv; }
public void setBenoetigtAktiv(List<Werkzeug> benoetigtAktiv) { this.benoetigtAktiv = benoetigtAktiv; }
public List<Werkzeug> getBenoetigtPassiv() { return benoetigtPassiv; }
public void setBenoetigtPassiv(List<Werkzeug> benoetigtPassiv) { this.benoetigtPassiv = 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;
}
}
}

View File

@@ -0,0 +1,27 @@
package de.oaa.xxx.session.aufgaben;
import java.util.List;
public class AufgabenList {
private List<Aufgabe> aufgaben;
private List<Sperre> sperren;
private List<Strafe> strafen;
public List<Aufgabe> getAufgaben() { return aufgaben; }
public void setAufgaben(List<Aufgabe> aufgaben) { this.aufgaben = aufgaben; }
public List<Sperre> getSperren() { return sperren; }
public void setSperren(List<Sperre> sperren) { this.sperren = sperren; }
public List<Strafe> getStrafen() { return strafen; }
public void setStrafen(List<Strafe> strafen) { this.strafen = strafen; }
public int size() {
int size = 0;
if (aufgaben != null) size += aufgaben.size();
if (sperren != null) size += sperren.size();
if (strafen != null) size += strafen.size();
return size;
}
}

View File

@@ -0,0 +1,52 @@
package de.oaa.xxx.session.aufgaben;
import de.oaa.xxx.session.Mitspieler;
import de.oaa.xxx.session.Werkzeug;
import java.util.List;
import java.util.UUID;
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;
public UUID getSperreId() { return sperreId; }
public void setSperreId(UUID sperreId) { this.sperreId = sperreId; }
public String getKurzText() { return kurzText; }
public void setKurzText(String kurzText) { this.kurzText = kurzText; }
public String getText() { return text; }
public void setText(String text) { this.text = text; }
public String getReleaseText() { return releaseText; }
public void setReleaseText(String releaseText) { this.releaseText = releaseText; }
public UUID getGruppeId() { return gruppeId; }
public void setGruppeId(UUID gruppeId) { this.gruppeId = gruppeId; }
public List<Werkzeug> getSperreFuer() { return sperreFuer; }
public void setSperreFuer(List<Werkzeug> sperreFuer) { this.sperreFuer = sperreFuer; }
public Integer getMinutenVon() { return minutenVon; }
public void setMinutenVon(Integer minutenVon) { this.minutenVon = minutenVon; }
public Integer getMinutenBis() { return minutenBis; }
public void setMinutenBis(Integer minutenBis) { this.minutenBis = minutenBis; }
public boolean isAufgabePassend(Mitspieler passiv) {
for (Werkzeug werkzeug : sperreFuer) {
if (!passiv.isVerfuegbar(werkzeug)) {
return false;
}
}
return true;
}
}

View File

@@ -0,0 +1,70 @@
package de.oaa.xxx.session.aufgaben;
import de.oaa.xxx.session.Mitspieler;
import de.oaa.xxx.session.Werkzeug;
import java.util.List;
import java.util.UUID;
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 UUID getStrafeId() { return strafeId; }
public void setStrafeId(UUID strafeId) { this.strafeId = strafeId; }
public Integer getLevel() { return level; }
public void setLevel(Integer level) { this.level = level; }
public String getText() { return text; }
public void setText(String text) { this.text = text; }
public String getKurzText() { return kurzText; }
public void setKurzText(String kurzText) { this.kurzText = kurzText; }
public Integer getSekundenVon() { return sekundenVon; }
public void setSekundenVon(Integer sekundenVon) { this.sekundenVon = sekundenVon; }
public Integer getSekundenBis() { return sekundenBis; }
public void setSekundenBis(Integer sekundenBis) { this.sekundenBis = sekundenBis; }
public UUID getGruppeId() { return gruppeId; }
public void setGruppeId(UUID gruppeId) { this.gruppeId = gruppeId; }
public List<Werkzeug> getBenoetigtAktiv() { return benoetigtAktiv; }
public void setBenoetigtAktiv(List<Werkzeug> benoetigtAktiv) { this.benoetigtAktiv = benoetigtAktiv; }
public List<Werkzeug> getBenoetigtPassiv() { return benoetigtPassiv; }
public void setBenoetigtPassiv(List<Werkzeug> benoetigtPassiv) { this.benoetigtPassiv = 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;
}
}
}

View File

@@ -0,0 +1,163 @@
package de.oaa.xxx.session.controller;
import com.fasterxml.jackson.databind.ObjectMapper;
import de.oaa.xxx.session.AufgabeAnzeige;
import de.oaa.xxx.session.Mitspieler;
import de.oaa.xxx.session.Session;
import de.oaa.xxx.session.SessionDurchfuehren;
import de.oaa.xxx.session.aufgaben.AufgabenList;
import de.oaa.xxx.session.entity.MitspielerEntity;
import de.oaa.xxx.session.entity.SessionEntity;
import de.oaa.xxx.session.repository.MitspielerRepository;
import de.oaa.xxx.session.repository.SessionRepository;
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.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
import java.time.LocalDateTime;
import java.util.UUID;
@RestController
@RequestMapping("/session")
@Transactional
public class SessionController {
private static final Logger LOGGER = LoggerFactory.getLogger(SessionController.class);
private final SessionRepository sessionRepository;
private final MitspielerRepository mitspielerRepository;
private final ObjectMapper objectMapper;
public SessionController(SessionRepository sessionRepository, MitspielerRepository mitspielerRepository,
ObjectMapper objectMapper) {
this.sessionRepository = sessionRepository;
this.mitspielerRepository = mitspielerRepository;
this.objectMapper = objectMapper;
}
@GetMapping("/{sessionId}")
public ResponseEntity<Session> getBySessionId(@PathVariable UUID sessionId) {
return sessionRepository.findById(sessionId)
.map(entity -> ResponseEntity.ok(toSession(entity)))
.orElse(ResponseEntity.noContent().build());
}
@GetMapping
public ResponseEntity<Session> getByUserId(@RequestParam UUID userId) {
return sessionRepository.findByUserId(userId)
.map(entity -> ResponseEntity.ok(toSession(entity)))
.orElse(ResponseEntity.noContent().build());
}
@PostMapping
public ResponseEntity<Void> create(@RequestBody Session session) {
UUID userId = (UUID) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
SessionEntity entity = new SessionEntity();
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.setWahrscheinlichkeitSperre(session.getWahrscheinlichkeitSperre() != null ? session.getWahrscheinlichkeitSperre() : 10);
entity.setWahrscheinlichkeitStrafe(session.getWahrscheinlichkeitStrafe() != null ? session.getWahrscheinlichkeitStrafe() : 10);
entity.setZeitfaktorZeitstrafen(session.getZeitfaktorZeitstrafen() != null ? session.getZeitfaktorZeitstrafen() : 1.0);
entity.setLevel(1);
sessionRepository.save(entity);
return ResponseEntity.created(
ServletUriComponentsBuilder.fromCurrentRequest().path("/{id}").buildAndExpand(entity.getSessionId()).toUri()
).build();
}
@DeleteMapping
public ResponseEntity<Void> deleteSession(@RequestBody Session session) {
return sessionRepository.findById(session.getSessionId())
.map(entity -> {
sessionRepository.delete(entity);
return ResponseEntity.accepted().<Void>build();
})
.orElse(ResponseEntity.noContent().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);
SessionEntity session = sessionRepository.findById(sessionId).orElse(null);
if (session == null) {
return ResponseEntity.badRequest().build();
}
session.setAufgaben(aufgaben);
sessionRepository.save(session);
return ResponseEntity.accepted().build();
} catch (Exception exception) {
LOGGER.error(exception.getMessage(), exception);
return ResponseEntity.internalServerError().build();
}
}
@GetMapping("/{sessionId}/aufgaben/next")
public ResponseEntity<AufgabeAnzeige> getNextAufgabe(@PathVariable UUID sessionId) {
try {
SessionEntity session = sessionRepository.findById(sessionId).orElse(null);
if (session == null) {
return ResponseEntity.badRequest().build();
}
session.setLetzteAktivitaet(LocalDateTime.now());
AufgabeAnzeige next = new SessionDurchfuehren(session).getNext();
return ResponseEntity.ok(next);
} catch (Exception exception) {
LOGGER.error(exception.getMessage(), exception);
return ResponseEntity.internalServerError().build();
}
}
@PostMapping("/{sessionId}/mitspieler")
public ResponseEntity<Void> addMitspieler(@RequestBody Mitspieler 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();
}
SessionEntity session = sessionRepository.findById(sessionId).orElse(null);
if (session == null) {
return ResponseEntity.badRequest().build();
}
MitspielerEntity entity = new MitspielerEntity();
entity.setMitspielerId(UUID.randomUUID());
entity.setGeschlecht(mitspieler.getGeschlecht());
entity.setName(mitspieler.getName());
entity.setRollen(mitspieler.getRollen());
entity.setSpieltMit(mitspieler.getSpieltMit());
entity.setWerkzeuge(mitspieler.getVerfuegbareWerkzeuge());
entity.setSession(session);
mitspielerRepository.save(entity);
return ResponseEntity.accepted().build();
}
private Session toSession(SessionEntity entity) {
Session session = new Session();
session.setSessionId(entity.getSessionId());
session.setUserId(entity.getUserId());
session.setAufgabenProLevel(entity.getAufgabenAufAktuellemLevel());
session.setWahrscheinlichkeitSperre(entity.getWahrscheinlichkeitSperre());
session.setWahrscheinlichkeitStrafe(entity.getWahrscheinlichkeitStrafe());
session.setZeitfaktorZeitstrafen(entity.getZeitfaktorZeitstrafen());
return session;
}
}

View File

@@ -0,0 +1,88 @@
package de.oaa.xxx.session.controller;
import de.oaa.xxx.session.entity.AktiveSperreEntity;
import de.oaa.xxx.session.repository.AktiveSperreRepository;
import de.oaa.xxx.session.repository.MitspielerRepository;
import de.oaa.xxx.session.repository.SessionRepository;
import de.oaa.xxx.session.sperre.SperreCallback;
import de.oaa.xxx.session.sperre.SperreVerarbeiten;
import de.oaa.xxx.session.sperre.SperrenVerlaengernCallback;
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.GetMapping;
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.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;
@RestController
@RequestMapping("/session/sperre")
@Transactional
public class SperreController {
private static final Logger LOGGER = LoggerFactory.getLogger(SperreController.class);
private final SessionRepository sessionRepository;
private final MitspielerRepository mitspielerRepository;
private final AktiveSperreRepository aktiveSperreRepository;
public SperreController(SessionRepository sessionRepository, MitspielerRepository mitspielerRepository,
AktiveSperreRepository aktiveSperreRepository) {
this.sessionRepository = sessionRepository;
this.mitspielerRepository = mitspielerRepository;
this.aktiveSperreRepository = aktiveSperreRepository;
}
@PostMapping
public ResponseEntity<Void> sperren(@RequestBody SperreCallback callback) {
try {
new SperreVerarbeiten().sperreAnwenden(callback, sessionRepository, mitspielerRepository, aktiveSperreRepository);
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();
}
}
@PostMapping("/verlaengern")
public ResponseEntity<Void> aktiveVerlaengern(@RequestBody SperrenVerlaengernCallback callback) {
if (callback == null || callback.getSpielerId() == null || callback.getFaktor() == null) {
return ResponseEntity.badRequest().build();
}
try {
List<AktiveSperreEntity> aktiveLocks = aktiveSperreRepository.findAktiveLocks(callback.getSpielerId());
SperreVerarbeiten verarbeiten = new SperreVerarbeiten();
aktiveLocks.forEach(lock -> verarbeiten.sperreVerlaengern(lock, callback.getFaktor(), aktiveSperreRepository));
return ResponseEntity.accepted().build();
} catch (Exception exception) {
LOGGER.error(exception.getMessage(), exception);
return ResponseEntity.internalServerError().build();
}
}
}

View File

@@ -0,0 +1,91 @@
package de.oaa.xxx.session.entity;
import de.oaa.xxx.session.AktiveSperre;
import de.oaa.xxx.session.Mitspieler;
import de.oaa.xxx.session.Werkzeug;
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.FetchType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
@Entity
@Table(name = "aktiveSperre")
public class AktiveSperreEntity {
@Id
@Column
private UUID aktiveSperreId;
@ManyToOne
@JoinColumn(name = "mitspielerId", nullable = false)
private MitspielerEntity mitspieler;
@Column
private Integer minuten;
@Column
private LocalDateTime startzeit;
@Column
private LocalDateTime endzeit;
@Enumerated(EnumType.STRING)
@ElementCollection(targetClass = Werkzeug.class, fetch = FetchType.EAGER)
@CollectionTable(name = "aktiveSperre_fuer", joinColumns = @JoinColumn(name = "aktiveSperreId"))
@Column(name = "werkzeug")
private List<Werkzeug> fuer = new ArrayList<>();
@Column
private String releaseText;
@ManyToOne
@JoinColumn(name = "sessionId", nullable = false)
private SessionEntity session;
public UUID getAktiveSperreId() { return aktiveSperreId; }
public void setAktiveSperreId(UUID aktiveSperreId) { this.aktiveSperreId = aktiveSperreId; }
public MitspielerEntity getMitspieler() { return mitspieler; }
public void setMitspieler(MitspielerEntity mitspieler) { this.mitspieler = mitspieler; }
public Integer getMinuten() { return minuten; }
public void setMinuten(Integer minuten) { this.minuten = minuten; }
public LocalDateTime getStartzeit() { return startzeit; }
public void setStartzeit(LocalDateTime startzeit) { this.startzeit = startzeit; }
public LocalDateTime getEndzeit() { return endzeit; }
public void setEndzeit(LocalDateTime endzeit) { this.endzeit = endzeit; }
public List<Werkzeug> getFuer() { return fuer; }
public void setFuer(List<Werkzeug> fuer) { this.fuer = fuer; }
public String getReleaseText() { return releaseText; }
public void setReleaseText(String releaseText) { this.releaseText = releaseText; }
public SessionEntity getSession() { return session; }
public void setSession(SessionEntity session) { this.session = session; }
public AktiveSperre toSperre(List<Mitspieler> mitspielerList) {
AktiveSperre sperre = new AktiveSperre();
sperre.setAktiveSperreId(aktiveSperreId);
sperre.setEndzeit(endzeit);
sperre.setFuer(fuer);
sperre.setMinuten(minuten);
sperre.setMitspieler(getMitspielerFromList(mitspielerList, mitspieler.getMitspielerId()));
sperre.setReleaseText(releaseText);
sperre.setStartzeit(startzeit);
return sperre;
}
private Mitspieler getMitspielerFromList(List<Mitspieler> mitspielerList, UUID id) {
Optional<Mitspieler> first = mitspielerList.stream().filter(m -> m.getId().equals(id)).findFirst();
return first.orElse(null);
}
}

View File

@@ -0,0 +1,91 @@
package de.oaa.xxx.session.entity;
import de.oaa.xxx.session.GeschlechtEnum;
import de.oaa.xxx.session.Mitspieler;
import de.oaa.xxx.session.RolleEnum;
import de.oaa.xxx.session.Werkzeug;
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.FetchType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
@Entity
@Table(name = "mitspieler")
public class MitspielerEntity {
@Id
@Column
private UUID mitspielerId;
@Column
private String name;
@Enumerated(EnumType.STRING)
@Column
private GeschlechtEnum geschlecht;
@Enumerated(EnumType.STRING)
@ElementCollection(targetClass = Werkzeug.class, fetch = FetchType.EAGER)
@CollectionTable(name = "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 = "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 = "mitspieler_rollen", joinColumns = @JoinColumn(name = "mitspielerId"))
@Column(name = "rolle")
private List<RolleEnum> rollen = new ArrayList<>();
@ManyToOne
@JoinColumn(name = "sessionId", nullable = false)
private SessionEntity session;
@OneToMany(mappedBy = "mitspieler", fetch = FetchType.EAGER)
private List<AktiveSperreEntity> aktiveSperren = new ArrayList<>();
public UUID getMitspielerId() { return mitspielerId; }
public void setMitspielerId(UUID mitspielerId) { this.mitspielerId = mitspielerId; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public GeschlechtEnum getGeschlecht() { return geschlecht; }
public void setGeschlecht(GeschlechtEnum geschlecht) { this.geschlecht = geschlecht; }
public List<Werkzeug> getWerkzeuge() { return werkzeuge; }
public void setWerkzeuge(List<Werkzeug> werkzeuge) { this.werkzeuge = werkzeuge; }
public List<GeschlechtEnum> getSpieltMit() { return spieltMit; }
public void setSpieltMit(List<GeschlechtEnum> spieltMit) { this.spieltMit = spieltMit; }
public List<RolleEnum> getRollen() { return rollen; }
public void setRollen(List<RolleEnum> rollen) { this.rollen = rollen; }
public SessionEntity getSession() { return session; }
public void setSession(SessionEntity session) { this.session = session; }
public List<AktiveSperreEntity> getAktiveSperren() { return aktiveSperren; }
public void setAktiveSperren(List<AktiveSperreEntity> aktiveSperren) { this.aktiveSperren = aktiveSperren; }
public Mitspieler toMitspieler() {
Mitspieler mitspieler = new Mitspieler();
mitspieler.setGeschlecht(geschlecht);
mitspieler.setId(mitspielerId);
mitspieler.setName(name);
mitspieler.setRollen(rollen);
mitspieler.setSpieltMit(spieltMit);
mitspieler.setVerfuegbareWerkzeuge(new ArrayList<>(werkzeuge));
return mitspieler;
}
}

View File

@@ -0,0 +1,85 @@
package de.oaa.xxx.session.entity;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.Id;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
@Entity
@Table(name = "session")
public class SessionEntity {
@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<MitspielerEntity> mitspieler = new ArrayList<>();
@OneToMany(mappedBy = "session", fetch = FetchType.EAGER)
private List<AktiveSperreEntity> aktiveSperren = new ArrayList<>();
@Column
private Integer wahrscheinlichkeitSperre;
@Column
private Integer wahrscheinlichkeitStrafe;
@Column
private Integer aufgabenProLevel;
@Column
private Integer level;
@Column
private Integer aufgabenAufAktuellemLevel;
@Column(columnDefinition = "TEXT")
private String aufgaben;
@Column
private Double zeitfaktorZeitstrafen;
public UUID getSessionId() { return sessionId; }
public void setSessionId(UUID sessionId) { this.sessionId = sessionId; }
public UUID getUserId() { return userId; }
public void setUserId(UUID userId) { this.userId = userId; }
public LocalDateTime getStartZeit() { return startZeit; }
public void setStartZeit(LocalDateTime startZeit) { this.startZeit = startZeit; }
public LocalDateTime getLetzteAktivitaet() { return letzteAktivitaet; }
public void setLetzteAktivitaet(LocalDateTime letzteAktivitaet) { this.letzteAktivitaet = letzteAktivitaet; }
public List<MitspielerEntity> getMitspieler() { return mitspieler; }
public void setMitspieler(List<MitspielerEntity> mitspieler) { this.mitspieler = mitspieler; }
public List<AktiveSperreEntity> getAktiveSperren() { return aktiveSperren; }
public void setAktiveSperren(List<AktiveSperreEntity> aktiveSperren) { this.aktiveSperren = aktiveSperren; }
public Integer getWahrscheinlichkeitSperre() { return wahrscheinlichkeitSperre; }
public void setWahrscheinlichkeitSperre(Integer wahrscheinlichkeitSperre) { this.wahrscheinlichkeitSperre = wahrscheinlichkeitSperre; }
public Integer getWahrscheinlichkeitStrafe() { return wahrscheinlichkeitStrafe; }
public void setWahrscheinlichkeitStrafe(Integer wahrscheinlichkeitStrafe) { this.wahrscheinlichkeitStrafe = wahrscheinlichkeitStrafe; }
public Integer getAufgabenProLevel() { return aufgabenProLevel; }
public void setAufgabenProLevel(Integer aufgabenProLevel) { this.aufgabenProLevel = aufgabenProLevel; }
public Integer getLevel() { return level; }
public void setLevel(Integer level) { this.level = level; }
public Integer getAufgabenAufAktuellemLevel() { return aufgabenAufAktuellemLevel; }
public void setAufgabenAufAktuellemLevel(Integer aufgabenAufAktuellemLevel) { this.aufgabenAufAktuellemLevel = aufgabenAufAktuellemLevel; }
public String getAufgaben() { return aufgaben; }
public void setAufgaben(String aufgaben) { this.aufgaben = aufgaben; }
public Double getZeitfaktorZeitstrafen() { return zeitfaktorZeitstrafen; }
public void setZeitfaktorZeitstrafen(Double zeitfaktorZeitstrafen) { this.zeitfaktorZeitstrafen = zeitfaktorZeitstrafen; }
}

View File

@@ -0,0 +1,19 @@
package de.oaa.xxx.session.repository;
import de.oaa.xxx.session.entity.AktiveSperreEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;
public interface AktiveSperreRepository extends JpaRepository<AktiveSperreEntity, UUID> {
@Query("select a from AktiveSperreEntity a join a.session s where a.endzeit < :now and s.sessionId = :sessionId")
List<AktiveSperreEntity> findAbgelaufene(@Param("sessionId") UUID sessionId, @Param("now") LocalDateTime now);
@Query("select a from AktiveSperreEntity a join a.mitspieler m where m.mitspielerId = :mitspielerId")
List<AktiveSperreEntity> findAktiveLocks(@Param("mitspielerId") UUID mitspielerId);
}

View File

@@ -0,0 +1,9 @@
package de.oaa.xxx.session.repository;
import de.oaa.xxx.session.entity.MitspielerEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.UUID;
public interface MitspielerRepository extends JpaRepository<MitspielerEntity, UUID> {
}

View File

@@ -0,0 +1,12 @@
package de.oaa.xxx.session.repository;
import de.oaa.xxx.session.entity.SessionEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.Optional;
import java.util.UUID;
public interface SessionRepository extends JpaRepository<SessionEntity, UUID> {
Optional<SessionEntity> findByUserId(UUID userId);
}

View File

@@ -0,0 +1,21 @@
package de.oaa.xxx.session.sperre;
import de.oaa.xxx.session.Callback;
import java.util.UUID;
public class SperreCallback extends Callback {
private UUID sperreId;
private UUID spielerId;
private String releaseText;
public UUID getSperreId() { return sperreId; }
public void setSperreId(UUID sperreId) { this.sperreId = sperreId; }
public UUID getSpielerId() { return spielerId; }
public void setSpielerId(UUID spielerId) { this.spielerId = spielerId; }
public String getReleaseText() { return releaseText; }
public void setReleaseText(String releaseText) { this.releaseText = releaseText; }
}

View File

@@ -0,0 +1,90 @@
package de.oaa.xxx.session.sperre;
import com.fasterxml.jackson.databind.ObjectMapper;
import de.oaa.xxx.session.aufgaben.AufgabenList;
import de.oaa.xxx.session.aufgaben.Sperre;
import de.oaa.xxx.session.entity.AktiveSperreEntity;
import de.oaa.xxx.session.entity.MitspielerEntity;
import de.oaa.xxx.session.entity.SessionEntity;
import de.oaa.xxx.session.repository.AktiveSperreRepository;
import de.oaa.xxx.session.repository.MitspielerRepository;
import de.oaa.xxx.session.repository.SessionRepository;
import java.time.LocalDateTime;
import java.util.Optional;
import java.util.Random;
import java.util.UUID;
public class SperreVerarbeiten {
private final ObjectMapper objectMapper = new ObjectMapper();
public void sperreAnwenden(SperreCallback callback, SessionRepository sessionRepository,
MitspielerRepository mitspielerRepository, AktiveSperreRepository sperreRepository) throws Exception {
SessionEntity session = sessionRepository.findById(callback.getSessionId()).orElse(null);
MitspielerEntity mitspieler = mitspielerRepository.findById(callback.getSpielerId()).orElse(null);
if (session != null) {
AufgabenList aufgaben = objectMapper.readValue(session.getAufgaben(), AufgabenList.class);
Optional<Sperre> first = aufgaben.getSperren().stream()
.filter(sperre -> sperre.getSperreId().equals(callback.getSperreId()))
.findFirst();
if (first.isPresent()) {
Sperre sperre = first.get();
AktiveSperreEntity aktiv = new AktiveSperreEntity();
fill(callback, session, mitspieler, sperre, aktiv);
sperreRepository.save(aktiv);
sperre.getSperreFuer().forEach(mitspieler.getWerkzeuge()::remove);
mitspielerRepository.save(mitspieler);
}
}
}
public String sperreAufheben(AktiveSperreEntity aufzuheben, AktiveSperreRepository sperreRepository,
MitspielerRepository mitspielerRepository) {
MitspielerEntity mitspieler = aufzuheben.getMitspieler();
aufzuheben.getFuer().forEach(mitspieler.getWerkzeuge()::add);
mitspielerRepository.save(mitspieler);
String releaseText = aufzuheben.getReleaseText();
sperreRepository.delete(aufzuheben);
return releaseText;
}
public void sperreVerlaengern(AktiveSperreEntity verlaengern, Integer faktor, AktiveSperreRepository sperreRepository) {
Integer neueDauer = verlaengern.getMinuten() * faktor;
verlaengern.setEndzeit(verlaengern.getStartzeit().plusMinutes(neueDauer));
verlaengern.setMinuten(neueDauer);
sperreRepository.save(verlaengern);
}
private void fill(SperreCallback callback, SessionEntity session, MitspielerEntity mitspieler,
Sperre sperre, AktiveSperreEntity aktiv) {
aktiv.setAktiveSperreId(UUID.randomUUID());
LocalDateTime now = LocalDateTime.now();
Integer minuten = berechneDauer(session, sperre);
aktiv.setStartzeit(now);
aktiv.setEndzeit(now.plusMinutes(minuten));
aktiv.setMinuten(minuten);
aktiv.setMitspieler(mitspieler);
aktiv.setSession(session);
aktiv.setFuer(sperre.getSperreFuer());
aktiv.setReleaseText(callback.getReleaseText());
}
private Integer berechneDauer(SessionEntity session, Sperre sperre) {
Integer minuten = 30;
if (sperre.getMinutenVon() != null) {
if (sperre.getMinutenBis() != null) {
minuten = new Random().nextInt(sperre.getMinutenVon(), sperre.getMinutenBis());
} else {
minuten = sperre.getMinutenVon();
}
}
if (session.getZeitfaktorZeitstrafen() != null) {
minuten = (int) (minuten * session.getZeitfaktorZeitstrafen());
}
if (minuten == 0) {
minuten = 1;
}
return minuten;
}
}

View File

@@ -0,0 +1,17 @@
package de.oaa.xxx.session.sperre;
import de.oaa.xxx.session.Callback;
import java.util.UUID;
public class SperrenVerlaengernCallback extends Callback {
private UUID spielerId;
private Integer faktor;
public UUID getSpielerId() { return spielerId; }
public void setSpielerId(UUID spielerId) { this.spielerId = spielerId; }
public Integer getFaktor() { return faktor; }
public void setFaktor(Integer faktor) { this.faktor = faktor; }
}

View File

@@ -0,0 +1,55 @@
package de.oaa.xxx.user;
import de.oaa.xxx.config.JwtService;
import jakarta.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.Optional;
import java.util.UUID;
@RestController
@RequestMapping("/login")
public class LoginController {
private static final Logger LOGGER = LoggerFactory.getLogger(LoginController.class);
private final UserRepository userRepository;
private final JwtService jwtService;
public LoginController(UserRepository userRepository, JwtService jwtService) {
this.userRepository = userRepository;
this.jwtService = jwtService;
}
@GetMapping
public ResponseEntity<String> login(@RequestParam String email, @RequestParam String hash,
HttpServletRequest req) {
Optional<UserEntity> user = userRepository.findByEmailAndPassword(email, hash);
if (user.isPresent()) {
LOGGER.info("User erfolgreich angemeldet: {}", email);
String token = jwtService.createToken(email, user.get().getUserId(), req.getRemoteAddr());
return ResponseEntity.ok(token);
} else {
return ResponseEntity.noContent().build();
}
}
@GetMapping("/{userId}")
public ResponseEntity<User> get(@PathVariable UUID userId) {
return userRepository.findById(userId)
.map(entity -> ResponseEntity.ok(entity.toUser()))
.orElse(ResponseEntity.noContent().build());
}
@GetMapping("/publickey")
public ResponseEntity<String> getPublicKey() {
return ResponseEntity.ok(jwtService.getPublicKeyBase64());
}
}

View File

@@ -0,0 +1,28 @@
package de.oaa.xxx.user;
import java.util.UUID;
public class Registration {
private UUID id;
private String name;
private String email;
private String passwordHash;
public UUID getId() { return id; }
public void setId(UUID id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
public String getPasswordHash() { return passwordHash; }
public void setPasswordHash(String passwordHash) { this.passwordHash = passwordHash; }
@Override
public String toString() {
return "Registration [id=" + id + ", name=" + name + ", email=" + email + "]";
}
}

View File

@@ -0,0 +1,23 @@
package de.oaa.xxx.user;
import java.util.UUID;
public class User {
private UUID userId;
private String name;
private String email;
private String password;
public UUID getUserId() { return userId; }
public void setUserId(UUID userId) { this.userId = userId; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
public String getPassword() { return password; }
public void setPassword(String password) { this.password = password; }
}

View File

@@ -0,0 +1,47 @@
package de.oaa.xxx.user;
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.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.UUID;
@RestController
@RequestMapping("/user")
public class UserController {
private static final Logger LOGGER = LoggerFactory.getLogger(UserController.class);
private final UserRepository userRepository;
public UserController(UserRepository userRepository) {
this.userRepository = userRepository;
}
@PostMapping
public ResponseEntity<Void> userAnlegen(@RequestBody Registration registration) {
if (registration.getEmail() == null || registration.getPasswordHash() == null || registration.getName() == null) {
return ResponseEntity.badRequest().build();
}
if (userRepository.findByEmail(registration.getEmail()).isPresent()) {
LOGGER.warn("User mit E-Mail {} bereits vorhanden", registration.getEmail());
return ResponseEntity.status(409).build();
}
try {
UserEntity entity = new UserEntity();
entity.setUserId(UUID.randomUUID());
entity.setEmail(registration.getEmail());
entity.setName(registration.getName());
entity.setPassword(registration.getPasswordHash());
userRepository.save(entity);
return ResponseEntity.status(201).build();
} catch (Exception exception) {
LOGGER.error(exception.getMessage(), exception);
return ResponseEntity.internalServerError().build();
}
}
}

View File

@@ -0,0 +1,43 @@
package de.oaa.xxx.user;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import java.util.UUID;
@Entity
@Table(name = "user")
public class UserEntity {
@Id
@Column
private UUID userId;
@Column
private String name;
@Column(unique = true)
private String email;
@Column
private String password;
public UUID getUserId() { return userId; }
public void setUserId(UUID userId) { this.userId = userId; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
public String getPassword() { return password; }
public void setPassword(String password) { this.password = password; }
public User toUser() {
User user = new User();
user.setEmail(email);
user.setName(name);
user.setUserId(userId);
return user;
}
}

View File

@@ -0,0 +1,13 @@
package de.oaa.xxx.user;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.Optional;
import java.util.UUID;
public interface UserRepository extends JpaRepository<UserEntity, UUID> {
Optional<UserEntity> findByEmailAndPassword(String email, String password);
Optional<UserEntity> findByEmail(String email);
}

View File

@@ -0,0 +1,27 @@
# Datasource
spring.datasource.url=jdbc:mysql://localhost:3306/xxxthegame?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC
spring.datasource.username=${DB_USER:xxx}
spring.datasource.password=${DB_PASSWORD:xxxthegame$123!}
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# JPA / Hibernate
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=false
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQLDialect
spring.jpa.properties.hibernate.type.preferred_uuid_jdbc_type=VARCHAR
# Mail
spring.mail.host=${MAIL_HOST:localhost}
spring.mail.port=${MAIL_PORT:25}
spring.mail.username=${MAIL_USER:}
spring.mail.password=${MAIL_PASSWORD:}
spring.mail.properties.mail.smtp.auth=false
spring.mail.properties.mail.smtp.starttls.enable=false
# JWT Keystore
jwt.keystore.path=classpath:xxx.jks
jwt.keystore.password=${JWT_KEYSTORE_PASSWORD:XUR!Rv&f$j3UsqD&}
jwt.keystore.alias=xxx
# Server
server.port=8080

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@@ -0,0 +1,256 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>XXX The Game Login</title>
<style>
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
background: #1a1a2e;
font-family: 'Segoe UI', sans-serif;
color: #eee;
}
.card {
background: #16213e;
border: 1px solid #0f3460;
border-radius: 12px;
padding: 2.5rem;
width: 100%;
max-width: 380px;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5);
}
h1 {
text-align: center;
font-size: 1.6rem;
margin-bottom: 0.25rem;
color: #e94560;
}
.subtitle {
text-align: center;
font-size: 0.85rem;
color: #888;
margin-bottom: 2rem;
}
label {
display: block;
font-size: 0.8rem;
color: #aaa;
margin-bottom: 0.3rem;
margin-top: 1rem;
}
input {
width: 100%;
padding: 0.65rem 0.9rem;
border: 1px solid #0f3460;
border-radius: 6px;
background: #0f3460;
color: #eee;
font-size: 1rem;
outline: none;
transition: border-color 0.2s;
}
input:focus {
border-color: #e94560;
}
button {
margin-top: 1.75rem;
width: 100%;
padding: 0.75rem;
background: #e94560;
color: #fff;
border: none;
border-radius: 6px;
font-size: 1rem;
font-weight: 600;
cursor: pointer;
transition: background 0.2s;
}
button:hover:not(:disabled) {
background: #c73652;
}
button:disabled {
opacity: 0.6;
cursor: not-allowed;
}
.message {
margin-top: 1.25rem;
padding: 0.65rem 0.9rem;
border-radius: 6px;
font-size: 0.85rem;
display: none;
word-break: break-all;
}
.message.error {
background: #3d0f1a;
border: 1px solid #e94560;
color: #e94560;
}
.message.success {
background: #0f3d1a;
border: 1px solid #2ecc71;
color: #2ecc71;
}
.token-box {
margin-top: 1.25rem;
padding: 0.65rem 0.9rem;
background: #0f1e3d;
border: 1px solid #0f3460;
border-radius: 6px;
font-size: 0.75rem;
color: #aaa;
word-break: break-all;
display: none;
}
.token-box span {
display: block;
font-size: 0.7rem;
color: #666;
margin-bottom: 0.4rem;
}
.copy-btn {
margin-top: 0.5rem;
width: auto;
padding: 0.3rem 0.7rem;
font-size: 0.75rem;
background: #0f3460;
font-weight: normal;
}
.copy-btn:hover {
background: #1a4a8a;
}
</style>
</head>
<body>
<div class="card">
<h1>XXX The Game</h1>
<p class="subtitle">Bitte melde dich an</p>
<label for="email">E-Mail</label>
<input type="email" id="email" placeholder="deine@email.de" autocomplete="username" />
<label for="password">Passwort</label>
<input type="password" id="password" placeholder="••••••••" autocomplete="current-password" />
<button id="loginBtn" onclick="login()">Anmelden</button>
<div class="message" id="message"></div>
<div class="token-box" id="tokenBox">
<span>JWT Token</span>
<div id="tokenText"></div>
<button class="copy-btn" onclick="copyToken()">Kopieren</button>
</div>
</div>
<script>
let currentToken = null;
document.addEventListener('keydown', e => {
if (e.key === 'Enter') login();
});
async function sha256(text) {
const encoder = new TextEncoder();
const data = encoder.encode(text);
const hashBuffer = await crypto.subtle.digest('SHA-256', data);
const hashArray = Array.from(new Uint8Array(hashBuffer));
return hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
}
async function login() {
const email = document.getElementById('email').value.trim();
const password = document.getElementById('password').value;
const btn = document.getElementById('loginBtn');
if (!email || !password) {
showMessage('Bitte E-Mail und Passwort eingeben.', 'error');
return;
}
btn.disabled = true;
btn.textContent = 'Wird geprüft…';
hideMessage();
hideToken();
try {
const hash = await sha256(password);
const url = `/login?email=${encodeURIComponent(email)}&hash=${encodeURIComponent(hash)}`;
const response = await fetch(url, { method: 'GET' });
if (response.ok) {
currentToken = await response.text();
showMessage('Login erfolgreich!', 'success');
showToken(currentToken);
} else if (response.status === 204) {
showMessage('E-Mail oder Passwort falsch.', 'error');
} else {
showMessage(`Fehler: HTTP ${response.status}`, 'error');
}
} catch (err) {
showMessage('Server nicht erreichbar.', 'error');
console.error(err);
} finally {
btn.disabled = false;
btn.textContent = 'Anmelden';
}
}
function showMessage(text, type) {
const el = document.getElementById('message');
el.textContent = text;
el.className = `message ${type}`;
el.style.display = 'block';
}
function hideMessage() {
document.getElementById('message').style.display = 'none';
}
function showToken(token) {
document.getElementById('tokenText').textContent = token;
document.getElementById('tokenBox').style.display = 'block';
}
function hideToken() {
document.getElementById('tokenBox').style.display = 'none';
currentToken = null;
}
function copyToken() {
if (currentToken) {
navigator.clipboard.writeText(currentToken).then(() => {
const btn = document.querySelector('.copy-btn');
btn.textContent = 'Kopiert!';
setTimeout(() => btn.textContent = 'Kopieren', 1500);
});
}
}
</script>
</body>
</html>

Binary file not shown.

View File

@@ -0,0 +1,14 @@
package de.oaa.xxx;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
@SpringBootTest
@ActiveProfiles("test")
class XxxThegameApplicationTests {
@Test
void contextLoads() {
}
}

View File

@@ -0,0 +1,14 @@
spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.properties.hibernate.type.preferred_uuid_jdbc_type=VARCHAR
jwt.keystore.path=classpath:xxx.jks
jwt.keystore.password=XUR!Rv&f$j3UsqD&
jwt.keystore.alias=xxx
spring.mail.host=localhost
spring.mail.port=25