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
11 changes: 11 additions & 0 deletions pom.xml
Original file line numberDiff line numberDiff line change
Expand Up@@ -124,6 +124,10 @@
<id>vault-repo</id>
<url>http://nexus.hc.to/content/repositories/pub_releases</url>
</repository>
<repository>
<id>matteodev</id>
<url>https://maven.devs.beer/</url>
</repository>
</repositories>

<!-- Your addon must contain Spigot and BentoBox APIs dependencies. -->
Expand All@@ -147,6 +151,13 @@
<artifactId>annotations</artifactId>
<version>18.0.0</version>
</dependency>

<dependency>
<groupId>dev.lone</groupId>
<artifactId>api-itemsadder</artifactId>
<version>4.0.10</version>
<scope>provided</scope>
</dependency>
</dependencies>

<!-- Build contains information for maven. It allows to create correct
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -33,6 +33,7 @@
import world.bentobox.controlpanel.database.objects.ControlPanelObject.ControlPanelButton;
import world.bentobox.controlpanel.panels.GuiUtils;
import world.bentobox.controlpanel.utils.Constants;
import world.bentobox.controlpanel.utils.ItemsAdderParse;
import world.bentobox.controlpanel.utils.Utils;


Expand DownExpand Up@@ -247,7 +248,6 @@ public void importControlPanels(@Nullable User user, @NotNull GameModeAddon addo
* @param user - user
* @param gameModeName - gamemode name where ControlPanels must be imported.
* @param fileName Specifies from which file control panel will be loaded
* @return true if successful
*/
private void importControlPanels(@Nullable User user, String gameModeName, @NotNull String fileName)
{
Expand DownExpand Up@@ -356,48 +356,53 @@ private void readControlPanel(YamlConfiguration config, @Nullable User user, fin
if (buttonListSection != null)
{
buttonListSection.getKeys(false).forEach(slotReference -> {
ControlPanelButton button = new ControlPanelButton();
button.setSlot(Integer.parseInt(slotReference));
for (int slotNum : Utils.readIntArray(List.of(slotReference))) {
ControlPanelButton button = new ControlPanelButton();
button.setSlot(slotNum);

ConfigurationSection buttonSection =
buttonListSection.getConfigurationSection(slotReference);
ConfigurationSection buttonSection =
buttonListSection.getConfigurationSection(slotReference);

if (buttonSection != null)
{
button.setName(buttonSection.getString("name"));
button.setCommand(buttonSection.getString("command", "[user_command]"));

// Create empty list
button.setDescriptionLines(new ArrayList<>());

if (buttonSection.isList("description"))
{
// Read description by each line
buttonSection.getStringList("description").forEach(line ->
button.getDescriptionLines().add(
line.replace("[gamemode]", gameMode.toLowerCase())));
}
else if (buttonSection.isString("description"))
if (buttonSection != null)
{
// Check if description is not defined as simple string
String input = buttonSection.getString("description", "");
button.setName(buttonSection.getString("name"));
button.setCommand(buttonSection.getString("command", "[user_command]"));

if (input != null && !input.isEmpty())
// Create empty list
button.setDescriptionLines(new ArrayList<>());

if (buttonSection.isList("description"))
{
button.getDescriptionLines().add(
input.replace("[gamemode]", gameMode.toLowerCase()));
// Read description by each line
buttonSection.getStringList("description").forEach(line ->
button.getDescriptionLines().add(
line.replace("[gamemode]", gameMode.toLowerCase())));
}
else if (buttonSection.isString("description"))
{
// Check if description is not defined as simple string
String input = buttonSection.getString("description", "");

if (!input.isEmpty())
{
button.getDescriptionLines().add(
input.replace("[gamemode]", gameMode.toLowerCase()));
}
}
else
{
this.addon.logWarning("Description for button "
+ button.getSlot() + " could not be read.");
}
}
else
{
this.addon.logWarning("Description for button " +
+ button.getSlot() + " could not be read.");
}

button.setMaterial(Material.matchMaterial(buttonSection.getString("material", "GRASS")));
button.setIcon(ItemParser.parse("icon", new ItemStack(Material.PAPER)));
button.setMaterial(Material.matchMaterial(buttonSection.getString("material", "GRASS")));
if(buttonSection.getString("icon") != null)
button.setIcon(ItemParser.parse(buttonSection.getString("icon"), new ItemStack(Material.PAPER)));
if(buttonSection.getString("itemsadder") != null)
button.setIcon(ItemsAdderParse.parse(buttonSection.getString("itemsadder")));

buttonList.add(button);
buttonList.add(button);
}
}
});
}
Expand DownExpand Up@@ -501,15 +506,15 @@ public ControlPanelObject getUserControlPanel(User user, World world, String per
/**
* Control Panel Addon instance.
*/
private ControlPanelAddon addon;
private final ControlPanelAddon addon;

/**
* This database allows to access to all stored control panels.
*/
private Database<ControlPanelObject> controlPanelDatabase;
private final Database<ControlPanelObject> controlPanelDatabase;

/**
* This map contains all control panel object linked to their reference game mode.
*/
private Map<String, ControlPanelObject> controlPanelCache;
private final Map<String, ControlPanelObject> controlPanelCache;
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
package world.bentobox.controlpanel.utils;

import dev.lone.itemsadder.api.CustomStack;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;

public class ItemsAdderParse {
public static ItemStack parse(String string, ItemStack itemStack)
{
if(!Bukkit.getServer().getPluginManager().isPluginEnabled("ItemsAdder")) return itemStack;
CustomStack stack = CustomStack.getInstance(string);
if(stack != null) return stack.getItemStack();
return itemStack;
}
public static ItemStack parse(String string)
{
return parse(string, new ItemStack(Material.PAPER));
}
}
60 changes: 60 additions & 0 deletions src/main/java/world/bentobox/controlpanel/utils/Utils.java
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,8 +9,11 @@

import org.bukkit.World;
import org.bukkit.permissions.PermissionAttachmentInfo;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.api.addons.GameModeAddon;
Expand DownExpand Up@@ -143,4 +146,61 @@ public static <T> T getPreviousValue(T[] values, T currentValue)

return currentValue;
}

/**
* Reads a list of objects and converts it into an array of integers.
* <p>
* The method processes each element in the list:
* <ul>
* <li>If the element is an Integer, it adds it directly to the result array.</li>
* <li>If the element is a String in the format "start-end", it adds all integers
* from "start" to "end" (inclusive) to the result array.</li>
* </ul>
*
* <b>Example:</b>
* If the input list is `["1-3", 5, "7-9"]`, the method will return an array
* containing `[1, 2, 3, 5, 7, 8, 9]`.
*
* @param objectList A list of objects, each of which can either be an Integer or a String
* in the format "start-end" (inclusive range).
* @return An array of integers containing all the integers parsed from the input list.
* The integers from ranges are added to the result array in order.
* @throws NumberFormatException If the string representation of a number is not valid.
*/
public static int[] readIntArray(List<?> objectList) {
List<Integer> values = new ArrayList<>();

// Process each item in the objectList
for (Object o : objectList) {
// If the object is an Integer, add it directly to values
if (o instanceof Integer) {
values.add((int) o);
}
// If the object is a String in the form "start-end"
else if (o instanceof String) {
try {
int n = Integer.parseInt((String) o);
values.add(n);
}catch (NumberFormatException ignored) {}
String[] args = ((String) o).split("-");
if (args.length >= 2) {
try {
int n0 = Integer.parseInt(args[0]);
int n1 = Integer.parseInt(args[1]) + 1; // Add 1 to include the upper bound
// Add all integers in the range [n0, n1)
for (int n : IntStream.range(n0, n1).toArray()) {
values.add(n);
}
continue;
} catch (NumberFormatException e) {
// Handle invalid number format if necessary
throw new NumberFormatException("Invalid number format in range string: " + o);
}
}
}
}

// Convert List<Integer> to a primitive int array and return it
return values.stream().mapToInt(Integer::intValue).toArray();
}
}
2 changes: 1 addition & 1 deletion src/main/resources/addon.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -19,7 +19,7 @@ authors:
- BONNe

# Soft dependencies of current addon.
softdepend: AcidIsland, BSkyBlock, CaveBlock, SkyGrid, AOneBlock
softdepend: AcidIsland, BSkyBlock, CaveBlock, SkyGrid, AOneBlock, ItemsAdder

# List of addon permissions
permissions:
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
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
11 changes: 11 additions & 0 deletions pom.xml
Original file line numberDiff line numberDiff line change
Expand Up@@ -124,6 +124,10 @@
<id>vault-repo</id>
<url>http://nexus.hc.to/content/repositories/pub_releases</url>
</repository>
<repository>
<id>matteodev</id>
<url>https://maven.devs.beer/</url>
</repository>
</repositories>

<!-- Your addon must contain Spigot and BentoBox APIs dependencies. -->
Expand All@@ -147,6 +151,13 @@
<artifactId>annotations</artifactId>
<version>18.0.0</version>
</dependency>

<dependency>
<groupId>dev.lone</groupId>
<artifactId>api-itemsadder</artifactId>
<version>4.0.10</version>
<scope>provided</scope>
</dependency>
</dependencies>

<!-- Build contains information for maven. It allows to create correct
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -33,6 +33,7 @@
import world.bentobox.controlpanel.database.objects.ControlPanelObject.ControlPanelButton;
import world.bentobox.controlpanel.panels.GuiUtils;
import world.bentobox.controlpanel.utils.Constants;
import world.bentobox.controlpanel.utils.ItemsAdderParse;
import world.bentobox.controlpanel.utils.Utils;


Expand DownExpand Up@@ -247,7 +248,6 @@ public void importControlPanels(@Nullable User user, @NotNull GameModeAddon addo
* @param user - user
* @param gameModeName - gamemode name where ControlPanels must be imported.
* @param fileName Specifies from which file control panel will be loaded
* @return true if successful
*/
private void importControlPanels(@Nullable User user, String gameModeName, @NotNull String fileName)
{
Expand DownExpand Up@@ -356,48 +356,53 @@ private void readControlPanel(YamlConfiguration config, @Nullable User user, fin
if (buttonListSection != null)
{
buttonListSection.getKeys(false).forEach(slotReference -> {
ControlPanelButton button = new ControlPanelButton();
button.setSlot(Integer.parseInt(slotReference));
for (int slotNum : Utils.readIntArray(List.of(slotReference))) {
ControlPanelButton button = new ControlPanelButton();
button.setSlot(slotNum);

ConfigurationSection buttonSection =
buttonListSection.getConfigurationSection(slotReference);
ConfigurationSection buttonSection =
buttonListSection.getConfigurationSection(slotReference);

if (buttonSection != null)
{
button.setName(buttonSection.getString("name"));
button.setCommand(buttonSection.getString("command", "[user_command]"));

// Create empty list
button.setDescriptionLines(new ArrayList<>());

if (buttonSection.isList("description"))
{
// Read description by each line
buttonSection.getStringList("description").forEach(line ->
button.getDescriptionLines().add(
line.replace("[gamemode]", gameMode.toLowerCase())));
}
else if (buttonSection.isString("description"))
if (buttonSection != null)
{
// Check if description is not defined as simple string
String input = buttonSection.getString("description", "");
button.setName(buttonSection.getString("name"));
button.setCommand(buttonSection.getString("command", "[user_command]"));

if (input != null && !input.isEmpty())
// Create empty list
button.setDescriptionLines(new ArrayList<>());

if (buttonSection.isList("description"))
{
button.getDescriptionLines().add(
input.replace("[gamemode]", gameMode.toLowerCase()));
// Read description by each line
buttonSection.getStringList("description").forEach(line ->
button.getDescriptionLines().add(
line.replace("[gamemode]", gameMode.toLowerCase())));
}
else if (buttonSection.isString("description"))
{
// Check if description is not defined as simple string
String input = buttonSection.getString("description", "");

if (!input.isEmpty())
{
button.getDescriptionLines().add(
input.replace("[gamemode]", gameMode.toLowerCase()));
}
}
else
{
this.addon.logWarning("Description for button "
+ button.getSlot() + " could not be read.");
}
}
else
{
this.addon.logWarning("Description for button " +
+ button.getSlot() + " could not be read.");
}

button.setMaterial(Material.matchMaterial(buttonSection.getString("material", "GRASS")));
button.setIcon(ItemParser.parse("icon", new ItemStack(Material.PAPER)));
button.setMaterial(Material.matchMaterial(buttonSection.getString("material", "GRASS")));
if(buttonSection.getString("icon") != null)
button.setIcon(ItemParser.parse(buttonSection.getString("icon"), new ItemStack(Material.PAPER)));
if(buttonSection.getString("itemsadder") != null)
button.setIcon(ItemsAdderParse.parse(buttonSection.getString("itemsadder")));

buttonList.add(button);
buttonList.add(button);
}
}
});
}
Expand DownExpand Up@@ -501,15 +506,15 @@ public ControlPanelObject getUserControlPanel(User user, World world, String per
/**
* Control Panel Addon instance.
*/
private ControlPanelAddon addon;
private final ControlPanelAddon addon;

/**
* This database allows to access to all stored control panels.
*/
private Database<ControlPanelObject> controlPanelDatabase;
private final Database<ControlPanelObject> controlPanelDatabase;

/**
* This map contains all control panel object linked to their reference game mode.
*/
private Map<String, ControlPanelObject> controlPanelCache;
private final Map<String, ControlPanelObject> controlPanelCache;
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
package world.bentobox.controlpanel.utils;

import dev.lone.itemsadder.api.CustomStack;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;

public class ItemsAdderParse {
public static ItemStack parse(String string, ItemStack itemStack)
{
if(!Bukkit.getServer().getPluginManager().isPluginEnabled("ItemsAdder")) return itemStack;
CustomStack stack = CustomStack.getInstance(string);
if(stack != null) return stack.getItemStack();
return itemStack;
}
public static ItemStack parse(String string)
{
return parse(string, new ItemStack(Material.PAPER));
}
}
60 changes: 60 additions & 0 deletions src/main/java/world/bentobox/controlpanel/utils/Utils.java
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,8 +9,11 @@

import org.bukkit.World;
import org.bukkit.permissions.PermissionAttachmentInfo;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.api.addons.GameModeAddon;
Expand DownExpand Up@@ -143,4 +146,61 @@ public static <T> T getPreviousValue(T[] values, T currentValue)

return currentValue;
}

/**
* Reads a list of objects and converts it into an array of integers.
* <p>
* The method processes each element in the list:
* <ul>
* <li>If the element is an Integer, it adds it directly to the result array.</li>
* <li>If the element is a String in the format "start-end", it adds all integers
* from "start" to "end" (inclusive) to the result array.</li>
* </ul>
*
* <b>Example:</b>
* If the input list is `["1-3", 5, "7-9"]`, the method will return an array
* containing `[1, 2, 3, 5, 7, 8, 9]`.
*
* @param objectList A list of objects, each of which can either be an Integer or a String
* in the format "start-end" (inclusive range).
* @return An array of integers containing all the integers parsed from the input list.
* The integers from ranges are added to the result array in order.
* @throws NumberFormatException If the string representation of a number is not valid.
*/
public static int[] readIntArray(List<?> objectList) {
List<Integer> values = new ArrayList<>();

// Process each item in the objectList
for (Object o : objectList) {
// If the object is an Integer, add it directly to values
if (o instanceof Integer) {
values.add((int) o);
}
// If the object is a String in the form "start-end"
else if (o instanceof String) {
try {
int n = Integer.parseInt((String) o);
values.add(n);
}catch (NumberFormatException ignored) {}
String[] args = ((String) o).split("-");
if (args.length >= 2) {
try {
int n0 = Integer.parseInt(args[0]);
int n1 = Integer.parseInt(args[1]) + 1; // Add 1 to include the upper bound
// Add all integers in the range [n0, n1)
for (int n : IntStream.range(n0, n1).toArray()) {
values.add(n);
}
continue;
} catch (NumberFormatException e) {
// Handle invalid number format if necessary
throw new NumberFormatException("Invalid number format in range string: " + o);
}
}
}
}

// Convert List<Integer> to a primitive int array and return it
return values.stream().mapToInt(Integer::intValue).toArray();
}
}
2 changes: 1 addition & 1 deletion src/main/resources/addon.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -19,7 +19,7 @@ authors:
- BONNe

# Soft dependencies of current addon.
softdepend: AcidIsland, BSkyBlock, CaveBlock, SkyGrid, AOneBlock
softdepend: AcidIsland, BSkyBlock, CaveBlock, SkyGrid, AOneBlock, ItemsAdder

# List of addon permissions
permissions:
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
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
11 changes: 11 additions & 0 deletions pom.xml
Original file line numberDiff line numberDiff line change
Expand Up@@ -124,6 +124,10 @@
<id>vault-repo</id>
<url>http://nexus.hc.to/content/repositories/pub_releases</url>
</repository>
<repository>
<id>matteodev</id>
<url>https://maven.devs.beer/</url>
</repository>
</repositories>

<!-- Your addon must contain Spigot and BentoBox APIs dependencies. -->
Expand All@@ -147,6 +151,13 @@
<artifactId>annotations</artifactId>
<version>18.0.0</version>
</dependency>

<dependency>
<groupId>dev.lone</groupId>
<artifactId>api-itemsadder</artifactId>
<version>4.0.10</version>
<scope>provided</scope>
</dependency>
</dependencies>

<!-- Build contains information for maven. It allows to create correct
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -33,6 +33,7 @@
import world.bentobox.controlpanel.database.objects.ControlPanelObject.ControlPanelButton;
import world.bentobox.controlpanel.panels.GuiUtils;
import world.bentobox.controlpanel.utils.Constants;
import world.bentobox.controlpanel.utils.ItemsAdderParse;
import world.bentobox.controlpanel.utils.Utils;


Expand DownExpand Up@@ -247,7 +248,6 @@ public void importControlPanels(@Nullable User user, @NotNull GameModeAddon addo
* @param user - user
* @param gameModeName - gamemode name where ControlPanels must be imported.
* @param fileName Specifies from which file control panel will be loaded
* @return true if successful
*/
private void importControlPanels(@Nullable User user, String gameModeName, @NotNull String fileName)
{
Expand DownExpand Up@@ -356,48 +356,53 @@ private void readControlPanel(YamlConfiguration config, @Nullable User user, fin
if (buttonListSection != null)
{
buttonListSection.getKeys(false).forEach(slotReference -> {
ControlPanelButton button = new ControlPanelButton();
button.setSlot(Integer.parseInt(slotReference));
for (int slotNum : Utils.readIntArray(List.of(slotReference))) {
ControlPanelButton button = new ControlPanelButton();
button.setSlot(slotNum);

ConfigurationSection buttonSection =
buttonListSection.getConfigurationSection(slotReference);
ConfigurationSection buttonSection =
buttonListSection.getConfigurationSection(slotReference);

if (buttonSection != null)
{
button.setName(buttonSection.getString("name"));
button.setCommand(buttonSection.getString("command", "[user_command]"));

// Create empty list
button.setDescriptionLines(new ArrayList<>());

if (buttonSection.isList("description"))
{
// Read description by each line
buttonSection.getStringList("description").forEach(line ->
button.getDescriptionLines().add(
line.replace("[gamemode]", gameMode.toLowerCase())));
}
else if (buttonSection.isString("description"))
if (buttonSection != null)
{
// Check if description is not defined as simple string
String input = buttonSection.getString("description", "");
button.setName(buttonSection.getString("name"));
button.setCommand(buttonSection.getString("command", "[user_command]"));

if (input != null && !input.isEmpty())
// Create empty list
button.setDescriptionLines(new ArrayList<>());

if (buttonSection.isList("description"))
{
button.getDescriptionLines().add(
input.replace("[gamemode]", gameMode.toLowerCase()));
// Read description by each line
buttonSection.getStringList("description").forEach(line ->
button.getDescriptionLines().add(
line.replace("[gamemode]", gameMode.toLowerCase())));
}
else if (buttonSection.isString("description"))
{
// Check if description is not defined as simple string
String input = buttonSection.getString("description", "");

if (!input.isEmpty())
{
button.getDescriptionLines().add(
input.replace("[gamemode]", gameMode.toLowerCase()));
}
}
else
{
this.addon.logWarning("Description for button "
+ button.getSlot() + " could not be read.");
}
}
else
{
this.addon.logWarning("Description for button " +
+ button.getSlot() + " could not be read.");
}

button.setMaterial(Material.matchMaterial(buttonSection.getString("material", "GRASS")));
button.setIcon(ItemParser.parse("icon", new ItemStack(Material.PAPER)));
button.setMaterial(Material.matchMaterial(buttonSection.getString("material", "GRASS")));
if(buttonSection.getString("icon") != null)
button.setIcon(ItemParser.parse(buttonSection.getString("icon"), new ItemStack(Material.PAPER)));
if(buttonSection.getString("itemsadder") != null)
button.setIcon(ItemsAdderParse.parse(buttonSection.getString("itemsadder")));

buttonList.add(button);
buttonList.add(button);
}
}
});
}
Expand DownExpand Up@@ -501,15 +506,15 @@ public ControlPanelObject getUserControlPanel(User user, World world, String per
/**
* Control Panel Addon instance.
*/
private ControlPanelAddon addon;
private final ControlPanelAddon addon;

/**
* This database allows to access to all stored control panels.
*/
private Database<ControlPanelObject> controlPanelDatabase;
private final Database<ControlPanelObject> controlPanelDatabase;

/**
* This map contains all control panel object linked to their reference game mode.
*/
private Map<String, ControlPanelObject> controlPanelCache;
private final Map<String, ControlPanelObject> controlPanelCache;
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
package world.bentobox.controlpanel.utils;

import dev.lone.itemsadder.api.CustomStack;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;

public class ItemsAdderParse {
public static ItemStack parse(String string, ItemStack itemStack)
{
if(!Bukkit.getServer().getPluginManager().isPluginEnabled("ItemsAdder")) return itemStack;
CustomStack stack = CustomStack.getInstance(string);
if(stack != null) return stack.getItemStack();
return itemStack;
}
public static ItemStack parse(String string)
{
return parse(string, new ItemStack(Material.PAPER));
}
}
60 changes: 60 additions & 0 deletions src/main/java/world/bentobox/controlpanel/utils/Utils.java
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,8 +9,11 @@

import org.bukkit.World;
import org.bukkit.permissions.PermissionAttachmentInfo;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.api.addons.GameModeAddon;
Expand DownExpand Up@@ -143,4 +146,61 @@ public static <T> T getPreviousValue(T[] values, T currentValue)

return currentValue;
}

/**
* Reads a list of objects and converts it into an array of integers.
* <p>
* The method processes each element in the list:
* <ul>
* <li>If the element is an Integer, it adds it directly to the result array.</li>
* <li>If the element is a String in the format "start-end", it adds all integers
* from "start" to "end" (inclusive) to the result array.</li>
* </ul>
*
* <b>Example:</b>
* If the input list is `["1-3", 5, "7-9"]`, the method will return an array
* containing `[1, 2, 3, 5, 7, 8, 9]`.
*
* @param objectList A list of objects, each of which can either be an Integer or a String
* in the format "start-end" (inclusive range).
* @return An array of integers containing all the integers parsed from the input list.
* The integers from ranges are added to the result array in order.
* @throws NumberFormatException If the string representation of a number is not valid.
*/
public static int[] readIntArray(List<?> objectList) {
List<Integer> values = new ArrayList<>();

// Process each item in the objectList
for (Object o : objectList) {
// If the object is an Integer, add it directly to values
if (o instanceof Integer) {
values.add((int) o);
}
// If the object is a String in the form "start-end"
else if (o instanceof String) {
try {
int n = Integer.parseInt((String) o);
values.add(n);
}catch (NumberFormatException ignored) {}
String[] args = ((String) o).split("-");
if (args.length >= 2) {
try {
int n0 = Integer.parseInt(args[0]);
int n1 = Integer.parseInt(args[1]) + 1; // Add 1 to include the upper bound
// Add all integers in the range [n0, n1)
for (int n : IntStream.range(n0, n1).toArray()) {
values.add(n);
}
continue;
} catch (NumberFormatException e) {
// Handle invalid number format if necessary
throw new NumberFormatException("Invalid number format in range string: " + o);
}
}
}
}

// Convert List<Integer> to a primitive int array and return it
return values.stream().mapToInt(Integer::intValue).toArray();
}
}
2 changes: 1 addition & 1 deletion src/main/resources/addon.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -19,7 +19,7 @@ authors:
- BONNe

# Soft dependencies of current addon.
softdepend: AcidIsland, BSkyBlock, CaveBlock, SkyGrid, AOneBlock
softdepend: AcidIsland, BSkyBlock, CaveBlock, SkyGrid, AOneBlock, ItemsAdder

# List of addon permissions
permissions:
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
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
11 changes: 11 additions & 0 deletions pom.xml
Original file line numberDiff line numberDiff line change
Expand Up@@ -124,6 +124,10 @@
<id>vault-repo</id>
<url>http://nexus.hc.to/content/repositories/pub_releases</url>
</repository>
<repository>
<id>matteodev</id>
<url>https://maven.devs.beer/</url>
</repository>
</repositories>

<!-- Your addon must contain Spigot and BentoBox APIs dependencies. -->
Expand All@@ -147,6 +151,13 @@
<artifactId>annotations</artifactId>
<version>18.0.0</version>
</dependency>

<dependency>
<groupId>dev.lone</groupId>
<artifactId>api-itemsadder</artifactId>
<version>4.0.10</version>
<scope>provided</scope>
</dependency>
</dependencies>

<!-- Build contains information for maven. It allows to create correct
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -33,6 +33,7 @@
import world.bentobox.controlpanel.database.objects.ControlPanelObject.ControlPanelButton;
import world.bentobox.controlpanel.panels.GuiUtils;
import world.bentobox.controlpanel.utils.Constants;
import world.bentobox.controlpanel.utils.ItemsAdderParse;
import world.bentobox.controlpanel.utils.Utils;


Expand DownExpand Up@@ -247,7 +248,6 @@ public void importControlPanels(@Nullable User user, @NotNull GameModeAddon addo
* @param user - user
* @param gameModeName - gamemode name where ControlPanels must be imported.
* @param fileName Specifies from which file control panel will be loaded
* @return true if successful
*/
private void importControlPanels(@Nullable User user, String gameModeName, @NotNull String fileName)
{
Expand DownExpand Up@@ -356,48 +356,53 @@ private void readControlPanel(YamlConfiguration config, @Nullable User user, fin
if (buttonListSection != null)
{
buttonListSection.getKeys(false).forEach(slotReference -> {
ControlPanelButton button = new ControlPanelButton();
button.setSlot(Integer.parseInt(slotReference));
for (int slotNum : Utils.readIntArray(List.of(slotReference))) {
ControlPanelButton button = new ControlPanelButton();
button.setSlot(slotNum);

ConfigurationSection buttonSection =
buttonListSection.getConfigurationSection(slotReference);
ConfigurationSection buttonSection =
buttonListSection.getConfigurationSection(slotReference);

if (buttonSection != null)
{
button.setName(buttonSection.getString("name"));
button.setCommand(buttonSection.getString("command", "[user_command]"));

// Create empty list
button.setDescriptionLines(new ArrayList<>());

if (buttonSection.isList("description"))
{
// Read description by each line
buttonSection.getStringList("description").forEach(line ->
button.getDescriptionLines().add(
line.replace("[gamemode]", gameMode.toLowerCase())));
}
else if (buttonSection.isString("description"))
if (buttonSection != null)
{
// Check if description is not defined as simple string
String input = buttonSection.getString("description", "");
button.setName(buttonSection.getString("name"));
button.setCommand(buttonSection.getString("command", "[user_command]"));

if (input != null && !input.isEmpty())
// Create empty list
button.setDescriptionLines(new ArrayList<>());

if (buttonSection.isList("description"))
{
button.getDescriptionLines().add(
input.replace("[gamemode]", gameMode.toLowerCase()));
// Read description by each line
buttonSection.getStringList("description").forEach(line ->
button.getDescriptionLines().add(
line.replace("[gamemode]", gameMode.toLowerCase())));
}
else if (buttonSection.isString("description"))
{
// Check if description is not defined as simple string
String input = buttonSection.getString("description", "");

if (!input.isEmpty())
{
button.getDescriptionLines().add(
input.replace("[gamemode]", gameMode.toLowerCase()));
}
}
else
{
this.addon.logWarning("Description for button "
+ button.getSlot() + " could not be read.");
}
}
else
{
this.addon.logWarning("Description for button " +
+ button.getSlot() + " could not be read.");
}

button.setMaterial(Material.matchMaterial(buttonSection.getString("material", "GRASS")));
button.setIcon(ItemParser.parse("icon", new ItemStack(Material.PAPER)));
button.setMaterial(Material.matchMaterial(buttonSection.getString("material", "GRASS")));
if(buttonSection.getString("icon") != null)
button.setIcon(ItemParser.parse(buttonSection.getString("icon"), new ItemStack(Material.PAPER)));
if(buttonSection.getString("itemsadder") != null)
button.setIcon(ItemsAdderParse.parse(buttonSection.getString("itemsadder")));

buttonList.add(button);
buttonList.add(button);
}
}
});
}
Expand DownExpand Up@@ -501,15 +506,15 @@ public ControlPanelObject getUserControlPanel(User user, World world, String per
/**
* Control Panel Addon instance.
*/
private ControlPanelAddon addon;
private final ControlPanelAddon addon;

/**
* This database allows to access to all stored control panels.
*/
private Database<ControlPanelObject> controlPanelDatabase;
private final Database<ControlPanelObject> controlPanelDatabase;

/**
* This map contains all control panel object linked to their reference game mode.
*/
private Map<String, ControlPanelObject> controlPanelCache;
private final Map<String, ControlPanelObject> controlPanelCache;
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
package world.bentobox.controlpanel.utils;

import dev.lone.itemsadder.api.CustomStack;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;

public class ItemsAdderParse {
public static ItemStack parse(String string, ItemStack itemStack)
{
if(!Bukkit.getServer().getPluginManager().isPluginEnabled("ItemsAdder")) return itemStack;
CustomStack stack = CustomStack.getInstance(string);
if(stack != null) return stack.getItemStack();
return itemStack;
}
public static ItemStack parse(String string)
{
return parse(string, new ItemStack(Material.PAPER));
}
}
60 changes: 60 additions & 0 deletions src/main/java/world/bentobox/controlpanel/utils/Utils.java
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,8 +9,11 @@

import org.bukkit.World;
import org.bukkit.permissions.PermissionAttachmentInfo;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.api.addons.GameModeAddon;
Expand DownExpand Up@@ -143,4 +146,61 @@ public static <T> T getPreviousValue(T[] values, T currentValue)

return currentValue;
}

/**
* Reads a list of objects and converts it into an array of integers.
* <p>
* The method processes each element in the list:
* <ul>
* <li>If the element is an Integer, it adds it directly to the result array.</li>
* <li>If the element is a String in the format "start-end", it adds all integers
* from "start" to "end" (inclusive) to the result array.</li>
* </ul>
*
* <b>Example:</b>
* If the input list is `["1-3", 5, "7-9"]`, the method will return an array
* containing `[1, 2, 3, 5, 7, 8, 9]`.
*
* @param objectList A list of objects, each of which can either be an Integer or a String
* in the format "start-end" (inclusive range).
* @return An array of integers containing all the integers parsed from the input list.
* The integers from ranges are added to the result array in order.
* @throws NumberFormatException If the string representation of a number is not valid.
*/
public static int[] readIntArray(List<?> objectList) {
List<Integer> values = new ArrayList<>();

// Process each item in the objectList
for (Object o : objectList) {
// If the object is an Integer, add it directly to values
if (o instanceof Integer) {
values.add((int) o);
}
// If the object is a String in the form "start-end"
else if (o instanceof String) {
try {
int n = Integer.parseInt((String) o);
values.add(n);
}catch (NumberFormatException ignored) {}
String[] args = ((String) o).split("-");
if (args.length >= 2) {
try {
int n0 = Integer.parseInt(args[0]);
int n1 = Integer.parseInt(args[1]) + 1; // Add 1 to include the upper bound
// Add all integers in the range [n0, n1)
for (int n : IntStream.range(n0, n1).toArray()) {
values.add(n);
}
continue;
} catch (NumberFormatException e) {
// Handle invalid number format if necessary
throw new NumberFormatException("Invalid number format in range string: " + o);
}
}
}
}

// Convert List<Integer> to a primitive int array and return it
return values.stream().mapToInt(Integer::intValue).toArray();
}
}
2 changes: 1 addition & 1 deletion src/main/resources/addon.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -19,7 +19,7 @@ authors:
- BONNe

# Soft dependencies of current addon.
softdepend: AcidIsland, BSkyBlock, CaveBlock, SkyGrid, AOneBlock
softdepend: AcidIsland, BSkyBlock, CaveBlock, SkyGrid, AOneBlock, ItemsAdder

# List of addon permissions
permissions:
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
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
11 changes: 11 additions & 0 deletions pom.xml
Original file line numberDiff line numberDiff line change
Expand Up@@ -124,6 +124,10 @@
<id>vault-repo</id>
<url>http://nexus.hc.to/content/repositories/pub_releases</url>
</repository>
<repository>
<id>matteodev</id>
<url>https://maven.devs.beer/</url>
</repository>
</repositories>

<!-- Your addon must contain Spigot and BentoBox APIs dependencies. -->
Expand All@@ -147,6 +151,13 @@
<artifactId>annotations</artifactId>
<version>18.0.0</version>
</dependency>

<dependency>
<groupId>dev.lone</groupId>
<artifactId>api-itemsadder</artifactId>
<version>4.0.10</version>
<scope>provided</scope>
</dependency>
</dependencies>

<!-- Build contains information for maven. It allows to create correct
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -33,6 +33,7 @@
import world.bentobox.controlpanel.database.objects.ControlPanelObject.ControlPanelButton;
import world.bentobox.controlpanel.panels.GuiUtils;
import world.bentobox.controlpanel.utils.Constants;
import world.bentobox.controlpanel.utils.ItemsAdderParse;
import world.bentobox.controlpanel.utils.Utils;


Expand DownExpand Up@@ -247,7 +248,6 @@ public void importControlPanels(@Nullable User user, @NotNull GameModeAddon addo
* @param user - user
* @param gameModeName - gamemode name where ControlPanels must be imported.
* @param fileName Specifies from which file control panel will be loaded
* @return true if successful
*/
private void importControlPanels(@Nullable User user, String gameModeName, @NotNull String fileName)
{
Expand DownExpand Up@@ -356,48 +356,53 @@ private void readControlPanel(YamlConfiguration config, @Nullable User user, fin
if (buttonListSection != null)
{
buttonListSection.getKeys(false).forEach(slotReference -> {
ControlPanelButton button = new ControlPanelButton();
button.setSlot(Integer.parseInt(slotReference));
for (int slotNum : Utils.readIntArray(List.of(slotReference))) {
ControlPanelButton button = new ControlPanelButton();
button.setSlot(slotNum);

ConfigurationSection buttonSection =
buttonListSection.getConfigurationSection(slotReference);
ConfigurationSection buttonSection =
buttonListSection.getConfigurationSection(slotReference);

if (buttonSection != null)
{
button.setName(buttonSection.getString("name"));
button.setCommand(buttonSection.getString("command", "[user_command]"));

// Create empty list
button.setDescriptionLines(new ArrayList<>());

if (buttonSection.isList("description"))
{
// Read description by each line
buttonSection.getStringList("description").forEach(line ->
button.getDescriptionLines().add(
line.replace("[gamemode]", gameMode.toLowerCase())));
}
else if (buttonSection.isString("description"))
if (buttonSection != null)
{
// Check if description is not defined as simple string
String input = buttonSection.getString("description", "");
button.setName(buttonSection.getString("name"));
button.setCommand(buttonSection.getString("command", "[user_command]"));

if (input != null && !input.isEmpty())
// Create empty list
button.setDescriptionLines(new ArrayList<>());

if (buttonSection.isList("description"))
{
button.getDescriptionLines().add(
input.replace("[gamemode]", gameMode.toLowerCase()));
// Read description by each line
buttonSection.getStringList("description").forEach(line ->
button.getDescriptionLines().add(
line.replace("[gamemode]", gameMode.toLowerCase())));
}
else if (buttonSection.isString("description"))
{
// Check if description is not defined as simple string
String input = buttonSection.getString("description", "");

if (!input.isEmpty())
{
button.getDescriptionLines().add(
input.replace("[gamemode]", gameMode.toLowerCase()));
}
}
else
{
this.addon.logWarning("Description for button "
+ button.getSlot() + " could not be read.");
}
}
else
{
this.addon.logWarning("Description for button " +
+ button.getSlot() + " could not be read.");
}

button.setMaterial(Material.matchMaterial(buttonSection.getString("material", "GRASS")));
button.setIcon(ItemParser.parse("icon", new ItemStack(Material.PAPER)));
button.setMaterial(Material.matchMaterial(buttonSection.getString("material", "GRASS")));
if(buttonSection.getString("icon") != null)
button.setIcon(ItemParser.parse(buttonSection.getString("icon"), new ItemStack(Material.PAPER)));
if(buttonSection.getString("itemsadder") != null)
button.setIcon(ItemsAdderParse.parse(buttonSection.getString("itemsadder")));

buttonList.add(button);
buttonList.add(button);
}
}
});
}
Expand DownExpand Up@@ -501,15 +506,15 @@ public ControlPanelObject getUserControlPanel(User user, World world, String per
/**
* Control Panel Addon instance.
*/
private ControlPanelAddon addon;
private final ControlPanelAddon addon;

/**
* This database allows to access to all stored control panels.
*/
private Database<ControlPanelObject> controlPanelDatabase;
private final Database<ControlPanelObject> controlPanelDatabase;

/**
* This map contains all control panel object linked to their reference game mode.
*/
private Map<String, ControlPanelObject> controlPanelCache;
private final Map<String, ControlPanelObject> controlPanelCache;
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
package world.bentobox.controlpanel.utils;

import dev.lone.itemsadder.api.CustomStack;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;

public class ItemsAdderParse {
public static ItemStack parse(String string, ItemStack itemStack)
{
if(!Bukkit.getServer().getPluginManager().isPluginEnabled("ItemsAdder")) return itemStack;
CustomStack stack = CustomStack.getInstance(string);
if(stack != null) return stack.getItemStack();
return itemStack;
}
public static ItemStack parse(String string)
{
return parse(string, new ItemStack(Material.PAPER));
}
}
60 changes: 60 additions & 0 deletions src/main/java/world/bentobox/controlpanel/utils/Utils.java
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,8 +9,11 @@

import org.bukkit.World;
import org.bukkit.permissions.PermissionAttachmentInfo;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.api.addons.GameModeAddon;
Expand DownExpand Up@@ -143,4 +146,61 @@ public static <T> T getPreviousValue(T[] values, T currentValue)

return currentValue;
}

/**
* Reads a list of objects and converts it into an array of integers.
* <p>
* The method processes each element in the list:
* <ul>
* <li>If the element is an Integer, it adds it directly to the result array.</li>
* <li>If the element is a String in the format "start-end", it adds all integers
* from "start" to "end" (inclusive) to the result array.</li>
* </ul>
*
* <b>Example:</b>
* If the input list is `["1-3", 5, "7-9"]`, the method will return an array
* containing `[1, 2, 3, 5, 7, 8, 9]`.
*
* @param objectList A list of objects, each of which can either be an Integer or a String
* in the format "start-end" (inclusive range).
* @return An array of integers containing all the integers parsed from the input list.
* The integers from ranges are added to the result array in order.
* @throws NumberFormatException If the string representation of a number is not valid.
*/
public static int[] readIntArray(List<?> objectList) {
List<Integer> values = new ArrayList<>();

// Process each item in the objectList
for (Object o : objectList) {
// If the object is an Integer, add it directly to values
if (o instanceof Integer) {
values.add((int) o);
}
// If the object is a String in the form "start-end"
else if (o instanceof String) {
try {
int n = Integer.parseInt((String) o);
values.add(n);
}catch (NumberFormatException ignored) {}
String[] args = ((String) o).split("-");
if (args.length >= 2) {
try {
int n0 = Integer.parseInt(args[0]);
int n1 = Integer.parseInt(args[1]) + 1; // Add 1 to include the upper bound
// Add all integers in the range [n0, n1)
for (int n : IntStream.range(n0, n1).toArray()) {
values.add(n);
}
continue;
} catch (NumberFormatException e) {
// Handle invalid number format if necessary
throw new NumberFormatException("Invalid number format in range string: " + o);
}
}
}
}

// Convert List<Integer> to a primitive int array and return it
return values.stream().mapToInt(Integer::intValue).toArray();
}
}
2 changes: 1 addition & 1 deletion src/main/resources/addon.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -19,7 +19,7 @@ authors:
- BONNe

# Soft dependencies of current addon.
softdepend: AcidIsland, BSkyBlock, CaveBlock, SkyGrid, AOneBlock
softdepend: AcidIsland, BSkyBlock, CaveBlock, SkyGrid, AOneBlock, ItemsAdder

# List of addon permissions
permissions:
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
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
11 changes: 11 additions & 0 deletions pom.xml
Original file line numberDiff line numberDiff line change
Expand Up@@ -124,6 +124,10 @@
<id>vault-repo</id>
<url>http://nexus.hc.to/content/repositories/pub_releases</url>
</repository>
<repository>
<id>matteodev</id>
<url>https://maven.devs.beer/</url>
</repository>
</repositories>

<!-- Your addon must contain Spigot and BentoBox APIs dependencies. -->
Expand All@@ -147,6 +151,13 @@
<artifactId>annotations</artifactId>
<version>18.0.0</version>
</dependency>

<dependency>
<groupId>dev.lone</groupId>
<artifactId>api-itemsadder</artifactId>
<version>4.0.10</version>
<scope>provided</scope>
</dependency>
</dependencies>

<!-- Build contains information for maven. It allows to create correct
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -33,6 +33,7 @@
import world.bentobox.controlpanel.database.objects.ControlPanelObject.ControlPanelButton;
import world.bentobox.controlpanel.panels.GuiUtils;
import world.bentobox.controlpanel.utils.Constants;
import world.bentobox.controlpanel.utils.ItemsAdderParse;
import world.bentobox.controlpanel.utils.Utils;


Expand DownExpand Up@@ -247,7 +248,6 @@ public void importControlPanels(@Nullable User user, @NotNull GameModeAddon addo
* @param user - user
* @param gameModeName - gamemode name where ControlPanels must be imported.
* @param fileName Specifies from which file control panel will be loaded
* @return true if successful
*/
private void importControlPanels(@Nullable User user, String gameModeName, @NotNull String fileName)
{
Expand DownExpand Up@@ -356,48 +356,53 @@ private void readControlPanel(YamlConfiguration config, @Nullable User user, fin
if (buttonListSection != null)
{
buttonListSection.getKeys(false).forEach(slotReference -> {
ControlPanelButton button = new ControlPanelButton();
button.setSlot(Integer.parseInt(slotReference));
for (int slotNum : Utils.readIntArray(List.of(slotReference))) {
ControlPanelButton button = new ControlPanelButton();
button.setSlot(slotNum);

ConfigurationSection buttonSection =
buttonListSection.getConfigurationSection(slotReference);
ConfigurationSection buttonSection =
buttonListSection.getConfigurationSection(slotReference);

if (buttonSection != null)
{
button.setName(buttonSection.getString("name"));
button.setCommand(buttonSection.getString("command", "[user_command]"));

// Create empty list
button.setDescriptionLines(new ArrayList<>());

if (buttonSection.isList("description"))
{
// Read description by each line
buttonSection.getStringList("description").forEach(line ->
button.getDescriptionLines().add(
line.replace("[gamemode]", gameMode.toLowerCase())));
}
else if (buttonSection.isString("description"))
if (buttonSection != null)
{
// Check if description is not defined as simple string
String input = buttonSection.getString("description", "");
button.setName(buttonSection.getString("name"));
button.setCommand(buttonSection.getString("command", "[user_command]"));

if (input != null && !input.isEmpty())
// Create empty list
button.setDescriptionLines(new ArrayList<>());

if (buttonSection.isList("description"))
{
button.getDescriptionLines().add(
input.replace("[gamemode]", gameMode.toLowerCase()));
// Read description by each line
buttonSection.getStringList("description").forEach(line ->
button.getDescriptionLines().add(
line.replace("[gamemode]", gameMode.toLowerCase())));
}
else if (buttonSection.isString("description"))
{
// Check if description is not defined as simple string
String input = buttonSection.getString("description", "");

if (!input.isEmpty())
{
button.getDescriptionLines().add(
input.replace("[gamemode]", gameMode.toLowerCase()));
}
}
else
{
this.addon.logWarning("Description for button "
+ button.getSlot() + " could not be read.");
}
}
else
{
this.addon.logWarning("Description for button " +
+ button.getSlot() + " could not be read.");
}

button.setMaterial(Material.matchMaterial(buttonSection.getString("material", "GRASS")));
button.setIcon(ItemParser.parse("icon", new ItemStack(Material.PAPER)));
button.setMaterial(Material.matchMaterial(buttonSection.getString("material", "GRASS")));
if(buttonSection.getString("icon") != null)
button.setIcon(ItemParser.parse(buttonSection.getString("icon"), new ItemStack(Material.PAPER)));
if(buttonSection.getString("itemsadder") != null)
button.setIcon(ItemsAdderParse.parse(buttonSection.getString("itemsadder")));

buttonList.add(button);
buttonList.add(button);
}
}
});
}
Expand DownExpand Up@@ -501,15 +506,15 @@ public ControlPanelObject getUserControlPanel(User user, World world, String per
/**
* Control Panel Addon instance.
*/
private ControlPanelAddon addon;
private final ControlPanelAddon addon;

/**
* This database allows to access to all stored control panels.
*/
private Database<ControlPanelObject> controlPanelDatabase;
private final Database<ControlPanelObject> controlPanelDatabase;

/**
* This map contains all control panel object linked to their reference game mode.
*/
private Map<String, ControlPanelObject> controlPanelCache;
private final Map<String, ControlPanelObject> controlPanelCache;
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
package world.bentobox.controlpanel.utils;

import dev.lone.itemsadder.api.CustomStack;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;

public class ItemsAdderParse {
public static ItemStack parse(String string, ItemStack itemStack)
{
if(!Bukkit.getServer().getPluginManager().isPluginEnabled("ItemsAdder")) return itemStack;
CustomStack stack = CustomStack.getInstance(string);
if(stack != null) return stack.getItemStack();
return itemStack;
}
public static ItemStack parse(String string)
{
return parse(string, new ItemStack(Material.PAPER));
}
}
60 changes: 60 additions & 0 deletions src/main/java/world/bentobox/controlpanel/utils/Utils.java
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,8 +9,11 @@

import org.bukkit.World;
import org.bukkit.permissions.PermissionAttachmentInfo;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.api.addons.GameModeAddon;
Expand DownExpand Up@@ -143,4 +146,61 @@ public static <T> T getPreviousValue(T[] values, T currentValue)

return currentValue;
}

/**
* Reads a list of objects and converts it into an array of integers.
* <p>
* The method processes each element in the list:
* <ul>
* <li>If the element is an Integer, it adds it directly to the result array.</li>
* <li>If the element is a String in the format "start-end", it adds all integers
* from "start" to "end" (inclusive) to the result array.</li>
* </ul>
*
* <b>Example:</b>
* If the input list is `["1-3", 5, "7-9"]`, the method will return an array
* containing `[1, 2, 3, 5, 7, 8, 9]`.
*
* @param objectList A list of objects, each of which can either be an Integer or a String
* in the format "start-end" (inclusive range).
* @return An array of integers containing all the integers parsed from the input list.
* The integers from ranges are added to the result array in order.
* @throws NumberFormatException If the string representation of a number is not valid.
*/
public static int[] readIntArray(List<?> objectList) {
List<Integer> values = new ArrayList<>();

// Process each item in the objectList
for (Object o : objectList) {
// If the object is an Integer, add it directly to values
if (o instanceof Integer) {
values.add((int) o);
}
// If the object is a String in the form "start-end"
else if (o instanceof String) {
try {
int n = Integer.parseInt((String) o);
values.add(n);
}catch (NumberFormatException ignored) {}
String[] args = ((String) o).split("-");
if (args.length >= 2) {
try {
int n0 = Integer.parseInt(args[0]);
int n1 = Integer.parseInt(args[1]) + 1; // Add 1 to include the upper bound
// Add all integers in the range [n0, n1)
for (int n : IntStream.range(n0, n1).toArray()) {
values.add(n);
}
continue;
} catch (NumberFormatException e) {
// Handle invalid number format if necessary
throw new NumberFormatException("Invalid number format in range string: " + o);
}
}
}
}

// Convert List<Integer> to a primitive int array and return it
return values.stream().mapToInt(Integer::intValue).toArray();
}
}
2 changes: 1 addition & 1 deletion src/main/resources/addon.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -19,7 +19,7 @@ authors:
- BONNe

# Soft dependencies of current addon.
softdepend: AcidIsland, BSkyBlock, CaveBlock, SkyGrid, AOneBlock
softdepend: AcidIsland, BSkyBlock, CaveBlock, SkyGrid, AOneBlock, ItemsAdder

# List of addon permissions
permissions:
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
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
11 changes: 11 additions & 0 deletions pom.xml
Original file line numberDiff line numberDiff line change
Expand Up@@ -124,6 +124,10 @@
<id>vault-repo</id>
<url>http://nexus.hc.to/content/repositories/pub_releases</url>
</repository>
<repository>
<id>matteodev</id>
<url>https://maven.devs.beer/</url>
</repository>
</repositories>

<!-- Your addon must contain Spigot and BentoBox APIs dependencies. -->
Expand All@@ -147,6 +151,13 @@
<artifactId>annotations</artifactId>
<version>18.0.0</version>
</dependency>

<dependency>
<groupId>dev.lone</groupId>
<artifactId>api-itemsadder</artifactId>
<version>4.0.10</version>
<scope>provided</scope>
</dependency>
</dependencies>

<!-- Build contains information for maven. It allows to create correct
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -33,6 +33,7 @@
import world.bentobox.controlpanel.database.objects.ControlPanelObject.ControlPanelButton;
import world.bentobox.controlpanel.panels.GuiUtils;
import world.bentobox.controlpanel.utils.Constants;
import world.bentobox.controlpanel.utils.ItemsAdderParse;
import world.bentobox.controlpanel.utils.Utils;


Expand DownExpand Up@@ -247,7 +248,6 @@ public void importControlPanels(@Nullable User user, @NotNull GameModeAddon addo
* @param user - user
* @param gameModeName - gamemode name where ControlPanels must be imported.
* @param fileName Specifies from which file control panel will be loaded
* @return true if successful
*/
private void importControlPanels(@Nullable User user, String gameModeName, @NotNull String fileName)
{
Expand DownExpand Up@@ -356,48 +356,53 @@ private void readControlPanel(YamlConfiguration config, @Nullable User user, fin
if (buttonListSection != null)
{
buttonListSection.getKeys(false).forEach(slotReference -> {
ControlPanelButton button = new ControlPanelButton();
button.setSlot(Integer.parseInt(slotReference));
for (int slotNum : Utils.readIntArray(List.of(slotReference))) {
ControlPanelButton button = new ControlPanelButton();
button.setSlot(slotNum);

ConfigurationSection buttonSection =
buttonListSection.getConfigurationSection(slotReference);
ConfigurationSection buttonSection =
buttonListSection.getConfigurationSection(slotReference);

if (buttonSection != null)
{
button.setName(buttonSection.getString("name"));
button.setCommand(buttonSection.getString("command", "[user_command]"));

// Create empty list
button.setDescriptionLines(new ArrayList<>());

if (buttonSection.isList("description"))
{
// Read description by each line
buttonSection.getStringList("description").forEach(line ->
button.getDescriptionLines().add(
line.replace("[gamemode]", gameMode.toLowerCase())));
}
else if (buttonSection.isString("description"))
if (buttonSection != null)
{
// Check if description is not defined as simple string
String input = buttonSection.getString("description", "");
button.setName(buttonSection.getString("name"));
button.setCommand(buttonSection.getString("command", "[user_command]"));

if (input != null && !input.isEmpty())
// Create empty list
button.setDescriptionLines(new ArrayList<>());

if (buttonSection.isList("description"))
{
button.getDescriptionLines().add(
input.replace("[gamemode]", gameMode.toLowerCase()));
// Read description by each line
buttonSection.getStringList("description").forEach(line ->
button.getDescriptionLines().add(
line.replace("[gamemode]", gameMode.toLowerCase())));
}
else if (buttonSection.isString("description"))
{
// Check if description is not defined as simple string
String input = buttonSection.getString("description", "");

if (!input.isEmpty())
{
button.getDescriptionLines().add(
input.replace("[gamemode]", gameMode.toLowerCase()));
}
}
else
{
this.addon.logWarning("Description for button "
+ button.getSlot() + " could not be read.");
}
}
else
{
this.addon.logWarning("Description for button " +
+ button.getSlot() + " could not be read.");
}

button.setMaterial(Material.matchMaterial(buttonSection.getString("material", "GRASS")));
button.setIcon(ItemParser.parse("icon", new ItemStack(Material.PAPER)));
button.setMaterial(Material.matchMaterial(buttonSection.getString("material", "GRASS")));
if(buttonSection.getString("icon") != null)
button.setIcon(ItemParser.parse(buttonSection.getString("icon"), new ItemStack(Material.PAPER)));
if(buttonSection.getString("itemsadder") != null)
button.setIcon(ItemsAdderParse.parse(buttonSection.getString("itemsadder")));

buttonList.add(button);
buttonList.add(button);
}
}
});
}
Expand DownExpand Up@@ -501,15 +506,15 @@ public ControlPanelObject getUserControlPanel(User user, World world, String per
/**
* Control Panel Addon instance.
*/
private ControlPanelAddon addon;
private final ControlPanelAddon addon;

/**
* This database allows to access to all stored control panels.
*/
private Database<ControlPanelObject> controlPanelDatabase;
private final Database<ControlPanelObject> controlPanelDatabase;

/**
* This map contains all control panel object linked to their reference game mode.
*/
private Map<String, ControlPanelObject> controlPanelCache;
private final Map<String, ControlPanelObject> controlPanelCache;
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
package world.bentobox.controlpanel.utils;

import dev.lone.itemsadder.api.CustomStack;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;

public class ItemsAdderParse {
public static ItemStack parse(String string, ItemStack itemStack)
{
if(!Bukkit.getServer().getPluginManager().isPluginEnabled("ItemsAdder")) return itemStack;
CustomStack stack = CustomStack.getInstance(string);
if(stack != null) return stack.getItemStack();
return itemStack;
}
public static ItemStack parse(String string)
{
return parse(string, new ItemStack(Material.PAPER));
}
}
60 changes: 60 additions & 0 deletions src/main/java/world/bentobox/controlpanel/utils/Utils.java
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,8 +9,11 @@

import org.bukkit.World;
import org.bukkit.permissions.PermissionAttachmentInfo;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.api.addons.GameModeAddon;
Expand DownExpand Up@@ -143,4 +146,61 @@ public static <T> T getPreviousValue(T[] values, T currentValue)

return currentValue;
}

/**
* Reads a list of objects and converts it into an array of integers.
* <p>
* The method processes each element in the list:
* <ul>
* <li>If the element is an Integer, it adds it directly to the result array.</li>
* <li>If the element is a String in the format "start-end", it adds all integers
* from "start" to "end" (inclusive) to the result array.</li>
* </ul>
*
* <b>Example:</b>
* If the input list is `["1-3", 5, "7-9"]`, the method will return an array
* containing `[1, 2, 3, 5, 7, 8, 9]`.
*
* @param objectList A list of objects, each of which can either be an Integer or a String
* in the format "start-end" (inclusive range).
* @return An array of integers containing all the integers parsed from the input list.
* The integers from ranges are added to the result array in order.
* @throws NumberFormatException If the string representation of a number is not valid.
*/
public static int[] readIntArray(List<?> objectList) {
List<Integer> values = new ArrayList<>();

// Process each item in the objectList
for (Object o : objectList) {
// If the object is an Integer, add it directly to values
if (o instanceof Integer) {
values.add((int) o);
}
// If the object is a String in the form "start-end"
else if (o instanceof String) {
try {
int n = Integer.parseInt((String) o);
values.add(n);
}catch (NumberFormatException ignored) {}
String[] args = ((String) o).split("-");
if (args.length >= 2) {
try {
int n0 = Integer.parseInt(args[0]);
int n1 = Integer.parseInt(args[1]) + 1; // Add 1 to include the upper bound
// Add all integers in the range [n0, n1)
for (int n : IntStream.range(n0, n1).toArray()) {
values.add(n);
}
continue;
} catch (NumberFormatException e) {
// Handle invalid number format if necessary
throw new NumberFormatException("Invalid number format in range string: " + o);
}
}
}
}

// Convert List<Integer> to a primitive int array and return it
return values.stream().mapToInt(Integer::intValue).toArray();
}
}
2 changes: 1 addition & 1 deletion src/main/resources/addon.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -19,7 +19,7 @@ authors:
- BONNe

# Soft dependencies of current addon.
softdepend: AcidIsland, BSkyBlock, CaveBlock, SkyGrid, AOneBlock
softdepend: AcidIsland, BSkyBlock, CaveBlock, SkyGrid, AOneBlock, ItemsAdder

# List of addon permissions
permissions:
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
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
11 changes: 11 additions & 0 deletions pom.xml
Original file line numberDiff line numberDiff line change
Expand Up@@ -124,6 +124,10 @@
<id>vault-repo</id>
<url>http://nexus.hc.to/content/repositories/pub_releases</url>
</repository>
<repository>
<id>matteodev</id>
<url>https://maven.devs.beer/</url>
</repository>
</repositories>

<!-- Your addon must contain Spigot and BentoBox APIs dependencies. -->
Expand All@@ -147,6 +151,13 @@
<artifactId>annotations</artifactId>
<version>18.0.0</version>
</dependency>

<dependency>
<groupId>dev.lone</groupId>
<artifactId>api-itemsadder</artifactId>
<version>4.0.10</version>
<scope>provided</scope>
</dependency>
</dependencies>

<!-- Build contains information for maven. It allows to create correct
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -33,6 +33,7 @@
import world.bentobox.controlpanel.database.objects.ControlPanelObject.ControlPanelButton;
import world.bentobox.controlpanel.panels.GuiUtils;
import world.bentobox.controlpanel.utils.Constants;
import world.bentobox.controlpanel.utils.ItemsAdderParse;
import world.bentobox.controlpanel.utils.Utils;


Expand DownExpand Up@@ -247,7 +248,6 @@ public void importControlPanels(@Nullable User user, @NotNull GameModeAddon addo
* @param user - user
* @param gameModeName - gamemode name where ControlPanels must be imported.
* @param fileName Specifies from which file control panel will be loaded
* @return true if successful
*/
private void importControlPanels(@Nullable User user, String gameModeName, @NotNull String fileName)
{
Expand DownExpand Up@@ -356,48 +356,53 @@ private void readControlPanel(YamlConfiguration config, @Nullable User user, fin
if (buttonListSection != null)
{
buttonListSection.getKeys(false).forEach(slotReference -> {
ControlPanelButton button = new ControlPanelButton();
button.setSlot(Integer.parseInt(slotReference));
for (int slotNum : Utils.readIntArray(List.of(slotReference))) {
ControlPanelButton button = new ControlPanelButton();
button.setSlot(slotNum);

ConfigurationSection buttonSection =
buttonListSection.getConfigurationSection(slotReference);
ConfigurationSection buttonSection =
buttonListSection.getConfigurationSection(slotReference);

if (buttonSection != null)
{
button.setName(buttonSection.getString("name"));
button.setCommand(buttonSection.getString("command", "[user_command]"));

// Create empty list
button.setDescriptionLines(new ArrayList<>());

if (buttonSection.isList("description"))
{
// Read description by each line
buttonSection.getStringList("description").forEach(line ->
button.getDescriptionLines().add(
line.replace("[gamemode]", gameMode.toLowerCase())));
}
else if (buttonSection.isString("description"))
if (buttonSection != null)
{
// Check if description is not defined as simple string
String input = buttonSection.getString("description", "");
button.setName(buttonSection.getString("name"));
button.setCommand(buttonSection.getString("command", "[user_command]"));

if (input != null && !input.isEmpty())
// Create empty list
button.setDescriptionLines(new ArrayList<>());

if (buttonSection.isList("description"))
{
button.getDescriptionLines().add(
input.replace("[gamemode]", gameMode.toLowerCase()));
// Read description by each line
buttonSection.getStringList("description").forEach(line ->
button.getDescriptionLines().add(
line.replace("[gamemode]", gameMode.toLowerCase())));
}
else if (buttonSection.isString("description"))
{
// Check if description is not defined as simple string
String input = buttonSection.getString("description", "");

if (!input.isEmpty())
{
button.getDescriptionLines().add(
input.replace("[gamemode]", gameMode.toLowerCase()));
}
}
else
{
this.addon.logWarning("Description for button "
+ button.getSlot() + " could not be read.");
}
}
else
{
this.addon.logWarning("Description for button " +
+ button.getSlot() + " could not be read.");
}

button.setMaterial(Material.matchMaterial(buttonSection.getString("material", "GRASS")));
button.setIcon(ItemParser.parse("icon", new ItemStack(Material.PAPER)));
button.setMaterial(Material.matchMaterial(buttonSection.getString("material", "GRASS")));
if(buttonSection.getString("icon") != null)
button.setIcon(ItemParser.parse(buttonSection.getString("icon"), new ItemStack(Material.PAPER)));
if(buttonSection.getString("itemsadder") != null)
button.setIcon(ItemsAdderParse.parse(buttonSection.getString("itemsadder")));

buttonList.add(button);
buttonList.add(button);
}
}
});
}
Expand DownExpand Up@@ -501,15 +506,15 @@ public ControlPanelObject getUserControlPanel(User user, World world, String per
/**
* Control Panel Addon instance.
*/
private ControlPanelAddon addon;
private final ControlPanelAddon addon;

/**
* This database allows to access to all stored control panels.
*/
private Database<ControlPanelObject> controlPanelDatabase;
private final Database<ControlPanelObject> controlPanelDatabase;

/**
* This map contains all control panel object linked to their reference game mode.
*/
private Map<String, ControlPanelObject> controlPanelCache;
private final Map<String, ControlPanelObject> controlPanelCache;
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
package world.bentobox.controlpanel.utils;

import dev.lone.itemsadder.api.CustomStack;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;

public class ItemsAdderParse {
public static ItemStack parse(String string, ItemStack itemStack)
{
if(!Bukkit.getServer().getPluginManager().isPluginEnabled("ItemsAdder")) return itemStack;
CustomStack stack = CustomStack.getInstance(string);
if(stack != null) return stack.getItemStack();
return itemStack;
}
public static ItemStack parse(String string)
{
return parse(string, new ItemStack(Material.PAPER));
}
}
60 changes: 60 additions & 0 deletions src/main/java/world/bentobox/controlpanel/utils/Utils.java
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,8 +9,11 @@

import org.bukkit.World;
import org.bukkit.permissions.PermissionAttachmentInfo;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.api.addons.GameModeAddon;
Expand DownExpand Up@@ -143,4 +146,61 @@ public static <T> T getPreviousValue(T[] values, T currentValue)

return currentValue;
}

/**
* Reads a list of objects and converts it into an array of integers.
* <p>
* The method processes each element in the list:
* <ul>
* <li>If the element is an Integer, it adds it directly to the result array.</li>
* <li>If the element is a String in the format "start-end", it adds all integers
* from "start" to "end" (inclusive) to the result array.</li>
* </ul>
*
* <b>Example:</b>
* If the input list is `["1-3", 5, "7-9"]`, the method will return an array
* containing `[1, 2, 3, 5, 7, 8, 9]`.
*
* @param objectList A list of objects, each of which can either be an Integer or a String
* in the format "start-end" (inclusive range).
* @return An array of integers containing all the integers parsed from the input list.
* The integers from ranges are added to the result array in order.
* @throws NumberFormatException If the string representation of a number is not valid.
*/
public static int[] readIntArray(List<?> objectList) {
List<Integer> values = new ArrayList<>();

// Process each item in the objectList
for (Object o : objectList) {
// If the object is an Integer, add it directly to values
if (o instanceof Integer) {
values.add((int) o);
}
// If the object is a String in the form "start-end"
else if (o instanceof String) {
try {
int n = Integer.parseInt((String) o);
values.add(n);
}catch (NumberFormatException ignored) {}
String[] args = ((String) o).split("-");
if (args.length >= 2) {
try {
int n0 = Integer.parseInt(args[0]);
int n1 = Integer.parseInt(args[1]) + 1; // Add 1 to include the upper bound
// Add all integers in the range [n0, n1)
for (int n : IntStream.range(n0, n1).toArray()) {
values.add(n);
}
continue;
} catch (NumberFormatException e) {
// Handle invalid number format if necessary
throw new NumberFormatException("Invalid number format in range string: " + o);
}
}
}
}

// Convert List<Integer> to a primitive int array and return it
return values.stream().mapToInt(Integer::intValue).toArray();
}
}
2 changes: 1 addition & 1 deletion src/main/resources/addon.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -19,7 +19,7 @@ authors:
- BONNe

# Soft dependencies of current addon.
softdepend: AcidIsland, BSkyBlock, CaveBlock, SkyGrid, AOneBlock
softdepend: AcidIsland, BSkyBlock, CaveBlock, SkyGrid, AOneBlock, ItemsAdder

# List of addon permissions
permissions:
Expand Down