Skip to content

Release 3.3.5 #2669

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
2 changes: 2 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
run: mvn -B verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -Dsonar.projectKey=BentoBoxWorld_BentoBox
- name: Debug - List target directory
run: ls -la /home/runner/work/BentoBox/BentoBox/target
- run: mvn --batch-mode clean org.jacoco:jacoco-maven-plugin:prepare-agent install
- run: mkdir staging && cp target/*.jar staging
- name: Save artifacts
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/modrinth-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ jobs:

- name: Build and package with Maven
run: mvn -B clean package -DskipTests -Pmaster --file pom.xml

- name: Debug - List target directory
run: ls -la /home/runner/work/BentoBox/BentoBox/target
- name: Upload to Modrinth
uses: cloudnode-pro/modrinth-publish@v2
with:
Expand Down
35 changes: 32 additions & 3 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@
<!-- Do not change unless you want different name for local builds. -->
<build.number>-LOCAL</build.number>
<!-- This allows to change between versions. -->
<build.version>3.3.4</build.version>
<build.version>3.3.5</build.version>
<sonar.organization>bentobox-world</sonar.organization>
<sonar.host.url>https://sonarcloud.io</sonar.host.url>
<server.jars>${project.basedir}/lib</server.jars>
Expand Down Expand Up @@ -161,6 +161,17 @@
<id>MG-Dev Jenkins CI Maven Repository</id>
<url>https://ci.mg-dev.eu/plugin/repository/everything</url>
</repository>
<!-- Used for Multiverse hook -->
<repository>
<id>multiverse-multiverse-releases</id>
<name>Multiverse Repository</name>
<url>https://repo.onarandombox.com/multiverse-releases</url>
</repository>
<repository>
<id>multiverse-multiverse-snapshots</id>
<name>Multiverse Repository</name>
<url>https://repo.onarandombox.com/multiverse-snapshots</url>
</repository>
<!-- For MythicMobs -->
<repository>
<id>nexus</id>
Expand Down Expand Up @@ -304,11 +315,29 @@
<version>5.3.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.mvplugins.multiverse.core</groupId>
<artifactId>multiverse-core</artifactId>
<version>5.0.0-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.onarandombox.multiversecore</groupId>
<artifactId>multiverse-core</artifactId>
<version>4.3.16</version>
<scope>provided</scope>
</dependency>
<!-- Shaded APIs -->
<!--
<dependency>
<groupId>com.github.TheBusyBiscuit</groupId>
<artifactId>GitHubWebAPI4Java</artifactId>
<version>${githubapi.version}</version>
</dependency>-->
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>com.github.Marcono1234</groupId>
Expand Down Expand Up @@ -512,10 +541,10 @@
<pattern>org.bstats</pattern>
<shadedPattern>world.bentobox.bentobox.util.metrics</shadedPattern>
</relocation>
<relocation>
<!-- <relocation>
<pattern>io.github.TheBusyBiscuit.GitHubWebAPI4Java</pattern>
<shadedPattern>world.bentobox.bentobox.api.github</shadedPattern>
</relocation>
</relocation>-->
<relocation>
<pattern>io.papermc.lib</pattern>
<shadedPattern>world.bentobox.bentobox.paperlib</shadedPattern>
Expand Down
18 changes: 16 additions & 2 deletions src/main/java/world/bentobox/bentobox/BentoBox.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@
import world.bentobox.bentobox.hooks.FancyNpcsHook;
import world.bentobox.bentobox.hooks.ItemsAdderHook;
import world.bentobox.bentobox.hooks.MultipaperHook;
import world.bentobox.bentobox.hooks.MultiverseCoreHook;
import world.bentobox.bentobox.hooks.MultiverseCore4Hook;
import world.bentobox.bentobox.hooks.MultiverseCore5Hook;
import world.bentobox.bentobox.hooks.MyWorldsHook;
import world.bentobox.bentobox.hooks.MythicMobsHook;
import world.bentobox.bentobox.hooks.SlimefunHook;
Expand Down Expand Up @@ -233,7 +234,11 @@ private void completeSetup(long loadTime) {

// Register Multiverse hook - MV loads AFTER BentoBox
// Make sure all worlds are already registered to Multiverse.
hooksManager.registerHook(new MultiverseCoreHook());
if (hasClass("org.mvplugins.multiverse.core.MultiverseCore")) {
hooksManager.registerHook(new MultiverseCore5Hook());
} else if (hasClass("com.onarandombox.MultiverseCore.MultiverseCore")) {
hooksManager.registerHook(new MultiverseCore4Hook());
}
hooksManager.registerHook(new MyWorldsHook());
islandWorldManager.registerWorldsToMultiverse(true);

Expand Down Expand Up @@ -281,6 +286,15 @@ private void completeSetup(long loadTime) {
}
}

private boolean hasClass(String className) {
try {
Class.forName(className);
return true;
} catch (ClassNotFoundException e) {
return false;
}
}

private void fireCriticalError(String message, String error) {
logError("*****************CRITICAL ERROR!******************");
logError(message);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
import world.bentobox.bentobox.api.commands.CompositeCommand;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.database.objects.Island;
import world.bentobox.bentobox.util.Util;

/**
* @author Poslovitch
Expand All @@ -24,9 +23,8 @@ public class AdminRangeDisplayCommand extends CompositeCommand {
private static final String DISPLAY = "display";
private static final String SHOW = "show";
private static final String HIDE = "hide";
public static final Particle PARTICLE = Util.findFirstMatchingEnum(Particle.class, "REDSTONE", "DUST");
private static final Particle PARTICLE2 = Util.findFirstMatchingEnum(Particle.class, "VILLAGER_HAPPY",
"HAPPY_VILLAGER");
public static final Particle PARTICLE = Particle.DUST;
private static final Particle PARTICLE2 = Particle.DUST;

// Map of users to which ranges must be displayed
private final Map<User, Integer> displayRanges = new HashMap<>();
Expand Down Expand Up @@ -80,7 +78,8 @@ private void showZones(User user) {

// Draw the default protected area if island protected zone is different
if (island.getProtectionRange() != getPlugin().getIWM().getIslandProtectionRange(getWorld())) {
drawZone(user, PARTICLE2, null, island, getPlugin().getIWM().getIslandProtectionRange(getWorld()));
drawZone(user, PARTICLE2, new Particle.DustOptions(Color.GREEN, 1.0F), island,
getPlugin().getIWM().getIslandProtectionRange(getWorld()));
}

// Draw the island area
Expand Down
87 changes: 87 additions & 0 deletions src/main/java/world/bentobox/bentobox/api/github/GitHubWebAPI.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package world.bentobox.bentobox.api.github;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Scanner;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

import world.bentobox.bentobox.api.github.objects.repositories.GitHubRepository;

/**
* Handles interactions with the GitHub API.
* This is a rewrite of {@link https://github.com/Poslovitch/GitHubWebAPI4}, which is now out of date
* and this code only implements parts that are used by BentoBox and not all of it.
*/
public class GitHubWebAPI {

private static final String API_BASE_URL = "https://api.github.com/";
private static final long RATE_LIMIT_INTERVAL_MS = 1000; // 1 second
private static long lastRequestTime = 0;

private final ExecutorService executor = Executors.newCachedThreadPool();

/**
* Fetches the content of a given API endpoint.
*
* @param endpoint The API endpoint to fetch.
* @return The JSON response as a JsonObject.
* @throws IOException If an error occurs during the request.
*/
public synchronized JsonObject fetch(String endpoint) throws IOException {
long currentTime = System.currentTimeMillis();
long timeSinceLastRequest = currentTime - lastRequestTime;

if (timeSinceLastRequest < RATE_LIMIT_INTERVAL_MS) {
try {
Thread.sleep(RATE_LIMIT_INTERVAL_MS - timeSinceLastRequest);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new IOException("Thread interrupted while waiting for rate limit", e);
}
}

lastRequestTime = System.currentTimeMillis();

URL url = new URL(API_BASE_URL + endpoint);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setRequestProperty("Accept", "application/vnd.github.v3+json");
connection.setRequestProperty("User-Agent", "BentoBox"); // Add User-Agent header

int responseCode = connection.getResponseCode();
if (responseCode == 403) {
throw new IOException("GitHub API rate limit exceeded or access forbidden. Response code: " + responseCode);
}

try (Scanner scanner = new Scanner(connection.getInputStream())) {
String response = scanner.useDelimiter("\\A").next();
return JsonParser.parseString(response).getAsJsonObject();
}
}

/**
* Fetches the content of a given API endpoint asynchronously.
*
* @param endpoint The API endpoint to fetch.
* @return A CompletableFuture containing the JSON response as a JsonObject.
*/
public CompletableFuture<JsonObject> fetchAsync(String endpoint) {
return CompletableFuture.supplyAsync(() -> {
try {
return fetch(endpoint);
} catch (IOException e) {
throw new RuntimeException("Failed to fetch data from GitHub API", e);
}
}, executor);
}

public GitHubRepository getRepository(String username, String repo) {
return new GitHubRepository(this, username + "/" + repo);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package world.bentobox.bentobox.api.github.objects.repositories;

/**
* Represents a contributor to a GitHub repository.
*/
public class GitHubContributor {

private final String username;
private final int contributionsAmount;

public GitHubContributor(String username, int contributionsAmount) {
this.username = username;
this.contributionsAmount = contributionsAmount;
}

public String getUsername() {
return username;
}

public int getContributionsAmount() {
return contributionsAmount;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package world.bentobox.bentobox.api.github.objects.repositories;

import java.io.IOException;

import com.google.gson.JsonObject;

import world.bentobox.bentobox.api.github.GitHubWebAPI;

/**
* Represents a file or a directory.
*/
public class GitHubFile {

private final GitHubWebAPI api;
private final String path;

public GitHubFile(GitHubWebAPI api, GitHubRepository gitHubRepository, String fullpath) {
this.api = api;
this.path = "repos/" + gitHubRepository.getFullName() + fullpath;
}

/**
* Returns the content of this file.
* @return the content of this file in Base64 or nothing if the connection to the GitHub API could not be established.
* @throws IOException - If an error occurs during the request.
*/
public String getContent() throws IllegalAccessException {
JsonObject response;
try {
response = api.fetch(path);
} catch (IOException e) {
// Cannot get a connection for some reason
return "";
}
return response.get("content").getAsString();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package world.bentobox.bentobox.api.github.objects.repositories;

import java.util.ArrayList;
import java.util.List;

import com.google.gson.JsonArray;
import com.google.gson.JsonObject;

import world.bentobox.bentobox.api.github.GitHubWebAPI;

/**
* Represents a GitHub repository and provides methods to fetch its data.
*/
public class GitHubRepository {

private final GitHubWebAPI api;
private final String fullName;

public GitHubRepository(GitHubWebAPI api, String fullName) {
this.api = api;
this.fullName = fullName;
}

public String getFullName() {
return fullName;
}

/**
* Fetches the content of a file in the repository.
*
* @param fpath The path to the file.
* @return A GitHubFile object representing the file content.
* @throws Exception If an error occurs during the request.
*/
public GitHubFile getContent(String path) throws Exception {
return new GitHubFile(api, this, "/contents/" + path);
}

/**
* Fetches the list of contributors to the repository.
*
* @return A list of GitHubContributor objects.
* @throws Exception If an error occurs during the request.
*/
public List<GitHubContributor> getContributors() throws Exception {
JsonArray response = api.fetch("repos/" + fullName + "/contributors").getAsJsonArray();
List<GitHubContributor> contributors = new ArrayList<>();
response.forEach(element -> {
JsonObject contributor = element.getAsJsonObject();
contributors.add(new GitHubContributor(
contributor.get("login").getAsString(),
contributor.get("contributions").getAsInt()
));
});
return contributors;
}
}
7 changes: 5 additions & 2 deletions src/main/java/world/bentobox/bentobox/api/user/User.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import org.apache.commons.lang.math.NumberUtils;
import org.bukkit.Bukkit;
Expand Down Expand Up @@ -823,8 +824,10 @@ public boolean inWorld() {
*/
public void spawnParticle(Particle particle, @Nullable Object dustOptions, double x, double y, double z) {
Class<?> expectedClass = VALIDATION_CHECK.get(particle);
if (expectedClass == null)
throw new IllegalArgumentException("Unexpected value: " + particle);
if (expectedClass == null) {
throw new IllegalArgumentException("Unexpected value: " + particle + "\nExpected one of:"
+ VALIDATION_CHECK.keySet().stream().map(Particle::name).collect(Collectors.joining(", ")));
}

if (!(expectedClass.isInstance(dustOptions))) {
throw new IllegalArgumentException("A non-null " + expectedClass.getSimpleName()
Expand Down
Loading