Skip to content

Commit 582d3bc

Browse files
authored
Merge pull request #2791 from BentoBoxWorld/develop
2 parents 555a33c + 0eb0142 commit 582d3bc

File tree

272 files changed

+12004
-3180
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

272 files changed

+12004
-3180
lines changed

build.gradle.kts

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ paperweight.reobfArtifactConfiguration = io.papermc.paperweight.userdev.ReobfArt
4646
group = "world.bentobox" // From <groupId>
4747

4848
// Base properties from <properties>
49-
val buildVersion = "3.11.1"
49+
val buildVersion = "3.11.2"
5050
val buildNumberDefault = "-LOCAL" // Local build identifier
5151
val snapshotSuffix = "-SNAPSHOT" // Indicates development/snapshot version
5252

@@ -86,8 +86,7 @@ val mariadbVersion = "3.0.5"
8686
val mysqlVersion = "8.0.27"
8787
val postgresqlVersion = "42.2.18"
8888
val hikaricpVersion = "5.0.1"
89-
val spigotVersion = "1.21.10-R0.1-SNAPSHOT"
90-
val paperVersion = "1.21.10-R0.1-SNAPSHOT"
89+
val paperVersion = "1.21.11-R0.1-SNAPSHOT"
9190
val bstatsVersion = "3.0.0"
9291
val vaultVersion = "1.7.1"
9392
val levelVersion = "2.21.3"
@@ -120,7 +119,6 @@ extra["mariadb.version"] = mariadbVersion
120119
extra["mysql.version"] = mysqlVersion
121120
extra["postgresql.version"] = postgresqlVersion
122121
extra["hikaricp.version"] = hikaricpVersion
123-
extra["spigot.version"] = spigotVersion
124122
extra["paper.version"] = paperVersion
125123
extra["bstats.version"] = bstatsVersion
126124
extra["vault.version"] = vaultVersion
@@ -146,6 +144,19 @@ java {
146144
tasks.withType<JavaCompile> {
147145
// Ensure UTF-8 encoding for all source files
148146
options.encoding = "UTF-8"
147+
// Suppress all deprecation and removal warnings during compilation
148+
options.compilerArgs.addAll(listOf("-Xlint:-deprecation", "-Xlint:-removal"))
149+
// Set explicit Java release version for Eclipse compatibility
150+
options.release.set(21)
151+
}
152+
153+
tasks.compileTestJava {
154+
// Ensure UTF-8 encoding for all source files
155+
options.encoding = "UTF-8"
156+
// Suppress all deprecation and removal warnings during compilation
157+
options.compilerArgs.addAll(listOf("-Xlint:-deprecation", "-Xlint:-removal"))
158+
// Set explicit Java release version for Eclipse compatibility
159+
options.release.set(21)
149160
}
150161

151162

@@ -190,6 +201,7 @@ dependencies {
190201
// --- Test Dependencies: Only used during testing, not in production ---
191202
testImplementation(platform("org.junit:junit-bom:$junitVersion"))
192203
testImplementation("org.junit.jupiter:junit-jupiter-api")
204+
testImplementation("org.junit.jupiter:junit-jupiter-params")
193205
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine")
194206
testRuntimeOnly("org.junit.platform:junit-platform-launcher:$junitVersion")
195207
testImplementation("org.mockito:mockito-junit-jupiter:$mockitoVersion")
@@ -202,9 +214,6 @@ dependencies {
202214
testImplementation("commons-lang:commons-lang:$commonsLangVersion")
203215

204216
// --- Compile Only Dependencies: Provided by the server at runtime ---
205-
compileOnly("org.spigotmc:spigot:$spigotVersion") {
206-
exclude(group = "org.spigotmc", module = "spigot-api")
207-
}
208217
compileOnly("org.mongodb:mongodb-driver:$mongodbVersion")
209218
compileOnly("com.zaxxer:HikariCP:$hikaricpVersion")
210219
compileOnly("com.github.MilkBowl:VaultAPI:$vaultVersion")
@@ -253,9 +262,6 @@ dependencies {
253262
paperweight {
254263
addServerDependencyTo = configurations.named(JavaPlugin.COMPILE_ONLY_CONFIGURATION_NAME).map { setOf(it) }
255264
javaLauncher = javaToolchains.launcherFor {
256-
// Example scenario:
257-
// Paper 1.17.1 was originally built with JDK 16 and the bundle
258-
// has not been updated to work with 21+ (but we want to compile with a 25 toolchain)
259265
// Use the project's configured Java version for paperweight tools (needs Java 21+)
260266
languageVersion = JavaLanguageVersion.of(javaVersion)
261267
}

src/main/java/world/bentobox/bentobox/BentoBox.java

Lines changed: 14 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
import org.bukkit.Bukkit;
1212
import org.bukkit.event.Listener;
1313
import org.bukkit.generator.ChunkGenerator;
14-
import org.bukkit.plugin.PluginManager;
1514
import org.bukkit.plugin.java.JavaPlugin;
1615
import org.bukkit.scheduler.BukkitTask;
1716
import org.eclipse.jdt.annotation.NonNull;
@@ -23,29 +22,10 @@
2322
import world.bentobox.bentobox.api.panels.Panel;
2423
import world.bentobox.bentobox.api.user.Notifier;
2524
import world.bentobox.bentobox.api.user.User;
26-
import world.bentobox.bentobox.commands.BentoBoxCommand;
2725
import world.bentobox.bentobox.database.DatabaseSetup;
28-
import world.bentobox.bentobox.hooks.FancyNpcsHook;
29-
import world.bentobox.bentobox.hooks.ItemsAdderHook;
30-
import world.bentobox.bentobox.hooks.MultipaperHook;
31-
import world.bentobox.bentobox.hooks.MultiverseCore4Hook;
32-
import world.bentobox.bentobox.hooks.MultiverseCore5Hook;
33-
import world.bentobox.bentobox.hooks.MyWorldsHook;
34-
import world.bentobox.bentobox.hooks.MythicMobsHook;
35-
import world.bentobox.bentobox.hooks.OraxenHook;
36-
import world.bentobox.bentobox.hooks.SlimefunHook;
26+
import world.bentobox.bentobox.hooks.BentoBoxHookRegistrar;
3727
import world.bentobox.bentobox.hooks.VaultHook;
38-
import world.bentobox.bentobox.hooks.ZNPCsPlusHook;
39-
import world.bentobox.bentobox.hooks.placeholders.PlaceholderAPIHook;
40-
import world.bentobox.bentobox.listeners.BannedCommands;
41-
import world.bentobox.bentobox.listeners.BlockEndDragon;
42-
import world.bentobox.bentobox.listeners.DeathListener;
43-
import world.bentobox.bentobox.listeners.JoinLeaveListener;
44-
import world.bentobox.bentobox.listeners.PanelListenerManager;
45-
import world.bentobox.bentobox.listeners.PrimaryIslandListener;
46-
import world.bentobox.bentobox.listeners.StandardSpawnProtectionListener;
47-
import world.bentobox.bentobox.listeners.teleports.EntityTeleportListener;
48-
import world.bentobox.bentobox.listeners.teleports.PlayerTeleportListener;
28+
import world.bentobox.bentobox.listeners.BentoBoxListenerRegistrar;
4929
import world.bentobox.bentobox.managers.AddonsManager;
5030
import world.bentobox.bentobox.managers.BlueprintsManager;
5131
import world.bentobox.bentobox.managers.CommandsManager;
@@ -95,7 +75,7 @@ public class BentoBox extends JavaPlugin implements Listener {
9575

9676
// Notifier
9777
private Notifier notifier;
98-
78+
9979
// Click limiter
10080
private ExpiringMap<Pair<UUID, String>, Boolean> lastClick ;
10181

@@ -147,7 +127,7 @@ public void onEnable(){
147127
}
148128
// Saving the config now.
149129
saveConfig();
150-
130+
151131
// Set up click timeout
152132
lastClick = new ExpiringMap<>(getSettings().getClickCooldownMs(), TimeUnit.MILLISECONDS);
153133

@@ -169,7 +149,7 @@ public void onEnable(){
169149
commandsManager = new CommandsManager();
170150

171151
// Load BentoBox commands
172-
new BentoBoxCommand();
152+
commandsManager.registerDefaultCommands();
173153

174154
// Start Island Worlds Manager
175155
islandWorldManager = new IslandWorldManager(this);
@@ -202,19 +182,9 @@ public void onEnable(){
202182
private void completeSetup(long loadTime) {
203183
final long enableStart = System.currentTimeMillis();
204184

205-
hooksManager.registerHook(new MultipaperHook());
206-
207-
hooksManager.registerHook(new VaultHook());
208-
209-
// FancyNpcs
210-
hooksManager.registerHook(new FancyNpcsHook());
211-
// ZNPCsPlus
212-
hooksManager.registerHook(new ZNPCsPlusHook());
185+
BentoBoxHookRegistrar hookRegistrar = new BentoBoxHookRegistrar(this);
186+
hookRegistrar.registerEarlyHooks();
213187

214-
// MythicMobs
215-
hooksManager.registerHook(new MythicMobsHook());
216-
217-
hooksManager.registerHook(new PlaceholderAPIHook());
218188
// Setup the Placeholders manager
219189
placeholdersManager = new PlaceholdersManager(this);
220190

@@ -245,35 +215,21 @@ private void completeSetup(long loadTime) {
245215

246216
// Register Multiverse hook - MV loads AFTER BentoBox
247217
// Make sure all worlds are already registered to Multiverse.
248-
if (hasClass("org.mvplugins.multiverse.core.MultiverseCore")) {
249-
hooksManager.registerHook(new MultiverseCore5Hook());
250-
} else if (hasClass("com.onarandombox.MultiverseCore.MultiverseCore")) {
251-
hooksManager.registerHook(new MultiverseCore4Hook());
252-
}
253-
hooksManager.registerHook(new MyWorldsHook());
218+
hookRegistrar.registerWorldHooks();
254219
islandWorldManager.registerWorldsToMultiverse(true);
255220

256-
// Register Slimefun
257-
hooksManager.registerHook(new SlimefunHook());
258-
259-
// Register ItemsAdder
260-
hooksManager.registerHook(new ItemsAdderHook(this));
261-
262-
// Register Oraxen
263-
hooksManager.registerHook(new OraxenHook(this));
221+
hookRegistrar.registerLateHooks();
264222

265223
// TODO: re-enable after implementation
266-
//hooksManager.registerHook(new DynmapHook());
267224
// TODO: re-enable after rework
268-
//hooksManager.registerHook(new LangUtilsHook());
269225

270226
webManager = new WebManager(this);
271227

272228
final long enableTime = System.currentTimeMillis() - enableStart;
273229

274230
// Show banner
275231
User.getInstance(Bukkit.getConsoleSender()).sendMessage("successfully-loaded",
276-
TextVariables.VERSION, instance.getDescription().getVersion(),
232+
TextVariables.VERSION, instance.getPluginMeta().getVersion(),
277233
"[time]", String.valueOf(loadTime + enableTime));
278234

279235
// Poll for blueprints loading to be finished - async so could be a completely variable time
@@ -300,15 +256,6 @@ private void completeSetup(long loadTime) {
300256
}
301257
}
302258

303-
private boolean hasClass(String className) {
304-
try {
305-
Class.forName(className);
306-
return true;
307-
} catch (ClassNotFoundException e) {
308-
return false;
309-
}
310-
}
311-
312259
private void fireCriticalError(String message, String error) {
313260
logError("*****************CRITICAL ERROR!******************");
314261
logError(message);
@@ -327,30 +274,9 @@ private void fireCriticalError(String message, String error) {
327274
* Registers listeners.
328275
*/
329276
private void registerListeners() {
330-
PluginManager manager = getServer().getPluginManager();
331-
// Player join events
332-
manager.registerEvents(new JoinLeaveListener(this), this);
333-
// Panel listener manager
334-
manager.registerEvents(new PanelListenerManager(), this);
335-
// Standard Nether/End spawns protection
336-
manager.registerEvents(new StandardSpawnProtectionListener(this), this);
337-
// Player portals
338-
manager.registerEvents(new PlayerTeleportListener(this), this);
339-
// Entity portals
340-
manager.registerEvents(new EntityTeleportListener(this), this);
341-
// End dragon blocking
342-
manager.registerEvents(new BlockEndDragon(this), this);
343-
// Banned visitor commands
344-
manager.registerEvents(new BannedCommands(this), this);
345-
// Death counter
346-
manager.registerEvents(new DeathListener(this), this);
347-
// MV unregister
348-
manager.registerEvents(this, this);
349-
// Island Delete Manager
350-
islandDeletionManager = new IslandDeletionManager(this);
351-
manager.registerEvents(islandDeletionManager, this);
352-
// Primary Island Listener
353-
manager.registerEvents(new PrimaryIslandListener(this), this);
277+
BentoBoxListenerRegistrar registrar = new BentoBoxListenerRegistrar(this);
278+
registrar.register();
279+
islandDeletionManager = registrar.getIslandDeletionManager();
354280
}
355281

356282
@Override
@@ -654,7 +580,7 @@ public void reloadConfig() {
654580
public boolean isShutdown() {
655581
return shutdown;
656582
}
657-
583+
658584
/**
659585
* Checks if a user can click a GUI or needs to slow down
660586
* @param user user

src/main/java/world/bentobox/bentobox/Settings.java

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@
1111

1212
import org.bukkit.Material;
1313

14-
import com.google.common.collect.ImmutableList;
15-
1614
import world.bentobox.bentobox.api.configuration.ConfigComment;
1715
import world.bentobox.bentobox.api.configuration.ConfigEntry;
1816
import world.bentobox.bentobox.api.configuration.ConfigObject;
@@ -41,6 +39,11 @@ public class Settings implements ConfigObject {
4139
@ConfigEntry(path = "general.use-economy")
4240
private boolean useEconomy = true;
4341

42+
@ConfigComment("Whether to charge the blueprint bundle cost when a player resets their island.")
43+
@ConfigComment("If false, only island creation will charge the cost. Default is false.")
44+
@ConfigEntry(path = "general.charge-for-blueprint-on-reset")
45+
private boolean chargeForBlueprintOnReset = false;
46+
4447
/* COMMANDS */
4548
@ConfigComment("Console commands to run when BentoBox has loaded all worlds and addons.")
4649
@ConfigComment("Commands are run as the console.")
@@ -381,6 +384,14 @@ public void setUseEconomy(boolean useEconomy) {
381384
this.useEconomy = useEconomy;
382385
}
383386

387+
public boolean isChargeForBlueprintOnReset() {
388+
return chargeForBlueprintOnReset;
389+
}
390+
391+
public void setChargeForBlueprintOnReset(boolean chargeForBlueprintOnReset) {
392+
this.chargeForBlueprintOnReset = chargeForBlueprintOnReset;
393+
}
394+
384395
public DatabaseType getDatabaseType() {
385396
return databaseType;
386397
}
@@ -1010,7 +1021,7 @@ public void setSafeSpotSearchRange(int safeSpotSearchRange) {
10101021
* @return an immutable list of readyCommands
10111022
*/
10121023
public List<String> getReadyCommands() {
1013-
return ImmutableList.copyOf(Objects.requireNonNullElse(readyCommands, Collections.emptyList()));
1024+
return List.copyOf(Objects.requireNonNullElse(readyCommands, Collections.emptyList()));
10141025
}
10151026

10161027
/**

src/main/java/world/bentobox/bentobox/api/addons/Addon.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
import java.util.jar.JarEntry;
1313
import java.util.jar.JarFile;
1414
import java.util.logging.Logger;
15-
import java.util.regex.Matcher;
1615

1716
import org.bukkit.Bukkit;
1817
import org.bukkit.Server;
@@ -306,7 +305,7 @@ public File saveResource(String jarResource, File destinationFolder, boolean rep
306305
}
307306
// There are two options, use the path of the resource or not
308307
File outFile = new File(destinationFolder,
309-
jarResource.replaceAll("/", Matcher.quoteReplacement(File.separator)));
308+
jarResource.replace("/", File.separator));
310309

311310
if (noPath) {
312311
outFile = new File(destinationFolder, outFile.getName());

src/main/java/world/bentobox/bentobox/api/addons/AddonClassLoader.java

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@
66
import java.net.URL;
77
import java.net.URLClassLoader;
88
import java.util.Arrays;
9-
import java.util.HashMap;
109
import java.util.Locale;
1110
import java.util.Map;
1211
import java.util.Objects;
1312
import java.util.Set;
13+
import java.util.concurrent.ConcurrentHashMap;
1414

1515
import org.bukkit.Material;
1616
import org.bukkit.configuration.file.YamlConfiguration;
@@ -42,7 +42,7 @@ public class AddonClassLoader extends URLClassLoader {
4242
/**
4343
* A cache of classes that have been loaded by this class loader.
4444
*/
45-
private final Map<String, Class<?>> classes = new HashMap<>();
45+
private final Map<String, Class<?>> classes = new ConcurrentHashMap<>();
4646
/**
4747
* The addon instance that was loaded by this class loader.
4848
*/
@@ -218,28 +218,30 @@ public Class<?> findClass(String name, boolean checkGlobal) {
218218
if (name.startsWith("world.bentobox.bentobox")) {
219219
return null;
220220
}
221-
// Check local cache first.
221+
// Check local cache first. Avoid computeIfAbsent: super.findClass() triggers recursive
222+
// class loading which would call findClass() again, causing ConcurrentHashMap to throw
223+
// IllegalStateException: Recursive update.
222224
Class<?> result = classes.get(name);
225+
if (result != null) {
226+
return result;
227+
}
228+
// Check global cache for classes from other addons.
229+
if (checkGlobal) {
230+
result = loader.getClassByName(name);
231+
}
223232
if (result == null) {
224-
// Check global cache for classes from other addons.
225-
if (checkGlobal) {
226-
result = loader.getClassByName(name);
233+
// Try to find the class in this addon's jar.
234+
try {
235+
result = super.findClass(name);
236+
} catch (ClassNotFoundException | NoClassDefFoundError e) {
237+
// Do nothing. The class is not in this jar.
227238
}
228-
229-
if (result == null) {
230-
// Try to find the class in this addon's jar.
231-
try {
232-
result = super.findClass(name);
233-
} catch (ClassNotFoundException | NoClassDefFoundError e) {
234-
// Do nothing. The class is not in this jar.
235-
}
236-
if (result != null) {
237-
// Class found in this addon's jar, so add it to the global cache.
238-
loader.setClass(name, result);
239-
240-
}
239+
if (result != null) {
240+
// Class found in this addon's jar, so add it to the global cache.
241+
loader.setClass(name, result);
241242
}
242-
// Add the class to the local cache.
243+
}
244+
if (result != null) {
243245
classes.put(name, result);
244246
}
245247
return result;

0 commit comments

Comments
 (0)