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
18 changes: 18 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<advancedcrafting.version>2.0.0</advancedcrafting.version>
<archeology-plugin.version>2.0.0</archeology-plugin.version>
<breweryx.version>3.7.0</breweryx.version>
<cooking.version>0.2.1</cooking.version>
<games.version>0.2.0</games.version>
<geiger_counter.version>2.0.0</geiger_counter.version>
Expand Down Expand Up @@ -248,6 +249,19 @@
</exclusion>
</exclusions>
</dependency>
<!-- BreweryX: provided plugin API, compiled against for its brewing events -->
<dependency>
<groupId>com.dre.brewery</groupId>
<artifactId>BreweryX</artifactId>
<version>${breweryx.version}</version>
<scope>provided</scope>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Constructor-free test fixtures through Objenesis' supported API. -->
<dependency>
<groupId>org.objenesis</groupId>
Expand All @@ -273,6 +287,10 @@
<id>placeholderapi</id>
<url>https://repo.extendedclip.com/releases/</url>
</repository>
<repository>
<id>breweryx</id>
<url>https://repo.jsinco.dev/releases/</url>
</repository>
</repositories>

<build>
Expand Down
7 changes: 7 additions & 0 deletions src/main/java/net/tfminecraft/activitytf/ActivityPlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import net.tfminecraft.activitytf.listeners.AdvancedCraftListener;
import net.tfminecraft.activitytf.listeners.ArchaeologyListener;
import net.tfminecraft.activitytf.listeners.BattleListener;
import net.tfminecraft.activitytf.listeners.BreweryListener;
import net.tfminecraft.activitytf.listeners.CasinoWinListener;
import net.tfminecraft.activitytf.listeners.CharacterChatListener;
import net.tfminecraft.activitytf.listeners.CraftListener;
Expand Down Expand Up @@ -162,6 +163,12 @@ private void registerHooks() {
getLogger().info("Hooked into Cooking.");
}

if (Bukkit.getPluginManager().isPluginEnabled("BreweryX")) {
getServer().getPluginManager().registerEvents(
new BreweryListener(ActivityManager.getInstance()), this);
getLogger().info("Hooked into BreweryX.");
}

if (Bukkit.getPluginManager().isPluginEnabled("PlaceholderAPI")) {
placeholderHook = new PlaceholderHook(ActivityManager.getInstance());
placeholderHook.register();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package net.tfminecraft.activitytf.listeners;

import com.dre.brewery.api.events.IngedientAddEvent;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import net.tfminecraft.activitytf.managers.ActivityManager;

public class BreweryListener implements Listener {

private final ActivityManager manager;

public BreweryListener(ActivityManager manager) {
this.manager = manager;
}

// BreweryX only fires this for an item a cauldron recipe accepts, once per item added.
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onIngredientAdd(IngedientAddEvent event) {
if (event.getPlayer() == null) {
return;
}
manager.recordAction(event.getPlayer().getUniqueId(), "brew_ingredient", 1);
}
}
14 changes: 14 additions & 0 deletions src/main/resources/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,20 @@ activities:
every: 5
points: 1
daily-cap: 2
# BreweryX activities (brew_*). The shipped config.yml is only written on a fresh
# install, so an existing server must copy these entries into its own config.yml
# and run /activity reload; until then they are unknown ids and earn nothing.
# BreweryX: ingredients put into a brewing cauldron
brew_ingredient:
Comment thread
coderabbitai[bot] marked this conversation as resolved.
display: "#e6ca40&lGather Brewing Ingredients"
description:
- "&7Add &a%every% &7ingredients to a brewing cauldron."
- "&7Earn &a%points% &7activity points per completion."
- "&7"
material: CAULDRON
every: 10
points: 1
daily-cap: 1
# RPCharacters: profession upgrades purchased
profession_upgrade:
display: "#e6ca40&lProfession Upgrade"
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/plugin.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ author: Justin
api-version: '1.21.10'
softdepend: [VotingPlugin, MusicalInstruments, geiger_counter, MMOCore, MMOItems, MythicLib, PlaceholderAPI,
VFBuilders, RPCharacters, InteractibleFurniture, SimpleFactions, AdvancedCrafting, TLibs, Archaeo,
MarketBlock, Games, Cooking, ItemsAdder]
MarketBlock, Games, Cooking, ItemsAdder, BreweryX]
commands:
activity:
description: Open the weekly activity bar, or run admin subcommands
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package net.tfminecraft.activitytf.listeners;

import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.junit.jupiter.api.Test;

import java.lang.reflect.Method;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

class BreweryListenerHandlersTest {

// BreweryListenerTest calls the handlers directly, which skips Bukkit's ignoreCancelled filter.
@Test
void everyHandlerSkipsCancelledEventsAtMonitor() {
int handlers = 0;
for (Method method : BreweryListener.class.getDeclaredMethods()) {
EventHandler handler = method.getAnnotation(EventHandler.class);
if (handler == null) {
continue;
}
handlers++;
assertTrue(handler.ignoreCancelled(), method.getName() + " must ignore cancelled events");
assertEquals(EventPriority.MONITOR, handler.priority(), method.getName());
}
assertTrue(handlers > 0);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package net.tfminecraft.activitytf.listeners;

import com.dre.brewery.api.events.IngedientAddEvent;
import net.tfminecraft.activitytf.managers.ActivityManager;
import net.tfminecraft.activitytf.managers.TestManagers;
import net.tfminecraft.activitytf.models.ActivityDef;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerEvent;
import org.junit.jupiter.api.Test;
import org.objenesis.ObjenesisStd;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.UUID;

import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;

class BreweryListenerTest {

private static Player stubPlayer(UUID uuid) {
InvocationHandler handler = (proxy, method, args) -> switch (method.getName()) {
case "getUniqueId" -> uuid;
case "toString" -> "stub-player";
case "hashCode" -> uuid.hashCode();
case "equals" -> proxy == args[0];
default -> throw new UnsupportedOperationException(
"unexpected call to Player#" + method.getName() + " - this test double only answers getUniqueId()");
};
return (Player) Proxy.newProxyInstance(
BreweryListenerTest.class.getClassLoader(), new Class<?>[]{Player.class}, handler);
}

static void set(Class<?> owner, Object target, String name, Object value) {
try {
Field field = owner.getDeclaredField(name);
field.setAccessible(true);
field.set(target, value);
} catch (ReflectiveOperationException e) {
throw new RuntimeException(e);
}
}

private static IngedientAddEvent ingredient(Player player) {
IngedientAddEvent event = new ObjenesisStd().newInstance(IngedientAddEvent.class);
set(PlayerEvent.class, event, "player", player);
return event;
}

/** A manager with every given activity revealed for the returned player. */
static UUID revealed(ActivityManager manager) {
TestManagers.bukkit();
TestManagers.storeLoaded(manager);
UUID uuid = UUID.randomUUID();
for (int slot = 0; slot < manager.tasks(uuid).tasks().size(); slot++) {
manager.reveal(uuid, slot);
}
return uuid;
}

static ActivityManager managerWith(String... ids) {
ActivityDef[] defs = new ActivityDef[ids.length];
for (int i = 0; i < ids.length; i++) {
defs[i] = new ActivityDef(ids[i], ids[i], Material.POTION, null, 1, 1, 0);
}
ActivityManager manager = TestManagers.manager(defs);
TestManagers.guarantee(manager, ids);
return manager;
}

@Test
void anIngredientWithoutAPlayerIsIgnored() {
BreweryListener listener = new BreweryListener(null);
assertDoesNotThrow(() -> listener.onIngredientAdd(ingredient(null)));
}

@Test
void eachIngredientAddedCreditsOne() {
ActivityManager manager = managerWith("brew_ingredient");
UUID uuid = revealed(manager);
BreweryListener listener = new BreweryListener(manager);

listener.onIngredientAdd(ingredient(stubPlayer(uuid)));
listener.onIngredientAdd(ingredient(stubPlayer(uuid)));

assertEquals(2, manager.tasks(uuid).count("brew_ingredient"));
}
}