mirror of
https://github.com/StarWishsama/Slimefun4.git
synced 2024-09-19 19:25:48 +00:00
Various improvements, including Pull Request #1790
This commit is contained in:
parent
dfb47ddfbb
commit
a04676b27c
@ -48,6 +48,8 @@
|
||||
* GEO Miner is now 2 seconds faster
|
||||
* All Generators will now stop consuming fuel if no energy is needed
|
||||
* /sf teleporter will now open your own Teleporter Menu if you specify no Player
|
||||
* Added counter-measures against Players who design Cargo networks in a way that intentionally lags out servers
|
||||
* API requests to Mojang are now spread across a longer time period to prevent rate-limits
|
||||
|
||||
#### Fixes
|
||||
* Fixed error message when clicking empty slots in the Slimefun Guide
|
||||
|
2
pom.xml
2
pom.xml
@ -216,7 +216,7 @@
|
||||
<dependency>
|
||||
<groupId>com.github.thebusybiscuit</groupId>
|
||||
<artifactId>CS-CoreLib2</artifactId>
|
||||
<version>0.14</version>
|
||||
<version>0.15</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
@ -1,11 +1,17 @@
|
||||
package io.github.thebusybiscuit.slimefun4.api;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Locale;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.PluginDescriptionFile;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
|
||||
import me.mrCookieSlime.Slimefun.Objects.Category;
|
||||
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
||||
|
||||
/**
|
||||
@ -89,4 +95,15 @@ public interface SlimefunAddon {
|
||||
return description.getDepend().contains(dependency) || description.getSoftDepend().contains(dependency);
|
||||
}
|
||||
|
||||
/**
|
||||
* This returns a {@link Collection} holding every {@link Category} that can be directly
|
||||
* linked to this {@link SlimefunAddon} based on its {@link NamespacedKey}.
|
||||
*
|
||||
* @return A {@link Collection} of every {@link Category} from this addon
|
||||
*/
|
||||
default Collection<Category> getCategories() {
|
||||
String namespace = getJavaPlugin().getName().toLowerCase(Locale.ROOT);
|
||||
return SlimefunPlugin.getRegistry().getCategories().stream().filter(cat -> cat.getKey().getNamespace().equals(namespace)).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -73,7 +73,7 @@ public final class SlimefunGuideSettings {
|
||||
return false;
|
||||
});
|
||||
|
||||
menu.addItem(2, new CustomItem(SkullItem.fromBase64("eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZTk1MmQyYjNmMzUxYTZiMDQ4N2NjNTlkYjMxYmY1ZjI2NDExMzNlNWJhMDAwNmIxODU3NmU5OTZhMDI5M2U1MiJ9fX0="), "&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.", "&7Here you can find them all", "", "&7\u21E8 &eClick to see our contributors"), (pl, slot, action, item) -> {
|
||||
menu.addItem(2, new CustomItem(SkullItem.fromHash("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) -> {
|
||||
ContributorsMenu.open(pl, 0);
|
||||
return false;
|
||||
});
|
||||
|
@ -1,32 +0,0 @@
|
||||
package io.github.thebusybiscuit.slimefun4.core.networks.cargo;
|
||||
|
||||
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
|
||||
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
|
||||
final class BlockUtils {
|
||||
|
||||
private BlockUtils() {}
|
||||
|
||||
public static boolean hasInventory(Block block) {
|
||||
if (block == null) return false;
|
||||
|
||||
Material type = block.getType();
|
||||
switch (type) {
|
||||
case CHEST:
|
||||
case TRAPPED_CHEST:
|
||||
case FURNACE:
|
||||
case DISPENSER:
|
||||
case DROPPER:
|
||||
case HOPPER:
|
||||
case BREWING_STAND:
|
||||
return true;
|
||||
default:
|
||||
if (type.name().endsWith("SHULKER_BOX")) return true;
|
||||
|
||||
return (SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_14) &&
|
||||
(type == Material.BARREL || type == Material.BLAST_FURNACE || type == Material.LECTERN || type == Material.SMOKER));
|
||||
}
|
||||
}
|
||||
}
|
@ -27,7 +27,7 @@ import me.mrCookieSlime.Slimefun.api.inventory.DirtyChestMenu;
|
||||
public class CargoNet extends ChestTerminalNetwork {
|
||||
|
||||
private static final int RANGE = 5;
|
||||
private static final int TICK_DELAY = SlimefunPlugin.getCfg().getInt("URID.cargo-network-tick-delay");
|
||||
private static final int TICK_DELAY = SlimefunPlugin.getCfg().getInt("networks.cargo-ticker-delay");
|
||||
|
||||
private final Set<Location> inputNodes = new HashSet<>();
|
||||
private final Set<Location> outputNodes = new HashSet<>();
|
||||
@ -183,7 +183,9 @@ public class CargoNet extends ChestTerminalNetwork {
|
||||
tickDelayThreshold++;
|
||||
return;
|
||||
}
|
||||
tickDelayThreshold = 0; // reset, so we can start skipping again
|
||||
|
||||
// Reset the internal threshold, so we can start skipping again
|
||||
tickDelayThreshold = 0;
|
||||
|
||||
Map<Location, Integer> inputs = new HashMap<>();
|
||||
Set<Location> providers = new HashSet<>();
|
||||
@ -208,6 +210,7 @@ public class CargoNet extends ChestTerminalNetwork {
|
||||
// (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()) {
|
||||
continue;
|
||||
@ -231,11 +234,14 @@ public class CargoNet extends ChestTerminalNetwork {
|
||||
|
||||
if (roundrobin) {
|
||||
int index = roundRobin.getOrDefault(input, 0);
|
||||
|
||||
if (index < outputlist.size()) {
|
||||
|
||||
for (int i = 0; i < index; i++) {
|
||||
Location temp = outputlist.remove(0);
|
||||
outputlist.add(temp);
|
||||
}
|
||||
|
||||
index++;
|
||||
}
|
||||
else {
|
||||
@ -260,7 +266,7 @@ public class CargoNet extends ChestTerminalNetwork {
|
||||
if (menu != null) {
|
||||
menu.replaceExistingItem(previousSlot, stack);
|
||||
}
|
||||
else if (BlockUtils.hasInventory(inputTarget)) {
|
||||
else if (CargoUtils.hasInventory(inputTarget)) {
|
||||
BlockState state = inputTarget.getState();
|
||||
|
||||
if (state instanceof InventoryHolder) {
|
||||
|
@ -12,9 +12,11 @@ import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
|
||||
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.inventory.BlockMenu;
|
||||
import me.mrCookieSlime.Slimefun.api.inventory.DirtyChestMenu;
|
||||
@ -27,11 +29,52 @@ final class CargoUtils {
|
||||
|
||||
private CargoUtils() {}
|
||||
|
||||
public static boolean hasInventory(Block block) {
|
||||
if (block == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Material type = block.getType();
|
||||
|
||||
switch (type) {
|
||||
case CHEST:
|
||||
case TRAPPED_CHEST:
|
||||
case FURNACE:
|
||||
case DISPENSER:
|
||||
case DROPPER:
|
||||
case HOPPER:
|
||||
case BREWING_STAND:
|
||||
case SHULKER_BOX:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (type.name().endsWith("_SHULKER_BOX")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_14)) {
|
||||
switch (type) {
|
||||
case BARREL:
|
||||
case BLAST_FURNACE:
|
||||
case SMOKER:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static ItemStack withdraw(Block node, Block target, ItemStack template) {
|
||||
DirtyChestMenu menu = getChestMenu(target);
|
||||
|
||||
if (menu == null) {
|
||||
if (BlockUtils.hasInventory(target)) {
|
||||
if (hasInventory(target)) {
|
||||
BlockState state = target.getState();
|
||||
|
||||
if (state instanceof InventoryHolder) {
|
||||
return withdrawFromVanillaInventory(node, template, ((InventoryHolder) state).getInventory());
|
||||
}
|
||||
@ -106,7 +149,7 @@ final class CargoUtils {
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (BlockUtils.hasInventory(target)) {
|
||||
else if (hasInventory(target)) {
|
||||
BlockState state = target.getState();
|
||||
|
||||
if (state instanceof InventoryHolder) {
|
||||
@ -141,13 +184,16 @@ final class CargoUtils {
|
||||
if (!matchesFilter(node, stack, index)) return stack;
|
||||
|
||||
DirtyChestMenu menu = getChestMenu(target);
|
||||
|
||||
if (menu == null) {
|
||||
if (BlockUtils.hasInventory(target)) {
|
||||
if (hasInventory(target)) {
|
||||
BlockState state = target.getState();
|
||||
|
||||
if (state instanceof InventoryHolder) {
|
||||
return insertIntoVanillaInventory(stack, ((InventoryHolder) state).getInventory());
|
||||
}
|
||||
}
|
||||
|
||||
return stack;
|
||||
}
|
||||
|
||||
@ -162,6 +208,7 @@ final class CargoUtils {
|
||||
|
||||
int maxStackSize = itemInSlot.getType().getMaxStackSize();
|
||||
int currentAmount = itemInSlot.getAmount();
|
||||
|
||||
if (SlimefunUtils.isItemSimilar(itemInSlot, wrapper, true, false) && currentAmount < maxStackSize) {
|
||||
int amount = currentAmount + stack.getAmount();
|
||||
|
||||
@ -183,7 +230,7 @@ final class CargoUtils {
|
||||
|
||||
private static ItemStack insertIntoVanillaInventory(ItemStack stack, Inventory inv) {
|
||||
ItemStack[] contents = inv.getContents();
|
||||
int minSlot = 0;
|
||||
int minSlot = 0;
|
||||
int maxSlot = contents.length;
|
||||
|
||||
// Check if it is a normal furnace
|
||||
@ -198,17 +245,18 @@ final class CargoUtils {
|
||||
}
|
||||
}
|
||||
else if (inv instanceof BrewerInventory) {
|
||||
// Check if it goes in the potion slot,
|
||||
|
||||
if (stack.getType() == Material.POTION || stack.getType() == Material.LINGERING_POTION || stack.getType() == Material.SPLASH_POTION) {
|
||||
// Potions slot
|
||||
maxSlot = 3;
|
||||
// The blaze powder slot,
|
||||
}
|
||||
else if (stack.getType() == Material.BLAZE_POWDER) {
|
||||
// Blaze Powder slot
|
||||
minSlot = 4;
|
||||
maxSlot = 5;
|
||||
}
|
||||
else {
|
||||
// Or the input
|
||||
// Input slot
|
||||
minSlot = 3;
|
||||
maxSlot = 4;
|
||||
}
|
||||
|
@ -254,7 +254,7 @@ abstract class ChestTerminalNetwork extends Network {
|
||||
handleWithdraw(blockMenu, items, l);
|
||||
}
|
||||
}
|
||||
else if (BlockUtils.hasInventory(target)) {
|
||||
else if (CargoUtils.hasInventory(target)) {
|
||||
BlockState state = target.getState();
|
||||
|
||||
if (state instanceof InventoryHolder) {
|
||||
|
@ -46,7 +46,7 @@ public class AutoSavingService {
|
||||
* This method saves every {@link PlayerProfile} in memory and removes profiles
|
||||
* that were markes for deletion.
|
||||
*/
|
||||
public void saveAllPlayers() {
|
||||
private void saveAllPlayers() {
|
||||
Iterator<PlayerProfile> iterator = PlayerProfile.iterator();
|
||||
int players = 0;
|
||||
|
||||
@ -71,7 +71,7 @@ public class AutoSavingService {
|
||||
/**
|
||||
* This method saves the data of every {@link Block} marked dirty by {@link BlockStorage}.
|
||||
*/
|
||||
public void saveAllBlocks() {
|
||||
private void saveAllBlocks() {
|
||||
Set<BlockStorage> worlds = new HashSet<>();
|
||||
|
||||
for (World world : Bukkit.getWorlds()) {
|
||||
|
@ -50,6 +50,7 @@ public class GitHubService {
|
||||
private void addDefaultContributors() {
|
||||
addContributor("Fuffles_", "&dArtist");
|
||||
addContributor("IMS_Art", "&dArtist");
|
||||
addContributor("nahkd123", "&aWinner of the 2020 Addon Jam");
|
||||
|
||||
new Translators(contributors);
|
||||
}
|
||||
|
@ -5,9 +5,14 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Level;
|
||||
|
||||
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 me.mrCookieSlime.Slimefun.api.Slimefun;
|
||||
|
||||
/**
|
||||
* This {@link GitHubTask} represents a {@link Runnable} that is run every X minutes.
|
||||
@ -21,6 +26,8 @@ import io.github.thebusybiscuit.cscorelib2.players.MinecraftAccount.TooManyReque
|
||||
*/
|
||||
class GitHubTask implements Runnable {
|
||||
|
||||
private static final int MAX_REQUESTS_PER_MINUTE = 12;
|
||||
|
||||
private final GitHubService gitHubService;
|
||||
|
||||
GitHubTask(GitHubService github) {
|
||||
@ -31,9 +38,14 @@ class GitHubTask implements Runnable {
|
||||
public void run() {
|
||||
gitHubService.getConnectors().forEach(GitHubConnector::pullFile);
|
||||
|
||||
grabTextures();
|
||||
}
|
||||
|
||||
private void grabTextures() {
|
||||
// Store all queried usernames to prevent 429 responses for pinging the
|
||||
// same URL twice in one run.
|
||||
Map<String, String> skins = new HashMap<>();
|
||||
int count = 0;
|
||||
|
||||
for (Contributor contributor : gitHubService.getContributors().values()) {
|
||||
if (!contributor.hasTexture()) {
|
||||
@ -43,18 +55,33 @@ class GitHubTask implements Runnable {
|
||||
}
|
||||
else {
|
||||
contributor.setTexture(grabTexture(skins, contributor.getMinecraftName()));
|
||||
count++;
|
||||
|
||||
if (count >= MAX_REQUESTS_PER_MINUTE) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (IllegalArgumentException x) {
|
||||
// There cannot be a texture found because it is not a valid MC username
|
||||
contributor.setTexture(null);
|
||||
}
|
||||
catch (Exception x) {
|
||||
catch (IOException | TooManyRequestsException x) {
|
||||
// Too many requests
|
||||
break;
|
||||
Slimefun.getLogger().log(Level.WARNING, "Attempted to connect to mojang.com, got this response: {0}: {1}", new Object[] { x.getClass().getSimpleName(), x.getMessage() });
|
||||
Slimefun.getLogger().log(Level.WARNING, "This usually means mojang.com is down or started to rate-limit this connection, this is not an error message!");
|
||||
|
||||
// Retry after 2 minutes
|
||||
Bukkit.getScheduler().runTaskLaterAsynchronously(SlimefunPlugin.instance, this::grabTextures, 2 * 60 * 20L);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (count >= MAX_REQUESTS_PER_MINUTE) {
|
||||
// Slow down API requests and wait a minute after more than x requests were made
|
||||
Bukkit.getScheduler().runTaskLaterAsynchronously(SlimefunPlugin.instance, this::grabTextures, 60 * 20L);
|
||||
}
|
||||
}
|
||||
|
||||
private String grabTexture(Map<String, String> skins, String username) throws TooManyRequestsException, IOException {
|
||||
|
@ -162,7 +162,7 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon {
|
||||
|
||||
// Setting up Networks
|
||||
gpsNetwork = new GPSNetwork();
|
||||
networkManager = new NetworkManager(config.getInt("options.max-network-size"));
|
||||
networkManager = new NetworkManager(config.getInt("networks.max-size"));
|
||||
|
||||
// Setting up bStats
|
||||
metricsService.start();
|
||||
|
@ -28,10 +28,13 @@ researches:
|
||||
|
||||
URID:
|
||||
info-delay: 3000
|
||||
cargo-network-tick-delay: 0
|
||||
custom-ticker-delay: 12
|
||||
enable-tickers: true
|
||||
|
||||
networks:
|
||||
max-size: 200
|
||||
cargo-ticker-delay: 0
|
||||
|
||||
items:
|
||||
talismans: true
|
||||
backpacks: true
|
||||
|
Loading…
Reference in New Issue
Block a user