Compare commits

..
27 Commits
Author SHA1 Message Date
Nassim Jahnke 4d06d0f6b8 4.0.0 Release 2022-03-17 10:07:29 +01:00
Nassim Jahnke 5e22098023 Update adventure, update changelog, fix publishing 2022-03-15 10:44:21 +01:00
Nassim Jahnke 80cc51e48e Update gradle wrapper to 7.4.1 2022-03-09 18:52:43 +01:00
Nassim Jahnke 15ebe045f6 Update language files 2022-03-08 21:47:20 +01:00
Nassim Jahnke be39524717 Minor cleanup 2022-03-08 19:39:36 +01:00
Nassim Jahnke b8616d84c8 Update Gradle wrapper to 7.4, adventure to 4.10.0 2022-03-05 12:14:01 +01:00
Nassim Jahnke 7515d95b82 Merge remote-tracking branch 'origin/dev' into adventure-support
# Conflicts:
#	maintenance-core/src/main/resources/language-de.yml
2022-02-21 09:21:31 +01:00
Ceddix 2c0172d11e fixed spelling issue that caused a message not to work (#75) 2022-02-19 09:32:24 +01:00
Nassim Jahnke 920e3477ee Update default config values 2022-01-19 18:59:21 +01:00
Nassim Jahnke d8e0b6497a Cleanup a bit of language file updating 2022-01-16 19:16:45 +01:00
Nassim Jahnke 113895b564 Fix multiline playercount hover 2022-01-16 16:49:07 +01:00
Nassim Jahnke 99fffb5056 Configurable singleServerMaintenanceListEntry, remove LuckPerm context for now 2022-01-16 15:50:29 +01:00
Nassim Jahnke 3d2aa0ba9c Update language files, update config header 2022-01-16 15:01:04 +01:00
Nassim Jahnke 5486b9542a Update copyright header 2022-01-09 22:31:16 +01:00
Nassim Jahnke 5c2ff9588f Update Sponge module to API v8 2022-01-09 22:27:56 +01:00
Nassim Jahnke 3bcce2dfb9 Fixup dependencies 2022-01-01 14:58:27 +01:00
Nassim Jahnke 0db0d608e5 Improve language updating, add <prefix> placeholder 2021-12-31 16:43:40 +01:00
Nassim Jahnke ae895f4db5 Update workflow 2021-12-28 18:14:43 +01:00
Nassim Jahnke 351d842f3a Major version bump
Convert project to Gradle
Change API class names and split module into two
Add adventure component support
2021-12-28 18:03:34 +01:00
Nassim Jahnke 44dc76f381 WIP LuckPerms contexts 2021-12-28 09:40:29 +01:00
Nassim Jahnke 48792413f7 Update dependencies 2021-12-27 12:12:24 +01:00
Slasherss a81ea8d87d Add polish translations (#73) 2021-12-22 09:45:42 +01:00
Nassim Jahnke ba142a1c31 Update language-es.yml (thanks to Jaximo) 2021-12-07 08:59:31 +01:00
Aurélien f849724a8c Remove extra point (#70) 2021-08-19 22:18:25 +02:00
Aurélien 5e17e60921 Update language-fr.yml (#69) 2021-08-19 22:13:55 +02:00
kennytv fad98d7a14 Update language-pt.yml (thanks to JoaoPinto) 2021-08-18 17:37:25 +02:00
kennytv 31da57c9b2 Bump version to 3.0.8-SNAPSHOT, fix missing scheduletimer keys 2021-08-18 12:54:18 +02:00
186 changed files with 3522 additions and 3293 deletions

No files matched your search

+22
View File
@@ -1,6 +1,28 @@
# Maintenance Changelog
This file contains update logs for this project. The top may contain a `Unreleased` section, gathering update logs for a future update during development.
---
## 4.0.0 - March 17th 2022
### Changed
* Added support for hex colors in messages and replaced the component parsing with adventure-minimessage
* This means that section symbols (`§`) are no longer the intended/supported format
* You can use the following page to edit and preview formatted text: https://webui.adventure.kyori.net/
* You can find full documentation on the format (including normal colors and formatting, rgb, click/hover events, and more) here: https://docs.adventure.kyori.net/minimessage/format
* Your config and language file will be updated to the new format automatically, you won't have to change anything manually!
* Note that the player count and player count hover messages do not support rgb colors
* Updated Sponge module to SpongeAPI v8 (Minecraft 1.15+)
* Changed `%NEWLINE%` replacement to `<br>`
* Changed `enable-timerspecific-messages` to default to `true` in newly generated config files
* Added `prefix` entry in language file to use the placeholder `<prefix>` instead of copy-pasting the actual prefix every time
* Added `singleServerMaintenanceListEntry` language string
* Added Polish translations (thanks to Slasherss1)
* Updated French translations (thanks to Aurelien30000)
* Updated Spanish translations (thanks to Jaximo)
* If you were using the MaintenanceAddon, you need to update it to [version 1.2.0](https://github.com/kennytv/MaintenanceAddon/releases/tag/1.2.0)
### Fixed
* Fixed missing language key warning for the scheduletimer command
* Fixed typo in `singleServerMaintenanceListEmpty` default language string
* Fixed typo in language key `whitelistEmpty` in the German language file (by Ceddix)
---
## 3.0.7 - August 17th 2021
### Changed
+31
View File
@@ -0,0 +1,31 @@
name: Build
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2.4.0
- uses: actions/cache@v2.1.7
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
restore-keys: ${{ runner.os }}-maven-
- name: Set up JDK 11
uses: actions/setup-java@v2.5.0
with:
java-version: 11
distribution: 'temurin'
- name: Build with Gradle
run: ./gradlew build
- name: Upload a Build Artifact
uses: actions/upload-artifact@v2.3.1
with:
name: MaintenanceFiles
path: build/libs
-36
View File
@@ -1,36 +0,0 @@
name: Build
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2.3.4
- uses: actions/cache@v2.1.6
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
restore-keys: ${{ runner.os }}-maven-
- name: Set up JDK 11
uses: actions/setup-java@v2.1.0
with:
java-version: 11
distribution: 'adopt'
- name: Build with Maven
run: mvn -B package --file pom.xml
- name: Upload a Build Artifact
uses: actions/upload-artifact@v2.2.4
with:
name: MaintenanceFiles
path: |
**/Maintenance.jar
**/MaintenanceSpigot.jar
**/MaintenanceBungee.jar
**/MaintenanceVelocity.jar
**/MaintenanceSponge.jar
+2 -1
View File
@@ -1,4 +1,6 @@
.metadata
build/
.gradle
bin/
tmp/
*.tmp
@@ -13,7 +15,6 @@ local.properties
.externalToolBuilders/
*.launch
*.pydevproject
*.jar
.cproject
.classpath
.factorypath
-7
View File
@@ -1,7 +0,0 @@
language: java
jdk:
- oraclejdk8
dist: trusty
cache:
directories:
- '$HOME/.m2/repository'
Binary file not shown.
+24
View File
@@ -0,0 +1,24 @@
plugins {
id("com.github.johnrengelman.shadow")
}
// Shade and relocate adventure in an extra module, so that common/the rest can directly depend on a
// relocated adventure without breaking native platform's adventure usage with project wide relocation
tasks {
shadowJar {
relocate("net.kyori", "eu.kennytv.maintenance.lib.kyori")
}
build {
dependsOn(shadowJar)
}
}
dependencies {
api(libs.bundles.adventure) {
exclude("net.kyori", "adventure-api")
exclude("net.kyori", "adventure-bom")
exclude("com.google.code.gson", "gson")
}
}
publishShadowJar()
@@ -0,0 +1,20 @@
plugins {
id("com.github.johnrengelman.shadow")
}
tasks {
shadowJar {
relocate("net.kyori", "eu.kennytv.maintenance.lib.kyori")
}
build {
dependsOn(shadowJar)
}
}
dependencies {
api(libs.adventurePlatformBukkit) {
exclude("net.kyori", "adventure-api")
}
}
publishShadowJar()
@@ -0,0 +1,20 @@
plugins {
id("com.github.johnrengelman.shadow")
}
tasks {
shadowJar {
relocate("net.kyori", "eu.kennytv.maintenance.lib.kyori")
}
build {
dependsOn(shadowJar)
}
}
dependencies {
api(libs.adventurePlatformBungee) {
exclude("net.kyori", "adventure-api")
}
}
publishShadowJar()
View File
Whitespace-only changes.
+14
View File
@@ -0,0 +1,14 @@
plugins {
id("maintenance.shadow-conventions")
}
dependencies {
api(projects.maintenanceApi)
compileOnly(projects.adventure.adventureApi) {
targetConfiguration = "shadow"
}
}
java {
withJavadocJar()
}
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -22,9 +22,6 @@ import eu.kennytv.maintenance.api.proxy.Server;
/**
* Notification event fired when maintenance mode has been changed on a proxied server.
*
* @author kennytv
* @since 3.0.1
*/
public final class ServerMaintenanceChangedEvent implements MaintenanceEvent {
private final Server server;
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -17,16 +17,12 @@
*/
package eu.kennytv.maintenance.api.proxy;
import eu.kennytv.maintenance.api.IMaintenance;
import eu.kennytv.maintenance.api.Maintenance;
import org.jetbrains.annotations.Nullable;
import java.util.Set;
/**
* @author kennytv
* @since 3.0
*/
public interface IMaintenanceProxy extends IMaintenance {
public interface MaintenanceProxy extends Maintenance {
/**
* Enables/disables maintenance mode on a proxied server.
@@ -63,6 +59,13 @@ public interface IMaintenanceProxy extends IMaintenance {
@Nullable
Server getServer(String server);
/**
* Returns the currently registered proxied servers.
*
* @return set of proxied servers
*/
Set<String> getServers();
/**
* @return immutable set with names of all proxied server that are currently under maintenance
*/
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -17,12 +17,11 @@
*/
package eu.kennytv.maintenance.api.proxy;
import eu.kennytv.maintenance.lib.kyori.adventure.text.Component;
/**
* Wrapper for a proxied server.
* Use {@link IMaintenanceProxy#getServer(String)} to get a server instance.
*
* @author kennytv
* @since 3.0
* Use {@link MaintenanceProxy#getServer(String)} to get a server instance.
*/
public interface Server {
@@ -39,9 +38,9 @@ public interface Server {
/**
* Sends a message to all players on the server.
*
* @param message message to be broadcasted
* @param component message to be broadcasted
*/
void broadcast(String message);
void broadcast(Component component);
/**
* Returns whether the server is registered under the proxy.
+11
View File
@@ -0,0 +1,11 @@
plugins {
id("maintenance.shadow-conventions")
}
dependencies {
compileOnlyApi(libs.jetbrainsAnnotations)
}
java {
withJavadocJar()
}
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -17,13 +17,9 @@
*/
package eu.kennytv.maintenance.api;
import eu.kennytv.maintenance.api.event.manager.IEventManager;
import eu.kennytv.maintenance.api.event.manager.EventManager;
/**
* @author kennytv
* @since 2.1
*/
public interface IMaintenance {
public interface Maintenance {
/**
* Enables/disables maintenance mode.
@@ -53,18 +49,18 @@ public interface IMaintenance {
String getVersion();
/**
* Returns the {@link ISettings} instance, which gives further insight into settings set in the config files.
* Returns the {@link Settings} instance, which gives further insight into settings set in the config files.
*
* @return {@link ISettings} instance
* @return {@link Settings} instance
*/
ISettings getSettings();
Settings getSettings();
/**
* Returns the {@link IEventManager} instance to register listeners to maintenance events.
* Returns the {@link EventManager} instance to register listeners to maintenance events.
*
* @return {@link IEventManager} instance
* @return {@link EventManager} instance
*/
IEventManager getEventManager();
EventManager getEventManager();
/**
* @return true if debug mode is enabled, currently only implemented on Bungee
@@ -0,0 +1,49 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package eu.kennytv.maintenance.api;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
/**
* Provider to get the maintenance api instance.
*/
public final class MaintenanceProvider {
private static Maintenance maintenance;
private MaintenanceProvider() {
throw new IllegalArgumentException();
}
@ApiStatus.Internal
public static void setMaintenance(final Maintenance maintenance) {
if (MaintenanceProvider.maintenance != null) {
throw new IllegalArgumentException("MaintenanceProvider is already set!");
}
MaintenanceProvider.maintenance = maintenance;
}
/**
* Returns the maintenance api instance, or null if not loaded yet.
*
* @return maintenance api instance
*/
public static @Nullable Maintenance get() {
return maintenance;
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,11 +20,7 @@ package eu.kennytv.maintenance.api;
import java.util.Map;
import java.util.UUID;
/**
* @author kennytv
* @since 2.1
*/
public interface ISettings {
public interface Settings {
/**
* Note that the value might need a few seconds to update, if you're on BungeeCord with MySQL enabled
@@ -88,7 +84,7 @@ public interface ISettings {
*
* @param uuid uuid of the player to add
* @param name of the player to add
* @return true if adding the player was successful
* @return true if adding the player was successful, false if already on the whitelist
*/
boolean addWhitelistedPlayer(UUID uuid, String name);
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -21,9 +21,6 @@ import eu.kennytv.maintenance.api.event.manager.MaintenanceEvent;
/**
* Notification event fired when maintenance mode has been changed.
*
* @author kennytv
* @since 3.0.1
*/
public final class MaintenanceChangedEvent implements MaintenanceEvent {
private final boolean maintenance;
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -17,17 +17,15 @@
*/
package eu.kennytv.maintenance.api.event;
import eu.kennytv.maintenance.api.IMaintenance;
import eu.kennytv.maintenance.api.Maintenance;
import eu.kennytv.maintenance.api.event.manager.MaintenanceEvent;
import eu.kennytv.maintenance.api.proxy.IMaintenanceProxy;
/**
* Notification event fired when Maintenance configuration is reloaded.
*
* @author kennytv
* @see IMaintenance#isMaintenance() for the new maintenance status
* @see IMaintenanceProxy#getMaintenanceServers() for the new list of servers under maintenance
* @since 3.0.6
* @see Maintenance#isMaintenance() for the new maintenance status
* //@see MaintenanceProxy#getMaintenanceServers() for the new list of servers under maintenance
*/
public final class MaintenanceReloadedEvent implements MaintenanceEvent {
}
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -21,8 +21,6 @@ package eu.kennytv.maintenance.api.event.manager;
* Abstract class representing a maintenance eventlistener.
*
* @param <T> event to be listened to
* @author kennytv
* @since 3.0.1
*/
public abstract class EventListener<T extends MaintenanceEvent> {
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -17,11 +17,7 @@
*/
package eu.kennytv.maintenance.api.event.manager;
/**
* @author kennytv
* @since 3.0.1
*/
public interface IEventManager {
public interface EventManager {
/**
* Registers an eventlistener for the given maintenance event.
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -19,9 +19,6 @@ package eu.kennytv.maintenance.api.event.manager;
/**
* Dummy interface representing a maintenance event.
*
* @author kennytv
* @since 3.0.1
*/
public interface MaintenanceEvent {
}
+12
View File
@@ -0,0 +1,12 @@
plugins {
`kotlin-dsl`
}
repositories {
gradlePluginPortal()
}
dependencies {
// version must be manually kept in sync with the one in root project settings.gradle.kts
implementation("gradle.plugin.com.github.johnrengelman", "shadow", "7.1.1")
}
+43
View File
@@ -0,0 +1,43 @@
import org.gradle.api.Project
import org.gradle.api.plugins.JavaPluginExtension
import org.gradle.api.publish.PublishingExtension
import org.gradle.api.publish.maven.MavenPublication
import org.gradle.jvm.toolchain.JavaLanguageVersion
import org.gradle.kotlin.dsl.configure
import org.gradle.kotlin.dsl.get
import org.gradle.kotlin.dsl.named
import java.io.ByteArrayOutputStream
fun Project.publishShadowJar() {
configurePublication {
artifact(tasks["shadowJar"])
artifact(tasks["sourcesJar"])
}
}
fun Project.publishJavaComponents() {
configurePublication {
from(components["java"])
}
}
private fun Project.configurePublication(configurer: MavenPublication.() -> Unit) {
extensions.configure<PublishingExtension> {
publications.named<MavenPublication>("mavenJava") {
apply(configurer)
}
}
}
fun Project.latestCommitHash(): String {
val byteOut = ByteArrayOutputStream()
exec {
commandLine = listOf("git", "rev-parse", "--short", "HEAD")
standardOutput = byteOut
}
return byteOut.toString(Charsets.UTF_8.name()).trim()
}
fun JavaPluginExtension.javaTarget(version: Int) {
toolchain.languageVersion.set(JavaLanguageVersion.of(version))
}
@@ -0,0 +1,34 @@
plugins {
`java-library`
`maven-publish`
}
tasks {
// Variable replacements
processResources {
filesMatching(listOf("plugin.yml", "bungee.yml")) {
expand("version" to project.version, "description" to project.description)
}
}
javadoc {
options.encoding = Charsets.UTF_8.name()
(options as StandardJavadocDocletOptions).addStringOption("Xdoclint:none", "-quiet")
}
compileJava {
options.encoding = Charsets.UTF_8.name()
options.compilerArgs.addAll(listOf("-nowarn", "-Xlint:-unchecked", "-Xlint:-deprecation"))
}
}
java {
javaTarget(8)
withSourcesJar()
}
publishing {
publications.create<MavenPublication>("mavenJava") {
groupId = rootProject.group as String
artifactId = project.name
version = rootProject.version as String
}
}
Whitespace-only changes.
@@ -0,0 +1,10 @@
plugins {
id("maintenance.shadow-conventions")
}
tasks {
shadowJar {
archiveFileName.set("Maintenance-${project.name.substringAfter("maintenance-").capitalize()}-${project.version}.jar")
destinationDirectory.set(rootProject.layout.buildDirectory.dir("libs"))
}
}
@@ -0,0 +1,28 @@
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
import org.gradle.jvm.tasks.Jar
import org.gradle.kotlin.dsl.named
plugins {
id("maintenance.base-conventions")
id("com.github.johnrengelman.shadow")
}
tasks {
named<Jar>("jar") {
archiveClassifier.set("unshaded")
from(project.rootProject.file("LICENSE.txt"))
}
val shadowJar = named<ShadowJar>("shadowJar") {
archiveClassifier.set("")
configureRelocations()
}
named("build") {
dependsOn(shadowJar)
}
}
publishShadowJar()
fun ShadowJar.configureRelocations() {
relocate("com.zaxxer.hikari", "eu.kennytv.maintenance.lib.hikari")
}
@@ -0,0 +1,5 @@
plugins {
id("maintenance.base-conventions")
}
publishJavaComponents()
+41
View File
@@ -0,0 +1,41 @@
import org.gradle.api.plugins.JavaPlugin.TEST_IMPLEMENTATION_CONFIGURATION_NAME
plugins {
base
id("maintenance.build-logic")
}
allprojects {
group = "eu.kennytv.maintenance"
version = property("projectVersion") as String // from gradle.properties
description = "Enable maintenance mode with a custom maintenance motd and icon."
}
val platforms = setOf(
projects.maintenanceSpigot,
projects.maintenanceBungee,
projects.maintenanceSponge,
projects.maintenanceVelocity
).map { it.dependencyProject }
val special = setOf(
projects.maintenance,
projects.maintenanceApi,
projects.maintenanceApiProxy,
projects.adventure,
projects.adventure.adventureApi,
projects.adventure.adventurePlatformBukkit,
projects.adventure.adventurePlatformBungee,
).map { it.dependencyProject }
subprojects {
when (this) {
in platforms -> plugins.apply("maintenance.platform-conventions")
in special -> plugins.apply("maintenance.base-conventions")
else -> plugins.apply("maintenance.standard-conventions")
}
dependencies {
TEST_IMPLEMENTATION_CONFIGURATION_NAME("org.junit.jupiter:junit-jupiter-engine:5.8.2")
}
}
+7
View File
@@ -0,0 +1,7 @@
dependencies {
implementation(projects.maintenanceCoreProxy)
implementation(projects.adventure.adventurePlatformBungee) {
targetConfiguration = "shadow"
}
compileOnly(libs.bungee)
}
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -17,13 +17,13 @@
*/
package eu.kennytv.maintenance.bungee;
import eu.kennytv.maintenance.api.IMaintenance;
import eu.kennytv.maintenance.api.IMaintenanceBase;
import eu.kennytv.maintenance.api.Maintenance;
import eu.kennytv.maintenance.core.MaintenanceBase;
import net.md_5.bungee.api.plugin.Plugin;
import java.io.File;
public final class MaintenanceBungeeBase extends Plugin implements IMaintenanceBase {
public final class MaintenanceBungeeBase extends Plugin implements MaintenanceBase {
private MaintenanceBungeePlugin maintenance;
@Override
@@ -37,7 +37,7 @@ public final class MaintenanceBungeeBase extends Plugin implements IMaintenanceB
}
@Override
public IMaintenance getApi() {
public Maintenance getApi() {
return maintenance;
}
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -17,8 +17,6 @@
*/
package eu.kennytv.maintenance.bungee;
import eu.kennytv.maintenance.api.bungee.MaintenanceBungeeAPI;
import eu.kennytv.maintenance.api.proxy.IMaintenanceProxy;
import eu.kennytv.maintenance.api.proxy.Server;
import eu.kennytv.maintenance.bungee.command.MaintenanceBungeeCommand;
import eu.kennytv.maintenance.bungee.command.MaintenanceBungeeCommandBase;
@@ -28,15 +26,19 @@ import eu.kennytv.maintenance.bungee.metrics.MetricsLite;
import eu.kennytv.maintenance.bungee.util.BungeeSenderInfo;
import eu.kennytv.maintenance.bungee.util.BungeeServer;
import eu.kennytv.maintenance.bungee.util.BungeeTask;
import eu.kennytv.maintenance.bungee.util.ComponentUtil;
import eu.kennytv.maintenance.core.dump.PluginDump;
import eu.kennytv.maintenance.core.hook.ServerListPlusHook;
import eu.kennytv.maintenance.core.proxy.MaintenanceProxyPlugin;
import eu.kennytv.maintenance.core.proxy.SettingsProxy;
import eu.kennytv.maintenance.core.proxy.hook.LuckPermsProxyHook;
import eu.kennytv.maintenance.core.proxy.util.ProfileLookup;
import eu.kennytv.maintenance.core.proxy.util.ProxyOfflineSenderInfo;
import eu.kennytv.maintenance.core.util.SenderInfo;
import eu.kennytv.maintenance.core.util.ServerType;
import eu.kennytv.maintenance.core.util.Task;
import eu.kennytv.maintenance.lib.kyori.adventure.platform.bungeecord.BungeeAudiences;
import eu.kennytv.maintenance.lib.kyori.adventure.text.Component;
import net.md_5.bungee.api.CommandSender;
import net.md_5.bungee.api.Favicon;
import net.md_5.bungee.api.ProxyServer;
@@ -44,6 +46,7 @@ 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.chat.hover.content.Text;
import net.md_5.bungee.api.config.ServerInfo;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import net.md_5.bungee.api.plugin.Plugin;
@@ -56,22 +59,22 @@ import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import java.util.logging.Logger;
import java.util.stream.Collectors;
/**
* @author kennytv
* @since 1.0
*/
public final class MaintenanceBungeePlugin extends MaintenanceProxyPlugin {
private final MaintenanceBungeeBase plugin;
private final BungeeAudiences audiences;
private Favicon favicon;
MaintenanceBungeePlugin(final MaintenanceBungeeBase plugin) {
super(plugin.getDescription().getVersion(), ServerType.BUNGEE);
this.plugin = plugin;
this.audiences = BungeeAudiences.create(plugin);
settingsProxy = new SettingsProxy(this);
settings = settingsProxy;
@@ -87,7 +90,6 @@ public final class MaintenanceBungeePlugin extends MaintenanceProxyPlugin {
continueLastEndtimer();
new MetricsLite(plugin);
// ServerListPlus integration
final Plugin serverListPlus = pm.getPlugin("ServerListPlus");
if (serverListPlus != null) {
serverListPlusHook = new ServerListPlusHook(serverListPlus);
@@ -96,11 +98,14 @@ public final class MaintenanceBungeePlugin extends MaintenanceProxyPlugin {
}
plugin.getLogger().info("Enabled ServerListPlus integration!");
}
}
@Deprecated
public static IMaintenanceProxy getAPI() {
return MaintenanceBungeeAPI.getAPI();
if (false && pm.getPlugin("LuckPerms") != null) {
LuckPermsProxyHook.<ProxiedPlayer>register(this, player -> {
final net.md_5.bungee.api.connection.Server server = player.getServer();
return server != null ? server.getInfo().getName() : null;
});
getLogger().info("Registered LuckPerms context");
}
}
@Override
@@ -109,7 +114,7 @@ public final class MaintenanceBungeePlugin extends MaintenanceProxyPlugin {
final TextComponent tc2 = new TextComponent(TextComponent.fromLegacyText("§cDownload it at: §6https://www.spigotmc.org/resources/maintenance.40699/"));
final TextComponent click = new TextComponent(TextComponent.fromLegacyText(" §7§l§o(CLICK ME)"));
click.setClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, "https://www.spigotmc.org/resources/maintenance.40699/"));
click.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder("§aDownload the latest version").create()));
click.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text(new ComponentBuilder("§aDownload the latest version").create())));
tc1.addExtra(tc2);
tc1.addExtra(click);
((BungeeSenderInfo) sender).sendMessage(tc1);
@@ -121,9 +126,9 @@ public final class MaintenanceBungeePlugin extends MaintenanceProxyPlugin {
@Override
protected void kickPlayersFromProxy() {
for (final ProxiedPlayer p : getProxy().getPlayers()) {
if (!hasPermission(p, "bypass") && !settingsProxy.isWhitelisted(p.getUniqueId())) {
p.disconnect(settingsProxy.getKickMessage());
for (final ProxiedPlayer player : getProxy().getPlayers()) {
if (!hasPermission(player, "bypass") && !settingsProxy.isWhitelisted(player.getUniqueId())) {
player.disconnect(ComponentUtil.toBadComponents(settingsProxy.getKickMessage()));
}
}
}
@@ -136,13 +141,13 @@ public final class MaintenanceBungeePlugin extends MaintenanceProxyPlugin {
for (final ProxiedPlayer player : ((BungeeServer) server).getServer().getPlayers()) {
if (!hasPermission(player, "bypass") && !settingsProxy.isWhitelisted(player.getUniqueId())) {
if (checkForFallback && fallbackServer.canAccess(player)) {
player.sendMessage(settingsProxy.getMessage("singleMaintenanceActivated").replace("%SERVER%", server.getName()));
audiences.player(player).sendMessage(settingsProxy.getMessage("singleMaintenanceActivated", "%SERVER%", server.getName()));
player.connect(fallbackServer);
} else {
player.disconnect(settingsProxy.getFullServerKickMessage(server.getName()));
player.disconnect(ComponentUtil.toBadComponents(settingsProxy.getFullServerKickMessage(server.getName())));
}
} else {
player.sendMessage(settingsProxy.getMessage("singleMaintenanceActivated").replace("%SERVER%", server.getName()));
audiences.player(player).sendMessage(settingsProxy.getMessage("singleMaintenanceActivated", "%SERVER%", server.getName()));
}
}
}
@@ -157,10 +162,10 @@ public final class MaintenanceBungeePlugin extends MaintenanceProxyPlugin {
if (player.getServer() != null && player.getServer().getInfo().getName().equals(serverInfo.getName()))
continue;
if (serverInfo.canAccess(player) && !isMaintenance(serverInfo)) {
player.sendMessage(settingsProxy.getMessage("sentToWaitingServer").replace("%SERVER%", server.getName()));
audiences.player(player).sendMessage(settingsProxy.getMessage("sentToWaitingServer", "%SERVER%", server.getName()));
player.connect(serverInfo);
} else {
player.disconnect(settingsProxy.getKickMessage());
player.disconnect(ComponentUtil.toBadComponents(settingsProxy.getKickMessage()));
}
}
}
@@ -170,6 +175,31 @@ public final class MaintenanceBungeePlugin extends MaintenanceProxyPlugin {
return new BungeeTask(getProxy().getScheduler().schedule(plugin, runnable, 0, 1, TimeUnit.SECONDS).getId());
}
@Override
public void getOfflinePlayer(final String name, final Consumer<@Nullable SenderInfo> consumer) {
final ProxiedPlayer player = getProxy().getPlayer(name);
if (player != null) {
consumer.accept(new BungeeSenderInfo(player));
return;
}
getProxy().getScheduler().runAsync(plugin, () -> {
try {
final ProfileLookup profile = doUUIDLookup(name);
consumer.accept(new ProxyOfflineSenderInfo(profile.getUuid(), profile.getName()));
} catch (final IOException e) {
e.printStackTrace();
consumer.accept(null);
}
});
}
@Override
public void getOfflinePlayer(final UUID uuid, final Consumer<@Nullable SenderInfo> consumer) {
final ProxiedPlayer player = getProxy().getPlayer(uuid);
consumer.accept(player != null ? new BungeeSenderInfo(player) : null);
}
@Override
@Nullable
public Server getServer(final String server) {
@@ -178,28 +208,8 @@ public final class MaintenanceBungeePlugin extends MaintenanceProxyPlugin {
}
@Override
@Nullable
public SenderInfo getOfflinePlayer(final String name) {
final ProxiedPlayer player = getProxy().getPlayer(name);
if (player != null) {
return new BungeeSenderInfo(player);
}
final ProfileLookup profile;
try {
profile = doUUIDLookup(name);
} catch (final IOException e) {
e.printStackTrace();
return null;
}
return new ProxyOfflineSenderInfo(profile.getUuid(), profile.getName());
}
@Override
@Nullable
public SenderInfo getOfflinePlayer(final UUID uuid) {
final ProxiedPlayer player = getProxy().getPlayer(uuid);
return player != null ? new BungeeSenderInfo(player) : null;
public Set<String> getServers() {
return getProxy().getServers().keySet();
}
@Override
@@ -221,8 +231,8 @@ public final class MaintenanceBungeePlugin extends MaintenanceProxyPlugin {
}
@Override
public void broadcast(final String message) {
getProxy().broadcast(message);
public void broadcast(final Component component) {
audiences.all().sendMessage(component);
}
@Override
@@ -282,4 +292,8 @@ public final class MaintenanceBungeePlugin extends MaintenanceProxyPlugin {
public Favicon getFavicon() {
return favicon;
}
public BungeeAudiences audiences() {
return audiences;
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -18,6 +18,7 @@
package eu.kennytv.maintenance.bungee.listener;
import eu.kennytv.maintenance.bungee.MaintenanceBungeePlugin;
import eu.kennytv.maintenance.bungee.util.ComponentUtil;
import eu.kennytv.maintenance.core.proxy.SettingsProxy;
import net.md_5.bungee.api.ServerPing;
import net.md_5.bungee.api.event.ProxyPingEvent;
@@ -40,7 +41,7 @@ public final class ProxyPingListener implements Listener {
final ServerPing ping = event.getResponse();
ServerPing.Players players = ping.getPlayers();
if (players == null) {
ping.setPlayers(players = new ServerPing.Players(0, 0, null));
ping.setPlayers(players = new ServerPing.Players(0, 0, null));
}
if (settings.hasCustomPlayerCountMessage()) {
@@ -49,12 +50,12 @@ public final class ProxyPingListener implements Listener {
.replace("%MAX%", Integer.toString(players.getMax())), 1));
}
ping.setDescription(settings.getRandomPingMessage());
ping.setDescriptionComponent(ComponentUtil.toBadComponents(settings.getRandomPingMessage()));
final String[] split = settings.getPlayerCountHoverMessage().split("\n");
final ServerPing.PlayerInfo[] samplePlayers = new ServerPing.PlayerInfo[split.length];
for (int i = 0; i < split.length; i++) {
samplePlayers[i] = new ServerPing.PlayerInfo(split[i], "");
final String[] lines = settings.getPlayerCountHoverLines();
final ServerPing.PlayerInfo[] samplePlayers = new ServerPing.PlayerInfo[lines.length];
for (int i = 0; i < lines.length; i++) {
samplePlayers[i] = new ServerPing.PlayerInfo(lines[i], "");
}
players.setSample(samplePlayers);
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -24,9 +24,8 @@ import eu.kennytv.maintenance.bungee.util.BungeeServer;
import eu.kennytv.maintenance.core.proxy.SettingsProxy;
import eu.kennytv.maintenance.core.proxy.listener.ProxyJoinListenerBase;
import eu.kennytv.maintenance.core.proxy.util.ServerConnectResult;
import eu.kennytv.maintenance.lib.kyori.adventure.text.Component;
import net.md_5.bungee.api.ProxyServer;
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 net.md_5.bungee.api.event.ServerConnectEvent;
import net.md_5.bungee.api.plugin.Listener;
@@ -46,17 +45,17 @@ public final class ServerConnectListener extends ProxyJoinListenerBase implement
// Global maintenance check
if (event.isCancelled() || event.getReason() != ServerConnectEvent.Reason.JOIN_PROXY) return;
final BungeeSenderInfo sender = new BungeeSenderInfo(event.getPlayer());
final BungeeSenderInfo player = new BungeeSenderInfo(event.getPlayer());
if (plugin.isDebug()) {
plugin.getLogger().info("Join permission check for " + event.getPlayer().getName()
+ " - Permission: " + sender.hasMaintenancePermission("bypass") + ", whitelist: " + settings.isWhitelisted(sender.getUuid()));
+ " - Permission: " + player.hasMaintenancePermission("bypass") + ", whitelist: " + settings.isWhitelisted(player.getUuid()));
}
if (shouldKick(sender)) {
final Server waitingServer = shouldConnectToWaitingServer(sender);
if (shouldKick(player)) {
final Server waitingServer = shouldConnectToWaitingServer(player);
if (waitingServer != null) {
event.setTarget(((BungeeServer) waitingServer).getServer());
sender.sendMessage(settings.getMessage("sentToWaitingServer"));
player.send(settings.getMessage("sentToWaitingServer"));
if (plugin.isDebug()) {
plugin.getLogger().info("Join to waiting server for " + event.getPlayer().getName());
@@ -65,9 +64,10 @@ public final class ServerConnectListener extends ProxyJoinListenerBase implement
}
event.setCancelled(true);
event.getPlayer().disconnect(settings.getKickMessage());
player.disconnect(settings.getKickMessage());
if (settings.isJoinNotifications()) {
broadcastJoinNotification(sender.getName());
broadcastJoinNotification(player.getName());
}
}
}
@@ -77,10 +77,11 @@ public final class ServerConnectListener extends ProxyJoinListenerBase implement
// Server specific maintenance check
if (event.isCancelled()) return;
final ProxiedPlayer player = event.getPlayer();
final ProxiedPlayer proxiedPlayer = event.getPlayer();
final boolean normalServerConnect = event.getReason() != ServerConnectEvent.Reason.JOIN_PROXY && event.getReason() != ServerConnectEvent.Reason.KICK_REDIRECT
&& event.getReason() != ServerConnectEvent.Reason.LOBBY_FALLBACK && event.getReason() != ServerConnectEvent.Reason.SERVER_DOWN_REDIRECT;
final ServerConnectResult connectResult = serverConnect(new BungeeSenderInfo(player), new BungeeServer(event.getTarget()), normalServerConnect);
final BungeeSenderInfo player = new BungeeSenderInfo(proxiedPlayer);
final ServerConnectResult connectResult = serverConnect(player, new BungeeServer(event.getTarget()), normalServerConnect);
if (plugin.isDebug()) {
plugin.getLogger().info("Connectresult for " + player.getName() + " to " + event.getTarget().getName() + ": " + connectResult);
}
@@ -89,7 +90,7 @@ public final class ServerConnectListener extends ProxyJoinListenerBase implement
event.setCancelled(true);
// Player has no server to connect to
if (player.getServer() == null) {
if (proxiedPlayer.getServer() == null) {
player.disconnect(settings.getKickMessage());
}
} else if (connectResult.getTarget() != null) {
@@ -108,10 +109,10 @@ public final class ServerConnectListener extends ProxyJoinListenerBase implement
}
private void sendJoinMessage(final Iterable<ProxiedPlayer> players, final String name) {
final BaseComponent[] message = TextComponent.fromLegacyText(settings.getMessage("joinNotification").replace("%PLAYER%", name));
final Component component = settings.getMessage("joinNotification", "%PLAYER%", name);
for (final ProxiedPlayer player : players) {
if (plugin.hasPermission(player, "joinnotification")) {
player.sendMessage(message);
plugin.audiences().player(player).sendMessage(component);
}
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -17,8 +17,11 @@
*/
package eu.kennytv.maintenance.bungee.util;
import eu.kennytv.maintenance.api.MaintenanceProvider;
import eu.kennytv.maintenance.api.proxy.Server;
import eu.kennytv.maintenance.bungee.MaintenanceBungeePlugin;
import eu.kennytv.maintenance.core.proxy.util.ProxySenderInfo;
import eu.kennytv.maintenance.lib.kyori.adventure.text.Component;
import net.md_5.bungee.api.CommandSender;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.api.connection.Connection;
@@ -49,10 +52,16 @@ public final class BungeeSenderInfo implements ProxySenderInfo {
}
@Override
@Deprecated
public void sendMessage(final String message) {
sender.sendMessage(message);
}
@Override
public void send(final Component component) {
((MaintenanceBungeePlugin) MaintenanceProvider.get()).audiences().sender(sender).sendMessage(component);
}
@Override
public boolean isPlayer() {
return sender instanceof ProxiedPlayer;
@@ -68,9 +77,9 @@ public final class BungeeSenderInfo implements ProxySenderInfo {
}
@Override
public void disconnect(final String message) {
public void disconnect(final Component component) {
if (sender instanceof Connection) {
((Connection) sender).disconnect(message);
((Connection) sender).disconnect(ComponentUtil.toBadComponent(component));
}
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -18,8 +18,8 @@
package eu.kennytv.maintenance.bungee.util;
import eu.kennytv.maintenance.api.proxy.Server;
import eu.kennytv.maintenance.lib.kyori.adventure.text.Component;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.api.config.ServerInfo;
import net.md_5.bungee.api.connection.ProxiedPlayer;
@@ -41,10 +41,10 @@ public final class BungeeServer implements Server {
}
@Override
public void broadcast(final String message) {
final BaseComponent[] s = TextComponent.fromLegacyText(message);
for (final ProxiedPlayer p : server.getPlayers()) {
p.sendMessage(s);
public void broadcast(final Component component) {
final BaseComponent[] components = ComponentUtil.toBadComponent(component);
for (final ProxiedPlayer player : server.getPlayers()) {
player.sendMessage(components);
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -0,0 +1,35 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package eu.kennytv.maintenance.bungee.util;
import eu.kennytv.maintenance.lib.kyori.adventure.text.Component;
import eu.kennytv.maintenance.lib.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.chat.ComponentSerializer;
public final class ComponentUtil {
public static BaseComponent[] toBadComponent(final Component component) {
return ComponentSerializer.parse(GsonComponentSerializer.gson().serialize(component));
}
public static BaseComponent toBadComponents(final Component component) {
return new TextComponent(ComponentSerializer.parse(GsonComponentSerializer.gson().serialize(component)));
}
}
@@ -1,7 +1,7 @@
name: Maintenance
version: ${project.version}
version: ${version}
main: eu.kennytv.maintenance.bungee.MaintenanceBungeeBase
author: kennytv
description: Enable maintenance mode with a custom maintenance motd and icon.
softDepends: [ServerListPlus]
description: ${description}
softDepends: [ServerListPlus, LuckPerms]
website: https://www.spigotmc.org/resources/maintenance.40699/
+12
View File
@@ -0,0 +1,12 @@
dependencies {
api(projects.maintenanceApiProxy)
api(projects.maintenanceCore)
implementation(libs.hikariCP)
compileOnly(libs.luckperms)
compileOnly(libs.guava)
compileOnly(libs.gson)
}
java {
withJavadocJar()
}
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,7 +20,7 @@ package eu.kennytv.maintenance.core.proxy;
import com.google.common.io.CharStreams;
import com.google.gson.JsonObject;
import eu.kennytv.maintenance.api.event.proxy.ServerMaintenanceChangedEvent;
import eu.kennytv.maintenance.api.proxy.IMaintenanceProxy;
import eu.kennytv.maintenance.api.proxy.MaintenanceProxy;
import eu.kennytv.maintenance.api.proxy.Server;
import eu.kennytv.maintenance.core.MaintenancePlugin;
import eu.kennytv.maintenance.core.proxy.command.MaintenanceProxyCommand;
@@ -51,7 +51,7 @@ import java.util.concurrent.TimeUnit;
* @author kennytv
* @since 3.0
*/
public abstract class MaintenanceProxyPlugin extends MaintenancePlugin implements IMaintenanceProxy {
public abstract class MaintenanceProxyPlugin extends MaintenancePlugin implements MaintenanceProxy {
private final Map<String, Task> serverTasks = new HashMap<>();
protected SettingsProxy settingsProxy;
@@ -105,7 +105,7 @@ public abstract class MaintenanceProxyPlugin extends MaintenancePlugin implement
}
kickPlayers(server, fallback);
} else {
server.broadcast(settingsProxy.getMessage("singleMaintenanceDeactivated").replace("%SERVER%", server.getName()));
server.broadcast(settingsProxy.getMessage("singleMaintenanceDeactivated", "%SERVER%", server.getName()));
}
cancelSingleTask(server);
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -21,6 +21,7 @@ import eu.kennytv.maintenance.api.proxy.Server;
import eu.kennytv.maintenance.core.Settings;
import eu.kennytv.maintenance.core.config.ConfigSection;
import eu.kennytv.maintenance.core.proxy.mysql.MySQL;
import eu.kennytv.maintenance.lib.kyori.adventure.text.Component;
import org.jetbrains.annotations.Nullable;
import java.sql.SQLException;
@@ -51,7 +52,7 @@ public final class SettingsProxy extends Settings {
this.proxyPlugin = plugin;
}
private void setupMySQL() throws Exception {
private void setupMySQL() {
plugin.getLogger().info("Trying to open database connection... (also, you can simply ignore the SLF4J soft-warning if it shows up)");
final ConfigSection section = config.getSection("mysql");
if (section == null) {
@@ -149,21 +150,21 @@ public final class SettingsProxy extends Settings {
return maintenanceServers.contains(serverName);
}
public String getServerKickMessage(final String server) {
String message = language.getString("singleMaintenanceKicks." + server);
public Component getServerKickMessage(final String server) {
Component message = getMessageOrNull("singleMaintenanceKicks." + server, "%SERVER%", server);
if (message == null) {
message = getMessage("singleMaintenanceKick");
message = getMessage("singleMaintenanceKick", "%SERVER%", server);
}
return plugin.replacePingVariables(message).replace("%SERVER%", server);
return plugin.replacePingVariables(message);
}
// Full = being kicked from the proxy, not just a proxied server
public String getFullServerKickMessage(final String server) {
String message = language.getString("singleMaintenanceKicksComplete." + server);
public Component getFullServerKickMessage(final String server) {
Component message = getMessageOrNull("singleMaintenanceKicksComplete." + server, "%SERVER%", server);
if (message == null) {
message = getMessage("singleMaintenanceKickComplete");
message = getMessage("singleMaintenanceKickComplete", "%SERVER%", server);
}
return plugin.replacePingVariables(message).replace("%SERVER%", server);
return plugin.replacePingVariables(message);
}
public boolean hasMySQL() {
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -62,11 +62,11 @@ public abstract class MaintenanceProxyCommand extends MaintenanceCommand {
public Server checkSingleTimerServerArg(final SenderInfo sender, final String serverName) {
final Server server = plugin.getServer(serverName);
if (server == null) {
sender.sendMessage(settings.getMessage("serverNotFound"));
sender.send(settings.getMessage("serverNotFound"));
return null;
}
if (plugin.isServerTaskRunning(server)) {
sender.sendMessage(settings.getMessage("singleTimerAlreadyRunning"));
sender.send(settings.getMessage("singleTimerAlreadyRunning"));
return null;
}
return server;
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -41,28 +41,28 @@ public final class AbortSingleTimerCommand extends ProxyCommandInfo {
if (args.length == 1) {
if (checkPermission(sender, "timer")) return;
if (!plugin.isTaskRunning()) {
sender.sendMessage(getMessage("timerNotRunning"));
sender.send(getMessage("timerNotRunning"));
return;
}
plugin.cancelTask();
sender.sendMessage(getMessage("timerCancelled"));
sender.send(getMessage("timerCancelled"));
} else if (args.length == 2) {
if (checkPermission(sender, "singleserver.timer")) return;
final Server server = plugin.getServer(args[1]);
if (server == null) {
sender.sendMessage(getMessage("serverNotFound"));
sender.send(getMessage("serverNotFound"));
return;
}
if (!plugin.isServerTaskRunning(server)) {
sender.sendMessage(getMessage("singleTimerNotRunning"));
sender.send(getMessage("singleTimerNotRunning"));
return;
}
plugin.cancelSingleTask(server);
sender.sendMessage(getMessage("singleTimerCancelled"));
sender.send(getMessage("singleTimerCancelled"));
} else
sender.sendMessage(getHelpMessage());
sender.send(getHelpMessage());
}
@Override
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -43,34 +43,34 @@ public final class SingleEndtimerCommand extends ProxyCommandInfo {
if (args.length == 2) {
if (checkPermission(sender, "timer")) return;
if (plugin.getCommandManager().checkTimerArgs(sender, args[1])) {
sender.sendMessage(getHelpMessage());
sender.send(getHelpMessage());
return;
}
if (!plugin.isMaintenance()) {
sender.sendMessage(getMessage("alreadyDisabled"));
sender.send(getMessage("alreadyDisabled"));
return;
}
plugin.startMaintenanceRunnable(Integer.parseInt(args[1]), TimeUnit.MINUTES, false);
sender.sendMessage(getMessage("endtimerStarted").replace("%TIME%", plugin.getRunnable().getTime()));
sender.send(getMessage("endtimerStarted", "%TIME%", plugin.getRunnable().getTime()));
} else if (args.length == 3) {
if (checkPermission(sender, "singleserver.timer")) return;
if (plugin.getCommandManager().checkTimerArgs(sender, args[2], false)) {
sender.sendMessage(getHelpMessage());
sender.send(getHelpMessage());
return;
}
final Server server = plugin.getCommandManager().checkSingleTimerServerArg(sender, args[1]);
if (server == null) return;
if (!plugin.isMaintenance(server)) {
sender.sendMessage(getMessage("singleServerAlreadyDisabled").replace("%SERVER%", server.getName()));
sender.send(getMessage("singleServerAlreadyDisabled", "%SERVER%", server.getName()));
return;
}
final MaintenanceRunnableBase runnable = plugin.startSingleMaintenanceRunnable(server, Integer.parseInt(args[2]), TimeUnit.MINUTES, false);
sender.sendMessage(getMessage("endtimerStarted").replace("%TIME%", runnable.getTime()));
sender.send(getMessage("endtimerStarted", "%TIME%", runnable.getTime()));
} else {
sender.sendMessage(getHelpMessage());
sender.send(getHelpMessage());
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -44,35 +44,35 @@ public final class SingleScheduleTimerCommand extends ProxyCommandInfo {
if (checkPermission(sender, "timer")) return;
if (plugin.getCommandManager().checkTimerArgs(sender, args[1])
|| plugin.getCommandManager().checkTimerArgs(sender, args[2], false)) {
sender.sendMessage(getHelpMessage());
sender.send(getHelpMessage());
return;
}
if (plugin.isMaintenance()) {
sender.sendMessage(getMessage("alreadyEnabled"));
sender.send(getMessage("alreadyEnabled"));
return;
}
plugin.scheduleMaintenanceRunnable(Integer.parseInt(args[1]), Integer.parseInt(args[2]), TimeUnit.MINUTES);
sender.sendMessage(getMessage("starttimerStarted").replace("%TIME%", plugin.getRunnable().getTime()));
sender.send(getMessage("starttimerStarted", "%TIME%", plugin.getRunnable().getTime()));
} else if (args.length == 4) {
if (checkPermission(sender, "singleserver.timer")) return;
if (plugin.getCommandManager().checkTimerArgs(sender, args[2], false)
|| plugin.getCommandManager().checkTimerArgs(sender, args[3], false)) {
sender.sendMessage(getHelpMessage());
sender.send(getHelpMessage());
return;
}
final Server server = plugin.getCommandManager().checkSingleTimerServerArg(sender, args[1]);
if (server == null) return;
if (plugin.isMaintenance(server)) {
sender.sendMessage(getMessage("singleServerAlreadyEnabled").replace("%SERVER%", server.getName()));
sender.send(getMessage("singleServerAlreadyEnabled", "%SERVER%", server.getName()));
return;
}
final MaintenanceRunnableBase runnable = plugin.scheduleSingleMaintenanceRunnable(server, Integer.parseInt(args[2]), Integer.parseInt(args[3]), TimeUnit.MINUTES);
sender.sendMessage(getMessage("starttimerStarted").replace("%TIME%", runnable.getTime()));
sender.send(getMessage("starttimerStarted", "%TIME%", runnable.getTime()));
} else {
sender.sendMessage(getHelpMessage());
sender.send(getHelpMessage());
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -43,34 +43,34 @@ public final class SingleStarttimerCommand extends ProxyCommandInfo {
if (args.length == 2) {
if (checkPermission(sender, "timer")) return;
if (plugin.getCommandManager().checkTimerArgs(sender, args[1])) {
sender.sendMessage(getHelpMessage());
sender.send(getHelpMessage());
return;
}
if (plugin.isMaintenance()) {
sender.sendMessage(getMessage("alreadyEnabled"));
sender.send(getMessage("alreadyEnabled"));
return;
}
plugin.startMaintenanceRunnable(Integer.parseInt(args[1]), TimeUnit.MINUTES, true);
sender.sendMessage(getMessage("starttimerStarted").replace("%TIME%", plugin.getRunnable().getTime()));
sender.send(getMessage("starttimerStarted", "%TIME%", plugin.getRunnable().getTime()));
} else if (args.length == 3) {
if (checkPermission(sender, "singleserver.timer")) return;
if (plugin.getCommandManager().checkTimerArgs(sender, args[2], false)) {
sender.sendMessage(getHelpMessage());
sender.send(getHelpMessage());
return;
}
final Server server = plugin.getCommandManager().checkSingleTimerServerArg(sender, args[1]);
if (server == null) return;
if (plugin.isMaintenance(server)) {
sender.sendMessage(getMessage("singleServerAlreadyEnabled").replace("%SERVER%", server.getName()));
sender.send(getMessage("singleServerAlreadyEnabled", "%SERVER%", server.getName()));
return;
}
final MaintenanceRunnableBase runnable = plugin.startSingleMaintenanceRunnable(server, Integer.parseInt(args[2]), TimeUnit.MINUTES, true);
sender.sendMessage(getMessage("starttimerStarted").replace("%TIME%", runnable.getTime()));
sender.send(getMessage("starttimerStarted", "%TIME%", runnable.getTime()));
} else {
sender.sendMessage(getHelpMessage());
sender.send(getHelpMessage());
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -43,7 +43,7 @@ public final class SingleToggleCommand extends ProxyCommandInfo {
if (checkPermission(sender, "toggle")) return;
final boolean maintenance = args[0].equalsIgnoreCase("on");
if (maintenance == plugin.isMaintenance()) {
sender.sendMessage(getMessage(maintenance ? "alreadyEnabled" : "alreadyDisabled"));
sender.send(getMessage(maintenance ? "alreadyEnabled" : "alreadyDisabled"));
return;
}
@@ -54,26 +54,26 @@ public final class SingleToggleCommand extends ProxyCommandInfo {
Server server = plugin.getServer(args[1]);
if (server == null) {
if (maintenance) {
sender.sendMessage(getMessage("serverNotFound"));
sender.send(getMessage("serverNotFound"));
return;
}
// Let servers be removed from the maintenance list, even if they don't exist on the proxy
server = new DummyServer(args[1]);
if (!plugin.isMaintenance(server)) {
sender.sendMessage(getMessage("serverNotFound"));
sender.send(getMessage("serverNotFound"));
return;
}
}
if (plugin.setMaintenanceToServer(server, maintenance)) {
if (!sender.isPlayer() || !server.getName().equals(plugin.getServerNameOf(sender))) {
sender.sendMessage(getMessage(maintenance ? "singleMaintenanceActivated" : "singleMaintenanceDeactivated").replace("%SERVER%", server.getName()));
sender.send(getMessage(maintenance ? "singleMaintenanceActivated" : "singleMaintenanceDeactivated", "%SERVER%", server.getName()));
}
} else {
sender.sendMessage(getMessage(maintenance ? "singleServerAlreadyEnabled" : "singleServerAlreadyDisabled").replace("%SERVER%", server.getName()));
sender.send(getMessage(maintenance ? "singleServerAlreadyEnabled" : "singleServerAlreadyDisabled", "%SERVER%", server.getName()));
}
} else {
sender.sendMessage(getHelpMessage());
sender.send(getHelpMessage());
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -30,13 +30,13 @@ public final class StatusCommand extends ProxyCommandInfo {
@Override
public void execute(final SenderInfo sender, final String[] args) {
if (getSettings().getMaintenanceServers().isEmpty()) {
sender.sendMessage(getMessage("singleServerMaintenanceListEmpty"));
sender.send(getMessage("singleServerMaintenanceListEmpty"));
return;
}
sender.sendMessage(getMessage("singleServerMaintenanceList"));
sender.send(getMessage("singleServerMaintenanceList"));
for (final String server : getSettings().getMaintenanceServers()) {
sender.sendMessage("§8- §b" + server);
sender.send(getMessage("singleServerMaintenanceListEntry", "%SERVER%", server));
}
}
}
@@ -0,0 +1,78 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package eu.kennytv.maintenance.core.proxy.hook;
import eu.kennytv.maintenance.core.hook.LuckPermsHook;
import eu.kennytv.maintenance.core.proxy.MaintenanceProxyPlugin;
import net.luckperms.api.LuckPermsProvider;
import net.luckperms.api.context.ContextCalculator;
import net.luckperms.api.context.ContextConsumer;
import net.luckperms.api.context.ContextSet;
import net.luckperms.api.context.ImmutableContextSet;
import org.jetbrains.annotations.NotNull;
import java.util.function.Function;
public final class LuckPermsProxyHook {
public static <T> void register(final MaintenanceProxyPlugin plugin, final Function<T, String> function) {
LuckPermsProvider.get().getContextManager().registerCalculator(new MaintenanceProxyCalculator<T>(plugin, function));
}
public static final class MaintenanceProxyCalculator<T> implements ContextCalculator<T> {
private static final String MAINTENANCE_ON_KEY = "is-maintenance-on-";
private static final String ON_MAINTENANCE_SERVER_KEY = "on-maintenance-server";
private final MaintenanceProxyPlugin maintenance;
private final Function<T, String> playerServerFunction;
private MaintenanceProxyCalculator(final MaintenanceProxyPlugin plugin, final Function<T, String> playerServerFunction) {
this.maintenance = plugin;
this.playerServerFunction = playerServerFunction;
}
@Override
public void calculate(@NotNull final T target, @NotNull final ContextConsumer consumer) {
consumer.accept(LuckPermsHook.MaintenanceCalculator.MAINTENANCE_KEY, Boolean.toString(maintenance.isMaintenance()));
/*for (final String serverName : maintenance.getServers()) {
final Server server = maintenance.getServer(serverName);
if (server != null) {
consumer.accept(MAINTENANCE_ON_KEY + server, Boolean.toString(maintenance.isMaintenance(server)));
}
}*/
final String server = playerServerFunction.apply(target);
if (server != null) {
final String value = Boolean.toString(maintenance.getSettingsProxy().isMaintenance(server));
consumer.accept(MAINTENANCE_ON_KEY + server, value);
consumer.accept(ON_MAINTENANCE_SERVER_KEY, value);
}
}
@Override
public ContextSet estimatePotentialContexts() {
final ImmutableContextSet.Builder builder = ImmutableContextSet.builder();
for (final String serverName : maintenance.getServers()) {
final String key = MAINTENANCE_ON_KEY + serverName;
builder.add(key, "true").add(key, "false");
}
return builder.add(ON_MAINTENANCE_SERVER_KEY, "true").add(ON_MAINTENANCE_SERVER_KEY, "false")
.add(LuckPermsHook.MaintenanceCalculator.MAINTENANCE_KEY, "true")
.add(LuckPermsHook.MaintenanceCalculator.MAINTENANCE_KEY, "false").build();
}
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -60,11 +60,11 @@ public abstract class ProxyJoinListenerBase extends JoinListenerBase {
// Player already is on the waiting server
final String currentServer = plugin.getServerNameOf(sender);
if (waitingServer.getName().equals(currentServer)) {
sender.sendMessage(settings.getMessage("forceWaitingServer"));
sender.send(settings.getMessage("forceWaitingServer"));
return DENIED;
}
sender.sendMessage(settings.getMessage("sentToWaitingServer"));
sender.send(settings.getMessage("sentToWaitingServer"));
return new ServerConnectResult(waitingServer);
}
@@ -80,7 +80,7 @@ public abstract class ProxyJoinListenerBase extends JoinListenerBase {
}
if (normalServerConnect) {
sender.sendMessage(settings.getServerKickMessage(target.getName()));
sender.send(settings.getServerKickMessage(target.getName()));
return DENIED;
}
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -17,11 +17,12 @@
*/
package eu.kennytv.maintenance.core.proxy.runnable;
import eu.kennytv.maintenance.api.proxy.IMaintenanceProxy;
import eu.kennytv.maintenance.api.proxy.MaintenanceProxy;
import eu.kennytv.maintenance.api.proxy.Server;
import eu.kennytv.maintenance.core.MaintenancePlugin;
import eu.kennytv.maintenance.core.Settings;
import eu.kennytv.maintenance.core.runnable.MaintenanceRunnableBase;
import eu.kennytv.maintenance.lib.kyori.adventure.text.Component;
public class SingleMaintenanceRunnable extends MaintenanceRunnableBase {
protected final Server server;
@@ -32,22 +33,26 @@ public class SingleMaintenanceRunnable extends MaintenanceRunnableBase {
}
@Override
protected void broadcast(final String message) {
server.broadcast(message);
protected void broadcast(final Component component) {
server.broadcast(component);
}
@Override
protected void finish() {
((IMaintenanceProxy) plugin).setMaintenanceToServer(server, enable);
((MaintenanceProxy) plugin).setMaintenanceToServer(server, enable);
}
@Override
protected String getStartMessage() {
return settings.getMessage("singleStarttimerBroadcast").replace("%TIME%", getTime()).replace("%SERVER%", server.getName());
protected Component getStartMessage() {
return settings.getMessage("singleStarttimerBroadcast",
"%TIME%", getTime(),
"%SERVER%", server.getName());
}
@Override
protected String getEndMessage() {
return settings.getMessage("singleEndtimerBroadcast").replace("%TIME%", getTime()).replace("%SERVER%", server.getName());
protected Component getEndMessage() {
return settings.getMessage("singleEndtimerBroadcast",
"%TIME%", getTime(),
"%SERVER%", server.getName());
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -21,6 +21,7 @@ import eu.kennytv.maintenance.api.proxy.Server;
import eu.kennytv.maintenance.core.MaintenancePlugin;
import eu.kennytv.maintenance.core.Settings;
import eu.kennytv.maintenance.core.proxy.MaintenanceProxyPlugin;
import eu.kennytv.maintenance.lib.kyori.adventure.text.Component;
import java.util.concurrent.TimeUnit;
@@ -39,8 +40,9 @@ public final class SingleMaintenanceScheduleRunnable extends SingleMaintenanceRu
}
@Override
protected String getStartMessage() {
return settings.getMessage("singleScheduletimerBroadcast").replace("%SERVER%", server.getName())
.replace("%TIME%", getTime()).replace("%DURATION%", plugin.getFormattedTime(maintenanceDuration));
protected Component getStartMessage() {
return settings.getMessage("singleScheduletimerBroadcast",
"%SERVER%", server.getName(),
"%TIME%", getTime(), "%DURATION%", plugin.getFormattedTime(maintenanceDuration));
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -18,6 +18,7 @@
package eu.kennytv.maintenance.core.proxy.server;
import eu.kennytv.maintenance.api.proxy.Server;
import eu.kennytv.maintenance.lib.kyori.adventure.text.Component;
public final class DummyServer implements Server {
private final String name;
@@ -37,7 +38,7 @@ public final class DummyServer implements Server {
}
@Override
public void broadcast(final String s) {
public void broadcast(final Component component) {
}
@Override
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -18,6 +18,7 @@
package eu.kennytv.maintenance.core.proxy.util;
import eu.kennytv.maintenance.api.proxy.Server;
import eu.kennytv.maintenance.lib.kyori.adventure.text.Component;
import java.util.UUID;
@@ -36,7 +37,7 @@ public final class ProxyOfflineSenderInfo implements ProxySenderInfo {
}
@Override
public void disconnect(final String message) {
public void disconnect(final Component component) {
}
@Override
@@ -55,9 +56,14 @@ public final class ProxyOfflineSenderInfo implements ProxySenderInfo {
}
@Override
@Deprecated
public void sendMessage(final String message) {
}
@Override
public void send(final Component component) {
}
@Override
public boolean isPlayer() {
return true;
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -19,10 +19,11 @@ package eu.kennytv.maintenance.core.proxy.util;
import eu.kennytv.maintenance.api.proxy.Server;
import eu.kennytv.maintenance.core.util.SenderInfo;
import eu.kennytv.maintenance.lib.kyori.adventure.text.Component;
public interface ProxySenderInfo extends SenderInfo {
boolean canAccess(Server server);
void disconnect(String message);
void disconnect(Component component);
}
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
+24
View File
@@ -0,0 +1,24 @@
plugins {
id("net.kyori.blossom")
}
blossom {
replaceToken("\$VERSION", project.version)
replaceToken("\$IMPL_VERSION", "git-Maintenance-${project.version}:${rootProject.latestCommitHash()}")
}
dependencies {
api(projects.maintenanceApi)
api(projects.adventure.adventureApi) {
targetConfiguration = "shadow"
}
compileOnly(libs.luckperms)
compileOnly(libs.serverlistplus)
compileOnly(libs.guava)
compileOnly(libs.gson)
compileOnly(libs.snakeyaml)
}
java {
withJavadocJar()
}
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -15,18 +15,17 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package eu.kennytv.maintenance.api;
package eu.kennytv.maintenance.core;
/**
* @author kennytv
* @since 2.2.2
*/
public interface IMaintenanceBase {
import eu.kennytv.maintenance.api.Maintenance;
@FunctionalInterface
public interface MaintenanceBase {
/**
* This method is used internally when getting the api instance.
*
* @return {@link IMaintenance} instance
* @return {@link Maintenance} instance
*/
IMaintenance getApi();
Maintenance getApi();
}
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -23,13 +23,13 @@ import com.google.common.io.CharStreams;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;
import eu.kennytv.maintenance.api.IMaintenance;
import eu.kennytv.maintenance.api.Maintenance;
import eu.kennytv.maintenance.api.MaintenanceProvider;
import eu.kennytv.maintenance.api.event.MaintenanceChangedEvent;
import eu.kennytv.maintenance.api.event.manager.IEventManager;
import eu.kennytv.maintenance.api.event.manager.EventManager;
import eu.kennytv.maintenance.core.command.MaintenanceCommand;
import eu.kennytv.maintenance.core.dump.MaintenanceDump;
import eu.kennytv.maintenance.core.dump.PluginDump;
import eu.kennytv.maintenance.core.event.EventManager;
import eu.kennytv.maintenance.core.hook.ServerListPlusHook;
import eu.kennytv.maintenance.core.runnable.MaintenanceRunnable;
import eu.kennytv.maintenance.core.runnable.MaintenanceScheduleRunnable;
@@ -37,6 +37,7 @@ import eu.kennytv.maintenance.core.util.SenderInfo;
import eu.kennytv.maintenance.core.util.ServerType;
import eu.kennytv.maintenance.core.util.Task;
import eu.kennytv.maintenance.core.util.Version;
import eu.kennytv.maintenance.lib.kyori.adventure.text.Component;
import org.jetbrains.annotations.Nullable;
import java.io.BufferedInputStream;
@@ -57,12 +58,13 @@ import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import java.util.logging.Level;
import java.util.logging.Logger;
public abstract class MaintenancePlugin implements IMaintenance {
public abstract class MaintenancePlugin implements Maintenance {
public static final Gson GSON = new GsonBuilder().create();
protected final EventManager eventManager;
protected final eu.kennytv.maintenance.core.event.EventManager eventManager;
protected final Version version;
protected Settings settings;
protected ServerListPlusHook serverListPlusHook;
@@ -77,7 +79,8 @@ public abstract class MaintenancePlugin implements IMaintenance {
this.version = new Version(version);
this.serverType = serverType;
this.prefix = "§8[§eMaintenance" + serverType + "§8] ";
this.eventManager = new EventManager();
this.eventManager = new eu.kennytv.maintenance.core.event.EventManager();
MaintenanceProvider.setMaintenance(this);
}
public void disable() {
@@ -120,28 +123,24 @@ public abstract class MaintenancePlugin implements IMaintenance {
eventManager.callEvent(new MaintenanceChangedEvent(maintenance));
}
public String replacePingVariables(String s) {
if (s.contains("%TIMER%")) {
s = s.replace("%TIMER%", getTimerMessage());
}
if (s.contains("%ONLINE%")) {
s = s.replace("%ONLINE%", Integer.toString(getOnlinePlayers()));
}
if (s.contains("%MAX%")) {
s = s.replace("%MAX%", Integer.toString(getMaxPlayers()));
}
return s;
public Component replacePingVariables(final Component component) {
return component.replaceText(builder -> builder.matchLiteral("%TIMER%").replacement(c -> getTimerMessage()))
.replaceText(builder -> builder.matchLiteral("%ONLINE%").replacement(c -> Component.text(getOnlinePlayers())))
.replaceText(builder -> builder.matchLiteral("%MAX%").replacement(c -> Component.text(getMaxPlayers())));
}
public String getTimerMessage() {
if (!isTaskRunning()) return settings.getMessage("motdTimerNotRunning", "-");
public Component getTimerMessage() {
if (!isTaskRunning()) {
return settings.getMessage("motdTimerNotRunning");
}
final int preHours = runnable.getSecondsLeft() / 60;
final int minutes = preHours % 60;
final int seconds = runnable.getSecondsLeft() % 60;
return settings.getMessage("motdTimer", "%HOURS%:%MINUTES%:%SECONDS%")
.replace("%HOURS%", String.format("%02d", preHours / 60))
.replace("%MINUTES%", String.format("%02d", minutes))
.replace("%SECONDS%", String.format("%02d", seconds));
return settings.getMessage("motdTimer",
"%HOURS%", String.format("%02d", preHours / 60),
"%MINUTES%", String.format("%02d", minutes),
"%SECONDS%", String.format("%02d", seconds));
}
public String getFormattedTime(final int timeSeconds) {
@@ -161,7 +160,7 @@ public abstract class MaintenancePlugin implements IMaintenance {
if (builder.length() != 0) {
builder.append(' ');
}
builder.append(time).append(' ').append(settings.getMessage(time == 1 ? timeUnit : timeUnit + "s"));
builder.append(time).append(' ').append(settings.language.getString(time == 1 ? timeUnit : timeUnit + "s"));
}
public void startMaintenanceRunnable(final long duration, final TimeUnit unit, final boolean enable) {
@@ -216,6 +215,7 @@ public abstract class MaintenancePlugin implements IMaintenance {
final int compare = version.compareTo(newestVersion);
if (compare == -1) {
//TODO mmmmmmmm legacy chat
getLogger().info("§cNewest version available: §aVersion " + newestVersion + "§c, you're on §a" + version);
} else if (compare == 1) {
if (version.getTag().equalsIgnoreCase("snapshot")) {
@@ -336,7 +336,7 @@ public abstract class MaintenancePlugin implements IMaintenance {
try {
uuid = UUID.fromString(s);
} catch (final Exception e) {
sender.sendMessage(settings.getMessage("invalidUuid"));
sender.send(settings.getMessage("invalidUuid"));
return null;
}
return uuid;
@@ -368,7 +368,7 @@ public abstract class MaintenancePlugin implements IMaintenance {
}
@Override
public IEventManager getEventManager() {
public EventManager getEventManager() {
return eventManager;
}
@@ -428,28 +428,28 @@ public abstract class MaintenancePlugin implements IMaintenance {
protected abstract void executeConsoleCommand(String command);
public abstract void broadcast(String message);
public abstract void broadcast(Component component);
public abstract void sendUpdateNotification(SenderInfo sender);
public abstract Task startMaintenanceRunnable(Runnable runnable);
/**
* Returns offline sender info of a player.
* Gets the offline sender info of a player.
* This method may do a web lookup.
*
* @param name name of the player
* @return sender info if found, else null
*/
@Nullable
public abstract SenderInfo getOfflinePlayer(String name);
public abstract void getOfflinePlayer(String name, Consumer<@Nullable SenderInfo> consumer);
@Nullable
public abstract SenderInfo getOfflinePlayer(UUID uuid);
public abstract void getOfflinePlayer(UUID uuid, Consumer<@Nullable SenderInfo> consumer);
public abstract File getDataFolder();
public abstract InputStream getResource(String name);
@Nullable
public InputStream getResource(String name) {
return this.getClass().getClassLoader().getResourceAsStream(name);
}
public abstract Logger getLogger();
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -17,17 +17,22 @@
*/
package eu.kennytv.maintenance.core;
import eu.kennytv.maintenance.api.ISettings;
import eu.kennytv.maintenance.api.event.MaintenanceReloadedEvent;
import eu.kennytv.maintenance.core.config.Config;
import eu.kennytv.maintenance.core.config.ConfigSection;
import eu.kennytv.maintenance.core.util.ServerType;
import eu.kennytv.maintenance.lib.kyori.adventure.text.Component;
import eu.kennytv.maintenance.lib.kyori.adventure.text.TextComponent;
import eu.kennytv.maintenance.lib.kyori.adventure.text.TextReplacementConfig;
import eu.kennytv.maintenance.lib.kyori.adventure.text.minimessage.MiniMessage;
import eu.kennytv.maintenance.lib.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -36,20 +41,23 @@ import java.util.Random;
import java.util.Set;
import java.util.UUID;
public class Settings implements ISettings {
private static final int CURRENT_CONFIG_VERSION = 5;
public class Settings implements eu.kennytv.maintenance.api.Settings {
public static final String NEW_LINE_REPLACEMENT = "<br>";
private static final int CONFIG_VERSION = 6;
private static final int LANGUAGE_VERSION = 1;
private static final Random RANDOM = new Random();
protected final MaintenancePlugin plugin;
private final Map<UUID, String> whitelistedPlayers = new HashMap<>();
private final String[] unsupportedFields;
protected boolean maintenance;
private Set<Integer> broadcastIntervals;
private List<String> pingMessages;
private List<String> timerSpecificPingMessages;
private List<Component> pingMessages;
private List<Component> timerSpecificPingMessages;
private List<String> commandsOnMaintenanceEnable;
private List<String> commandsOnMaintenanceDisable;
private String playerCountMessage;
private String playerCountHoverMessage;
private Component playerCountMessage;
private List<Component> playerCountHoverLines;
private Component prefix;
private String languageName;
private boolean enablePingMessages;
private boolean customPlayerCountMessage;
@@ -87,8 +95,8 @@ public class Settings implements ISettings {
config.resetAwesomeHeader();
whitelist = new Config(new File(plugin.getDataFolder(), "WhitelistedPlayers.yml"));
whitelist.load();
} catch (final IOException e) {
throw new RuntimeException("Unable to load Maintenance files!", e);
} catch (final Exception e) {
throw new RuntimeException("Unable to load Maintenance files - probably a malformed config file", e);
}
loadSettings();
@@ -98,27 +106,21 @@ public class Settings implements ISettings {
language = new Config(new File(plugin.getDataFolder(), "language-" + languageName + ".yml"));
language.load();
} catch (final IOException e) {
throw new RuntimeException("Unable to load Maintenance language file!", e);
throw new RuntimeException("Unable to load Maintenance language file - probably a malformed file", e);
}
updateLanguageFile();
try {
updateLanguageFile();
} catch (final IOException e) {
plugin.getLogger().severe("Couldn't update language file");
e.printStackTrace();
}
// Directly cache colored messages - this should not be saved!
transformColoredMessages(language.getValues());
prefix = MiniMessage.miniMessage().deserialize(language.getString("prefix"));
plugin.getEventManager().callEvent(new MaintenanceReloadedEvent());
}
private void transformColoredMessages(final Map<String, Object> map) {
for (final Map.Entry<String, Object> entry : map.entrySet()) {
if (entry.getValue() instanceof Map) {
transformColoredMessages((Map<String, Object>) entry.getValue());
} else if (entry.getValue() instanceof String) {
entry.setValue(getColoredString(replaceNewlineVar((String) entry.getValue())));
}
}
}
public void saveConfig() {
try {
config.save();
@@ -173,9 +175,9 @@ public class Settings implements ISettings {
updateConfig();
enablePingMessages = config.getBoolean("enable-pingmessages", true);
pingMessages = config.getStringList("pingmessages");
pingMessages = loadPingMessages("pingmessages");
if (config.getBoolean("enable-timerspecific-messages")) {
timerSpecificPingMessages = config.getStringList("timerspecific-pingmessages");
timerSpecificPingMessages = loadPingMessages("timerspecific-pingmessages");
}
maintenance = config.getBoolean("maintenance-enabled");
commandsOnMaintenanceEnable = config.getStringList("commands-on-maintenance-enable");
@@ -185,10 +187,16 @@ public class Settings implements ISettings {
joinNotifications = config.getBoolean("send-join-notification");
broadcastIntervals = new HashSet<>(config.getIntList("timer-broadcast-for-seconds"));
if (plugin.getServerType() != ServerType.SPONGE) {
playerCountMessage = getColoredString(getConfigString("playercountmessage"));
playerCountMessage = getConfigMessage("playercountmessage");
}
playerCountHoverMessage = replaceNewlineVar(getColoredString(getConfigString("playercounthovermessage")));
languageName = getConfigString("language").toLowerCase();
playerCountHoverLines = new ArrayList<>();
final String playerHoverMessage = config.getString("playercounthovermessage");
for (final String line : playerHoverMessage.split("<br>")) {
playerCountHoverLines.add(MiniMessage.miniMessage().deserialize(line));
}
languageName = config.getString("language").toLowerCase();
kickOnlinePlayers = config.getBoolean("kick-online-players", true);
updateChecks = config.getBoolean("update-checks", true);
debug = config.getBoolean("debug");
@@ -215,14 +223,15 @@ public class Settings implements ISettings {
private void updatePluginDirectory() {
// All plugin identifiers were changed to 'Maintenance' ('maintenance' for Sponge and Velocity) in 3.0.5
// Don't worry, this is only checked if no plugin folder is found
String oldDirName = "Maintenance" + plugin.getServerType();
if (plugin.getServerType() == ServerType.SPONGE || plugin.getServerType() == ServerType.VELOCITY) {
oldDirName = oldDirName.toLowerCase();
}
final File oldDir = new File(plugin.getDataFolder().getParentFile(), oldDirName);
if (!oldDir.exists()) return;
if (!oldDir.exists()) {
return;
}
try {
Files.move(oldDir.toPath(), plugin.getDataFolder().toPath());
@@ -234,11 +243,17 @@ public class Settings implements ISettings {
}
private void updateConfig() {
boolean changed = false;
final int version = config.getInt("config-version");
if (version != CONFIG_VERSION) {
plugin.getLogger().info("Updating config to the latest version...");
if (version < 6) {
// Legacy text to MiniMessage
legacyToMinimessage(config.getStringList("pingmessages"));
legacyToMinimessage(config.getStringList("timerspecific-pingmessages"));
config.set("playercounthovermessage", legacyToMinimessage(config.getString("playercounthovermessage")));
config.set("playercountmessage", legacyToMinimessage(config.getString("playercountmessage")));
}
// Update config to latest version (config version included since 3.0.1)
if (config.getInt("config-version") != CURRENT_CONFIG_VERSION) {
plugin.getLogger().info("Updating config to latest version...");
createFile("config-new.yml", "config.yml");
final File file = new File(plugin.getDataFolder(), "config-new.yml");
final Config tempConfig = new Config(file, unsupportedFields);
@@ -249,108 +264,132 @@ public class Settings implements ISettings {
}
config.addMissingFields(tempConfig.getValues(), tempConfig.getComments());
config.set("config-version", CURRENT_CONFIG_VERSION);
config.set("config-version", CONFIG_VERSION);
file.delete();
tempConfig.clear();
changed = true;
}
if (changed) {
saveConfig();
plugin.getLogger().info("Done! Updated config!");
}
}
private void updateLanguageFile() {
final String filePrefix = "language-" + languageName;
try {
createFile(filePrefix + "-new.yml", filePrefix + ".yml");
} catch (final NullPointerException e) {
plugin.getLogger().info("Not checking for updated language strings, since there is no " + filePrefix + ".yml in the resource files (if your file is self translated and up to date, you can ignore this).");
return;
} catch (final Exception e) {
plugin.getLogger().warning("Couldn't update language file, as the " + filePrefix + ".yml could not be loaded from the resource files!");
e.printStackTrace();
private void updateLanguageFile() throws IOException {
final int version = language.getInt("language-version");
if (version == LANGUAGE_VERSION) {
return;
}
plugin.getLogger().info("Updating language file to the latest version...");
if (version < 1) {
for (final Map.Entry<String, Object> entry : language.getValues().entrySet()) {
if (!(entry.getValue() instanceof String)) {
continue;
}
String value = (String) entry.getValue();
value = value.replace("&8[&eMaintenance&8] ", "<prefix>");
value = legacyToMinimessage(value);
value = value.replace("%NEWLINE%", NEW_LINE_REPLACEMENT);
language.set(entry.getKey(), value);
}
}
final String filePrefix = "language-" + languageName;
createFile(filePrefix + "-new.yml", filePrefix + ".yml");
final File file = new File(plugin.getDataFolder(), filePrefix + "-new.yml");
final Config tempConfig = new Config(file);
try {
tempConfig.load();
} catch (final IOException e) {
e.printStackTrace();
return;
} finally {
file.delete();
}
final boolean updated = language.addMissingFields(tempConfig.getValues(), tempConfig.getComments());
language.addMissingFields(tempConfig.getValues(), tempConfig.getComments());
tempConfig.clear();
file.delete();
if (updated) {
try {
language.save();
plugin.getLogger().info("Updated language file!");
} catch (final IOException e) {
e.printStackTrace();
}
language.set("language-version", LANGUAGE_VERSION);
language.save();
plugin.getLogger().info("Updated language file!");
}
private String legacyToMinimessage(final String s) {
final TextComponent component = LegacyComponentSerializer.legacyAmpersand().deserialize(s);
final String serialized = MiniMessage.miniMessage().serialize(component);
//TODO hack to remove explicit closing until fixed in MM
return serialized.replaceAll("</[a-z_]+>", "");
}
private void legacyToMinimessage(final List<String> list) {
for (int i = 0; i < list.size(); i++) {
list.set(i, legacyToMinimessage(list.get(i)));
}
}
private static final String ALL_CODES = "0123456789AaBbCcDdEeFfKkLlMmNnOoRr";
public String getColoredString(final String s) {
// Method taken from Bungee
final char[] b = s.toCharArray();
for (int i = 0; i < b.length - 1; i++) {
if (b[i] == '&' && ALL_CODES.indexOf(b[i + 1]) > -1) {
b[i] = '§';
b[i + 1] = Character.toLowerCase(b[i + 1]);
}
}
return new String(b);
}
public String getConfigString(final String path) {
public Component getConfigMessage(final String path) {
final String s = config.getString(path);
if (s == null) {
plugin.getLogger().warning("The config is missing the following string: " + path);
return "null";
plugin.getLogger().warning("The config file is missing the following string: " + path);
return Component.text("null");
}
return s;
return MiniMessage.miniMessage().deserialize(replaceNewlineVar(s));
}
public String getMessage(final String path) {
return getMessage(path, "null");
}
public String getMessage(final String path, final String def) {
final String s = language.getString(path);
public Component getMessage(final String path, final String... replacements) {
String s = language.getString(path);
if (s == null) {
plugin.getLogger().warning("The language file is missing the following string: " + path);
return def;
return Component.text("null");
}
return s;
if (replacements.length != 0) {
if (replacements.length % 2 != 0) {
throw new IllegalArgumentException("Invalid replacement count: " + replacements.length);
}
for (int i = 0; i < replacements.length; i += 2) {
final String key = replacements[i];
s = s.replace(key, replacements[i + 1]);
}
}
return MiniMessage.miniMessage().deserialize(replaceNewlineVar(s))
.replaceText(TextReplacementConfig.builder().matchLiteral("<prefix>").replacement(prefix).build());
}
public String getRandomPingMessage() {
public @Nullable Component getMessageOrNull(final String path, final String... replacements) {
return language.contains(path) ? getMessage(path, replacements) : null;
}
public Component getRandomPingMessage() {
if (plugin.isTaskRunning() && !plugin.getRunnable().shouldEnable()
&& hasTimerSpecificPingMessages() && !timerSpecificPingMessages.isEmpty()) {
return getPingMessage(timerSpecificPingMessages);
}
return pingMessages.isEmpty() ? "" : getPingMessage(pingMessages);
return pingMessages.isEmpty() ? Component.empty() : getPingMessage(pingMessages);
}
private String getPingMessage(final List<String> list) {
final String s = list.size() == 1 ? list.get(0) : list.get(RANDOM.nextInt(list.size()));
return getColoredString(replaceNewlineVar(plugin.replacePingVariables(s)));
private Component getPingMessage(final List<Component> list) {
final Component component = list.size() == 1 ? list.get(0) : list.get(RANDOM.nextInt(list.size()));
return plugin.replacePingVariables(component);
}
private List<Component> loadPingMessages(final String path) {
final List<String> list = config.getStringList(path);
final List<Component> components = new ArrayList<>(list.size());
for (final String s : list) {
components.add(MiniMessage.miniMessage().deserialize(replaceNewlineVar(s)));
}
return components;
}
@Override
public boolean removeWhitelistedPlayer(final UUID uuid) {
if (!whitelistedPlayers.containsKey(uuid)) return false;
whitelistedPlayers.remove(uuid);
if (whitelistedPlayers.remove(uuid) == null) {
return false;
}
whitelist.remove(uuid.toString());
saveWhitelistedPlayers();
return true;
@@ -367,7 +406,9 @@ public class Settings implements ISettings {
}
}
if (uuid == null) return false;
if (uuid == null) {
return false;
}
whitelistedPlayers.remove(uuid);
whitelist.remove(uuid.toString());
@@ -377,11 +418,10 @@ public class Settings implements ISettings {
@Override
public boolean addWhitelistedPlayer(final UUID uuid, final String name) {
final boolean contains = !whitelistedPlayers.containsKey(uuid);
whitelistedPlayers.put(uuid, name);
final boolean added = whitelistedPlayers.put(uuid, name) == null;
whitelist.set(uuid.toString(), name);
saveWhitelistedPlayers();
return contains;
return added;
}
@Override
@@ -454,8 +494,7 @@ public class Settings implements ISettings {
return config;
}
// The ping messages still contain the %NEWLINE% (if they have 2 lines)
public List<String> getPingMessages() {
public List<Component> getPingMessages() {
return pingMessages;
}
@@ -468,7 +507,7 @@ public class Settings implements ISettings {
}
@Nullable
public List<String> getTimerSpecificPingMessages() {
public List<Component> getTimerSpecificPingMessages() {
return timerSpecificPingMessages;
}
@@ -476,15 +515,21 @@ public class Settings implements ISettings {
return broadcastIntervals;
}
// Yikeseroo
public String getPlayerCountMessage() {
return plugin.replacePingVariables(playerCountMessage);
return LegacyComponentSerializer.legacySection().serialize(plugin.replacePingVariables(playerCountMessage));
}
public String getPlayerCountHoverMessage() {
return plugin.replacePingVariables(playerCountHoverMessage);
public String[] getPlayerCountHoverLines() {
final String[] lines = new String[playerCountHoverLines.size()];
for (int i = 0; i < playerCountHoverLines.size(); i++) {
final Component component = plugin.replacePingVariables(playerCountHoverLines.get(i));
lines[i] = LegacyComponentSerializer.legacySection().serialize(component);
}
return lines;
}
public String getKickMessage() {
public Component getKickMessage() {
return plugin.replacePingVariables(getMessage("kickmessage"));
}
@@ -503,11 +548,11 @@ public class Settings implements ISettings {
* Second line text.
* ...
*
* This also happens to string lists, making those practically unreadable (in partciular the motd list), as well as confusing for most users in general.
* Because of this, I replace %NEWLINE% manually, to spare users from these ugly breaks.
* This also happens to string lists, making those practically unreadable (in particular the motd list), as well as confusing for most users in general.
* Because of this, I replace <br> manually, to spare users from these ugly breaks (before I inevitably switch to a different configuration library).
*/
protected String replaceNewlineVar(final String s) {
return s.replace("%NEWLINE%", "\n");
return s.replace(NEW_LINE_REPLACEMENT, "\n");
}
protected void loadExtraSettings() {
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,6 +20,7 @@ package eu.kennytv.maintenance.core.command;
import eu.kennytv.maintenance.core.MaintenancePlugin;
import eu.kennytv.maintenance.core.Settings;
import eu.kennytv.maintenance.core.util.SenderInfo;
import eu.kennytv.maintenance.lib.kyori.adventure.text.Component;
import org.jetbrains.annotations.Nullable;
import java.util.Collections;
@@ -51,7 +52,7 @@ public abstract class CommandInfo {
return visible;
}
public String getHelpMessage() {
public Component getHelpMessage() {
return getMessage(helpMessageKey);
}
@@ -63,7 +64,7 @@ public abstract class CommandInfo {
protected boolean checkPermission(final SenderInfo sender, final String permission) {
if (!sender.hasMaintenancePermission(permission)) {
sender.sendMessage(getMessage("noPermission"));
sender.send(getMessage("noPermission"));
return true;
}
return false;
@@ -71,14 +72,14 @@ public abstract class CommandInfo {
protected boolean checkArgs(final SenderInfo sender, final String[] args, final int length) {
if (args.length != length) {
sender.sendMessage(getHelpMessage());
sender.send(getHelpMessage());
return true;
}
return false;
}
protected String getMessage(final String s) {
return plugin.getSettings().getMessage(s);
protected Component getMessage(final String path, final String... replacements) {
return plugin.getSettings().getMessage(path, replacements);
}
protected Settings getSettings() {
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -85,7 +85,7 @@ public abstract class MaintenanceCommand {
public void execute(final SenderInfo sender, final String[] args) {
if (!sender.hasMaintenancePermission("command")) {
sender.sendMessage(settings.getMessage("noPermission"));
sender.send(settings.getMessage("noPermission"));
return;
}
if (args.length == 0) {
@@ -99,7 +99,7 @@ public abstract class MaintenanceCommand {
return;
}
if (!command.hasPermission(sender)) {
sender.sendMessage(settings.getMessage("noPermission"));
sender.send(settings.getMessage("noPermission"));
return;
}
@@ -129,14 +129,14 @@ public abstract class MaintenanceCommand {
if (!plugin.isNumeric(time)) return true;
if (taskCheck) {
if (plugin.isTaskRunning()) {
sender.sendMessage(settings.getMessage("timerAlreadyRunning"));
sender.send(settings.getMessage("timerAlreadyRunning"));
return true;
}
}
final int minutes = Integer.parseInt(time);
if (minutes > 40320) {
sender.sendMessage(settings.getMessage("timerTooLong"));
sender.send(settings.getMessage("timerTooLong"));
return true;
}
if (minutes < 1) {
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -30,16 +30,16 @@ public final class AbortTimerCommand extends CommandInfo {
@Override
public void execute(final SenderInfo sender, final String[] args) {
if (args.length != 1) {
sender.sendMessage(getHelpMessage());
sender.send(getHelpMessage());
return;
}
if (!plugin.isTaskRunning()) {
sender.sendMessage(getMessage("timerNotRunning"));
sender.send(getMessage("timerNotRunning"));
return;
}
plugin.cancelTask();
sender.sendMessage(getMessage("timerCancelled"));
sender.send(getMessage("timerCancelled"));
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -33,15 +33,15 @@ public final class EndtimerCommand extends CommandInfo {
public void execute(final SenderInfo sender, final String[] args) {
if (checkArgs(sender, args, 2)) return;
if (plugin.getCommandManager().checkTimerArgs(sender, args[1])) {
sender.sendMessage(getHelpMessage());
sender.send(getHelpMessage());
return;
}
if (!plugin.isMaintenance()) {
sender.sendMessage(getMessage("alreadyDisabled"));
sender.send(getMessage("alreadyDisabled"));
return;
}
plugin.startMaintenanceRunnable(Integer.parseInt(args[1]), TimeUnit.MINUTES, false);
sender.sendMessage(getMessage("endtimerStarted").replace("%TIME%", plugin.getRunnable().getTime()));
sender.send(getMessage("endtimerStarted", "%TIME%", plugin.getRunnable().getTime()));
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -21,6 +21,7 @@ import com.google.common.base.Preconditions;
import eu.kennytv.maintenance.core.MaintenancePlugin;
import eu.kennytv.maintenance.core.command.CommandInfo;
import eu.kennytv.maintenance.core.util.SenderInfo;
import eu.kennytv.maintenance.lib.kyori.adventure.text.Component;
import java.util.ArrayList;
import java.util.List;
@@ -35,7 +36,7 @@ public final class HelpCommand extends CommandInfo {
@Override
public void execute(final SenderInfo sender, final String[] args) {
if (args.length > 2) {
sender.sendMessage(getHelpMessage());
sender.send(getHelpMessage());
return;
}
@@ -45,7 +46,7 @@ public final class HelpCommand extends CommandInfo {
}
if (!plugin.isNumeric(args[1])) {
sender.sendMessage(getHelpMessage());
sender.send(getHelpMessage());
return;
}
@@ -59,35 +60,37 @@ public final class HelpCommand extends CommandInfo {
public void sendUsage(final SenderInfo sender, final int page) {
Preconditions.checkArgument(page > 0);
final List<String> commands = new ArrayList<>();
final List<Component> commands = new ArrayList<>();
for (final CommandInfo cmd : plugin.getCommandManager().getCommands()) {
if (cmd.isVisible() && cmd.hasPermission(sender)) {
commands.add(cmd.getHelpMessage());
}
}
if ((page - 1) * COMMANDS_PER_PAGE >= commands.size()) {
sender.sendMessage(getMessage("helpPageNotFound"));
sender.send(getMessage("helpPageNotFound"));
return;
}
final List<String> filteredCommands = commands.subList((page - 1) * COMMANDS_PER_PAGE, Math.min(page * COMMANDS_PER_PAGE, commands.size()));
final List<Component> filteredCommands = commands.subList((page - 1) * COMMANDS_PER_PAGE, Math.min(page * COMMANDS_PER_PAGE, commands.size()));
final String header = getMessage("helpHeader").replace("%NAME%", "Maintenance" + plugin.getServerType())
.replace("%PAGE%", Integer.toString(page)).replace("%MAX%", Integer.toString((commands.size() + getDivide(commands.size())) / COMMANDS_PER_PAGE));
sender.sendMessage("");
sender.sendMessage(header);
for (final String command : filteredCommands) {
sender.sendMessage(command);
final Component header = getMessage("helpHeader",
"%NAME%", "Maintenance" + plugin.getServerType(),
"%PAGE%", Integer.toString(page),
"%MAX%", Integer.toString((commands.size() + getDivide(commands.size())) / COMMANDS_PER_PAGE));
sender.send(Component.empty());
sender.send(header);
for (final Component command : filteredCommands) {
sender.send(command);
}
if (page * COMMANDS_PER_PAGE < commands.size()) {
sender.sendMessage(getMessage("helpNextPage").replace("%PAGE%", Integer.toString(page + 1)));
sender.send(getMessage("helpNextPage", "%PAGE%", Integer.toString(page + 1)));
} else {
sender.sendMessage("§8× §eVersion " + plugin.getVersion() + " §7by §bkennytv");
}
sender.sendMessage(header);
sender.sendMessage("");
sender.send(header);
sender.send(Component.empty());
}
private int getDivide(final int size) {
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,6 +20,8 @@ package eu.kennytv.maintenance.core.command.subcommand;
import eu.kennytv.maintenance.core.MaintenancePlugin;
import eu.kennytv.maintenance.core.command.CommandInfo;
import eu.kennytv.maintenance.core.util.SenderInfo;
import eu.kennytv.maintenance.lib.kyori.adventure.text.Component;
import eu.kennytv.maintenance.lib.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import java.util.Collections;
import java.util.List;
@@ -36,28 +38,26 @@ public final class MotdCommand extends CommandInfo {
sendList(sender, getSettings().getPingMessages());
} else if (args.length == 2 && args[1].equalsIgnoreCase("timer")) {
if (!getSettings().hasTimerSpecificPingMessages()) {
sender.sendMessage(getMessage("timerMotdDisabled"));
sender.send(getMessage("timerMotdDisabled"));
return;
}
sendList(sender, getSettings().getTimerSpecificPingMessages());
} else {
sender.sendMessage(getHelpMessage());
sender.send(getHelpMessage());
}
}
private void sendList(final SenderInfo sender, final List<String> list) {
private void sendList(final SenderInfo sender, final List<Component> list) {
if (list == null || list.isEmpty()) {
sender.sendMessage(getMessage("motdListEmpty"));
sender.send(getMessage("motdListEmpty"));
return;
}
sender.sendMessage(getMessage("motdList"));
sender.send(getMessage("motdList"));
for (int i = 0; i < list.size(); i++) {
sender.sendMessage("§b" + (i + 1) + "§8§m---------");
for (final String motd : getSettings().getColoredString(list.get(i)).split("%NEWLINE%")) {
sender.sendMessage(motd);
}
sender.send(list.get(i));
}
sender.sendMessage("§8§m----------");
}
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -31,6 +31,6 @@ public final class ReloadCommand extends CommandInfo {
public void execute(final SenderInfo sender, final String[] args) {
if (checkArgs(sender, args, 1)) return;
getSettings().reloadConfigs();
sender.sendMessage(getMessage("reload"));
sender.send(getMessage("reload"));
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -21,6 +21,7 @@ import eu.kennytv.maintenance.core.MaintenancePlugin;
import eu.kennytv.maintenance.core.Settings;
import eu.kennytv.maintenance.core.command.CommandInfo;
import eu.kennytv.maintenance.core.util.SenderInfo;
import eu.kennytv.maintenance.lib.kyori.adventure.text.Component;
import java.util.ArrayList;
import java.util.Collections;
@@ -37,7 +38,7 @@ public final class RemoveMotdCommand extends CommandInfo {
boolean timerPingMessages = false;
if (args.length == 3 && args[1].equalsIgnoreCase("timer")) {
if (!getSettings().hasTimerSpecificPingMessages()) {
sender.sendMessage(getMessage("timerMotdDisabled"));
sender.send(getMessage("timerMotdDisabled"));
return;
}
@@ -46,28 +47,31 @@ public final class RemoveMotdCommand extends CommandInfo {
}
if (checkArgs(sender, args, 2)) return;
if (!plugin.isNumeric(args[1])) {
sender.sendMessage(getHelpMessage());
sender.send(getHelpMessage());
return;
}
final Settings settings = getSettings();
final List<String> pingMessages = timerPingMessages ? settings.getTimerSpecificPingMessages() : settings.getPingMessages();
final List<String> pingMessages = settings.getConfig().getStringList(timerPingMessages ? "timerspecific-pingmessages" : "pingmessages");
if (pingMessages.size() < 2) {
sender.sendMessage(getMessage("removeMotdError"));
sender.send(getMessage("removeMotdError"));
return;
}
final int index = Integer.parseInt(args[1]);
if (index == 0 || index > pingMessages.size()) {
sender.sendMessage(getMessage("setMotdIndexError").replace("%MOTDS%", Integer.toString(pingMessages.size()))
.replace("%NEWAMOUNT%", Integer.toString(pingMessages.size())));
sender.send(getMessage("setMotdIndexError",
"%MOTDS%", Integer.toString(pingMessages.size()),
"%NEWAMOUNT%", Integer.toString(pingMessages.size())));
return;
}
final List<Component> pingComponents = timerPingMessages ? settings.getTimerSpecificPingMessages() : settings.getPingMessages();
pingComponents.remove(index - 1);
pingMessages.remove(index - 1);
settings.getConfig().set(timerPingMessages ? "timerspecific-pingmessages" : "pingmessages", pingMessages);
settings.saveConfig();
sender.sendMessage(getMessage("removedMotd").replace("%INDEX%", args[1]));
sender.send(getMessage("removedMotd", "%INDEX%", args[1]));
}
@Override
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -34,15 +34,15 @@ public final class ScheduleTimerCommand extends CommandInfo {
if (checkArgs(sender, args, 3)) return;
if (plugin.getCommandManager().checkTimerArgs(sender, args[1])
|| plugin.getCommandManager().checkTimerArgs(sender, args[2], false)) {
sender.sendMessage(getHelpMessage());
sender.send(getHelpMessage());
return;
}
if (plugin.isMaintenance()) {
sender.sendMessage(getMessage("alreadyEnabled"));
sender.send(getMessage("alreadyEnabled"));
return;
}
plugin.scheduleMaintenanceRunnable(Integer.parseInt(args[1]), Integer.parseInt(args[2]), TimeUnit.MINUTES);
sender.sendMessage(getMessage("starttimerStarted").replace("%TIME%", plugin.getRunnable().getTime()));
sender.send(getMessage("starttimerStarted", "%TIME%", plugin.getRunnable().getTime()));
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -21,12 +21,16 @@ import eu.kennytv.maintenance.core.MaintenancePlugin;
import eu.kennytv.maintenance.core.Settings;
import eu.kennytv.maintenance.core.command.CommandInfo;
import eu.kennytv.maintenance.core.util.SenderInfo;
import eu.kennytv.maintenance.lib.kyori.adventure.text.Component;
import eu.kennytv.maintenance.lib.kyori.adventure.text.minimessage.MiniMessage;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import static eu.kennytv.maintenance.core.Settings.NEW_LINE_REPLACEMENT;
public final class SetMotdCommand extends CommandInfo {
public SetMotdCommand(final MaintenancePlugin plugin) {
@@ -38,7 +42,7 @@ public final class SetMotdCommand extends CommandInfo {
boolean timerPingMessages = false;
if (args.length > 1 && args[1].equalsIgnoreCase("timer")) {
if (!getSettings().hasTimerSpecificPingMessages()) {
sender.sendMessage(getMessage("timerMotdDisabled"));
sender.send(getMessage("timerMotdDisabled"));
return;
}
@@ -47,27 +51,29 @@ public final class SetMotdCommand extends CommandInfo {
timerPingMessages = true;
}
if (args.length < 4 || !plugin.isNumeric(args[1])) {
sender.sendMessage(getHelpMessage());
sender.send(getHelpMessage());
return;
}
final Settings settings = getSettings();
final List<String> pingMessages = timerPingMessages ? settings.getTimerSpecificPingMessages() : settings.getPingMessages();
final List<Component> pingComponents = timerPingMessages ? settings.getTimerSpecificPingMessages() : settings.getPingMessages();
final List<String> pingMessages = settings.getConfig().getStringList(timerPingMessages ? "timerspecific-pingmessages" : "pingmessages");
final int index = Integer.parseInt(args[1]);
if (index == 0 || index > pingMessages.size() + 1) {
sender.sendMessage(getMessage("setMotdIndexError").replace("%MOTDS%", Integer.toString(pingMessages.size()))
.replace("%NEWAMOUNT%", Integer.toString(pingMessages.size() + 1)));
sender.send(getMessage("setMotdIndexError",
"%MOTDS%", Integer.toString(pingMessages.size()),
"%NEWAMOUNT%", Integer.toString(pingMessages.size() + 1)));
return;
}
if (!plugin.isNumeric(args[2])) {
sender.sendMessage(getMessage("setMotdLineError"));
sender.send(getMessage("setMotdLineError"));
return;
}
final int line = Integer.parseInt(args[2]);
if (line != 1 && line != 2) {
sender.sendMessage(getMessage("setMotdLineError"));
sender.send(getMessage("setMotdLineError"));
return;
}
@@ -75,23 +81,28 @@ public final class SetMotdCommand extends CommandInfo {
final String oldMessage = index > pingMessages.size() ? "" : pingMessages.get(index - 1);
final String newMessage;
if (line == 1) {
newMessage = oldMessage.contains("%NEWLINE%") ?
message + "%NEWLINE%" + oldMessage.split("%NEWLINE%", 2)[1] : message;
newMessage = oldMessage.contains(NEW_LINE_REPLACEMENT) ?
message + NEW_LINE_REPLACEMENT + oldMessage.split(NEW_LINE_REPLACEMENT, 2)[1] : message;
} else {
newMessage = oldMessage.contains("%NEWLINE%") ?
oldMessage.split("%NEWLINE%", 2)[0] + "%NEWLINE%" + message : oldMessage + "%NEWLINE%" + message;
newMessage = oldMessage.contains(NEW_LINE_REPLACEMENT) ?
oldMessage.split(NEW_LINE_REPLACEMENT, 2)[0] + NEW_LINE_REPLACEMENT + message : oldMessage + NEW_LINE_REPLACEMENT + message;
}
// Replace component in config and the cached list
final Component component = MiniMessage.miniMessage().deserialize(newMessage.replace(NEW_LINE_REPLACEMENT, "\n"));
if (index > pingMessages.size()) {
pingMessages.add(newMessage);
pingComponents.add(component);
} else {
pingMessages.set(index - 1, newMessage);
pingComponents.set(index - 1, component);
}
settings.getConfig().set(timerPingMessages ? "timerspecific-pingmessages" : "pingmessages", pingMessages);
settings.saveConfig();
sender.sendMessage(settings.getMessage("setMotd").replace("%LINE%", args[2]).replace("%INDEX%", args[1])
.replace("%MOTD%", "§f" + settings.getColoredString(message)));
sender.send(settings.getMessage("setMotd",
"%LINE%", args[2],
"%INDEX%", args[1]).replaceText(builder -> builder.matchLiteral("%MOTD%").replacement(component)));
}
@Override
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -33,15 +33,15 @@ public final class StarttimerCommand extends CommandInfo {
public void execute(final SenderInfo sender, final String[] args) {
if (checkArgs(sender, args, 2)) return;
if (plugin.getCommandManager().checkTimerArgs(sender, args[1])) {
sender.sendMessage(getHelpMessage());
sender.send(getHelpMessage());
return;
}
if (plugin.isMaintenance()) {
sender.sendMessage(getMessage("alreadyEnabled"));
sender.send(getMessage("alreadyEnabled"));
return;
}
plugin.startMaintenanceRunnable(Integer.parseInt(args[1]), TimeUnit.MINUTES, true);
sender.sendMessage(getMessage("starttimerStarted").replace("%TIME%", plugin.getRunnable().getTime()));
sender.send(getMessage("starttimerStarted", "%TIME%", plugin.getRunnable().getTime()));
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -33,7 +33,7 @@ public final class ToggleCommand extends CommandInfo {
final boolean maintenance = args[0].equalsIgnoreCase("on");
if (maintenance == plugin.isMaintenance()) {
sender.sendMessage(getMessage(maintenance ? "alreadyEnabled" : "alreadyDisabled"));
sender.send(getMessage(maintenance ? "alreadyEnabled" : "alreadyDisabled"));
return;
}
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -44,11 +44,11 @@ public final class UpdateCommand extends CommandInfo {
return;
}
sender.sendMessage(getMessage("updateDownloading"));
sender.send(getMessage("updateDownloading"));
if (plugin.installUpdate()) {
sender.sendMessage(getMessage("updateFinished"));
sender.send(getMessage("updateFinished"));
} else {
sender.sendMessage(getMessage("updateFailed"));
sender.send(getMessage("updateFailed"));
}
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -45,7 +45,7 @@ public final class WhitelistAddCommand extends CommandInfo {
}
} else if (args.length == 3) {
if (args[1].length() != 36) {
sender.sendMessage(getHelpMessage());
sender.send(getHelpMessage());
return;
}
@@ -54,7 +54,7 @@ public final class WhitelistAddCommand extends CommandInfo {
addPlayerToWhitelist(sender, new DummySenderInfo(uuid, args[2]));
}
} else {
sender.sendMessage(getHelpMessage());
sender.send(getHelpMessage());
}
}
@@ -64,30 +64,32 @@ public final class WhitelistAddCommand extends CommandInfo {
}
private void addPlayerToWhitelist(final SenderInfo sender, final String name) {
final SenderInfo selected = plugin.getOfflinePlayer(name);
if (selected == null) {
sender.sendMessage(getMessage("playerNotOnline"));
return;
}
plugin.getOfflinePlayer(name, selected -> {
if (selected == null) {
sender.send(getMessage("playerNotOnline"));
return;
}
addPlayerToWhitelist(sender, selected);
addPlayerToWhitelist(sender, selected);
});
}
private void addPlayerToWhitelist(final SenderInfo sender, final UUID uuid) {
final SenderInfo selected = plugin.getOfflinePlayer(uuid);
if (selected == null) {
sender.sendMessage(getMessage("playerNotFoundUuid"));
return;
}
plugin.getOfflinePlayer(uuid, selected -> {
if (selected == null) {
sender.send(getMessage("playerNotFoundUuid"));
return;
}
addPlayerToWhitelist(sender, selected);
addPlayerToWhitelist(sender, selected);
});
}
private void addPlayerToWhitelist(final SenderInfo sender, final SenderInfo selected) {
if (getSettings().addWhitelistedPlayer(selected.getUuid(), selected.getName())) {
sender.sendMessage(getMessage("whitelistAdded").replace("%PLAYER%", selected.getName()));
sender.send(getMessage("whitelistAdded", "%PLAYER%", selected.getName()));
} else {
sender.sendMessage(getMessage("whitelistAlreadyAdded").replace("%PLAYER%", selected.getName()));
sender.send(getMessage("whitelistAlreadyAdded", "%PLAYER%", selected.getName()));
}
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,6 +20,7 @@ package eu.kennytv.maintenance.core.command.subcommand;
import eu.kennytv.maintenance.core.MaintenancePlugin;
import eu.kennytv.maintenance.core.command.CommandInfo;
import eu.kennytv.maintenance.core.util.SenderInfo;
import eu.kennytv.maintenance.lib.kyori.adventure.text.Component;
import java.util.Map;
import java.util.UUID;
@@ -36,16 +37,17 @@ public final class WhitelistCommand extends CommandInfo {
final Map<UUID, String> players = getSettings().getWhitelistedPlayers();
if (players.isEmpty()) {
sender.sendMessage(getMessage("whitelistEmpty"));
sender.send(getMessage("whitelistEmpty"));
return;
}
sender.sendMessage(getMessage("whitelistedPlayers"));
final String format = getMessage("whitelistedPlayersFormat");
sender.send(getMessage("whitelistedPlayers"));
final Component format = getMessage("whitelistedPlayersFormat");
for (final Map.Entry<UUID, String> entry : players.entrySet()) {
sender.sendMessage(format.replace("%NAME%", entry.getValue()).replace("%UUID%", entry.getKey().toString()));
sender.send(format.replaceText(builder -> builder.matchLiteral("%NAME%").replacement(entry.getValue()))
.replaceText(builder -> builder.matchLiteral("%UUID%").replacement(entry.getKey().toString())));
}
sender.sendMessage("");
sender.send(Component.empty());
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -59,33 +59,35 @@ public final class WhitelistRemoveCommand extends CommandInfo {
}
private void removePlayerFromWhitelist(final SenderInfo sender, final String name) {
final SenderInfo selected = plugin.getOfflinePlayer(name);
if (selected == null) {
if (getSettings().removeWhitelistedPlayer(name)) {
sender.sendMessage(getMessage("whitelistRemoved").replace("%PLAYER%", name));
} else {
sender.sendMessage(getMessage("whitelistNotFound"));
plugin.getOfflinePlayer(name, selected -> {
if (selected == null) {
if (getSettings().removeWhitelistedPlayer(name)) {
sender.send(getMessage("whitelistRemoved", "%PLAYER%", name));
} else {
sender.send(getMessage("whitelistNotFound"));
}
return;
}
return;
}
removePlayerFromWhitelist(sender, selected.getUuid(), selected.getName());
removePlayerFromWhitelist(sender, selected.getUuid(), selected.getName());
});
}
private void removePlayerFromWhitelist(final SenderInfo sender, final UUID uuid) {
final SenderInfo selected = plugin.getOfflinePlayer(uuid);
if (selected == null) {
removePlayerFromWhitelist(sender, uuid, uuid.toString());
} else {
removePlayerFromWhitelist(sender, selected.getUuid(), selected.getName());
}
plugin.getOfflinePlayer(uuid, selected -> {
if (selected == null) {
removePlayerFromWhitelist(sender, uuid, uuid.toString());
} else {
removePlayerFromWhitelist(sender, selected.getUuid(), selected.getName());
}
});
}
private void removePlayerFromWhitelist(final SenderInfo sender, final UUID uuid, final String toReplace) {
if (getSettings().removeWhitelistedPlayer(uuid)) {
sender.sendMessage(getMessage("whitelistRemoved").replace("%PLAYER%", toReplace));
sender.send(getMessage("whitelistRemoved", "%PLAYER%", toReplace));
} else {
sender.sendMessage(getMessage("whitelistNotFound"));
sender.send(getMessage("whitelistNotFound"));
}
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -41,16 +41,17 @@ import java.util.Set;
public final class Config extends ConfigSection {
private static final String AWESOME_HEADER =
"#######################################################################################################################\n" +
"# __ __ _ _ _ _ __ _______ __ #\n" +
"# | \\/ | __ _(_)_ __ | |_ ___ _ __ __ _ _ __ ___ ___ | |__ _ _ | |/ /___ _ __ _ __ _ |_ _\\ \\ / / #\n" +
"# | |\\/| |/ _` | | '_ \\| __/ _ \\ '_ \\ / _` | '_ \\ / __/ _ \\ | '_ \\| | | | | ' // _ \\ '_ \\| '_ \\| | | || | \\ \\ / / #\n" +
"# | | | | (_| | | | | | || __/ | | | (_| | | | | (_| __/ | |_) | |_| | | . \\ __/ | | | | | | |_| || | \\ V / #\n" +
"# |_| |_|\\__,_|_|_| |_|\\__\\___|_| |_|\\__,_|_| |_|\\___\\___| |_.__/ \\__, | |_|\\_\\___|_| |_|_| |_|\\__, ||_| \\_/ #\n" +
"# |___/ |___/ #\n" +
"#######################################################################################################################\n" +
"###################################################################################################################\n" +
"# __ __ _ _ _ _ _ #\n" +
"# | \\/ | __ _(_)_ __ | |_ ___ _ __ __ _ _ __ ___ ___ | |__ _ _ | | _____ _ __ _ __ _ _| |___ __ #\n" +
"# | |\\/| |/ _` | | '_ \\| __/ _ \\ '_ \\ / _` | '_ \\ / __/ _ \\ | '_ \\| | | | | |/ / _ \\ '_ \\| '_ \\| | | | __\\ \\ / / #\n" +
"# | | | | (_| | | | | | || __/ | | | (_| | | | | (_| __/ | |_) | |_| | | < __/ | | | | | | |_| | |_ \\ V / #\n" +
"# |_| |_|\\__,_|_|_| |_|\\__\\___|_| |_|\\__,_|_| |_|\\___\\___| |_.__/ \\__, | |_|\\_\\___|_| |_|_| |_|\\__, |\\__| \\_/ #\n" +
"# |___/ |___/ #\n" +
"###################################################################################################################\n" +
"# You can report bugs here: https://github.com/kennytv/Maintenance/issues\n" +
"# If you need any other help/support, you can also join my Discord server: https://discord.gg/vGCUzHq\n";
"# If you need any other help/support, you can also join my Discord server: https://discord.gg/vGCUzHq\n" +
"# The config and language files use MiniMessage, NOT legacy text for input. Use https://webui.adventure.kyori.net/ to edit and preview the formatted text.";
private final Yaml yaml = createYaml();
private final File file;
private final Set<String> unsupportedFields;
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -18,7 +18,6 @@
package eu.kennytv.maintenance.core.event;
import eu.kennytv.maintenance.api.event.manager.EventListener;
import eu.kennytv.maintenance.api.event.manager.IEventManager;
import eu.kennytv.maintenance.api.event.manager.MaintenanceEvent;
import java.util.ArrayList;
@@ -26,7 +25,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
public final class EventManager implements IEventManager {
public final class EventManager implements eu.kennytv.maintenance.api.event.manager.EventManager {
private final Map<String, List<EventListener>> listeners = new HashMap<>();
@Override
@@ -0,0 +1,53 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package eu.kennytv.maintenance.core.hook;
import eu.kennytv.maintenance.api.Maintenance;
import net.luckperms.api.LuckPermsProvider;
import net.luckperms.api.context.ContextCalculator;
import net.luckperms.api.context.ContextConsumer;
import net.luckperms.api.context.ContextSet;
import net.luckperms.api.context.ImmutableContextSet;
import org.jetbrains.annotations.NotNull;
public final class LuckPermsHook {
public static <T> void register(final Maintenance maintenance) {
LuckPermsProvider.get().getContextManager().registerCalculator(new MaintenanceCalculator<T>(maintenance));
}
public static final class MaintenanceCalculator<T> implements ContextCalculator<T> {
public static final String MAINTENANCE_KEY = "is-maintenance";
private final Maintenance maintenance;
private MaintenanceCalculator(final Maintenance maintenance) {
this.maintenance = maintenance;
}
@Override
public void calculate(@NotNull final T target, @NotNull final ContextConsumer consumer) {
consumer.accept(MAINTENANCE_KEY, Boolean.toString(maintenance.isMaintenance()));
}
@Override
public ContextSet estimatePotentialContexts() {
return ImmutableContextSet.builder().add(MAINTENANCE_KEY, "true").add(MAINTENANCE_KEY, "false").build();
}
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -19,6 +19,7 @@ package eu.kennytv.maintenance.core.runnable;
import eu.kennytv.maintenance.core.MaintenancePlugin;
import eu.kennytv.maintenance.core.Settings;
import eu.kennytv.maintenance.lib.kyori.adventure.text.Component;
public class MaintenanceRunnable extends MaintenanceRunnableBase {
@@ -32,12 +33,12 @@ public class MaintenanceRunnable extends MaintenanceRunnableBase {
}
@Override
protected String getStartMessage() {
return settings.getMessage("starttimerBroadcast").replace("%TIME%", getTime());
protected Component getStartMessage() {
return settings.getMessage("starttimerBroadcast", "%TIME%", getTime());
}
@Override
protected String getEndMessage() {
return settings.getMessage("endtimerBroadcast").replace("%TIME%", getTime());
protected Component getEndMessage() {
return settings.getMessage("endtimerBroadcast", "%TIME%", getTime());
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,6 +20,7 @@ package eu.kennytv.maintenance.core.runnable;
import eu.kennytv.maintenance.core.MaintenancePlugin;
import eu.kennytv.maintenance.core.Settings;
import eu.kennytv.maintenance.core.util.Task;
import eu.kennytv.maintenance.lib.kyori.adventure.text.Component;
public abstract class MaintenanceRunnableBase implements Runnable {
protected final MaintenancePlugin plugin;
@@ -63,13 +64,13 @@ public abstract class MaintenanceRunnableBase implements Runnable {
return task;
}
protected void broadcast(final String message) {
protected void broadcast(final Component message) {
plugin.broadcast(message);
}
protected abstract void finish();
protected abstract String getStartMessage();
protected abstract Component getStartMessage();
protected abstract String getEndMessage();
protected abstract Component getEndMessage();
}
@@ -1,6 +1,6 @@
/*
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
* Copyright (C) 2018-2022 kennytv (https://github.com/kennytv)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -19,6 +19,7 @@ package eu.kennytv.maintenance.core.runnable;
import eu.kennytv.maintenance.core.MaintenancePlugin;
import eu.kennytv.maintenance.core.Settings;
import eu.kennytv.maintenance.lib.kyori.adventure.text.Component;
import java.util.concurrent.TimeUnit;
@@ -39,8 +40,9 @@ public final class MaintenanceScheduleRunnable extends MaintenanceRunnable {
}
@Override
protected String getStartMessage() {
return settings.getMessage("scheduletimerBroadcast")
.replace("%TIME%", getTime()).replace("%DURATION%", plugin.getFormattedTime(maintenanceDuration));
protected Component getStartMessage() {
return settings.getMessage("scheduletimerBroadcast",
"%TIME%", getTime(),
"%DURATION%", plugin.getFormattedTime(maintenanceDuration));
}
}
Loaded 100 of 186 files, more files were not shown because too many files have changed in this diff. Show more