geforkt von SteamWar/BungeeCore
Commits vergleichen
180 Commits
Autor | SHA1 | Datum | |
---|---|---|---|
c0f8058c60 | |||
153d354c60 | |||
c6ccaa6abb | |||
59b2e397ba | |||
a6feb68bf3 | |||
457b787179 | |||
9572347419 | |||
a0a2d70c46 | |||
f214751d0b | |||
8f3422dce6 | |||
|
2c6de937b3 | ||
49238463a5 | |||
0fd86300ac | |||
c74178abe1 | |||
a3a65b0f53 | |||
1c99a9fb4b | |||
628e7b093c | |||
dd90ee1ced | |||
8029dd09e9 | |||
1e40decc9e | |||
437d1c055c | |||
1436069cb5 | |||
|
b852423442 | ||
|
6f5bb3eb97 | ||
55d08ce0db | |||
b3efb223af | |||
74291bc143 | |||
dabd880209 | |||
3b7fa8054d | |||
54b15ddd95 | |||
70662386a7 | |||
d7e9bb23fc | |||
|
04ebed15d3 | ||
|
9688c38954 | ||
|
760cf4b3b1 | ||
|
443a1b29c9 | ||
c7c541676c | |||
d7a5b72f72 | |||
510fed73d3 | |||
f0e85c21ce | |||
9567bd4c3f | |||
|
3752f3f145 | ||
|
2cdbe68665 | ||
ed5f84dc20 | |||
|
c72a042bbb | ||
|
334afbac63 | ||
779d5f57dc | |||
5162c5b05b | |||
1b3ed278c6 | |||
|
e1a0c4802f | ||
|
23291a7732 | ||
d22766fedd | |||
|
5a0cf47878 | ||
|
99f3ad5f03 | ||
3d67919f0a | |||
|
c017fd23a1 | ||
a05ec1d6d9 | |||
|
28f09e54b9 | ||
7411d9d875 | |||
|
bdbe615790 | ||
|
bfefd5a197 | ||
|
56a9bd077c | ||
6dd35a265b | |||
f270d4197b | |||
2d85746d9f | |||
9de6b8602d | |||
57b220f77c | |||
74cf9d4657 | |||
3ea910501a | |||
4979889468 | |||
8e51002e6c | |||
dad5c6029e | |||
|
a571832d67 | ||
|
6f31058d61 | ||
e36d18ae9d | |||
|
bb8b46c437 | ||
0df03a7dfb | |||
792bbd610d | |||
45cacced9d | |||
d8d519765a | |||
20481029c7 | |||
c3a011d98e | |||
|
183d43dadb | ||
19903e9548 | |||
04a2a31d80 | |||
|
ec6cb89bdb | ||
3d64ee3b6f | |||
|
9be6ec94dc | ||
69720bfbd8 | |||
|
d46c89101d | ||
|
c4fcbdcb43 | ||
24d909a4da | |||
6aeeff235a | |||
65fcb5329f | |||
e981cf5c02 | |||
|
5b627a7819 | ||
|
157aea068e | ||
38eb8d9c06 | |||
ffc2cefcfe | |||
0fc0954d82 | |||
43bd25c13e | |||
b892450e2d | |||
6fe4dbe13a | |||
dbc9ed8b57 | |||
ecf17dd347 | |||
244f922091 | |||
ee05b42a07 | |||
fbbfc1bd03 | |||
1e9b5ead35 | |||
19b12c0055 | |||
e443235e34 | |||
cd044adc55 | |||
a308f9b940 | |||
af357cb554 | |||
356afc9bff | |||
2f928349d7 | |||
7f05d0f9ca | |||
00e08b5943 | |||
4db2ba6a5d | |||
b35d5e214a | |||
3980961b76 | |||
e5cc016652 | |||
3db61577b0 | |||
c0e1d3eff7 | |||
6284cd8e7b | |||
443ce0377f | |||
0c3f200a91 | |||
8c03d2a348 | |||
5aa402d6e8 | |||
59168c3447 | |||
137ef647fb | |||
1128a43010 | |||
5da9d55cb8 | |||
|
df3e082774 | ||
|
6192d0d458 | ||
|
3254755e61 | ||
|
e99f24b01b | ||
01c90dc4ae | |||
|
4dad89ec34 | ||
4385cd3589 | |||
eacf7fd6cf | |||
feeca8f523 | |||
|
e5d48024cb | ||
|
8ed0847bcc | ||
|
e43a724550 | ||
|
9385f57612 | ||
|
6002af7f6a | ||
|
60d5a04d0c | ||
|
9e1653740d | ||
|
618c4d24a2 | ||
|
fbcb043d1c | ||
|
fcd686a9ba | ||
|
4422fbdc8b | ||
|
9af07f821d | ||
|
7cd4a5bac8 | ||
|
6c540c3bac | ||
|
9e6c6ace27 | ||
|
aaadb0e5e2 | ||
|
6ed534bcb3 | ||
|
6848bac447 | ||
|
6a3c47994a | ||
ab207b2234 | |||
|
5e09d018ba | ||
|
0c0cf594c4 | ||
|
9039928eb4 | ||
44e9c084c7 | |||
3fa5e51f30 | |||
98e80442b2 | |||
|
65950a939b | ||
|
4b38ed7c54 | ||
3df1e556ae | |||
5ac85f4e9d | |||
|
ff75a43c11 | ||
|
95a9e8d2a6 | ||
|
ab24041d44 | ||
4052e342fb | |||
|
efc7a3fe48 | ||
4f42c0eca4 | |||
|
481d4a7892 | ||
|
265c841920 |
@ -1 +1 @@
|
|||||||
Subproject commit 595df40e1e9078c310cbbb4bbded07744c361f15
|
Subproject commit 20c22c47f940c4510de17594b28eb0a96cb9da0c
|
216
build.gradle
216
build.gradle
@ -17,10 +17,6 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import org.apache.tools.ant.taskdefs.condition.Os
|
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
// Adding the base plugin fixes the following gradle warnings in IntelliJ:
|
// Adding the base plugin fixes the following gradle warnings in IntelliJ:
|
||||||
//
|
//
|
||||||
@ -33,36 +29,19 @@ plugins {
|
|||||||
id 'java'
|
id 'java'
|
||||||
id 'application'
|
id 'application'
|
||||||
|
|
||||||
id 'com.github.johnrengelman.shadow' version '5.0.0'
|
id 'com.github.johnrengelman.shadow' version '8.1.1'
|
||||||
|
id 'de.steamwar.gradle' version 'RELEASE'
|
||||||
}
|
}
|
||||||
|
|
||||||
group 'de.steamwar'
|
group 'de.steamwar'
|
||||||
version ''
|
version ''
|
||||||
|
|
||||||
Properties steamwarProperties = new Properties()
|
|
||||||
if (file("steamwar.properties").exists()) {
|
|
||||||
steamwarProperties.load(file("steamwar.properties").newDataInputStream())
|
|
||||||
}
|
|
||||||
|
|
||||||
ext {
|
|
||||||
buildName = 'BungeeCore'
|
|
||||||
artifactName = 'bungeecore'
|
|
||||||
|
|
||||||
uberJarName = "${buildName}-all.jar"
|
|
||||||
jarName = "${artifactName}.jar"
|
|
||||||
libs = "${buildDir}/libs"
|
|
||||||
|
|
||||||
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
|
|
||||||
operatingSystem = "windows"
|
|
||||||
} else {
|
|
||||||
operatingSystem = "unix"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
compileJava.options.encoding = 'UTF-8'
|
compileJava.options.encoding = 'UTF-8'
|
||||||
|
|
||||||
sourceCompatibility = 1.8
|
java {
|
||||||
targetCompatibility = 1.8
|
sourceCompatibility = JavaVersion.VERSION_17
|
||||||
|
targetCompatibility = JavaVersion.VERSION_17
|
||||||
|
}
|
||||||
|
|
||||||
mainClassName = ''
|
mainClassName = ''
|
||||||
|
|
||||||
@ -81,12 +60,32 @@ sourceSets {
|
|||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
maven {
|
maven {
|
||||||
url 'https://m2.dv8tion.net/releases'
|
name = 'papermc'
|
||||||
|
url = 'https://repo.papermc.io/repository/maven-public/'
|
||||||
|
}
|
||||||
|
maven {
|
||||||
|
url = 'https://m2.dv8tion.net/releases'
|
||||||
|
content {
|
||||||
|
includeGroup 'net.dv8tion'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
maven {
|
||||||
|
url = 'https://repo.lunarclient.dev'
|
||||||
|
content {
|
||||||
|
includeGroup 'com.lunarclient'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
maven { url 'https://jitpack.io' }
|
||||||
|
mavenLocal()
|
||||||
}
|
}
|
||||||
|
|
||||||
maven {
|
shadowJar {
|
||||||
url = uri('https://steamwar.de/maven')
|
exclude 'META-INF/*'
|
||||||
|
//https://imperceptiblethoughts.com/shadow/configuration/minimizing/
|
||||||
|
minimize {
|
||||||
|
exclude project(':')
|
||||||
}
|
}
|
||||||
|
duplicatesStrategy DuplicatesStrategy.INCLUDE
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
@ -95,159 +94,24 @@ dependencies {
|
|||||||
annotationProcessor 'org.projectlombok:lombok:1.18.22'
|
annotationProcessor 'org.projectlombok:lombok:1.18.22'
|
||||||
testAnnotationProcessor 'org.projectlombok:lombok:1.18.22'
|
testAnnotationProcessor 'org.projectlombok:lombok:1.18.22'
|
||||||
|
|
||||||
compileOnly 'de.steamwar:waterfall:RELEASE'
|
compileOnly 'com.velocitypowered:velocity-api:3.3.0-SNAPSHOT'
|
||||||
compileOnly 'de.steamwar:persistentbungeecore:RELEASE'
|
annotationProcessor 'com.velocitypowered:velocity-api:3.3.0-SNAPSHOT'
|
||||||
|
compileOnly 'com.velocitypowered:velocity-proxy:3.3.0-SNAPSHOT'
|
||||||
|
|
||||||
|
compileOnly 'de.steamwar:persistentvelocitycore:DEV'
|
||||||
implementation("net.dv8tion:JDA:4.4.0_352") {
|
implementation("net.dv8tion:JDA:4.4.0_352") {
|
||||||
exclude module: 'opus-java'
|
exclude module: 'opus-java'
|
||||||
}
|
}
|
||||||
|
|
||||||
implementation project(":CommonCore")
|
implementation project(":CommonCore")
|
||||||
}
|
|
||||||
|
|
||||||
task buildProject {
|
implementation 'com.lunarclient:apollo-api:1.1.0'
|
||||||
description 'Build this project'
|
implementation 'com.lunarclient:apollo-common:1.1.0'
|
||||||
group "Steamwar"
|
|
||||||
|
|
||||||
dependsOn build
|
implementation 'org.reflections:reflections:0.10.2'
|
||||||
}
|
|
||||||
|
|
||||||
task finalizeProject {
|
compileOnly 'io.netty:netty-buffer:4.1.106.Final'
|
||||||
description 'Finalize this project'
|
compileOnly 'io.netty:netty-transport:4.1.106.Final'
|
||||||
group "Steamwar"
|
|
||||||
|
|
||||||
doLast {
|
implementation 'com.github.Carleslc.Simple-YAML:Simple-Yaml:1.8.4'
|
||||||
if ("${buildDir}" == null) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
delete fileTree("${libs}").matching {
|
|
||||||
exclude("${uberJarName}")
|
|
||||||
}
|
|
||||||
file(libs + "/" + uberJarName).renameTo(file(libs + "/" + jarName))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
build.finalizedBy(finalizeProject)
|
|
||||||
|
|
||||||
if (steamwarProperties.containsKey("hostname")) {
|
|
||||||
String hostname = steamwarProperties.get("hostname")
|
|
||||||
String uploadPath = steamwarProperties.getOrDefault("uploadPath", "~")
|
|
||||||
|
|
||||||
String server = steamwarProperties.getOrDefault("server", "DevBungee")
|
|
||||||
String serverStartFlags = steamwarProperties.getOrDefault("serverStartFlags", "")
|
|
||||||
|
|
||||||
task uploadProject {
|
|
||||||
description 'Upload this project'
|
|
||||||
group "Steamwar"
|
|
||||||
|
|
||||||
doLast {
|
|
||||||
await(shell("scp ${libs}/${jarName} ${hostname}:${uploadPath}/${server}/plugins"))
|
|
||||||
if (steamwarProperties.getOrDefault("directStart", "false") == "false" && !answer("Start ${server} server?")) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
serverStart(server, serverStartFlags, hostname)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
uploadProject.dependsOn(buildProject)
|
|
||||||
|
|
||||||
task startDevServer {
|
|
||||||
description 'Start the DevBungee'
|
|
||||||
group "Steamwar"
|
|
||||||
|
|
||||||
doLast {
|
|
||||||
serverStart(server, serverStartFlags, hostname)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private def await(Process proc) {
|
|
||||||
def out = new StringBuilder()
|
|
||||||
def err = new StringBuilder()
|
|
||||||
proc.waitForProcessOutput(out, err)
|
|
||||||
return [out, err, proc.exitValue()]
|
|
||||||
}
|
|
||||||
|
|
||||||
private def shell(String command) {
|
|
||||||
if (operatingSystem == "unix") {
|
|
||||||
return ['bash', '-c', command].execute()
|
|
||||||
} else {
|
|
||||||
return ["cmd", "/c", command].execute()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private def serverStart(String serverName, String serverFlags, String hostname) {
|
|
||||||
def proc = shell("ssh -t ${hostname} \"./mc ${serverFlags} ${serverName}\"")
|
|
||||||
|
|
||||||
Set<String> strings = new HashSet<>()
|
|
||||||
File file = new File("${projectDir}/ignoredlog");
|
|
||||||
if (file.exists()) {
|
|
||||||
new BufferedReader(new InputStreamReader(new FileInputStream(file))).readLines().forEach({ s ->
|
|
||||||
strings.add(s)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
Thread outputThread = new Thread({
|
|
||||||
Reader reader = proc.getInputStream().newReader();
|
|
||||||
Writer writer = System.out.newWriter();
|
|
||||||
try {
|
|
||||||
while (proc.alive) {
|
|
||||||
String s = reader.readLine()
|
|
||||||
if (s == null) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (strings.stream().anyMatch({check -> s.contains(check)})) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
writer.write(s + "\n")
|
|
||||||
writer.flush()
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
// Ignored
|
|
||||||
}
|
|
||||||
})
|
|
||||||
outputThread.setName("${serverName} - OutputThread")
|
|
||||||
outputThread.start()
|
|
||||||
|
|
||||||
Writer writer
|
|
||||||
Thread inputThread = new Thread({
|
|
||||||
Reader reader = System.in.newReader()
|
|
||||||
writer = proc.getOutputStream().newWriter()
|
|
||||||
try {
|
|
||||||
while (proc.alive) {
|
|
||||||
String s = reader.readLine()
|
|
||||||
writer.write(s + "\n")
|
|
||||||
writer.flush()
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
// Ignored
|
|
||||||
}
|
|
||||||
})
|
|
||||||
inputThread.setName("${serverName} - InputThread")
|
|
||||||
inputThread.start()
|
|
||||||
|
|
||||||
gradle.buildFinished { buildResult ->
|
|
||||||
if (!proc.alive) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
writer = proc.getOutputStream().newWriter()
|
|
||||||
writer.write("stop\n")
|
|
||||||
writer.flush()
|
|
||||||
awaitClose(proc, outputThread, inputThread)
|
|
||||||
}
|
|
||||||
awaitClose(proc, outputThread, inputThread)
|
|
||||||
};
|
|
||||||
|
|
||||||
private static def awaitClose(Process proc, Thread outputThread, Thread inputThread) {
|
|
||||||
while (proc.alive) {
|
|
||||||
Thread.sleep(10)
|
|
||||||
}
|
|
||||||
proc.closeStreams()
|
|
||||||
outputThread.interrupt()
|
|
||||||
inputThread.interrupt()
|
|
||||||
}
|
|
||||||
|
|
||||||
private def answer(String question) {
|
|
||||||
while (System.in.available() > 0) System.in.read()
|
|
||||||
println(question)
|
|
||||||
boolean valid = "Yy".contains(((char) System.in.read()).toString())
|
|
||||||
while (System.in.available() > 0) System.in.read()
|
|
||||||
return valid
|
|
||||||
}
|
}
|
86
deployarena.py
Ausführbare Datei
86
deployarena.py
Ausführbare Datei
@ -0,0 +1,86 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import datetime
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
import sys
|
||||||
|
import tarfile
|
||||||
|
from os import path
|
||||||
|
|
||||||
|
# Non stdlib
|
||||||
|
from nbt import nbt
|
||||||
|
from ruamel.yaml import YAML
|
||||||
|
yaml = YAML()
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
configfile = f'/configs/GameModes/{sys.argv[1]}'
|
||||||
|
version = int(sys.argv[2])
|
||||||
|
worldname = sys.argv[3]
|
||||||
|
|
||||||
|
with open(configfile, 'r') as file:
|
||||||
|
gamemode = yaml.load(file)
|
||||||
|
|
||||||
|
builderworld = path.expanduser(f'~/builder{version}/{worldname}')
|
||||||
|
arenaworld = f'/servers/{gamemode["Server"]["Folder"]}/arenas/{worldname}'
|
||||||
|
|
||||||
|
if path.exists(arenaworld):
|
||||||
|
backupworld = path.expanduser(f'~/backup/arenas/{datetime.datetime.now()}-{worldname}-{version}.tar.xz')
|
||||||
|
with tarfile.open(backupworld, 'w:xz') as tar:
|
||||||
|
tar.add(arenaworld, arcname=worldname)
|
||||||
|
|
||||||
|
shutil.rmtree(arenaworld)
|
||||||
|
else:
|
||||||
|
gamemode['Server']['Maps'].append(worldname)
|
||||||
|
|
||||||
|
with open(configfile, 'w') as file:
|
||||||
|
yaml.dump(gamemode, file)
|
||||||
|
|
||||||
|
|
||||||
|
level = nbt.NBTFile(f'{builderworld}/level.dat')
|
||||||
|
level['Data']['Difficulty'] = nbt.TAG_Byte(2)
|
||||||
|
gameRules = level['Data']['GameRules']
|
||||||
|
gameRules['announceAdvancements'] = nbt.TAG_String('false')
|
||||||
|
gameRules['disableRaids'] = nbt.TAG_String('true')
|
||||||
|
gameRules['doDaylightCycle'] = nbt.TAG_String('false')
|
||||||
|
gameRules['doEntityDrops'] = nbt.TAG_String('false')
|
||||||
|
gameRules['doFireTick'] = nbt.TAG_String('true')
|
||||||
|
gameRules['doImmediateRespawn'] = nbt.TAG_String('true')
|
||||||
|
gameRules['doInsomnia'] = nbt.TAG_String('false')
|
||||||
|
gameRules['doLimitedCrafting'] = nbt.TAG_String('false')
|
||||||
|
gameRules['doMobLoot'] = nbt.TAG_String('false')
|
||||||
|
gameRules['doMobSpawning'] = nbt.TAG_String('false')
|
||||||
|
gameRules['doPatrolSpawning'] = nbt.TAG_String('false')
|
||||||
|
gameRules['doTileDrops'] = nbt.TAG_String('true')
|
||||||
|
gameRules['doTraderSpawning'] = nbt.TAG_String('false')
|
||||||
|
gameRules['doWardenSpawning'] = nbt.TAG_String('false')
|
||||||
|
gameRules['doWeatherCycle'] = nbt.TAG_String('false')
|
||||||
|
gameRules['drowningDamage'] = nbt.TAG_String('true')
|
||||||
|
gameRules['fallDamage'] = nbt.TAG_String('true')
|
||||||
|
gameRules['fireDamage'] = nbt.TAG_String('true')
|
||||||
|
gameRules['freezeDamage'] = nbt.TAG_String('true')
|
||||||
|
gameRules['keepInventory'] = nbt.TAG_String('true')
|
||||||
|
gameRules['lavaSourceConversion'] = nbt.TAG_String('false')
|
||||||
|
gameRules['maxEntityCramming'] = nbt.TAG_String('24')
|
||||||
|
gameRules['mobGriefing'] = nbt.TAG_String('false')
|
||||||
|
gameRules['naturalRegeneration'] = nbt.TAG_String('false')
|
||||||
|
gameRules['randomTickSpeed'] = nbt.TAG_String('3')
|
||||||
|
gameRules['reducedDebugInfo'] = nbt.TAG_String('true')
|
||||||
|
gameRules['snowAccumulationHeight'] = nbt.TAG_String('1')
|
||||||
|
gameRules['spawnRadius'] = nbt.TAG_String('0')
|
||||||
|
gameRules['spectatorsGenerateChunks'] = nbt.TAG_String('true')
|
||||||
|
gameRules['waterSourceConversion'] = nbt.TAG_String('true')
|
||||||
|
level.write_file()
|
||||||
|
|
||||||
|
if path.exists(arenaworld):
|
||||||
|
shutil.rmtree(arenaworld)
|
||||||
|
|
||||||
|
os.makedirs(f'{arenaworld}/backup')
|
||||||
|
shutil.copy2(f'{builderworld}/level.dat', f'{arenaworld}/backup/level.dat')
|
||||||
|
shutil.copytree(f'{builderworld}/region', f'{arenaworld}/backup/region')
|
||||||
|
|
||||||
|
shutil.copy2(f'{builderworld}/level.dat', f'{arenaworld}/level.dat')
|
||||||
|
shutil.copytree(f'{builderworld}/region', f'{arenaworld}/region')
|
||||||
|
shutil.copy2(f'{builderworld}/config.yml', f'{arenaworld}/config.yml')
|
||||||
|
|
||||||
|
if path.exists(f'{builderworld}/paper-world.yml'):
|
||||||
|
shutil.copy2(f'{builderworld}/paper-world.yml', f'{arenaworld}/backup/paper-world.yml')
|
||||||
|
shutil.copy2(f'{builderworld}/paper-world.yml', f'{arenaworld}/paper-world.yml')
|
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,5 +1,5 @@
|
|||||||
#Sat Apr 10 23:34:12 CEST 2021
|
#Sat Apr 10 23:34:12 CEST 2021
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.1-all.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.1-all.zip
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
@ -17,6 +17,15 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
rootProject.name = 'BungeeCore'
|
pluginManagement {
|
||||||
|
repositories {
|
||||||
|
gradlePluginPortal()
|
||||||
|
maven {
|
||||||
|
url = uri("https://steamwar.de/maven/")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rootProject.name = 'VelocityCore'
|
||||||
|
|
||||||
include 'CommonCore'
|
include 'CommonCore'
|
@ -20,10 +20,8 @@
|
|||||||
package de.steamwar.bungeecore;
|
package de.steamwar.bungeecore;
|
||||||
|
|
||||||
import de.steamwar.sql.SchematicType;
|
import de.steamwar.sql.SchematicType;
|
||||||
import net.md_5.bungee.api.ProxyServer;
|
import org.simpleyaml.configuration.Configuration;
|
||||||
import net.md_5.bungee.config.Configuration;
|
import org.simpleyaml.configuration.file.YamlFile;
|
||||||
import net.md_5.bungee.config.ConfigurationProvider;
|
|
||||||
import net.md_5.bungee.config.YamlConfiguration;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -32,19 +30,29 @@ import java.util.stream.Collectors;
|
|||||||
|
|
||||||
public class ArenaMode {
|
public class ArenaMode {
|
||||||
|
|
||||||
|
private static final Random random = new Random();
|
||||||
|
|
||||||
private static final Map<String, ArenaMode> byChat = new HashMap<>();
|
private static final Map<String, ArenaMode> byChat = new HashMap<>();
|
||||||
private static final Map<String, ArenaMode> byInternal = new HashMap<>();
|
private static final Map<String, ArenaMode> byInternal = new HashMap<>();
|
||||||
private static final Map<SchematicType, ArenaMode> bySchemType = new HashMap<>();
|
private static final Map<SchematicType, ArenaMode> bySchemType = new HashMap<>();
|
||||||
private static final List<ArenaMode> allModes = new LinkedList<>();
|
private static final List<ArenaMode> allModes = new LinkedList<>();
|
||||||
private static final Random random = new Random();
|
|
||||||
|
|
||||||
static {
|
static {
|
||||||
File folder = new File(ProxyServer.getInstance().getPluginsFolder(), "FightSystem");
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void init() {
|
||||||
|
byChat.clear();
|
||||||
|
byInternal.clear();
|
||||||
|
bySchemType.clear();
|
||||||
|
allModes.clear();
|
||||||
|
|
||||||
|
File folder = new File(VelocityCore.get().getDataDirectory().getParent().toFile(), "FightSystem");
|
||||||
|
|
||||||
for(File configFile : Arrays.stream(folder.listFiles((file, name) -> name.endsWith(".yml") && !name.endsWith(".kits.yml"))).sorted().collect(Collectors.toList())) {
|
for(File configFile : Arrays.stream(folder.listFiles((file, name) -> name.endsWith(".yml") && !name.endsWith(".kits.yml"))).sorted().collect(Collectors.toList())) {
|
||||||
Configuration config;
|
Configuration config;
|
||||||
try {
|
try {
|
||||||
config = ConfigurationProvider.getProvider(YamlConfiguration.class).load(configFile);
|
config = YamlFile.loadConfiguration(configFile);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new SecurityException("Could not load SchematicTypes", e);
|
throw new SecurityException("Could not load SchematicTypes", e);
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,8 @@
|
|||||||
|
|
||||||
package de.steamwar.bungeecore;
|
package de.steamwar.bungeecore;
|
||||||
|
|
||||||
import net.md_5.bungee.api.ProxyServer;
|
import de.steamwar.messages.ChatSender;
|
||||||
|
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||||
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
@ -29,14 +30,15 @@ class Broadcaster {
|
|||||||
private int lastBroadCast = 0;
|
private int lastBroadCast = 0;
|
||||||
|
|
||||||
Broadcaster(){
|
Broadcaster(){
|
||||||
ProxyServer.getInstance().getScheduler().schedule(BungeeCore.get(), () -> {
|
VelocityCore.get().getProxyServer().getScheduler().buildTask(VelocityCore.get(), () -> {
|
||||||
if(!ProxyServer.getInstance().getPlayers().isEmpty() && broadCastMsgs.length > 0)
|
if(!VelocityCore.get().getProxyServer().getAllPlayers().isEmpty() && broadCastMsgs.length > 0) {
|
||||||
BungeeCore.broadcast(BungeeCore.CHAT_PREFIX + broadCastMsgs[lastBroadCast]);
|
VelocityCore.get().getProxyServer().sendMessage(LegacyComponentSerializer.legacySection().deserialize(VelocityCore.CHAT_PREFIX + broadCastMsgs[lastBroadCast]));
|
||||||
|
}
|
||||||
lastBroadCast++;
|
lastBroadCast++;
|
||||||
if(lastBroadCast == broadCastMsgs.length){
|
if(lastBroadCast == broadCastMsgs.length){
|
||||||
lastBroadCast = 0;
|
lastBroadCast = 0;
|
||||||
}
|
}
|
||||||
}, 10, 10, TimeUnit.MINUTES);
|
}).repeat(10, TimeUnit.MINUTES);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setBroadCastMsgs(String[] broadCastMsgs) {
|
static void setBroadCastMsgs(String[] broadCastMsgs) {
|
||||||
|
@ -87,6 +87,7 @@ public class ErrorLogger extends Handler {
|
|||||||
contains.add("Server is online mode!");
|
contains.add("Server is online mode!");
|
||||||
contains.add(" took ");
|
contains.add(" took ");
|
||||||
contains.add("Could not translate packet ");
|
contains.add("Could not translate packet ");
|
||||||
|
contains.add("455420");
|
||||||
ignoreContains = Collections.unmodifiableList(contains);
|
ignoreContains = Collections.unmodifiableList(contains);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,41 +20,36 @@
|
|||||||
package de.steamwar.bungeecore;
|
package de.steamwar.bungeecore;
|
||||||
|
|
||||||
import de.steamwar.sql.EventFight;
|
import de.steamwar.sql.EventFight;
|
||||||
import de.steamwar.sql.SteamwarUser;
|
|
||||||
import de.steamwar.sql.Team;
|
import de.steamwar.sql.Team;
|
||||||
import de.steamwar.sql.Event;
|
import net.kyori.adventure.text.event.ClickEvent;
|
||||||
import net.md_5.bungee.api.ProxyServer;
|
|
||||||
import net.md_5.bungee.api.chat.ClickEvent;
|
|
||||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
|
||||||
import net.md_5.bungee.api.scheduler.ScheduledTask;
|
|
||||||
|
|
||||||
import java.sql.Timestamp;
|
import java.sql.Timestamp;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Queue;
|
import java.util.Queue;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import static de.steamwar.bungeecore.Storage.eventServer;
|
import static de.steamwar.bungeecore.Storage.eventServer;
|
||||||
|
|
||||||
public class EventStarter implements Runnable {
|
public class EventStarter {
|
||||||
|
|
||||||
private static ScheduledTask task = null;
|
private static final Map<Integer, String> spectatePorts = new HashMap<>();
|
||||||
|
|
||||||
EventStarter(){
|
public static void addSpectateServer(int port, String command) {
|
||||||
|
spectatePorts.put(port, command);
|
||||||
|
}
|
||||||
|
|
||||||
|
public EventStarter() {
|
||||||
EventFight.loadAllComingFights();
|
EventFight.loadAllComingFights();
|
||||||
|
VelocityCore.get().getProxyServer().getScheduler().buildTask(VelocityCore.get(), this::run).repeat(10, TimeUnit.SECONDS);
|
||||||
if(task != null)
|
|
||||||
task.cancel();
|
|
||||||
|
|
||||||
ProxyServer.getInstance().getScheduler().schedule(BungeeCore.get(), this, 1, 10, TimeUnit.SECONDS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Map<Integer, Subserver> getEventServer() {
|
public static Map<Integer, Subserver> getEventServer() {
|
||||||
return eventServer;
|
return eventServer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private void run() {
|
||||||
public void run() {
|
eventServer.entrySet().removeIf(entry -> Subserver.getSubserver(entry.getValue().getServer()) == null);
|
||||||
eventServer.entrySet().removeIf(entry -> !Subserver.getServerList().contains(entry.getValue()));
|
|
||||||
Queue<EventFight> fights = EventFight.getFights();
|
Queue<EventFight> fights = EventFight.getFights();
|
||||||
|
|
||||||
EventFight next;
|
EventFight next;
|
||||||
@ -63,22 +58,19 @@ public class EventStarter implements Runnable {
|
|||||||
Team red = Team.get(next.getTeamRed());
|
Team red = Team.get(next.getTeamRed());
|
||||||
|
|
||||||
//Don't start EventServer if not the event bungee
|
//Don't start EventServer if not the event bungee
|
||||||
if(BungeeCore.EVENT_MODE || !Event.get(next.getEventID()).spectateSystem()) {
|
if(VelocityCore.EVENT_MODE || next.getSpectatePort() == 0) {
|
||||||
ServerStarter starter = new ServerStarter().event(next);
|
ServerStarter starter = new ServerStarter().event(next);
|
||||||
|
|
||||||
ProxiedPlayer leiter = ProxyServer.getInstance().getPlayer(SteamwarUser.get(next.getKampfleiter()).getUUID());
|
starter.callback(subserver -> {
|
||||||
if(leiter != null)
|
|
||||||
starter.send(leiter);
|
|
||||||
|
|
||||||
Subserver subserver = starter.start();
|
|
||||||
|
|
||||||
eventServer.put(blue.getTeamId(), subserver);
|
eventServer.put(blue.getTeamId(), subserver);
|
||||||
eventServer.put(red.getTeamId(), subserver);
|
eventServer.put(red.getTeamId(), subserver);
|
||||||
|
}).start();
|
||||||
|
|
||||||
Message.broadcast("EVENT_FIGHT_BROADCAST", "EVENT_FIGHT_BROADCAST_HOVER",
|
Message.broadcast("EVENT_FIGHT_BROADCAST", "EVENT_FIGHT_BROADCAST_HOVER",
|
||||||
new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/event " + blue.getTeamKuerzel()), blue.getTeamColor(), blue.getTeamName(), red.getTeamColor(), red.getTeamName());
|
ClickEvent.runCommand("/event " + blue.getTeamKuerzel()), blue.getTeamColor(), blue.getTeamName(), red.getTeamColor(), red.getTeamName());
|
||||||
} else {
|
} else {
|
||||||
Message.broadcast("EVENT_FIGHT_BROADCAST", "EVENT_FIGHT_BROADCAST_HOVER",
|
Message.broadcast("EVENT_FIGHT_BROADCAST", "EVENT_FIGHT_BROADCAST_HOVER",
|
||||||
new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/spectate"), blue.getTeamColor(), blue.getTeamName(), red.getTeamColor(), red.getTeamName());
|
ClickEvent.runCommand("/" + spectatePorts.get(next.getSpectatePort())), blue.getTeamColor(), blue.getTeamName(), red.getTeamColor(), red.getTeamName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,12 +19,13 @@
|
|||||||
|
|
||||||
package de.steamwar.bungeecore;
|
package de.steamwar.bungeecore;
|
||||||
|
|
||||||
|
import com.velocitypowered.api.command.CommandSource;
|
||||||
import de.steamwar.messages.ChatSender;
|
import de.steamwar.messages.ChatSender;
|
||||||
import de.steamwar.messages.SteamwarResourceBundle;
|
import de.steamwar.messages.SteamwarResourceBundle;
|
||||||
import net.md_5.bungee.api.ChatMessageType;
|
import net.kyori.adventure.identity.Identity;
|
||||||
import net.md_5.bungee.api.CommandSender;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.md_5.bungee.api.chat.ClickEvent;
|
import net.kyori.adventure.text.event.ClickEvent;
|
||||||
import net.md_5.bungee.api.chat.TextComponent;
|
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||||
|
|
||||||
import java.text.DateFormat;
|
import java.text.DateFormat;
|
||||||
import java.text.MessageFormat;
|
import java.text.MessageFormat;
|
||||||
@ -35,17 +36,17 @@ import java.util.ResourceBundle;
|
|||||||
public class Message {
|
public class Message {
|
||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public static TextComponent parseToComponent(String message, boolean prefixed, CommandSender sender, Object... params){
|
public static Component parseToComponent(String message, boolean prefixed, CommandSource sender, Object... params){
|
||||||
return new TextComponent(TextComponent.fromLegacyText(parse(message, prefixed, locale(sender), params)));
|
return LegacyComponentSerializer.legacySection().deserialize(parse(message, prefixed, locale(sender), params));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public static String parsePrefixed(String message, CommandSender sender, Object... params){
|
public static String parsePrefixed(String message, CommandSource sender, Object... params){
|
||||||
return parse(message, true, locale(sender), params);
|
return parse(message, true, locale(sender), params);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public static String parse(String message, CommandSender sender, Object... params){
|
public static String parse(String message, CommandSource sender, Object... params){
|
||||||
return parse(message, false, locale(sender), params);
|
return parse(message, false, locale(sender), params);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,8 +56,8 @@ public class Message {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
private static Locale locale(CommandSender sender) {
|
private static Locale locale(CommandSource sender) {
|
||||||
return ChatSender.of(sender).getLocale();
|
return sender.get(Identity.LOCALE).orElse(Locale.GERMAN);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
@ -82,32 +83,32 @@ public class Message {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public static void send(String message, CommandSender sender, Object... params){
|
public static void send(String message, CommandSource sender, Object... params){
|
||||||
send(message, true, sender, ChatMessageType.SYSTEM, null, null, params);
|
send(message, true, sender, null, null, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public static void sendPrefixless(String message, CommandSender sender, Object... params){
|
public static void sendPrefixless(String message, CommandSource sender, Object... params){
|
||||||
send(message, false, sender, ChatMessageType.SYSTEM, null, null, params);
|
send(message, false, sender, null, null, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public static void send(String message, CommandSender sender, String onHover, ClickEvent onClick, Object... params){
|
public static void send(String message, CommandSource sender, String onHover, ClickEvent onClick, Object... params){
|
||||||
send(message, true, sender, ChatMessageType.SYSTEM, onHover, onClick, params);
|
send(message, true, sender, onHover, onClick, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public static void sendPrefixless(String message, CommandSender sender, String onHover, ClickEvent onClick, Object... params){
|
public static void sendPrefixless(String message, CommandSource sender, String onHover, ClickEvent onClick, Object... params){
|
||||||
send(message, false, sender, ChatMessageType.SYSTEM, onHover, onClick, params);
|
send(message, false, sender, onHover, onClick, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
private static void send(String message, boolean prefixed, CommandSender s, ChatMessageType type, String onHover, ClickEvent onClick, Object... params){
|
private static void send(String message, boolean prefixed, CommandSource s, String onHover, ClickEvent onClick, Object... params){
|
||||||
ChatSender sender = ChatSender.of(s);
|
ChatSender sender = ChatSender.of(s);
|
||||||
if(type == ChatMessageType.CHAT && !sender.chatShown())
|
if(!sender.chatShown())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
sender.send(prefixed, type, onHover != null ? new Message("PLAIN_STRING", onHover) : null, onClick, new Message(message, params));
|
sender.send(prefixed, onHover != null ? new Message("PLAIN_STRING", onHover) : null, onClick, new Message(message, params));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void broadcast(String message, Object... params) {
|
public static void broadcast(String message, Object... params) {
|
||||||
@ -123,7 +124,7 @@ public class Message {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void team(String message, String onHover, ClickEvent onClick, Object... params) {
|
public static void team(String message, String onHover, ClickEvent onClick, Object... params) {
|
||||||
ChatSender.serverteamReceivers().filter(player -> player.user().getUserGroup().isTeamGroup()).forEach(player -> player.prefixless(message, onHover != null ? new Message(onHover, params) : null, onClick, params));
|
ChatSender.serverteamReceivers().forEach(player -> player.prefixless(message, onHover != null ? new Message(onHover, params) : null, onClick, params));
|
||||||
}
|
}
|
||||||
|
|
||||||
private final String format;
|
private final String format;
|
||||||
|
@ -23,6 +23,7 @@ import net.md_5.bungee.BungeeCord;
|
|||||||
import net.md_5.bungee.api.ProxyServer;
|
import net.md_5.bungee.api.ProxyServer;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
import java.nio.file.Files;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
@ -30,7 +31,13 @@ import java.util.logging.Level;
|
|||||||
|
|
||||||
public abstract class Node {
|
public abstract class Node {
|
||||||
|
|
||||||
private static final List<String> OPENJ9_ARGS = Arrays.asList("-Xgc:excessiveGCratio=80", "-Xsyslog:none", "-Xtrace:none", "-Xdisableexplicitgc", "-XX:+AlwaysPreTouch", "-XX:+CompactStrings", "-XX:-HeapDumpOnOutOfMemory", "-XX:+ExitOnOutOfMemoryError", "-Dlog4j.configurationFile=log4j2.xml", "-Dio.netty.allocator.numHeapArenas=1", "-Xmos128M", "-Xmns48M"); // initial heap half values of memory observed by 1.19 spectate server
|
//-Xquickstart Langzeitperformance testen!
|
||||||
|
private static final List<String> OPENJ9_ARGS = Arrays.asList(
|
||||||
|
"-XX:+EnableCRIUSupport", "-XX:-CRIURestoreNonPortableMode",
|
||||||
|
"-Xgc:excessiveGCratio=80", "-Xdisableexplicitgc", "-Xnoclassgc", "-Xmos128M", "-Xmns48M", "-XX:+ExitOnOutOfMemoryError", // initial heap half values of memory observed by 1.19 spectate server
|
||||||
|
"-Xsyslog:none", "-Xtrace:none", "-Xverify:none", "-Xdump:system:none", "-Xdump:jit:none", "-Xdump:snap:none",
|
||||||
|
"-Dlog4j.configurationFile=log4j2.xml"
|
||||||
|
);
|
||||||
private static final Set<String> JAVA_8 = new HashSet<>();
|
private static final Set<String> JAVA_8 = new HashSet<>();
|
||||||
static {
|
static {
|
||||||
JAVA_8.add("paper-1.8.8.jar");
|
JAVA_8.add("paper-1.8.8.jar");
|
||||||
@ -41,7 +48,6 @@ public abstract class Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static final long MIN_FREE_MEM = 4 * 1024 * 1024L; // 4 GiB
|
private static final long MIN_FREE_MEM = 4 * 1024 * 1024L; // 4 GiB
|
||||||
private static final double MAX_LOAD = 0.8;
|
|
||||||
|
|
||||||
private static final List<Node> nodes = new ArrayList<>();
|
private static final List<Node> nodes = new ArrayList<>();
|
||||||
|
|
||||||
@ -65,13 +71,10 @@ public abstract class Node {
|
|||||||
protected final String hostname;
|
protected final String hostname;
|
||||||
protected volatile boolean belowLoadLimit = true;
|
protected volatile boolean belowLoadLimit = true;
|
||||||
|
|
||||||
private long previousCpuLoaded = 0;
|
|
||||||
private long previousCpuTotal = 0;
|
|
||||||
|
|
||||||
protected Node(String hostname) {
|
protected Node(String hostname) {
|
||||||
this.hostname = hostname;
|
this.hostname = hostname;
|
||||||
nodes.add(this);
|
nodes.add(this);
|
||||||
BungeeCord.getInstance().getScheduler().schedule(BungeeCore.get(), this::calcLoadLimit, 1, 2, TimeUnit.SECONDS);
|
VelocityCore.get().getProxyServer().getScheduler().buildTask(VelocityCore.get(), () -> calcLoadLimit()).repeat(2, TimeUnit.SECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void execute(String... command) {
|
public void execute(String... command) {
|
||||||
@ -80,7 +83,7 @@ public abstract class Node {
|
|||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new SecurityException("Could not execute command", e);
|
throw new SecurityException("Could not execute command", e);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
ProxyServer.getInstance().getLogger().log(Level.SEVERE, "Interrupted during execution", e);
|
VelocityCore.get().getLogger().log(Level.SEVERE, "Interrupted during execution", e);
|
||||||
Thread.currentThread().interrupt();
|
Thread.currentThread().interrupt();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -96,17 +99,18 @@ public abstract class Node {
|
|||||||
if (JAVA_8.contains(serverJar))
|
if (JAVA_8.contains(serverJar))
|
||||||
cmd.add("/usr/lib/jvm/java-8-openj9-amd64/bin/java");
|
cmd.add("/usr/lib/jvm/java-8-openj9-amd64/bin/java");
|
||||||
else
|
else
|
||||||
cmd.add("java");
|
cmd.add("/usr/lib/jvm/java-21-openj9-amd64/bin/java");
|
||||||
|
|
||||||
for(String param : dParams){
|
for(String param : dParams){
|
||||||
cmd.add("-D" + param);
|
cmd.add("-D" + param);
|
||||||
}
|
}
|
||||||
cmd.add("-Xmx" + xmx);
|
|
||||||
cmd.add("-Xshareclasses:nonfatal,name=" + directory.getName());
|
cmd.add("-Xshareclasses:nonfatal,name=" + directory.getName());
|
||||||
|
cmd.add("-Xmx" + xmx);
|
||||||
cmd.addAll(OPENJ9_ARGS);
|
cmd.addAll(OPENJ9_ARGS);
|
||||||
if (!JAVA_8.contains(serverJar)) {
|
if (!JAVA_8.contains(serverJar)) {
|
||||||
cmd.add("--add-opens");
|
cmd.add("--add-opens");
|
||||||
cmd.add("java.base/jdk.internal.misc=ALL-UNNAMED");
|
cmd.add("java.base/jdk.internal.misc=ALL-UNNAMED");
|
||||||
|
cmd.add("-XX:-CRIUSecProvider");
|
||||||
}
|
}
|
||||||
cmd.add("-jar");
|
cmd.add("-jar");
|
||||||
cmd.add("/binarys/" + serverJar);
|
cmd.add("/binarys/" + serverJar);
|
||||||
@ -120,28 +124,18 @@ public abstract class Node {
|
|||||||
cmd.add("nogui");
|
cmd.add("nogui");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void calcLoadLimit(BufferedReader stat, BufferedReader meminfo) throws IOException {
|
protected void calcLoadLimit(BufferedReader meminfo) throws IOException {
|
||||||
String[] cpuline = stat.readLine().split(" "); // 0-1: prefix, 2: user, 3: nice, 4: system, 5: idle, 6: iowait, 7: irq, 8: softirq, 9: steal, 10: guest, 11: guest_nice
|
|
||||||
long cpuLoaded = Long.parseLong(cpuline[2]) + Long.parseLong(cpuline[4]) + Long.parseLong(cpuline[6]) + Long.parseLong(cpuline[7]) + Long.parseLong(cpuline[8]) + Long.parseLong(cpuline[9]) + Long.parseLong(cpuline[10]) + Long.parseLong(cpuline[11]);
|
|
||||||
long cpuTotal = cpuLoaded + Long.parseLong(cpuline[3]) + Long.parseLong(cpuline[5]);
|
|
||||||
|
|
||||||
cpuLoaded -= previousCpuLoaded;
|
|
||||||
cpuTotal -= previousCpuTotal;
|
|
||||||
previousCpuLoaded += cpuLoaded;
|
|
||||||
previousCpuTotal += cpuTotal;
|
|
||||||
|
|
||||||
String line = meminfo.readLine();
|
String line = meminfo.readLine();
|
||||||
while(!line.startsWith("MemAvailable")) {
|
while(!line.startsWith("MemAvailable")) {
|
||||||
line = meminfo.readLine();
|
line = meminfo.readLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
long availableMem = Long.parseLong(line.replaceAll(" +", " ").split(" ")[1]);
|
long availableMem = Long.parseLong(line.replaceAll(" +", " ").split(" ")[1]);
|
||||||
belowLoadLimit = cpuLoaded / (double)cpuTotal <= MAX_LOAD && availableMem >= MIN_FREE_MEM;
|
belowLoadLimit = availableMem >= MIN_FREE_MEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class LocalNode extends Node {
|
public static class LocalNode extends Node {
|
||||||
private static final File MEMINFO = new File("/proc/meminfo");
|
private static final File MEMINFO = new File("/proc/meminfo");
|
||||||
private static final File STAT = new File("/proc/stat");
|
|
||||||
|
|
||||||
public LocalNode() {
|
public LocalNode() {
|
||||||
super("sw");
|
super("sw");
|
||||||
@ -158,12 +152,10 @@ public abstract class Node {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void calcLoadLimit() {
|
protected void calcLoadLimit() {
|
||||||
try (BufferedReader loadavg = new BufferedReader(new InputStreamReader(new FileInputStream(STAT)))) {
|
try (BufferedReader meminfo = new BufferedReader(new InputStreamReader(Files.newInputStream(MEMINFO.toPath())))) {
|
||||||
try (BufferedReader meminfo = new BufferedReader(new InputStreamReader(new FileInputStream(MEMINFO)))) {
|
calcLoadLimit(meminfo);
|
||||||
calcLoadLimit(loadavg, meminfo);
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
BungeeCore.get().getLogger().log(Level.SEVERE, "Could not read local load", e);
|
VelocityCore.get().getLogger().log(Level.SEVERE, "Could not read local load", e);
|
||||||
belowLoadLimit = false;
|
belowLoadLimit = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -178,7 +170,7 @@ public abstract class Node {
|
|||||||
|
|
||||||
public RemoteNode(String hostname) {
|
public RemoteNode(String hostname) {
|
||||||
super(hostname);
|
super(hostname);
|
||||||
BungeeCore.get().getLogger().log(Level.INFO, "Added node " + hostname);
|
VelocityCore.get().getLogger().log(Level.INFO, "Added node " + hostname);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -207,17 +199,15 @@ public abstract class Node {
|
|||||||
@Override
|
@Override
|
||||||
protected void calcLoadLimit() {
|
protected void calcLoadLimit() {
|
||||||
try {
|
try {
|
||||||
Process process = prepareExecution("cat /proc/stat /proc/meminfo").start();
|
Process process = prepareExecution("cat /proc/meminfo").start();
|
||||||
if(!process.waitFor(1, TimeUnit.SECONDS))
|
if(!process.waitFor(1, TimeUnit.SECONDS))
|
||||||
throw new IOException(hostname + " timeout");
|
throw new IOException(hostname + " timeout");
|
||||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
|
try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
|
||||||
if(reader == null)
|
calcLoadLimit(reader);
|
||||||
throw new IOException("Why reader null? " + process.getInputStream());
|
|
||||||
calcLoadLimit(reader, reader);
|
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
if(belowLoadLimit)
|
if(belowLoadLimit)
|
||||||
BungeeCore.get().getLogger().log(Level.SEVERE, "Could read remote load", e);
|
VelocityCore.get().getLogger().log(Level.SEVERE, "Could read remote load", e);
|
||||||
belowLoadLimit = false;
|
belowLoadLimit = false;
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
Thread.currentThread().interrupt();
|
Thread.currentThread().interrupt();
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
package de.steamwar.bungeecore;
|
package de.steamwar.bungeecore;
|
||||||
|
|
||||||
import de.steamwar.sql.EventFight;
|
import com.velocitypowered.api.proxy.Player;
|
||||||
import de.steamwar.sql.SteamwarUser;
|
|
||||||
import de.steamwar.sql.Team;
|
|
||||||
import de.steamwar.sql.Tutorial;
|
|
||||||
import de.steamwar.messages.ChatSender;
|
import de.steamwar.messages.ChatSender;
|
||||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
import de.steamwar.sql.*;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.io.DataOutputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
@ -14,23 +13,22 @@ import java.nio.file.Files;
|
|||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.function.BooleanSupplier;
|
import java.util.function.BooleanSupplier;
|
||||||
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class ServerStarter {
|
public class ServerStarter {
|
||||||
|
|
||||||
private static final Portrange BAU_PORTS = BungeeCore.MAIN_SERVER ? new Portrange(10100, 20000) : new Portrange(2100, 2200);
|
private static final Portrange BAU_PORTS = VelocityCore.MAIN_SERVER ? new Portrange(10100, 20000) : new Portrange(2100, 2200);
|
||||||
private static final Portrange ARENA_PORTS = BungeeCore.MAIN_SERVER ? new Portrange(3000, 3100) : (BungeeCore.EVENT_MODE ? new Portrange(4000, 5000) : BAU_PORTS);
|
private static final Portrange ARENA_PORTS = VelocityCore.MAIN_SERVER ? new Portrange(3000, 3100) : (VelocityCore.EVENT_MODE ? new Portrange(4000, 5000) : BAU_PORTS);
|
||||||
|
|
||||||
private static final String SERVER_PATH = "/servers/";
|
private static final String SERVER_PATH = "/servers/";
|
||||||
private static final String USER_HOME = System.getProperty("user.home") + "/";
|
private static final String USER_HOME = System.getProperty("user.home") + "/";
|
||||||
private static final String EVENT_PATH = USER_HOME + "event/";
|
private static final String EVENT_PATH = USER_HOME + "event/";
|
||||||
public static final String TEMP_WORLD_PATH = USER_HOME + "arenaserver/";
|
public static final String TEMP_WORLD_PATH = USER_HOME + "arenaserver/";
|
||||||
public static final String TUTORIAL_PATH = USER_HOME + "tutorials/";
|
public static final String TUTORIAL_PATH = USER_HOME + "tutorials/";
|
||||||
public static final String WORLDS12_PATH = USER_HOME + "userworlds/";
|
|
||||||
public static final String WORLDS15_PATH = USER_HOME + "userworlds15/";
|
|
||||||
public static final String WORLDS19_PATH = USER_HOME + "userworlds19/";
|
|
||||||
|
|
||||||
|
public static final String WORLDS_BASE_PATH = USER_HOME + "userworlds";
|
||||||
public static final String BUILDER_BASE_PATH = USER_HOME + "builder";
|
public static final String BUILDER_BASE_PATH = USER_HOME + "builder";
|
||||||
|
|
||||||
private File directory = null;
|
private File directory = null;
|
||||||
@ -48,9 +46,11 @@ public class ServerStarter {
|
|||||||
private boolean allowMerge = false;
|
private boolean allowMerge = false;
|
||||||
private String fightMap = null;
|
private String fightMap = null;
|
||||||
private String gameMode = null;
|
private String gameMode = null;
|
||||||
private ServerConstructor constructor = (serverName, port, builder, shutdownCallback) -> new Arenaserver(serverName, gameMode, fightMap, allowMerge, port, builder, shutdownCallback);
|
private boolean checkpoint = false;
|
||||||
|
private ServerConstructor constructor = (serverName, port, builder, shutdownCallback, failureCallback) -> new Arenaserver(serverName, gameMode, fightMap, allowMerge, port, builder, shutdownCallback);
|
||||||
|
private Consumer<Subserver> callback = subserver -> {};
|
||||||
|
|
||||||
private final Set<ProxiedPlayer> playersToSend = new HashSet<>();
|
private final Set<Player> playersToSend = new HashSet<>();
|
||||||
private final Map<String, String> arguments = new HashMap<>();
|
private final Map<String, String> arguments = new HashMap<>();
|
||||||
|
|
||||||
public ServerStarter arena(ArenaMode mode, String map) {
|
public ServerStarter arena(ArenaMode mode, String map) {
|
||||||
@ -68,7 +68,7 @@ public class ServerStarter {
|
|||||||
|
|
||||||
public ServerStarter event(EventFight eventFight) {
|
public ServerStarter event(EventFight eventFight) {
|
||||||
arena(ArenaMode.getByInternal(eventFight.getSpielmodus()), eventFight.getMap());
|
arena(ArenaMode.getByInternal(eventFight.getSpielmodus()), eventFight.getMap());
|
||||||
node = BungeeCore.local;
|
node = Node.LocalNode.getNode();
|
||||||
worldDir = EVENT_PATH;
|
worldDir = EVENT_PATH;
|
||||||
worldCleanup = () -> {};
|
worldCleanup = () -> {};
|
||||||
arguments.put("fightID", String.valueOf(eventFight.getFightID()));
|
arguments.put("fightID", String.valueOf(eventFight.getFightID()));
|
||||||
@ -81,7 +81,7 @@ public class ServerStarter {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ServerStarter test(ArenaMode mode, String map, ProxiedPlayer owner) {
|
public ServerStarter test(ArenaMode mode, String map, Player owner) {
|
||||||
arena(mode, map);
|
arena(mode, map);
|
||||||
buildWithTemp(owner);
|
buildWithTemp(owner);
|
||||||
portrange = BAU_PORTS;
|
portrange = BAU_PORTS;
|
||||||
@ -89,12 +89,12 @@ public class ServerStarter {
|
|||||||
return send(owner);
|
return send(owner);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ServerStarter blueLeader(ProxiedPlayer player) {
|
public ServerStarter blueLeader(Player player) {
|
||||||
arguments.put("blueLeader", player.getUniqueId().toString());
|
arguments.put("blueLeader", player.getUniqueId().toString());
|
||||||
return send(player);
|
return send(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ServerStarter redLeader(ProxiedPlayer player) {
|
public ServerStarter redLeader(Player player) {
|
||||||
arguments.put("redLeader", player.getUniqueId().toString());
|
arguments.put("redLeader", player.getUniqueId().toString());
|
||||||
return send(player);
|
return send(player);
|
||||||
}
|
}
|
||||||
@ -114,34 +114,46 @@ public class ServerStarter {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ServerStarter build19(UUID owner) {
|
public ServerStarter build(Version version, UUID owner) {
|
||||||
directory = new File(SERVER_PATH, "Bau19");
|
directory = version.getServerDirectory("Bau");
|
||||||
serverJar = "paper-1.19.3.jar";
|
serverJar = version.getServerJar();
|
||||||
worldDir = WORLDS19_PATH;
|
worldDir = version.getWorldFolder(WORLDS_BASE_PATH);
|
||||||
worldName = String.valueOf(SteamwarUser.get(owner).getId());
|
worldName = version != Version.SPIGOT_12 ? String.valueOf(SteamwarUser.get(owner).getId()) : owner.toString();
|
||||||
buildWithWorld(owner, new File(directory, "Bauwelt").getPath());
|
checkpoint = true;
|
||||||
|
|
||||||
|
build(owner);
|
||||||
|
|
||||||
|
worldSetup = () -> {
|
||||||
|
File world = new File(worldDir, worldName);
|
||||||
|
if (!world.exists())
|
||||||
|
copyWorld(node, new File(directory, "Bauwelt").getPath(), world.getPath());
|
||||||
|
};
|
||||||
|
|
||||||
|
// Send players to existing server
|
||||||
|
startCondition = () -> {
|
||||||
|
Bauserver subserver = Bauserver.get(owner);
|
||||||
|
if(subserver != null) {
|
||||||
|
for(Player p : playersToSend)
|
||||||
|
SubserverSystem.sendPlayer(subserver, p);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
boolean atLeastOneSupervisor = playersToSend.stream().anyMatch(player -> {
|
||||||
|
if (player.getUniqueId().equals(owner)) return true;
|
||||||
|
BauweltMember bauweltMember = BauweltMember.getBauMember(owner, player.getUniqueId());
|
||||||
|
return bauweltMember.isSupervisor();
|
||||||
|
});
|
||||||
|
if (!atLeastOneSupervisor) {
|
||||||
|
for (Player p : playersToSend) {
|
||||||
|
ChatSender.of(p).system("BAU_START_NOT_ALLOWED");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return atLeastOneSupervisor;
|
||||||
|
};
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ServerStarter build15(UUID owner) {
|
public ServerStarter tutorial(Player owner, Tutorial tutorial) {
|
||||||
directory = new File(SERVER_PATH, "Bau15");
|
|
||||||
worldDir = WORLDS15_PATH;
|
|
||||||
worldName = String.valueOf(SteamwarUser.get(owner).getId());
|
|
||||||
buildWithWorld(owner, new File(directory, "Bauwelt").getPath());
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ServerStarter build12(UUID owner) {
|
|
||||||
directory = new File(SERVER_PATH, "Bau12");
|
|
||||||
serverJar = "spigot-1.12.2.jar";
|
|
||||||
xmx = "256M";
|
|
||||||
worldDir = WORLDS12_PATH;
|
|
||||||
worldName = owner.toString();
|
|
||||||
buildWithWorld(owner, new File(directory, "Bauwelt").getPath());
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ServerStarter tutorial(ProxiedPlayer owner, Tutorial tutorial) {
|
|
||||||
directory = new File(SERVER_PATH, "Tutorial");
|
directory = new File(SERVER_PATH, "Tutorial");
|
||||||
buildWithTemp(owner);
|
buildWithTemp(owner);
|
||||||
tempWorld(TUTORIAL_PATH + tutorial.getTutorialId());
|
tempWorld(TUTORIAL_PATH + tutorial.getTutorialId());
|
||||||
@ -155,29 +167,7 @@ public class ServerStarter {
|
|||||||
worldCleanup = () -> SubserverSystem.deleteFolder(node, worldDir + worldName);
|
worldCleanup = () -> SubserverSystem.deleteFolder(node, worldDir + worldName);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void buildWithWorld(UUID owner, String prototype) {
|
private void buildWithTemp(Player owner) {
|
||||||
build(owner);
|
|
||||||
|
|
||||||
worldSetup = () -> {
|
|
||||||
File world = new File(worldDir, worldName);
|
|
||||||
if (!world.exists())
|
|
||||||
copyWorld(node, prototype, world.getPath());
|
|
||||||
};
|
|
||||||
|
|
||||||
// Send players to existing server
|
|
||||||
startCondition = () -> {
|
|
||||||
for(Subserver subserver : Subserver.getServerList()) {
|
|
||||||
if(subserver.getType() == Servertype.BAUSERVER && ((Bauserver)subserver).getOwner().equals(owner)) {
|
|
||||||
for(ProxiedPlayer p : playersToSend)
|
|
||||||
SubserverSystem.sendPlayer(subserver, p);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private void buildWithTemp(ProxiedPlayer owner) {
|
|
||||||
build(owner.getUniqueId());
|
build(owner.getUniqueId());
|
||||||
|
|
||||||
// Stop existing build server
|
// Stop existing build server
|
||||||
@ -185,19 +175,16 @@ public class ServerStarter {
|
|||||||
if(startingBau(owner))
|
if(startingBau(owner))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for (Subserver subserver : Subserver.getServerList()) {
|
Bauserver subserver = Bauserver.get(owner.getUniqueId());
|
||||||
if (subserver.getType() == Servertype.BAUSERVER && ((Bauserver) subserver).getOwner().equals(owner.getUniqueId()) && subserver.hasStarted()) {
|
if(subserver != null && subserver.isStarted())
|
||||||
subserver.stop();
|
subserver.stop();
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return !startingBau(owner);
|
return !startingBau(owner);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private void build(UUID owner) {
|
private void build(UUID owner) {
|
||||||
constructor = (serverName, port, builder, shutdownCallback) -> new Bauserver(serverName, owner, port, builder, shutdownCallback);
|
constructor = (serverName, port, builder, shutdownCallback, failureCallback) -> new Bauserver(serverName, owner, port, builder, shutdownCallback, failureCallback);
|
||||||
serverNameProvider = port -> bauServerName(SteamwarUser.get(owner));
|
serverNameProvider = port -> bauServerName(SteamwarUser.get(owner));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -207,17 +194,17 @@ public class ServerStarter {
|
|||||||
worldDir = version.getWorldFolder(BUILDER_BASE_PATH);
|
worldDir = version.getWorldFolder(BUILDER_BASE_PATH);
|
||||||
worldName = map;
|
worldName = map;
|
||||||
serverNameProvider = port -> "⛏" + map;
|
serverNameProvider = port -> "⛏" + map;
|
||||||
constructor = (serverName, port, builder, shutdownCallback) -> new Builderserver(serverName, worldName, port, builder, shutdownCallback);
|
checkpoint = true;
|
||||||
|
constructor = (serverName, port, builder, shutdownCallback, failureCallback) -> new Builderserver(serverName, worldName, port, builder, shutdownCallback, failureCallback);
|
||||||
|
|
||||||
// Send players to existing server
|
// Send players to existing server
|
||||||
startCondition = () -> {
|
startCondition = () -> {
|
||||||
for(Subserver subserver : Subserver.getServerList()) {
|
Builderserver subserver = Builderserver.get(worldName);
|
||||||
if(subserver.getType() == Servertype.BUILDER && ((Builderserver)subserver).getMap().equals(worldName)) {
|
if (subserver != null) {
|
||||||
for(ProxiedPlayer p : playersToSend)
|
for(Player p : playersToSend)
|
||||||
SubserverSystem.sendPlayer(subserver, p);
|
SubserverSystem.sendPlayer(subserver, p);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -235,14 +222,19 @@ public class ServerStarter {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ServerStarter send(ProxiedPlayer player) {
|
public ServerStarter send(Player player) {
|
||||||
playersToSend.add(player);
|
playersToSend.add(player);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Subserver start() {
|
public ServerStarter callback(Consumer<Subserver> callback) {
|
||||||
|
this.callback = callback;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean start() {
|
||||||
if(!startCondition.getAsBoolean())
|
if(!startCondition.getAsBoolean())
|
||||||
return null;
|
return false;
|
||||||
|
|
||||||
int port = portrange.freePort();
|
int port = portrange.freePort();
|
||||||
String serverName = serverNameProvider.apply(port);
|
String serverName = serverNameProvider.apply(port);
|
||||||
@ -250,10 +242,10 @@ public class ServerStarter {
|
|||||||
if(node == null) {
|
if(node == null) {
|
||||||
node = Node.getNode();
|
node = Node.getNode();
|
||||||
if(node == null) {
|
if(node == null) {
|
||||||
for (ProxiedPlayer p : playersToSend)
|
for (Player p : playersToSend)
|
||||||
ChatSender.of(p).system("SERVER_START_OVERLOAD");
|
ChatSender.of(p).system("SERVER_START_OVERLOAD");
|
||||||
|
|
||||||
return null;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(worldName == null)
|
if(worldName == null)
|
||||||
@ -262,22 +254,45 @@ public class ServerStarter {
|
|||||||
worldSetup.run();
|
worldSetup.run();
|
||||||
arguments.put("logPath", worldName);
|
arguments.put("logPath", worldName);
|
||||||
|
|
||||||
Subserver subserver = constructor.construct(serverName, port, node.startServer(
|
File checkpointDir = new File("/tmp/" + System.getProperty("user.name") + ".checkpoints/" + directory.getName() + "/" + worldName);
|
||||||
serverJar, directory, worldDir, worldName, port, xmx, arguments.entrySet().stream().map(entry -> entry.getKey() + "=" + entry.getValue()).toArray(String[]::new)
|
if(checkpoint)
|
||||||
), worldCleanup);
|
arguments.put("checkpoint", checkpointDir.getPath());
|
||||||
|
|
||||||
for(ProxiedPlayer p : playersToSend)
|
if(checkpoint && checkpointDir.exists()) {
|
||||||
SubserverSystem.sendPlayer(subserver, p);
|
try {
|
||||||
|
new DataOutputStream(Files.newOutputStream(new File(checkpointDir, "port").toPath())).writeInt(port);
|
||||||
return subserver;
|
} catch (IOException e) {
|
||||||
|
throw new SecurityException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
postStart(constructor.construct(serverName, port, node.prepareExecution(
|
||||||
|
"criu", "restore", "-D", checkpointDir.getPath(), "--auto-dedup", "--shell-job", "-v"
|
||||||
|
), worldCleanup, e -> regularStart(serverName, port)));
|
||||||
|
} else {
|
||||||
|
regularStart(serverName, port);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean startingBau(ProxiedPlayer p) {
|
|
||||||
for (Subserver subserver : Subserver.getServerList()) {
|
|
||||||
if (subserver.getType() == Servertype.BAUSERVER && ((Bauserver) subserver).getOwner().equals(p.getUniqueId()) && !subserver.hasStarted()) {
|
|
||||||
Message.send("BAU_START_ALREADY", p);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void regularStart(String serverName, int port) {
|
||||||
|
postStart(constructor.construct(serverName, port, node.startServer(
|
||||||
|
serverJar, directory, worldDir, worldName, port, xmx, arguments.entrySet().stream().map(entry -> entry.getKey() + "=" + entry.getValue()).toArray(String[]::new)
|
||||||
|
), worldCleanup, null));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void postStart(Subserver subserver) {
|
||||||
|
for(Player p : playersToSend)
|
||||||
|
SubserverSystem.sendPlayer(subserver, p);
|
||||||
|
|
||||||
|
callback.accept(subserver);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean startingBau(Player p) {
|
||||||
|
Bauserver subserver = Bauserver.get(p.getUniqueId());
|
||||||
|
if(subserver != null && !subserver.isStarted()) {
|
||||||
|
ChatSender.of(p).system("BAU_START_ALREADY");
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -295,7 +310,7 @@ public class ServerStarter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private interface ServerConstructor {
|
private interface ServerConstructor {
|
||||||
Subserver construct(String serverName, int port, ProcessBuilder builder, Runnable shutdownCallback);
|
Subserver construct(String serverName, int port, ProcessBuilder builder, Runnable shutdownCallback, Consumer<Exception> failureCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class Portrange {
|
private static class Portrange {
|
||||||
@ -334,10 +349,12 @@ public class ServerStarter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Getter
|
||||||
public enum Version {
|
public enum Version {
|
||||||
SPIGOT_12("spigot-1.12.2.jar", 12),
|
SPIGOT_12("spigot-1.12.2.jar", 12),
|
||||||
SPIGOT_15("spigot-1.15.2.jar", 15),
|
SPIGOT_15("spigot-1.15.2.jar", 15),
|
||||||
PAPER_19("paper-1.19.3.jar", 19);
|
PAPER_19("paper-1.19.3.jar", 19),
|
||||||
|
PAPER_20("paper-1.20.1.jar", 20);
|
||||||
|
|
||||||
private final String serverJar;
|
private final String serverJar;
|
||||||
private final int versionSuffix;
|
private final int versionSuffix;
|
||||||
@ -347,10 +364,6 @@ public class ServerStarter {
|
|||||||
this.versionSuffix = versionSuffix;
|
this.versionSuffix = versionSuffix;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getServerJar() {
|
|
||||||
return serverJar;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getWorldFolder(String base) {
|
public String getWorldFolder(String base) {
|
||||||
return base + versionSuffix + "/";
|
return base + versionSuffix + "/";
|
||||||
}
|
}
|
||||||
|
@ -19,14 +19,13 @@
|
|||||||
|
|
||||||
package de.steamwar.bungeecore;
|
package de.steamwar.bungeecore;
|
||||||
|
|
||||||
|
import com.velocitypowered.api.proxy.Player;
|
||||||
import de.steamwar.bungeecore.network.NetworkSender;
|
import de.steamwar.bungeecore.network.NetworkSender;
|
||||||
import de.steamwar.bungeecore.network.handlers.FightInfoHandler;
|
import de.steamwar.bungeecore.network.handlers.FightInfoHandler;
|
||||||
import de.steamwar.sql.IgnoreSystem;
|
import de.steamwar.sql.IgnoreSystem;
|
||||||
import de.steamwar.sql.SteamwarUser;
|
import de.steamwar.sql.SteamwarUser;
|
||||||
import de.steamwar.network.packets.server.StartingServerPacket;
|
import de.steamwar.network.packets.server.StartingServerPacket;
|
||||||
import net.md_5.bungee.api.ProxyServer;
|
import net.kyori.adventure.text.event.ClickEvent;
|
||||||
import net.md_5.bungee.api.chat.ClickEvent;
|
|
||||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
@ -37,23 +36,26 @@ public class SubserverSystem {
|
|||||||
node.execute("rm", "-r", worldName);
|
node.execute("rm", "-r", worldName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void sendDeniedMessage(ProxiedPlayer p, UUID owner){
|
public static void sendDeniedMessage(Player p, UUID owner){
|
||||||
ProxiedPlayer o = ProxyServer.getInstance().getPlayer(owner);
|
Player o = VelocityCore.get().getProxyServer().getPlayer(owner).orElse(null);
|
||||||
if(o == null)
|
|
||||||
|
if(o == null){
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if(IgnoreSystem.isIgnored(owner, p.getUniqueId())){
|
if(IgnoreSystem.isIgnored(owner, p.getUniqueId())){
|
||||||
Message.send("SERVER_IGNORED", p);
|
Message.send("SERVER_IGNORED", p);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Message.send("SERVER_ADD_MEMBER", o, p.getName());
|
Message.send("SERVER_ADD_MEMBER", o, p.getUsername());
|
||||||
Message.sendPrefixless("SERVER_ADD_MESSAGE", o, Message.parse("SERVER_ADD_MESSAGE_HOVER", o, p.getName()),
|
Message.sendPrefixless("SERVER_ADD_MESSAGE", o, Message.parse("SERVER_ADD_MESSAGE_HOVER", o, p.getUsername()),
|
||||||
new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/bau addmember " + p.getName()));
|
ClickEvent.runCommand("/bau addmember " + p.getUsername()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void sendPlayer(Subserver subserver, ProxiedPlayer player) {
|
public static void sendPlayer(Subserver subserver, Player player) {
|
||||||
subserver.sendPlayer(player);
|
subserver.sendPlayer(player);
|
||||||
if(!subserver.hasStarted() && FightInfoHandler.onLobby(player))
|
if(!subserver.isStarted() && FightInfoHandler.onLobby(player))
|
||||||
NetworkSender.send(player, new StartingServerPacket(SteamwarUser.get(player.getUniqueId()).getId()));
|
NetworkSender.send(player, new StartingServerPacket(SteamwarUser.get(player.getUniqueId()).getId()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,50 +19,51 @@
|
|||||||
|
|
||||||
package de.steamwar.bungeecore;
|
package de.steamwar.bungeecore;
|
||||||
|
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
import com.google.inject.Injector;
|
||||||
|
import com.velocitypowered.api.event.Subscribe;
|
||||||
|
import com.velocitypowered.api.event.proxy.ProxyInitializeEvent;
|
||||||
|
import com.velocitypowered.api.event.proxy.ProxyReloadEvent;
|
||||||
|
import com.velocitypowered.api.plugin.Plugin;
|
||||||
|
import com.velocitypowered.api.plugin.annotation.DataDirectory;
|
||||||
|
import com.velocitypowered.api.proxy.Player;
|
||||||
|
import com.velocitypowered.api.proxy.ProxyServer;
|
||||||
import de.steamwar.bungeecore.bot.SteamwarDiscordBot;
|
import de.steamwar.bungeecore.bot.SteamwarDiscordBot;
|
||||||
import de.steamwar.bungeecore.bot.config.SteamwarDiscordBotConfig;
|
import de.steamwar.bungeecore.bot.config.SteamwarDiscordBotConfig;
|
||||||
import de.steamwar.bungeecore.commands.*;
|
import de.steamwar.bungeecore.commands.*;
|
||||||
import de.steamwar.bungeecore.listeners.*;
|
import de.steamwar.bungeecore.listeners.*;
|
||||||
import de.steamwar.bungeecore.listeners.mods.*;
|
import de.steamwar.bungeecore.mods.ServerListPing;
|
||||||
import de.steamwar.bungeecore.listeners.ping.PingListener;
|
import de.steamwar.bungeecore.mods.*;
|
||||||
import de.steamwar.bungeecore.network.BungeeNetworkHandler;
|
import de.steamwar.bungeecore.network.BungeeNetworkHandler;
|
||||||
import de.steamwar.bungeecore.network.NetworkReceiver;
|
|
||||||
import de.steamwar.bungeecore.network.SWScriptSyntaxForwarder;
|
|
||||||
import de.steamwar.sql.Punishment;
|
|
||||||
import de.steamwar.sql.SteamwarUser;
|
|
||||||
import de.steamwar.sql.UserElo;
|
|
||||||
import de.steamwar.bungeecore.tablist.TablistManager;
|
import de.steamwar.bungeecore.tablist.TablistManager;
|
||||||
|
import de.steamwar.bungeecore.util.SteamWarModule;
|
||||||
|
import de.steamwar.bungeecore.util.annotations.Create;
|
||||||
import de.steamwar.command.SWCommandUtils;
|
import de.steamwar.command.SWCommandUtils;
|
||||||
import de.steamwar.command.SWTypeMapperCreator;
|
import de.steamwar.command.SWTypeMapperCreator;
|
||||||
import de.steamwar.command.TabCompletionCache;
|
import de.steamwar.command.TabCompletionCache;
|
||||||
import de.steamwar.command.TypeMapper;
|
import de.steamwar.command.TypeMapper;
|
||||||
|
import de.steamwar.sql.Punishment;
|
||||||
|
import de.steamwar.sql.SteamwarUser;
|
||||||
import de.steamwar.sql.Team;
|
import de.steamwar.sql.Team;
|
||||||
|
import de.steamwar.sql.UserElo;
|
||||||
import de.steamwar.sql.internal.Statement;
|
import de.steamwar.sql.internal.Statement;
|
||||||
import net.md_5.bungee.BungeeCord;
|
import lombok.Getter;
|
||||||
import net.md_5.bungee.api.ChatMessageType;
|
import org.reflections.Reflections;
|
||||||
import net.md_5.bungee.api.CommandSender;
|
|
||||||
import net.md_5.bungee.api.ProxyServer;
|
|
||||||
import net.md_5.bungee.api.chat.ClickEvent;
|
|
||||||
import net.md_5.bungee.api.chat.HoverEvent;
|
|
||||||
import net.md_5.bungee.api.chat.TextComponent;
|
|
||||||
import net.md_5.bungee.api.config.ServerInfo;
|
|
||||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
|
||||||
import net.md_5.bungee.api.plugin.Plugin;
|
|
||||||
import net.md_5.bungee.config.Configuration;
|
|
||||||
import net.md_5.bungee.config.ConfigurationProvider;
|
|
||||||
import net.md_5.bungee.config.YamlConfiguration;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.InetSocketAddress;
|
import java.nio.file.Path;
|
||||||
import java.util.Collection;
|
import java.util.*;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
public class BungeeCore extends Plugin {
|
@Plugin(
|
||||||
|
id = "velocitycore",
|
||||||
|
name = "VelocityCore",
|
||||||
|
authors = {"SteamWar"}
|
||||||
|
)
|
||||||
|
public class VelocityCore {
|
||||||
|
|
||||||
public static boolean MAIN_SERVER;
|
public static boolean MAIN_SERVER;
|
||||||
|
|
||||||
@ -70,69 +71,76 @@ public class BungeeCore extends Plugin {
|
|||||||
public static String LOBBY_SERVER;
|
public static String LOBBY_SERVER;
|
||||||
public static boolean EVENT_MODE;
|
public static boolean EVENT_MODE;
|
||||||
|
|
||||||
private static BungeeCore instance;
|
private static VelocityCore instance;
|
||||||
|
|
||||||
public static final Map<String, String> serverPermissions = new HashMap<>();
|
|
||||||
public static final Map<String, String> commands = new HashMap<>();
|
|
||||||
|
|
||||||
public static Node local;
|
|
||||||
private ErrorLogger errorLogger;
|
private ErrorLogger errorLogger;
|
||||||
private TablistManager tablistManager;
|
private TablistManager tablistManager;
|
||||||
|
|
||||||
@Override
|
@Getter
|
||||||
public void onEnable(){
|
private final ProxyServer proxyServer;
|
||||||
getProxy().registerChannel("sw:bridge");
|
|
||||||
getProxy().registerChannel("fabricmodsender:mods");
|
|
||||||
getProxy().registerChannel("nochatreports:sync");
|
|
||||||
getProxy().registerChannel("sw:script_syntax");
|
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private final Logger logger;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private final Path dataDirectory;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private Injector injector;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public VelocityCore(ProxyServer proxyServer, Logger logger, @DataDirectory Path dataDirectory, Injector injector) {
|
||||||
|
this.proxyServer = proxyServer;
|
||||||
|
this.logger = logger;
|
||||||
|
this.dataDirectory = dataDirectory;
|
||||||
|
this.injector = injector;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onProxyInitialization(ProxyInitializeEvent event) {
|
||||||
setInstance(this);
|
setInstance(this);
|
||||||
MAIN_SERVER = ProxyServer.getInstance().getConfig().getListeners().stream().anyMatch(info -> ((InetSocketAddress) info.getSocketAddress()).getPort() == 25565);
|
MAIN_SERVER = proxyServer.getBoundAddress().getPort() == 25565;
|
||||||
loadConfig();
|
loadConfig();
|
||||||
|
|
||||||
|
injector = injector.createChildInjector(new SteamWarModule(this));
|
||||||
|
|
||||||
errorLogger = new ErrorLogger();
|
errorLogger = new ErrorLogger();
|
||||||
|
|
||||||
SWCommandUtils.init((SWTypeMapperCreator<TypeMapper<Object>, CommandSender, Object>) (mapper, tabCompleter) -> new TypeMapper<Object>() {
|
SWCommandUtils.init((SWTypeMapperCreator<TypeMapper<Object>, Player, Object>) (mapper, tabCompleter) -> new TypeMapper<Object>() {
|
||||||
@Override
|
@Override
|
||||||
public Object map(CommandSender commandSender, String[] previousArguments, String s) {
|
public Object map(Player commandSender, String[] previousArguments, String s) {
|
||||||
return mapper.apply(s);
|
return mapper.apply(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<String> tabCompletes(CommandSender sender, String[] previousArguments, String s) {
|
public Collection<String> tabCompletes(Player sender, String[] previousArguments, String s) {
|
||||||
return tabCompleter.apply(sender, s);
|
return tabCompleter.apply(sender, s);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
BungeeCord.getInstance().getScheduler().schedule(this, TabCompletionCache::invalidateOldEntries, 1, 1, TimeUnit.SECONDS);
|
proxyServer.getScheduler().buildTask(this, TabCompletionCache::invalidateOldEntries).repeat(1, TimeUnit.SECONDS);
|
||||||
|
|
||||||
new NonFabricFabricCheck();
|
Reflections reflections = new Reflections("de.steamwar.bungeecore");
|
||||||
|
reflections.getTypesAnnotatedWith(Create.class)
|
||||||
|
.forEach(clazz -> {
|
||||||
|
Create create = clazz.getAnnotation(Create.class);
|
||||||
|
if (create.eventProxy() || MAIN_SERVER) {
|
||||||
|
Object obj = injector.getInstance(clazz);
|
||||||
|
if (Arrays.stream(clazz.getDeclaredMethods()).anyMatch(method -> method.isAnnotationPresent(Subscribe.class))) {
|
||||||
|
proxyServer.getEventManager().register(this, obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
new SWScriptSyntaxForwarder();
|
|
||||||
new ConnectionListener();
|
new ConnectionListener();
|
||||||
new Forge();
|
|
||||||
new Forge12();
|
|
||||||
new LabyMod();
|
|
||||||
new Badlion();
|
|
||||||
new ChatListener();
|
new ChatListener();
|
||||||
new BanListener();
|
new BanListener();
|
||||||
new CheckListener();
|
new CheckListener();
|
||||||
new ModLoaderBlocker();
|
new IPSanitizer();
|
||||||
new WorldDownloader();
|
|
||||||
new BrandListener();
|
|
||||||
new Fabric();
|
|
||||||
new SubserverProtocolFixer();
|
|
||||||
new PingListener();
|
|
||||||
|
|
||||||
local = new Node.LocalNode();
|
|
||||||
if(MAIN_SERVER) {
|
if(MAIN_SERVER) {
|
||||||
//new Node.RemoteNode("lx");
|
//new Node.RemoteNode("lx");
|
||||||
}
|
}
|
||||||
|
|
||||||
commands.put("/tp", null);
|
|
||||||
commands.put("/bc", null);
|
|
||||||
commands.put("/bauchat", null);
|
|
||||||
commands.put("/local", null);
|
|
||||||
|
|
||||||
new TeamchatCommand();
|
new TeamchatCommand();
|
||||||
new MsgCommand();
|
new MsgCommand();
|
||||||
new RCommand();
|
new RCommand();
|
||||||
@ -166,9 +174,6 @@ public class BungeeCore extends Plugin {
|
|||||||
new SetLocaleCommand();
|
new SetLocaleCommand();
|
||||||
new BuilderCloudCommand();
|
new BuilderCloudCommand();
|
||||||
|
|
||||||
new CalendarCommand();
|
|
||||||
new CalendarListener();
|
|
||||||
|
|
||||||
new ModCommand();
|
new ModCommand();
|
||||||
|
|
||||||
// Punishment Commands:
|
// Punishment Commands:
|
||||||
@ -199,16 +204,15 @@ public class BungeeCore extends Plugin {
|
|||||||
|
|
||||||
new EventStarter();
|
new EventStarter();
|
||||||
new SessionManager();
|
new SessionManager();
|
||||||
new NetworkReceiver();
|
|
||||||
BungeeNetworkHandler.register();
|
BungeeNetworkHandler.register();
|
||||||
tablistManager = new TablistManager();
|
tablistManager = new TablistManager();
|
||||||
new SettingsChangedListener();
|
new SettingsChangedListener();
|
||||||
|
|
||||||
getProxy().getScheduler().schedule(this, () -> {
|
proxyServer.getScheduler().buildTask(this, () -> {
|
||||||
SteamwarUser.clear();
|
SteamwarUser.clear();
|
||||||
UserElo.clear();
|
UserElo.clear();
|
||||||
Team.clear();
|
Team.clear();
|
||||||
}, 1, 1, TimeUnit.HOURS);
|
}).repeat(1, TimeUnit.HOURS);
|
||||||
|
|
||||||
if (SteamwarDiscordBotConfig.loaded) {
|
if (SteamwarDiscordBotConfig.loaded) {
|
||||||
try {
|
try {
|
||||||
@ -219,8 +223,8 @@ public class BungeeCore extends Plugin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Subscribe
|
||||||
public void onDisable(){
|
public void onDisable(ProxyReloadEvent event) {
|
||||||
if (SteamwarDiscordBotConfig.loaded) {
|
if (SteamwarDiscordBotConfig.loaded) {
|
||||||
try {
|
try {
|
||||||
SteamwarDiscordBot.instance().getJda().shutdown();
|
SteamwarDiscordBot.instance().getJda().shutdown();
|
||||||
@ -235,64 +239,10 @@ public class BungeeCore extends Plugin {
|
|||||||
Statement.closeAll();
|
Statement.closeAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BungeeCore get() {
|
public static VelocityCore get() {
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TextComponent stringToText(String msg){
|
|
||||||
return new TextComponent(TextComponent.fromLegacyText(msg));
|
|
||||||
}
|
|
||||||
public static void send(ProxiedPlayer player, String msg){
|
|
||||||
send(player, msg, null, null);
|
|
||||||
}
|
|
||||||
public static void send(CommandSender sender, String msg){
|
|
||||||
sender.sendMessage(stringToText(msg));
|
|
||||||
}
|
|
||||||
public static void send(ProxiedPlayer player, ChatMessageType type, String msg){
|
|
||||||
send(player, type, msg, null, null);
|
|
||||||
}
|
|
||||||
public static void send(ProxiedPlayer player, String msg, String onHover, ClickEvent onClick){
|
|
||||||
send(player, ChatMessageType.SYSTEM, msg, onHover, onClick);
|
|
||||||
}
|
|
||||||
public static void send(ProxiedPlayer player, ChatMessageType type, String msg, String onHover, ClickEvent onClick){
|
|
||||||
if(type == ChatMessageType.CHAT && player.getChatMode() != ProxiedPlayer.ChatMode.SHOWN)
|
|
||||||
return;
|
|
||||||
TextComponent message = stringToText(msg);
|
|
||||||
if(onHover != null)
|
|
||||||
message.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, TextComponent.fromLegacyText(onHover)));
|
|
||||||
if(onClick != null)
|
|
||||||
message.setClickEvent(onClick);
|
|
||||||
player.sendMessage(type, message);
|
|
||||||
}
|
|
||||||
public static void broadcast(String msg){
|
|
||||||
ProxyServer.getInstance().broadcast(stringToText(msg));
|
|
||||||
}
|
|
||||||
public static void broadcast(String msg, String onHover, ClickEvent onClick){
|
|
||||||
TextComponent message = stringToText(msg);
|
|
||||||
if(onHover != null)
|
|
||||||
message.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, TextComponent.fromLegacyText(onHover)));
|
|
||||||
if(onClick != null)
|
|
||||||
message.setClickEvent(onClick);
|
|
||||||
ProxyServer.getInstance().broadcast(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void log(final ServerInfo server, final String msg){
|
|
||||||
log(server.getName() + ": " + msg);
|
|
||||||
}
|
|
||||||
public static void log(final ProxiedPlayer player, final String msg){
|
|
||||||
log(player.getName() + ": " + msg);
|
|
||||||
}
|
|
||||||
public static void log(final String msg){
|
|
||||||
log(Level.INFO, msg);
|
|
||||||
}
|
|
||||||
public static void log(final Level logLevel, final String msg){
|
|
||||||
get().getLogger().log(logLevel, msg);
|
|
||||||
}
|
|
||||||
public static void log(final String msg, final Throwable e){
|
|
||||||
get().getLogger().log(Level.SEVERE, msg, e);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private static void loadConfig(){
|
private static void loadConfig(){
|
||||||
Configuration config;
|
Configuration config;
|
||||||
try{
|
try{
|
||||||
@ -319,24 +269,21 @@ public class BungeeCore extends Plugin {
|
|||||||
EVENT_MODE = config.getBoolean("eventmode");
|
EVENT_MODE = config.getBoolean("eventmode");
|
||||||
Broadcaster.setBroadCastMsgs(config.getStringList("broadcasts").toArray(new String[1]));
|
Broadcaster.setBroadCastMsgs(config.getStringList("broadcasts").toArray(new String[1]));
|
||||||
PollSystem.init(config.getString("poll.question"), config.getStringList("poll.answers"));
|
PollSystem.init(config.getString("poll.question"), config.getStringList("poll.answers"));
|
||||||
Persistent.setChatPrefix(CHAT_PREFIX);
|
|
||||||
Persistent.setLobbyServer(LOBBY_SERVER);
|
|
||||||
|
|
||||||
final Configuration servers = config.getSection("servers");
|
final Configuration servers = config.getSection("servers");
|
||||||
for(final String serverName : servers.getKeys()){
|
for(final String serverName : servers.getKeys()){
|
||||||
final Configuration server = servers.getSection(serverName);
|
final Configuration server = servers.getSection(serverName);
|
||||||
List<String> cmds = server.getStringList("commands");
|
List<String> cmds = server.getStringList("commands");
|
||||||
serverPermissions.put(serverName, "bungeecore.server." + server.getString("permission"));
|
|
||||||
String cmd = cmds.remove(0);
|
String cmd = cmds.remove(0);
|
||||||
|
|
||||||
|
if(server.contains("spectatePort"))
|
||||||
|
EventStarter.addSpectateServer(server.getInt("spectatePort"), cmd);
|
||||||
|
|
||||||
new ServerSwitchCommand(
|
new ServerSwitchCommand(
|
||||||
cmd,
|
cmd,
|
||||||
serverName,
|
serverName,
|
||||||
serverPermissions.get(serverName),
|
|
||||||
cmds.toArray(new String[0])
|
cmds.toArray(new String[0])
|
||||||
);
|
);
|
||||||
if(server.getBoolean("modchecked", false)) {
|
|
||||||
ModLoaderBlocker.addServer(serverName);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
File discordFile = new File(System.getProperty("user.home"), "discord.yml");
|
File discordFile = new File(System.getProperty("user.home"), "discord.yml");
|
||||||
@ -349,7 +296,7 @@ public class BungeeCore extends Plugin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void setInstance(BungeeCore core){
|
private static void setInstance(VelocityCore core){
|
||||||
instance = core;
|
instance = core;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
package de.steamwar.bungeecore.bot;
|
package de.steamwar.bungeecore.bot;
|
||||||
|
|
||||||
import de.steamwar.bungeecore.BungeeCore;
|
import de.steamwar.bungeecore.VelocityCore;
|
||||||
import de.steamwar.bungeecore.bot.config.SteamwarDiscordBotConfig;
|
import de.steamwar.bungeecore.bot.config.SteamwarDiscordBotConfig;
|
||||||
import de.steamwar.sql.SteamwarUser;
|
import de.steamwar.sql.SteamwarUser;
|
||||||
import net.dv8tion.jda.api.MessageBuilder;
|
import net.dv8tion.jda.api.MessageBuilder;
|
||||||
@ -46,8 +46,8 @@ public class AuthManager {
|
|||||||
String code = Base64.getEncoder().encodeToString(randBytes);
|
String code = Base64.getEncoder().encodeToString(randBytes);
|
||||||
|
|
||||||
TOKENS.put(code, member.getIdLong());
|
TOKENS.put(code, member.getIdLong());
|
||||||
BungeeCore.log("Created Discord Auth-Token: " + code + " for: " + member.getUser().getAsTag());
|
VelocityCore.log("Created Discord Auth-Token: " + code + " for: " + member.getUser().getAsTag());
|
||||||
BungeeCore.get().getProxy().getScheduler().schedule(BungeeCore.get(), () -> TOKENS.remove(code), 10, TimeUnit.MINUTES);
|
VelocityCore.get().getProxy().getScheduler().schedule(VelocityCore.get(), () -> TOKENS.remove(code), 10, TimeUnit.MINUTES);
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
package de.steamwar.bungeecore.bot;
|
package de.steamwar.bungeecore.bot;
|
||||||
|
|
||||||
import de.steamwar.bungeecore.BungeeCore;
|
import de.steamwar.bungeecore.VelocityCore;
|
||||||
import de.steamwar.bungeecore.bot.commands.*;
|
import de.steamwar.bungeecore.bot.commands.*;
|
||||||
import de.steamwar.bungeecore.bot.config.SteamwarDiscordBotConfig;
|
import de.steamwar.bungeecore.bot.config.SteamwarDiscordBotConfig;
|
||||||
import de.steamwar.bungeecore.bot.events.EventManager;
|
import de.steamwar.bungeecore.bot.events.EventManager;
|
||||||
@ -81,7 +81,7 @@ public class SteamwarDiscordBot {
|
|||||||
} catch (LoginException e) {
|
} catch (LoginException e) {
|
||||||
throw new SecurityException("Could not Login: " + SteamwarDiscordBotConfig.TOKEN, e);
|
throw new SecurityException("Could not Login: " + SteamwarDiscordBotConfig.TOKEN, e);
|
||||||
}
|
}
|
||||||
ProxyServer.getInstance().getScheduler().runAsync(BungeeCore.get(), () -> {
|
ProxyServer.getInstance().getScheduler().runAsync(VelocityCore.get(), () -> {
|
||||||
try {
|
try {
|
||||||
jda.awaitReady();
|
jda.awaitReady();
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
@ -90,11 +90,11 @@ public class SteamwarDiscordBot {
|
|||||||
try {
|
try {
|
||||||
activity();
|
activity();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
BungeeCore.get().getLogger().log(Level.SEVERE, "Could not set initial activity to discord", e);
|
VelocityCore.get().getLogger().log(Level.SEVERE, "Could not set initial activity to discord", e);
|
||||||
}
|
}
|
||||||
EventManager.update();
|
EventManager.update();
|
||||||
SchematicsManager.update();
|
SchematicsManager.update();
|
||||||
ProxyServer.getInstance().getScheduler().schedule(BungeeCore.get(), () -> {
|
ProxyServer.getInstance().getScheduler().schedule(VelocityCore.get(), () -> {
|
||||||
try {
|
try {
|
||||||
activity();
|
activity();
|
||||||
EventManager.update();
|
EventManager.update();
|
||||||
@ -148,7 +148,7 @@ public class SteamwarDiscordBot {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
int count = BungeeCore.get().getProxy().getOnlineCount();
|
int count = VelocityCore.get().getProxy().getOnlineCount();
|
||||||
if (count == 1) {
|
if (count == 1) {
|
||||||
jda.getPresence().setActivity(Activity.playing("mit 1 Spieler"));
|
jda.getPresence().setActivity(Activity.playing("mit 1 Spieler"));
|
||||||
} else {
|
} else {
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
package de.steamwar.bungeecore.bot.commands;
|
package de.steamwar.bungeecore.bot.commands;
|
||||||
|
|
||||||
import de.steamwar.sql.SteamwarUser;
|
import de.steamwar.sql.SteamwarUser;
|
||||||
import de.steamwar.sql.UserGroup;
|
import de.steamwar.sql.UserPerm;
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
import net.dv8tion.jda.api.events.interaction.SlashCommandEvent;
|
import net.dv8tion.jda.api.events.interaction.SlashCommandEvent;
|
||||||
import net.dv8tion.jda.api.interactions.commands.build.CommandData;
|
import net.dv8tion.jda.api.interactions.commands.build.CommandData;
|
||||||
@ -45,7 +45,7 @@ public abstract class BasicDiscordCommand extends CommandData {
|
|||||||
protected boolean testPermission(SlashCommandEvent event) {
|
protected boolean testPermission(SlashCommandEvent event) {
|
||||||
Member member = event.getMember();
|
Member member = event.getMember();
|
||||||
SteamwarUser steamwarUser = SteamwarUser.get(member.getIdLong());
|
SteamwarUser steamwarUser = SteamwarUser.get(member.getIdLong());
|
||||||
if (steamwarUser == null || (!steamwarUser.getUserGroup().isTeamGroup() && steamwarUser.getUserGroup() != UserGroup.Builder)) {
|
if (steamwarUser == null || (!steamwarUser.hasPerm(UserPerm.TEAM))) {
|
||||||
event.reply("Du hast für " + event.getName() + " keine Rechte oder es existiert keine Verknüpfung für dich.").setEphemeral(true).queue();
|
event.reply("Du hast für " + event.getName() + " keine Rechte oder es existiert keine Verknüpfung für dich.").setEphemeral(true).queue();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
package de.steamwar.bungeecore.bot.config;
|
package de.steamwar.bungeecore.bot.config;
|
||||||
|
|
||||||
import de.steamwar.sql.UserGroup;
|
import de.steamwar.sql.UserPerm;
|
||||||
import net.md_5.bungee.config.Configuration;
|
import net.md_5.bungee.config.Configuration;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -52,7 +52,7 @@ public class SteamwarDiscordBotConfig {
|
|||||||
public static String TICKET_CREATED;
|
public static String TICKET_CREATED;
|
||||||
public static String TICKET_LOG;
|
public static String TICKET_LOG;
|
||||||
public static Map<String, DiscordTicketType> TICKET_TYPES;
|
public static Map<String, DiscordTicketType> TICKET_TYPES;
|
||||||
public static Map<UserGroup, String> RANKS;
|
public static Map<UserPerm, String> RANKS;
|
||||||
|
|
||||||
public static void loadConfig(Configuration config) {
|
public static void loadConfig(Configuration config) {
|
||||||
TOKEN = config.getString("token");
|
TOKEN = config.getString("token");
|
||||||
@ -109,7 +109,7 @@ public class SteamwarDiscordBotConfig {
|
|||||||
RANKS = new HashMap<>();
|
RANKS = new HashMap<>();
|
||||||
Configuration ranksSections = config.getSection("ranks");
|
Configuration ranksSections = config.getSection("ranks");
|
||||||
for (String type : ranksSections.getKeys()) {
|
for (String type : ranksSections.getKeys()) {
|
||||||
RANKS.put(UserGroup.getUsergroup(type), ranksSections.getString(type));
|
RANKS.put(UserPerm.valueOf(type.toUpperCase()), ranksSections.getString(type));
|
||||||
}
|
}
|
||||||
loaded = true;
|
loaded = true;
|
||||||
}
|
}
|
||||||
|
@ -19,11 +19,12 @@
|
|||||||
|
|
||||||
package de.steamwar.bungeecore.bot.listeners;
|
package de.steamwar.bungeecore.bot.listeners;
|
||||||
|
|
||||||
import de.steamwar.bungeecore.BungeeCore;
|
import de.steamwar.bungeecore.VelocityCore;
|
||||||
import de.steamwar.bungeecore.Message;
|
import de.steamwar.bungeecore.Message;
|
||||||
import de.steamwar.bungeecore.bot.config.DiscordTicketType;
|
import de.steamwar.bungeecore.bot.config.DiscordTicketType;
|
||||||
import de.steamwar.bungeecore.bot.config.SteamwarDiscordBotConfig;
|
import de.steamwar.bungeecore.bot.config.SteamwarDiscordBotConfig;
|
||||||
import de.steamwar.sql.SteamwarUser;
|
import de.steamwar.sql.SteamwarUser;
|
||||||
|
import de.steamwar.sql.UserPerm;
|
||||||
import net.dv8tion.jda.api.EmbedBuilder;
|
import net.dv8tion.jda.api.EmbedBuilder;
|
||||||
import net.dv8tion.jda.api.MessageBuilder;
|
import net.dv8tion.jda.api.MessageBuilder;
|
||||||
import net.dv8tion.jda.api.Permission;
|
import net.dv8tion.jda.api.Permission;
|
||||||
@ -136,15 +137,15 @@ public class DiscordTicketListener extends BasicDiscordListener {
|
|||||||
public void onGuildMessageReceived(@NotNull GuildMessageReceivedEvent event) {
|
public void onGuildMessageReceived(@NotNull GuildMessageReceivedEvent event) {
|
||||||
if(event.getChannel().getParent() != null && event.getChannel().getParent().getId().equals(SteamwarDiscordBotConfig.TICKET_CATEGORY)) {
|
if(event.getChannel().getParent() != null && event.getChannel().getParent().getId().equals(SteamwarDiscordBotConfig.TICKET_CATEGORY)) {
|
||||||
if(!event.getChannel().getId().equals(SteamwarDiscordBotConfig.TICKET_CHANNEL) && !event.getChannel().getId().equals(SteamwarDiscordBotConfig.TICKET_LOG)) {
|
if(!event.getChannel().getId().equals(SteamwarDiscordBotConfig.TICKET_CHANNEL) && !event.getChannel().getId().equals(SteamwarDiscordBotConfig.TICKET_LOG)) {
|
||||||
BungeeCore.get().getProxy().getPlayers().forEach(player -> {
|
VelocityCore.get().getProxy().getPlayers().forEach(player -> {
|
||||||
if(event.getAuthor().isBot() || event.getAuthor().isSystem()) return;
|
if(event.getAuthor().isBot() || event.getAuthor().isSystem()) return;
|
||||||
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
||||||
boolean sendMessage;
|
boolean sendMessage;
|
||||||
if(user.getDiscordId() == null) {
|
if(user.getDiscordId() == null) {
|
||||||
sendMessage = user.getUserGroup().isCheckSchematics();
|
sendMessage = user.hasPerm(UserPerm.CHECK);
|
||||||
} else {
|
} else {
|
||||||
if(event.getAuthor().getId().equals(user.getDiscordId())) return;
|
if(event.getAuthor().getId().equals(user.getDiscordId())) return;
|
||||||
sendMessage = user.getDiscordId().equals(event.getChannel().getTopic()) || user.getUserGroup().isCheckSchematics();
|
sendMessage = user.getDiscordId().equals(event.getChannel().getTopic()) || user.hasPerm(UserPerm.CHECK);
|
||||||
}
|
}
|
||||||
if(sendMessage) {
|
if(sendMessage) {
|
||||||
Message.sendPrefixless("DISCORD_TICKET_MESSAGE", player, "Zur nachricht", new ClickEvent(ClickEvent.Action.OPEN_URL, event.getMessage().getJumpUrl()), event.getChannel().getName(), event.getAuthor().getName(), event.getMessage().getContentRaw());
|
Message.sendPrefixless("DISCORD_TICKET_MESSAGE", player, "Zur nachricht", new ClickEvent(ClickEvent.Action.OPEN_URL, event.getMessage().getJumpUrl()), event.getChannel().getName(), event.getAuthor().getName(), event.getMessage().getContentRaw());
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
package de.steamwar.bungeecore.bot.listeners;
|
package de.steamwar.bungeecore.bot.listeners;
|
||||||
|
|
||||||
import de.steamwar.bungeecore.BungeeCore;
|
import de.steamwar.bungeecore.VelocityCore;
|
||||||
import de.steamwar.sql.NodeData;
|
import de.steamwar.sql.NodeData;
|
||||||
import de.steamwar.sql.Punishment;
|
import de.steamwar.sql.Punishment;
|
||||||
import de.steamwar.sql.SchematicNode;
|
import de.steamwar.sql.SchematicNode;
|
||||||
@ -72,7 +72,7 @@ public class PrivateMessageListener extends BasicDiscordListener {
|
|||||||
event.getMessage().reply("`" + name + "` wurde erfolgreich hochgeladen").queue();
|
event.getMessage().reply("`" + name + "` wurde erfolgreich hochgeladen").queue();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
event.getMessage().reply("`" + name + "` konnte nicht hochgeladen werden, bitte versuche es später nochmal oder wende dich an einen Developer").queue();
|
event.getMessage().reply("`" + name + "` konnte nicht hochgeladen werden, bitte versuche es später nochmal oder wende dich an einen Developer").queue();
|
||||||
BungeeCore.log("Could not Upload Schem \"" + name + "\" from User \"" + user.getUserName() + "\"", e);
|
VelocityCore.log("Could not Upload Schem \"" + name + "\" from User \"" + user.getUserName() + "\"", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ public class DiscordRanks {
|
|||||||
guild.retrieveMemberById(steamwarUser.getDiscordId()).queue(member -> {
|
guild.retrieveMemberById(steamwarUser.getDiscordId()).queue(member -> {
|
||||||
List<Role> roleList = member.getRoles();
|
List<Role> roleList = member.getRoles();
|
||||||
Set<String> strings = new HashSet<>(SteamwarDiscordBotConfig.RANKS.values());
|
Set<String> strings = new HashSet<>(SteamwarDiscordBotConfig.RANKS.values());
|
||||||
String needed = SteamwarDiscordBotConfig.RANKS.get(steamwarUser.getUserGroup());
|
String needed = SteamwarDiscordBotConfig.RANKS.get(steamwarUser.prefix());
|
||||||
for (Role role : roleList) {
|
for (Role role : roleList) {
|
||||||
if (!strings.contains(role.getId())) {
|
if (!strings.contains(role.getId())) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -21,6 +21,7 @@ package de.steamwar.bungeecore.commands;
|
|||||||
|
|
||||||
import de.steamwar.bungeecore.Message;
|
import de.steamwar.bungeecore.Message;
|
||||||
import de.steamwar.bungeecore.bot.SteamwarDiscordBot;
|
import de.steamwar.bungeecore.bot.SteamwarDiscordBot;
|
||||||
|
import de.steamwar.bungeecore.listeners.ConnectionListener;
|
||||||
import de.steamwar.command.SWCommand;
|
import de.steamwar.command.SWCommand;
|
||||||
import de.steamwar.messages.ChatSender;
|
import de.steamwar.messages.ChatSender;
|
||||||
import net.md_5.bungee.api.ChatColor;
|
import net.md_5.bungee.api.ChatColor;
|
||||||
@ -29,7 +30,7 @@ import net.md_5.bungee.api.CommandSender;
|
|||||||
public class AlertCommand extends SWCommand {
|
public class AlertCommand extends SWCommand {
|
||||||
|
|
||||||
public AlertCommand() {
|
public AlertCommand() {
|
||||||
super("alert", "bungeecore.alert", "broadcast", "bbc");
|
super("alert", ConnectionListener.ALERT_PERMISSION, "broadcast", "bbc");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Register(description = "USAGE_ALERT")
|
@Register(description = "USAGE_ALERT")
|
||||||
|
@ -24,13 +24,13 @@ import de.steamwar.bungeecore.inventory.SWInventory;
|
|||||||
import de.steamwar.bungeecore.inventory.SWItem;
|
import de.steamwar.bungeecore.inventory.SWItem;
|
||||||
import de.steamwar.bungeecore.network.NetworkSender;
|
import de.steamwar.bungeecore.network.NetworkSender;
|
||||||
import de.steamwar.bungeecore.util.BauLock;
|
import de.steamwar.bungeecore.util.BauLock;
|
||||||
|
import de.steamwar.bungeecore.util.BauLockState;
|
||||||
import de.steamwar.bungeecore.util.Chat19;
|
import de.steamwar.bungeecore.util.Chat19;
|
||||||
|
import de.steamwar.command.PreviousArguments;
|
||||||
import de.steamwar.command.SWCommand;
|
import de.steamwar.command.SWCommand;
|
||||||
import de.steamwar.command.TypeMapper;
|
import de.steamwar.command.TypeMapper;
|
||||||
import de.steamwar.command.TypeValidator;
|
import de.steamwar.command.TypeValidator;
|
||||||
import de.steamwar.messages.ChatSender;
|
|
||||||
import de.steamwar.network.packets.server.BaumemberUpdatePacket;
|
import de.steamwar.network.packets.server.BaumemberUpdatePacket;
|
||||||
import de.steamwar.bungeecore.util.BauLockState;
|
|
||||||
import de.steamwar.sql.BauweltMember;
|
import de.steamwar.sql.BauweltMember;
|
||||||
import de.steamwar.sql.SteamwarUser;
|
import de.steamwar.sql.SteamwarUser;
|
||||||
import net.md_5.bungee.api.CommandSender;
|
import net.md_5.bungee.api.CommandSender;
|
||||||
@ -39,8 +39,10 @@ import net.md_5.bungee.api.config.ServerInfo;
|
|||||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class BauCommand extends SWCommand {
|
public class BauCommand extends SWCommand {
|
||||||
|
|
||||||
@ -57,61 +59,48 @@ public class BauCommand extends SWCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Register
|
@Register
|
||||||
public void toBau(ProxiedPlayer p, @Mapper("version") @OptionalValue(value = "", onlyUINIG = true) int version) {
|
public void toBau(ProxiedPlayer p, @Mapper("version") @OptionalValue(value = "", onlyUINIG = true) ServerStarter.Version version) {
|
||||||
versionSelector(version,
|
new ServerStarter().build(version, p.getUniqueId()).send(p).start();
|
||||||
() -> new ServerStarter().build12(p.getUniqueId()).send(p).start(),
|
|
||||||
() -> new ServerStarter().build15(p.getUniqueId()).send(p).start(),
|
|
||||||
() -> new ServerStarter().build19(p.getUniqueId()).send(p).start()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void versionSelector(int version, Runnable r12, Runnable r15, Runnable r19) {
|
|
||||||
switch (version) {
|
|
||||||
case 12:
|
|
||||||
r12.run();
|
|
||||||
break;
|
|
||||||
case 15:
|
|
||||||
r15.run();
|
|
||||||
break;
|
|
||||||
case 19:
|
|
||||||
r19.run();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Mapper(value = "version", local = true)
|
@Mapper(value = "version", local = true)
|
||||||
public TypeMapper<Integer> versionMapper() {
|
public TypeMapper<ServerStarter.Version> versionMapper() {
|
||||||
Map<String, Integer> versionMap = new HashMap<>();
|
Map<String, ServerStarter.Version> versionMap = new HashMap<>();
|
||||||
versionMap.put("19", 19);
|
versionMap.put("20", ServerStarter.Version.PAPER_20);
|
||||||
versionMap.put("1.19", 19);
|
versionMap.put("1.20", ServerStarter.Version.PAPER_20);
|
||||||
versionMap.put("mwg", 19);
|
versionMap.put("as", ServerStarter.Version.PAPER_20);
|
||||||
versionMap.put("miniwargear", 19);
|
versionMap.put("airship", ServerStarter.Version.PAPER_20);
|
||||||
versionMap.put("wg", 19);
|
versionMap.put("wg", ServerStarter.Version.PAPER_20);
|
||||||
versionMap.put("wargear", 19);
|
versionMap.put("wargear", ServerStarter.Version.PAPER_20);
|
||||||
versionMap.put("ws", 15);
|
versionMap.put("ws", ServerStarter.Version.PAPER_20);
|
||||||
|
versionMap.put("warship", ServerStarter.Version.PAPER_20);
|
||||||
|
|
||||||
versionMap.put("15", 15);
|
versionMap.put("19", ServerStarter.Version.PAPER_19);
|
||||||
versionMap.put("1.15", 15);
|
versionMap.put("1.19", ServerStarter.Version.PAPER_19);
|
||||||
versionMap.put("warship", 15);
|
versionMap.put("mwg", ServerStarter.Version.PAPER_19);
|
||||||
versionMap.put("as", 15);
|
versionMap.put("miniwargear", ServerStarter.Version.PAPER_19);
|
||||||
versionMap.put("airship", 15);
|
|
||||||
|
|
||||||
versionMap.put("12", 12);
|
versionMap.put("15", ServerStarter.Version.SPIGOT_15);
|
||||||
versionMap.put("1.12", 12);
|
versionMap.put("1.15", ServerStarter.Version.SPIGOT_15);
|
||||||
|
|
||||||
return new TypeMapper<Integer>() {
|
versionMap.put("12", ServerStarter.Version.SPIGOT_12);
|
||||||
|
versionMap.put("1.12", ServerStarter.Version.SPIGOT_12);
|
||||||
|
|
||||||
|
return new TypeMapper<ServerStarter.Version>() {
|
||||||
@Override
|
@Override
|
||||||
public Integer map(CommandSender commandSender, String[] previousArguments, String s) {
|
public ServerStarter.Version map(CommandSender commandSender, String[] previousArguments, String s) {
|
||||||
if (commandSender == null) return null;
|
if (commandSender == null) return null;
|
||||||
ProxiedPlayer player = (ProxiedPlayer) commandSender;
|
ProxiedPlayer player = (ProxiedPlayer) commandSender;
|
||||||
if (s.isEmpty()) {
|
if (s.isEmpty()) {
|
||||||
int version = player.getPendingConnection().getVersion();
|
int version = player.getPendingConnection().getVersion();
|
||||||
if (version > 578) { // Version > 1.15.2
|
if (version > 762) { // Version > 1.19.4
|
||||||
return 19;
|
return ServerStarter.Version.PAPER_20;
|
||||||
|
} else if (version > 578) { // Version > 1.15.2
|
||||||
|
return ServerStarter.Version.PAPER_19;
|
||||||
} else if (version > 340) { // Version > 1.12.2
|
} else if (version > 340) { // Version > 1.12.2
|
||||||
return 15;
|
return ServerStarter.Version.SPIGOT_15;
|
||||||
} else {
|
} else {
|
||||||
return 12;
|
return ServerStarter.Version.SPIGOT_12;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return versionMap.get(s.toLowerCase());
|
return versionMap.get(s.toLowerCase());
|
||||||
@ -155,12 +144,8 @@ public class BauCommand extends SWCommand {
|
|||||||
|
|
||||||
@Register(value = "tp", description = "BAU_TP_USAGE")
|
@Register(value = "tp", description = "BAU_TP_USAGE")
|
||||||
@Register("teleport")
|
@Register("teleport")
|
||||||
public void teleport(ProxiedPlayer p, @Validator("teleportTarget") SteamwarUser worldOwner, @Mapper("version") @OptionalValue(value = "", onlyUINIG = true) int version) {
|
public void teleport(ProxiedPlayer p, @Validator("teleportTarget") SteamwarUser worldOwner, @Mapper("version") @OptionalValue(value = "", onlyUINIG = true) ServerStarter.Version version) {
|
||||||
versionSelector(version,
|
new ServerStarter().build(version, worldOwner.getUUID()).send(p).start();
|
||||||
() -> new ServerStarter().build12(worldOwner.getUUID()).send(p).start(),
|
|
||||||
() -> new ServerStarter().build15(worldOwner.getUUID()).send(p).start(),
|
|
||||||
() -> new ServerStarter().build19(worldOwner.getUUID()).send(p).start()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Validator(value = "teleportTarget", local = true)
|
@Validator(value = "teleportTarget", local = true)
|
||||||
@ -176,11 +161,7 @@ public class BauCommand extends SWCommand {
|
|||||||
messageSender.send("BAU_TP_NOALLOWED");
|
messageSender.send("BAU_TP_NOALLOWED");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if(BauLock.isLocked(value, SteamwarUser.get(p.getUniqueId()))) {
|
return !BauLock.checkNotifyLocked(value, p);
|
||||||
messageSender.send("BAU_LOCKED_NOALLOWED");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -189,34 +170,52 @@ public class BauCommand extends SWCommand {
|
|||||||
Chat19.chat(p, "/bauinfo");
|
Chat19.chat(p, "/bauinfo");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Register("togglewe")
|
@Register("setspectator")
|
||||||
public void togglewe(ProxiedPlayer p, @AllowNull @OptionalValue("") SteamwarUser user) {
|
public void setSpectator(ProxiedPlayer p, @Mapper("addedUsers") @AllowNull @OptionalValue("") SteamwarUser user) {
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
Message.send("BAU_MEMBER_TOGGLE_USAGE", p, "togglewe");
|
Message.send("BAU_MEMBER_SET_USAGE", p, "setspectator");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
BauweltMember target = member(p, user);
|
BauweltMember target = member(p, user);
|
||||||
if (target == null)
|
if (target == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
target.setWorldEdit(!target.isWorldEdit());
|
target.setBuild(false);
|
||||||
|
target.setSupervisor(false);
|
||||||
clearMembercache(p);
|
clearMembercache(p);
|
||||||
isAllowedTo(target.isWorldEdit(), p, target, "BAU_MEMBER_TOGGLE_WORLD_EDIT");
|
sendPermissionUpdate(p, target, "BAU_MEMBER_SET_SPECTATOR");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Register("toggleworld")
|
@Register("setbuild")
|
||||||
public void toggleworld(ProxiedPlayer p, @AllowNull @OptionalValue("") SteamwarUser user) {
|
public void setBuild(ProxiedPlayer p, @Mapper("addedUsers") @AllowNull @OptionalValue("") SteamwarUser user) {
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
Message.send("BAU_MEMBER_TOGGLE_USAGE", p, "toggleworld");
|
Message.send("BAU_MEMBER_SET_USAGE", p, "setbuild");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
BauweltMember target = member(p, user);
|
BauweltMember target = member(p, user);
|
||||||
if (target == null)
|
if (target == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
target.setWorld(!target.isWorld());
|
target.setBuild(true);
|
||||||
|
target.setSupervisor(false);
|
||||||
clearMembercache(p);
|
clearMembercache(p);
|
||||||
isAllowedTo(target.isWorld(), p, target, "BAU_MEMBER_TOGGLE_WORLD");
|
sendPermissionUpdate(p, target, "BAU_MEMBER_SET_BUILDER");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Register("setsupervisor")
|
||||||
|
public void setSupervisor(ProxiedPlayer p, @Mapper("addedUsers") @AllowNull @OptionalValue("") SteamwarUser user) {
|
||||||
|
if (user == null) {
|
||||||
|
Message.send("BAU_MEMBER_SET_USAGE", p, "setsupervisor");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
BauweltMember target = member(p, user);
|
||||||
|
if (target == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
target.setBuild(true);
|
||||||
|
target.setSupervisor(true);
|
||||||
|
clearMembercache(p);
|
||||||
|
sendPermissionUpdate(p, target, "BAU_MEMBER_SET_SUPERVISOR");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void clearMembercache(ProxiedPlayer p){
|
private static void clearMembercache(ProxiedPlayer p){
|
||||||
@ -230,7 +229,7 @@ public class BauCommand extends SWCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Register(value = "delmember", description = "BAU_DELMEMBER_USAGE")
|
@Register(value = "delmember", description = "BAU_DELMEMBER_USAGE")
|
||||||
public void delmember(ProxiedPlayer p, SteamwarUser user) {
|
public void delmember(ProxiedPlayer p, @Mapper("addedUsers") SteamwarUser user) {
|
||||||
BauweltMember target = member(p, user);
|
BauweltMember target = member(p, user);
|
||||||
if (target == null)
|
if (target == null)
|
||||||
return;
|
return;
|
||||||
@ -246,21 +245,35 @@ public class BauCommand extends SWCommand {
|
|||||||
Message.send("BAU_DELMEMBER_DELETED_TARGET", toRemove, p.getName());
|
Message.send("BAU_DELMEMBER_DELETED_TARGET", toRemove, p.getName());
|
||||||
Subserver currentServer = Subserver.getSubserver(toRemove.getServer().getInfo());
|
Subserver currentServer = Subserver.getSubserver(toRemove.getServer().getInfo());
|
||||||
if (currentServer != null && currentServer.getType() == Servertype.BAUSERVER && ((Bauserver) currentServer).getOwner().equals(p.getUniqueId())) {
|
if (currentServer != null && currentServer.getType() == Servertype.BAUSERVER && ((Bauserver) currentServer).getOwner().equals(p.getUniqueId())) {
|
||||||
toRemove.connect(ProxyServer.getInstance().getServerInfo(BungeeCore.LOBBY_SERVER));
|
toRemove.connect(ProxyServer.getInstance().getServerInfo(VelocityCore.LOBBY_SERVER));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Message.send("BAU_DELMEMBER_DELETED", p);
|
Message.send("BAU_DELMEMBER_DELETED", p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Mapper(value = "addedUsers", local = true)
|
||||||
|
public TypeMapper<SteamwarUser> addedUsers() {
|
||||||
|
return new TypeMapper<SteamwarUser>() {
|
||||||
|
@Override
|
||||||
|
public SteamwarUser map(CommandSender commandSender, String[] previousArguments, String s) {
|
||||||
|
return SteamwarUser.get(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<String> tabCompletes(CommandSender sender, PreviousArguments previousArguments, String s) {
|
||||||
|
if (!(sender instanceof ProxiedPlayer)) return Collections.emptyList();
|
||||||
|
return BauweltMember.getMembers(((ProxiedPlayer) sender).getUniqueId()).stream()
|
||||||
|
.map(bauweltMember -> SteamwarUser.get(bauweltMember.getMemberID()))
|
||||||
|
.map(steamwarUser -> steamwarUser.getUserName())
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
@Register("resetall")
|
@Register("resetall")
|
||||||
@Register("delete")
|
@Register("delete")
|
||||||
public void delete(ProxiedPlayer p, @Mapper("version") @OptionalValue(value = "", onlyUINIG = true) int version) {
|
public void delete(ProxiedPlayer p, @Mapper("version") @OptionalValue(value = "", onlyUINIG = true) ServerStarter.Version version) {
|
||||||
SteamwarUser user = SteamwarUser.get(p.getUniqueId());
|
deleteConfirmation(p, () -> deleteWorld(p, version.getWorldFolder(ServerStarter.WORLDS_BASE_PATH) + (version != ServerStarter.Version.SPIGOT_12 ? SteamwarUser.get(p.getUniqueId()).getId() : p.getUniqueId().toString())));
|
||||||
versionSelector(version,
|
|
||||||
() -> deleteConfirmation(p, () -> deleteWorld(p, ServerStarter.WORLDS12_PATH + p.getUniqueId().toString())),
|
|
||||||
() -> deleteConfirmation(p, () -> deleteWorld(p, ServerStarter.WORLDS15_PATH + user.getId())),
|
|
||||||
() -> deleteConfirmation(p, () -> deleteWorld(p, ServerStarter.WORLDS19_PATH + user.getId()))
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void deleteConfirmation(ProxiedPlayer p, Runnable worldDeletion) {
|
private static void deleteConfirmation(ProxiedPlayer p, Runnable worldDeletion) {
|
||||||
@ -276,14 +289,12 @@ public class BauCommand extends SWCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static void deleteWorld(ProxiedPlayer player, String world) {
|
private static void deleteWorld(ProxiedPlayer player, String world) {
|
||||||
ProxyServer.getInstance().getScheduler().runAsync(BungeeCore.get(), () -> {
|
ProxyServer.getInstance().getScheduler().runAsync(VelocityCore.get(), () -> {
|
||||||
for (Subserver subserver : Subserver.getServerList()) {
|
Bauserver subserver = Bauserver.get(player.getUniqueId());
|
||||||
if (subserver.getType() == Servertype.BAUSERVER && ((Bauserver) subserver).getOwner().equals(player.getUniqueId())) {
|
if(subserver != null)
|
||||||
subserver.stop();
|
subserver.stop();
|
||||||
break;
|
|
||||||
}
|
SubserverSystem.deleteFolder(VelocityCore.local, world);
|
||||||
}
|
|
||||||
SubserverSystem.deleteFolder(BungeeCore.local, world);
|
|
||||||
Message.send("BAU_DELETE_DELETED", player);
|
Message.send("BAU_DELETE_DELETED", player);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -292,7 +303,7 @@ public class BauCommand extends SWCommand {
|
|||||||
@Register("testarena")
|
@Register("testarena")
|
||||||
public void testarena(ProxiedPlayer p, @Mapper("nonHistoricArenaMode") @OptionalValue("") @AllowNull ArenaMode arenaMode, @Mapper("arenaMap") @OptionalValue("") @AllowNull String map) {
|
public void testarena(ProxiedPlayer p, @Mapper("nonHistoricArenaMode") @OptionalValue("") @AllowNull ArenaMode arenaMode, @Mapper("arenaMap") @OptionalValue("") @AllowNull String map) {
|
||||||
FightCommand.createArena(p, "/bau testarena ", false, arenaMode, map, false, (player, mode, m) -> {
|
FightCommand.createArena(p, "/bau testarena ", false, arenaMode, map, false, (player, mode, m) -> {
|
||||||
ProxyServer.getInstance().getScheduler().runAsync(BungeeCore.get(), () -> new ServerStarter().test(mode, m, p).start());
|
ProxyServer.getInstance().getScheduler().runAsync(VelocityCore.get(), () -> new ServerStarter().test(mode, m, p).start());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -320,17 +331,10 @@ public class BauCommand extends SWCommand {
|
|||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void isAllowedTo(boolean permission, ProxiedPlayer p, BauweltMember target, String what){
|
private static void sendPermissionUpdate(ProxiedPlayer p, BauweltMember target, String what){
|
||||||
ProxiedPlayer player = ProxyServer.getInstance().getPlayer(SteamwarUser.get(target.getMemberID()).getUUID());
|
ProxiedPlayer player = ProxyServer.getInstance().getPlayer(SteamwarUser.get(target.getMemberID()).getUUID());
|
||||||
|
|
||||||
if(permission){
|
|
||||||
if(player != null)
|
if(player != null)
|
||||||
Message.send("BAU_MEMBER_TOGGLE_TARGET", player, p.getName(), Message.parse(what, player));
|
Message.send("BAU_MEMBER_SET_TARGET", player, p.getName(), Message.parse(what, player));
|
||||||
Message.send("BAU_MEMBER_TOGGLE", p, Message.parse(what, p));
|
Message.send("BAU_MEMBER_SET", p, Message.parse(what, p));
|
||||||
}else{
|
|
||||||
if(player != null)
|
|
||||||
Message.send("BAU_MEMBER_TOGGLE_TARGET_OFF", player, p.getName(), Message.parse(what, player));
|
|
||||||
Message.send("BAU_MEMBER_TOGGLE_OFF", p, Message.parse(what, p));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,19 @@
|
|||||||
package de.steamwar.bungeecore.commands;
|
package de.steamwar.bungeecore.commands;
|
||||||
|
|
||||||
|
import de.steamwar.bungeecore.ArenaMode;
|
||||||
|
import de.steamwar.bungeecore.VelocityCore;
|
||||||
import de.steamwar.bungeecore.ServerStarter;
|
import de.steamwar.bungeecore.ServerStarter;
|
||||||
|
import de.steamwar.bungeecore.listeners.ConnectionListener;
|
||||||
import de.steamwar.command.SWCommand;
|
import de.steamwar.command.SWCommand;
|
||||||
import de.steamwar.command.TypeMapper;
|
import de.steamwar.command.TypeMapper;
|
||||||
|
import de.steamwar.messages.ChatSender;
|
||||||
import net.md_5.bungee.api.CommandSender;
|
import net.md_5.bungee.api.CommandSender;
|
||||||
|
import net.md_5.bungee.api.ProxyServer;
|
||||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@ -15,7 +22,7 @@ public class BuilderCloudCommand extends SWCommand {
|
|||||||
private final Map<String, ServerStarter.Version> versionMap = new HashMap<>();
|
private final Map<String, ServerStarter.Version> versionMap = new HashMap<>();
|
||||||
|
|
||||||
public BuilderCloudCommand() {
|
public BuilderCloudCommand() {
|
||||||
super("buildercloud", "bungeecore.server.team");
|
super("buildercloud", ConnectionListener.BUILDERCLOUD_PERMISSION, "builder");
|
||||||
|
|
||||||
versionMap.put("15", ServerStarter.Version.SPIGOT_15);
|
versionMap.put("15", ServerStarter.Version.SPIGOT_15);
|
||||||
versionMap.put("1.15", ServerStarter.Version.SPIGOT_15);
|
versionMap.put("1.15", ServerStarter.Version.SPIGOT_15);
|
||||||
@ -23,11 +30,62 @@ public class BuilderCloudCommand extends SWCommand {
|
|||||||
versionMap.put("19", ServerStarter.Version.PAPER_19);
|
versionMap.put("19", ServerStarter.Version.PAPER_19);
|
||||||
versionMap.put("1.19", ServerStarter.Version.PAPER_19);
|
versionMap.put("1.19", ServerStarter.Version.PAPER_19);
|
||||||
versionMap.put("1.19.2", ServerStarter.Version.PAPER_19);
|
versionMap.put("1.19.2", ServerStarter.Version.PAPER_19);
|
||||||
|
versionMap.put("20", ServerStarter.Version.PAPER_20);
|
||||||
|
versionMap.put("1.20", ServerStarter.Version.PAPER_20);
|
||||||
|
versionMap.put("1.20.1", ServerStarter.Version.PAPER_20);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Register(value = "create", description = "BUILDERCLOUD_CREATE_USAGE")
|
||||||
|
public void create(ProxiedPlayer player, @ErrorMessage("BUILDERCLOUD_VERSION") ServerStarter.Version version, @Mapper("map") String map, @OptionalValue("") @Mapper("generator") @AllowNull File generator) {
|
||||||
|
mapFile(version, map).mkdir();
|
||||||
|
new ServerStarter().builder(version, map, generator).send(player).start();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Register(description = "BUILDERCLOUD_USAGE")
|
@Register(description = "BUILDERCLOUD_USAGE")
|
||||||
public void genericCommand(ProxiedPlayer player, @ErrorMessage("BUILDERCLOUD_VERSION") ServerStarter.Version version, @Mapper("map") String map, @OptionalValue("") @Mapper("generator") @AllowNull File generator) {
|
public void start(ProxiedPlayer player, @ErrorMessage("BUILDERCLOUD_VERSION") ServerStarter.Version version, @Mapper("map") String map) {
|
||||||
new ServerStarter().builder(version, map, generator).send(player).start();
|
if(!mapFile(version, map).exists()) {
|
||||||
|
ChatSender.of(player).system("BUILDERCLOUD_UNKNOWN_MAP");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
new ServerStarter().builder(version, map, null).send(player).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Register(value = "rename", description = "BUILDERCLOUD_RENAME_USAGE")
|
||||||
|
public void rename(ProxiedPlayer player, @ErrorMessage("BUILDERCLOUD_VERSION") ServerStarter.Version version, @Mapper("map") String oldName, String newName) {
|
||||||
|
File oldMap = mapFile(version, oldName);
|
||||||
|
if(!oldMap.exists()) {
|
||||||
|
ChatSender.of(player).system("BUILDERCLOUD_UNKNOWN_MAP");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
File newMap = mapFile(version, newName);
|
||||||
|
if(newMap.exists()) {
|
||||||
|
ChatSender.of(player).system("BUILDERCLOUD_EXISTING_MAP");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
Files.move(oldMap.toPath(), newMap.toPath());
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new SecurityException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
ChatSender.of(player).system("BUILDERCLOUD_RENAMED");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Register(value = "deploy", description = "BUILDERCLOUD_DEPLOY_USAGE")
|
||||||
|
public void deploy(ProxiedPlayer player, @Mapper("nonHistoricArenaMode") ArenaMode arenaMode, @ErrorMessage("BUILDERCLOUD_VERSION") ServerStarter.Version version, @Mapper("map") String map) {
|
||||||
|
if(!mapFile(version, map).exists()) {
|
||||||
|
ChatSender.of(player).system("BUILDERCLOUD_UNKNOWN_MAP");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ProxyServer.getInstance().getScheduler().runAsync(VelocityCore.get(), () -> {
|
||||||
|
VelocityCore.local.execute("/binarys/deployarena.py", arenaMode.getConfig(), Integer.toString(version.getVersionSuffix()), map);
|
||||||
|
ArenaMode.init();
|
||||||
|
ChatSender.of(player).system("BUILDERCLOUD_DEPLOY_FINISHED");
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ClassMapper(value = ServerStarter.Version.class, local = true)
|
@ClassMapper(value = ServerStarter.Version.class, local = true)
|
||||||
@ -52,16 +110,7 @@ public class BuilderCloudCommand extends SWCommand {
|
|||||||
return new TypeMapper<String>() {
|
return new TypeMapper<String>() {
|
||||||
@Override
|
@Override
|
||||||
public String map(CommandSender commandSender, String[] previousArguments, String s) {
|
public String map(CommandSender commandSender, String[] previousArguments, String s) {
|
||||||
File folder = getWorldFolder(previousArguments, 1);
|
return s;
|
||||||
|
|
||||||
if(folder == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
File map = new File(folder, s);
|
|
||||||
if(!map.exists() && !map.mkdir())
|
|
||||||
return null;
|
|
||||||
|
|
||||||
return map.getName();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -72,7 +121,7 @@ public class BuilderCloudCommand extends SWCommand {
|
|||||||
if(folder == null || (files = folder.list()) == null)
|
if(folder == null || (files = folder.list()) == null)
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
|
|
||||||
return Arrays.stream(files).filter(file -> new File(folder, file).isDirectory()).collect(Collectors.toList());
|
return Arrays.stream(files).filter(file -> new File(folder, file).isDirectory()).filter(file -> s.startsWith(".") || !file.startsWith(".")).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -112,6 +161,10 @@ public class BuilderCloudCommand extends SWCommand {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private File mapFile(ServerStarter.Version version, String map) {
|
||||||
|
return new File(version.getWorldFolder(ServerStarter.BUILDER_BASE_PATH), map);
|
||||||
|
}
|
||||||
|
|
||||||
private File getWorldFolder(String[] previousArguments, int offset) {
|
private File getWorldFolder(String[] previousArguments, int offset) {
|
||||||
ServerStarter.Version v = versionMap.get(previousArguments[previousArguments.length - offset]);
|
ServerStarter.Version v = versionMap.get(previousArguments[previousArguments.length - offset]);
|
||||||
if(v == null)
|
if(v == null)
|
||||||
|
@ -1,113 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2022 SteamWar.de-Serverteam
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.bungeecore.commands;
|
|
||||||
|
|
||||||
import de.steamwar.bungeecore.Message;
|
|
||||||
import de.steamwar.bungeecore.inventory.SWInventory;
|
|
||||||
import de.steamwar.bungeecore.inventory.SWItem;
|
|
||||||
import de.steamwar.sql.NodeMember;
|
|
||||||
import de.steamwar.sql.SchematicNode;
|
|
||||||
import de.steamwar.sql.SteamwarUser;
|
|
||||||
import de.steamwar.command.SWCommand;
|
|
||||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
|
||||||
|
|
||||||
import java.time.LocalDate;
|
|
||||||
import java.time.Month;
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
public class CalendarCommand extends SWCommand {
|
|
||||||
|
|
||||||
private static Map<Integer, Integer> dayToSchematicId = new HashMap<>();
|
|
||||||
|
|
||||||
static {
|
|
||||||
dayToSchematicId.put(1, 105386);
|
|
||||||
dayToSchematicId.put(2, 105463);
|
|
||||||
dayToSchematicId.put(3, 105438);
|
|
||||||
dayToSchematicId.put(4, 105383);
|
|
||||||
dayToSchematicId.put(5, 105381);
|
|
||||||
dayToSchematicId.put(6, 105396);
|
|
||||||
dayToSchematicId.put(7, 105462);
|
|
||||||
dayToSchematicId.put(8, 105457);
|
|
||||||
dayToSchematicId.put(9, 105388);
|
|
||||||
dayToSchematicId.put(10, 105390);
|
|
||||||
dayToSchematicId.put(11, 105385);
|
|
||||||
dayToSchematicId.put(12, 105397);
|
|
||||||
dayToSchematicId.put(13, 105455);
|
|
||||||
dayToSchematicId.put(14, 105389);
|
|
||||||
dayToSchematicId.put(15, 105454);
|
|
||||||
dayToSchematicId.put(16, 105394);
|
|
||||||
dayToSchematicId.put(17, 105459);
|
|
||||||
dayToSchematicId.put(18, 105384);
|
|
||||||
dayToSchematicId.put(19, 105392);
|
|
||||||
dayToSchematicId.put(20, 105465);
|
|
||||||
dayToSchematicId.put(21, 105393);
|
|
||||||
dayToSchematicId.put(22, 105464);
|
|
||||||
dayToSchematicId.put(23, 105380);
|
|
||||||
dayToSchematicId.put(24, 105505);
|
|
||||||
dayToSchematicId.put(25, 107355);
|
|
||||||
dayToSchematicId.put(26, 107355);
|
|
||||||
dayToSchematicId.put(31, 105507);
|
|
||||||
}
|
|
||||||
|
|
||||||
public CalendarCommand() {
|
|
||||||
super("calendar", null, "cal");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Register
|
|
||||||
public void genericCommand(ProxiedPlayer player) {
|
|
||||||
LocalDate localDate = LocalDate.now();
|
|
||||||
int day = localDate.getDayOfMonth();
|
|
||||||
Month month = localDate.getMonth();
|
|
||||||
Random random = new Random(localDate.getYear());
|
|
||||||
|
|
||||||
if (month != Month.NOVEMBER && month != Month.DECEMBER && month != Month.JANUARY) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
|
||||||
List<SWItem> items = new ArrayList<>();
|
|
||||||
for (Map.Entry<Integer, Integer> present : dayToSchematicId.entrySet()) {
|
|
||||||
boolean b = NodeMember.getNodeMember(present.getValue(), user.getId()) != null;
|
|
||||||
SWItem randomPresent = random.nextDouble() > 0.5 ? SWItem.getSkull("MHF_Present1") : SWItem.getSkull("MHF_Present2");
|
|
||||||
SWItem swItem = b ? SWItem.getSkull("MHF_Chest") : randomPresent;
|
|
||||||
swItem.setName(Message.parse("ADVENT_CALENDAR_DAY", player, present.getKey()));
|
|
||||||
swItem.setCallback(click -> {
|
|
||||||
if (b) return;
|
|
||||||
if (month != Month.DECEMBER) return;
|
|
||||||
if (present.getKey() != day) return;
|
|
||||||
if (NodeMember.getNodeMember(present.getValue(), user.getId()) != null) return;
|
|
||||||
NodeMember.createNodeMember(present.getValue(), user.getId());
|
|
||||||
Message.send("ADVENT_CALENDAR_OPEN", player, SchematicNode.getSchematicNode(present.getValue()).getName());
|
|
||||||
});
|
|
||||||
items.add(swItem);
|
|
||||||
}
|
|
||||||
Collections.shuffle(items, random);
|
|
||||||
|
|
||||||
SWInventory inventory = new SWInventory(player, 27, Message.parse("ADVENT_CALENDAR_TITLE", player));
|
|
||||||
for (int i = 0; i < items.size(); i++) {
|
|
||||||
inventory.addItem(i, items.get(i));
|
|
||||||
}
|
|
||||||
inventory.open();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean hasDay(int day) {
|
|
||||||
return dayToSchematicId.containsKey(day);
|
|
||||||
}
|
|
||||||
}
|
|
@ -43,11 +43,9 @@ public class ChallengeCommand extends SWCommand {
|
|||||||
challenges.remove(target);
|
challenges.remove(target);
|
||||||
challenges.remove(p);
|
challenges.remove(p);
|
||||||
|
|
||||||
Subserver arena = new ServerStarter().arena(mode, map).blueLeader(player).redLeader(target).start();
|
new ServerStarter().arena(mode, map).blueLeader(player).redLeader(target).callback(
|
||||||
if(arena != null) {
|
arena -> Message.broadcast("CHALLENGE_BROADCAST", "CHALLENGE_BROADCAST_HOVER", new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/arena " + arena.getServer().getName()), mode.getDisplayName(), p.getName(), target.getName())
|
||||||
Message.broadcast("CHALLENGE_BROADCAST", "CHALLENGE_BROADCAST_HOVER",
|
).start();
|
||||||
new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/arena " + arena.getServer().getName()), mode.getDisplayName(), p.getName(), target.getName());
|
|
||||||
}
|
|
||||||
}else{
|
}else{
|
||||||
if(!challenges.containsKey(p)){
|
if(!challenges.containsKey(p)){
|
||||||
challenges.put(p, new LinkedList<>());
|
challenges.put(p, new LinkedList<>());
|
||||||
|
@ -19,20 +19,14 @@
|
|||||||
|
|
||||||
package de.steamwar.bungeecore.commands;
|
package de.steamwar.bungeecore.commands;
|
||||||
|
|
||||||
|
import com.velocitypowered.api.proxy.Player;
|
||||||
import de.steamwar.bungeecore.*;
|
import de.steamwar.bungeecore.*;
|
||||||
import de.steamwar.bungeecore.bot.util.DiscordSchemAlert;
|
import de.steamwar.bungeecore.bot.util.DiscordSchemAlert;
|
||||||
import de.steamwar.bungeecore.listeners.ConnectionListener;
|
import de.steamwar.bungeecore.listeners.ConnectionListener;
|
||||||
import de.steamwar.sql.CheckedSchematic;
|
import de.steamwar.sql.*;
|
||||||
import de.steamwar.sql.SchematicNode;
|
|
||||||
import de.steamwar.sql.SchematicType;
|
|
||||||
import de.steamwar.sql.SteamwarUser;
|
|
||||||
import de.steamwar.command.SWCommand;
|
import de.steamwar.command.SWCommand;
|
||||||
import net.md_5.bungee.api.ChatColor;
|
import net.kyori.adventure.text.event.ClickEvent;
|
||||||
import net.md_5.bungee.api.ProxyServer;
|
import org.simpleyaml.configuration.Configuration;
|
||||||
import net.md_5.bungee.api.chat.ClickEvent;
|
|
||||||
import net.md_5.bungee.api.chat.TextComponent;
|
|
||||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
|
||||||
import net.md_5.bungee.config.Configuration;
|
|
||||||
|
|
||||||
import java.sql.Timestamp;
|
import java.sql.Timestamp;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
@ -58,27 +52,27 @@ public class CheckCommand extends SWCommand {
|
|||||||
fightTypes.put(checkType, fightType);
|
fightTypes.put(checkType, fightType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isChecking(ProxiedPlayer player){
|
public static boolean isChecking(Player player){
|
||||||
return currentCheckers.containsKey(player.getUniqueId());
|
return currentCheckers.containsKey(player.getUniqueId());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SchematicNode getCheckingSchem(ProxiedPlayer player) {
|
public static SchematicNode getCheckingSchem(Player player) {
|
||||||
return currentCheckers.get(player.getUniqueId()).schematic;
|
return currentCheckers.get(player.getUniqueId()).schematic;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CheckCommand() {
|
public CheckCommand() {
|
||||||
super("check", ConnectionListener.CHECK_PERMISSION);
|
super("check", ConnectionListener.CHECK_PERMISSION);
|
||||||
|
|
||||||
ProxyServer.getInstance().getScheduler().schedule(BungeeCore.get(), () -> {
|
VelocityCore.get().getProxyServer().getScheduler().buildTask(VelocityCore.get(), () -> {
|
||||||
List<SchematicNode> schematics = getSchemsToCheck();
|
List<SchematicNode> schematics = getSchemsToCheck();
|
||||||
if(schematics.size() != currentCheckers.size())
|
if(schematics.size() != currentCheckers.size())
|
||||||
Message.team("CHECK_REMINDER", "CHECK_REMINDER_HOVER", new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/check list"), schematics.size() - currentCheckers.size());
|
Message.team("CHECK_REMINDER", "CHECK_REMINDER_HOVER", ClickEvent.runCommand("/check list"), schematics.size() - currentCheckers.size());
|
||||||
}, 10, 10, TimeUnit.MINUTES);
|
}).repeat(10, TimeUnit.MINUTES).schedule();
|
||||||
}
|
}
|
||||||
public static void sendReminder(ProxiedPlayer player) {
|
public static void sendReminder(Player player) {
|
||||||
List<SchematicNode> schematics = getSchemsToCheck();
|
List<SchematicNode> schematics = getSchemsToCheck();
|
||||||
if(schematics.size() != currentCheckers.size())
|
if(schematics.size() != currentCheckers.size())
|
||||||
Message.send("CHECK_REMINDER", player, Message.parse("CHECK_REMINDER_HOVER", player), new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/check list"), schematics.size() - currentCheckers.size());
|
Message.send("CHECK_REMINDER", player, Message.parse("CHECK_REMINDER_HOVER", player), ClickEvent.runCommand("/check list"), schematics.size() - currentCheckers.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Register(value = "list", description = "CHECK_HELP_LIST")
|
@Register(value = "list", description = "CHECK_HELP_LIST")
|
||||||
@ -117,15 +111,21 @@ public class CheckCommand extends SWCommand {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SteamwarUser checkingUser = SteamwarUser.get(player.getUniqueId());
|
||||||
SchematicNode schem = SchematicNode.getSchematicNode(Integer.parseInt(schemID));
|
SchematicNode schem = SchematicNode.getSchematicNode(Integer.parseInt(schemID));
|
||||||
if(!schem.getSchemtype().check()){
|
if(!schem.getSchemtype().check()){
|
||||||
ProxyServer.getInstance().getLogger().log(Level.SEVERE, player.getName() + " tried to check an uncheckable schematic!");
|
ProxyServer.getInstance().getLogger().log(Level.SEVERE, player.getName() + " tried to check an uncheckable schematic!");
|
||||||
return;
|
return;
|
||||||
}else if(schem.getOwner() == SteamwarUser.get(player.getUniqueId()).getId()) {
|
}else if(schem.getOwner() == checkingUser.getId()) {
|
||||||
Message.send("CHECK_SCHEMATIC_OWN", player);
|
Message.send("CHECK_SCHEMATIC_OWN", player);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int playerTeam = checkingUser.hasPerm(UserPerm.MODERATION) ? 0 : checkingUser.getTeam();
|
||||||
|
if (playerTeam != 0 && SteamwarUser.get(schem.getOwner()).getTeam() == playerTeam) {
|
||||||
|
Message.send("CHECK_SCHEMATIC_OWN_TEAM", player);
|
||||||
|
return;
|
||||||
|
}
|
||||||
new CheckSession(player, schem);
|
new CheckSession(player, schem);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -217,9 +217,9 @@ public class CheckCommand extends SWCommand {
|
|||||||
this.startTime = Timestamp.from(Instant.now());
|
this.startTime = Timestamp.from(Instant.now());
|
||||||
this.checkList = checkQuestions.get(schematic.getSchemtype()).listIterator();
|
this.checkList = checkQuestions.get(schematic.getSchemtype()).listIterator();
|
||||||
|
|
||||||
ProxyServer.getInstance().getScheduler().runAsync(BungeeCore.get(), () -> {
|
ProxyServer.getInstance().getScheduler().runAsync(VelocityCore.get(), () -> {
|
||||||
ArenaMode mode = ArenaMode.getBySchemType(fightTypes.get(schematic.getSchemtype()));
|
ArenaMode mode = ArenaMode.getBySchemType(fightTypes.get(schematic.getSchemtype()));
|
||||||
if(new ServerStarter().test(mode, mode.getRandomMap(), checker).check(schematic.getId()).start() == null) {
|
if(!new ServerStarter().test(mode, mode.getRandomMap(), checker).check(schematic.getId()).start()) {
|
||||||
remove();
|
remove();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -314,13 +314,10 @@ public class CheckCommand extends SWCommand {
|
|||||||
private void stop(){
|
private void stop(){
|
||||||
currentCheckers.remove(checker.getUniqueId());
|
currentCheckers.remove(checker.getUniqueId());
|
||||||
currentSchems.remove(schematic.getId());
|
currentSchems.remove(schematic.getId());
|
||||||
ProxyServer.getInstance().getScheduler().runAsync(BungeeCore.get(), () -> {
|
ProxyServer.getInstance().getScheduler().runAsync(VelocityCore.get(), () -> {
|
||||||
for (Subserver subserver : Subserver.getServerList()) {
|
Bauserver subserver = Bauserver.get(checker.getUniqueId());
|
||||||
if (subserver.getType() == Servertype.BAUSERVER && ((Bauserver) subserver).getOwner().equals(checker.getUniqueId())) {
|
if(subserver != null)
|
||||||
subserver.stop();
|
subserver.stop();
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,7 +107,7 @@ public class EventCommand extends SWCommand {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BungeeCore.send(player, fline.toString());
|
VelocityCore.send(player, fline.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
package de.steamwar.bungeecore.commands;
|
package de.steamwar.bungeecore.commands;
|
||||||
|
|
||||||
import de.steamwar.bungeecore.Message;
|
import de.steamwar.bungeecore.Message;
|
||||||
|
import de.steamwar.bungeecore.listeners.ConnectionListener;
|
||||||
import de.steamwar.sql.EventFight;
|
import de.steamwar.sql.EventFight;
|
||||||
import de.steamwar.sql.Team;
|
import de.steamwar.sql.Team;
|
||||||
import de.steamwar.command.SWCommand;
|
import de.steamwar.command.SWCommand;
|
||||||
@ -39,7 +40,7 @@ import java.util.stream.Stream;
|
|||||||
public class EventRescheduleCommand extends SWCommand {
|
public class EventRescheduleCommand extends SWCommand {
|
||||||
|
|
||||||
public EventRescheduleCommand() {
|
public EventRescheduleCommand() {
|
||||||
super("eventreschedule", "bungeecore.softreload");
|
super("eventreschedule", ConnectionListener.EVENTRELOAD_PERMISSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Register
|
@Register
|
||||||
|
@ -19,13 +19,14 @@
|
|||||||
|
|
||||||
package de.steamwar.bungeecore.commands;
|
package de.steamwar.bungeecore.commands;
|
||||||
|
|
||||||
|
import de.steamwar.bungeecore.listeners.ConnectionListener;
|
||||||
import de.steamwar.sql.EventFight;
|
import de.steamwar.sql.EventFight;
|
||||||
import de.steamwar.command.SWCommand;
|
import de.steamwar.command.SWCommand;
|
||||||
import net.md_5.bungee.api.CommandSender;
|
import net.md_5.bungee.api.CommandSender;
|
||||||
|
|
||||||
public class EventreloadCommand extends SWCommand {
|
public class EventreloadCommand extends SWCommand {
|
||||||
public EventreloadCommand() {
|
public EventreloadCommand() {
|
||||||
super("eventreload", "bungeecore.softreload");
|
super("eventreload", ConnectionListener.EVENTRELOAD_PERMISSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Register
|
@Register
|
||||||
|
@ -87,34 +87,6 @@ public class FightCommand extends SWCommand {
|
|||||||
sender.sendMessage(ChatMessageType.SYSTEM, start);
|
sender.sendMessage(ChatMessageType.SYSTEM, start);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void getMaps(ChatSender sender, String precommand, ArenaMode mode){
|
|
||||||
TextComponent start = new TextComponent();
|
|
||||||
TextComponent current = start;
|
|
||||||
if(mode.getMaps().size() > 1){
|
|
||||||
String command = precommand + mode.getChatName() + " Random";
|
|
||||||
start.setBold(true);
|
|
||||||
start.setColor(ChatColor.GRAY);
|
|
||||||
start.setText(sender.parseToPlain("FIGHT_ARENA_RANDOM") + " ");
|
|
||||||
start.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text("§e" + command)));
|
|
||||||
start.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, command));
|
|
||||||
current = new TextComponent();
|
|
||||||
}
|
|
||||||
|
|
||||||
for(String map : mode.getMaps()){
|
|
||||||
String command = precommand + mode.getChatName() + " " + map;
|
|
||||||
current.setBold(true);
|
|
||||||
current.setColor(ChatColor.GRAY);
|
|
||||||
current.setText(map + " ");
|
|
||||||
current.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text("§e" + command)));
|
|
||||||
current.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, command));
|
|
||||||
if(current != start)
|
|
||||||
start.addExtra(current);
|
|
||||||
current = new TextComponent();
|
|
||||||
}
|
|
||||||
|
|
||||||
sender.sendMessage(ChatMessageType.SYSTEM, start);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean alreadyInArena(ProxiedPlayer player){
|
private static boolean alreadyInArena(ProxiedPlayer player){
|
||||||
Subserver subserver = Subserver.getSubserver(player);
|
Subserver subserver = Subserver.getSubserver(player);
|
||||||
if(subserver != null && subserver.getType() == Servertype.ARENA){
|
if(subserver != null && subserver.getType() == Servertype.ARENA){
|
||||||
@ -136,16 +108,8 @@ public class FightCommand extends SWCommand {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (map == null) {
|
if (map == null)
|
||||||
if (arenaMode.getMaps().size() == 1) {
|
|
||||||
map = arenaMode.getRandomMap();
|
map = arenaMode.getRandomMap();
|
||||||
} else {
|
|
||||||
getMaps(sender, precommand, arenaMode);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else if (map.equalsIgnoreCase("random")) {
|
|
||||||
map = arenaMode.getRandomMap();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!allowMerging) {
|
if (!allowMerging) {
|
||||||
callback.run(player, arenaMode, map);
|
callback.run(player, arenaMode, map);
|
||||||
@ -160,7 +124,7 @@ public class FightCommand extends SWCommand {
|
|||||||
for (Subserver subserver : Subserver.getServerList()) {
|
for (Subserver subserver : Subserver.getServerList()) {
|
||||||
if(subserver instanceof Arenaserver) {
|
if(subserver instanceof Arenaserver) {
|
||||||
Arenaserver arenaserver = (Arenaserver) subserver;
|
Arenaserver arenaserver = (Arenaserver) subserver;
|
||||||
if(mode.getInternalName().equals(arenaserver.getMode()) && map.equals(arenaserver.getMap()) && arenaserver.isAllowMerge() && arenaserver.getServer().getPlayers().size() == 1) {
|
if(mode.getInternalName().equals(arenaserver.getMode()) && arenaserver.isAllowMerge() && arenaserver.getServer().getPlayers().size() == 1) {
|
||||||
mergable = arenaserver;
|
mergable = arenaserver;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -195,13 +159,11 @@ public class FightCommand extends SWCommand {
|
|||||||
|
|
||||||
@Register
|
@Register
|
||||||
public void fight(@Validator("arenaPlayer") ProxiedPlayer player, @Mapper("nonHistoricArenaMode") @OptionalValue("") @AllowNull ArenaMode arenaMode, @Mapper("arenaMap") @OptionalValue("") @AllowNull String map) {
|
public void fight(@Validator("arenaPlayer") ProxiedPlayer player, @Mapper("nonHistoricArenaMode") @OptionalValue("") @AllowNull ArenaMode arenaMode, @Mapper("arenaMap") @OptionalValue("") @AllowNull String map) {
|
||||||
createArena(player, "/fight ", true, arenaMode, map, false, (p, mode, m) -> {
|
createArena(player, "/fight ", true, arenaMode, map, false,
|
||||||
Subserver arena = new ServerStarter().arena(mode, m).blueLeader(p).start();
|
(p, mode, m) -> new ServerStarter().arena(mode, m).blueLeader(p).callback(
|
||||||
if(arena != null) {
|
arena -> Message.broadcast("FIGHT_BROADCAST", "FIGHT_BROADCAST_HOVER", new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/arena " + arena.getServer().getName()), mode.getDisplayName(), p.getName())
|
||||||
Message.broadcast("FIGHT_BROADCAST", "FIGHT_BROADCAST_HOVER"
|
).start()
|
||||||
, new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/arena " + arena.getServer().getName()), mode.getDisplayName(), p.getName());
|
);
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package de.steamwar.bungeecore.commands;
|
package de.steamwar.bungeecore.commands;
|
||||||
|
|
||||||
import de.steamwar.bungeecore.BungeeCore;
|
import de.steamwar.bungeecore.VelocityCore;
|
||||||
import de.steamwar.bungeecore.Message;
|
import de.steamwar.bungeecore.Message;
|
||||||
import de.steamwar.sql.internal.Statement;
|
import de.steamwar.sql.internal.Statement;
|
||||||
import de.steamwar.sql.SteamwarUser;
|
import de.steamwar.sql.SteamwarUser;
|
||||||
@ -31,7 +31,7 @@ public class GDPRQuery extends SWCommand {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
BungeeCord.getInstance().getScheduler().runAsync(BungeeCore.get(), () -> {
|
BungeeCord.getInstance().getScheduler().runAsync(VelocityCore.get(), () -> {
|
||||||
try {
|
try {
|
||||||
createZip(player, user);
|
createZip(player, user);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
@ -22,10 +22,8 @@ package de.steamwar.bungeecore.commands;
|
|||||||
import de.steamwar.bungeecore.Message;
|
import de.steamwar.bungeecore.Message;
|
||||||
import de.steamwar.command.SWCommand;
|
import de.steamwar.command.SWCommand;
|
||||||
import de.steamwar.messages.ChatSender;
|
import de.steamwar.messages.ChatSender;
|
||||||
import net.md_5.bungee.api.CommandSender;
|
|
||||||
import net.md_5.bungee.api.chat.ClickEvent;
|
import net.md_5.bungee.api.chat.ClickEvent;
|
||||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||||
import net.md_5.bungee.protocol.packet.Chat;
|
|
||||||
|
|
||||||
public class HelpCommand extends SWCommand {
|
public class HelpCommand extends SWCommand {
|
||||||
|
|
||||||
@ -69,7 +67,9 @@ public class HelpCommand extends SWCommand {
|
|||||||
|
|
||||||
@Register({"build","other"})
|
@Register({"build","other"})
|
||||||
public void buildOther(ProxiedPlayer player) {
|
public void buildOther(ProxiedPlayer player) {
|
||||||
printPage(ChatSender.of(player), "HELP_BAU_GROUP_OTHER_TITLE", "HELP_TESTBLOCK", "HELP_SKULL", "HELP_BAUINFO");
|
ChatSender sender = ChatSender.of(player);
|
||||||
|
printPage(sender, "HELP_BAU_GROUP_OTHER_TITLE", "HELP_TESTBLOCK", "HELP_SKULL", "HELP_BAUINFO");
|
||||||
|
sender.prefixless("HELP_SCHEMSUBMIT", new Message("HELP_SCHEMSUBMIT_HOVER"), new ClickEvent(ClickEvent.Action.OPEN_URL, "https://www.youtube.com/watch?v=9QrQ3UBWveE"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Register("build")
|
@Register("build")
|
||||||
@ -91,8 +91,9 @@ public class HelpCommand extends SWCommand {
|
|||||||
"HELP_BAU_TP", "/build tp ",
|
"HELP_BAU_TP", "/build tp ",
|
||||||
"HELP_BAU_ADDMEMBER", "/build addmember ",
|
"HELP_BAU_ADDMEMBER", "/build addmember ",
|
||||||
"HELP_BAU_DELMEMBER", "/build delmember ",
|
"HELP_BAU_DELMEMBER", "/build delmember ",
|
||||||
"HELP_BAU_TOGGLEWE", "/build togglewe ",
|
"HELP_BAU_SET_SPECTATOR", "/build setSpectator ",
|
||||||
"HELP_BAU_TOGGLEWORLD", "/build toggleworld ",
|
"HELP_BAU_SET_BUILDER", "/build setBuilder ",
|
||||||
|
"HELP_BAU_SET_SUPERVISOR", "/build setSupervisor ",
|
||||||
"HELP_BAU_DELETE", "/build delete ",
|
"HELP_BAU_DELETE", "/build delete ",
|
||||||
"HELP_BAU_TESTARENA", "/build testarena ",
|
"HELP_BAU_TESTARENA", "/build testarena ",
|
||||||
"HELP_BAU_LOCK", "/build lock ",
|
"HELP_BAU_LOCK", "/build lock ",
|
||||||
|
@ -22,7 +22,6 @@ package de.steamwar.bungeecore.commands;
|
|||||||
import de.steamwar.bungeecore.ArenaMode;
|
import de.steamwar.bungeecore.ArenaMode;
|
||||||
import de.steamwar.bungeecore.Message;
|
import de.steamwar.bungeecore.Message;
|
||||||
import de.steamwar.bungeecore.ServerStarter;
|
import de.steamwar.bungeecore.ServerStarter;
|
||||||
import de.steamwar.bungeecore.Subserver;
|
|
||||||
import de.steamwar.command.SWCommand;
|
import de.steamwar.command.SWCommand;
|
||||||
import net.md_5.bungee.api.chat.ClickEvent;
|
import net.md_5.bungee.api.chat.ClickEvent;
|
||||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||||
@ -35,11 +34,9 @@ public class HistoricCommand extends SWCommand {
|
|||||||
@Register
|
@Register
|
||||||
public void historic(@Validator("arenaPlayer") ProxiedPlayer player, @Mapper("historicArenaMode") @OptionalValue("") @AllowNull ArenaMode arenaMode, @Mapper("arenaMap") @OptionalValue("") @AllowNull String map) {
|
public void historic(@Validator("arenaPlayer") ProxiedPlayer player, @Mapper("historicArenaMode") @OptionalValue("") @AllowNull ArenaMode arenaMode, @Mapper("arenaMap") @OptionalValue("") @AllowNull String map) {
|
||||||
FightCommand.createArena(player, "/historic ", true, arenaMode, map, true, (p, mode, m) -> {
|
FightCommand.createArena(player, "/historic ", true, arenaMode, map, true, (p, mode, m) -> {
|
||||||
Subserver arena = new ServerStarter().arena(mode, m).blueLeader(p).start();
|
new ServerStarter().arena(mode, m).blueLeader(p).callback(
|
||||||
if(arena != null) {
|
arena -> Message.broadcast("HISTORIC_BROADCAST", "HISTORIC_BROADCAST_HOVER", new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/arena " + arena.getServer().getName()), mode.getDisplayName(), p.getName())
|
||||||
Message.broadcast("HISTORIC_BROADCAST", "HISTORIC_BROADCAST_HOVER",
|
).start();
|
||||||
new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/arena " + arena.getServer().getName()), mode.getDisplayName(), p.getName());
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,16 +20,11 @@
|
|||||||
package de.steamwar.bungeecore.commands;
|
package de.steamwar.bungeecore.commands;
|
||||||
|
|
||||||
import de.steamwar.bungeecore.Message;
|
import de.steamwar.bungeecore.Message;
|
||||||
|
import de.steamwar.command.SWCommand;
|
||||||
import de.steamwar.sql.IgnoreSystem;
|
import de.steamwar.sql.IgnoreSystem;
|
||||||
import de.steamwar.sql.SteamwarUser;
|
import de.steamwar.sql.SteamwarUser;
|
||||||
import de.steamwar.command.SWCommand;
|
|
||||||
import de.steamwar.command.SWCommandUtils;
|
|
||||||
import de.steamwar.command.TypeMapper;
|
|
||||||
import net.md_5.bungee.BungeeCord;
|
|
||||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||||
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
public class IgnoreCommand extends SWCommand {
|
public class IgnoreCommand extends SWCommand {
|
||||||
|
|
||||||
public IgnoreCommand() {
|
public IgnoreCommand() {
|
||||||
@ -37,14 +32,9 @@ public class IgnoreCommand extends SWCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Register(description = "USAGE_IGNORE")
|
@Register(description = "USAGE_IGNORE")
|
||||||
public void genericCommand(ProxiedPlayer p, @Mapper("player") String toIgnore) {
|
public void genericCommand(ProxiedPlayer p, @ErrorMessage("UNKNOWN_PLAYER") SteamwarUser target) {
|
||||||
SteamwarUser user = SteamwarUser.get(p.getUniqueId());
|
SteamwarUser user = SteamwarUser.get(p.getUniqueId());
|
||||||
|
|
||||||
SteamwarUser target = SteamwarUser.get(toIgnore);
|
|
||||||
if(target == null){
|
|
||||||
Message.send("UNKNOWN_PLAYER", p);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(target.equals(user)){
|
if(target.equals(user)){
|
||||||
Message.send("IGNORE_YOURSELF", p);
|
Message.send("IGNORE_YOURSELF", p);
|
||||||
return;
|
return;
|
||||||
@ -57,9 +47,4 @@ public class IgnoreCommand extends SWCommand {
|
|||||||
IgnoreSystem.ignore(user, target);
|
IgnoreSystem.ignore(user, target);
|
||||||
Message.send("IGNORE_MESSAGE", p, target.getUserName());
|
Message.send("IGNORE_MESSAGE", p, target.getUserName());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Mapper(value = "player", local = true)
|
|
||||||
public TypeMapper<String> playerTypeMapper() {
|
|
||||||
return SWCommandUtils.createMapper(s -> s, s -> BungeeCord.getInstance().getPlayers().stream().map(ProxiedPlayer::getName).collect(Collectors.toList()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -19,13 +19,13 @@
|
|||||||
|
|
||||||
package de.steamwar.bungeecore.commands;
|
package de.steamwar.bungeecore.commands;
|
||||||
|
|
||||||
import de.steamwar.bungeecore.*;
|
import de.steamwar.bungeecore.Message;
|
||||||
import de.steamwar.sql.BauweltMember;
|
import de.steamwar.bungeecore.Subserver;
|
||||||
import de.steamwar.command.SWCommand;
|
import de.steamwar.command.SWCommand;
|
||||||
import de.steamwar.command.TypeValidator;
|
import de.steamwar.command.TypeValidator;
|
||||||
import net.md_5.bungee.api.CommandSender;
|
import de.steamwar.sql.SteamwarUser;
|
||||||
|
import de.steamwar.sql.UserPerm;
|
||||||
import net.md_5.bungee.api.chat.ClickEvent;
|
import net.md_5.bungee.api.chat.ClickEvent;
|
||||||
import net.md_5.bungee.api.config.ServerInfo;
|
|
||||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||||
|
|
||||||
public class JoinmeCommand extends SWCommand {
|
public class JoinmeCommand extends SWCommand {
|
||||||
@ -36,7 +36,7 @@ public class JoinmeCommand extends SWCommand {
|
|||||||
|
|
||||||
@Register(description = "JOINME_USAGE")
|
@Register(description = "JOINME_USAGE")
|
||||||
public void genericCommand(ProxiedPlayer player) {
|
public void genericCommand(ProxiedPlayer player) {
|
||||||
if (!player.hasPermission("bungeecore.joinme")) {
|
if (!SteamwarUser.get(player.getUniqueId()).hasPerm(UserPerm.TEAM)) {
|
||||||
Message.send("JOINME_USAGE", player);
|
Message.send("JOINME_USAGE", player);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -50,35 +50,9 @@ public class JoinmeCommand extends SWCommand {
|
|||||||
Message.send("JOINME_PLAYER_SELF", player);
|
Message.send("JOINME_PLAYER_SELF", player);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ServerInfo server = target.getServer().getInfo();
|
|
||||||
String serverPerm = BungeeCore.serverPermissions.get(server.getName());
|
|
||||||
Subserver subserver = Subserver.getSubserver(target);
|
|
||||||
|
|
||||||
if(subserver != null) {
|
Subserver subserver = Subserver.getSubserver(target);
|
||||||
Servertype type = subserver.getType();
|
TpCommand.teleport(player, subserver != null ? subserver.getServer() : target.getServer().getInfo());
|
||||||
if (type == Servertype.ARENA) {
|
|
||||||
SubserverSystem.sendPlayer(subserver, player);
|
|
||||||
} else if (type == Servertype.BAUSERVER) {
|
|
||||||
Bauserver bauserver = (Bauserver) subserver;
|
|
||||||
if (bauserver.getOwner().equals(player.getUniqueId()) ||
|
|
||||||
BauweltMember.getBauMember(bauserver.getOwner(), player.getUniqueId()) != null) {
|
|
||||||
SubserverSystem.sendPlayer(subserver, player);
|
|
||||||
} else {
|
|
||||||
SubserverSystem.sendDeniedMessage(player, bauserver.getOwner());
|
|
||||||
Message.send("JOIN_PLAYER_BLOCK", player);
|
|
||||||
}
|
|
||||||
} else if(type == Servertype.BUILDER && !player.hasPermission("bungeecore.server.team")) {
|
|
||||||
Message.send("JOIN_PLAYER_BLOCK", player);
|
|
||||||
} else {
|
|
||||||
SubserverSystem.sendPlayer(subserver, player);
|
|
||||||
}
|
|
||||||
}else if(serverPerm != null && !player.hasPermission(serverPerm)){
|
|
||||||
Message.send("JOIN_PLAYER_BLOCK", player);
|
|
||||||
}else if(serverPerm == null && !player.getGroups().contains("team")) {
|
|
||||||
Message.send("JOIN_PLAYER_BLOCK", player);
|
|
||||||
}else{
|
|
||||||
player.connect(server);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ClassValidator(ProxiedPlayer.class)
|
@ClassValidator(ProxiedPlayer.class)
|
||||||
|
@ -19,42 +19,26 @@
|
|||||||
|
|
||||||
package de.steamwar.bungeecore.commands;
|
package de.steamwar.bungeecore.commands;
|
||||||
|
|
||||||
import de.steamwar.bungeecore.BungeeCore;
|
import de.steamwar.bungeecore.VelocityCore;
|
||||||
import de.steamwar.bungeecore.Message;
|
import de.steamwar.bungeecore.Message;
|
||||||
|
import de.steamwar.bungeecore.listeners.ConnectionListener;
|
||||||
import de.steamwar.command.SWCommand;
|
import de.steamwar.command.SWCommand;
|
||||||
import de.steamwar.command.SWCommandUtils;
|
|
||||||
import de.steamwar.command.TypeMapper;
|
|
||||||
import net.md_5.bungee.BungeeCord;
|
|
||||||
import net.md_5.bungee.api.CommandSender;
|
import net.md_5.bungee.api.CommandSender;
|
||||||
import net.md_5.bungee.api.ProxyServer;
|
|
||||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||||
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
public class KickCommand extends SWCommand {
|
public class KickCommand extends SWCommand {
|
||||||
|
|
||||||
public KickCommand() {
|
public KickCommand() {
|
||||||
super("kick", "bungeecore.kick");
|
super("kick", ConnectionListener.KICK_PERMISSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Register(description = "KICK_USAGE")
|
@Register(description = "KICK_USAGE")
|
||||||
public void genericCommand(CommandSender sender, @Mapper("player") String player, String... message) {
|
public void genericCommand(CommandSender sender, @ErrorMessage("KICK_OFFLINE") ProxiedPlayer target, String... message) {
|
||||||
ProxiedPlayer target = ProxyServer.getInstance().getPlayer(player);
|
|
||||||
if(target == null){
|
|
||||||
Message.send("KICK_OFFLINE", sender);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (message.length == 0) {
|
if (message.length == 0) {
|
||||||
target.disconnect(Message.parseToComponent("KICK_NORMAL", true, target));
|
target.disconnect(Message.parseToComponent("KICK_NORMAL", true, target));
|
||||||
} else {
|
} else {
|
||||||
target.disconnect(BungeeCore.stringToText(BungeeCore.CHAT_PREFIX + "§c" + String.join(" ", message)));
|
target.disconnect(VelocityCore.stringToText(VelocityCore.CHAT_PREFIX + "§c" + String.join(" ", message)));
|
||||||
}
|
}
|
||||||
Message.send("KICK_CONFIRM", sender, target.getName());
|
Message.send("KICK_CONFIRM", sender, target.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Mapper(value = "player", local = true)
|
|
||||||
public TypeMapper<String> playerTypeMapper() {
|
|
||||||
return SWCommandUtils.createMapper(s -> s, s -> BungeeCord.getInstance().getPlayers().stream().map(ProxiedPlayer::getName).collect(Collectors.toList()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@ import de.steamwar.bungeecore.inventory.SWInventory;
|
|||||||
import de.steamwar.bungeecore.inventory.SWItem;
|
import de.steamwar.bungeecore.inventory.SWItem;
|
||||||
import de.steamwar.bungeecore.inventory.SWListInv;
|
import de.steamwar.bungeecore.inventory.SWListInv;
|
||||||
import de.steamwar.bungeecore.inventory.SWStreamInv;
|
import de.steamwar.bungeecore.inventory.SWStreamInv;
|
||||||
|
import de.steamwar.bungeecore.listeners.ConnectionListener;
|
||||||
import de.steamwar.command.SWCommand;
|
import de.steamwar.command.SWCommand;
|
||||||
import de.steamwar.sql.Mod;
|
import de.steamwar.sql.Mod;
|
||||||
import net.md_5.bungee.api.chat.ClickEvent;
|
import net.md_5.bungee.api.chat.ClickEvent;
|
||||||
@ -36,7 +37,7 @@ import java.util.stream.Collectors;
|
|||||||
public class ModCommand extends SWCommand {
|
public class ModCommand extends SWCommand {
|
||||||
|
|
||||||
public ModCommand() {
|
public ModCommand() {
|
||||||
super("mod", "bungeecore.softreload", "mods");
|
super("mod", ConnectionListener.MOD_PERMISSION, "mods");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final Map<ProxiedPlayer, Mod.ModType> playerFilterType = new HashMap<>();
|
public static final Map<ProxiedPlayer, Mod.ModType> playerFilterType = new HashMap<>();
|
||||||
|
@ -34,9 +34,10 @@ public class PlaytimeCommand extends SWCommand {
|
|||||||
|
|
||||||
@Register
|
@Register
|
||||||
public void genericCommand(ProxiedPlayer player) {
|
public void genericCommand(ProxiedPlayer player) {
|
||||||
NumberFormat format = NumberFormat.getNumberInstance((player).getLocale());
|
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
||||||
|
NumberFormat format = NumberFormat.getNumberInstance(user.getLocale());
|
||||||
format.setMaximumFractionDigits(2);
|
format.setMaximumFractionDigits(2);
|
||||||
String formattedText = format.format((SteamwarUser.get(player.getUniqueId()).getOnlinetime() / (double) 3600));
|
String formattedText = format.format((user.getOnlinetime() / (double) 3600));
|
||||||
|
|
||||||
Message.send("HOURS_PLAYED", player, formattedText);
|
Message.send("HOURS_PLAYED", player, formattedText);
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
package de.steamwar.bungeecore.commands;
|
package de.steamwar.bungeecore.commands;
|
||||||
|
|
||||||
import de.steamwar.bungeecore.Message;
|
import de.steamwar.bungeecore.Message;
|
||||||
|
import de.steamwar.bungeecore.listeners.ConnectionListener;
|
||||||
import de.steamwar.bungeecore.listeners.PollSystem;
|
import de.steamwar.bungeecore.listeners.PollSystem;
|
||||||
import de.steamwar.sql.PollAnswer;
|
import de.steamwar.sql.PollAnswer;
|
||||||
import de.steamwar.command.SWCommand;
|
import de.steamwar.command.SWCommand;
|
||||||
@ -31,7 +32,7 @@ import java.util.Map;
|
|||||||
public class PollresultCommand extends SWCommand {
|
public class PollresultCommand extends SWCommand {
|
||||||
|
|
||||||
public PollresultCommand() {
|
public PollresultCommand() {
|
||||||
super("pollresult", "bungeecore.pollresults");
|
super("pollresult", ConnectionListener.POLLRESULT_PERMISSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Register
|
@Register
|
||||||
|
@ -20,13 +20,19 @@
|
|||||||
package de.steamwar.bungeecore.commands;
|
package de.steamwar.bungeecore.commands;
|
||||||
|
|
||||||
import com.google.gson.JsonParser;
|
import com.google.gson.JsonParser;
|
||||||
import de.steamwar.bungeecore.BungeeCore;
|
import de.steamwar.bungeecore.VelocityCore;
|
||||||
import de.steamwar.bungeecore.Message;
|
import de.steamwar.bungeecore.Message;
|
||||||
|
import de.steamwar.bungeecore.listeners.ConnectionListener;
|
||||||
|
import de.steamwar.bungeecore.listeners.IPSanitizer;
|
||||||
|
import de.steamwar.command.PreviousArguments;
|
||||||
import de.steamwar.command.SWCommand;
|
import de.steamwar.command.SWCommand;
|
||||||
|
import de.steamwar.command.TypeMapper;
|
||||||
import de.steamwar.messages.ChatSender;
|
import de.steamwar.messages.ChatSender;
|
||||||
import de.steamwar.sql.BannedUserIPs;
|
import de.steamwar.sql.BannedUserIPs;
|
||||||
import de.steamwar.sql.Punishment;
|
import de.steamwar.sql.Punishment;
|
||||||
import de.steamwar.sql.SteamwarUser;
|
import de.steamwar.sql.SteamwarUser;
|
||||||
|
import de.steamwar.sql.UserPerm;
|
||||||
|
import net.md_5.bungee.BungeeCord;
|
||||||
import net.md_5.bungee.api.ChatMessageType;
|
import net.md_5.bungee.api.ChatMessageType;
|
||||||
import net.md_5.bungee.api.CommandSender;
|
import net.md_5.bungee.api.CommandSender;
|
||||||
import net.md_5.bungee.api.ProxyServer;
|
import net.md_5.bungee.api.ProxyServer;
|
||||||
@ -40,12 +46,10 @@ import java.text.SimpleDateFormat;
|
|||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.time.temporal.ChronoUnit;
|
import java.time.temporal.ChronoUnit;
|
||||||
import java.util.Date;
|
import java.util.*;
|
||||||
import java.util.NoSuchElementException;
|
|
||||||
import java.util.Scanner;
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class PunishmentCommand {
|
public class PunishmentCommand {
|
||||||
|
|
||||||
@ -74,7 +78,7 @@ public class PunishmentCommand {
|
|||||||
} catch (NoSuchElementException e) {
|
} catch (NoSuchElementException e) {
|
||||||
// ignore, player does not exist
|
// ignore, player does not exist
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
BungeeCore.get().getLogger().log(Level.SEVERE, "Could not get offline player UUID " + playerName, e);
|
VelocityCore.get().getLogger().log(Level.SEVERE, "Could not get offline player UUID " + playerName, e);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -93,14 +97,15 @@ public class PunishmentCommand {
|
|||||||
|
|
||||||
ProxiedPlayer player = ProxyServer.getInstance().getPlayer(user.getUUID());
|
ProxiedPlayer player = ProxyServer.getInstance().getPlayer(user.getUUID());
|
||||||
if (player != null) {
|
if (player != null) {
|
||||||
|
String ip = IPSanitizer.getTrueAddress(player.getPendingConnection()).getHostAddress();
|
||||||
ChatSender.disconnect(player).system(punishmentMessage(user, Punishment.PunishmentType.Ban));
|
ChatSender.disconnect(player).system(punishmentMessage(user, Punishment.PunishmentType.Ban));
|
||||||
for (BannedUserIPs banned : BannedUserIPs.get(player.getAddress().getAddress().getHostAddress())) {
|
for (BannedUserIPs banned : BannedUserIPs.get(ip)) {
|
||||||
SteamwarUser bannedUser = SteamwarUser.get(banned.getUserID());
|
SteamwarUser bannedUser = SteamwarUser.get(banned.getUserID());
|
||||||
if (bannedUser.isPunished(Punishment.PunishmentType.Ban) && bannedUser.getPunishment(Punishment.PunishmentType.Ban).getEndTime().before(time)) {
|
if (bannedUser.isPunished(Punishment.PunishmentType.Ban) && bannedUser.getPunishment(Punishment.PunishmentType.Ban).getEndTime().before(time)) {
|
||||||
bannedUser.punish(Punishment.PunishmentType.Ban, time, banReason, punisher.getId(), perma);
|
bannedUser.punish(Punishment.PunishmentType.Ban, time, banReason, punisher.getId(), perma);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BannedUserIPs.banIP(user.getId(), player.getAddress().getAddress().getHostAddress());
|
BannedUserIPs.banIP(user.getId(), ip);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,12 +119,12 @@ public class PunishmentCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public PunishmentCommand(String command, Punishment.PunishmentType punishmentType) {
|
public PunishmentCommand(String command, Punishment.PunishmentType punishmentType) {
|
||||||
new SWCommand(command, "bungeecore.ban") {
|
new SWCommand(command, ConnectionListener.BAN_PERMISSION) {
|
||||||
|
|
||||||
@Register
|
@Register
|
||||||
public void genericCommand(ProxiedPlayer player, String toPunish, String date, @ErrorMessage(allowEAs = false, value = "PUNISHMENT_USAGE_REASON") String... message) {
|
public void genericCommand(ProxiedPlayer player, @Mapper("toPunish") String toPunish, String date, @ErrorMessage(allowEAs = false, value = "PUNISHMENT_USAGE_REASON") String... message) {
|
||||||
SteamwarUser punisher = SteamwarUser.get(player.getUniqueId());
|
SteamwarUser punisher = SteamwarUser.get(player.getUniqueId());
|
||||||
if (punishmentType.isNeedsAdmin() && !punisher.getUserGroup().isAdminGroup()) {
|
if (punishmentType.isNeedsAdmin() && !punisher.hasPerm(UserPerm.MODERATION)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,21 +149,35 @@ public class PunishmentCommand {
|
|||||||
public void genericError(ProxiedPlayer player, String... args) {
|
public void genericError(ProxiedPlayer player, String... args) {
|
||||||
ChatSender.of(player).send(true, ChatMessageType.CHAT, null, null, new Message("PUNISHMENT_USAGE", command));
|
ChatSender.of(player).send(true, ChatMessageType.CHAT, null, null, new Message("PUNISHMENT_USAGE", command));
|
||||||
}
|
}
|
||||||
};
|
|
||||||
if (punishmentType.getUnpunishmentMessage() == null) {
|
@Mapper(value = "toPunish", local = true)
|
||||||
return;
|
public TypeMapper<String> allUsers() {
|
||||||
}
|
return new TypeMapper<String>() {
|
||||||
String antiCommand = "un" + command;
|
@Override
|
||||||
new SWCommand(antiCommand, "bungeecore.ban") {
|
public String map(CommandSender commandSender, String[] previousArguments, String s) {
|
||||||
@Register
|
return s;
|
||||||
public void genericCommand(ProxiedPlayer player, String toUnpunish) {
|
|
||||||
if (punishmentType.isNeedsAdmin() && !SteamwarUser.get(player.getUniqueId()).getUserGroup().isAdminGroup()) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SteamwarUser target = existingUser(player, toUnpunish);
|
@Override
|
||||||
if (target == null)
|
public Collection<String> tabCompletes(CommandSender sender, PreviousArguments previousArguments, String s) {
|
||||||
|
List<String> players = BungeeCord.getInstance().getPlayers().stream()
|
||||||
|
.map(CommandSender::getName)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
players.add(s);
|
||||||
|
return players;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (punishmentType.getUnpunishmentMessage() == null) return;
|
||||||
|
String antiCommand = "un" + command;
|
||||||
|
new SWCommand(antiCommand, ConnectionListener.BAN_PERMISSION) {
|
||||||
|
@Register
|
||||||
|
public void genericCommand(ProxiedPlayer player, @ErrorMessage("UNKNOWN_PLAYER") SteamwarUser target) {
|
||||||
|
if (punishmentType.isNeedsAdmin() && !SteamwarUser.get(player.getUniqueId()).hasPerm(UserPerm.MODERATION)) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!target.isPunished(punishmentType)) {
|
if (!target.isPunished(punishmentType)) {
|
||||||
Message.send(punishmentType.getUsageNotPunished(), player);
|
Message.send(punishmentType.getUsageNotPunished(), player);
|
||||||
@ -178,13 +197,6 @@ public class PunishmentCommand {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
protected SteamwarUser existingUser(CommandSender sender, String arg){
|
|
||||||
SteamwarUser target = SteamwarUser.get(arg);
|
|
||||||
if(target == null)
|
|
||||||
Message.send("UNKNOWN_PLAYER", sender);
|
|
||||||
return target;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected SteamwarUser unsafeUser(CommandSender sender, String arg){
|
protected SteamwarUser unsafeUser(CommandSender sender, String arg){
|
||||||
SteamwarUser target = getOrCreateOfflinePlayer(arg);
|
SteamwarUser target = getOrCreateOfflinePlayer(arg);
|
||||||
if(target == null)
|
if(target == null)
|
||||||
|
@ -21,11 +21,11 @@ package de.steamwar.bungeecore.commands;
|
|||||||
|
|
||||||
import de.steamwar.bungeecore.ArenaMode;
|
import de.steamwar.bungeecore.ArenaMode;
|
||||||
import de.steamwar.bungeecore.Message;
|
import de.steamwar.bungeecore.Message;
|
||||||
import de.steamwar.sql.SteamwarUser;
|
|
||||||
import de.steamwar.sql.UserElo;
|
|
||||||
import de.steamwar.command.SWCommand;
|
import de.steamwar.command.SWCommand;
|
||||||
import de.steamwar.command.SWCommandUtils;
|
import de.steamwar.command.SWCommandUtils;
|
||||||
import de.steamwar.command.TypeMapper;
|
import de.steamwar.command.TypeMapper;
|
||||||
|
import de.steamwar.sql.SteamwarUser;
|
||||||
|
import de.steamwar.sql.UserElo;
|
||||||
import net.md_5.bungee.BungeeCord;
|
import net.md_5.bungee.BungeeCord;
|
||||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||||
|
|
||||||
@ -40,47 +40,30 @@ public class RankCommand extends SWCommand {
|
|||||||
|
|
||||||
@Register
|
@Register
|
||||||
public void ownRank(ProxiedPlayer player) {
|
public void ownRank(ProxiedPlayer player) {
|
||||||
rank(player, player.getName());
|
rank(player, SteamwarUser.get(player.getUniqueId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Register
|
@Register
|
||||||
public void rank(ProxiedPlayer player, @Mapper("player") String s) {
|
public void rank(ProxiedPlayer player, @ErrorMessage("RANK_PLAYER_NOT_FOUND") SteamwarUser user) {
|
||||||
SteamwarUser user = SteamwarUser.get(s);
|
if (!player.getName().equals(user.getUserName())) {
|
||||||
if (user == null) {
|
Message.sendPrefixless("RANK_PLAYER_FOUND", player, user.getUserName());
|
||||||
Message.send("RANK_PLAYER_NOT_FOUND", player);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!player.getName().equals(s)) {
|
|
||||||
Message.send("RANK_PLAYER_FOUND", player, user.getUserName());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for(ArenaMode mode : ArenaMode.getAllModes()) {
|
for(ArenaMode mode : ArenaMode.getAllModes()) {
|
||||||
if (!mode.isRanked())
|
if (!mode.isRanked())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Message.send("RANK_HEADER", player, mode.getChatName());
|
|
||||||
|
|
||||||
Optional<Integer> elo = UserElo.getElo(user.getId(), mode.getSchemType());
|
Optional<Integer> elo = UserElo.getElo(user.getId(), mode.getSchemType());
|
||||||
|
String eloString;
|
||||||
if (elo.isPresent()) {
|
if (elo.isPresent()) {
|
||||||
int placement = UserElo.getPlacement(elo.get(), mode.getSchemType());
|
int placement = UserElo.getPlacement(elo.get(), mode.getSchemType());
|
||||||
Message.send("RANK_PLACED", player, placement, elo.get());
|
eloString = Message.parse("RANK_PLACED", player, placement, elo.get());
|
||||||
} else {
|
} else {
|
||||||
Message.send("RANK_UNPLACED", player);
|
eloString = Message.parse("RANK_UNPLACED", player);
|
||||||
}
|
|
||||||
Message.send("RANK_EMBLEM", player, getEmblemProgression(player, mode.getChatName(), user.getId()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String getEmblemProgression(ProxiedPlayer player, String gameMode, int userId) {
|
Message.sendPrefixless("RANK_HEADER", player, mode.getChatName(), eloString);
|
||||||
int fightsOfSeason = UserElo.getFightsOfSeason(userId, gameMode);
|
Message.sendPrefixless("RANK_EMBLEM", player, UserElo.getEmblemProgression(mode.getChatName(), user.getId()));
|
||||||
if (fightsOfSeason < 10)
|
}
|
||||||
return Message.parse("RANK_NEEDED_FIGHTS_LEFT", player, "§8✧ ✦ ✶ ✷ ✸ ✹ ❂", 10 - fightsOfSeason);
|
|
||||||
|
|
||||||
return UserElo.getEmblemProgression(gameMode, userId);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Mapper(value = "player", local = true)
|
|
||||||
public TypeMapper<String> playerTypeMapper() {
|
|
||||||
return SWCommandUtils.createMapper(s -> s, s -> BungeeCord.getInstance().getPlayers().stream().map(ProxiedPlayer::getName).collect(Collectors.toList()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,5 +36,7 @@ public class RegelnCommand extends SWCommand {
|
|||||||
Message.sendPrefixless("REGELN_MWG", player, Message.parse("REGELN_MWG_HOVER", player), new ClickEvent(ClickEvent.Action.OPEN_URL, Message.parse("REGELN_MWG_URL", player)));
|
Message.sendPrefixless("REGELN_MWG", player, Message.parse("REGELN_MWG_HOVER", player), new ClickEvent(ClickEvent.Action.OPEN_URL, Message.parse("REGELN_MWG_URL", player)));
|
||||||
Message.sendPrefixless("REGELN_WG", player, Message.parse("REGELN_WG_HOVER", player), new ClickEvent(ClickEvent.Action.OPEN_URL, Message.parse("REGELN_WG_URL", player)));
|
Message.sendPrefixless("REGELN_WG", player, Message.parse("REGELN_WG_HOVER", player), new ClickEvent(ClickEvent.Action.OPEN_URL, Message.parse("REGELN_WG_URL", player)));
|
||||||
Message.sendPrefixless("REGELN_WS", player, Message.parse("REGELN_WS_HOVER", player), new ClickEvent(ClickEvent.Action.OPEN_URL, Message.parse("REGELN_WS_URL", player)));
|
Message.sendPrefixless("REGELN_WS", player, Message.parse("REGELN_WS_HOVER", player), new ClickEvent(ClickEvent.Action.OPEN_URL, Message.parse("REGELN_WS_URL", player)));
|
||||||
|
Message.sendPrefixless("REGELN_QG", player, Message.parse("REGELN_QG_HOVER", player), new ClickEvent(ClickEvent.Action.OPEN_URL, Message.parse("REGELN_QG_URL", player)));
|
||||||
|
Message.sendPrefixless("REGELN_CONDUCT", player, Message.parse("REGELN_CONDUCT_HOVER", player), new ClickEvent(ClickEvent.Action.OPEN_URL, Message.parse("REGELN_CONDUCT_URL", player)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,10 +23,7 @@ import de.steamwar.bungeecore.*;
|
|||||||
import de.steamwar.bungeecore.inventory.SWItem;
|
import de.steamwar.bungeecore.inventory.SWItem;
|
||||||
import de.steamwar.bungeecore.inventory.SWListInv;
|
import de.steamwar.bungeecore.inventory.SWListInv;
|
||||||
import de.steamwar.bungeecore.inventory.SWStreamInv;
|
import de.steamwar.bungeecore.inventory.SWStreamInv;
|
||||||
import de.steamwar.sql.Fight;
|
import de.steamwar.sql.*;
|
||||||
import de.steamwar.sql.Punishment;
|
|
||||||
import de.steamwar.sql.SchematicType;
|
|
||||||
import de.steamwar.sql.SteamwarUser;
|
|
||||||
import de.steamwar.command.SWCommand;
|
import de.steamwar.command.SWCommand;
|
||||||
import de.steamwar.messages.ChatSender;
|
import de.steamwar.messages.ChatSender;
|
||||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||||
@ -58,7 +55,7 @@ public class ReplayCommand extends SWCommand {
|
|||||||
if (tMap != null) map = tMap;
|
if (tMap != null) map = tMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (user.getUserGroup().isAdminGroup() && click.isShiftClick() && fight.replayExists()) {
|
if (user.hasPerm(UserPerm.MODERATION) && click.isShiftClick() && fight.replayExists()) {
|
||||||
starter.test(mode, map, player).start();
|
starter.test(mode, map, player).start();
|
||||||
} else if(!fight.replayAllowed()) {
|
} else if(!fight.replayAllowed()) {
|
||||||
sender.system("REPLAY_UNAVAILABLE");
|
sender.system("REPLAY_UNAVAILABLE");
|
||||||
|
@ -20,17 +20,16 @@
|
|||||||
package de.steamwar.bungeecore.commands;
|
package de.steamwar.bungeecore.commands;
|
||||||
|
|
||||||
import de.steamwar.command.SWCommand;
|
import de.steamwar.command.SWCommand;
|
||||||
import net.md_5.bungee.api.CommandSender;
|
|
||||||
import net.md_5.bungee.api.ProxyServer;
|
import net.md_5.bungee.api.ProxyServer;
|
||||||
import net.md_5.bungee.api.config.ServerInfo;
|
import net.md_5.bungee.api.config.ServerInfo;
|
||||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||||
|
|
||||||
public class ServerSwitchCommand extends SWCommand {
|
public class ServerSwitchCommand extends SWCommand {
|
||||||
|
|
||||||
private String serverName;
|
private final String serverName;
|
||||||
|
|
||||||
public ServerSwitchCommand(String cmd, String name, String permission, String... aliases) {
|
public ServerSwitchCommand(String cmd, String name, String... aliases) {
|
||||||
super(cmd, permission, aliases);
|
super(cmd, null, aliases);
|
||||||
serverName = name;
|
serverName = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
package de.steamwar.bungeecore.commands;
|
package de.steamwar.bungeecore.commands;
|
||||||
|
|
||||||
import de.steamwar.bungeecore.listeners.ChatListener;
|
import de.steamwar.bungeecore.listeners.ChatListener;
|
||||||
|
import de.steamwar.bungeecore.listeners.ConnectionListener;
|
||||||
import de.steamwar.command.SWCommand;
|
import de.steamwar.command.SWCommand;
|
||||||
import de.steamwar.messages.ChatSender;
|
import de.steamwar.messages.ChatSender;
|
||||||
import net.md_5.bungee.api.CommandSender;
|
import net.md_5.bungee.api.CommandSender;
|
||||||
@ -27,7 +28,7 @@ import net.md_5.bungee.api.CommandSender;
|
|||||||
public class ServerTeamchatCommand extends SWCommand {
|
public class ServerTeamchatCommand extends SWCommand {
|
||||||
|
|
||||||
public ServerTeamchatCommand() {
|
public ServerTeamchatCommand() {
|
||||||
super("stc", "bungeecore.teamchat","serverteamchat");
|
super("stc", ConnectionListener.TEAMCHAT_PERMISSION,"serverteamchat");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Register(description = "STC_USAGE")
|
@Register(description = "STC_USAGE")
|
||||||
|
@ -23,15 +23,12 @@ import de.steamwar.bungeecore.Message;
|
|||||||
import de.steamwar.bungeecore.Storage;
|
import de.steamwar.bungeecore.Storage;
|
||||||
import de.steamwar.bungeecore.inventory.SWItem;
|
import de.steamwar.bungeecore.inventory.SWItem;
|
||||||
import de.steamwar.bungeecore.inventory.SWListInv;
|
import de.steamwar.bungeecore.inventory.SWListInv;
|
||||||
import de.steamwar.sql.Punishment;
|
|
||||||
import de.steamwar.sql.SteamwarUser;
|
|
||||||
import de.steamwar.sql.Team;
|
|
||||||
import de.steamwar.sql.TeamTeilnahme;
|
|
||||||
import de.steamwar.command.PreviousArguments;
|
import de.steamwar.command.PreviousArguments;
|
||||||
import de.steamwar.command.SWCommand;
|
import de.steamwar.command.SWCommand;
|
||||||
import de.steamwar.command.TypeMapper;
|
import de.steamwar.command.TypeMapper;
|
||||||
|
import de.steamwar.command.TypeValidator;
|
||||||
import de.steamwar.messages.ChatSender;
|
import de.steamwar.messages.ChatSender;
|
||||||
import de.steamwar.sql.Event;
|
import de.steamwar.sql.*;
|
||||||
import net.md_5.bungee.BungeeCord;
|
import net.md_5.bungee.BungeeCord;
|
||||||
import net.md_5.bungee.api.ChatColor;
|
import net.md_5.bungee.api.ChatColor;
|
||||||
import net.md_5.bungee.api.CommandSender;
|
import net.md_5.bungee.api.CommandSender;
|
||||||
@ -50,6 +47,7 @@ import java.time.Instant;
|
|||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import static de.steamwar.bungeecore.Storage.teamInvitations;
|
import static de.steamwar.bungeecore.Storage.teamInvitations;
|
||||||
|
|
||||||
@ -117,11 +115,9 @@ public class TeamCommand extends SWCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Register(value = "create", description = "TEAM_CREATE_USAGE")
|
@Register(value = "create", description = "TEAM_CREATE_USAGE")
|
||||||
public void create(ProxiedPlayer player, @Length(min = 2, max = 4) @ErrorMessage("TEAM_KUERZEL_LENGTH") String kuerzel, @Length(min = 4, max = 15) @ErrorMessage("TEAM_NAME_LENGTH") String name){
|
public void create(@Validator("isNotInTeam") ProxiedPlayer player, @Length(min = 2, max = 4) @ErrorMessage("TEAM_KUERZEL_LENGTH") String kuerzel, @Length(min = 4, max = 15) @ErrorMessage("TEAM_NAME_LENGTH") String name){
|
||||||
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
||||||
Team team = Team.get(user.getTeam());
|
Team team = Team.get(user.getTeam());
|
||||||
if(unwantedInTeam(player, user))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(checkTeamKuerzel(player, team, kuerzel))
|
if(checkTeamKuerzel(player, team, kuerzel))
|
||||||
return;
|
return;
|
||||||
@ -136,10 +132,8 @@ public class TeamCommand extends SWCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Register("join")
|
@Register("join")
|
||||||
public void join(ProxiedPlayer player, String... args){
|
public void join(@Validator("isNotInTeam") ProxiedPlayer player, String... args){
|
||||||
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
||||||
if(unwantedInTeam(player, user))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(notDuringEvent(player))
|
if(notDuringEvent(player))
|
||||||
return;
|
return;
|
||||||
@ -186,13 +180,11 @@ public class TeamCommand extends SWCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Register("stepback")
|
@Register("stepback")
|
||||||
public void stepBack(ProxiedPlayer player) {
|
public void stepBack(@Validator("isLeader") ProxiedPlayer player) {
|
||||||
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
||||||
Team team = Team.get(user.getTeam());
|
Team team = Team.get(user.getTeam());
|
||||||
if(notLeader(player, user))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(team.size() > 1 && team.getMembers().stream().map(SteamwarUser::get).filter(member -> user != member).noneMatch(SteamwarUser::isLeader)){
|
if(noRemainingLeaders(team, user)){
|
||||||
Message.send("TEAM_OTHER_LEADER_REQUIRED", player);
|
Message.send("TEAM_OTHER_LEADER_REQUIRED", player);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -202,14 +194,12 @@ public class TeamCommand extends SWCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Register("leave")
|
@Register("leave")
|
||||||
public void leave(ProxiedPlayer player){
|
public void leave(@Validator("isInTeam") ProxiedPlayer player){
|
||||||
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
||||||
Team team = Team.get(user.getTeam());
|
Team team = Team.get(user.getTeam());
|
||||||
if(notInTeam(player, user))
|
|
||||||
return;
|
|
||||||
|
|
||||||
int teamSize = team.size();
|
int teamSize = team.size();
|
||||||
if(teamSize > 1 && user.isLeader() && team.getMembers().stream().map(SteamwarUser::get).filter(member -> user != member).noneMatch(SteamwarUser::isLeader)){
|
if(teamSize > 1 && user.isLeader() && noRemainingLeaders(team, user)) {
|
||||||
Message.send("TEAM_OTHER_LEADER_REQUIRED", player);
|
Message.send("TEAM_OTHER_LEADER_REQUIRED", player);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -223,18 +213,19 @@ public class TeamCommand extends SWCommand {
|
|||||||
Message.send("TEAM_LEAVE_LEFT", player);
|
Message.send("TEAM_LEAVE_LEFT", player);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean noRemainingLeaders(Team team, SteamwarUser except) {
|
||||||
|
return SteamwarUser.getTeam(team.getTeamId()).stream().filter(member -> except.getId() != member.getId()).noneMatch(SteamwarUser::isLeader);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Register(value = "invite", description = "TEAM_INVITE_USAGE")
|
@Register(value = "invite", description = "TEAM_INVITE_USAGE")
|
||||||
public void invite(ProxiedPlayer player, String toInvite){
|
public void invite(@Validator("isLeader") ProxiedPlayer player, @AllowNull SteamwarUser target){
|
||||||
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
||||||
Team team = Team.get(user.getTeam());
|
Team team = Team.get(user.getTeam());
|
||||||
if(notLeader(player, user))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(notDuringEvent(player))
|
if(notDuringEvent(player))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
SteamwarUser target = SteamwarUser.get(toInvite);
|
|
||||||
if(target == null){
|
if(target == null){
|
||||||
Message.send("TEAM_INVITE_NO_PLAYER", player);
|
Message.send("TEAM_INVITE_NO_PLAYER", player);
|
||||||
return;
|
return;
|
||||||
@ -253,20 +244,17 @@ public class TeamCommand extends SWCommand {
|
|||||||
|
|
||||||
teamInvitations.get(target.getId()).add(team.getTeamId());
|
teamInvitations.get(target.getId()).add(team.getTeamId());
|
||||||
|
|
||||||
Message.send("TEAM_INVITE_INVITED", player, toInvite);
|
Message.send("TEAM_INVITE_INVITED", player, target.getUserName());
|
||||||
ProxiedPlayer p = ProxyServer.getInstance().getPlayer(target.getUUID());
|
ProxiedPlayer p = ProxyServer.getInstance().getPlayer(target.getUUID());
|
||||||
if(p != null)
|
if(p != null)
|
||||||
Message.send("TEAM_INVITE_INVITED_TARGET", p, team.getTeamColor(), team.getTeamName());
|
Message.send("TEAM_INVITE_INVITED_TARGET", p, team.getTeamColor(), team.getTeamName());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Register(value = "remove", description = "TEAM_REMOVE_USAGE")
|
@Register(value = "remove", description = "TEAM_REMOVE_USAGE")
|
||||||
public void remove(ProxiedPlayer player, String toRemove){
|
public void remove(@Validator("isLeader") ProxiedPlayer player, @AllowNull @Mapper("memberList") SteamwarUser target){
|
||||||
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
||||||
Team team = Team.get(user.getTeam());
|
Team team = Team.get(user.getTeam());
|
||||||
if(notLeader(player, user))
|
|
||||||
return;
|
|
||||||
|
|
||||||
SteamwarUser target = SteamwarUser.get(toRemove);
|
|
||||||
if(target == null){
|
if(target == null){
|
||||||
Message.send("TEAM_REMOVE_NOT_PLAYER", player);
|
Message.send("TEAM_REMOVE_NOT_PLAYER", player);
|
||||||
return;
|
return;
|
||||||
@ -301,12 +289,31 @@ public class TeamCommand extends SWCommand {
|
|||||||
Message.send("TEAM_REMOVE_REMOVED_TARGET", player);
|
Message.send("TEAM_REMOVE_REMOVED_TARGET", player);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Mapper(value = "memberList", local = true)
|
||||||
|
public TypeMapper<SteamwarUser> memberList() {
|
||||||
|
return new TypeMapper<SteamwarUser>() {
|
||||||
|
@Override
|
||||||
|
public SteamwarUser map(CommandSender commandSender, String[] previousArguments, String s) {
|
||||||
|
return SteamwarUser.get(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<String> tabCompletes(CommandSender sender, PreviousArguments previousArguments, String s) {
|
||||||
|
if (!(sender instanceof ProxiedPlayer)) return Collections.emptyList();
|
||||||
|
ProxiedPlayer player = (ProxiedPlayer) sender;
|
||||||
|
Team team = Team.get(SteamwarUser.get(player.getUniqueId()).getTeam());
|
||||||
|
return team.getMembers().stream()
|
||||||
|
.map(SteamwarUser::get)
|
||||||
|
.map(SteamwarUser::getUserName)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
@Register(value = "changekurzel", description = "TEAM_KUERZEL_USAGE")
|
@Register(value = "changekurzel", description = "TEAM_KUERZEL_USAGE")
|
||||||
public void changekuerzel(ProxiedPlayer player, @Length(min = 2, max = 4) @ErrorMessage("TEAM_KUERZEL_LENGTH") String kuerzel){
|
public void changekuerzel(@Validator("isLeader") ProxiedPlayer player, @Length(min = 2, max = 4) @ErrorMessage("TEAM_KUERZEL_LENGTH") String kuerzel){
|
||||||
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
||||||
Team team = Team.get(user.getTeam());
|
Team team = Team.get(user.getTeam());
|
||||||
if(notLeader(player, user))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(notDuringEvent(player))
|
if(notDuringEvent(player))
|
||||||
return;
|
return;
|
||||||
@ -319,11 +326,9 @@ public class TeamCommand extends SWCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Register(value = "changename", description = "TEAM_NAME_USAGE")
|
@Register(value = "changename", description = "TEAM_NAME_USAGE")
|
||||||
public void changename(ProxiedPlayer player, @Length(min = 4, max = 15) @ErrorMessage("TEAM_NAME_LENGTH") String name){
|
public void changename(@Validator("isLeader") ProxiedPlayer player, @Length(min = 4, max = 15) @ErrorMessage("TEAM_NAME_LENGTH") String name){
|
||||||
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
||||||
Team team = Team.get(user.getTeam());
|
Team team = Team.get(user.getTeam());
|
||||||
if(notLeader(player, user))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(notDuringEvent(player))
|
if(notDuringEvent(player))
|
||||||
return;
|
return;
|
||||||
@ -336,17 +341,14 @@ public class TeamCommand extends SWCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Register(value = "promote", description = "TEAM_LEADER_USAGE")
|
@Register(value = "promote", description = "TEAM_LEADER_USAGE")
|
||||||
public void promote(ProxiedPlayer player, String toPromote){
|
public void promote(@Validator("isLeader") ProxiedPlayer player, @AllowNull @Mapper("memberList") SteamwarUser target){
|
||||||
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
||||||
if(notLeader(player, user))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(notDuringEvent(player))
|
if(notDuringEvent(player))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
SteamwarUser target = SteamwarUser.get(toPromote);
|
|
||||||
if(target == null){
|
if(target == null){
|
||||||
Message.send("TEAM_LEADER_NOT_USER", player, toPromote);
|
Message.send("TEAM_LEADER_NOT_USER", player);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -356,7 +358,7 @@ public class TeamCommand extends SWCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
target.setLeader(true);
|
target.setLeader(true);
|
||||||
Message.send("TEAM_LEADER_PROMOTED", player, toPromote);
|
Message.send("TEAM_LEADER_PROMOTED", player, target.getUserName());
|
||||||
}
|
}
|
||||||
|
|
||||||
private String playerName(SteamwarUser user){
|
private String playerName(SteamwarUser user){
|
||||||
@ -364,31 +366,25 @@ public class TeamCommand extends SWCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Register("info")
|
@Register("info")
|
||||||
public void info(ProxiedPlayer player, String... args){
|
public void info(@Validator("isInTeam") ProxiedPlayer player){
|
||||||
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
||||||
Team team = Team.get(user.getTeam());
|
Team team = Team.get(user.getTeam());
|
||||||
if(args.length == 0 && user.getTeam() == 0){
|
info(player, team);
|
||||||
Message.send("TEAM_INFO_USAGE", player);
|
|
||||||
return;
|
|
||||||
}else if(user.getTeam() == 0 || args.length == 1){
|
|
||||||
team = Team.get(args[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(team == null){
|
|
||||||
Message.send("UNKNOWN_TEAM", player);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Register(value = "info", description = "TEAM_INFO_USAGE")
|
||||||
|
public void info(ProxiedPlayer player, @ErrorMessage("UNKNOWN_TEAM") Team team){
|
||||||
|
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
||||||
Message.sendPrefixless("TEAM_INFO_TEAM", player, team.getTeamName(), team.getTeamColor(), team.getTeamKuerzel());
|
Message.sendPrefixless("TEAM_INFO_TEAM", player, team.getTeamName(), team.getTeamColor(), team.getTeamKuerzel());
|
||||||
|
|
||||||
List<SteamwarUser> users = team.getMembers().stream().map(SteamwarUser::get).collect(Collectors.toList());
|
List<SteamwarUser> users = team.getMembers().stream().map(SteamwarUser::get).collect(Collectors.toList());
|
||||||
|
|
||||||
Message.sendPrefixless("TEAM_INFO_LEADER", player, getMemberList(users, true));
|
Message.sendPrefixless("TEAM_INFO_LEADER", player, users.stream().filter(SteamwarUser::isLeader).count(), getMemberList(users, true));
|
||||||
|
|
||||||
String members = getMemberList(users, false);
|
String members = getMemberList(users, false);
|
||||||
|
|
||||||
if(members.length() > 0) {
|
if(members.length() > 0) {
|
||||||
Message.sendPrefixless("TEAM_INFO_MEMBER", player, members);
|
Message.sendPrefixless("TEAM_INFO_MEMBER", player, users.stream().filter(u -> !u.isLeader()).count(), members);
|
||||||
}
|
}
|
||||||
|
|
||||||
Set<Event> events = TeamTeilnahme.getEvents(team.getTeamId());
|
Set<Event> events = TeamTeilnahme.getEvents(team.getTeamId());
|
||||||
@ -448,11 +444,9 @@ public class TeamCommand extends SWCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Register("event")
|
@Register("event")
|
||||||
public void event(ProxiedPlayer player) {
|
public void event(@Validator("isInTeam") ProxiedPlayer player) {
|
||||||
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
||||||
Team team = Team.get(user.getTeam());
|
Team team = Team.get(user.getTeam());
|
||||||
if(notInTeam(player, user))
|
|
||||||
return;
|
|
||||||
|
|
||||||
Message.send("TEAM_EVENT_USAGE", player);
|
Message.send("TEAM_EVENT_USAGE", player);
|
||||||
Set<Event> events = TeamTeilnahme.getEvents(team.getTeamId());
|
Set<Event> events = TeamTeilnahme.getEvents(team.getTeamId());
|
||||||
@ -465,14 +459,9 @@ public class TeamCommand extends SWCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Register("event")
|
@Register("event")
|
||||||
public void event(ProxiedPlayer player, Event event){
|
public void event(@Validator("isLeader") ProxiedPlayer player, Event event){
|
||||||
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
||||||
Team team = Team.get(user.getTeam());
|
Team team = Team.get(user.getTeam());
|
||||||
if(notInTeam(player, user))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(notLeader(player, user))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(notDuringEvent(player))
|
if(notDuringEvent(player))
|
||||||
return;
|
return;
|
||||||
@ -493,34 +482,33 @@ public class TeamCommand extends SWCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Register("tp")
|
@Register("tp")
|
||||||
public void tp(ProxiedPlayer player, String... args){
|
public void tp(@Validator("isInTeam") ProxiedPlayer player) {
|
||||||
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
||||||
Team team = Team.get(user.getTeam());
|
Team team = Team.get(user.getTeam());
|
||||||
if(args.length == 0){
|
|
||||||
if(notInTeam(player, user))
|
|
||||||
return;
|
|
||||||
tp(player, team);
|
tp(player, team);
|
||||||
return;
|
|
||||||
}
|
|
||||||
Team targetTeam = Team.get(args[0]);
|
|
||||||
if(targetTeam == null){
|
|
||||||
Message.send("TEAM_TP_NO_TEAM", player);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
tp(player, targetTeam);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void tp(ProxiedPlayer player, Team targetTeam) {
|
@Register("tp")
|
||||||
if (targetTeam.getAddress() == null) {
|
public void tp(ProxiedPlayer player, @ErrorMessage("TEAM_TP_NO_TEAM") @Mapper("teamWithTeamServer") Team targetTeam) {
|
||||||
|
if (targetTeam.getAddress() == null || targetTeam.getAddress().isEmpty()) {
|
||||||
Message.send("TEAM_NO_ADDRESS", player);
|
Message.send("TEAM_NO_ADDRESS", player);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ServerInfo serverInfo = Storage.teamServers.computeIfAbsent(targetTeam.getTeamId(), integer -> {
|
|
||||||
InetSocketAddress address = new InetSocketAddress(targetTeam.getAddress(), targetTeam.getPort());
|
InetSocketAddress address = new InetSocketAddress(targetTeam.getAddress(), targetTeam.getPort());
|
||||||
|
ServerInfo serverInfo = Storage.teamServers.computeIfAbsent(targetTeam.getTeamId(), integer -> {
|
||||||
ServerInfo info = ProxyServer.getInstance().constructServerInfo("Team " + targetTeam.getTeamKuerzel(), address, "SteamWar.de - Teamserver", false);
|
ServerInfo info = ProxyServer.getInstance().constructServerInfo("Team " + targetTeam.getTeamKuerzel(), address, "SteamWar.de - Teamserver", false);
|
||||||
ProxyServer.getInstance().getServers().put(info.getName(), info);
|
ProxyServer.getInstance().getServers().put(info.getName(), info);
|
||||||
return info;
|
return info;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (!address.equals(serverInfo.getSocketAddress())) {
|
||||||
|
serverInfo = Storage.teamServers.remove(targetTeam.getTeamId());
|
||||||
|
ProxyServer.getInstance().getServers().remove(serverInfo.getName());
|
||||||
|
tp(player, targetTeam);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
player.connect(ServerConnectRequest.builder()
|
player.connect(ServerConnectRequest.builder()
|
||||||
.target(serverInfo)
|
.target(serverInfo)
|
||||||
.connectTimeout(BungeeCord.getInstance().getConfig().getServerConnectTimeout())
|
.connectTimeout(BungeeCord.getInstance().getConfig().getServerConnectTimeout())
|
||||||
@ -542,11 +530,9 @@ public class TeamCommand extends SWCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Register(value = "server", description = "TEAM_SERVER_USAGE")
|
@Register(value = "server", description = "TEAM_SERVER_USAGE")
|
||||||
public void server(ProxiedPlayer player, String server, @Min(intValue = 1) @Max(intValue = 65535) @ErrorMessage("TEAM_SERVER_PORT_INVALID") int port){
|
public void server(@Validator("isLeader") ProxiedPlayer player, String server, @Min(intValue = 1) @Max(intValue = 65535) @ErrorMessage("TEAM_SERVER_PORT_INVALID") int port){
|
||||||
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
||||||
Team team = Team.get(user.getTeam());
|
Team team = Team.get(user.getTeam());
|
||||||
if(notLeader(player, user))
|
|
||||||
return;
|
|
||||||
if (PunishmentCommand.isPunishedWithMessage(ChatSender.of(player), Punishment.PunishmentType.NoTeamServer)) {
|
if (PunishmentCommand.isPunishedWithMessage(ChatSender.of(player), Punishment.PunishmentType.NoTeamServer)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -581,11 +567,9 @@ public class TeamCommand extends SWCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Register("color")
|
@Register("color")
|
||||||
public void changeColor(ProxiedPlayer player) {
|
public void changeColor(@Validator("isLeader") ProxiedPlayer player) {
|
||||||
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
||||||
Team team = Team.get(user.getTeam());
|
Team team = Team.get(user.getTeam());
|
||||||
if(notLeader(player, user))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(notDuringEvent(player))
|
if(notDuringEvent(player))
|
||||||
return;
|
return;
|
||||||
@ -630,6 +614,89 @@ public class TeamCommand extends SWCommand {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Validator(value = "isNotInTeam", local = true)
|
||||||
|
public TypeValidator<ProxiedPlayer> isNotInTeamValidator() {
|
||||||
|
return (sender, value, messageSender) -> {
|
||||||
|
if (!(sender instanceof ProxiedPlayer)) return false;
|
||||||
|
ProxiedPlayer player = (ProxiedPlayer) sender;
|
||||||
|
SteamwarUser steamwarUser = SteamwarUser.get(player.getUniqueId());
|
||||||
|
if (steamwarUser.getTeam() != 0) {
|
||||||
|
messageSender.send("TEAM_IN_TEAM");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Validator(value = "isInTeam", local = true)
|
||||||
|
public TypeValidator<ProxiedPlayer> isInTeamValidator() {
|
||||||
|
return (sender, value, messageSender) -> {
|
||||||
|
if (!(sender instanceof ProxiedPlayer)) return false;
|
||||||
|
ProxiedPlayer player = (ProxiedPlayer) sender;
|
||||||
|
SteamwarUser steamwarUser = SteamwarUser.get(player.getUniqueId());
|
||||||
|
if (steamwarUser.getTeam() == 0) {
|
||||||
|
messageSender.send("TEAM_NOT_IN_TEAM");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Validator(value = "isLeader", local = true)
|
||||||
|
public TypeValidator<ProxiedPlayer> isLeaderValidator() {
|
||||||
|
return (sender, value, messageSender) -> {
|
||||||
|
if (!(sender instanceof ProxiedPlayer)) return false;
|
||||||
|
ProxiedPlayer player = (ProxiedPlayer) sender;
|
||||||
|
SteamwarUser steamwarUser = SteamwarUser.get(player.getUniqueId());
|
||||||
|
if (steamwarUser.getTeam() == 0) {
|
||||||
|
messageSender.send("TEAM_NOT_IN_TEAM");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!steamwarUser.isLeader()) {
|
||||||
|
messageSender.send("TEAM_NOT_LEADER");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@ClassMapper(Team.class)
|
||||||
|
@Cached(global = true, cacheDuration = 60)
|
||||||
|
public TypeMapper<Team> team() {
|
||||||
|
return new TypeMapper<Team>() {
|
||||||
|
@Override
|
||||||
|
public Team map(CommandSender commandSender, String[] previousArguments, String s) {
|
||||||
|
return Team.get(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<String> tabCompletes(CommandSender sender, PreviousArguments previousArguments, String s) {
|
||||||
|
return Team.getAll().stream()
|
||||||
|
.flatMap(team -> Stream.of(team.getTeamName(), team.getTeamKuerzel()))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Mapper(value = "teamWithTeamServer", local = true)
|
||||||
|
@Cached(global = true, cacheDuration = 60)
|
||||||
|
public TypeMapper<Team> teamWithTeamServer() {
|
||||||
|
return new TypeMapper<Team>() {
|
||||||
|
@Override
|
||||||
|
public Team map(CommandSender commandSender, String[] previousArguments, String s) {
|
||||||
|
return Team.get(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<String> tabCompletes(CommandSender sender, PreviousArguments previousArguments, String s) {
|
||||||
|
return Team.getAll().stream()
|
||||||
|
.filter(team -> team.getAddress() != null && !team.getAddress().isEmpty())
|
||||||
|
.flatMap(team -> Stream.of(team.getTeamName(), team.getTeamKuerzel()))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
private boolean checkTeamName(ProxiedPlayer player, Team team, String arg){
|
private boolean checkTeamName(ProxiedPlayer player, Team team, String arg){
|
||||||
Team t = Team.get(arg);
|
Team t = Team.get(arg);
|
||||||
if(t != null && t.getTeamId() != team.getTeamId()){
|
if(t != null && t.getTeamId() != team.getTeamId()){
|
||||||
@ -648,32 +715,6 @@ public class TeamCommand extends SWCommand {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean unwantedInTeam(ProxiedPlayer player, SteamwarUser user){
|
|
||||||
if(user.getTeam() != 0){
|
|
||||||
Message.send("TEAM_IN_TEAM", player);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean notInTeam(ProxiedPlayer player, SteamwarUser user){
|
|
||||||
if(user.getTeam() == 0){
|
|
||||||
Message.send("TEAM_NOT_IN_TEAM", player);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean notLeader(ProxiedPlayer player, SteamwarUser user){
|
|
||||||
if(notInTeam(player, user))
|
|
||||||
return true;
|
|
||||||
if(!user.isLeader()){
|
|
||||||
Message.send("TEAM_NOT_LEADER", player);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean notDuringEvent(ProxiedPlayer player){
|
private boolean notDuringEvent(ProxiedPlayer player){
|
||||||
if(Event.get() != null){
|
if(Event.get() != null){
|
||||||
Message.send("TEAM_NOT_IN_EVENT", player);
|
Message.send("TEAM_NOT_IN_EVENT", player);
|
||||||
|
@ -20,25 +20,19 @@
|
|||||||
package de.steamwar.bungeecore.commands;
|
package de.steamwar.bungeecore.commands;
|
||||||
|
|
||||||
import de.steamwar.bungeecore.*;
|
import de.steamwar.bungeecore.*;
|
||||||
import de.steamwar.sql.BauweltMember;
|
import de.steamwar.sql.*;
|
||||||
import de.steamwar.sql.Punishment;
|
|
||||||
import de.steamwar.sql.SteamwarUser;
|
|
||||||
import de.steamwar.sql.Team;
|
|
||||||
import de.steamwar.bungeecore.util.BauLock;
|
import de.steamwar.bungeecore.util.BauLock;
|
||||||
import de.steamwar.bungeecore.util.Chat19;
|
import de.steamwar.bungeecore.util.Chat19;
|
||||||
import de.steamwar.command.SWCommand;
|
import de.steamwar.command.SWCommand;
|
||||||
import de.steamwar.command.TypeMapper;
|
import de.steamwar.command.TypeMapper;
|
||||||
import de.steamwar.messages.ChatSender;
|
import de.steamwar.messages.ChatSender;
|
||||||
import de.steamwar.sql.Event;
|
|
||||||
import net.md_5.bungee.BungeeCord;
|
import net.md_5.bungee.BungeeCord;
|
||||||
import net.md_5.bungee.api.CommandSender;
|
import net.md_5.bungee.api.CommandSender;
|
||||||
import net.md_5.bungee.api.ProxyServer;
|
import net.md_5.bungee.api.ProxyServer;
|
||||||
import net.md_5.bungee.api.config.ServerInfo;
|
import net.md_5.bungee.api.config.ServerInfo;
|
||||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class TpCommand extends SWCommand {
|
public class TpCommand extends SWCommand {
|
||||||
|
|
||||||
@ -69,7 +63,7 @@ public class TpCommand extends SWCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Mapper("to")
|
@Mapper("to")
|
||||||
@Cached(cacheDuration = 10, global = true)
|
@Cached(cacheDuration = 10)
|
||||||
public TypeMapper<String> tabCompleter() {
|
public TypeMapper<String> tabCompleter() {
|
||||||
return new TypeMapper<String>() {
|
return new TypeMapper<String>() {
|
||||||
@Override
|
@Override
|
||||||
@ -90,6 +84,11 @@ public class TpCommand extends SWCommand {
|
|||||||
list.add(team.getTeamKuerzel());
|
list.add(team.getTeamKuerzel());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
if (Storage.teamServers.containsValue(((ProxiedPlayer) sender).getServer().getInfo())) {
|
||||||
|
Storage.directTabItems.getOrDefault((ProxiedPlayer) sender, Collections.emptyMap()).forEach((uuid, item) -> {
|
||||||
|
list.add(item.getUsername());
|
||||||
|
});
|
||||||
|
}
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -102,41 +101,44 @@ public class TpCommand extends SWCommand {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
String serverPerm = BungeeCore.serverPermissions.get(server.getName());
|
|
||||||
Subserver subserver = Subserver.getSubserver(server);
|
Subserver subserver = Subserver.getSubserver(server);
|
||||||
|
if(subserver == null) {
|
||||||
|
player.connect(server);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (subserver != null && subserver.getType() == Servertype.ARENA) {
|
switch (subserver.getType()) {
|
||||||
if (!PunishmentCommand.isPunishedWithMessage(sender, Punishment.PunishmentType.NoFightServer))
|
case ARENA:
|
||||||
SubserverSystem.sendPlayer(subserver, player);
|
if (PunishmentCommand.isPunishedWithMessage(sender, Punishment.PunishmentType.NoFightServer))
|
||||||
|
return;
|
||||||
|
break;
|
||||||
|
|
||||||
} else if(subserver instanceof Bauserver) {
|
case BAUSERVER:
|
||||||
Bauserver bauserver = (Bauserver) subserver;
|
Bauserver bauserver = (Bauserver) subserver;
|
||||||
ProxiedPlayer checker = BungeeCord.getInstance().getPlayer(bauserver.getOwner());
|
ProxiedPlayer checker = BungeeCord.getInstance().getPlayer(bauserver.getOwner());
|
||||||
if (checker != null && CheckCommand.isChecking(checker)) {
|
if (checker != null && CheckCommand.isChecking(checker)) {
|
||||||
SteamwarUser steamwarUser = SteamwarUser.get(player.getUniqueId());
|
if (!sender.user().hasPerm(UserPerm.CHECK) && CheckCommand.getCheckingSchem(checker).getOwner() != sender.user().getId()) {
|
||||||
if (steamwarUser.getUserGroup().isCheckSchematics() || CheckCommand.getCheckingSchem(checker).getOwner() == steamwarUser.getId()) {
|
|
||||||
SubserverSystem.sendPlayer(subserver, player);
|
|
||||||
} else {
|
|
||||||
sender.system("JOIN_PLAYER_BLOCK");
|
sender.system("JOIN_PLAYER_BLOCK");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}else if (BauLock.isLocked(SteamwarUser.get(bauserver.getOwner()), sender.user())) {
|
} else if (BauLock.checkNotifyLocked(SteamwarUser.get(bauserver.getOwner()), player)) {
|
||||||
Message.send("BAU_LOCKED_NOALLOWED", player);
|
return;
|
||||||
}else if (bauserver.getOwner().equals(player.getUniqueId()) || BauweltMember.getBauMember(bauserver.getOwner(), player.getUniqueId()) != null) {
|
} else if (!bauserver.getOwner().equals(player.getUniqueId()) && BauweltMember.getBauMember(bauserver.getOwner(), player.getUniqueId()) == null) {
|
||||||
SubserverSystem.sendPlayer(subserver, player);
|
|
||||||
} else {
|
|
||||||
SubserverSystem.sendDeniedMessage(player, bauserver.getOwner());
|
SubserverSystem.sendDeniedMessage(player, bauserver.getOwner());
|
||||||
sender.system("JOIN_PLAYER_BLOCK");
|
sender.system("JOIN_PLAYER_BLOCK");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BUILDER:
|
||||||
|
if(!sender.user().hasPerm(UserPerm.BUILD)) {
|
||||||
|
sender.system("JOIN_PLAYER_BLOCK");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if(subserver instanceof Builderserver && !player.hasPermission("bungeecore.server.team")) {
|
SubserverSystem.sendPlayer(subserver, player);
|
||||||
sender.system("JOIN_PLAYER_BLOCK");
|
|
||||||
} else if (serverPerm != null && !player.hasPermission(serverPerm)) {
|
|
||||||
sender.system("JOIN_PLAYER_BLOCK");
|
|
||||||
} else if (serverPerm == null && !player.getGroups().contains("team")) {
|
|
||||||
sender.system("JOIN_PLAYER_BLOCK");
|
|
||||||
} else {
|
|
||||||
player.connect(server);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ServerInfo getTarget(String arg) {
|
private static ServerInfo getTarget(String arg) {
|
||||||
|
@ -29,6 +29,7 @@ import de.steamwar.command.SWCommand;
|
|||||||
import de.steamwar.command.TypeValidator;
|
import de.steamwar.command.TypeValidator;
|
||||||
import de.steamwar.sql.SteamwarUser;
|
import de.steamwar.sql.SteamwarUser;
|
||||||
import de.steamwar.sql.Tutorial;
|
import de.steamwar.sql.Tutorial;
|
||||||
|
import de.steamwar.sql.UserPerm;
|
||||||
import net.md_5.bungee.api.ProxyServer;
|
import net.md_5.bungee.api.ProxyServer;
|
||||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||||
|
|
||||||
@ -83,9 +84,7 @@ public class TutorialCommand extends SWCommand {
|
|||||||
|
|
||||||
@Validator("unreleased")
|
@Validator("unreleased")
|
||||||
public TypeValidator<ProxiedPlayer> unreleasedChecker() {
|
public TypeValidator<ProxiedPlayer> unreleasedChecker() {
|
||||||
return (sender, value, messageSender) -> {
|
return (sender, value, messageSender) -> (SteamwarUser.get((value).getUniqueId()).hasPerm(UserPerm.TEAM));
|
||||||
return (SteamwarUser.get((value).getUniqueId()).getUserGroup().isTeamGroup());
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void openInventory(ProxiedPlayer player, boolean released, boolean own) {
|
private void openInventory(ProxiedPlayer player, boolean released, boolean own) {
|
||||||
@ -95,13 +94,13 @@ public class TutorialCommand extends SWCommand {
|
|||||||
player,
|
player,
|
||||||
Message.parse("TUTORIAL_TITLE", player),
|
Message.parse("TUTORIAL_TITLE", player),
|
||||||
(click, tutorial) -> {
|
(click, tutorial) -> {
|
||||||
if(!released && click.isShiftClick() && user.getUserGroup().isTeamGroup() && user.getId() != tutorial.getCreator()) {
|
if(!released && click.isShiftClick() && user.hasPerm(UserPerm.TEAM) && user.getId() != tutorial.getCreator()) {
|
||||||
tutorial.release();
|
tutorial.release();
|
||||||
openInventory(player, released, own);
|
openInventory(player, released, own);
|
||||||
return;
|
return;
|
||||||
} else if(own && click.isShiftClick() && click.isRightClick()) {
|
} else if(own && click.isShiftClick() && click.isRightClick()) {
|
||||||
tutorial.delete();
|
tutorial.delete();
|
||||||
SubserverSystem.deleteFolder(BungeeCore.local, world(tutorial).getPath());
|
SubserverSystem.deleteFolder(VelocityCore.local, world(tutorial).getPath());
|
||||||
openInventory(player, released, own);
|
openInventory(player, released, own);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -152,13 +151,13 @@ public class TutorialCommand extends SWCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
subserver.execute("save-all");
|
subserver.execute("save-all");
|
||||||
ProxyServer.getInstance().getScheduler().schedule(BungeeCore.get(), () -> {
|
ProxyServer.getInstance().getScheduler().schedule(VelocityCore.get(), () -> {
|
||||||
Tutorial tutorial = Tutorial.create(user.getId(), name, item);
|
Tutorial tutorial = Tutorial.create(user.getId(), name, item);
|
||||||
File tutorialWorld = world(tutorial);
|
File tutorialWorld = world(tutorial);
|
||||||
|
|
||||||
if (tutorialWorld.exists())
|
if (tutorialWorld.exists())
|
||||||
SubserverSystem.deleteFolder(BungeeCore.local, tutorialWorld.getPath());
|
SubserverSystem.deleteFolder(VelocityCore.local, tutorialWorld.getPath());
|
||||||
ServerStarter.copyWorld(BungeeCore.local, tempWorld.getPath(), tutorialWorld.getPath());
|
ServerStarter.copyWorld(VelocityCore.local, tempWorld.getPath(), tutorialWorld.getPath());
|
||||||
Message.send("TUTORIAL_CREATED", player);
|
Message.send("TUTORIAL_CREATED", player);
|
||||||
}, 1, TimeUnit.SECONDS);
|
}, 1, TimeUnit.SECONDS);
|
||||||
}
|
}
|
||||||
|
@ -20,19 +20,16 @@
|
|||||||
package de.steamwar.bungeecore.commands;
|
package de.steamwar.bungeecore.commands;
|
||||||
|
|
||||||
import de.steamwar.bungeecore.ArenaMode;
|
import de.steamwar.bungeecore.ArenaMode;
|
||||||
import de.steamwar.bungeecore.listeners.mods.ModLoaderBlocker;
|
|
||||||
import de.steamwar.sql.Punishment;
|
|
||||||
import de.steamwar.command.SWCommandUtils;
|
import de.steamwar.command.SWCommandUtils;
|
||||||
import de.steamwar.command.TypeMapper;
|
import de.steamwar.command.TypeMapper;
|
||||||
import de.steamwar.command.TypeValidator;
|
import de.steamwar.command.TypeValidator;
|
||||||
import de.steamwar.messages.ChatSender;
|
import de.steamwar.messages.ChatSender;
|
||||||
|
import de.steamwar.sql.Punishment;
|
||||||
import lombok.experimental.UtilityClass;
|
import lombok.experimental.UtilityClass;
|
||||||
import net.md_5.bungee.api.CommandSender;
|
import net.md_5.bungee.api.CommandSender;
|
||||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@UtilityClass
|
@UtilityClass
|
||||||
public class TypeMappers {
|
public class TypeMappers {
|
||||||
@ -51,10 +48,6 @@ public class TypeMappers {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ModLoaderBlocker.isFabric(value)) {
|
|
||||||
messageSender.send("MODLOADER_DENIED");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -78,7 +71,6 @@ public class TypeMappers {
|
|||||||
@Override
|
@Override
|
||||||
public String map(CommandSender commandSender, String[] previousArguments, String s) {
|
public String map(CommandSender commandSender, String[] previousArguments, String s) {
|
||||||
if (previousArguments.length == 0) return null;
|
if (previousArguments.length == 0) return null;
|
||||||
if (s.equalsIgnoreCase("random")) return "random";
|
|
||||||
return ArenaMode.getByChat(previousArguments[previousArguments.length - 1]).convertToRealMapName(s);
|
return ArenaMode.getByChat(previousArguments[previousArguments.length - 1]).convertToRealMapName(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,9 +79,7 @@ public class TypeMappers {
|
|||||||
if (previousArguments.length == 0) return null;
|
if (previousArguments.length == 0) return null;
|
||||||
ArenaMode arenaMode = ArenaMode.getByChat(previousArguments[previousArguments.length - 1]);
|
ArenaMode arenaMode = ArenaMode.getByChat(previousArguments[previousArguments.length - 1]);
|
||||||
if (arenaMode == null) return null;
|
if (arenaMode == null) return null;
|
||||||
List<String> stringList = new ArrayList<>(arenaMode.getMaps());
|
return arenaMode.getMaps();
|
||||||
stringList.add("random");
|
|
||||||
return stringList;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
package de.steamwar.bungeecore.commands;
|
package de.steamwar.bungeecore.commands;
|
||||||
|
|
||||||
import de.steamwar.bungeecore.BungeeCore;
|
import de.steamwar.bungeecore.VelocityCore;
|
||||||
import de.steamwar.bungeecore.Message;
|
import de.steamwar.bungeecore.Message;
|
||||||
import de.steamwar.bungeecore.bot.AuthManager;
|
import de.steamwar.bungeecore.bot.AuthManager;
|
||||||
import de.steamwar.sql.SteamwarUser;
|
import de.steamwar.sql.SteamwarUser;
|
||||||
@ -52,7 +52,7 @@ public class VerifyCommand extends SWCommand {
|
|||||||
if(bytes[0] == 'D' && bytes[1] == 'C') {
|
if(bytes[0] == 'D' && bytes[1] == 'C') {
|
||||||
Member member = AuthManager.connectAuth(SteamwarUser.get(sender.getName()), code);
|
Member member = AuthManager.connectAuth(SteamwarUser.get(sender.getName()), code);
|
||||||
if(member != null) {
|
if(member != null) {
|
||||||
BungeeCore.log(sender.getName() + " Verified with Discorduser: " + member.getIdLong());
|
VelocityCore.log(sender.getName() + " Verified with Discorduser: " + member.getIdLong());
|
||||||
Message.send("VERIFY_SUCCESS", sender, member.getUser().getAsTag());
|
Message.send("VERIFY_SUCCESS", sender, member.getUser().getAsTag());
|
||||||
} else {
|
} else {
|
||||||
Message.send("VERIFY_INVALID", sender);
|
Message.send("VERIFY_INVALID", sender);
|
||||||
|
@ -21,10 +21,11 @@ package de.steamwar.bungeecore.commands;
|
|||||||
|
|
||||||
import de.steamwar.bungeecore.Message;
|
import de.steamwar.bungeecore.Message;
|
||||||
import de.steamwar.bungeecore.Storage;
|
import de.steamwar.bungeecore.Storage;
|
||||||
import de.steamwar.bungeecore.listeners.mods.Utils;
|
import de.steamwar.bungeecore.mods.ModUtils;
|
||||||
import de.steamwar.command.SWCommand;
|
import de.steamwar.command.SWCommand;
|
||||||
import de.steamwar.command.SWCommandUtils;
|
import de.steamwar.command.SWCommandUtils;
|
||||||
import de.steamwar.command.TypeMapper;
|
import de.steamwar.command.TypeMapper;
|
||||||
|
import de.steamwar.messages.ChatSender;
|
||||||
import de.steamwar.sql.*;
|
import de.steamwar.sql.*;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import net.md_5.bungee.BungeeCord;
|
import net.md_5.bungee.BungeeCord;
|
||||||
@ -47,14 +48,18 @@ public class WhoisCommand extends SWCommand {
|
|||||||
|
|
||||||
@Register(description = "WHOIS_USAGE")
|
@Register(description = "WHOIS_USAGE")
|
||||||
public void genericCommand(ProxiedPlayer player, @Mapper("player") String target, WhoisParameterTypes... parameters) {
|
public void genericCommand(ProxiedPlayer player, @Mapper("player") String target, WhoisParameterTypes... parameters) {
|
||||||
|
ChatSender sender = ChatSender.of(player);
|
||||||
SteamwarUser user = SteamwarUser.get(target);
|
SteamwarUser user = SteamwarUser.get(target);
|
||||||
|
if (sender.user().hasPerm(UserPerm.ADMINISTRATION)) {
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
try {
|
try {
|
||||||
int id = Integer.parseInt(target);
|
int id = Integer.parseInt(target);
|
||||||
user = SteamwarUser.get(id);
|
user = SteamwarUser.get(id);
|
||||||
} catch (NumberFormatException ignored) {
|
} catch (NumberFormatException ignored) {
|
||||||
|
// Ignored
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
try {
|
try {
|
||||||
long id = Long.parseLong(target);
|
long id = Long.parseLong(target);
|
||||||
@ -63,12 +68,13 @@ public class WhoisCommand extends SWCommand {
|
|||||||
// Ignored
|
// Ignored
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
Message.send("UNKNOWN_PLAYER", player);
|
sender.system("UNKNOWN_PLAYER");
|
||||||
} else {
|
} else {
|
||||||
EnumSet<WhoisParameterTypes> set = parameters.length == 0 ? EnumSet.noneOf(WhoisParameterTypes.class) : EnumSet.copyOf(Arrays.asList(parameters));
|
EnumSet<WhoisParameterTypes> set = parameters.length == 0 ? EnumSet.noneOf(WhoisParameterTypes.class) : EnumSet.copyOf(Arrays.asList(parameters));
|
||||||
sendUserinfo(player, user, set);
|
sendUserinfo(sender, user, set);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,56 +83,57 @@ public class WhoisCommand extends SWCommand {
|
|||||||
return SWCommandUtils.createMapper(s -> s, s -> BungeeCord.getInstance().getPlayers().stream().map(ProxiedPlayer::getName).collect(Collectors.toList()));
|
return SWCommandUtils.createMapper(s -> s, s -> BungeeCord.getInstance().getPlayers().stream().map(ProxiedPlayer::getName).collect(Collectors.toList()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void sendUserinfo(ProxiedPlayer player, SteamwarUser user, EnumSet<WhoisParameterTypes> parameterTypes) {
|
private static void sendUserinfo(ChatSender sender, SteamwarUser user, EnumSet<WhoisParameterTypes> parameterTypes) {
|
||||||
UserGroup userGroup = SteamwarUser.get(player.getUniqueId()).getUserGroup();
|
|
||||||
|
|
||||||
Message.send("WHOIS_USERNAME", player, user.getUserName());
|
|
||||||
Message.send("WHOIS_GROUP", player, user.getUserGroup().getColorCode(), user.getUserGroup().name());
|
|
||||||
Team team = Team.get(user.getTeam());
|
Team team = Team.get(user.getTeam());
|
||||||
Message.send("WHOIS_TEAM", player, Message.parse("WHOIS_TEAM_HOVER", player, team.getTeamName()), new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/team info " + team.getTeamKuerzel()), team.getTeamColor(), team.getTeamKuerzel(), team.getTeamName());
|
|
||||||
if (!userGroup.isTeamGroup()) return;
|
|
||||||
|
|
||||||
if (userGroup.isAdminGroup()) {
|
sender.system("WHOIS_USERNAME", user.getUserName());
|
||||||
Message.send("WHOIS_UUID", player, Message.parse("WHOIS_UUID_HOVER", player), new ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, user.getUUID().toString()), user.getUUID().toString());
|
sender.system("WHOIS_PREFIX", user.prefix().getColorCode() + user.prefix().getChatPrefix());
|
||||||
Message.send("WHOIS_ID", player, user.getId());
|
sender.system("WHOIS_TEAM", new Message("WHOIS_TEAM_HOVER", team.getTeamName()), new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/team info " + team.getTeamKuerzel()), team.getTeamColor(), team.getTeamKuerzel(), team.getTeamName());
|
||||||
if (user.getDiscordId() != null) {
|
|
||||||
Message.send("WHOIS_DISCORD_ID", player, user.getDiscordId());
|
if (!sender.user().hasPerm(UserPerm.TEAM))
|
||||||
}
|
return;
|
||||||
|
|
||||||
|
if (sender.user().hasPerm(UserPerm.MODERATION)) {
|
||||||
|
sender.system("WHOIS_ID", user.getId());
|
||||||
|
sender.system("WHOIS_UUID", new Message("WHOIS_UUID_HOVER"), new ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, user.getUUID().toString()), user.getUUID().toString());
|
||||||
|
if (user.getDiscordId() != null)
|
||||||
|
sender.system("WHOIS_DISCORD_ID", user.getDiscordId());
|
||||||
|
|
||||||
|
sender.system("WHOIS_PERMS", user.perms().stream().map(Enum::name).collect(Collectors.joining(", ")));
|
||||||
}
|
}
|
||||||
|
|
||||||
Timestamp firstJoin = user.getFirstjoin();
|
|
||||||
if (firstJoin == null) {
|
|
||||||
Message.send("WHOIS_JOINED_FIRST", player, "0000-00-00 00:00:00");
|
|
||||||
} else {
|
|
||||||
Message.send("WHOIS_JOINED_FIRST", player, firstJoin.toString());
|
|
||||||
}
|
|
||||||
Message.send("WHOIS_HOURS_PLAYED", player, new DecimalFormat("###.##").format(user.getOnlinetime() / 3600d));
|
|
||||||
|
|
||||||
if(BungeeCord.getInstance().getPlayer(user.getUUID()) != null) {
|
|
||||||
ProxiedPlayer target = BungeeCord.getInstance().getPlayer(user.getUUID());
|
ProxiedPlayer target = BungeeCord.getInstance().getPlayer(user.getUUID());
|
||||||
Message.send("WHOIS_CURRENT_PLAYED", player, new DecimalFormat("####.##").format((Instant.now().getEpochSecond() - Storage.sessions.get(target).toInstant().getEpochSecond()) / 60d));
|
Timestamp firstJoin = user.getFirstjoin();
|
||||||
Message.send("WHOIS_CURRENT_SERVER", player, target.getServer().getInfo().getName());
|
double onlineTime = user.getOnlinetime();
|
||||||
Message.send("WHOIS_CURRENT_PROTOCOL", player, target.getPendingConnection().getVersion());
|
if(firstJoin == null && target != null) {
|
||||||
|
firstJoin = Storage.sessions.get(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Utils.playerModMap.containsKey(user.getUUID())) {
|
if(firstJoin != null)
|
||||||
Mod.Platform modPlatform = Utils.playerModMap.get(user.getUUID()).get(0).getPlatform();
|
sender.system("WHOIS_JOINED_FIRST", firstJoin.toString());
|
||||||
Message.send("WHOIS_PLATFORM", player, modPlatform.toString());
|
sender.system("WHOIS_HOURS_PLAYED", new DecimalFormat("###.##").format(onlineTime / 3600d));
|
||||||
}
|
|
||||||
|
if(target != null) {
|
||||||
|
sender.system("WHOIS_CURRENT_PLAYED", new DecimalFormat("####.##").format((Instant.now().getEpochSecond() - Storage.sessions.get(target).toInstant().getEpochSecond()) / 60d));
|
||||||
|
sender.system("WHOIS_CURRENT_SERVER", target.getServer().getInfo().getName());
|
||||||
|
sender.system("WHOIS_CURRENT_PROTOCOL", target.getPendingConnection().getVersion());
|
||||||
|
|
||||||
|
List<Mod> mods = ModUtils.getPlayerModMap().get(user.getUUID());
|
||||||
|
if(mods == null)
|
||||||
|
mods = Collections.emptyList();
|
||||||
|
|
||||||
|
sender.system("WHOIS_PLATFORM", mods.isEmpty() ? "Vanilla" : mods.get(0).getPlatform().toString());
|
||||||
|
|
||||||
if (parameterTypes.contains(WhoisParameterTypes.MOD)) {
|
if (parameterTypes.contains(WhoisParameterTypes.MOD)) {
|
||||||
List<Mod> activeMods = Utils.playerModMap.get(user.getUUID());
|
if (!mods.isEmpty()) {
|
||||||
|
sender.system("WHOIS_ACTIVE_MODS", mods.size(), mods.stream().map(mod -> "§" + mod.getModType().getColorCode() + mod.getModName()).collect(Collectors.joining("§8, ")));
|
||||||
if (activeMods != null && !activeMods.isEmpty()) {
|
|
||||||
Message.send("WHOIS_ACTIVE_MODS", player,activeMods.size());
|
|
||||||
String result = activeMods.stream().map(mod -> "§" + mod.getModType().getColorCode() + mod.getModName()).collect(Collectors.joining("§8, "));
|
|
||||||
Message.send("WHOIS_ACTIVE_MOD", player, result);
|
|
||||||
} else {
|
} else {
|
||||||
Message.send("WHOIS_NO_ACTIVE_MODS", player);
|
sender.system("WHOIS_NO_ACTIVE_MODS");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Message.send("WHOIS_PUNISHMENTS", player);
|
sender.system("WHOIS_PUNISHMENTS");
|
||||||
List<Punishment> punishmentList = Punishment.getAllPunishmentsOfPlayer(user.getId());
|
List<Punishment> punishmentList = Punishment.getAllPunishmentsOfPlayer(user.getId());
|
||||||
Set<Punishment.PunishmentType> found = new HashSet<>();
|
Set<Punishment.PunishmentType> found = new HashSet<>();
|
||||||
boolean isPunished = false;
|
boolean isPunished = false;
|
||||||
@ -138,11 +145,11 @@ public class WhoisCommand extends SWCommand {
|
|||||||
if (!all && !punishment.isCurrent()) {
|
if (!all && !punishment.isCurrent()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Message.sendPrefixless("WHOIS_PUNISHMENT", player, SteamwarUser.get(punishment.getPunisher()).getUserName(), punishment.getType().name(), punishment.getBantime(punishment.getStartTime(), false), punishment.getBantime(punishment.getEndTime(), punishment.isPerma()), punishment.getReason());
|
sender.prefixless("WHOIS_PUNISHMENT", SteamwarUser.get(punishment.getPunisher()).getUserName(), punishment.getType().name(), punishment.getBantime(punishment.getStartTime(), false), punishment.getBantime(punishment.getEndTime(), punishment.isPerma()), punishment.getReason());
|
||||||
isPunished = true;
|
isPunished = true;
|
||||||
}
|
}
|
||||||
if (!isPunished) {
|
if (!isPunished) {
|
||||||
Message.send(all ? "WHOIS_NO_ALL_PUNISHMENT" : "WHOIS_NO_PUNISHMENT", player);
|
sender.system(all ? "WHOIS_NO_ALL_PUNISHMENT" : "WHOIS_NO_PUNISHMENT");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,9 +160,9 @@ public class WhoisCommand extends SWCommand {
|
|||||||
return new TypeMapper<WhoisParameterTypes>() {
|
return new TypeMapper<WhoisParameterTypes>() {
|
||||||
@Override
|
@Override
|
||||||
public WhoisParameterTypes map(CommandSender commandSender, String[] previousArguments, String s) {
|
public WhoisParameterTypes map(CommandSender commandSender, String[] previousArguments, String s) {
|
||||||
UserGroup userGroup = SteamwarUser.get(((ProxiedPlayer) commandSender).getUniqueId()).getUserGroup();
|
SteamwarUser user = SteamwarUser.get(((ProxiedPlayer) commandSender).getUniqueId());
|
||||||
return Stream.of(values)
|
return Stream.of(values)
|
||||||
.filter(p -> p.userGroupSet.contains(userGroup))
|
.filter(p -> user.hasPerm(p.perm))
|
||||||
.filter(p -> p.getTabCompletes().contains(s))
|
.filter(p -> p.getTabCompletes().contains(s))
|
||||||
.findFirst()
|
.findFirst()
|
||||||
.orElse(null);
|
.orElse(null);
|
||||||
@ -163,9 +170,9 @@ public class WhoisCommand extends SWCommand {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<String> tabCompletes(CommandSender commandSender, String[] previousArguments, String s) {
|
public Collection<String> tabCompletes(CommandSender commandSender, String[] previousArguments, String s) {
|
||||||
UserGroup userGroup = SteamwarUser.get(((ProxiedPlayer) commandSender).getUniqueId()).getUserGroup();
|
SteamwarUser user = SteamwarUser.get(((ProxiedPlayer) commandSender).getUniqueId());
|
||||||
return Stream.of(values)
|
return Stream.of(values)
|
||||||
.filter(p -> p.userGroupSet.contains(userGroup))
|
.filter(p -> user.hasPerm(p.perm))
|
||||||
.flatMap(p -> p.getTabCompletes().stream())
|
.flatMap(p -> p.getTabCompletes().stream())
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
@ -173,17 +180,17 @@ public class WhoisCommand extends SWCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private enum WhoisParameterTypes {
|
private enum WhoisParameterTypes {
|
||||||
ALL(Arrays.asList("-a", "-all"), UserGroup.Admin, UserGroup.Moderator, UserGroup.Developer, UserGroup.Supporter, UserGroup.Builder),
|
ALL(Arrays.asList("-a", "-all"), UserPerm.TEAM),
|
||||||
MOD(Arrays.asList("-m", "-mod", "-mods"), UserGroup.Admin, UserGroup.Moderator, UserGroup.Developer);
|
MOD(Arrays.asList("-m", "-mod", "-mods"), UserPerm.MODERATION);
|
||||||
|
|
||||||
private final EnumSet<UserGroup> userGroupSet;
|
private final UserPerm perm;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private List<String> tabCompletes;
|
private List<String> tabCompletes;
|
||||||
|
|
||||||
|
|
||||||
WhoisParameterTypes(List<String> tabCompletes, UserGroup... userGroups) {
|
WhoisParameterTypes(List<String> tabCompletes, UserPerm perm) {
|
||||||
this.userGroupSet = EnumSet.copyOf(Arrays.asList(userGroups));
|
this.perm = perm;
|
||||||
this.tabCompletes = tabCompletes;
|
this.tabCompletes = tabCompletes;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,48 +19,44 @@
|
|||||||
|
|
||||||
package de.steamwar.bungeecore.listeners;
|
package de.steamwar.bungeecore.listeners;
|
||||||
|
|
||||||
import de.steamwar.bungeecore.BungeeCore;
|
import de.steamwar.bungeecore.VelocityCore;
|
||||||
import de.steamwar.bungeecore.Message;
|
import de.steamwar.bungeecore.Message;
|
||||||
import de.steamwar.bungeecore.commands.PunishmentCommand;
|
import de.steamwar.bungeecore.commands.PunishmentCommand;
|
||||||
import de.steamwar.bungeecore.commands.WebpasswordCommand;
|
import de.steamwar.bungeecore.commands.WebpasswordCommand;
|
||||||
import de.steamwar.bungeecore.listeners.mods.Forge;
|
import de.steamwar.messages.ChatSender;
|
||||||
import de.steamwar.sql.BannedUserIPs;
|
import de.steamwar.sql.BannedUserIPs;
|
||||||
import de.steamwar.sql.Punishment;
|
import de.steamwar.sql.Punishment;
|
||||||
import de.steamwar.sql.SteamwarUser;
|
import de.steamwar.sql.SteamwarUser;
|
||||||
import de.steamwar.messages.ChatSender;
|
|
||||||
import net.md_5.bungee.api.ProxyServer;
|
import net.md_5.bungee.api.ProxyServer;
|
||||||
import net.md_5.bungee.api.chat.ClickEvent;
|
import net.md_5.bungee.api.chat.ClickEvent;
|
||||||
import net.md_5.bungee.api.chat.ComponentBuilder;
|
|
||||||
import net.md_5.bungee.api.chat.HoverEvent;
|
|
||||||
import net.md_5.bungee.api.chat.TextComponent;
|
|
||||||
import net.md_5.bungee.api.connection.PendingConnection;
|
import net.md_5.bungee.api.connection.PendingConnection;
|
||||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
|
||||||
import net.md_5.bungee.api.event.LoginEvent;
|
import net.md_5.bungee.api.event.LoginEvent;
|
||||||
import net.md_5.bungee.event.EventHandler;
|
import net.md_5.bungee.event.EventHandler;
|
||||||
|
|
||||||
import java.sql.Timestamp;
|
import java.sql.Timestamp;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class BanListener extends BasicListener {
|
public class BanListener extends BasicListener {
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onLogin(LoginEvent event) {
|
public void onLogin(LoginEvent event) {
|
||||||
event.registerIntent(BungeeCore.get());
|
event.registerIntent(VelocityCore.get());
|
||||||
ProxyServer.getInstance().getScheduler().runAsync(BungeeCore.get(), () -> {
|
ProxyServer.getInstance().getScheduler().runAsync(VelocityCore.get(), () -> {
|
||||||
PendingConnection connection = event.getConnection();
|
PendingConnection connection = event.getConnection();
|
||||||
SteamwarUser user = SteamwarUser.getOrCreate(connection.getUniqueId(), connection.getName(), ConnectionListener::newPlayer, WebpasswordCommand::changeUsername);
|
SteamwarUser user = SteamwarUser.getOrCreate(connection.getUniqueId(), connection.getName(), ConnectionListener::newPlayer, WebpasswordCommand::changeUsername);
|
||||||
|
String ip = IPSanitizer.getTrueAddress(connection).getHostAddress();
|
||||||
if (user.isPunished(Punishment.PunishmentType.Ban)) {
|
if (user.isPunished(Punishment.PunishmentType.Ban)) {
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
BannedUserIPs.banIP(user.getId(), connection.getAddress().getAddress().getHostAddress());
|
BannedUserIPs.banIP(user.getId(), ip);
|
||||||
ChatSender.of(event).system(PunishmentCommand.punishmentMessage(user, Punishment.PunishmentType.Ban));
|
ChatSender.of(event).system(PunishmentCommand.punishmentMessage(user, Punishment.PunishmentType.Ban));
|
||||||
event.completeIntent(BungeeCore.get());
|
event.completeIntent(VelocityCore.get());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<BannedUserIPs> ips = BannedUserIPs.get(connection.getAddress().getAddress().getHostAddress());
|
List<BannedUserIPs> ips = BannedUserIPs.get(ip);
|
||||||
if(!ips.isEmpty()){
|
if(!ips.isEmpty()){
|
||||||
|
|
||||||
Timestamp highestBan = ips.get(0).getTimestamp();
|
Timestamp highestBan = ips.get(0).getTimestamp();
|
||||||
boolean perma = false;
|
boolean perma = false;
|
||||||
for(BannedUserIPs banned : ips) {
|
for(BannedUserIPs banned : ips) {
|
||||||
@ -77,30 +73,22 @@ public class BanListener extends BasicListener {
|
|||||||
}
|
}
|
||||||
ClickEvent clickEvent = new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/ban " + user.getUserName() + " "
|
ClickEvent clickEvent = new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/ban " + user.getUserName() + " "
|
||||||
+ (perma?"perma":highestBan.toLocalDateTime().format(DateTimeFormatter.ofPattern("dd.MM.yyyy_HH:mm")))
|
+ (perma?"perma":highestBan.toLocalDateTime().format(DateTimeFormatter.ofPattern("dd.MM.yyyy_HH:mm")))
|
||||||
+ " Bannumgehung");
|
+ " Ban Evasion - Bannumgehung");
|
||||||
|
|
||||||
for (ProxiedPlayer target : ProxyServer.getInstance().getPlayers()){
|
ChatSender.serverteamReceivers().forEach(sender -> sender.system(
|
||||||
if ((target.hasPermission("bungeecore.teamchat"))
|
"BAN_AVOIDING_ALERT",
|
||||||
&& (target.getChatMode() == ProxiedPlayer.ChatMode.COMMANDS_ONLY
|
new Message("BAN_AVOIDING_BAN_HOVER"),
|
||||||
|| target.getChatMode() == ProxiedPlayer.ChatMode.SHOWN)){
|
clickEvent,
|
||||||
StringBuilder potentialBan = new StringBuilder();
|
user.getUserName(),
|
||||||
potentialBan.append(Message.parsePrefixed("BAN_AVOIDING_ALERT", target, user.getUserName()));
|
ips.stream().map(banned -> {
|
||||||
|
|
||||||
for(BannedUserIPs banned : ips) {
|
|
||||||
SteamwarUser bannedUser = SteamwarUser.get(banned.getUserID());
|
SteamwarUser bannedUser = SteamwarUser.get(banned.getUserID());
|
||||||
potentialBan.append(Message.parse("BAN_AVOIDING_LIST", target, bannedUser.getUserName(),
|
return sender.parseToLegacy("BAN_AVOIDING_LIST", bannedUser.getUserName(),
|
||||||
banned.getTimestamp().toLocalDateTime().format(DateTimeFormatter.ofPattern(Message.parse("TIMEFORMAT", target)))));
|
banned.getTimestamp().toLocalDateTime().format(DateTimeFormatter.ofPattern(sender.parseToPlain("TIMEFORMAT"))));
|
||||||
|
}).collect(Collectors.joining(" "))
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
TextComponent msg = new TextComponent(potentialBan.toString());
|
event.completeIntent(VelocityCore.get());
|
||||||
msg.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder(Message.parse("BAN_AVOIDING_BAN_HOVER", target)).create()));
|
|
||||||
msg.setClickEvent(clickEvent);
|
|
||||||
target.sendMessage(msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Forge.onServerConnected(event);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,31 +0,0 @@
|
|||||||
/*
|
|
||||||
This file is a part of the SteamWar software.
|
|
||||||
|
|
||||||
Copyright (C) 2020 SteamWar.de-Serverteam
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU Affero General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU Affero General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Affero General Public License
|
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.bungeecore.listeners;
|
|
||||||
|
|
||||||
import de.steamwar.bungeecore.BungeeCore;
|
|
||||||
import net.md_5.bungee.api.ProxyServer;
|
|
||||||
import net.md_5.bungee.api.plugin.Listener;
|
|
||||||
|
|
||||||
public abstract class BasicListener implements Listener {
|
|
||||||
|
|
||||||
public BasicListener(){
|
|
||||||
ProxyServer.getInstance().getPluginManager().registerListener(BungeeCore.get(), this);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,71 +0,0 @@
|
|||||||
/*
|
|
||||||
This file is a part of the SteamWar software.
|
|
||||||
|
|
||||||
Copyright (C) 2020 SteamWar.de-Serverteam
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU Affero General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU Affero General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Affero General Public License
|
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.bungeecore.listeners;
|
|
||||||
|
|
||||||
import de.steamwar.messages.ChatSender;
|
|
||||||
import io.netty.buffer.ByteBuf;
|
|
||||||
import io.netty.buffer.ByteBufAllocator;
|
|
||||||
import net.md_5.bungee.api.ProxyServer;
|
|
||||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
|
||||||
import net.md_5.bungee.api.event.PluginMessageEvent;
|
|
||||||
import net.md_5.bungee.event.EventHandler;
|
|
||||||
import net.md_5.bungee.protocol.DefinedPacket;
|
|
||||||
|
|
||||||
import java.net.InetAddress;
|
|
||||||
import java.net.NetworkInterface;
|
|
||||||
import java.net.SocketException;
|
|
||||||
|
|
||||||
public class BrandListener extends BasicListener {
|
|
||||||
|
|
||||||
private static boolean isLocalHost(InetAddress addr) {
|
|
||||||
if (addr.isAnyLocalAddress() || addr.isLoopbackAddress()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
return NetworkInterface.getByInetAddress(addr) != null;
|
|
||||||
} catch (SocketException e) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void onServerSwitch(PluginMessageEvent event) {
|
|
||||||
if(!event.getTag().equals("minecraft:brand") && !event.getTag().equals("MC|Brand")) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isLocalHost(event.getReceiver().getAddress().getAddress())) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(event.getReceiver() instanceof ProxiedPlayer)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
event.setCancelled(true);
|
|
||||||
|
|
||||||
ProxiedPlayer player = (ProxiedPlayer) event.getReceiver();
|
|
||||||
String brandString = ChatSender.of(player).parseToLegacy("STEAMWAR_BRAND", ProxyServer.getInstance().getName(), player.getServer().getInfo().getName(), new String(event.getData(), 1, event.getData().length - 1));
|
|
||||||
|
|
||||||
ByteBuf brand = ByteBufAllocator.DEFAULT.heapBuffer();
|
|
||||||
DefinedPacket.writeString(brandString, brand);
|
|
||||||
player.sendData(event.getTag(), DefinedPacket.toArray(brand));
|
|
||||||
brand.release();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,54 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2022 SteamWar.de-Serverteam
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.bungeecore.listeners;
|
|
||||||
|
|
||||||
import de.steamwar.bungeecore.BungeeCore;
|
|
||||||
import de.steamwar.bungeecore.Message;
|
|
||||||
import de.steamwar.bungeecore.commands.CalendarCommand;
|
|
||||||
import net.md_5.bungee.BungeeCord;
|
|
||||||
import net.md_5.bungee.api.chat.ClickEvent;
|
|
||||||
import net.md_5.bungee.api.event.PostLoginEvent;
|
|
||||||
import net.md_5.bungee.event.EventHandler;
|
|
||||||
|
|
||||||
import java.time.LocalDate;
|
|
||||||
import java.time.Month;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
public class CalendarListener extends BasicListener {
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void onPostLogin(PostLoginEvent event) {
|
|
||||||
LocalDate localDate = LocalDate.now();
|
|
||||||
int day = localDate.getDayOfMonth();
|
|
||||||
Month month = localDate.getMonth();
|
|
||||||
|
|
||||||
if (month != Month.DECEMBER) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!CalendarCommand.hasDay(day)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
BungeeCord.getInstance().getScheduler().schedule(BungeeCore.get(), () -> {
|
|
||||||
Message.send("ADVENT_CALENDAR_MESSAGE", event.getPlayer(), Message.parse("ADVENT_CALENDAR_MESSAGE_HOVER", event.getPlayer()), new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/calendar"));
|
|
||||||
}, 2, TimeUnit.SECONDS);
|
|
||||||
}
|
|
||||||
}
|
|
@ -27,7 +27,6 @@ import de.steamwar.bungeecore.util.Chat19;
|
|||||||
import de.steamwar.messages.ChatSender;
|
import de.steamwar.messages.ChatSender;
|
||||||
import de.steamwar.network.packets.server.PingPacket;
|
import de.steamwar.network.packets.server.PingPacket;
|
||||||
import de.steamwar.sql.*;
|
import de.steamwar.sql.*;
|
||||||
import net.md_5.bungee.api.*;
|
|
||||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||||
import net.md_5.bungee.api.event.ChatEvent;
|
import net.md_5.bungee.api.event.ChatEvent;
|
||||||
import net.md_5.bungee.api.event.TabCompleteEvent;
|
import net.md_5.bungee.api.event.TabCompleteEvent;
|
||||||
@ -46,13 +45,6 @@ public class ChatListener extends BasicListener {
|
|||||||
|
|
||||||
private static final List<String> rankedModes = ArenaMode.getAllModes().stream().filter(ArenaMode::isRanked).map(ArenaMode::getSchemType).collect(Collectors.toList());
|
private static final List<String> rankedModes = ArenaMode.getAllModes().stream().filter(ArenaMode::isRanked).map(ArenaMode::getSchemType).collect(Collectors.toList());
|
||||||
|
|
||||||
private static final Set<Integer> coloredTeams = new HashSet<>();
|
|
||||||
static {
|
|
||||||
coloredTeams.add(12);
|
|
||||||
coloredTeams.add(54);
|
|
||||||
coloredTeams.add(285);
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onChatEvent(ChatEvent e) {
|
public void onChatEvent(ChatEvent e) {
|
||||||
if(!(e.getSender() instanceof ProxiedPlayer))
|
if(!(e.getSender() instanceof ProxiedPlayer))
|
||||||
@ -65,7 +57,7 @@ public class ChatListener extends BasicListener {
|
|||||||
if (message.contains("jndi:ldap")) {
|
if (message.contains("jndi:ldap")) {
|
||||||
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
||||||
PunishmentCommand.ban(user, Punishment.PERMA_TIME, "Versuchte Exploit-Ausnutzung", SteamwarUser.get(-1), true);
|
PunishmentCommand.ban(user, Punishment.PERMA_TIME, "Versuchte Exploit-Ausnutzung", SteamwarUser.get(-1), true);
|
||||||
BungeeCore.log(Level.SEVERE, user.getUserName() + " " + user.getId() + " wurde automatisch wegen jndi:ldap gebannt.");
|
VelocityCore.log(Level.SEVERE, user.getUserName() + " " + user.getId() + " wurde automatisch wegen jndi:ldap gebannt.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,7 +93,7 @@ public class ChatListener extends BasicListener {
|
|||||||
|
|
||||||
public static void sendChat(ChatSender sender, Stream<ChatSender> receivers, String format, ChatSender msgReceiver, String message) {
|
public static void sendChat(ChatSender sender, Stream<ChatSender> receivers, String format, ChatSender msgReceiver, String message) {
|
||||||
SteamwarUser user = sender.user();
|
SteamwarUser user = sender.user();
|
||||||
final String coloredMessage = (user.getUserGroup() != UserGroup.Member || coloredTeams.contains(user.getTeam())) ? ChatColor.translateAlternateColorCodes('&', message) : message;
|
final String coloredMessage = user.hasPerm(UserPerm.COLOR_CHAT) ? ChatColor.translateAlternateColorCodes('&', message) : message;
|
||||||
if(chatFilter(sender, coloredMessage))
|
if(chatFilter(sender, coloredMessage))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -153,8 +145,7 @@ public class ChatListener extends BasicListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SteamwarUser user = sender.user();
|
SteamwarUser user = sender.user();
|
||||||
UserGroup group = user.getUserGroup();
|
if(!user.hasPerm(UserPerm.TEAM) && (message.contains("http:") || message.contains("https:") || message.contains("www."))){
|
||||||
if(!group.isTeamGroup() && (message.contains("http:") || message.contains("https:") || message.contains("www."))){
|
|
||||||
sender.system("CHAT_NO_LINKS");
|
sender.system("CHAT_NO_LINKS");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -173,16 +164,17 @@ public class ChatListener extends BasicListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static void chatToReciever(ChatSender receiver, ChatSender msgReceiver, SteamwarUser sender, String format, String message) {
|
private static void chatToReciever(ChatSender receiver, ChatSender msgReceiver, SteamwarUser sender, String format, String message) {
|
||||||
UserGroup group = sender.getUserGroup();
|
UserPerm.Prefix prefix = sender.prefix();
|
||||||
|
String chatColorCode = sender.hasPerm(UserPerm.TEAM) ? "§f" : "§7";
|
||||||
receiver.chat(new Message(format,
|
receiver.chat(new Message(format,
|
||||||
sender,
|
sender,
|
||||||
msgReceiver == null ? receiver : msgReceiver,
|
msgReceiver == null ? receiver : msgReceiver,
|
||||||
highlightMentions(message, group.getChatColorCode(), receiver),
|
highlightMentions(message, chatColorCode, receiver),
|
||||||
sender.getTeam() == 0 ? "" : "§" + Team.get(sender.getTeam()).getTeamColor() + Team.get(sender.getTeam()).getTeamKuerzel() + " ",
|
sender.getTeam() == 0 ? "" : "§" + Team.get(sender.getTeam()).getTeamColor() + Team.get(sender.getTeam()).getTeamKuerzel() + " ",
|
||||||
UserElo.getEmblem(sender, rankedModes),
|
UserElo.getEmblem(sender, rankedModes),
|
||||||
group.getColorCode(),
|
prefix.getColorCode(),
|
||||||
group.getChatPrefix().length() == 0 ? "§f" : group.getChatPrefix() + " ",
|
prefix.getChatPrefix().length() == 0 ? "§f" : prefix.getChatPrefix() + " ",
|
||||||
group.getChatColorCode()));
|
chatColorCode));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean filteredCommand(CommandSender sender, String message) {
|
private static boolean filteredCommand(CommandSender sender, String message) {
|
||||||
@ -199,7 +191,7 @@ public class ChatListener extends BasicListener {
|
|||||||
TaskScheduler scheduler = ProxyServer.getInstance().getScheduler();
|
TaskScheduler scheduler = ProxyServer.getInstance().getScheduler();
|
||||||
for(int i = 0; i < delay.length; i++) {
|
for(int i = 0; i < delay.length; i++) {
|
||||||
int finalI = i;
|
int finalI = i;
|
||||||
scheduler.schedule(BungeeCore.get(), () -> sender.prefixless("CHAT_MSG", name, sender.user(), new Message(baseMessage + (finalI+1))), delay[i], TimeUnit.SECONDS);
|
scheduler.schedule(VelocityCore.get(), () -> sender.prefixless("CHAT_MSG", name, sender.user(), new Message(baseMessage + (finalI+1))), delay[i], TimeUnit.SECONDS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -217,42 +209,6 @@ public class ChatListener extends BasicListener {
|
|||||||
}).collect(Collectors.joining(" "));
|
}).collect(Collectors.joining(" "));
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void onTabCompleteEvent(TabCompleteEvent e){
|
|
||||||
List<String> suggestions = e.getSuggestions();
|
|
||||||
String [] cursor = e.getCursor().split(" ");
|
|
||||||
String last;
|
|
||||||
if(cursor.length != 0)
|
|
||||||
last = cursor[cursor.length - 1];
|
|
||||||
else
|
|
||||||
last = "";
|
|
||||||
for(ProxiedPlayer player : ProxyServer.getInstance().getPlayers()){
|
|
||||||
String name = player.getName();
|
|
||||||
if (last.isEmpty() || name.startsWith(last)) {
|
|
||||||
suggestions.add(name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(last.startsWith("@")) {
|
|
||||||
String plrName = last.replace("@", "");
|
|
||||||
for(ProxiedPlayer player : ProxyServer.getInstance().getPlayers()){
|
|
||||||
String name = player.getName();
|
|
||||||
if ((plrName.isEmpty() || name.startsWith(plrName)) && !plrName.equalsIgnoreCase(name)) {
|
|
||||||
suggestions.add("@" + name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(e.getSender() instanceof ProxiedPlayer && cursor.length == 1 && cursor[0].startsWith("/")){
|
|
||||||
ProxiedPlayer player = (ProxiedPlayer) e.getSender();
|
|
||||||
for(String cmd : BungeeCore.commands.keySet()){
|
|
||||||
if(cmd.startsWith(cursor[0]) && player.hasPermission(BungeeCore.commands.get(cmd))){
|
|
||||||
suggestions.add(cmd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onTabCompleteResponseEvent(TabCompleteResponseEvent e){
|
public void onTabCompleteResponseEvent(TabCompleteResponseEvent e){
|
||||||
List<String> suggestions = e.getSuggestions();
|
List<String> suggestions = e.getSuggestions();
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
package de.steamwar.bungeecore.listeners;
|
package de.steamwar.bungeecore.listeners;
|
||||||
|
|
||||||
import de.steamwar.bungeecore.BungeeCore;
|
import de.steamwar.bungeecore.VelocityCore;
|
||||||
import de.steamwar.bungeecore.Message;
|
import de.steamwar.bungeecore.Message;
|
||||||
import de.steamwar.bungeecore.Servertype;
|
import de.steamwar.bungeecore.Servertype;
|
||||||
import de.steamwar.bungeecore.Subserver;
|
import de.steamwar.bungeecore.Subserver;
|
||||||
@ -29,9 +29,9 @@ import de.steamwar.bungeecore.commands.ChallengeCommand;
|
|||||||
import de.steamwar.bungeecore.commands.CheckCommand;
|
import de.steamwar.bungeecore.commands.CheckCommand;
|
||||||
import de.steamwar.bungeecore.commands.ModCommand;
|
import de.steamwar.bungeecore.commands.ModCommand;
|
||||||
import de.steamwar.bungeecore.commands.MsgCommand;
|
import de.steamwar.bungeecore.commands.MsgCommand;
|
||||||
import de.steamwar.bungeecore.listeners.mods.Utils;
|
import de.steamwar.bungeecore.mods.ModUtils;
|
||||||
import de.steamwar.sql.SteamwarUser;
|
import de.steamwar.sql.SteamwarUser;
|
||||||
import de.steamwar.sql.UserGroup;
|
import de.steamwar.sql.UserPerm;
|
||||||
import net.md_5.bungee.api.AbstractReconnectHandler;
|
import net.md_5.bungee.api.AbstractReconnectHandler;
|
||||||
import net.md_5.bungee.api.ProxyServer;
|
import net.md_5.bungee.api.ProxyServer;
|
||||||
import net.md_5.bungee.api.chat.ClickEvent;
|
import net.md_5.bungee.api.chat.ClickEvent;
|
||||||
@ -39,18 +39,26 @@ import net.md_5.bungee.api.config.ServerInfo;
|
|||||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||||
import net.md_5.bungee.api.event.PlayerDisconnectEvent;
|
import net.md_5.bungee.api.event.PlayerDisconnectEvent;
|
||||||
import net.md_5.bungee.api.event.PostLoginEvent;
|
import net.md_5.bungee.api.event.PostLoginEvent;
|
||||||
import net.md_5.bungee.api.event.ServerDisconnectEvent;
|
|
||||||
import net.md_5.bungee.api.event.ServerKickEvent;
|
import net.md_5.bungee.api.event.ServerKickEvent;
|
||||||
import net.md_5.bungee.event.EventHandler;
|
import net.md_5.bungee.event.EventHandler;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class ConnectionListener extends BasicListener {
|
public class ConnectionListener extends BasicListener {
|
||||||
|
|
||||||
private static final String ADMIN_GROUP = "admin";
|
public static final String ALERT_PERMISSION = "bungeecore.alert";
|
||||||
public static final String TEAM_GROUP = "team";
|
public static final String BAN_PERMISSION = "bungeecore.ban";
|
||||||
|
public static final String BUILDERCLOUD_PERMISSION = "bungeecore.buildercloud";
|
||||||
public static final String CHECK_PERMISSION = "bungeecore.check";
|
public static final String CHECK_PERMISSION = "bungeecore.check";
|
||||||
private static final String YOUTUBER_MODS = "bungeecore.youtubermods";
|
public static final String EVENTRELOAD_PERMISSION = "bungeecore.eventreload";
|
||||||
|
public static final String KICK_PERMISSION = "bungeecore.kick";
|
||||||
|
public static final String POLLRESULT_PERMISSION = "bungeecore.pollresult";
|
||||||
|
public static final String SOFTRELOAD_PERMISSION = "bungeecore.softreload";
|
||||||
|
public static final String TEAMCHAT_PERMISSION = "bungeecore.teamchat";
|
||||||
|
public static final String MOD_PERMISSION = "bungeecore.mod";
|
||||||
|
|
||||||
private static final Set<UUID> newPlayers = new HashSet<>();
|
private static final Set<UUID> newPlayers = new HashSet<>();
|
||||||
|
|
||||||
@ -63,25 +71,36 @@ public class ConnectionListener extends BasicListener {
|
|||||||
ProxiedPlayer player = event.getPlayer();
|
ProxiedPlayer player = event.getPlayer();
|
||||||
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
||||||
|
|
||||||
player.removeGroups("Admin", "team");
|
if(user.hasPerm(UserPerm.ADMINISTRATION)) {
|
||||||
|
player.setPermission("bungeecord.command.end", true);
|
||||||
if(user.getUserGroup().isAdminGroup())
|
player.setPermission("bungeecord.command.reload", true);
|
||||||
player.addGroups(ADMIN_GROUP);
|
player.setPermission("bungeecord.command.ip", true);
|
||||||
|
player.setPermission(SOFTRELOAD_PERMISSION, true);
|
||||||
if(user.getUserGroup().isTeamGroup()) {
|
|
||||||
player.addGroups(TEAM_GROUP);
|
|
||||||
CheckCommand.sendReminder(player);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(user.getUserGroup().isCheckSchematics())
|
if(user.hasPerm(UserPerm.MODERATION)) {
|
||||||
player.setPermission(CHECK_PERMISSION, true);
|
player.setPermission(ALERT_PERMISSION, true);
|
||||||
|
player.setPermission(KICK_PERMISSION, true);
|
||||||
|
player.setPermission(POLLRESULT_PERMISSION, true);
|
||||||
|
player.setPermission(EVENTRELOAD_PERMISSION, true);
|
||||||
|
player.setPermission(MOD_PERMISSION, true);
|
||||||
|
}
|
||||||
|
|
||||||
if(user.getUserGroup() != UserGroup.Member) {
|
if(user.hasPerm(UserPerm.TEAM)) {
|
||||||
player.setPermission(YOUTUBER_MODS, true);
|
player.setPermission("bungeecord.command.list", true);
|
||||||
player.setDisplayName(user.getUserGroup().getColorCode() + user.getUserGroup().getChatPrefix() + " " + player.getName() + "§r");
|
player.setPermission("bungeecord.command.send", true);
|
||||||
player.setPermission("bungeecore.group." + user.getUserGroup().name().toLowerCase(), true);
|
player.setPermission("bungeecord.command.server", true);
|
||||||
}else {
|
player.setPermission(TEAMCHAT_PERMISSION, true);
|
||||||
player.setDisplayName("§f" + player.getName());
|
player.setPermission(BAN_PERMISSION, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(user.hasPerm(UserPerm.CHECK)) {
|
||||||
|
CheckCommand.sendReminder(player);
|
||||||
|
player.setPermission(CHECK_PERMISSION, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(user.hasPerm(UserPerm.BUILD)) {
|
||||||
|
player.setPermission(BUILDERCLOUD_PERMISSION, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(Subserver subserver : Subserver.getServerList()){
|
for(Subserver subserver : Subserver.getServerList()){
|
||||||
@ -123,7 +142,7 @@ public class ConnectionListener extends BasicListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ServerInfo kickTo = ProxyServer.getInstance().getServerInfo(BungeeCore.LOBBY_SERVER);
|
ServerInfo kickTo = ProxyServer.getInstance().getServerInfo(VelocityCore.LOBBY_SERVER);
|
||||||
|
|
||||||
if (kickedFrom != null && kickedFrom.equals(kickTo)) {
|
if (kickedFrom != null && kickedFrom.equals(kickTo)) {
|
||||||
return;
|
return;
|
||||||
@ -137,20 +156,7 @@ public class ConnectionListener extends BasicListener {
|
|||||||
public void onDisconnect(PlayerDisconnectEvent e){
|
public void onDisconnect(PlayerDisconnectEvent e){
|
||||||
ChallengeCommand.remove(e.getPlayer());
|
ChallengeCommand.remove(e.getPlayer());
|
||||||
MsgCommand.remove(e.getPlayer());
|
MsgCommand.remove(e.getPlayer());
|
||||||
Utils.playerModMap.remove(e.getPlayer().getUniqueId());
|
ModUtils.getPlayerModMap().remove(e.getPlayer().getUniqueId());
|
||||||
ModCommand.playerFilterType.remove(e.getPlayer());
|
ModCommand.playerFilterType.remove(e.getPlayer());
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void onServerDisconnect(ServerDisconnectEvent e){
|
|
||||||
ServerInfo server = e.getTarget();
|
|
||||||
Subserver subserver = Subserver.getSubserver(server);
|
|
||||||
if(subserver == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
ProxiedPlayer player = e.getPlayer();
|
|
||||||
Collection<ProxiedPlayer> players = server.getPlayers();
|
|
||||||
if(players.isEmpty() || (players.size() == 1 && players.contains(player)))
|
|
||||||
ProxyServer.getInstance().getScheduler().runAsync(BungeeCore.get(), subserver::waitForTermination);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,7 @@
|
|||||||
package de.steamwar.bungeecore.listeners;
|
package de.steamwar.bungeecore.listeners;
|
||||||
|
|
||||||
import de.steamwar.bungeecore.Message;
|
import de.steamwar.bungeecore.Message;
|
||||||
import de.steamwar.sql.EventFight;
|
import de.steamwar.sql.*;
|
||||||
import de.steamwar.sql.SteamwarUser;
|
|
||||||
import de.steamwar.sql.TeamTeilnahme;
|
|
||||||
import de.steamwar.sql.Event;
|
|
||||||
import net.md_5.bungee.api.chat.TextComponent;
|
import net.md_5.bungee.api.chat.TextComponent;
|
||||||
import net.md_5.bungee.api.event.PostLoginEvent;
|
import net.md_5.bungee.api.event.PostLoginEvent;
|
||||||
import net.md_5.bungee.event.EventHandler;
|
import net.md_5.bungee.event.EventHandler;
|
||||||
@ -24,10 +21,8 @@ public class EventModeListener extends BasicListener {
|
|||||||
if(TeamTeilnahme.nimmtTeil(user.getTeam(), event.getEventID()))
|
if(TeamTeilnahme.nimmtTeil(user.getTeam(), event.getEventID()))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for(EventFight eventFight : EventFight.getEvent(event.getEventID())){
|
if(Referee.get(event.getEventID()).contains(user.getId()))
|
||||||
if(eventFight.getKampfleiter() == user.getId())
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
e.getPlayer().disconnect(TextComponent.fromLegacyText(Message.parse("EVENTMODE_KICK", e.getPlayer())));
|
e.getPlayer().disconnect(TextComponent.fromLegacyText(Message.parse("EVENTMODE_KICK", e.getPlayer())));
|
||||||
}
|
}
|
||||||
|
74
src/de/steamwar/bungeecore/listeners/IPSanitizer.java
Normale Datei
74
src/de/steamwar/bungeecore/listeners/IPSanitizer.java
Normale Datei
@ -0,0 +1,74 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of the SteamWar software.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2020 SteamWar.de-Serverteam
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.bungeecore.listeners;
|
||||||
|
|
||||||
|
import com.velocitypowered.api.event.Subscribe;
|
||||||
|
import com.velocitypowered.api.event.connection.PreLoginEvent;
|
||||||
|
import com.velocitypowered.api.proxy.InboundConnection;
|
||||||
|
import com.velocitypowered.proxy.connection.MinecraftConnection;
|
||||||
|
import com.velocitypowered.proxy.connection.client.InitialInboundConnection;
|
||||||
|
import com.velocitypowered.proxy.connection.client.LoginInboundConnection;
|
||||||
|
import de.steamwar.bungeecore.VelocityCore;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
public class IPSanitizer {
|
||||||
|
|
||||||
|
private static final Field delegateField;
|
||||||
|
private static final Field remoteAddressField;
|
||||||
|
static {
|
||||||
|
try {
|
||||||
|
delegateField = LoginInboundConnection.class.getDeclaredField("delegate");
|
||||||
|
remoteAddressField = MinecraftConnection.class.getDeclaredField("remoteAddress");
|
||||||
|
} catch (NoSuchFieldException e) {
|
||||||
|
throw new SecurityException("Could not initialize Reflection", e);
|
||||||
|
}
|
||||||
|
delegateField.setAccessible(true);
|
||||||
|
remoteAddressField.setAccessible(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MinecraftConnection getChannelWrapper(InboundConnection connection) {
|
||||||
|
try {
|
||||||
|
return ((InitialInboundConnection) delegateField.get(connection)).getConnection();
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
throw new SecurityException("Could not get channel wrapper", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static InetAddress getTrueAddress(InboundConnection connection) {
|
||||||
|
return ((InetSocketAddress) getChannelWrapper(connection).getRemoteAddress()).getAddress();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private final InetSocketAddress sanitized = new InetSocketAddress("127.127.127.127", 25565);
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void loginEvent(PreLoginEvent e) {
|
||||||
|
VelocityCore.get().getLogger().log(Level.INFO, e.getConnection().getRemoteAddress().getAddress().toString() + " has logged in with user name " + e.getUsername());
|
||||||
|
try {
|
||||||
|
remoteAddressField.set(getChannelWrapper(e.getConnection()), sanitized);
|
||||||
|
} catch (IllegalAccessException ex) {
|
||||||
|
throw new SecurityException("Could not set remote address", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,97 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2022 SteamWar.de-Serverteam
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.bungeecore.listeners;
|
|
||||||
|
|
||||||
import de.steamwar.bungeecore.BungeeCore;
|
|
||||||
import de.steamwar.bungeecore.Message;
|
|
||||||
import de.steamwar.bungeecore.Storage;
|
|
||||||
import net.md_5.bungee.BungeeCord;
|
|
||||||
import net.md_5.bungee.api.connection.Connection;
|
|
||||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
|
||||||
import net.md_5.bungee.api.event.LoginEvent;
|
|
||||||
import net.md_5.bungee.api.event.PlayerDisconnectEvent;
|
|
||||||
import net.md_5.bungee.api.event.PluginMessageEvent;
|
|
||||||
import net.md_5.bungee.event.EventHandler;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
public class NonFabricFabricCheck extends BasicListener {
|
|
||||||
|
|
||||||
private final Set<UUID> usingFabric = new HashSet<>();
|
|
||||||
|
|
||||||
private final Set<ProxiedPlayer> checking = new HashSet<>();
|
|
||||||
private final Set<ProxiedPlayer> vanilla = new HashSet<>();
|
|
||||||
|
|
||||||
{
|
|
||||||
BungeeCord.getInstance().getScheduler().schedule(BungeeCore.get(), usingFabric::clear, 0, 15, TimeUnit.MINUTES);
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void pluginMessageEvent(PluginMessageEvent e) {
|
|
||||||
Connection sender = e.getSender();
|
|
||||||
if(!(sender instanceof ProxiedPlayer))
|
|
||||||
return;
|
|
||||||
|
|
||||||
ProxiedPlayer p = (ProxiedPlayer) sender;
|
|
||||||
if (e.getTag().equals("minecraft:register") && new String(e.getData()).contains("fabric-screen-handler-api-v1:open_screen")) {
|
|
||||||
BungeeCord.getInstance().getScheduler().schedule(BungeeCore.get(), () -> {
|
|
||||||
if (!sender.isConnected()) return;
|
|
||||||
if (!vanilla.remove(p)) return;
|
|
||||||
if (Storage.fabricCheckedPlayers.containsKey(p)) return;
|
|
||||||
p.disconnect(Message.parse("MOD_USE_MODSENDER", p));
|
|
||||||
}, 25, TimeUnit.SECONDS);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!e.getTag().equals("minecraft:brand"))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(!new String(e.getData()).equals("vanilla"))
|
|
||||||
return;
|
|
||||||
vanilla.add(p);
|
|
||||||
|
|
||||||
BungeeCord.getInstance().getScheduler().schedule(BungeeCore.get(), () -> {
|
|
||||||
if (!p.isConnected()) return;
|
|
||||||
if (Storage.fabricCheckedPlayers.containsKey(p)) return;
|
|
||||||
checking.add(p);
|
|
||||||
p.sendData("fabric-screen-handler-api-v1:open_screen", new byte[] {0});
|
|
||||||
BungeeCord.getInstance().getScheduler().schedule(BungeeCore.get(), () -> checking.remove(p), 1, TimeUnit.SECONDS);
|
|
||||||
}, 30, TimeUnit.SECONDS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void onPlayerPreLogin(LoginEvent e) {
|
|
||||||
if (usingFabric.remove(e.getConnection().getUniqueId())) {
|
|
||||||
e.getConnection().disconnect(Message.parse("MOD_USE_MODSENDER", Locale.getDefault()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void onPlayerDisconnect(PlayerDisconnectEvent e) {
|
|
||||||
if (checking.remove(e.getPlayer())) {
|
|
||||||
usingFabric.add(e.getPlayer().getUniqueId());
|
|
||||||
}
|
|
||||||
vanilla.remove(e.getPlayer());
|
|
||||||
}
|
|
||||||
}
|
|
331
src/de/steamwar/bungeecore/listeners/PluginMessage.java
Normale Datei
331
src/de/steamwar/bungeecore/listeners/PluginMessage.java
Normale Datei
@ -0,0 +1,331 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of the SteamWar software.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2024 SteamWar.de-Serverteam
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.bungeecore.listeners;
|
||||||
|
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
import com.lunarclient.apollo.ApolloManager;
|
||||||
|
import com.velocitypowered.api.event.connection.PluginMessageEvent;
|
||||||
|
import com.velocitypowered.api.proxy.Player;
|
||||||
|
import com.velocitypowered.api.proxy.ServerConnection;
|
||||||
|
import com.velocitypowered.api.proxy.messages.MinecraftChannelIdentifier;
|
||||||
|
import de.steamwar.bungeecore.VelocityCore;
|
||||||
|
import de.steamwar.bungeecore.Message;
|
||||||
|
import de.steamwar.bungeecore.commands.TeamCommand;
|
||||||
|
import de.steamwar.bungeecore.mods.*;
|
||||||
|
import de.steamwar.bungeecore.network.ServerMetaInfo;
|
||||||
|
import de.steamwar.bungeecore.util.annotations.Create;
|
||||||
|
import de.steamwar.messages.ChatSender;
|
||||||
|
import de.steamwar.network.packets.NetworkPacket;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.buffer.Unpooled;
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
@Create
|
||||||
|
public class PluginMessage {
|
||||||
|
|
||||||
|
private final Lunar lunar;
|
||||||
|
private final LabyMod labyMod;
|
||||||
|
private final WorldDownloader wdl;
|
||||||
|
private final FabricModSender fms;
|
||||||
|
private final FML flm;
|
||||||
|
|
||||||
|
public static void send(Player player, String legacyChannel, String channel, byte[] data) {
|
||||||
|
// 1.12 format change
|
||||||
|
send(player, player.getProtocolVersion().getProtocol() > 340 ? channel : legacyChannel, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void send(Player player, String channel, byte[] data) {
|
||||||
|
player.sendPluginMessage(MinecraftChannelIdentifier.from(channel), data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] genBufPacket(Consumer<ByteBuf> generator) {
|
||||||
|
ByteBuf buf = Unpooled.buffer();
|
||||||
|
generator.accept(buf);
|
||||||
|
|
||||||
|
byte[] packet = new byte[buf.readableBytes()];
|
||||||
|
buf.readBytes(packet);
|
||||||
|
return packet;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] genStreamPacket(StreamConsumer generator) {
|
||||||
|
ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
||||||
|
DataOutputStream out = new DataOutputStream(stream);
|
||||||
|
|
||||||
|
try {
|
||||||
|
generator.accept(out);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new SecurityException("Could not create PluginMessage packet", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return stream.toByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface StreamConsumer {
|
||||||
|
void accept(DataOutputStream out) throws IOException;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Parser UNKNOWN = event -> {
|
||||||
|
VelocityCore.get().getLogger().log(Level.WARNING, () -> "Undefined PluginMessage on channel " + event.getIdentifier().getId() + " from " + (event.getSource() instanceof Player pl ? pl.getUsername() : event.getSource().toString()) + " received.\n" + new String(event.getData()) + "\n" + Arrays.toString(event.getData()));
|
||||||
|
event.setResult(PluginMessageEvent.ForwardResult.handled());
|
||||||
|
};
|
||||||
|
private static final Parser PASS_THROUGH = event -> event.setResult(PluginMessageEvent.ForwardResult.forward());
|
||||||
|
private static final Parser DROP = event -> event.setResult(PluginMessageEvent.ForwardResult.handled());
|
||||||
|
|
||||||
|
private final Set<String> knownBrands = new HashSet<>();
|
||||||
|
private final Map<String, Consumer<Player>> channelRegisterHandlers = new HashMap<>();
|
||||||
|
private final Map<String, Parser> handlers = new HashMap<>();
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public PluginMessage(Lunar lunar, LabyMod labyMod, WorldDownloader wdl, FabricModSender fms, FML flm) {
|
||||||
|
this.lunar = lunar;
|
||||||
|
this.labyMod = labyMod;
|
||||||
|
this.wdl = wdl;
|
||||||
|
this.fms = fms;
|
||||||
|
this.flm = flm;
|
||||||
|
|
||||||
|
knownBrands.addAll(Arrays.asList("vanilla", "fabric", "quilt", "forge", "optifine", "Geyser", "labymod", "Feather Fabric"));
|
||||||
|
|
||||||
|
for(String channel : Arrays.asList(
|
||||||
|
"fabric:container/open", "fabric:registry/sync/direct", "fabric:registry/sync",
|
||||||
|
"fabric-screen-handler-api-v1:open_screen",
|
||||||
|
|
||||||
|
FML.CHANNEL, "fml:loginwrapper", "fml:handshake", "fml:play", "forge:tier_sorting", "forge:split",
|
||||||
|
"forge:login", "forge:handshake",
|
||||||
|
|
||||||
|
"labymod3:main", "labymod:neo",
|
||||||
|
|
||||||
|
"floodgate:skin", "floodgate:form", "floodgate:transfer", "floodgate:packet",
|
||||||
|
|
||||||
|
"Replay|Restrict", "replaymod:restrict",
|
||||||
|
"WDL|CONTROL", "wdl:control",
|
||||||
|
"tpshud:handshake", "tpshud:tps", //https://github.com/mooziii/tpshud-fabric/tree/main
|
||||||
|
"methane_server:statepacket", //https://modrinth.com/mod/methane
|
||||||
|
"servux:structures", //https://modrinth.com/mod/servux
|
||||||
|
"architectury:spawn_entity_packet", //https://modrinth.com/mod/architectury-api
|
||||||
|
"jei:channel", //https://modrinth.com/mod/jei
|
||||||
|
"shulkerboxtooltip:s2c_handshake", "shulkerboxtooltip:ec_update", //https://modrinth.com/mod/shulkerboxtooltip
|
||||||
|
"owo:local_packet", "owo:sync_screen_handler_properties", //https://modrinth.com/mod/owo-lib
|
||||||
|
"essential:", //https://essential.gg/
|
||||||
|
"libgui:screen_message_s2c", //https://github.com/CottonMC/LibGui
|
||||||
|
"minecraft:intave", //https://intave.ac seems to be a client side integration of intave with labymod 4
|
||||||
|
"midnightcontrols:feature", "midnightcontrols:controls_mode", //https://modrinth.com/mod/midnightcontrols
|
||||||
|
"controlify:vibrate_from_origin", "controlify:vibration", "controlify:vibrate_from_entity",
|
||||||
|
"carpet:structures", //https://modrinth.com/mod/carpet
|
||||||
|
"appleskin:exhaustion_sync", "appleskin:saturation_sync", //https://modrinth.com/mod/appleskin
|
||||||
|
"puzzleslib:1/1", //https://modrinth.com/mod/puzzles-lib
|
||||||
|
"pickupnotifier:1/1", //https://modrinth.com/mod/pick-up-notifier
|
||||||
|
"plasmo:voice/v2/installed", "plasmo:voice/v2", //https://modrinth.com/plugin/plasmo-voice
|
||||||
|
"whereisit:s2c_founditem", //https://modrinth.com/mod/where-is-it (needs server side component to work)
|
||||||
|
"inventorysorter:sync_blacklist_packet", //https://github.com/cpw/inventorysorter (needs server side component to work)
|
||||||
|
|
||||||
|
//https://github.com/bernie-g/geckolib
|
||||||
|
"geckolib:block_entity_anim_trigger_sync", "geckolib:entity_anim_trigger_sync",
|
||||||
|
"geckolib:block_entity_anim_data_sync", "geckolib:anim_data_sync",
|
||||||
|
"geckolib:entity_anim_data_sync", "geckolib:anim_trigger_sync",
|
||||||
|
|
||||||
|
//https://github.com/Noxcrew/noxesium
|
||||||
|
"noxesium-v1:reset", "noxesium-v1:change_server_rules", "noxesium-v1:server_info",
|
||||||
|
"noxesium-v1:mcc_server", "noxesium-v1:mcc_game_state", "noxesium-v1:reset_server_rules",
|
||||||
|
"noxesium-v1:stop_sound", "noxesium-v1:start_sound", "noxesium-v1:modify_sound"
|
||||||
|
)) {
|
||||||
|
channelRegisterHandlers.put(channel, player -> {
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
channelRegisterHandlers.put(ApolloManager.PLUGIN_MESSAGE_CHANNEL, lunar::sendRestrictions);
|
||||||
|
channelRegisterHandlers.put(Feather.CHANNEL.getId(), new Feather()::sendRestrictions);
|
||||||
|
channelRegisterHandlers.put("xaerominimap:main", player -> player.sendMessage(Component.text("§n§o§m§i§n§i§m§a§p"))); //https://www.curseforge.com/minecraft/mc-mods/xaeros-minimap
|
||||||
|
channelRegisterHandlers.put("litemoretica:init_easy_place", player -> player.disconnect(ChatSender.of(player).parseToComponent(false, new Message("MOD_YELLOW_SING", "litematica")))); //https://github.com/Earthcomputer/litemoretica/tree/master
|
||||||
|
channelRegisterHandlers.put("voxelmap:settings", player -> player.disconnect(ChatSender.of(player).parseToComponent(false, new Message("MOD_YELLOW_SING", "voxelmap")))); //https://modrinth.com/mod/voxelmap-updated undocumented
|
||||||
|
channelRegisterHandlers.put("worldinfo:world_id", player -> player.disconnect(ChatSender.of(player).parseToComponent(false, new Message("MOD_YELLOW_SING", "minimap")))); // JourneyMap and VoxelMap
|
||||||
|
channelRegisterHandlers.put(Controlify.CHANNEL.getId(), new Controlify()::onRegister);
|
||||||
|
|
||||||
|
registerBiDirPassthrough("worldedit:cui");
|
||||||
|
|
||||||
|
registerPassthroughToClient(
|
||||||
|
"axiom:enable", "axiom:initialize_hotbars",
|
||||||
|
"axiom:response_chunk_data", "axiom:register_world_properties", "axiom:set_world_property",
|
||||||
|
"axiom:ack_world_properties", "axiom:restrictions", "axiom:marker_data", "axiom:marker_nbt_response",
|
||||||
|
"axiom:custom_blocks", "axiom:editor_warning", "axiom:blueprint_manifest", "axiom:response_blueprint"
|
||||||
|
);
|
||||||
|
registerBiDirPassthrough("axiom:handle_big_payload", "axiom:set_editor_views");
|
||||||
|
registerPassthroughToServer(
|
||||||
|
"axiom:hello", "axiom:set_gamemode", "axiom:set_fly_speed", "axiom:set_world_time",
|
||||||
|
"axiom:set_world_property", "axiom:set_block", "axiom:set_hotbar_slot", "axiom:switch_active_hotbar",
|
||||||
|
"axiom:teleport", "axiom:request_chunk_data", "axiom:spawn_entity",
|
||||||
|
"axiom:manipulate_entity", "axiom:delete_entity", "axiom:marker_nbt_request", "axiom:set_buffer"
|
||||||
|
);
|
||||||
|
|
||||||
|
for(String channel : Arrays.asList(
|
||||||
|
"UNREGISTER", "minecraft:unregister", // used by carpet and servux
|
||||||
|
"WDL|REQUEST", "wdl:request",
|
||||||
|
"minecraft:intave", //undocumented, byte stringlength, clientconfig, byte length, json {"legacySneakHeight":false,"legacyOldRange":false,"legacyOldSlowdown":false}
|
||||||
|
"waila:entity", "waila:block",
|
||||||
|
"lambdacontrols:hello",
|
||||||
|
"midnightcontrols:controls_mode",
|
||||||
|
"inventorysorter:sync_settings_packet",
|
||||||
|
"voicechat:request_secret", "voicechat:update_state", //https://modrinth.com/plugin/simple-voice-chat
|
||||||
|
"shulkerboxtooltip:c2s_handshake"
|
||||||
|
))
|
||||||
|
register(channel, false, directional(UNKNOWN, DROP));
|
||||||
|
|
||||||
|
register("REGISTER", false, directional(this::serverRegistersChannel, this::clientRegistersChannel));
|
||||||
|
register("minecraft:register", false, directional(this::serverRegistersChannel, this::clientRegistersChannel));
|
||||||
|
|
||||||
|
register("BungeeCord", false, onlySWSource(PASS_THROUGH));
|
||||||
|
register("bungeecord:main", false, onlySWSource(PASS_THROUGH));
|
||||||
|
register("MC|Brand", false, directional(this::steamWarBrand, this::userBrand));
|
||||||
|
register("minecraft:brand", false, directional(this::steamWarBrand, this::userBrand));
|
||||||
|
|
||||||
|
//Needs to be registered cause paper refuses to send PluginMessages on unregistered channels...
|
||||||
|
register("sw:bridge", true, directional(onlySWSource(async(event -> NetworkPacket.handle(new ServerMetaInfo(((ServerConnection) event.getSource()).getServerInfo()), event.getData()))), UNKNOWN));
|
||||||
|
register("sw:hotkeys", false, directional(UNKNOWN, PASS_THROUGH));
|
||||||
|
register("fabricmodsender:mods", true, directional(UNKNOWN, async(fms::handlePluginMessage)));
|
||||||
|
|
||||||
|
register("WDL|INIT", true, directional(UNKNOWN, wdl::handlePluginMessage));
|
||||||
|
register("wdl:init", true, directional(UNKNOWN, wdl::handlePluginMessage));
|
||||||
|
|
||||||
|
register(ApolloManager.PLUGIN_MESSAGE_CHANNEL, true, async(lunar::handlePluginMessage));
|
||||||
|
register("LMC", true, directional(UNKNOWN, async(labyMod::handlePluginMessage)));
|
||||||
|
register("labymod3:main", true, directional(UNKNOWN, async(labyMod::handlePluginMessage)));
|
||||||
|
register("labymod:neo", false, directional(UNKNOWN, DROP)); //undocumented, JSON format "0" byte, packetlängen byte, {"version":"4.1.25"}
|
||||||
|
register(FML.CHANNEL, true, directional(UNKNOWN, async(flm::handlePluginMessage)));
|
||||||
|
|
||||||
|
//vanilla does not register any channels (sends only one minecraft:brand vanilla, nothing else (potential spoofed client detection))
|
||||||
|
//Forge interestingly registers all channels the server registers
|
||||||
|
//meteor https://github.com/MeteorDevelopment/meteor-client/blob/master/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/ServerSpoof.java https://github.com/MeteorDevelopment/meteor-client/blob/master/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/DiscordPresence.java
|
||||||
|
//litematica/malilib https://github.com/maruohon/litematica/issues/75 https://github.com/maruohon/malilib/blob/liteloader_1.12.2/src/main/java/malilib/network/message/ConfigLockPacketHandler.java#L65
|
||||||
|
// Hackclientlike modsuppressor for labymod: https://github.com/Neocraftr/LabyMod-NeoEssentials (Potentially recognizable from NO Addons/NO Mods?) https://github.com/Neocraftr/LabyMod-NeoEssentials/blob/master/src/main/java/de/neocraftr/neoessentials/utils/BytecodeMethods.java
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onPluginMessage(PluginMessageEvent event) {
|
||||||
|
event.setCancelled(true);
|
||||||
|
|
||||||
|
try {
|
||||||
|
handlers.getOrDefault(event.getTag(), UNKNOWN).handle(event);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new SecurityException("PluginMessage handling exception: " + event + "\n" + Arrays.toString(event.getData()), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void registerPassthroughToClient(String... channels) {
|
||||||
|
for(String channel : channels) {
|
||||||
|
channelRegisterHandlers.put(channel, player -> {});
|
||||||
|
register(channel, false, directional(PASS_THROUGH, UNKNOWN));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void registerPassthroughToServer(String... channels) {
|
||||||
|
for(String channel : channels)
|
||||||
|
register(channel, false, directional(UNKNOWN, PASS_THROUGH));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void registerBiDirPassthrough(String... channels) {
|
||||||
|
for(String channel : channels) {
|
||||||
|
channelRegisterHandlers.put(channel, player -> {});
|
||||||
|
register(channel, false, PASS_THROUGH);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void register(String channel, boolean clientSideRegister, Parser handler) {
|
||||||
|
handlers.put(channel, handler);
|
||||||
|
if(clientSideRegister)
|
||||||
|
ProxyServer.getInstance().registerChannel(channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void clientRegistersChannel(PluginMessageEvent event) {
|
||||||
|
ProxiedPlayer player = (ProxiedPlayer) event.getSender();
|
||||||
|
|
||||||
|
for(String channel : new String(event.getData()).split("\0")) {
|
||||||
|
channelRegisterHandlers.getOrDefault(channel, p -> VelocityCore.get().getLogger().log(Level.WARNING, () -> p.getName() + " registered unknown channel " + channel)).accept(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
PASS_THROUGH.handle(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void serverRegistersChannel(PluginMessageEvent event) {
|
||||||
|
ProxiedPlayer player = (ProxiedPlayer)event.getReceiver();
|
||||||
|
|
||||||
|
List<String> channels = new ArrayList<>(Arrays.asList(new String(event.getData()).split("\0")));
|
||||||
|
channels.removeIf(channel -> channel.equals("sw:bridge"));
|
||||||
|
player.sendData((player).getPendingConnection().getVersion() > 340 ? "minecraft:register" : "REGISTER", String.join("\0", channels).getBytes());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void userBrand(PluginMessageEvent event) {
|
||||||
|
ProxiedPlayer player = (ProxiedPlayer) event.getSender();
|
||||||
|
ByteBuf buf = Unpooled.wrappedBuffer(event.getData());
|
||||||
|
String brand = DefinedPacket.readString(buf);
|
||||||
|
boolean lunarclient = brand.startsWith("lunarclient:");
|
||||||
|
|
||||||
|
VelocityCore.get().getLogger().log(knownBrands.contains(brand) || lunarclient ? Level.INFO : Level.WARNING, () -> player.getName() + " joins with brand: " + brand);
|
||||||
|
if(lunarclient)
|
||||||
|
lunar.sendRestrictions(player);
|
||||||
|
|
||||||
|
PASS_THROUGH.handle(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void steamWarBrand(PluginMessageEvent event) {
|
||||||
|
ProxiedPlayer player = (ProxiedPlayer) event.getReceiver();
|
||||||
|
String brandString = ChatSender.of(player).parseToLegacy("STEAMWAR_BRAND", ProxyServer.getInstance().getName(), player.getServer().getInfo().getName(), new String(event.getData(), 1, event.getData().length - 1));
|
||||||
|
|
||||||
|
ByteBuf brand = ByteBufAllocator.DEFAULT.heapBuffer();
|
||||||
|
DefinedPacket.writeString(brandString, brand);
|
||||||
|
player.sendData(event.getTag(), DefinedPacket.toArray(brand));
|
||||||
|
brand.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private Parser directional(Parser fromServer, Parser fromPlayer) {
|
||||||
|
return event -> {
|
||||||
|
if(event.getSender() instanceof ProxiedPlayer)
|
||||||
|
fromPlayer.handle(event);
|
||||||
|
else
|
||||||
|
fromServer.handle(event);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
private Parser onlySWSource(Parser parser) {
|
||||||
|
return event -> {
|
||||||
|
Connection sender = event.getSender();
|
||||||
|
if(TeamCommand.isLocalhost(sender instanceof ProxiedPlayer ? IPSanitizer.getTrueAddress(((ProxiedPlayer) sender).getPendingConnection()) : sender.getAddress().getAddress()))
|
||||||
|
parser.handle(event);
|
||||||
|
else
|
||||||
|
UNKNOWN.handle(event);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private Parser async(Parser parser) {
|
||||||
|
return event -> ProxyServer.getInstance().getScheduler().runAsync(VelocityCore.get(), () -> parser.handle(event));
|
||||||
|
}
|
||||||
|
|
||||||
|
private interface Parser {
|
||||||
|
void handle(PluginMessageEvent event);
|
||||||
|
}
|
||||||
|
}
|
@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
package de.steamwar.bungeecore.listeners;
|
package de.steamwar.bungeecore.listeners;
|
||||||
|
|
||||||
import de.steamwar.bungeecore.BungeeCore;
|
import de.steamwar.bungeecore.VelocityCore;
|
||||||
import de.steamwar.sql.Session;
|
import de.steamwar.sql.Session;
|
||||||
import de.steamwar.sql.SteamwarUser;
|
import de.steamwar.sql.SteamwarUser;
|
||||||
import net.md_5.bungee.api.ProxyServer;
|
import net.md_5.bungee.api.ProxyServer;
|
||||||
@ -43,7 +43,7 @@ public class SessionManager extends BasicListener {
|
|||||||
public void onDisconnect(PlayerDisconnectEvent e){
|
public void onDisconnect(PlayerDisconnectEvent e){
|
||||||
Timestamp timestamp = sessions.remove(e.getPlayer());
|
Timestamp timestamp = sessions.remove(e.getPlayer());
|
||||||
if(timestamp != null) {
|
if(timestamp != null) {
|
||||||
ProxyServer.getInstance().getScheduler().runAsync(BungeeCore.get(), () -> Session.insertSession(SteamwarUser.get(e.getPlayer().getUniqueId()).getId(), timestamp));
|
ProxyServer.getInstance().getScheduler().runAsync(VelocityCore.get(), () -> Session.insertSession(SteamwarUser.get(e.getPlayer().getUniqueId()).getId(), timestamp));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
package de.steamwar.bungeecore.listeners;
|
package de.steamwar.bungeecore.listeners;
|
||||||
|
|
||||||
import de.steamwar.bungeecore.BungeeCore;
|
import de.steamwar.bungeecore.VelocityCore;
|
||||||
import de.steamwar.bungeecore.network.NetworkSender;
|
import de.steamwar.bungeecore.network.NetworkSender;
|
||||||
import de.steamwar.sql.SteamwarUser;
|
import de.steamwar.sql.SteamwarUser;
|
||||||
import de.steamwar.network.packets.server.LocaleInvalidationPacket;
|
import de.steamwar.network.packets.server.LocaleInvalidationPacket;
|
||||||
@ -32,7 +32,7 @@ public class SettingsChangedListener extends BasicListener {
|
|||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onSettingsChanged(SettingsChangedEvent event) {
|
public void onSettingsChanged(SettingsChangedEvent event) {
|
||||||
BungeeCord.getInstance().getScheduler().runAsync(BungeeCore.get(), () -> {
|
BungeeCord.getInstance().getScheduler().runAsync(VelocityCore.get(), () -> {
|
||||||
ProxiedPlayer player = event.getPlayer();
|
ProxiedPlayer player = event.getPlayer();
|
||||||
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
||||||
user.setLocale(player.getLocale(), false);
|
user.setLocale(player.getLocale(), false);
|
||||||
|
@ -1,70 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2020 SteamWar.de-Serverteam
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.bungeecore.listeners;
|
|
||||||
|
|
||||||
import net.md_5.bungee.BungeeCord;
|
|
||||||
import net.md_5.bungee.api.event.LoginEvent;
|
|
||||||
import net.md_5.bungee.connection.InitialHandler;
|
|
||||||
import net.md_5.bungee.connection.LoginResult;
|
|
||||||
import net.md_5.bungee.event.EventHandler;
|
|
||||||
import net.md_5.bungee.protocol.Property;
|
|
||||||
import net.md_5.bungee.util.AddressUtil;
|
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.net.InetSocketAddress;
|
|
||||||
import java.util.logging.Level;
|
|
||||||
|
|
||||||
public class SubserverProtocolFixer extends BasicListener {
|
|
||||||
|
|
||||||
private final InetSocketAddress inetSocketAddress = new InetSocketAddress("127.127.127.127", 25565);
|
|
||||||
|
|
||||||
private Field field;
|
|
||||||
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
field = InitialHandler.class.getDeclaredField("extraDataInHandshake");
|
|
||||||
field.setAccessible(true);
|
|
||||||
} catch (NoSuchFieldException e) {
|
|
||||||
BungeeCord.getInstance().getLogger().log(Level.SEVERE, e.getMessage(), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void loginEvent(LoginEvent e) {
|
|
||||||
InitialHandler initialHandler = ((InitialHandler) e.getConnection());
|
|
||||||
|
|
||||||
String undashedUUID = initialHandler.getUniqueId().toString().replace("-", "");
|
|
||||||
String extraData = "\00" + AddressUtil.sanitizeAddress(inetSocketAddress) + "\00" + undashedUUID;
|
|
||||||
|
|
||||||
LoginResult result = initialHandler.getLoginProfile();
|
|
||||||
if (result != null) {
|
|
||||||
Property[] properties = result.getProperties();
|
|
||||||
if (properties.length > 0) {
|
|
||||||
extraData += "\00" + BungeeCord.getInstance().gson.toJson(properties);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
field.set(initialHandler, extraData);
|
|
||||||
} catch (IllegalAccessException ex) {
|
|
||||||
BungeeCord.getInstance().getLogger().log(Level.SEVERE, ex.getMessage(), ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
package de.steamwar.bungeecore.listeners.mods;
|
|
||||||
|
|
||||||
import de.steamwar.bungeecore.listeners.BasicListener;
|
|
||||||
import net.md_5.bungee.api.event.PostLoginEvent;
|
|
||||||
import net.md_5.bungee.event.EventHandler;
|
|
||||||
import net.md_5.bungee.protocol.packet.PluginMessage;
|
|
||||||
|
|
||||||
public class Badlion extends BasicListener {
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void onPostLogin(PostLoginEvent event) {
|
|
||||||
/*
|
|
||||||
{
|
|
||||||
"modsDisallowed": {
|
|
||||||
"Clear Glass":{"disabled":true},
|
|
||||||
"ClearWater":{"disabled":true},
|
|
||||||
"FOV Changer":{"disabled":true},
|
|
||||||
"Hitboxes":{"disabled":true},
|
|
||||||
"MiniMap":{"disabled":true},
|
|
||||||
"MLG Cobweb":{"disabled":true},
|
|
||||||
"Replay":{"disabled":true},
|
|
||||||
"Schematica":{"disabled":true},
|
|
||||||
"ToggleSneak":{"disabled":true},
|
|
||||||
"ToggleSprint":{"disabled":true},
|
|
||||||
"TNT Time":{"disabled":true}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
event.getPlayer().unsafe().sendPacket(new PluginMessage("badlion:mods", ("{\"Clear Glass\":{\"disabled\":true},\"ClearWater\":{\"disabled\":true},\"FOV Changer\":{\"disabled\":true},\"Hitboxes\":{\"disabled\":true},\"MiniMap\":{\"disabled\":true},\"MLG Cobweb\":{\"disabled\":true},\"Replay\":{\"disabled\":true},\"Schematica\":{\"disabled\":true},\"ToggleSneak\":{\"disabled\":true},\"ToggleSprint\":{\"disabled\":true},\"TNT Time\":{\"disabled\":true}}").getBytes(), false));
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,194 +0,0 @@
|
|||||||
/*
|
|
||||||
This file is a part of the SteamWar software.
|
|
||||||
|
|
||||||
Copyright (C) 2020 SteamWar.de-Serverteam
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU Affero General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU Affero General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Affero General Public License
|
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.bungeecore.listeners.mods;
|
|
||||||
|
|
||||||
import com.google.gson.JsonArray;
|
|
||||||
import com.google.gson.JsonElement;
|
|
||||||
import com.google.gson.JsonParser;
|
|
||||||
import com.google.gson.JsonSyntaxException;
|
|
||||||
import de.steamwar.bungeecore.BungeeCore;
|
|
||||||
import de.steamwar.bungeecore.Message;
|
|
||||||
import de.steamwar.bungeecore.Storage;
|
|
||||||
import de.steamwar.bungeecore.listeners.BasicListener;
|
|
||||||
import de.steamwar.sql.Mod;
|
|
||||||
import de.steamwar.sql.SWException;
|
|
||||||
import de.steamwar.sql.SteamwarUser;
|
|
||||||
import net.md_5.bungee.BungeeCord;
|
|
||||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
|
||||||
import net.md_5.bungee.api.event.PluginMessageEvent;
|
|
||||||
import net.md_5.bungee.api.event.ServerSwitchEvent;
|
|
||||||
import net.md_5.bungee.event.EventHandler;
|
|
||||||
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.nio.charset.UnsupportedCharsetException;
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
public class Fabric extends BasicListener {
|
|
||||||
|
|
||||||
public static void remove(ProxiedPlayer player) {
|
|
||||||
Storage.fabricCheckedPlayers.remove(player);
|
|
||||||
synchronized (Storage.fabricExpectPluginMessage) {
|
|
||||||
Storage.fabricExpectPluginMessage.remove(player);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final HashSet<String> ppCircumventerList = new HashSet<>();
|
|
||||||
static {
|
|
||||||
ppCircumventerList.add("java");
|
|
||||||
ppCircumventerList.add("minecraft");
|
|
||||||
ppCircumventerList.add("org_joml_joml");
|
|
||||||
ppCircumventerList.add("steamwarmodsender");
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Set<String> neededMods = new HashSet<>();
|
|
||||||
static {
|
|
||||||
neededMods.add("java");
|
|
||||||
neededMods.add("minecraft");
|
|
||||||
neededMods.add("fabricloader");
|
|
||||||
neededMods.add("steamwarmodsender");
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
BungeeCord.getInstance().getScheduler().schedule(BungeeCore.get(), () -> {
|
|
||||||
synchronized (Storage.fabricExpectPluginMessage) {
|
|
||||||
for (Map.Entry<ProxiedPlayer, Long> entry : Storage.fabricExpectPluginMessage.entrySet()) {
|
|
||||||
if (!Storage.fabricCheckedPlayers.containsKey(entry.getKey())) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (System.currentTimeMillis() - entry.getValue() > TimeUnit.SECONDS.toMillis(20)) {
|
|
||||||
logMessage(SteamwarUser.get(entry.getKey().getUniqueId()), "Expected message not received", String.valueOf(entry.getValue()));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, 0, 1, TimeUnit.SECONDS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void onPluginMessageEvent(PluginMessageEvent e){
|
|
||||||
if(!e.getTag().equals("fabricmodsender:mods"))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!(e.getSender() instanceof ProxiedPlayer)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ProxiedPlayer player = (ProxiedPlayer) e.getSender();
|
|
||||||
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
|
||||||
byte[] data = e.getData();
|
|
||||||
|
|
||||||
if (!Storage.fabricCheckedPlayers.containsKey(player)) {
|
|
||||||
synchronized (Storage.fabricExpectPluginMessage) {
|
|
||||||
if (Storage.fabricExpectPluginMessage.containsKey(player)) {
|
|
||||||
logMessage(user, "Was not fabric checked but send message nonetheless", Arrays.toString(data));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Storage.fabricExpectPluginMessage.remove(player);
|
|
||||||
|
|
||||||
List<Mod> mods = new ArrayList<>();
|
|
||||||
|
|
||||||
Utils.VarInt varInt = Utils.readVarInt(data,0);
|
|
||||||
|
|
||||||
if(data.length != varInt.length + varInt.value) {
|
|
||||||
logMessage(user, "Invalid message length", Arrays.toString(data));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
data = Arrays.copyOfRange(data,varInt.length, data.length);
|
|
||||||
|
|
||||||
String dataString;
|
|
||||||
|
|
||||||
try{
|
|
||||||
dataString = new String(data, StandardCharsets.UTF_8);
|
|
||||||
}catch (UnsupportedCharsetException exception) {
|
|
||||||
logMessage(user, "Unsupported charset", Arrays.toString(data));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
JsonArray array;
|
|
||||||
|
|
||||||
try {
|
|
||||||
array = JsonParser.parseString(dataString).getAsJsonArray();
|
|
||||||
}catch (JsonSyntaxException exception) {
|
|
||||||
logMessage(user, "Invalid json", dataString);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(JsonElement mod : array) {
|
|
||||||
mods.add(Mod.getOrCreate(mod.getAsString(), Mod.Platform.FABRIC));
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean neededMods = neededModsContained(mods);
|
|
||||||
if(!neededMods) {
|
|
||||||
logMessage(user, "Needed mods are not contained", dataString);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(ppCircumventerCheck(mods))
|
|
||||||
logMessage(user, "PP circumventer suspicion", dataString);
|
|
||||||
|
|
||||||
if(!Utils.handleMods(player,mods))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (Storage.fabricCheckedPlayers.containsKey(player)) {
|
|
||||||
long current = Storage.fabricCheckedPlayers.get(player);
|
|
||||||
if (current != dataString.hashCode()) {
|
|
||||||
logMessage(user, "Mods changed during runtime", dataString);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Message.send("MODIFICATION_CHECK_SUCCESS", player);
|
|
||||||
Storage.fabricCheckedPlayers.put(player, dataString.hashCode());
|
|
||||||
}
|
|
||||||
Storage.fabricPlayers.remove(player);
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void onServerSwitchEvent(ServerSwitchEvent e) {
|
|
||||||
if (e.getFrom() == null) return;
|
|
||||||
synchronized (Storage.fabricExpectPluginMessage) {
|
|
||||||
Storage.fabricExpectPluginMessage.put(e.getPlayer(), System.currentTimeMillis());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean neededModsContained(List<Mod> mods) {
|
|
||||||
return mods.stream()
|
|
||||||
.map(Mod::getModName)
|
|
||||||
.filter(neededMods::contains)
|
|
||||||
.count() == neededMods.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void logMessage(SteamwarUser user, String reason, String data) {
|
|
||||||
SWException.log("FabricModSender " + user.getUserName() + ": " + reason, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean ppCircumventerCheck(List<Mod> mods) {
|
|
||||||
for(Mod mod : mods) {
|
|
||||||
String name = mod.getModName();
|
|
||||||
if(!name.startsWith("fabric") && !ppCircumventerList.contains(name))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,147 +0,0 @@
|
|||||||
/*
|
|
||||||
This file is a part of the SteamWar software.
|
|
||||||
|
|
||||||
Copyright (C) 2020 SteamWar.de-Serverteam
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU Affero General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU Affero General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Affero General Public License
|
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.bungeecore.listeners.mods;
|
|
||||||
|
|
||||||
import de.steamwar.bungeecore.BungeeCore;
|
|
||||||
import de.steamwar.bungeecore.listeners.BasicListener;
|
|
||||||
import de.steamwar.sql.Mod;
|
|
||||||
import io.netty.channel.ChannelPipeline;
|
|
||||||
import net.md_5.bungee.api.chat.TextComponent;
|
|
||||||
import net.md_5.bungee.api.connection.PendingConnection;
|
|
||||||
import net.md_5.bungee.api.event.LoginEvent;
|
|
||||||
import net.md_5.bungee.connection.InitialHandler;
|
|
||||||
import net.md_5.bungee.netty.ChannelWrapper;
|
|
||||||
import net.md_5.bungee.netty.HandlerBoss;
|
|
||||||
import net.md_5.bungee.netty.PacketHandler;
|
|
||||||
import net.md_5.bungee.protocol.packet.LoginPayloadRequest;
|
|
||||||
import net.md_5.bungee.protocol.packet.LoginPayloadResponse;
|
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.logging.Level;
|
|
||||||
|
|
||||||
public class Forge extends BasicListener {
|
|
||||||
|
|
||||||
private static final String WRAPPER = "fml:loginwrapper";
|
|
||||||
|
|
||||||
private static final Field initialHandlerCh;
|
|
||||||
static{
|
|
||||||
try {
|
|
||||||
initialHandlerCh = InitialHandler.class.getDeclaredField("ch");
|
|
||||||
} catch (NoSuchFieldException e) {
|
|
||||||
throw new SecurityException("Could not initialize Reflection", e);
|
|
||||||
}
|
|
||||||
initialHandlerCh.setAccessible(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void onServerConnected(LoginEvent event) {
|
|
||||||
if(event.getConnection().getVersion() < 341) { //1.13+
|
|
||||||
event.completeIntent(BungeeCore.get());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//fml:handshake without mods, channels and registries
|
|
||||||
//for more information see https://wiki.vg/Minecraft_Forge_Handshake#FML2_protocol_.281.13_-_Current.29
|
|
||||||
event.getConnection().unsafe().sendPacket(new LoginPayloadRequest(1, WRAPPER, new byte[]{13,102,109,108,58,104,97,110,100,115,104,97,107,101,4,1,0,0,0}));
|
|
||||||
|
|
||||||
InitialHandler handler = (InitialHandler) event.getConnection();
|
|
||||||
|
|
||||||
ChannelWrapper wrapper;
|
|
||||||
try{
|
|
||||||
wrapper = (ChannelWrapper) initialHandlerCh.get(handler);
|
|
||||||
} catch (IllegalAccessException e) {
|
|
||||||
BungeeCore.get().getLogger().log(Level.SEVERE, "Could not get Channel", e);
|
|
||||||
event.completeIntent(BungeeCore.get());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ChannelPipeline pipeline = wrapper.getHandle().pipeline();
|
|
||||||
if(pipeline != null) {
|
|
||||||
HandlerBoss handlerBoss = pipeline.get(HandlerBoss.class);
|
|
||||||
if(handlerBoss != null)
|
|
||||||
handlerBoss.setHandler(new CustomPacketHandler(event));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class CustomPacketHandler extends PacketHandler {
|
|
||||||
private final LoginEvent event;
|
|
||||||
|
|
||||||
public CustomPacketHandler(LoginEvent event) {
|
|
||||||
this.event = event;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "SteamWar Forge Handler";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handle(LoginPayloadResponse response){
|
|
||||||
byte[] data = response.getData();
|
|
||||||
if(data == null) {
|
|
||||||
event.completeIntent(BungeeCore.get());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//for more information see https://wiki.vg/Minecraft_Forge_Handshake#FML2_protocol_.281.13_-_Current.29
|
|
||||||
Utils.VarInt channelLength = Utils.readVarInt(data, 0);
|
|
||||||
int pos = channelLength.length;
|
|
||||||
if(!new String(data, pos, channelLength.value).equals("fml:handshake")) {
|
|
||||||
event.getConnection().disconnect(TextComponent.fromLegacyText("Invalid forge registry response (0x00)"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
pos += channelLength.value;
|
|
||||||
|
|
||||||
Utils.VarInt length = Utils.readVarInt(data, pos);
|
|
||||||
pos += length.length;
|
|
||||||
if(channelLength.length + channelLength.value + length.length + length.value != data.length) {
|
|
||||||
event.getConnection().disconnect(TextComponent.fromLegacyText("Invalid forge registry response (0x01)"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Utils.VarInt packetId = Utils.readVarInt(data, pos);
|
|
||||||
pos += packetId.length;
|
|
||||||
if(packetId.value != 2) {
|
|
||||||
event.getConnection().disconnect(TextComponent.fromLegacyText("Invalid forge registry response (0x02)"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Utils.VarInt modCount = Utils.readVarInt(data, pos);
|
|
||||||
pos += modCount.length;
|
|
||||||
|
|
||||||
List<Mod> mods = new ArrayList<>();
|
|
||||||
for(int i = 0; i < modCount.value; i++) {
|
|
||||||
Utils.VarInt nameLength = Utils.readVarInt(data, pos);
|
|
||||||
pos += nameLength.length;
|
|
||||||
|
|
||||||
mods.add(Mod.getOrCreate(new String(data, pos, nameLength.value), Mod.Platform.FORGE));
|
|
||||||
pos += nameLength.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
PendingConnection connection = event.getConnection();
|
|
||||||
if(!Utils.handleMods(connection.getUniqueId(), Locale.getDefault(), event::setCancelReason, mods)) {
|
|
||||||
event.setCancelled(true);
|
|
||||||
}
|
|
||||||
event.completeIntent(BungeeCore.get());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,113 +0,0 @@
|
|||||||
/*
|
|
||||||
This file is a part of the SteamWar software.
|
|
||||||
|
|
||||||
Copyright (C) 2022 SteamWar.de-Serverteam
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU Affero General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU Affero General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Affero General Public License
|
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.bungeecore.listeners.mods;
|
|
||||||
|
|
||||||
import de.steamwar.bungeecore.BungeeCore;
|
|
||||||
import de.steamwar.bungeecore.listeners.BasicListener;
|
|
||||||
import de.steamwar.sql.Mod;
|
|
||||||
import io.netty.buffer.ByteBuf;
|
|
||||||
import io.netty.buffer.UnpooledByteBufAllocator;
|
|
||||||
import net.md_5.bungee.api.ProxyServer;
|
|
||||||
import net.md_5.bungee.api.connection.Connection;
|
|
||||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
|
||||||
import net.md_5.bungee.api.event.PluginMessageEvent;
|
|
||||||
import net.md_5.bungee.api.event.PostLoginEvent;
|
|
||||||
import net.md_5.bungee.event.EventHandler;
|
|
||||||
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
public class Forge12 extends BasicListener {
|
|
||||||
private static final String FMLHS = "FML|HS";
|
|
||||||
private static final byte[] REGISTER;
|
|
||||||
private static final byte[] HELLO = new byte[]{0, 2, 0, 0, 0, 0};
|
|
||||||
|
|
||||||
private static final Set<UUID> unlocked = new HashSet<>();
|
|
||||||
|
|
||||||
static {
|
|
||||||
ByteBuf buf = UnpooledByteBufAllocator.DEFAULT.directBuffer(7);
|
|
||||||
buf.writeByte(6);
|
|
||||||
buf.writeCharSequence(FMLHS, StandardCharsets.UTF_8);
|
|
||||||
REGISTER = new byte[buf.readableBytes()];
|
|
||||||
buf.readBytes(REGISTER);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void onPostLogin(PostLoginEvent event) {
|
|
||||||
ProxiedPlayer player = event.getPlayer();
|
|
||||||
|
|
||||||
synchronized (unlocked) {
|
|
||||||
if(unlocked.contains(player.getUniqueId())){
|
|
||||||
unlocked.remove(player.getUniqueId());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(player.getPendingConnection().getVersion() <= 340) {
|
|
||||||
player.sendData("REGISTER", REGISTER); //1.12-
|
|
||||||
player.sendData(FMLHS, HELLO);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void onPluginMessageEvent(PluginMessageEvent e){
|
|
||||||
if(!e.getTag().equals(FMLHS))
|
|
||||||
return;
|
|
||||||
|
|
||||||
e.setCancelled(true);
|
|
||||||
byte[] data = e.getData();
|
|
||||||
|
|
||||||
Connection sender = e.getSender();
|
|
||||||
if(!(sender instanceof ProxiedPlayer))
|
|
||||||
return;
|
|
||||||
ProxiedPlayer p = (ProxiedPlayer) sender;
|
|
||||||
|
|
||||||
if (data[0] == 2) {
|
|
||||||
Utils.VarInt numMods = Utils.readVarInt(data, 1);
|
|
||||||
List<Mod> mods = new LinkedList<>();
|
|
||||||
|
|
||||||
int bytePos = 1 + numMods.length;
|
|
||||||
for (int i = 0; i < numMods.value; i++) {
|
|
||||||
byte[] name = Arrays.copyOfRange(data, bytePos + 1, bytePos + data[bytePos] + 1);
|
|
||||||
bytePos += 1 + data[bytePos];
|
|
||||||
//Version information is unused
|
|
||||||
bytePos += 1 + data[bytePos];
|
|
||||||
|
|
||||||
mods.add(Mod.getOrCreate(new String(name), Mod.Platform.FORGE));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Utils.handleMods(p, mods)) {
|
|
||||||
synchronized (unlocked) {
|
|
||||||
unlocked.add(p.getUniqueId());
|
|
||||||
}
|
|
||||||
ProxyServer.getInstance().getScheduler().schedule(BungeeCore.get(),
|
|
||||||
() -> p.disconnect(BungeeCore.stringToText("§7Deine installierten Mods wurden überprüft\n§aDu kannst nun §eSteam§8War §abetreten")),
|
|
||||||
2, TimeUnit.SECONDS);
|
|
||||||
ProxyServer.getInstance().getScheduler().schedule(BungeeCore.get(), () -> {
|
|
||||||
synchronized (unlocked) {
|
|
||||||
unlocked.remove(p.getUniqueId());
|
|
||||||
}
|
|
||||||
}, 30, TimeUnit.SECONDS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,184 +0,0 @@
|
|||||||
/*
|
|
||||||
This file is a part of the SteamWar software.
|
|
||||||
|
|
||||||
Copyright (C) 2020 SteamWar.de-Serverteam
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU Affero General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU Affero General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Affero General Public License
|
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.bungeecore.listeners.mods;
|
|
||||||
|
|
||||||
import com.google.gson.JsonObject;
|
|
||||||
import com.google.gson.stream.JsonReader;
|
|
||||||
import de.steamwar.bungeecore.BungeeCore;
|
|
||||||
import de.steamwar.bungeecore.listeners.BasicListener;
|
|
||||||
import de.steamwar.sql.Mod;
|
|
||||||
import net.md_5.bungee.api.ProxyServer;
|
|
||||||
import net.md_5.bungee.api.connection.Connection;
|
|
||||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
|
||||||
import net.md_5.bungee.api.event.PluginMessageEvent;
|
|
||||||
import net.md_5.bungee.event.EventHandler;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.StringReader;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public class LabyMod extends BasicListener {
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void onPluginMessageEvent(PluginMessageEvent event){
|
|
||||||
if(!event.getTag().equals("LMC"))
|
|
||||||
return;
|
|
||||||
|
|
||||||
Connection sender = event.getSender();
|
|
||||||
if(!(sender instanceof ProxiedPlayer))
|
|
||||||
return;
|
|
||||||
|
|
||||||
event.setCancelled(true);
|
|
||||||
updateGameInfo((ProxiedPlayer) sender);
|
|
||||||
byte[] data = event.getData();
|
|
||||||
|
|
||||||
ProxyServer.getInstance().getScheduler().runAsync(BungeeCore.get(), () -> runAsync(data, (ProxiedPlayer) sender));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void runAsync(byte[] data, ProxiedPlayer player) {
|
|
||||||
VarString purpose = readString(data, 0);
|
|
||||||
if(!"INFO".equals(purpose.value))
|
|
||||||
return;
|
|
||||||
|
|
||||||
VarString value = readString(data, purpose.length);
|
|
||||||
List<Mod> mods = new LinkedList<>();
|
|
||||||
|
|
||||||
try{
|
|
||||||
InfoPacket info = new InfoPacket(value.value);
|
|
||||||
for(InfoPacket.Addon addon : info.addons) {
|
|
||||||
mods.add(Mod.getOrCreate(addon.name, Mod.Platform.LABYMOD));
|
|
||||||
}
|
|
||||||
}catch(IOException e){
|
|
||||||
BungeeCore.log("Could not read JSON", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
Utils.handleMods(player, mods);
|
|
||||||
}
|
|
||||||
|
|
||||||
private VarString readString(byte[] array, int startPos){
|
|
||||||
Utils.VarInt varInt = Utils.readVarInt(array, startPos);
|
|
||||||
startPos += varInt.length;
|
|
||||||
return new VarString(varInt.value+varInt.length, new String(Arrays.copyOfRange(array, startPos, startPos + varInt.value), StandardCharsets.UTF_8));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateGameInfo(ProxiedPlayer proxiedPlayer) {
|
|
||||||
JsonObject obj = new JsonObject();
|
|
||||||
obj.addProperty("hasGame", true);
|
|
||||||
obj.addProperty("game_mode", "steamwar.de");
|
|
||||||
obj.addProperty("game_startTime", 0);
|
|
||||||
obj.addProperty("game_endTime", 0);
|
|
||||||
String output = "{ \"hasGame\" : \"true\", \"game_mode\" : \"steamwar.de\", \"game_startTime\" : \"0\", \"game_endTime\" : \"0\" }";
|
|
||||||
|
|
||||||
proxiedPlayer.sendData("LMC", output.getBytes());
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class VarString{
|
|
||||||
private final int length;
|
|
||||||
private final String value;
|
|
||||||
|
|
||||||
private VarString(int length, String value) {
|
|
||||||
this.length = length;
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class InfoPacket{
|
|
||||||
String version = null;
|
|
||||||
Feature ccp = null;
|
|
||||||
Feature shadow = null;
|
|
||||||
List<Addon> addons = new LinkedList<>();
|
|
||||||
|
|
||||||
InfoPacket(String input) throws IOException {
|
|
||||||
JsonReader reader = new JsonReader(new StringReader(input));
|
|
||||||
reader.beginObject();
|
|
||||||
while(reader.hasNext()){
|
|
||||||
String name = reader.nextName();
|
|
||||||
switch(name){
|
|
||||||
case "version":
|
|
||||||
version = reader.nextString();
|
|
||||||
break;
|
|
||||||
case "ccp":
|
|
||||||
ccp = new Feature(reader);
|
|
||||||
break;
|
|
||||||
case "shadow":
|
|
||||||
shadow = new Feature(reader);
|
|
||||||
break;
|
|
||||||
case "addons":
|
|
||||||
reader.beginArray();
|
|
||||||
while(reader.hasNext()){
|
|
||||||
addons.add(new Addon(reader));
|
|
||||||
}
|
|
||||||
reader.endArray();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
reader.skipValue();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
reader.endObject();
|
|
||||||
reader.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
static class Addon{
|
|
||||||
UUID uuid = null;
|
|
||||||
String name = null;
|
|
||||||
|
|
||||||
Addon(JsonReader reader) throws IOException {
|
|
||||||
reader.beginObject();
|
|
||||||
while(reader.hasNext()){
|
|
||||||
String n = reader.nextName();
|
|
||||||
if(n.equals("uuid"))
|
|
||||||
try{
|
|
||||||
uuid = UUID.fromString(reader.nextString());
|
|
||||||
}catch(IllegalArgumentException ignored){
|
|
||||||
//ignored
|
|
||||||
}
|
|
||||||
else if(n.equals("name"))
|
|
||||||
name = reader.nextString();
|
|
||||||
else
|
|
||||||
reader.skipValue();
|
|
||||||
}
|
|
||||||
reader.endObject();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static class Feature{
|
|
||||||
boolean enabled;
|
|
||||||
int version;
|
|
||||||
|
|
||||||
Feature(JsonReader reader) throws IOException {
|
|
||||||
reader.beginObject();
|
|
||||||
while(reader.hasNext()){
|
|
||||||
String name = reader.nextName();
|
|
||||||
if(name.equals("version"))
|
|
||||||
version = reader.nextInt();
|
|
||||||
else if(name.equals("enabled"))
|
|
||||||
enabled = reader.nextBoolean();
|
|
||||||
else
|
|
||||||
reader.skipValue();
|
|
||||||
}
|
|
||||||
reader.endObject();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,87 +0,0 @@
|
|||||||
/*
|
|
||||||
This file is a part of the SteamWar software.
|
|
||||||
|
|
||||||
Copyright (C) 2020 SteamWar.de-Serverteam
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU Affero General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU Affero General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Affero General Public License
|
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.bungeecore.listeners.mods;
|
|
||||||
|
|
||||||
import de.steamwar.bungeecore.*;
|
|
||||||
import de.steamwar.bungeecore.listeners.BasicListener;
|
|
||||||
import net.md_5.bungee.api.connection.Connection;
|
|
||||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
|
||||||
import net.md_5.bungee.api.event.PlayerDisconnectEvent;
|
|
||||||
import net.md_5.bungee.api.event.PluginMessageEvent;
|
|
||||||
import net.md_5.bungee.api.event.ServerSwitchEvent;
|
|
||||||
import net.md_5.bungee.event.EventHandler;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
public class ModLoaderBlocker extends BasicListener {
|
|
||||||
|
|
||||||
private static final Set<String> BLOCKED_SERVER = new HashSet<>();
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void onPluginMessageEvent(PluginMessageEvent e){
|
|
||||||
Connection sender = e.getSender();
|
|
||||||
if(!(sender instanceof ProxiedPlayer))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(!e.getTag().equals("minecraft:brand"))
|
|
||||||
return;
|
|
||||||
|
|
||||||
String brand = new String(e.getData());
|
|
||||||
if(brand.contains("fabric") || brand.contains("quilt")){
|
|
||||||
ProxiedPlayer p = (ProxiedPlayer) sender;
|
|
||||||
if (!Storage.fabricCheckedPlayers.containsKey(p) && !Storage.fabricPlayers.contains(p)) {
|
|
||||||
Storage.fabricPlayers.add(p);
|
|
||||||
Message.send("MODLOADER_INSTALLED_FABRIC", p, "Fabric");
|
|
||||||
}
|
|
||||||
}else if(brand.contains("LiteLoader")) {
|
|
||||||
ProxiedPlayer p = (ProxiedPlayer) sender;
|
|
||||||
if (!Storage.fabricPlayers.contains(p)) {
|
|
||||||
Storage.fabricPlayers.add(p);
|
|
||||||
Message.send("MODLOADER_INSTALLED", p, "LiteLoader");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void onDisconnect(PlayerDisconnectEvent e){
|
|
||||||
Fabric.remove(e.getPlayer());
|
|
||||||
Storage.fabricPlayers.remove(e.getPlayer());
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void onServerSwitch(ServerSwitchEvent event) {
|
|
||||||
if(((Subserver.getSubserver(event.getPlayer()) != null
|
|
||||||
&& Subserver.getSubserver(event.getPlayer()).getType() == Servertype.ARENA)
|
|
||||||
|| BLOCKED_SERVER.contains(event.getPlayer().getServer().getInfo().getName()))
|
|
||||||
&& isFabric(event.getPlayer())) {
|
|
||||||
event.getPlayer().connect(BungeeCore.get().getProxy().getServerInfo(BungeeCore.LOBBY_SERVER));
|
|
||||||
Message.send("MODLOADER_DENIED", event.getPlayer());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isFabric(ProxiedPlayer player) {
|
|
||||||
return Storage.fabricPlayers.contains(player);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void addServer(String server) {
|
|
||||||
BLOCKED_SERVER.add(server);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,117 +0,0 @@
|
|||||||
/*
|
|
||||||
This file is a part of the SteamWar software.
|
|
||||||
|
|
||||||
Copyright (C) 2020 SteamWar.de-Serverteam
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU Affero General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU Affero General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Affero General Public License
|
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.bungeecore.listeners.mods;
|
|
||||||
|
|
||||||
import de.steamwar.bungeecore.BungeeCore;
|
|
||||||
import de.steamwar.bungeecore.Message;
|
|
||||||
import de.steamwar.bungeecore.commands.PunishmentCommand;
|
|
||||||
import de.steamwar.sql.SteamwarUser;
|
|
||||||
import de.steamwar.messages.ChatSender;
|
|
||||||
import de.steamwar.sql.Mod;
|
|
||||||
import de.steamwar.sql.Mod.ModType;
|
|
||||||
import net.md_5.bungee.api.chat.BaseComponent;
|
|
||||||
import net.md_5.bungee.api.chat.TextComponent;
|
|
||||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
|
||||||
|
|
||||||
import java.sql.Timestamp;
|
|
||||||
import java.time.Instant;
|
|
||||||
import java.time.temporal.ChronoUnit;
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
import java.util.logging.Level;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
public class Utils {
|
|
||||||
|
|
||||||
public static final Map<UUID,List<Mod>> playerModMap = new HashMap<>();
|
|
||||||
|
|
||||||
private Utils(){}
|
|
||||||
|
|
||||||
static VarInt readVarInt(byte[] array, int startPos) {
|
|
||||||
int numRead = 0;
|
|
||||||
int result = 0;
|
|
||||||
byte read;
|
|
||||||
do {
|
|
||||||
read = array[startPos + numRead];
|
|
||||||
int value = (read & 0b01111111);
|
|
||||||
result |= (value << (7 * numRead));
|
|
||||||
|
|
||||||
numRead++;
|
|
||||||
if (numRead > 5) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} while ((read & 0b10000000) != 0);
|
|
||||||
|
|
||||||
return new VarInt(numRead, result);
|
|
||||||
}
|
|
||||||
|
|
||||||
static boolean handleMods(ProxiedPlayer player, List<Mod> mods) {
|
|
||||||
return handleMods(player.getUniqueId(), ChatSender.of(player).getLocale(), player::disconnect, mods);
|
|
||||||
}
|
|
||||||
|
|
||||||
static boolean handleMods(UUID uuid, Locale locale, Consumer<BaseComponent[]> disconnect, List<Mod> mods){
|
|
||||||
SteamwarUser user = SteamwarUser.get(uuid);
|
|
||||||
boolean privileged = user.getUserGroup().isPrivilegedMods();
|
|
||||||
playerModMap.put(uuid,new ArrayList<>(mods));
|
|
||||||
|
|
||||||
ModType max = ModType.YELLOW;
|
|
||||||
Iterator<Mod> it = mods.iterator();
|
|
||||||
while(it.hasNext()){
|
|
||||||
Mod mod = it.next();
|
|
||||||
if(mod.getModType() == ModType.UNKLASSIFIED || mod.getModType() == ModType.GREEN || (mod.getModType() == ModType.YOUTUBER_ONLY && privileged))
|
|
||||||
it.remove();
|
|
||||||
else if(mod.getModType() == ModType.RED)
|
|
||||||
max = ModType.RED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(mods.isEmpty()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ModType finalMax = max;
|
|
||||||
String modList = mods.stream().filter(mod -> finalMax == ModType.YELLOW || mod.getModType() == ModType.RED).map(Mod::getModName).collect(Collectors.joining("\n"));
|
|
||||||
String message;
|
|
||||||
|
|
||||||
if(mods.size() == 1) {
|
|
||||||
message = Message.parse(max == ModType.RED ? "MOD_RED_SING" : "MOD_YELLOW_SING", locale, modList);
|
|
||||||
} else {
|
|
||||||
message = Message.parse(max == ModType.RED ? "MOD_RED_PLUR" : "MOD_YELLOW_PLUR", locale, modList);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(max == ModType.RED) {
|
|
||||||
PunishmentCommand.ban(user, Timestamp.from(Instant.now().plus(7, ChronoUnit.DAYS)), message, SteamwarUser.get(-1), false);
|
|
||||||
BungeeCore.log(Level.SEVERE, user.getUserName() + " " + user.getId() + " wurde automatisch wegen der Mods " + modList + " gebannt.");
|
|
||||||
}
|
|
||||||
|
|
||||||
disconnect.accept(TextComponent.fromLegacyText(message));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static class VarInt{
|
|
||||||
final int length;
|
|
||||||
final int value;
|
|
||||||
|
|
||||||
VarInt(int length, int value){
|
|
||||||
this.length = length;
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,33 +0,0 @@
|
|||||||
package de.steamwar.bungeecore.listeners.mods;
|
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
|
||||||
import com.google.common.collect.Sets;
|
|
||||||
import de.steamwar.bungeecore.listeners.BasicListener;
|
|
||||||
import de.steamwar.sql.Mod;
|
|
||||||
import net.md_5.bungee.api.connection.Connection;
|
|
||||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
|
||||||
import net.md_5.bungee.api.event.PluginMessageEvent;
|
|
||||||
import net.md_5.bungee.event.EventHandler;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
public class WorldDownloader extends BasicListener {
|
|
||||||
|
|
||||||
private static final Set<String> wdlTags = Collections.unmodifiableSet(
|
|
||||||
Sets.newHashSet("WDL|INIT", "wdl:init", "WDL|REQUEST", "wdl:request")
|
|
||||||
);
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void onPluginMessageEvent(PluginMessageEvent event){
|
|
||||||
if(!wdlTags.contains(event.getTag()))
|
|
||||||
return;
|
|
||||||
|
|
||||||
Connection sender = event.getSender();
|
|
||||||
if(!(sender instanceof ProxiedPlayer))
|
|
||||||
return;
|
|
||||||
|
|
||||||
event.setCancelled(true);
|
|
||||||
Utils.handleMods((ProxiedPlayer) sender, Lists.newArrayList(Mod.getOrCreate("wdl", Mod.Platform.FORGE)));
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
/*
|
|
||||||
This file is a part of the SteamWar software.
|
|
||||||
|
|
||||||
Copyright (C) 2022 SteamWar.de-Serverteam
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU Affero General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU Affero General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Affero General Public License
|
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.bungeecore.listeners.ping;
|
|
||||||
|
|
||||||
import de.steamwar.bungeecore.listeners.BasicListener;
|
|
||||||
import net.md_5.bungee.api.event.ProxyPingEvent;
|
|
||||||
import net.md_5.bungee.event.EventHandler;
|
|
||||||
|
|
||||||
public class PingListener extends BasicListener {
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void onPing(ProxyPingEvent event) {
|
|
||||||
event.setResponse(new SteamWarServerPing(event.getResponse(), event.getConnection().getVersion()));
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,90 +0,0 @@
|
|||||||
/*
|
|
||||||
This file is a part of the SteamWar software.
|
|
||||||
|
|
||||||
Copyright (C) 2022 SteamWar.de-Serverteam
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU Affero General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU Affero General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Affero General Public License
|
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.bungeecore.listeners.ping;
|
|
||||||
|
|
||||||
import net.md_5.bungee.api.ServerPing;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class SteamWarServerPing extends ServerPing {
|
|
||||||
|
|
||||||
private final boolean preventsChatReports = true;
|
|
||||||
private final ForgeData forgeData;
|
|
||||||
|
|
||||||
public SteamWarServerPing(ServerPing existing, int version) {
|
|
||||||
super(existing.getVersion(), existing.getPlayers(), existing.getDescriptionComponent(), existing.getFaviconObject());
|
|
||||||
forgeData = new ForgeData(version);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class ForgeData {
|
|
||||||
private final List<ForgeChannel> channels = new ArrayList<>();
|
|
||||||
private final List<ForgeMod> mods = new ArrayList<>();
|
|
||||||
private final int fmlNetworkVersion = 2;
|
|
||||||
|
|
||||||
public ForgeData(int versionNumber) {
|
|
||||||
channels.add(new ForgeChannel("minecraft:unregister"));
|
|
||||||
channels.add(new ForgeChannel("minecraft:register"));
|
|
||||||
channels.add(new ForgeChannel("fml:handshake"));
|
|
||||||
mods.add(new ForgeMod("minecraft", ProtocolVersion.getVersion(versionNumber)));
|
|
||||||
mods.add(new ForgeMod("forge", "ANY"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public final static class ProtocolVersion {
|
|
||||||
|
|
||||||
private static final HashMap<Integer, String> versions;
|
|
||||||
|
|
||||||
static {
|
|
||||||
versions = new HashMap();
|
|
||||||
versions.put(757, "1.18");
|
|
||||||
versions.put(756, "1.17.1");
|
|
||||||
versions.put(754, "1.16.5");
|
|
||||||
versions.put(578, "1.15.2");
|
|
||||||
versions.put(498, "1.14.1");
|
|
||||||
versions.put(393, "1.13");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getVersion(int version) {
|
|
||||||
return versions.get(version);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class ForgeChannel {
|
|
||||||
private final String res;
|
|
||||||
private final String version = "FML2";
|
|
||||||
private final boolean required = true;
|
|
||||||
|
|
||||||
private ForgeChannel(String res) {
|
|
||||||
this.res = res;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class ForgeMod {
|
|
||||||
private final String modId;
|
|
||||||
private final String modmarker;
|
|
||||||
|
|
||||||
private ForgeMod(String modId, String modmarker) {
|
|
||||||
this.modId = modId;
|
|
||||||
this.modmarker = modmarker;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
59
src/de/steamwar/bungeecore/mods/Badlion.java
Normale Datei
59
src/de/steamwar/bungeecore/mods/Badlion.java
Normale Datei
@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of the SteamWar software.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2024 SteamWar.de-Serverteam
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.bungeecore.mods;
|
||||||
|
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import com.velocitypowered.api.event.Subscribe;
|
||||||
|
import com.velocitypowered.api.event.connection.PostLoginEvent;
|
||||||
|
import com.velocitypowered.api.proxy.messages.MinecraftChannelIdentifier;
|
||||||
|
import de.steamwar.bungeecore.util.annotations.Create;
|
||||||
|
|
||||||
|
@Create
|
||||||
|
public class Badlion {
|
||||||
|
// https://github.com/BadlionClient/BadlionClientModAPI
|
||||||
|
|
||||||
|
private final byte[] packet;
|
||||||
|
|
||||||
|
public Badlion() { //TODO check if working or (json) modsDisallowed wrapper necessary
|
||||||
|
JsonObject disabled = new JsonObject();
|
||||||
|
disabled.addProperty("disabled", true);
|
||||||
|
|
||||||
|
JsonObject json = new JsonObject();
|
||||||
|
json.add("Clear Glass", disabled);
|
||||||
|
json.add("ClearWater", disabled);
|
||||||
|
json.add("FOV Changer", disabled);
|
||||||
|
json.add("Hitboxes", disabled);
|
||||||
|
json.add("LevelHead", disabled);
|
||||||
|
json.add("MiniMap", disabled);
|
||||||
|
json.add("MLG Cobweb", disabled);
|
||||||
|
json.add("Replay", disabled); //TODO check if ReplayMod restrictions work
|
||||||
|
json.add("Schematica", disabled);
|
||||||
|
json.add("ToggleSneak", disabled);
|
||||||
|
json.add("ToggleSprint", disabled);
|
||||||
|
json.add("TNT Time", disabled);
|
||||||
|
|
||||||
|
packet = json.toString().getBytes();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onPostLogin(PostLoginEvent event) {
|
||||||
|
event.getPlayer().sendPluginMessage(MinecraftChannelIdentifier.from("badlion:mods"), packet);
|
||||||
|
}
|
||||||
|
}
|
54
src/de/steamwar/bungeecore/mods/Controlify.java
Normale Datei
54
src/de/steamwar/bungeecore/mods/Controlify.java
Normale Datei
@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of the SteamWar software.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2024 SteamWar.de-Serverteam
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.bungeecore.mods;
|
||||||
|
|
||||||
|
import com.velocitypowered.api.proxy.Player;
|
||||||
|
import com.velocitypowered.api.proxy.messages.ChannelIdentifier;
|
||||||
|
import com.velocitypowered.api.proxy.messages.MinecraftChannelIdentifier;
|
||||||
|
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
||||||
|
import de.steamwar.bungeecore.listeners.PluginMessage;
|
||||||
|
|
||||||
|
public class Controlify {
|
||||||
|
//https://modrinth.com/mod/controlify
|
||||||
|
//https://github.com/isXander/Controlify/blob/1.20.x/dev/src/main/java/dev/isxander/controlify/server/ServerPolicyPacket.java
|
||||||
|
//https://github.com/isXander/Controlify/blob/1.20.x/dev/src/main/java/dev/isxander/controlify/server/ServerPolicies.java
|
||||||
|
|
||||||
|
public static final ChannelIdentifier CHANNEL = MinecraftChannelIdentifier.from("controlify:server_policy");
|
||||||
|
|
||||||
|
private final byte[][] packets;
|
||||||
|
public Controlify() {
|
||||||
|
packets = new byte[][] {
|
||||||
|
restrict("reachAround"),
|
||||||
|
restrict("disableFlyDrifting")
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] restrict(String name) {
|
||||||
|
return PluginMessage.genBufPacket(buf -> {
|
||||||
|
ProtocolUtils.writeString(buf, name);
|
||||||
|
buf.writeBoolean(false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onRegister(Player player) {
|
||||||
|
for(byte[] packet : packets)
|
||||||
|
player.sendPluginMessage(CHANNEL, packet);
|
||||||
|
}
|
||||||
|
}
|
136
src/de/steamwar/bungeecore/mods/FML.java
Normale Datei
136
src/de/steamwar/bungeecore/mods/FML.java
Normale Datei
@ -0,0 +1,136 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of the SteamWar software.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2024 SteamWar.de-Serverteam
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.bungeecore.mods;
|
||||||
|
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
import com.velocitypowered.api.event.Subscribe;
|
||||||
|
import com.velocitypowered.api.event.connection.ConnectionHandshakeEvent;
|
||||||
|
import com.velocitypowered.api.event.connection.PluginMessageEvent;
|
||||||
|
import com.velocitypowered.api.event.connection.PostLoginEvent;
|
||||||
|
import com.velocitypowered.api.proxy.LoginPhaseConnection;
|
||||||
|
import com.velocitypowered.api.proxy.Player;
|
||||||
|
import com.velocitypowered.api.proxy.ProxyServer;
|
||||||
|
import com.velocitypowered.api.proxy.messages.ChannelIdentifier;
|
||||||
|
import com.velocitypowered.api.proxy.messages.MinecraftChannelIdentifier;
|
||||||
|
import com.velocitypowered.proxy.connection.ConnectionType;
|
||||||
|
import com.velocitypowered.proxy.connection.ConnectionTypes;
|
||||||
|
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
|
||||||
|
import com.velocitypowered.proxy.connection.client.InitialInboundConnection;
|
||||||
|
import com.velocitypowered.proxy.connection.client.LoginInboundConnection;
|
||||||
|
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
||||||
|
import com.velocitypowered.proxy.protocol.packet.HandshakePacket;
|
||||||
|
import de.steamwar.bungeecore.VelocityCore;
|
||||||
|
import de.steamwar.bungeecore.util.annotations.Create;
|
||||||
|
import de.steamwar.sql.Mod;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.buffer.Unpooled;
|
||||||
|
import lombok.SneakyThrows;
|
||||||
|
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
@Create
|
||||||
|
public class FML {
|
||||||
|
// https://wiki.vg/Minecraft_Forge_Handshake#FML_protocol_.281.7_-_1.12.29
|
||||||
|
|
||||||
|
private static final Field delegateField;
|
||||||
|
private static final Field handshakeField;
|
||||||
|
|
||||||
|
static {
|
||||||
|
try {
|
||||||
|
delegateField = LoginInboundConnection.class.getDeclaredField("delegate");
|
||||||
|
handshakeField = InitialInboundConnection.class.getDeclaredField("handshake");
|
||||||
|
} catch (NoSuchFieldException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final ModUtils utils;
|
||||||
|
private final ProxyServer proxyServer;
|
||||||
|
private final VelocityCore core;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public FML(ModUtils utils, ProxyServer proxyServer, VelocityCore core) {
|
||||||
|
this.utils = utils;
|
||||||
|
this.proxyServer = proxyServer;
|
||||||
|
this.core = core;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SneakyThrows
|
||||||
|
public static boolean isFML(LoginPhaseConnection connection, String type) {
|
||||||
|
return handshakeField.get(delegateField.get(connection)) instanceof HandshakePacket packet && packet.getServerAddress().endsWith("\0" + type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final ChannelIdentifier CHANNEL = MinecraftChannelIdentifier.from("FML|HS");
|
||||||
|
private final byte[] helloPacket = new byte[]{
|
||||||
|
/* Packet type: ServerHello */ 0,
|
||||||
|
/* FML protocol version */ 2,
|
||||||
|
/* Override dimension (int) */ 0, 0, 0, 0
|
||||||
|
};
|
||||||
|
|
||||||
|
private static final Set<UUID> unlocked = new HashSet<>();
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onPostLogin(PostLoginEvent event) {
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
|
||||||
|
synchronized (unlocked) {
|
||||||
|
if(unlocked.contains(player.getUniqueId())){
|
||||||
|
unlocked.remove(player.getUniqueId());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(((ConnectedPlayer) event.getPlayer()).getConnection().getType() == ConnectionTypes.LEGACY_FORGE) {
|
||||||
|
player.sendPluginMessage(CHANNEL, helloPacket);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handlePluginMessage(PluginMessageEvent event) {
|
||||||
|
Player p = (Player) event.getSource();
|
||||||
|
ByteBuf buf = Unpooled.wrappedBuffer(event.getData());
|
||||||
|
|
||||||
|
if (buf.readByte() == /* ModList */ 2) {
|
||||||
|
int numMods = ProtocolUtils.readVarInt(buf);
|
||||||
|
|
||||||
|
List<Mod> mods = new ArrayList<>();
|
||||||
|
for(int i = 0; i < numMods; i++) {
|
||||||
|
String name = ProtocolUtils.readString(buf);
|
||||||
|
ProtocolUtils.readString(buf); // version
|
||||||
|
|
||||||
|
mods.add(Mod.getOrCreate(name, Mod.Platform.FORGE));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (utils.handleMods(p, mods)) {
|
||||||
|
synchronized (unlocked) {
|
||||||
|
unlocked.add(p.getUniqueId());
|
||||||
|
}
|
||||||
|
p.disconnect(LegacyComponentSerializer.legacySection().deserialize("§7Deine installierten Mods wurden überprüft\n§aDu kannst nun §eSteam§8War §abetreten"));
|
||||||
|
proxyServer.getScheduler().buildTask(core, () -> {
|
||||||
|
synchronized (unlocked) {
|
||||||
|
unlocked.remove(p.getUniqueId());
|
||||||
|
}
|
||||||
|
}).delay(30, TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
183
src/de/steamwar/bungeecore/mods/FML2.java
Normale Datei
183
src/de/steamwar/bungeecore/mods/FML2.java
Normale Datei
@ -0,0 +1,183 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of the SteamWar software.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2024 SteamWar.de-Serverteam
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.bungeecore.mods;
|
||||||
|
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
import com.velocitypowered.api.event.Subscribe;
|
||||||
|
import com.velocitypowered.api.event.connection.PreLoginEvent;
|
||||||
|
import com.velocitypowered.api.proxy.LoginPhaseConnection;
|
||||||
|
import com.velocitypowered.api.proxy.messages.MinecraftChannelIdentifier;
|
||||||
|
import com.velocitypowered.proxy.connection.client.LoginInboundConnection;
|
||||||
|
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
||||||
|
import com.velocitypowered.proxy.protocol.StateRegistry;
|
||||||
|
import de.steamwar.bungeecore.VelocityCore;
|
||||||
|
import de.steamwar.bungeecore.listeners.IPSanitizer;
|
||||||
|
import de.steamwar.bungeecore.listeners.PluginMessage;
|
||||||
|
import de.steamwar.bungeecore.util.annotations.Create;
|
||||||
|
import de.steamwar.sql.Mod;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.buffer.Unpooled;
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
@Create
|
||||||
|
public class FML2 {
|
||||||
|
|
||||||
|
protected final ModUtils modUtils;
|
||||||
|
// FML2: https://wiki.vg/Minecraft_Forge_Handshake#FML2_protocol_.281.13_-_Current.29
|
||||||
|
// FML3: https://github.com/adde0109/Ambassador/tree/non-api/src/main/java/org/adde0109/ambassador/forge
|
||||||
|
|
||||||
|
// FORGE: https://github.com/MinecraftForge/MinecraftForge/blob/1.20.x/src/main/java/net/minecraftforge/network/NetworkInitialization.java
|
||||||
|
// FORGE: https://github.com/MinecraftForge/MinecraftForge/blob/1.20.x/src/main/java/net/minecraftforge/network/ForgePacketHandler.java
|
||||||
|
// FORGE: https://github.com/MinecraftForge/MinecraftForge/blob/1.20.x/src/main/java/net/minecraftforge/network/packets/ModVersions.java
|
||||||
|
|
||||||
|
private final byte[] fml2ModListPacket;
|
||||||
|
private final byte[] fml3ModListPacket;
|
||||||
|
private final byte[] forgeModListPacket;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public FML2(ModUtils modUtils) {
|
||||||
|
this.modUtils = modUtils;
|
||||||
|
fml2ModListPacket = generateModListPacket(false);
|
||||||
|
fml3ModListPacket = generateModListPacket(true);
|
||||||
|
forgeModListPacket = PluginMessage.genBufPacket(buf -> {
|
||||||
|
buf.writeByte(0); // Login wrapper packet
|
||||||
|
ProtocolUtils.writeString(buf, "forge:handshake");
|
||||||
|
|
||||||
|
ByteBuf packet = Unpooled.buffer();
|
||||||
|
packet.writeByte(1); // Mod list packet
|
||||||
|
ProtocolUtils.writeVarInt(packet, 0); // Mod amount
|
||||||
|
|
||||||
|
ProtocolUtils.writeVarInt(buf, packet.readableBytes());
|
||||||
|
buf.writeBytes(packet);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onLogin(PreLoginEvent event) {
|
||||||
|
LoginInboundConnection connection = (LoginInboundConnection) event.getConnection();
|
||||||
|
|
||||||
|
boolean fml2 = FML.isFML(connection, "FML2\0");
|
||||||
|
boolean fml3 = FML.isFML(connection, "FML3\0");
|
||||||
|
boolean forge = FML.isFML(connection, "FORGE");
|
||||||
|
if(!fml2 && !fml3 && !forge)
|
||||||
|
return;
|
||||||
|
|
||||||
|
FML2LoginHandler handler = new FML2LoginHandler(connection, event.getUniqueId(), forge);
|
||||||
|
|
||||||
|
if(forge) {
|
||||||
|
((LoginInboundConnection) event.getConnection()).sendLoginPluginMessage(MinecraftChannelIdentifier.from("forge:login"), forgeModListPacket, handler);
|
||||||
|
} else {
|
||||||
|
((LoginInboundConnection) event.getConnection()).sendLoginPluginMessage(MinecraftChannelIdentifier.from("fml:loginwrapper"), fml3 ? fml3ModListPacket : fml2ModListPacket, handler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] generateModListPacket(boolean fml3) {
|
||||||
|
return PluginMessage.genBufPacket(buf -> {
|
||||||
|
ProtocolUtils.writeString(buf, "fml:handshake");
|
||||||
|
|
||||||
|
ByteBuf packet = Unpooled.buffer();
|
||||||
|
packet.writeByte(1); // Mod list packet
|
||||||
|
ProtocolUtils.writeVarInt(packet, 0); // Mod amount
|
||||||
|
|
||||||
|
if(fml3) {
|
||||||
|
ProtocolUtils.writeVarInt(packet,1); // Channel amount
|
||||||
|
ProtocolUtils.writeString(packet, "forge:tier_sorting");
|
||||||
|
ProtocolUtils.writeString(packet, "1.0");
|
||||||
|
} else {
|
||||||
|
ProtocolUtils.writeVarInt(packet, 0); // Channel amount
|
||||||
|
}
|
||||||
|
|
||||||
|
ProtocolUtils.writeVarInt(packet, 0); // Registries amount
|
||||||
|
if(fml3)
|
||||||
|
ProtocolUtils.writeVarInt(packet, 0); // DataPacks amount
|
||||||
|
|
||||||
|
ProtocolUtils.writeVarInt(buf, packet.readableBytes());
|
||||||
|
buf.writeBytes(packet);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private class FML2LoginHandler implements LoginPhaseConnection.MessageConsumer {
|
||||||
|
private final LoginInboundConnection connection;
|
||||||
|
private final UUID uuid;
|
||||||
|
private final boolean forge;
|
||||||
|
|
||||||
|
private FML2LoginHandler(LoginInboundConnection connection, UUID uuid, boolean forge) {
|
||||||
|
this.connection = connection;
|
||||||
|
this.uuid = uuid;
|
||||||
|
this.forge = forge;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "SteamWar Forge Handler";
|
||||||
|
}
|
||||||
|
|
||||||
|
private void abort(byte[] response, String error) {
|
||||||
|
|
||||||
|
VelocityCore.get().getLogger().log(Level.SEVERE, () -> error + "\n" + Base64.getEncoder().encodeToString(response));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onMessageResponse(byte @Nullable [] data) {
|
||||||
|
if(data == null) {
|
||||||
|
abort(null, "Not FML2/3 client");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ByteBuf buf = Unpooled.wrappedBuffer(data);
|
||||||
|
if(forge && buf.readByte() != 0) {
|
||||||
|
abort(data, "Not FORGE login wrapper");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!ProtocolUtils.readString(buf).equals(forge ? "forge:handshake" : "fml:handshake")) {
|
||||||
|
abort(data, "Not FML2/3/FORGE handshake response");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ProtocolUtils.readVarInt(buf) != buf.readableBytes()) {
|
||||||
|
abort(data, "FML2/3/FORGE packet size mismatch");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ProtocolUtils.readVarInt(buf) != (forge ? /* Mod Versions */ 1 : /* Mod List Reply */ 2)) {
|
||||||
|
abort(data, "Not FML2/3/FORGE mod list reply");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Mod> mods = new ArrayList<>();
|
||||||
|
|
||||||
|
int modCount = ProtocolUtils.readVarInt(buf);
|
||||||
|
for(int i = 0; i < modCount; i++) {
|
||||||
|
mods.add(Mod.getOrCreate(ProtocolUtils.readString(buf), Mod.Platform.FORGE));
|
||||||
|
|
||||||
|
if(forge) {
|
||||||
|
ProtocolUtils.readString(buf); // Human readable name
|
||||||
|
ProtocolUtils.readString(buf); // Version
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
modUtils.handleMods(uuid, Locale.getDefault(), connection::disconnect, mods);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
156
src/de/steamwar/bungeecore/mods/FabricModSender.java
Normale Datei
156
src/de/steamwar/bungeecore/mods/FabricModSender.java
Normale Datei
@ -0,0 +1,156 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of the SteamWar software.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2024 SteamWar.de-Serverteam
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.bungeecore.mods;
|
||||||
|
|
||||||
|
import com.google.gson.JsonArray;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonParser;
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
import com.velocitypowered.api.event.Subscribe;
|
||||||
|
import com.velocitypowered.api.event.connection.DisconnectEvent;
|
||||||
|
import com.velocitypowered.api.event.connection.PluginMessageEvent;
|
||||||
|
import com.velocitypowered.api.event.player.ServerConnectedEvent;
|
||||||
|
import com.velocitypowered.api.event.player.ServerPostConnectEvent;
|
||||||
|
import com.velocitypowered.api.proxy.Player;
|
||||||
|
import com.velocitypowered.api.proxy.ProxyServer;
|
||||||
|
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
||||||
|
import de.steamwar.bungeecore.VelocityCore;
|
||||||
|
import de.steamwar.bungeecore.Storage;
|
||||||
|
import de.steamwar.bungeecore.util.annotations.Create;
|
||||||
|
import de.steamwar.sql.Mod;
|
||||||
|
import de.steamwar.sql.SWException;
|
||||||
|
import de.steamwar.sql.SteamwarUser;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.buffer.Unpooled;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
@Create
|
||||||
|
public class FabricModSender {
|
||||||
|
|
||||||
|
private final ModUtils utils;
|
||||||
|
private final ProxyServer proxyServer;
|
||||||
|
private final VelocityCore core;
|
||||||
|
|
||||||
|
private final Set<String> neededFabricMods = new HashSet<>();
|
||||||
|
private final Set<String> neededQuiltMods = new HashSet<>();
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public FabricModSender(ModUtils utils, ProxyServer proxyServer, VelocityCore core) {
|
||||||
|
this.utils = utils;
|
||||||
|
this.proxyServer = proxyServer;
|
||||||
|
this.core = core;
|
||||||
|
neededFabricMods.add("java");
|
||||||
|
neededFabricMods.add("minecraft");
|
||||||
|
neededFabricMods.add("steamwarmodsender");
|
||||||
|
neededQuiltMods.addAll(neededFabricMods);
|
||||||
|
|
||||||
|
neededFabricMods.add("fabricloader");
|
||||||
|
neededQuiltMods.add("quilt_loader");
|
||||||
|
|
||||||
|
proxyServer.getScheduler().buildTask(VelocityCore.get(), () -> {
|
||||||
|
synchronized (Storage.fabricExpectPluginMessage) {
|
||||||
|
for (Map.Entry<Player, Long> entry : Storage.fabricExpectPluginMessage.entrySet()) {
|
||||||
|
if (!Storage.fabricCheckedPlayers.containsKey(entry.getKey())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (System.currentTimeMillis() - entry.getValue() > TimeUnit.SECONDS.toMillis(20)) {
|
||||||
|
Storage.fabricExpectPluginMessage.remove(entry.getKey());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).repeat(1, TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handlePluginMessage(PluginMessageEvent e){
|
||||||
|
Player player = (Player) e.getSource();
|
||||||
|
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
||||||
|
|
||||||
|
if (!Storage.fabricCheckedPlayers.containsKey(player)) {
|
||||||
|
synchronized (Storage.fabricExpectPluginMessage) {
|
||||||
|
if (Storage.fabricExpectPluginMessage.containsKey(player)) {
|
||||||
|
logMessage(user, "Was not fabric checked but send message nonetheless", Arrays.toString(e.getData()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Storage.fabricExpectPluginMessage.remove(player);
|
||||||
|
|
||||||
|
List<Mod> mods = new ArrayList<>();
|
||||||
|
|
||||||
|
ByteBuf buf = Unpooled.wrappedBuffer(e.getData());
|
||||||
|
String data = ProtocolUtils.readString(buf, 1024*1024);
|
||||||
|
if(buf.readableBytes() > 0) {
|
||||||
|
logMessage(user, "Invalid message length", Arrays.toString(e.getData()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonArray array = JsonParser.parseString(data).getAsJsonArray();
|
||||||
|
|
||||||
|
for(JsonElement mod : array) {
|
||||||
|
mods.add(Mod.getOrCreate(mod.getAsString(), Mod.Platform.FABRIC));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!neededModsContained(neededFabricMods, mods) && !neededModsContained(neededQuiltMods, mods)) {
|
||||||
|
logMessage(user, "Needed mods are not contained", data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!utils.handleMods(player,mods))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!Storage.fabricCheckedPlayers.containsKey(player)) {
|
||||||
|
Storage.fabricCheckedPlayers.put(player, data.hashCode());
|
||||||
|
} else if (Storage.fabricCheckedPlayers.get(player) != data.hashCode()) {
|
||||||
|
logMessage(user, "Mods changed during runtime", data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onServerSwitchEvent(ServerConnectedEvent e) {
|
||||||
|
if (e.getPreviousServer().isEmpty()) return;
|
||||||
|
synchronized (Storage.fabricExpectPluginMessage) {
|
||||||
|
Storage.fabricExpectPluginMessage.put(e.getPlayer(), System.currentTimeMillis());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onDisconnect(DisconnectEvent e) {
|
||||||
|
Player player = e.getPlayer();
|
||||||
|
|
||||||
|
Storage.fabricCheckedPlayers.remove(player);
|
||||||
|
synchronized (Storage.fabricExpectPluginMessage) {
|
||||||
|
Storage.fabricExpectPluginMessage.remove(player);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean neededModsContained(Set<String> neededMods, List<Mod> mods) {
|
||||||
|
return mods.stream()
|
||||||
|
.map(Mod::getModName)
|
||||||
|
.filter(neededMods::contains)
|
||||||
|
.count() == neededFabricMods.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void logMessage(SteamwarUser user, String reason, String data) {
|
||||||
|
SWException.log("FabricModSender " + user.getUserName() + ": " + reason, data);
|
||||||
|
}
|
||||||
|
}
|
58
src/de/steamwar/bungeecore/mods/Feather.java
Normale Datei
58
src/de/steamwar/bungeecore/mods/Feather.java
Normale Datei
@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of the SteamWar software.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2024 SteamWar.de-Serverteam
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.bungeecore.mods;
|
||||||
|
|
||||||
|
import com.google.gson.JsonArray;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import com.velocitypowered.api.proxy.Player;
|
||||||
|
import com.velocitypowered.api.proxy.messages.ChannelIdentifier;
|
||||||
|
import com.velocitypowered.api.proxy.messages.MinecraftChannelIdentifier;
|
||||||
|
|
||||||
|
public class Feather {
|
||||||
|
//https://github.com/Koupah/Feather-Client-API/blob/main/src/club/koupah/feather/packets/FeatherMod.java
|
||||||
|
//https://archive.org/details/feather-server-api
|
||||||
|
public static final ChannelIdentifier CHANNEL = MinecraftChannelIdentifier.from("feather:client");
|
||||||
|
|
||||||
|
private final byte[] packet;
|
||||||
|
public Feather() {
|
||||||
|
JsonArray array = new JsonArray();
|
||||||
|
array.add("clearWater");
|
||||||
|
array.add("coordinates");
|
||||||
|
array.add("coordinates");
|
||||||
|
array.add("hitbox");
|
||||||
|
array.add("hypixel");
|
||||||
|
array.add("reachDisplay");
|
||||||
|
array.add("snaplook");
|
||||||
|
array.add("toggleSprint");
|
||||||
|
|
||||||
|
JsonObject mods = new JsonObject();
|
||||||
|
mods.add("mods", array);
|
||||||
|
|
||||||
|
JsonObject obj = new JsonObject();
|
||||||
|
obj.addProperty("packetType", "DISABLE_MODS");
|
||||||
|
obj.add("payload", mods);
|
||||||
|
|
||||||
|
packet = obj.toString().getBytes();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendRestrictions(Player player) {
|
||||||
|
player.sendPluginMessage(CHANNEL, packet);
|
||||||
|
}
|
||||||
|
}
|
56
src/de/steamwar/bungeecore/mods/Hostname.java
Normale Datei
56
src/de/steamwar/bungeecore/mods/Hostname.java
Normale Datei
@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of the SteamWar software.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2024 SteamWar.de-Serverteam
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.bungeecore.mods;
|
||||||
|
|
||||||
|
import com.velocitypowered.api.event.Subscribe;
|
||||||
|
import com.velocitypowered.api.event.proxy.ProxyPingEvent;
|
||||||
|
import de.steamwar.bungeecore.VelocityCore;
|
||||||
|
import de.steamwar.bungeecore.util.annotations.Create;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
@Create
|
||||||
|
public class Hostname {
|
||||||
|
|
||||||
|
private final Set<String> knownHostnames = new HashSet<>();
|
||||||
|
|
||||||
|
public Hostname() {
|
||||||
|
knownHostnames.add("steamwar.de");
|
||||||
|
knownHostnames.add("78.31.71.136");
|
||||||
|
knownHostnames.add("memewar.de"); // Chaoscaot
|
||||||
|
knownHostnames.add("dampfkrieg.de"); // Chaoscaot
|
||||||
|
knownHostnames.add("127.0.0.1"); // Geyser
|
||||||
|
|
||||||
|
knownHostnames.add("@mat:matdoes.dev "); //https://github.com/mat-1/matscan
|
||||||
|
knownHostnames.add("wtf.mynx.lol"); //https://discord.com/invite/serverseeker
|
||||||
|
knownHostnames.add("masscan");
|
||||||
|
knownHostnames.add("aaa");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onHandshake(ProxyPingEvent event) {
|
||||||
|
String hostname = event.getConnection().getVirtualHost().map(inetSocketAddress -> inetSocketAddress.getHostName()).orElse("");
|
||||||
|
if (!knownHostnames.contains(hostname) && !hostname.endsWith(".steamwar.de")) {
|
||||||
|
VelocityCore.get().getLogger().log(Level.WARNING, () -> event.getConnection().getRemoteAddress().toString() + " connected with unknown hostname '" + hostname + "'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
92
src/de/steamwar/bungeecore/mods/LabyMod.java
Normale Datei
92
src/de/steamwar/bungeecore/mods/LabyMod.java
Normale Datei
@ -0,0 +1,92 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of the SteamWar software.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2024 SteamWar.de-Serverteam
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.bungeecore.mods;
|
||||||
|
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import com.google.gson.JsonParser;
|
||||||
|
import com.velocitypowered.api.event.connection.PluginMessageEvent;
|
||||||
|
import com.velocitypowered.api.proxy.Player;
|
||||||
|
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
||||||
|
import de.steamwar.bungeecore.VelocityCore;
|
||||||
|
import de.steamwar.bungeecore.listeners.PluginMessage;
|
||||||
|
import de.steamwar.bungeecore.util.annotations.Create;
|
||||||
|
import de.steamwar.sql.Mod;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.buffer.Unpooled;
|
||||||
|
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
@Create
|
||||||
|
public class LabyMod {
|
||||||
|
// https://docs.labymod.net/pages/server/introduction/
|
||||||
|
// https://github.com/LabyMod/labymod-server-api
|
||||||
|
// https://dl.labymod.net/addons.json
|
||||||
|
|
||||||
|
private final ModUtils utils;
|
||||||
|
|
||||||
|
private final byte[] gameInfoPacket;
|
||||||
|
public LabyMod(ModUtils utils) {
|
||||||
|
this.utils = utils;
|
||||||
|
gameInfoPacket = PluginMessage.genBufPacket(buf -> {
|
||||||
|
ProtocolUtils.writeString(buf, "discord_rpc");
|
||||||
|
|
||||||
|
JsonObject json = new JsonObject();
|
||||||
|
json.addProperty("hasGame", true);
|
||||||
|
json.addProperty("game_mode", "steamwar.de");
|
||||||
|
json.addProperty("game_startTime", 0);
|
||||||
|
json.addProperty("game_endTime", 0);
|
||||||
|
ProtocolUtils.writeString(buf, json.toString());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handlePluginMessage(PluginMessageEvent event) {
|
||||||
|
Player player = (Player) event.getSource();
|
||||||
|
player.sendPluginMessage(event.getIdentifier(), gameInfoPacket);
|
||||||
|
|
||||||
|
ByteBuf buf = Unpooled.wrappedBuffer(event.getData());
|
||||||
|
String purpose = ProtocolUtils.readString(buf);
|
||||||
|
if(!"INFO".equals(purpose))
|
||||||
|
return;
|
||||||
|
|
||||||
|
JsonObject message = JsonParser.parseString(ProtocolUtils.readString(buf)).getAsJsonObject();
|
||||||
|
List<Mod> mods = new LinkedList<>();
|
||||||
|
|
||||||
|
if(message.has("addons")) {
|
||||||
|
for(JsonElement element : message.getAsJsonArray("addons")) {
|
||||||
|
JsonObject addon = element.getAsJsonObject();
|
||||||
|
mods.add(Mod.getOrCreate(addon.get("name").getAsString(), Mod.Platform.LABYMOD));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(message.has("mods")) {
|
||||||
|
VelocityCore.get().getLogger().log(Level.WARNING, () -> "LabyMod External Mods for debugging: " + message.getAsJsonArray("mods"));
|
||||||
|
for(JsonElement element : message.getAsJsonArray("mods")) {
|
||||||
|
JsonObject addon = element.getAsJsonObject();
|
||||||
|
//TODO observe: FORGE and FABRIC mods available, do they always and with .jar? (would equal new mod platform)
|
||||||
|
//mods.add(Mod.getOrCreate(addon.get("name").getAsString().replace(".jar", ""), Mod.Platform.FORGE));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
utils.handleMods(player, mods);
|
||||||
|
}
|
||||||
|
}
|
142
src/de/steamwar/bungeecore/mods/Lunar.java
Normale Datei
142
src/de/steamwar/bungeecore/mods/Lunar.java
Normale Datei
@ -0,0 +1,142 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of the SteamWar software.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2024 SteamWar.de-Serverteam
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.bungeecore.mods;
|
||||||
|
|
||||||
|
import com.lunarclient.apollo.ApolloManager;
|
||||||
|
import com.lunarclient.apollo.libs.protobuf.Any;
|
||||||
|
import com.lunarclient.apollo.libs.protobuf.InvalidProtocolBufferException;
|
||||||
|
import com.lunarclient.apollo.libs.protobuf.Message;
|
||||||
|
import com.lunarclient.apollo.mods.impl.*;
|
||||||
|
import com.lunarclient.apollo.module.ApolloModuleManager;
|
||||||
|
import com.lunarclient.apollo.module.ApolloModuleManagerImpl;
|
||||||
|
import com.lunarclient.apollo.module.modsetting.ModSettingModule;
|
||||||
|
import com.lunarclient.apollo.network.NetworkOptions;
|
||||||
|
import com.lunarclient.apollo.option.Options;
|
||||||
|
import com.lunarclient.apollo.player.AbstractApolloPlayer;
|
||||||
|
import com.lunarclient.apollo.player.v1.ModMessage;
|
||||||
|
import com.lunarclient.apollo.player.v1.PlayerHandshakeMessage;
|
||||||
|
import com.velocitypowered.api.event.connection.PluginMessageEvent;
|
||||||
|
import com.velocitypowered.api.proxy.Player;
|
||||||
|
import com.velocitypowered.api.proxy.messages.ChannelIdentifier;
|
||||||
|
import com.velocitypowered.api.proxy.messages.MinecraftChannelIdentifier;
|
||||||
|
import de.steamwar.bungeecore.VelocityCore;
|
||||||
|
import de.steamwar.bungeecore.util.annotations.Create;
|
||||||
|
import de.steamwar.sql.Mod;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
@Create
|
||||||
|
public class Lunar {
|
||||||
|
// https://lunarclient.dev/apollo/introduction
|
||||||
|
// https://github.com/LunarClient/Apollo
|
||||||
|
|
||||||
|
private final ApolloModuleManager manager = new ApolloModuleManagerImpl().addModule(ModSettingModule.class);
|
||||||
|
|
||||||
|
private final ModUtils utils;
|
||||||
|
|
||||||
|
public Lunar(ModUtils utils) { //TODO seems defunct
|
||||||
|
Options modSettings = manager.getModule(ModSettingModule.class).getOptions();
|
||||||
|
modSettings.set(ModReplaymod.ENABLED, false); // TODO check if restrictions working
|
||||||
|
modSettings.set(ModFreelook.ENABLED, false);
|
||||||
|
modSettings.set(ModHypixelMod.ENABLED, false);
|
||||||
|
modSettings.set(ModMinimap.ENABLED, false);
|
||||||
|
modSettings.set(ModNametag.ENABLED, false);
|
||||||
|
modSettings.set(ModTeamView.ENABLED, false);
|
||||||
|
modSettings.set(ModTntCountdown.ENABLED, false);
|
||||||
|
modSettings.set(ModToggleSneak.TOGGLE_SNEAK_CONTAINER, false);
|
||||||
|
|
||||||
|
this.utils = utils;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendRestrictions(Player player) {
|
||||||
|
NetworkOptions.sendOptions(manager.getModules(), true, new SWApolloPlayer(player));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handlePluginMessage(PluginMessageEvent event) {
|
||||||
|
Player player = (Player) event.getSource();
|
||||||
|
Any packet;
|
||||||
|
|
||||||
|
try {
|
||||||
|
packet = Any.parseFrom(event.getData());
|
||||||
|
} catch (InvalidProtocolBufferException e) {
|
||||||
|
throw new SecurityException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
handle(PlayerHandshakeMessage.class, packet, handshake -> {
|
||||||
|
List<Mod> mods = new ArrayList<>();
|
||||||
|
|
||||||
|
for(ModMessage mod : handshake.getInstalledModsList()) {
|
||||||
|
switch(mod.getType()) {
|
||||||
|
case TYPE_FABRIC_INTERNAL:
|
||||||
|
case TYPE_FORGE_INTERNAL:
|
||||||
|
// Controlled with ModSettings
|
||||||
|
break;
|
||||||
|
case TYPE_FABRIC_EXTERNAL:
|
||||||
|
mods.add(Mod.getOrCreate(mod.getName(), Mod.Platform.FABRIC));
|
||||||
|
break;
|
||||||
|
case TYPE_FORGE_EXTERNAL:
|
||||||
|
mods.add(Mod.getOrCreate(mod.getName(), Mod.Platform.FORGE));
|
||||||
|
break;
|
||||||
|
case TYPE_UNSPECIFIED:
|
||||||
|
case UNRECOGNIZED:
|
||||||
|
default:
|
||||||
|
VelocityCore.get().getLogger().log(Level.INFO, () -> player.getUsername() + " uses Lunar mod with unknown type " + mod);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
utils.handleMods(player, mods);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T extends Message> void handle(Class<T> type, Any packet, Consumer<T> handler) {
|
||||||
|
try {
|
||||||
|
handler.accept(packet.unpack(type));
|
||||||
|
} catch (InvalidProtocolBufferException ignored) { /*ignored*/ }
|
||||||
|
}
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
private static class SWApolloPlayer extends AbstractApolloPlayer {
|
||||||
|
|
||||||
|
private static final ChannelIdentifier CHANNEL = MinecraftChannelIdentifier.from(ApolloManager.PLUGIN_MESSAGE_CHANNEL);
|
||||||
|
|
||||||
|
private final Player player;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendPacket(Message message) {
|
||||||
|
sendPacket(Any.pack(message).toByteArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendPacket(byte[] bytes) {
|
||||||
|
player.sendPluginMessage(CHANNEL, bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public UUID getUniqueId() { return player.getUniqueId(); }
|
||||||
|
@Override public String getName() { return player.getUsername(); }
|
||||||
|
@Override public boolean hasPermission(String s) { return player.hasPermission(s); }
|
||||||
|
@Override public Object getPlayer() { return player; }
|
||||||
|
}
|
||||||
|
}
|
101
src/de/steamwar/bungeecore/mods/ModUtils.java
Normale Datei
101
src/de/steamwar/bungeecore/mods/ModUtils.java
Normale Datei
@ -0,0 +1,101 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of the SteamWar software.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2024 SteamWar.de-Serverteam
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.bungeecore.mods;
|
||||||
|
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
import com.velocitypowered.api.proxy.Player;
|
||||||
|
import de.steamwar.bungeecore.VelocityCore;
|
||||||
|
import de.steamwar.bungeecore.Message;
|
||||||
|
import de.steamwar.bungeecore.commands.PunishmentCommand;
|
||||||
|
import de.steamwar.bungeecore.util.annotations.Create;
|
||||||
|
import de.steamwar.sql.SteamwarUser;
|
||||||
|
import de.steamwar.messages.ChatSender;
|
||||||
|
import de.steamwar.sql.Mod;
|
||||||
|
import de.steamwar.sql.Mod.ModType;
|
||||||
|
import de.steamwar.sql.UserPerm;
|
||||||
|
import lombok.Getter;
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||||
|
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.time.temporal.ChronoUnit;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Create
|
||||||
|
public class ModUtils {
|
||||||
|
|
||||||
|
private final Logger logger;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private final Map<UUID,List<Mod>> playerModMap = new HashMap<>();
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public ModUtils(Logger logger) {
|
||||||
|
this.logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean handleMods(Player player, List<Mod> mods) {
|
||||||
|
return handleMods(player.getUniqueId(), ChatSender.of(player).getLocale(), player::disconnect, mods);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean handleMods(UUID uuid, Locale locale, Consumer<Component> disconnect, List<Mod> mods){
|
||||||
|
SteamwarUser user = SteamwarUser.get(uuid);
|
||||||
|
playerModMap.put(uuid,new ArrayList<>(mods));
|
||||||
|
VelocityCore.get().getLogger().log(Level.INFO, user.getUserName() + " declares mods: " + mods.stream().map(mod -> mod.getPlatform() + ":" + mod.getModName()).collect(Collectors.joining(" ")));
|
||||||
|
|
||||||
|
ModType max = ModType.YELLOW;
|
||||||
|
Iterator<Mod> it = mods.iterator();
|
||||||
|
while(it.hasNext()){
|
||||||
|
Mod mod = it.next();
|
||||||
|
if(mod.getModType() == ModType.UNKLASSIFIED || mod.getModType() == ModType.GREEN || (mod.getModType() == ModType.YOUTUBER_ONLY && user.hasPerm(UserPerm.RESTRICTED_MODS)))
|
||||||
|
it.remove();
|
||||||
|
else if(mod.getModType() == ModType.RED)
|
||||||
|
max = ModType.RED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(mods.isEmpty()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ModType finalMax = max;
|
||||||
|
String modList = mods.stream().filter(mod -> finalMax == ModType.YELLOW || mod.getModType() == ModType.RED).map(Mod::getModName).collect(Collectors.joining("\n"));
|
||||||
|
String message;
|
||||||
|
|
||||||
|
if(mods.size() == 1) {
|
||||||
|
message = Message.parse(max == ModType.RED ? "MOD_RED_SING" : "MOD_YELLOW_SING", locale, modList);
|
||||||
|
} else {
|
||||||
|
message = Message.parse(max == ModType.RED ? "MOD_RED_PLUR" : "MOD_YELLOW_PLUR", locale, modList);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(max == ModType.RED) {
|
||||||
|
PunishmentCommand.ban(user, Timestamp.from(Instant.now().plus(7, ChronoUnit.DAYS)), message, SteamwarUser.get(-1), false);
|
||||||
|
logger.log(Level.SEVERE, user.getUserName() + " " + user.getId() + " wurde automatisch wegen der Mods " + modList + " gebannt.");
|
||||||
|
}
|
||||||
|
|
||||||
|
disconnect.accept(LegacyComponentSerializer.legacySection().deserialize(message));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
67
src/de/steamwar/bungeecore/mods/ReplayMod.java
Normale Datei
67
src/de/steamwar/bungeecore/mods/ReplayMod.java
Normale Datei
@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of the SteamWar software.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2024 SteamWar.de-Serverteam
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.bungeecore.mods;
|
||||||
|
|
||||||
|
import de.steamwar.bungeecore.Bauserver;
|
||||||
|
import de.steamwar.bungeecore.Builderserver;
|
||||||
|
import de.steamwar.bungeecore.VelocityCore;
|
||||||
|
import de.steamwar.bungeecore.Subserver;
|
||||||
|
import de.steamwar.bungeecore.listeners.BasicListener;
|
||||||
|
import de.steamwar.bungeecore.listeners.PluginMessage;
|
||||||
|
import net.md_5.bungee.api.ProxyServer;
|
||||||
|
import net.md_5.bungee.api.config.ServerInfo;
|
||||||
|
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||||
|
import net.md_5.bungee.api.event.ServerSwitchEvent;
|
||||||
|
import net.md_5.bungee.event.EventHandler;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
public class ReplayMod extends BasicListener {
|
||||||
|
// https://gist.github.com/Johni0702/2547c463e51f65f312cb
|
||||||
|
// https://github.com/ReplayMod/replay-restrictions/blob/master/bungeecord/src/main/java/de/johni0702/replay/restrictions/BungeeCordPlugin.java
|
||||||
|
// https://github.com/ReplayMod/ReplayMod/blob/stable/src/main/java/com/replaymod/core/utils/Restrictions.java
|
||||||
|
|
||||||
|
private final byte[] restrict;
|
||||||
|
|
||||||
|
public ReplayMod() {
|
||||||
|
restrict = PluginMessage.genStreamPacket(out -> {
|
||||||
|
for(String restriction : Arrays.asList("no_xray", "no_noclip", "only_first_person", "only_recording_player")) {
|
||||||
|
byte[] bytes = restriction.getBytes();
|
||||||
|
out.writeByte(bytes.length);
|
||||||
|
out.write(bytes);
|
||||||
|
out.writeBoolean(true); // restrict
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onPlayerJoin(ServerSwitchEvent event) {
|
||||||
|
ProxiedPlayer player = event.getPlayer();
|
||||||
|
ServerInfo server = player.getServer().getInfo();
|
||||||
|
if(ProxyServer.getInstance().getServerInfo(VelocityCore.LOBBY_SERVER) == server)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Subserver subserver = Subserver.getSubserver(server);
|
||||||
|
if(subserver instanceof Builderserver || (subserver instanceof Bauserver && ((Bauserver) subserver).getOwner().equals(player.getUniqueId())))
|
||||||
|
return;
|
||||||
|
|
||||||
|
PluginMessage.send(player, "Replay|Restrict", "replaymod:restrict", restrict);
|
||||||
|
}
|
||||||
|
}
|
40
src/de/steamwar/bungeecore/mods/Schematica.java
Normale Datei
40
src/de/steamwar/bungeecore/mods/Schematica.java
Normale Datei
@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of the SteamWar software.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2024 SteamWar.de-Serverteam
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.bungeecore.mods;
|
||||||
|
|
||||||
|
import de.steamwar.bungeecore.listeners.BasicListener;
|
||||||
|
import net.md_5.bungee.api.event.PostLoginEvent;
|
||||||
|
import net.md_5.bungee.event.EventHandler;
|
||||||
|
|
||||||
|
public class Schematica extends BasicListener {
|
||||||
|
// https://github.com/Lunatrius/SchematicaPlugin/blob/master/src/main/java/com/github/lunatrius/schematica/plugin/SchematicaPlugin.java
|
||||||
|
|
||||||
|
private final byte[] packet = new byte[] {
|
||||||
|
/* ProtocolVersion? */ 0,
|
||||||
|
/* PERM_PRINTER */ 1,
|
||||||
|
/* PERM_SAVE */ 0,
|
||||||
|
/* PERM_LOAD */ 1
|
||||||
|
};
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onPostLogin(PostLoginEvent event) {
|
||||||
|
event.getPlayer().sendData("schematica", packet);
|
||||||
|
}
|
||||||
|
}
|
86
src/de/steamwar/bungeecore/mods/ServerListPing.java
Normale Datei
86
src/de/steamwar/bungeecore/mods/ServerListPing.java
Normale Datei
@ -0,0 +1,86 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of the SteamWar software.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2024 SteamWar.de-Serverteam
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.bungeecore.mods;
|
||||||
|
|
||||||
|
import com.google.gson.*;
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
import com.velocitypowered.api.proxy.ProxyServer;
|
||||||
|
import com.velocitypowered.api.proxy.server.ServerPing;
|
||||||
|
import de.steamwar.bungeecore.util.annotations.Create;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
|
||||||
|
@Create
|
||||||
|
public class ServerListPing {
|
||||||
|
// https://github.com/Aizistral-Studios/No-Chat-Reports/discussions/206
|
||||||
|
// https://github.com/Aizistral-Studios/No-Chat-Reports/wiki/How-to-Get-Safe-Server-Status
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private final ProxyServer proxyServer;
|
||||||
|
|
||||||
|
private static final String[] FIELDS_TO_OVERRIDE = new String[] {
|
||||||
|
"PRE_1_16_PING_SERIALIZER",
|
||||||
|
"PRE_1_20_3_PING_SERIALIZER",
|
||||||
|
"MODERN_PING_SERIALIZER"
|
||||||
|
};
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public ServerListPing(ProxyServer proxyServer) {
|
||||||
|
this.proxyServer = proxyServer;
|
||||||
|
|
||||||
|
try {
|
||||||
|
for (String fieldName : FIELDS_TO_OVERRIDE) {
|
||||||
|
Field field = proxyServer.getClass().getDeclaredField(fieldName);
|
||||||
|
field.setAccessible(true);
|
||||||
|
Object obj = field.get(null);
|
||||||
|
if (obj instanceof Gson gsonOld) {
|
||||||
|
Gson gsonNew = new GsonBuilder()
|
||||||
|
.registerTypeAdapter(ServerPing.class, new ServerListPingSerializer(gsonOld))
|
||||||
|
.create();
|
||||||
|
field.set(null, gsonNew);
|
||||||
|
} else {
|
||||||
|
throw new SecurityException("Failed to inject ServerListPing in " + fieldName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
|
||||||
|
throw new SecurityException("Failed to inject ServerListPing", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private record ServerListPingSerializer(
|
||||||
|
Gson gson) implements JsonSerializer<ServerPing>, JsonDeserializer<ServerPing> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonElement serialize(ServerPing ping, Type type, JsonSerializationContext context) {
|
||||||
|
JsonElement element = gson.toJsonTree(ping, type);
|
||||||
|
|
||||||
|
JsonObject object = element.getAsJsonObject();
|
||||||
|
object.addProperty("preventsChatReports", true);
|
||||||
|
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ServerPing deserialize(JsonElement element, Type type, JsonDeserializationContext context) throws JsonParseException {
|
||||||
|
return gson.fromJson(element, ServerPing.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
48
src/de/steamwar/bungeecore/mods/WorldDownloader.java
Normale Datei
48
src/de/steamwar/bungeecore/mods/WorldDownloader.java
Normale Datei
@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of the SteamWar software.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2024 SteamWar.de-Serverteam
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.bungeecore.mods;
|
||||||
|
|
||||||
|
import com.velocitypowered.api.event.connection.PluginMessageEvent;
|
||||||
|
import com.velocitypowered.api.proxy.Player;
|
||||||
|
import de.steamwar.bungeecore.listeners.PluginMessage;
|
||||||
|
|
||||||
|
public class WorldDownloader {
|
||||||
|
// https://wiki.vg/Plugin_channels/World_downloader
|
||||||
|
// https://github.com/Pokechu22/WorldDownloader-Serverside-Companion
|
||||||
|
// https://github.com/Pokechu22/WorldDownloader
|
||||||
|
|
||||||
|
private final byte[] controlPacket;
|
||||||
|
|
||||||
|
public WorldDownloader() {
|
||||||
|
controlPacket = PluginMessage.genStreamPacket(out -> {
|
||||||
|
out.writeInt(1); // basic data packet
|
||||||
|
out.writeBoolean(false); // General download enabled
|
||||||
|
out.writeInt(-1); // Save radius
|
||||||
|
out.writeBoolean(false); // Chunk caching enabled
|
||||||
|
out.writeBoolean(false); // Entity saving enabled
|
||||||
|
out.writeBoolean(false); // Tile entity saving disabled
|
||||||
|
out.writeBoolean(false); // Container saving disabled
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handlePluginMessage(PluginMessageEvent event) {
|
||||||
|
PluginMessage.send((Player) event.getSource(), "WDL|CONTROL", "wdl:control", controlPacket);
|
||||||
|
}
|
||||||
|
}
|
@ -25,8 +25,9 @@ import lombok.experimental.UtilityClass;
|
|||||||
@UtilityClass
|
@UtilityClass
|
||||||
public class BungeeNetworkHandler {
|
public class BungeeNetworkHandler {
|
||||||
public static void register() {
|
public static void register() {
|
||||||
|
new EloPlayerHandler().register();
|
||||||
|
new EloSchemHandler().register();
|
||||||
new ExecuteCommandHandler().register();
|
new ExecuteCommandHandler().register();
|
||||||
new FightEndsHandler().register();
|
|
||||||
new FightInfoHandler().register();
|
new FightInfoHandler().register();
|
||||||
new ImALobbyHandler().register();
|
new ImALobbyHandler().register();
|
||||||
new InventoryCallbackHandler().register();
|
new InventoryCallbackHandler().register();
|
||||||
|
@ -1,58 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2022 SteamWar.de-Serverteam
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.bungeecore.network;
|
|
||||||
|
|
||||||
import de.steamwar.bungeecore.BungeeCore;
|
|
||||||
import de.steamwar.bungeecore.commands.TeamCommand;
|
|
||||||
import de.steamwar.bungeecore.listeners.BasicListener;
|
|
||||||
import de.steamwar.sql.SWException;
|
|
||||||
import de.steamwar.network.packets.NetworkPacket;
|
|
||||||
import net.md_5.bungee.api.ProxyServer;
|
|
||||||
import net.md_5.bungee.api.connection.Server;
|
|
||||||
import net.md_5.bungee.api.event.PluginMessageEvent;
|
|
||||||
import net.md_5.bungee.event.EventHandler;
|
|
||||||
import net.md_5.bungee.event.EventPriority;
|
|
||||||
|
|
||||||
import java.net.InetSocketAddress;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Base64;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class NetworkReceiver extends BasicListener {
|
|
||||||
|
|
||||||
private static final List<String> blockedTags = Arrays.asList("bungeecord:main", "BungeeCord", "sw:bridge");
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST)
|
|
||||||
public void onPluginMessage(PluginMessageEvent event) {
|
|
||||||
if (blockedTags.contains(event.getTag()) && !TeamCommand.isLocalhost(((InetSocketAddress) event.getSender().getSocketAddress()).getAddress())) {
|
|
||||||
SWException.log(((InetSocketAddress) event.getSender().getSocketAddress()).getHostString() + " tried to send a plugin message with tag " + event.getTag(), Base64.getEncoder().encodeToString(event.getData()));
|
|
||||||
event.setCancelled(true);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(!event.getTag().equals("sw:bridge"))
|
|
||||||
return;
|
|
||||||
|
|
||||||
event.setCancelled(true);
|
|
||||||
if(!(event.getSender() instanceof Server))
|
|
||||||
return;
|
|
||||||
|
|
||||||
ProxyServer.getInstance().getScheduler().runAsync(BungeeCore.get(), () -> NetworkPacket.handle(new ServerMetaInfo(((Server) event.getSender()).getInfo()), event.getData()));
|
|
||||||
}
|
|
||||||
}
|
|
@ -19,20 +19,22 @@
|
|||||||
|
|
||||||
package de.steamwar.bungeecore.network;
|
package de.steamwar.bungeecore.network;
|
||||||
|
|
||||||
|
import com.velocitypowered.api.proxy.Player;
|
||||||
|
import com.velocitypowered.api.proxy.messages.ChannelIdentifier;
|
||||||
|
import com.velocitypowered.api.proxy.messages.MinecraftChannelIdentifier;
|
||||||
|
import com.velocitypowered.api.proxy.server.RegisteredServer;
|
||||||
import de.steamwar.network.packets.NetworkPacket;
|
import de.steamwar.network.packets.NetworkPacket;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import net.md_5.bungee.api.config.ServerInfo;
|
|
||||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
|
||||||
|
|
||||||
public class NetworkSender {
|
public class NetworkSender {
|
||||||
|
|
||||||
@SneakyThrows
|
private static final ChannelIdentifier CHANNEL = MinecraftChannelIdentifier.create("sw", "bridge");
|
||||||
public static void send(ProxiedPlayer player, NetworkPacket packet) {
|
|
||||||
player.getServer().sendData("sw:bridge", packet.serialize());
|
public static void send(Player player, NetworkPacket packet) {
|
||||||
|
player.getCurrentServer().ifPresent(serverConnection -> send(serverConnection.getServer(), packet));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void send(ServerInfo serverInfo, NetworkPacket packet) {
|
public static void send(RegisteredServer server, NetworkPacket packet) {
|
||||||
ProxiedPlayer player = serverInfo.getPlayers().iterator().next();
|
server.sendPluginMessage(CHANNEL, packet.serialize());
|
||||||
send(player, packet);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,48 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2022 SteamWar.de-Serverteam
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.bungeecore.network;
|
|
||||||
|
|
||||||
import de.steamwar.bungeecore.commands.TeamCommand;
|
|
||||||
import de.steamwar.bungeecore.listeners.BasicListener;
|
|
||||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
|
||||||
import net.md_5.bungee.api.connection.Server;
|
|
||||||
import net.md_5.bungee.api.event.PluginMessageEvent;
|
|
||||||
import net.md_5.bungee.event.EventHandler;
|
|
||||||
import net.md_5.bungee.event.EventPriority;
|
|
||||||
|
|
||||||
import java.net.InetSocketAddress;
|
|
||||||
|
|
||||||
public class SWScriptSyntaxForwarder extends BasicListener {
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST)
|
|
||||||
public void onPluginMessage(PluginMessageEvent event) {
|
|
||||||
if (!event.getTag().equals("sw:script_syntax")) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
event.setCancelled(true);
|
|
||||||
if (!(event.getSender() instanceof Server)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!TeamCommand.isLocalhost(((InetSocketAddress) event.getSender().getSocketAddress()).getAddress())) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
((ProxiedPlayer) event.getReceiver()).sendData("sw:script_syntax", event.getData());
|
|
||||||
}
|
|
||||||
}
|
|
@ -19,18 +19,11 @@
|
|||||||
|
|
||||||
package de.steamwar.bungeecore.network;
|
package de.steamwar.bungeecore.network;
|
||||||
|
|
||||||
|
import com.velocitypowered.api.proxy.server.RegisteredServer;
|
||||||
import de.steamwar.network.packets.MetaInfos;
|
import de.steamwar.network.packets.MetaInfos;
|
||||||
import net.md_5.bungee.api.config.ServerInfo;
|
import lombok.Getter;
|
||||||
|
|
||||||
public class ServerMetaInfo implements MetaInfos {
|
@Getter
|
||||||
|
public record ServerMetaInfo(RegisteredServer sender) implements MetaInfos {
|
||||||
|
|
||||||
private ServerInfo sender;
|
|
||||||
|
|
||||||
public ServerMetaInfo(ServerInfo sender) {
|
|
||||||
this.sender = sender;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ServerInfo getSender() {
|
|
||||||
return sender;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
263
src/de/steamwar/bungeecore/network/handlers/EloPlayerHandler.java
Normale Datei
263
src/de/steamwar/bungeecore/network/handlers/EloPlayerHandler.java
Normale Datei
@ -0,0 +1,263 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of the SteamWar software.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2022 SteamWar.de-Serverteam
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.bungeecore.network.handlers;
|
||||||
|
|
||||||
|
import com.velocitypowered.api.proxy.Player;
|
||||||
|
import com.velocitypowered.api.scheduler.Scheduler;
|
||||||
|
import de.steamwar.bungeecore.ArenaMode;
|
||||||
|
import de.steamwar.bungeecore.VelocityCore;
|
||||||
|
import de.steamwar.network.packets.PacketHandler;
|
||||||
|
import de.steamwar.network.packets.common.FightEndsPacket;
|
||||||
|
import de.steamwar.sql.SchematicNode;
|
||||||
|
import de.steamwar.sql.SchematicType;
|
||||||
|
import de.steamwar.sql.SteamwarUser;
|
||||||
|
import de.steamwar.sql.UserElo;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||||
|
import net.kyori.adventure.title.Title;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.function.IntFunction;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class EloPlayerHandler extends PacketHandler {
|
||||||
|
|
||||||
|
private static final int MEDIAN_ELO_GAIN = 40;
|
||||||
|
private static final int MEDIAN_ELO_LOSE = 20;
|
||||||
|
private static final long REMATCH_LIFETIME = (long) 60 * 60 * 1000;
|
||||||
|
|
||||||
|
private Map<String, LinkedList<Game>> gameModeGames = new HashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link FightEndsPacket#getWin()} == 1 -> Blue won
|
||||||
|
* {@link FightEndsPacket#getWin()} == 2 -> Red won
|
||||||
|
*/
|
||||||
|
@Handler
|
||||||
|
public void handle(FightEndsPacket fightEndsPacket) {
|
||||||
|
if (!ArenaMode.getBySchemType(SchematicType.fromDB(fightEndsPacket.getGameMode())).isRanked()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean bluePublic = SchematicNode.getSchematicNode(fightEndsPacket.getBlueSchem()).getOwner() == 0;
|
||||||
|
boolean redPublic = SchematicNode.getSchematicNode(fightEndsPacket.getRedSchem()).getOwner() == 0;
|
||||||
|
|
||||||
|
if (bluePublic ^ redPublic) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Die nächsten Zeilen filtern ein Fight innerhalb eines Teams nicht gewertet wird, bzw auch wenn nur Teile beider Teams im
|
||||||
|
// gleichen Team sind dieser ungewertet ist.
|
||||||
|
Set<Integer> teamsIds = fightEndsPacket.getBluePlayers().stream().map(SteamwarUser::get).map(SteamwarUser::getTeam).collect(Collectors.toSet());
|
||||||
|
for (int redPlayer : fightEndsPacket.getRedPlayers()) {
|
||||||
|
int team = SteamwarUser.get(redPlayer).getTeam();
|
||||||
|
if (team != 0 && teamsIds.contains(team)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int blueRank = SchematicNode.getSchematicNode(fightEndsPacket.getBlueSchem()).getRank();
|
||||||
|
int redRank = SchematicNode.getSchematicNode(fightEndsPacket.getRedSchem()).getRank();
|
||||||
|
|
||||||
|
double blueRankFactor = blueRank > redRank ? (fightEndsPacket.getWin() == 1 ? 0.9 : 1.0) : (fightEndsPacket.getWin() == 1 ? 1.5 : 1.0);
|
||||||
|
double redRankFactor = redRank > blueRank ? (fightEndsPacket.getWin() == 2 ? 0.9 : 1.0) : (fightEndsPacket.getWin() == 2 ? 1.5 : 1.0);
|
||||||
|
|
||||||
|
// Get sizes of both teams
|
||||||
|
int blueTeamSize = fightEndsPacket.getBluePlayers().size();
|
||||||
|
int redTeamSize = fightEndsPacket.getRedPlayers().size();
|
||||||
|
|
||||||
|
// Calculate the favored team
|
||||||
|
double bluePlayerFactor = 1 / (1 + Math.exp(0 - (fightEndsPacket.getWin() == 2 ? (double) redTeamSize / blueTeamSize : (double) blueTeamSize / redTeamSize) * 3 + 3)) * 2;
|
||||||
|
double redPlayerFactor = 1 / (1 + Math.exp(0 - (fightEndsPacket.getWin() == 1 ? (double) blueTeamSize / redTeamSize : (double) redTeamSize / blueTeamSize) * 3 + 3)) * 2;
|
||||||
|
|
||||||
|
// Calculate the time factor
|
||||||
|
double timeFactor = getTimeFactor(fightEndsPacket.getDuration());
|
||||||
|
|
||||||
|
// Get total elo of both teams
|
||||||
|
int blueTeamElo = fightEndsPacket.getBluePlayers().stream().mapToInt(player -> UserElo.getEloOrDefault(player, fightEndsPacket.getGameMode())).sum();
|
||||||
|
int redTeamElo = fightEndsPacket.getRedPlayers().stream().mapToInt(player -> UserElo.getEloOrDefault(player, fightEndsPacket.getGameMode())).sum();
|
||||||
|
|
||||||
|
// Adaptive elo bonus
|
||||||
|
int blueTeamEloBonus = 0;
|
||||||
|
int redTeamEloBonus = 0;
|
||||||
|
if (Math.abs(blueTeamElo / (double) fightEndsPacket.getBluePlayers().size() - redTeamElo / (double) fightEndsPacket.getRedPlayers().size()) > 400) {
|
||||||
|
int outlivedDuration = Math.max(fightEndsPacket.getDuration() - 60, 0);
|
||||||
|
if (fightEndsPacket.getWin() == 1 && blueTeamElo < redTeamElo) {
|
||||||
|
blueTeamEloBonus = outlivedDuration / 20;
|
||||||
|
redTeamEloBonus = -(blueTeamEloBonus / 2);
|
||||||
|
} else if (fightEndsPacket.getWin() == 2 && redTeamElo < blueTeamElo) {
|
||||||
|
redTeamEloBonus = outlivedDuration / 20;
|
||||||
|
blueTeamEloBonus = -(redTeamEloBonus / 2);
|
||||||
|
} else if (fightEndsPacket.getWin() == 0) {
|
||||||
|
if (redTeamElo < blueTeamElo) {
|
||||||
|
blueTeamEloBonus = outlivedDuration / 20;
|
||||||
|
redTeamEloBonus = -(blueTeamEloBonus / 2);
|
||||||
|
} else if (blueTeamElo < redTeamElo) {
|
||||||
|
redTeamEloBonus = outlivedDuration / 20;
|
||||||
|
blueTeamEloBonus = -(redTeamEloBonus / 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate the elo factor
|
||||||
|
double blueEloFactor = ((fightEndsPacket.getWin() == 1 ? 1 : 0) - 1 / (1 + Math.pow(10, (redTeamElo - blueTeamElo) / 600.0))) * (1 / (1 + Math.exp(-Math.abs(blueTeamElo - redTeamElo) / 1200))) * 4;
|
||||||
|
double redEloFactor = blueEloFactor * -1;
|
||||||
|
|
||||||
|
// Calculate favoured team on draw
|
||||||
|
if (fightEndsPacket.getWin() == 0) {
|
||||||
|
if (bluePlayerFactor > 1) {
|
||||||
|
blueEloFactor = Math.abs(blueEloFactor) * -1;
|
||||||
|
redEloFactor = Math.abs(redEloFactor);
|
||||||
|
} else if (bluePlayerFactor < 1) {
|
||||||
|
blueEloFactor = Math.abs(blueEloFactor);
|
||||||
|
redEloFactor = Math.abs(redEloFactor) * -1;
|
||||||
|
} else {
|
||||||
|
if (Math.abs(blueEloFactor) > 1) {
|
||||||
|
// Do nothing
|
||||||
|
} else if (Math.abs(blueEloFactor) < 1) {
|
||||||
|
blueEloFactor = ((fightEndsPacket.getWin() == 1 ? 1 : 0) - 1 / (1 + Math.pow(10, (blueTeamElo - redTeamElo) / 600.0))) * (1 / (1 + Math.exp(-Math.abs(redTeamElo - blueTeamElo) / 1200))) * -4;
|
||||||
|
redEloFactor = blueEloFactor * -1;
|
||||||
|
} else {
|
||||||
|
blueEloFactor = 0;
|
||||||
|
redEloFactor = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate the rematch factor
|
||||||
|
double rematchFactor = getRematchFactor(fightEndsPacket);
|
||||||
|
|
||||||
|
// Calculate the win factor
|
||||||
|
double blueWinFactor = (fightEndsPacket.getWin() == 1 ? 1 : 0.7);
|
||||||
|
double redWinFactor = (fightEndsPacket.getWin() == 2 ? 1 : 0.7);
|
||||||
|
|
||||||
|
// Calculate division factor
|
||||||
|
double divisionFactor = 1D / Math.max(blueTeamSize, redTeamSize);
|
||||||
|
|
||||||
|
double blueFactor = blueRankFactor * bluePlayerFactor * timeFactor * blueEloFactor * rematchFactor * blueWinFactor * divisionFactor;
|
||||||
|
double redFactor = redRankFactor * redPlayerFactor * timeFactor * redEloFactor * rematchFactor * redWinFactor * divisionFactor;
|
||||||
|
|
||||||
|
// Calculate the elo gain for each player
|
||||||
|
int blueEloGain = (int) Math.round((blueFactor < 0 ? MEDIAN_ELO_LOSE : MEDIAN_ELO_GAIN) * blueFactor) + blueTeamEloBonus;
|
||||||
|
int redEloGain = (int) Math.round((redFactor < 0 ? MEDIAN_ELO_LOSE : MEDIAN_ELO_GAIN) * redFactor) + redTeamEloBonus;
|
||||||
|
|
||||||
|
// BungeeCore.get().getLogger().info("Blue: " + fightEndsPacket.getBluePlayers() + " " + blueTeamSize + " " + bluePlayerFactor + " " + timeFactor + " " + blueEloFactor + " " + rematchFactor + " " + blueWinFactor + " " + divisionFactor + " " + blueEloGain);
|
||||||
|
// BungeeCore.get().getLogger().info("Red: " + fightEndsPacket.getRedPlayers() + " " + redTeamSize + " " + redPlayerFactor + " " + timeFactor + " " + redEloFactor + " " + rematchFactor + " " + redWinFactor + " " + divisionFactor + " " + redEloGain);
|
||||||
|
|
||||||
|
update(fightEndsPacket.getBluePlayers(), fightEndsPacket.getGameMode(), blueEloGain);
|
||||||
|
update(fightEndsPacket.getRedPlayers(), fightEndsPacket.getGameMode(), redEloGain);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void update(List<Integer> players, String gameMode, int eloGain) {
|
||||||
|
for (int player : players) {
|
||||||
|
// BungeeCore.get().getLogger().log(Level.INFO, "Player: " + player + " Elo: " + UserElo.getEloOrDefault(player, gameMode) + " Factor: " + factor);
|
||||||
|
int playerElo = UserElo.getEloOrDefault(player, gameMode);
|
||||||
|
playerElo += eloGain;
|
||||||
|
if (playerElo < 0) playerElo = 0;
|
||||||
|
|
||||||
|
int oldProgression = UserElo.getProgression(player, gameMode);
|
||||||
|
UserElo.setElo(player, gameMode, playerElo);
|
||||||
|
int newProgression = UserElo.getProgression(player, gameMode);
|
||||||
|
|
||||||
|
animate(player(player), UserElo.toEmblem(oldProgression).trim(), UserElo.toEmblem(newProgression).trim(), (oldProgression < newProgression) ? "§a" : "§c", eloGain);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void animate(Player player, String oldEmblem, String newEmblem, String arrowColor, int eloGain) {
|
||||||
|
String finalOldEmblem = (oldEmblem.isEmpty() ? "/" : oldEmblem).trim();
|
||||||
|
String finalNewEmblem = (newEmblem.isEmpty() ? "/" : newEmblem).trim();
|
||||||
|
|
||||||
|
IntFunction<String> getRankup = i -> {
|
||||||
|
if (oldEmblem.equals(newEmblem)) return "§8" + finalOldEmblem;
|
||||||
|
if (i < 8) return "§8" + finalOldEmblem;
|
||||||
|
if (i < 16) return "§8" + finalOldEmblem + arrowColor + " >";
|
||||||
|
if (i < 24) return "§8" + finalOldEmblem + arrowColor + " >>";
|
||||||
|
if (i < 32) return "§8" + finalOldEmblem + arrowColor + " >>>";
|
||||||
|
return "§8" + finalOldEmblem + arrowColor + " >>> §8" + finalNewEmblem;
|
||||||
|
};
|
||||||
|
|
||||||
|
String color = ((eloGain > 0) ? "§a+" : (eloGain == 0 ? "§7" : "§c"));
|
||||||
|
|
||||||
|
Scheduler scheduler = VelocityCore.get().getProxyServer().getScheduler();
|
||||||
|
double eloStep = eloGain / 40.0;
|
||||||
|
for (int i = 0; i < 40; i++) {
|
||||||
|
Component eloGainComponent = LegacyComponentSerializer.legacySection().deserialize(color + (int) (eloStep * (i + 1)));
|
||||||
|
int finalI = i;
|
||||||
|
scheduler.buildTask(VelocityCore.get(), () -> {
|
||||||
|
if (player == null) return;
|
||||||
|
Title title = Title.title(LegacyComponentSerializer.legacySection().deserialize(getRankup.apply(finalI)), eloGainComponent, Title.Times.times(
|
||||||
|
Duration.ofSeconds(finalI == 0 ? 5 : 0),
|
||||||
|
Duration.ofSeconds(2),
|
||||||
|
Duration.ofSeconds(finalI == 39 ? 5 : 0)
|
||||||
|
));
|
||||||
|
player.showTitle(title);
|
||||||
|
}).delay(i * 50L, TimeUnit.MILLISECONDS).schedule();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private @Nullable Player player(int userId) {
|
||||||
|
return VelocityCore.get().getProxyServer().getPlayer(SteamwarUser.get(userId).getUUID()).orElseThrow();
|
||||||
|
}
|
||||||
|
|
||||||
|
private double getTimeFactor(int duration) {
|
||||||
|
if (duration <= 10) {
|
||||||
|
return 0.5;
|
||||||
|
}
|
||||||
|
if (duration <= 60) {
|
||||||
|
return 0.8;
|
||||||
|
}
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private double getRematchFactor(FightEndsPacket fightEndsPacket) {
|
||||||
|
gameModeGames.computeIfAbsent(fightEndsPacket.getGameMode(), s -> new LinkedList<>()).add(new Game(fightEndsPacket.getBluePlayers(), fightEndsPacket.getRedPlayers()));
|
||||||
|
|
||||||
|
LinkedList<Game> games = gameModeGames.get(fightEndsPacket.getGameMode());
|
||||||
|
while (!games.isEmpty()) {
|
||||||
|
Game game = games.getFirst();
|
||||||
|
if (game.livedMillis() > REMATCH_LIFETIME) {
|
||||||
|
games.removeFirst();
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
long rematchCount = games.stream().filter(game -> game.isSame(fightEndsPacket.getBluePlayers(), fightEndsPacket.getRedPlayers())).count();
|
||||||
|
return 1.0 / rematchCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
private static class Game {
|
||||||
|
private final long time = System.currentTimeMillis();
|
||||||
|
private final List<Integer> bluePlayers;
|
||||||
|
private final List<Integer> redPlayers;
|
||||||
|
|
||||||
|
public long livedMillis() {
|
||||||
|
return System.currentTimeMillis() - time;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSame(List<Integer> bluePlayers, List<Integer> redPlayers) {
|
||||||
|
return bluePlayers.containsAll(this.bluePlayers) && redPlayers.containsAll(this.redPlayers);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
73
src/de/steamwar/bungeecore/network/handlers/EloSchemHandler.java
Normale Datei
73
src/de/steamwar/bungeecore/network/handlers/EloSchemHandler.java
Normale Datei
@ -0,0 +1,73 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of the SteamWar software.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2022 SteamWar.de-Serverteam
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.bungeecore.network.handlers;
|
||||||
|
|
||||||
|
import de.steamwar.bungeecore.ArenaMode;
|
||||||
|
import de.steamwar.network.packets.PacketHandler;
|
||||||
|
import de.steamwar.network.packets.common.FightEndsPacket;
|
||||||
|
import de.steamwar.sql.SchemElo;
|
||||||
|
import de.steamwar.sql.SchematicNode;
|
||||||
|
import de.steamwar.sql.SchematicType;
|
||||||
|
|
||||||
|
public class EloSchemHandler extends PacketHandler {
|
||||||
|
|
||||||
|
private final int K = 20;
|
||||||
|
|
||||||
|
@Handler
|
||||||
|
public void handle(FightEndsPacket fightEndsPacket) {
|
||||||
|
if (!ArenaMode.getBySchemType(SchematicType.fromDB(fightEndsPacket.getGameMode())).isRanked()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean bluePublic = SchematicNode.getSchematicNode(fightEndsPacket.getBlueSchem()).getOwner() == 0;
|
||||||
|
boolean redPublic = SchematicNode.getSchematicNode(fightEndsPacket.getRedSchem()).getOwner() == 0;
|
||||||
|
|
||||||
|
if (bluePublic ^ redPublic) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
calcSchemElo(fightEndsPacket);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void calcSchemElo(FightEndsPacket fightEndsPacket) {
|
||||||
|
double blueResult;
|
||||||
|
if (fightEndsPacket.getWin() == 0) {
|
||||||
|
blueResult = 0.5;
|
||||||
|
} else if (fightEndsPacket.getWin() == 1) {
|
||||||
|
blueResult = 1;
|
||||||
|
} else {
|
||||||
|
blueResult = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int blueSchemElo = SchemElo.getCurrentElo(fightEndsPacket.getBlueSchem());
|
||||||
|
int redSchemElo = SchemElo.getCurrentElo(fightEndsPacket.getRedSchem());
|
||||||
|
calcSchemElo(redSchemElo, blueSchemElo, fightEndsPacket.getRedSchem(), blueResult);
|
||||||
|
calcSchemElo(blueSchemElo, redSchemElo, fightEndsPacket.getBlueSchem(), 1 - blueResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void calcSchemElo(int eloSchemOwn, int eloSchemEnemy, int schemId, double result) {
|
||||||
|
double winSchemExpectation = calcWinExpectation(eloSchemOwn, eloSchemEnemy);
|
||||||
|
SchemElo.setElo(schemId, (int) Math.round(eloSchemOwn + K * (result - winSchemExpectation)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private double calcWinExpectation(int eloOwn, int eloEnemy) {
|
||||||
|
return 1 / (1 + Math.pow(10, (eloEnemy - eloOwn) / 600f));
|
||||||
|
}
|
||||||
|
}
|
@ -19,10 +19,10 @@
|
|||||||
|
|
||||||
package de.steamwar.bungeecore.network.handlers;
|
package de.steamwar.bungeecore.network.handlers;
|
||||||
|
|
||||||
|
import de.steamwar.bungeecore.VelocityCore;
|
||||||
import de.steamwar.sql.SteamwarUser;
|
import de.steamwar.sql.SteamwarUser;
|
||||||
import de.steamwar.network.packets.PacketHandler;
|
import de.steamwar.network.packets.PacketHandler;
|
||||||
import de.steamwar.network.packets.client.ExecuteCommandPacket;
|
import de.steamwar.network.packets.client.ExecuteCommandPacket;
|
||||||
import net.md_5.bungee.api.ProxyServer;
|
|
||||||
|
|
||||||
public class ExecuteCommandHandler extends PacketHandler {
|
public class ExecuteCommandHandler extends PacketHandler {
|
||||||
|
|
||||||
@ -31,6 +31,6 @@ public class ExecuteCommandHandler extends PacketHandler {
|
|||||||
SteamwarUser target = SteamwarUser.get(packet.getPlayerId());
|
SteamwarUser target = SteamwarUser.get(packet.getPlayerId());
|
||||||
String command = packet.getCommand();
|
String command = packet.getCommand();
|
||||||
|
|
||||||
ProxyServer.getInstance().getPluginManager().dispatchCommand(ProxyServer.getInstance().getPlayer(target.getUUID()), command);
|
VelocityCore.get().getProxyServer().getPlayer(target.getUUID()).ifPresent(player -> VelocityCore.get().getProxyServer().getCommandManager().executeAsync(player, command));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,155 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2020 SteamWar.de-Serverteam
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.bungeecore.network.handlers;
|
|
||||||
|
|
||||||
import de.steamwar.bungeecore.ArenaMode;
|
|
||||||
import de.steamwar.network.packets.PacketHandler;
|
|
||||||
import de.steamwar.network.packets.common.FightEndsPacket;
|
|
||||||
import de.steamwar.sql.*;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
public class FightEndsHandler extends PacketHandler {
|
|
||||||
|
|
||||||
private Map<String, LinkedList<Game>> gameModeGames = new HashMap<>();
|
|
||||||
|
|
||||||
private int K = 20;
|
|
||||||
|
|
||||||
private long defaultFightRange = 1000 /* Milliseconds */ * 60 /* Seconds */ * 15L /* Minutes */;
|
|
||||||
private Map<String, Long> fightRanges = new HashMap<>();
|
|
||||||
private long defaultFightCount = 1;
|
|
||||||
private Map<String, Long> fightCounts = new HashMap<>();
|
|
||||||
|
|
||||||
{
|
|
||||||
fightRanges.put("miniwargear", 1000 /* Milliseconds */ * 60 /* Seconds */ * 30L /* Minutes */);
|
|
||||||
fightCounts.put("miniwargear", 3L);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Handler
|
|
||||||
public void handle(FightEndsPacket fightEndsPacket) {
|
|
||||||
if (!ArenaMode.getBySchemType(SchematicType.fromDB(fightEndsPacket.getGameMode())).isRanked()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int bluePlayerSize = fightEndsPacket.getBluePlayers().size();
|
|
||||||
int redPlayerSize = fightEndsPacket.getRedPlayers().size();
|
|
||||||
double playerRatio = bluePlayerSize > redPlayerSize ? (double) redPlayerSize / bluePlayerSize : (double) bluePlayerSize / redPlayerSize;
|
|
||||||
if (playerRatio < 0.6) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean bluePublic = SchematicNode.getSchematicNode(fightEndsPacket.getBlueSchem()).getOwner() == 0;
|
|
||||||
boolean redPublic = SchematicNode.getSchematicNode(fightEndsPacket.getRedSchem()).getOwner() == 0;
|
|
||||||
|
|
||||||
if (bluePublic ^ redPublic) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
double blueResult;
|
|
||||||
if (fightEndsPacket.getWin() == 0) {
|
|
||||||
blueResult = 0.5;
|
|
||||||
} else if (fightEndsPacket.getWin() == 1) {
|
|
||||||
blueResult = 1;
|
|
||||||
} else {
|
|
||||||
blueResult = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Die nächsten Zeilen filtern ein Fight innerhalb eines Teams nicht gewertet wird, bzw auch wenn nur Teile beider Teams im
|
|
||||||
// gleichen Team sind dieser ungewertet ist.
|
|
||||||
Set<Integer> teamsIds = fightEndsPacket.getBluePlayers().stream().map(SteamwarUser::get).map(SteamwarUser::getTeam).collect(Collectors.toSet());
|
|
||||||
for (int redPlayer : fightEndsPacket.getRedPlayers()) {
|
|
||||||
if (teamsIds.contains(SteamwarUser.get(redPlayer).getTeam())) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (teamComboExistedAlready(fightEndsPacket.getBluePlayers(), fightEndsPacket.getRedPlayers(), fightEndsPacket.getGameMode())) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
gameModeGames.computeIfAbsent(fightEndsPacket.getGameMode(), s -> new LinkedList<>()).add(new Game(fightEndsPacket.getBluePlayers(), fightEndsPacket.getRedPlayers()));
|
|
||||||
}
|
|
||||||
|
|
||||||
int blueSchemElo = SchemElo.getCurrentElo(fightEndsPacket.getBlueSchem());
|
|
||||||
int redSchemElo = SchemElo.getCurrentElo(fightEndsPacket.getRedSchem());
|
|
||||||
|
|
||||||
int blueTeamElo = fightEndsPacket.getBluePlayers().stream().mapToInt(player -> UserElo.getEloOrDefault(player, fightEndsPacket.getGameMode())).sum();
|
|
||||||
int redTeamElo = fightEndsPacket.getRedPlayers().stream().mapToInt(player -> UserElo.getEloOrDefault(player, fightEndsPacket.getGameMode())).sum();
|
|
||||||
|
|
||||||
calculateEloOfTeam(fightEndsPacket.getBlueSchem(), blueSchemElo, redSchemElo, blueTeamElo, redTeamElo, blueResult, fightEndsPacket.getBluePlayers(), fightEndsPacket.getGameMode(), bluePublic || redPublic);
|
|
||||||
calculateEloOfTeam(fightEndsPacket.getRedSchem(), redSchemElo, blueSchemElo, redTeamElo, blueTeamElo, 1 - blueResult, fightEndsPacket.getRedPlayers(), fightEndsPacket.getGameMode(), bluePublic || redPublic);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void calculateEloOfTeam(int schemId, int eloSchemOwn, int eloSchemEnemy, int eloTeamOwn, int eloTeamEnemy, double result, List<Integer> players, String gameMode, boolean noPlayerRank) {
|
|
||||||
double winSchemExpectation = calsWinExpectation(eloSchemOwn, eloSchemEnemy);
|
|
||||||
SchemElo.setElo(schemId, (int) Math.round(eloSchemOwn + K * (result - winSchemExpectation)));
|
|
||||||
|
|
||||||
if (noPlayerRank) return;
|
|
||||||
double winTeamExpectation = calsWinExpectation(eloTeamOwn, eloTeamEnemy);
|
|
||||||
for (int player : players) {
|
|
||||||
int playerElo = UserElo.getEloOrDefault(player, gameMode);
|
|
||||||
int fights = UserElo.getFightsOfSeason(player, gameMode);
|
|
||||||
UserElo.setElo(player, gameMode, (int) Math.round(playerElo + getK(fights) * (result - winTeamExpectation)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private double calsWinExpectation(int eloOwn, int eloEnemy) {
|
|
||||||
return 1 / (1 + Math.pow(10, (eloEnemy - eloOwn) / 600f));
|
|
||||||
}
|
|
||||||
|
|
||||||
private double getK(int fights) {
|
|
||||||
return K * Math.max(1.3 - (fights / 200.0), 0.8);
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean teamComboExistedAlready(List<Integer> bluePlayers, List<Integer> redPlayers, String gameMode) {
|
|
||||||
if (!gameModeGames.containsKey(gameMode)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
LinkedList<Game> games = gameModeGames.get(gameMode);
|
|
||||||
long lifetime = fightRanges.getOrDefault(gameMode, defaultFightRange);
|
|
||||||
while (!games.isEmpty()) {
|
|
||||||
Game game = games.getFirst();
|
|
||||||
if (game.livedMillis() > lifetime) {
|
|
||||||
games.removeFirst();
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return games.stream().filter(game -> game.isSame(bluePlayers, redPlayers)).count() > fightCounts.getOrDefault(gameMode, defaultFightCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
private static class Game {
|
|
||||||
private long time = System.currentTimeMillis();
|
|
||||||
private final List<Integer> bluePlayers;
|
|
||||||
private final List<Integer> redPlayers;
|
|
||||||
|
|
||||||
public long livedMillis() {
|
|
||||||
return System.currentTimeMillis() - time;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isSame(List<Integer> bluePlayers, List<Integer> redPlayers) {
|
|
||||||
return bluePlayers.containsAll(this.bluePlayers) && redPlayers.containsAll(this.redPlayers);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -19,6 +19,8 @@
|
|||||||
|
|
||||||
package de.steamwar.bungeecore.network.handlers;
|
package de.steamwar.bungeecore.network.handlers;
|
||||||
|
|
||||||
|
import com.velocitypowered.api.proxy.Player;
|
||||||
|
import com.velocitypowered.api.proxy.server.RegisteredServer;
|
||||||
import de.steamwar.bungeecore.network.NetworkSender;
|
import de.steamwar.bungeecore.network.NetworkSender;
|
||||||
import de.steamwar.bungeecore.network.ServerMetaInfo;
|
import de.steamwar.bungeecore.network.ServerMetaInfo;
|
||||||
import de.steamwar.bungeecore.tablist.TablistManager;
|
import de.steamwar.bungeecore.tablist.TablistManager;
|
||||||
@ -33,28 +35,28 @@ import java.util.Set;
|
|||||||
|
|
||||||
public class FightInfoHandler extends PacketHandler {
|
public class FightInfoHandler extends PacketHandler {
|
||||||
|
|
||||||
private static final Set<ServerInfo> lobbys = new HashSet<>();
|
private static final Set<RegisteredServer> lobbys = new HashSet<>();
|
||||||
|
|
||||||
public static void addLobby(ServerInfo lobby) {
|
public static void addLobby(RegisteredServer lobby) {
|
||||||
lobbys.add(lobby);
|
lobbys.add(lobby);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean onLobby(ProxiedPlayer player) {
|
public static boolean onLobby(Player player) {
|
||||||
return lobbys.contains(player.getServer().getInfo());
|
return player.getCurrentServer().map(serverConnection -> lobbys.contains(serverConnection.getServer())).orElse(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Handler
|
@Handler
|
||||||
public void handle(FightInfoPacket packet) {
|
public void handle(FightInfoPacket packet) {
|
||||||
ServerInfo info = ((ServerMetaInfo) packet.getMetaInfos()).getSender();
|
RegisteredServer info = ((ServerMetaInfo) packet.getMetaInfos()).sender();
|
||||||
|
|
||||||
FightInfoPacket lobbyPacket = packet.withServerName(info.getName());
|
FightInfoPacket lobbyPacket = packet.withServerName(info.getServerInfo().getName());
|
||||||
|
|
||||||
TablistManager.newFightInfo(info, packet);
|
TablistManager.newFightInfo(info, packet);
|
||||||
|
|
||||||
Iterator<ServerInfo> lobbyIt = lobbys.iterator();
|
Iterator<RegisteredServer> lobbyIt = lobbys.iterator();
|
||||||
while(lobbyIt.hasNext()) {
|
while(lobbyIt.hasNext()) {
|
||||||
ServerInfo lobby = lobbyIt.next();
|
RegisteredServer lobby = lobbyIt.next();
|
||||||
Iterator<ProxiedPlayer> it = lobby.getPlayers().iterator();
|
Iterator<Player> it = lobby.getPlayersConnected().iterator();
|
||||||
if(!it.hasNext()){
|
if(!it.hasNext()){
|
||||||
lobbyIt.remove();
|
lobbyIt.remove();
|
||||||
continue;
|
continue;
|
||||||
|
@ -27,6 +27,6 @@ public class ImALobbyHandler extends PacketHandler {
|
|||||||
|
|
||||||
@Handler
|
@Handler
|
||||||
public void handle(ImALobbyPacket packet) {
|
public void handle(ImALobbyPacket packet) {
|
||||||
FightInfoHandler.addLobby(((ServerMetaInfo) packet.getMetaInfos()).getSender());
|
FightInfoHandler.addLobby(((ServerMetaInfo) packet.getMetaInfos()).sender());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Einige Dateien werden nicht angezeigt, da zu viele Dateien in diesem Diff geändert wurden Mehr anzeigen
In neuem Issue referenzieren
Einen Benutzer sperren