Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@

import java.util.List;
import java.util.Set;
import java.util.UUID;

public interface ForcePackPlayer {

UUID uniqueId();

Set<ResourcePack> getWaitingPacks();

List<SpoofCheck> getChecks();
Expand Down
2 changes: 1 addition & 1 deletion build-logic/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ repositories {
}

dependencies {
implementation("com.gradleup.shadow:shadow-gradle-plugin:9.4.1")
implementation("com.gradleup.shadow:shadow-gradle-plugin:9.4.2")
implementation("com.diffplug.spotless:spotless-plugin-gradle:8.4.0")
implementation("com.modrinth.minotaur:com.modrinth.minotaur.gradle.plugin:2.+")
}
3 changes: 0 additions & 3 deletions paper/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,6 @@ dependencies {
exclude("net.kyori", "adventure-api") // not up-to-date - use minimessage version
}
implementation("net.kyori:adventure-text-minimessage:4.25.0")
implementation("com.convallyria.languagy:api:3.0.3-SNAPSHOT") {
exclude("com.convallyria.languagy.libs")
}
implementation("org.bstats:bstats-bukkit:3.0.2")
implementation("com.github.retrooper:packetevents-spigot:2.12.2+6dca3cc-SNAPSHOT")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,13 @@
import com.convallyria.forcepack.paper.listener.ExemptionListener;
import com.convallyria.forcepack.paper.listener.PacketListener;
import com.convallyria.forcepack.paper.listener.ResourcePackListener;
import com.convallyria.forcepack.paper.listener.VelocityMessageListener;
import com.convallyria.forcepack.paper.player.ForcePackPaperPlayer;
import com.convallyria.forcepack.paper.resourcepack.PaperResourcePack;
import com.convallyria.forcepack.paper.schedule.BukkitScheduler;
import com.convallyria.forcepack.paper.translation.Translations;
import com.convallyria.forcepack.paper.util.ProtocolUtil;
import com.convallyria.forcepack.webserver.ForcePackWebServer;
import com.convallyria.forcepack.webserver.downloader.WebServerDependencyDownloader;
import com.convallyria.languagy.api.adventure.AdventurePlatform;
import com.convallyria.languagy.api.language.Language;
import com.convallyria.languagy.api.language.Translator;
import com.github.retrooper.packetevents.PacketEvents;
import io.github.retrooper.packetevents.factory.spigot.SpigotPacketEventsBuilder;
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
Expand All @@ -35,7 +31,6 @@
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerResourcePackStatusEvent;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin;
Expand All @@ -61,7 +56,7 @@

public final class ForcePackPaper extends JavaPlugin implements ForcePackPlatform {

private Translator translator;
private final MiniMessage miniMessage = MiniMessage.miniMessage();
private PlatformScheduler<?> scheduler;
private final Map<ResourcePackVersion, Set<ResourcePack>> resourcePacks = new HashMap<>();
public boolean velocityMode;
Expand All @@ -70,14 +65,22 @@ public final class ForcePackPaper extends JavaPlugin implements ForcePackPlatfor

public final Set<UUID> temporaryExemptedPlayers = new HashSet<>();

public MiniMessage miniMessage() {
return miniMessage;
}

public BukkitAudiences adventure() {
return adventure;
}

@Override
public Set<ResourcePack> getResourcePacks() {
return resourcePacks.values().stream()
.flatMap(Set::stream)
.collect(Collectors.toCollection(LinkedHashSet::new));
}

public Set<ResourcePack> getPacksForVersion(Player player) {
public Set<ResourcePack> getPacksForVersion(UUID player) {
final int protocolVersion = ProtocolUtil.getProtocolVersion(player);
return getPacksForVersion(protocolVersion);
}
Expand All @@ -92,17 +95,16 @@ public boolean exemptNextResourcePackSend(UUID uuid) {
return temporaryExemptedPlayers.add(uuid);
}

private final Map<UUID, ForcePackPlayer> waiting = new HashMap<>();
private final Map<UUID, ForcePackPaperPlayer> waiting = new HashMap<>();

public void processWaitingResourcePack(Player player, UUID packId) {
final UUID playerId = player.getUniqueId();
public void processWaitingResourcePack(UUID player, UUID packId) {
// If the player is on a version older than 1.20.3, they can only have one resource pack.
if (ProtocolUtil.getProtocolVersion(player) < 765) {
removeFromWaiting(player);
return;
}

final ForcePackPlayer newPlayer = waiting.computeIfPresent(playerId, (a, forcePackPlayer) -> {
final ForcePackPlayer newPlayer = waiting.computeIfPresent(player, (a, forcePackPlayer) -> {
final Set<ResourcePack> packs = forcePackPlayer.getWaitingPacks();
packs.removeIf(pack -> pack.getUUID().equals(packId));
return forcePackPlayer;
Expand All @@ -113,33 +115,33 @@ public void processWaitingResourcePack(Player player, UUID packId) {
}
}

public Optional<ForcePackPlayer> getForcePackPlayer(Player player) {
return Optional.ofNullable(waiting.get(player.getUniqueId()));
public Optional<ForcePackPaperPlayer> getForcePackPlayer(UUID player) {
return Optional.ofNullable(waiting.get(player));
}

public boolean isWaiting(Player player) {
return waiting.containsKey(player.getUniqueId());
public boolean isWaiting(UUID player) {
return waiting.containsKey(player);
}

public boolean isWaitingFor(Player player, UUID packId) {
public boolean isWaitingFor(UUID player, UUID packId) {
if (!isWaiting(player)) return false;

// If the player is on a version older than 1.20.3, they can only have one resource pack.
if (ProtocolUtil.getProtocolVersion(player) < 765) {
return true;
}

final Set<ResourcePack> waitingPacks = waiting.get(player.getUniqueId()).getWaitingPacks();
final Set<ResourcePack> waitingPacks = waiting.get(player).getWaitingPacks();
return waitingPacks.stream().anyMatch(pack -> pack.getUUID().equals(packId));
}

public void removeFromWaiting(Player player) {
waiting.remove(player.getUniqueId());
public void removeFromWaiting(UUID uuid) {
waiting.remove(uuid);
}

public void addToWaiting(UUID uuid, @NonNull Set<ResourcePack> packs) {
waiting.compute(uuid, (a, existing) -> {
ForcePackPlayer newPlayer = existing != null ? existing : new ForcePackPaperPlayer(Bukkit.getPlayer(uuid));
public ForcePackPaperPlayer addToWaiting(UUID uuid, @NonNull Set<ResourcePack> packs) {
return waiting.compute(uuid, (a, existing) -> {
ForcePackPaperPlayer newPlayer = existing != null ? existing : new ForcePackPaperPlayer(uuid);
newPlayer.getWaitingPacks().addAll(packs);
return newPlayer;
});
Expand All @@ -163,12 +165,10 @@ public void onEnable() {
GeyserUtil.isGeyserInstalledHere = Bukkit.getPluginManager().getPlugin("Geyser-Spigot") != null;

this.adventure = BukkitAudiences.create(this);
MiniMessage miniMessage = MiniMessage.miniMessage();
this.velocityMode = getConfig().getBoolean("velocity-mode");
this.scheduler = FoliaScheduler.RUNNING_FOLIA ? new FoliaScheduler(this) : new BukkitScheduler(this);
this.registerListeners();
this.registerCommands();
this.translator = Translator.of(this, "lang", Language.BRITISH_ENGLISH, debug(), AdventurePlatform.create(miniMessage, adventure));
PacketEvents.getAPI().init();

// Convert legacy config
Expand Down Expand Up @@ -227,7 +227,6 @@ public void onEnable() {
public void onDisable() {
PacketEvents.getAPI().terminate();
if (webServer != null) webServer.shutdown();
if (translator != null) translator.close();
if (this.adventure != null) {
this.adventure.close();
this.adventure = null;
Expand Down Expand Up @@ -362,8 +361,10 @@ private boolean checkPack(@Nullable ResourcePackVersion version, String url, boo
private void registerListeners() {
PluginManager pm = Bukkit.getPluginManager();
if (velocityMode) {
// Proxy resource pack statuses (play + configuration phase) are handled directly
// via PacketEvents in PacketListener, as Bukkit's plugin messaging only delivers
// during the play phase.
getLogger().info("Enabled velocity listener");
this.getServer().getMessenger().registerIncomingPluginChannel(this, "forcepack:status", new VelocityMessageListener(this));
}

pm.registerEvents(new ResourcePackListener(this), this);
Expand Down Expand Up @@ -450,10 +451,6 @@ private void checkForServerProperties() throws IOException {
}
}

public Translator getTranslator() {
return translator;
}

public boolean debug() {
return getConfig().getBoolean("Server.debug");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,18 +48,18 @@ public void onReload(CommandSender sender,
Bukkit.getPluginManager().callEvent(new ForcePackReloadEvent());
if (!plugin.velocityMode && send) {
for (Player player : Bukkit.getOnlinePlayers()) {
if (plugin.isWaiting(player)) continue;
if (plugin.isWaiting(player.getUniqueId())) continue;
boolean geyser = plugin.getConfig().getBoolean("Server.geyser") && GeyserUtil.isBedrockPlayer(player.getUniqueId());
boolean canBypass = player.hasPermission(Permissions.BYPASS) && plugin.getConfig().getBoolean("Server.bypass-permission");
plugin.log(player.getName() + "'s exemptions: geyser, " + geyser + ". permission, " + canBypass + ".");
if (geyser || canBypass) continue;

Translations.RELOADING.send(player);

final Set<ResourcePack> resourcePacks = plugin.getPacksForVersion(player);
final Set<ResourcePack> resourcePacks = plugin.getPacksForVersion(player.getUniqueId());
plugin.addToWaiting(player.getUniqueId(), resourcePacks);
if (ProtocolUtil.getProtocolVersion(player) >= 765) { // 1.20.3+
ProtocolUtil.sendPacketBypassingVia(player, new WrapperPlayServerResourcePackRemove((UUID) null));
if (ProtocolUtil.getProtocolVersion(player.getUniqueId()) >= 765) { // 1.20.3+
ProtocolUtil.sendPacketBypassingVia(player.getUniqueId(), new WrapperPlayServerResourcePackRemove((UUID) null));
}
resourcePacks.forEach(pack -> pack.setResourcePack(player.getUniqueId()));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.convallyria.forcepack.paper.event;

import com.convallyria.forcepack.paper.util.GameProfile;
import net.kyori.adventure.resource.ResourcePackStatus;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
Expand All @@ -12,35 +12,35 @@
import java.util.UUID;

/**
* Like {@link PlayerResourcePackStatusEvent} but helps with multiple version support
* Like {@link PlayerResourcePackStatusEvent} but helps with multiple version support.
* <p>
* Unlike the native event, this event may be fired during the configuration phase, where no
* {@link org.bukkit.entity.Player} object exists yet. For that reason it carries the player's profile instead.
*/
public class MultiVersionResourcePackStatusEvent extends Event implements Cancellable {

private static final HandlerList HANDLER_LIST = new HandlerList();

private final Player player;
private final GameProfile profile;
private final UUID id;
private final ResourcePackStatus status;
private final boolean proxy;
private final boolean proxyRemove;
private boolean cancel;

public MultiVersionResourcePackStatusEvent(@NotNull final Player who, @NotNull UUID id, @NotNull ResourcePackStatus resourcePackStatus, boolean proxy, boolean proxyRemove) {
public MultiVersionResourcePackStatusEvent(@NotNull final GameProfile profile,
@NotNull UUID id, @NotNull ResourcePackStatus resourcePackStatus,
boolean proxy, boolean proxyRemove) {
super(true);
this.player = who;
this.profile = profile;
this.id = id;
this.status = resourcePackStatus;
this.proxy = proxy;
this.proxyRemove = proxyRemove;
}

/**
* Returns the player involved in this event
* @return Player who is involved in this event
*/
@NotNull
public final Player getPlayer() {
return player;
public GameProfile getProfile() {
return profile;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,15 @@ public void onDamageByEntity(EntityDamageByEntityEvent event) {

if (event.getEntity() instanceof Player) {
Player player = (Player) event.getEntity();
if (plugin.isWaiting(player)) {
if (plugin.isWaiting(player.getUniqueId())) {
event.setCancelled(true);
plugin.log("Cancelled damage for player '" + player.getName() + "' due to resource pack not applied.");
}
}

if (event.getDamager() instanceof Player) {
Player damager = (Player) event.getDamager();
if (plugin.isWaiting(damager)) {
if (plugin.isWaiting(damager.getUniqueId())) {
event.setCancelled(true);
plugin.log("Cancelled damage for damager '" + damager.getName() + "' due to resource pack not applied.");
}
Expand All @@ -43,7 +43,7 @@ public void onDamage(EntityDamageEvent event) {

if (event.getEntity() instanceof Player) {
Player damaged = (Player) event.getEntity();
if (plugin.isWaiting(damaged)) {
if (plugin.isWaiting(damaged.getUniqueId())) {
event.setCancelled(true);
plugin.log("Cancelled damage for player '" + damaged.getName() + "' due to resource pack not applied.");
}
Expand All @@ -55,7 +55,7 @@ public void onMove(PlayerMoveEvent event) {
if (!plugin.getConfig().getBoolean("prevent-movement")) return;

final Player player = event.getPlayer();
if (plugin.isWaiting(player)) {
if (plugin.isWaiting(player.getUniqueId())) {
event.setCancelled(true);
plugin.log("Cancelled movement for player '" + player.getName() + "' due to resource pack not applied.");
}
Expand Down
Loading