diff --git a/.claude/settings.local.json b/.claude/settings.local.json index 3f08b9f..46c036b 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -39,7 +39,8 @@ "Bash(head -15 grep -n -B5 -A2 \"max-width: 480px\\\\|max-width:480px\" /home/mario/Workspaces/xxx-thegame/xxxthegame/src/main/resources/static/joinlock.html)", "Bash(stat /home/mario/Workspaces/xxx-thegame/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/ttlock/*)", "Bash(git -C /home/mario/Workspaces/xxx-thegame diff HEAD xxxthegame/src/main/resources/static/neulock.html)", - "Bash(1:*)" + "Bash(1:*)", + "Bash(python3:*)" ] } } diff --git a/.metadata/.lock_info b/.metadata/.lock_info index 0297dc6..052839f 100644 --- a/.metadata/.lock_info +++ b/.metadata/.lock_info @@ -1,5 +1,5 @@ -#Tue Mar 24 11:25:59 CET 2026 +#Wed Mar 25 07:26:10 CET 2026 display=\:0 host=mario-mint -process-id=2972 +process-id=4033 user=mario diff --git a/.metadata/.log b/.metadata/.log index 19646a1..f4053ce 100644 --- a/.metadata/.log +++ b/.metadata/.log @@ -683,3 +683,74 @@ java.lang.NullPointerException: Cannot invoke "org.eclipse.e4.ui.model.applicati at org.eclipse.equinox.launcher.Main.basicRun(Main.java:563) at org.eclipse.equinox.launcher.Main.run(Main.java:1415) at org.eclipse.equinox.launcher.Main.main(Main.java:1387) + +!ENTRY org.springframework.tooling.boot.ls 1 0 2026-03-24 22:52:54.244 +!MESSAGE DelegatingStreamConnectionProvider - Stopping Boot LS +!SESSION 2026-03-25 07:26:05.291 ----------------------------------------------- +eclipse.buildId=4.39.0.20260305-0817 +java.version=21.0.6 +java.vendor=Eclipse Adoptium +BootLoader constants: OS=linux, ARCH=x86_64, WS=gtk, NL=de_DE +Framework arguments: -product org.eclipse.epp.package.java.product +Command-line arguments: -os linux -ws gtk -arch x86_64 -clean -product org.eclipse.epp.package.java.product + +!ENTRY ch.qos.logback.classic 1 0 2026-03-25 07:26:06.750 +!MESSAGE Activated before the state location was initialized. Retry after the state location is initialized. + +!ENTRY ch.qos.logback.classic 1 0 2026-03-25 07:26:10.860 +!MESSAGE Logback config file: /home/mario/Workspaces/xxx-thegame/.metadata/.plugins/org.eclipse.m2e.logback/logback.2.7.101.20251017-1242.xml + +!ENTRY org.eclipse.ui 2 0 2026-03-25 07:26:11.009 +!MESSAGE Warnings while parsing the commands from the 'org.eclipse.ui.commands' and 'org.eclipse.ui.actionDefinitions' extension points. +!SUBENTRY 1 org.eclipse.ui 2 0 2026-03-25 07:26:11.009 +!MESSAGE Commands should really have a category: plug-in='org.springframework.tooling.boot.ls', id='spring.initializr.addStarters', categoryId='org.eclipse.lsp4e.commandCategory' + +!ENTRY org.eclipse.ui 2 0 2026-03-25 07:26:11.149 +!MESSAGE Warnings while parsing the commands from the 'org.eclipse.ui.commands' and 'org.eclipse.ui.actionDefinitions' extension points. +!SUBENTRY 1 org.eclipse.ui 2 0 2026-03-25 07:26:11.149 +!MESSAGE Commands should really have a category: plug-in='org.springframework.tooling.boot.ls', id='spring.initializr.addStarters', categoryId='org.eclipse.lsp4e.commandCategory' + +!ENTRY org.eclipse.jface 2 0 2026-03-25 11:50:50.380 +!MESSAGE Keybinding conflicts occurred. They may interfere with normal accelerator operation. +!SUBENTRY 1 org.eclipse.jface 2 0 2026-03-25 11:50:50.380 +!MESSAGE A conflict occurred for CTRL+R: +Binding(CTRL+R, + ParameterizedCommand(Command(org.eclipse.debug.ui.commands.RunToLine,Run to Line, + Resume and break when execution reaches the current line, + Category(org.eclipse.debug.ui.category.run,Run/Debug,Run/Debug command category,true), + WorkbenchHandlerServiceHandler("org.eclipse.debug.ui.commands.RunToLine"), + ,,true),null), + org.eclipse.ui.defaultAcceleratorConfiguration, + org.eclipse.debug.ui.debugging,,,system) +Binding(CTRL+R, + ParameterizedCommand(Command(org.springframework.ide.eclipse.boot.restart.commands.restart,Trigger Restart, + Restart Spring Boot Application, + Category(org.eclipse.debug.ui.category.run,Run/Debug,Run/Debug command category,true), + WorkbenchHandlerServiceHandler("org.springframework.ide.eclipse.boot.restart.commands.restart"), + ,,true),null), + org.eclipse.ui.defaultAcceleratorConfiguration, + org.eclipse.debug.ui.console,,,system) + +!ENTRY org.eclipse.jface 2 0 2026-03-25 16:00:33.268 +!MESSAGE Keybinding conflicts occurred. They may interfere with normal accelerator operation. +!SUBENTRY 1 org.eclipse.jface 2 0 2026-03-25 16:00:33.268 +!MESSAGE A conflict occurred for CTRL+SHIFT+T: +Binding(CTRL+SHIFT+T, + ParameterizedCommand(Command(org.eclipse.jdt.ui.navigate.open.type,Open Type, + Open a type in a Java editor, + Category(org.eclipse.ui.category.navigate,Navigate,null,true), + WorkbenchHandlerServiceHandler("org.eclipse.jdt.ui.navigate.open.type"), + ,,true),null), + org.eclipse.ui.defaultAcceleratorConfiguration, + org.eclipse.ui.contexts.window,,,system) +Binding(CTRL+SHIFT+T, + ParameterizedCommand(Command(org.eclipse.lsp4e.symbolInWorkspace,Go to Symbol in Workspace, + , + Category(org.eclipse.lsp4e.category,Language Servers,null,true), + WorkbenchHandlerServiceHandler("org.eclipse.lsp4e.symbolInWorkspace"), + ,,true),null), + org.eclipse.ui.defaultAcceleratorConfiguration, + org.eclipse.ui.contexts.window,,,system) + +!ENTRY org.springframework.tooling.boot.ls 1 0 2026-03-25 16:28:18.002 +!MESSAGE DelegatingStreamConnectionProvider - Stopping Boot LS diff --git a/.metadata/.plugins/org.eclipse.buildship.core/gradle/versions.json b/.metadata/.plugins/org.eclipse.buildship.core/gradle/versions.json index eab5449..243f1de 100644 --- a/.metadata/.plugins/org.eclipse.buildship.core/gradle/versions.json +++ b/.metadata/.plugins/org.eclipse.buildship.core/gradle/versions.json @@ -1,24 +1,7 @@ [ { - "version" : "9.6.0-20260323005019+0000", - "buildTime" : "20260323005019+0000", - "commitId" : "d20e3feb4da17c82d2df8774ea838cdd230628ce", - "current" : false, - "snapshot" : true, - "nightly" : true, - "releaseNightly" : false, - "activeRc" : false, - "rcFor" : "", - "milestoneFor" : "", - "broken" : false, - "downloadUrl" : "https://services.gradle.org/distributions-snapshots/gradle-9.6.0-20260323005019+0000-bin.zip", - "checksumUrl" : "https://services.gradle.org/distributions-snapshots/gradle-9.6.0-20260323005019+0000-bin.zip.sha256", - "checksum" : "22865868bc4c8aa1f3cffb398397d3d6058246129490e168ecbbaaed24cd9fa1", - "wrapperChecksumUrl" : "https://services.gradle.org/distributions-snapshots/gradle-9.6.0-20260323005019+0000-wrapper.jar.sha256", - "wrapperChecksum" : "f307680272dffdb8e636f1169adfbf693513005c80aa06e8d381f20390a06e6a" -}, { - "version" : "9.5.0-20260322013634+0000", - "buildTime" : "20260322013634+0000", - "commitId" : "01db0eb99f616dd415a084ffcce4cb2c185d5a2a", + "version" : "9.5.0-20260325015243+0000", + "buildTime" : "20260325015243+0000", + "commitId" : "627839c6a3532eeab60306fd7b577d6f1c866ece", "current" : false, "snapshot" : true, "nightly" : false, @@ -27,10 +10,27 @@ "rcFor" : "", "milestoneFor" : "", "broken" : false, - "downloadUrl" : "https://services.gradle.org/distributions-snapshots/gradle-9.5.0-20260322013634+0000-bin.zip", - "checksumUrl" : "https://services.gradle.org/distributions-snapshots/gradle-9.5.0-20260322013634+0000-bin.zip.sha256", - "checksum" : "3e8a6689594399f81087ad962b1c489e0ae57201af0c6c00ea63d9d07e48506e", - "wrapperChecksumUrl" : "https://services.gradle.org/distributions-snapshots/gradle-9.5.0-20260322013634+0000-wrapper.jar.sha256", + "downloadUrl" : "https://services.gradle.org/distributions-snapshots/gradle-9.5.0-20260325015243+0000-bin.zip", + "checksumUrl" : "https://services.gradle.org/distributions-snapshots/gradle-9.5.0-20260325015243+0000-bin.zip.sha256", + "checksum" : "f031a868b2d9707fe07c78ad0888d4be5d6bb87e3f8a118ffbf3b0b497c32922", + "wrapperChecksumUrl" : "https://services.gradle.org/distributions-snapshots/gradle-9.5.0-20260325015243+0000-wrapper.jar.sha256", + "wrapperChecksum" : "f307680272dffdb8e636f1169adfbf693513005c80aa06e8d381f20390a06e6a" +}, { + "version" : "9.6.0-20260325005438+0000", + "buildTime" : "20260325005438+0000", + "commitId" : "4a2f60ed3e5db8c8eadc899d49da7c6abf7140ee", + "current" : false, + "snapshot" : true, + "nightly" : true, + "releaseNightly" : false, + "activeRc" : false, + "rcFor" : "", + "milestoneFor" : "", + "broken" : false, + "downloadUrl" : "https://services.gradle.org/distributions-snapshots/gradle-9.6.0-20260325005438+0000-bin.zip", + "checksumUrl" : "https://services.gradle.org/distributions-snapshots/gradle-9.6.0-20260325005438+0000-bin.zip.sha256", + "checksum" : "1419ec3a9f2e924772188c709cd681d073c7c821dbd82beb9a6e8f6b78f7723b", + "wrapperChecksumUrl" : "https://services.gradle.org/distributions-snapshots/gradle-9.6.0-20260325005438+0000-wrapper.jar.sha256", "wrapperChecksum" : "f307680272dffdb8e636f1169adfbf693513005c80aa06e8d381f20390a06e6a" }, { "version" : "9.4.1", diff --git a/.metadata/.plugins/org.eclipse.core.resources/.safetable/org.eclipse.core.resources b/.metadata/.plugins/org.eclipse.core.resources/.safetable/org.eclipse.core.resources index 32e55a0..cc86e3e 100644 Binary files a/.metadata/.plugins/org.eclipse.core.resources/.safetable/org.eclipse.core.resources and b/.metadata/.plugins/org.eclipse.core.resources/.safetable/org.eclipse.core.resources differ diff --git a/.metadata/.plugins/org.eclipse.e4.workbench/workbench.xmi b/.metadata/.plugins/org.eclipse.e4.workbench/workbench.xmi index 9eb36f7..3ccebc0 100644 --- a/.metadata/.plugins/org.eclipse.e4.workbench/workbench.xmi +++ b/.metadata/.plugins/org.eclipse.e4.workbench/workbench.xmi @@ -1,8 +1,8 @@ - - + + activeSchemeId:org.eclipse.ui.defaultAcceleratorConfiguration - + @@ -11,9 +11,9 @@ topLevel shellMaximized - - - + + + persp.actionSet:org.eclipse.mylyn.tasks.ui.navigation persp.actionSet:org.eclipse.ui.cheatsheets.actionSet @@ -83,131 +83,136 @@ persp.editorOnboardingCommand:Show Key Assist$$$Shift+Ctrl+L persp.editorOnboardingCommand:New$$$Ctrl+N persp.editorOnboardingCommand:Open Type$$$Shift+Ctrl+T - - - - + persp.actionSet:org.eclipse.debug.ui.debugActionSet + + + + org.eclipse.e4.primaryNavigationStack - active noFocus - + View categoryTag:Java - + View categoryTag:Java - + View categoryTag:General - + View categoryTag:Java - + Minimized - + View categoryTag:Spring - - + + View categoryTag:Git - - - - + + + + org.eclipse.e4.secondaryNavigationStack Minimized - + View categoryTag:General - + View categoryTag:General - + View categoryTag:General - + View categoryTag:Mylyn - + View categoryTag:Java - + View categoryTag:Ant - + org.eclipse.e4.secondaryDataStack Oomph Gradle - + Debug + Version Control (Team) + View categoryTag:General - + View categoryTag:Java - + View categoryTag:Java - + View categoryTag:General - + View categoryTag:General - + View categoryTag:General - + View categoryTag:General - + View categoryTag:Terminal - + View categoryTag:Gradle - + View categoryTag:Gradle - + View - categoryTag:Oomph - NoRestore + categoryTag:Debug + + + View + categoryTag:Version Control (Team) - + persp.actionSet:org.eclipse.mylyn.tasks.ui.navigation persp.actionSet:org.eclipse.ui.cheatsheets.actionSet @@ -234,15 +239,8 @@ persp.viewSC:org.eclipse.ui.views.ProblemView persp.viewSC:org.eclipse.ui.navigator.ProjectExplorer persp.viewSC:org.eclipse.pde.runtime.LogView - persp.editorOnboardingImageUri:platform:/plugin/org.eclipse.debug.ui/icons/full/onboarding_debug_persp.svg - persp.editorOnboardingText:Go hunt your bugs here. persp.actionSet:org.eclipse.debug.ui.breakpointActionSet persp.showIn:org.eclipse.ui.navigator.ProjectExplorer - persp.editorOnboardingCommand:Find Actions$$$Ctrl+3 - persp.editorOnboardingCommand:Step Into$$$F5 - persp.editorOnboardingCommand:Step Over$$$F6 - persp.editorOnboardingCommand:Step Return$$$F7 - persp.editorOnboardingCommand:Resume$$$F8 persp.perspSC:org.eclipse.jdt.ui.JavaPerspective persp.perspSC:org.eclipse.jdt.ui.JavaBrowsingPerspective persp.actionSet:org.eclipse.jdt.ui.JavaActionSet @@ -256,100 +254,107 @@ persp.showIn:org.eclipse.egit.ui.RepositoriesView persp.viewSC:org.eclipse.jdt.junit.ResultView persp.viewSC:org.eclipse.ant.ui.views.AntView - - + persp.editorOnboardingImageUri:platform:/plugin/org.eclipse.debug.ui/icons/full/onboarding_debug_persp.svg + persp.editorOnboardingText:Go hunt your bugs here. + persp.editorOnboardingCommand:Find Actions$$$Ctrl+3 + persp.editorOnboardingCommand:Step Into$$$F5 + persp.editorOnboardingCommand:Step Over$$$F6 + persp.editorOnboardingCommand:Step Return$$$F7 + persp.editorOnboardingCommand:Resume$$$F8 + + org.eclipse.e4.primaryNavigationStack - + View categoryTag:Debug - + View categoryTag:General - + View categoryTag:Java - + View categoryTag:Java - + View categoryTag:Java - - - - + + + + org.eclipse.e4.secondaryNavigationStack - Minimized - + active + View categoryTag:Debug - + View categoryTag:Debug - + View categoryTag:Debug - + View categoryTag:General - + View categoryTag:General - + View categoryTag:General - + View categoryTag:Ant - - + + View categoryTag:General - + View categoryTag:General - + View categoryTag:Debug - + View categoryTag:General - + View categoryTag:General - + View categoryTag:General - + View categoryTag:Terminal - + View categoryTag:Debug - + View categoryTag:General @@ -358,2676 +363,2743 @@ - - + + View categoryTag:Help - + View categoryTag:General - + View categoryTag:Help - + View categoryTag:Help - + View categoryTag:General - + ViewMenu menuContribution:menu - + - + View categoryTag:Help - - + + EditorStack - - + + Editor removeOnHide org.eclipse.jdt.ui.CompilationUnitEditor - + Editor removeOnHide org.eclipse.jdt.ui.CompilationUnitEditor - + Editor removeOnHide org.eclipse.jdt.ui.CompilationUnitEditor - + Editor removeOnHide org.eclipse.jdt.ui.CompilationUnitEditor - - + + + Editor + removeOnHide + org.eclipse.jdt.ui.CompilationUnitEditor + + + + Editor + removeOnHide + org.eclipse.ui.genericeditor.GenericEditor + + + + Editor + removeOnHide + org.eclipse.ui.genericeditor.GenericEditor + + + + Editor + removeOnHide + org.eclipse.ui.genericeditor.GenericEditor + + + + Editor + removeOnHide + org.eclipse.ui.genericeditor.GenericEditor + + + + Editor + removeOnHide + org.eclipse.ui.genericeditor.GenericEditor + + + + Editor + removeOnHide + org.eclipse.ui.genericeditor.GenericEditor + + + + Editor + removeOnHide + org.eclipse.ui.genericeditor.GenericEditor + + + + Editor + removeOnHide + org.eclipse.jdt.ui.CompilationUnitEditor + + + + Editor + removeOnHide + org.eclipse.jdt.ui.CompilationUnitEditor + + + + Editor + removeOnHide + org.eclipse.jdt.ui.CompilationUnitEditor + + + Editor removeOnHide org.eclipse.jdt.ui.CompilationUnitEditor - + View categoryTag:Java - active - + ViewMenu menuContribution:menu - + - + View categoryTag:Java - + View categoryTag:General - + View categoryTag:General - + ViewMenu menuContribution:menu - + - + View categoryTag:Java - + View categoryTag:Java - + - + View categoryTag:General - + highlighted + ViewMenu menuContribution:menu - + - + View categoryTag:General - + ViewMenu menuContribution:menu - + - + View categoryTag:General - + View categoryTag:General - + ViewMenu menuContribution:menu - + - + View categoryTag:General - + ViewMenu menuContribution:menu - + - + View categoryTag:General - + View categoryTag:General - + View categoryTag:Mylyn - + View categoryTag:Terminal - + View categoryTag:Java - + View categoryTag:Git - + View categoryTag:Java - + View categoryTag:Spring - + ViewMenu menuContribution:menu - + - + View categoryTag:Ant - + View categoryTag:Gradle - + ViewMenu menuContribution:menu - + - + View categoryTag:Gradle - + ViewMenu menuContribution:menu - + - - - - - View - categoryTag:Oomph - NoRestore - - ViewMenu - menuContribution:menu - - - - + View categoryTag:Debug - busy - + ViewMenu menuContribution:menu - + - + View categoryTag:Debug - + View categoryTag:Debug - + ViewMenu menuContribution:menu - + - + View categoryTag:Debug - + active + activeOnClose + ViewMenu menuContribution:menu - + - + View categoryTag:Debug - + ViewMenu menuContribution:menu - + - + View categoryTag:General - + View categoryTag:General - + - + View categoryTag:Debug - + ViewMenu menuContribution:menu - + - - + + + + + View + categoryTag:Version Control (Team) + + ViewMenu + menuContribution:menu + + + + + toolbarSeparator - + - + Draggable - + - + toolbarSeparator - + - + Draggable - - + + - + toolbarSeparator - + - + Draggable - + Draggable - + Draggable - + Draggable - + toolbarSeparator - + - + Draggable - + - - Draggable - - + toolbarSeparator - + - + toolbarSeparator - + - + Draggable - + stretch SHOW_RESTORE_MENU - + Draggable HIDEABLE SHOW_RESTORE_MENU - - + + stretch - + Draggable - + Draggable - - + + TrimStack Draggable - + TrimStack Draggable - + TrimStack Draggable - + TrimStack Draggable - - + + TrimStack Draggable - + TrimStack Draggable - + TrimStack Draggable - + + TrimStack + Draggable + + TrimStack Draggable - - - - - - - - - - - - - - + + + + + + + + + + + + + + platform:gtk - - - - + + + + platform:gtk - - - - - - - - + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - + + + + + + + + + + + + + - - - - - + + + + + - - + + - - - - - - - - - + + + + + + + + + - - + + - - - + + + - - - - - + + + + + - - + + - - - + + + - - - + + + - - - - - - - - + + + + + + + + platform:gtk - - - - - + + + + + - - + + - - + + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - - - - + + + + - - + + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + - - - - - - - - - - - + + + + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - + + - - - - - - - + + + + + + + - - - - + + + + - - - - - - - - + + + + + + + + - - + + - - - - - - + + + + + + - - - - - - + + + + + + - - + + - - - - - - - - + + + + + + + + - - - + + + - - - - + + + + - - + + - - + + - - - + + + - - + + - - + + - - + + - - + + - - + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + - - + + - - - - - - - - - + + + + + + + + + - - - - - + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Editor removeOnHide - + View categoryTag:Ant - + View categoryTag:Gradle - + View categoryTag:Gradle - + View categoryTag:Debug - + View categoryTag:Debug - + View categoryTag:Debug - + View categoryTag:Debug - + View categoryTag:Debug - + View categoryTag:Debug - + View categoryTag:Debug - + View categoryTag:Debug - + View categoryTag:Java - + View categoryTag:Git - + View categoryTag:Git - + View categoryTag:Git - + View categoryTag:Git NoRestore - + View categoryTag:Git - + View categoryTag:Help - + View categoryTag:Java - + View categoryTag:Java - + View categoryTag:Debug - + View categoryTag:Java - + View categoryTag:Java - + View categoryTag:Java - + View categoryTag:Java Browsing - + View categoryTag:Java Browsing - + View categoryTag:Java Browsing - + View categoryTag:Java Browsing - + View categoryTag:Java - + View categoryTag:General - + View categoryTag:Java - + View categoryTag:Java - + View categoryTag:Docker - + View categoryTag:Docker - + View categoryTag:Docker - + View categoryTag:Docker - + View categoryTag:Language Servers - + View categoryTag:Language Servers - + View categoryTag:Language Servers - + View categoryTag:Maven - + View categoryTag:Maven - + View categoryTag:Maven - + View categoryTag:Mylyn - + View categoryTag:Mylyn - + View categoryTag:Mylyn - + View categoryTag:Mylyn - + View categoryTag:Mylyn - + View categoryTag:Mylyn - + View categoryTag:Oomph - + View categoryTag:Oomph NoRestore - + View categoryTag:Plug-in Development - + View categoryTag:General - + View categoryTag:Version Control (Team) - + View categoryTag:Version Control (Team) - + View categoryTag:Terminal - + View categoryTag:Help - + View categoryTag:General - + View categoryTag:General - + View categoryTag:Help - + View categoryTag:General - + View categoryTag:General - + View categoryTag:General - + View categoryTag:General - + View categoryTag:General - + View categoryTag:General - + View categoryTag:General - + View categoryTag:General - + View categoryTag:General - + View categoryTag:General - + View categoryTag:General - + View categoryTag:Spring - + View categoryTag:Spring - + View categoryTag:Spring - - + + glue move_after:PerspectiveSpacer SHOW_RESTORE_MENU - + move_after:Spacer Glue HIDEABLE SHOW_RESTORE_MENU - + glue move_after:SearchField SHOW_RESTORE_MENU - - - - - + + + + + - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + - - - - - - - - - - + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - + + + + + + + + + + + + + - - - - - - - - - - - + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + - - - - - - - + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - - - - + + + + - - - - - - - + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - + + + + + + + - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + - - - + + + - - - - - - - - - + + + + + + + + + - - - - - + + + + + - - - + + + - - - - - + + + + + - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + - - - - - - - - - - + + + + + + + + + + - - - - - + + + + + - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.metadata/.plugins/org.eclipse.jdt.core/externalFilesCache b/.metadata/.plugins/org.eclipse.jdt.core/externalFilesCache index 0f60b77..bc0f1a5 100644 Binary files a/.metadata/.plugins/org.eclipse.jdt.core/externalFilesCache and b/.metadata/.plugins/org.eclipse.jdt.core/externalFilesCache differ diff --git a/.metadata/.plugins/org.eclipse.jdt.core/nonChainingJarsCache b/.metadata/.plugins/org.eclipse.jdt.core/nonChainingJarsCache index 31c1d00..934aa7b 100644 Binary files a/.metadata/.plugins/org.eclipse.jdt.core/nonChainingJarsCache and b/.metadata/.plugins/org.eclipse.jdt.core/nonChainingJarsCache differ diff --git a/.metadata/.plugins/org.eclipse.jdt.ui/OpenTypeHistory.xml b/.metadata/.plugins/org.eclipse.jdt.ui/OpenTypeHistory.xml index 14bad2f..38813f0 100644 --- a/.metadata/.plugins/org.eclipse.jdt.ui/OpenTypeHistory.xml +++ b/.metadata/.plugins/org.eclipse.jdt.ui/OpenTypeHistory.xml @@ -2,4 +2,14 @@ + + + + + + + + + + diff --git a/.metadata/.plugins/org.eclipse.jdt.ui/QualifiedTypeNameHistory.xml b/.metadata/.plugins/org.eclipse.jdt.ui/QualifiedTypeNameHistory.xml index 9e390f5..2e7dc7c 100644 --- a/.metadata/.plugins/org.eclipse.jdt.ui/QualifiedTypeNameHistory.xml +++ b/.metadata/.plugins/org.eclipse.jdt.ui/QualifiedTypeNameHistory.xml @@ -1,2 +1,31 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.metadata/.plugins/org.eclipse.jdt.ui/dialog_settings.xml b/.metadata/.plugins/org.eclipse.jdt.ui/dialog_settings.xml index 58be2e1..1352c02 100644 --- a/.metadata/.plugins/org.eclipse.jdt.ui/dialog_settings.xml +++ b/.metadata/.plugins/org.eclipse.jdt.ui/dialog_settings.xml @@ -1,11 +1,12 @@
+
- - + +
@@ -25,4 +26,54 @@
+
+ + + + + +
+
+ + + + + +
+
+ +
+
+ +
+
+ + +
+
+ + + + + +
+
+
+
+ + + + + +
+
+ + + + +
+
+ + +
diff --git a/.metadata/.plugins/org.eclipse.m2e.logback/0.log b/.metadata/.plugins/org.eclipse.m2e.logback/0.log index 80de81c..7fbb4a0 100644 --- a/.metadata/.plugins/org.eclipse.m2e.logback/0.log +++ b/.metadata/.plugins/org.eclipse.m2e.logback/0.log @@ -7,3 +7,4 @@ 2026-03-23 21:09:44,347 [Worker-7: Loading available Gradle versions] INFO o.e.b.c.i.u.g.PublishedGradleVersions - Gradle version information cache is up-to-date. Trying to read. 2026-03-24 06:41:47,661 [Worker-2: Loading available Gradle versions] INFO o.e.b.c.i.u.g.PublishedGradleVersions - Gradle version information cache is up-to-date. Trying to read. 2026-03-24 11:26:24,107 [Worker-2: Loading available Gradle versions] INFO o.e.b.c.i.u.g.PublishedGradleVersions - Gradle version information cache is up-to-date. Trying to read. +2026-03-25 07:26:14,133 [Worker-5: Loading available Gradle versions] INFO o.e.b.c.i.u.g.PublishedGradleVersions - Gradle version information cache is out-of-date. Trying to update. diff --git a/.metadata/version.ini b/.metadata/version.ini index 7c59b45..de1ba2c 100644 --- a/.metadata/version.ini +++ b/.metadata/version.ini @@ -1,3 +1,3 @@ -#Tue Mar 24 11:25:59 CET 2026 +#Wed Mar 25 07:26:10 CET 2026 org.eclipse.core.runtime=2 org.eclipse.platform=4.39.0.v20260226-0420 diff --git a/bilder/banner.png b/bilder/banner.png new file mode 100644 index 0000000..9f3671b Binary files /dev/null and b/bilder/banner.png differ diff --git a/xxxthegame/src/main/resources/sex.png b/bilder/sex.png similarity index 100% rename from xxxthegame/src/main/resources/sex.png rename to bilder/sex.png diff --git a/xxxthegame/src/main/java/de/oaa/xxx/admin/AdminController.java b/xxxthegame/src/main/java/de/oaa/xxx/admin/AdminController.java index b68ecb8..a42aee6 100644 --- a/xxxthegame/src/main/java/de/oaa/xxx/admin/AdminController.java +++ b/xxxthegame/src/main/java/de/oaa/xxx/admin/AdminController.java @@ -31,6 +31,10 @@ import de.oaa.xxx.aufgaben.repository.GruppenAboRepository; import de.oaa.xxx.aufgaben.repository.SperreRepository; import de.oaa.xxx.aufgaben.repository.StrafeRepository; import de.oaa.xxx.aufgaben.repository.ToyRepository; +import de.oaa.xxx.feedback.FeedbackEntity; +import de.oaa.xxx.feedback.FeedbackRepository; +import de.oaa.xxx.feedback.FeedbackStatus; +import de.oaa.xxx.support.SupportUserService; import de.oaa.xxx.games.chastity.ttlock.TTLockConfigEntity; import de.oaa.xxx.games.chastity.ttlock.TTLockConfigRepository; import de.oaa.xxx.meldung.MeldungEntity; @@ -50,6 +54,8 @@ public class AdminController { private final AdminRepository adminRepository; private final UserRepository userRepository; private final MeldungRepository meldungRepository; + private final FeedbackRepository feedbackRepository; + private final SupportUserService supportUserService; private final AufgabenGruppeRepository aufgabenGruppeRepository; private final AufgabeRepository aufgabeRepository; private final StrafeRepository strafeRepository; @@ -62,6 +68,8 @@ public class AdminController { public AdminController(AdminRepository adminRepository, UserRepository userRepository, MeldungRepository meldungRepository, + FeedbackRepository feedbackRepository, + SupportUserService supportUserService, AufgabenGruppeRepository aufgabenGruppeRepository, AufgabeRepository aufgabeRepository, StrafeRepository strafeRepository, @@ -74,6 +82,8 @@ public class AdminController { this.adminRepository = adminRepository; this.userRepository = userRepository; this.meldungRepository = meldungRepository; + this.feedbackRepository = feedbackRepository; + this.supportUserService = supportUserService; this.aufgabenGruppeRepository = aufgabenGruppeRepository; this.aufgabeRepository = aufgabeRepository; this.strafeRepository = strafeRepository; @@ -109,6 +119,12 @@ public class AdminController { record SubscriptionStatusDto(UUID userId, String userName, String subscriptionType, LocalDate subscribedAt, LocalDate validUntil) {} + record FeedbackDto(UUID feedbackId, String name, String seite, String grund, + String text, LocalDateTime eingegangen, FeedbackStatus status, + String inArbeitVonName) {} + + record FeedbackAntwortRequest(String text) {} + // ── Hilfsmethoden ──────────────────────────────────────────────────────── private AdminEntity requireAdmin(Principal principal) { @@ -413,6 +429,74 @@ public class AdminController { )); } + // ── Feedback ───────────────────────────────────────────────────────────── + + private FeedbackDto toFeedbackDto(FeedbackEntity e) { + String inArbeitName = null; + if (e.getInArbeitVon() != null) { + inArbeitName = userRepository.findById(e.getInArbeitVon()) + .map(UserEntity::getName).orElse("?"); + } + return new FeedbackDto(e.getFeedbackId(), e.getName(), e.getSeite(), e.getGrund(), + e.getText(), e.getEingegangen(), e.getStatus(), inArbeitName); + } + + @GetMapping("/feedback") + public ResponseEntity>> getFeedback(Principal principal) { + requireAdmin(principal); + List ungelesen = feedbackRepository + .findByStatusOrderByEingegangenDesc(FeedbackStatus.UNGELESEN) + .stream().map(this::toFeedbackDto).toList(); + List inArbeit = feedbackRepository + .findByStatusOrderByEingegangenDesc(FeedbackStatus.IN_ARBEIT) + .stream().map(this::toFeedbackDto).toList(); + List beantwortet = feedbackRepository + .findByStatusOrderByEingegangenDesc(FeedbackStatus.BEANTWORTET) + .stream().map(this::toFeedbackDto).toList(); + return ResponseEntity.ok(java.util.Map.of( + "ungelesen", ungelesen, + "inArbeit", inArbeit, + "beantwortet", beantwortet)); + } + + @PutMapping("/feedback/{id}/annehmen") + public ResponseEntity feedbackAnnehmen(@PathVariable("id") UUID id, Principal principal) { + AdminEntity admin = requireAdmin(principal); + FeedbackEntity f = feedbackRepository.findById(id) + .orElseThrow(() -> new org.springframework.web.server.ResponseStatusException( + org.springframework.http.HttpStatus.NOT_FOUND)); + if (f.getStatus() == FeedbackStatus.IN_ARBEIT) { + // Bereits von jemand anderem in Arbeit – Konflikt + return ResponseEntity.status(409).build(); + } + f.setStatus(FeedbackStatus.IN_ARBEIT); + f.setInArbeitVon(admin.getUserId()); + feedbackRepository.save(f); + return ResponseEntity.noContent().build(); + } + + @PostMapping("/feedback/{id}/antworten") + public ResponseEntity feedbackAntworten(@PathVariable("id") UUID id, + @RequestBody FeedbackAntwortRequest body, + Principal principal) { + requireAdmin(principal); + if (body.text() == null || body.text().isBlank()) { + return ResponseEntity.badRequest().build(); + } + FeedbackEntity f = feedbackRepository.findById(id) + .orElseThrow(() -> new org.springframework.web.server.ResponseStatusException( + org.springframework.http.HttpStatus.NOT_FOUND)); + f.setStatus(FeedbackStatus.BEANTWORTET); + feedbackRepository.save(f); + + // DM an den Nutzer senden, falls er eingeloggt war + if (f.getUserId() != null) { + String dm = "Ursprüngliche Nachricht\n" + f.getText() + "\n\nAntwort\n" + body.text(); + supportUserService.sendDm(f.getUserId(), dm); + } + return ResponseEntity.noContent().build(); + } + // ── TTLock-Konfiguration (nur SUPERADMIN) ───────────────────────────────── @GetMapping("/ttlock") diff --git a/xxxthegame/src/main/java/de/oaa/xxx/config/SecurityConfig.java b/xxxthegame/src/main/java/de/oaa/xxx/config/SecurityConfig.java index a3508ac..4e54107 100644 --- a/xxxthegame/src/main/java/de/oaa/xxx/config/SecurityConfig.java +++ b/xxxthegame/src/main/java/de/oaa/xxx/config/SecurityConfig.java @@ -76,6 +76,7 @@ public class SecurityConfig { .requestMatchers("/notifications/**").authenticated() .requestMatchers("/events/**").authenticated() .requestMatchers("/*.html").permitAll() + .requestMatchers("/help/*.html").permitAll() .requestMatchers("/css/**").permitAll() .requestMatchers("/js/**").permitAll() .requestMatchers("/images/**").permitAll() @@ -100,6 +101,7 @@ public class SecurityConfig { .requestMatchers(HttpMethod.POST, "/password-reset/confirm").permitAll() .requestMatchers(HttpMethod.GET, "/email-change/**").permitAll() .requestMatchers(HttpMethod.GET, "/keyholder/invitation/**").permitAll() + .requestMatchers(HttpMethod.POST, "/api/feedback").permitAll() .requestMatchers(HttpMethod.POST, "/filler").permitAll() .requestMatchers(HttpMethod.POST, "/api/ttlock/callback").permitAll() .requestMatchers(HttpMethod.GET, "/api/ttlock/callback").permitAll() diff --git a/xxxthegame/src/main/java/de/oaa/xxx/feedback/FeedbackController.java b/xxxthegame/src/main/java/de/oaa/xxx/feedback/FeedbackController.java new file mode 100644 index 0000000..59c7887 --- /dev/null +++ b/xxxthegame/src/main/java/de/oaa/xxx/feedback/FeedbackController.java @@ -0,0 +1,89 @@ +package de.oaa.xxx.feedback; + +import de.oaa.xxx.mail.Email; +import de.oaa.xxx.mail.MailService; +import de.oaa.xxx.support.SupportUserService; +import de.oaa.xxx.user.UserRepository; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.security.Principal; +import java.time.LocalDateTime; +import java.util.UUID; + +@RestController +@RequestMapping("/api/feedback") +public class FeedbackController { + + private final MailService mailService; + private final FeedbackRepository feedbackRepository; + private final UserRepository userRepository; + private final SupportUserService supportUserService; + + public FeedbackController(MailService mailService, + FeedbackRepository feedbackRepository, + UserRepository userRepository, + SupportUserService supportUserService) { + this.mailService = mailService; + this.feedbackRepository = feedbackRepository; + this.userRepository = userRepository; + this.supportUserService = supportUserService; + } + + record FeedbackRequest(String name, String seite, String grund, String text) {} + + @PostMapping + public ResponseEntity send(@RequestBody FeedbackRequest req, Principal principal) { + if (req.text() == null || req.text().isBlank() || req.text().length() < 10 || req.text().length() > 1000) { + return ResponseEntity.badRequest().build(); + } + + // Eingeloggten User ermitteln (optional) + UUID userId = null; + if (principal != null) { + userId = userRepository.findByEmail(principal.getName()) + .map(u -> u.getUserId()).orElse(null); + } + + FeedbackEntity entity = new FeedbackEntity(); + entity.setUserId(userId); + entity.setName(req.name()); + entity.setSeite(req.seite()); + entity.setGrund(req.grund()); + entity.setText(req.text()); + entity.setEingegangen(LocalDateTime.now()); + entity.setStatus(FeedbackStatus.UNGELESEN); + feedbackRepository.save(entity); + + // Bestätigungs-DM an eingeloggten Nutzer + if (userId != null) { + supportUserService.sendDm(userId, + "Vielen Dank für dein Feedback! ✉️\n\n" + + "Wir haben deine Nachricht erhalten und werden uns so schnell wie möglich darum kümmern.\n\n" + + "Bitte antworte nicht auf diese Nachricht – du kannst uns jederzeit über " + + "Kontakt & Feedback erneut erreichen."); + } + + try { + Email email = new Email(); + email.setEmailAdresse("kontakt@xxx-sphere.de"); + email.setTitel("[xXx Sphere] " + esc(req.grund())); + email.setText( + "Von: " + esc(req.name()) + "
" + + "Seite: " + esc(req.seite()) + "
" + + "Grund: " + esc(req.grund()) + "

" + + "Nachricht:
" + esc(req.text()).replace("\n", "
") + ); + mailService.send(email); + } catch (Exception e) { + // Mail-Server nicht erreichbar – Eintrag ist bereits gespeichert + } + + return ResponseEntity.ok().build(); + } + + private String esc(String s) { + if (s == null) return ""; + return s.replace("&", "&").replace("<", "<").replace(">", ">"); + } +} diff --git a/xxxthegame/src/main/java/de/oaa/xxx/feedback/FeedbackEntity.java b/xxxthegame/src/main/java/de/oaa/xxx/feedback/FeedbackEntity.java new file mode 100644 index 0000000..af061e4 --- /dev/null +++ b/xxxthegame/src/main/java/de/oaa/xxx/feedback/FeedbackEntity.java @@ -0,0 +1,38 @@ +package de.oaa.xxx.feedback; + +import jakarta.persistence.*; +import lombok.Getter; +import lombok.Setter; + +import java.time.LocalDateTime; +import java.util.UUID; + +@Entity +@Table(name = "feedback") +@Getter +@Setter +public class FeedbackEntity { + + @Id + @GeneratedValue(strategy = GenerationType.UUID) + private UUID feedbackId; + + /** Eingeloggter Nutzer – null wenn Gast */ + private UUID userId; + + private String name; + private String seite; + private String grund; + + @Column(columnDefinition = "TEXT") + private String text; + + private LocalDateTime eingegangen; + + @Enumerated(EnumType.STRING) + @Column(nullable = false, length = 20) + private FeedbackStatus status = FeedbackStatus.UNGELESEN; + + /** Admin-UserId der den Eintrag in Arbeit genommen hat */ + private UUID inArbeitVon; +} diff --git a/xxxthegame/src/main/java/de/oaa/xxx/feedback/FeedbackRepository.java b/xxxthegame/src/main/java/de/oaa/xxx/feedback/FeedbackRepository.java new file mode 100644 index 0000000..b2f465a --- /dev/null +++ b/xxxthegame/src/main/java/de/oaa/xxx/feedback/FeedbackRepository.java @@ -0,0 +1,11 @@ +package de.oaa.xxx.feedback; + +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; +import java.util.UUID; + +public interface FeedbackRepository extends JpaRepository { + + List findByStatusOrderByEingegangenDesc(FeedbackStatus status); +} diff --git a/xxxthegame/src/main/java/de/oaa/xxx/feedback/FeedbackStatus.java b/xxxthegame/src/main/java/de/oaa/xxx/feedback/FeedbackStatus.java new file mode 100644 index 0000000..b6e0197 --- /dev/null +++ b/xxxthegame/src/main/java/de/oaa/xxx/feedback/FeedbackStatus.java @@ -0,0 +1,7 @@ +package de.oaa.xxx.feedback; + +public enum FeedbackStatus { + UNGELESEN, + IN_ARBEIT, + BEANTWORTET +} diff --git a/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/cardlock/CardLockController.java b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/cardlock/CardLockController.java index 82594cf..1af7dbf 100644 --- a/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/cardlock/CardLockController.java +++ b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/cardlock/CardLockController.java @@ -595,6 +595,7 @@ public class CardLockController { result.put("testLock", l.isTestLock()); result.put("emergencyUnlockRequested", l.getEmergencyUnlockRequestedAt() != null); + result.put("controllType", l.getControllType() != null ? l.getControllType().name() : "UNLOCK_CODE"); if (l.isTestLock()) { result.put("unlockCode", l.getUnlockCode() != null ? l.getUnlockCode() : ""); } diff --git a/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/timelock/TimeLockController.java b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/timelock/TimeLockController.java index 9a3b05e..1d5f38b 100644 --- a/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/timelock/TimeLockController.java +++ b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/timelock/TimeLockController.java @@ -118,7 +118,6 @@ public class TimeLockController { TimeLockEntity lock = buildBaseEntity(template, myId, req.lockeeUserId(), false); lock.setStartTime(null); - lock.setUnlockTime(null); timeLockRepository.save(lock); String token = UUID.randomUUID().toString().replace("-", ""); @@ -328,6 +327,7 @@ public class TimeLockController { result.put("spinEnabled", spinEnabled); result.put("spinDue", spinDue); result.put("nextSpinIn", nextSpinIn); + result.put("spinningWheelEntries", l.getSpinningWheelEntries() != null ? l.getSpinningWheelEntries() : List.of()); result.put("taskTimingEnabled", taskTimingEnabled); result.put("nextTaskIn", nextTaskIn); diff --git a/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/timelock/TimeLockEntity.java b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/timelock/TimeLockEntity.java index 70762b2..c9773a6 100644 --- a/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/timelock/TimeLockEntity.java +++ b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/timelock/TimeLockEntity.java @@ -21,10 +21,6 @@ import lombok.Setter; @DiscriminatorValue("TIMELOCK") public class TimeLockEntity extends BaseLockEntity { - @Column - private LocalDateTime startTime; - @Column - private LocalDateTime unlockTime; @Column private boolean endTimeVisible; @Column diff --git a/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/timelock/TimeLockService.java b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/timelock/TimeLockService.java index a41daa7..9692001 100644 --- a/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/timelock/TimeLockService.java +++ b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/timelock/TimeLockService.java @@ -317,6 +317,7 @@ public class TimeLockService extends BaseLockService implements LockControlCallb } public void check() { + if (lock.getStartTime() == null) return; LocalDate today = LocalDate.now(); if (!lock.getStartTime().toLocalDate().equals(today)) { if (lock.getLastCheck() != null || today.isAfter(lock.getLastCheck())) { diff --git a/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/ttlock/TTLockUserConfigEntity.java b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/ttlock/TTLockUserConfigEntity.java index e00d970..41b4841 100644 --- a/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/ttlock/TTLockUserConfigEntity.java +++ b/xxxthegame/src/main/java/de/oaa/xxx/games/chastity/ttlock/TTLockUserConfigEntity.java @@ -29,4 +29,8 @@ public class TTLockUserConfigEntity { /** ID des aktuell gesetzten PINs auf dem Schloss – wird zum Löschen beim nächsten lock() benötigt */ @Column private Integer currentKeyboardPwdId; + + /** true, wenn der Anwender mindestens einmal erfolgreich die Verbindung getestet hat */ + @Column(nullable = false, columnDefinition = "boolean default false") + private boolean testSuccessful; } diff --git a/xxxthegame/src/main/java/de/oaa/xxx/social/SocialController.java b/xxxthegame/src/main/java/de/oaa/xxx/social/SocialController.java index 69e0835..636a622 100644 --- a/xxxthegame/src/main/java/de/oaa/xxx/social/SocialController.java +++ b/xxxthegame/src/main/java/de/oaa/xxx/social/SocialController.java @@ -10,6 +10,7 @@ import de.oaa.xxx.social.entity.MessageCause; import de.oaa.xxx.social.entity.MessageEntity; import de.oaa.xxx.social.repository.FriendshipRepository; import de.oaa.xxx.social.repository.MessageRepository; +import de.oaa.xxx.support.SupportUserService; import de.oaa.xxx.user.UserEntity; import de.oaa.xxx.user.UserRepository; import org.slf4j.Logger; @@ -219,6 +220,11 @@ public class SocialController { if (body.text() == null || body.text().isBlank()) return ResponseEntity.badRequest().build(); + // Nachrichten an den Support-Account sind nicht erlaubt + if (SupportUserService.SUPPORT_USER_ID.equals(body.receiverId())) { + return ResponseEntity.status(403).build(); + } + MessageEntity msg = new MessageEntity(); msg.setMessageId(UUID.randomUUID()); msg.setSenderId(myId); diff --git a/xxxthegame/src/main/java/de/oaa/xxx/social/SystemMessageService.java b/xxxthegame/src/main/java/de/oaa/xxx/social/SystemMessageService.java index 6113b0b..3239cb6 100644 --- a/xxxthegame/src/main/java/de/oaa/xxx/social/SystemMessageService.java +++ b/xxxthegame/src/main/java/de/oaa/xxx/social/SystemMessageService.java @@ -97,6 +97,7 @@ public class SystemMessageService { case GAME_STATE -> "XXX The Game – Spielstatus-Änderung"; case EMERGENCY -> "XXX The Game – ⚠️ Notfall"; case FRIENDREQUEST -> "XXX The Game – Neue Freundschaftsanfrage"; + case SUPPORT -> "xXx Sphere – Nachricht vom Support"; }; } diff --git a/xxxthegame/src/main/java/de/oaa/xxx/social/entity/MessageCause.java b/xxxthegame/src/main/java/de/oaa/xxx/social/entity/MessageCause.java index 9bbbac6..c48a816 100644 --- a/xxxthegame/src/main/java/de/oaa/xxx/social/entity/MessageCause.java +++ b/xxxthegame/src/main/java/de/oaa/xxx/social/entity/MessageCause.java @@ -4,5 +4,6 @@ public enum MessageCause { INVITATION, GAME_STATE, EMERGENCY, - FRIENDREQUEST + FRIENDREQUEST, + SUPPORT } diff --git a/xxxthegame/src/main/java/de/oaa/xxx/support/SupportUserService.java b/xxxthegame/src/main/java/de/oaa/xxx/support/SupportUserService.java new file mode 100644 index 0000000..754d789 --- /dev/null +++ b/xxxthegame/src/main/java/de/oaa/xxx/support/SupportUserService.java @@ -0,0 +1,112 @@ +package de.oaa.xxx.support; + +import de.oaa.xxx.social.entity.MessageCause; +import de.oaa.xxx.social.entity.MessageEntity; +import de.oaa.xxx.social.repository.MessageRepository; +import de.oaa.xxx.user.UserEntity; +import de.oaa.xxx.user.UserRepository; +import jakarta.annotation.PostConstruct; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.io.ClassPathResource; +import org.springframework.stereotype.Service; + +import javax.imageio.ImageIO; +import java.awt.*; +import java.awt.image.BufferedImage; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.nio.charset.StandardCharsets; +import java.time.LocalDateTime; +import java.util.Base64; +import java.util.UUID; + +@Service +public class SupportUserService { + + private static final Logger LOGGER = LoggerFactory.getLogger(SupportUserService.class); + + /** Deterministischer UUID – ändert sich nie. */ + public static final UUID SUPPORT_USER_ID = + UUID.nameUUIDFromBytes("xxxsphere-support".getBytes(StandardCharsets.UTF_8)); + + private static final String SUPPORT_NAME = "xXx Support"; + private static final String SUPPORT_EMAIL = "support@system.local"; + + private final UserRepository userRepository; + private final MessageRepository messageRepository; + + public SupportUserService(UserRepository userRepository, MessageRepository messageRepository) { + this.userRepository = userRepository; + this.messageRepository = messageRepository; + } + + /** Stellt sicher, dass der Support-Fake-User in der DB existiert. */ + @PostConstruct + public void ensureExists() { + try { + String icon = loadIconBase64(); + userRepository.findById(SUPPORT_USER_ID).ifPresentOrElse(u -> { + if (u.getProfilePicture() == null && icon != null) { + try { + u.setProfilePicture(icon); + userRepository.save(u); + } catch (Exception e) { + LOGGER.warn("Support-User-Avatar konnte nicht gespeichert werden: {}", e.getMessage()); + } + } + }, () -> { + UserEntity u = new UserEntity(); + u.setUserId(SUPPORT_USER_ID); + u.setName(SUPPORT_NAME); + u.setEmail(SUPPORT_EMAIL); + u.setPassword("__SYSTEM__"); // kein gültiges Login + try { + u.setProfilePicture(icon); + userRepository.save(u); + } catch (Exception e) { + LOGGER.warn("Support-User konnte nicht mit Avatar gespeichert werden, versuche ohne: {}", e.getMessage()); + u.setProfilePicture(null); + userRepository.save(u); + } + }); + } catch (Exception e) { + LOGGER.error("Support-User konnte nicht initialisiert werden: {}", e.getMessage()); + } + } + + private String loadIconBase64() { + try { + byte[] bytes = new ClassPathResource("static/img/icon.png").getInputStream().readAllBytes(); + BufferedImage original = ImageIO.read(new ByteArrayInputStream(bytes)); + BufferedImage thumb = new BufferedImage(64, 64, BufferedImage.TYPE_INT_ARGB); + Graphics2D g = thumb.createGraphics(); + g.drawImage(original.getScaledInstance(64, 64, Image.SCALE_SMOOTH), 0, 0, null); + g.dispose(); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ImageIO.write(thumb, "png", baos); + return Base64.getEncoder().encodeToString(baos.toByteArray()); + } catch (Exception e) { + LOGGER.warn("Support-Avatar konnte nicht geladen werden: {}", e.getMessage()); + return null; + } + } + + /** + * Sendet eine Direktnachricht vom Support-Account an den Nutzer. + * Die Nachricht erscheint als normale DM (systemMessage = false), + * damit sie in nachrichten.html sichtbar ist. + */ + public void sendDm(UUID receiverId, String text) { + if (receiverId == null) return; + MessageEntity msg = new MessageEntity(); + msg.setMessageId(UUID.randomUUID()); + msg.setSenderId(SUPPORT_USER_ID); + msg.setReceiverId(receiverId); + msg.setText(text); + msg.setSentAt(LocalDateTime.now()); + msg.setSystemMessage(false); + msg.setMessageCause(MessageCause.SUPPORT); + messageRepository.save(msg); + } +} diff --git a/xxxthegame/src/main/java/de/oaa/xxx/user/UserController.java b/xxxthegame/src/main/java/de/oaa/xxx/user/UserController.java index 31bc3b0..0f5c0ae 100644 --- a/xxxthegame/src/main/java/de/oaa/xxx/user/UserController.java +++ b/xxxthegame/src/main/java/de/oaa/xxx/user/UserController.java @@ -83,7 +83,7 @@ public class UserController { record ProfilePictureRequest(String picture, String pictureHq) {} record NameChangeRequest(String name) {} record GeburtsdatumChangeRequest(LocalDate geburtsdatum) {} - record TtlockUserConfigDto(String username, boolean passwordSet, Integer lockId) {} + record TtlockUserConfigDto(String username, boolean passwordSet, Integer lockId, boolean testSuccessful) {} record TtlockUserConfigRequest(String username, String password, Integer lockId) {} record ProfileRequest(Integer groesse, Integer gewicht, Geschlecht geschlecht, Neigung neigung, Beziehungsstatus beziehungsstatus, String beschreibung) {} @@ -308,7 +308,8 @@ public class UserController { return ResponseEntity.ok(new TtlockUserConfigDto( cfg.getUsername(), cfg.getPasswordMd5() != null && !cfg.getPasswordMd5().isBlank(), - cfg.getLockId() + cfg.getLockId(), + cfg.isTestSuccessful() )); } @@ -319,6 +320,12 @@ public class UserController { UUID userId = userOpt.get().getUserId(); TTLockUserConfigEntity cfg = ttLockUserConfigRepository.findById(userId) .orElseGet(() -> { TTLockUserConfigEntity n = new TTLockUserConfigEntity(); n.setUserId(userId); return n; }); + boolean credentialsChanged = !java.util.Objects.equals(cfg.getUsername(), body.username()) + || !java.util.Objects.equals(cfg.getLockId(), body.lockId()) + || (body.password() != null && !body.password().isBlank()); + if (credentialsChanged) { + cfg.setTestSuccessful(false); + } cfg.setUsername(body.username()); if (body.password() != null && !body.password().isBlank()) { cfg.setPasswordMd5(DigestUtils.md5DigestAsHex(body.password().getBytes(StandardCharsets.UTF_8))); @@ -357,6 +364,9 @@ public class UserController { return ResponseEntity.status(502).body(Map.of("error", "lock_detail_failed", "message", msg)); } + userCfg.setTestSuccessful(true); + ttLockUserConfigRepository.save(userCfg); + Map result = new LinkedHashMap<>(); result.put("lockId", detail.getLockId()); result.put("lockName", detail.getLockName()); diff --git a/xxxthegame/src/main/resources/femaleCB.png b/xxxthegame/src/main/resources/femaleCB.png deleted file mode 100644 index def74dc..0000000 Binary files a/xxxthegame/src/main/resources/femaleCB.png and /dev/null differ diff --git a/xxxthegame/src/main/resources/knebel.png b/xxxthegame/src/main/resources/knebel.png deleted file mode 100644 index 47c66fd..0000000 Binary files a/xxxthegame/src/main/resources/knebel.png and /dev/null differ diff --git a/xxxthegame/src/main/resources/maleCB.png b/xxxthegame/src/main/resources/maleCB.png deleted file mode 100644 index 13cfd7d..0000000 Binary files a/xxxthegame/src/main/resources/maleCB.png and /dev/null differ diff --git a/xxxthegame/src/main/resources/peitsche.png b/xxxthegame/src/main/resources/peitsche.png deleted file mode 100644 index 29f9950..0000000 Binary files a/xxxthegame/src/main/resources/peitsche.png and /dev/null differ diff --git a/xxxthegame/src/main/resources/plugs.png b/xxxthegame/src/main/resources/plugs.png deleted file mode 100644 index 0aa9d64..0000000 Binary files a/xxxthegame/src/main/resources/plugs.png and /dev/null differ diff --git a/xxxthegame/src/main/resources/static/abonnements.html b/xxxthegame/src/main/resources/static/abonnements.html index d17adf7..6e0c8cf 100644 --- a/xxxthegame/src/main/resources/static/abonnements.html +++ b/xxxthegame/src/main/resources/static/abonnements.html @@ -4,7 +4,7 @@ - Abonnements – XXX The Game + Abonnements – xXx Sphere + + +
+
+ +
+

📄 Impressum

+

Angaben gemäß § 5 TMG

+
+ +
+

Verantwortlich

+
+ Vorname Nachname
+ Musterstraße 1
+ 12345 Musterstadt
+ Deutschland +
+
+ +
+

Kontakt

+

+ E-Mail: kontakt@xxx-sphere.de +

+
+ +
+

Hinweis

+

+ xXx Sphere ist ein privat betriebenes Projekt ohne kommerzielle Absicht. + Die Plattform richtet sich ausschließlich an volljährige Personen. +

+
+ +
+

Haftungsausschluss

+

+ Trotz sorgfältiger inhaltlicher Kontrolle übernehmen wir keine Haftung für die Inhalte externer Links. + Für den Inhalt verlinkter Seiten sind ausschließlich deren Betreiber verantwortlich. +

+
+ +
+
+ + + + diff --git a/xxxthegame/src/main/resources/static/help/kontakt.html b/xxxthegame/src/main/resources/static/help/kontakt.html new file mode 100644 index 0000000..30a48b6 --- /dev/null +++ b/xxxthegame/src/main/resources/static/help/kontakt.html @@ -0,0 +1,265 @@ + + + + + + + Kontakt & Feedback – xXx Sphere + + + + + +
+
+ +
+

✉️ Kontakt & Feedback

+

Hast du Fragen, Ideen oder einen Fehler gefunden? Schreib uns!

+
+ +
+ Alternativ per E-Mail: Du kannst uns auch direkt schreiben – + kontakt@xxx-sphere.de +
+ + + +
+
+ + + + + diff --git a/xxxthegame/src/main/resources/static/help/overview.html b/xxxthegame/src/main/resources/static/help/overview.html new file mode 100644 index 0000000..247dda7 --- /dev/null +++ b/xxxthegame/src/main/resources/static/help/overview.html @@ -0,0 +1,221 @@ + + + + + + + Hilfe-Übersicht – xXx Sphere + + + + + +
+
+ +
+

❓ Hilfe-Übersicht

+

Hier findest du Anleitungen und Erklärungen zu allen Bereichen von xXx Sphere.

+
+ + + +
+
+
⚙️ Allgemeine Einstellungen
+
Profil, Benachrichtigungen, Datenschutz und weitere Kontoeinstellungen.
+ +
+
+
🔒 TTLock-Integration
+
Verbinde deine physische Schlüsselbox mit xXx Sphere für automatische Code-Verwaltung.
+ +
+
+
💳 Abonnements
+
Informationen zu Premium-Funktionen und wie du dein Abonnement verwaltest.
+ +
+
+ + + +
+
+
🔒 Chastity Game
+
Alles rund um Schlösser, Keyholder, Karten und Aufgaben im Chastity Game.
+ +
+
+
⛓️ BDSM Game
+
Sessions erstellen, Spieler einladen und Aufgaben verwalten.
+ +
+
+
⚪ Vanilla Game
+
Leichtere Spiele ohne strenge Regeln – für den entspannten Einstieg.
+ +
+
+ + + +
+
+
👥 Gruppen
+
Gruppen erstellen, beitreten und verwalten.
+ +
+
+
📰 Feed & Profil
+
Beiträge teilen, Profile entdecken und die Community kennenlernen.
+ +
+
+
🏆 Community Votes
+
Verifikationen bewerten und an Community-Abstimmungen teilnehmen.
+ +
+
+ + + +
+
+
🔐 Sicherheit & Datenschutz
+
Wie deine Daten gespeichert werden und welche Sicherheitsmaßnahmen wir treffen.
+ +
+
+
🐛 Fehler melden
+
Hast du einen Fehler gefunden oder einen Verbesserungsvorschlag?
+ +
+
+ +
+
+ + + + diff --git a/xxxthegame/src/main/resources/static/help/template.html b/xxxthegame/src/main/resources/static/help/template.html new file mode 100644 index 0000000..4ace6d8 --- /dev/null +++ b/xxxthegame/src/main/resources/static/help/template.html @@ -0,0 +1,345 @@ + + + + + + + SEITENTITEL – xXx Sphere + + + + + +
+
+ + +
+

🔒 SEITENTITEL

+

Kurze Beschreibung, worum es auf dieser Hilfeseite geht.

+
+ + +
+
+ 📖 Was ist das? + +
+
+

+ Hier steht ein einleitender Text. Du kannst mehrere Absätze verwenden, + um das Thema zu erklären. +

+

+ Zweiter Absatz mit weiteren Informationen. Links gehen so: + neues Lock starten. +

+ + +
+ Hinweis: Hier steht ein wichtiger, aber freundlicher Hinweis. +
+
+
+ + +
+
+ 🚀 So funktioniert es + +
+
+

Führe diese Schritte der Reihe nach aus:

+
    +
  1. + 1 + Erster Schritt – was der Nutzer hier tun muss. +
  2. +
  3. + 2 + Zweiter Schritt – weitere Aktion mit Erklärung. +
  4. +
  5. + 3 + Dritter Schritt – Abschluss oder Ergebnis. +
  6. +
+ + +
+ Achtung: Hier steht eine Warnung, z. B. dass eine Aktion nicht rückgängig gemacht werden kann. +
+
+
+ + +
+
+ 📋 Übersicht + +
+
+ + + + + + + + + + + + + + + + + + + + + +
FunktionBeschreibung
Beispiel AErklärung zu Funktion A.
Beispiel BErklärung zu Funktion B.
Beispiel CErklärung zu Funktion C.
+
+
+ + +
+
+ ❓ Häufige Frage 1? + +
+
+

+ Antwort auf die erste häufige Frage. Kann auch mehrere Absätze haben. +

+
+ Neutrale Info-Box für ergänzende Details ohne Wertung. +
+
+
+ +
+
+ ❓ Häufige Frage 2? + +
+
+

+ Antwort auf die zweite häufige Frage. +

+
+
+ +
+
+ + + + + + diff --git a/xxxthegame/src/main/resources/static/help/ttlock.html b/xxxthegame/src/main/resources/static/help/ttlock.html new file mode 100644 index 0000000..8a6956f --- /dev/null +++ b/xxxthegame/src/main/resources/static/help/ttlock.html @@ -0,0 +1,360 @@ + + + + + + + Hilfe TTLock – xXx Sphere + + + + + +
+
+ + +
+

🔒 TTLock

+

Hilfe zur Einrichtung der Kommunikation mit einer TTLock-Schlüsselbox

+
+ + +
+
+ 📖 Was ist das? + +
+
+

+ TTLock ist ein weit verbreitetes System für die Verwaltung von smarten Schlössern und Schlüsselboxen. Die Hardware kommuniziert in der Regel via Bluetooth, lässt sich aber über ein G2-Gateway auch aus der Ferne steuern. +

+

+ Für Entwickler und Unternehmen bietet die TTLock Open Platform eine leistungsstarke REST-API. Damit lässt sich die Schlossverwaltung in eigene Anwendungen integrieren. + Diese API verwenden wir, um die Codes deiner Schlüsselbox zu steuern - kein nerviges manuelles Eintragen des generierten Schlüssels mehr. +

+

+ TTLock steht allen Premium-Abonenten zur Verfügung. +

+
+
+ + +
+
+ 📋 Voraussetzungen + +
+
+
+ Achtung: Für die Verwendung ist zwingend ein G2-Gateway für die Kommunikation von TTLock-Server zu Deiner Schlüsselbox notwendig. +
+
+ Hinweis: Für die Verwendung einer TTLock-Schlüsselbox in Spielen ist zwingend ein Premium-Abonement notwendig. +
+
+
+ + +
+
+ 🚀 So funktioniert es + +
+
+

Führe diese Schritte der Reihe nach aus:

+
    +
  1. + 1 + App-Setup: Verbinde deine Schlüsselbox in der TTLock-App. Wichtig: Für die Fernsteuerung muss ein Gateway (G2) eingerichtet und aktiv sein. +
  2. +
  3. + 2 + Fernzugriff aktivieren: Aktiviere die Funktion in den App-Einstellungen. Tipp: Schalte das WLAN an deinem Handy aus und versuche, die Box über mobile Daten zu öffnen. Funktioniert das? Dann ist alles bereit. +
  4. +
  5. + 3 + Accounts verknüpfen: Trage deine TTLock-Zugangsdaten unter Einstellungen > TTLock ein. +
  6. +
  7. + 4 + Lock-ID hinterlegen: Gib die ID deiner Box an (zu finden unter MAC/ID). Wichtig: Nur den Teil hinter dem Schrägstrich nutzen (z.B. bei 00:11.../123456 nur 123456). +
  8. +
  9. + 5 + Verbindung testen: Klicke auf „Verbindung testen“. Erst nach einem grünen Licht ist das System aktiv. +
  10. +
+ + +
+ Hinweis: Wir speichern dein Passwort nicht im Klartext in der Datenbank sondern nur als MD5-Hash. +
+
+
+ + +
+
+ ❓ Warum steht dieser Dienst nur für Abonennten zur Verfügung? + +
+
+

+ Die Verwendung der API von TTLock ist nur begrenzt kostenlos verwendbar. Ab bestimmten Kontingenten wird die Verwendung für uns kostenpflichtig. +

+
+ Es gilt weiter der Grundsatz, XXX-Sphere soll niemanden reich machen - Die Abonemments dienen dazu die laufenden Kosten (Server, API-Schnittstellen etc.) zu decken. +
+
+
+ +
+
+ ❓ Hilfe - ich komme nicht mehr raus...Was machen Sachen? + +
+
+

+ Sollte sich der Schlüssel noch in der Box befinden und ihr nicht in einem aktiven Lock sein, besteht die Möglichkeit einen neuen Code für eine Notfallöffnung zu generieren: +

+ +
    +
  1. + 1 + Öffne die Einstellungen +
  2. +
  3. + 2 + Navigiere zum Bereich '🔒 TTLock' +
  4. +
  5. + 3 + Drücke '🔒 Öffnen' +
  6. +
+

+ Der temporäre Code zum Öffnen wird euch angezeigt - damit lässt sich die Box dann öffnen. +

+
+
+ +
+
+ + + + + + diff --git a/xxxthegame/src/main/resources/static/img/banner.png b/xxxthegame/src/main/resources/static/img/banner.png new file mode 100644 index 0000000..9f3671b Binary files /dev/null and b/xxxthegame/src/main/resources/static/img/banner.png differ diff --git a/xxxthegame/src/main/resources/static/index.html b/xxxthegame/src/main/resources/static/index.html index fcae3b8..60bd6de 100644 --- a/xxxthegame/src/main/resources/static/index.html +++ b/xxxthegame/src/main/resources/static/index.html @@ -3,7 +3,7 @@ - xXx Games + xXx Sphere diff --git a/xxxthegame/src/main/resources/static/infobdsm.html b/xxxthegame/src/main/resources/static/infobdsm.html index 697bc0a..3b0bcf4 100644 --- a/xxxthegame/src/main/resources/static/infobdsm.html +++ b/xxxthegame/src/main/resources/static/infobdsm.html @@ -4,7 +4,7 @@ - BDSM Game – Info – XXX The Game + BDSM Game – Info – xXx Sphere diff --git a/xxxthegame/src/main/resources/static/infochastity.html b/xxxthegame/src/main/resources/static/infochastity.html index 0f7c883..a08b00d 100644 --- a/xxxthegame/src/main/resources/static/infochastity.html +++ b/xxxthegame/src/main/resources/static/infochastity.html @@ -4,7 +4,7 @@ - Chastity Game – Info – XXX The Game + Chastity Game – Info – xXx Sphere diff --git a/xxxthegame/src/main/resources/static/infovanilla.html b/xxxthegame/src/main/resources/static/infovanilla.html index 49e6bd2..6976334 100644 --- a/xxxthegame/src/main/resources/static/infovanilla.html +++ b/xxxthegame/src/main/resources/static/infovanilla.html @@ -4,7 +4,7 @@ - Vanilla Game – Info – XXX The Game + Vanilla Game – Info – xXx Sphere diff --git a/xxxthegame/src/main/resources/static/joinlock.html b/xxxthegame/src/main/resources/static/joinlock.html index fcb813a..8b8cda6 100644 --- a/xxxthegame/src/main/resources/static/joinlock.html +++ b/xxxthegame/src/main/resources/static/joinlock.html @@ -4,7 +4,7 @@ - Lock-Einladung – XXX The Game + Lock-Einladung – xXx Sphere