1
mirror of https://github.com/StarWishsama/Slimefun4.git synced 2024-09-20 11:45:51 +00:00

Merge branch 'experimental' into ShulkerShell

This commit is contained in:
TheBusyBiscuit 2020-07-13 17:05:39 +02:00 committed by GitHub
commit 572d3dceec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
410 changed files with 10306 additions and 6719 deletions

View File

@ -2,7 +2,8 @@
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of contents**
- [Release Candidate 14 (TBD)](#release-candidate-14-tbd)
- [Release Candidate 15 (TBD)](#release-candidate-15-tbd)
- [Release Candidate 14 (12 Jul 2020)](#release-candidate-14-12-jul-2020)
- [Release Candidate 13 (16 Jun 2020)](#release-candidate-13-16-jun-2020)
- [Release Candidate 12 (27 May 2020)](#release-candidate-12-27-may-2020)
- [Release Candidate 11 (25 Apr 2020)](#release-candidate-11-25-apr-2020)
@ -19,9 +20,25 @@
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
## Release Candidate 14 (TBD)
## Release Candidate 15 (TBD)
#### Additions
* Added Reinforced Cloth
* Added Bee protection to Hazmat Suit
* Added Enchantment Rune
* Added Tape Measure
#### Changes
* Changed recipe of Hazmat Suits
* Uranium can no longer be placed down
#### Fixes
* Fixed Slimefun Armor sometimes not applying its effects
## Release Candidate 14 (12 Jul 2020)
#### Additions
* Added support for Minecraft 1.16
* Added a starting sound for the Ancient Altar
* Added config option to disable backwards compatibility and improve performance
* Added ReactorExplodeEvent to the API
@ -29,18 +46,42 @@
* Added Nether Quartz Ore Crusher Recipe
* Added a new language: Tagalog
* Added Magical Zombie Pills
* Added 1.13 compatibility to the Auto Drier
* Added Corals to the fuel list for the Bio Generator
* Added Clay -> Clay blocks recipe to the Electric Press
* (1.16+) Slimefun guide can now show Smithing Table recipes
* (1.16+) Added Nether Gold Ore recipe to the Ore Crusher
* (1.16+) Added Gilded Blackstone recipe to the Ore Crusher
* (1.16+) Added Shroomlights to the fuel list for the Bio Generator
* (1.16+) Added Warped and Crimson Fungus to the fuel list for the Bio Generator
* Added an AoE damage effect to the Explosive Bow
* Added runtime deprecation warnings for ItemHandlers and Attributes used by Addons
* Added a proper lag profiler
* Added per-plugin lag info to /sf timings
* Added Indonesian translations
#### Changes
* Coolant Cells now last twice as long
* Ticking blocks will now catch more errors caused by addons
* Massive performance improvements to GPS/GEO machines, especially Oil Pump and GEO Miner
* Changed the texture for the Nuclear Reactor
* Changed the texture for the Nether Star Reactor
* Performance improvements to Rainbow Blocks
* Crafting Tin cans now produces 8 items instead of 4
* Multi Tool lore now says "Crouch" instead of "Hold Shift"
* items which cannot be distributed by a Cargo Net will be dropped on the ground now instead of getting deleted
* Small performance improvements to the Cargo Net
* Items which cannot be distributed by a Cargo Net will be dropped on the ground now instead of getting deleted
* Slimefun no longer supports CraftBukkit
* Item Energy is now also stored persistently via NBT
* Performance improvements to GPS/GEO machines, especially Oil Pump and GEO Miner
* Performance improvements for ticking blocks
* Performance improvements to the Cargo Net
* performance improvements to the Energy Net
* Performance improvements to Rainbow Blocks
* Performance improvements to Androids
* performance improvements to Generators and Electric Machines
* Cargo timings will now be attributed to the corresponding node and not the Cargo manager
* Thunderstorms now count as night time for Solar Generators
* Coolant Cells can no longer be placed on the ground
* Crafting Nether Ice Coolant Cells now results in 4 items
* Moved Soulbound Backpack to the "Magical Gadgets" Category
#### Fixes
* Fixed #2005
@ -49,6 +90,28 @@
* Fixed Infused Magnet working even if you haven't researched it
* Fixed Rainbow blocks duplication glitch when timing the block break right
* Fixed #1855
* Fixed some issues with AsyncWorldEdit
* Fixed some problems with unregistered or fake worlds
* Fixed a rare concurrency issue with world saving
* Fixed some contributors showing up twice
* Fixed #2062
* Fixed Grappling hooks disappearing when fired at Item frames or paintaings
* Fixed Grappling hooks not getting removed when the Player leaves
* Fixed Grappling hooks making Bat sounds
* Fixed #1959
* Fixed Melon Juice requiring Melons instead of Melon Slices
* Fixed Cargo networks not showing up in /sf timings
* Fixed /sf timings reporting slightly inaccurate timings
* Fixed concurrency-related issues with the profiling
* Fixed #2066
* Fixed Rainbow Glass Panes not properly connecting to blocks
* Fixed Androids turning in the wrong direction
* Fixed contributors losing their texture after restarts
* Fixed "korean" showing up as "null"
* Fixed an issue with moving androids getting stuck
* Fixed Cargo nodes sometimes preventing chunks from unloading
* Fixed #2081
* Fixed a NullPointerException when Generators throw an Error Report
## Release Candidate 13 (16 Jun 2020)
https://thebusybiscuit.github.io/builds/TheBusyBiscuit/Slimefun4/stable/#13

View File

@ -1,7 +1,7 @@
# Slimefun 4
Looking for the download link? [**Click here**](https://github.com/TheBusyBiscuit/Slimefun4/blob/master/README.md#download-slimefun-4)
Slimefun is a plugin which aims to turn your Bukkit/Spigot Server into a modpack without ever installing a single mod. It offers everything you could possibly imagine. From Backpacks to Jetpacks! Slimefun lets every player decide on their own how much they want to dive into Magic or Tech.<br>
Slimefun is a plugin which aims to turn your Spigot Server into a modpack without ever installing a single mod. It offers everything you could possibly imagine. From Backpacks to Jetpacks! Slimefun lets every player decide on their own how much they want to dive into Magic or Tech.<br>
We got everything from magical wands to nuclear reactors.<br>
We feature a magical altar, an electric power grid and even item transport systems.
@ -22,13 +22,15 @@ Check out our [Addons](https://github.com/TheBusyBiscuit/Slimefun4/wiki/Addons),
## Download Slimefun 4
(See also: [How to install Slimefun](https://github.com/TheBusyBiscuit/Slimefun4/wiki/Installing-Slimefun))
**Due to [Spigot's abandonce of the Bukkit API](https://www.spigotmc.org/threads/spigot-bungeecord-1-16-1.447405/#post-3852349), Slimefun is no longer able to work on CraftBukkit, please switch over to Spigot or Paper if you haven't already.**
Slimefun 4 can be downloaded **for free** on our builds page.<br>
We currently provide two distinct versions of Slimefun, development builds and "stable" builds.<br>
Here is a full summary of the differences between the two different versions of Slimefun.
| | development (latest) | "stable" |
| ------------------ | -------- | -------- |
| **Minecraft version(s)** | :video_game: 1.13.X - 1.15.X | :video_game: 1.13.X - 1.15.X |
| **Minecraft version(s)** | :video_game: **1.13.\* - 1.16.\*** | :video_game: **1.13.\* - 1.16.\*** |
| **automatic updates** | :heavy_check_mark: | :heavy_check_mark: |
| **frequent updates** | :heavy_check_mark: | :x: |
| **latest content** | :heavy_check_mark: | :x: |
@ -101,6 +103,19 @@ So not everything may be available for translation yet.<br>
This is an open-source community project, so **your contributions keep this plugin alive!**<br>
Pull Requests can be fixes, changes or even additions, but please keep in mind that if you add too much content to Slimefun 4, you should maybe consider making an Addon for it instead ([Developer Guide](https://github.com/TheBusyBiscuit/Slimefun4/wiki/Developer-Guide)).
#### Compiling
Slimefun is written in Java and uses [Maven](https://maven.apache.org/) for compilation.<br>
To compile Slimefun yourself, follow these steps:
1. Clone the project via git<br>
`$ git clone https://github.com/TheBusyBiscuit/Slimefun4/`
2. Compile the project using Maven<br>
`$ mvn clean package`
If you are already using an IDE, make sure to import the project via git and set it as a *Maven project*. Then you should be able build it via Maven using the goals `clean package`.
If you have any further questions, then please join our [Discord Support Server](#discord) and ask your questions in the `#programming-help` channel. Note that we will not accept any bug reports from custom-compiled versions of Slimefun.
### Code Quality
Slimefun uses [Sonarcloud.io](https://sonarcloud.io/dashboard?id=TheBusyBiscuit_Slimefun4) to monitor Code Quality.

28
pom.xml
View File

@ -13,7 +13,7 @@
<inceptionYear>2013</inceptionYear>
<packaging>jar</packaging>
<description>Slimefun is a Bukkit / Spigot plugin that simulates a modpack-like atmosphere by adding over 500 new items and recipes to your Minecraft Server.</description>
<description>Slimefun is a Spigot plugin that simulates a modpack-like atmosphere by adding over 500 new items and recipes to your Minecraft Server.</description>
<url>https://github.com/TheBusyBiscuit/Slimefun4</url>
<properties>
@ -21,9 +21,9 @@
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<!-- Bukkit properties -->
<bukkit.version>1.15.2</bukkit.version>
<bukkit.javadocs>https://hub.spigotmc.org/javadocs/bukkit/</bukkit.javadocs>
<!-- Spigot properties -->
<spigot.version>1.16.1</spigot.version>
<spigot.javadocs>https://hub.spigotmc.org/javadocs/spigot/</spigot.javadocs>
<!-- Default settings for sonarcloud.io -->
<sonar.projectKey>TheBusyBiscuit_Slimefun4</sonar.projectKey>
@ -60,7 +60,7 @@
<url>https://repo.destroystokyo.com/repository/maven-public/</url>
</repository>
<repository>
<id>worldedit-worldguard-repo</id>
<id>worldedit-repo</id>
<url>https://maven.sk89q.com/repo/</url>
</repository>
<repository>
@ -209,7 +209,7 @@
<!-- We can reference Bukkit's API in our Javadocs -->
<links>
<link>${bukkit.javadocs}</link>
<link>${spigot.javadocs}</link>
</links>
<!-- We can group pakages together in our Javadocs -->
@ -270,15 +270,15 @@
<dependencies>
<!-- Hard dependencies -->
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>bukkit</artifactId>
<version>${bukkit.version}-R0.1-SNAPSHOT</version>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>${spigot.version}-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.github.TheBusyBiscuit</groupId>
<artifactId>CS-CoreLib</artifactId>
<version>4a7fce5202</version>
<version>31390302cf</version>
<scope>provided</scope>
</dependency>
@ -298,15 +298,15 @@
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>3.3.3</version>
<version>3.4.0</version>
<scope>test</scope>
</dependency>
<!-- Shaded packages -->
<dependency>
<groupId>com.github.thebusybiscuit</groupId>
<groupId>com.github.TheBusyBiscuit</groupId>
<artifactId>CS-CoreLib2</artifactId>
<version>0.21</version>
<version>0.23.2</version>
<scope>compile</scope>
</dependency>
<dependency>
@ -350,4 +350,4 @@
<scope>provided</scope>
</dependency>
</dependencies>
</project>
</project>

View File

@ -1,7 +1,6 @@
package io.github.thebusybiscuit.slimefun4.api;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
@ -18,7 +17,7 @@ import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.plugin.Plugin;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.Objects.handlers.BlockTicker;
import me.mrCookieSlime.Slimefun.api.BlockStorage;
@ -82,7 +81,7 @@ public class ErrorReport {
throwable.printStackTrace(stream);
addon.getLogger().log(Level.WARNING, "");
addon.getLogger().log(Level.WARNING, "An Error occured! It has been saved as: ");
addon.getLogger().log(Level.WARNING, "An Error occurred! It has been saved as: ");
addon.getLogger().log(Level.WARNING, "/plugins/Slimefun/error-reports/{0}", file.getName());
addon.getLogger().log(Level.WARNING, "Please put this file on https://pastebin.com and report this to the developer(s).");
@ -92,8 +91,8 @@ public class ErrorReport {
addon.getLogger().log(Level.WARNING, "");
}
catch (IOException x) {
addon.getLogger().log(Level.SEVERE, x, () -> "An Error occured while saving an Error-Report for Slimefun " + SlimefunPlugin.getVersion());
catch (Exception x) {
addon.getLogger().log(Level.SEVERE, x, () -> "An Error occurred while saving an Error-Report for Slimefun " + SlimefunPlugin.getVersion());
}
});
}
@ -109,9 +108,19 @@ public class ErrorReport {
stream.println(" Block Data: " + l.getBlock().getBlockData().getClass().getName());
stream.println(" State: " + l.getBlock().getState().getClass().getName());
stream.println();
stream.println("Ticker-Info:");
stream.println(" Type: " + (item.getBlockTicker().isSynchronized() ? "Synchronized" : "Asynchronous"));
stream.println();
if (item.getBlockTicker() != null) {
stream.println("Ticker-Info:");
stream.println(" Type: " + (item.getBlockTicker().isSynchronized() ? "Synchronized" : "Asynchronous"));
stream.println();
}
if (item.getEnergyTicker() != null) {
stream.println("Ticker-Info:");
stream.println(" Type: Indirect (Energy Network)");
stream.println();
}
stream.println("Slimefun Data:");
stream.println(" ID: " + item.getID());
stream.println(" Inventory: " + BlockStorage.getStorage(l.getWorld()).hasInventory(l));

View File

@ -2,7 +2,7 @@ package io.github.thebusybiscuit.slimefun4.api;
import org.apache.commons.lang.Validate;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
/**
* This enum holds all versions of Minecraft that we currently support.
@ -32,6 +32,12 @@ public enum MinecraftVersion {
*/
MINECRAFT_1_15("1.15.x"),
/**
* This constant represents Minecraft (Java Edition) Version 1.16
* (The "Nether Update")
*/
MINECRAFT_1_16("1.16.x"),
/**
* This constant represents an exceptional state in which we were unable
* to identify the Minecraft Version we are using

View File

@ -10,7 +10,7 @@ import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginDescriptionFile;
import org.bukkit.plugin.java.JavaPlugin;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;

View File

@ -2,8 +2,8 @@ package io.github.thebusybiscuit.slimefun4.api.exceptions;
import org.bukkit.plugin.Plugin;
import io.github.thebusybiscuit.slimefun4.core.handlers.BlockUseHandler;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.Objects.handlers.BlockUseHandler;
import me.mrCookieSlime.Slimefun.Objects.handlers.ItemHandler;
/**

View File

@ -0,0 +1,36 @@
package io.github.thebusybiscuit.slimefun4.api.exceptions;
import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.slimefun4.core.attributes.DamageableItem;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
/**
* A {@link WrongItemStackException} is thrown when someone tries to alter an {@link ItemStack}
* but actually wanted to alter a different one.
*
* If for example a {@link DamageableItem} accidentally damages the original {@link SlimefunItem}
* instead of the held {@link ItemStack}, this will be thrown.
*
* @author TheBusyBiscuit
*
* @see SlimefunItemStack
* @see SlimefunItem
*
*/
public class WrongItemStackException extends RuntimeException {
private static final long serialVersionUID = 9144658137363309071L;
/**
* This constructs a new {@link WrongItemStackException} with the given error context.
*
* @param message
* An error message to display
*/
public WrongItemStackException(String message) {
super("You probably wanted alter a different ItemStack: " + message);
}
}

View File

@ -10,9 +10,9 @@ import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.slimefun4.api.events.GEOResourceGenerationEvent;
import io.github.thebusybiscuit.slimefun4.core.services.localization.Language;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.items.geo.GEOMiner;
import io.github.thebusybiscuit.slimefun4.implementation.items.geo.GEOScanner;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
/**
* A {@link GEOResource} is a virtual resource that can be thought of as world-gen.
@ -91,7 +91,7 @@ public interface GEOResource extends Keyed {
* @return The localized name for this {@link GEOResource}
*/
default String getName(Player p) {
String name = SlimefunPlugin.getLocal().getResourceString(p, "resources." + getKey().getNamespace() + "." + getKey().getKey());
String name = SlimefunPlugin.getLocalization().getResourceString(p, "resources." + getKey().getNamespace() + "." + getKey().getKey());
return name == null ? getName() : name;
}

View File

@ -9,6 +9,7 @@ import java.util.concurrent.ThreadLocalRandom;
import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.World;
@ -20,12 +21,13 @@ import io.github.thebusybiscuit.cscorelib2.config.Config;
import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
import io.github.thebusybiscuit.slimefun4.api.events.GEOResourceGenerationEvent;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.items.geo.GEOMiner;
import io.github.thebusybiscuit.slimefun4.implementation.items.geo.GEOScanner;
import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils;
import io.github.thebusybiscuit.slimefun4.utils.HeadTexture;
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.api.BlockStorage;
/**
@ -42,7 +44,6 @@ import me.mrCookieSlime.Slimefun.api.BlockStorage;
public class ResourceManager {
private final int[] backgroundSlots = { 0, 1, 2, 3, 5, 6, 7, 8, 9, 17, 18, 26, 27, 35, 36, 44, 45, 46, 48, 49, 50, 52, 53 };
private final ItemStack chunkTexture = SlimefunUtils.getCustomHead("8449b9318e33158e64a46ab0de121c3d40000e3332c1574932b3c849d8fa0dc2");
private final Config config;
public ResourceManager(SlimefunPlugin plugin) {
@ -77,7 +78,26 @@ public class ResourceManager {
}
}
/**
* This method returns the amount of a certain {@link GEOResource} found in a given {@link Chunk}.
* The result is an {@link OptionalInt} which will be empty if this {@link GEOResource}
* has not been generated at that {@link Location} yet.
*
* @param resource
* The {@link GEOResource} to query
* @param world
* The {@link World} of this {@link Location}
* @param x
* The {@link Chunk} x cordinate
* @param z
* The {@link Chunk} z cordinate
*
* @return An {@link OptionalInt}, either empty or containing the amount of the given {@link GEOResource}
*/
public OptionalInt getSupplies(GEOResource resource, World world, int x, int z) {
Validate.notNull(resource, "Cannot get supplies for null");
Validate.notNull(world, "World must not be null");
String key = resource.getKey().toString().replace(':', '-');
String value = BlockStorage.getChunkInfo(world, x, z, key);
@ -90,11 +110,17 @@ public class ResourceManager {
}
public void setSupplies(GEOResource resource, World world, int x, int z, int value) {
Validate.notNull(resource, "Cannot set supplies for null");
Validate.notNull(world, "World cannot be null");
String key = resource.getKey().toString().replace(':', '-');
BlockStorage.setChunkInfo(world, x, z, key, String.valueOf(value));
}
private int generate(GEOResource resource, World world, int x, int z) {
Validate.notNull(resource, "Cannot generate resources for null");
Validate.notNull(world, "World cannot be null");
Block block = world.getBlockAt(x << 4, 72, z << 4);
int value = resource.getDefaultSupply(world.getEnvironment(), block.getBiome());
@ -133,20 +159,20 @@ public class ResourceManager {
*/
public void scan(Player p, Block block, int page) {
if (SlimefunPlugin.getGPSNetwork().getNetworkComplexity(p.getUniqueId()) < 600) {
SlimefunPlugin.getLocal().sendMessages(p, "gps.insufficient-complexity", true, msg -> msg.replace("%complexity%", "600"));
SlimefunPlugin.getLocalization().sendMessages(p, "gps.insufficient-complexity", true, msg -> msg.replace("%complexity%", "600"));
return;
}
int x = block.getX() >> 4;
int z = block.getZ() >> 4;
ChestMenu menu = new ChestMenu("&4" + SlimefunPlugin.getLocal().getResourceString(p, "tooltips.results"));
ChestMenu menu = new ChestMenu("&4" + SlimefunPlugin.getLocalization().getResourceString(p, "tooltips.results"));
for (int slot : backgroundSlots) {
menu.addItem(slot, ChestMenuUtils.getBackground(), ChestMenuUtils.getEmptyClickHandler());
}
menu.addItem(4, new CustomItem(chunkTexture, "&e" + SlimefunPlugin.getLocal().getResourceString(p, "tooltips.chunk"), "", "&8\u21E8 &7" + SlimefunPlugin.getLocal().getResourceString(p, "tooltips.world") + ": " + block.getWorld().getName(), "&8\u21E8 &7X: " + x + " Z: " + z), ChestMenuUtils.getEmptyClickHandler());
menu.addItem(4, new CustomItem(SlimefunUtils.getCustomHead(HeadTexture.MINECRAFT_CHUNK.getTexture()), ChatColor.YELLOW + SlimefunPlugin.getLocalization().getResourceString(p, "tooltips.chunk"), "", "&8\u21E8 &7" + SlimefunPlugin.getLocalization().getResourceString(p, "tooltips.world") + ": " + block.getWorld().getName(), "&8\u21E8 &7X: " + x + " Z: " + z), ChestMenuUtils.getEmptyClickHandler());
List<GEOResource> resources = new ArrayList<>(SlimefunPlugin.getRegistry().getGEOResources().values());
Collections.sort(resources, (a, b) -> a.getName(p).toLowerCase(Locale.ROOT).compareTo(b.getName(p).toLowerCase(Locale.ROOT)));
@ -157,9 +183,9 @@ public class ResourceManager {
GEOResource resource = resources.get(i);
OptionalInt optional = getSupplies(resource, block.getWorld(), x, z);
int supplies = optional.isPresent() ? optional.getAsInt() : generate(resource, block.getWorld(), x, z);
String suffix = SlimefunPlugin.getLocal().getResourceString(p, supplies == 1 ? "tooltips.unit" : "tooltips.units");
String suffix = SlimefunPlugin.getLocalization().getResourceString(p, supplies == 1 ? "tooltips.unit" : "tooltips.units");
ItemStack item = new CustomItem(resource.getItem(), "&r" + resource.getName(p), "&8\u21E8 &e" + supplies + ' ' + suffix);
ItemStack item = new CustomItem(resource.getItem(), "&f" + resource.getName(p), "&8\u21E8 &e" + supplies + ' ' + suffix);
if (supplies > 1) {
item.setAmount(supplies > item.getMaxStackSize() ? item.getMaxStackSize() : supplies);

View File

@ -26,12 +26,12 @@ import io.github.thebusybiscuit.slimefun4.api.geo.GEOResource;
import io.github.thebusybiscuit.slimefun4.api.geo.ResourceManager;
import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.items.gps.GPSTransmitter;
import io.github.thebusybiscuit.slimefun4.implementation.items.gps.Teleporter;
import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils;
import io.github.thebusybiscuit.slimefun4.utils.HeadTexture;
import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.api.BlockStorage;
import me.mrCookieSlime.Slimefun.api.Slimefun;
@ -54,7 +54,7 @@ public class GPSNetwork {
private final Map<UUID, Set<Location>> transmitters = new HashMap<>();
private final TeleportationManager teleportation = new TeleportationManager();
private final ResourceManager resourceManager = new ResourceManager(SlimefunPlugin.instance);
private final ResourceManager resourceManager = new ResourceManager(SlimefunPlugin.instance());
/**
* This method updates the status of a {@link GPSTransmitter}.
@ -123,24 +123,24 @@ public class GPSNetwork {
}
public void openTransmitterControlPanel(Player p) {
ChestMenu menu = new ChestMenu(ChatColor.BLUE + SlimefunPlugin.getLocal().getMessage(p, "machines.GPS_CONTROL_PANEL.title"));
ChestMenu menu = new ChestMenu(ChatColor.BLUE + SlimefunPlugin.getLocalization().getMessage(p, "machines.GPS_CONTROL_PANEL.title"));
for (int slot : border) {
menu.addItem(slot, ChestMenuUtils.getBackground(), ChestMenuUtils.getEmptyClickHandler());
}
menu.addItem(2, new CustomItem(SlimefunItems.GPS_TRANSMITTER, im -> {
im.setDisplayName(ChatColor.GRAY + SlimefunPlugin.getLocal().getMessage(p, "machines.GPS_CONTROL_PANEL.transmitters"));
im.setDisplayName(ChatColor.GRAY + SlimefunPlugin.getLocalization().getMessage(p, "machines.GPS_CONTROL_PANEL.transmitters"));
im.setLore(null);
}));
menu.addMenuClickHandler(2, ChestMenuUtils.getEmptyClickHandler());
int complexity = getNetworkComplexity(p.getUniqueId());
menu.addItem(4, new CustomItem(SlimefunItems.GPS_CONTROL_PANEL, "&7Network Info", "", "&8\u21E8 &7Status: " + (complexity > 0 ? "&2&lONLINE" : "&4&lOFFLINE"), "&8\u21E8 &7Complexity: &r" + complexity));
menu.addItem(4, new CustomItem(SlimefunItems.GPS_CONTROL_PANEL, "&7Network Info", "", "&8\u21E8 &7Status: " + (complexity > 0 ? "&2&lONLINE" : "&4&lOFFLINE"), "&8\u21E8 &7Complexity: &f" + complexity));
menu.addMenuClickHandler(4, ChestMenuUtils.getEmptyClickHandler());
menu.addItem(6, new CustomItem(HeadTexture.GLOBE_OVERWORLD.getAsItemStack(), "&7" + SlimefunPlugin.getLocal().getMessage(p, "machines.GPS_CONTROL_PANEL.waypoints"), "", ChatColor.GRAY + "\u21E8 " + SlimefunPlugin.getLocal().getMessage(p, "guide.tooltips.open-category")));
menu.addItem(6, new CustomItem(HeadTexture.GLOBE_OVERWORLD.getAsItemStack(), "&7" + SlimefunPlugin.getLocalization().getMessage(p, "machines.GPS_CONTROL_PANEL.waypoints"), "", ChatColor.GRAY + "\u21E8 " + SlimefunPlugin.getLocalization().getMessage(p, "guide.tooltips.open-category")));
menu.addMenuClickHandler(6, (pl, slot, item, action) -> {
openWaypointControlPanel(pl);
return false;
@ -154,7 +154,7 @@ public class GPSNetwork {
if (sfi instanceof GPSTransmitter) {
int slot = inventory[index];
menu.addItem(slot, new CustomItem(SlimefunItems.GPS_TRANSMITTER, "&bGPS Transmitter", "&8\u21E8 &7World: &r" + l.getWorld().getName(), "&8\u21E8 &7X: &r" + l.getX(), "&8\u21E8 &7Y: &r" + l.getY(), "&8\u21E8 &7Z: &r" + l.getZ(), "", "&8\u21E8 &7Signal Strength: &r" + ((GPSTransmitter) sfi).getMultiplier(l.getBlockY()), "&8\u21E8 &7Ping: &r" + DoubleHandler.fixDouble(1000D / l.getY()) + "ms"));
menu.addItem(slot, new CustomItem(SlimefunItems.GPS_TRANSMITTER, "&bGPS Transmitter", "&8\u21E8 &7World: &f" + l.getWorld().getName(), "&8\u21E8 &7X: &f" + l.getX(), "&8\u21E8 &7Y: &f" + l.getY(), "&8\u21E8 &7Z: &f" + l.getZ(), "", "&8\u21E8 &7Signal Strength: &f" + ((GPSTransmitter) sfi).getMultiplier(l.getBlockY()), "&8\u21E8 &7Ping: &f" + DoubleHandler.fixDouble(1000D / l.getY()) + "ms"));
menu.addMenuClickHandler(slot, ChestMenuUtils.getEmptyClickHandler());
index++;
@ -196,23 +196,23 @@ public class GPSNetwork {
public void openWaypointControlPanel(Player p) {
PlayerProfile.get(p, profile -> {
ChestMenu menu = new ChestMenu(ChatColor.BLUE + SlimefunPlugin.getLocal().getMessage(p, "machines.GPS_CONTROL_PANEL.title"));
ChestMenu menu = new ChestMenu(ChatColor.BLUE + SlimefunPlugin.getLocalization().getMessage(p, "machines.GPS_CONTROL_PANEL.title"));
for (int slot : border) {
menu.addItem(slot, ChestMenuUtils.getBackground(), ChestMenuUtils.getEmptyClickHandler());
}
menu.addItem(2, new CustomItem(SlimefunItems.GPS_TRANSMITTER, "&7" + SlimefunPlugin.getLocal().getMessage(p, "machines.GPS_CONTROL_PANEL.transmitters"), "", ChatColor.GRAY + "\u21E8 " + SlimefunPlugin.getLocal().getMessage(p, "guide.tooltips.open-category")));
menu.addItem(2, new CustomItem(SlimefunItems.GPS_TRANSMITTER, "&7" + SlimefunPlugin.getLocalization().getMessage(p, "machines.GPS_CONTROL_PANEL.transmitters"), "", ChatColor.GRAY + "\u21E8 " + SlimefunPlugin.getLocalization().getMessage(p, "guide.tooltips.open-category")));
menu.addMenuClickHandler(2, (pl, slot, item, action) -> {
openTransmitterControlPanel(pl);
return false;
});
int complexity = getNetworkComplexity(p.getUniqueId());
menu.addItem(4, new CustomItem(SlimefunItems.GPS_CONTROL_PANEL, "&7Network Info", "", "&8\u21E8 &7Status: " + (complexity > 0 ? "&2&lONLINE" : "&4&lOFFLINE"), "&8\u21E8 &7Complexity: &r" + complexity));
menu.addItem(4, new CustomItem(SlimefunItems.GPS_CONTROL_PANEL, "&7Network Info", "", "&8\u21E8 &7Status: " + (complexity > 0 ? "&2&lONLINE" : "&4&lOFFLINE"), "&8\u21E8 &7Complexity: &f" + complexity));
menu.addMenuClickHandler(4, ChestMenuUtils.getEmptyClickHandler());
menu.addItem(6, new CustomItem(HeadTexture.GLOBE_OVERWORLD.getAsItemStack(), "&7" + SlimefunPlugin.getLocal().getMessage(p, "machines.GPS_CONTROL_PANEL.waypoints")));
menu.addItem(6, new CustomItem(HeadTexture.GLOBE_OVERWORLD.getAsItemStack(), "&7" + SlimefunPlugin.getLocalization().getMessage(p, "machines.GPS_CONTROL_PANEL.waypoints")));
menu.addMenuClickHandler(6, ChestMenuUtils.getEmptyClickHandler());
int index = 0;
@ -221,7 +221,7 @@ public class GPSNetwork {
int slot = inventory[index];
Location l = waypoint.getLocation();
menu.addItem(slot, new CustomItem(waypoint.getIcon(), waypoint.getName().replace("player:death ", ""), "&8\u21E8 &7World: &r" + l.getWorld().getName(), "&8\u21E8 &7X: &r" + l.getX(), "&8\u21E8 &7Y: &r" + l.getY(), "&8\u21E8 &7Z: &r" + l.getZ(), "", "&8\u21E8 &cClick to delete"));
menu.addItem(slot, new CustomItem(waypoint.getIcon(), waypoint.getName().replace("player:death ", ""), "&8\u21E8 &7World: &f" + l.getWorld().getName(), "&8\u21E8 &7X: &f" + l.getX(), "&8\u21E8 &7Y: &f" + l.getY(), "&8\u21E8 &7Z: &f" + l.getZ(), "", "&8\u21E8 &cClick to delete"));
menu.addMenuClickHandler(slot, (pl, s, item, action) -> {
profile.removeWaypoint(waypoint);
pl.playSound(pl.getLocation(), Sound.UI_BUTTON_CLICK, 1F, 1F);
@ -249,14 +249,14 @@ public class GPSNetwork {
public void createWaypoint(Player p, Location l) {
PlayerProfile.get(p, profile -> {
if ((profile.getWaypoints().size() + 2) > inventory.length) {
SlimefunPlugin.getLocal().sendMessage(p, "gps.waypoint.max", true);
SlimefunPlugin.getLocalization().sendMessage(p, "gps.waypoint.max", true);
return;
}
SlimefunPlugin.getLocal().sendMessage(p, "gps.waypoint.new", true);
SlimefunPlugin.getLocalization().sendMessage(p, "gps.waypoint.new", true);
p.playSound(p.getLocation(), Sound.BLOCK_NOTE_BLOCK_PLING, 0.5F, 1F);
ChatInput.waitForPlayer(SlimefunPlugin.instance, p, message -> addWaypoint(p, message, l));
ChatInput.waitForPlayer(SlimefunPlugin.instance(), p, message -> addWaypoint(p, message, l));
});
}
@ -273,7 +273,7 @@ public class GPSNetwork {
public void addWaypoint(Player p, String name, Location l) {
PlayerProfile.get(p, profile -> {
if ((profile.getWaypoints().size() + 2) > inventory.length) {
SlimefunPlugin.getLocal().sendMessage(p, "gps.waypoint.max", true);
SlimefunPlugin.getLocalization().sendMessage(p, "gps.waypoint.max", true);
return;
}
@ -286,7 +286,7 @@ public class GPSNetwork {
profile.addWaypoint(new Waypoint(profile, id, event.getLocation(), event.getName()));
p.playSound(p.getLocation(), Sound.BLOCK_NOTE_BLOCK_PLING, 1F, 1F);
SlimefunPlugin.getLocal().sendMessage(p, "gps.waypoint.added", true);
SlimefunPlugin.getLocalization().sendMessage(p, "gps.waypoint.added", true);
}
});
});

View File

@ -18,10 +18,10 @@ import io.github.thebusybiscuit.cscorelib2.chat.ChatColors;
import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
import io.github.thebusybiscuit.cscorelib2.math.DoubleHandler;
import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils;
import io.github.thebusybiscuit.slimefun4.utils.HeadTexture;
import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.api.Slimefun;
public final class TeleportationManager {
@ -46,7 +46,7 @@ public final class TeleportationManager {
menu.addItem(slot, ChestMenuUtils.getBackground(), ChestMenuUtils.getEmptyClickHandler());
}
menu.addItem(4, new CustomItem(HeadTexture.GLOBE_OVERWORLD.getAsItemStack(), ChatColor.YELLOW + SlimefunPlugin.getLocal().getMessage(p, "machines.TELEPORTER.gui.title")));
menu.addItem(4, new CustomItem(HeadTexture.GLOBE_OVERWORLD.getAsItemStack(), ChatColor.YELLOW + SlimefunPlugin.getLocalization().getMessage(p, "machines.TELEPORTER.gui.title")));
menu.addMenuClickHandler(4, ChestMenuUtils.getEmptyClickHandler());
Location source = new Location(b.getWorld(), b.getX() + 0.5D, b.getY() + 2D, b.getZ() + 0.5D);
@ -61,7 +61,7 @@ public final class TeleportationManager {
Location l = waypoint.getLocation();
menu.addItem(slot,
new CustomItem(waypoint.getIcon(), waypoint.getName().replace("player:death ", ""), "", "&8\u21E8 &7" + SlimefunPlugin.getLocal().getResourceString(p, "tooltips.world") + ": &r" + l.getWorld().getName(), "&8\u21E8 &7X: &r" + l.getX(), "&8\u21E8 &7Y: &r" + l.getY(), "&8\u21E8 &7Z: &r" + l.getZ(), "&8\u21E8 &7" + SlimefunPlugin.getLocal().getMessage(p, "machines.TELEPORTER.gui.time") + ": &r" + DoubleHandler.fixDouble(0.5 * getTeleportationTime(complexity, source, l)) + "s", "", "&8\u21E8 &c" + SlimefunPlugin.getLocal().getMessage(p, "machines.TELEPORTER.gui.tooltip")));
new CustomItem(waypoint.getIcon(), waypoint.getName().replace("player:death ", ""), "", "&8\u21E8 &7" + SlimefunPlugin.getLocalization().getResourceString(p, "tooltips.world") + ": &f" + l.getWorld().getName(), "&8\u21E8 &7X: &f" + l.getX(), "&8\u21E8 &7Y: &f" + l.getY(), "&8\u21E8 &7Z: &f" + l.getZ(), "&8\u21E8 &7" + SlimefunPlugin.getLocalization().getMessage(p, "machines.TELEPORTER.gui.time") + ": &f" + DoubleHandler.fixDouble(0.5 * getTeleportationTime(complexity, source, l)) + "s", "", "&8\u21E8 &c" + SlimefunPlugin.getLocalization().getMessage(p, "machines.TELEPORTER.gui.tooltip")));
menu.addMenuClickHandler(slot, (pl, s, item, action) -> {
pl.closeInventory();
teleport(pl.getUniqueId(), complexity, source, l, false);
@ -107,7 +107,7 @@ public final class TeleportationManager {
teleporterUsers.remove(uuid);
if (p != null) {
p.sendTitle(ChatColors.color(SlimefunPlugin.getLocal().getMessage(p, "machines.TELEPORTER.cancelled")), ChatColors.color("&c&k40&r&c%"), 20, 60, 20);
p.sendTitle(ChatColors.color(SlimefunPlugin.getLocalization().getMessage(p, "machines.TELEPORTER.cancelled")), ChatColors.color("&c&k40&f&c%"), 20, 60, 20);
}
}
@ -116,12 +116,12 @@ public final class TeleportationManager {
if (isValid(p, source)) {
if (progress > 99) {
p.sendTitle(ChatColors.color(SlimefunPlugin.getLocal().getMessage(p, "machines.TELEPORTER.teleported")), ChatColors.color("&b100%"), 20, 60, 20);
p.sendTitle(ChatColors.color(SlimefunPlugin.getLocalization().getMessage(p, "machines.TELEPORTER.teleported")), ChatColors.color("&b100%"), 20, 60, 20);
p.teleport(destination);
if (resistance) {
p.addPotionEffect(new PotionEffect(PotionEffectType.DAMAGE_RESISTANCE, 600, 20));
SlimefunPlugin.getLocal().sendMessage(p, "machines.TELEPORTER.invulnerability");
SlimefunPlugin.getLocalization().sendMessage(p, "machines.TELEPORTER.invulnerability");
}
destination.getWorld().spawnParticle(Particle.PORTAL, new Location(destination.getWorld(), destination.getX(), destination.getY() + 1, destination.getZ()), progress * 2, 0.2F, 0.8F, 0.2F);
@ -129,7 +129,7 @@ public final class TeleportationManager {
teleporterUsers.remove(uuid);
}
else {
p.sendTitle(ChatColors.color(SlimefunPlugin.getLocal().getMessage(p, "machines.TELEPORTER.teleporting")), ChatColors.color("&b" + progress + "%"), 0, 60, 0);
p.sendTitle(ChatColors.color(SlimefunPlugin.getLocalization().getMessage(p, "machines.TELEPORTER.teleporting")), ChatColors.color("&b" + progress + "%"), 0, 60, 0);
source.getWorld().spawnParticle(Particle.PORTAL, source, progress * 2, 0.2F, 0.8F, 0.2F);
source.getWorld().playSound(source, Sound.BLOCK_BEACON_AMBIENT, 1F, 0.6F);

View File

@ -9,8 +9,8 @@ import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.slimefun4.api.events.WaypointCreateEvent;
import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.items.gps.Teleporter;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
/**
* A {@link Waypoint} represents a named {@link Location} that was created by a {@link Player}.

View File

@ -78,7 +78,7 @@ public final class HashedArmorpiece {
*/
public boolean hasDiverged(ItemStack stack) {
if (stack == null || stack.getType() == Material.AIR) {
return hash == 0;
return hash != 0;
}
else {
ItemStack copy = stack.clone();

View File

@ -5,7 +5,7 @@ import java.util.logging.Level;
import org.apache.commons.lang.Validate;
import io.github.thebusybiscuit.cscorelib2.config.Config;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.api.Slimefun;

View File

@ -8,6 +8,7 @@ import java.util.Set;
import org.apache.commons.lang.Validate;
import org.bukkit.Color;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Particle;
import org.bukkit.Particle.DustOptions;
@ -26,6 +27,34 @@ import me.mrCookieSlime.Slimefun.api.Slimefun;
*/
public abstract class Network {
private final NetworkManager manager;
protected Location regulator;
private Queue<Location> nodeQueue = new ArrayDeque<>();
protected final Set<Location> connectedLocations = new HashSet<>();
protected final Set<Location> regulatorNodes = new HashSet<>();
protected final Set<Location> connectorNodes = new HashSet<>();
protected final Set<Location> terminusNodes = new HashSet<>();
/**
* This constructs a new {@link Network} at the given {@link Location}.
*
* @param manager
* The {@link NetworkManager} instance
* @param regulator
* The {@link Location} marking the regulator of this {@link Network}.
*/
protected Network(NetworkManager manager, Location regulator) {
Validate.notNull(manager, "A NetworkManager must be provided");
Validate.notNull(regulator, "No regulator was specified");
this.manager = manager;
this.regulator = regulator;
connectedLocations.add(regulator);
nodeQueue.add(regulator.clone());
}
/**
* This method returns the range of the {@link Network}.
* The range determines how far the {@link Network} will search for
@ -60,34 +89,6 @@ public abstract class Network {
*/
public abstract void onClassificationChange(Location l, NetworkComponent from, NetworkComponent to);
protected Location regulator;
private Queue<Location> nodeQueue = new ArrayDeque<>();
private final NetworkManager manager;
protected final Set<Location> connectedLocations = new HashSet<>();
protected final Set<Location> regulatorNodes = new HashSet<>();
protected final Set<Location> connectorNodes = new HashSet<>();
protected final Set<Location> terminusNodes = new HashSet<>();
/**
* This constructs a new {@link Network} at the given {@link Location}.
*
* @param manager
* The {@link NetworkManager} instance
* @param regulator
* The {@link Location} marking the regulator of this {@link Network}.
*/
protected Network(NetworkManager manager, Location regulator) {
Validate.notNull(manager, "A NetworkManager must be provided");
Validate.notNull(regulator, "No regulator was specified");
this.manager = manager;
this.regulator = regulator;
connectedLocations.add(regulator);
nodeQueue.add(regulator.clone());
}
/**
* This returns the size of this {@link Network}. It is equivalent to the amount
* of {@link Location Locations} connected to this {@link Network}.
@ -208,18 +209,26 @@ public abstract class Network {
/**
* This method runs the network visualizer which displays a {@link Particle} on
* every {@link Location} that this {@link Network} can connect to.
* every {@link Location} that this {@link Network} is connected to.
*/
public void display() {
Slimefun.runSync(() -> {
DustOptions options = new DustOptions(Color.BLUE, 2F);
DustOptions options = new DustOptions(Color.BLUE, 3F);
for (Location l : connectedLocations) {
l.getWorld().spawnParticle(Particle.REDSTONE, l.getX() + 0.5, l.getY() + 0.5, l.getZ() + 0.5, 1, 0, 0, 0, 1, options);
Material type = l.getBlock().getType();
if (type == Material.PLAYER_HEAD || type == Material.PLAYER_WALL_HEAD) {
l.getWorld().spawnParticle(Particle.REDSTONE, l.getX() + 0.5, l.getY() + 0.5, l.getZ() + 0.5, 1, 0, 0, 0, 1, options);
}
}
});
}
public Location getRegulator() {
return regulator;
}
public void tick() {
discoverStep();
}

View File

@ -19,6 +19,7 @@ import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.NamespacedKey;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@ -31,11 +32,14 @@ import io.github.thebusybiscuit.cscorelib2.chat.ChatColors;
import io.github.thebusybiscuit.cscorelib2.config.Config;
import io.github.thebusybiscuit.slimefun4.api.gps.Waypoint;
import io.github.thebusybiscuit.slimefun4.api.items.HashedArmorpiece;
import io.github.thebusybiscuit.slimefun4.core.attributes.ProtectiveArmor;
import io.github.thebusybiscuit.slimefun4.core.attributes.ProtectionType;
import io.github.thebusybiscuit.slimefun4.core.guide.GuideHistory;
import io.github.thebusybiscuit.slimefun4.core.researching.Research;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.items.armor.SlimefunArmorPiece;
import io.github.thebusybiscuit.slimefun4.utils.NumberUtils;
import io.github.thebusybiscuit.slimefun4.utils.PatternUtils;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.api.Slimefun;
/**
@ -47,6 +51,7 @@ import me.mrCookieSlime.Slimefun.api.Slimefun;
* @see Research
* @see Waypoint
* @see PlayerBackpack
* @see HashedArmorpiece
*
*/
public final class PlayerProfile {
@ -367,7 +372,7 @@ public final class PlayerProfile {
return true;
}
Bukkit.getScheduler().runTaskAsynchronously(SlimefunPlugin.instance, () -> {
Bukkit.getScheduler().runTaskAsynchronously(SlimefunPlugin.instance(), () -> {
PlayerProfile pp = new PlayerProfile(p);
SlimefunPlugin.getRegistry().getPlayerProfiles().put(uuid, pp);
callback.accept(pp);
@ -388,7 +393,7 @@ public final class PlayerProfile {
public static boolean request(OfflinePlayer p) {
if (!SlimefunPlugin.getRegistry().getPlayerProfiles().containsKey(p.getUniqueId())) {
// Should probably prevent multiple requests for the same profile in the future
Bukkit.getScheduler().runTaskAsynchronously(SlimefunPlugin.instance, () -> {
Bukkit.getScheduler().runTaskAsynchronously(SlimefunPlugin.instance(), () -> {
PlayerProfile pp = new PlayerProfile(p);
SlimefunPlugin.getRegistry().getPlayerProfiles().put(p.getUniqueId(), pp);
});
@ -448,6 +453,41 @@ public final class PlayerProfile {
}
}
public boolean hasFullProtectionAgainst(ProtectionType type) {
int armorCount = 0;
NamespacedKey setId = null;
for (HashedArmorpiece armorpiece : armor) {
Optional<SlimefunArmorPiece> armorPiece = armorpiece.getItem();
if (!armorPiece.isPresent()) {
return false;
}
if (armorPiece.get() instanceof ProtectiveArmor) {
ProtectiveArmor protectedArmor = (ProtectiveArmor) armorPiece.get();
if (setId == null && protectedArmor.isFullSetRequired()) {
setId = protectedArmor.getArmorSetId();
}
for (ProtectionType protectionType : protectedArmor.getProtectionTypes()) {
if (protectionType == type) {
if (setId == null) {
return true;
}
else if (setId.equals(protectedArmor.getArmorSetId())) {
armorCount++;
}
}
}
}
}
return armorCount == 4;
}
@Override
public int hashCode() {
return uuid.hashCode();

View File

@ -10,7 +10,6 @@ import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import org.bukkit.Location;
import org.bukkit.Server;
@ -19,6 +18,7 @@ import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.cscorelib2.collections.KeyMap;
import io.github.thebusybiscuit.cscorelib2.config.Config;
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
import io.github.thebusybiscuit.slimefun4.api.geo.GEOResource;
import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile;
import io.github.thebusybiscuit.slimefun4.core.attributes.WitherProof;
@ -26,6 +26,7 @@ import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideImplementation
import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideLayout;
import io.github.thebusybiscuit.slimefun4.core.multiblocks.MultiBlock;
import io.github.thebusybiscuit.slimefun4.core.researching.Research;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.guide.BookSlimefunGuide;
import io.github.thebusybiscuit.slimefun4.implementation.guide.CheatSheetSlimefunGuide;
import io.github.thebusybiscuit.slimefun4.implementation.guide.ChestSlimefunGuide;
@ -76,8 +77,8 @@ public class SlimefunRegistry {
private final Set<String> chargeableBlocks = new HashSet<>();
private final Map<String, WitherProof> witherProofBlocks = new HashMap<>();
private final ConcurrentMap<UUID, PlayerProfile> profiles = new ConcurrentHashMap<>();
private final Map<String, BlockStorage> worlds = new HashMap<>();
private final Map<UUID, PlayerProfile> profiles = new ConcurrentHashMap<>();
private final Map<String, BlockStorage> worlds = new ConcurrentHashMap<>();
private final Map<String, BlockInfoConfig> chunks = new HashMap<>();
private final Map<SlimefunGuideLayout, SlimefunGuideImplementation> layouts = new EnumMap<>(SlimefunGuideLayout.class);
private final Map<EntityType, Set<ItemStack>> drops = new EnumMap<>(EntityType.class);
@ -100,7 +101,7 @@ public class SlimefunRegistry {
researchRanks.addAll(cfg.getStringList("research-ranks"));
backwardsCompatibility = cfg.getBoolean("options.backwards-compatibility");
backwardsCompatibility = cfg.getBoolean("options.backwards-compatibility") || SlimefunPlugin.getMinecraftVersion().isBefore(MinecraftVersion.MINECRAFT_1_14);
freeCreativeResearches = cfg.getBoolean("researches.free-in-creative-mode");
researchFireworks = cfg.getBoolean("researches.enable-fireworks");
}
@ -234,7 +235,7 @@ public class SlimefunRegistry {
return universalInventories;
}
public ConcurrentMap<UUID, PlayerProfile> getPlayerProfiles() {
public Map<UUID, PlayerProfile> getPlayerProfiles() {
return profiles;
}

View File

@ -2,7 +2,7 @@ package io.github.thebusybiscuit.slimefun4.core.attributes;
import io.github.thebusybiscuit.slimefun4.core.networks.energy.EnergyNet;
import io.github.thebusybiscuit.slimefun4.core.networks.energy.EnergyNetComponentType;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
/**

View File

@ -0,0 +1,26 @@
package io.github.thebusybiscuit.slimefun4.core.attributes;
import org.bukkit.entity.Bee;
/**
* Represents the {@link ProtectionType} that a {@link ProtectiveArmor}
* prevents the damage from.
*
* @author Linox
*
* @see ProtectiveArmor
*
*/
public enum ProtectionType {
/**
* This damage type represents damage inflicted by {@link Radioactive} materials.
*/
RADIATION,
/**
* This damage type represents damage caused by a {@link Bee}
*/
BEES;
}

View File

@ -0,0 +1,48 @@
package io.github.thebusybiscuit.slimefun4.core.attributes;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Player;
import io.github.thebusybiscuit.slimefun4.implementation.items.armor.HazmatArmorPiece;
import io.github.thebusybiscuit.slimefun4.implementation.items.armor.SlimefunArmorPiece;
/**
* Implement this interface to a {@link SlimefunArmorPiece} to protect
* the {@link Player} who wears that {@link SlimefunArmorPiece} from
* {@link ProtectionType} damage.
*
* <b>Important:</b> You need to specify which {@link ProtectionType} damages
* to protect the {@link Player} from.
*
* @author Linox
*
* @see SlimefunArmorPiece
* @see HazmatArmorPiece
* @see ItemAttribute
*
*/
public interface ProtectiveArmor extends ItemAttribute {
/**
* This returns which {@link ProtectionType} damages this {@link ItemAttribute}
* will protect the {@link Player} from.
*
* @return The {@link ProtectionType}s.
*/
ProtectionType[] getProtectionTypes();
/**
* This returns whether the full set is required for {@link Player}'s protection on
* assigned {@link ProtectionType} damages.
*
* @return Whether or not he full set is required.
*/
boolean isFullSetRequired();
/**
* This returns the armor set {@link NamespacedKey} of this {@link SlimefunArmorPiece}.
*
* @return The set {@link NamespacedKey}, <code>null</code> if none is found.
*/
NamespacedKey getArmorSetId();
}

View File

@ -0,0 +1,35 @@
package io.github.thebusybiscuit.slimefun4.core.attributes;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.event.entity.EntityDeathEvent;
import io.github.thebusybiscuit.slimefun4.implementation.items.misc.BasicCircuitBoard;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.MobDropListener;
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
/**
* This interface, when attached to a {@link SlimefunItem}, provides an easy method for adding
* a % chance to drop for an {@link SlimefunItem} on {@link EntityDeathEvent}, this chance is 0-100
* and used in conjunction with the MOB_DROP {@link RecipeType}.
*
* @author dNiym
*
* @see BasicCircuitBoard
* @see MobDropListener
*
*/
@FunctionalInterface
public interface RandomMobDrop extends ItemAttribute {
/**
* Implement this method to make the object have a variable chance of being
* added to the dropList when {@link EntityType} (specified in the recipe)
* is killed by the {@link Player}
*
* @return The integer chance (0-100%) {@link SlimefunItem} has to drop.
*/
int getMobDropChance();
}

View File

@ -0,0 +1,150 @@
package io.github.thebusybiscuit.slimefun4.core.attributes;
import org.apache.commons.lang.Validate;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import io.github.thebusybiscuit.slimefun4.core.networks.energy.EnergyNet;
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.gadgets.Jetpack;
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.gadgets.MultiTool;
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.ChargingBench;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
/**
* A {@link Rechargeable} {@link SlimefunItem} can hold energy and is able to
* be recharged using a {@link ChargingBench}.
* Any {@link SlimefunItem} which is supposed to be chargeable <b>must</b> implement this interface.
*
* @author TheBusyBiscuit
*
* @see ChargingBench
* @see EnergyNet
* @see Jetpack
* @see MultiTool
*
*/
@FunctionalInterface
public interface Rechargeable extends ItemAttribute {
/**
* This method returns the maximum charge the given {@link ItemStack} is capable of holding.
*
* @param item
* The {@link ItemStack} for which to determine the maximum charge
*
* @return The maximum energy charge for this {@link ItemStack}
*/
float getMaxItemCharge(ItemStack item);
/**
* This method sets the stored energy charge for a given {@link ItemStack}.
* The charge must be at least zero and at most {@link #getMaxItemCharge(ItemStack)}.
*
* @param item
* The {@link ItemStack} to charge
* @param charge
* The amount of charge to store
*/
default void setItemCharge(ItemStack item, float charge) {
if (item == null || item.getType() == Material.AIR) {
throw new IllegalArgumentException("Cannot set Item charge for null or AIR");
}
float maximum = getMaxItemCharge(item);
if (charge < 0 || charge > maximum) {
throw new IllegalArgumentException("Charge must be between zero and " + maximum + ".");
}
ItemMeta meta = item.getItemMeta();
RechargeableHelper.setCharge(meta, charge, maximum);
item.setItemMeta(meta);
}
/**
* This method returns the currently stored energy charge on the provided {@link ItemStack}.
*
* @param item
* The {@link ItemStack} to get the charge from
*
* @return The charge stored on this {@link ItemStack}
*/
default float getItemCharge(ItemStack item) {
if (item == null || item.getType() == Material.AIR) {
throw new IllegalArgumentException("Cannot get Item charge for null or AIR");
}
return RechargeableHelper.getCharge(item.getItemMeta());
}
/**
* This method adds the given charge to the provided {@link ItemStack}.
* The method will also return whether this operation was successful.
* If the {@link ItemStack} is already at maximum charge, the method will return <code>false</code>.
*
* @param item
* The {@link ItemStack} to charge
* @param charge
* The amount of charge to add
*
* @return Whether the given charge could be added successfully
*/
default boolean addItemCharge(ItemStack item, float charge) {
Validate.isTrue(charge > 0, "Charge must be above zero!");
if (item == null || item.getType() == Material.AIR) {
throw new IllegalArgumentException("Cannot add Item charge for null or AIR");
}
ItemMeta meta = item.getItemMeta();
float currentCharge = RechargeableHelper.getCharge(meta);
float maximum = getMaxItemCharge(item);
// If the item is already fully charged, we abort.
if (currentCharge >= maximum) {
return false;
}
float newCharge = Math.min(currentCharge + charge, maximum);
RechargeableHelper.setCharge(meta, newCharge, maximum);
item.setItemMeta(meta);
return true;
}
/**
* This method removes the given charge to the provided {@link ItemStack}.
* The method will also return whether this operation was successful.
* If the {@link ItemStack} does not have enough charge, the method will return <code>false</code>.
*
* @param item
* The {@link ItemStack} to remove the charge from
* @param charge
* The amount of charge to remove
*
* @return Whether the given charge could be removed successfully
*/
default boolean removeItemCharge(ItemStack item, float charge) {
Validate.isTrue(charge > 0, "Charge must be above zero!");
if (item == null || item.getType() == Material.AIR) {
throw new IllegalArgumentException("Cannot remove Item charge for null or AIR");
}
ItemMeta meta = item.getItemMeta();
float currentCharge = RechargeableHelper.getCharge(meta);
// If the item does not have enough charge, we abort
if (currentCharge < charge) {
return false;
}
float newCharge = Math.max(currentCharge - charge, 0);
RechargeableHelper.setCharge(meta, newCharge, getMaxItemCharge(item));
item.setItemMeta(meta);
return true;
}
}

View File

@ -0,0 +1,82 @@
package io.github.thebusybiscuit.slimefun4.core.attributes;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
import org.bukkit.NamespacedKey;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataType;
import io.github.thebusybiscuit.cscorelib2.chat.ChatColors;
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.utils.PatternUtils;
import net.md_5.bungee.api.ChatColor;
/**
* This is just a simple helper class to provide static methods to the {@link Rechargeable}
* interface.
*
* @author TheBusyBiscuit
*
* @see Rechargeable
*
*/
final class RechargeableHelper {
private static final NamespacedKey CHARGE_KEY = new NamespacedKey(SlimefunPlugin.instance(), "item_charge");
private static final String LORE_PREFIX = ChatColors.color("&8\u21E8 &e\u26A1 &7");
private static final Pattern REGEX = Pattern.compile(ChatColors.color("(&c&o)?" + LORE_PREFIX) + "[0-9\\.]+ \\/ [0-9\\.]+ J");
private RechargeableHelper() {}
static void setCharge(ItemMeta meta, float charge, float capacity) {
BigDecimal decimal = BigDecimal.valueOf(charge).setScale(2, RoundingMode.HALF_UP);
float value = decimal.floatValue();
if (SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_14)) {
meta.getPersistentDataContainer().set(CHARGE_KEY, PersistentDataType.FLOAT, value);
}
List<String> lore = meta.hasLore() ? meta.getLore() : new ArrayList<>();
for (int i = 0; i < lore.size(); i++) {
String line = lore.get(i);
if (REGEX.matcher(line).matches()) {
lore.set(i, LORE_PREFIX + value + " / " + capacity + " J");
meta.setLore(lore);
return;
}
}
lore.add(LORE_PREFIX + value + " / " + capacity + " J");
meta.setLore(lore);
}
static float getCharge(ItemMeta meta) {
if (SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_14)) {
Float value = meta.getPersistentDataContainer().get(CHARGE_KEY, PersistentDataType.FLOAT);
// If persistent data is available, we just return this value
if (value != null) {
return value;
}
}
// If no persistent data exists, we will just fall back to the lore
if (meta.hasLore()) {
for (String line : meta.getLore()) {
if (REGEX.matcher(line).matches()) {
String data = ChatColor.stripColor(PatternUtils.SLASH_SEPARATOR.split(line)[0].replace(LORE_PREFIX, ""));
return Float.parseFloat(data);
}
}
}
return 0;
}
}

View File

@ -6,9 +6,9 @@ import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuide;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.items.geo.GEOMiner;
import io.github.thebusybiscuit.slimefun4.implementation.items.tools.GoldPan;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AGenerator;
@ -45,6 +45,6 @@ public interface RecipeDisplayItem extends ItemAttribute {
}
default String getRecipeSectionLabel(Player p) {
return "&7\u21E9 " + SlimefunPlugin.getLocal().getMessage(p, getLabelLocalPath()) + " \u21E9";
return "&7\u21E9 " + SlimefunPlugin.getLocalization().getMessage(p, getLabelLocalPath()) + " \u21E9";
}
}

View File

@ -12,7 +12,7 @@ import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.api.Slimefun;

View File

@ -15,7 +15,7 @@ import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import io.github.thebusybiscuit.cscorelib2.chat.ChatColors;
import io.github.thebusybiscuit.slimefun4.core.commands.subcommands.Commands;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
/**
* This {@link CommandExecutor} holds the functionality of our {@code /slimefun} command.

View File

@ -12,7 +12,7 @@ import org.bukkit.command.CommandSender;
import org.bukkit.command.TabCompleter;
import io.github.thebusybiscuit.slimefun4.core.researching.Research;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
class SlimefunTabCompleter implements TabCompleter {

View File

@ -7,7 +7,7 @@ import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import io.github.thebusybiscuit.slimefun4.core.services.localization.Language;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
/**
* This class represents a {@link SubCommand}, it is a {@link Command} that starts with
@ -53,10 +53,10 @@ public abstract class SubCommand {
*/
public String getDescription(CommandSender sender) {
if (sender instanceof Player) {
return SlimefunPlugin.getLocal().getMessage((Player) sender, getDescription());
return SlimefunPlugin.getLocalization().getMessage((Player) sender, getDescription());
}
else {
return SlimefunPlugin.getLocal().getMessage(getDescription());
return SlimefunPlugin.getLocalization().getMessage(getDescription());
}
}

View File

@ -10,8 +10,8 @@ import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile;
import io.github.thebusybiscuit.slimefun4.core.commands.SlimefunCommand;
import io.github.thebusybiscuit.slimefun4.core.commands.SubCommand;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.utils.PatternUtils;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.api.Slimefun;
class BackpackCommand extends SubCommand {
@ -38,17 +38,17 @@ class BackpackCommand extends SubCommand {
@Override
public void onExecute(CommandSender sender, String[] args) {
if (!(sender instanceof Player) || !sender.hasPermission("slimefun.command.backpack")) {
SlimefunPlugin.getLocal().sendMessage(sender, "messages.no-permission", true);
SlimefunPlugin.getLocalization().sendMessage(sender, "messages.no-permission", true);
return;
}
if (args.length != 3) {
SlimefunPlugin.getLocal().sendMessage(sender, "messages.usage", true, msg -> msg.replace("%usage%", "/sf backpack <Player> <ID>"));
SlimefunPlugin.getLocalization().sendMessage(sender, "messages.usage", true, msg -> msg.replace("%usage%", "/sf backpack <Player> <ID>"));
return;
}
if (!PatternUtils.NUMERIC.matcher(args[2]).matches()) {
SlimefunPlugin.getLocal().sendMessage(sender, "commands.backpack.invalid-id");
SlimefunPlugin.getLocalization().sendMessage(sender, "commands.backpack.invalid-id");
return;
}
@ -56,7 +56,7 @@ class BackpackCommand extends SubCommand {
OfflinePlayer backpackOwner = Bukkit.getOfflinePlayer(args[1]);
if (!(backpackOwner instanceof Player) && !backpackOwner.hasPlayedBefore()) {
SlimefunPlugin.getLocal().sendMessage(sender, "commands.backpack.player-never-joined");
SlimefunPlugin.getLocalization().sendMessage(sender, "commands.backpack.player-never-joined");
return;
}
@ -64,7 +64,7 @@ class BackpackCommand extends SubCommand {
PlayerProfile.get(backpackOwner, profile -> {
if (!profile.getBackpack(id).isPresent()) {
SlimefunPlugin.getLocal().sendMessage(sender, "commands.backpack.backpack-does-not-exist");
SlimefunPlugin.getLocalization().sendMessage(sender, "commands.backpack.backpack-does-not-exist");
return;
}
@ -72,7 +72,7 @@ class BackpackCommand extends SubCommand {
ItemStack item = SlimefunItems.RESTORED_BACKPACK.clone();
SlimefunPlugin.getBackpackListener().setBackpackId(backpackOwner, item, 2, id);
((Player) sender).getInventory().addItem(item);
SlimefunPlugin.getLocal().sendMessage(sender, "commands.backpack.restored-backpack-given");
SlimefunPlugin.getLocalization().sendMessage(sender, "commands.backpack.restored-backpack-given");
});
});
}

View File

@ -6,7 +6,7 @@ import org.bukkit.entity.Player;
import io.github.thebusybiscuit.slimefun4.core.commands.SlimefunCommand;
import io.github.thebusybiscuit.slimefun4.core.commands.SubCommand;
import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuide;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
class CheatCommand extends SubCommand {
@ -31,11 +31,11 @@ class CheatCommand extends SubCommand {
SlimefunGuide.openCheatMenu((Player) sender);
}
else {
SlimefunPlugin.getLocal().sendMessage(sender, "messages.no-permission", true);
SlimefunPlugin.getLocalization().sendMessage(sender, "messages.no-permission", true);
}
}
else {
SlimefunPlugin.getLocal().sendMessage(sender, "messages.only-players", true);
SlimefunPlugin.getLocalization().sendMessage(sender, "messages.only-players", true);
}
}

View File

@ -4,7 +4,7 @@ import java.util.Collection;
import io.github.thebusybiscuit.slimefun4.core.commands.SlimefunCommand;
import io.github.thebusybiscuit.slimefun4.core.commands.SubCommand;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
public final class Commands {

View File

@ -6,7 +6,7 @@ import org.bukkit.entity.Player;
import io.github.thebusybiscuit.slimefun4.core.commands.SlimefunCommand;
import io.github.thebusybiscuit.slimefun4.core.commands.SubCommand;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
class DebugFishCommand extends SubCommand {
@ -30,7 +30,7 @@ class DebugFishCommand extends SubCommand {
((Player) sender).getInventory().addItem(SlimefunItems.DEBUG_FISH);
}
else {
SlimefunPlugin.getLocal().sendMessage(sender, "messages.no-permission", true);
SlimefunPlugin.getLocalization().sendMessage(sender, "messages.no-permission", true);
}
}

View File

@ -11,8 +11,8 @@ import io.github.thebusybiscuit.cscorelib2.players.PlayerList;
import io.github.thebusybiscuit.slimefun4.core.commands.SlimefunCommand;
import io.github.thebusybiscuit.slimefun4.core.commands.SubCommand;
import io.github.thebusybiscuit.slimefun4.core.multiblocks.MultiBlockMachine;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.utils.PatternUtils;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
class GiveCommand extends SubCommand {
@ -50,36 +50,36 @@ class GiveCommand extends SubCommand {
giveItem(sender, p, sfItem, args);
}
else {
SlimefunPlugin.getLocal().sendMessage(sender, "messages.not-valid-item", true, msg -> msg.replace(PLACEHOLDER_ITEM, args[2]));
SlimefunPlugin.getLocalization().sendMessage(sender, "messages.not-valid-item", true, msg -> msg.replace(PLACEHOLDER_ITEM, args[2]));
}
}
else {
SlimefunPlugin.getLocal().sendMessage(sender, "messages.not-online", true, msg -> msg.replace(PLACEHOLDER_PLAYER, args[1]));
SlimefunPlugin.getLocalization().sendMessage(sender, "messages.not-online", true, msg -> msg.replace(PLACEHOLDER_PLAYER, args[1]));
}
}
else {
SlimefunPlugin.getLocal().sendMessage(sender, "messages.usage", true, msg -> msg.replace("%usage%", "/sf give <Player> <Slimefun Item> [Amount]"));
SlimefunPlugin.getLocalization().sendMessage(sender, "messages.usage", true, msg -> msg.replace("%usage%", "/sf give <Player> <Slimefun Item> [Amount]"));
}
}
else {
SlimefunPlugin.getLocal().sendMessage(sender, "messages.no-permission", true);
SlimefunPlugin.getLocalization().sendMessage(sender, "messages.no-permission", true);
}
}
private void giveItem(CommandSender sender, Player p, SlimefunItem sfItem, String[] args) {
if (sfItem instanceof MultiBlockMachine) {
SlimefunPlugin.getLocal().sendMessage(sender, "guide.cheat.no-multiblocks");
SlimefunPlugin.getLocalization().sendMessage(sender, "guide.cheat.no-multiblocks");
}
else {
int amount = parseAmount(args);
if (amount > 0) {
SlimefunPlugin.getLocal().sendMessage(p, "messages.given-item", true, msg -> msg.replace(PLACEHOLDER_ITEM, sfItem.getItemName()).replace(PLACEHOLDER_AMOUNT, String.valueOf(amount)));
SlimefunPlugin.getLocalization().sendMessage(p, "messages.given-item", true, msg -> msg.replace(PLACEHOLDER_ITEM, sfItem.getItemName()).replace(PLACEHOLDER_AMOUNT, String.valueOf(amount)));
p.getInventory().addItem(new CustomItem(sfItem.getItem(), amount));
SlimefunPlugin.getLocal().sendMessage(sender, "messages.give-item", true, msg -> msg.replace(PLACEHOLDER_PLAYER, args[1]).replace(PLACEHOLDER_ITEM, sfItem.getItemName()).replace(PLACEHOLDER_AMOUNT, String.valueOf(amount)));
SlimefunPlugin.getLocalization().sendMessage(sender, "messages.give-item", true, msg -> msg.replace(PLACEHOLDER_PLAYER, args[1]).replace(PLACEHOLDER_ITEM, sfItem.getItemName()).replace(PLACEHOLDER_AMOUNT, String.valueOf(amount)));
}
else {
SlimefunPlugin.getLocal().sendMessage(sender, "messages.not-valid-amount", true, msg -> msg.replace(PLACEHOLDER_AMOUNT, args[3]));
SlimefunPlugin.getLocalization().sendMessage(sender, "messages.not-valid-amount", true, msg -> msg.replace(PLACEHOLDER_AMOUNT, args[3]));
}
}
}

View File

@ -7,7 +7,7 @@ import io.github.thebusybiscuit.slimefun4.core.commands.SlimefunCommand;
import io.github.thebusybiscuit.slimefun4.core.commands.SubCommand;
import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuide;
import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideLayout;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
class GuideCommand extends SubCommand {
@ -32,11 +32,11 @@ class GuideCommand extends SubCommand {
((Player) sender).getInventory().addItem(SlimefunGuide.getItem(SlimefunPlugin.getCfg().getBoolean("guide.default-view-book") ? SlimefunGuideLayout.BOOK : SlimefunGuideLayout.CHEST));
}
else {
SlimefunPlugin.getLocal().sendMessage(sender, "messages.no-permission", true);
SlimefunPlugin.getLocalization().sendMessage(sender, "messages.no-permission", true);
}
}
else {
SlimefunPlugin.getLocal().sendMessage(sender, "messages.only-players", true);
SlimefunPlugin.getLocalization().sendMessage(sender, "messages.only-players", true);
}
}

View File

@ -4,7 +4,7 @@ import org.bukkit.command.CommandSender;
import io.github.thebusybiscuit.slimefun4.core.commands.SlimefunCommand;
import io.github.thebusybiscuit.slimefun4.core.commands.SubCommand;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
class HelpCommand extends SubCommand {

View File

@ -7,7 +7,7 @@ import io.github.thebusybiscuit.slimefun4.core.commands.SlimefunCommand;
import io.github.thebusybiscuit.slimefun4.core.commands.SubCommand;
import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuide;
import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideLayout;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
class OpenGuideCommand extends SubCommand {
@ -33,11 +33,11 @@ class OpenGuideCommand extends SubCommand {
SlimefunGuide.openGuide((Player) sender, book ? SlimefunGuideLayout.BOOK : SlimefunGuideLayout.CHEST);
}
else {
SlimefunPlugin.getLocal().sendMessage(sender, "messages.no-permission", true);
SlimefunPlugin.getLocalization().sendMessage(sender, "messages.no-permission", true);
}
}
else {
SlimefunPlugin.getLocal().sendMessage(sender, "messages.only-players", true);
SlimefunPlugin.getLocalization().sendMessage(sender, "messages.only-players", true);
}
}

View File

@ -11,7 +11,7 @@ import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile;
import io.github.thebusybiscuit.slimefun4.core.commands.SlimefunCommand;
import io.github.thebusybiscuit.slimefun4.core.commands.SubCommand;
import io.github.thebusybiscuit.slimefun4.core.researching.Research;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
class ResearchCommand extends SubCommand {
@ -60,13 +60,13 @@ class ResearchCommand extends SubCommand {
});
}
else {
SlimefunPlugin.getLocal().sendMessage(sender, "messages.not-online", true, msg -> msg.replace(PLACEHOLDER_PLAYER, args[1]));
SlimefunPlugin.getLocalization().sendMessage(sender, "messages.not-online", true, msg -> msg.replace(PLACEHOLDER_PLAYER, args[1]));
}
}
else SlimefunPlugin.getLocal().sendMessage(sender, "messages.no-permission", true);
else SlimefunPlugin.getLocalization().sendMessage(sender, "messages.no-permission", true);
}
else {
SlimefunPlugin.getLocal().sendMessage(sender, "messages.usage", true, msg -> msg.replace("%usage%", "/sf research <Player> <all/reset/Research>"));
SlimefunPlugin.getLocalization().sendMessage(sender, "messages.usage", true, msg -> msg.replace("%usage%", "/sf research <Player> <all/reset/Research>"));
}
}
@ -76,18 +76,18 @@ class ResearchCommand extends SubCommand {
if (research.isPresent()) {
research.get().unlock(p, true, player -> {
UnaryOperator<String> variables = msg -> msg.replace(PLACEHOLDER_PLAYER, player.getName()).replace(PLACEHOLDER_RESEARCH, research.get().getName(player));
SlimefunPlugin.getLocal().sendMessage(player, "messages.give-research", true, variables);
SlimefunPlugin.getLocalization().sendMessage(player, "messages.give-research", true, variables);
});
}
else {
SlimefunPlugin.getLocal().sendMessage(sender, "messages.not-valid-research", true, msg -> msg.replace(PLACEHOLDER_RESEARCH, input));
SlimefunPlugin.getLocalization().sendMessage(sender, "messages.not-valid-research", true, msg -> msg.replace(PLACEHOLDER_RESEARCH, input));
}
}
private void researchAll(CommandSender sender, PlayerProfile profile, Player p) {
for (Research res : SlimefunPlugin.getRegistry().getResearches()) {
if (!profile.hasUnlocked(res)) {
SlimefunPlugin.getLocal().sendMessage(sender, "messages.give-research", true, msg -> msg.replace(PLACEHOLDER_PLAYER, p.getName()).replace(PLACEHOLDER_RESEARCH, res.getName(p)));
SlimefunPlugin.getLocalization().sendMessage(sender, "messages.give-research", true, msg -> msg.replace(PLACEHOLDER_PLAYER, p.getName()).replace(PLACEHOLDER_RESEARCH, res.getName(p)));
}
res.unlock(p, true);
@ -99,7 +99,7 @@ class ResearchCommand extends SubCommand {
profile.setResearched(research, false);
}
SlimefunPlugin.getLocal().sendMessage(p, "commands.research.reset", true, msg -> msg.replace(PLACEHOLDER_PLAYER, p.getName()));
SlimefunPlugin.getLocalization().sendMessage(p, "commands.research.reset", true, msg -> msg.replace(PLACEHOLDER_PLAYER, p.getName()));
}
private Optional<Research> getResearchFromString(String input) {

View File

@ -9,7 +9,7 @@ import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile;
import io.github.thebusybiscuit.slimefun4.core.commands.SlimefunCommand;
import io.github.thebusybiscuit.slimefun4.core.commands.SubCommand;
import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuide;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
class SearchCommand extends SubCommand {
@ -36,15 +36,15 @@ class SearchCommand extends SubCommand {
PlayerProfile.get((Player) sender, profile -> SlimefunGuide.openSearch(profile, query, true, true));
}
else {
SlimefunPlugin.getLocal().sendMessage(sender, "messages.usage", true, msg -> msg.replace("%usage%", "/sf search <SearchTerm>"));
SlimefunPlugin.getLocalization().sendMessage(sender, "messages.usage", true, msg -> msg.replace("%usage%", "/sf search <SearchTerm>"));
}
}
else {
SlimefunPlugin.getLocal().sendMessage(sender, "messages.no-permission", true);
SlimefunPlugin.getLocalization().sendMessage(sender, "messages.no-permission", true);
}
}
else {
SlimefunPlugin.getLocal().sendMessage(sender, "messages.only-players", true);
SlimefunPlugin.getLocalization().sendMessage(sender, "messages.only-players", true);
}
}

View File

@ -10,7 +10,7 @@ import io.github.thebusybiscuit.cscorelib2.players.PlayerList;
import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile;
import io.github.thebusybiscuit.slimefun4.core.commands.SlimefunCommand;
import io.github.thebusybiscuit.slimefun4.core.commands.SubCommand;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
class StatsCommand extends SubCommand {
@ -38,16 +38,16 @@ class StatsCommand extends SubCommand {
PlayerProfile.get(player.get(), profile -> profile.sendStats(sender));
}
else {
SlimefunPlugin.getLocal().sendMessage(sender, "messages.not-online", true, msg -> msg.replace("%player%", args[1]));
SlimefunPlugin.getLocalization().sendMessage(sender, "messages.not-online", true, msg -> msg.replace("%player%", args[1]));
}
}
else SlimefunPlugin.getLocal().sendMessage(sender, "messages.no-permission", true);
else SlimefunPlugin.getLocalization().sendMessage(sender, "messages.no-permission", true);
}
else if (sender instanceof Player) {
PlayerProfile.get((Player) sender, profile -> profile.sendStats(sender));
}
else {
SlimefunPlugin.getLocal().sendMessage(sender, "messages.only-players", true);
SlimefunPlugin.getLocalization().sendMessage(sender, "messages.only-players", true);
}
}

View File

@ -8,7 +8,7 @@ import org.bukkit.entity.Player;
import io.github.thebusybiscuit.slimefun4.core.commands.SlimefunCommand;
import io.github.thebusybiscuit.slimefun4.core.commands.SubCommand;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
class TeleporterCommand extends SubCommand {
@ -43,19 +43,19 @@ class TeleporterCommand extends SubCommand {
SlimefunPlugin.getGPSNetwork().getTeleportationManager().openTeleporterGUI((Player) sender, player.getUniqueId(), ((Player) sender).getLocation().getBlock().getRelative(BlockFace.DOWN), 999999999);
}
else {
SlimefunPlugin.getLocal().sendMessage(sender, "messages.unknown-player", msg -> msg.replace("%player%", args[1]));
SlimefunPlugin.getLocalization().sendMessage(sender, "messages.unknown-player", msg -> msg.replace("%player%", args[1]));
}
}
else {
SlimefunPlugin.getLocal().sendMessage(sender, "messages.usage", msg -> msg.replace("%usage%", "/sf teleporter [Player]"));
SlimefunPlugin.getLocalization().sendMessage(sender, "messages.usage", msg -> msg.replace("%usage%", "/sf teleporter [Player]"));
}
}
else {
SlimefunPlugin.getLocal().sendMessage(sender, "messages.no-permission");
SlimefunPlugin.getLocalization().sendMessage(sender, "messages.no-permission");
}
}
else {
SlimefunPlugin.getLocal().sendMessage(sender, "messages.only-players");
SlimefunPlugin.getLocalization().sendMessage(sender, "messages.only-players");
}
}

View File

@ -5,7 +5,7 @@ import org.bukkit.command.ConsoleCommandSender;
import io.github.thebusybiscuit.slimefun4.core.commands.SlimefunCommand;
import io.github.thebusybiscuit.slimefun4.core.commands.SubCommand;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
class TimingsCommand extends SubCommand {
@ -26,10 +26,11 @@ class TimingsCommand extends SubCommand {
@Override
public void onExecute(CommandSender sender, String[] args) {
if (sender.hasPermission("slimefun.command.timings") || sender instanceof ConsoleCommandSender) {
SlimefunPlugin.getTicker().info(sender);
sender.sendMessage("Please wait a second... The results are coming in!");
SlimefunPlugin.getProfiler().requestSummary(sender);
}
else {
SlimefunPlugin.getLocal().sendMessage(sender, "messages.no-permission", true);
SlimefunPlugin.getLocalization().sendMessage(sender, "messages.no-permission", true);
}
}

View File

@ -12,7 +12,7 @@ import io.github.thebusybiscuit.cscorelib2.chat.ChatColors;
import io.github.thebusybiscuit.cscorelib2.reflection.ReflectionUtils;
import io.github.thebusybiscuit.slimefun4.core.commands.SlimefunCommand;
import io.github.thebusybiscuit.slimefun4.core.commands.SubCommand;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
class VersionsCommand extends SubCommand {
@ -57,7 +57,7 @@ class VersionsCommand extends SubCommand {
}
}
else {
SlimefunPlugin.getLocal().sendMessage(sender, "messages.no-permission", true);
SlimefunPlugin.getLocalization().sendMessage(sender, "messages.no-permission", true);
}
}

View File

@ -12,10 +12,10 @@ import org.bukkit.inventory.meta.ItemMeta;
import io.github.thebusybiscuit.cscorelib2.chat.ChatColors;
import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.guide.BookSlimefunGuide;
import io.github.thebusybiscuit.slimefun4.implementation.guide.ChestSlimefunGuide;
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.api.Slimefun;
@ -102,7 +102,7 @@ public final class SlimefunGuide {
private static void openMainMenuAsync(Player player, SlimefunGuideLayout layout, int selectedPage) {
if (!PlayerProfile.get(player, profile -> Slimefun.runSync(() -> openMainMenu(profile, layout, selectedPage)))) {
SlimefunPlugin.getLocal().sendMessage(player, "messages.opening-guide");
SlimefunPlugin.getLocalization().sendMessage(player, "messages.opening-guide");
}
}

View File

@ -8,9 +8,9 @@ import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile;
import io.github.thebusybiscuit.slimefun4.core.researching.Research;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.guide.BookSlimefunGuide;
import io.github.thebusybiscuit.slimefun4.implementation.guide.ChestSlimefunGuide;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;

View File

@ -14,26 +14,26 @@ import org.bukkit.inventory.meta.SkullMeta;
import io.github.thebusybiscuit.cscorelib2.chat.ChatColors;
import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
import io.github.thebusybiscuit.slimefun4.core.services.github.Contributor;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.utils.ChatUtils;
import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils;
import io.github.thebusybiscuit.slimefun4.utils.PatternUtils;
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
final class ContributorsMenu {
private ContributorsMenu() {}
public static void open(Player p, int page) {
ChestMenu menu = new ChestMenu(SlimefunPlugin.getLocal().getMessage(p, "guide.title.credits"));
ChestMenu menu = new ChestMenu(SlimefunPlugin.getLocalization().getMessage(p, "guide.title.credits"));
menu.setEmptySlotsClickable(false);
menu.addMenuOpeningHandler(pl -> pl.playSound(pl.getLocation(), Sound.BLOCK_NOTE_BLOCK_HARP, 0.7F, 0.7F));
ChestMenuUtils.drawBackground(menu, 0, 2, 3, 4, 5, 6, 7, 8, 45, 47, 48, 49, 50, 51, 52);
menu.addItem(1, new CustomItem(ChestMenuUtils.getBackButton(p, "", "&7" + SlimefunPlugin.getLocal().getMessage(p, "guide.back.settings"))));
menu.addItem(1, new CustomItem(ChestMenuUtils.getBackButton(p, "", "&7" + SlimefunPlugin.getLocalization().getMessage(p, "guide.back.settings"))));
menu.addMenuClickHandler(1, (pl, slot, item, action) -> {
SlimefunGuideSettings.openSettings(pl, p.getInventory().getItemInMainHand());
return false;
@ -60,13 +60,19 @@ final class ContributorsMenu {
menu.addItem(46, ChestMenuUtils.getPreviousButton(p, page + 1, pages));
menu.addMenuClickHandler(46, (pl, slot, item, action) -> {
if (page > 0) open(pl, page - 1);
if (page > 0) {
open(pl, page - 1);
}
return false;
});
menu.addItem(52, ChestMenuUtils.getNextButton(p, page + 1, pages));
menu.addMenuClickHandler(52, (pl, slot, item, action) -> {
if (page + 1 < pages) open(pl, page + 1);
if (page + 1 < pages) {
open(pl, page + 1);
}
return false;
});
@ -87,15 +93,15 @@ final class ContributorsMenu {
if (!info.startsWith("&")) {
String[] segments = PatternUtils.COMMA.split(info);
info = SlimefunPlugin.getLocal().getMessage(p, "guide.credits.roles." + segments[0]);
info = SlimefunPlugin.getLocalization().getMessage(p, "guide.credits.roles." + segments[0]);
if (segments.length == 2) {
info += " &7(" + SlimefunPlugin.getLocal().getMessage(p, "languages." + segments[1]) + ')';
info += " &7(" + SlimefunPlugin.getLocalization().getMessage(p, "languages." + segments[1]) + ')';
}
}
if (entry.getValue() > 0) {
String commits = SlimefunPlugin.getLocal().getMessage(p, "guide.credits." + (entry.getValue() > 1 ? "commits" : "commit"));
String commits = SlimefunPlugin.getLocalization().getMessage(p, "guide.credits." + (entry.getValue() > 1 ? "commits" : "commit"));
info += " &7(" + entry.getValue() + ' ' + commits + ')';
}
@ -105,7 +111,7 @@ final class ContributorsMenu {
if (contributor.getProfile() != null) {
lore.add("");
lore.add(ChatColors.color("&7\u21E8 &e") + SlimefunPlugin.getLocal().getMessage(p, "guide.credits.profile-link"));
lore.add(ChatColors.color("&7\u21E8 &e") + SlimefunPlugin.getLocalization().getMessage(p, "guide.credits.profile-link"));
}
meta.setLore(lore);

View File

@ -10,18 +10,18 @@ import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.cscorelib2.data.PersistentDataAPI;
import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
import io.github.thebusybiscuit.slimefun4.api.SlimefunAddon;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
class FireworksOption implements SlimefunGuideOption<Boolean> {
@Override
public SlimefunAddon getAddon() {
return SlimefunPlugin.instance;
return SlimefunPlugin.instance();
}
@Override
public NamespacedKey getKey() {
return new NamespacedKey(SlimefunPlugin.instance, "research_fireworks");
return new NamespacedKey(SlimefunPlugin.instance(), "research_fireworks");
}
@Override

View File

@ -14,20 +14,20 @@ import org.bukkit.inventory.meta.ItemMeta;
import io.github.thebusybiscuit.slimefun4.api.SlimefunAddon;
import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuide;
import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideLayout;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.utils.ChatUtils;
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
class GuideLayoutOption implements SlimefunGuideOption<SlimefunGuideLayout> {
@Override
public SlimefunAddon getAddon() {
return SlimefunPlugin.instance;
return SlimefunPlugin.instance();
}
@Override
public NamespacedKey getKey() {
return new NamespacedKey(SlimefunPlugin.instance, "guide_layout");
return new NamespacedKey(SlimefunPlugin.instance(), "guide_layout");
}
@Override

View File

@ -13,31 +13,31 @@ import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
import io.github.thebusybiscuit.slimefun4.api.SlimefunAddon;
import io.github.thebusybiscuit.slimefun4.api.events.PlayerLanguageChangeEvent;
import io.github.thebusybiscuit.slimefun4.core.services.localization.Language;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.utils.ChatUtils;
import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils;
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
class PlayerLanguageOption implements SlimefunGuideOption<String> {
@Override
public SlimefunAddon getAddon() {
return SlimefunPlugin.instance;
return SlimefunPlugin.instance();
}
@Override
public NamespacedKey getKey() {
return SlimefunPlugin.getLocal().getKey();
return SlimefunPlugin.getLocalization().getKey();
}
@Override
public Optional<ItemStack> getDisplayItem(Player p, ItemStack guide) {
if (SlimefunPlugin.getLocal().isEnabled()) {
Language language = SlimefunPlugin.getLocal().getLanguage(p);
String languageName = language.isDefault() ? (SlimefunPlugin.getLocal().getMessage(p, "languages.default") + ChatColor.DARK_GRAY + " (" + language.getName(p) + ")") : SlimefunPlugin.getLocal().getMessage(p, "languages." + language.getId());
if (SlimefunPlugin.getLocalization().isEnabled()) {
Language language = SlimefunPlugin.getLocalization().getLanguage(p);
String languageName = language.isDefault() ? (SlimefunPlugin.getLocalization().getMessage(p, "languages.default") + ChatColor.DARK_GRAY + " (" + language.getName(p) + ")") : SlimefunPlugin.getLocalization().getMessage(p, "languages." + language.getId());
return Optional.of(new CustomItem(language.getItem(), "&7" + SlimefunPlugin.getLocal().getMessage(p, "guide.languages.selected-language") + " &a" + languageName, "", "&7You now have the option to change", "&7the language in which Slimefun", "&7will send you messages.", "&7Note that this only translates", "&7some messages, not items.", "&7&oThis feature is still being worked on", "", "&7\u21E8 &eClick to change your language"));
return Optional.of(new CustomItem(language.getItem(), "&7" + SlimefunPlugin.getLocalization().getMessage(p, "guide.languages.selected-language") + " &a" + languageName, "", "&7You now have the option to change", "&7the language in which Slimefun", "&7will send you messages.", "&7Note that this only translates", "&7some messages, not items.", "&7&oThis feature is still being worked on", "", "&7\u21E8 &eClick to change your language"));
}
else {
return Optional.empty();
@ -51,7 +51,7 @@ class PlayerLanguageOption implements SlimefunGuideOption<String> {
@Override
public Optional<String> getSelectedOption(Player p, ItemStack guide) {
return Optional.of(SlimefunPlugin.getLocal().getLanguage(p).getId());
return Optional.of(SlimefunPlugin.getLocalization().getLanguage(p).getId());
}
@Override
@ -65,20 +65,20 @@ class PlayerLanguageOption implements SlimefunGuideOption<String> {
}
private void openLanguageSelection(Player p, ItemStack guide) {
ChestMenu menu = new ChestMenu(SlimefunPlugin.getLocal().getMessage(p, "guide.title.languages"));
ChestMenu menu = new ChestMenu(SlimefunPlugin.getLocalization().getMessage(p, "guide.title.languages"));
menu.setEmptySlotsClickable(false);
menu.addMenuOpeningHandler(pl -> pl.playSound(pl.getLocation(), Sound.BLOCK_NOTE_BLOCK_HARP, 0.7F, 0.7F));
for (int i = 0; i < 9; i++) {
if (i == 1) {
menu.addItem(1, ChestMenuUtils.getBackButton(p, "", "&7" + SlimefunPlugin.getLocal().getMessage(p, "guide.back.settings")), (pl, slot, item, action) -> {
menu.addItem(1, ChestMenuUtils.getBackButton(p, "", "&7" + SlimefunPlugin.getLocalization().getMessage(p, "guide.back.settings")), (pl, slot, item, action) -> {
SlimefunGuideSettings.openSettings(pl, guide);
return false;
});
}
else if (i == 7) {
menu.addItem(7, new CustomItem(SlimefunUtils.getCustomHead("3edd20be93520949e6ce789dc4f43efaeb28c717ee6bfcbbe02780142f716"), SlimefunPlugin.getLocal().getMessage(p, "guide.languages.translations.name"), "", "&7\u21E8 &e" + SlimefunPlugin.getLocal().getMessage(p, "guide.languages.translations.lore")), (pl, slot, item, action) -> {
menu.addItem(7, new CustomItem(SlimefunUtils.getCustomHead("3edd20be93520949e6ce789dc4f43efaeb28c717ee6bfcbbe02780142f716"), SlimefunPlugin.getLocalization().getMessage(p, "guide.languages.translations.name"), "", "&7\u21E8 &e" + SlimefunPlugin.getLocalization().getMessage(p, "guide.languages.translations.lore")), (pl, slot, item, action) -> {
ChatUtils.sendURL(pl, "https://github.com/TheBusyBiscuit/Slimefun4/wiki/Translating-Slimefun");
pl.closeInventory();
return false;
@ -89,14 +89,14 @@ class PlayerLanguageOption implements SlimefunGuideOption<String> {
}
}
Language defaultLanguage = SlimefunPlugin.getLocal().getDefaultLanguage();
String defaultLanguageString = SlimefunPlugin.getLocal().getMessage(p, "languages.default");
Language defaultLanguage = SlimefunPlugin.getLocalization().getDefaultLanguage();
String defaultLanguageString = SlimefunPlugin.getLocalization().getMessage(p, "languages.default");
menu.addItem(9, new CustomItem(defaultLanguage.getItem(), ChatColor.GRAY + defaultLanguageString + ChatColor.DARK_GRAY + " (" + defaultLanguage.getName(p) + ")", "", "&7\u21E8 &e" + SlimefunPlugin.getLocal().getMessage(p, "guide.languages.select-default")), (pl, i, item, action) -> {
SlimefunPlugin.instance.getServer().getPluginManager().callEvent(new PlayerLanguageChangeEvent(pl, SlimefunPlugin.getLocal().getLanguage(pl), defaultLanguage));
menu.addItem(9, new CustomItem(defaultLanguage.getItem(), ChatColor.GRAY + defaultLanguageString + ChatColor.DARK_GRAY + " (" + defaultLanguage.getName(p) + ")", "", "&7\u21E8 &e" + SlimefunPlugin.getLocalization().getMessage(p, "guide.languages.select-default")), (pl, i, item, action) -> {
SlimefunPlugin.instance().getServer().getPluginManager().callEvent(new PlayerLanguageChangeEvent(pl, SlimefunPlugin.getLocalization().getLanguage(pl), defaultLanguage));
setSelectedOption(pl, guide, null);
SlimefunPlugin.getLocal().sendMessage(pl, "guide.languages.updated", msg -> msg.replace("%lang%", defaultLanguageString));
SlimefunPlugin.getLocalization().sendMessage(pl, "guide.languages.updated", msg -> msg.replace("%lang%", defaultLanguageString));
SlimefunGuideSettings.openSettings(pl, guide);
return false;
@ -104,13 +104,13 @@ class PlayerLanguageOption implements SlimefunGuideOption<String> {
int slot = 10;
for (Language language : SlimefunPlugin.getLocal().getLanguages()) {
menu.addItem(slot, new CustomItem(language.getItem(), ChatColor.GREEN + language.getName(p), "&b" + SlimefunPlugin.getLocal().getProgress(language) + '%', "", "&7\u21E8 &e" + SlimefunPlugin.getLocal().getMessage(p, "guide.languages.select")), (pl, i, item, action) -> {
SlimefunPlugin.instance.getServer().getPluginManager().callEvent(new PlayerLanguageChangeEvent(pl, SlimefunPlugin.getLocal().getLanguage(pl), language));
for (Language language : SlimefunPlugin.getLocalization().getLanguages()) {
menu.addItem(slot, new CustomItem(language.getItem(), ChatColor.GREEN + language.getName(p), "&b" + SlimefunPlugin.getLocalization().getProgress(language) + '%', "", "&7\u21E8 &e" + SlimefunPlugin.getLocalization().getMessage(p, "guide.languages.select")), (pl, i, item, action) -> {
SlimefunPlugin.instance().getServer().getPluginManager().callEvent(new PlayerLanguageChangeEvent(pl, SlimefunPlugin.getLocalization().getLanguage(pl), language));
setSelectedOption(pl, guide, language.getId());
String name = language.getName(pl);
SlimefunPlugin.getLocal().sendMessage(pl, "guide.languages.updated", msg -> msg.replace("%lang%", name));
SlimefunPlugin.getLocalization().sendMessage(pl, "guide.languages.updated", msg -> msg.replace("%lang%", name));
SlimefunGuideSettings.openSettings(pl, guide);
return false;

View File

@ -15,12 +15,12 @@ import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuide;
import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideLayout;
import io.github.thebusybiscuit.slimefun4.core.services.localization.Language;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.utils.ChatUtils;
import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils;
import io.github.thebusybiscuit.slimefun4.utils.NumberUtils;
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
/**
* This static utility class offers various methods that provide access to the
@ -54,7 +54,7 @@ public final class SlimefunGuideSettings {
}
public static void openSettings(Player p, ItemStack guide) {
ChestMenu menu = new ChestMenu(SlimefunPlugin.getLocal().getMessage(p, "guide.title.settings"));
ChestMenu menu = new ChestMenu(SlimefunPlugin.getLocalization().getMessage(p, "guide.title.settings"));
menu.setEmptySlotsClickable(false);
menu.addMenuOpeningHandler(pl -> pl.playSound(pl.getLocation(), Sound.BLOCK_NOTE_BLOCK_HARP, 0.7F, 0.7F));
@ -68,39 +68,39 @@ public final class SlimefunGuideSettings {
}
private static void addHeader(Player p, ChestMenu menu, ItemStack guide) {
menu.addItem(0, new CustomItem(SlimefunGuide.getItem(SlimefunGuideLayout.CHEST), "&e\u21E6 " + SlimefunPlugin.getLocal().getMessage(p, "guide.back.title"), "", "&7" + SlimefunPlugin.getLocal().getMessage(p, "guide.back.guide")), (pl, slot, item, action) -> {
menu.addItem(0, new CustomItem(SlimefunGuide.getItem(SlimefunGuideLayout.CHEST), "&e\u21E6 " + SlimefunPlugin.getLocalization().getMessage(p, "guide.back.title"), "", "&7" + SlimefunPlugin.getLocalization().getMessage(p, "guide.back.guide")), (pl, slot, item, action) -> {
SlimefunGuide.openGuide(pl, guide);
return false;
});
menu.addItem(2, new CustomItem(SlimefunUtils.getCustomHead("e952d2b3f351a6b0487cc59db31bf5f2641133e5ba0006b18576e996a0293e52"), "&c" + SlimefunPlugin.getLocal().getMessage(p, "guide.title.credits"), "", "&7Contributors: &e" + SlimefunPlugin.getGitHubService().getContributors().size(), "", "&7Slimefun is an open-source project", "&7and maintained by a large community of people.", "&7Here you can see who helped shape the project.", "", "&7\u21E8 &eClick to see our contributors"), (pl, slot, action, item) -> {
menu.addItem(2, new CustomItem(SlimefunUtils.getCustomHead("e952d2b3f351a6b0487cc59db31bf5f2641133e5ba0006b18576e996a0293e52"), "&c" + SlimefunPlugin.getLocalization().getMessage(p, "guide.title.credits"), "", "&7Contributors: &e" + SlimefunPlugin.getGitHubService().getContributors().size(), "", "&7Slimefun is an open-source project", "&7and maintained by a large community of people.", "&7Here you can see who helped shape the project.", "", "&7\u21E8 &eClick to see our contributors"), (pl, slot, action, item) -> {
ContributorsMenu.open(pl, 0);
return false;
});
menu.addItem(4, new CustomItem(Material.WRITABLE_BOOK, "&aSlimefun Version", "&7&o" + SlimefunPlugin.getLocal().getMessage(p, "guide.tooltips.versions-notice"), "", "&rMinecraft Version: &a" + Bukkit.getBukkitVersion(), "&rSlimefun Version: &a" + SlimefunPlugin.getVersion(), "&rCS-CoreLib Version: &a" + SlimefunPlugin.getCSCoreLibVersion()), ChestMenuUtils.getEmptyClickHandler());
menu.addItem(4, new CustomItem(Material.WRITABLE_BOOK, "&aSlimefun Version", "&7&o" + SlimefunPlugin.getLocalization().getMessage(p, "guide.tooltips.versions-notice"), "", "&fMinecraft Version: &a" + Bukkit.getBukkitVersion(), "&fSlimefun Version: &a" + SlimefunPlugin.getVersion(), "&fCS-CoreLib Version: &a" + SlimefunPlugin.getCSCoreLibVersion()), ChestMenuUtils.getEmptyClickHandler());
menu.addItem(6, new CustomItem(Material.COMPARATOR, "&e" + SlimefunPlugin.getLocal().getMessage(p, "guide.title.source"), "", "&7Last Activity: &a" + NumberUtils.getElapsedTime(SlimefunPlugin.getGitHubService().getLastUpdate()) + " ago", "&7Forks: &e" + SlimefunPlugin.getGitHubService().getForks(), "&7Stars: &e" + SlimefunPlugin.getGitHubService().getStars(), "", "&7&oSlimefun 4 is a community project,", "&7&othe source code is available on GitHub", "&7&oand if you want to keep this Plugin alive,", "&7&othen please consider contributing to it", "", "&7\u21E8 &eClick to go to GitHub"));
menu.addItem(6, new CustomItem(Material.COMPARATOR, "&e" + SlimefunPlugin.getLocalization().getMessage(p, "guide.title.source"), "", "&7Last Activity: &a" + NumberUtils.getElapsedTime(SlimefunPlugin.getGitHubService().getLastUpdate()) + " ago", "&7Forks: &e" + SlimefunPlugin.getGitHubService().getForks(), "&7Stars: &e" + SlimefunPlugin.getGitHubService().getStars(), "", "&7&oSlimefun 4 is a community project,", "&7&othe source code is available on GitHub", "&7&oand if you want to keep this Plugin alive,", "&7&othen please consider contributing to it", "", "&7\u21E8 &eClick to go to GitHub"));
menu.addMenuClickHandler(6, (pl, slot, item, action) -> {
pl.closeInventory();
ChatUtils.sendURL(pl, "https://github.com/TheBusyBiscuit/Slimefun4");
return false;
});
menu.addItem(8, new CustomItem(Material.KNOWLEDGE_BOOK, "&3" + SlimefunPlugin.getLocal().getMessage(p, "guide.title.wiki"), "", "&7Do you need help with an Item or machine?", "&7You cannot figure out what to do?", "&7Check out our community-maintained Wiki", "&7and become one of our Editors!", "", "&7\u21E8 &eClick to go to the official Slimefun Wiki"), (pl, slot, item, action) -> {
menu.addItem(8, new CustomItem(Material.KNOWLEDGE_BOOK, "&3" + SlimefunPlugin.getLocalization().getMessage(p, "guide.title.wiki"), "", "&7Do you need help with an Item or machine?", "&7You cannot figure out what to do?", "&7Check out our community-maintained Wiki", "&7and become one of our Editors!", "", "&7\u21E8 &eClick to go to the official Slimefun Wiki"), (pl, slot, item, action) -> {
pl.closeInventory();
ChatUtils.sendURL(pl, "https://github.com/TheBusyBiscuit/Slimefun4/wiki");
return false;
});
menu.addItem(47, new CustomItem(Material.BOOKSHELF, "&3" + SlimefunPlugin.getLocal().getMessage(p, "guide.title.addons"), "", "&7Slimefun is huge. But its addons are what makes", "&7this plugin truly shine. Go check them out, some", "&7of them may be exactly what you were missing out on!", "", "&7Installed on this Server: &b" + SlimefunPlugin.getInstalledAddons().size(), "", "&7\u21E8 &eClick to see all available Addons for Slimefun4"), (pl, slot, item, action) -> {
menu.addItem(47, new CustomItem(Material.BOOKSHELF, "&3" + SlimefunPlugin.getLocalization().getMessage(p, "guide.title.addons"), "", "&7Slimefun is huge. But its addons are what makes", "&7this plugin truly shine. Go check them out, some", "&7of them may be exactly what you were missing out on!", "", "&7Installed on this Server: &b" + SlimefunPlugin.getInstalledAddons().size(), "", "&7\u21E8 &eClick to see all available Addons for Slimefun4"), (pl, slot, item, action) -> {
pl.closeInventory();
ChatUtils.sendURL(pl, "https://github.com/TheBusyBiscuit/Slimefun4/wiki/Addons");
return false;
});
if (SlimefunPlugin.getUpdater().getBranch().isOfficial()) {
menu.addItem(49, new CustomItem(Material.REDSTONE_TORCH, "&4" + SlimefunPlugin.getLocal().getMessage(p, "guide.title.bugs"), "", "&7&oBug reports have to be made in English!", "", "&7Open Issues: &a" + SlimefunPlugin.getGitHubService().getOpenissues(), "&7Pending Pull Requests: &a" + SlimefunPlugin.getGitHubService().getPendingPullRequests(), "", "&7\u21E8 &eClick to go to the Slimefun4 Bug Tracker"), (pl, slot, item, action) -> {
menu.addItem(49, new CustomItem(Material.REDSTONE_TORCH, "&4" + SlimefunPlugin.getLocalization().getMessage(p, "guide.title.bugs"), "", "&7&oBug reports have to be made in English!", "", "&7Open Issues: &a" + SlimefunPlugin.getGitHubService().getOpenissues(), "&7Pending Pull Requests: &a" + SlimefunPlugin.getGitHubService().getPendingPullRequests(), "", "&7\u21E8 &eClick to go to the Slimefun4 Bug Tracker"), (pl, slot, item, action) -> {
pl.closeInventory();
ChatUtils.sendURL(pl, "https://github.com/TheBusyBiscuit/Slimefun4/issues");
return false;

View File

@ -0,0 +1,19 @@
package io.github.thebusybiscuit.slimefun4.core.handlers;
import java.util.List;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.inventory.ItemStack;
import me.mrCookieSlime.Slimefun.Objects.handlers.ItemHandler;
@FunctionalInterface
public interface BlockBreakHandler extends ItemHandler {
boolean onBlockBreak(BlockBreakEvent e, ItemStack item, int fortune, List<ItemStack> drops);
@Override
default Class<? extends ItemHandler> getIdentifier() {
return BlockBreakHandler.class;
}
}

View File

@ -1,4 +1,4 @@
package me.mrCookieSlime.Slimefun.Objects.handlers;
package io.github.thebusybiscuit.slimefun4.core.handlers;
import java.util.Optional;
@ -11,6 +11,7 @@ import io.github.thebusybiscuit.slimefun4.api.exceptions.IncompatibleItemHandler
import io.github.thebusybiscuit.slimefun4.core.attributes.NotPlaceable;
import io.github.thebusybiscuit.slimefun4.implementation.items.blocks.BlockPlacer;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.Objects.handlers.ItemHandler;
/**
* This {@link ItemHandler} is triggered when the {@link SlimefunItem} it was assigned to

View File

@ -1,12 +1,15 @@
package me.mrCookieSlime.Slimefun.Objects.handlers;
package io.github.thebusybiscuit.slimefun4.core.handlers;
import org.bukkit.entity.Player;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.inventory.ItemStack;
import me.mrCookieSlime.Slimefun.Objects.handlers.ItemHandler;
@FunctionalInterface
public interface BlockPlaceHandler extends ItemHandler {
boolean onBlockPlace(BlockPlaceEvent e, ItemStack item);
boolean onBlockPlace(Player p, BlockPlaceEvent e, ItemStack item);
@Override
default Class<? extends ItemHandler> getIdentifier() {

View File

@ -1,4 +1,4 @@
package me.mrCookieSlime.Slimefun.Objects.handlers;
package io.github.thebusybiscuit.slimefun4.core.handlers;
import java.util.Optional;
@ -6,6 +6,7 @@ import io.github.thebusybiscuit.slimefun4.api.events.PlayerRightClickEvent;
import io.github.thebusybiscuit.slimefun4.api.exceptions.IncompatibleItemHandlerException;
import io.github.thebusybiscuit.slimefun4.core.attributes.NotPlaceable;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.Objects.handlers.ItemHandler;
@FunctionalInterface
public interface BlockUseHandler extends ItemHandler {

View File

@ -1,4 +1,4 @@
package me.mrCookieSlime.Slimefun.Objects.handlers;
package io.github.thebusybiscuit.slimefun4.core.handlers;
import java.util.Optional;
@ -9,6 +9,7 @@ import org.bukkit.event.entity.EntityDamageByEntityEvent;
import io.github.thebusybiscuit.slimefun4.api.exceptions.IncompatibleItemHandlerException;
import io.github.thebusybiscuit.slimefun4.implementation.items.weapons.SlimefunBow;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.Objects.handlers.ItemHandler;
/**
* This {@link ItemHandler} is triggered when the {@link SlimefunItem} it was assigned to

View File

@ -1,4 +1,4 @@
package me.mrCookieSlime.Slimefun.Objects.handlers;
package io.github.thebusybiscuit.slimefun4.core.handlers;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
@ -6,8 +6,9 @@ import org.bukkit.event.player.PlayerInteractAtEntityEvent;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SimpleSlimefunItem;
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.Objects.handlers.ItemHandler;
/**
* This is triggered when a {@link Player} interacts with an {@link Entity}.

View File

@ -1,12 +1,13 @@
package me.mrCookieSlime.Slimefun.Objects.handlers;
package io.github.thebusybiscuit.slimefun4.core.handlers;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.entity.EntityDeathEvent;
import org.bukkit.inventory.ItemStack;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SimpleSlimefunItem;
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.Objects.handlers.ItemHandler;
/**
* If this {@link ItemHandler} is added to a {@link SlimefunItem} it will listen

View File

@ -1,13 +1,14 @@
package me.mrCookieSlime.Slimefun.Objects.handlers;
package io.github.thebusybiscuit.slimefun4.core.handlers;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerItemConsumeEvent;
import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
import io.github.thebusybiscuit.slimefun4.implementation.items.food.DietCookie;
import io.github.thebusybiscuit.slimefun4.implementation.items.food.FortuneCookie;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SimpleSlimefunItem;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.Objects.handlers.ItemHandler;
/**
* This {@link ItemHandler} is triggered when the {@link SlimefunItem} it was assigned to

View File

@ -1,9 +1,11 @@
package me.mrCookieSlime.Slimefun.Objects.handlers;
package io.github.thebusybiscuit.slimefun4.core.handlers;
import org.bukkit.entity.Item;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerDropItemEvent;
import me.mrCookieSlime.Slimefun.Objects.handlers.ItemHandler;
@FunctionalInterface
public interface ItemDropHandler extends ItemHandler {

View File

@ -0,0 +1,37 @@
package io.github.thebusybiscuit.slimefun4.core.handlers;
import org.bukkit.entity.Player;
import io.github.thebusybiscuit.slimefun4.api.events.PlayerRightClickEvent;
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.Objects.handlers.ItemHandler;
/**
* This {@link ItemHandler} is triggered when the {@link SlimefunItem} it was assigned to
* is right-clicked.
*
* @author TheBusyBiscuit
*
* @see ItemHandler
* @see SimpleSlimefunItem
*
*/
@FunctionalInterface
public interface ItemUseHandler extends ItemHandler {
/**
* This function is triggered when a {@link Player} right clicks with the assigned {@link SlimefunItem}
* in his hand.
*
* @param e
* The {@link PlayerRightClickEvent} that was triggered
*/
void onRightClick(PlayerRightClickEvent e);
@Override
default Class<? extends ItemHandler> getIdentifier() {
return ItemUseHandler.class;
}
}

View File

@ -0,0 +1,45 @@
package io.github.thebusybiscuit.slimefun4.core.handlers;
import java.util.Optional;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import io.github.thebusybiscuit.slimefun4.api.exceptions.IncompatibleItemHandlerException;
import io.github.thebusybiscuit.slimefun4.core.multiblocks.MultiBlock;
import io.github.thebusybiscuit.slimefun4.core.multiblocks.MultiBlockMachine;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.Objects.handlers.ItemHandler;
/**
* This {@link ItemHandler} is called whenever a {@link Player} interacts with
* this {@link MultiBlock}.
* Note that this {@link MultiBlockInteractionHandler} should be assigned to
* a class that inherits from {@link MultiBlockMachine}.
*
* @author TheBusyBiscuit
*
* @see ItemHandler
* @see MultiBlock
* @see MultiBlockMachine
*
*/
@FunctionalInterface
public interface MultiBlockInteractionHandler extends ItemHandler {
boolean onInteract(Player p, MultiBlock mb, Block b);
@Override
default Optional<IncompatibleItemHandlerException> validate(SlimefunItem item) {
if (!(item instanceof MultiBlockMachine)) {
return Optional.of(new IncompatibleItemHandlerException("Only classes inheriting 'MultiBlockMachine' can have a MultiBlockInteractionHandler", item, this));
}
return Optional.empty();
}
@Override
default Class<? extends ItemHandler> getIdentifier() {
return MultiBlockInteractionHandler.class;
}
}

View File

@ -1,19 +1,22 @@
package me.mrCookieSlime.Slimefun.Objects.handlers;
package io.github.thebusybiscuit.slimefun4.core.handlers;
import java.util.Arrays;
import org.apache.commons.lang.Validate;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.Waterlogged;
import org.bukkit.block.data.type.GlassPane;
import io.github.thebusybiscuit.cscorelib2.collections.LoopIterator;
import io.github.thebusybiscuit.cscorelib2.materials.MaterialCollection;
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.items.blocks.RainbowBlock;
import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.Objects.handlers.BlockTicker;
/**
* This is a {@link BlockTicker} that is exclusively used for Rainbow blocks.
@ -25,34 +28,36 @@ import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
* @see RainbowBlock
*
*/
public class RainbowTicker extends BlockTicker {
public class RainbowTickHandler extends BlockTicker {
private final LoopIterator<Material> iterator;
private final boolean waterlogged;
private final boolean glassPanes;
private Material material;
public RainbowTicker(Material... materials) {
public RainbowTickHandler(Material... materials) {
Validate.noNullElements(materials, "A RainbowTicker cannot have a Material that is null!");
if (materials.length == 0) {
throw new IllegalArgumentException("A RainbowTicker must have at least one Material associated with it!");
}
waterlogged = containsWaterlogged(materials);
glassPanes = containsGlassPanes(materials);
iterator = new LoopIterator<>(Arrays.asList(materials));
material = iterator.next();
}
/**
* This method checks whether a given {@link Material} array contains any {@link Material}
* that would result in a {@link Waterlogged} {@link BlockData}.
* that would result in a {@link GlassPane} {@link BlockData}.
* This is done to save performance, so we don't have to validate {@link BlockData} at
* runtime.
*
* @param materials
* The {@link Material} Array to check
*
* @return Whether the array contained any {@link Waterlogged} materials
* @return Whether the array contained any {@link GlassPane} materials
*/
private boolean containsWaterlogged(Material[] materials) {
private boolean containsGlassPanes(Material[] materials) {
if (SlimefunPlugin.getMinecraftVersion() == MinecraftVersion.UNIT_TEST) {
// BlockData is not available to us during Unit Tests :/
return false;
@ -61,8 +66,8 @@ public class RainbowTicker extends BlockTicker {
for (Material type : materials) {
// This BlockData is purely virtual and only created on startup, it should have
// no impact on performance, in fact it should save performance as it preloads
// the data but also saves heavy calls for non-waterlogged Materials
if (type.createBlockData() instanceof Waterlogged) {
// the data but also saves heavy calls for other Materials
if (type.createBlockData() instanceof GlassPane) {
return true;
}
}
@ -70,7 +75,7 @@ public class RainbowTicker extends BlockTicker {
return false;
}
public RainbowTicker(MaterialCollection collection) {
public RainbowTickHandler(MaterialCollection collection) {
this(collection.getAsArray());
}
@ -82,20 +87,29 @@ public class RainbowTicker extends BlockTicker {
return;
}
if (waterlogged) {
if (glassPanes) {
BlockData blockData = b.getBlockData();
b.setType(material, true);
if (blockData instanceof GlassPane) {
BlockData block = material.createBlockData(bd -> {
if (bd instanceof GlassPane) {
GlassPane previousData = (GlassPane) blockData;
GlassPane nextData = (GlassPane) bd;
nextData.setWaterlogged(previousData.isWaterlogged());
for (BlockFace face : previousData.getAllowedFaces()) {
nextData.setFace(face, previousData.hasFace(face));
}
}
});
if (blockData instanceof Waterlogged && ((Waterlogged) blockData).isWaterlogged()) {
Waterlogged block = (Waterlogged) b.getBlockData();
block.setWaterlogged(true);
b.setBlockData(block);
return;
}
}
else {
b.setType(material, false);
}
b.setType(material, false);
}
@Override

View File

@ -0,0 +1,5 @@
/**
* This package contains all variations of {@link me.mrCookieSlime.Slimefun.Objects.handlers.ItemHandler} that
* can be assigned to a {@link me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem}
*/
package io.github.thebusybiscuit.slimefun4.core.handlers;

View File

@ -13,9 +13,9 @@ import org.bukkit.block.BlockFace;
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
import io.github.thebusybiscuit.slimefun4.api.events.MultiBlockInteractEvent;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.core.handlers.MultiBlockInteractionHandler;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.Objects.handlers.MultiBlockInteractionHandler;
/**
* A {@link MultiBlock} represents a structure build in a {@link World}.

View File

@ -20,11 +20,11 @@ import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction;
import io.github.thebusybiscuit.slimefun4.api.SlimefunAddon;
import io.github.thebusybiscuit.slimefun4.core.attributes.NotPlaceable;
import io.github.thebusybiscuit.slimefun4.core.attributes.RecipeDisplayItem;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.core.handlers.MultiBlockInteractionHandler;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.Objects.handlers.MultiBlockInteractionHandler;
import me.mrCookieSlime.Slimefun.api.BlockStorage;
import me.mrCookieSlime.Slimefun.api.Slimefun;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;

View File

@ -1,6 +1,5 @@
package io.github.thebusybiscuit.slimefun4.core.networks.cargo;
import java.util.Deque;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
@ -12,19 +11,14 @@ import java.util.logging.Level;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.slimefun4.api.network.Network;
import io.github.thebusybiscuit.slimefun4.api.network.NetworkComponent;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.utils.holograms.SimpleHologram;
import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.api.BlockStorage;
import me.mrCookieSlime.Slimefun.api.Slimefun;
import me.mrCookieSlime.Slimefun.api.inventory.DirtyChestMenu;
/**
* The {@link CargoNet} is a type of {@link Network} which deals with {@link ItemStack} transportation.
@ -49,7 +43,7 @@ public class CargoNet extends ChestTerminalNetwork {
private final Set<Location> inputNodes = new HashSet<>();
private final Set<Location> outputNodes = new HashSet<>();
private final Map<Location, Integer> roundRobin = new HashMap<>();
protected final Map<Location, Integer> roundRobin = new HashMap<>();
private int tickDelayThreshold = 0;
public static CargoNet getNetworkFromLocation(Location l) {
@ -111,6 +105,8 @@ public class CargoNet extends ChestTerminalNetwork {
@Override
public void onClassificationChange(Location l, NetworkComponent from, NetworkComponent to) {
connectorCache.remove(l);
if (from == NetworkComponent.TERMINUS) {
inputNodes.remove(l);
outputNodes.remove(l);
@ -120,7 +116,8 @@ public class CargoNet extends ChestTerminalNetwork {
}
if (to == NetworkComponent.TERMINUS) {
switch (BlockStorage.checkID(l)) {
String id = BlockStorage.checkID(l);
switch (id) {
case "CARGO_NODE_INPUT":
inputNodes.add(l);
break;
@ -156,28 +153,65 @@ public class CargoNet extends ChestTerminalNetwork {
}
else {
SimpleHologram.update(b, "&7Status: &a&lONLINE");
Map<Integer, List<Location>> output = mapOutputNodes();
// Chest Terminal Stuff
Set<Location> destinations = new HashSet<>();
List<Location> output16 = output.get(16);
if (output16 != null) {
destinations.addAll(output16);
// Skip ticking if the threshold is not reached. The delay is not same as minecraft tick,
// but it's based on 'custom-ticker-delay' config.
if (tickDelayThreshold < TICK_DELAY) {
tickDelayThreshold++;
return;
}
Slimefun.runSync(() -> run(b, destinations, output));
// Reset the internal threshold, so we can start skipping again
tickDelayThreshold = 0;
// Chest Terminal Stuff
Set<Location> chestTerminalInputs = new HashSet<>();
Set<Location> chestTerminalOutputs = new HashSet<>();
Map<Location, Integer> inputs = mapInputNodes(chestTerminalInputs);
Map<Integer, List<Location>> outputs = mapOutputNodes(chestTerminalOutputs);
if (BlockStorage.getLocationInfo(b.getLocation(), "visualizer") == null) {
display();
}
SlimefunPlugin.getProfiler().scheduleEntries(1 + inputNodes.size());
CargoNetworkTask runnable = new CargoNetworkTask(this, inputs, outputs, chestTerminalInputs, chestTerminalOutputs);
Slimefun.runSync(runnable);
}
}
private Map<Integer, List<Location>> mapOutputNodes() {
private Map<Location, Integer> mapInputNodes(Set<Location> chestTerminalNodes) {
Map<Location, Integer> inputs = new HashMap<>();
for (Location node : inputNodes) {
int frequency = getFrequency(node);
if (frequency == 16) {
chestTerminalNodes.add(node);
}
else if (frequency >= 0 && frequency < 16) {
inputs.put(node, frequency);
}
}
return inputs;
}
private Map<Integer, List<Location>> mapOutputNodes(Set<Location> chestTerminalOutputs) {
Map<Integer, List<Location>> output = new HashMap<>();
List<Location> list = new LinkedList<>();
int lastFrequency = -1;
for (Location outputNode : outputNodes) {
int frequency = getFrequency(outputNode);
for (Location node : outputNodes) {
int frequency = getFrequency(node);
if (frequency == 16) {
chestTerminalOutputs.add(node);
continue;
}
if (frequency != lastFrequency && lastFrequency != -1) {
output.merge(lastFrequency, list, (prev, next) -> {
@ -188,7 +222,7 @@ public class CargoNet extends ChestTerminalNetwork {
list = new LinkedList<>();
}
list.add(outputNode);
list.add(node);
lastFrequency = frequency;
}
@ -202,153 +236,6 @@ public class CargoNet extends ChestTerminalNetwork {
return output;
}
private void run(Block b, Set<Location> destinations, Map<Integer, List<Location>> output) {
if (BlockStorage.getLocationInfo(b.getLocation(), "visualizer") == null) {
display();
}
// Skip ticking if the threshold is not reached. The delay is not same as minecraft tick,
// but it's based on 'custom-ticker-delay' config.
if (tickDelayThreshold < TICK_DELAY) {
tickDelayThreshold++;
return;
}
// Reset the internal threshold, so we can start skipping again
tickDelayThreshold = 0;
Map<Location, Integer> inputs = new HashMap<>();
Set<Location> providers = new HashSet<>();
for (Location node : inputNodes) {
int frequency = getFrequency(node);
if (frequency == 16) {
providers.add(node);
}
else if (frequency >= 0 && frequency < 16) {
inputs.put(node, frequency);
}
}
// Chest Terminal Code
if (SlimefunPlugin.getThirdPartySupportService().isChestTerminalInstalled()) {
handleItemRequests(providers, destinations);
}
// All operations happen here: Everything gets iterated from the Input Nodes.
// (Apart from ChestTerminal Buses)
for (Map.Entry<Location, Integer> entry : inputs.entrySet()) {
Location input = entry.getKey();
Optional<Block> attachedBlock = getAttachedBlock(input.getBlock());
if (attachedBlock.isPresent()) {
routeItems(input, attachedBlock.get(), entry.getValue(), output);
}
}
// Chest Terminal Code
if (SlimefunPlugin.getThirdPartySupportService().isChestTerminalInstalled()) {
updateTerminals(providers);
}
}
private void routeItems(Location inputNode, Block inputTarget, int frequency, Map<Integer, List<Location>> outputNodes) {
ItemStackAndInteger slot = CargoUtils.withdraw(inputNode.getBlock(), inputTarget);
if (slot == null) {
return;
}
ItemStack stack = slot.getItem();
int previousSlot = slot.getInt();
List<Location> outputs = outputNodes.get(frequency);
if (outputs != null) {
stack = distributeItem(stack, inputNode, outputs);
}
if (stack != null) {
DirtyChestMenu menu = CargoUtils.getChestMenu(inputTarget);
if (menu != null) {
if (menu.getItemInSlot(previousSlot) == null) {
menu.replaceExistingItem(previousSlot, stack);
}
else {
inputTarget.getWorld().dropItem(inputTarget.getLocation().add(0, 1, 0), stack);
}
}
else if (CargoUtils.hasInventory(inputTarget)) {
BlockState state = inputTarget.getState();
if (state instanceof InventoryHolder) {
Inventory inv = ((InventoryHolder) state).getInventory();
if (inv.getItem(previousSlot) == null) {
inv.setItem(previousSlot, stack);
}
else {
inputTarget.getWorld().dropItem(inputTarget.getLocation().add(0, 1, 0), stack);
}
}
}
}
}
private ItemStack distributeItem(ItemStack stack, Location inputNode, List<Location> outputNodes) {
ItemStack item = stack;
Deque<Location> destinations = new LinkedList<>(outputNodes);
Config cfg = BlockStorage.getLocationInfo(inputNode);
boolean roundrobin = "true".equals(cfg.getString("round-robin"));
if (roundrobin) {
roundRobinSort(inputNode, destinations);
}
for (Location output : destinations) {
Optional<Block> target = getAttachedBlock(output.getBlock());
if (target.isPresent()) {
item = CargoUtils.insert(output.getBlock(), target.get(), item);
if (item == null) {
break;
}
}
}
return item;
}
/**
* This method sorts a given {@link Deque} of output node locations using a semi-accurate
* round-robin method.
*
* @param inputNode
* The {@link Location} of the input node
* @param outputNodes
* A {@link Deque} of {@link Location Locations} of the output nodes
*/
private void roundRobinSort(Location inputNode, Deque<Location> outputNodes) {
int index = roundRobin.getOrDefault(inputNode, 0);
if (index < outputNodes.size()) {
// Not ideal but actually not bad performance-wise over more elegant alternatives
for (int i = 0; i < index; i++) {
Location temp = outputNodes.removeFirst();
outputNodes.add(temp);
}
index++;
}
else {
index = 1;
}
roundRobin.put(inputNode, index);
}
/**
* This method returns the frequency a given node is set to.
* Should there be an {@link Exception} to this method it will fall back to zero in

View File

@ -0,0 +1,183 @@
package io.github.thebusybiscuit.slimefun4.core.networks.cargo;
import java.util.Deque;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config;
import me.mrCookieSlime.Slimefun.api.BlockStorage;
import me.mrCookieSlime.Slimefun.api.inventory.DirtyChestMenu;
/**
* The {@link CargoNetworkTask} is the actual {@link Runnable} responsible for moving {@link ItemStack ItemStacks}
* around the {@link CargoNet}.
*
* Inbefore this was just a method in the {@link CargoNet} class.
* However for aesthetic reasons but mainly to prevent the Cargo Task from showing up as
* "lambda:xyz-123" in timing reports... this was moved.
*
* @see CargoNet
* @see CargoUtils
* @see ChestTerminalNetwork
*
*/
class CargoNetworkTask implements Runnable {
private final CargoNet network;
private final Map<Location, Inventory> inventories = new HashMap<>();
private final Map<Location, Integer> inputs;
private final Map<Integer, List<Location>> outputs;
private final Set<Location> chestTerminalInputs;
private final Set<Location> chestTerminalOutputs;
CargoNetworkTask(CargoNet network, Map<Location, Integer> inputs, Map<Integer, List<Location>> outputs, Set<Location> chestTerminalInputs, Set<Location> chestTerminalOutputs) {
this.network = network;
this.inputs = inputs;
this.outputs = outputs;
this.chestTerminalInputs = chestTerminalInputs;
this.chestTerminalOutputs = chestTerminalOutputs;
}
@Override
public void run() {
long timestamp = System.nanoTime();
// Chest Terminal Code
if (SlimefunPlugin.getThirdPartySupportService().isChestTerminalInstalled()) {
network.handleItemRequests(inventories, chestTerminalInputs, chestTerminalOutputs);
}
// All operations happen here: Everything gets iterated from the Input Nodes.
// (Apart from ChestTerminal Buses)
for (Map.Entry<Location, Integer> entry : inputs.entrySet()) {
long nodeTimestamp = System.nanoTime();
Location input = entry.getKey();
Optional<Block> attachedBlock = network.getAttachedBlock(input);
if (attachedBlock.isPresent()) {
routeItems(input, attachedBlock.get(), entry.getValue(), outputs);
}
// This will prevent this timings from showing up for the Cargo Manager
timestamp += SlimefunPlugin.getProfiler().closeEntry(entry.getKey(), SlimefunItems.CARGO_INPUT_NODE.getItem(), nodeTimestamp);
}
// Chest Terminal Code
if (SlimefunPlugin.getThirdPartySupportService().isChestTerminalInstalled()) {
network.updateTerminals(chestTerminalInputs);
}
// Submit a timings report
SlimefunPlugin.getProfiler().closeEntry(network.getRegulator(), SlimefunItems.CARGO_MANAGER.getItem(), timestamp);
}
private void routeItems(Location inputNode, Block inputTarget, int frequency, Map<Integer, List<Location>> outputNodes) {
ItemStackAndInteger slot = CargoUtils.withdraw(inventories, inputNode.getBlock(), inputTarget);
if (slot == null) {
return;
}
ItemStack stack = slot.getItem();
int previousSlot = slot.getInt();
List<Location> destinations = outputNodes.get(frequency);
if (destinations != null) {
stack = distributeItem(stack, inputNode, destinations);
}
if (stack != null) {
Inventory inv = inventories.get(inputTarget.getLocation());
if (inv != null) {
if (inv.getItem(previousSlot) == null) {
inv.setItem(previousSlot, stack);
}
else {
inputTarget.getWorld().dropItem(inputTarget.getLocation().add(0, 1, 0), stack);
}
}
else {
DirtyChestMenu menu = CargoUtils.getChestMenu(inputTarget);
if (menu != null) {
if (menu.getItemInSlot(previousSlot) == null) {
menu.replaceExistingItem(previousSlot, stack);
}
else {
inputTarget.getWorld().dropItem(inputTarget.getLocation().add(0, 1, 0), stack);
}
}
}
}
}
private ItemStack distributeItem(ItemStack stack, Location inputNode, List<Location> outputNodes) {
ItemStack item = stack;
Deque<Location> destinations = new LinkedList<>(outputNodes);
Config cfg = BlockStorage.getLocationInfo(inputNode);
boolean roundrobin = "true".equals(cfg.getString("round-robin"));
if (roundrobin) {
roundRobinSort(inputNode, destinations);
}
for (Location output : destinations) {
Optional<Block> target = network.getAttachedBlock(output);
if (target.isPresent()) {
item = CargoUtils.insert(inventories, output.getBlock(), target.get(), item);
if (item == null) {
break;
}
}
}
return item;
}
/**
* This method sorts a given {@link Deque} of output node locations using a semi-accurate
* round-robin method.
*
* @param inputNode
* The {@link Location} of the input node
* @param outputNodes
* A {@link Deque} of {@link Location Locations} of the output nodes
*/
private void roundRobinSort(Location inputNode, Deque<Location> outputNodes) {
int index = network.roundRobin.getOrDefault(inputNode, 0);
if (index < outputNodes.size()) {
// Not ideal but actually not bad performance-wise over more elegant alternatives
for (int i = 0; i < index; i++) {
Location temp = outputNodes.removeFirst();
outputNodes.add(temp);
}
index++;
}
else {
index = 1;
}
network.roundRobin.put(inputNode, index);
}
}

View File

@ -1,9 +1,9 @@
package io.github.thebusybiscuit.slimefun4.core.networks.cargo;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Tag;
import org.bukkit.block.Block;
@ -16,10 +16,10 @@ import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.cscorelib2.blocks.BlockPosition;
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
import io.github.thebusybiscuit.slimefun4.utils.itemstack.ItemStackWrapper;
import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.api.BlockStorage;
import me.mrCookieSlime.Slimefun.api.Slimefun;
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
@ -82,15 +82,23 @@ final class CargoUtils {
return false;
}
static ItemStack withdraw(Block node, Block target, ItemStack template) {
static ItemStack withdraw(Map<Location, Inventory> inventories, Block node, Block target, ItemStack template) {
DirtyChestMenu menu = getChestMenu(target);
if (menu == null) {
if (hasInventory(target)) {
Inventory inventory = inventories.get(target.getLocation());
if (inventory != null) {
return withdrawFromVanillaInventory(node, template, inventory);
}
BlockState state = target.getState();
if (state instanceof InventoryHolder) {
return withdrawFromVanillaInventory(node, template, ((InventoryHolder) state).getInventory());
inventory = ((InventoryHolder) state).getInventory();
inventories.put(target.getLocation(), inventory);
return withdrawFromVanillaInventory(node, template, inventory);
}
}
@ -134,10 +142,10 @@ final class CargoUtils {
ItemStackWrapper wrapper = new ItemStackWrapper(template);
for (int slot = minSlot; slot < maxSlot; slot++) {
// Changes to this ItemStack are synchronized with the Item in the Inventory
// Changes to these ItemStacks are synchronized with the Item in the Inventory
ItemStack itemInSlot = contents[slot];
if (SlimefunUtils.isItemSimilar(itemInSlot, wrapper, true) && matchesFilter(node, itemInSlot)) {
if (SlimefunUtils.isItemSimilar(itemInSlot, wrapper, true, false) && matchesFilter(node, itemInSlot)) {
if (itemInSlot.getAmount() > template.getAmount()) {
itemInSlot.setAmount(itemInSlot.getAmount() - template.getAmount());
return template;
@ -153,7 +161,7 @@ final class CargoUtils {
return null;
}
static ItemStackAndInteger withdraw(Block node, Block target) {
static ItemStackAndInteger withdraw(Map<Location, Inventory> inventories, Block node, Block target) {
DirtyChestMenu menu = getChestMenu(target);
if (menu != null) {
@ -167,38 +175,50 @@ final class CargoUtils {
}
}
else if (hasInventory(target)) {
Inventory inventory = inventories.get(target.getLocation());
if (inventory != null) {
return withdrawFromVanillaInventory(node, inventory);
}
BlockState state = target.getState();
if (state instanceof InventoryHolder) {
Inventory inv = ((InventoryHolder) state).getInventory();
ItemStack[] contents = inv.getContents();
int minSlot = 0;
int maxSlot = contents.length;
if (inv instanceof FurnaceInventory) {
minSlot = 2;
maxSlot = 3;
}
else if (inv instanceof BrewerInventory) {
maxSlot = 3;
}
for (int slot = minSlot; slot < maxSlot; slot++) {
ItemStack is = contents[slot];
if (matchesFilter(node, is)) {
inv.setItem(slot, null);
return new ItemStackAndInteger(is, slot);
}
}
inventory = ((InventoryHolder) state).getInventory();
inventories.put(target.getLocation(), inventory);
return withdrawFromVanillaInventory(node, inventory);
}
}
return null;
}
static ItemStack insert(Block node, Block target, ItemStack stack) {
private static ItemStackAndInteger withdrawFromVanillaInventory(Block node, Inventory inv) {
ItemStack[] contents = inv.getContents();
int minSlot = 0;
int maxSlot = contents.length;
if (inv instanceof FurnaceInventory) {
minSlot = 2;
maxSlot = 3;
}
else if (inv instanceof BrewerInventory) {
maxSlot = 3;
}
for (int slot = minSlot; slot < maxSlot; slot++) {
ItemStack is = contents[slot];
if (matchesFilter(node, is)) {
inv.setItem(slot, null);
return new ItemStackAndInteger(is, slot);
}
}
return null;
}
static ItemStack insert(Map<Location, Inventory> inventories, Block node, Block target, ItemStack stack) {
if (!matchesFilter(node, stack)) {
return stack;
}
@ -207,10 +227,18 @@ final class CargoUtils {
if (menu == null) {
if (hasInventory(target)) {
Inventory inventory = inventories.get(target.getLocation());
if (inventory != null) {
return insertIntoVanillaInventory(stack, inventory);
}
BlockState state = target.getState();
if (state instanceof InventoryHolder) {
return insertIntoVanillaInventory(stack, ((InventoryHolder) state).getInventory());
inventory = ((InventoryHolder) state).getInventory();
inventories.put(target.getLocation(), inventory);
return insertIntoVanillaInventory(stack, inventory);
}
}
@ -248,7 +276,7 @@ final class CargoUtils {
return stack;
}
static ItemStack insertIntoVanillaInventory(ItemStack stack, Inventory inv) {
private static ItemStack insertIntoVanillaInventory(ItemStack stack, Inventory inv) {
ItemStack[] contents = inv.getContents();
int minSlot = 0;
int maxSlot = contents.length;
@ -338,7 +366,7 @@ final class CargoUtils {
return stack != null && Tag.LOGS.isTagged(stack.getType());
}
else {
return SlimefunPlugin.getMinecraftRecipes().isSmeltable(stack);
return SlimefunPlugin.getMinecraftRecipeService().isSmeltable(stack);
}
}
@ -356,63 +384,52 @@ final class CargoUtils {
}
// Store the returned Config instance to avoid heavy calls
Config blockInfo = BlockStorage.getLocationInfo(block.getLocation());
String id = blockInfo.getString("id");
Config blockData = BlockStorage.getLocationInfo(block.getLocation());
String id = blockData.getString("id");
// Cargo Output nodes have no filter actually
if (id.equals("CARGO_NODE_OUTPUT")) {
return true;
}
try {
BlockMenu menu = BlockStorage.getInventory(block.getLocation());
if (menu == null) {
return false;
}
boolean lore = "true".equals(blockInfo.getString("filter-lore"));
ItemStackWrapper wrapper = new ItemStackWrapper(item);
if ("whitelist".equals(blockInfo.getString("filter-type"))) {
List<ItemStack> templateItems = new LinkedList<>();
for (int slot : FILTER_SLOTS) {
ItemStack template = menu.getItemInSlot(slot);
if (template != null) {
templateItems.add(template);
}
}
if (templateItems.isEmpty()) {
return false;
}
for (ItemStack stack : templateItems) {
if (SlimefunUtils.isItemSimilar(wrapper, stack, lore)) {
return true;
}
}
return false;
}
else {
for (int slot : FILTER_SLOTS) {
ItemStack itemInSlot = menu.getItemInSlot(slot);
if (itemInSlot != null && SlimefunUtils.isItemSimilar(wrapper, itemInSlot, lore, false)) {
return false;
}
}
return true;
}
boolean lore = "true".equals(blockData.getString("filter-lore"));
boolean allowByDefault = !"whitelist".equals(blockData.getString("filter-type"));
return matchesFilterList(item, menu, lore, allowByDefault);
}
catch (Exception x) {
Slimefun.getLogger().log(Level.SEVERE, x, () -> "An Exception occured while trying to filter items for a Cargo Node (" + id + ") at " + new BlockPosition(block));
Slimefun.getLogger().log(Level.SEVERE, x, () -> "An Exception occurred while trying to filter items for a Cargo Node (" + id + ") at " + new BlockPosition(block));
return false;
}
}
private static boolean matchesFilterList(ItemStack item, BlockMenu menu, boolean respectLore, boolean defaultValue) {
ItemStackWrapper wrapper = null;
for (int slot : FILTER_SLOTS) {
ItemStack stack = menu.getItemInSlot(slot);
if (stack != null) {
if (wrapper == null) {
// Only create this as needed to save performance
wrapper = new ItemStackWrapper(item);
}
if (SlimefunUtils.isItemSimilar(stack, wrapper, respectLore, false)) {
return !defaultValue;
}
}
}
return defaultValue;
}
/**
* Get the whitelist/blacklist slots in a Cargo Input Node. If you wish to access the items
* in the cargo (without hardcoding the slots in case of change) then you can use this method.

View File

@ -3,10 +3,12 @@ package io.github.thebusybiscuit.slimefun4.core.networks.cargo;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Queue;
import java.util.Set;
@ -26,10 +28,11 @@ import io.github.thebusybiscuit.cscorelib2.chat.ChatColors;
import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
import io.github.thebusybiscuit.cscorelib2.math.DoubleHandler;
import io.github.thebusybiscuit.slimefun4.api.network.Network;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils;
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.api.BlockStorage;
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
import me.mrCookieSlime.Slimefun.api.inventory.DirtyChestMenu;
@ -57,22 +60,37 @@ abstract class ChestTerminalNetwork extends Network {
// This represents a Queue of requests to handle
private final Queue<ItemRequest> itemRequests = new LinkedList<>();
// This is a cache for the BlockFace a node is facing, so we don't need to request the
// BlockData each time we visit a node
protected Map<Location, BlockFace> connectorCache = new HashMap<>();
protected ChestTerminalNetwork(Location regulator) {
super(SlimefunPlugin.getNetworkManager(), regulator);
}
protected static Optional<Block> getAttachedBlock(Block block) {
if (block.getType() == Material.PLAYER_WALL_HEAD) {
BlockFace face = ((Directional) block.getBlockData()).getFacing().getOppositeFace();
return Optional.of(block.getRelative(face));
protected Optional<Block> getAttachedBlock(Location l) {
if (l.getWorld().isChunkLoaded(l.getBlockX() >> 4, l.getBlockZ() >> 4)) {
Block block = l.getBlock();
if (block.getType() == Material.PLAYER_WALL_HEAD) {
BlockFace cached = connectorCache.get(l);
if (cached != null) {
return Optional.of(block.getRelative(cached));
}
BlockFace face = ((Directional) block.getBlockData()).getFacing().getOppositeFace();
connectorCache.put(l, face);
return Optional.of(block.getRelative(face));
}
}
return Optional.empty();
}
protected void handleItemRequests(Set<Location> providers, Set<Location> destinations) {
collectImportRequests();
collectExportRequests();
protected void handleItemRequests(Map<Location, Inventory> inventories, Set<Location> providers, Set<Location> destinations) {
collectImportRequests(inventories);
collectExportRequests(inventories);
collectTerminalRequests();
Iterator<ItemRequest> iterator = itemRequests.iterator();
@ -84,10 +102,10 @@ abstract class ChestTerminalNetwork extends Network {
switch (request.getDirection()) {
case INSERT:
distributeInsertionRequest(request, menu, iterator, destinations);
distributeInsertionRequest(inventories, request, menu, iterator, destinations);
break;
case WITHDRAW:
collectExtractionRequest(request, menu, iterator, providers);
collectExtractionRequest(inventories, request, menu, iterator, providers);
break;
default:
break;
@ -96,14 +114,14 @@ abstract class ChestTerminalNetwork extends Network {
}
}
private void distributeInsertionRequest(ItemRequest request, BlockMenu terminal, Iterator<ItemRequest> iterator, Set<Location> destinations) {
private void distributeInsertionRequest(Map<Location, Inventory> inventories, ItemRequest request, BlockMenu terminal, Iterator<ItemRequest> iterator, Set<Location> destinations) {
ItemStack item = request.getItem();
for (Location l : destinations) {
Optional<Block> target = getAttachedBlock(l.getBlock());
Optional<Block> target = getAttachedBlock(l);
if (target.isPresent()) {
item = CargoUtils.insert(l.getBlock(), target.get(), item);
item = CargoUtils.insert(inventories, l.getBlock(), target.get(), item);
if (item == null) {
terminal.replaceExistingItem(request.getSlot(), null);
@ -119,7 +137,7 @@ abstract class ChestTerminalNetwork extends Network {
iterator.remove();
}
private void collectExtractionRequest(ItemRequest request, BlockMenu terminal, Iterator<ItemRequest> iterator, Set<Location> providers) {
private void collectExtractionRequest(Map<Location, Inventory> inventories, ItemRequest request, BlockMenu terminal, Iterator<ItemRequest> iterator, Set<Location> providers) {
int slot = request.getSlot();
ItemStack prevStack = terminal.getItemInSlot(slot);
@ -132,10 +150,10 @@ abstract class ChestTerminalNetwork extends Network {
ItemStack item = request.getItem();
for (Location l : providers) {
Optional<Block> target = getAttachedBlock(l.getBlock());
Optional<Block> target = getAttachedBlock(l);
if (target.isPresent()) {
ItemStack is = CargoUtils.withdraw(l.getBlock(), target.get(), item);
ItemStack is = CargoUtils.withdraw(inventories, l.getBlock(), target.get(), item);
if (is != null) {
if (stack == null) {
@ -169,15 +187,18 @@ abstract class ChestTerminalNetwork extends Network {
iterator.remove();
}
private void collectImportRequests() {
private void collectImportRequests(Map<Location, Inventory> inventories) {
SlimefunItem item = SlimefunItem.getByID("CT_IMPORT_BUS");
for (Location bus : imports) {
long timestamp = SlimefunPlugin.getProfiler().newEntry();
BlockMenu menu = BlockStorage.getInventory(bus);
if (menu.getItemInSlot(17) == null) {
Optional<Block> target = getAttachedBlock(bus.getBlock());
Optional<Block> target = getAttachedBlock(bus);
if (target.isPresent()) {
ItemStackAndInteger stack = CargoUtils.withdraw(bus.getBlock(), target.get());
ItemStackAndInteger stack = CargoUtils.withdraw(inventories, bus.getBlock(), target.get());
if (stack != null) {
menu.replaceExistingItem(17, stack.getItem());
@ -188,18 +209,23 @@ abstract class ChestTerminalNetwork extends Network {
if (menu.getItemInSlot(17) != null) {
itemRequests.add(new ItemRequest(bus, 17, menu.getItemInSlot(17), ItemTransportFlow.INSERT));
}
SlimefunPlugin.getProfiler().closeEntry(bus, item, timestamp);
}
}
private void collectExportRequests() {
private void collectExportRequests(Map<Location, Inventory> inventories) {
SlimefunItem item = SlimefunItem.getByID("CT_EXPORT_BUS");
for (Location bus : exports) {
long timestamp = SlimefunPlugin.getProfiler().newEntry();
BlockMenu menu = BlockStorage.getInventory(bus);
if (menu.getItemInSlot(17) != null) {
Optional<Block> target = getAttachedBlock(bus.getBlock());
Optional<Block> target = getAttachedBlock(bus);
if (target.isPresent()) {
menu.replaceExistingItem(17, CargoUtils.insert(bus.getBlock(), target.get(), menu.getItemInSlot(17)));
menu.replaceExistingItem(17, CargoUtils.insert(inventories, bus.getBlock(), target.get(), menu.getItemInSlot(17)));
}
}
@ -208,7 +234,10 @@ abstract class ChestTerminalNetwork extends Network {
for (int slot : slots) {
ItemStack template = menu.getItemInSlot(slot);
if (template != null) items.add(new CustomItem(template, 1));
if (template != null) {
items.add(new CustomItem(template, 1));
}
}
if (!items.isEmpty()) {
@ -223,17 +252,24 @@ abstract class ChestTerminalNetwork extends Network {
itemRequests.add(new ItemRequest(bus, 17, items.get(index), ItemTransportFlow.WITHDRAW));
}
}
SlimefunPlugin.getProfiler().closeEntry(bus, item, timestamp);
}
}
private void collectTerminalRequests() {
SlimefunItem item = SlimefunItem.getByID("CHEST_TERMINAL");
for (Location terminal : terminals) {
long timestamp = SlimefunPlugin.getProfiler().newEntry();
BlockMenu menu = BlockStorage.getInventory(terminal);
ItemStack sendingItem = menu.getItemInSlot(TERMINAL_OUT_SLOT);
if (sendingItem != null) {
itemRequests.add(new ItemRequest(terminal, TERMINAL_OUT_SLOT, sendingItem, ItemTransportFlow.INSERT));
}
SlimefunPlugin.getProfiler().closeEntry(terminal, item, timestamp);
}
}
@ -269,6 +305,7 @@ abstract class ChestTerminalNetwork extends Network {
ItemStackAndInteger item = items.get(index);
ItemStack stack = item.getItem().clone();
stack.setAmount(1);
ItemMeta im = stack.getItemMeta();
List<String> lore = new ArrayList<>();
lore.add("");
@ -308,7 +345,7 @@ abstract class ChestTerminalNetwork extends Network {
List<ItemStackAndInteger> items = new LinkedList<>();
for (Location l : providers) {
Optional<Block> block = getAttachedBlock(l.getBlock());
Optional<Block> block = getAttachedBlock(l);
if (block.isPresent()) {
Block target = block.get();
@ -366,7 +403,7 @@ abstract class ChestTerminalNetwork extends Network {
}
if (add) {
items.add(new ItemStackAndInteger(new CustomItem(is, 1), is.getAmount() + stored));
items.add(new ItemStackAndInteger(is, is.getAmount() + stored));
}
}
}
@ -378,19 +415,19 @@ abstract class ChestTerminalNetwork extends Network {
}
}
private void filter(ItemStack is, List<ItemStackAndInteger> items, Location l) {
if (is != null && CargoUtils.matchesFilter(l.getBlock(), is)) {
private void filter(ItemStack stack, List<ItemStackAndInteger> items, Location node) {
if (stack != null && CargoUtils.matchesFilter(node.getBlock(), stack)) {
boolean add = true;
for (ItemStackAndInteger item : items) {
if (SlimefunUtils.isItemSimilar(is, item.getItem(), true)) {
if (SlimefunUtils.isItemSimilar(stack, item.getItem(), true)) {
add = false;
item.add(is.getAmount());
item.add(stack.getAmount());
}
}
if (add) {
items.add(new ItemStackAndInteger(new CustomItem(is, 1), is.getAmount()));
items.add(new ItemStackAndInteger(stack, stack.getAmount()));
}
}
}

View File

@ -3,6 +3,8 @@ package io.github.thebusybiscuit.slimefun4.core.networks.energy;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.LongConsumer;
import org.bukkit.Location;
import org.bukkit.Material;
@ -13,10 +15,11 @@ import io.github.thebusybiscuit.slimefun4.api.ErrorReport;
import io.github.thebusybiscuit.slimefun4.api.network.Network;
import io.github.thebusybiscuit.slimefun4.api.network.NetworkComponent;
import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetComponent;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.reactors.Reactor;
import io.github.thebusybiscuit.slimefun4.utils.holograms.SimpleHologram;
import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.Objects.handlers.GeneratorTicker;
import me.mrCookieSlime.Slimefun.api.BlockStorage;
@ -127,6 +130,8 @@ public class EnergyNet extends Network {
}
public void tick(Block b) {
AtomicLong timestamp = new AtomicLong(SlimefunPlugin.getProfiler().newEntry());
if (!regulator.equals(b.getLocation())) {
SimpleHologram.update(b, "&4Multiple Energy Regulators connected");
return;
@ -138,85 +143,90 @@ public class EnergyNet extends Network {
SimpleHologram.update(b, "&4No Energy Network found");
}
else {
double supply = DoubleHandler.fixDouble(tickAllGenerators() + tickAllCapacitors());
double supply = DoubleHandler.fixDouble(tickAllGenerators(timestamp::getAndAdd) + tickAllCapacitors());
double demand = 0;
int available = (int) supply;
int availableEnergy = (int) supply;
for (Location destination : consumers) {
int capacity = ChargableBlock.getMaxCharge(destination);
int charge = ChargableBlock.getCharge(destination);
for (Location machine : consumers) {
int capacity = ChargableBlock.getMaxCharge(machine);
int charge = ChargableBlock.getCharge(machine);
if (charge < capacity) {
int rest = capacity - charge;
demand += rest;
int availableSpace = capacity - charge;
demand += availableSpace;
if (available > 0) {
if (available > rest) {
ChargableBlock.setUnsafeCharge(destination, capacity, false);
available = available - rest;
if (availableEnergy > 0) {
if (availableEnergy > availableSpace) {
ChargableBlock.setUnsafeCharge(machine, capacity, false);
availableEnergy -= availableSpace;
}
else {
ChargableBlock.setUnsafeCharge(destination, charge + available, false);
available = 0;
ChargableBlock.setUnsafeCharge(machine, charge + availableEnergy, false);
availableEnergy = 0;
}
}
}
}
for (Location battery : storage) {
if (available > 0) {
int capacity = ChargableBlock.getMaxCharge(battery);
storeExcessEnergy(availableEnergy);
updateHologram(b, supply, demand);
}
// We have subtracted the timings from Generators, so they do not show up twice.
SlimefunPlugin.getProfiler().closeEntry(b.getLocation(), SlimefunItems.ENERGY_REGULATOR.getItem(), timestamp.get());
}
private void storeExcessEnergy(int available) {
for (Location capacitor : storage) {
if (available > 0) {
int capacity = ChargableBlock.getMaxCharge(capacitor);
if (available > capacity) {
ChargableBlock.setUnsafeCharge(capacitor, capacity, true);
available -= capacity;
}
else {
ChargableBlock.setUnsafeCharge(capacitor, available, true);
available = 0;
}
}
else {
ChargableBlock.setUnsafeCharge(capacitor, 0, true);
}
}
for (Location generator : generators) {
int capacity = ChargableBlock.getMaxCharge(generator);
if (capacity > 0) {
if (available > 0) {
if (available > capacity) {
ChargableBlock.setUnsafeCharge(battery, capacity, true);
ChargableBlock.setUnsafeCharge(generator, capacity, false);
available = available - capacity;
}
else {
ChargableBlock.setUnsafeCharge(battery, available, true);
ChargableBlock.setUnsafeCharge(generator, available, false);
available = 0;
}
}
else {
ChargableBlock.setUnsafeCharge(battery, 0, true);
ChargableBlock.setUnsafeCharge(generator, 0, false);
}
}
for (Location source : generators) {
if (ChargableBlock.isChargable(source)) {
if (available > 0) {
int capacity = ChargableBlock.getMaxCharge(source);
if (available > capacity) {
ChargableBlock.setUnsafeCharge(source, capacity, false);
available = available - capacity;
}
else {
ChargableBlock.setUnsafeCharge(source, available, false);
available = 0;
}
}
else {
ChargableBlock.setUnsafeCharge(source, 0, false);
}
}
}
updateHologram(b, supply, demand);
}
}
private double tickAllGenerators() {
private double tickAllGenerators(LongConsumer timeCallback) {
double supply = 0;
Set<Location> exploded = new HashSet<>();
for (Location source : generators) {
long timestamp = System.currentTimeMillis();
SlimefunItem item = BlockStorage.check(source);
long timestamp = SlimefunPlugin.getProfiler().newEntry();
Config config = BlockStorage.getLocationInfo(source);
SlimefunItem item = SlimefunItem.getByID(config.getString("id"));
if (item != null) {
Config config = BlockStorage.getLocationInfo(source);
try {
GeneratorTicker generator = item.getEnergyTicker();
@ -247,7 +257,8 @@ public class EnergyNet extends Network {
new ErrorReport(t, source, item);
}
SlimefunPlugin.getTicker().addBlockTimings(source, System.currentTimeMillis() - timestamp);
long time = SlimefunPlugin.getProfiler().closeEntry(source, item, timestamp);
timeCallback.accept(time);
}
else {
// This block seems to be gone now, better remove it to be extra safe
@ -263,8 +274,8 @@ public class EnergyNet extends Network {
private double tickAllCapacitors() {
double supply = 0;
for (Location battery : storage) {
supply += ChargableBlock.getCharge(battery);
for (Location capacitor : storage) {
supply += ChargableBlock.getCharge(capacitor);
}
return supply;

View File

@ -18,9 +18,9 @@ import io.github.thebusybiscuit.slimefun4.api.events.ResearchUnlockEvent;
import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile;
import io.github.thebusybiscuit.slimefun4.core.guide.options.SlimefunGuideSettings;
import io.github.thebusybiscuit.slimefun4.core.services.localization.Language;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.setup.ResearchSetup;
import io.github.thebusybiscuit.slimefun4.utils.FireworkUtils;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.api.Slimefun;
@ -110,7 +110,7 @@ public class Research implements Keyed {
* @return The localized Name of this {@link Research}.
*/
public String getName(Player p) {
String localized = SlimefunPlugin.getLocal().getResearchName(p, key);
String localized = SlimefunPlugin.getLocalization().getResearchName(p, key);
return localized != null ? localized : name;
}
@ -222,7 +222,7 @@ public class Research implements Keyed {
if (!instant) {
Slimefun.runSync(() -> {
p.playSound(p.getLocation(), Sound.ENTITY_BAT_TAKEOFF, 0.7F, 1F);
SlimefunPlugin.getLocal().sendMessage(p, "messages.research.progress", true, msg -> msg.replace(PLACEHOLDER_RESEARCH, getName(p)).replace("%progress%", "0%"));
SlimefunPlugin.getLocalization().sendMessage(p, "messages.research.progress", true, msg -> msg.replace(PLACEHOLDER_RESEARCH, getName(p)).replace("%progress%", "0%"));
}, 10L);
}
PlayerProfile.get(p, profile -> {
@ -235,7 +235,7 @@ public class Research implements Keyed {
finishResearch(p, profile, callback);
}
else if (SlimefunPlugin.getRegistry().getCurrentlyResearchingPlayers().add(p.getUniqueId())) {
SlimefunPlugin.getLocal().sendMessage(p, "messages.research.start", true, msg -> msg.replace(PLACEHOLDER_RESEARCH, getName(p)));
SlimefunPlugin.getLocalization().sendMessage(p, "messages.research.start", true, msg -> msg.replace(PLACEHOLDER_RESEARCH, getName(p)));
playResearchAnimation(p);
Slimefun.runSync(() -> {
@ -251,7 +251,7 @@ public class Research implements Keyed {
private void finishResearch(Player p, PlayerProfile profile, Consumer<Player> callback) {
profile.setResearched(this, true);
SlimefunPlugin.getLocal().sendMessage(p, "messages.unlocked", true, msg -> msg.replace(PLACEHOLDER_RESEARCH, getName(p)));
SlimefunPlugin.getLocalization().sendMessage(p, "messages.unlocked", true, msg -> msg.replace(PLACEHOLDER_RESEARCH, getName(p)));
callback.accept(p);
if (SlimefunPlugin.getRegistry().isResearchFireworkEnabled() && SlimefunGuideSettings.hasFireworksEnabled(p)) {
@ -265,7 +265,7 @@ public class Research implements Keyed {
Slimefun.runSync(() -> {
p.playSound(p.getLocation(), Sound.ENTITY_BAT_TAKEOFF, 0.7F, 1F);
SlimefunPlugin.getLocal().sendMessage(p, "messages.research.progress", true, msg -> msg.replace(PLACEHOLDER_RESEARCH, getName(p)).replace("%progress%", RESEARCH_PROGRESS[j - 1] + "%"));
SlimefunPlugin.getLocalization().sendMessage(p, "messages.research.progress", true, msg -> msg.replace(PLACEHOLDER_RESEARCH, getName(p)).replace("%progress%", RESEARCH_PROGRESS[j - 1] + "%"));
}, i * 20L);
}
}

View File

@ -11,7 +11,7 @@ import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.api.BlockStorage;
import me.mrCookieSlime.Slimefun.api.Slimefun;

View File

@ -15,7 +15,7 @@ import java.util.logging.Level;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.api.Slimefun;
/**
@ -60,7 +60,7 @@ public class BackupService implements Runnable {
}
}
catch (IOException x) {
Slimefun.getLogger().log(Level.SEVERE, x, () -> "An Error occured while creating a backup for Slimefun " + SlimefunPlugin.getVersion());
Slimefun.getLogger().log(Level.SEVERE, x, () -> "An Error occurred while creating a backup for Slimefun " + SlimefunPlugin.getVersion());
}
}
}

View File

@ -12,7 +12,7 @@ import org.bukkit.persistence.PersistentDataHolder;
import org.bukkit.plugin.Plugin;
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
/**
* The {@link BlockDataService} is similar to the {@link CustomItemDataService},

View File

@ -3,6 +3,7 @@ package io.github.thebusybiscuit.slimefun4.core.services;
import java.util.Optional;
import org.bukkit.Keyed;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
@ -65,7 +66,7 @@ public class CustomItemDataService implements PersistentDataService, Keyed {
* @return An {@link Optional} describing the result
*/
public Optional<String> getItemData(ItemStack item) {
if (item == null || !item.hasItemMeta()) {
if (item == null || item.getType() == Material.AIR || !item.hasItemMeta()) {
return Optional.empty();
}

View File

@ -8,7 +8,7 @@ import org.bukkit.inventory.meta.ItemMeta;
import io.github.thebusybiscuit.cscorelib2.config.Config;
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;

View File

@ -19,7 +19,7 @@ import org.bukkit.entity.Player;
import io.github.thebusybiscuit.cscorelib2.math.DoubleHandler;
import io.github.thebusybiscuit.slimefun4.core.services.localization.Language;
import io.github.thebusybiscuit.slimefun4.core.services.localization.SlimefunLocalization;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.api.Slimefun;
/**

View File

@ -21,7 +21,7 @@ import io.github.thebusybiscuit.cscorelib2.collections.OptionalMap;
import io.github.thebusybiscuit.cscorelib2.config.Config;
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
import io.github.thebusybiscuit.slimefun4.api.SlimefunAddon;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
/**
@ -53,7 +53,7 @@ public class PerWorldSettingsService {
migrate();
}
catch (IOException e) {
plugin.getLogger().log(Level.WARNING, "An error occured while migrating old world settings", e);
plugin.getLogger().log(Level.WARNING, "An error occurred while migrating old world settings", e);
}
for (World world : worlds) {

View File

@ -12,7 +12,7 @@ import org.bukkit.permissions.Permissible;
import org.bukkit.permissions.Permission;
import io.github.thebusybiscuit.cscorelib2.config.Config;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
/**

View File

@ -8,7 +8,7 @@ import org.bukkit.persistence.PersistentDataHolder;
import org.bukkit.persistence.PersistentDataType;
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
/**
* This interface is used to defer calls to Persistent Data and make sure they are only called

View File

@ -9,8 +9,8 @@ import io.github.thebusybiscuit.cscorelib2.config.Config;
import io.github.thebusybiscuit.cscorelib2.updater.GitHubBuildsUpdater;
import io.github.thebusybiscuit.cscorelib2.updater.Updater;
import io.github.thebusybiscuit.slimefun4.api.SlimefunBranch;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.utils.PatternUtils;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
/**
* This Class represents our {@link Updater} Service.

View File

@ -13,6 +13,7 @@ import org.apache.commons.lang.Validate;
import org.bukkit.ChatColor;
import io.github.thebusybiscuit.cscorelib2.data.ComputedOptional;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.utils.HeadTexture;
/**
@ -132,7 +133,8 @@ public class Contributor {
*/
public String getTexture() {
if (!headTexture.isComputed() || !headTexture.isPresent()) {
return HeadTexture.UNKNOWN.getTexture();
String cached = SlimefunPlugin.getGitHubService().getCachedTexture(githubUsername);
return cached != null ? cached : HeadTexture.UNKNOWN.getTexture();
}
else {
return headTexture.get();

View File

@ -16,7 +16,7 @@ import java.util.logging.Level;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.api.Slimefun;
abstract class GitHubConnector {
@ -98,7 +98,7 @@ abstract class GitHubConnector {
onSuccess(element);
}
catch (IOException x) {
Slimefun.getLogger().log(Level.SEVERE, x, () -> "An Error occured while parsing GitHub-Data for Slimefun " + SlimefunPlugin.getVersion());
Slimefun.getLogger().log(Level.SEVERE, x, () -> "An Error occurred while parsing GitHub-Data for Slimefun " + SlimefunPlugin.getVersion());
onFailure();
}
}

View File

@ -14,8 +14,9 @@ import com.google.gson.JsonObject;
import io.github.thebusybiscuit.cscorelib2.config.Config;
import io.github.thebusybiscuit.slimefun4.core.services.localization.Translators;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.utils.HeadTexture;
import io.github.thebusybiscuit.slimefun4.utils.NumberUtils;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
/**
* This Service is responsible for grabbing every {@link Contributor} to this project
@ -30,7 +31,9 @@ public class GitHubService {
private final String repository;
private final Set<GitHubConnector> connectors;
private final ConcurrentMap<String, Contributor> contributors;
private final Config uuidCache = new Config("plugins/Slimefun/cache/github/uuids.yml");
private final Config texturesCache = new Config("plugins/Slimefun/cache/github/skins.yml");
private boolean logging = false;
@ -73,10 +76,12 @@ public class GitHubService {
contributors.put(name, contributor);
}
public Contributor addContributor(String name, String profile, String role, int commits) {
Contributor contributor = contributors.computeIfAbsent(name, key -> new Contributor(name, profile));
public Contributor addContributor(String minecraftName, String profile, String role, int commits) {
String username = profile.substring(profile.lastIndexOf('/') + 1);
Contributor contributor = contributors.computeIfAbsent(username, key -> new Contributor(minecraftName, profile));
contributor.setContribution(role, commits);
contributor.setUniqueId(uuidCache.getUUID(name));
contributor.setUniqueId(uuidCache.getUUID(minecraftName));
return contributor;
}
@ -194,18 +199,31 @@ public class GitHubService {
}
/**
* This will store the {@link UUID} of all {@link Contributor Contributors} in memory
* in a {@link File} to save requests the next time we iterate over them.
* This will store the {@link UUID} and texture of all {@link Contributor Contributors}
* in memory in a {@link File} to save requests the next time we iterate over them.
*/
protected void saveUUIDCache() {
protected void saveCache() {
for (Contributor contributor : contributors.values()) {
Optional<UUID> uuid = contributor.getUniqueId();
if (uuid.isPresent()) {
uuidCache.setValue(contributor.getName(), uuid.get());
}
if (contributor.hasTexture()) {
String texture = contributor.getTexture();
if (!texture.equals(HeadTexture.UNKNOWN.getTexture())) {
texturesCache.setValue(contributor.getName(), texture);
}
}
}
uuidCache.save();
texturesCache.save();
}
protected String getCachedTexture(String name) {
return texturesCache.getString(name);
}
}

View File

@ -11,7 +11,7 @@ import org.bukkit.Bukkit;
import io.github.thebusybiscuit.cscorelib2.players.MinecraftAccount;
import io.github.thebusybiscuit.cscorelib2.players.MinecraftAccount.TooManyRequestsException;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.api.Slimefun;
/**
@ -56,9 +56,9 @@ class GitHubTask implements Runnable {
}
}
if (requests >= MAX_REQUESTS_PER_MINUTE) {
if (requests >= MAX_REQUESTS_PER_MINUTE && SlimefunPlugin.instance() != null && SlimefunPlugin.instance().isEnabled()) {
// Slow down API requests and wait a minute after more than x requests were made
Bukkit.getScheduler().runTaskLaterAsynchronously(SlimefunPlugin.instance, this::grabTextures, 2 * 60 * 20L);
Bukkit.getScheduler().runTaskLaterAsynchronously(SlimefunPlugin.instance(), this::grabTextures, 2 * 60 * 20L);
}
for (GitHubConnector connector : gitHubService.getConnectors()) {
@ -69,7 +69,7 @@ class GitHubTask implements Runnable {
// We only wanna save this if all Connectors finished already
// This will run multiple times but thats okay, this way we get as much data as possible stored
gitHubService.saveUUIDCache();
gitHubService.saveCache();
}
private int requestTexture(Contributor contributor, Map<String, String> skins) {
@ -94,14 +94,14 @@ class GitHubTask implements Runnable {
// Retry after 5 minutes if it was rate-limiting
if (x.getMessage().contains("429")) {
Bukkit.getScheduler().runTaskLaterAsynchronously(SlimefunPlugin.instance, this::grabTextures, 5 * 60 * 20L);
Bukkit.getScheduler().runTaskLaterAsynchronously(SlimefunPlugin.instance(), this::grabTextures, 5 * 60 * 20L);
}
return -1;
}
catch (TooManyRequestsException x) {
Slimefun.getLogger().log(Level.WARNING, "Received a rate-limit from mojang.com, retrying in 4 minutes");
Bukkit.getScheduler().runTaskLaterAsynchronously(SlimefunPlugin.instance, this::grabTextures, 4 * 60 * 20L);
Bukkit.getScheduler().runTaskLaterAsynchronously(SlimefunPlugin.instance(), this::grabTextures, 4 * 60 * 20L);
return -1;
}

View File

@ -10,8 +10,8 @@ import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuide;
import io.github.thebusybiscuit.slimefun4.core.services.LocalizationService;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
/**
* This Class represents a {@link Language} that Slimefun can recognize and use.
@ -129,7 +129,7 @@ public final class Language {
* @return The localized name of this {@link Language}
*/
public String getName(Player p) {
String name = SlimefunPlugin.getLocal().getMessage(p, "languages." + id);
String name = SlimefunPlugin.getLocalization().getMessage(p, "languages." + id);
return name != null ? name : toString();
}
@ -140,7 +140,7 @@ public final class Language {
* @return Whether this is the default {@link Language} of this {@link Server}
*/
public boolean isDefault() {
return this == SlimefunPlugin.getLocal().getDefaultLanguage();
return this == SlimefunPlugin.getLocalization().getDefaultLanguage();
}
@Override

View File

@ -21,7 +21,7 @@ import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
import io.github.thebusybiscuit.slimefun4.api.SlimefunBranch;
import io.github.thebusybiscuit.slimefun4.core.services.LocalizationService;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
/**

View File

@ -39,11 +39,11 @@ enum SupportedLanguage {
GREEK("el", false, "1514de6dd2b7682b1d3ebcd10291ae1f021e3012b5c8beffeb75b1819eb4259d"),
SLOVAK("sk", true, "6c72a8c115a1fb669a25715c4d15f22136ac4c2452784e4894b3d56bc5b0b9"),
VIETNAMESE("vi", true, "8a57b9d7dd04169478cfdb8d0b6fd0b8c82b6566bb28371ee9a7c7c1671ad0bb"),
INDONESIAN("id", false, "5db2678ccaba7934412cb97ee16d416463a392574c5906352f18dea42895ee"),
INDONESIAN("id", true, "5db2678ccaba7934412cb97ee16d416463a392574c5906352f18dea42895ee"),
CHINESE_CHINA("zh-CN", true, "7f9bc035cdc80f1ab5e1198f29f3ad3fdd2b42d9a69aeb64de990681800b98dc"),
CHINESE_TAIWAN("zh-TW", true, "702a4afb2e1e2e3a1894a8b74272f95cfa994ce53907f9ac140bd3c932f9f"),
JAPANESE("ja", true, "d640ae466162a47d3ee33c4076df1cab96f11860f07edb1f0832c525a9e33323"),
KOREAN("kr", false, "fc1be5f12f45e413eda56f3de94e08d90ede8e339c7b1e8f32797390e9a5f"),
KOREAN("ko", false, "fc1be5f12f45e413eda56f3de94e08d90ede8e339c7b1e8f32797390e9a5f"),
HEBREW("he", false, "1ba086a2cc7272cf5ba49c80248546c22e5ef1bab54120e8a8e5d9e75b6a"),
ARABIC("ar", true, "a4be759a9cf7f0a19a7e8e62f23789ad1d21cebae38af9d9541676a3db001572"),
TURKISH("tr", true, "9852b9aba3482348514c1034d0affe73545c9de679ae4647f99562b5e5f47d09"),

View File

@ -130,6 +130,10 @@ public class Translators {
// Translators - Indonesian
addTranslator("diradho", SupportedLanguage.INDONESIAN, false);
addTranslator("Frozenkamui", SupportedLanguage.INDONESIAN, false);
addTranslator("aril3721", SupportedLanguage.INDONESIAN, false);
addTranslator("JunederZ", SupportedLanguage.INDONESIAN, false);
addTranslator("EnderWingZ", SupportedLanguage.INDONESIAN, false);
// Translators - Thai
addTranslator("phoomin2012", SupportedLanguage.THAI, false);
@ -154,6 +158,8 @@ public class Translators {
addTranslator("G4stavoM1ster", SupportedLanguage.PORTUGUESE_BRAZIL, true);
addTranslator("yurinogueira", SupportedLanguage.PORTUGUESE_BRAZIL, true);
addTranslator("Sakanas", SupportedLanguage.PORTUGUESE_BRAZIL, true);
addTranslator("krazybeat", SupportedLanguage.PORTUGUESE_BRAZIL, true);
addTranslator("FaolanMalcadh", SupportedLanguage.PORTUGUESE_BRAZIL, true);
}
private void addTranslator(String name, SupportedLanguage lang, boolean lock) {

View File

@ -6,7 +6,7 @@ import java.util.Map;
import org.bstats.bukkit.Metrics.AdvancedPie;
import org.bukkit.plugin.Plugin;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
class AddonsChart extends AdvancedPie {

View File

@ -2,7 +2,7 @@ package io.github.thebusybiscuit.slimefun4.core.services.metrics;
import org.bstats.bukkit.Metrics.SimplePie;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
class AutoUpdaterChart extends SimplePie {

View File

@ -6,7 +6,7 @@ import java.util.Map;
import org.bstats.bukkit.Metrics.AdvancedPie;
import io.github.thebusybiscuit.slimefun4.core.commands.SubCommand;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
class CommandChart extends AdvancedPie {

View File

@ -2,7 +2,7 @@ package io.github.thebusybiscuit.slimefun4.core.services.metrics;
import org.bstats.bukkit.Metrics.SimplePie;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
class CompatibilityModeChart extends SimplePie {

View File

@ -2,7 +2,7 @@ package io.github.thebusybiscuit.slimefun4.core.services.metrics;
import org.bstats.bukkit.Metrics.SimplePie;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
class GuideLayoutChart extends SimplePie {

View File

@ -3,7 +3,7 @@ package io.github.thebusybiscuit.slimefun4.core.services.metrics;
import org.bstats.bukkit.Metrics;
import org.bukkit.plugin.Plugin;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
/**
* This Class represents a Metrics Service that sends data to https://bstats.org/

View File

@ -8,7 +8,7 @@ import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import io.github.thebusybiscuit.slimefun4.core.services.localization.Language;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
class PlayerLanguageChart extends AdvancedPie {
@ -17,8 +17,8 @@ class PlayerLanguageChart extends AdvancedPie {
Map<String, Integer> languages = new HashMap<>();
for (Player p : Bukkit.getOnlinePlayers()) {
Language language = SlimefunPlugin.getLocal().getLanguage(p);
boolean supported = SlimefunPlugin.getLocal().isLanguageLoaded(language.getId());
Language language = SlimefunPlugin.getLocalization().getLanguage(p);
boolean supported = SlimefunPlugin.getLocalization().isLanguageLoaded(language.getId());
String lang = supported ? language.getId() : "Unsupported Language";
languages.merge(lang, 1, Integer::sum);

View File

@ -2,7 +2,7 @@ package io.github.thebusybiscuit.slimefun4.core.services.metrics;
import org.bstats.bukkit.Metrics.SimplePie;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
class ResearchesEnabledChart extends SimplePie {

View File

@ -2,7 +2,7 @@ package io.github.thebusybiscuit.slimefun4.core.services.metrics;
import org.bstats.bukkit.Metrics.SimplePie;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
class ResourcePackChart extends SimplePie {

View File

@ -3,14 +3,14 @@ package io.github.thebusybiscuit.slimefun4.core.services.metrics;
import org.bstats.bukkit.Metrics.SimplePie;
import io.github.thebusybiscuit.slimefun4.core.services.localization.Language;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
class ServerLanguageChart extends SimplePie {
ServerLanguageChart() {
super("language", () -> {
Language language = SlimefunPlugin.getLocal().getDefaultLanguage();
boolean supported = SlimefunPlugin.getLocal().isLanguageLoaded(language.getId());
Language language = SlimefunPlugin.getLocalization().getDefaultLanguage();
boolean supported = SlimefunPlugin.getLocalization().isLanguageLoaded(language.getId());
return supported ? language.getId() : "Unsupported Language";
});
}

View File

@ -5,7 +5,7 @@ import java.util.Map;
import org.bstats.bukkit.Metrics.DrilldownPie;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
class SlimefunVersionChart extends DrilldownPie {

Some files were not shown because too many files have changed in this diff Show More