mirror of
https://github.com/DiscordSRV/Ascension.git
synced 2024-12-24 16:58:44 +01:00
Progress on require linking, add folia support, achievements/advancements
This commit is contained in:
parent
42ec392bcb
commit
ec02e5f88a
@ -36,6 +36,7 @@ allprojects {
|
|||||||
filter {
|
filter {
|
||||||
includeGroup 'com.destroystokyo.paper'
|
includeGroup 'com.destroystokyo.paper'
|
||||||
includeGroup 'io.papermc.paper'
|
includeGroup 'io.papermc.paper'
|
||||||
|
includeGroup 'dev.folia'
|
||||||
includeGroup 'org.spigotmc'
|
includeGroup 'org.spigotmc'
|
||||||
includeGroup 'net.md-5'
|
includeGroup 'net.md-5'
|
||||||
}
|
}
|
||||||
@ -55,21 +56,24 @@ allprojects {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
|
||||||
// Platform
|
|
||||||
compileOnly(libs.paperapi.old)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
// API
|
// API
|
||||||
annotationProcessor project(':api')
|
annotationProcessor project(':api')
|
||||||
|
|
||||||
|
// Platform
|
||||||
|
compileOnly(libs.spigotapi)
|
||||||
|
|
||||||
// Common
|
// Common
|
||||||
compileOnly project(':common')
|
compileOnly project(':common')
|
||||||
implementation project(path: ':common', configuration: 'runtimeElements')
|
implementation project(path: ':common', configuration: 'runtimeElements')
|
||||||
|
|
||||||
|
// Folia, modern bukkit
|
||||||
|
api project(':bukkit:bukkit-folia')
|
||||||
|
api project(':bukkit:bukkit-paper')
|
||||||
|
api project(':bukkit:bukkit-bukkit1_12')
|
||||||
|
|
||||||
// DependencyDownload
|
// DependencyDownload
|
||||||
implementation(libs.mcdependencydownload.bukkit.bootstrap)
|
implementation(libs.mcdependencydownload.bukkit.bootstrap)
|
||||||
|
|
||||||
|
10
bukkit/bukkit1_12/build.gradle
Normal file
10
bukkit/bukkit1_12/build.gradle
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
dependencies {
|
||||||
|
// Platform
|
||||||
|
compileOnly(libs.spigotapi.onetwelve)
|
||||||
|
|
||||||
|
// Adventure (runtime downloaded by :bukkit)
|
||||||
|
compileOnly(libs.adventure.platform.bukkit)
|
||||||
|
|
||||||
|
// Common
|
||||||
|
compileOnly project(':common')
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
package com.discordsrv.bukkit.listener.award;
|
||||||
|
|
||||||
|
import com.discordsrv.common.DiscordSRV;
|
||||||
|
import com.discordsrv.common.logging.Logger;
|
||||||
|
import com.discordsrv.common.logging.NamedLogger;
|
||||||
|
import com.github.benmanes.caffeine.cache.Cache;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
|
public abstract class AbstractBukkitAwardListener implements Listener {
|
||||||
|
|
||||||
|
private final Cache<UUID, AtomicInteger> advancementCount;
|
||||||
|
protected final Logger logger;
|
||||||
|
protected final IBukkitAwardForwarder forwarder;
|
||||||
|
|
||||||
|
public AbstractBukkitAwardListener(DiscordSRV discordSRV, IBukkitAwardForwarder forwarder) {
|
||||||
|
this.advancementCount = discordSRV.caffeineBuilder()
|
||||||
|
.expireAfterWrite(5, TimeUnit.SECONDS)
|
||||||
|
.build();
|
||||||
|
this.logger = new NamedLogger(discordSRV, "AWARD_LISTENER");
|
||||||
|
this.forwarder = forwarder;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("DataFlowIssue") // Not possible
|
||||||
|
public boolean checkIfShouldSkip(Player player) {
|
||||||
|
int count = advancementCount.get(player.getUniqueId(), key -> new AtomicInteger(0)).incrementAndGet();
|
||||||
|
boolean skip = count >= 5;
|
||||||
|
if (skip && (count % 5 == 0)) {
|
||||||
|
logger.debug("Skipping advancement/achievement processing for player: " + player.getName()
|
||||||
|
+ " currently at " + advancementCount + " advancements/achievements per 5 seconds");
|
||||||
|
}
|
||||||
|
return skip;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
package com.discordsrv.bukkit.listener.award;
|
||||||
|
|
||||||
|
import com.discordsrv.common.DiscordSRV;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
|
import org.bukkit.event.player.PlayerAdvancementDoneEvent;
|
||||||
|
|
||||||
|
public class BukkitAdvancementListener extends AbstractBukkitAwardListener {
|
||||||
|
|
||||||
|
public BukkitAdvancementListener(DiscordSRV discordSRV, IBukkitAwardForwarder forwarder) {
|
||||||
|
super(discordSRV, forwarder);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.MONITOR)
|
||||||
|
public void onPlayerAdvancementDone(PlayerAdvancementDoneEvent event) {
|
||||||
|
// TODO:
|
||||||
|
// - NMS: check if the advancement should be broadcasted to chat, returning if not
|
||||||
|
// - run checkIfShouldSkip from parent
|
||||||
|
// - NMS: get advancement and/or 'advancement award message'
|
||||||
|
// - run forwarder.publishEvent
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
package com.discordsrv.bukkit.listener.award;
|
||||||
|
|
||||||
|
import com.discordsrv.api.component.MinecraftComponent;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
public interface IBukkitAwardForwarder {
|
||||||
|
void publishEvent(Player player, MinecraftComponent message, MinecraftComponent name, boolean cancelled);
|
||||||
|
}
|
9
bukkit/folia/build.gradle
Normal file
9
bukkit/folia/build.gradle
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
disableAutoTargetJvm() // Requires Java 17, we target 8
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
// Platform
|
||||||
|
compileOnly(libs.folia)
|
||||||
|
|
||||||
|
// Common
|
||||||
|
compileOnly project(':common')
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of DiscordSRV, licensed under the GPLv3 License
|
||||||
|
* Copyright (c) 2016-2023 Austin "Scarsz" Shapiro, Henri "Vankka" Schubin and DiscordSRV contributors
|
||||||
|
*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.discordsrv.bukkit.scheduler;
|
||||||
|
|
||||||
|
import com.discordsrv.common.scheduler.ServerScheduler;
|
||||||
|
import org.bukkit.Server;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.plugin.Plugin;
|
||||||
|
|
||||||
|
import java.util.function.BiConsumer;
|
||||||
|
|
||||||
|
public interface IBukkitScheduler extends ServerScheduler {
|
||||||
|
|
||||||
|
void runWithArgs(BiConsumer<Server, Plugin> runNormal);
|
||||||
|
|
||||||
|
default void runOnMainThread(CommandSender sender, Runnable task) {
|
||||||
|
runOnMainThread(task);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of DiscordSRV, licensed under the GPLv3 License
|
||||||
|
* Copyright (c) 2016-2023 Austin "Scarsz" Shapiro, Henri "Vankka" Schubin and DiscordSRV contributors
|
||||||
|
*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.discordsrv.bukkit.scheduler;
|
||||||
|
|
||||||
|
import com.discordsrv.common.scheduler.ServerScheduler;
|
||||||
|
import org.bukkit.command.BlockCommandSender;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.command.ProxiedCommandSender;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
|
||||||
|
public interface IFoliaScheduler extends ServerScheduler, IBukkitScheduler {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default void runOnMainThread(CommandSender sender, Runnable task) {
|
||||||
|
if (sender instanceof ProxiedCommandSender) {
|
||||||
|
runOnMainThread(((ProxiedCommandSender) sender).getCallee(), task);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sender instanceof Entity) {
|
||||||
|
runWithArgs((server, plugin) -> ((Entity) sender).getScheduler().run(
|
||||||
|
plugin,
|
||||||
|
r -> task.run(),
|
||||||
|
null
|
||||||
|
));
|
||||||
|
} else if (sender instanceof BlockCommandSender) {
|
||||||
|
runWithArgs((server, plugin) -> server.getRegionScheduler().run(
|
||||||
|
plugin,
|
||||||
|
((BlockCommandSender) sender).getBlock().getLocation(),
|
||||||
|
r -> task.run()
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
runOnMainThread(task);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default void runOnMainThread(Runnable task) {
|
||||||
|
runWithArgs((server, plugin) -> server.getGlobalRegionScheduler().execute(plugin, task));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default void runOnMainThreadLaterInTicks(Runnable task, int ticks) {
|
||||||
|
runWithArgs((server, plugin) -> server.getGlobalRegionScheduler().runDelayed(plugin, r -> task.run(), ticks));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default void runOnMainThreadAtFixedRateInTicks(Runnable task, int initialTicks, int rateTicks) {
|
||||||
|
runWithArgs((server, plugin) -> server.getGlobalRegionScheduler().execute(plugin, task));
|
||||||
|
}
|
||||||
|
}
|
@ -6,6 +6,9 @@ dependencies {
|
|||||||
// API
|
// API
|
||||||
implementation project(':common:common-api')
|
implementation project(':common:common-api')
|
||||||
|
|
||||||
|
// Platform
|
||||||
|
compileOnly(libs.spigotapi)
|
||||||
|
|
||||||
// DependencyDownload
|
// DependencyDownload
|
||||||
implementation(libs.mcdependencydownload.bukkit.loader)
|
implementation(libs.mcdependencydownload.bukkit.loader)
|
||||||
}
|
}
|
||||||
|
@ -4,8 +4,14 @@ version: @VERSION@
|
|||||||
description: ""
|
description: ""
|
||||||
authors: [Scarsz, Vankka]
|
authors: [Scarsz, Vankka]
|
||||||
load: STARTUP
|
load: STARTUP
|
||||||
|
|
||||||
|
# Marks the plugin non-legacy in versions 1.13 and above
|
||||||
|
# This does not mean that the plugin only supports 1.13
|
||||||
api-version: 1.13
|
api-version: 1.13
|
||||||
|
|
||||||
|
# Marks the plugin as supporting Folia
|
||||||
|
folia-supported: true
|
||||||
|
|
||||||
softdepend: [
|
softdepend: [
|
||||||
# Permission + group providers
|
# Permission + group providers
|
||||||
Vault, LuckPerms,
|
Vault, LuckPerms,
|
||||||
|
13
bukkit/paper/build.gradle
Normal file
13
bukkit/paper/build.gradle
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
disableAutoTargetJvm() // Requires Java 17, we target 8
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
// Platform
|
||||||
|
compileOnly(libs.paperapi)
|
||||||
|
|
||||||
|
// Adventure (runtime downloaded by :bukkit)
|
||||||
|
compileOnly(libs.adventure.platform.bukkit)
|
||||||
|
|
||||||
|
// Common
|
||||||
|
compileOnly project(':bukkit:bukkit-bukkit1_12')
|
||||||
|
compileOnly project(':common')
|
||||||
|
}
|
@ -64,7 +64,7 @@ public class PaperComponentHandle<T> {
|
|||||||
if (handle != null) {
|
if (handle != null) {
|
||||||
Object unrelocated = null;
|
Object unrelocated = null;
|
||||||
try {
|
try {
|
||||||
unrelocated = handle.invoke(target);
|
unrelocated = handle.invokeExact(target);
|
||||||
} catch (Throwable ignored) {}
|
} catch (Throwable ignored) {}
|
||||||
if (unrelocated != null) {
|
if (unrelocated != null) {
|
||||||
MinecraftComponent component = discordSRV.componentFactory().empty();
|
MinecraftComponent component = discordSRV.componentFactory().empty();
|
@ -23,7 +23,6 @@ import dev.vankka.dynamicproxy.processor.Proxy;
|
|||||||
import net.kyori.adventure.platform.bukkit.BukkitComponentSerializer;
|
import net.kyori.adventure.platform.bukkit.BukkitComponentSerializer;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.kyori.adventure.text.serializer.bungeecord.BungeeComponentSerializer;
|
import net.kyori.adventure.text.serializer.bungeecord.BungeeComponentSerializer;
|
||||||
import net.md_5.bungee.api.chat.BaseComponent;
|
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
@ -31,6 +30,7 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation") // Paper
|
||||||
@Proxy(value = CommandSender.class, className = "BukkitCommandExecutorProxy")
|
@Proxy(value = CommandSender.class, className = "BukkitCommandExecutorProxy")
|
||||||
public abstract class BukkitCommandExecutorProxyTemplate implements CommandSender {
|
public abstract class BukkitCommandExecutorProxyTemplate implements CommandSender {
|
||||||
|
|
||||||
@ -81,7 +81,6 @@ public abstract class BukkitCommandExecutorProxyTemplate implements CommandSende
|
|||||||
return spigot;
|
return spigot;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
public class Spigot extends CommandSender.Spigot {
|
public class Spigot extends CommandSender.Spigot {
|
||||||
|
|
||||||
private final CommandSender.Spigot spigot;
|
private final CommandSender.Spigot spigot;
|
||||||
@ -91,30 +90,30 @@ public abstract class BukkitCommandExecutorProxyTemplate implements CommandSende
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendMessage(@Nullable UUID sender, @NotNull BaseComponent component) {
|
public void sendMessage(@Nullable UUID sender, @NotNull net.md_5.bungee.api.chat.BaseComponent component) {
|
||||||
spigot.sendMessage(sender, component);
|
spigot.sendMessage(sender, component);
|
||||||
forwardBungee(new BaseComponent[] {component});
|
forwardBungee(new net.md_5.bungee.api.chat.BaseComponent[] {component});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendMessage(@NotNull BaseComponent component) {
|
public void sendMessage(@NotNull net.md_5.bungee.api.chat.BaseComponent component) {
|
||||||
spigot.sendMessage(component);
|
spigot.sendMessage(component);
|
||||||
forwardBungee(new BaseComponent[] {component});
|
forwardBungee(new net.md_5.bungee.api.chat.BaseComponent[] {component});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendMessage(@Nullable UUID sender, @NotNull BaseComponent... components) {
|
public void sendMessage(@Nullable UUID sender, @NotNull net.md_5.bungee.api.chat.BaseComponent... components) {
|
||||||
spigot.sendMessage(components);
|
spigot.sendMessage(components);
|
||||||
forwardBungee(components);
|
forwardBungee(components);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendMessage(@NotNull BaseComponent... components) {
|
public void sendMessage(@NotNull net.md_5.bungee.api.chat.BaseComponent... components) {
|
||||||
spigot.sendMessage(components);
|
spigot.sendMessage(components);
|
||||||
forwardBungee(components);
|
forwardBungee(components);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void forwardBungee(BaseComponent[] components) {
|
private void forwardBungee(net.md_5.bungee.api.chat.BaseComponent[] components) {
|
||||||
componentConsumer.accept(BungeeComponentSerializer.get().deserialize(components));
|
componentConsumer.accept(BungeeComponentSerializer.get().deserialize(components));
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -0,0 +1,55 @@
|
|||||||
|
package com.discordsrv.bukkit.listener.award;
|
||||||
|
|
||||||
|
import com.discordsrv.api.component.MinecraftComponent;
|
||||||
|
import com.discordsrv.bukkit.component.PaperComponentHandle;
|
||||||
|
import com.discordsrv.common.DiscordSRV;
|
||||||
|
import io.papermc.paper.advancement.AdvancementDisplay;
|
||||||
|
import org.bukkit.advancement.Advancement;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
|
import org.bukkit.event.player.PlayerAdvancementDoneEvent;
|
||||||
|
|
||||||
|
public class PaperModernAdvancementListener extends AbstractBukkitAwardListener {
|
||||||
|
|
||||||
|
private static final PaperComponentHandle<PlayerAdvancementDoneEvent> MESSAGE_HANDLE;
|
||||||
|
private static final PaperComponentHandle<Advancement> DISPLAY_NAME_HANDLE;
|
||||||
|
|
||||||
|
static {
|
||||||
|
MESSAGE_HANDLE = new PaperComponentHandle<>(
|
||||||
|
PlayerAdvancementDoneEvent.class,
|
||||||
|
"message",
|
||||||
|
null
|
||||||
|
);
|
||||||
|
DISPLAY_NAME_HANDLE = new PaperComponentHandle<>(
|
||||||
|
Advancement.class,
|
||||||
|
"displayName",
|
||||||
|
null
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final DiscordSRV discordSRV;
|
||||||
|
|
||||||
|
public PaperModernAdvancementListener(DiscordSRV discordSRV, IBukkitAwardForwarder forwarder) {
|
||||||
|
super(discordSRV, forwarder);
|
||||||
|
this.discordSRV = discordSRV;
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.MONITOR)
|
||||||
|
public void onPlayerAdvancementDone(PlayerAdvancementDoneEvent event) {
|
||||||
|
Advancement advancement = event.getAdvancement();
|
||||||
|
AdvancementDisplay display = advancement.getDisplay();
|
||||||
|
if (display == null || !display.doesAnnounceToChat()) {
|
||||||
|
logger.trace("Skipping advancement display of \"" + advancement.getKey().getKey() + "\" for "
|
||||||
|
+ event.getPlayer() + ": advancement display == null or does not broadcast to chat");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (checkIfShouldSkip(event.getPlayer())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MinecraftComponent message = MESSAGE_HANDLE.getComponent(discordSRV, event);
|
||||||
|
MinecraftComponent displayName = DISPLAY_NAME_HANDLE.getComponent(discordSRV, advancement);
|
||||||
|
forwarder.publishEvent(event.getPlayer(), message, displayName, false);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
package com.discordsrv.bukkit.listener.chat;
|
||||||
|
|
||||||
|
import com.discordsrv.api.component.MinecraftComponent;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
public interface IBukkitChatForwarder {
|
||||||
|
|
||||||
|
void publishEvent(Player player, MinecraftComponent component, boolean cancelled);
|
||||||
|
}
|
@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of DiscordSRV, licensed under the GPLv3 License
|
||||||
|
* Copyright (c) 2016-2023 Austin "Scarsz" Shapiro, Henri "Vankka" Schubin and DiscordSRV contributors
|
||||||
|
*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.discordsrv.bukkit.listener.chat;
|
||||||
|
|
||||||
|
import com.discordsrv.api.component.MinecraftComponent;
|
||||||
|
import com.discordsrv.bukkit.component.PaperComponentHandle;
|
||||||
|
import com.discordsrv.common.DiscordSRV;
|
||||||
|
import io.papermc.paper.event.player.AsyncChatEvent;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
|
||||||
|
public class PaperChatListener implements Listener {
|
||||||
|
|
||||||
|
private static final PaperComponentHandle<AsyncChatEvent> COMPONENT_HANDLE;
|
||||||
|
|
||||||
|
static {
|
||||||
|
COMPONENT_HANDLE = new PaperComponentHandle<>(
|
||||||
|
AsyncChatEvent.class,
|
||||||
|
"message",
|
||||||
|
null
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final DiscordSRV discordSRV;
|
||||||
|
private final IBukkitChatForwarder listener;
|
||||||
|
|
||||||
|
public PaperChatListener(DiscordSRV discordSRV, IBukkitChatForwarder listener) {
|
||||||
|
this.discordSRV = discordSRV;
|
||||||
|
this.listener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.MONITOR)
|
||||||
|
public void onAsyncChat(AsyncChatEvent event) {
|
||||||
|
MinecraftComponent component = COMPONENT_HANDLE.getComponent(discordSRV, event);
|
||||||
|
listener.publishEvent(event.getPlayer(), component, event.isCancelled());
|
||||||
|
}
|
||||||
|
}
|
@ -25,14 +25,18 @@ import com.discordsrv.bukkit.config.main.BukkitConfig;
|
|||||||
import com.discordsrv.bukkit.config.manager.BukkitConfigManager;
|
import com.discordsrv.bukkit.config.manager.BukkitConfigManager;
|
||||||
import com.discordsrv.bukkit.config.manager.BukkitConnectionConfigManager;
|
import com.discordsrv.bukkit.config.manager.BukkitConnectionConfigManager;
|
||||||
import com.discordsrv.bukkit.console.BukkitConsole;
|
import com.discordsrv.bukkit.console.BukkitConsole;
|
||||||
import com.discordsrv.bukkit.listener.BukkitChatListener;
|
|
||||||
import com.discordsrv.bukkit.listener.BukkitConnectionListener;
|
import com.discordsrv.bukkit.listener.BukkitConnectionListener;
|
||||||
import com.discordsrv.bukkit.listener.BukkitDeathListener;
|
import com.discordsrv.bukkit.listener.BukkitDeathListener;
|
||||||
|
import com.discordsrv.bukkit.listener.BukkitRequiredLinkingListener;
|
||||||
import com.discordsrv.bukkit.listener.BukkitStatusMessageListener;
|
import com.discordsrv.bukkit.listener.BukkitStatusMessageListener;
|
||||||
|
import com.discordsrv.bukkit.listener.award.BukkitAwardForwarder;
|
||||||
|
import com.discordsrv.bukkit.listener.chat.BukkitChatForwarder;
|
||||||
import com.discordsrv.bukkit.player.BukkitPlayerProvider;
|
import com.discordsrv.bukkit.player.BukkitPlayerProvider;
|
||||||
import com.discordsrv.bukkit.plugin.BukkitPluginManager;
|
import com.discordsrv.bukkit.plugin.BukkitPluginManager;
|
||||||
import com.discordsrv.bukkit.requiredlinking.BukkitRequiredLinkingModule;
|
import com.discordsrv.bukkit.requiredlinking.BukkitRequiredLinkingModule;
|
||||||
import com.discordsrv.bukkit.scheduler.BukkitScheduler;
|
import com.discordsrv.bukkit.scheduler.BukkitScheduler;
|
||||||
|
import com.discordsrv.bukkit.scheduler.FoliaScheduler;
|
||||||
|
import com.discordsrv.bukkit.scheduler.IBukkitScheduler;
|
||||||
import com.discordsrv.common.ServerDiscordSRV;
|
import com.discordsrv.common.ServerDiscordSRV;
|
||||||
import com.discordsrv.common.command.game.handler.ICommandHandler;
|
import com.discordsrv.common.command.game.handler.ICommandHandler;
|
||||||
import com.discordsrv.common.component.translation.Translation;
|
import com.discordsrv.common.component.translation.Translation;
|
||||||
@ -60,19 +64,29 @@ public class BukkitDiscordSRV extends ServerDiscordSRV<DiscordSRVBukkitBootstrap
|
|||||||
|
|
||||||
private BukkitAudiences audiences;
|
private BukkitAudiences audiences;
|
||||||
|
|
||||||
private final BukkitScheduler scheduler;
|
private final IBukkitScheduler scheduler;
|
||||||
private final BukkitConsole console;
|
private final BukkitConsole console;
|
||||||
private final BukkitPlayerProvider playerProvider;
|
private final BukkitPlayerProvider playerProvider;
|
||||||
private final BukkitPluginManager pluginManager;
|
private final BukkitPluginManager pluginManager;
|
||||||
private AbstractBukkitCommandHandler commandHandler;
|
private AbstractBukkitCommandHandler commandHandler;
|
||||||
|
private final BukkitRequiredLinkingListener requiredLinkingListener;
|
||||||
|
|
||||||
private final BukkitConnectionConfigManager connectionConfigManager;
|
private final BukkitConnectionConfigManager connectionConfigManager;
|
||||||
private final BukkitConfigManager configManager;
|
private final BukkitConfigManager configManager;
|
||||||
|
|
||||||
|
private static IBukkitScheduler createScheduler(BukkitDiscordSRV discordSRV) {
|
||||||
|
try {
|
||||||
|
Class.forName("io.papermc.paper.threadedregions.scheduler.GlobalRegionScheduler");
|
||||||
|
return new FoliaScheduler(discordSRV);
|
||||||
|
} catch (ClassNotFoundException ignored) {
|
||||||
|
return new BukkitScheduler(discordSRV);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public BukkitDiscordSRV(DiscordSRVBukkitBootstrap bootstrap) {
|
public BukkitDiscordSRV(DiscordSRVBukkitBootstrap bootstrap) {
|
||||||
super(bootstrap);
|
super(bootstrap);
|
||||||
|
|
||||||
this.scheduler = new BukkitScheduler(this);
|
this.scheduler = createScheduler(this);
|
||||||
this.console = new BukkitConsole(this);
|
this.console = new BukkitConsole(this);
|
||||||
this.playerProvider = new BukkitPlayerProvider(this);
|
this.playerProvider = new BukkitPlayerProvider(this);
|
||||||
this.pluginManager = new BukkitPluginManager(this);
|
this.pluginManager = new BukkitPluginManager(this);
|
||||||
@ -82,6 +96,8 @@ public class BukkitDiscordSRV extends ServerDiscordSRV<DiscordSRVBukkitBootstrap
|
|||||||
this.configManager = new BukkitConfigManager(this);
|
this.configManager = new BukkitConfigManager(this);
|
||||||
|
|
||||||
load();
|
load();
|
||||||
|
|
||||||
|
this.requiredLinkingListener = new BukkitRequiredLinkingListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public JavaPlugin plugin() {
|
public JavaPlugin plugin() {
|
||||||
@ -97,7 +113,7 @@ public class BukkitDiscordSRV extends ServerDiscordSRV<DiscordSRVBukkitBootstrap
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BukkitScheduler scheduler() {
|
public IBukkitScheduler scheduler() {
|
||||||
return scheduler;
|
return scheduler;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -217,7 +233,8 @@ public class BukkitDiscordSRV extends ServerDiscordSRV<DiscordSRVBukkitBootstrap
|
|||||||
commandHandler = AbstractBukkitCommandHandler.get(this);
|
commandHandler = AbstractBukkitCommandHandler.get(this);
|
||||||
|
|
||||||
// Register listeners
|
// Register listeners
|
||||||
server().getPluginManager().registerEvents(BukkitChatListener.get(this), plugin());
|
server().getPluginManager().registerEvents(BukkitAwardForwarder.get(this), plugin());
|
||||||
|
server().getPluginManager().registerEvents(BukkitChatForwarder.get(this), plugin());
|
||||||
server().getPluginManager().registerEvents(new BukkitDeathListener(this), plugin());
|
server().getPluginManager().registerEvents(new BukkitDeathListener(this), plugin());
|
||||||
server().getPluginManager().registerEvents(new BukkitStatusMessageListener(this), plugin());
|
server().getPluginManager().registerEvents(new BukkitStatusMessageListener(this), plugin());
|
||||||
|
|
||||||
@ -241,4 +258,10 @@ public class BukkitDiscordSRV extends ServerDiscordSRV<DiscordSRVBukkitBootstrap
|
|||||||
server().getPluginManager().registerEvents(new BukkitConnectionListener(this), plugin());
|
server().getPluginManager().registerEvents(new BukkitConnectionListener(this), plugin());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void disable() {
|
||||||
|
super.disable();
|
||||||
|
|
||||||
|
requiredLinkingListener.disable();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,17 +25,36 @@ import com.discordsrv.common.command.game.handler.ICommandHandler;
|
|||||||
import com.discordsrv.common.command.game.sender.ICommandSender;
|
import com.discordsrv.common.command.game.sender.ICommandSender;
|
||||||
import com.discordsrv.common.logging.Logger;
|
import com.discordsrv.common.logging.Logger;
|
||||||
import com.discordsrv.common.logging.NamedLogger;
|
import com.discordsrv.common.logging.NamedLogger;
|
||||||
|
import org.bukkit.Server;
|
||||||
|
import org.bukkit.command.CommandMap;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.command.ConsoleCommandSender;
|
import org.bukkit.command.ConsoleCommandSender;
|
||||||
import org.bukkit.command.PluginCommand;
|
import org.bukkit.command.PluginCommand;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.plugin.Plugin;
|
import org.bukkit.plugin.Plugin;
|
||||||
|
|
||||||
|
import java.lang.invoke.MethodHandle;
|
||||||
|
import java.lang.invoke.MethodHandles;
|
||||||
|
import java.lang.invoke.MethodType;
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
public abstract class AbstractBukkitCommandHandler implements ICommandHandler {
|
public abstract class AbstractBukkitCommandHandler implements ICommandHandler {
|
||||||
|
|
||||||
|
private static final MethodHandle COMMAND_MAP_HANDLE;
|
||||||
|
|
||||||
|
static {
|
||||||
|
MethodHandle handle = null;
|
||||||
|
try {
|
||||||
|
handle = MethodHandles.lookup().findVirtual(
|
||||||
|
Server.class,
|
||||||
|
"getCommandMap",
|
||||||
|
MethodType.methodType(CommandMap.class)
|
||||||
|
);
|
||||||
|
} catch (ReflectiveOperationException ignored) {}
|
||||||
|
COMMAND_MAP_HANDLE = handle;
|
||||||
|
}
|
||||||
|
|
||||||
public static AbstractBukkitCommandHandler get(BukkitDiscordSRV discordSRV) {
|
public static AbstractBukkitCommandHandler get(BukkitDiscordSRV discordSRV) {
|
||||||
try {
|
try {
|
||||||
Class.forName("me.lucko.commodore.Commodore");
|
Class.forName("me.lucko.commodore.Commodore");
|
||||||
@ -76,13 +95,20 @@ public abstract class AbstractBukkitCommandHandler implements ICommandHandler {
|
|||||||
return pluginCommand;
|
return pluginCommand;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (COMMAND_MAP_HANDLE == null) {
|
||||||
|
// CommandMap unusable, can't get the command from it
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
PluginCommand command = null;
|
PluginCommand command = null;
|
||||||
try {
|
try {
|
||||||
Constructor<?> constructor = PluginCommand.class.getDeclaredConstructor(String.class, Plugin.class);
|
Constructor<?> constructor = PluginCommand.class.getDeclaredConstructor(String.class, Plugin.class);
|
||||||
constructor.setAccessible(true);
|
constructor.setAccessible(true);
|
||||||
command = (PluginCommand) constructor.newInstance(label, discordSRV.plugin());
|
command = (PluginCommand) constructor.newInstance(label, discordSRV.plugin());
|
||||||
discordSRV.server().getCommandMap().register(label, discordSRV.plugin().getName().toLowerCase(Locale.ROOT), command);
|
|
||||||
} catch (ReflectiveOperationException ignored) {}
|
CommandMap commandMap = (CommandMap) COMMAND_MAP_HANDLE.invokeExact(discordSRV.server());
|
||||||
|
commandMap.register(label, discordSRV.plugin().getName().toLowerCase(Locale.ROOT), command);
|
||||||
|
} catch (Throwable ignored) {}
|
||||||
|
|
||||||
return command;
|
return command;
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ public class BukkitCommandSender implements ICommandSender {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void runCommand(String command) {
|
public void runCommand(String command) {
|
||||||
discordSRV.scheduler().runOnMainThread(() -> discordSRV.server().dispatchCommand(commandSender, command));
|
discordSRV.scheduler().runOnMainThread(commandSender, () -> discordSRV.server().dispatchCommand(commandSender, command));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -34,6 +34,6 @@ public class CommandSenderExecutor implements CommandExecutor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void runCommand(String command) {
|
public void runCommand(String command) {
|
||||||
discordSRV.scheduler().runOnMainThread(() -> discordSRV.server().dispatchCommand(commandSender, command));
|
discordSRV.scheduler().runOnMainThread(commandSender, () -> discordSRV.server().dispatchCommand(commandSender, command));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,99 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of DiscordSRV, licensed under the GPLv3 License
|
|
||||||
* Copyright (c) 2016-2023 Austin "Scarsz" Shapiro, Henri "Vankka" Schubin and DiscordSRV contributors
|
|
||||||
*
|
|
||||||
* 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 <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.discordsrv.bukkit.listener;
|
|
||||||
|
|
||||||
import com.discordsrv.api.component.MinecraftComponent;
|
|
||||||
import com.discordsrv.api.event.events.message.receive.game.GameChatMessageReceiveEvent;
|
|
||||||
import com.discordsrv.bukkit.BukkitDiscordSRV;
|
|
||||||
import com.discordsrv.bukkit.component.PaperComponentHandle;
|
|
||||||
import com.discordsrv.common.channel.GlobalChannel;
|
|
||||||
import com.discordsrv.common.component.util.ComponentUtil;
|
|
||||||
import io.papermc.paper.event.player.AsyncChatEvent;
|
|
||||||
import net.kyori.adventure.platform.bukkit.BukkitComponentSerializer;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.EventPriority;
|
|
||||||
import org.bukkit.event.Listener;
|
|
||||||
|
|
||||||
public abstract class BukkitChatListener implements Listener {
|
|
||||||
|
|
||||||
public static BukkitChatListener get(BukkitDiscordSRV discordSRV) {
|
|
||||||
// TODO: config option
|
|
||||||
//noinspection ConstantConditions,PointlessBooleanExpression
|
|
||||||
if (1 == 2 && PaperComponentHandle.IS_PAPER_ADVENTURE) {
|
|
||||||
return new Paper(discordSRV);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Bukkit(discordSRV);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected final BukkitDiscordSRV discordSRV;
|
|
||||||
|
|
||||||
public BukkitChatListener(BukkitDiscordSRV discordSRV) {
|
|
||||||
this.discordSRV = discordSRV;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void publishEvent(Player player, MinecraftComponent component, boolean cancelled) {
|
|
||||||
discordSRV.scheduler().run(() -> discordSRV.eventBus().publish(
|
|
||||||
new GameChatMessageReceiveEvent(
|
|
||||||
discordSRV.playerProvider().player(player),
|
|
||||||
new GlobalChannel(discordSRV),
|
|
||||||
component,
|
|
||||||
cancelled
|
|
||||||
)
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
static class Bukkit extends BukkitChatListener {
|
|
||||||
|
|
||||||
public Bukkit(BukkitDiscordSRV discordSRV) {
|
|
||||||
super(discordSRV);
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("deprecation") // Paper
|
|
||||||
@EventHandler(priority = EventPriority.MONITOR)
|
|
||||||
public void onAsyncPlayerChat(org.bukkit.event.player.AsyncPlayerChatEvent event) {
|
|
||||||
MinecraftComponent component = ComponentUtil.toAPI(
|
|
||||||
BukkitComponentSerializer.legacy().deserialize(event.getMessage()));
|
|
||||||
|
|
||||||
publishEvent(event.getPlayer(), component, event.isCancelled());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static class Paper extends BukkitChatListener {
|
|
||||||
|
|
||||||
private final PaperComponentHandle<AsyncChatEvent> componentHandle;
|
|
||||||
|
|
||||||
public Paper(BukkitDiscordSRV discordSRV) {
|
|
||||||
super(discordSRV);
|
|
||||||
this.componentHandle = new PaperComponentHandle<>(
|
|
||||||
AsyncChatEvent.class,
|
|
||||||
"message",
|
|
||||||
null
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.MONITOR)
|
|
||||||
public void onAsyncChat(AsyncChatEvent event) {
|
|
||||||
MinecraftComponent component = componentHandle.getComponent(discordSRV, event);
|
|
||||||
publishEvent(event.getPlayer(), component, event.isCancelled());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -23,32 +23,59 @@ import com.discordsrv.api.event.events.message.receive.game.DeathMessageReceiveE
|
|||||||
import com.discordsrv.api.player.DiscordSRVPlayer;
|
import com.discordsrv.api.player.DiscordSRVPlayer;
|
||||||
import com.discordsrv.bukkit.BukkitDiscordSRV;
|
import com.discordsrv.bukkit.BukkitDiscordSRV;
|
||||||
import com.discordsrv.bukkit.component.PaperComponentHandle;
|
import com.discordsrv.bukkit.component.PaperComponentHandle;
|
||||||
|
import org.bukkit.event.Cancellable;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.EventPriority;
|
import org.bukkit.event.EventPriority;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.event.entity.PlayerDeathEvent;
|
import org.bukkit.event.entity.PlayerDeathEvent;
|
||||||
|
|
||||||
|
import java.lang.invoke.MethodHandle;
|
||||||
|
import java.lang.invoke.MethodHandles;
|
||||||
|
import java.lang.invoke.MethodType;
|
||||||
|
|
||||||
public class BukkitDeathListener implements Listener {
|
public class BukkitDeathListener implements Listener {
|
||||||
|
|
||||||
private final BukkitDiscordSRV discordSRV;
|
private static final PaperComponentHandle<PlayerDeathEvent> COMPONENT_HANDLE;
|
||||||
private final PaperComponentHandle<PlayerDeathEvent> componentHandle;
|
private static final MethodHandle CANCELLED_HANDLE;
|
||||||
|
|
||||||
@SuppressWarnings("deprecation") // Paper
|
static {
|
||||||
public BukkitDeathListener(BukkitDiscordSRV discordSRV) {
|
COMPONENT_HANDLE = new PaperComponentHandle<>(
|
||||||
this.discordSRV = discordSRV;
|
|
||||||
this.componentHandle = new PaperComponentHandle<>(
|
|
||||||
PlayerDeathEvent.class,
|
PlayerDeathEvent.class,
|
||||||
"deathMessage",
|
"deathMessage",
|
||||||
PlayerDeathEvent::getDeathMessage
|
PlayerDeathEvent::getDeathMessage
|
||||||
);
|
);
|
||||||
|
|
||||||
|
MethodHandle handle = null;
|
||||||
|
try {
|
||||||
|
handle = MethodHandles.lookup().findVirtual(
|
||||||
|
Cancellable.class,
|
||||||
|
"isCancelled",
|
||||||
|
MethodType.methodType(boolean.class)
|
||||||
|
);
|
||||||
|
} catch (ReflectiveOperationException ignored) {}
|
||||||
|
CANCELLED_HANDLE = handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final BukkitDiscordSRV discordSRV;
|
||||||
|
|
||||||
|
public BukkitDeathListener(BukkitDiscordSRV discordSRV) {
|
||||||
|
this.discordSRV = discordSRV;
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.MONITOR)
|
@EventHandler(priority = EventPriority.MONITOR)
|
||||||
public void onPlayerDeath(PlayerDeathEvent event) {
|
public void onPlayerDeath(PlayerDeathEvent event) {
|
||||||
DiscordSRVPlayer player = discordSRV.playerProvider().player(event.getEntity());
|
DiscordSRVPlayer player = discordSRV.playerProvider().player(event.getEntity());
|
||||||
MinecraftComponent component = componentHandle.getComponent(discordSRV, event);
|
MinecraftComponent component = COMPONENT_HANDLE.getComponent(discordSRV, event);
|
||||||
|
|
||||||
|
boolean cancelled = false;
|
||||||
|
if (CANCELLED_HANDLE != null) {
|
||||||
|
try {
|
||||||
|
cancelled = (boolean) CANCELLED_HANDLE.invokeExact(event);
|
||||||
|
} catch (Throwable ignored) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean wasCancelled = cancelled;
|
||||||
discordSRV.scheduler().run(() -> discordSRV.eventBus().publish(
|
discordSRV.scheduler().run(() -> discordSRV.eventBus().publish(
|
||||||
new DeathMessageReceiveEvent(player, null, component, event.isCancelled())));
|
new DeathMessageReceiveEvent(player, null, component, wasCancelled)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,284 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of DiscordSRV, licensed under the GPLv3 License
|
||||||
|
* Copyright (c) 2016-2023 Austin "Scarsz" Shapiro, Henri "Vankka" Schubin and DiscordSRV contributors
|
||||||
|
*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.discordsrv.bukkit.listener;
|
||||||
|
|
||||||
|
import com.discordsrv.bukkit.BukkitDiscordSRV;
|
||||||
|
import com.discordsrv.bukkit.config.main.BukkitRequiredLinkingConfig;
|
||||||
|
import com.discordsrv.bukkit.requiredlinking.BukkitRequiredLinkingModule;
|
||||||
|
import com.discordsrv.common.DiscordSRV;
|
||||||
|
import com.discordsrv.common.player.IPlayer;
|
||||||
|
import net.kyori.adventure.platform.bukkit.BukkitComponentSerializer;
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.*;
|
||||||
|
import org.bukkit.event.player.*;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.function.BiConsumer;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
public class BukkitRequiredLinkingListener implements Listener {
|
||||||
|
|
||||||
|
private final BukkitDiscordSRV discordSRV;
|
||||||
|
|
||||||
|
public BukkitRequiredLinkingListener(BukkitDiscordSRV discordSRV) {
|
||||||
|
this.discordSRV = discordSRV;
|
||||||
|
|
||||||
|
register(PlayerLoginEvent.class, this::handle);
|
||||||
|
register(AsyncPlayerPreLoginEvent.class, this::handle);
|
||||||
|
discordSRV.server().getPluginManager().registerEvents(this, discordSRV.plugin());
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private <T extends Event> void register(Class<T> eventType, BiConsumer<T, EventPriority> eventConsumer) {
|
||||||
|
for (EventPriority priority : EventPriority.values()) {
|
||||||
|
if (priority == EventPriority.MONITOR) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
discordSRV.server().getPluginManager().registerEvent(
|
||||||
|
eventType,
|
||||||
|
this,
|
||||||
|
priority,
|
||||||
|
(listener, event) -> eventConsumer.accept((T) event, priority),
|
||||||
|
discordSRV.plugin(),
|
||||||
|
true
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void disable() {
|
||||||
|
HandlerList.unregisterAll(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private BukkitRequiredLinkingModule getModule() {
|
||||||
|
int tries = 0;
|
||||||
|
|
||||||
|
BukkitRequiredLinkingModule module;
|
||||||
|
do {
|
||||||
|
module = discordSRV.getModule(BukkitRequiredLinkingModule.class);
|
||||||
|
|
||||||
|
try {
|
||||||
|
Thread.sleep(100);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
}
|
||||||
|
tries++;
|
||||||
|
} while (module == null || tries >= 50);
|
||||||
|
|
||||||
|
return module;
|
||||||
|
}
|
||||||
|
|
||||||
|
private CompletableFuture<Component> getBlockReason(UUID playerUUID) {
|
||||||
|
BukkitRequiredLinkingModule module = getModule();
|
||||||
|
if (module == null) {
|
||||||
|
return CompletableFuture.completedFuture(Component.text("Discord unavailable, please try again later"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return module.getBlockReason(playerUUID);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Kick
|
||||||
|
//
|
||||||
|
|
||||||
|
private void handle(AsyncPlayerPreLoginEvent event, EventPriority priority) {
|
||||||
|
handle(
|
||||||
|
"AsyncPlayerPreLoginEvent",
|
||||||
|
priority,
|
||||||
|
event.getUniqueId(),
|
||||||
|
() -> event.getLoginResult() != AsyncPlayerPreLoginEvent.Result.ALLOWED ? event.getLoginResult().name() : null,
|
||||||
|
text -> event.disallow(AsyncPlayerPreLoginEvent.Result.KICK_OTHER, text)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handle(PlayerLoginEvent event, EventPriority priority) {
|
||||||
|
handle(
|
||||||
|
"PlayerLoginEvent",
|
||||||
|
priority,
|
||||||
|
event.getPlayer().getUniqueId(),
|
||||||
|
() -> event.getResult() != PlayerLoginEvent.Result.ALLOWED ? event.getResult().name() : null,
|
||||||
|
text -> event.disallow(PlayerLoginEvent.Result.KICK_OTHER, text)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handle(
|
||||||
|
String eventType,
|
||||||
|
EventPriority priority,
|
||||||
|
UUID playerUUID,
|
||||||
|
Supplier<String> alreadyBlocked,
|
||||||
|
Consumer<String> disallow
|
||||||
|
) {
|
||||||
|
BukkitRequiredLinkingConfig config = discordSRV.config().requiredLinking;
|
||||||
|
if (!config.enabled || !config.action.equalsIgnoreCase("KICK")
|
||||||
|
|| !eventType.equals(config.kick.event) || !priority.name().equals(config.kick.priority)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String blockType = alreadyBlocked.get();
|
||||||
|
if (blockType != null) {
|
||||||
|
discordSRV.logger().debug(playerUUID + " is already blocked for " + eventType + "/" + priority + " (" + blockType + ")");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Component kickReason = getBlockReason(playerUUID).join();
|
||||||
|
if (kickReason != null) {
|
||||||
|
disallow.accept(BukkitComponentSerializer.legacy().serialize(kickReason));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Freeze
|
||||||
|
//
|
||||||
|
|
||||||
|
private final Map<UUID, Component> frozen = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
private boolean isFrozen(Player player) {
|
||||||
|
return frozen.containsKey(player.getUniqueId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||||
|
public void onPreLogin(AsyncPlayerPreLoginEvent event) {
|
||||||
|
if (event.getLoginResult() != AsyncPlayerPreLoginEvent.Result.ALLOWED) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (discordSRV.isShutdown()) {
|
||||||
|
return;
|
||||||
|
} else if (!discordSRV.isReady()) {
|
||||||
|
try {
|
||||||
|
discordSRV.waitForStatus(DiscordSRV.Status.CONNECTED);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BukkitRequiredLinkingConfig config = discordSRV.config().requiredLinking;
|
||||||
|
if (!config.enabled || !config.action.equalsIgnoreCase("FREEZE")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Component blockReason = getBlockReason(event.getUniqueId()).join();
|
||||||
|
if (blockReason != null) {
|
||||||
|
frozen.put(event.getUniqueId(), blockReason);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.MONITOR)
|
||||||
|
public void onLogin(PlayerLoginEvent event) {
|
||||||
|
if (event.getResult() != PlayerLoginEvent.Result.ALLOWED) {
|
||||||
|
frozen.remove(event.getPlayer().getUniqueId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.MONITOR)
|
||||||
|
public void onJoin(PlayerJoinEvent event) {
|
||||||
|
UUID uuid = event.getPlayer().getUniqueId();
|
||||||
|
Component blockReason = frozen.get(uuid);
|
||||||
|
if (blockReason == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
IPlayer player = discordSRV.playerProvider().player(uuid);
|
||||||
|
if (player == null) {
|
||||||
|
throw new IllegalStateException("Player not available: " + uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
player.sendMessage(blockReason);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
|
||||||
|
public void onPlayerMove(PlayerMoveEvent event) {
|
||||||
|
Component freezeReason = frozen.get(event.getPlayer().getUniqueId());
|
||||||
|
if (freezeReason == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Location from = event.getFrom(), to = event.getTo();
|
||||||
|
if (from.getWorld().getName().equals(to.getWorld().getName())
|
||||||
|
&& from.getBlockX() == to.getBlockX()
|
||||||
|
&& from.getBlockZ() == to.getBlockZ()
|
||||||
|
&& from.getBlockY() >= to.getBlockY()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
event.setTo(
|
||||||
|
new Location(
|
||||||
|
from.getWorld(),
|
||||||
|
from.getBlockX() + 0.5,
|
||||||
|
from.getBlockY(),
|
||||||
|
from.getBlockZ() + 0.5,
|
||||||
|
from.getYaw(),
|
||||||
|
from.getPitch()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
IPlayer player = discordSRV.playerProvider().player(event.getPlayer());
|
||||||
|
player.sendMessage(freezeReason);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
|
||||||
|
public void onPlayerChat(AsyncPlayerChatEvent event) {
|
||||||
|
Component freezeReason = frozen.get(event.getPlayer().getUniqueId());
|
||||||
|
if (freezeReason == null) {
|
||||||
|
event.getRecipients().removeIf(this::isFrozen);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
event.setCancelled(true);
|
||||||
|
|
||||||
|
IPlayer player = discordSRV.playerProvider().player(event.getPlayer());
|
||||||
|
player.sendMessage(freezeReason);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
|
||||||
|
public void onPlayerCommand(PlayerCommandPreprocessEvent event) {
|
||||||
|
if (!isFrozen(event.getPlayer())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
event.setCancelled(true);
|
||||||
|
|
||||||
|
String message = event.getMessage();
|
||||||
|
if (message.startsWith("/")) message = message.substring(1);
|
||||||
|
if (message.equals("linked")) {
|
||||||
|
IPlayer player = discordSRV.playerProvider().player(event.getPlayer());
|
||||||
|
player.sendMessage(Component.text("Checking..."));
|
||||||
|
|
||||||
|
UUID uuid = player.uniqueId();
|
||||||
|
getBlockReason(uuid).whenComplete((reason, t) -> {
|
||||||
|
if (t != null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reason == null) {
|
||||||
|
frozen.remove(uuid);
|
||||||
|
} else {
|
||||||
|
frozen.put(uuid, reason);
|
||||||
|
player.sendMessage(reason);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -32,29 +32,32 @@ import org.bukkit.event.player.PlayerQuitEvent;
|
|||||||
|
|
||||||
public class BukkitStatusMessageListener implements Listener {
|
public class BukkitStatusMessageListener implements Listener {
|
||||||
|
|
||||||
private final BukkitDiscordSRV discordSRV;
|
private static final PaperComponentHandle<PlayerJoinEvent> JOIN_HANDLE;
|
||||||
private final PaperComponentHandle<PlayerJoinEvent> joinHandle;
|
private static final PaperComponentHandle<PlayerQuitEvent> QUIT_HANDLE;
|
||||||
private final PaperComponentHandle<PlayerQuitEvent> quitHandle;
|
|
||||||
|
|
||||||
@SuppressWarnings("deprecation") // Paper
|
static {
|
||||||
public BukkitStatusMessageListener(BukkitDiscordSRV discordSRV) {
|
JOIN_HANDLE = new PaperComponentHandle<>(
|
||||||
this.discordSRV = discordSRV;
|
|
||||||
this.joinHandle = new PaperComponentHandle<>(
|
|
||||||
PlayerJoinEvent.class,
|
PlayerJoinEvent.class,
|
||||||
"joinMessage",
|
"joinMessage",
|
||||||
PlayerJoinEvent::getJoinMessage
|
PlayerJoinEvent::getJoinMessage
|
||||||
);
|
);
|
||||||
this.quitHandle = new PaperComponentHandle<>(
|
QUIT_HANDLE = new PaperComponentHandle<>(
|
||||||
PlayerQuitEvent.class,
|
PlayerQuitEvent.class,
|
||||||
"quitMessage",
|
"quitMessage",
|
||||||
PlayerQuitEvent::getQuitMessage
|
PlayerQuitEvent::getQuitMessage
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final BukkitDiscordSRV discordSRV;
|
||||||
|
|
||||||
|
public BukkitStatusMessageListener(BukkitDiscordSRV discordSRV) {
|
||||||
|
this.discordSRV = discordSRV;
|
||||||
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.MONITOR)
|
@EventHandler(priority = EventPriority.MONITOR)
|
||||||
public void onPlayerJoin(PlayerJoinEvent event) {
|
public void onPlayerJoin(PlayerJoinEvent event) {
|
||||||
DiscordSRVPlayer player = discordSRV.playerProvider().player(event.getPlayer());
|
DiscordSRVPlayer player = discordSRV.playerProvider().player(event.getPlayer());
|
||||||
MinecraftComponent component = joinHandle.getComponent(discordSRV, event);
|
MinecraftComponent component = JOIN_HANDLE.getComponent(discordSRV, event);
|
||||||
boolean firstJoin = !event.getPlayer().hasPlayedBefore();
|
boolean firstJoin = !event.getPlayer().hasPlayedBefore();
|
||||||
|
|
||||||
discordSRV.scheduler().run(() -> discordSRV.eventBus().publish(
|
discordSRV.scheduler().run(() -> discordSRV.eventBus().publish(
|
||||||
@ -65,7 +68,7 @@ public class BukkitStatusMessageListener implements Listener {
|
|||||||
@EventHandler(priority = EventPriority.HIGH)
|
@EventHandler(priority = EventPriority.HIGH)
|
||||||
public void onPlayerQuit(PlayerQuitEvent event) {
|
public void onPlayerQuit(PlayerQuitEvent event) {
|
||||||
DiscordSRVPlayer player = discordSRV.playerProvider().player(event.getPlayer());
|
DiscordSRVPlayer player = discordSRV.playerProvider().player(event.getPlayer());
|
||||||
MinecraftComponent component = quitHandle.getComponent(discordSRV, event);
|
MinecraftComponent component = QUIT_HANDLE.getComponent(discordSRV, event);
|
||||||
|
|
||||||
discordSRV.scheduler().run(() -> discordSRV.eventBus().publish(
|
discordSRV.scheduler().run(() -> discordSRV.eventBus().publish(
|
||||||
new LeaveMessageReceiveEvent(player, null, component, false)
|
new LeaveMessageReceiveEvent(player, null, component, false)
|
||||||
|
@ -0,0 +1,26 @@
|
|||||||
|
package com.discordsrv.bukkit.listener.award;
|
||||||
|
|
||||||
|
import com.discordsrv.api.component.MinecraftComponent;
|
||||||
|
import com.discordsrv.common.DiscordSRV;
|
||||||
|
import com.discordsrv.common.component.util.ComponentUtil;
|
||||||
|
import net.kyori.adventure.platform.bukkit.BukkitComponentSerializer;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
|
import org.bukkit.event.player.PlayerAchievementAwardedEvent;
|
||||||
|
|
||||||
|
public class BukkitAchievementListener extends AbstractBukkitAwardListener {
|
||||||
|
|
||||||
|
public BukkitAchievementListener(DiscordSRV discordSRV, IBukkitAwardForwarder forwarder) {
|
||||||
|
super(discordSRV, forwarder);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.MONITOR)
|
||||||
|
public void onPlayerAchievementAwarded(PlayerAchievementAwardedEvent event) {
|
||||||
|
if (checkIfShouldSkip(event.getPlayer())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MinecraftComponent name = ComponentUtil.toAPI(BukkitComponentSerializer.legacy().deserialize(event.getAchievement().name()));
|
||||||
|
forwarder.publishEvent(event.getPlayer(), null, name, event.isCancelled());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
package com.discordsrv.bukkit.listener.award;
|
||||||
|
|
||||||
|
import com.discordsrv.api.component.MinecraftComponent;
|
||||||
|
import com.discordsrv.bukkit.BukkitDiscordSRV;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
|
||||||
|
public class BukkitAwardForwarder implements IBukkitAwardForwarder {
|
||||||
|
|
||||||
|
public static Listener get(BukkitDiscordSRV discordSRV) {
|
||||||
|
try {
|
||||||
|
Class.forName("org.bukkit.event.player.PlayerAdvancementDoneEvent");
|
||||||
|
try {
|
||||||
|
Class.forName("io.papermc.paper.advancement.AdvancementDisplay");
|
||||||
|
|
||||||
|
return new PaperModernAdvancementListener(discordSRV, new BukkitAwardForwarder(discordSRV));
|
||||||
|
} catch (ClassNotFoundException ignored) {
|
||||||
|
return new BukkitAdvancementListener(discordSRV, new BukkitAwardForwarder(discordSRV));
|
||||||
|
}
|
||||||
|
} catch (ClassNotFoundException ignored) {
|
||||||
|
return new BukkitAchievementListener(discordSRV, new BukkitAwardForwarder(discordSRV));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final BukkitDiscordSRV discordSRV;
|
||||||
|
|
||||||
|
protected BukkitAwardForwarder(BukkitDiscordSRV discordSRV) {
|
||||||
|
this.discordSRV = discordSRV;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void publishEvent(Player player, MinecraftComponent message, MinecraftComponent advancementName, boolean cancelled) {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of DiscordSRV, licensed under the GPLv3 License
|
||||||
|
* Copyright (c) 2016-2023 Austin "Scarsz" Shapiro, Henri "Vankka" Schubin and DiscordSRV contributors
|
||||||
|
*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.discordsrv.bukkit.listener.chat;
|
||||||
|
|
||||||
|
import com.discordsrv.api.component.MinecraftComponent;
|
||||||
|
import com.discordsrv.api.event.events.message.receive.game.GameChatMessageReceiveEvent;
|
||||||
|
import com.discordsrv.bukkit.BukkitDiscordSRV;
|
||||||
|
import com.discordsrv.bukkit.component.PaperComponentHandle;
|
||||||
|
import com.discordsrv.common.channel.GlobalChannel;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
|
||||||
|
public class BukkitChatForwarder implements IBukkitChatForwarder {
|
||||||
|
|
||||||
|
public static Listener get(BukkitDiscordSRV discordSRV) {
|
||||||
|
// TODO: config option
|
||||||
|
//noinspection ConstantConditions,PointlessBooleanExpression
|
||||||
|
if (1 == 2 && PaperComponentHandle.IS_PAPER_ADVENTURE) {
|
||||||
|
return new PaperChatListener(discordSRV, new BukkitChatForwarder(discordSRV));
|
||||||
|
}
|
||||||
|
|
||||||
|
return new BukkitChatListener(new BukkitChatForwarder(discordSRV));
|
||||||
|
}
|
||||||
|
|
||||||
|
private final BukkitDiscordSRV discordSRV;
|
||||||
|
|
||||||
|
protected BukkitChatForwarder(BukkitDiscordSRV discordSRV) {
|
||||||
|
this.discordSRV = discordSRV;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void publishEvent(Player player, MinecraftComponent component, boolean cancelled) {
|
||||||
|
discordSRV.scheduler().run(() -> discordSRV.eventBus().publish(
|
||||||
|
new GameChatMessageReceiveEvent(
|
||||||
|
discordSRV.playerProvider().player(player),
|
||||||
|
new GlobalChannel(discordSRV),
|
||||||
|
component,
|
||||||
|
cancelled
|
||||||
|
)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
package com.discordsrv.bukkit.listener.chat;
|
||||||
|
|
||||||
|
import com.discordsrv.api.component.MinecraftComponent;
|
||||||
|
import com.discordsrv.common.component.util.ComponentUtil;
|
||||||
|
import net.kyori.adventure.platform.bukkit.BukkitComponentSerializer;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
|
||||||
|
public class BukkitChatListener implements Listener {
|
||||||
|
|
||||||
|
private final IBukkitChatForwarder forwarder;
|
||||||
|
|
||||||
|
public BukkitChatListener(IBukkitChatForwarder forwarder) {
|
||||||
|
this.forwarder = forwarder;
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.MONITOR)
|
||||||
|
public void onAsyncPlayerChat(org.bukkit.event.player.AsyncPlayerChatEvent event) {
|
||||||
|
MinecraftComponent component = ComponentUtil.toAPI(
|
||||||
|
BukkitComponentSerializer.legacy().deserialize(event.getMessage()));
|
||||||
|
|
||||||
|
forwarder.publishEvent(event.getPlayer(), component, event.isCancelled());
|
||||||
|
}
|
||||||
|
}
|
@ -19,24 +19,10 @@
|
|||||||
package com.discordsrv.bukkit.requiredlinking;
|
package com.discordsrv.bukkit.requiredlinking;
|
||||||
|
|
||||||
import com.discordsrv.bukkit.BukkitDiscordSRV;
|
import com.discordsrv.bukkit.BukkitDiscordSRV;
|
||||||
import com.discordsrv.bukkit.config.main.BukkitRequiredLinkingConfig;
|
|
||||||
import com.discordsrv.common.config.main.linking.RequirementsConfig;
|
import com.discordsrv.common.config.main.linking.RequirementsConfig;
|
||||||
import com.discordsrv.common.linking.requirelinking.ServerRequireLinkingModule;
|
import com.discordsrv.common.linking.requirelinking.ServerRequireLinkingModule;
|
||||||
import net.kyori.adventure.platform.bukkit.BukkitComponentSerializer;
|
|
||||||
import net.kyori.adventure.text.Component;
|
|
||||||
import org.bukkit.event.Event;
|
|
||||||
import org.bukkit.event.EventPriority;
|
|
||||||
import org.bukkit.event.HandlerList;
|
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.event.player.AsyncPlayerPreLoginEvent;
|
|
||||||
import org.bukkit.event.player.PlayerLoginEvent;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.function.BiConsumer;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
// TODO: implement freeze
|
|
||||||
public class BukkitRequiredLinkingModule extends ServerRequireLinkingModule<BukkitDiscordSRV> implements Listener {
|
public class BukkitRequiredLinkingModule extends ServerRequireLinkingModule<BukkitDiscordSRV> implements Listener {
|
||||||
|
|
||||||
public BukkitRequiredLinkingModule(BukkitDiscordSRV discordSRV) {
|
public BukkitRequiredLinkingModule(BukkitDiscordSRV discordSRV) {
|
||||||
@ -47,84 +33,4 @@ public class BukkitRequiredLinkingModule extends ServerRequireLinkingModule<Bukk
|
|||||||
public RequirementsConfig config() {
|
public RequirementsConfig config() {
|
||||||
return discordSRV.config().requiredLinking.requirements;
|
return discordSRV.config().requiredLinking.requirements;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void enable() {
|
|
||||||
super.enable();
|
|
||||||
|
|
||||||
register(PlayerLoginEvent.class, this::handle);
|
|
||||||
register(AsyncPlayerPreLoginEvent.class, this::handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
private <T extends Event> void register(Class<T> eventType, BiConsumer<T, EventPriority> eventConsumer) {
|
|
||||||
for (EventPriority priority : EventPriority.values()) {
|
|
||||||
if (priority == EventPriority.MONITOR) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
discordSRV.server().getPluginManager().registerEvent(
|
|
||||||
eventType,
|
|
||||||
this,
|
|
||||||
priority,
|
|
||||||
(listener, event) -> eventConsumer.accept((T) event, priority),
|
|
||||||
discordSRV.plugin(),
|
|
||||||
true
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("deprecation") // Component is relocated so using it here is inconvenient
|
|
||||||
private void handle(AsyncPlayerPreLoginEvent event, EventPriority priority) {
|
|
||||||
handle(
|
|
||||||
"AsyncPlayerPreLoginEvent",
|
|
||||||
priority,
|
|
||||||
event.getUniqueId(),
|
|
||||||
() -> event.getLoginResult() != AsyncPlayerPreLoginEvent.Result.ALLOWED ? event.getLoginResult().name() : null,
|
|
||||||
text -> event.disallow(AsyncPlayerPreLoginEvent.Result.KICK_OTHER, text)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("deprecation") // Component is relocated so using it here is inconvenient
|
|
||||||
private void handle(PlayerLoginEvent event, EventPriority priority) {
|
|
||||||
handle(
|
|
||||||
"PlayerLoginEvent",
|
|
||||||
priority,
|
|
||||||
event.getPlayer().getUniqueId(),
|
|
||||||
() -> event.getResult() != PlayerLoginEvent.Result.ALLOWED ? event.getResult().name() : null,
|
|
||||||
text -> event.disallow(PlayerLoginEvent.Result.KICK_OTHER, text)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handle(
|
|
||||||
String eventType,
|
|
||||||
EventPriority priority,
|
|
||||||
UUID playerUUID,
|
|
||||||
Supplier<String> alreadyBlocked,
|
|
||||||
Consumer<String> disallow
|
|
||||||
) {
|
|
||||||
BukkitRequiredLinkingConfig config = discordSRV.config().requiredLinking;
|
|
||||||
if (!config.enabled || !config.action.equalsIgnoreCase("KICK")
|
|
||||||
|| !eventType.equals(config.kick.event) || !priority.name().equals(config.kick.priority)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
String blockType = alreadyBlocked.get();
|
|
||||||
if (blockType != null) {
|
|
||||||
discordSRV.logger().debug(playerUUID + " is already blocked for " + eventType + "/" + priority + " (" + blockType + ")");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Component kickReason = getKickReason(playerUUID).join();
|
|
||||||
if (kickReason != null) {
|
|
||||||
disallow.accept(BukkitComponentSerializer.legacy().serialize(kickReason));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void disable() {
|
|
||||||
super.disable();
|
|
||||||
|
|
||||||
HandlerList.unregisterAll(this);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of DiscordSRV, licensed under the GPLv3 License
|
||||||
|
* Copyright (c) 2016-2023 Austin "Scarsz" Shapiro, Henri "Vankka" Schubin and DiscordSRV contributors
|
||||||
|
*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.discordsrv.bukkit.scheduler;
|
||||||
|
|
||||||
|
import com.discordsrv.bukkit.BukkitDiscordSRV;
|
||||||
|
import com.discordsrv.common.scheduler.ServerScheduler;
|
||||||
|
import com.discordsrv.common.scheduler.StandardScheduler;
|
||||||
|
import org.bukkit.Server;
|
||||||
|
import org.bukkit.plugin.Plugin;
|
||||||
|
|
||||||
|
import java.util.function.BiConsumer;
|
||||||
|
|
||||||
|
public abstract class AbstractBukkitScheduler extends StandardScheduler implements ServerScheduler, IBukkitScheduler {
|
||||||
|
|
||||||
|
protected final BukkitDiscordSRV discordSRV;
|
||||||
|
|
||||||
|
public AbstractBukkitScheduler(BukkitDiscordSRV discordSRV) {
|
||||||
|
super(discordSRV);
|
||||||
|
this.discordSRV = discordSRV;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void runWithArgs(BiConsumer<Server, Plugin> runNormal) {
|
||||||
|
runNormal.accept(discordSRV.server(), discordSRV.plugin());
|
||||||
|
}
|
||||||
|
}
|
@ -21,43 +21,39 @@ package com.discordsrv.bukkit.scheduler;
|
|||||||
import com.discordsrv.bukkit.BukkitDiscordSRV;
|
import com.discordsrv.bukkit.BukkitDiscordSRV;
|
||||||
import com.discordsrv.bukkit.DiscordSRVBukkitBootstrap;
|
import com.discordsrv.bukkit.DiscordSRVBukkitBootstrap;
|
||||||
import com.discordsrv.common.DiscordSRV;
|
import com.discordsrv.common.DiscordSRV;
|
||||||
import com.discordsrv.common.scheduler.ServerScheduler;
|
import org.bukkit.Server;
|
||||||
import com.discordsrv.common.scheduler.StandardScheduler;
|
|
||||||
import org.bukkit.plugin.Plugin;
|
import org.bukkit.plugin.Plugin;
|
||||||
|
|
||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
|
|
||||||
public class BukkitScheduler extends StandardScheduler implements ServerScheduler {
|
public class BukkitScheduler extends AbstractBukkitScheduler {
|
||||||
|
|
||||||
private final BukkitDiscordSRV discordSRV;
|
|
||||||
|
|
||||||
public BukkitScheduler(BukkitDiscordSRV discordSRV) {
|
public BukkitScheduler(BukkitDiscordSRV discordSRV) {
|
||||||
super(discordSRV);
|
super(discordSRV);
|
||||||
this.discordSRV = discordSRV;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkDisable(Runnable task, BiConsumer<org.bukkit.scheduler.BukkitScheduler, Plugin> runNormal) {
|
protected void checkDisable(Runnable task, BiConsumer<Server, Plugin> runNormal) {
|
||||||
// Can't run tasks when disabling, so we'll push those to the bootstrap to run after disable
|
// Can't run tasks when disabling, so we'll push those to the bootstrap to run after disable
|
||||||
if (!discordSRV.plugin().isEnabled() && discordSRV.status() == DiscordSRV.Status.SHUTTING_DOWN) {
|
if (!discordSRV.plugin().isEnabled() && discordSRV.status() == DiscordSRV.Status.SHUTTING_DOWN) {
|
||||||
((DiscordSRVBukkitBootstrap) discordSRV.bootstrap()).mainThreadTasksForDisable().add(task);
|
((DiscordSRVBukkitBootstrap) discordSRV.bootstrap()).mainThreadTasksForDisable().add(task);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
runNormal.accept(discordSRV.server().getScheduler(), discordSRV.plugin());
|
runWithArgs(runNormal);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void runOnMainThread(Runnable task) {
|
public void runOnMainThread(Runnable task) {
|
||||||
checkDisable(task, (scheduler, plugin) -> scheduler.runTask(plugin, task));
|
checkDisable(task, (server, plugin) -> server.getScheduler().runTask(plugin, task));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void runOnMainThreadLaterInTicks(Runnable task, int ticks) {
|
public void runOnMainThreadLaterInTicks(Runnable task, int ticks) {
|
||||||
checkDisable(task, (scheduler, plugin) -> scheduler.runTaskLater(plugin, task, ticks));
|
checkDisable(task, (server, plugin) -> server.getScheduler().runTaskLater(plugin, task, ticks));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void runOnMainThreadAtFixedRateInTicks(Runnable task, int initialTicks, int rateTicks) {
|
public void runOnMainThreadAtFixedRateInTicks(Runnable task, int initialTicks, int rateTicks) {
|
||||||
checkDisable(task, (scheduler, plugin) -> scheduler.runTaskTimer(plugin, task, initialTicks, rateTicks));
|
checkDisable(task, (server, plugin) -> server.getScheduler().runTaskTimer(plugin, task, initialTicks, rateTicks));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of DiscordSRV, licensed under the GPLv3 License
|
||||||
|
* Copyright (c) 2016-2023 Austin "Scarsz" Shapiro, Henri "Vankka" Schubin and DiscordSRV contributors
|
||||||
|
*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.discordsrv.bukkit.scheduler;
|
||||||
|
|
||||||
|
import com.discordsrv.bukkit.BukkitDiscordSRV;
|
||||||
|
|
||||||
|
public class FoliaScheduler extends AbstractBukkitScheduler implements IFoliaScheduler {
|
||||||
|
|
||||||
|
public FoliaScheduler(BukkitDiscordSRV discordSRV) {
|
||||||
|
super(discordSRV);
|
||||||
|
}
|
||||||
|
}
|
@ -25,10 +25,10 @@ import com.discordsrv.common.debug.file.TextDebugFile;
|
|||||||
import com.discordsrv.common.paste.Paste;
|
import com.discordsrv.common.paste.Paste;
|
||||||
import com.discordsrv.common.paste.PasteService;
|
import com.discordsrv.common.paste.PasteService;
|
||||||
import com.discordsrv.common.plugin.Plugin;
|
import com.discordsrv.common.plugin.Plugin;
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
import com.fasterxml.jackson.databind.node.ArrayNode;
|
import com.fasterxml.jackson.databind.node.ArrayNode;
|
||||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||||
import net.dv8tion.jda.api.JDA;
|
import net.dv8tion.jda.api.JDA;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.apache.commons.lang3.exception.ExceptionUtils;
|
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -113,7 +113,9 @@ public class DebugReport {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void addFile(DebugFile file) {
|
public void addFile(DebugFile file) {
|
||||||
files.add(file);
|
if (file != null) {
|
||||||
|
files.add(file);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private DebugFile environment() {
|
private DebugFile environment() {
|
||||||
@ -167,24 +169,12 @@ public class DebugReport {
|
|||||||
.sorted(Comparator.comparing(plugin -> plugin.name().toLowerCase(Locale.ROOT)))
|
.sorted(Comparator.comparing(plugin -> plugin.name().toLowerCase(Locale.ROOT)))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
int longestName = 0;
|
try {
|
||||||
int longestVersion = 0;
|
String json = discordSRV.json().writeValueAsString(plugins);
|
||||||
for (Plugin plugin : plugins) {
|
return new TextDebugFile(5, "plugins.json", json);
|
||||||
longestName = Math.max(longestName, plugin.name().length());
|
} catch (JsonProcessingException e) {
|
||||||
longestVersion = Math.max(longestVersion, plugin.version().length());
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
longestName++;
|
|
||||||
longestVersion++;
|
|
||||||
StringBuilder builder = new StringBuilder("Plugins (" + plugins.size() + "):\n");
|
|
||||||
|
|
||||||
for (Plugin plugin : plugins) {
|
|
||||||
builder.append('\n')
|
|
||||||
.append(StringUtils.rightPad(plugin.name(), longestName))
|
|
||||||
.append(" v").append(StringUtils.rightPad(plugin.version(), longestVersion))
|
|
||||||
.append(" ").append(plugin.authors());
|
|
||||||
}
|
|
||||||
return new TextDebugFile(5, "plugins.txt", builder.toString());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private DebugFile readFile(int order, Path file) {
|
private DebugFile readFile(int order, Path file) {
|
||||||
|
@ -50,7 +50,7 @@ public abstract class ServerRequireLinkingModule<T extends DiscordSRV> extends R
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public CompletableFuture<Component> getKickReason(UUID playerUUID) {
|
public CompletableFuture<Component> getBlockReason(UUID playerUUID) {
|
||||||
RequirementsConfig config = config();
|
RequirementsConfig config = config();
|
||||||
if (config.bypassUUIDs.contains(playerUUID.toString())) {
|
if (config.bypassUUIDs.contains(playerUUID.toString())) {
|
||||||
// Bypasses: let them through
|
// Bypasses: let them through
|
||||||
@ -63,7 +63,7 @@ public abstract class ServerRequireLinkingModule<T extends DiscordSRV> extends R
|
|||||||
return CompletableFuture.completedFuture(Component.text("Unable to check linking status at this time"));
|
return CompletableFuture.completedFuture(Component.text("Unable to check linking status at this time"));
|
||||||
}
|
}
|
||||||
|
|
||||||
return linkProvider.getUserId(playerUUID)
|
return linkProvider.queryUserId(playerUUID)
|
||||||
.thenCompose(opt -> {
|
.thenCompose(opt -> {
|
||||||
if (!opt.isPresent()) {
|
if (!opt.isPresent()) {
|
||||||
// User is not linked
|
// User is not linked
|
||||||
|
@ -38,7 +38,7 @@ public class BytebinPasteService implements PasteService {
|
|||||||
public Paste uploadFile(byte[] fileContent) throws Throwable {
|
public Paste uploadFile(byte[] fileContent) throws Throwable {
|
||||||
Request request = new Request.Builder()
|
Request request = new Request.Builder()
|
||||||
.url(bytebinUrl + "/post")
|
.url(bytebinUrl + "/post")
|
||||||
.header("Content-Encoding", "gzip")
|
//.header("Content-Encoding", "gzip")
|
||||||
.post(RequestBody.create(MediaType.get("application/octet-stream"), fileContent))
|
.post(RequestBody.create(MediaType.get("application/octet-stream"), fileContent))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
@ -18,13 +18,19 @@
|
|||||||
|
|
||||||
package com.discordsrv.common.plugin;
|
package com.discordsrv.common.plugin;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class Plugin {
|
public class Plugin {
|
||||||
|
|
||||||
|
@JsonProperty("identifier")
|
||||||
private final String identifier;
|
private final String identifier;
|
||||||
|
@JsonProperty("name")
|
||||||
private final String name;
|
private final String name;
|
||||||
|
@JsonProperty("version")
|
||||||
private final String version;
|
private final String version;
|
||||||
|
@JsonProperty("authors")
|
||||||
private final List<String> authors;
|
private final List<String> authors;
|
||||||
|
|
||||||
public Plugin(String name, String version, List<String> authors) {
|
public Plugin(String name, String version, List<String> authors) {
|
||||||
|
@ -16,10 +16,14 @@ dependencyResolutionManagement {
|
|||||||
plugin('indra-git', 'net.kyori.indra.git').version('2.1.1')
|
plugin('indra-git', 'net.kyori.indra.git').version('2.1.1')
|
||||||
|
|
||||||
// Bukkit
|
// Bukkit
|
||||||
version('bukkit', '1.16.5-R0.1-SNAPSHOT')
|
version('bukkit_minimum', '1.8.8-R0.1-SNAPSHOT')
|
||||||
library('paperapi', 'io.papermc.paper', 'paper-api').versionRef('bukkit')
|
version('bukkit1_12', '1.12.2-R0.1-SNAPSHOT')
|
||||||
library('paperapi-old', 'com.destroystokyo.paper', 'paper-api').versionRef('bukkit')
|
version('bukkit_latest', '1.19.4-R0.1-SNAPSHOT')
|
||||||
library('spigotapi', 'org.spigotmc', 'spigot-api').versionRef('bukkit')
|
version('folia', '1.19.4-R0.1-SNAPSHOT')
|
||||||
|
library('paperapi', 'io.papermc.paper', 'paper-api').versionRef('bukkit_latest')
|
||||||
|
library('spigotapi', 'org.spigotmc', 'spigot-api').versionRef('bukkit_minimum')
|
||||||
|
library('spigotapi-onetwelve', 'org.spigotmc', 'spigot-api').versionRef('bukkit1_12')
|
||||||
|
library('folia', 'dev.folia', 'folia-api').versionRef('folia')
|
||||||
|
|
||||||
// Bungee
|
// Bungee
|
||||||
library('bungee', 'net.md-5', 'bungeecord-api').version('1.17-R0.1-SNAPSHOT')
|
library('bungee', 'net.md-5', 'bungeecord-api').version('1.17-R0.1-SNAPSHOT')
|
||||||
@ -141,7 +145,7 @@ rootProject.name = 'DiscordSRV2'
|
|||||||
'common', 'common:api',
|
'common', 'common:api',
|
||||||
'i18n',
|
'i18n',
|
||||||
'api',
|
'api',
|
||||||
'bukkit', 'bukkit:loader',
|
'bukkit', 'bukkit:loader', 'bukkit:folia', 'bukkit:paper', 'bukkit:bukkit1_12',
|
||||||
'bungee', 'bungee:loader',
|
'bungee', 'bungee:loader',
|
||||||
'sponge', 'sponge:loader',
|
'sponge', 'sponge:loader',
|
||||||
'velocity'
|
'velocity'
|
||||||
|
Loading…
Reference in New Issue
Block a user