New modules again + some pom refactor
This commit is contained in:
parent
f4d436671c
commit
aff229164c
43
pandalib-bungee-permissions/pom.xml
Normal file
43
pandalib-bungee-permissions/pom.xml
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<parent>
|
||||||
|
<artifactId>pandalib-parent</artifactId>
|
||||||
|
<groupId>fr.pandacube.lib</groupId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<artifactId>pandalib-bungee-permissions</artifactId>
|
||||||
|
|
||||||
|
<repositories>
|
||||||
|
<repository>
|
||||||
|
<id>bungeecord-repo</id>
|
||||||
|
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
|
||||||
|
</repository>
|
||||||
|
</repositories>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>fr.pandacube.lib</groupId>
|
||||||
|
<artifactId>pandalib-players-permissible</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>fr.pandacube.lib</groupId>
|
||||||
|
<artifactId>pandalib-permissions</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>net.md-5</groupId>
|
||||||
|
<artifactId>bungeecord-api</artifactId>
|
||||||
|
<version>${bungeecord.version}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
|
||||||
|
</project>
|
@ -0,0 +1,57 @@
|
|||||||
|
package fr.pandacube.lib.bungee.permissions;
|
||||||
|
|
||||||
|
import net.md_5.bungee.api.CommandSender;
|
||||||
|
import net.md_5.bungee.api.ProxyServer;
|
||||||
|
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||||
|
import net.md_5.bungee.api.connection.Server;
|
||||||
|
import net.md_5.bungee.api.event.PermissionCheckEvent;
|
||||||
|
import net.md_5.bungee.api.plugin.Listener;
|
||||||
|
import net.md_5.bungee.api.plugin.Plugin;
|
||||||
|
import net.md_5.bungee.event.EventHandler;
|
||||||
|
|
||||||
|
import fr.pandacube.lib.permissions.Permissions;
|
||||||
|
import fr.pandacube.lib.players.permissible.PermissibleOnlinePlayer;
|
||||||
|
import fr.pandacube.lib.players.permissible.PermissiblePlayerManager;
|
||||||
|
|
||||||
|
public class PandalibBungeePermissions implements Listener {
|
||||||
|
|
||||||
|
public static void init(Plugin bungeePlugin) {
|
||||||
|
ProxyServer.getInstance().getPluginManager().registerListener(bungeePlugin, new PandalibBungeePermissions());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@EventHandler(priority = Byte.MAX_VALUE)
|
||||||
|
public void onPermissionCheck(PermissionCheckEvent event)
|
||||||
|
{
|
||||||
|
CommandSender s = event.getSender();
|
||||||
|
if (s instanceof ProxiedPlayer p) {
|
||||||
|
event.setHasPermission(hasPerm(p, event.getPermission()));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
event.setHasPermission(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private volatile boolean tryPermPlayerManager = true;
|
||||||
|
|
||||||
|
private boolean hasPerm(ProxiedPlayer p, String permission) {
|
||||||
|
if (tryPermPlayerManager) {
|
||||||
|
try {
|
||||||
|
PermissiblePlayerManager<?, ?> pm = PermissiblePlayerManager.getInstance();
|
||||||
|
if (pm != null) {
|
||||||
|
PermissibleOnlinePlayer op = pm.get(p.getUniqueId());
|
||||||
|
if (op != null) {
|
||||||
|
return op.hasPermission(permission);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (NoClassDefFoundError ignored) {
|
||||||
|
tryPermPlayerManager = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if not using player manager, fallback to directly call permissions API
|
||||||
|
Server sv = p.getServer();
|
||||||
|
String server = sv == null ? null : sv.getInfo().getName();
|
||||||
|
return Permissions.getPlayer(p.getUniqueId()).hasPermissionOr(permission, server, null, false);
|
||||||
|
}
|
||||||
|
}
|
49
pandalib-bungee-players/pom.xml
Normal file
49
pandalib-bungee-players/pom.xml
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<parent>
|
||||||
|
<artifactId>pandalib-parent</artifactId>
|
||||||
|
<groupId>fr.pandacube.lib</groupId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<artifactId>pandalib-bungee-players</artifactId>
|
||||||
|
|
||||||
|
<repositories>
|
||||||
|
<repository>
|
||||||
|
<id>bungeecord-repo</id>
|
||||||
|
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
|
||||||
|
</repository>
|
||||||
|
</repositories>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>fr.pandacube.lib</groupId>
|
||||||
|
<artifactId>pandalib-players-standalone</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>fr.pandacube.lib</groupId>
|
||||||
|
<artifactId>pandalib-reflect</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>net.md-5</groupId>
|
||||||
|
<artifactId>bungeecord-api</artifactId>
|
||||||
|
<version>${bungeecord.version}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>net.md-5</groupId>
|
||||||
|
<artifactId>bungeecord-protocol</artifactId>
|
||||||
|
<version>${bungeecord.version}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
</project>
|
@ -0,0 +1,26 @@
|
|||||||
|
package fr.pandacube.lib.bungee.players;
|
||||||
|
|
||||||
|
import net.md_5.bungee.api.ProxyServer;
|
||||||
|
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||||
|
|
||||||
|
import fr.pandacube.lib.players.standalone.StandaloneOffPlayer;
|
||||||
|
|
||||||
|
public interface BungeeOffPlayer extends StandaloneOffPlayer {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Related class instances
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return l'instance Bungee du joueur en ligne, ou null si il n'est pas en
|
||||||
|
* ligne
|
||||||
|
*/
|
||||||
|
default ProxiedPlayer getBungeeProxiedPlayer() {
|
||||||
|
return ProxyServer.getInstance().getPlayer(getUniqueId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
BungeeOnlinePlayer getOnlineInstance();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,208 @@
|
|||||||
|
package fr.pandacube.lib.bungee.players;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.buffer.ByteBufAllocator;
|
||||||
|
import net.kyori.adventure.identity.Identified;
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import net.kyori.adventure.text.ComponentLike;
|
||||||
|
import net.md_5.bungee.api.ProxyServer;
|
||||||
|
import net.md_5.bungee.api.SkinConfiguration;
|
||||||
|
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||||
|
import net.md_5.bungee.api.connection.ProxiedPlayer.ChatMode;
|
||||||
|
import net.md_5.bungee.api.connection.ProxiedPlayer.MainHand;
|
||||||
|
import net.md_5.bungee.protocol.DefinedPacket;
|
||||||
|
import net.md_5.bungee.protocol.packet.ClientSettings;
|
||||||
|
import net.md_5.bungee.protocol.packet.PluginMessage;
|
||||||
|
|
||||||
|
import fr.pandacube.lib.chat.Chat;
|
||||||
|
import fr.pandacube.lib.players.standalone.StandaloneOnlinePlayer;
|
||||||
|
import fr.pandacube.lib.reflect.Reflect;
|
||||||
|
|
||||||
|
public interface BungeeOnlinePlayer extends BungeeOffPlayer, StandaloneOnlinePlayer {
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
ProxiedPlayer getBungeeProxiedPlayer();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sending packet and stuff to player
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default void sendMessage(Component message) {
|
||||||
|
getBungeeProxiedPlayer().sendMessage(Chat.toBungee(message));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default void sendMessage(ComponentLike message, UUID sender) {
|
||||||
|
getBungeeProxiedPlayer().sendMessage(sender, Chat.toBungee(message.asComponent()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default void sendMessage(Component message, Identified sender) {
|
||||||
|
getBungeeProxiedPlayer().sendMessage(sender.identity().uuid(), Chat.toBungee(message));
|
||||||
|
}
|
||||||
|
|
||||||
|
default void sendMessage(ComponentLike message, ProxiedPlayer sender) {
|
||||||
|
getBungeeProxiedPlayer().sendMessage(sender.getUniqueId(), Chat.toBungee(message.asComponent()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default void sendTitle(Component title, Component subtitle, int fadeIn, int stay, int fadeOut) {
|
||||||
|
ProxyServer.getInstance().createTitle()
|
||||||
|
.title(Chat.toBungee(title)).subTitle(Chat.toBungee(subtitle))
|
||||||
|
.fadeIn(fadeIn).stay(stay).fadeOut(fadeOut)
|
||||||
|
.send(getBungeeProxiedPlayer());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default void sendServerBrand(String legacyText) {
|
||||||
|
try {
|
||||||
|
ByteBuf payload = ByteBufAllocator.DEFAULT.heapBuffer();
|
||||||
|
DefinedPacket.writeString(legacyText, payload);
|
||||||
|
getBungeeProxiedPlayer().unsafe().sendPacket(new PluginMessage("minecraft:brand", DefinedPacket.toArray(payload), false));
|
||||||
|
payload.release();
|
||||||
|
} catch (Exception ignored) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Client options
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default BungeeClientOptions getClientOptions() {
|
||||||
|
return new BungeeClientOptions(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
class BungeeClientOptions implements StandaloneOnlinePlayer.ClientOptions {
|
||||||
|
|
||||||
|
BungeeOnlinePlayer op;
|
||||||
|
public BungeeClientOptions(BungeeOnlinePlayer op) {
|
||||||
|
this.op = op;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ClientSettings getBungeeSettings() {
|
||||||
|
ProxiedPlayer pp = op.getBungeeProxiedPlayer();
|
||||||
|
try {
|
||||||
|
return (ClientSettings) Reflect.ofClassOfInstance(pp).method("getSettings").invoke(pp);
|
||||||
|
} catch (ReflectiveOperationException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasChatColorEnabled() {
|
||||||
|
return op.getBungeeProxiedPlayer().hasChatColors();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChatMode getChatMode() {
|
||||||
|
return op.getBungeeProxiedPlayer().getChatMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isChatFullyVisible() {
|
||||||
|
ChatMode v = getChatMode();
|
||||||
|
return v == ChatMode.SHOWN || v == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isChatOnlyDisplayingSystemMessages() {
|
||||||
|
return getChatMode() == ChatMode.COMMANDS_ONLY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isChatHidden() {
|
||||||
|
return getChatMode() == ChatMode.HIDDEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Locale getLocale() {
|
||||||
|
return op.getBungeeProxiedPlayer().getLocale();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getViewDistance() {
|
||||||
|
return op.getBungeeProxiedPlayer().getViewDistance();
|
||||||
|
}
|
||||||
|
|
||||||
|
public MainHand getMainHand() {
|
||||||
|
return op.getBungeeProxiedPlayer().getMainHand();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isLeftHanded() {
|
||||||
|
return getMainHand() == MainHand.LEFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isRightHanded() {
|
||||||
|
return getMainHand() == MainHand.RIGHT;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isTextFilteringEnabled() {
|
||||||
|
ClientSettings settings = getBungeeSettings();
|
||||||
|
return settings != null && settings.isDisableTextFiltering(); // Bungee badly named the method
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean allowsServerListing() {
|
||||||
|
ClientSettings settings = getBungeeSettings();
|
||||||
|
return settings != null && settings.isAllowServerListing();
|
||||||
|
}
|
||||||
|
|
||||||
|
public SkinConfiguration getSkinParts() {
|
||||||
|
return op.getBungeeProxiedPlayer().getSkinParts();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasSkinCapeEnabled() {
|
||||||
|
return getSkinParts().hasCape();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasSkinJacketEnabled() {
|
||||||
|
return getSkinParts().hasJacket();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasSkinLeftSleeveEnabled() {
|
||||||
|
return getSkinParts().hasLeftSleeve();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasSkinRightSleeveEnabled() {
|
||||||
|
return getSkinParts().hasRightSleeve();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasSkinLeftPantsEnabled() {
|
||||||
|
return getSkinParts().hasLeftPants();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasSkinRightPantsEnabled() {
|
||||||
|
return getSkinParts().hasRightPants();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasSkinHatsEnabled() {
|
||||||
|
return getSkinParts().hasHat();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -18,20 +18,12 @@
|
|||||||
</repositories>
|
</repositories>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
|
||||||
<groupId>fr.pandacube.lib</groupId>
|
|
||||||
<artifactId>pandalib-core</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.md-5</groupId>
|
<groupId>net.md-5</groupId>
|
||||||
<artifactId>bungeecord-api</artifactId>
|
<artifactId>bungeecord-api</artifactId>
|
||||||
<version>${bungeecord.version}</version>
|
<version>${bungeecord.version}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
@ -23,12 +23,19 @@
|
|||||||
</repositories>
|
</repositories>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>fr.pandacube.lib</groupId>
|
<groupId>fr.pandacube.lib</groupId>
|
||||||
<artifactId>pandalib-core</artifactId>
|
<artifactId>pandalib-core</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>fr.pandacube.lib</groupId>
|
||||||
|
<artifactId>pandalib-reflect</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.md-5</groupId>
|
<groupId>net.md-5</groupId>
|
||||||
|
@ -35,36 +35,5 @@
|
|||||||
<artifactId>pandalib-chat</artifactId>
|
<artifactId>pandalib-chat</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>fr.pandacube.lib</groupId>
|
|
||||||
<artifactId>pandalib-db</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>fr.pandacube.lib</groupId>
|
|
||||||
<artifactId>pandalib-reflect</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>fr.pandacube.lib</groupId>
|
|
||||||
<artifactId>pandalib-permissions</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>fr.pandacube.lib</groupId>
|
|
||||||
<artifactId>pandalib-players-standalone</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.geysermc.floodgate</groupId>
|
|
||||||
<artifactId>api</artifactId>
|
|
||||||
<version>2.0-SNAPSHOT</version>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
# pandacube-net
|
# pandalib-net
|
||||||
|
|
||||||
A TCP network library that uses the standard Java socket API, to ease the ommunication between the different processes
|
A TCP network library that uses the standard Java socket API, to ease the ommunication between the different processes
|
||||||
running the server network Pandacube.
|
running the server network Pandacube.
|
||||||
|
|
||||||
It’s still in development (actually not touched since years), and it’s supposed to be a replacement for the old
|
It’s still in development (actually not touched since years), and it’s supposed to be a replacement for the old
|
||||||
`pandalib-network-api`. This module is then marked as Beta using the Google Guava annotation.
|
`pandalib-netapi`. This module is then marked as Beta using the Google Guava annotation.
|
||||||
|
|
||||||
- Packet based communication
|
- Packet based communication
|
||||||
- Supports Request/Answer packets
|
- Supports Request/Answer packets
|
||||||
|
93
pandalib-paper-permissions/pom.xml
Normal file
93
pandalib-paper-permissions/pom.xml
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<parent>
|
||||||
|
<artifactId>pandalib-parent</artifactId>
|
||||||
|
<groupId>fr.pandacube.lib</groupId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<artifactId>pandalib-paper-permissions</artifactId>
|
||||||
|
|
||||||
|
<repositories>
|
||||||
|
<repository>
|
||||||
|
<id>papermc</id>
|
||||||
|
<url>https://papermc.io/repo/repository/maven-public/</url>
|
||||||
|
</repository>
|
||||||
|
|
||||||
|
<!-- WorldEdit -->
|
||||||
|
<repository>
|
||||||
|
<id>sk89q-repo</id>
|
||||||
|
<url>https://maven.enginehub.org/repo/</url>
|
||||||
|
</repository>
|
||||||
|
|
||||||
|
<!-- Vault and maybe other dependecies -->
|
||||||
|
<repository>
|
||||||
|
<id>jitpack.io</id>
|
||||||
|
<url>https://jitpack.io</url>
|
||||||
|
</repository>
|
||||||
|
</repositories>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>fr.pandacube.lib</groupId>
|
||||||
|
<artifactId>pandalib-players-permissible</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>fr.pandacube.lib</groupId>
|
||||||
|
<artifactId>pandalib-permissions</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>fr.pandacube.lib</groupId>
|
||||||
|
<artifactId>pandalib-reflect</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Paper -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.papermc.paper</groupId>
|
||||||
|
<artifactId>paper-api</artifactId>
|
||||||
|
<version>${paper.version}-SNAPSHOT</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Vault -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.MilkBowl</groupId>
|
||||||
|
<artifactId>VaultAPI</artifactId>
|
||||||
|
<version>1.7.1</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
<optional>true</optional>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.bukkit</groupId>
|
||||||
|
<artifactId>bukkit</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- WorldEdit -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.sk89q.worldedit</groupId>
|
||||||
|
<artifactId>worldedit-bukkit</artifactId>
|
||||||
|
<version>7.2.9</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.bukkit</groupId>
|
||||||
|
<artifactId>bukkit</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.sk89q.bukkit</groupId>
|
||||||
|
<artifactId>bukkit-classloader-check</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
</project>
|
@ -0,0 +1,143 @@
|
|||||||
|
package fr.pandacube.lib.paper.permissions;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.player.PlayerLoginEvent;
|
||||||
|
import org.bukkit.event.player.PlayerQuitEvent;
|
||||||
|
import org.bukkit.permissions.Permissible;
|
||||||
|
import org.bukkit.permissions.Permission;
|
||||||
|
import org.bukkit.permissions.ServerOperator;
|
||||||
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
|
||||||
|
import fr.pandacube.lib.permissions.Permissions;
|
||||||
|
import fr.pandacube.lib.util.Log;
|
||||||
|
|
||||||
|
public class PandalibPaperPermissions implements Listener {
|
||||||
|
|
||||||
|
/* package */ static JavaPlugin plugin;
|
||||||
|
/* package */ static String serverName;
|
||||||
|
/* package */ static final Map<String, String> permissionMap = new HashMap<>();
|
||||||
|
|
||||||
|
public static void init(JavaPlugin plugin, String serverName) {
|
||||||
|
PandalibPaperPermissions.plugin = plugin;
|
||||||
|
PandalibPaperPermissions.serverName = serverName;
|
||||||
|
PermissionsInjectorBukkit.inject(Bukkit.getConsoleSender());
|
||||||
|
PermissionsInjectorVault.inject();
|
||||||
|
PermissionsInjectorWEPIF.inject();
|
||||||
|
|
||||||
|
Bukkit.getPluginManager().registerEvents(new PandalibPaperPermissions(), plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the provided pair of permission into an internal permission map. This is used when a plugin asks the value of
|
||||||
|
* the sourcePerm, then the permission system actually check for the destPerm.
|
||||||
|
* <p>
|
||||||
|
* This mapping is useful, for instance, when the bukkit dispatcher force the fake vanilla commands to have a
|
||||||
|
* permission starting with {@code minecraft.command.} even if we defined a custom permission in the plugin.
|
||||||
|
* @param sourcePerm the source permission to replace
|
||||||
|
* @param destPerm the replacement permission
|
||||||
|
*/
|
||||||
|
public static void addPermissionMapping(String sourcePerm, String destPerm) {
|
||||||
|
Objects.requireNonNull(sourcePerm, "sourcePerm");
|
||||||
|
if (destPerm == null) {
|
||||||
|
permissionMap.remove(sourcePerm);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
permissionMap.put(sourcePerm, destPerm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.LOWEST)
|
||||||
|
public void onPlayerLogin(PlayerLoginEvent event) {
|
||||||
|
Permissions.clearPlayerCache(event.getPlayer().getUniqueId());
|
||||||
|
Permissions.precachePlayerAsync(event.getPlayer().getUniqueId());
|
||||||
|
|
||||||
|
PermissionsInjectorBukkit.inject(event.getPlayer());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.MONITOR)
|
||||||
|
public void onPlayerQuit(PlayerQuitEvent event) {
|
||||||
|
PermissionsInjectorBukkit.uninject(event.getPlayer());
|
||||||
|
Permissions.clearPlayerCache(event.getPlayer().getUniqueId());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* package */ static Function<String, List<Permission>> SUPERPERMS_PARENT_PERMISSION_GETTER = childPerm -> {
|
||||||
|
return Bukkit.getPluginManager().getPermissions().stream()
|
||||||
|
.filter(p -> p.getChildren().containsKey(childPerm))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
};
|
||||||
|
|
||||||
|
/* package */ static ServerOperator dummyOperator(boolean isOp) {
|
||||||
|
return new ServerOperator() {
|
||||||
|
@Override public void setOp(boolean op) { }
|
||||||
|
@Override public boolean isOp() { return isOp; }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/* package */ static Boolean hasSuperPermsPermission(ServerOperator opable, String permission, Predicate<String> parentPermissionChecker) {
|
||||||
|
if (opable instanceof CommandSender sender) {
|
||||||
|
Permissible permissible = PermissionsInjectorBukkit.getPermissible(sender);
|
||||||
|
if (permissible instanceof PermissionsInjectorBukkit.PandaPermissible pPerm)
|
||||||
|
return hasSuperPermsPermission(opable, permission, parentPermissionChecker, pPerm);
|
||||||
|
}
|
||||||
|
return hasSuperPermsPermission(opable, permission, parentPermissionChecker, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* package */ static Boolean hasSuperPermsPermission(ServerOperator opable, String permission, Predicate<String> parentPermissionChecker, PermissionsInjectorBukkit.PandaPermissible pandaPermissible) {
|
||||||
|
|
||||||
|
boolean reversed = permission.startsWith("-");
|
||||||
|
if (reversed) {
|
||||||
|
permission = permission.substring(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean defined = false;
|
||||||
|
Permission perm = Bukkit.getPluginManager().getPermission(permission);
|
||||||
|
if (perm != null) {
|
||||||
|
if (perm.getDefault().getValue(opable.isOp()))
|
||||||
|
return !reversed;
|
||||||
|
defined = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
List<Permission> parents = pandaPermissible != null ? pandaPermissible.superPermsPermissionCache.get(permission) : SUPERPERMS_PARENT_PERMISSION_GETTER.apply(permission);
|
||||||
|
|
||||||
|
for (Permission parent : parents) {
|
||||||
|
Boolean childValue = parent.getChildren().get(permission);
|
||||||
|
if (childValue == null)
|
||||||
|
continue;
|
||||||
|
boolean parentPerm = parentPermissionChecker.test(parent.getName());
|
||||||
|
if (parentPerm == childValue)
|
||||||
|
return !reversed;
|
||||||
|
defined = true;
|
||||||
|
}
|
||||||
|
} catch (ExecutionException e) {
|
||||||
|
Log.severe("Unable to compute SuperPerms permission", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
Boolean ret = defined ? reversed : null;
|
||||||
|
if (Log.isDebugEnabled()) {
|
||||||
|
String name = (opable instanceof CommandSender cs) ? cs.getName() : "unknown entity";
|
||||||
|
String actualPerm = permission;
|
||||||
|
if (reversed) actualPerm = "-" + permission;
|
||||||
|
Log.debug("[SuperPerms] For " + name + ", '" + actualPerm + "' is " + ret);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,313 @@
|
|||||||
|
package fr.pandacube.lib.paper.permissions;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import com.google.common.cache.Cache;
|
||||||
|
import com.google.common.cache.CacheBuilder;
|
||||||
|
import com.google.common.cache.CacheLoader;
|
||||||
|
import com.google.common.cache.LoadingCache;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.command.ConsoleCommandSender;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.permissions.Permissible;
|
||||||
|
import org.bukkit.permissions.PermissibleBase;
|
||||||
|
import org.bukkit.permissions.Permission;
|
||||||
|
import org.bukkit.permissions.PermissionAttachment;
|
||||||
|
import org.bukkit.permissions.PermissionAttachmentInfo;
|
||||||
|
import org.bukkit.plugin.Plugin;
|
||||||
|
|
||||||
|
import fr.pandacube.lib.permissions.Permissions;
|
||||||
|
import fr.pandacube.lib.reflect.Reflect;
|
||||||
|
import fr.pandacube.lib.util.Log;
|
||||||
|
|
||||||
|
public class PermissionsInjectorBukkit
|
||||||
|
{
|
||||||
|
|
||||||
|
// to be called : onEnable for console, onPlayerLogin (not Join) (Priority LOWEST) for players
|
||||||
|
public static void inject(CommandSender sender) {
|
||||||
|
Permissible oldP = getPermissible(sender);
|
||||||
|
if (oldP instanceof PandaPermissible)
|
||||||
|
return;
|
||||||
|
if (!oldP.getClass().equals(PermissibleBase.class)) {
|
||||||
|
Log.warning("Another plugin is already injecting permissions into Bukkit for " + sender.getName() + ": " + oldP.getClass().getName());
|
||||||
|
Log.warning("Not injecting our own permissions.");
|
||||||
|
}
|
||||||
|
PandaPermissible p = new PandaPermissible(sender, getPermissible(sender));
|
||||||
|
setPermissible(p.sender, p);
|
||||||
|
p.recalculatePermissions();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// to be called : onDisable for console, onPlayerQuit () and onDisable for players
|
||||||
|
public static void uninject(CommandSender sender)
|
||||||
|
{
|
||||||
|
Permissible perm = getPermissible(sender);
|
||||||
|
if (perm instanceof PandaPermissible p) {
|
||||||
|
setPermissible(sender, p.oldPermissible);
|
||||||
|
p.oldPermissible.recalculatePermissions();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void setPermissible(CommandSender sender, Permissible newpermissible)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
Field perm = getPermField(sender);
|
||||||
|
if (perm == null)
|
||||||
|
return;
|
||||||
|
perm.setAccessible(true);
|
||||||
|
perm.set(sender, newpermissible);
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
Log.severe(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* package */ static Permissible getPermissible(CommandSender sender)
|
||||||
|
{
|
||||||
|
Field perm = getPermField(sender);
|
||||||
|
if (perm == null)
|
||||||
|
return null;
|
||||||
|
try {
|
||||||
|
perm.setAccessible(true);
|
||||||
|
Permissible p = (Permissible) perm.get(sender);
|
||||||
|
if (p == null) {
|
||||||
|
Log.warning("Null permissible instance found in provided CommandSender: " + sender, new Throwable());
|
||||||
|
}
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
Log.severe(e);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Field getPermField(CommandSender sender)
|
||||||
|
{
|
||||||
|
if (sender == null) {
|
||||||
|
throw new IllegalArgumentException("sender cannot be null");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
if (sender instanceof Player || sender instanceof ConsoleCommandSender)
|
||||||
|
return Reflect.ofClassOfInstance(sender).field("perm").get();
|
||||||
|
else
|
||||||
|
throw new IllegalArgumentException("Unsupported type for sender: " + sender.getClass());
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
Log.severe(e);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* package */ static class PandaPermissible extends PermissibleBase
|
||||||
|
{
|
||||||
|
private final CommandSender sender;
|
||||||
|
private final Permissible oldPermissible;
|
||||||
|
|
||||||
|
/* package */ LoadingCache<String, List<Permission>> superPermsPermissionCache = CacheBuilder.newBuilder()
|
||||||
|
.build(CacheLoader.from(PandalibPaperPermissions.SUPERPERMS_PARENT_PERMISSION_GETTER::apply));
|
||||||
|
|
||||||
|
private boolean init = false;
|
||||||
|
|
||||||
|
private PandaPermissible(CommandSender sender, Permissible oldPermissible)
|
||||||
|
{
|
||||||
|
super(sender);
|
||||||
|
this.sender = sender;
|
||||||
|
this.oldPermissible = oldPermissible;
|
||||||
|
init = true;
|
||||||
|
recalculatePermissions();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Boolean hasPermissionOnServerInWorld(String permission) {
|
||||||
|
if (sender instanceof Player player) {
|
||||||
|
String world = player.getWorld().getName();
|
||||||
|
return Permissions.getPlayer(player.getUniqueId()).hasPermission(permission, PandalibPaperPermissions.serverName, world);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasPermission(String permission)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* WARNING: don’t call PermissibleOnlinePlayer#hasPermission(String) here or it will result on a stack overflow
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (permission.toLowerCase().startsWith("minecraft.command."))
|
||||||
|
permission = PandalibPaperPermissions.permissionMap.getOrDefault(permission.toLowerCase(), permission);
|
||||||
|
|
||||||
|
Boolean res = hasPermissionOnServerInWorld(permission); // supports negative permission
|
||||||
|
if (res != null)
|
||||||
|
return res;
|
||||||
|
|
||||||
|
res = PandalibPaperPermissions.hasSuperPermsPermission(sender, permission, this::hasPermission, this); // supports negative permission
|
||||||
|
if (res != null)
|
||||||
|
return res;
|
||||||
|
|
||||||
|
boolean reversed = permission.startsWith("-");
|
||||||
|
if (reversed) {
|
||||||
|
permission = permission.substring(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return oldPermissible.hasPermission(permission) != reversed;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasPermission(Permission permission)
|
||||||
|
{
|
||||||
|
if (permission.getName().toLowerCase().startsWith("minecraft.command.") && PandalibPaperPermissions.permissionMap.containsKey(permission.getName().toLowerCase())) {
|
||||||
|
return hasPermission(PandalibPaperPermissions.permissionMap.get(permission.getName().toLowerCase()));
|
||||||
|
}
|
||||||
|
|
||||||
|
Boolean res = hasPermissionOnServerInWorld(permission.getName()); // supports negative permission
|
||||||
|
if (res != null)
|
||||||
|
return res;
|
||||||
|
|
||||||
|
res = PandalibPaperPermissions.hasSuperPermsPermission(sender, permission.getName(), this::hasPermission, this); // supports negative permission
|
||||||
|
if (res != null)
|
||||||
|
return res;
|
||||||
|
|
||||||
|
return oldPermissible.hasPermission(permission); // doesn’t need to manage negative permission (should not happend)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void recalculatePermissions()
|
||||||
|
{
|
||||||
|
// need this check because super class constructor calls this method,
|
||||||
|
// thus before oldPermissible has its value assigned
|
||||||
|
if (!init)
|
||||||
|
return;
|
||||||
|
|
||||||
|
oldPermissible.recalculatePermissions();
|
||||||
|
|
||||||
|
superPermsPermissionCache.invalidateAll();
|
||||||
|
|
||||||
|
effectivePermissionsListCache.invalidateAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private Map<String, Boolean> getEffectivePermissionsOnServerInWorld() {
|
||||||
|
if (sender instanceof Player player) {
|
||||||
|
String world = player.getWorld().getName();
|
||||||
|
return Permissions.getPlayer(player.getUniqueId()).listEffectivePermissions(PandalibPaperPermissions.serverName, world);
|
||||||
|
}
|
||||||
|
return new HashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// key is world
|
||||||
|
private final Cache<String, Set<PermissionAttachmentInfo>> effectivePermissionsListCache = CacheBuilder.newBuilder()
|
||||||
|
.expireAfterAccess(10, TimeUnit.MINUTES)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<PermissionAttachmentInfo> getEffectivePermissions()
|
||||||
|
{
|
||||||
|
// PlotSquared uses this method to optimize permission range (plots.limit.10 for example)
|
||||||
|
// MobArena uses this method when a player leave the arena
|
||||||
|
// LibsDisguises uses this method (and only this one) to parse all the permissions
|
||||||
|
|
||||||
|
//Log.warning("There is a plugin calling CommandSender#getEffectivePermissions(). See the stacktrace to understand the reason for that.", new Throwable());
|
||||||
|
|
||||||
|
String world = null;
|
||||||
|
if (sender instanceof Player player) {
|
||||||
|
world = player.getWorld().getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return effectivePermissionsListCache.get(world, () -> {
|
||||||
|
// first get the superperms effective permissions (taht take isOp into accound)
|
||||||
|
Map<String, PermissionAttachmentInfo> perms = oldPermissible.getEffectivePermissions().stream()
|
||||||
|
.collect(Collectors.toMap(PermissionAttachmentInfo::getPermission, Function.identity()));
|
||||||
|
|
||||||
|
// then override them with the permissions from our permission system (that has priority, and take current world into account)
|
||||||
|
for (Map.Entry<String, Boolean> permE : getEffectivePermissionsOnServerInWorld().entrySet()) {
|
||||||
|
perms.put(permE.getKey(), new PermissionAttachmentInfo(this, permE.getKey(), null, permE.getValue()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return new LinkedHashSet<>(perms.values());
|
||||||
|
});
|
||||||
|
} catch (ExecutionException e) {
|
||||||
|
Log.severe(e);
|
||||||
|
return oldPermissible.getEffectivePermissions();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isOp()
|
||||||
|
{
|
||||||
|
return oldPermissible.isOp();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setOp(boolean value)
|
||||||
|
{
|
||||||
|
oldPermissible.setOp(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isPermissionSet(String permission)
|
||||||
|
{
|
||||||
|
Boolean res = hasPermissionOnServerInWorld(permission);
|
||||||
|
if (res != null)
|
||||||
|
return true;
|
||||||
|
return oldPermissible.isPermissionSet(permission);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isPermissionSet(Permission permission)
|
||||||
|
{
|
||||||
|
Boolean res = hasPermissionOnServerInWorld(permission.getName());
|
||||||
|
if (res != null)
|
||||||
|
return true;
|
||||||
|
return oldPermissible.isPermissionSet(permission);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PermissionAttachment addAttachment(Plugin plugin)
|
||||||
|
{
|
||||||
|
return oldPermissible.addAttachment(plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PermissionAttachment addAttachment(Plugin plugin, int ticks)
|
||||||
|
{
|
||||||
|
return oldPermissible.addAttachment(plugin, ticks);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PermissionAttachment addAttachment(Plugin plugin, String name, boolean value)
|
||||||
|
{
|
||||||
|
return oldPermissible.addAttachment(plugin, name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PermissionAttachment addAttachment(Plugin plugin, String name, boolean value, int ticks)
|
||||||
|
{
|
||||||
|
return oldPermissible.addAttachment(plugin, name, value, ticks);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeAttachment(PermissionAttachment attachment)
|
||||||
|
{
|
||||||
|
oldPermissible.removeAttachment(attachment);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized void clearPermissions()
|
||||||
|
{
|
||||||
|
if (oldPermissible instanceof PermissibleBase)
|
||||||
|
((PermissibleBase) oldPermissible).clearPermissions();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,255 @@
|
|||||||
|
package fr.pandacube.lib.paper.permissions;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.OfflinePlayer;
|
||||||
|
import org.bukkit.plugin.ServicePriority;
|
||||||
|
|
||||||
|
import fr.pandacube.lib.permissions.PermGroup;
|
||||||
|
import fr.pandacube.lib.permissions.Permissions;
|
||||||
|
import fr.pandacube.lib.util.Log;
|
||||||
|
|
||||||
|
public class PermissionsInjectorVault {
|
||||||
|
|
||||||
|
public static PandaVaultPermission permInstance;
|
||||||
|
|
||||||
|
public static void inject() {
|
||||||
|
try {
|
||||||
|
permInstance = new PandaVaultPermission();
|
||||||
|
PandaVaultChat chat = new PandaVaultChat(permInstance);
|
||||||
|
Bukkit.getServicesManager().register(net.milkbowl.vault.permission.Permission.class, permInstance,
|
||||||
|
PandalibPaperPermissions.plugin, ServicePriority.High);
|
||||||
|
Bukkit.getServicesManager().register(net.milkbowl.vault.chat.Chat.class, chat,
|
||||||
|
PandalibPaperPermissions.plugin, ServicePriority.High);
|
||||||
|
Log.info("Providing permissions and chat prefix/suffix through Vault API.");
|
||||||
|
} catch (NoClassDefFoundError e) {
|
||||||
|
Log.warning("Vault plugin not detected. Not using it to provide permissions and prefix/suffix." + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static class PandaVaultPermission extends net.milkbowl.vault.permission.Permission {
|
||||||
|
|
||||||
|
private PandaVaultPermission() { }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "Pandalib";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEnabled() {
|
||||||
|
return PandalibPaperPermissions.plugin != null && PandalibPaperPermissions.plugin.isEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasSuperPermsCompat() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
@Override
|
||||||
|
public boolean playerHas(String world, String player, String permission) {
|
||||||
|
return playerHas(world, Bukkit.getOfflinePlayer(player), permission);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean playerHas(String world, OfflinePlayer player, String permission) {
|
||||||
|
Boolean res = Permissions.getPlayer(player.getUniqueId()).hasPermission(permission, PandalibPaperPermissions.serverName, world);
|
||||||
|
if (res != null)
|
||||||
|
return res;
|
||||||
|
|
||||||
|
res = PandalibPaperPermissions.hasSuperPermsPermission(player, permission, p -> playerHas(world, player, p));
|
||||||
|
if (res != null)
|
||||||
|
return res;
|
||||||
|
|
||||||
|
return permission.startsWith("-");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean playerAdd(String world, String player, String permission) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean playerRemove(String world, String player, String permission) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean groupHas(String world, String group, String permission) {
|
||||||
|
Boolean res = Permissions.getGroup(group).hasPermission(permission, PandalibPaperPermissions.serverName, world);
|
||||||
|
if (res != null)
|
||||||
|
return res;
|
||||||
|
|
||||||
|
res = PandalibPaperPermissions.hasSuperPermsPermission(PandalibPaperPermissions.dummyOperator(false), permission, p -> groupHas(world, group, p), null);
|
||||||
|
if (res != null)
|
||||||
|
return res;
|
||||||
|
|
||||||
|
return permission.startsWith("-");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean groupAdd(String world, String group, String permission) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean groupRemove(String world, String group, String permission) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
@Override
|
||||||
|
public boolean playerInGroup(String world, String player, String group) {
|
||||||
|
return playerInGroup(world, Bukkit.getOfflinePlayer(player), group);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean playerInGroup(String world, OfflinePlayer player, String group) {
|
||||||
|
return Permissions.getPlayer(player.getUniqueId()).isInGroup(group);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean playerAddGroup(String world, String player, String group) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean playerRemoveGroup(String world, String player, String group) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
@Override
|
||||||
|
public String[] getPlayerGroups(String world, String player) {
|
||||||
|
return getPlayerGroups(world, Bukkit.getOfflinePlayer(player));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String[] getPlayerGroups(String world, OfflinePlayer player) {
|
||||||
|
List<String> groups = Permissions.getPlayer(player.getUniqueId()).getGroupsString();
|
||||||
|
return groups.toArray(new String[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
@Override
|
||||||
|
public String getPrimaryGroup(String world, String player) {
|
||||||
|
return getPrimaryGroup(world, Bukkit.getOfflinePlayer(player));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPrimaryGroup(String world, OfflinePlayer player) {
|
||||||
|
return Permissions.getPlayer(player.getUniqueId()).getGroupsString().stream()
|
||||||
|
.findFirst().orElse(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String[] getGroups() {
|
||||||
|
return Permissions.getGroups().stream()
|
||||||
|
.map(PermGroup::getName).toArray(String[]::new);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasGroupSupport() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static class PandaVaultChat extends net.milkbowl.vault.chat.Chat {
|
||||||
|
|
||||||
|
public PandaVaultChat(net.milkbowl.vault.permission.Permission perms) {
|
||||||
|
super(perms);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "Pandalib";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEnabled() {
|
||||||
|
return PandalibPaperPermissions.plugin != null && PandalibPaperPermissions.plugin.isEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
@Override
|
||||||
|
public String getPlayerPrefix(String world, String player) {
|
||||||
|
return getPlayerPrefix(world, Bukkit.getOfflinePlayer(player));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPlayerPrefix(String world, OfflinePlayer player) {
|
||||||
|
return Permissions.getPlayer(player.getUniqueId()).getPrefix();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
@Override
|
||||||
|
public String getPlayerSuffix(String world, String player) {
|
||||||
|
return getPlayerSuffix(world, Bukkit.getOfflinePlayer(player));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPlayerSuffix(String world, OfflinePlayer player) {
|
||||||
|
return Permissions.getPlayer(player.getUniqueId()).getSuffix();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getGroupPrefix(String world, String group) {
|
||||||
|
return Permissions.getGroup(group).getPrefix();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getGroupSuffix(String world, String group) {
|
||||||
|
return Permissions.getGroup(group).getSuffix();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setPlayerPrefix(String world, String player, String prefix) { /* unsupported */ }
|
||||||
|
@Override
|
||||||
|
public void setPlayerSuffix(String world, String player, String suffix) { /* unsupported */ }
|
||||||
|
@Override
|
||||||
|
public void setGroupPrefix(String world, String group, String prefix) { /* unsupported */ }
|
||||||
|
@Override
|
||||||
|
public void setGroupSuffix(String world, String group, String suffix) { /* unsupported */ }
|
||||||
|
@Override
|
||||||
|
public int getPlayerInfoInteger(String world, String player, String node, int defaultValue) { return defaultValue; }
|
||||||
|
@Override
|
||||||
|
public void setPlayerInfoInteger(String world, String player, String node, int value) { /* unsupported */ }
|
||||||
|
@Override
|
||||||
|
public int getGroupInfoInteger(String world, String group, String node, int defaultValue) { return defaultValue; }
|
||||||
|
@Override
|
||||||
|
public void setGroupInfoInteger(String world, String group, String node, int value) { /* unsupported */ }
|
||||||
|
@Override
|
||||||
|
public double getPlayerInfoDouble(String world, String player, String node, double defaultValue) { return defaultValue; }
|
||||||
|
@Override
|
||||||
|
public void setPlayerInfoDouble(String world, String player, String node, double value) { /* unsupported */ }
|
||||||
|
@Override
|
||||||
|
public double getGroupInfoDouble(String world, String group, String node, double defaultValue) { return defaultValue; }
|
||||||
|
@Override
|
||||||
|
public void setGroupInfoDouble(String world, String group, String node, double value) { /* unsupported */ }
|
||||||
|
@Override
|
||||||
|
public boolean getPlayerInfoBoolean(String world, String player, String node, boolean defaultValue) { return defaultValue; }
|
||||||
|
@Override
|
||||||
|
public void setPlayerInfoBoolean(String world, String player, String node, boolean value) { /* unsupported */ }
|
||||||
|
@Override
|
||||||
|
public boolean getGroupInfoBoolean(String world, String group, String node, boolean defaultValue) { return defaultValue; }
|
||||||
|
@Override
|
||||||
|
public void setGroupInfoBoolean(String world, String group, String node, boolean value) { /* unsupported */ }
|
||||||
|
@Override
|
||||||
|
public String getPlayerInfoString(String world, String player, String node, String defaultValue) { return defaultValue; }
|
||||||
|
@Override
|
||||||
|
public void setPlayerInfoString(String world, String player, String node, String value) { /* unsupported */ }
|
||||||
|
@Override
|
||||||
|
public String getGroupInfoString(String world, String group, String node, String defaultValue) { return defaultValue; }
|
||||||
|
@Override
|
||||||
|
public void setGroupInfoString(String world, String group, String node, String value) { /* unsupported */ }
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,93 @@
|
|||||||
|
package fr.pandacube.lib.paper.permissions;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.OfflinePlayer;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.plugin.Plugin;
|
||||||
|
import org.bukkit.plugin.ServicePriority;
|
||||||
|
|
||||||
|
import fr.pandacube.lib.permissions.PermPlayer;
|
||||||
|
import fr.pandacube.lib.permissions.Permissions;
|
||||||
|
import fr.pandacube.lib.util.Log;
|
||||||
|
|
||||||
|
public class PermissionsInjectorWEPIF {
|
||||||
|
|
||||||
|
public static PandaWEPIFPermissionsProvider permInstance;
|
||||||
|
|
||||||
|
public static void inject() {
|
||||||
|
try {
|
||||||
|
permInstance = new PandaWEPIFPermissionsProvider();
|
||||||
|
Bukkit.getServicesManager().register(com.sk89q.wepif.PermissionsProvider.class, permInstance,
|
||||||
|
PandalibPaperPermissions.plugin, ServicePriority.Highest);
|
||||||
|
Log.info("Providing permissions through WEPIF");
|
||||||
|
Plugin pl = Bukkit.getPluginManager().getPlugin("WorldEdit");
|
||||||
|
if (pl == null || !pl.isEnabled())
|
||||||
|
return;
|
||||||
|
((WorldEditPlugin) pl).getPermissionsResolver().findResolver();
|
||||||
|
} catch (NoClassDefFoundError e) {
|
||||||
|
Log.warning("WorldEdit plugin not detected. Not using WEPIF to provide permissions and prefix/suffix." + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static class PandaWEPIFPermissionsProvider implements com.sk89q.wepif.PermissionsProvider {
|
||||||
|
private PandaWEPIFPermissionsProvider() { }
|
||||||
|
|
||||||
|
private PermPlayer getPlayer(OfflinePlayer player) {
|
||||||
|
return Permissions.getPlayer(player.getUniqueId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String[] getGroups(OfflinePlayer player) {
|
||||||
|
List<String> groups = getPlayer(player).getGroupsString();
|
||||||
|
return groups.toArray(new String[0]);
|
||||||
|
}
|
||||||
|
@Deprecated
|
||||||
|
@Override
|
||||||
|
public String[] getGroups(String player) {
|
||||||
|
return getGroups(Bukkit.getOfflinePlayer(player));
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public boolean hasPermission(OfflinePlayer player, String permission) {
|
||||||
|
Player p = Bukkit.getPlayer(player.getUniqueId());
|
||||||
|
return hasPermission(p != null ? p.getWorld().getName() : null, player, permission);
|
||||||
|
}
|
||||||
|
@Deprecated
|
||||||
|
@Override
|
||||||
|
public boolean hasPermission(String player, String permission) {
|
||||||
|
return hasPermission(Bukkit.getOfflinePlayer(player), permission);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public boolean hasPermission(String worldName, OfflinePlayer player, String permission) {
|
||||||
|
Boolean res = Permissions.getPlayer(player.getUniqueId()).hasPermission(permission, PandalibPaperPermissions.serverName, worldName);
|
||||||
|
if (res != null)
|
||||||
|
return res;
|
||||||
|
|
||||||
|
res = PandalibPaperPermissions.hasSuperPermsPermission(player, permission, p -> hasPermission(worldName, player, p));
|
||||||
|
if (res != null)
|
||||||
|
return res;
|
||||||
|
|
||||||
|
return permission.startsWith("-");
|
||||||
|
}
|
||||||
|
@Deprecated
|
||||||
|
@Override
|
||||||
|
public boolean hasPermission(String worldName, String player, String permission) {
|
||||||
|
return hasPermission(worldName, Bukkit.getOfflinePlayer(player), permission);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public boolean inGroup(OfflinePlayer player, String group) {
|
||||||
|
return getPlayer(player).isInGroup(group);
|
||||||
|
}
|
||||||
|
@Deprecated
|
||||||
|
@Override
|
||||||
|
public boolean inGroup(String player, String group) {
|
||||||
|
return inGroup(Bukkit.getOfflinePlayer(player), group);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -24,7 +24,7 @@
|
|||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>fr.pandacube.lib</groupId>
|
<groupId>fr.pandacube.lib</groupId>
|
||||||
<artifactId>pandalib-core</artifactId>
|
<artifactId>pandalib-chat</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
<exclusions>
|
<exclusions>
|
||||||
<exclusion>
|
<exclusion>
|
||||||
@ -37,17 +37,31 @@
|
|||||||
</exclusion>
|
</exclusion>
|
||||||
</exclusions>
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>fr.pandacube.lib</groupId>
|
||||||
|
<artifactId>pandalib-reflect</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>fr.pandacube.lib</groupId>
|
||||||
|
<artifactId>pandalib-util</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!-- Paper -->
|
<!-- Paper -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.papermc.paper</groupId>
|
<groupId>io.papermc.paper</groupId>
|
||||||
<artifactId>paper-api</artifactId>
|
<artifactId>paper-api</artifactId>
|
||||||
<version>${paper.version}-SNAPSHOT</version>
|
<version>${paper.version}-SNAPSHOT</version>
|
||||||
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.papermc.paper</groupId>
|
<groupId>io.papermc.paper</groupId>
|
||||||
<artifactId>paper-mojangapi</artifactId>
|
<artifactId>paper-mojangapi</artifactId>
|
||||||
<version>${paper.version}-SNAPSHOT</version>
|
<version>${paper.version}-SNAPSHOT</version>
|
||||||
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
@ -23,7 +23,6 @@
|
|||||||
<groupId>fr.pandacube.lib</groupId>
|
<groupId>fr.pandacube.lib</groupId>
|
||||||
<artifactId>pandalib-players-standalone</artifactId>
|
<artifactId>pandalib-players-standalone</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
3
pom.xml
3
pom.xml
@ -59,6 +59,9 @@
|
|||||||
<module>pandalib-reflect</module>
|
<module>pandalib-reflect</module>
|
||||||
<module>pandalib-util</module>
|
<module>pandalib-util</module>
|
||||||
<module>pandalib-players-permissible</module>
|
<module>pandalib-players-permissible</module>
|
||||||
|
<module>pandalib-bungee-permissions</module>
|
||||||
|
<module>pandalib-bungee-players</module>
|
||||||
|
<module>pandalib-paper-permissions</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
Loading…
Reference in New Issue
Block a user