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 .github/scripts/install-local-dependencies.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/usr/bin/env bash
set -euo pipefail
# Run from the repository root after downloading the pinned JARs.
# Hash-qualified versions prevent different private JARs sharing a Maven cache key.
sha256sum --check .github/dependencies.sha256

mvn -B --no-transfer-progress org.apache.maven.plugins:maven-install-plugin:3.1.4:install-file \
-Dfile="libs/VotingPlugin-7.0.jar" -DgroupId="local" -DartifactId="VotingPlugin" \
-Dversion="7.0-tfmc-27e9906f1377" -Dpackaging=jar -DgeneratePom=true "$@"
mvn -B --no-transfer-progress org.apache.maven.plugins:maven-install-plugin:3.1.4:install-file \
-Dfile="libs/MMOCore-1.13.1.jar" -DgroupId="local" -DartifactId="MMOCore" \
-Dversion="1.13.1-tfmc-14850d745437" -Dpackaging=jar -DgeneratePom=true "$@"
mvn -B --no-transfer-progress org.apache.maven.plugins:maven-install-plugin:3.1.4:install-file \
-Dfile="libs/MMOItems-6.10.1.jar" -DgroupId="local" -DartifactId="MMOItems" \
-Dversion="6.10.1-tfmc-8ff714bd3f48" -Dpackaging=jar -DgeneratePom=true "$@"
mvn -B --no-transfer-progress org.apache.maven.plugins:maven-install-plugin:3.1.4:install-file \
-Dfile="libs/MythicLib-dist-1.7.1.jar" -DgroupId="local" -DartifactId="MythicLib" \
-Dversion="1.7.1-tfmc-a3f86a50d382" -Dpackaging=jar -DgeneratePom=true "$@"
2 changes: 1 addition & 1 deletion .github/scripts/prepare-release.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ curl --fail --location --silent --show-error --retry 3 -H "Authorization: Bearer
curl --fail --location --silent --show-error --retry 3 -H "Authorization: Bearer $GH_TOKEN" -H "Accept: application/vnd.github.raw+json" "https://api.github.com/repos/TF-Minecraft/ServerAssets/contents/jars/14850d745437/MMOCore-1.13.1.jar?ref=$ref" > "libs/MMOCore-1.13.1.jar"
curl --fail --location --silent --show-error --retry 3 -H "Authorization: Bearer $GH_TOKEN" -H "Accept: application/vnd.github.raw+json" "https://api.github.com/repos/TF-Minecraft/ServerAssets/contents/jars/8ff714bd3f48/MMOItems-6.10.1-20250521.175300-22.jar?ref=$ref" > "libs/MMOItems-6.10.1.jar"
curl --fail --location --silent --show-error --retry 3 -H "Authorization: Bearer $GH_TOKEN" -H "Accept: application/vnd.github.raw+json" "https://api.github.com/repos/TF-Minecraft/ServerAssets/contents/jars/a3f86a50d382/MythicLib-dist-1.7.1.jar?ref=$ref" > "libs/MythicLib-dist-1.7.1.jar"
sha256sum --check .github/dependencies.sha256
bash .github/scripts/install-local-dependencies.sh "$@"
27 changes: 15 additions & 12 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,8 @@
<dependency>
<groupId>local</groupId>
<artifactId>VotingPlugin</artifactId>
<version>7.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/libs/VotingPlugin-7.0.jar</systemPath>
<version>7.0-tfmc-27e9906f1377</version>
<scope>provided</scope>
</dependency>
<!-- MusicalInstruments: provided plugin API, compiled against for InstrumentPlayEvent -->
<dependency>
Expand Down Expand Up @@ -82,28 +81,25 @@
<dependency>
<groupId>local</groupId>
<artifactId>MMOCore</artifactId>
<version>1.13.1</version>
<scope>system</scope>
<systemPath>${project.basedir}/libs/MMOCore-1.13.1.jar</systemPath>
<version>1.13.1-tfmc-14850d745437</version>
<scope>provided</scope>
</dependency>
<!-- MMOItems: jar-only release, compiled against for
PlayerUseCraftingStationEvent -->
<dependency>
<groupId>local</groupId>
<artifactId>MMOItems</artifactId>
<version>6.10.1</version>
<scope>system</scope>
<systemPath>${project.basedir}/libs/MMOItems-6.10.1.jar</systemPath>
<version>6.10.1-tfmc-8ff714bd3f48</version>
<scope>provided</scope>
</dependency>
<!-- MythicLib: MMOCore's own hard dependency. Not used directly, but
MMOCore's Profession implements one of its interfaces, so javac
needs it on the classpath to resolve Profession at all. -->
<dependency>
<groupId>local</groupId>
<artifactId>MythicLib</artifactId>
<version>1.7.1</version>
<scope>system</scope>
<systemPath>${project.basedir}/libs/MythicLib-dist-1.7.1.jar</systemPath>
<version>1.7.1-tfmc-a3f86a50d382</version>
<scope>provided</scope>
</dependency>
<!-- VFBuilders: provided plugin API, compiled against for VehicleConstructEvent -->
<dependency>
Expand Down Expand Up @@ -252,6 +248,13 @@
</exclusion>
</exclusions>
</dependency>
<!-- Constructor-free test fixtures through Objenesis' supported API. -->
<dependency>
<groupId>org.objenesis</groupId>
<artifactId>objenesis</artifactId>
<version>3.3</version>
<scope>test</scope>
</dependency>
<!-- Tests -->
<dependency>
<groupId>org.junit.jupiter</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,8 @@ private static boolean isToday(PlayerData data, ActivityConfiguration.Keys keys)
return data != null && data.weekKey().equals(keys.week()) && data.dayKey().equals(keys.day());
}

// Keep the existing legacy text representation, formatting, and exact-string comparisons.
@SuppressWarnings("deprecation")
private void handleCheck(CommandSender sender, String[] args) {
if (args.length < 2) {
usage(sender);
Expand Down Expand Up @@ -300,6 +302,8 @@ private void handleAdd(CommandSender sender, String[] args) {
+ " result=" + outcome);
}

// Keep the existing legacy text representation, formatting, and exact-string comparisons.
@SuppressWarnings("deprecation")
private void handleAddPoints(CommandSender sender, String[] args) {
if (args.length != 3) {
usage(sender);
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/net/tfminecraft/activitytf/gui/ActivityGui.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ public Inventory getInventory() {
}
}

// Keep the existing legacy text representation, formatting, and exact-string comparisons.
@SuppressWarnings("deprecation")
public Inventory build(Player player) {
ActivityConfiguration config = manager.getConfiguration();
Messages messages = config.messages();
Expand Down Expand Up @@ -229,6 +231,8 @@ private ItemStack item(Material material, String name, List<String> lore) {
return item(new ItemStack(material), name, lore);
}

// Keep the existing legacy text representation, formatting, and exact-string comparisons.
@SuppressWarnings("deprecation")
private ItemStack item(ItemStack stack, String name, List<String> lore) {
ItemMeta meta = stack.getItemMeta();
if (meta != null) {
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/net/tfminecraft/activitytf/utils/Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

public class Utils {

// Keep the existing legacy text representation, formatting, and exact-string comparisons.
@SuppressWarnings("deprecation")
public static String colorize(String msg) {
Matcher match = Pattern.compile("#[a-fA-F0-9]{6}").matcher(msg);
while (match.find()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,10 @@
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import sun.reflect.ReflectionFactory;
import org.objenesis.ObjenesisStd;
import net.tfminecraft.activitytf.models.RewardEntry;

import java.io.StringReader;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
Expand All @@ -36,10 +35,7 @@ private static final class TestPlugin extends JavaPlugin {

private static JavaPlugin stubPlugin() {
try {
ReflectionFactory rf = ReflectionFactory.getReflectionFactory();
Constructor<Object> objectCtor = Object.class.getDeclaredConstructor();
Constructor<?> bypass = rf.newConstructorForSerialization(TestPlugin.class, objectCtor);
JavaPlugin plugin = (JavaPlugin) bypass.newInstance();
JavaPlugin plugin = new ObjenesisStd().newInstance(TestPlugin.class);

Field loggerField = JavaPlugin.class.getDeclaredField("logger");
loggerField.setAccessible(true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.plugin.java.JavaPlugin;
import org.junit.jupiter.api.Test;
import sun.reflect.ReflectionFactory;
import org.objenesis.ObjenesisStd;

import java.io.StringReader;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Optional;
Expand All @@ -24,10 +23,7 @@ private static final class TestPlugin extends JavaPlugin {

private static JavaPlugin stubPlugin() {
try {
ReflectionFactory rf = ReflectionFactory.getReflectionFactory();
Constructor<Object> objectCtor = Object.class.getDeclaredConstructor();
Constructor<?> bypass = rf.newConstructorForSerialization(TestPlugin.class, objectCtor);
JavaPlugin plugin = (JavaPlugin) bypass.newInstance();
JavaPlugin plugin = new ObjenesisStd().newInstance(TestPlugin.class);

Field loggerField = JavaPlugin.class.getDeclaredField("logger");
loggerField.setAccessible(true);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
package net.tfminecraft.activitytf.config;

import org.bukkit.plugin.java.JavaPlugin;
import sun.reflect.ReflectionFactory;
import org.objenesis.ObjenesisStd;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.util.List;
import java.util.logging.Handler;
Expand All @@ -21,10 +20,7 @@ private static final class TestPlugin extends JavaPlugin {

static JavaPlugin capturing(List<String> logged) {
try {
ReflectionFactory rf = ReflectionFactory.getReflectionFactory();
Constructor<Object> objectCtor = Object.class.getDeclaredConstructor();
Constructor<?> bypass = rf.newConstructorForSerialization(TestPlugin.class, objectCtor);
JavaPlugin plugin = (JavaPlugin) bypass.newInstance();
JavaPlugin plugin = new ObjenesisStd().newInstance(TestPlugin.class);

Logger logger = Logger.getAnonymousLogger();
logger.setUseParentHandlers(false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ void everyChecksumJarHasMatchingDownloadAndViceVersa() throws IOException {
}

@Test
void everyPomSystemPathJarIsListedInSha256sums() throws IOException {
void everyInstalledLocalJarIsChecksumPinned() throws IOException {
Path pomFile = Path.of("pom.xml");
assertTrue(Files.exists(pomFile), "pom.xml should exist");
Path sumsFile = Path.of(".github/dependencies.sha256");
Expand All @@ -179,14 +179,19 @@ void everyPomSystemPathJarIsListedInSha256sums() throws IOException {
jarsInSums.add(m.group(1));
}

Pattern systemPath = Pattern.compile("<systemPath>[^<]*?libs/([^<]+\\.jar)</systemPath>");
Matcher m = systemPath.matcher(Files.readString(pomFile));
Set<String> jarsInPom = new HashSet<>();
while (m.find()) {
jarsInPom.add(m.group(1));
String pom = Files.readString(pomFile);
assertFalse(pom.contains("<systemPath>"), "Local APIs must use provided Maven dependencies");
String installer = Files.readString(Path.of(".github/scripts/install-local-dependencies.sh"));
assertTrue(installer.contains("sha256sum --check .github/dependencies.sha256"));
Set<String> installed = new HashSet<>();
Matcher files = Pattern.compile("-Dfile=\"libs/([^\"]+\\.jar)\"").matcher(installer);
while (files.find()) installed.add(files.group(1));
assertEquals(jarsInSums, installed, "Every installed JAR must have a pinned checksum");
for (String line : Files.readAllLines(sumsFile)) {
if (line.isBlank()) continue;
String suffix = "-tfmc-" + line.substring(0, 12);
assertTrue(installer.contains(suffix), "Installer must use hash-qualified coordinates");
assertTrue(pom.contains(suffix + "</version>"), "POM must use the same pinned coordinates");
}
assertFalse(jarsInPom.isEmpty(), "pom.xml should have at least one systemPath jar");

assertEquals(jarsInPom, jarsInSums, "Every system dependency must have exactly one pinned checksum");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ void quittingClearsTheCarrySoALaterHalfWinCreditsNothing() {
Player player = stubPlayer(uuid);

listener.onPlayerWonMoney(win(player, 0.5));
listener.onQuit(new PlayerQuitEvent(player, (String) null));
listener.onQuit(new PlayerQuitEvent(player, (net.kyori.adventure.text.Component) null, PlayerQuitEvent.QuitReason.DISCONNECTED));
listener.onPlayerWonMoney(win(player, 0.5));

assertEquals(0, manager.tasks(uuid).count("casino_win"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,15 +104,15 @@ void aDoubleClickOnTheResultSlotTakesNothing() {
}

@Test
@SuppressWarnings("deprecation")
@SuppressWarnings({"deprecation", "removal"})
void aNumberKeySwapOntoAnOccupiedSlotTakesNothing() {
assertFalse(CraftListener.takesFromResult(ClickType.NUMBER_KEY, InventoryAction.HOTBAR_MOVE_AND_READD, OCCUPIED));
assertFalse(CraftListener.takesFromResult(ClickType.NUMBER_KEY, InventoryAction.HOTBAR_SWAP, OCCUPIED));
assertTrue(CraftListener.takesFromResult(ClickType.NUMBER_KEY, InventoryAction.HOTBAR_MOVE_AND_READD, EMPTY));
}

@Test
@SuppressWarnings("deprecation")
@SuppressWarnings({"deprecation", "removal"})
void anOffhandSwapOntoAnOccupiedOffhandTakesNothing() {
assertFalse(CraftListener.takesFromResult(ClickType.SWAP_OFFHAND, InventoryAction.HOTBAR_MOVE_AND_READD, OCCUPIED));
assertFalse(CraftListener.takesFromResult(ClickType.SWAP_OFFHAND, InventoryAction.HOTBAR_SWAP, OCCUPIED));
Expand Down Expand Up @@ -150,7 +150,7 @@ void unlistedClickTypesTakeNothing() {
private static final int RESULT_SLOT = 0;

@Test
@SuppressWarnings("deprecation")
@SuppressWarnings({"deprecation", "removal"})
void anEmptyResultSlotCreditsNothingWhateverTheClick() {
for (ClickType click : ClickType.values()) {
for (InventoryAction action : InventoryAction.values()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@
import net.tfminecraft.cooking.events.DishCookedEvent;
import org.bukkit.entity.Player;
import org.junit.jupiter.api.Test;
import sun.reflect.ReflectionFactory;
import org.objenesis.ObjenesisStd;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
Expand All @@ -31,10 +30,7 @@ private static Player stubPlayer(UUID uuid) {

private static DishCookedEvent dish(Player player) {
try {
ReflectionFactory rf = ReflectionFactory.getReflectionFactory();
Constructor<Object> objectCtor = Object.class.getDeclaredConstructor();
Constructor<?> bypass = rf.newConstructorForSerialization(DishCookedEvent.class, objectCtor);
DishCookedEvent event = (DishCookedEvent) bypass.newInstance();
DishCookedEvent event = new ObjenesisStd().newInstance(DishCookedEvent.class);

Field playerField = DishCookedEvent.class.getDeclaredField("player");
playerField.setAccessible(true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ void quittingClearsTheCarrySoALaterHalfSaleCreditsNothing() {
Player player = stubPlayer(uuid);

listener.onMarketSale(sale(player, 0.5));
listener.onQuit(new PlayerQuitEvent(player, (String) null));
listener.onQuit(new PlayerQuitEvent(player, (net.kyori.adventure.text.Component) null, PlayerQuitEvent.QuitReason.DISCONNECTED));
listener.onMarketSale(sale(player, 0.5));

assertEquals(0, manager.tasks(uuid).count("market_sale"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,11 @@
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.EnumSource;
import sun.reflect.ReflectionFactory;
import org.objenesis.ObjenesisStd;
import net.tfminecraft.activitytf.config.ActivityConfiguration;
import net.tfminecraft.activitytf.managers.ActivityManager;
import net.tfminecraft.activitytf.models.ActivityDef;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
Expand Down Expand Up @@ -47,16 +46,8 @@ private static Player stubPlayer(UUID uuid) {
MmoItemsStationListenerTest.class.getClassLoader(), new Class<?>[]{Player.class}, handler);
}

@SuppressWarnings("unchecked")
private static <T> T bypassNew(Class<T> type) {
try {
ReflectionFactory rf = ReflectionFactory.getReflectionFactory();
Constructor<Object> objectCtor = Object.class.getDeclaredConstructor();
Constructor<?> bypass = rf.newConstructorForSerialization(type, objectCtor);
return (T) bypass.newInstance();
} catch (ReflectiveOperationException e) {
throw new RuntimeException(e);
}
return new ObjenesisStd().newInstance(type);
}

private static void setField(Object target, Class<?> declaringClass, String name, Object value) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import sun.reflect.ReflectionFactory;
import org.objenesis.ObjenesisStd;
import net.tfminecraft.activitytf.config.ActivityConfiguration;
import net.tfminecraft.activitytf.models.ActivityDef;
import net.tfminecraft.activitytf.models.RewardEntry;
Expand Down Expand Up @@ -221,10 +221,7 @@ public static Logger logger() {

private static JavaPlugin stubPlugin() {
try {
ReflectionFactory rf = ReflectionFactory.getReflectionFactory();
Constructor<Object> objectCtor = Object.class.getDeclaredConstructor();
Constructor<?> bypass = rf.newConstructorForSerialization(TestPlugin.class, objectCtor);
JavaPlugin plugin = (JavaPlugin) bypass.newInstance();
JavaPlugin plugin = new ObjenesisStd().newInstance(TestPlugin.class);

Field logger = JavaPlugin.class.getDeclaredField("logger");
logger.setAccessible(true);
Expand Down