Compare commits
38 Commits
Author | SHA1 | Date |
---|---|---|
Taah | 2e40ddc6bc | |
Telesphoreo | ff9cf12acc | |
Telesphoreo | 94528860f2 | |
Telesphoreo | c83f8f1d8e | |
Focusvity | 31cd561b92 | |
Telesphoreo | f0582e03e6 | |
Telesphoreo | 4e593e1b5e | |
Telesphoreo | 026b29a98c | |
Telesphoreo | 266a8d6384 | |
Telesphoreo | 21ee54cf98 | |
Telesphoreo | 492c6bd8eb | |
Telesphoreo | a7c76e6089 | |
Telesphoreo | 7a996004f0 | |
Telesphoreo | 46ff09bf58 | |
Telesphoreo | 4426c4b4b7 | |
Telesphoreo | fc8811d453 | |
Telesphoreo | 459f62e0d3 | |
Telesphoreo | 4918cf55f3 | |
Telesphoreo | e9395e193a | |
Telesphoreo | a257fb2f9c | |
Telesphoreo | fc9924754a | |
Telesphoreo | 867e3ff79b | |
Telesphoreo | 8bef589b7a | |
Allink | 5a0ae8746c | |
Telesphoreo | 41a2475e3d | |
Telesphoreo | 0bcbc7e79c | |
Telesphoreo | 95043a33db | |
Telesphoreo | 93619dd05e | |
Taah | 244d027e5d | |
Telesphoreo | ceea975729 | |
Telesphoreo | 32f17a23f3 | |
Telesphoreo | 1148ff5da9 | |
Telesphoreo | a0ae4a9720 | |
Telesphoreo | 82238fa3ed | |
Telesphoreo | 6e152417b7 | |
Telesphoreo | 22bb27af24 | |
Telesphoreo | 2b24f0ee4c | |
Telesphoreo | 7769f34f74 |
|
@ -0,0 +1,18 @@
|
||||||
|
name: Gradle
|
||||||
|
|
||||||
|
on: [ push ]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Set up JDK 17
|
||||||
|
uses: actions/setup-java@v2
|
||||||
|
with:
|
||||||
|
distribution: temurin
|
||||||
|
java-version: 17
|
||||||
|
cache: gradle
|
||||||
|
- name: Build with Gradle
|
||||||
|
run: chmod a+x gradlew && ./gradlew build --no-daemon
|
|
@ -0,0 +1,49 @@
|
||||||
|
<component name="ProjectCodeStyleConfiguration">
|
||||||
|
<code_scheme name="Plexus Code Style" version="1">
|
||||||
|
<JavaCodeStyleSettings>
|
||||||
|
<option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="20" />
|
||||||
|
<option name="IMPORT_LAYOUT_TABLE">
|
||||||
|
<value>
|
||||||
|
<package name="" withSubpackages="true" static="false" />
|
||||||
|
<package name="" withSubpackages="true" static="true" />
|
||||||
|
</value>
|
||||||
|
</option>
|
||||||
|
</JavaCodeStyleSettings>
|
||||||
|
<JetCodeStyleSettings>
|
||||||
|
<option name="PACKAGES_TO_USE_STAR_IMPORTS">
|
||||||
|
<value>
|
||||||
|
<package name="java.util" alias="false" withSubpackages="false" />
|
||||||
|
<package name="kotlinx.android.synthetic" alias="false" withSubpackages="true" />
|
||||||
|
<package name="io.ktor" alias="false" withSubpackages="true" />
|
||||||
|
</value>
|
||||||
|
</option>
|
||||||
|
<option name="PACKAGES_IMPORT_LAYOUT">
|
||||||
|
<value>
|
||||||
|
<package name="" alias="false" withSubpackages="true" />
|
||||||
|
<package name="java" alias="false" withSubpackages="true" />
|
||||||
|
<package name="javax" alias="false" withSubpackages="true" />
|
||||||
|
<package name="kotlin" alias="false" withSubpackages="true" />
|
||||||
|
<package name="" alias="true" withSubpackages="true" />
|
||||||
|
</value>
|
||||||
|
</option>
|
||||||
|
</JetCodeStyleSettings>
|
||||||
|
<codeStyleSettings language="JAVA">
|
||||||
|
<option name="BRACE_STYLE" value="2" />
|
||||||
|
<option name="CLASS_BRACE_STYLE" value="2" />
|
||||||
|
<option name="METHOD_BRACE_STYLE" value="2" />
|
||||||
|
<option name="LAMBDA_BRACE_STYLE" value="2" />
|
||||||
|
<option name="ELSE_ON_NEW_LINE" value="true" />
|
||||||
|
<option name="WHILE_ON_NEW_LINE" value="true" />
|
||||||
|
<option name="CATCH_ON_NEW_LINE" value="true" />
|
||||||
|
<option name="FINALLY_ON_NEW_LINE" value="true" />
|
||||||
|
<option name="SPACE_AFTER_TYPE_CAST" value="true" />
|
||||||
|
<option name="IF_BRACE_FORCE" value="3" />
|
||||||
|
<option name="DOWHILE_BRACE_FORCE" value="3" />
|
||||||
|
<option name="WHILE_BRACE_FORCE" value="3" />
|
||||||
|
<option name="FOR_BRACE_FORCE" value="3" />
|
||||||
|
<option name="BLANK_LINES_AFTER_CLASS_HEADER" value="0" />
|
||||||
|
<option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="1" />
|
||||||
|
<option name="KEEP_FIRST_COLUMN_COMMENT" value="false" />
|
||||||
|
</codeStyleSettings>
|
||||||
|
</code_scheme>
|
||||||
|
</component>
|
|
@ -0,0 +1,5 @@
|
||||||
|
<component name="ProjectCodeStyleConfiguration">
|
||||||
|
<state>
|
||||||
|
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Plexus Code Style" />
|
||||||
|
</state>
|
||||||
|
</component>
|
|
@ -0,0 +1,24 @@
|
||||||
|
For those who are wanting to contribute, we fully encourage doing so. There are a few rules we require following when contributing however.
|
||||||
|
|
||||||
|
## Steps
|
||||||
|
1. Make an issue and get feedback. It's important to know if your idea will be accepted before writing any code.
|
||||||
|
- If it is a feature request, describe the feature and be extremely specific.
|
||||||
|
- If it is a bug report, ensure you include how to reproduce the bug and the expected outcome
|
||||||
|
- If it is an enhancement, describe your proposed changes. Ensure you are extremely specific.
|
||||||
|
2. Fork this project
|
||||||
|
3. Create a new branch that describes the new feature, enhancement, or bug fix. For example, this is good: `feature/add-xyz`. This is bad: `fix-this-lol`.
|
||||||
|
4. Write the code that addresses your change.
|
||||||
|
- Keep in mind that it **must** be formatted correctly. If you are using IntelliJ, there is a `codeStyle.xml` file that tells IntelliJ how to format your code. Check this link for information on how to use the file: https://www.jetbrains.com/help/idea/configuring-code-style.html#import-export-schemes
|
||||||
|
- If you are not using IntelliJ, that is fine. We use the Plexus Code Style (which is almost the same as Allman) so please format your code accordingly.
|
||||||
|
6. Push your changes to your new branch and make a PR based off of that branch.
|
||||||
|
|
||||||
|
## Requirements for a PR
|
||||||
|
- The issue must be marked as approved
|
||||||
|
- It must only address each specific issue. Don't make one PR for multiple issues.
|
||||||
|
- Your PR must compile and work. If it does not compile or work, your PR will most likely be rejected.
|
||||||
|
|
||||||
|
## Code requirements
|
||||||
|
- Most importantly, your code must be efficient. Your pull request may be rejected if your code is deemed inefficient or sloppy.
|
||||||
|
- Do not repeat yourself. Create functions as needed if you're using large blocks of code over and over again.
|
||||||
|
- Do not use an excessive amount of commits when making your PR. It makes the master branch look messy.
|
||||||
|
- Your code must be consistent with Plex's codebase. If a function already exists, use it.
|
|
@ -1,2 +1,2 @@
|
||||||
# Module-HTTPD
|
# Module-HTTPD [![Build Status](https://ci.plex.us.org/job/Module-HTTPD/badge/icon)](https://ci.plex.us.org/job/Module-HTTPD/)
|
||||||
The HTTPD module for Plex
|
The HTTPD module for Plex
|
||||||
|
|
|
@ -5,71 +5,75 @@ plugins {
|
||||||
}
|
}
|
||||||
|
|
||||||
group = "dev.plex"
|
group = "dev.plex"
|
||||||
version = "1.0.2"
|
version = "1.4-SNAPSHOT"
|
||||||
description = "Module-HTTPD"
|
description = "Module-HTTPD"
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
|
|
||||||
maven {
|
maven {
|
||||||
url = uri("https://papermc.io/repo/repository/maven-public/")
|
url = uri("https://repo.papermc.io/repository/maven-public/")
|
||||||
}
|
}
|
||||||
|
|
||||||
maven {
|
maven {
|
||||||
url = uri("https://nexus.telesphoreo.me/repository/plex/")
|
url = uri("https://nexus.telesphoreo.me/repository/plex/")
|
||||||
}
|
}
|
||||||
|
|
||||||
maven {
|
|
||||||
url = uri("https://nexus.telesphoreo.me/repository/totalfreedom/")
|
|
||||||
}
|
|
||||||
maven {
|
maven {
|
||||||
url = uri("https://jitpack.io")
|
url = uri("https://jitpack.io")
|
||||||
|
content {
|
||||||
|
includeGroup("com.github.MilkBowl")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation("org.projectlombok:lombok:1.18.22")
|
implementation("org.projectlombok:lombok:1.18.30")
|
||||||
annotationProcessor("org.projectlombok:lombok:1.18.22")
|
annotationProcessor("org.projectlombok:lombok:1.18.30")
|
||||||
implementation("io.papermc.paper:paper-api:1.18.2-R0.1-SNAPSHOT")
|
implementation("io.papermc.paper:paper-api:1.20.4-R0.1-SNAPSHOT")
|
||||||
implementation("dev.plex:Plex:1.0.2-SNAPSHOT")
|
implementation("dev.plex:server:1.4-SNAPSHOT")
|
||||||
implementation("org.json:json:20220320")
|
implementation("org.json:json:20231013")
|
||||||
implementation("org.reflections:reflections:0.10.2")
|
implementation("org.reflections:reflections:0.10.2")
|
||||||
implementation("org.eclipse.jetty:jetty-server:11.0.9")
|
implementation("org.eclipse.jetty:jetty-server:11.0.19")
|
||||||
implementation("org.eclipse.jetty:jetty-servlet:11.0.9")
|
implementation("org.eclipse.jetty:jetty-servlet:11.0.19")
|
||||||
implementation("org.eclipse.jetty:jetty-proxy:11.0.9")
|
implementation("org.eclipse.jetty:jetty-proxy:11.0.19")
|
||||||
implementation("com.github.MilkBowl:VaultAPI:1.7")
|
implementation("com.github.MilkBowl:VaultAPI:1.7.1") {
|
||||||
|
exclude("org.bukkit", "bukkit")
|
||||||
|
}
|
||||||
|
implementation(platform("com.intellectualsites.bom:bom-newest:1.40")) // Ref: https://github.com/IntellectualSites/bom
|
||||||
|
compileOnly("com.fastasyncworldedit:FastAsyncWorldEdit-Core")
|
||||||
|
implementation("commons-io:commons-io:2.15.1")
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.getByName<Jar>("jar") {
|
||||||
|
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||||||
|
archiveBaseName.set("Module-HTTPD")
|
||||||
|
archiveVersion.set("")
|
||||||
|
from("src/main/resources") {
|
||||||
|
exclude("dev/**")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
java {
|
||||||
|
toolchain.languageVersion.set(JavaLanguageVersion.of(17))
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks {
|
tasks {
|
||||||
compileJava {
|
compileJava {
|
||||||
options.encoding = Charsets.UTF_8.name() // We want UTF-8 for everything
|
options.encoding = Charsets.UTF_8.name()
|
||||||
|
|
||||||
// Set the release flag. This configures what version bytecode the compiler will emit, as well as what JDK APIs are usable.
|
|
||||||
// See https://openjdk.java.net/jeps/247 for more information.
|
|
||||||
options.release.set(17)
|
|
||||||
}
|
}
|
||||||
javadoc {
|
javadoc {
|
||||||
options.encoding = Charsets.UTF_8.name() // We want UTF-8 for everything
|
options.encoding = Charsets.UTF_8.name()
|
||||||
}
|
}
|
||||||
processResources {
|
processResources {
|
||||||
filteringCharset = Charsets.UTF_8.name() // We want UTF-8 for everything
|
filteringCharset = Charsets.UTF_8.name()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
publishing {
|
publishing {
|
||||||
publications {
|
publications {
|
||||||
create<MavenPublication>("maven") {
|
create<MavenPublication>("maven") {
|
||||||
from(components["java"])
|
from(components["java"])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
tasks.getByName<Jar>("jar") {
|
|
||||||
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
|
||||||
archiveBaseName.set("Plex-HTTPD")
|
|
||||||
archiveVersion.set("")
|
|
||||||
from("src/main/resources") {
|
|
||||||
exclude("dev/**")
|
|
||||||
}
|
|
||||||
}
|
}
|
Binary file not shown.
|
@ -1,5 +1,7 @@
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
|
||||||
|
networkTimeout=10000
|
||||||
|
validateDistributionUrl=true
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
|
|
@ -55,7 +55,7 @@
|
||||||
# Darwin, MinGW, and NonStop.
|
# Darwin, MinGW, and NonStop.
|
||||||
#
|
#
|
||||||
# (3) This script is generated from the Groovy template
|
# (3) This script is generated from the Groovy template
|
||||||
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||||
# within the Gradle project.
|
# within the Gradle project.
|
||||||
#
|
#
|
||||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||||
|
@ -80,13 +80,11 @@ do
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
# This is normally unused
|
||||||
|
# shellcheck disable=SC2034
|
||||||
APP_NAME="Gradle"
|
|
||||||
APP_BASE_NAME=${0##*/}
|
APP_BASE_NAME=${0##*/}
|
||||||
|
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
|
||||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
|
||||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
|
||||||
|
|
||||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
MAX_FD=maximum
|
MAX_FD=maximum
|
||||||
|
@ -133,22 +131,29 @@ location of your Java installation."
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
JAVACMD=java
|
JAVACMD=java
|
||||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
if ! command -v java >/dev/null 2>&1
|
||||||
|
then
|
||||||
|
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
|
||||||
Please set the JAVA_HOME variable in your environment to match the
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
location of your Java installation."
|
location of your Java installation."
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Increase the maximum file descriptors if we can.
|
# Increase the maximum file descriptors if we can.
|
||||||
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||||
case $MAX_FD in #(
|
case $MAX_FD in #(
|
||||||
max*)
|
max*)
|
||||||
|
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
|
||||||
|
# shellcheck disable=SC3045
|
||||||
MAX_FD=$( ulimit -H -n ) ||
|
MAX_FD=$( ulimit -H -n ) ||
|
||||||
warn "Could not query maximum file descriptor limit"
|
warn "Could not query maximum file descriptor limit"
|
||||||
esac
|
esac
|
||||||
case $MAX_FD in #(
|
case $MAX_FD in #(
|
||||||
'' | soft) :;; #(
|
'' | soft) :;; #(
|
||||||
*)
|
*)
|
||||||
|
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
|
||||||
|
# shellcheck disable=SC3045
|
||||||
ulimit -n "$MAX_FD" ||
|
ulimit -n "$MAX_FD" ||
|
||||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||||
esac
|
esac
|
||||||
|
@ -193,6 +198,10 @@ if "$cygwin" || "$msys" ; then
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||||
|
|
||||||
# Collect all arguments for the java command;
|
# Collect all arguments for the java command;
|
||||||
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
|
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
|
||||||
# shell script including quotes and variable substitutions, so put them in
|
# shell script including quotes and variable substitutions, so put them in
|
||||||
|
@ -205,6 +214,12 @@ set -- \
|
||||||
org.gradle.wrapper.GradleWrapperMain \
|
org.gradle.wrapper.GradleWrapperMain \
|
||||||
"$@"
|
"$@"
|
||||||
|
|
||||||
|
# Stop when "xargs" is not available.
|
||||||
|
if ! command -v xargs >/dev/null 2>&1
|
||||||
|
then
|
||||||
|
die "xargs is not available"
|
||||||
|
fi
|
||||||
|
|
||||||
# Use "xargs" to parse quoted args.
|
# Use "xargs" to parse quoted args.
|
||||||
#
|
#
|
||||||
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
@rem limitations under the License.
|
@rem limitations under the License.
|
||||||
@rem
|
@rem
|
||||||
|
|
||||||
@if "%DEBUG%" == "" @echo off
|
@if "%DEBUG%"=="" @echo off
|
||||||
@rem ##########################################################################
|
@rem ##########################################################################
|
||||||
@rem
|
@rem
|
||||||
@rem Gradle startup script for Windows
|
@rem Gradle startup script for Windows
|
||||||
|
@ -25,7 +25,8 @@
|
||||||
if "%OS%"=="Windows_NT" setlocal
|
if "%OS%"=="Windows_NT" setlocal
|
||||||
|
|
||||||
set DIRNAME=%~dp0
|
set DIRNAME=%~dp0
|
||||||
if "%DIRNAME%" == "" set DIRNAME=.
|
if "%DIRNAME%"=="" set DIRNAME=.
|
||||||
|
@rem This is normally unused
|
||||||
set APP_BASE_NAME=%~n0
|
set APP_BASE_NAME=%~n0
|
||||||
set APP_HOME=%DIRNAME%
|
set APP_HOME=%DIRNAME%
|
||||||
|
|
||||||
|
@ -40,7 +41,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome
|
||||||
|
|
||||||
set JAVA_EXE=java.exe
|
set JAVA_EXE=java.exe
|
||||||
%JAVA_EXE% -version >NUL 2>&1
|
%JAVA_EXE% -version >NUL 2>&1
|
||||||
if "%ERRORLEVEL%" == "0" goto execute
|
if %ERRORLEVEL% equ 0 goto execute
|
||||||
|
|
||||||
echo.
|
echo.
|
||||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
@ -75,13 +76,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||||
|
|
||||||
:end
|
:end
|
||||||
@rem End local scope for the variables with windows NT shell
|
@rem End local scope for the variables with windows NT shell
|
||||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
if %ERRORLEVEL% equ 0 goto mainEnd
|
||||||
|
|
||||||
:fail
|
:fail
|
||||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||||
rem the _cmd.exe /c_ return code!
|
rem the _cmd.exe /c_ return code!
|
||||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
set EXIT_CODE=%ERRORLEVEL%
|
||||||
exit /b 1
|
if %EXIT_CODE% equ 0 set EXIT_CODE=1
|
||||||
|
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
|
||||||
|
exit /b %EXIT_CODE%
|
||||||
|
|
||||||
:mainEnd
|
:mainEnd
|
||||||
if "%OS%"=="Windows_NT" endlocal
|
if "%OS%"=="Windows_NT" endlocal
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package dev.plex;
|
package dev.plex;
|
||||||
|
|
||||||
|
import dev.plex.authentication.AuthenticationManager;
|
||||||
import dev.plex.cache.FileCache;
|
import dev.plex.cache.FileCache;
|
||||||
import dev.plex.config.ModuleConfig;
|
import dev.plex.config.ModuleConfig;
|
||||||
import dev.plex.module.PlexModule;
|
import dev.plex.module.PlexModule;
|
||||||
|
@ -7,25 +8,19 @@ import dev.plex.request.AbstractServlet;
|
||||||
import dev.plex.request.SchematicUploadServlet;
|
import dev.plex.request.SchematicUploadServlet;
|
||||||
import dev.plex.request.impl.*;
|
import dev.plex.request.impl.*;
|
||||||
import dev.plex.util.PlexLog;
|
import dev.plex.util.PlexLog;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
|
||||||
|
|
||||||
import jakarta.servlet.MultipartConfigElement;
|
import jakarta.servlet.MultipartConfigElement;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import net.milkbowl.vault.permission.Permission;
|
import net.milkbowl.vault.permission.Permission;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.plugin.RegisteredServiceProvider;
|
import org.bukkit.plugin.RegisteredServiceProvider;
|
||||||
import org.eclipse.jetty.server.Connector;
|
import org.eclipse.jetty.server.*;
|
||||||
import org.eclipse.jetty.server.ForwardedRequestCustomizer;
|
|
||||||
import org.eclipse.jetty.server.HttpConfiguration;
|
|
||||||
import org.eclipse.jetty.server.HttpConnectionFactory;
|
|
||||||
import org.eclipse.jetty.server.Server;
|
|
||||||
import org.eclipse.jetty.server.ServerConnector;
|
|
||||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||||
import org.eclipse.jetty.servlet.ServletHandler;
|
import org.eclipse.jetty.servlet.ServletHandler;
|
||||||
import org.eclipse.jetty.servlet.ServletHolder;
|
import org.eclipse.jetty.servlet.ServletHolder;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
public class HTTPDModule extends PlexModule
|
public class HTTPDModule extends PlexModule
|
||||||
{
|
{
|
||||||
public static ServletContextHandler context;
|
public static ServletContextHandler context;
|
||||||
|
@ -41,6 +36,8 @@ public class HTTPDModule extends PlexModule
|
||||||
|
|
||||||
public static final String template = AbstractServlet.readFileReal(HTTPDModule.class.getResourceAsStream("/httpd/template.html"));
|
public static final String template = AbstractServlet.readFileReal(HTTPDModule.class.getResourceAsStream("/httpd/template.html"));
|
||||||
|
|
||||||
|
private AuthenticationManager authenticationManager;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void load()
|
public void load()
|
||||||
{
|
{
|
||||||
|
@ -53,10 +50,22 @@ public class HTTPDModule extends PlexModule
|
||||||
{
|
{
|
||||||
moduleConfig.load();
|
moduleConfig.load();
|
||||||
PlexLog.debug("HTTPD Module Port: {0}", moduleConfig.getInt("server.port"));
|
PlexLog.debug("HTTPD Module Port: {0}", moduleConfig.getInt("server.port"));
|
||||||
if (!setupPermissions() && getPlex().getSystem().equalsIgnoreCase("permissions") && !Bukkit.getPluginManager().isPluginEnabled("Vault"))
|
if ((!Bukkit.getPluginManager().isPluginEnabled("Vault") || !setupPermissions()))
|
||||||
{
|
{
|
||||||
throw new RuntimeException("Plex-HTTPD requires the 'Vault' plugin as well as a Permissions plugin that hooks into 'Vault'. We recommend LuckPerms!");
|
throw new RuntimeException("Plex-HTTPD requires the 'Vault' plugin as well as a Permissions plugin that hooks into 'Vault'. We recommend LuckPerms!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.authenticationManager = new AuthenticationManager();
|
||||||
|
if (this.authenticationManager.provider() != null)
|
||||||
|
{
|
||||||
|
PlexLog.debug(this.authenticationManager.provider().generateLogin());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PlexLog.debug("Provider was not found for Authentication so disabled");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
serverThread = new Thread(() ->
|
serverThread = new Thread(() ->
|
||||||
{
|
{
|
||||||
Server server = new Server();
|
Server server = new Server();
|
||||||
|
@ -70,18 +79,21 @@ public class HTTPDModule extends PlexModule
|
||||||
connector.setHost(moduleConfig.getString("server.bind-address"));
|
connector.setHost(moduleConfig.getString("server.bind-address"));
|
||||||
connector.setPort(moduleConfig.getInt("server.port"));
|
connector.setPort(moduleConfig.getInt("server.port"));
|
||||||
|
|
||||||
new AdminsEndpoint();
|
|
||||||
new IndefBansEndpoint();
|
new IndefBansEndpoint();
|
||||||
new IndexEndpoint();
|
new IndexEndpoint();
|
||||||
new ListEndpoint();
|
new ListEndpoint();
|
||||||
new PunishmentsEndpoint();
|
new PunishmentsEndpoint();
|
||||||
|
new CommandsEndpoint();
|
||||||
new SchematicDownloadEndpoint();
|
new SchematicDownloadEndpoint();
|
||||||
new SchematicUploadEndpoint();
|
new SchematicUploadEndpoint();
|
||||||
|
|
||||||
ServletHolder uploadHolder = HTTPDModule.context.addServlet(SchematicUploadServlet.class, "/api/schematics/uploading");
|
ServletHolder uploadHolder = HTTPDModule.context.addServlet(SchematicUploadServlet.class, "/api/schematics/uploading");
|
||||||
|
|
||||||
File uploadLoc = new File(System.getProperty("java.io.tmpdir"), "schematic-temp-dir");
|
File uploadLoc = new File(System.getProperty("java.io.tmpdir"), "schematic-temp-dir");
|
||||||
if (!uploadLoc.exists()) uploadLoc.mkdirs();
|
if (!uploadLoc.exists())
|
||||||
|
{
|
||||||
|
uploadLoc.mkdirs();
|
||||||
|
}
|
||||||
uploadHolder.getRegistration().setMultipartConfig(new MultipartConfigElement(uploadLoc.getAbsolutePath(), 1024 * 1024 * 5, 1024 * 1024 * 25, 1024 * 1024));
|
uploadHolder.getRegistration().setMultipartConfig(new MultipartConfigElement(uploadLoc.getAbsolutePath(), 1024 * 1024 * 5, 1024 * 1024 * 25, 1024 * 1024));
|
||||||
|
|
||||||
server.setConnectors(new Connector[]{connector});
|
server.setConnectors(new Connector[]{connector});
|
||||||
|
@ -140,7 +152,7 @@ public class HTTPDModule extends PlexModule
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isFileSystemCaseSensitive = !new File( "a" ).equals( new File( "A" ) );
|
private static boolean isFileSystemCaseSensitive = !new File("a").equals(new File("A"));
|
||||||
|
|
||||||
public static boolean fileNameEquals(String filename1, String filename2)
|
public static boolean fileNameEquals(String filename1, String filename2)
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
package dev.plex.authentication;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
import java.time.ZonedDateTime;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Taah
|
||||||
|
* @since 6:37 PM [03-05-2024]
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Accessors(fluent = true)
|
||||||
|
public class AuthenticatedUser
|
||||||
|
{
|
||||||
|
private final String ip;
|
||||||
|
private final ZonedDateTime lastAuthenticated;
|
||||||
|
private final LinkedList<String> roles = Lists.newLinkedList();
|
||||||
|
private final UserType userType = UserType.UNKNOWN;
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
package dev.plex.authentication;
|
||||||
|
|
||||||
|
import dev.plex.HTTPDModule;
|
||||||
|
import dev.plex.authentication.impl.DiscordOAuth2Provider;
|
||||||
|
import dev.plex.util.PlexLog;
|
||||||
|
import org.apache.commons.lang3.NotImplementedException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Taah
|
||||||
|
* @since 7:08 PM [03-05-2024]
|
||||||
|
*/
|
||||||
|
public class AuthenticationManager
|
||||||
|
{
|
||||||
|
private final OAuth2Provider provider;
|
||||||
|
|
||||||
|
public AuthenticationManager()
|
||||||
|
{
|
||||||
|
final boolean enabled = HTTPDModule.moduleConfig.getBoolean("authentication.enabled", false);
|
||||||
|
if (!enabled)
|
||||||
|
{
|
||||||
|
provider = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
PlexLog.debug("[HTTPD] Auth is enabled");
|
||||||
|
|
||||||
|
final String providerName = HTTPDModule.moduleConfig.getString("authentication.provider.name", "");
|
||||||
|
if (providerName.isEmpty())
|
||||||
|
{
|
||||||
|
PlexLog.error("OAuth2 Authentication is enabled but no provider was given!");
|
||||||
|
provider = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
PlexLog.debug("[HTTPD] Provider name is {0}", providerName);
|
||||||
|
|
||||||
|
switch (providerName.toLowerCase())
|
||||||
|
{
|
||||||
|
case "discord" -> {
|
||||||
|
provider = new DiscordOAuth2Provider();
|
||||||
|
}
|
||||||
|
case "xenforo" -> {
|
||||||
|
throw new NotImplementedException("XenForo OAuth2 is not implemented yet!");
|
||||||
|
}
|
||||||
|
default -> {
|
||||||
|
provider = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PlexLog.log("Using {0} provider for authentication", providerName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public OAuth2Provider provider()
|
||||||
|
{
|
||||||
|
return this.provider;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
package dev.plex.authentication;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.server.Response;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Taah
|
||||||
|
* @since 6:36 PM [03-05-2024]
|
||||||
|
*/
|
||||||
|
public interface OAuth2Provider
|
||||||
|
{
|
||||||
|
HashMap<String, AuthenticatedUser> sessions();
|
||||||
|
|
||||||
|
AuthenticatedUser login(Response response, UserType type);
|
||||||
|
|
||||||
|
String[] roles(AuthenticatedUser user);
|
||||||
|
|
||||||
|
String generateLogin();
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
package dev.plex.authentication;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Taah
|
||||||
|
* @since 6:37 PM [03-05-2024]
|
||||||
|
*/
|
||||||
|
public enum UserType
|
||||||
|
{
|
||||||
|
DISCORD, UNKNOWN
|
||||||
|
}
|
|
@ -0,0 +1,81 @@
|
||||||
|
package dev.plex.authentication.impl;
|
||||||
|
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
import dev.plex.HTTPDModule;
|
||||||
|
import dev.plex.authentication.AuthenticatedUser;
|
||||||
|
import dev.plex.authentication.OAuth2Provider;
|
||||||
|
import dev.plex.authentication.UserType;
|
||||||
|
import dev.plex.util.PlexLog;
|
||||||
|
import org.eclipse.jetty.client.HttpClient;
|
||||||
|
import org.eclipse.jetty.server.Response;
|
||||||
|
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Taah
|
||||||
|
* @since 6:41 PM [03-05-2024]
|
||||||
|
*/
|
||||||
|
public class DiscordOAuth2Provider implements OAuth2Provider
|
||||||
|
{
|
||||||
|
private final HashMap<String, AuthenticatedUser> sessions = Maps.newHashMap();
|
||||||
|
|
||||||
|
private final String token;
|
||||||
|
private final String clientId;
|
||||||
|
private final String redirectUri;
|
||||||
|
|
||||||
|
public DiscordOAuth2Provider()
|
||||||
|
{
|
||||||
|
token = System.getenv("BOT_TOKEN").isEmpty() ? HTTPDModule.moduleConfig.getString("authentication.provider.discord.token", System.getProperty("BOT_TOKEN", "")) : System.getenv("BOT_TOKEN");
|
||||||
|
clientId = HTTPDModule.moduleConfig.getString("authentication.provider.discord.clientId", "");
|
||||||
|
redirectUri = URLEncoder.encode(HTTPDModule.moduleConfig.getString("authentication.provider.redirectUri", ""), StandardCharsets.UTF_8);
|
||||||
|
|
||||||
|
PlexLog.debug("[HTTPD] Client ID: {0}, Redirect URL: {1}", clientId, redirectUri);
|
||||||
|
|
||||||
|
if (redirectUri.isEmpty())
|
||||||
|
{
|
||||||
|
PlexLog.error("Provided authentication redirect url was empty for HTTPD!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (token.isEmpty())
|
||||||
|
{
|
||||||
|
PlexLog.error("Provided discord authentication token was empty for HTTPD!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clientId.isEmpty())
|
||||||
|
{
|
||||||
|
PlexLog.error("Provided discord client ID was empty for HTTPD!");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HashMap<String, AuthenticatedUser> sessions()
|
||||||
|
{
|
||||||
|
return sessions;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AuthenticatedUser login(Response response, UserType type)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String[] roles(AuthenticatedUser user)
|
||||||
|
{
|
||||||
|
return new String[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String generateLogin()
|
||||||
|
{
|
||||||
|
return String.format("https://discord.com/oauth2/authorize?client_id=%s&scope=%s&redirect_uri=%s",
|
||||||
|
clientId,
|
||||||
|
"identify%20guilds%20guilds.members.read",
|
||||||
|
redirectUri);
|
||||||
|
}
|
||||||
|
}
|
|
@ -98,6 +98,7 @@ public class AbstractServlet extends HttpServlet
|
||||||
base = base.replace("${ACTIVE_ADMINS}", "");
|
base = base.replace("${ACTIVE_ADMINS}", "");
|
||||||
base = base.replace("${ACTIVE_INDEFBANS}", "");
|
base = base.replace("${ACTIVE_INDEFBANS}", "");
|
||||||
base = base.replace("${ACTIVE_LIST}", "");
|
base = base.replace("${ACTIVE_LIST}", "");
|
||||||
|
base = base.replace("${ACTIVE_COMMANDS}", "");
|
||||||
base = base.replace("${ACTIVE_PUNISHMENTS}", "");
|
base = base.replace("${ACTIVE_PUNISHMENTS}", "");
|
||||||
base = base.replace("${ACTIVE_SCHEMATICS}", "");
|
base = base.replace("${ACTIVE_SCHEMATICS}", "");
|
||||||
base = base.replace("${CONTENT}", info[2]);
|
base = base.replace("${CONTENT}", info[2]);
|
||||||
|
|
|
@ -1,26 +1,27 @@
|
||||||
package dev.plex.request;
|
package dev.plex.request;
|
||||||
|
|
||||||
|
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat;
|
||||||
|
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats;
|
||||||
import dev.plex.HTTPDModule;
|
import dev.plex.HTTPDModule;
|
||||||
import dev.plex.Plex;
|
|
||||||
import dev.plex.cache.DataUtils;
|
import dev.plex.cache.DataUtils;
|
||||||
import dev.plex.player.PlexPlayer;
|
import dev.plex.player.PlexPlayer;
|
||||||
import dev.plex.rank.enums.Rank;
|
|
||||||
import dev.plex.util.PlexLog;
|
import dev.plex.util.PlexLog;
|
||||||
import jakarta.servlet.ServletException;
|
import jakarta.servlet.ServletException;
|
||||||
import jakarta.servlet.http.HttpServlet;
|
import jakarta.servlet.http.HttpServlet;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import jakarta.servlet.http.Part;
|
import jakarta.servlet.http.Part;
|
||||||
import java.io.File;
|
import org.apache.commons.io.FileUtils;
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.StandardCopyOption;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.OfflinePlayer;
|
import org.bukkit.OfflinePlayer;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
public class SchematicUploadServlet extends HttpServlet
|
public class SchematicUploadServlet extends HttpServlet
|
||||||
{
|
{
|
||||||
private static final Pattern schemNameMatcher = Pattern.compile("^[a-z0-9'!,_ -]{1,30}\\.schem(atic)?$", Pattern.CASE_INSENSITIVE);
|
private static final Pattern schemNameMatcher = Pattern.compile("^[a-z0-9'!,_ -]{1,30}\\.schem(atic)?$", Pattern.CASE_INSENSITIVE);
|
||||||
|
@ -39,24 +40,12 @@ public class SchematicUploadServlet extends HttpServlet
|
||||||
response.getWriter().println(schematicUploadBadHTML("Couldn't load your IP Address: " + request.getRemoteAddr() + ". Have you joined the server before?"));
|
response.getWriter().println(schematicUploadBadHTML("Couldn't load your IP Address: " + request.getRemoteAddr() + ". Have you joined the server before?"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (Plex.get().getSystem().equalsIgnoreCase("ranks"))
|
PlexLog.debug("Plex-HTTPD using permissions check");
|
||||||
|
final OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(plexPlayer.getUuid());
|
||||||
|
if (!HTTPDModule.getPermissions().playerHas(null, offlinePlayer, "plex.httpd.schematics.upload"))
|
||||||
{
|
{
|
||||||
PlexLog.debug("Plex-HTTPD using ranks check");
|
response.getWriter().println(schematicUploadBadHTML("You do not have permission to upload schematics."));
|
||||||
if (!plexPlayer.getRankFromString().isAtLeast(Rank.ADMIN))
|
return;
|
||||||
{
|
|
||||||
response.getWriter().println(schematicUploadBadHTML("You must be an admin or above to upload schematics."));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (Plex.get().getSystem().equalsIgnoreCase("permissions"))
|
|
||||||
{
|
|
||||||
PlexLog.debug("Plex-HTTPD using permissions check");
|
|
||||||
final OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(plexPlayer.getUuid());
|
|
||||||
if (!HTTPDModule.getPermissions().playerHas(null, offlinePlayer, "plex.httpd.schematics.upload"))
|
|
||||||
{
|
|
||||||
response.getWriter().println(schematicUploadBadHTML("You do not have permission to upload schematics."));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
File worldeditFolder = HTTPDModule.getWorldeditFolder();
|
File worldeditFolder = HTTPDModule.getWorldeditFolder();
|
||||||
if (worldeditFolder == null)
|
if (worldeditFolder == null)
|
||||||
|
@ -88,9 +77,31 @@ public class SchematicUploadServlet extends HttpServlet
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
InputStream inputStream = uploadPart.getInputStream();
|
InputStream inputStream = uploadPart.getInputStream();
|
||||||
Files.copy(inputStream, new File(worldeditFolder, filename).toPath(), StandardCopyOption.REPLACE_EXISTING);
|
File schematicFile = new File(worldeditFolder, filename);
|
||||||
|
FileUtils.copyInputStreamToFile(inputStream, schematicFile);
|
||||||
|
ClipboardFormat schematicFormat = ClipboardFormats.findByFile(schematicFile);
|
||||||
|
if (schematicFormat == null)
|
||||||
|
{
|
||||||
|
PlexLog.log("IP Address: " + request.getRemoteAddr() + " FAILED to upload schematic with filename: " + filename);
|
||||||
|
response.getWriter().println(schematicUploadBadHTML("Schematic is not a valid format."));
|
||||||
|
FileUtils.deleteQuietly(schematicFile);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
schematicFormat.getReader(new FileInputStream(schematicFile));
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
PlexLog.log("IP Address: " + request.getRemoteAddr() + " FAILED to upload schematic with filename: " + filename);
|
||||||
|
response.getWriter().println(schematicUploadBadHTML("Schematic is not a valid format."));
|
||||||
|
FileUtils.deleteQuietly(schematicFile);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Files.copy(inputStream, schematic.toPath(), StandardCopyOption.REPLACE_EXISTING);
|
||||||
inputStream.close();
|
inputStream.close();
|
||||||
response.getWriter().println(schematicUploadGoodHTML("Successfully uploaded <b>" + filename + "."));
|
response.getWriter().println(schematicUploadGoodHTML("Successfully uploaded <b>" + filename + "</b>."));
|
||||||
|
PlexLog.log("IP Address: " + request.getRemoteAddr() + " uploaded schematic with filename: " + filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String schematicUploadBadHTML(String message)
|
private String schematicUploadBadHTML(String message)
|
||||||
|
|
|
@ -1,69 +0,0 @@
|
||||||
package dev.plex.request.impl;
|
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
|
||||||
import com.google.gson.GsonBuilder;
|
|
||||||
import dev.plex.HTTPDModule;
|
|
||||||
import dev.plex.Plex;
|
|
||||||
import dev.plex.cache.DataUtils;
|
|
||||||
import dev.plex.player.PlexPlayer;
|
|
||||||
import dev.plex.rank.enums.Rank;
|
|
||||||
import dev.plex.request.AbstractServlet;
|
|
||||||
import dev.plex.request.GetMapping;
|
|
||||||
import dev.plex.util.PlexLog;
|
|
||||||
import dev.plex.util.adapter.ZonedDateTimeSerializer;
|
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.time.ZonedDateTime;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.OfflinePlayer;
|
|
||||||
|
|
||||||
public class AdminsEndpoint extends AbstractServlet
|
|
||||||
{
|
|
||||||
private static final String TITLE = "Admins - Plex HTTPD";
|
|
||||||
|
|
||||||
@GetMapping(endpoint = "/api/admins/")
|
|
||||||
public String getAdmins(HttpServletRequest request, HttpServletResponse response)
|
|
||||||
{
|
|
||||||
String ipAddress = request.getRemoteAddr();
|
|
||||||
if (ipAddress == null)
|
|
||||||
{
|
|
||||||
return adminsHTML("An IP address could not be detected. Please ensure you are connecting using IPv4.");
|
|
||||||
}
|
|
||||||
final PlexPlayer player = DataUtils.getPlayerByIP(ipAddress);
|
|
||||||
if (player == null)
|
|
||||||
{
|
|
||||||
// This likely means they've never joined the server before. That's okay. We can just not return IPs.
|
|
||||||
return new GsonBuilder().registerTypeAdapter(ZonedDateTime.class, new ZonedDateTimeSerializer()).setPrettyPrinting().create().toJson(Plex.get().getAdminList().getAllAdminPlayers().stream().peek(plexPlayer -> plexPlayer.setIps(Lists.newArrayList())).peek(plexPlayer -> plexPlayer.setPunishments(Lists.newArrayList())).collect(Collectors.toList()));
|
|
||||||
}
|
|
||||||
if (Plex.get().getSystem().equalsIgnoreCase("ranks"))
|
|
||||||
{
|
|
||||||
PlexLog.debug("Plex-HTTPD using ranks check");
|
|
||||||
if (!player.getRankFromString().isAtLeast(Rank.ADMIN))
|
|
||||||
{
|
|
||||||
// Don't return IPs either if the person is not an Admin or above.
|
|
||||||
return new GsonBuilder().registerTypeAdapter(ZonedDateTime.class, new ZonedDateTimeSerializer()).setPrettyPrinting().create().toJson(Plex.get().getAdminList().getAllAdminPlayers().stream().peek(plexPlayer -> plexPlayer.setIps(Lists.newArrayList())).peek(plexPlayer -> plexPlayer.setPunishments(Lists.newArrayList())).collect(Collectors.toList()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (Plex.get().getSystem().equalsIgnoreCase("permissions"))
|
|
||||||
{
|
|
||||||
PlexLog.debug("Plex-HTTPD using permissions check");
|
|
||||||
final OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(player.getUuid());
|
|
||||||
if (!HTTPDModule.getPermissions().playerHas(null, offlinePlayer, "plex.httpd.admins.access"))
|
|
||||||
{
|
|
||||||
// If the person doesn't have permission, don't return IPs
|
|
||||||
return new GsonBuilder().registerTypeAdapter(ZonedDateTime.class, new ZonedDateTimeSerializer()).setPrettyPrinting().create().toJson(Plex.get().getAdminList().getAllAdminPlayers().stream().peek(plexPlayer -> plexPlayer.setIps(Lists.newArrayList())).peek(plexPlayer -> plexPlayer.setPunishments(Lists.newArrayList())).collect(Collectors.toList()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new GsonBuilder().registerTypeAdapter(ZonedDateTime.class, new ZonedDateTimeSerializer()).setPrettyPrinting().create().toJson(Plex.get().getAdminList().getAllAdminPlayers());
|
|
||||||
}
|
|
||||||
|
|
||||||
private String adminsHTML(String message)
|
|
||||||
{
|
|
||||||
String file = readFile(this.getClass().getResourceAsStream("/httpd/admins.html"));
|
|
||||||
file = file.replace("${MESSAGE}", message);
|
|
||||||
return file;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
package dev.plex.request.impl;
|
||||||
|
|
||||||
|
import dev.plex.command.PlexCommand;
|
||||||
|
import dev.plex.command.annotation.CommandPermissions;
|
||||||
|
import dev.plex.request.AbstractServlet;
|
||||||
|
import dev.plex.request.GetMapping;
|
||||||
|
import dev.plex.util.PlexLog;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.command.Command;
|
||||||
|
import org.bukkit.command.CommandMap;
|
||||||
|
import org.bukkit.command.PluginIdentifiableCommand;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class AuthenticationEndpoint extends AbstractServlet
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
@GetMapping(endpoint = "/oauth2")
|
||||||
|
public String login(HttpServletRequest request, HttpServletResponse response)
|
||||||
|
{
|
||||||
|
// TODO: Nuh uh
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,111 @@
|
||||||
|
package dev.plex.request.impl;
|
||||||
|
|
||||||
|
import dev.plex.command.PlexCommand;
|
||||||
|
import dev.plex.command.annotation.CommandPermissions;
|
||||||
|
import dev.plex.request.AbstractServlet;
|
||||||
|
import dev.plex.request.GetMapping;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.SortedMap;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.command.Command;
|
||||||
|
import org.bukkit.command.CommandMap;
|
||||||
|
import org.bukkit.command.PluginIdentifiableCommand;
|
||||||
|
|
||||||
|
public class CommandsEndpoint extends AbstractServlet
|
||||||
|
{
|
||||||
|
|
||||||
|
private final StringBuilder list = new StringBuilder();
|
||||||
|
private boolean loadedCommands = false;
|
||||||
|
|
||||||
|
@GetMapping(endpoint = "/api/commands/")
|
||||||
|
public String getCommands(HttpServletRequest request, HttpServletResponse response)
|
||||||
|
{
|
||||||
|
if (!loadedCommands)
|
||||||
|
{
|
||||||
|
final SortedMap<String, List<Command>> commandMap = new TreeMap<>();
|
||||||
|
final CommandMap map = Bukkit.getCommandMap();
|
||||||
|
for (Command command : map.getKnownCommands().values())
|
||||||
|
{
|
||||||
|
String plugin = "Bukkit";
|
||||||
|
if (command instanceof PluginIdentifiableCommand)
|
||||||
|
{
|
||||||
|
plugin = ((PluginIdentifiableCommand) command).getPlugin().getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Command> pluginCommands = commandMap.computeIfAbsent(plugin, k -> new ArrayList<>());
|
||||||
|
if (!pluginCommands.contains(command))
|
||||||
|
{
|
||||||
|
pluginCommands.add(command);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (String key : commandMap.keySet())
|
||||||
|
{
|
||||||
|
commandMap.get(key).sort(Comparator.comparing(Command::getName));
|
||||||
|
StringBuilder rows = new StringBuilder();
|
||||||
|
for (Command command : commandMap.get(key))
|
||||||
|
{
|
||||||
|
String permission = command.getPermission();
|
||||||
|
if (command instanceof PlexCommand plexCmd)
|
||||||
|
{
|
||||||
|
CommandPermissions perms = plexCmd.getClass().getAnnotation(CommandPermissions.class);
|
||||||
|
if (perms != null)
|
||||||
|
{
|
||||||
|
permission = (perms.permission().isBlank() ? "N/A" : perms.permission());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rows.append(createRow(command.getName(), command.getAliases(), command.getDescription(), command.getUsage(), permission));
|
||||||
|
}
|
||||||
|
|
||||||
|
list.append(createTable(key, rows.toString())).append("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
loadedCommands = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return commandsHTML(list.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
private String commandsHTML(String commandsList)
|
||||||
|
{
|
||||||
|
String file = readFile(this.getClass().getResourceAsStream("/httpd/commands.html"));
|
||||||
|
file = file.replace("${commands}", commandsList);
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String createTable(String pluginName, String commandRows)
|
||||||
|
{
|
||||||
|
return "<details id=\"" + pluginName + "\"><summary>" + pluginName + "</summary>\n"
|
||||||
|
+ "<table id=\"" + pluginName + "Table\" class=\"table table-striped table-bordered\">\n"
|
||||||
|
+ " <thead>\n <tr>\n <th scope=\"col\">Name (Aliases)</th>\n "
|
||||||
|
+ "<th scope=\"col\">Description</th>\n "
|
||||||
|
+ "<th scope=\"col\">Usage</th>\n "
|
||||||
|
+ "<th scope=\"col\">Permission</th>\n </tr>\n</thead>\n"
|
||||||
|
+ "<tbody>\n " + commandRows + "\n</tbody>\n</table>\n</details>";
|
||||||
|
}
|
||||||
|
|
||||||
|
private String createRow(String name, List<String> aliases, String description, String usage, String permission)
|
||||||
|
{
|
||||||
|
return " <tr>\n <th scope=\"row\">" + name
|
||||||
|
+ (aliases.isEmpty() || aliases.toString().equals("[]") ? "" : " (" + String.join(", ", aliases) + ")") + "</th>\n"
|
||||||
|
+ " <th scope=\"row\">" + description + "</th>\n"
|
||||||
|
+ " <th scope=\"row\"><code>" + cleanUsage(usage) + "</code></th>\n"
|
||||||
|
+ " <th scope=\"row\">" + (permission != null ? permission.replaceAll(";", "<br>") : "N/A") + "</th>\n </tr>";
|
||||||
|
}
|
||||||
|
|
||||||
|
private String cleanUsage(String usage)
|
||||||
|
{
|
||||||
|
usage = usage.replaceAll("<", "<").replaceAll(">", ">");
|
||||||
|
if (usage.isBlank())
|
||||||
|
{
|
||||||
|
usage = "Not Provided";
|
||||||
|
}
|
||||||
|
return usage.startsWith("/") || usage.equals("Not Provided") ? usage : "/" + usage;
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,7 +5,6 @@ import dev.plex.HTTPDModule;
|
||||||
import dev.plex.Plex;
|
import dev.plex.Plex;
|
||||||
import dev.plex.cache.DataUtils;
|
import dev.plex.cache.DataUtils;
|
||||||
import dev.plex.player.PlexPlayer;
|
import dev.plex.player.PlexPlayer;
|
||||||
import dev.plex.rank.enums.Rank;
|
|
||||||
import dev.plex.request.AbstractServlet;
|
import dev.plex.request.AbstractServlet;
|
||||||
import dev.plex.request.GetMapping;
|
import dev.plex.request.GetMapping;
|
||||||
import dev.plex.util.PlexLog;
|
import dev.plex.util.PlexLog;
|
||||||
|
@ -31,23 +30,14 @@ public class IndefBansEndpoint extends AbstractServlet
|
||||||
{
|
{
|
||||||
return indefbansHTML("Couldn't load your IP Address: " + ipAddress + ". Have you joined the server before?");
|
return indefbansHTML("Couldn't load your IP Address: " + ipAddress + ". Have you joined the server before?");
|
||||||
}
|
}
|
||||||
if (Plex.get().getSystem().equalsIgnoreCase("ranks"))
|
PlexLog.debug("Plex-HTTPD using permissions check");
|
||||||
|
final OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(player.getUuid());
|
||||||
|
if (!HTTPDModule.getPermissions().playerHas(null, offlinePlayer, "plex.httpd.indefbans.access"))
|
||||||
{
|
{
|
||||||
PlexLog.debug("Plex-HTTPD using ranks check");
|
return indefbansHTML("Not enough permissions to view this page.");
|
||||||
if (!player.getRankFromString().isAtLeast(Rank.ADMIN))
|
|
||||||
{
|
|
||||||
return indefbansHTML("Not a high enough rank to view this page.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (Plex.get().getSystem().equalsIgnoreCase("permissions"))
|
|
||||||
{
|
|
||||||
PlexLog.debug("Plex-HTTPD using permissions check");
|
|
||||||
final OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(player.getUuid());
|
|
||||||
if (!HTTPDModule.getPermissions().playerHas(null, offlinePlayer, "plex.httpd.indefbans.access"))
|
|
||||||
{
|
|
||||||
return indefbansHTML("Not enough permissions to view this page.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
response.setHeader("content-type", "application/json");
|
||||||
return new GsonBuilder().setPrettyPrinting().create().toJson(Plex.get().getPunishmentManager().getIndefiniteBans().stream().toList());
|
return new GsonBuilder().setPrettyPrinting().create().toJson(Plex.get().getPunishmentManager().getIndefiniteBans().stream().toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ package dev.plex.request.impl;
|
||||||
import com.google.gson.GsonBuilder;
|
import com.google.gson.GsonBuilder;
|
||||||
import dev.plex.request.AbstractServlet;
|
import dev.plex.request.AbstractServlet;
|
||||||
import dev.plex.request.GetMapping;
|
import dev.plex.request.GetMapping;
|
||||||
|
import dev.plex.request.MappingHeaders;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -14,6 +15,7 @@ import org.bukkit.entity.Player;
|
||||||
public class ListEndpoint extends AbstractServlet
|
public class ListEndpoint extends AbstractServlet
|
||||||
{
|
{
|
||||||
@GetMapping(endpoint = "/api/list/")
|
@GetMapping(endpoint = "/api/list/")
|
||||||
|
@MappingHeaders(headers = "content-type;application/json")
|
||||||
public String getOnlinePlayers(HttpServletRequest request, HttpServletResponse response)
|
public String getOnlinePlayers(HttpServletRequest request, HttpServletResponse response)
|
||||||
{
|
{
|
||||||
List<String> players = new ArrayList<>();
|
List<String> players = new ArrayList<>();
|
||||||
|
|
|
@ -2,20 +2,15 @@ package dev.plex.request.impl;
|
||||||
|
|
||||||
import com.google.gson.GsonBuilder;
|
import com.google.gson.GsonBuilder;
|
||||||
import dev.plex.HTTPDModule;
|
import dev.plex.HTTPDModule;
|
||||||
import dev.plex.Plex;
|
|
||||||
import dev.plex.cache.DataUtils;
|
import dev.plex.cache.DataUtils;
|
||||||
import dev.plex.player.PlexPlayer;
|
import dev.plex.player.PlexPlayer;
|
||||||
import dev.plex.rank.enums.Rank;
|
|
||||||
import dev.plex.request.AbstractServlet;
|
import dev.plex.request.AbstractServlet;
|
||||||
import dev.plex.request.GetMapping;
|
import dev.plex.request.GetMapping;
|
||||||
import dev.plex.util.PlexLog;
|
import dev.plex.util.adapter.ZonedDateTimeAdapter;
|
||||||
import dev.plex.util.adapter.ZonedDateTimeSerializer;
|
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import java.time.LocalDateTime;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.OfflinePlayer;
|
import org.bukkit.OfflinePlayer;
|
||||||
|
|
||||||
|
@ -59,28 +54,17 @@ public class PunishmentsEndpoint extends AbstractServlet
|
||||||
if (player == null)
|
if (player == null)
|
||||||
{
|
{
|
||||||
// If the player is null, give it to them without the IPs
|
// If the player is null, give it to them without the IPs
|
||||||
return new GsonBuilder().registerTypeAdapter(ZonedDateTime.class, new ZonedDateTimeSerializer()).setPrettyPrinting().create().toJson(punishedPlayer.getPunishments().stream().peek(punishment -> punishment.setIp("")).toList());
|
return new GsonBuilder().registerTypeAdapter(ZonedDateTime.class, new ZonedDateTimeAdapter()).setPrettyPrinting().create().toJson(punishedPlayer.getPunishments().stream().peek(punishment -> punishment.setIp("")).toList());
|
||||||
}
|
}
|
||||||
if (Plex.get().getSystem().equalsIgnoreCase("ranks"))
|
final OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(player.getUuid());
|
||||||
|
if (!HTTPDModule.getPermissions().playerHas(null, offlinePlayer, "plex.httpd.punishments.access"))
|
||||||
{
|
{
|
||||||
PlexLog.debug("Plex-HTTPD using ranks check");
|
// If the person doesn't have permission, don't return IPs
|
||||||
if (!player.getRankFromString().isAtLeast(Rank.ADMIN))
|
return new GsonBuilder().registerTypeAdapter(ZonedDateTime.class, new ZonedDateTimeAdapter()).setPrettyPrinting().create().toJson(punishedPlayer.getPunishments().stream().peek(punishment -> punishment.setIp("")).toList());
|
||||||
{
|
|
||||||
// Don't return IPs either if the person is not an Admin or above.
|
|
||||||
return new GsonBuilder().registerTypeAdapter(ZonedDateTime.class, new ZonedDateTimeSerializer()).setPrettyPrinting().create().toJson(punishedPlayer.getPunishments().stream().peek(punishment -> punishment.setIp("")).toList());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (Plex.get().getSystem().equalsIgnoreCase("permissions"))
|
|
||||||
{
|
response.setHeader("content-type", "application/json");
|
||||||
PlexLog.debug("Plex-HTTPD using permissions check");
|
return new GsonBuilder().registerTypeAdapter(ZonedDateTime.class, new ZonedDateTimeAdapter()).setPrettyPrinting().create().toJson(punishedPlayer.getPunishments().stream().toList());
|
||||||
final OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(player.getUuid());
|
|
||||||
if (!HTTPDModule.getPermissions().playerHas(null, offlinePlayer, "plex.httpd.punishments.access"))
|
|
||||||
{
|
|
||||||
// If the person doesn't have permission, don't return IPs
|
|
||||||
return new GsonBuilder().registerTypeAdapter(ZonedDateTime.class, new ZonedDateTimeSerializer()).setPrettyPrinting().create().toJson(punishedPlayer.getPunishments().stream().peek(punishment -> punishment.setIp("")).toList());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new GsonBuilder().registerTypeAdapter(ZonedDateTime.class, new ZonedDateTimeSerializer()).setPrettyPrinting().create().toJson(punishedPlayer.getPunishments().stream().toList());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String punishmentsHTML(String message)
|
private String punishmentsHTML(String message)
|
||||||
|
|
|
@ -3,15 +3,21 @@ package dev.plex.request.impl;
|
||||||
import dev.plex.HTTPDModule;
|
import dev.plex.HTTPDModule;
|
||||||
import dev.plex.request.AbstractServlet;
|
import dev.plex.request.AbstractServlet;
|
||||||
import dev.plex.request.GetMapping;
|
import dev.plex.request.GetMapping;
|
||||||
|
import dev.plex.util.PlexLog;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class SchematicDownloadEndpoint extends AbstractServlet
|
public class SchematicDownloadEndpoint extends AbstractServlet
|
||||||
{
|
{
|
||||||
|
List<File> files = new ArrayList<>();
|
||||||
|
|
||||||
@GetMapping(endpoint = "/api/schematics/download/")
|
@GetMapping(endpoint = "/api/schematics/download/")
|
||||||
public String downloadSchematic(HttpServletRequest request, HttpServletResponse response)
|
public String downloadSchematic(HttpServletRequest request, HttpServletResponse response)
|
||||||
{
|
{
|
||||||
|
@ -72,20 +78,35 @@ public class SchematicDownloadEndpoint extends AbstractServlet
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
File[] alphabetical = worldeditFolder.listFiles();
|
for (File worldeditFile : listFilesForFolder(worldeditFolder))
|
||||||
if (alphabetical != null)
|
|
||||||
{
|
{
|
||||||
Arrays.sort(alphabetical);
|
String fixedPath = worldeditFile.getPath().replace("plugins/FastAsyncWorldEdit/schematics/", "");
|
||||||
for (File worldeditFile : alphabetical)
|
fixedPath = fixedPath.replace("plugins/WorldEdit/schematics/", "");
|
||||||
{
|
String sanitizedName = fixedPath.replaceAll("<", "<").replaceAll(">", ">");
|
||||||
String sanitizedName = worldeditFile.getName().replaceAll("<","<").replaceAll(">",">");
|
sb.append(" <tr>\n" +
|
||||||
sb.append("<tr>" +
|
" <th scope=\"row\">\n <a href=\"" + fixedPath + "\" download>" + sanitizedName + "</a>\n </th>\n" +
|
||||||
"<th scope=\"row\"><a href=\"" + worldeditFile.getName() + "\" download>" + sanitizedName + "</a></th>" +
|
" <td>\n " + formattedSize(worldeditFile.length()) + "\n </td>\n" +
|
||||||
"<td>" + formattedSize(worldeditFile.length()) + "</td>" +
|
" </tr>\n");
|
||||||
"</tr>");
|
|
||||||
}
|
|
||||||
file = file.replace("${schematics}", sb.toString());
|
|
||||||
}
|
}
|
||||||
|
file = file.replace("${schematics}", sb.toString());
|
||||||
|
files.clear();
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<File> listFilesForFolder(final File folder)
|
||||||
|
{
|
||||||
|
for (File fileEntry : folder.listFiles())
|
||||||
|
{
|
||||||
|
if (fileEntry.isDirectory())
|
||||||
|
{
|
||||||
|
PlexLog.debug("Found directory");
|
||||||
|
listFilesForFolder(fileEntry);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
files.add(fileEntry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return files;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
package dev.plex.request.impl;
|
package dev.plex.request.impl;
|
||||||
|
|
||||||
import dev.plex.HTTPDModule;
|
import dev.plex.HTTPDModule;
|
||||||
import dev.plex.Plex;
|
|
||||||
import dev.plex.cache.DataUtils;
|
import dev.plex.cache.DataUtils;
|
||||||
import dev.plex.player.PlexPlayer;
|
import dev.plex.player.PlexPlayer;
|
||||||
import dev.plex.rank.enums.Rank;
|
|
||||||
import dev.plex.request.AbstractServlet;
|
import dev.plex.request.AbstractServlet;
|
||||||
import dev.plex.request.GetMapping;
|
import dev.plex.request.GetMapping;
|
||||||
import dev.plex.util.PlexLog;
|
import dev.plex.util.PlexLog;
|
||||||
|
@ -28,22 +26,11 @@ public class SchematicUploadEndpoint extends AbstractServlet
|
||||||
{
|
{
|
||||||
return schematicsHTML("Couldn't load your IP Address: " + ipAddress + ". Have you joined the server before?");
|
return schematicsHTML("Couldn't load your IP Address: " + ipAddress + ". Have you joined the server before?");
|
||||||
}
|
}
|
||||||
if (Plex.get().getSystem().equalsIgnoreCase("ranks"))
|
PlexLog.debug("Plex-HTTPD using permissions check");
|
||||||
|
final OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(player.getUuid());
|
||||||
|
if (!HTTPDModule.getPermissions().playerHas(null, offlinePlayer, "plex.httpd.schematics.upload"))
|
||||||
{
|
{
|
||||||
PlexLog.debug("Plex-HTTPD using ranks check");
|
return schematicsHTML("You do not have permission to upload schematics.");
|
||||||
if (!player.getRankFromString().isAtLeast(Rank.ADMIN))
|
|
||||||
{
|
|
||||||
return schematicsHTML("You must be an admin or above to upload schematics.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (Plex.get().getSystem().equalsIgnoreCase("permissions"))
|
|
||||||
{
|
|
||||||
PlexLog.debug("Plex-HTTPD using permissions check");
|
|
||||||
final OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(player.getUuid());
|
|
||||||
if (!HTTPDModule.getPermissions().playerHas(null, offlinePlayer, "plex.httpd.schematics.upload"))
|
|
||||||
{
|
|
||||||
return schematicsHTML("You do not have permission to upload schematics.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return readFile(this.getClass().getResourceAsStream("/httpd/schematic_upload.html"));
|
return readFile(this.getClass().getResourceAsStream("/httpd/schematic_upload.html"));
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,18 +2,21 @@
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet"
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/css/bootstrap.min.css" rel="stylesheet"
|
||||||
integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
|
integrity="sha384-KK94CHFLLe+nY2dmCWGMq91rCGa5gtU4mk92HdvYe+M/SXH301p5ILy+dN9+nJOZ" crossorigin="anonymous">
|
||||||
<script type="text/javascript"
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/js/bootstrap.bundle.min.js"
|
||||||
src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"
|
integrity="sha384-ENjdO4Dr2bkBIFxQpeoTz1HIcje39Wm4jDKdf19U8gI4ddQ3GYNS7NTKfAdVQSZe"
|
||||||
integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p"
|
|
||||||
crossorigin="anonymous"></script>
|
crossorigin="anonymous"></script>
|
||||||
|
<script src="https://cdn.jsdelivr.net/gh/Telesphoreo/bootstrap-color-switcher@master/script.js"></script>
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@200;400&display=swap" rel="stylesheet">
|
||||||
<title>${TITLE} - Plex HTTPD</title>
|
<title>${TITLE} - Plex HTTPD</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body style="font-family: 'IBM Plex Sans', sans-serif;">
|
||||||
<nav class="navbar navbar-expand-lg navbar-light bg-light">
|
<nav class="navbar navbar-expand-lg bg-body-tertiary">
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<a class="navbar-brand" href="/">Plex HTTPD</a>
|
<a class="navbar-brand" href="/" style="font-weight:200;">Plex HTTPD</a>
|
||||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav"
|
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav"
|
||||||
aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
|
aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
|
||||||
<span class="navbar-toggler-icon"></span>
|
<span class="navbar-toggler-icon"></span>
|
||||||
|
@ -23,9 +26,6 @@
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link ${ACTIVE_HOME}" href="/">Home</a>
|
<a class="nav-link ${ACTIVE_HOME}" href="/">Home</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link ${ACTIVE_ADMINS}" href="/api/admins/">Admins</a>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link ${ACTIVE_INDEFBANS}" href="/api/indefbans/">Indefinite Bans</a>
|
<a class="nav-link ${ACTIVE_INDEFBANS}" href="/api/indefbans/">Indefinite Bans</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
Admins
|
|
||||||
ADMINS
|
|
||||||
<h2>Admins</h2>
|
|
||||||
<h5 class="alert alert-danger mb-3 w-auto p-3" role="alert"><b>Error:</b> ${MESSAGE}</h5>
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
Commands
|
||||||
|
COMMANDS
|
||||||
|
<style>
|
||||||
|
summary {
|
||||||
|
font-size: 24px;
|
||||||
|
padding: 16px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<h2>Commands List</h2>
|
||||||
|
<h5>A list of commands is below.</h5>
|
||||||
|
<br><br>
|
||||||
|
${commands}
|
|
@ -1,4 +1,15 @@
|
||||||
server:
|
server:
|
||||||
bind-address: 0.0.0.0
|
bind-address: 0.0.0.0
|
||||||
port: 27192
|
port: 27192
|
||||||
logging: false
|
logging: false
|
||||||
|
|
||||||
|
authentication:
|
||||||
|
enabled: false
|
||||||
|
|
||||||
|
# Providers: discord
|
||||||
|
provider:
|
||||||
|
name: discord
|
||||||
|
redirectUri: ""
|
||||||
|
discord: # Fill if using discord provider
|
||||||
|
clientId: ""
|
||||||
|
token: "" # Can also use environment variable or system property BOT_TOKEN
|
|
@ -15,7 +15,7 @@ SCHEMATICS
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
${schematics}
|
${schematics}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<script>
|
<script>
|
||||||
|
|
|
@ -2,18 +2,21 @@
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet"
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/css/bootstrap.min.css" rel="stylesheet"
|
||||||
integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
|
integrity="sha384-KK94CHFLLe+nY2dmCWGMq91rCGa5gtU4mk92HdvYe+M/SXH301p5ILy+dN9+nJOZ" crossorigin="anonymous">
|
||||||
<script type="text/javascript"
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/js/bootstrap.bundle.min.js"
|
||||||
src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"
|
integrity="sha384-ENjdO4Dr2bkBIFxQpeoTz1HIcje39Wm4jDKdf19U8gI4ddQ3GYNS7NTKfAdVQSZe"
|
||||||
integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p"
|
|
||||||
crossorigin="anonymous"></script>
|
crossorigin="anonymous"></script>
|
||||||
|
<script src="https://cdn.jsdelivr.net/gh/Telesphoreo/bootstrap-color-switcher@master/script.js"></script>
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@200;400&display=swap" rel="stylesheet">
|
||||||
<title>${TITLE} - Plex HTTPD</title>
|
<title>${TITLE} - Plex HTTPD</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body style="font-family: 'IBM Plex Sans', sans-serif;">
|
||||||
<nav class="navbar navbar-expand-lg navbar-light bg-light">
|
<nav class="navbar navbar-expand-lg bg-body-tertiary">
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<a class="navbar-brand" href="/">Plex HTTPD</a>
|
<a class="navbar-brand" href="/" style="font-weight:200;">Plex HTTPD</a>
|
||||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav"
|
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav"
|
||||||
aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
|
aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
|
||||||
<span class="navbar-toggler-icon"></span>
|
<span class="navbar-toggler-icon"></span>
|
||||||
|
@ -23,9 +26,6 @@
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link ${ACTIVE_HOME}" href="/">Home</a>
|
<a class="nav-link ${ACTIVE_HOME}" href="/">Home</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link ${ACTIVE_ADMINS}" href="/api/admins/">Admins</a>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link ${ACTIVE_INDEFBANS}" href="/api/indefbans/">Indefinite Bans</a>
|
<a class="nav-link ${ACTIVE_INDEFBANS}" href="/api/indefbans/">Indefinite Bans</a>
|
||||||
</li>
|
</li>
|
||||||
|
@ -35,6 +35,9 @@
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link ${ACTIVE_PUNISHMENTS}" href="/api/punishments/">Punishments</a>
|
<a class="nav-link ${ACTIVE_PUNISHMENTS}" href="/api/punishments/">Punishments</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<a class="nav-link ${ACTIVE_COMMANDS}" href="/api/commands/">Commands</a>
|
||||||
|
</li>
|
||||||
<li class="nav-item dropdown">
|
<li class="nav-item dropdown">
|
||||||
<a class="nav-link dropdown-toggle ${ACTIVE_SCHEMATICS}" id="navbarDropdownMenuLink" role="button"
|
<a class="nav-link dropdown-toggle ${ACTIVE_SCHEMATICS}" id="navbarDropdownMenuLink" role="button"
|
||||||
data-bs-toggle="dropdown" aria-expanded="false">
|
data-bs-toggle="dropdown" aria-expanded="false">
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
name: Plex-HTTPD
|
name: Module-HTTPD
|
||||||
version: 1.0.2
|
version: 1.4-SNAPSHOT
|
||||||
description: HTTPD server for Plex
|
description: HTTPD server for Plex
|
||||||
main: dev.plex.HTTPDModule
|
main: dev.plex.HTTPDModule
|
Loading…
Reference in New Issue