Compare commits

..

27 Commits

Author SHA1 Message Date
Auxilor
0c0370e256 Updated to 6.16.2 2021-12-08 20:47:22 +00:00
Auxilor
227b748f85 Fixed bStats issues 2021-12-08 20:46:26 +00:00
Auxilor
c8382bd8cf Updated to 6.16.1 2021-12-08 20:40:59 +00:00
Auxilor
df22768367 Fixed bugs 2021-12-08 20:40:39 +00:00
Auxilor
00ea3506ca config.yml changes 2021-12-08 20:32:55 +00:00
Auxilor
521659cfec bStats changes 2021-12-08 20:32:31 +00:00
Auxilor
bbe5f1eba4 Merge remote-tracking branch 'origin/develop' into develop
# Conflicts:
#	eco-core/core-plugin/build.gradle
2021-12-08 20:24:07 +00:00
Auxilor
eae5d29f8d Downgraded bStats 2021-12-08 20:16:59 +00:00
Auxilor
c878d6fd12 Implemented stipped-down bStats directly (recoded in kotlin) 2021-12-08 16:08:03 +00:00
Auxilor
2b97c0072f Downgraded bStats 2021-12-08 14:18:24 +00:00
Auxilor
63079df745 Removed explicit buffer size 2021-12-08 12:41:24 +00:00
Auxilor
079b41e877 Switched to old config behavior 2021-12-08 12:40:13 +00:00
Auxilor
1aaab459d8 Updated bStats to 2.2.1 2021-12-08 12:34:38 +00:00
Auxilor
db78c2eb4c Fixed javadoc + codestyle 2021-12-08 12:22:51 +00:00
Auxilor
02fd07b3c8 Fixed shadowed name 2021-12-08 12:17:22 +00:00
Auxilor
3de2e53031 Fixed default captive items bug 2021-12-08 11:27:33 +00:00
Auxilor
cb088bb70b Allowed specifiying default captive items 2021-12-08 11:23:23 +00:00
Auxilor
36fca7016f Fixed ArgParserEnchantment never returning null 2021-12-08 11:11:59 +00:00
Auxilor
7e1137da06 Cleaned up SS2 integration 2021-12-08 10:53:16 +00:00
Auxilor
0da104d614 Added color:#fffff support x 2021-12-08 10:51:25 +00:00
Auxilor
9095de7d19 Updated to 6.16.0 2021-12-08 10:50:36 +00:00
Auxilor
7a8abac1a2 Pull Request Fixes / Changes, config changes 2021-12-08 10:50:12 +00:00
0ft3n
1ddcb6e964 Merge branch 'master' into master 2021-12-07 14:11:40 +03:00
_OfTeN_
4d0858ad84 Added AntigriefManager#canPickupItem and created and implemented DropQueuePushEvent event 2021-12-07 14:08:04 +03:00
_OfTeN_
3d05695a36 Added Items#getItem 2021-12-07 13:30:36 +03:00
_OfTeN_
3a9f5bc139 Added support for DecentHolograms 2021-12-03 21:10:40 +03:00
_OfTeN_
03ae9e89b3 Added color:#FFFFFF, color:FFFFFF or color:red,green,blue parser for leather armor color 2021-12-02 23:26:38 +03:00
40 changed files with 689 additions and 137 deletions

View File

@@ -35,7 +35,7 @@ allprojects {
// NMS (for jitpack compilation)
maven("https://repo.codemc.org/repository/nms/")
// bStats, mcMMO, BentoBox
// mcMMO, BentoBox
maven("https://repo.codemc.org/repository/maven-public/")
// Spigot API, Bungee API

View File

@@ -0,0 +1,143 @@
package com.willfp.eco.core.events;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
/**
* Called on DropQueue push.
*/
public class DropQueuePushEvent extends PlayerEvent implements Cancellable {
/**
* Cancel state.
*/
private boolean cancelled;
/**
* If telekinetic.
*/
private final boolean isTelekinetic;
/**
* The items.
*/
private final Collection<? extends ItemStack> items;
/**
* The xp.
*/
private final int xp;
/**
* The location.
*/
private final Location location;
/**
* Bukkit parity.
*/
private static final HandlerList HANDLERS = new HandlerList();
/**
* Create a new DropQueuePushEvent.
*
* @param player The player.
* @param items The items.
* @param location The location.
* @param xp The xp.
* @param isTelekinetic If the event is telekinetic.
*/
public DropQueuePushEvent(@NotNull final Player player,
@NotNull final Collection<? extends ItemStack> items,
@NotNull final Location location,
final int xp,
final boolean isTelekinetic) {
super(player);
this.items = items;
this.location = location;
this.xp = xp;
this.isTelekinetic = isTelekinetic;
}
/**
* Gets a list of handlers handling this event.
*
* @return A list of handlers handling this event.
*/
@Override
@NotNull
public HandlerList getHandlers() {
return HANDLERS;
}
/**
* Bukkit parity.
*
* @return The handler list.
*/
public static HandlerList getHandlerList() {
return HANDLERS;
}
/**
* Get cancel state.
*
* @return The cancel state.
*/
@Override
public boolean isCancelled() {
return this.cancelled;
}
/**
* Set cancel state.
*
* @param cancelled If cancelled.
*/
@Override
public void setCancelled(final boolean cancelled) {
this.cancelled = cancelled;
}
/**
* Get the items to be dropped.
*
* @return The items.
*/
public Collection<? extends ItemStack> getItems() {
return items;
}
/**
* Get the xp to be dropped.
*
* @return The xp.
*/
public int getXp() {
return xp;
}
/**
* Get the location.
*
* @return The location.
*/
public Location getLocation() {
return location;
}
/**
* Get force telekinesis state.
*
* @return The force telekinesis state.
*/
public boolean isTelekinetic() {
return this.isTelekinetic;
}
}

View File

@@ -37,6 +37,17 @@ public final class AntigriefManager {
REGISTERED.remove(antigrief);
}
/**
* Can player pickup item.
*
* @param player The player.
* @param location The location.
* @return If player can pick up item.
*/
public static boolean canPickupItem(@NotNull final Player player, @NotNull final Location location) {
return REGISTERED.stream().allMatch(antigriefWrapper -> antigriefWrapper.canPickupItem(player, location));
}
/**
* Can player break block.
*
@@ -45,7 +56,7 @@ public final class AntigriefManager {
* @return If player can break block.
*/
public static boolean canBreakBlock(@NotNull final Player player,
@NotNull final Block block) {
@NotNull final Block block) {
return REGISTERED.stream().allMatch(antigriefWrapper -> antigriefWrapper.canBreakBlock(player, block));
}
@@ -57,7 +68,7 @@ public final class AntigriefManager {
* @return If player can create explosion.
*/
public static boolean canCreateExplosion(@NotNull final Player player,
@NotNull final Location location) {
@NotNull final Location location) {
return REGISTERED.stream().allMatch(antigriefWrapper -> antigriefWrapper.canCreateExplosion(player, location));
}
@@ -69,7 +80,7 @@ public final class AntigriefManager {
* @return If player can place block.
*/
public static boolean canPlaceBlock(@NotNull final Player player,
@NotNull final Block block) {
@NotNull final Block block) {
return REGISTERED.stream().allMatch(antigriefWrapper -> antigriefWrapper.canPlaceBlock(player, block));
}
@@ -81,7 +92,7 @@ public final class AntigriefManager {
* @return If player can injure.
*/
public static boolean canInjure(@NotNull final Player player,
@NotNull final LivingEntity victim) {
@NotNull final LivingEntity victim) {
return REGISTERED.stream().allMatch(antigriefWrapper -> antigriefWrapper.canInjure(player, victim));
}

View File

@@ -5,6 +5,7 @@ import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
/**
* Wrapper class for antigrief integrations.
@@ -17,7 +18,7 @@ public interface AntigriefWrapper extends Integration {
* @param block The block.
* @return If player can break block.
*/
boolean canBreakBlock(Player player, Block block);
boolean canBreakBlock(@NotNull Player player, @NotNull Block block);
/**
* Can player create explosion at location.
@@ -26,7 +27,7 @@ public interface AntigriefWrapper extends Integration {
* @param location The location.
* @return If player can create explosion.
*/
boolean canCreateExplosion(Player player, Location location);
boolean canCreateExplosion(@NotNull Player player, @NotNull Location location);
/**
* Can player place block.
@@ -35,7 +36,7 @@ public interface AntigriefWrapper extends Integration {
* @param block The block.
* @return If player can place block.
*/
boolean canPlaceBlock(Player player, Block block);
boolean canPlaceBlock(@NotNull Player player, @NotNull Block block);
/**
* Can player injure living entity.
@@ -44,5 +45,16 @@ public interface AntigriefWrapper extends Integration {
* @param victim The victim.
* @return If player can injure.
*/
boolean canInjure(Player player, LivingEntity victim);
boolean canInjure(@NotNull Player player, @NotNull LivingEntity victim);
/**
* Can player pick up item.
*
* @param player The player.
* @param location The location.
* @return If player can pick up item.
*/
default boolean canPickupItem(@NotNull Player player, @NotNull Location location) {
return true;
}
}

View File

@@ -50,7 +50,7 @@ public final class Items {
* @param item The item.
*/
public static void registerCustomItem(@NotNull final NamespacedKey key,
@NotNull final TestableItem item) {
@NotNull final TestableItem item) {
REGISTRY.put(key, item);
}
@@ -104,6 +104,7 @@ public final class Items {
* @param key The lookup string.
* @return The testable item, or an {@link EmptyTestableItem}.
*/
@NotNull
public static TestableItem lookup(@NotNull final String key) {
if (key.contains("?")) {
String[] options = key.split("\\?");
@@ -235,6 +236,37 @@ public final class Items {
}
}
/**
* Get a Testable Item from an ItemStack.
* <p>
* Will search for registered items first. If there are no matches in the registry,
* then it will return a {@link MaterialTestableItem} matching the item type.
* <p>
* Does not account for modifiers (arg parser data).
*
* @param item The ItemStack.
* @return The found Testable Item.
*/
@NotNull
public static TestableItem getItem(@Nullable final ItemStack item) {
if (item == null || item.getType().isAir()) {
return new EmptyTestableItem();
}
CustomItem customItem = getCustomItem(item);
if (customItem != null) {
return customItem;
}
for (TestableItem known : REGISTRY.values()) {
if (known.matches(item)) {
return known;
}
}
return new MaterialTestableItem(item.getType());
}
/**
* Get if itemStack is a custom item.
*
@@ -284,6 +316,7 @@ public final class Items {
* @param item The item.
* @return The CustomItem.
*/
@NotNull
public static CustomItem getOrWrap(@NotNull final TestableItem item) {
if (item instanceof CustomItem) {
return (CustomItem) item;

View File

@@ -14,7 +14,7 @@ import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.awt.*;
import java.awt.Color;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

View File

@@ -30,7 +30,7 @@ open class EcoLoadableJSONConfig(
}
}
override fun createFile() {
final override fun createFile() {
val inputStream = source.getResourceAsStream(resourcePath)!!
val outFile = File(this.plugin.dataFolder, resourcePath)
val lastIndex = resourcePath.lastIndexOf('/')
@@ -40,7 +40,7 @@ open class EcoLoadableJSONConfig(
}
if (!outFile.exists()) {
val out: OutputStream = FileOutputStream(outFile)
inputStream.copyTo(out, 1024)
inputStream.copyTo(out)
out.close()
inputStream.close()
}

View File

@@ -40,11 +40,10 @@ open class EcoLoadableYamlConfig(
}
if (!outFile.exists()) {
val out: OutputStream = FileOutputStream(outFile)
inputStream.copyTo(out, 1024)
inputStream.copyTo(out)
out.close()
inputStream.close()
}
plugin.configHandler.addConfig(this)
}
override fun getResourcePath(): String {

View File

@@ -1,6 +1,8 @@
package com.willfp.eco.internal.drops.impl
import com.willfp.eco.core.drops.InternalDropQueue
import com.willfp.eco.core.events.DropQueuePushEvent
import com.willfp.eco.core.integrations.antigrief.AntigriefManager
import com.willfp.eco.util.TelekinesisUtils
import org.bukkit.Bukkit
import org.bukkit.Location
@@ -15,7 +17,7 @@ import org.bukkit.util.Vector
open class EcoDropQueue(val player: Player) : InternalDropQueue {
val items = mutableListOf<ItemStack>()
var xp: Int = 0
var loc: Location
var location: Location
var hasTelekinesis = false
override fun addItem(item: ItemStack): InternalDropQueue {
@@ -34,7 +36,7 @@ open class EcoDropQueue(val player: Player) : InternalDropQueue {
}
override fun setLocation(location: Location): InternalDropQueue {
loc = location
this.location = location
return this
}
@@ -47,8 +49,20 @@ open class EcoDropQueue(val player: Player) : InternalDropQueue {
if (!hasTelekinesis) {
hasTelekinesis = TelekinesisUtils.testPlayer(player)
}
val world = loc.world!!
loc = loc.add(0.5, 0.5, 0.5)
if (hasTelekinesis && !AntigriefManager.canPickupItem(player, location)) {
hasTelekinesis = false
}
val pushEvent = DropQueuePushEvent(player, items, location, xp, hasTelekinesis)
Bukkit.getServer().pluginManager.callEvent(pushEvent)
if (pushEvent.isCancelled) {
return
}
val world = location.world!!
location = location.add(0.5, 0.5, 0.5)
items.removeIf { itemStack: ItemStack -> itemStack.type == Material.AIR }
if (items.isEmpty()) {
return
@@ -56,7 +70,7 @@ open class EcoDropQueue(val player: Player) : InternalDropQueue {
if (hasTelekinesis) {
val leftover = player.inventory.addItem(*items.toTypedArray())
for (drop in leftover.values) {
world.dropItem(loc, drop!!).velocity = Vector()
world.dropItem(location, drop!!).velocity = Vector()
}
if (xp > 0) {
val event = PlayerExpChangeEvent(player, xp)
@@ -68,16 +82,16 @@ open class EcoDropQueue(val player: Player) : InternalDropQueue {
}
} else {
for (drop in items) {
world.dropItem(loc, drop).velocity = Vector()
world.dropItem(location, drop).velocity = Vector()
}
if (xp > 0) {
val orb = world.spawnEntity(loc, EntityType.EXPERIENCE_ORB) as ExperienceOrb
val orb = world.spawnEntity(location, EntityType.EXPERIENCE_ORB) as ExperienceOrb
orb.experience = xp
}
}
}
init {
loc = player.location
location = player.location
}
}

View File

@@ -10,10 +10,10 @@ class EcoFastCollatedDropQueue(player: Player) : EcoDropQueue(player) {
val fetched = COLLATED_MAP[player]
if (fetched == null) {
COLLATED_MAP[player] = CollatedDrops(items, loc, xp, hasTelekinesis)
COLLATED_MAP[player] = CollatedDrops(items, location, xp, hasTelekinesis)
} else {
fetched.addDrops(items)
fetched.location = loc
fetched.location = location
fetched.addXp(xp)
if (this.hasTelekinesis) {
fetched.forceTelekinesis()

View File

@@ -1,8 +1,8 @@
package com.willfp.eco.internal.gui.menu
import com.willfp.eco.internal.gui.slot.EcoCaptivatorSlot
import com.willfp.eco.util.MenuUtils
import com.willfp.eco.util.StringUtils
import org.bukkit.Material
import org.bukkit.NamespacedKey
import org.bukkit.entity.Player
import org.bukkit.inventory.Inventory
@@ -20,12 +20,14 @@ class ExtendedInventory(
for (i in 0 until inventory.size) {
val (row, column) = MenuUtils.convertSlotToRowColumn(i)
val slot = menu.getSlot(row, column)
if (slot is EcoCaptivatorSlot) {
if (slot.isCaptive) {
val defaultItem = slot.getItemStack(player)
val item = inventory.getItem(i) ?: continue
if (item != defaultItem) {
captiveItems.add(item)
if (item == defaultItem && item.type == Material.AIR) {
continue
}
captiveItems.add(item)
}
}

View File

@@ -1,28 +0,0 @@
package com.willfp.eco.internal.gui.slot
import com.willfp.eco.core.Eco
import com.willfp.eco.core.gui.slot.functional.SlotHandler
import org.bukkit.Material
import org.bukkit.inventory.ItemStack
class EcoCaptivatorSlot : EcoSlot(
{ _, _ -> ItemStack(Material.AIR) },
allowMovingItem,
allowMovingItem,
allowMovingItem,
allowMovingItem,
allowMovingItem,
{ _, _, _ -> }
) {
companion object {
val plugin = Eco.getHandler().ecoPlugin
val allowMovingItem = SlotHandler { event, _, _ ->
event.isCancelled = false
}
}
override fun isCaptive(): Boolean {
return true
}
}

View File

@@ -0,0 +1,24 @@
package com.willfp.eco.internal.gui.slot
import com.willfp.eco.core.gui.slot.functional.SlotHandler
import com.willfp.eco.core.gui.slot.functional.SlotProvider
class EcoCaptiveSlot(
provider: SlotProvider
) : EcoSlot(
provider,
allowMovingItem,
allowMovingItem,
allowMovingItem,
allowMovingItem,
allowMovingItem,
{ _, _, _ -> }
) {
override fun isCaptive(): Boolean {
return true
}
}
private val allowMovingItem = SlotHandler { event, _, _ ->
event.isCancelled = false
}

View File

@@ -31,8 +31,7 @@ open class EcoSlot(
ClickType.SHIFT_LEFT -> this.onShiftLeftClick.handle(event, this, menu)
ClickType.SHIFT_RIGHT -> this.onShiftRightClick.handle(event, this, menu)
ClickType.MIDDLE -> this.onMiddleClick.handle(event, this, menu)
else -> {
}
else -> {}
}
}

View File

@@ -58,7 +58,7 @@ class EcoSlotBuilder(private val provider: SlotProvider) : SlotBuilder {
override fun build(): Slot {
return if (captive) {
EcoCaptivatorSlot()
EcoCaptiveSlot(provider)
} else {
EcoSlot(provider, onLeftClick, onRightClick, onShiftLeftClick, onShiftRightClick, onMiddleClick, modifier)
}

View File

@@ -23,7 +23,7 @@ class ArgParserColor : LookupArgParser {
if (argSplit.size < 2) {
continue
}
color = argSplit[1]
color = argSplit[1].replace("#","")
}
color ?: return null

View File

@@ -28,6 +28,10 @@ class ArgParserEnchantment : LookupArgParser {
}
}
if (enchants.isEmpty()) {
return null
}
for ((enchant, level) in enchants) {
if (meta is EnchantmentStorageMeta) {
meta.addStoredEnchant(enchant, level, true)

View File

@@ -2,7 +2,6 @@ group 'com.willfp'
version rootProject.version
dependencies {
implementation 'org.bstats:bstats-bukkit:1.7'
implementation('net.kyori:adventure-text-minimessage:4.1.0-SNAPSHOT') {
exclude group: 'net.kyori', module: 'adventure-api'
}
@@ -40,6 +39,7 @@ dependencies {
compileOnly 'com.iridium:IridiumSkyblock:3.1.2'
compileOnly 'com.github.WillFP:CrashClaim:1.0.19'
compileOnly 'com.wolfyscript.wolfyutilities:wolfyutilities:1.7.8.1'
compileOnly 'com.github.decentsoftware-eu:decentholograms:2.1.2'
// CombatLogX V10 + NewbieHelper Expansion
compileOnly 'com.SirBlobman.combatlogx:CombatLogX-API:10.0.0.0-SNAPSHOT'

View File

@@ -118,7 +118,7 @@ class EcoHandler : com.willfp.eco.internal.spigot.EcoSpigotPlugin(), Handler {
}
override fun registerBStats(plugin: EcoPlugin) {
MetricHandler.createMetrics(plugin, this.ecoPlugin)
MetricHandler.createMetrics(plugin)
}
override fun getRequirementFactory(): EcoRequirementFactory {

View File

@@ -69,6 +69,7 @@ import com.willfp.eco.internal.spigot.integrations.customitems.CustomItemsItemsA
import com.willfp.eco.internal.spigot.integrations.customitems.CustomItemsOraxen
import com.willfp.eco.internal.spigot.integrations.economy.EconomyVault
import com.willfp.eco.internal.spigot.integrations.hologram.HologramCMI
import com.willfp.eco.internal.spigot.integrations.hologram.HologramDecentHolograms
import com.willfp.eco.internal.spigot.integrations.hologram.HologramHolographicDisplays
import com.willfp.eco.internal.spigot.integrations.mcmmo.McmmoIntegrationImpl
import com.willfp.eco.internal.spigot.integrations.multiverseinventories.MultiverseInventoriesIntegration
@@ -131,20 +132,6 @@ abstract class EcoSpigotPlugin : EcoPlugin(
this.logger.info("Ignore messages about deprecated events!")
if (!this.configYml.getBool("enable-bstats")) {
logger.severe("")
logger.severe("----------------------------")
logger.severe("")
logger.severe("Looks like you've disabled bStats!")
logger.severe("This means that information about java version,")
logger.severe("player count, server version, and other data")
logger.severe("isn't able to be used to ensure that support isn't dropped!")
logger.severe("Enable bStats in /plugins/eco/config.yml")
logger.severe("")
logger.severe("----------------------------")
logger.severe("")
}
// Init FIS
this.getProxy(FastItemStackFactoryProxy::class.java).create(ItemStack(Material.AIR)).unwrap()
}
@@ -218,6 +205,7 @@ abstract class EcoSpigotPlugin : EcoPlugin(
// Hologram
IntegrationLoader("HolographicDisplays") { HologramManager.register(HologramHolographicDisplays(this)) },
IntegrationLoader("CMI") { HologramManager.register(HologramCMI()) },
IntegrationLoader("DecentHolograms") { HologramManager.register(HologramDecentHolograms()) },
//IntegrationLoader("GHolo") { HologramManager.register(HologramGHolo()) },
// AFK

View File

@@ -57,6 +57,11 @@ class AntigriefBentoBox : AntigriefWrapper {
}
}
override fun canPickupItem(player: Player, location: Location): Boolean {
val island = BentoBox.getInstance().islandsManager.getIslandAt(location).orElse(null) ?: return true
return island.isAllowed(User.getInstance(player), Flags.ITEM_PICKUP)
}
override fun getPluginName(): String {
return "BentoBox"
}

View File

@@ -55,6 +55,10 @@ class AntigriefCombatLogXV10 : AntigriefWrapper {
return true
}
override fun canPickupItem(player: Player, location: Location): Boolean {
return true
}
override fun getPluginName(): String {
return "CombatLogX"
}

View File

@@ -58,6 +58,10 @@ class AntigriefCombatLogXV11 : AntigriefWrapper {
return true
}
override fun canPickupItem(player: Player, location: Location): Boolean {
return true
}
override fun getPluginName(): String {
return "CombatLogX"
}

View File

@@ -48,6 +48,10 @@ class AntigriefCrashClaim : AntigriefWrapper {
}
}
override fun canPickupItem(player: Player, location: Location): Boolean {
return true
}
override fun getPluginName(): String {
return "CrashClaim"
}

View File

@@ -31,4 +31,8 @@ class AntigriefDeluxeCombat: AntigriefWrapper {
else -> true
}
}
override fun canPickupItem(player: Player, location: Location): Boolean {
return true
}
}

View File

@@ -65,6 +65,10 @@ class AntigriefFactionsUUID : AntigriefWrapper {
return true
}
override fun canPickupItem(player: Player, location: Location): Boolean {
return true
}
override fun getPluginName(): String {
return "FactionsUUID"
}

View File

@@ -51,6 +51,10 @@ class AntigriefGriefPrevention : AntigriefWrapper {
}
}
override fun canPickupItem(player: Player, location: Location): Boolean {
return true
}
override fun getPluginName(): String {
return "GriefPrevention"
}

View File

@@ -48,6 +48,11 @@ class AntigriefIridiumSkyblock : AntigriefWrapper {
}
}
override fun canPickupItem(player: Player, location: Location): Boolean {
val api = IridiumSkyblockAPI.getInstance() ?: return true
return api.getIslandPermission(api.getIslandViaLocation(location).orElse(null) ?: return true, api.getUser(player), PermissionType.PICKUP_ITEMS)
}
override fun getPluginName(): String {
return "IridiumSkyblock"
}

View File

@@ -65,6 +65,10 @@ class AntigriefKingdoms : AntigriefWrapper {
}
}
override fun canPickupItem(player: Player, location: Location): Boolean {
return true
}
override fun getPluginName(): String {
return "Kingdoms"
}

View File

@@ -52,6 +52,11 @@ class AntigriefLands(private val plugin: EcoPlugin) : AntigriefWrapper {
}
}
override fun canPickupItem(player: Player, location: Location): Boolean {
val area = landsIntegration.getAreaByLoc(location) ?: return true
return area.hasFlag(player, Flags.ITEM_PICKUP, false)
}
override fun getPluginName(): String {
return "Lands"
}

View File

@@ -4,13 +4,13 @@ import com.bgsoftware.superiorskyblock.api.SuperiorSkyblockAPI
import com.bgsoftware.superiorskyblock.api.enums.HitActionResult
import com.bgsoftware.superiorskyblock.api.island.Island
import com.bgsoftware.superiorskyblock.api.island.IslandPrivilege
import com.bgsoftware.superiorskyblock.api.key.Key
import com.bgsoftware.superiorskyblock.api.wrappers.SuperiorPlayer
import com.willfp.eco.core.integrations.antigrief.AntigriefWrapper
import org.bukkit.Location
import org.bukkit.Material
import org.bukkit.block.Block
import org.bukkit.entity.*
import org.bukkit.entity.LivingEntity
import org.bukkit.entity.Monster
import org.bukkit.entity.Player
class AntigriefSuperiorSkyblock2 : AntigriefWrapper {
override fun getPluginName(): String {
@@ -18,34 +18,19 @@ class AntigriefSuperiorSkyblock2 : AntigriefWrapper {
}
override fun canBreakBlock(player: Player, block: Block): Boolean {
val island: Island? =
SuperiorSkyblockAPI.getIslandAt(block.location)
val superiorPlayer: SuperiorPlayer =
SuperiorSkyblockAPI.getPlayer(player)
val island = SuperiorSkyblockAPI.getIslandAt(block.location)
val superiorPlayer = SuperiorSkyblockAPI.getPlayer(player)
if (island == null) {
if (!superiorPlayer.hasBypassModeEnabled() && SuperiorSkyblockAPI.getSuperiorSkyblock().grid
.isIslandsWorld(player.world)
.isIslandsWorld(superiorPlayer.world)
) {
return false
}
return true
}
val blockType = block.type
val islandPermission: IslandPrivilege =
if (blockType == Material.SPAWNER) IslandPrivilege.getByName("SPAWNER_BREAK") else IslandPrivilege.getByName("BREAK")
if (!island.hasPermission(superiorPlayer, islandPermission)) {
return false
}
if (SuperiorSkyblockAPI.getSuperiorSkyblock().settings.valuableBlocks
.contains(Key.of(block)) &&
!island.hasPermission(superiorPlayer, IslandPrivilege.getByName("VALUABLE_BREAK"))
) {
if (!island.hasPermission(superiorPlayer, IslandPrivilege.getByName("BREAK"))) {
return false
}
@@ -64,14 +49,12 @@ class AntigriefSuperiorSkyblock2 : AntigriefWrapper {
}
override fun canPlaceBlock(player: Player, block: Block): Boolean {
val island: Island? =
SuperiorSkyblockAPI.getIslandAt(block.location)
val superiorPlayer: SuperiorPlayer =
SuperiorSkyblockAPI.getPlayer(player)
val island = SuperiorSkyblockAPI.getIslandAt(block.location)
val superiorPlayer: SuperiorPlayer = SuperiorSkyblockAPI.getPlayer(player)
if (island == null) {
if (!superiorPlayer.hasBypassModeEnabled() && SuperiorSkyblockAPI.getSuperiorSkyblock().grid.isIslandsWorld(superiorPlayer.world)
if (!superiorPlayer.hasBypassModeEnabled() && SuperiorSkyblockAPI.getSuperiorSkyblock().grid
.isIslandsWorld(superiorPlayer.world)
) {
return false
}
@@ -90,19 +73,28 @@ class AntigriefSuperiorSkyblock2 : AntigriefWrapper {
}
override fun canInjure(player: Player, victim: LivingEntity): Boolean {
if (SuperiorSkyblockAPI.getPlayer(player).hasBypassModeEnabled()) {
return true
val island: Island? = SuperiorSkyblockAPI.getSuperiorSkyblock().grid.getIslandAt(victim.location)
if (victim is Player) return SuperiorSkyblockAPI.getPlayer(player).canHit(SuperiorSkyblockAPI.getPlayer(victim))
.equals(HitActionResult.SUCCESS)
val islandPermission = when (victim) {
is Monster -> IslandPrivilege.getByName("MONSTER_DAMAGE")
else -> IslandPrivilege.getByName("ANIMAL_DAMAGE")
}
return when (victim) {
is Player -> SuperiorSkyblockAPI.getPlayer(player).canHit(SuperiorSkyblockAPI.getPlayer(victim)).equals(HitActionResult.SUCCESS)
else -> {
val island: Island? = SuperiorSkyblockAPI.getSuperiorSkyblock().grid.getIslandAt(victim.location)
val islandPermission = if (victim is Monster) IslandPrivilege.getByName("MONSTER_DAMAGE") else IslandPrivilege.getByName("ANIMAL_DAMAGE")
if (island != null ) {
return island.hasPermission(player, islandPermission)
}
return true
}
if (island != null && !island.hasPermission(player, islandPermission)) {
return false
}
return true
}
override fun canPickupItem(player: Player, location: Location): Boolean {
val superiorPlayer: SuperiorPlayer =
SuperiorSkyblockAPI.getPlayer(player)
val island = SuperiorSkyblockAPI.getSuperiorSkyblock().grid.getIslandAt(location) ?: return true
return island.hasPermission(superiorPlayer, IslandPrivilege.getByName("PICKUP_DROPS"))
}
}

View File

@@ -69,6 +69,10 @@ class AntigriefTowny : AntigriefWrapper {
return townBlock.permissions.pvp
}
override fun canPickupItem(player: Player, location: Location): Boolean {
return true
}
override fun getPluginName(): String {
return "Towny"
}

View File

@@ -98,6 +98,20 @@ class AntigriefWorldGuard : AntigriefWrapper {
}
}
override fun canPickupItem(player: Player, location: Location): Boolean {
val localPlayer: LocalPlayer = WorldGuardPlugin.inst().wrapPlayer(player)
val container: RegionContainer = WorldGuard.getInstance().platform.regionContainer
val query: RegionQuery = container.createQuery()
val world = location.world
Validate.notNull(world, "World cannot be null!")
return if (!query.testBuild(BukkitAdapter.adapt(location), localPlayer, Flags.ITEM_PICKUP)) {
WorldGuard.getInstance().platform.sessionManager.hasBypass(
localPlayer,
BukkitAdapter.adapt(world)
)
} else true
}
override fun getPluginName(): String {
return "WorldGuard"
}

View File

@@ -1,21 +1,9 @@
package com.willfp.eco.internal.spigot.integrations.bstats
import com.willfp.eco.core.EcoPlugin
import org.bstats.bukkit.Metrics
import org.bukkit.configuration.file.YamlConfiguration
import java.io.File
object MetricHandler {
fun createMetrics(plugin: EcoPlugin, ecoPlugin: EcoPlugin) {
val bStatsFolder = File(plugin.dataFolder.parentFile, "bStats")
val configFile = File(bStatsFolder, "config.yml")
val config = YamlConfiguration.loadConfiguration(configFile)
if (config.isSet("serverUuid")) {
config.set("enabled", ecoPlugin.configYml.getBool("enable-bstats"))
config.save(configFile)
}
Metrics(plugin, plugin.bStatsId)
fun createMetrics(plugin: EcoPlugin) {
Metrics(plugin)
}
}

View File

@@ -0,0 +1,279 @@
package com.willfp.eco.internal.spigot.integrations.bstats
import com.willfp.eco.core.EcoPlugin
import org.bukkit.Bukkit
import org.bukkit.configuration.file.YamlConfiguration
import java.io.BufferedReader
import java.io.ByteArrayOutputStream
import java.io.DataOutputStream
import java.io.File
import java.io.InputStreamReader
import java.net.URL
import java.nio.charset.StandardCharsets
import java.util.UUID
import java.util.concurrent.Executors
import java.util.concurrent.TimeUnit
import java.util.function.Consumer
import java.util.function.Supplier
import java.util.logging.Level
import java.util.zip.GZIPOutputStream
import javax.net.ssl.HttpsURLConnection
@Suppress("UNCHECKED_CAST")
class Metrics(private val plugin: EcoPlugin) {
private val metricsBase: MetricsBase
private fun appendPlatformData(builder: JsonObjectBuilder) {
builder.appendField("playerAmount", playerAmount)
builder.appendField("onlineMode", if (Bukkit.getOnlineMode()) 1 else 0)
builder.appendField("bukkitVersion", Bukkit.getVersion())
builder.appendField("bukkitName", Bukkit.getName())
builder.appendField("javaVersion", System.getProperty("java.version"))
builder.appendField("osName", System.getProperty("os.name"))
builder.appendField("osArch", System.getProperty("os.arch"))
builder.appendField("osVersion", System.getProperty("os.version"))
builder.appendField("coreCount", Runtime.getRuntime().availableProcessors())
}
private fun appendServiceData(builder: JsonObjectBuilder) {
builder.appendField("pluginVersion", plugin.description.version)
}
private val playerAmount: Int
get() = Bukkit.getOnlinePlayers().size
class MetricsBase(
private val platform: String,
private val serverUuid: String,
private val serviceId: Int,
private val appendPlatformDataConsumer: Consumer<JsonObjectBuilder>,
private val appendServiceDataConsumer: Consumer<JsonObjectBuilder>,
private val submitTaskConsumer: Consumer<Runnable>?,
private val checkServiceEnabledSupplier: Supplier<Boolean>,
private val infoLogger: Consumer<String>,
private val logSentData: Boolean,
private val logResponseStatusText: Boolean
) {
private fun startSubmitting() {
val submitTask = Runnable {
if (!checkServiceEnabledSupplier.get()) {
// Submitting data or service is disabled
scheduler.shutdown()
return@Runnable
}
if (submitTaskConsumer != null) {
submitTaskConsumer.accept { submitData() }
} else {
submitData()
}
}
// Many servers tend to restart at a fixed time at xx:00 which causes an uneven distribution
// of requests on the
// bStats backend. To circumvent this problem, we introduce some randomness into the initial
// and second delay.
// WARNING: You must not modify and part of this Metrics class, including the submit delay or
// frequency!
// WARNING: Modifying this code will get your plugin banned on bStats. Just don't do it!
val initialDelay = (1000 * 60 * (3 + Math.random() * 3)).toLong()
val secondDelay = (1000 * 60 * (Math.random() * 30)).toLong()
runIgnoring {
scheduler.schedule(submitTask, initialDelay, TimeUnit.MILLISECONDS)
scheduler.scheduleAtFixedRate(
submitTask, initialDelay + secondDelay, (1000 * 60 * 30).toLong(), TimeUnit.MILLISECONDS
)
}
}
private fun submitData() {
val baseJsonBuilder = JsonObjectBuilder()
appendPlatformDataConsumer.accept(baseJsonBuilder)
val serviceJsonBuilder = JsonObjectBuilder()
appendServiceDataConsumer.accept(serviceJsonBuilder)
serviceJsonBuilder.appendField("id", serviceId)
baseJsonBuilder.appendField("service", serviceJsonBuilder.build())
baseJsonBuilder.appendField("serverUUID", serverUuid)
baseJsonBuilder.appendField("metricsVersion", METRICS_VERSION)
val data = baseJsonBuilder.build()
runIgnoring {
scheduler.execute {
runIgnoring { sendData(data) }
}
}
}
@Throws(Exception::class)
private fun sendData(data: JsonObjectBuilder.JsonObject) {
if (logSentData) {
infoLogger.accept("Sent bStats metrics data: $data")
}
val url = String.format(REPORT_URL, platform)
val connection = URL(url).openConnection() as HttpsURLConnection
// Compress the data to save bandwidth
val compressedData = compress(data.toString())
connection.requestMethod = "POST"
connection.addRequestProperty("Accept", "application/json")
connection.addRequestProperty("Connection", "close")
connection.addRequestProperty("Content-Encoding", "gzip")
connection.addRequestProperty("Content-Length", compressedData!!.size.toString())
connection.setRequestProperty("Content-Type", "application/json")
connection.setRequestProperty("User-Agent", "Metrics-Service/1")
connection.doOutput = true
DataOutputStream(connection.outputStream).use { outputStream -> outputStream.write(compressedData) }
val builder = StringBuilder()
BufferedReader(InputStreamReader(connection.inputStream)).use { bufferedReader ->
var line: String?
while (bufferedReader.readLine().also { line = it } != null) {
builder.append(line)
}
}
if (logResponseStatusText) {
infoLogger.accept("Sent data to bStats and received response: $builder")
}
}
companion object {
const val METRICS_VERSION = "2.2.1"
private val scheduler =
Executors.newScheduledThreadPool(1) { task: Runnable? -> Thread(task, "bStats-Metrics") }
private const val REPORT_URL = "https://bStats.org/api/v2/data/%s"
private fun compress(str: String?): ByteArray? {
if (str == null) {
return null
}
val outputStream = ByteArrayOutputStream()
GZIPOutputStream(outputStream).use { gzip -> gzip.write(str.toByteArray(StandardCharsets.UTF_8)) }
return outputStream.toByteArray()
}
}
init {
startSubmitting()
}
}
class JsonObjectBuilder {
private var builder: StringBuilder? = StringBuilder()
private var hasAtLeastOneField = false
fun appendField(key: String?, value: String?): JsonObjectBuilder {
requireNotNull(value) { "JSON value must not be null" }
appendFieldUnescaped(key, "\"" + escape(value) + "\"")
return this
}
fun appendField(key: String?, value: Int): JsonObjectBuilder {
appendFieldUnescaped(key, value.toString())
return this
}
fun appendField(key: String?, `object`: JsonObject?): JsonObjectBuilder {
requireNotNull(`object`) { "JSON object must not be null" }
appendFieldUnescaped(key, `object`.toString())
return this
}
private fun appendFieldUnescaped(key: String?, escapedValue: String) {
checkNotNull(builder) { "JSON has already been built" }
requireNotNull(key) { "JSON key must not be null" }
if (hasAtLeastOneField) {
builder!!.append(",")
}
builder!!.append("\"").append(escape(key)).append("\":").append(escapedValue)
hasAtLeastOneField = true
}
fun build(): JsonObject {
checkNotNull(builder) { "JSON has already been built" }
val obj = JsonObject(
builder!!.append("}").toString()
)
builder = null
return obj
}
class JsonObject(private val value: String) {
override fun toString(): String {
return value
}
}
companion object {
private fun escape(value: String): String {
val builder = StringBuilder()
for (element in value) {
if (element == '"') {
builder.append("\\\"")
} else if (element == '\\') {
builder.append("\\\\")
} else if (element <= '\u000F') {
builder.append("\\u000").append(Integer.toHexString(element.code))
} else if (element <= '\u001F') {
builder.append("\\u00").append(Integer.toHexString(element.code))
} else {
builder.append(element)
}
}
return builder.toString()
}
}
init {
builder!!.append("{")
}
}
init {
// Get the config file
val bStatsFolder = File(plugin.dataFolder.parentFile, "bStats")
val configFile = File(bStatsFolder, "config.yml")
val config = YamlConfiguration.loadConfiguration(configFile)
if (!config.isSet("serverUuid")) {
config.addDefault("enabled", true)
config.addDefault("serverUuid", UUID.randomUUID().toString())
config.addDefault("logFailedRequests", false)
config.addDefault("logSentData", false)
config.addDefault("logResponseStatusText", false)
// Inform the server owners about bStats
config
.options()
.header(
"""
bStats (https://bStats.org) collects some basic information for plugin authors, like how
many people use their plugin and their total player count. It's recommended to keep bStats
enabled, but if you're not comfortable with this, you can turn this setting off. There is no
performance penalty associated with having metrics enabled, and data sent to bStats is fully
anonymous.
""".trimIndent()
)
.copyDefaults(true)
config.save(configFile)
}
// Load the data
val serverUUID = config.getString("serverUuid")!!
val logSentData = config.getBoolean("logSentData", false)
val logResponseStatusText = config.getBoolean("logResponseStatusText", false)
metricsBase = MetricsBase(
"bukkit",
serverUUID,
plugin.bStatsId,
{ builder: JsonObjectBuilder -> appendPlatformData(builder) },
{ builder: JsonObjectBuilder -> appendServiceData(builder) },
{ submitDataTask: Runnable? -> Bukkit.getScheduler().runTask(plugin, submitDataTask!!) },
{ plugin.isEnabled },
{ message: String? -> this.plugin.logger.log(Level.INFO, message) },
logSentData,
logResponseStatusText
)
}
}
private fun runIgnoring(func: () -> Unit) {
try {
func()
} catch (e: Exception) {
// Do nothing
}
}

View File

@@ -0,0 +1,34 @@
package com.willfp.eco.internal.spigot.integrations.hologram
import com.willfp.eco.core.integrations.hologram.Hologram
import com.willfp.eco.core.integrations.hologram.HologramWrapper
import eu.decentsoftware.holograms.api.DHAPI
import org.bukkit.Location
import java.util.UUID
@Suppress("DEPRECATION")
class HologramDecentHolograms : HologramWrapper {
override fun createHologram(location: Location, contents: MutableList<String>): Hologram {
val id = UUID.randomUUID().toString()
DHAPI.createHologram(id, location, contents)
return HologramImplDecentHolograms(id)
}
override fun getPluginName(): String {
return "DecentHolograms"
}
class HologramImplDecentHolograms(
private val id: String,
) : Hologram {
override fun remove() {
DHAPI.getHologram(id)?.destroy()
}
override fun setContents(contents: MutableList<String>) {
DHAPI.setHologramLines(DHAPI.getHologram(id), contents)
}
}
}

View File

@@ -21,7 +21,7 @@ class ShopShopGuiPlus : ShopWrapper {
override fun loadItem(configurationSection: ConfigurationSection): ItemStack? {
val id = configurationSection.getString("eco")
return if (id == null) null else Items.lookup(id)?.item
return if (id == null) null else Items.lookup(id).item
}
override fun compare(itemStack1: ItemStack, itemStack2: ItemStack): Boolean {

View File

@@ -25,10 +25,6 @@ villager-display-fix: false
# Disable it if it changes drop mechanics too much for you.
use-fast-collated-drops: true
# bStats is important and you should keep it enabled.
# This option is only here because of compliance with data protection laws.
enable-bstats: true
# Some plugins use their own item display systems (eg Triton)
# And must be run after eco. Don't enable this unless you run a conflicting plugin
# and have been told to enable it.

View File

@@ -38,6 +38,7 @@ softdepend:
- IridiumSkyblock
- SuperiorSkyblock2
- CrashClaim
- DecentHolograms
libraries:
- 'org.reflections:reflections:0.9.12'
- 'org.apache.maven:maven-artifact:3.0.3'

View File

@@ -1,3 +1,3 @@
version = 6.15.2
version = 6.16.2
plugin-name = eco
kotlin.code.style = official