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

Merge branch 'master' into beeArmor

This commit is contained in:
LinoxGH 2020-10-04 08:48:05 +03:00 committed by GitHub
commit 6347e2f6ca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
112 changed files with 1459 additions and 532 deletions

7
.github/CODEOWNERS vendored Normal file
View File

@ -0,0 +1,7 @@
# Modifications to the source code should be handled by the review team
*.java @Slimefun/code-reviewers
# Modifications to sensitive files should be reviewed by maintainers
/.github/ @Slimefun/slimefun4-maintainers
pom.xml @Slimefun/slimefun4-maintainers
CONTRIBUTING.md @Slimefun/slimefun4-maintainers

View File

@ -19,7 +19,7 @@ We generally expect users to engage in the Issues section by reporting bugs or c
Pull Requests are very much welcome and encouraged! They keep the project alive, so if you see an Issue and know how to fix it, feel free to create a Pull Request! Pull Requests are very much welcome and encouraged! They keep the project alive, so if you see an Issue and know how to fix it, feel free to create a Pull Request!
Issues that are considered "good first issues", indicated by the [good first issue](https://github.com/Slimefun/Slimefun4/labels/good%20first%20issue) label, are generally expected to be beginner-friendly. Issues that are considered "good first issues", indicated by the [good first issue](https://github.com/Slimefun/Slimefun4/labels/good%20first%20issue) label, are generally expected to be beginner-friendly.
And even if you shouldn't know where to start or how to proceed, our [Discord Server](https://github.com/Slimefun/Slimefun4#discord) and its community will be there for you! And even if you shouldn't know where to start or how to proceed, our [Discord Server](https://discord.gg/slimefun) and its community will be there for you!
When commenting, please keep in mind that this software is offered for **free**. Don't expect to receive lightning-fast replies 24 hours a day. When commenting, please keep in mind that this software is offered for **free**. Don't expect to receive lightning-fast replies 24 hours a day.
Everyone here works on this project in their free time and usually has work, school, university or family to take care of, so we appreciate patience and understanding. Everyone here works on this project in their free time and usually has work, school, university or family to take care of, so we appreciate patience and understanding.
@ -59,7 +59,7 @@ https://github.com/orgs/Slimefun/people
## :wrench: Enforcement ## :wrench: Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders (labelled on Discord as "Admins" or "Moderators") responsible for enforcement on our [Discord Server](https://github.com/Slimefun/Slimefun4#discord). reported to the community leaders (labelled on Discord as "Admins" or "Moderators") responsible for enforcement on our [Discord Server](discord.gg/slimefun).
If you want your issue to be handled discreetly, message `TheBusyBiscuit#2610` or `Walshy#9709` privately on Discord and state your concerns. If you want your issue to be handled discreetly, message `TheBusyBiscuit#2610` or `Walshy#9709` privately on Discord and state your concerns.
All complaints will be reviewed and investigated promptly and fairly. All complaints will be reviewed and investigated promptly and fairly.

View File

@ -7,5 +7,5 @@ contact_links:
url: https://github.com/Slimefun/Slimefun4/wiki/How-to-report-bugs url: https://github.com/Slimefun/Slimefun4/wiki/How-to-report-bugs
about: Guidelines on how to make good Bug reports about: Guidelines on how to make good Bug reports
- name: Discord Server (for Questions and Suggestions) - name: Discord Server (for Questions and Suggestions)
url: https://discord.gg/fsD4Bkh url: https://discord.gg/slimefun
about: Please ask and answer questions here. about: Please ask and answer questions here.

View File

@ -45,10 +45,10 @@ If you need help on how to get started, maybe try looking into the following res
* [Hacktoberfest FAQ](https://hacktoberfest.digitalocean.com/faq) * [Hacktoberfest FAQ](https://hacktoberfest.digitalocean.com/faq)
* GitHub/Open-Source * GitHub/Open-Source
* [How to contribute to Open-Source](https://opensource.guide/how-to-contribute/) * [How to contribute to Open-Source](https://opensource.guide/how-to-contribute/)
* [Working with forks](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/working-with-forks) * [Working with forks](https://docs.github.com/en/free-pro-team@latest/github/collaborating-with-issues-and-pull-requests/working-with-forks)
* [Creating a Pull Request](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request-from-a-fork) * [Creating a Pull Request](https://docs.github.com/en/free-pro-team@latest/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request-from-a-fork)
* Slimefun * Slimefun
* [Contributing to Slimefun](https://github.com/Slimefun/Slimefun4/blob/master/.github/CONTRIBUTING.md) * [Contributing to Slimefun](https://github.com/Slimefun/Slimefun4/blob/master/CONTRIBUTING.md)
* [Code of Conduct](https://github.com/Slimefun/Slimefun4/blob/master/.github/CODE_OF_CONDUCT.md) * [Code of Conduct](https://github.com/Slimefun/Slimefun4/blob/master/.github/CODE_OF_CONDUCT.md)
<hr> <hr>

View File

@ -23,4 +23,4 @@ jobs:
print_all: False print_all: False
retry_count: 2 retry_count: 2
## These URLs will always be correct, even if their services may be offline right now ## These URLs will always be correct, even if their services may be offline right now
white_listed_patterns: http://textures.minecraft.net/texture/,https://pastebin.com/,https://www.spigotmc.org/threads/spigot-bungeecord-1-16-1.447405/#post-3852349 white_listed_patterns: http://textures.minecraft.net/texture/,https://pastebin.com/,https://www.spigotmc.org/threads/spigot-bungeecord-1-16-1.447405/#post-3852349,https://gitlocalize.com/repo/3841

View File

@ -27,9 +27,16 @@
#### Additions #### Additions
* Added /sf charge * Added /sf charge
* Added Energized Energy Capacitor * Added Energized Energy Capacitor
* Added various new fuel types to the Coal Generator
* Added a config option for Grappling Hooks to not be consumed on use
* Added Talisman of the Caveman
* You can now convert any gold ingot into gold dust with slightly less returns
* (API) Added SlimefunGuideOpenEvent
#### Changes #### Changes
* Improved Auto-Updater (Multi-Threading and more) * Improved Auto-Updater (Multi-Threading and more)
* General performance improvements
* /sf cheat now shows seasonal categories all year through
#### Fixes #### Fixes
* Fixed #2300 * Fixed #2300
@ -41,6 +48,16 @@
* Fixed #2325 * Fixed #2325
* Fixed Climbing Pick having no animation in creative mode * Fixed Climbing Pick having no animation in creative mode
* Fixed #2322 * Fixed #2322
* Fixed some cargo incompatibilities with overflowing inventories
* Fixed #2353
* Fixed #2359
* Fixed #2356
* Fixed #2358
* Fixed #2360
* Fixed #2351
* Fixed #2357
* Fixed Auto Enchanters being unaffected by speed modifications from addons
* Fixed Auto Disenchanters being unaffected by speed modifications from addons
## Release Candidate 16 (07 Sep 2020) ## Release Candidate 16 (07 Sep 2020)
https://thebusybiscuit.github.io/builds/TheBusyBiscuit/Slimefun4/stable/#16 https://thebusybiscuit.github.io/builds/TheBusyBiscuit/Slimefun4/stable/#16

View File

@ -26,7 +26,7 @@ You can also comment on the existing Issue, proposing your idea or communicating
## :wrench: 3. Pull Requests: Additions/Changes ## :wrench: 3. Pull Requests: Additions/Changes
Slimefun is an Open-Source project and anyone is allowed to make changes or add content to this plugin! Slimefun is an Open-Source project and anyone is allowed to make changes or add content to this plugin!
Please visit our [Discord Server](https://github.com/Slimefun/Slimefun4#discord) and share your ideas first, we hate to reject changes because the community disagrees.<br> Please visit our [Discord Server](https://discord.gg/slimefun) and share your ideas first, we hate to reject changes because the community disagrees.<br>
So communicating your intended changes before-hand will ensure that you don't put too much work into something that might get rejected. So communicating your intended changes before-hand will ensure that you don't put too much work into something that might get rejected.
We also have a suggestions section in our Discord Server too. Suggestions can be placed in the `#suggestions` channel and community members can vote on a suggestion. We also have a suggestions section in our Discord Server too. Suggestions can be placed in the `#suggestions` channel and community members can vote on a suggestion.
@ -58,11 +58,11 @@ You can find a tutorial on how to contribute to our wiki right here:<br>
https://github.com/Slimefun/Slimefun4/wiki/Expanding-the-Wiki https://github.com/Slimefun/Slimefun4/wiki/Expanding-the-Wiki
## :star: 6. Pull Requests: Code Quality ## :star: 6. Pull Requests: Code Quality
Slimefun uses [sonarcloud.io](https://sonarcloud.io/dashboard?id=TheBusyBiscuit_Slimefun4) to monitor Code Quality. Slimefun uses [sonarcloud.io](https://sonarcloud.io/dashboard?id=Slimefun_Slimefun4) to monitor Code Quality.
We always welcome quality improvements to the code and the "Code Smells" section on [sonarcloud.io](https://sonarcloud.io/dashboard?id=TheBusyBiscuit_Slimefun4) is a great place to start. We always welcome quality improvements to the code and the "Code Smells" section on [sonarcloud.io](https://sonarcloud.io/dashboard?id=Slimefun_Slimefun4) is a great place to start.
But please keep in mind that some design patterns may not be changed too abruptly if an addon depends on them. But please keep in mind that some design patterns may not be changed too abruptly if an addon depends on them.
To prevent any accidents from happening, please contact us on our [Discord Server](https://github.com/Slimefun/Slimefun4#discord) before-hand and state your intended changes. To prevent any accidents from happening, please contact us on our [Discord Server](https://discord.gg/slimefun) before-hand and state your intended changes.
#### Documentation #### Documentation
Code documentation is also a great way to improve the maintainability of the project. Code documentation is also a great way to improve the maintainability of the project.
@ -92,5 +92,5 @@ To compile Slimefun yourself, follow these steps:
If you are already using an IDE, make sure to import the project via git and set it up as a *Maven project*. If you are already using an IDE, make sure to import the project via git and set it up as a *Maven project*.
Then you should be able build it via Maven using the goals `clean package`. 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.<br> If you have any further questions, then please join our [Discord Support Server](https://discord.gg/slimefun) and ask your questions in the `#programming-help` channel.<br>
**Note that we will not accept any bug reports from custom-compiled versions of Slimefun**. **Note that we will not accept any bug reports from custom-compiled versions of Slimefun**.

View File

@ -19,7 +19,7 @@ Check out our [Addons](https://github.com/Slimefun/Slimefun4/wiki/Addons), you m
* **[Bug Tracker](https://github.com/Slimefun/Slimefun4/issues)** * **[Bug Tracker](https://github.com/Slimefun/Slimefun4/issues)**
* **[Wiki](https://github.com/Slimefun/Slimefun4/wiki)** * **[Wiki](https://github.com/Slimefun/Slimefun4/wiki)**
* **[FAQ](https://github.com/Slimefun/Slimefun4/wiki/FAQ)** * **[FAQ](https://github.com/Slimefun/Slimefun4/wiki/FAQ)**
* **[How to contribute](https://github.com/Slimefun/Slimefun4/blob/master/.github/CONTRIBUTING.md)** * **[How to contribute](https://github.com/Slimefun/Slimefun4/blob/master/CONTRIBUTING.md)**
## Download Slimefun 4 ## Download Slimefun 4
(See also: [How to install Slimefun](https://github.com/Slimefun/Slimefun4/wiki/Installing-Slimefun)) (See also: [How to install Slimefun](https://github.com/Slimefun/Slimefun4/wiki/Installing-Slimefun))
@ -76,10 +76,9 @@ Due to the sheer size of this discord server, we need to enforce some [important
Not following these rules can lead to a kick or even a ban from the server. Not following these rules can lead to a kick or even a ban from the server.
<p align="center"> <p align="center">
<a href="https://discord.gg/fsD4Bkh"> <a href="https://discord.gg/slimefun">
<img src="https://img.shields.io/discord/565557184348422174?color=7289DA&label=Discord&style=for-the-badge" alt="Discord Invite"/> <img src="https://discordapp.com/api/guilds/565557184348422174/widget.png?style=banner3" alt="Discord Invite"/>
</a><br> </a>
(Click the badge to join)
</p> </p>
## Wiki ## Wiki
@ -106,7 +105,7 @@ Slimefun 4 is an Open-Source project and licensed under
Over 150+ people have already contributed to this amazing project. You guys are awesome.<br> Over 150+ people have already contributed to this amazing project. You guys are awesome.<br>
Please consider helping us maintain this project too, your engagement keeps the project alive <3. Please consider helping us maintain this project too, your engagement keeps the project alive <3.
You can find more info on how to contribute to this project in our [CONTRIBUTING.md](https://github.com/Slimefun/Slimefun4/blob/master/.github/CONTRIBUTING.md). You can find more info on how to contribute to this project in our [CONTRIBUTING.md](https://github.com/Slimefun/Slimefun4/blob/master/CONTRIBUTING.md).
## Disclaimers ## Disclaimers
Slimefun4 uses various systems that collect usage information or download automatic updates as well as the latest information about the project. Slimefun4 uses various systems that collect usage information or download automatic updates as well as the latest information about the project.

15
pom.xml
View File

@ -4,7 +4,7 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>com.github.thebusybiscuit</groupId> <groupId>com.github.slimefun</groupId>
<artifactId>Slimefun</artifactId> <artifactId>Slimefun</artifactId>
<!-- Our default version will be UNOFFICIAL, this will prevent auto updates --> <!-- Our default version will be UNOFFICIAL, this will prevent auto updates -->
@ -26,8 +26,8 @@
<spigot.javadocs>https://hub.spigotmc.org/javadocs/spigot/</spigot.javadocs> <spigot.javadocs>https://hub.spigotmc.org/javadocs/spigot/</spigot.javadocs>
<!-- Default settings for sonarcloud.io --> <!-- Default settings for sonarcloud.io -->
<sonar.projectKey>TheBusyBiscuit_Slimefun4</sonar.projectKey> <sonar.projectKey>Slimefun_Slimefun4</sonar.projectKey>
<sonar.organization>thebusybiscuit-github</sonar.organization> <sonar.organization>slimefun</sonar.organization>
<sonar.host.url>https://sonarcloud.io</sonar.host.url> <sonar.host.url>https://sonarcloud.io</sonar.host.url>
<sonar.log.level>DEBUG</sonar.log.level> <sonar.log.level>DEBUG</sonar.log.level>
<sonar.exclusions>src/main/java/me/mrCookieSlime/Slimefun/bstats/bukkit/Metrics.java</sonar.exclusions> <sonar.exclusions>src/main/java/me/mrCookieSlime/Slimefun/bstats/bukkit/Metrics.java</sonar.exclusions>
@ -77,6 +77,7 @@
<build> <build>
<sourceDirectory>${project.basedir}/src/main/java</sourceDirectory> <sourceDirectory>${project.basedir}/src/main/java</sourceDirectory>
<testSourceDirectory>${project.basedir}/src/test/java</testSourceDirectory> <testSourceDirectory>${project.basedir}/src/test/java</testSourceDirectory>
<defaultGoal>clean package</defaultGoal>
<finalName>${project.name} v${project.version}</finalName> <finalName>${project.name} v${project.version}</finalName>
@ -213,7 +214,7 @@
<link>${spigot.javadocs}</link> <link>${spigot.javadocs}</link>
</links> </links>
<!-- We can group pakages together in our Javadocs --> <!-- We can group packages together in our Javadocs -->
<groups> <groups>
<group> <group>
<title>Slimefun4 - API</title> <title>Slimefun4 - API</title>
@ -309,7 +310,7 @@
<dependency> <dependency>
<groupId>com.github.seeseemelk</groupId> <groupId>com.github.seeseemelk</groupId>
<artifactId>MockBukkit-v1.16</artifactId> <artifactId>MockBukkit-v1.16</artifactId>
<version>0.5.2</version> <version>0.6.0</version>
<scope>test</scope> <scope>test</scope>
<exclusions> <exclusions>
<exclusion> <exclusion>
@ -323,7 +324,7 @@
<dependency> <dependency>
<groupId>org.mockito</groupId> <groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId> <artifactId>mockito-core</artifactId>
<version>3.5.11</version> <version>3.5.13</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
@ -343,7 +344,7 @@
<dependency> <dependency>
<groupId>com.konghq</groupId> <groupId>com.konghq</groupId>
<artifactId>unirest-java</artifactId> <artifactId>unirest-java</artifactId>
<version>3.10.00</version> <version>3.11.00</version>
<scope>compile</scope> <scope>compile</scope>
<exclusions> <exclusions>
<exclusion> <exclusion>

View File

@ -27,7 +27,6 @@ import io.papermc.lib.PaperLib;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.Objects.handlers.BlockTicker; import me.mrCookieSlime.Slimefun.Objects.handlers.BlockTicker;
import me.mrCookieSlime.Slimefun.api.BlockStorage; import me.mrCookieSlime.Slimefun.api.BlockStorage;
import me.mrCookieSlime.Slimefun.api.Slimefun;
/** /**
* This class represents an {@link ErrorReport}. * This class represents an {@link ErrorReport}.
@ -53,7 +52,7 @@ public class ErrorReport<T extends Throwable> {
this.throwable = throwable; this.throwable = throwable;
this.addon = addon; this.addon = addon;
Slimefun.runSync(() -> print(printer)); SlimefunPlugin.runSync(() -> print(printer));
} }
@ParametersAreNonnullByDefault @ParametersAreNonnullByDefault

View File

@ -0,0 +1,65 @@
package io.github.thebusybiscuit.slimefun4.api.events;
import javax.annotation.Nonnull;
import javax.annotation.ParametersAreNonnullByDefault;
import org.bukkit.Location;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AGenerator;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.MachineFuel;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
/**
* This {@link Event} is fired whenever an {@link AGenerator} has completed its process.
*
* @author poma123
*
*/
public class AsyncGeneratorProcessCompleteEvent extends AsyncMachineProcessCompleteEvent {
private static final HandlerList handlers = new HandlerList();
private final AGenerator generator;
private final MachineFuel machineFuel;
@ParametersAreNonnullByDefault
public AsyncGeneratorProcessCompleteEvent(Location l, AGenerator generator, MachineFuel machineFuel) {
super(l, null, null);
this.generator = generator;
this.machineFuel = machineFuel;
}
/**
* The {@link SlimefunItem} instance of the generator.
*
* @return The {@link SlimefunItem} instance of the generator
*/
@Nonnull
public AGenerator getGenerator() {
return generator;
}
/**
* This returns the used {@link MachineFuel} in the process.
*
* @return The {@link MachineFuel} of the process
*/
@Nonnull
public MachineFuel getMachineFuel() {
return machineFuel;
}
@Nonnull
public static HandlerList getHandlerList() {
return handlers;
}
@Nonnull
@Override
public HandlerList getHandlers() {
return getHandlerList();
}
}

View File

@ -1,14 +1,15 @@
package io.github.thebusybiscuit.slimefun4.api.events; package io.github.thebusybiscuit.slimefun4.api.events;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.ParametersAreNonnullByDefault; import javax.annotation.Nullable;
import org.bukkit.block.Block; import org.bukkit.Location;
import org.bukkit.event.Event; import org.bukkit.event.Event;
import org.bukkit.event.HandlerList; import org.bukkit.event.HandlerList;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AContainer; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AContainer;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.MachineRecipe; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.MachineRecipe;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
/** /**
* This {@link Event} is fired whenever an {@link AContainer} has completed its process. * This {@link Event} is fired whenever an {@link AContainer} has completed its process.
@ -20,33 +21,44 @@ public class AsyncMachineProcessCompleteEvent extends Event {
private static final HandlerList handlers = new HandlerList(); private static final HandlerList handlers = new HandlerList();
private final Block block; private final Location location;
private final AContainer container;
private final MachineRecipe machineRecipe; private final MachineRecipe machineRecipe;
@ParametersAreNonnullByDefault public AsyncMachineProcessCompleteEvent(@Nonnull Location l, @Nullable AContainer container, @Nullable MachineRecipe machineRecipe) {
public AsyncMachineProcessCompleteEvent(Block block, MachineRecipe machineRecipe) {
super(true); super(true);
this.block = block; this.location = l;
this.container = container;
this.machineRecipe = machineRecipe; this.machineRecipe = machineRecipe;
} }
/** /**
* This method returns the {@link Block} of the machine. * This returns the {@link Location} of the machine.
* *
* @return the {@link Block} of the machine * @return The {@link Location} of the machine
*/ */
@Nonnull @Nonnull
public Block getMachine() { public Location getLocation() {
return block; return location;
}
/**
* The {@link SlimefunItem} instance of the machine.
*
* @return The {@link SlimefunItem} instance of the machine
*/
@Nullable
public AContainer getMachine() {
return container;
} }
/** /**
* This returns the used {@link MachineRecipe} in the process. * This returns the used {@link MachineRecipe} in the process.
* *
* @return the {@link MachineRecipe} of the process. * @return The {@link MachineRecipe} of the process
*/ */
@Nonnull @Nullable
public MachineRecipe getMachineRecipe() { public MachineRecipe getMachineRecipe() {
return machineRecipe; return machineRecipe;
} }

View File

@ -0,0 +1,65 @@
package io.github.thebusybiscuit.slimefun4.api.events;
import javax.annotation.Nonnull;
import javax.annotation.ParametersAreNonnullByDefault;
import org.bukkit.Location;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.reactors.Reactor;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.MachineFuel;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
/**
* This {@link Event} is fired whenever a {@link Reactor} has completed its process.
*
* @author poma123
*
*/
public class AsyncReactorProcessCompleteEvent extends AsyncMachineProcessCompleteEvent {
private static final HandlerList handlers = new HandlerList();
private final Reactor reactor;
private final MachineFuel machineFuel;
@ParametersAreNonnullByDefault
public AsyncReactorProcessCompleteEvent(Location l, Reactor reactor, MachineFuel machineFuel) {
super(l, null, null);
this.reactor = reactor;
this.machineFuel = machineFuel;
}
/**
* The {@link SlimefunItem} instance of the reactor.
*
* @return The {@link SlimefunItem} instance of the reactor
*/
@Nonnull
public Reactor getReactor() {
return reactor;
}
/**
* This returns the used {@link MachineFuel} in the process.
*
* @return The {@link MachineFuel} of the process
*/
@Nonnull
public MachineFuel getMachineFuel() {
return machineFuel;
}
@Nonnull
public static HandlerList getHandlerList() {
return handlers;
}
@Nonnull
@Override
public HandlerList getHandlers() {
return getHandlerList();
}
}

View File

@ -0,0 +1,104 @@
package io.github.thebusybiscuit.slimefun4.api.events;
import javax.annotation.Nonnull;
import org.apache.commons.lang.Validate;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideLayout;
/**
* This {@link Event} is called whenever a {@link Player} tries to open the Slimefun Guide book.
*
* @author Linox
*
* @see SlimefunGuideLayout
*/
public class SlimefunGuideOpenEvent extends Event implements Cancellable {
private static final HandlerList handlers = new HandlerList();
private final Player player;
private final ItemStack guide;
private SlimefunGuideLayout layout;
private boolean cancelled;
public SlimefunGuideOpenEvent(@Nonnull Player p, @Nonnull ItemStack guide, @Nonnull SlimefunGuideLayout layout) {
Validate.notNull(p, "The Player cannot be null");
Validate.notNull(guide, "Guide cannot be null");
Validate.notNull(layout, "Layout cannot be null");
this.player = p;
this.guide = guide;
this.layout = layout;
}
/**
* This returns the {@link Player} that tries to open
* the Slimefun Guide.
*
* @return The {@link Player}
*/
@Nonnull
public Player getPlayer() {
return player;
}
/**
* This returns the {@link ItemStack} that {@link Player}
* tries to open the Slimefun Guide with.
*
* @return The {@link ItemStack}
*/
@Nonnull
public ItemStack getGuide() {
return guide;
}
/**
* This returns the {@link SlimefunGuideLayout} of the Slimefun Guide
* that {@link Player} tries to open.
*
* @return The {@link SlimefunGuideLayout}
*/
@Nonnull
public SlimefunGuideLayout getGuideLayout() {
return layout;
}
/**
* Changes the {@link SlimefunGuideLayout} that was tried to be opened with.
*
* @param layout
* The new {@link SlimefunGuideLayout}
*/
public void setGuideLayout(@Nonnull SlimefunGuideLayout layout) {
Validate.notNull(layout, "You must specify a layout that is not-null!");
this.layout = layout;
}
@Override
public boolean isCancelled() {
return cancelled;
}
@Override
public void setCancelled(boolean cancel) {
this.cancelled = cancel;
}
@Nonnull
public static HandlerList getHandlerList() {
return handlers;
}
@Nonnull
@Override
public HandlerList getHandlers() {
return getHandlerList();
}
}

View File

@ -37,7 +37,6 @@ import io.github.thebusybiscuit.slimefun4.utils.HeadTexture;
import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu; import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.api.BlockStorage; import me.mrCookieSlime.Slimefun.api.BlockStorage;
import me.mrCookieSlime.Slimefun.api.Slimefun;
/** /**
* The {@link GPSNetwork} is a manager class for all {@link GPSTransmitter Transmitters} and waypoints. * The {@link GPSNetwork} is a manager class for all {@link GPSTransmitter Transmitters} and waypoints.
@ -288,7 +287,7 @@ public class GPSNetwork {
return; return;
} }
Slimefun.runSync(() -> { SlimefunPlugin.runSync(() -> {
WaypointCreateEvent event = new WaypointCreateEvent(p, name, l); WaypointCreateEvent event = new WaypointCreateEvent(p, name, l);
Bukkit.getPluginManager().callEvent(event); Bukkit.getPluginManager().callEvent(event);

View File

@ -27,7 +27,6 @@ import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils;
import io.github.thebusybiscuit.slimefun4.utils.HeadTexture; import io.github.thebusybiscuit.slimefun4.utils.HeadTexture;
import io.papermc.lib.PaperLib; import io.papermc.lib.PaperLib;
import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu; import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu;
import me.mrCookieSlime.Slimefun.api.Slimefun;
public final class TeleportationManager { public final class TeleportationManager {
@ -79,7 +78,7 @@ public final class TeleportationManager {
index++; index++;
} }
Slimefun.runSync(() -> menu.open(p)); SlimefunPlugin.runSync(() -> menu.open(p));
}); });
} }
@ -137,7 +136,7 @@ public final class TeleportationManager {
source.getWorld().spawnParticle(Particle.PORTAL, source, progress * 2, 0.2F, 0.8F, 0.2F); 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); source.getWorld().playSound(source, Sound.BLOCK_BEACON_AMBIENT, 1F, 0.6F);
Slimefun.runSync(() -> updateProgress(uuid, speed, progress + speed, source, destination, resistance), 10L); SlimefunPlugin.runSync(() -> updateProgress(uuid, speed, progress + speed, source, destination, resistance), 10L);
} }
} }
else { else {
@ -149,7 +148,7 @@ public final class TeleportationManager {
private void onTeleport(Player p, Location destination, boolean success, boolean resistance) { private void onTeleport(Player p, Location destination, boolean success, boolean resistance) {
// This needs to run on the main Thread so we force it, as the // This needs to run on the main Thread so we force it, as the
// async teleportation might happen on a separate Thread. // async teleportation might happen on a separate Thread.
Slimefun.runSync(() -> { SlimefunPlugin.runSync(() -> {
if (success) { if (success) {
// Apply Resistance Effect, if enabled // Apply Resistance Effect, if enabled
if (resistance) { if (resistance) {

View File

@ -16,8 +16,8 @@ import org.bukkit.Particle;
import org.bukkit.Particle.DustOptions; import org.bukkit.Particle.DustOptions;
import io.github.thebusybiscuit.slimefun4.core.networks.NetworkManager; import io.github.thebusybiscuit.slimefun4.core.networks.NetworkManager;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.NetworkListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.NetworkListener;
import me.mrCookieSlime.Slimefun.api.Slimefun;
/** /**
* An abstract Network class to manage networks in a stateful way * An abstract Network class to manage networks in a stateful way
@ -217,7 +217,7 @@ public abstract class Network {
* every {@link Location} that this {@link Network} is connected to. * every {@link Location} that this {@link Network} is connected to.
*/ */
public void display() { public void display() {
Slimefun.runSync(() -> { SlimefunPlugin.runSync(() -> {
DustOptions options = new DustOptions(Color.BLUE, 3F); DustOptions options = new DustOptions(Color.BLUE, 3F);
for (Location l : connectedLocations) { for (Location l : connectedLocations) {

View File

@ -10,9 +10,9 @@ import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.cscorelib2.config.Config; import io.github.thebusybiscuit.cscorelib2.config.Config;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.items.backpacks.SlimefunBackpack; import io.github.thebusybiscuit.slimefun4.implementation.items.backpacks.SlimefunBackpack;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.BackpackListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.BackpackListener;
import me.mrCookieSlime.Slimefun.api.Slimefun;
/** /**
* This class represents the instance of a {@link SlimefunBackpack} that is ready to * This class represents the instance of a {@link SlimefunBackpack} that is ready to
@ -123,7 +123,7 @@ public class PlayerBackpack {
* The players who this Backpack will be shown to * The players who this Backpack will be shown to
*/ */
public void open(Player... players) { public void open(Player... players) {
Slimefun.runSync(() -> { SlimefunPlugin.runSync(() -> {
for (Player p : players) { for (Player p : players) {
p.openInventory(inventory); p.openInventory(inventory);
} }

View File

@ -11,7 +11,6 @@ import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import org.bukkit.Location;
import org.bukkit.Server; import org.bukkit.Server;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType; import org.bukkit.entity.EntityType;
@ -70,7 +69,6 @@ public class SlimefunRegistry {
private final Set<String> tickers = new HashSet<>(); private final Set<String> tickers = new HashSet<>();
private final Set<SlimefunItem> radioactive = new HashSet<>(); private final Set<SlimefunItem> radioactive = new HashSet<>();
private final Set<String> activeChunks = ConcurrentHashMap.newKeySet();
private final Set<ItemStack> barterDrops = new HashSet<>(); private final Set<ItemStack> barterDrops = new HashSet<>();
private final KeyMap<GEOResource> geoResources = new KeyMap<>(); private final KeyMap<GEOResource> geoResources = new KeyMap<>();
@ -86,8 +84,6 @@ public class SlimefunRegistry {
private final Map<Class<? extends ItemHandler>, Set<ItemHandler>> globalItemHandlers = new HashMap<>(); private final Map<Class<? extends ItemHandler>, Set<ItemHandler>> globalItemHandlers = new HashMap<>();
private final Map<String, SlimefunBlockHandler> blockHandlers = new HashMap<>(); private final Map<String, SlimefunBlockHandler> blockHandlers = new HashMap<>();
private final Map<String, Set<Location>> activeTickers = new ConcurrentHashMap<>();
private final Map<String, ItemStack> automatedCraftingChamberRecipes = new HashMap<>(); private final Map<String, ItemStack> automatedCraftingChamberRecipes = new HashMap<>();
public void load(Config cfg) { public void load(Config cfg) {
@ -226,10 +222,6 @@ public class SlimefunRegistry {
return tickers; return tickers;
} }
public Set<String> getActiveChunks() {
return activeChunks;
}
public Map<String, SlimefunItem> getSlimefunItemIds() { public Map<String, SlimefunItem> getSlimefunItemIds() {
return slimefunIds; return slimefunIds;
} }
@ -262,10 +254,6 @@ public class SlimefunRegistry {
return chunks; return chunks;
} }
public Map<String, Set<Location>> getActiveTickers() {
return activeTickers;
}
public KeyMap<GEOResource> getGEOResources() { public KeyMap<GEOResource> getGEOResources() {
return geoResources; return geoResources;
} }

View File

@ -12,7 +12,6 @@ import io.github.thebusybiscuit.slimefun4.core.commands.SubCommand;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.utils.PatternUtils; import io.github.thebusybiscuit.slimefun4.utils.PatternUtils;
import me.mrCookieSlime.Slimefun.api.Slimefun;
class BackpackCommand extends SubCommand { class BackpackCommand extends SubCommand {
@ -27,11 +26,8 @@ class BackpackCommand extends SubCommand {
@Override @Override
public void onExecute(CommandSender sender, String[] args) { public void onExecute(CommandSender sender, String[] args) {
if (!(sender instanceof Player) || !sender.hasPermission("slimefun.command.backpack")) { if (sender instanceof Player) {
SlimefunPlugin.getLocalization().sendMessage(sender, "messages.no-permission", true); if (sender.hasPermission("slimefun.command.backpack")) {
return;
}
if (args.length != 3) { if (args.length != 3) {
SlimefunPlugin.getLocalization().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; return;
@ -58,7 +54,7 @@ class BackpackCommand extends SubCommand {
return; return;
} }
Slimefun.runSync(() -> { SlimefunPlugin.runSync(() -> {
ItemStack item = SlimefunItems.RESTORED_BACKPACK.clone(); ItemStack item = SlimefunItems.RESTORED_BACKPACK.clone();
SlimefunPlugin.getBackpackListener().setBackpackId(backpackOwner, item, 2, id); SlimefunPlugin.getBackpackListener().setBackpackId(backpackOwner, item, 2, id);
((Player) sender).getInventory().addItem(item); ((Player) sender).getInventory().addItem(item);
@ -66,4 +62,12 @@ class BackpackCommand extends SubCommand {
}); });
}); });
} }
else {
SlimefunPlugin.getLocalization().sendMessage(sender, "messages.no-permission", true);
}
}
else {
SlimefunPlugin.getLocalization().sendMessage(sender, "messages.only-players", true);
}
}
} }

View File

@ -14,7 +14,6 @@ import io.github.thebusybiscuit.slimefun4.implementation.guide.ChestSlimefunGuid
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.api.Slimefun;
/** /**
* This is a static utility class that provides convenient access to the methods * This is a static utility class that provides convenient access to the methods
@ -73,7 +72,7 @@ public final class SlimefunGuide {
} }
private static void openMainMenuAsync(Player player, SlimefunGuideLayout layout, int selectedPage) { private static void openMainMenuAsync(Player player, SlimefunGuideLayout layout, int selectedPage) {
if (!PlayerProfile.get(player, profile -> Slimefun.runSync(() -> openMainMenu(profile, layout, selectedPage)))) { if (!PlayerProfile.get(player, profile -> SlimefunPlugin.runSync(() -> openMainMenu(profile, layout, selectedPage)))) {
SlimefunPlugin.getLocalization().sendMessage(player, "messages.opening-guide"); SlimefunPlugin.getLocalization().sendMessage(player, "messages.opening-guide");
} }
} }

View File

@ -180,7 +180,7 @@ public class CargoNet extends ChestTerminalNetwork {
SlimefunPlugin.getProfiler().scheduleEntries((terminals.isEmpty() ? 1 : 2) + inputs.size()); SlimefunPlugin.getProfiler().scheduleEntries((terminals.isEmpty() ? 1 : 2) + inputs.size());
CargoNetworkTask runnable = new CargoNetworkTask(this, inputs, outputs, chestTerminalInputs, chestTerminalOutputs); CargoNetworkTask runnable = new CargoNetworkTask(this, inputs, outputs, chestTerminalInputs, chestTerminalOutputs);
Slimefun.runSync(runnable); SlimefunPlugin.runSync(runnable);
} }
} }

View File

@ -108,11 +108,18 @@ class CargoNetworkTask implements Runnable {
Inventory inv = inventories.get(inputTarget.getLocation()); Inventory inv = inventories.get(inputTarget.getLocation());
if (inv != null) { if (inv != null) {
// Check if the original slot hasn't been occupied in the meantime
if (inv.getItem(previousSlot) == null) { if (inv.getItem(previousSlot) == null) {
inv.setItem(previousSlot, stack); inv.setItem(previousSlot, stack);
} }
else { else {
inputTarget.getWorld().dropItem(inputTarget.getLocation().add(0, 1, 0), stack); // Try to add the item into another available slot then
ItemStack rest = inv.addItem(stack).get(0);
if (rest != null) {
// If the item still couldn't be inserted, simply drop it on the ground
inputTarget.getWorld().dropItem(inputTarget.getLocation().add(0, 1, 0), rest);
}
} }
} }
else { else {

View File

@ -27,7 +27,6 @@ import io.github.thebusybiscuit.slimefun4.utils.holograms.SimpleHologram;
import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config; import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.api.BlockStorage; import me.mrCookieSlime.Slimefun.api.BlockStorage;
import me.mrCookieSlime.Slimefun.api.Slimefun;
/** /**
* The {@link EnergyNet} is an implementation of {@link Network} that deals with * The {@link EnergyNet} is an implementation of {@link Network} that deals with
@ -229,7 +228,7 @@ public class EnergyNet extends Network {
explodedBlocks.add(loc); explodedBlocks.add(loc);
BlockStorage.clearBlockInfo(loc); BlockStorage.clearBlockInfo(loc);
Slimefun.runSync(() -> { SlimefunPlugin.runSync(() -> {
loc.getBlock().setType(Material.LAVA); loc.getBlock().setType(Material.LAVA);
loc.getWorld().createExplosion(loc, 0F, false); loc.getWorld().createExplosion(loc, 0F, false);
}); });

View File

@ -26,7 +26,6 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.setup.ResearchSetup; import io.github.thebusybiscuit.slimefun4.implementation.setup.ResearchSetup;
import io.github.thebusybiscuit.slimefun4.utils.FireworkUtils; import io.github.thebusybiscuit.slimefun4.utils.FireworkUtils;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.api.Slimefun;
/** /**
* Represents a research, which is bound to one * Represents a research, which is bound to one
@ -230,7 +229,7 @@ public class Research implements Keyed {
*/ */
public void unlock(@Nonnull Player p, boolean instant, @Nonnull Consumer<Player> callback) { public void unlock(@Nonnull Player p, boolean instant, @Nonnull Consumer<Player> callback) {
if (!instant) { if (!instant) {
Slimefun.runSync(() -> { SlimefunPlugin.runSync(() -> {
p.playSound(p.getLocation(), Sound.ENTITY_BAT_TAKEOFF, 0.7F, 1F); p.playSound(p.getLocation(), Sound.ENTITY_BAT_TAKEOFF, 0.7F, 1F);
SlimefunPlugin.getLocalization().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); }, 10L);
@ -238,7 +237,7 @@ public class Research implements Keyed {
PlayerProfile.get(p, profile -> { PlayerProfile.get(p, profile -> {
if (!profile.hasUnlocked(this)) { if (!profile.hasUnlocked(this)) {
Slimefun.runSync(() -> { SlimefunPlugin.runSync(() -> {
ResearchUnlockEvent event = new ResearchUnlockEvent(p, this); ResearchUnlockEvent event = new ResearchUnlockEvent(p, this);
Bukkit.getPluginManager().callEvent(event); Bukkit.getPluginManager().callEvent(event);
@ -250,7 +249,7 @@ public class Research implements Keyed {
SlimefunPlugin.getLocalization().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); playResearchAnimation(p);
Slimefun.runSync(() -> { SlimefunPlugin.runSync(() -> {
finishResearch(p, profile, callback); finishResearch(p, profile, callback);
SlimefunPlugin.getRegistry().getCurrentlyResearchingPlayers().remove(p.getUniqueId()); SlimefunPlugin.getRegistry().getCurrentlyResearchingPlayers().remove(p.getUniqueId());
}, (RESEARCH_PROGRESS.length + 1) * 20L); }, (RESEARCH_PROGRESS.length + 1) * 20L);
@ -275,7 +274,7 @@ public class Research implements Keyed {
for (int i = 1; i < RESEARCH_PROGRESS.length + 1; i++) { for (int i = 1; i < RESEARCH_PROGRESS.length + 1; i++) {
int j = i; int j = i;
Slimefun.runSync(() -> { SlimefunPlugin.runSync(() -> {
p.playSound(p.getLocation(), Sound.ENTITY_BAT_TAKEOFF, 0.7F, 1F); p.playSound(p.getLocation(), Sound.ENTITY_BAT_TAKEOFF, 0.7F, 1F);
SlimefunPlugin.getLocalization().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); }, i * 20L);

View File

@ -51,6 +51,8 @@ public class CustomTextureService {
config.setDefaultValue("SLIMEFUN_GUIDE", 0); config.setDefaultValue("SLIMEFUN_GUIDE", 0);
config.setDefaultValue("_UI_BACKGROUND", 0); config.setDefaultValue("_UI_BACKGROUND", 0);
config.setDefaultValue("_UI_INPUT_SLOT", 0);
config.setDefaultValue("_UI_OUTPUT_SLOT", 0);
config.setDefaultValue("_UI_BACK", 0); config.setDefaultValue("_UI_BACK", 0);
config.setDefaultValue("_UI_MENU", 0); config.setDefaultValue("_UI_MENU", 0);
config.setDefaultValue("_UI_SEARCH", 0); config.setDefaultValue("_UI_SEARCH", 0);

View File

@ -22,7 +22,6 @@ import kong.unirest.HttpResponse;
import kong.unirest.JsonNode; import kong.unirest.JsonNode;
import kong.unirest.Unirest; import kong.unirest.Unirest;
import kong.unirest.UnirestException; import kong.unirest.UnirestException;
import me.mrCookieSlime.Slimefun.api.Slimefun;
/** /**
* This Class represents a Metrics Service that sends data to https://bstats.org/ * This Class represents a Metrics Service that sends data to https://bstats.org/
@ -102,7 +101,7 @@ public class MetricsService {
String version = metricsClass.getPackage().getImplementationVersion(); String version = metricsClass.getPackage().getImplementationVersion();
// This is required to be sync due to bStats. // This is required to be sync due to bStats.
Slimefun.runSync(() -> { SlimefunPlugin.runSync(() -> {
try { try {
start.invoke(null); start.invoke(null);
plugin.getLogger().info("Metrics build #" + version + " started."); plugin.getLogger().info("Metrics build #" + version + " started.");

View File

@ -1,8 +1,6 @@
package io.github.thebusybiscuit.slimefun4.core.services; package io.github.thebusybiscuit.slimefun4.core.services;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
@ -12,8 +10,10 @@ import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.logging.Level;
import javax.annotation.Nonnull;
import org.apache.commons.lang.Validate;
import org.bukkit.Server; import org.bukkit.Server;
import org.bukkit.World; import org.bukkit.World;
@ -38,7 +38,7 @@ public class PerWorldSettingsService {
private final Map<SlimefunAddon, Set<String>> disabledAddons = new HashMap<>(); private final Map<SlimefunAddon, Set<String>> disabledAddons = new HashMap<>();
private final Set<UUID> disabledWorlds = new HashSet<>(); private final Set<UUID> disabledWorlds = new HashSet<>();
public PerWorldSettingsService(SlimefunPlugin plugin) { public PerWorldSettingsService(@Nonnull SlimefunPlugin plugin) {
this.plugin = plugin; this.plugin = plugin;
} }
@ -48,14 +48,7 @@ public class PerWorldSettingsService {
* @param worlds * @param worlds
* An {@link Iterable} of {@link World Worlds} to load * An {@link Iterable} of {@link World Worlds} to load
*/ */
public void load(Iterable<World> worlds) { public void load(@Nonnull Iterable<World> worlds) {
try {
migrate();
}
catch (IOException e) {
plugin.getLogger().log(Level.WARNING, "An error occurred while migrating old world settings", e);
}
for (World world : worlds) { for (World world : worlds) {
load(world); load(world);
} }
@ -67,41 +60,11 @@ public class PerWorldSettingsService {
* @param world * @param world
* The {@link World} to load * The {@link World} to load
*/ */
public void load(World world) { public void load(@Nonnull World world) {
Validate.notNull(world, "Cannot load a world that is null");
disabledItems.putIfAbsent(world.getUID(), loadWorldFromConfig(world)); disabledItems.putIfAbsent(world.getUID(), loadWorldFromConfig(world));
} }
/**
* Temporary migration method for the old system
*
* @throws IOException
* This will be thrown if we failed to delete the old {@link File}
*/
private void migrate() throws IOException {
Config oldConfig = new Config(plugin, "whitelist.yml");
if (oldConfig.getFile().exists()) {
for (String world : oldConfig.getKeys()) {
Config newConfig = new Config(plugin, "world-settings/" + world + ".yml");
newConfig.setDefaultValue("enabled", oldConfig.getBoolean(world + ".enabled"));
for (String id : oldConfig.getKeys(world + ".enabled-items")) {
SlimefunItem item = SlimefunItem.getByID(id);
if (item != null) {
String addon = item.getAddon().getName().toLowerCase(Locale.ROOT);
newConfig.setDefaultValue(addon + ".enabled", true);
newConfig.setDefaultValue(addon + '.' + id, oldConfig.getBoolean(world + ".enabled-items." + id));
}
}
newConfig.save();
}
Files.delete(oldConfig.getFile().toPath());
}
}
/** /**
* This method checks whether the given {@link SlimefunItem} is enabled in the given {@link World}. * This method checks whether the given {@link SlimefunItem} is enabled in the given {@link World}.
* *
@ -112,7 +75,10 @@ public class PerWorldSettingsService {
* *
* @return Whether the given {@link SlimefunItem} is enabled in that {@link World} * @return Whether the given {@link SlimefunItem} is enabled in that {@link World}
*/ */
public boolean isEnabled(World world, SlimefunItem item) { public boolean isEnabled(@Nonnull World world, @Nonnull SlimefunItem item) {
Validate.notNull(world, "The world cannot be null");
Validate.notNull(item, "The SlimefunItem cannot be null");
Set<String> items = disabledItems.computeIfAbsent(world.getUID(), id -> loadWorldFromConfig(world)); Set<String> items = disabledItems.computeIfAbsent(world.getUID(), id -> loadWorldFromConfig(world));
if (disabledWorlds.contains(world.getUID())) { if (disabledWorlds.contains(world.getUID())) {
@ -132,7 +98,10 @@ public class PerWorldSettingsService {
* @param enabled * @param enabled
* Whether the given {@link SlimefunItem} should be enabled in that world * Whether the given {@link SlimefunItem} should be enabled in that world
*/ */
public void setEnabled(World world, SlimefunItem item, boolean enabled) { public void setEnabled(@Nonnull World world, @Nonnull SlimefunItem item, boolean enabled) {
Validate.notNull(world, "The world cannot be null");
Validate.notNull(item, "The SlimefunItem cannot be null");
Set<String> items = disabledItems.computeIfAbsent(world.getUID(), id -> loadWorldFromConfig(world)); Set<String> items = disabledItems.computeIfAbsent(world.getUID(), id -> loadWorldFromConfig(world));
if (enabled) { if (enabled) {
@ -151,7 +120,8 @@ public class PerWorldSettingsService {
* @param enabled * @param enabled
* Whether this {@link World} should be enabled or not * Whether this {@link World} should be enabled or not
*/ */
public void setEnabled(World world, boolean enabled) { public void setEnabled(@Nonnull World world, boolean enabled) {
Validate.notNull(world, "null is not a valid World");
load(world); load(world);
if (enabled) { if (enabled) {
@ -170,7 +140,8 @@ public class PerWorldSettingsService {
* *
* @return Whether this {@link World} is enabled * @return Whether this {@link World} is enabled
*/ */
public boolean isWorldEnabled(World world) { public boolean isWorldEnabled(@Nonnull World world) {
Validate.notNull(world, "null is not a valid World");
load(world); load(world);
return !disabledWorlds.contains(world.getUID()); return !disabledWorlds.contains(world.getUID());
@ -186,7 +157,9 @@ public class PerWorldSettingsService {
* *
* @return Whether this addon is enabled in that {@link World} * @return Whether this addon is enabled in that {@link World}
*/ */
public boolean isAddonEnabled(World world, SlimefunAddon addon) { public boolean isAddonEnabled(@Nonnull World world, @Nonnull SlimefunAddon addon) {
Validate.notNull(world, "World cannot be null");
Validate.notNull(addon, "Addon cannot be null");
return isWorldEnabled(world) && disabledAddons.getOrDefault(addon, Collections.emptySet()).contains(world.getName()); return isWorldEnabled(world) && disabledAddons.getOrDefault(addon, Collections.emptySet()).contains(world.getName());
} }
@ -198,7 +171,8 @@ public class PerWorldSettingsService {
* @param world * @param world
* The {@link World} to save * The {@link World} to save
*/ */
public void save(World world) { public void save(@Nonnull World world) {
Validate.notNull(world, "Cannot save a World that does not exist");
Set<String> items = disabledItems.computeIfAbsent(world.getUID(), id -> loadWorldFromConfig(world)); Set<String> items = disabledItems.computeIfAbsent(world.getUID(), id -> loadWorldFromConfig(world));
Config config = getConfig(world); Config config = getConfig(world);
@ -213,7 +187,10 @@ public class PerWorldSettingsService {
config.save(); config.save();
} }
private Set<String> loadWorldFromConfig(World world) { @Nonnull
private Set<String> loadWorldFromConfig(@Nonnull World world) {
Validate.notNull(world, "Cannot load a World that does not exist");
String name = world.getName(); String name = world.getName();
Optional<Set<String>> optional = disabledItems.get(world.getUID()); Optional<Set<String>> optional = disabledItems.get(world.getUID());
@ -231,6 +208,7 @@ public class PerWorldSettingsService {
if (config.getBoolean("enabled")) { if (config.getBoolean("enabled")) {
loadItemsFromWorldConfig(name, config, items); loadItemsFromWorldConfig(name, config, items);
// We don't actually wanna write to disk during a Unit test
if (SlimefunPlugin.getMinecraftVersion() != MinecraftVersion.UNIT_TEST) { if (SlimefunPlugin.getMinecraftVersion() != MinecraftVersion.UNIT_TEST) {
config.save(); config.save();
} }
@ -243,13 +221,14 @@ public class PerWorldSettingsService {
} }
} }
private void loadItemsFromWorldConfig(String worldName, Config config, Set<String> items) { private void loadItemsFromWorldConfig(@Nonnull String worldName, @Nonnull Config config, @Nonnull Set<String> items) {
for (SlimefunItem item : SlimefunPlugin.getRegistry().getEnabledSlimefunItems()) { for (SlimefunItem item : SlimefunPlugin.getRegistry().getEnabledSlimefunItems()) {
if (item != null) { if (item != null) {
String addon = item.getAddon().getName().toLowerCase(Locale.ROOT); String addon = item.getAddon().getName().toLowerCase(Locale.ROOT);
config.setDefaultValue(addon + ".enabled", true); config.setDefaultValue(addon + ".enabled", true);
config.setDefaultValue(addon + '.' + item.getID(), true); config.setDefaultValue(addon + '.' + item.getID(), true);
// Whether the entire addon has been disabled
boolean isAddonDisabled = config.getBoolean(addon + ".enabled"); boolean isAddonDisabled = config.getBoolean(addon + ".enabled");
if (isAddonDisabled) { if (isAddonDisabled) {
@ -264,7 +243,17 @@ public class PerWorldSettingsService {
} }
} }
private Config getConfig(World world) { /**
* This method returns the relevant {@link Config} for the given {@link World}
*
* @param world
* Our {@link World}
*
* @return The corresponding {@link Config}
*/
@Nonnull
private Config getConfig(@Nonnull World world) {
Validate.notNull(world, "World cannot be null");
return new Config(plugin, "world-settings/" + world.getName() + ".yml"); return new Config(plugin, "world-settings/" + world.getName() + ".yml");
} }

View File

@ -0,0 +1,22 @@
package io.github.thebusybiscuit.slimefun4.core.services.github;
import java.time.LocalDateTime;
import javax.annotation.Nonnull;
@FunctionalInterface
interface ActivityCallback {
/**
* This method is called when the {@link GitHubActivityConnector} finished loading.
*
* @param forks
* The amount of forks
* @param stars
* The amount of stars
* @param date
* The {@link LocalDateTime} of the last activity
*/
void accept(int forks, int stars, @Nonnull LocalDateTime date);
}

View File

@ -61,14 +61,14 @@ class ContributionsConnector extends GitHubConnector {
} }
@Override @Override
public void onSuccess(JsonNode element) { public void onSuccess(@Nonnull JsonNode response) {
finished = true; finished = true;
if (element.isArray()) { if (response.isArray()) {
computeContributors(element.getArray()); computeContributors(response.getArray());
} }
else { else {
Slimefun.getLogger().log(Level.WARNING, "Received an unusual answer from GitHub, possibly a timeout? ({0})", element); Slimefun.getLogger().log(Level.WARNING, "Received an unusual answer from GitHub, possibly a timeout? ({0})", response);
} }
} }
@ -96,7 +96,8 @@ class ContributionsConnector extends GitHubConnector {
String profile = object.getString("html_url"); String profile = object.getString("html_url");
if (!blacklist.contains(name)) { if (!blacklist.contains(name)) {
github.addContributor(aliases.getOrDefault(name, name), profile, role, commits); String username = aliases.getOrDefault(name, name);
github.addContributor(username, profile, role, commits);
} }
} }
} }

View File

@ -40,15 +40,29 @@ public class Contributor {
private Optional<UUID> uuid = Optional.empty(); private Optional<UUID> uuid = Optional.empty();
private boolean locked = false; private boolean locked = false;
public Contributor(@Nonnull String username, @Nonnull String profile) { /**
Validate.notNull(username, "Username must never be null!"); * This creates a new {@link Contributor} with the given ingame name and GitHub profile.
*
* @param minecraftName
* The ingame name in Minecraft for this {@link Contributor}
* @param profile
* A link to their GitHub profile
*/
public Contributor(@Nonnull String minecraftName, @Nonnull String profile) {
Validate.notNull(minecraftName, "Username must never be null!");
Validate.notNull(profile, "The profile cannot be null!"); Validate.notNull(profile, "The profile cannot be null!");
githubUsername = profile.substring(profile.lastIndexOf('/') + 1); githubUsername = profile.substring(profile.lastIndexOf('/') + 1);
minecraftUsername = username; minecraftUsername = minecraftName;
profileLink = profile; profileLink = profile;
} }
/**
* This creates a new {@link Contributor} with the given username.
*
* @param username
* The username of this {@link Contributor}
*/
public Contributor(@Nonnull String username) { public Contributor(@Nonnull String username) {
Validate.notNull(username, "Username must never be null!"); Validate.notNull(username, "Username must never be null!");
@ -57,8 +71,18 @@ public class Contributor {
profileLink = null; profileLink = null;
} }
public void setContribution(@Nonnull String role, int commits) { /**
* This sets the amount of contributions of this {@link Contributor} for the
* specified role.
*
* @param role
* The role
* @param commits
* The amount of contributions made as that role
*/
public void setContributions(@Nonnull String role, int commits) {
Validate.notNull(role, "The role cannot be null!"); Validate.notNull(role, "The role cannot be null!");
Validate.isTrue(commits >= 0, "Contributions cannot be negative");
if (!locked || role.startsWith("translator,")) { if (!locked || role.startsWith("translator,")) {
contributions.put(role, commits); contributions.put(role, commits);
@ -66,9 +90,9 @@ public class Contributor {
} }
/** /**
* Returns the name of this contributor. * Returns the name of this {@link Contributor}.
* *
* @return the name of this contributor * @return the name of this {@link Contributor}
*/ */
@Nonnull @Nonnull
public String getName() { public String getName() {
@ -76,10 +100,10 @@ public class Contributor {
} }
/** /**
* Returns the MC name of the contributor. * Returns the Minecraft username of the {@link Contributor}.
* This may be the same as {@link #getName()}. * This can be the same as {@link #getName()}.
* *
* @return The MC username of this contributor. * @return The Minecraft username of this {@link Contributor}.
*/ */
@Nonnull @Nonnull
public String getMinecraftName() { public String getMinecraftName() {
@ -109,6 +133,7 @@ public class Contributor {
* *
* @param role * @param role
* The role for which to count the contributions. * The role for which to count the contributions.
*
* @return The amount of contributions this {@link Contributor} submitted as the given role * @return The amount of contributions this {@link Contributor} submitted as the given role
*/ */
public int getContributions(@Nonnull String role) { public int getContributions(@Nonnull String role) {
@ -137,7 +162,7 @@ public class Contributor {
} }
/** /**
* Returns this Creator's head texture. * Returns this contributor's head texture.
* If no texture could be found, or it hasn't been pulled yet, * If no texture could be found, or it hasn't been pulled yet,
* then it will return a placeholder texture. * then it will return a placeholder texture.
* *
@ -171,10 +196,22 @@ public class Contributor {
return headTexture.isComputed(); return headTexture.isComputed();
} }
/**
* This sets the skin texture of this {@link Contributor} or clears it.
*
* @param skin
* The base64 skin texture or null
*/
public void setTexture(@Nullable String skin) { public void setTexture(@Nullable String skin) {
headTexture.compute(skin); headTexture.compute(skin);
} }
/**
* This returns the total amount of contributions towards this project for this
* {@link Contributor}.
*
* @return The total amount of contributions
*/
public int getTotalContributions() { public int getTotalContributions() {
return contributions.values().stream().mapToInt(Integer::intValue).sum(); return contributions.values().stream().mapToInt(Integer::intValue).sum();
} }

View File

@ -0,0 +1,42 @@
package io.github.thebusybiscuit.slimefun4.core.services.github;
import java.time.LocalDateTime;
import javax.annotation.Nonnull;
import javax.annotation.ParametersAreNonnullByDefault;
import io.github.thebusybiscuit.slimefun4.utils.NumberUtils;
import kong.unirest.JsonNode;
import kong.unirest.json.JSONObject;
class GitHubActivityConnector extends GitHubConnector {
private final ActivityCallback callback;
@ParametersAreNonnullByDefault
GitHubActivityConnector(GitHubService github, String repository, ActivityCallback callback) {
super(github, repository);
this.callback = callback;
}
@Override
public void onSuccess(@Nonnull JsonNode response) {
JSONObject object = response.getObject();
int forks = object.getInt("forks");
int stars = object.getInt("stargazers_count");
LocalDateTime lastPush = NumberUtils.parseGitHubDate(object.getString("pushed_at"));
callback.accept(forks, stars, lastPush);
}
@Override
public String getFileName() {
return "repo";
}
@Override
public String getURLSuffix() {
return "";
}
}

View File

@ -10,6 +10,7 @@ import java.nio.charset.StandardCharsets;
import java.util.logging.Level; import java.util.logging.Level;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault; import javax.annotation.ParametersAreNonnullByDefault;
import kong.unirest.HttpResponse; import kong.unirest.HttpResponse;
@ -19,6 +20,14 @@ import kong.unirest.UnirestException;
import kong.unirest.json.JSONException; import kong.unirest.json.JSONException;
import me.mrCookieSlime.Slimefun.api.Slimefun; import me.mrCookieSlime.Slimefun.api.Slimefun;
/**
* The {@link GitHubConnector} is used to connect to the GitHub API service.
* It can be extended by subclasses, this just serves as an abstract super class for
* other connectors.
*
* @author TheBusyBiscuit
* @author Walshy
*/
abstract class GitHubConnector { abstract class GitHubConnector {
private static final String API_URL = "https://api.github.com/"; private static final String API_URL = "https://api.github.com/";
@ -33,12 +42,23 @@ abstract class GitHubConnector {
this.repository = repository; this.repository = repository;
} }
@Nonnull
public abstract String getFileName(); public abstract String getFileName();
@Nonnull
public abstract String getURLSuffix(); public abstract String getURLSuffix();
public abstract void onSuccess(JsonNode element); /**
* This method is called when the connection finished successfully.
*
* @param response
* The response
*/
public abstract void onSuccess(@Nonnull JsonNode response);
/**
* This method is called when the connection has failed.
*/
public void onFailure() { public void onFailure() {
// Don't do anything by default // Don't do anything by default
} }
@ -61,7 +81,7 @@ abstract class GitHubConnector {
} }
else { else {
if (github.isLoggingEnabled()) { if (github.isLoggingEnabled()) {
Slimefun.getLogger().log(Level.WARNING, "Failed to fetch {0}: {1} - {2}", new Object[] {repository + getURLSuffix(), resp.getStatus(), resp.getBody()}); Slimefun.getLogger().log(Level.WARNING, "Failed to fetch {0}: {1} - {2}", new Object[] { repository + getURLSuffix(), resp.getStatus(), resp.getBody() });
} }
// It has the cached file, let's just read that then // It has the cached file, let's just read that then
@ -94,12 +114,13 @@ abstract class GitHubConnector {
} }
} }
@Nullable
private JsonNode readCacheFile() { private JsonNode readCacheFile() {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8))) { try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8))) {
return new JsonNode(reader.readLine()); return new JsonNode(reader.readLine());
} }
catch (IOException | JSONException e) { catch (IOException | JSONException e) {
Slimefun.getLogger().log(Level.WARNING, "Failed to read Github cache file: {0} - {1}: {2}", new Object[] {file.getName(), e.getClass().getSimpleName(), e.getMessage()}); Slimefun.getLogger().log(Level.WARNING, "Failed to read Github cache file: {0} - {1}: {2}", new Object[] { file.getName(), e.getClass().getSimpleName(), e.getMessage() });
return null; return null;
} }
} }
@ -109,7 +130,7 @@ abstract class GitHubConnector {
output.write(node.toString().getBytes(StandardCharsets.UTF_8)); output.write(node.toString().getBytes(StandardCharsets.UTF_8));
} }
catch (IOException e) { catch (IOException e) {
Slimefun.getLogger().log(Level.WARNING, "Failed to populate GitHub cache: {0} - {1}", new Object[] {e.getClass().getSimpleName(), e.getMessage()}); Slimefun.getLogger().log(Level.WARNING, "Failed to populate GitHub cache: {0} - {1}", new Object[] { e.getClass().getSimpleName(), e.getMessage() });
} }
} }
} }

View File

@ -2,6 +2,7 @@ package io.github.thebusybiscuit.slimefun4.core.services.github;
import java.util.logging.Level; import java.util.logging.Level;
import javax.annotation.Nonnull;
import javax.annotation.ParametersAreNonnullByDefault; import javax.annotation.ParametersAreNonnullByDefault;
import kong.unirest.JsonNode; import kong.unirest.JsonNode;
@ -9,20 +10,20 @@ import kong.unirest.json.JSONArray;
import kong.unirest.json.JSONObject; import kong.unirest.json.JSONObject;
import me.mrCookieSlime.Slimefun.api.Slimefun; import me.mrCookieSlime.Slimefun.api.Slimefun;
class GitHubIssuesTracker extends GitHubConnector { class GitHubIssuesConnector extends GitHubConnector {
private final IssuesTrackerConsumer callback; private final IssuesCallback callback;
@ParametersAreNonnullByDefault @ParametersAreNonnullByDefault
GitHubIssuesTracker(GitHubService github, String repository, IssuesTrackerConsumer callback) { GitHubIssuesConnector(GitHubService github, String repository, IssuesCallback callback) {
super(github, repository); super(github, repository);
this.callback = callback; this.callback = callback;
} }
@Override @Override
public void onSuccess(JsonNode element) { public void onSuccess(@Nonnull JsonNode response) {
if (element.isArray()) { if (response.isArray()) {
JSONArray array = element.getArray(); JSONArray array = response.getArray();
int issues = 0; int issues = 0;
int pullRequests = 0; int pullRequests = 0;
@ -41,7 +42,7 @@ class GitHubIssuesTracker extends GitHubConnector {
callback.accept(issues, pullRequests); callback.accept(issues, pullRequests);
} }
else { else {
Slimefun.getLogger().log(Level.WARNING, "Received an unusual answer from GitHub, possibly a timeout? ({0})", element); Slimefun.getLogger().log(Level.WARNING, "Received an unusual answer from GitHub, possibly a timeout? ({0})", response);
} }
} }

View File

@ -16,9 +16,6 @@ import io.github.thebusybiscuit.cscorelib2.config.Config;
import io.github.thebusybiscuit.slimefun4.core.services.localization.Translators; import io.github.thebusybiscuit.slimefun4.core.services.localization.Translators;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.utils.HeadTexture; import io.github.thebusybiscuit.slimefun4.utils.HeadTexture;
import io.github.thebusybiscuit.slimefun4.utils.NumberUtils;
import kong.unirest.JsonNode;
import kong.unirest.json.JSONObject;
/** /**
* This Service is responsible for grabbing every {@link Contributor} to this project * This Service is responsible for grabbing every {@link Contributor} to this project
@ -39,11 +36,11 @@ public class GitHubService {
private boolean logging = false; private boolean logging = false;
private int issues = 0;
private int pullRequests = 0;
private int forks = 0;
private int stars = 0;
private LocalDateTime lastUpdate = LocalDateTime.now(); private LocalDateTime lastUpdate = LocalDateTime.now();
private int openIssues = 0;
private int pendingPullRequests = 0;
private int publicForks = 0;
private int stargazers = 0;
/** /**
* This creates a new {@link GitHubService} for the given repository. * This creates a new {@link GitHubService} for the given repository.
@ -63,6 +60,11 @@ public class GitHubService {
plugin.getServer().getScheduler().runTaskTimerAsynchronously(plugin, new GitHubTask(this), 80L, 60 * 60 * 20L); plugin.getServer().getScheduler().runTaskTimerAsynchronously(plugin, new GitHubTask(this), 80L, 60 * 60 * 20L);
} }
/**
* This method adds a few default {@link Contributor Contributors}.
* Think of them like honorable mentions that aren't listed through
* the usual methods.
*/
private void addDefaultContributors() { private void addDefaultContributors() {
addContributor("Fuffles_", "&dArtist"); addContributor("Fuffles_", "&dArtist");
addContributor("IMS_Art", "&dArtist"); addContributor("IMS_Art", "&dArtist");
@ -73,7 +75,7 @@ public class GitHubService {
private void addContributor(@Nonnull String name, @Nonnull String role) { private void addContributor(@Nonnull String name, @Nonnull String role) {
Contributor contributor = new Contributor(name); Contributor contributor = new Contributor(name);
contributor.setContribution(role, 0); contributor.setContributions(role, 0);
contributor.setUniqueId(uuidCache.getUUID(name)); contributor.setUniqueId(uuidCache.getUUID(name));
contributors.put(name, contributor); contributors.put(name, contributor);
} }
@ -83,7 +85,7 @@ public class GitHubService {
String username = profileURL.substring(profileURL.lastIndexOf('/') + 1); String username = profileURL.substring(profileURL.lastIndexOf('/') + 1);
Contributor contributor = contributors.computeIfAbsent(username, key -> new Contributor(minecraftName, profileURL)); Contributor contributor = contributors.computeIfAbsent(username, key -> new Contributor(minecraftName, profileURL));
contributor.setContribution(role, commits); contributor.setContributions(role, commits);
contributor.setUniqueId(uuidCache.getUUID(minecraftName)); contributor.setUniqueId(uuidCache.getUUID(minecraftName));
return contributor; return contributor;
} }
@ -97,37 +99,22 @@ public class GitHubService {
connectors.add(new ContributionsConnector(this, "code2", 2, repository, "developer")); connectors.add(new ContributionsConnector(this, "code2", 2, repository, "developer"));
// TheBusyBiscuit/Slimefun4-Wiki // TheBusyBiscuit/Slimefun4-Wiki
connectors.add(new ContributionsConnector(this, "wiki", 1, "Slimefun/Slimefun-wiki", "wiki")); connectors.add(new ContributionsConnector(this, "wiki", 1, "Slimefun/Wiki", "wiki"));
// TheBusyBiscuit/Slimefun4-Resourcepack // TheBusyBiscuit/Slimefun4-Resourcepack
connectors.add(new ContributionsConnector(this, "resourcepack", 1, "Slimefun/Resourcepack", "resourcepack")); connectors.add(new ContributionsConnector(this, "resourcepack", 1, "Slimefun/Resourcepack", "resourcepack"));
// Issues and Pull Requests // Issues and Pull Requests
connectors.add(new GitHubIssuesTracker(this, repository, (openIssues, openPullRequests) -> { connectors.add(new GitHubIssuesConnector(this, repository, (issues, pullRequests) -> {
this.issues = openIssues; this.openIssues = issues;
this.pullRequests = openPullRequests; this.pendingPullRequests = pullRequests;
})); }));
connectors.add(new GitHubConnector(this, repository) { connectors.add(new GitHubActivityConnector(this, repository, (forks, stars, date) -> {
this.publicForks = forks;
@Override this.stargazers = stars;
public void onSuccess(JsonNode element) { this.lastUpdate = date;
JSONObject object = element.getObject(); }));
forks = object.getInt("forks");
stars = object.getInt("stargazers_count");
lastUpdate = NumberUtils.parseGitHubDate(object.getString("pushed_at"));
}
@Override
public String getFileName() {
return "repo";
}
@Override
public String getURLSuffix() {
return "";
}
});
} }
@Nonnull @Nonnull
@ -155,7 +142,7 @@ public class GitHubService {
* @return The amount of forks * @return The amount of forks
*/ */
public int getForks() { public int getForks() {
return forks; return publicForks;
} }
/** /**
@ -164,7 +151,7 @@ public class GitHubService {
* @return The amount of people who starred the repository * @return The amount of people who starred the repository
*/ */
public int getStars() { public int getStars() {
return stars; return stargazers;
} }
/** /**
@ -173,7 +160,7 @@ public class GitHubService {
* @return The amount of open issues * @return The amount of open issues
*/ */
public int getOpenIssues() { public int getOpenIssues() {
return issues; return openIssues;
} }
/** /**
@ -192,7 +179,7 @@ public class GitHubService {
* @return The amount of pending pull requests * @return The amount of pending pull requests
*/ */
public int getPendingPullRequests() { public int getPendingPullRequests() {
return pullRequests; return pendingPullRequests;
} }
/** /**
@ -212,7 +199,6 @@ public class GitHubService {
protected void saveCache() { protected void saveCache() {
for (Contributor contributor : contributors.values()) { for (Contributor contributor : contributors.values()) {
Optional<UUID> uuid = contributor.getUniqueId(); Optional<UUID> uuid = contributor.getUniqueId();
uuid.ifPresent(value -> uuidCache.setValue(contributor.getName(), value)); uuid.ifPresent(value -> uuidCache.setValue(contributor.getName(), value));
if (contributor.hasTexture()) { if (contributor.hasTexture()) {

View File

@ -8,6 +8,7 @@ import java.util.UUID;
import java.util.logging.Level; import java.util.logging.Level;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@ -29,7 +30,6 @@ import me.mrCookieSlime.Slimefun.api.Slimefun;
class GitHubTask implements Runnable { class GitHubTask implements Runnable {
private static final int MAX_REQUESTS_PER_MINUTE = 16; private static final int MAX_REQUESTS_PER_MINUTE = 16;
private final GitHubService gitHubService; private final GitHubService gitHubService;
GitHubTask(@Nonnull GitHubService github) { GitHubTask(@Nonnull GitHubService github) {
@ -39,7 +39,6 @@ class GitHubTask implements Runnable {
@Override @Override
public void run() { public void run() {
gitHubService.getConnectors().forEach(GitHubConnector::pullFile); gitHubService.getConnectors().forEach(GitHubConnector::pullFile);
grabTextures(); grabTextures();
} }
@ -112,12 +111,12 @@ class GitHubTask implements Runnable {
return 0; return 0;
} }
@Nullable
private String pullTexture(@Nonnull Contributor contributor, @Nonnull Map<String, String> skins) throws TooManyRequestsException, IOException { private String pullTexture(@Nonnull Contributor contributor, @Nonnull Map<String, String> skins) throws TooManyRequestsException, IOException {
Optional<UUID> uuid = contributor.getUniqueId(); Optional<UUID> uuid = contributor.getUniqueId();
if (!uuid.isPresent()) { if (!uuid.isPresent()) {
uuid = MinecraftAccount.getUUID(contributor.getMinecraftName()); uuid = MinecraftAccount.getUUID(contributor.getMinecraftName());
uuid.ifPresent(contributor::setUniqueId); uuid.ifPresent(contributor::setUniqueId);
} }

View File

@ -1,10 +1,10 @@
package io.github.thebusybiscuit.slimefun4.core.services.github; package io.github.thebusybiscuit.slimefun4.core.services.github;
@FunctionalInterface @FunctionalInterface
interface IssuesTrackerConsumer { interface IssuesCallback {
/** /**
* This method is called when the {@link GitHubIssuesTracker} finished loading. * This method is called when the {@link GitHubIssuesConnector} finished loading.
* *
* @param issues * @param issues
* The amount of open Issues * The amount of open Issues

View File

@ -560,6 +560,7 @@ public final class SlimefunItems {
public static final SlimefunItemStack TALISMAN_KNIGHT = new SlimefunItemStack("KNIGHT_TALISMAN", Material.EMERALD, "&aTalisman of the Knight", "", "&fWhile you have this Talisman", "&fin your Inventory it gives", "&fyou a 30% Chance for 5 Seconds of Regeneration", "&fwhenever You get hit", "&fbut will then be consumed"); public static final SlimefunItemStack TALISMAN_KNIGHT = new SlimefunItemStack("KNIGHT_TALISMAN", Material.EMERALD, "&aTalisman of the Knight", "", "&fWhile you have this Talisman", "&fin your Inventory it gives", "&fyou a 30% Chance for 5 Seconds of Regeneration", "&fwhenever You get hit", "&fbut will then be consumed");
public static final SlimefunItemStack TALISMAN_WHIRLWIND = new SlimefunItemStack("WHIRLWIND_TALISMAN", Material.EMERALD, "&aTalisman of the Whirlwind", "", "&fHaving this Talisman", "&fin your Inventory will reflect", "&f60% of any projectiles fired at you.", "&e&oOnly a thrown Trident can pierce", "&e&othrough this layer of protection"); public static final SlimefunItemStack TALISMAN_WHIRLWIND = new SlimefunItemStack("WHIRLWIND_TALISMAN", Material.EMERALD, "&aTalisman of the Whirlwind", "", "&fHaving this Talisman", "&fin your Inventory will reflect", "&f60% of any projectiles fired at you.", "&e&oOnly a thrown Trident can pierce", "&e&othrough this layer of protection");
public static final SlimefunItemStack TALISMAN_WIZARD = new SlimefunItemStack("WIZARD_TALISMAN", Material.EMERALD, "&aTalisman of the Wizard", "", "&fWhile you have this Talisman", "&fin your Inventory it allows you to", "&fobtain Fortune Level 4/5 however", "&fit also has a chance to lower the", "&fLevel of some Enchantments on your Item"); public static final SlimefunItemStack TALISMAN_WIZARD = new SlimefunItemStack("WIZARD_TALISMAN", Material.EMERALD, "&aTalisman of the Wizard", "", "&fWhile you have this Talisman", "&fin your Inventory it allows you to", "&fobtain Fortune Level 4/5 however", "&fit also has a chance to lower the", "&fLevel of some Enchantments on your Item");
public static final SlimefunItemStack TALISMAN_CAVEMAN = new SlimefunItemStack("CAVEMAN_TALISMAN", Material.EMERALD, "&aTalisman of the Caveman", "", "&fWhile you have this Talisman", "&fin your inventory it gives", "&fyou a 50% chance for a decent", "&fHaste buff when you mine any ore");
/* Staves */ /* Staves */
public static final SlimefunItemStack STAFF_ELEMENTAL = new SlimefunItemStack("STAFF_ELEMENTAL", Material.STICK, "&6Elemental Staff"); public static final SlimefunItemStack STAFF_ELEMENTAL = new SlimefunItemStack("STAFF_ELEMENTAL", Material.STICK, "&6Elemental Staff");

View File

@ -13,6 +13,7 @@ import java.util.stream.Collectors;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Server; import org.bukkit.Server;
import org.bukkit.command.Command; import org.bukkit.command.Command;
@ -21,6 +22,7 @@ import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginDescriptionFile; import org.bukkit.plugin.PluginDescriptionFile;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.plugin.java.JavaPluginLoader; import org.bukkit.plugin.java.JavaPluginLoader;
import org.bukkit.scheduler.BukkitTask;
import io.github.thebusybiscuit.cscorelib2.config.Config; import io.github.thebusybiscuit.cscorelib2.config.Config;
import io.github.thebusybiscuit.cscorelib2.math.DoubleHandler; import io.github.thebusybiscuit.cscorelib2.math.DoubleHandler;
@ -102,7 +104,6 @@ import me.mrCookieSlime.CSCoreLibPlugin.CSCoreLib;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AContainer; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AContainer;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AGenerator; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AGenerator;
import me.mrCookieSlime.Slimefun.api.BlockStorage; import me.mrCookieSlime.Slimefun.api.BlockStorage;
import me.mrCookieSlime.Slimefun.api.Slimefun;
import me.mrCookieSlime.Slimefun.api.inventory.UniversalBlockMenu; import me.mrCookieSlime.Slimefun.api.inventory.UniversalBlockMenu;
/** /**
@ -242,7 +243,7 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon {
registerListeners(); registerListeners();
// Initiating various Stuff and all items with a slight delay (0ms after the Server finished loading) // Initiating various Stuff and all items with a slight delay (0ms after the Server finished loading)
Slimefun.runSync(new SlimefunStartupTask(this, () -> { runSync(new SlimefunStartupTask(this, () -> {
protections = new ProtectionManager(getServer()); protections = new ProtectionManager(getServer());
textureService.register(registry.getAllSlimefunItems(), true); textureService.register(registry.getAllSlimefunItems(), true);
permissionsService.register(registry.getAllSlimefunItems(), true); permissionsService.register(registry.getAllSlimefunItems(), true);
@ -708,4 +709,63 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon {
return "https://github.com/Slimefun/Slimefun4/issues"; return "https://github.com/Slimefun/Slimefun4/issues";
} }
/**
* This method schedules a delayed synchronous task for Slimefun.
* <strong>For Slimefun only, not for addons.</strong>
*
* This method should only be invoked by Slimefun itself.
* Addons must schedule their own tasks using their own {@link Plugin} instance.
*
* @param runnable
* The {@link Runnable} to run
* @param delay
* The delay for this task
*
* @return The resulting {@link BukkitTask} or null if Slimefun was disabled
*/
@Nullable
public static BukkitTask runSync(@Nonnull Runnable runnable, long delay) {
Validate.notNull(runnable, "Cannot run null");
Validate.isTrue(delay >= 0, "The delay cannot be negative");
if (getMinecraftVersion() == MinecraftVersion.UNIT_TEST) {
runnable.run();
return null;
}
if (instance == null || !instance.isEnabled()) {
return null;
}
return instance.getServer().getScheduler().runTaskLater(instance, runnable, delay);
}
/**
* This method schedules a synchronous task for Slimefun.
* <strong>For Slimefun only, not for addons.</strong>
*
* This method should only be invoked by Slimefun itself.
* Addons must schedule their own tasks using their own {@link Plugin} instance.
*
* @param runnable
* The {@link Runnable} to run
*
* @return The resulting {@link BukkitTask} or null if Slimefun was disabled
*/
@Nullable
public static BukkitTask runSync(@Nonnull Runnable runnable) {
Validate.notNull(runnable, "Cannot run null");
if (getMinecraftVersion() == MinecraftVersion.UNIT_TEST) {
runnable.run();
return null;
}
if (instance == null || !instance.isEnabled()) {
return null;
}
return instance.getServer().getScheduler().runTask(instance, runnable);
}
} }

View File

@ -80,7 +80,7 @@ public class BookSlimefunGuide implements SlimefunGuideImplementation {
ChatComponent header = new ChatComponent(ChatColors.color("&b&l- " + SlimefunPlugin.getLocalization().getMessage(p, "guide.title.main") + " -\n\n")); ChatComponent header = new ChatComponent(ChatColors.color("&b&l- " + SlimefunPlugin.getLocalization().getMessage(p, "guide.title.main") + " -\n\n"));
header.setHoverEvent(new HoverEvent(ChestMenuUtils.getSearchButton(p))); header.setHoverEvent(new HoverEvent(ChestMenuUtils.getSearchButton(p)));
header.setClickEvent(new ClickEvent(guideSearch, player -> Slimefun.runSync(() -> { header.setClickEvent(new ClickEvent(guideSearch, player -> SlimefunPlugin.runSync(() -> {
SlimefunPlugin.getLocalization().sendMessage(player, "guide.search.message"); SlimefunPlugin.getLocalization().sendMessage(player, "guide.search.message");
ChatInput.waitForPlayer(SlimefunPlugin.instance(), player, msg -> SlimefunGuide.openSearch(profile, msg, true, true)); ChatInput.waitForPlayer(SlimefunPlugin.instance(), player, msg -> SlimefunGuide.openSearch(profile, msg, true, true));
}, 1))); }, 1)));
@ -234,13 +234,13 @@ public class BookSlimefunGuide implements SlimefunGuideImplementation {
} }
component.setHoverEvent(new HoverEvent(lore)); component.setHoverEvent(new HoverEvent(lore));
component.setClickEvent(new ClickEvent(key, player -> Slimefun.runSync(() -> displayItem(profile, item, true)))); component.setClickEvent(new ClickEvent(key, player -> SlimefunPlugin.runSync(() -> displayItem(profile, item, true))));
items.add(component); items.add(component);
} }
} }
private void research(Player p, PlayerProfile profile, SlimefunItem item, Research research, Category category, int page) { private void research(Player p, PlayerProfile profile, SlimefunItem item, Research research, Category category, int page) {
Slimefun.runSync(() -> { SlimefunPlugin.runSync(() -> {
if (!SlimefunPlugin.getRegistry().getCurrentlyResearchingPlayers().contains(p.getUniqueId())) { if (!SlimefunPlugin.getRegistry().getCurrentlyResearchingPlayers().contains(p.getUniqueId())) {
if (research.canUnlock(p)) { if (research.canUnlock(p)) {
if (profile.hasUnlocked(research)) { if (profile.hasUnlocked(research)) {

View File

@ -1,14 +1,23 @@
package io.github.thebusybiscuit.slimefun4.implementation.guide; package io.github.thebusybiscuit.slimefun4.implementation.guide;
import javax.annotation.Nonnull;
import java.util.LinkedList;
import java.util.List;
import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuide;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.Recipe; import org.bukkit.inventory.Recipe;
import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile; import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile;
import io.github.thebusybiscuit.slimefun4.core.categories.FlexCategory;
import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideLayout; import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideLayout;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils; import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils;
import io.github.thebusybiscuit.slimefun4.utils.itemstack.SlimefunGuideItem; import io.github.thebusybiscuit.slimefun4.utils.itemstack.SlimefunGuideItem;
import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu; import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu;
import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
/** /**
@ -33,6 +42,29 @@ public class CheatSheetSlimefunGuide extends ChestSlimefunGuide {
return false; return false;
} }
/**
* Returns a {@link List} of visible {@link Category} instances that the {@link SlimefunGuide} would display.
*
* @param p
* The {@link Player} who opened his {@link SlimefunGuide}
* @param profile
* The {@link PlayerProfile} of the {@link Player}
* @return a {@link List} of visible {@link Category} instances
*/
@Nonnull
@Override
protected List<Category> getVisibleCategories(@Nonnull Player p, @Nonnull PlayerProfile profile) {
List<Category> categories = new LinkedList<>();
for (Category category : SlimefunPlugin.getRegistry().getCategories()) {
if (!(category instanceof FlexCategory)) {
categories.add(category);
}
}
return categories;
}
@Override @Override
public SlimefunGuideLayout getLayout() { public SlimefunGuideLayout getLayout() {
return SlimefunGuideLayout.CHEAT_SHEET; return SlimefunGuideLayout.CHEAT_SHEET;

View File

@ -1,5 +1,7 @@
package io.github.thebusybiscuit.slimefun4.implementation.guide; package io.github.thebusybiscuit.slimefun4.implementation.guide;
import javax.annotation.Nonnull;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.LinkedList; import java.util.LinkedList;
@ -96,7 +98,17 @@ public class ChestSlimefunGuide implements SlimefunGuideImplementation {
return true; return true;
} }
private List<Category> getVisibleCategories(Player p, PlayerProfile profile) { /**
* Returns a {@link List} of visible {@link Category} instances that the {@link SlimefunGuide} would display.
*
* @param p
* The {@link Player} who opened his {@link SlimefunGuide}
* @param profile
* The {@link PlayerProfile} of the {@link Player}
* @return a {@link List} of visible {@link Category} instances
*/
@Nonnull
protected List<Category> getVisibleCategories(@Nonnull Player p, @Nonnull PlayerProfile profile) {
List<Category> categories = new LinkedList<>(); List<Category> categories = new LinkedList<>();
for (Category category : SlimefunPlugin.getRegistry().getCategories()) { for (Category category : SlimefunPlugin.getRegistry().getCategories()) {

View File

@ -1,9 +1,11 @@
package io.github.thebusybiscuit.slimefun4.implementation.items.androids; package io.github.thebusybiscuit.slimefun4.implementation.items.androids;
import javax.annotation.Nonnull;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.cscorelib2.item.CustomItem; import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; import io.github.thebusybiscuit.slimefun4.utils.HeadTexture;
/** /**
* This enum covers all different fuel sources a {@link ProgrammableAndroid} can have. * This enum covers all different fuel sources a {@link ProgrammableAndroid} can have.
@ -30,7 +32,7 @@ public enum AndroidFuelSource {
private final String[] lore; private final String[] lore;
AndroidFuelSource(String... lore) { AndroidFuelSource(@Nonnull String... lore) {
this.lore = lore; this.lore = lore;
} }
@ -39,8 +41,9 @@ public enum AndroidFuelSource {
* *
* @return An {@link ItemStack} to display * @return An {@link ItemStack} to display
*/ */
@Nonnull
public ItemStack getItem() { public ItemStack getItem() {
return new CustomItem(SlimefunItems.COAL_GENERATOR, "&8\u21E9 &cFuel Input &8\u21E9", lore); return new CustomItem(HeadTexture.GENERATOR.getAsItemStack(), "&8\u21E9 &cFuel Input &8\u21E9", lore);
} }
} }

View File

@ -7,6 +7,9 @@ import java.util.Optional;
import java.util.function.Predicate; import java.util.function.Predicate;
import java.util.logging.Level; import java.util.logging.Level;
import javax.annotation.Nonnull;
import javax.annotation.ParametersAreNonnullByDefault;
import org.apache.commons.lang.Validate; import org.apache.commons.lang.Validate;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.Location; import org.bukkit.Location;
@ -55,7 +58,6 @@ import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.interfaces.InventoryBlock;
import me.mrCookieSlime.Slimefun.Objects.handlers.BlockTicker; import me.mrCookieSlime.Slimefun.Objects.handlers.BlockTicker;
import me.mrCookieSlime.Slimefun.Objects.handlers.ItemHandler; import me.mrCookieSlime.Slimefun.Objects.handlers.ItemHandler;
import me.mrCookieSlime.Slimefun.api.BlockStorage; import me.mrCookieSlime.Slimefun.api.BlockStorage;
import me.mrCookieSlime.Slimefun.api.Slimefun;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu; import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset; import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset;
@ -221,6 +223,7 @@ public class ProgrammableAndroid extends SlimefunItem implements InventoryBlock,
}); });
} }
@ParametersAreNonnullByDefault
public void openScript(Player p, Block b, String sourceCode) { public void openScript(Player p, Block b, String sourceCode) {
ChestMenu menu = new ChestMenu(ChatColor.DARK_AQUA + SlimefunPlugin.getLocalization().getMessage(p, "android.scripts.editor")); ChestMenu menu = new ChestMenu(ChatColor.DARK_AQUA + SlimefunPlugin.getLocalization().getMessage(p, "android.scripts.editor"));
menu.setEmptySlotsClickable(false); menu.setEmptySlotsClickable(false);
@ -291,6 +294,7 @@ public class ProgrammableAndroid extends SlimefunItem implements InventoryBlock,
menu.open(p); menu.open(p);
} }
@ParametersAreNonnullByDefault
private String addInstruction(String[] script, int index, Instruction instruction) { private String addInstruction(String[] script, int index, Instruction instruction) {
int i = 0; int i = 0;
StringBuilder builder = new StringBuilder(Instruction.START.name() + '-'); StringBuilder builder = new StringBuilder(Instruction.START.name() + '-');
@ -311,7 +315,7 @@ public class ProgrammableAndroid extends SlimefunItem implements InventoryBlock,
return builder.toString(); return builder.toString();
} }
private String duplicateInstruction(String[] script, int index) { private String duplicateInstruction(@Nonnull String[] script, int index) {
int i = 0; int i = 0;
StringBuilder builder = new StringBuilder(Instruction.START + "-"); StringBuilder builder = new StringBuilder(Instruction.START + "-");
@ -437,13 +441,9 @@ public class ProgrammableAndroid extends SlimefunItem implements InventoryBlock,
menu.open(p); menu.open(p);
} }
@ParametersAreNonnullByDefault
private void uploadScript(Player p, Block b, int page) { private void uploadScript(Player p, Block b, int page) {
String code = getScript(b.getLocation()); String code = getScript(b.getLocation());
if (code == null) {
return;
}
int nextId = 1; int nextId = 1;
for (Script script : Script.getUploadedScripts(getAndroidType())) { for (Script script : Script.getUploadedScripts(getAndroidType())) {
@ -542,12 +542,13 @@ public class ProgrammableAndroid extends SlimefunItem implements InventoryBlock,
menu.open(p); menu.open(p);
} }
protected String getScript(Location l) { @Nonnull
protected String getScript(@Nonnull Location l) {
String script = BlockStorage.getLocationInfo(l, "script"); String script = BlockStorage.getLocationInfo(l, "script");
return script != null ? script : DEFAULT_SCRIPT; return script != null ? script : DEFAULT_SCRIPT;
} }
protected void setScript(Location l, String script) { protected void setScript(@Nonnull Location l, @Nonnull String script) {
BlockStorage.addBlockInfo(l, "script", script); BlockStorage.addBlockInfo(l, "script", script);
} }
@ -784,10 +785,11 @@ public class ProgrammableAndroid extends SlimefunItem implements InventoryBlock,
return false; return false;
} }
@ParametersAreNonnullByDefault
private void consumeFuel(Block b, BlockMenu menu) { private void consumeFuel(Block b, BlockMenu menu) {
ItemStack item = menu.getItemInSlot(43); ItemStack item = menu.getItemInSlot(43);
if (item != null) { if (item != null && item.getType() != Material.AIR) {
for (MachineFuel fuel : fuelTypes) { for (MachineFuel fuel : fuelTypes) {
if (fuel.test(item)) { if (fuel.test(item)) {
menu.consumeItem(43); menu.consumeItem(43);
@ -804,12 +806,12 @@ public class ProgrammableAndroid extends SlimefunItem implements InventoryBlock,
} }
} }
private void constructMenu(BlockMenuPreset preset) { private void constructMenu(@Nonnull BlockMenuPreset preset) {
for (int i : BORDER) { for (int i : BORDER) {
preset.addItem(i, new CustomItem(new ItemStack(Material.GRAY_STAINED_GLASS_PANE), " "), ChestMenuUtils.getEmptyClickHandler()); preset.addItem(i, ChestMenuUtils.getBackground(), ChestMenuUtils.getEmptyClickHandler());
} }
for (int i : OUTPUT_BORDER) { for (int i : OUTPUT_BORDER) {
preset.addItem(i, new CustomItem(new ItemStack(Material.ORANGE_STAINED_GLASS_PANE), " "), ChestMenuUtils.getEmptyClickHandler()); preset.addItem(i, ChestMenuUtils.getOutputSlotTexture(), ChestMenuUtils.getEmptyClickHandler());
} }
for (int i : getOutputSlots()) { for (int i : getOutputSlots()) {
@ -848,7 +850,7 @@ public class ProgrammableAndroid extends SlimefunItem implements InventoryBlock,
}); });
block.setBlockData(blockData); block.setBlockData(blockData);
Slimefun.runSync(() -> SkullBlock.setFromBase64(block, texture)); SlimefunPlugin.runSync(() -> SkullBlock.setFromBase64(block, texture));
b.setType(Material.AIR); b.setType(Material.AIR);
BlockStorage.moveBlockInfo(b.getLocation(), block.getLocation()); BlockStorage.moveBlockInfo(b.getLocation(), block.getLocation());

View File

@ -32,7 +32,6 @@ import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.api.BlockStorage; import me.mrCookieSlime.Slimefun.api.BlockStorage;
import me.mrCookieSlime.Slimefun.api.Slimefun;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
/** /**
@ -156,7 +155,7 @@ public class BlockPlacer extends SlimefunItem {
dispenser.getInventory().removeItem(new CustomItem(item, 1)); dispenser.getInventory().removeItem(new CustomItem(item, 1));
} }
else { else {
Slimefun.runSync(() -> dispenser.getInventory().removeItem(item), 2L); SlimefunPlugin.runSync(() -> dispenser.getInventory().removeItem(item), 2L);
} }
} }
}); });
@ -171,7 +170,7 @@ public class BlockPlacer extends SlimefunItem {
dispenser.getInventory().removeItem(new CustomItem(item, 1)); dispenser.getInventory().removeItem(new CustomItem(item, 1));
} }
else { else {
Slimefun.runSync(() -> dispenser.getInventory().removeItem(item), 2L); SlimefunPlugin.runSync(() -> dispenser.getInventory().removeItem(item), 2L);
} }
} }
} }
@ -209,7 +208,7 @@ public class BlockPlacer extends SlimefunItem {
dispenser.getInventory().removeItem(new CustomItem(item, 1)); dispenser.getInventory().removeItem(new CustomItem(item, 1));
} }
else { else {
Slimefun.runSync(() -> dispenser.getInventory().removeItem(item), 2L); SlimefunPlugin.runSync(() -> dispenser.getInventory().removeItem(item), 2L);
} }
} }
} }

View File

@ -4,6 +4,9 @@ import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import javax.annotation.Nonnull;
import javax.annotation.ParametersAreNonnullByDefault;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.Sound; import org.bukkit.Sound;
import org.bukkit.Tag; import org.bukkit.Tag;
@ -24,7 +27,6 @@ import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.api.BlockStorage; import me.mrCookieSlime.Slimefun.api.BlockStorage;
import me.mrCookieSlime.Slimefun.api.Slimefun;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
public class Crucible extends SimpleSlimefunItem<BlockUseHandler> implements RecipeDisplayItem { public class Crucible extends SimpleSlimefunItem<BlockUseHandler> implements RecipeDisplayItem {
@ -100,6 +102,7 @@ public class Crucible extends SimpleSlimefunItem<BlockUseHandler> implements Rec
}; };
} }
@ParametersAreNonnullByDefault
private boolean craft(Player p, ItemStack input) { private boolean craft(Player p, ItemStack input) {
for (int i = 0; i < recipes.size(); i += 2) { for (int i = 0; i < recipes.size(); i += 2) {
ItemStack convert = recipes.get(i); ItemStack convert = recipes.get(i);
@ -116,7 +119,7 @@ public class Crucible extends SimpleSlimefunItem<BlockUseHandler> implements Rec
return false; return false;
} }
private void generateLiquid(Block block, boolean water) { private void generateLiquid(@Nonnull Block block, boolean water) {
if (block.getType() == (water ? Material.WATER : Material.LAVA)) { if (block.getType() == (water ? Material.WATER : Material.LAVA)) {
addLiquidLevel(block, water); addLiquidLevel(block, water);
} }
@ -126,11 +129,11 @@ public class Crucible extends SimpleSlimefunItem<BlockUseHandler> implements Rec
block.getWorld().playSound(block.getLocation(), Sound.BLOCK_LAVA_EXTINGUISH, 1F, 1F); block.getWorld().playSound(block.getLocation(), Sound.BLOCK_LAVA_EXTINGUISH, 1F, 1F);
} }
else { else {
Slimefun.runSync(() -> placeLiquid(block, water), 50L); SlimefunPlugin.runSync(() -> placeLiquid(block, water), 50L);
} }
} }
private void addLiquidLevel(Block block, boolean water) { private void addLiquidLevel(@Nonnull Block block, boolean water) {
int level = ((Levelled) block.getBlockData()).getLevel(); int level = ((Levelled) block.getBlockData()).getLevel();
if (level > 7) { if (level > 7) {
@ -142,11 +145,11 @@ public class Crucible extends SimpleSlimefunItem<BlockUseHandler> implements Rec
} }
else { else {
int finalLevel = 7 - level; int finalLevel = 7 - level;
Slimefun.runSync(() -> runPostTask(block, water ? Sound.ENTITY_PLAYER_SPLASH : Sound.BLOCK_LAVA_POP, finalLevel), 50L); SlimefunPlugin.runSync(() -> runPostTask(block, water ? Sound.ENTITY_PLAYER_SPLASH : Sound.BLOCK_LAVA_POP, finalLevel), 50L);
} }
} }
private void placeLiquid(Block block, boolean water) { private void placeLiquid(@Nonnull Block block, boolean water) {
if (block.getType() == Material.AIR || block.getType() == Material.CAVE_AIR || block.getType() == Material.VOID_AIR) { if (block.getType() == Material.AIR || block.getType() == Material.CAVE_AIR || block.getType() == Material.VOID_AIR) {
block.setType(water ? Material.WATER : Material.LAVA); block.setType(water ? Material.WATER : Material.LAVA);
} }
@ -167,6 +170,7 @@ public class Crucible extends SimpleSlimefunItem<BlockUseHandler> implements Rec
runPostTask(block, water ? Sound.ENTITY_PLAYER_SPLASH : Sound.BLOCK_LAVA_POP, 1); runPostTask(block, water ? Sound.ENTITY_PLAYER_SPLASH : Sound.BLOCK_LAVA_POP, 1);
} }
@ParametersAreNonnullByDefault
private void runPostTask(Block block, Sound sound, int times) { private void runPostTask(Block block, Sound sound, int times) {
if (!(block.getBlockData() instanceof Levelled)) { if (!(block.getBlockData() instanceof Levelled)) {
block.getWorld().playSound(block.getLocation(), Sound.BLOCK_METAL_BREAK, 1F, 1F); block.getWorld().playSound(block.getLocation(), Sound.BLOCK_METAL_BREAK, 1F, 1F);
@ -180,7 +184,7 @@ public class Crucible extends SimpleSlimefunItem<BlockUseHandler> implements Rec
block.setBlockData(le, false); block.setBlockData(le, false);
if (times < 8) { if (times < 8) {
Slimefun.runSync(() -> runPostTask(block, sound, times + 1), 50L); SlimefunPlugin.runSync(() -> runPostTask(block, sound, times + 1), 50L);
} }
else { else {
block.getWorld().playSound(block.getLocation(), Sound.ENTITY_ARROW_HIT_PLAYER, 1F, 1F); block.getWorld().playSound(block.getLocation(), Sound.ENTITY_ARROW_HIT_PLAYER, 1F, 1F);

View File

@ -83,7 +83,7 @@ abstract class AbstractCargoNode extends SlimefunItem {
menu.addMenuClickHandler(slotPrev, (p, slot, item, action) -> { menu.addMenuClickHandler(slotPrev, (p, slot, item, action) -> {
int newChannel = channel - 1; int newChannel = channel - 1;
if (channel < 0) { if (newChannel < 0) {
if (isChestTerminalInstalled) { if (isChestTerminalInstalled) {
newChannel = 16; newChannel = 16;
} }

View File

@ -10,6 +10,8 @@ import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AGenerator;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.MachineFuel; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.MachineFuel;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
import javax.annotation.Nonnull;
public abstract class CoalGenerator extends AGenerator { public abstract class CoalGenerator extends AGenerator {
public CoalGenerator(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { public CoalGenerator(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
@ -22,21 +24,62 @@ public abstract class CoalGenerator extends AGenerator {
registerFuel(new MachineFuel(12, new ItemStack(Material.BLAZE_ROD))); registerFuel(new MachineFuel(12, new ItemStack(Material.BLAZE_ROD)));
registerFuel(new MachineFuel(20, new ItemStack(Material.DRIED_KELP_BLOCK))); registerFuel(new MachineFuel(20, new ItemStack(Material.DRIED_KELP_BLOCK)));
// Boats
for (Material mat : Tag.ITEMS_BOATS.getValues()) {
registerFuel(new MachineFuel(5, new ItemStack(mat)));
}
// Coal & Charcoal // Coal & Charcoal
registerFuel(new MachineFuel(8, new ItemStack(Material.COAL))); registerFuel(new MachineFuel(8, new ItemStack(Material.COAL)));
registerFuel(new MachineFuel(8, new ItemStack(Material.CHARCOAL))); registerFuel(new MachineFuel(8, new ItemStack(Material.CHARCOAL)));
// Logs // Logs
for (Material mat : Tag.LOGS.getValues()) { for (Material mat : Tag.LOGS.getValues()) {
registerFuel(new MachineFuel(2, new ItemStack(mat))); registerFuel(new MachineFuel(4, new ItemStack(mat)));
} }
// Wooden Planks // Wooden Planks
for (Material mat : Tag.PLANKS.getValues()) { for (Material mat : Tag.PLANKS.getValues()) {
registerFuel(new MachineFuel(1, new ItemStack(mat))); registerFuel(new MachineFuel(1, new ItemStack(mat)));
} }
// Wooden Slabs
for (Material mat : Tag.WOODEN_SLABS.getValues()) {
registerFuel(new MachineFuel(1, new ItemStack(mat)));
} }
// Wooden Buttons
for (Material mat : Tag.WOODEN_BUTTONS.getValues()) {
registerFuel(new MachineFuel(1, new ItemStack(mat)));
}
// Wooden Fences
for (Material mat : Tag.WOODEN_FENCES.getValues()) {
registerFuel(new MachineFuel(1, new ItemStack(mat)));
}
// wooden Trapdoors
for (Material mat : Tag.WOODEN_TRAPDOORS.getValues()) {
registerFuel(new MachineFuel(3, new ItemStack(mat)));
}
// Wooden Pressure Plates
for (Material mat : Tag.WOODEN_PRESSURE_PLATES.getValues()) {
registerFuel(new MachineFuel(2, new ItemStack(mat)));
}
// Wooden Doors
for (Material mat : Tag.WOODEN_DOORS.getValues()) {
registerFuel(new MachineFuel(2, new ItemStack(mat)));
}
// Signs
for (Material mat : Tag.SIGNS.getValues()) {
registerFuel(new MachineFuel(2, new ItemStack(mat)));
}
}
@Nonnull
@Override @Override
public ItemStack getProgressBar() { public ItemStack getProgressBar() {
return new ItemStack(Material.FLINT_AND_STEEL); return new ItemStack(Material.FLINT_AND_STEEL);

View File

@ -28,7 +28,6 @@ import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.UnregisterReason; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.UnregisterReason;
import me.mrCookieSlime.Slimefun.Objects.handlers.BlockTicker; import me.mrCookieSlime.Slimefun.Objects.handlers.BlockTicker;
import me.mrCookieSlime.Slimefun.api.BlockStorage; import me.mrCookieSlime.Slimefun.api.BlockStorage;
import me.mrCookieSlime.Slimefun.api.Slimefun;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu; import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset; import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset;
@ -206,7 +205,7 @@ public abstract class AbstractEntityAssembler<T extends Entity> extends SimpleSl
removeCharge(b.getLocation(), getEnergyConsumption()); removeCharge(b.getLocation(), getEnergyConsumption());
double offset = Double.parseDouble(BlockStorage.getLocationInfo(b.getLocation(), KEY_OFFSET)); double offset = Double.parseDouble(BlockStorage.getLocationInfo(b.getLocation(), KEY_OFFSET));
Slimefun.runSync(() -> { SlimefunPlugin.runSync(() -> {
Location loc = new Location(b.getWorld(), b.getX() + 0.5D, b.getY() + offset, b.getZ() + 0.5D); Location loc = new Location(b.getWorld(), b.getX() + 0.5D, b.getY() + offset, b.getZ() + 0.5D);
spawnEntity(loc); spawnEntity(loc);

View File

@ -108,7 +108,7 @@ public class AutoDisenchanter extends AContainer {
EmeraldEnchants.getInstance().getRegistry().applyEnchantment(disenchantedItem, ench.getEnchantment(), 0); EmeraldEnchants.getInstance().getRegistry().applyEnchantment(disenchantedItem, ench.getEnchantment(), 0);
} }
MachineRecipe recipe = new MachineRecipe(90 * amount, new ItemStack[] { target, item }, new ItemStack[] { disenchantedItem, book }); MachineRecipe recipe = new MachineRecipe(90 * amount / this.getSpeed() , new ItemStack[] { target, item }, new ItemStack[] { disenchantedItem, book });
if (!InvUtils.fitAll(menu.toInventory(), recipe.getOutput(), getOutputSlots())) { if (!InvUtils.fitAll(menu.toInventory(), recipe.getOutput(), getOutputSlots())) {
return null; return null;

View File

@ -97,7 +97,7 @@ public class AutoEnchanter extends AContainer {
EmeraldEnchants.getInstance().getRegistry().applyEnchantment(enchantedItem, ench.getEnchantment(), ench.getLevel()); EmeraldEnchants.getInstance().getRegistry().applyEnchantment(enchantedItem, ench.getEnchantment(), ench.getLevel());
} }
MachineRecipe recipe = new MachineRecipe(75 * amount, new ItemStack[] { target, item }, new ItemStack[] { enchantedItem, new ItemStack(Material.BOOK) }); MachineRecipe recipe = new MachineRecipe(75 * amount / this.getSpeed(), new ItemStack[] { target, item }, new ItemStack[] { enchantedItem, new ItemStack(Material.BOOK) });
if (!InvUtils.fitAll(menu.toInventory(), recipe.getOutput(), getOutputSlots())) { if (!InvUtils.fitAll(menu.toInventory(), recipe.getOutput(), getOutputSlots())) {
return null; return null;

View File

@ -13,11 +13,11 @@ import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType; import org.bukkit.potion.PotionEffectType;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.utils.holograms.ReactorHologram; import io.github.thebusybiscuit.slimefun4.utils.holograms.ReactorHologram;
import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.MachineFuel; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.MachineFuel;
import me.mrCookieSlime.Slimefun.api.Slimefun;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
/** /**
@ -43,7 +43,7 @@ public abstract class NetherStarReactor extends Reactor {
@Override @Override
public void extraTick(@Nonnull Location l) { public void extraTick(@Nonnull Location l) {
Slimefun.runSync(() -> { SlimefunPlugin.runSync(() -> {
ArmorStand hologram = ReactorHologram.getArmorStand(l, true); ArmorStand hologram = ReactorHologram.getArmorStand(l, true);
for (Entity entity : hologram.getNearbyEntities(5, 5, 5)) { for (Entity entity : hologram.getNearbyEntities(5, 5, 5)) {
if (entity instanceof LivingEntity && entity.isValid()) { if (entity instanceof LivingEntity && entity.isValid()) {

View File

@ -21,6 +21,7 @@ import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.cscorelib2.item.CustomItem; import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction; import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction;
import io.github.thebusybiscuit.slimefun4.api.events.AsyncReactorProcessCompleteEvent;
import io.github.thebusybiscuit.slimefun4.api.events.ReactorExplodeEvent; import io.github.thebusybiscuit.slimefun4.api.events.ReactorExplodeEvent;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
@ -37,7 +38,6 @@ import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AGenerator; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AGenerator;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.MachineFuel; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.MachineFuel;
import me.mrCookieSlime.Slimefun.api.BlockStorage; import me.mrCookieSlime.Slimefun.api.BlockStorage;
import me.mrCookieSlime.Slimefun.api.Slimefun;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu; import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset; import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset;
@ -332,7 +332,7 @@ public abstract class Reactor extends AbstractEnergyProvider {
boolean explosion = explosionsQueue.contains(l); boolean explosion = explosionsQueue.contains(l);
if (explosion) { if (explosion) {
Slimefun.runSync(() -> { SlimefunPlugin.runSync(() -> {
ReactorExplodeEvent event = new ReactorExplodeEvent(l, Reactor.this); ReactorExplodeEvent event = new ReactorExplodeEvent(l, Reactor.this);
Bukkit.getPluginManager().callEvent(event); Bukkit.getPluginManager().callEvent(event);
@ -349,7 +349,7 @@ public abstract class Reactor extends AbstractEnergyProvider {
} }
private void checkForWaterBlocks(Location l) { private void checkForWaterBlocks(Location l) {
Slimefun.runSync(() -> { SlimefunPlugin.runSync(() -> {
// We will pick a surrounding block at random and see if this is water. // We will pick a surrounding block at random and see if this is water.
// If it isn't, then we will make it explode. // If it isn't, then we will make it explode.
int index = ThreadLocalRandom.current().nextInt(WATER_BLOCKS.length); int index = ThreadLocalRandom.current().nextInt(WATER_BLOCKS.length);
@ -376,6 +376,8 @@ public abstract class Reactor extends AbstractEnergyProvider {
} }
} }
Bukkit.getPluginManager().callEvent(new AsyncReactorProcessCompleteEvent(l, Reactor.this, getProcessing(l)));
progress.remove(l); progress.remove(l);
processing.remove(l); processing.remove(l);
} }

View File

@ -12,6 +12,7 @@ import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType; import org.bukkit.potion.PotionEffectType;
import io.github.thebusybiscuit.slimefun4.core.handlers.ItemConsumptionHandler; import io.github.thebusybiscuit.slimefun4.core.handlers.ItemConsumptionHandler;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem; import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
import io.github.thebusybiscuit.slimefun4.implementation.items.backpacks.Cooler; import io.github.thebusybiscuit.slimefun4.implementation.items.backpacks.Cooler;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.CoolerListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.CoolerListener;
@ -19,7 +20,6 @@ import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.api.Slimefun;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
/** /**
@ -81,18 +81,18 @@ public class Juice extends SimpleSlimefunItem<ItemConsumptionHandler> {
private void removeGlassBottle(Player p, ItemStack item) { private void removeGlassBottle(Player p, ItemStack item) {
if (SlimefunUtils.isItemSimilar(item, p.getInventory().getItemInMainHand(), true)) { if (SlimefunUtils.isItemSimilar(item, p.getInventory().getItemInMainHand(), true)) {
if (p.getInventory().getItemInMainHand().getAmount() == 1) { if (p.getInventory().getItemInMainHand().getAmount() == 1) {
Slimefun.runSync(() -> p.getEquipment().getItemInMainHand().setAmount(0)); SlimefunPlugin.runSync(() -> p.getEquipment().getItemInMainHand().setAmount(0));
} }
else { else {
Slimefun.runSync(() -> p.getInventory().removeItem(new ItemStack(Material.GLASS_BOTTLE, 1))); SlimefunPlugin.runSync(() -> p.getInventory().removeItem(new ItemStack(Material.GLASS_BOTTLE, 1)));
} }
} }
else if (SlimefunUtils.isItemSimilar(item, p.getInventory().getItemInOffHand(), true)) { else if (SlimefunUtils.isItemSimilar(item, p.getInventory().getItemInOffHand(), true)) {
if (p.getInventory().getItemInOffHand().getAmount() == 1) { if (p.getInventory().getItemInOffHand().getAmount() == 1) {
Slimefun.runSync(() -> p.getEquipment().getItemInOffHand().setAmount(0)); SlimefunPlugin.runSync(() -> p.getEquipment().getItemInOffHand().setAmount(0));
} }
else { else {
Slimefun.runSync(() -> p.getInventory().removeItem(new ItemStack(Material.GLASS_BOTTLE, 1))); SlimefunPlugin.runSync(() -> p.getInventory().removeItem(new ItemStack(Material.GLASS_BOTTLE, 1)));
} }
} }
} }

View File

@ -5,10 +5,10 @@ import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType; import org.bukkit.potion.PotionEffectType;
import io.github.thebusybiscuit.slimefun4.core.handlers.ItemConsumptionHandler; import io.github.thebusybiscuit.slimefun4.core.handlers.ItemConsumptionHandler;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem; import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.api.Slimefun;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
/** /**
@ -27,7 +27,7 @@ public class MonsterJerky extends SimpleSlimefunItem<ItemConsumptionHandler> {
@Override @Override
public ItemConsumptionHandler getItemHandler() { public ItemConsumptionHandler getItemHandler() {
return (e, p, item) -> Slimefun.runSync(() -> { return (e, p, item) -> SlimefunPlugin.runSync(() -> {
if (p.hasPotionEffect(PotionEffectType.HUNGER)) { if (p.hasPotionEffect(PotionEffectType.HUNGER)) {
p.removePotionEffect(PotionEffectType.HUNGER); p.removePotionEffect(PotionEffectType.HUNGER);
} }

View File

@ -34,7 +34,6 @@ import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu;
import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.api.BlockStorage; import me.mrCookieSlime.Slimefun.api.BlockStorage;
import me.mrCookieSlime.Slimefun.api.Slimefun;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
public class ElevatorPlate extends SimpleSlimefunItem<BlockUseHandler> { public class ElevatorPlate extends SimpleSlimefunItem<BlockUseHandler> {
@ -152,7 +151,7 @@ public class ElevatorPlate extends SimpleSlimefunItem<BlockUseHandler> {
@ParametersAreNonnullByDefault @ParametersAreNonnullByDefault
private void teleport(Player player, String floorName, Block target) { private void teleport(Player player, String floorName, Block target) {
Slimefun.runSync(() -> { SlimefunPlugin.runSync(() -> {
users.add(player.getUniqueId()); users.add(player.getUniqueId());
float yaw = player.getEyeLocation().getYaw() + 180; float yaw = player.getEyeLocation().getYaw() + 180;

View File

@ -67,7 +67,7 @@ public class EnchantmentRune extends SimpleSlimefunItem<ItemDropHandler> {
return (e, p, item) -> { return (e, p, item) -> {
if (isItem(item.getItemStack())) { if (isItem(item.getItemStack())) {
if (Slimefun.hasUnlocked(p, this, true)) { if (Slimefun.hasUnlocked(p, this, true)) {
Slimefun.runSync(() -> { SlimefunPlugin.runSync(() -> {
try { try {
addRandomEnchantment(p, item); addRandomEnchantment(p, item);
} }
@ -124,7 +124,7 @@ public class EnchantmentRune extends SimpleSlimefunItem<ItemDropHandler> {
// This lightning is just an effect, it deals no damage. // This lightning is just an effect, it deals no damage.
l.getWorld().strikeLightningEffect(l); l.getWorld().strikeLightningEffect(l);
Slimefun.runSync(() -> { SlimefunPlugin.runSync(() -> {
// Being sure entities are still valid and not picked up or whatsoever. // Being sure entities are still valid and not picked up or whatsoever.
if (rune.isValid() && item.isValid() && itemStack.getAmount() == 1) { if (rune.isValid() && item.isValid() && itemStack.getAmount() == 1) {

View File

@ -11,7 +11,10 @@ import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.cscorelib2.inventory.ItemUtils; import io.github.thebusybiscuit.cscorelib2.inventory.ItemUtils;
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion; import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
import io.github.thebusybiscuit.slimefun4.api.events.PlayerRightClickEvent;
import io.github.thebusybiscuit.slimefun4.core.attributes.NotPlaceable;
import io.github.thebusybiscuit.slimefun4.core.handlers.EntityInteractHandler; import io.github.thebusybiscuit.slimefun4.core.handlers.EntityInteractHandler;
import io.github.thebusybiscuit.slimefun4.core.handlers.ItemUseHandler;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem; import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Lists.RecipeType;
@ -31,10 +34,12 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
* @see EntityInteractHandler * @see EntityInteractHandler
* *
*/ */
public class MagicalZombiePills extends SimpleSlimefunItem<EntityInteractHandler> { public class MagicalZombiePills extends SimpleSlimefunItem<EntityInteractHandler> implements NotPlaceable {
public MagicalZombiePills(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe, ItemStack recipeOutput) { public MagicalZombiePills(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe, ItemStack recipeOutput) {
super(category, item, recipeType, recipe, recipeOutput); super(category, item, recipeType, recipe, recipeOutput);
addItemHandler(onRightClick());
} }
@Override @Override
@ -61,4 +66,12 @@ public class MagicalZombiePills extends SimpleSlimefunItem<EntityInteractHandler
}; };
} }
/**
* This method cancels {@link PlayerRightClickEvent} to prevent placing {@link MagicalZombiePills}.
*
* @return the {@link ItemUseHandler} of this {@link SlimefunItem}
*/
public ItemUseHandler onRightClick() {
return PlayerRightClickEvent::cancel;
}
} }

View File

@ -50,7 +50,7 @@ public class SoulboundRune extends SimpleSlimefunItem<ItemDropHandler> {
return true; return true;
} }
Slimefun.runSync(() -> activate(p, item), 20L); SlimefunPlugin.runSync(() -> activate(p, item), 20L);
return true; return true;
} }
@ -76,7 +76,7 @@ public class SoulboundRune extends SimpleSlimefunItem<ItemDropHandler> {
// This lightning is just an effect, it deals no damage. // This lightning is just an effect, it deals no damage.
l.getWorld().strikeLightningEffect(l); l.getWorld().strikeLightningEffect(l);
Slimefun.runSync(() -> { SlimefunPlugin.runSync(() -> {
// Being sure entities are still valid and not picked up or whatsoever. // Being sure entities are still valid and not picked up or whatsoever.
if (rune.isValid() && item.isValid() && itemStack.getAmount() == 1) { if (rune.isValid() && item.isValid() && itemStack.getAmount() == 1) {

View File

@ -84,7 +84,7 @@ public class ArmorForge extends MultiBlockMachine {
for (int j = 0; j < 4; j++) { for (int j = 0; j < 4; j++) {
int current = j; int current = j;
Slimefun.runSync(() -> { SlimefunPlugin.runSync(() -> {
if (current < 3) { if (current < 3) {
p.getWorld().playSound(p.getLocation(), Sound.BLOCK_ANVIL_USE, 1F, 2F); p.getWorld().playSound(p.getLocation(), Sound.BLOCK_ANVIL_USE, 1F, 2F);
} }

View File

@ -21,7 +21,6 @@ import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
import io.papermc.lib.PaperLib; import io.papermc.lib.PaperLib;
import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.api.Slimefun;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
public class Compressor extends MultiBlockMachine { public class Compressor extends MultiBlockMachine {
@ -83,7 +82,7 @@ public class Compressor extends MultiBlockMachine {
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
int j = i; int j = i;
Slimefun.runSync(() -> { SlimefunPlugin.runSync(() -> {
if (j < 3) { if (j < 3) {
p.getWorld().playSound(p.getLocation(), j == 1 ? Sound.BLOCK_PISTON_CONTRACT : Sound.BLOCK_PISTON_EXTEND, 1F, j == 0 ? 1F : 2F); p.getWorld().playSound(p.getLocation(), j == 1 ? Sound.BLOCK_PISTON_CONTRACT : Sound.BLOCK_PISTON_EXTEND, 1F, j == 0 ? 1F : 2F);
} }

View File

@ -94,7 +94,7 @@ public class MagicWorkbench extends BackpackCrafter {
private void startAnimation(Player p, Block b, Inventory inv, ItemStack output) { private void startAnimation(Player p, Block b, Inventory inv, ItemStack output) {
for (int j = 0; j < 4; j++) { for (int j = 0; j < 4; j++) {
int current = j; int current = j;
Slimefun.runSync(() -> { SlimefunPlugin.runSync(() -> {
p.getWorld().playEffect(b.getLocation(), Effect.MOBSPAWNER_FLAMES, 1); p.getWorld().playEffect(b.getLocation(), Effect.MOBSPAWNER_FLAMES, 1);
p.getWorld().playEffect(b.getLocation(), Effect.ENDER_SIGNAL, 1); p.getWorld().playEffect(b.getLocation(), Effect.ENDER_SIGNAL, 1);

View File

@ -53,6 +53,36 @@ public class OreCrusher extends MultiBlockMachine {
recipes.add(SlimefunItems.GOLD_4K); recipes.add(SlimefunItems.GOLD_4K);
recipes.add(SlimefunItems.GOLD_DUST); recipes.add(SlimefunItems.GOLD_DUST);
recipes.add(SlimefunItems.GOLD_6K);
recipes.add(new SlimefunItemStack(SlimefunItems.GOLD_DUST, 2));
recipes.add(SlimefunItems.GOLD_8K);
recipes.add(new SlimefunItemStack(SlimefunItems.GOLD_DUST, 2));
recipes.add(SlimefunItems.GOLD_10K);
recipes.add(new SlimefunItemStack(SlimefunItems.GOLD_DUST, 3));
recipes.add(SlimefunItems.GOLD_12K);
recipes.add(new SlimefunItemStack(SlimefunItems.GOLD_DUST, 3));
recipes.add(SlimefunItems.GOLD_14K);
recipes.add(new SlimefunItemStack(SlimefunItems.GOLD_DUST, 4));
recipes.add(SlimefunItems.GOLD_16K);
recipes.add(new SlimefunItemStack(SlimefunItems.GOLD_DUST, 4));
recipes.add(SlimefunItems.GOLD_18K);
recipes.add(new SlimefunItemStack(SlimefunItems.GOLD_DUST, 5));
recipes.add(SlimefunItems.GOLD_20K);
recipes.add(new SlimefunItemStack(SlimefunItems.GOLD_DUST, 5));
recipes.add(SlimefunItems.GOLD_22K);
recipes.add(new SlimefunItemStack(SlimefunItems.GOLD_DUST, 6));
recipes.add(SlimefunItems.GOLD_24K);
recipes.add(new SlimefunItemStack(SlimefunItems.GOLD_DUST, 6));
recipes.add(new ItemStack(Material.GRAVEL)); recipes.add(new ItemStack(Material.GRAVEL));
recipes.add(new ItemStack(Material.SAND)); recipes.add(new ItemStack(Material.SAND));

View File

@ -22,7 +22,6 @@ import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
import io.papermc.lib.PaperLib; import io.papermc.lib.PaperLib;
import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.api.Slimefun;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
public class PressureChamber extends MultiBlockMachine { public class PressureChamber extends MultiBlockMachine {
@ -75,7 +74,7 @@ public class PressureChamber extends MultiBlockMachine {
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
int j = i; int j = i;
Slimefun.runSync(() -> { SlimefunPlugin.runSync(() -> {
p.getWorld().playSound(b.getLocation(), Sound.ENTITY_TNT_PRIMED, 1, 1); p.getWorld().playSound(b.getLocation(), Sound.ENTITY_TNT_PRIMED, 1, 1);
p.getWorld().playEffect(b.getRelative(BlockFace.UP).getLocation(), Effect.SMOKE, 4); p.getWorld().playEffect(b.getRelative(BlockFace.UP).getLocation(), Effect.SMOKE, 4);
p.getWorld().playEffect(b.getRelative(BlockFace.UP).getLocation(), Effect.SMOKE, 4); p.getWorld().playEffect(b.getRelative(BlockFace.UP).getLocation(), Effect.SMOKE, 4);

View File

@ -191,7 +191,7 @@ class ActiveMiner implements Runnable {
ores++; ores++;
// Repeat the same column when we hit an ore. // Repeat the same column when we hit an ore.
Slimefun.runSync(this, 4); SlimefunPlugin.runSync(this, 4);
return; return;
} }
} }
@ -232,7 +232,7 @@ class ActiveMiner implements Runnable {
return; return;
} }
Slimefun.runSync(this, 5); SlimefunPlugin.runSync(this, 5);
} }
/** /**

View File

@ -36,7 +36,6 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem; import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.api.Slimefun;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
/** /**
@ -151,7 +150,7 @@ public class ClimbingPick extends SimpleSlimefunItem<ItemUseHandler> implements
power += efficiencyLevel * 0.1; power += efficiencyLevel * 0.1;
} }
Slimefun.runSync(() -> users.remove(p.getUniqueId()), 4L); SlimefunPlugin.runSync(() -> users.remove(p.getUniqueId()), 4L);
Vector velocity = new Vector(0, power * BASE_POWER, 0); Vector velocity = new Vector(0, power * BASE_POWER, 0);
ClimbingPickLaunchEvent event = new ClimbingPickLaunchEvent(p, velocity, this, item, block); ClimbingPickLaunchEvent event = new ClimbingPickLaunchEvent(p, velocity, this, item, block);
Bukkit.getPluginManager().callEvent(event); Bukkit.getPluginManager().callEvent(event);

View File

@ -15,6 +15,7 @@ import io.github.thebusybiscuit.cscorelib2.collections.RandomizedSet;
import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction; import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction;
import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting; import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting;
import io.github.thebusybiscuit.slimefun4.core.attributes.RecipeDisplayItem; import io.github.thebusybiscuit.slimefun4.core.attributes.RecipeDisplayItem;
import io.github.thebusybiscuit.slimefun4.core.handlers.EntityInteractHandler;
import io.github.thebusybiscuit.slimefun4.core.handlers.ItemUseHandler; import io.github.thebusybiscuit.slimefun4.core.handlers.ItemUseHandler;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
@ -47,6 +48,7 @@ public class GoldPan extends SimpleSlimefunItem<ItemUseHandler> implements Recip
drops.addAll(getGoldPanDrops()); drops.addAll(getGoldPanDrops());
addItemSetting(drops.toArray(new GoldPanDrop[0])); addItemSetting(drops.toArray(new GoldPanDrop[0]));
addItemHandler(onEntityInteract());
} }
protected Material getInput() { protected Material getInput() {
@ -115,6 +117,16 @@ public class GoldPan extends SimpleSlimefunItem<ItemUseHandler> implements Recip
}; };
} }
/**
* This method cancels {@link EntityInteractHandler} to prevent interacting {@link GoldPan}
* with entities.
*
* @return the {@link EntityInteractHandler} of this {@link SlimefunItem}
*/
public EntityInteractHandler onEntityInteract() {
return (e, item, offHand) -> e.setCancelled(true);
}
@Override @Override
public List<ItemStack> getDisplayRecipes() { public List<ItemStack> getDisplayRecipes() {
List<ItemStack> recipes = new LinkedList<>(); List<ItemStack> recipes = new LinkedList<>();

View File

@ -22,12 +22,14 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
public class GrapplingHook extends SimpleSlimefunItem<ItemUseHandler> { public class GrapplingHook extends SimpleSlimefunItem<ItemUseHandler> {
private final ItemSetting<Boolean> consumeOnUse = new ItemSetting<>("consume-on-use", true);
private final ItemSetting<Integer> despawnTicks = new ItemSetting<>("despawn-seconds", 60); private final ItemSetting<Integer> despawnTicks = new ItemSetting<>("despawn-seconds", 60);
public GrapplingHook(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { public GrapplingHook(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(category, item, recipeType, recipe); super(category, item, recipeType, recipe);
addItemSetting(despawnTicks); addItemSetting(despawnTicks);
addItemSetting(consumeOnUse);
} }
@Override @Override
@ -35,6 +37,7 @@ public class GrapplingHook extends SimpleSlimefunItem<ItemUseHandler> {
return e -> { return e -> {
Player p = e.getPlayer(); Player p = e.getPlayer();
UUID uuid = p.getUniqueId(); UUID uuid = p.getUniqueId();
boolean consumeOnUseValue = consumeOnUse.getValue();
if (!e.getClickedBlock().isPresent() && !SlimefunPlugin.getGrapplingHookListener().isGrappling(uuid)) { if (!e.getClickedBlock().isPresent() && !SlimefunPlugin.getGrapplingHookListener().isGrappling(uuid)) {
e.cancel(); e.cancel();
@ -47,8 +50,11 @@ public class GrapplingHook extends SimpleSlimefunItem<ItemUseHandler> {
ItemStack item = e.getItem(); ItemStack item = e.getItem();
if (item.getType() == Material.LEAD) { if (item.getType() == Material.LEAD) {
//If consume on use is enabled, the if statement below will take 1 grappling hook out of player's hand
if (consumeOnUseValue) {
item.setAmount(item.getAmount() - 1); item.setAmount(item.getAmount() - 1);
} }
}
Vector direction = p.getEyeLocation().getDirection().multiply(2.0); Vector direction = p.getEyeLocation().getDirection().multiply(2.0);
Arrow arrow = p.getWorld().spawn(p.getEyeLocation().add(direction.getX(), direction.getY(), direction.getZ()), Arrow.class); Arrow arrow = p.getWorld().spawn(p.getEyeLocation().add(direction.getX(), direction.getY(), direction.getZ()), Arrow.class);
@ -63,7 +69,7 @@ public class GrapplingHook extends SimpleSlimefunItem<ItemUseHandler> {
bat.setLeashHolder(arrow); bat.setLeashHolder(arrow);
boolean state = item.getType() != Material.SHEARS; boolean state = item.getType() != Material.SHEARS;
SlimefunPlugin.getGrapplingHookListener().addGrapplingHook(p, arrow, bat, state, despawnTicks.getValue()); SlimefunPlugin.getGrapplingHookListener().addGrapplingHook(p, arrow, bat, state, despawnTicks.getValue(), consumeOnUseValue);
} }
}; };
} }

View File

@ -1,7 +1,10 @@
package io.github.thebusybiscuit.slimefun4.implementation.items.tools; package io.github.thebusybiscuit.slimefun4.implementation.items.tools;
import javax.annotation.ParametersAreNonnullByDefault;
import org.bukkit.Sound; import org.bukkit.Sound;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.CraftingInventory;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.slimefun4.core.attributes.NotPlaceable; import io.github.thebusybiscuit.slimefun4.core.attributes.NotPlaceable;
@ -11,8 +14,16 @@ import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
/**
* The {@link PortableCrafter} is one of the oldest items in Slimefun.
* It allows a {@link Player} to open up the {@link CraftingInventory} via right click.
*
* @author TheBusyBiscuit
*
*/
public class PortableCrafter extends SimpleSlimefunItem<ItemUseHandler> implements NotPlaceable { public class PortableCrafter extends SimpleSlimefunItem<ItemUseHandler> implements NotPlaceable {
@ParametersAreNonnullByDefault
public PortableCrafter(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { public PortableCrafter(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(category, item, recipeType, recipe); super(category, item, recipeType, recipe);
} }

View File

@ -4,6 +4,9 @@ import java.text.DecimalFormat;
import java.util.Optional; import java.util.Optional;
import java.util.UUID; import java.util.UUID;
import javax.annotation.Nonnull;
import javax.annotation.ParametersAreNonnullByDefault;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.NamespacedKey; import org.bukkit.NamespacedKey;
import org.bukkit.block.Block; import org.bukkit.block.Block;
@ -34,6 +37,7 @@ public class TapeMeasure extends SimpleSlimefunItem<ItemUseHandler> implements N
private final NamespacedKey key = new NamespacedKey(SlimefunPlugin.instance(), "anchor"); private final NamespacedKey key = new NamespacedKey(SlimefunPlugin.instance(), "anchor");
private final DecimalFormat format = new DecimalFormat("##.###"); private final DecimalFormat format = new DecimalFormat("##.###");
@ParametersAreNonnullByDefault
public TapeMeasure(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { public TapeMeasure(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(category, item, recipeType, recipe); super(category, item, recipeType, recipe);
} }
@ -56,6 +60,7 @@ public class TapeMeasure extends SimpleSlimefunItem<ItemUseHandler> implements N
}; };
} }
@ParametersAreNonnullByDefault
private void setAnchor(Player p, ItemStack item, Block block) { private void setAnchor(Player p, ItemStack item, Block block) {
ItemMeta meta = item.getItemMeta(); ItemMeta meta = item.getItemMeta();
@ -74,6 +79,8 @@ public class TapeMeasure extends SimpleSlimefunItem<ItemUseHandler> implements N
} }
@Nonnull
@ParametersAreNonnullByDefault
private Optional<Location> getAnchor(Player p, ItemStack item) { private Optional<Location> getAnchor(Player p, ItemStack item) {
ItemMeta meta = item.getItemMeta(); ItemMeta meta = item.getItemMeta();
@ -102,6 +109,7 @@ public class TapeMeasure extends SimpleSlimefunItem<ItemUseHandler> implements N
} }
} }
@ParametersAreNonnullByDefault
private void measure(Player p, ItemStack item, Block block) { private void measure(Player p, ItemStack item, Block block) {
Optional<Location> anchor = getAnchor(p, item); Optional<Location> anchor = getAnchor(p, item);

View File

@ -155,7 +155,7 @@ public class AncientAltarListener implements Listener {
UUID uuid = entity.getUniqueId(); UUID uuid = entity.getUniqueId();
removedItems.add(uuid); removedItems.add(uuid);
Slimefun.runSync(() -> removedItems.remove(uuid), 30L); SlimefunPlugin.runSync(() -> removedItems.remove(uuid), 30L);
entity.remove(); entity.remove();
p.getInventory().addItem(pedestalItem.getOriginalItemStack(entity)); p.getInventory().addItem(pedestalItem.getOriginalItemStack(entity));
@ -228,7 +228,7 @@ public class AncientAltarListener implements Listener {
b.getWorld().playSound(b.getLocation(), Sound.ENTITY_ILLUSIONER_PREPARE_MIRROR, 1, 1); b.getWorld().playSound(b.getLocation(), Sound.ENTITY_ILLUSIONER_PREPARE_MIRROR, 1, 1);
AncientAltarTask task = new AncientAltarTask(this, b, altarItem.getSpeed(), result.get(), pedestals, consumed, p); AncientAltarTask task = new AncientAltarTask(this, b, altarItem.getSpeed(), result.get(), pedestals, consumed, p);
Slimefun.runSync(task, 10L); SlimefunPlugin.runSync(task, 10L);
} }
else { else {
altars.remove(b); altars.remove(b);

View File

@ -32,6 +32,7 @@ import me.mrCookieSlime.Slimefun.api.BlockStorage;
* @author VoidAngel * @author VoidAngel
* @author Poslovitch * @author Poslovitch
* @author TheBusyBiscuit * @author TheBusyBiscuit
* @author AccelShark
* *
*/ */
public class BlockPhysicsListener implements Listener { public class BlockPhysicsListener implements Listener {
@ -54,21 +55,29 @@ public class BlockPhysicsListener implements Listener {
@EventHandler @EventHandler
public void onPistonExtend(BlockPistonExtendEvent e) { public void onPistonExtend(BlockPistonExtendEvent e) {
if (BlockStorage.hasBlockInfo(e.getBlock())) {
e.setCancelled(true);
}
else {
for (Block b : e.getBlocks()) { for (Block b : e.getBlocks()) {
if (BlockStorage.hasBlockInfo(b) || (b.getRelative(e.getDirection()).getType() == Material.AIR && BlockStorage.hasBlockInfo(b.getRelative(e.getDirection())))) { if (BlockStorage.hasBlockInfo(b) || (b.getRelative(e.getDirection()).getType() == Material.AIR && BlockStorage.hasBlockInfo(b.getRelative(e.getDirection())))) {
e.setCancelled(true); e.setCancelled(true);
return; break;
}
} }
} }
} }
@EventHandler @EventHandler
public void onPistonRetract(BlockPistonRetractEvent e) { public void onPistonRetract(BlockPistonRetractEvent e) {
if (e.isSticky()) { if (BlockStorage.hasBlockInfo(e.getBlock())) {
e.setCancelled(true);
}
else if (e.isSticky()) {
for (Block b : e.getBlocks()) { for (Block b : e.getBlocks()) {
if (BlockStorage.hasBlockInfo(b) || (b.getRelative(e.getDirection()).getType() == Material.AIR && BlockStorage.hasBlockInfo(b.getRelative(e.getDirection())))) { if (BlockStorage.hasBlockInfo(b) || (b.getRelative(e.getDirection()).getType() == Material.AIR && BlockStorage.hasBlockInfo(b.getRelative(e.getDirection())))) {
e.setCancelled(true); e.setCancelled(true);
return; break;
} }
} }
} }

View File

@ -23,7 +23,6 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.items.androids.AndroidInstance; import io.github.thebusybiscuit.slimefun4.implementation.items.androids.AndroidInstance;
import io.github.thebusybiscuit.slimefun4.implementation.items.androids.ButcherAndroid; import io.github.thebusybiscuit.slimefun4.implementation.items.androids.ButcherAndroid;
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
import me.mrCookieSlime.Slimefun.api.Slimefun;
/** /**
* This {@link Listener} handles the collection of drops from an {@link Entity} that was * This {@link Listener} handles the collection of drops from an {@link Entity} that was
@ -45,7 +44,7 @@ public class ButcherAndroidListener implements Listener {
if (e.getEntity().hasMetadata(METADATA_KEY)) { if (e.getEntity().hasMetadata(METADATA_KEY)) {
AndroidInstance obj = (AndroidInstance) e.getEntity().getMetadata(METADATA_KEY).get(0).value(); AndroidInstance obj = (AndroidInstance) e.getEntity().getMetadata(METADATA_KEY).get(0).value();
Slimefun.runSync(() -> { SlimefunPlugin.runSync(() -> {
List<ItemStack> items = new ArrayList<>(); List<ItemStack> items = new ArrayList<>();
// Collect any nearby dropped items // Collect any nearby dropped items

View File

@ -23,8 +23,10 @@ import io.github.thebusybiscuit.slimefun4.implementation.items.food.Juice;
import me.mrCookieSlime.Slimefun.api.Slimefun; import me.mrCookieSlime.Slimefun.api.Slimefun;
/** /**
* This {@link Listener} listens for a {@link FoodLevelChangeEvent} or an {@link EntityDamageEvent} for starvation damage * This {@link Listener} listens for a {@link FoodLevelChangeEvent} or an {@link EntityDamageEvent} for starvation
* and consumes a {@link Juice} from any {@link Cooler} that can be found in the {@link Inventory} of the given {@link Player}. * damage
* and consumes a {@link Juice} from any {@link Cooler} that can be found in the {@link Inventory} of the given
* {@link Player}.
* *
* @author TheBusyBiscuit * @author TheBusyBiscuit
* @author Linox * @author Linox
@ -92,7 +94,7 @@ public class CoolerListener implements Listener {
private void takeJuiceFromCooler(@Nonnull Player p, @Nonnull ItemStack cooler) { private void takeJuiceFromCooler(@Nonnull Player p, @Nonnull ItemStack cooler) {
PlayerProfile.getBackpack(cooler, backpack -> { PlayerProfile.getBackpack(cooler, backpack -> {
if (backpack != null) { if (backpack != null) {
Slimefun.runSync(() -> consumeJuice(p, backpack)); SlimefunPlugin.runSync(() -> consumeJuice(p, backpack));
} }
}); });
} }

View File

@ -15,13 +15,14 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
final class GrapplingHookEntity { final class GrapplingHookEntity {
private final boolean dropItem; private final boolean dropItem;
private final boolean wasConsumed;
private final Arrow arrow; private final Arrow arrow;
private final Entity leashTarget; private final Entity leashTarget;
@ParametersAreNonnullByDefault @ParametersAreNonnullByDefault
GrapplingHookEntity(Player p, Arrow arrow, Entity leashTarget, boolean dropItem) { GrapplingHookEntity(Player p, Arrow arrow, Entity leashTarget, boolean dropItem, boolean wasConsumed) {
this.arrow = arrow; this.arrow = arrow;
this.wasConsumed = wasConsumed;
this.leashTarget = leashTarget; this.leashTarget = leashTarget;
this.dropItem = p.getGameMode() != GameMode.CREATIVE && dropItem; this.dropItem = p.getGameMode() != GameMode.CREATIVE && dropItem;
} }
@ -33,10 +34,13 @@ final class GrapplingHookEntity {
public void drop(@Nonnull Location l) { public void drop(@Nonnull Location l) {
if (dropItem) { if (dropItem) {
//If a grappling hook was consumed, then the below if statement will be executed and will drop one grappling hook on the floor
if (wasConsumed) {
Item item = l.getWorld().dropItem(l, SlimefunItems.GRAPPLING_HOOK.clone()); Item item = l.getWorld().dropItem(l, SlimefunItems.GRAPPLING_HOOK.clone());
item.setPickupDelay(16); item.setPickupDelay(16);
} }
} }
}
public void remove() { public void remove() {
if (arrow.isValid()) { if (arrow.isValid()) {

View File

@ -10,6 +10,7 @@ import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault; import javax.annotation.ParametersAreNonnullByDefault;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.entity.Arrow; import org.bukkit.entity.Arrow;
import org.bukkit.entity.Bat; import org.bukkit.entity.Bat;
@ -24,11 +25,12 @@ import org.bukkit.event.entity.ProjectileHitEvent;
import org.bukkit.event.hanging.HangingBreakByEntityEvent; import org.bukkit.event.hanging.HangingBreakByEntityEvent;
import org.bukkit.event.player.PlayerKickEvent; import org.bukkit.event.player.PlayerKickEvent;
import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.entity.PlayerLeashEntityEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.items.tools.GrapplingHook; import io.github.thebusybiscuit.slimefun4.implementation.items.tools.GrapplingHook;
import me.mrCookieSlime.Slimefun.api.Slimefun;
/** /**
* This {@link Listener} is responsible for the mechanics behind the {@link GrapplingHook}. * This {@link Listener} is responsible for the mechanics behind the {@link GrapplingHook}.
@ -74,7 +76,7 @@ public class GrapplingHookListener implements Listener {
return; return;
} }
Slimefun.runSync(() -> { SlimefunPlugin.runSync(() -> {
if (e.getEntity() instanceof Arrow) { if (e.getEntity() instanceof Arrow) {
handleGrapplingHook((Arrow) e.getEntity()); handleGrapplingHook((Arrow) e.getEntity());
} }
@ -137,6 +139,23 @@ public class GrapplingHookListener implements Listener {
} }
} }
// Fixing Issue #2351
@EventHandler
public void onLeash(PlayerLeashEntityEvent e) {
if (!isEnabled()) {
return;
}
Player p = e.getPlayer();
ItemStack item = p.getInventory().getItemInMainHand();
SlimefunItem slimeItem = SlimefunItem.getByItem(item);
if (slimeItem instanceof GrapplingHook) {
e.setCancelled(true);
}
}
private void handleGrapplingHook(@Nullable Arrow arrow) { private void handleGrapplingHook(@Nullable Arrow arrow) {
if (arrow != null && arrow.isValid() && arrow.getShooter() instanceof Player) { if (arrow != null && arrow.isValid() && arrow.getShooter() instanceof Player) {
Player p = (Player) arrow.getShooter(); Player p = (Player) arrow.getShooter();
@ -174,7 +193,7 @@ public class GrapplingHookListener implements Listener {
p.setVelocity(velocity); p.setVelocity(velocity);
hook.remove(); hook.remove();
Slimefun.runSync(() -> activeHooks.remove(p.getUniqueId()), 20L); SlimefunPlugin.runSync(() -> activeHooks.remove(p.getUniqueId()), 20L);
} }
} }
} }
@ -184,21 +203,21 @@ public class GrapplingHookListener implements Listener {
} }
@ParametersAreNonnullByDefault @ParametersAreNonnullByDefault
public void addGrapplingHook(Player p, Arrow arrow, Bat bat, boolean dropItem, long despawnTicks) { public void addGrapplingHook(Player p, Arrow arrow, Bat bat, boolean dropItem, long despawnTicks, boolean wasConsumed) {
GrapplingHookEntity hook = new GrapplingHookEntity(p, arrow, bat, dropItem); GrapplingHookEntity hook = new GrapplingHookEntity(p, arrow, bat, dropItem, wasConsumed);
UUID uuid = p.getUniqueId(); UUID uuid = p.getUniqueId();
activeHooks.put(uuid, hook); activeHooks.put(uuid, hook);
// To fix issue #253 // To fix issue #253
Slimefun.runSync(() -> { SlimefunPlugin.runSync(() -> {
GrapplingHookEntity entity = activeHooks.get(uuid); GrapplingHookEntity entity = activeHooks.get(uuid);
if (entity != null) { if (entity != null) {
SlimefunPlugin.getBowListener().getProjectileData().remove(uuid); SlimefunPlugin.getBowListener().getProjectileData().remove(uuid);
entity.remove(); entity.remove();
Slimefun.runSync(() -> { SlimefunPlugin.runSync(() -> {
activeHooks.remove(uuid); activeHooks.remove(uuid);
invulnerability.remove(uuid); invulnerability.remove(uuid);
}, 20L); }, 20L);

View File

@ -21,7 +21,6 @@ import io.github.thebusybiscuit.slimefun4.core.handlers.BowShootHandler;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.items.weapons.SlimefunBow; import io.github.thebusybiscuit.slimefun4.implementation.items.weapons.SlimefunBow;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.api.Slimefun;
/** /**
* This {@link Listener} is responsible for tracking {@link Arrow Arrows} fired from a * This {@link Listener} is responsible for tracking {@link Arrow Arrows} fired from a
@ -64,7 +63,7 @@ public class SlimefunBowListener implements Listener {
@EventHandler @EventHandler
public void onArrowHit(ProjectileHitEvent e) { public void onArrowHit(ProjectileHitEvent e) {
Slimefun.runSync(() -> { SlimefunPlugin.runSync(() -> {
if (e.getEntity().isValid() && e.getEntity() instanceof Arrow) { if (e.getEntity().isValid() && e.getEntity() instanceof Arrow) {
projectiles.remove(e.getEntity().getUniqueId()); projectiles.remove(e.getEntity().getUniqueId());
} }

View File

@ -3,6 +3,7 @@ package io.github.thebusybiscuit.slimefun4.implementation.listeners;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.ParametersAreNonnullByDefault; import javax.annotation.ParametersAreNonnullByDefault;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.Event.Result; import org.bukkit.event.Event.Result;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
@ -11,6 +12,7 @@ import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.slimefun4.api.events.SlimefunGuideOpenEvent;
import io.github.thebusybiscuit.slimefun4.api.events.PlayerRightClickEvent; import io.github.thebusybiscuit.slimefun4.api.events.PlayerRightClickEvent;
import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuide; import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuide;
import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideLayout; import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideLayout;
@ -45,23 +47,23 @@ public class SlimefunGuideListener implements Listener {
public void onInteract(PlayerRightClickEvent e) { public void onInteract(PlayerRightClickEvent e) {
Player p = e.getPlayer(); Player p = e.getPlayer();
if (openGuide(e, SlimefunGuideLayout.BOOK) == Result.ALLOW) { if (tryOpenGuide(p, e, SlimefunGuideLayout.BOOK) == Result.ALLOW) {
if (p.isSneaking()) { if (p.isSneaking()) {
SlimefunGuideSettings.openSettings(p, e.getItem()); SlimefunGuideSettings.openSettings(p, e.getItem());
} }
else { else {
SlimefunGuide.openGuide(p, SlimefunGuideLayout.BOOK); openGuide(p, e, SlimefunGuideLayout.BOOK);
} }
} }
else if (openGuide(e, SlimefunGuideLayout.CHEST) == Result.ALLOW) { else if (tryOpenGuide(p, e, SlimefunGuideLayout.CHEST) == Result.ALLOW) {
if (p.isSneaking()) { if (p.isSneaking()) {
SlimefunGuideSettings.openSettings(p, e.getItem()); SlimefunGuideSettings.openSettings(p, e.getItem());
} }
else { else {
SlimefunGuide.openGuide(p, SlimefunGuideLayout.CHEST); openGuide(p, e, SlimefunGuideLayout.CHEST);
} }
} }
else if (openGuide(e, SlimefunGuideLayout.CHEAT_SHEET) == Result.ALLOW) { else if (tryOpenGuide(p, e, SlimefunGuideLayout.CHEAT_SHEET) == Result.ALLOW) {
if (p.isSneaking()) { if (p.isSneaking()) {
SlimefunGuideSettings.openSettings(p, e.getItem()); SlimefunGuideSettings.openSettings(p, e.getItem());
} }
@ -73,14 +75,22 @@ public class SlimefunGuideListener implements Listener {
} }
} }
@ParametersAreNonnullByDefault
private void openGuide(Player p, PlayerRightClickEvent e, SlimefunGuideLayout layout) {
SlimefunGuideOpenEvent event = new SlimefunGuideOpenEvent(p, e.getItem(), layout);
Bukkit.getPluginManager().callEvent(event);
if (!event.isCancelled()) {
e.cancel();
SlimefunGuide.openGuide(p, event.getGuideLayout());
}
}
@Nonnull @Nonnull
@ParametersAreNonnullByDefault @ParametersAreNonnullByDefault
private Result openGuide(PlayerRightClickEvent e, SlimefunGuideLayout layout) { private Result tryOpenGuide(Player p, PlayerRightClickEvent e, SlimefunGuideLayout layout) {
Player p = e.getPlayer();
ItemStack item = e.getItem(); ItemStack item = e.getItem();
if (SlimefunUtils.isItemSimilar(item, SlimefunGuide.getItem(layout), true, false)) { if (SlimefunUtils.isItemSimilar(item, SlimefunGuide.getItem(layout), true, false)) {
e.cancel();
if (!SlimefunPlugin.getWorldSettingsService().isWorldEnabled(p.getWorld())) { if (!SlimefunPlugin.getWorldSettingsService().isWorldEnabled(p.getWorld())) {
SlimefunPlugin.getLocalization().sendMessage(p, "messages.disabled-item", true); SlimefunPlugin.getLocalization().sendMessage(p, "messages.disabled-item", true);

View File

@ -24,6 +24,7 @@ import org.bukkit.entity.Trident;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockDropItemEvent; import org.bukkit.event.block.BlockDropItemEvent;
import org.bukkit.event.enchantment.EnchantItemEvent; import org.bukkit.event.enchantment.EnchantItemEvent;
import org.bukkit.event.entity.EntityDamageByEntityEvent; import org.bukkit.event.entity.EntityDamageByEntityEvent;
@ -45,7 +46,6 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.items.magical.talismans.MagicianTalisman; import io.github.thebusybiscuit.slimefun4.implementation.items.magical.talismans.MagicianTalisman;
import io.github.thebusybiscuit.slimefun4.implementation.items.magical.talismans.Talisman; import io.github.thebusybiscuit.slimefun4.implementation.items.magical.talismans.Talisman;
import io.github.thebusybiscuit.slimefun4.implementation.items.magical.talismans.TalismanEnchantment; import io.github.thebusybiscuit.slimefun4.implementation.items.magical.talismans.TalismanEnchantment;
import me.mrCookieSlime.Slimefun.api.Slimefun;
public class TalismanListener implements Listener { public class TalismanListener implements Listener {
@ -216,7 +216,7 @@ public class TalismanListener implements Listener {
int itemSlot = slot; int itemSlot = slot;
// Update the item forcefully // Update the item forcefully
Slimefun.runSync(() -> inv.setItem(itemSlot, item), 1L); SlimefunPlugin.runSync(() -> inv.setItem(itemSlot, item), 1L);
} }
} }
@ -285,6 +285,13 @@ public class TalismanListener implements Listener {
} }
} }
@EventHandler
public void onBlockBreak(BlockBreakEvent e) {
if (e.getBlock().getType().name().endsWith("_ORE")) {
Talisman.checkFor(e, SlimefunItems.TALISMAN_CAVEMAN);
}
}
private int getAmountWithFortune(@Nonnull Material type, int fortuneLevel) { private int getAmountWithFortune(@Nonnull Material type, int fortuneLevel) {
if (fortuneLevel > 0) { if (fortuneLevel > 0) {
Random random = ThreadLocalRandom.current(); Random random = ThreadLocalRandom.current();

View File

@ -41,8 +41,7 @@ public class VanillaMachinesListener implements Listener {
@EventHandler(ignoreCancelled = true) @EventHandler(ignoreCancelled = true)
public void onGrindstone(InventoryClickEvent e) { public void onGrindstone(InventoryClickEvent e) {
// The Grindstone was only ever added in MC 1.14 // The Grindstone was only ever added in MC 1.14
MinecraftVersion minecraftVersion = SlimefunPlugin.getMinecraftVersion(); if (!SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_14)) {
if (!minecraftVersion.isAtLeast(MinecraftVersion.MINECRAFT_1_14)) {
return; return;
} }
@ -97,6 +96,24 @@ public class VanillaMachinesListener implements Listener {
} }
} }
@EventHandler(ignoreCancelled = true)
public void onCartographyTable(InventoryClickEvent e) {
// The Cartography Table was only ever added in MC 1.14
if (!SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_14)) {
return;
}
if (e.getRawSlot() == 2 && e.getInventory().getType() == InventoryType.CARTOGRAPHY && e.getWhoClicked() instanceof Player) {
ItemStack item1 = e.getInventory().getContents()[0];
ItemStack item2 = e.getInventory().getContents()[1];
if (checkForUnallowedItems(item1, item2)) {
e.setResult(Result.DENY);
SlimefunPlugin.getLocalization().sendMessage((Player) e.getWhoClicked(), "cartography_table.not-working", true);
}
}
}
@EventHandler(ignoreCancelled = true) @EventHandler(ignoreCancelled = true)
public void onPreBrew(InventoryClickEvent e) { public void onPreBrew(InventoryClickEvent e) {
Inventory clickedInventory = e.getClickedInventory(); Inventory clickedInventory = e.getClickedInventory();

View File

@ -104,7 +104,7 @@ public final class PostSetup {
sender.sendMessage(ChatColor.GREEN + " - Wiki: https://github.com/Slimefun/Slimefun4/wiki"); sender.sendMessage(ChatColor.GREEN + " - Wiki: https://github.com/Slimefun/Slimefun4/wiki");
sender.sendMessage(ChatColor.GREEN + " - Addons: https://github.com/Slimefun/Slimefun4/wiki/Addons"); sender.sendMessage(ChatColor.GREEN + " - Addons: https://github.com/Slimefun/Slimefun4/wiki/Addons");
sender.sendMessage(ChatColor.GREEN + " - Bug Reports: https://github.com/Slimefun/Slimefun4/issues"); sender.sendMessage(ChatColor.GREEN + " - Bug Reports: https://github.com/Slimefun/Slimefun4/issues");
sender.sendMessage(ChatColor.GREEN + " - Discord: https://discord.gg/fsD4Bkh"); sender.sendMessage(ChatColor.GREEN + " - Discord: https://discord.gg/slimefun");
} }
else { else {
sender.sendMessage(ChatColor.GREEN + " - UNOFFICIALLY MODIFIED BUILD - NO OFFICIAL SUPPORT GIVEN"); sender.sendMessage(ChatColor.GREEN + " - UNOFFICIALLY MODIFIED BUILD - NO OFFICIAL SUPPORT GIVEN");

View File

@ -275,7 +275,8 @@ public final class ResearchSetup {
register("villager_rune", 264, "Reset Villager Trades", 26, SlimefunItems.VILLAGER_RUNE, SlimefunItems.STRANGE_NETHER_GOO); register("villager_rune", 264, "Reset Villager Trades", 26, SlimefunItems.VILLAGER_RUNE, SlimefunItems.STRANGE_NETHER_GOO);
register("climbing_pick", 265, "Block Raider", 20, SlimefunItems.CLIMBING_PICK); register("climbing_pick", 265, "Block Raider", 20, SlimefunItems.CLIMBING_PICK);
register("even_higher_tier_capacitors", 266, "Tier 3 Capacitors", 40, SlimefunItems.ENERGIZED_CAPACITOR); register("even_higher_tier_capacitors", 266, "Tier 3 Capacitors", 40, SlimefunItems.ENERGIZED_CAPACITOR);
register("bee_armor", 267, "Bee Armor", 24, SlimefunItems.BEE_HELMET, SlimefunItems.BEE_WINGS, SlimefunItems.BEE_LEGGINGS, SlimefunItems.BEE_BOOTS); register("caveman_talisman", 267, "Talisman of the Caveman", 20, SlimefunItems.TALISMAN_CAVEMAN);
register("bee_armor", 268, "Bee Armor", 24, SlimefunItems.BEE_HELMET, SlimefunItems.BEE_WINGS, SlimefunItems.BEE_LEGGINGS, SlimefunItems.BEE_BOOTS);
} }
private static void register(String key, int id, String name, int defaultCost, ItemStack... items) { private static void register(String key, int id, String name, int defaultCost, ItemStack... items) {

View File

@ -872,6 +872,11 @@ public final class SlimefunItemSetup {
"knight", 30, new PotionEffect(PotionEffectType.REGENERATION, 100, 3)) "knight", 30, new PotionEffect(PotionEffectType.REGENERATION, 100, 3))
.register(plugin); .register(plugin);
new Talisman(SlimefunItems.TALISMAN_CAVEMAN,
new ItemStack[] { SlimefunItems.MAGIC_LUMP_3, null, SlimefunItems.MAGIC_LUMP_3, new ItemStack(Material.GOLDEN_PICKAXE), SlimefunItems.TALISMAN_MINER, SlimefunItems.EARTH_RUNE, SlimefunItems.MAGIC_LUMP_3, null, SlimefunItems.MAGIC_LUMP_3},
false, false, "caveman", 50, new PotionEffect(PotionEffectType.FAST_DIGGING, 800, 2))
.register(plugin);
new SlimefunItem(categories.resources, SlimefunItems.GILDED_IRON, RecipeType.SMELTERY, new SlimefunItem(categories.resources, SlimefunItems.GILDED_IRON, RecipeType.SMELTERY,
new ItemStack[] {SlimefunItems.GOLD_24K, SlimefunItems.IRON_DUST, null, null, null, null, null, null, null}) new ItemStack[] {SlimefunItems.GOLD_24K, SlimefunItems.IRON_DUST, null, null, null, null, null, null, null})
.register(plugin); .register(plugin);
@ -1120,7 +1125,7 @@ public final class SlimefunItemSetup {
new ItemStack[] {SlimefunItems.COBALT_INGOT, SlimefunItems.COBALT_INGOT, SlimefunItems.COBALT_INGOT, null, SlimefunItems.NICKEL_INGOT, null, null, SlimefunItems.NICKEL_INGOT, null}) new ItemStack[] {SlimefunItems.COBALT_INGOT, SlimefunItems.COBALT_INGOT, SlimefunItems.COBALT_INGOT, null, SlimefunItems.NICKEL_INGOT, null, null, SlimefunItems.NICKEL_INGOT, null})
.register(plugin); .register(plugin);
new SlimefunItem(categories.magicalResources, SlimefunItems.NECROTIC_SKULL, RecipeType.MAGIC_WORKBENCH, new UnplaceableBlock(categories.magicalResources, SlimefunItems.NECROTIC_SKULL, RecipeType.MAGIC_WORKBENCH,
new ItemStack[] {SlimefunItems.MAGIC_LUMP_3, null, SlimefunItems.MAGIC_LUMP_3, null, new ItemStack(Material.WITHER_SKELETON_SKULL), null, SlimefunItems.MAGIC_LUMP_3, null, SlimefunItems.MAGIC_LUMP_3}) new ItemStack[] {SlimefunItems.MAGIC_LUMP_3, null, SlimefunItems.MAGIC_LUMP_3, null, new ItemStack(Material.WITHER_SKELETON_SKULL), null, SlimefunItems.MAGIC_LUMP_3, null, SlimefunItems.MAGIC_LUMP_3})
.register(plugin); .register(plugin);

View File

@ -27,7 +27,6 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.items.altar.AncientAltar; import io.github.thebusybiscuit.slimefun4.implementation.items.altar.AncientAltar;
import io.github.thebusybiscuit.slimefun4.implementation.items.altar.AncientPedestal; import io.github.thebusybiscuit.slimefun4.implementation.items.altar.AncientPedestal;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.AncientAltarListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.AncientAltarListener;
import me.mrCookieSlime.Slimefun.api.Slimefun;
/** /**
* The {@link AncientAltarTask} is responsible for the animation that happens when a ritual * The {@link AncientAltarTask} is responsible for the animation that happens when a ritual
@ -103,7 +102,7 @@ public class AncientAltarTask implements Runnable {
} }
this.stage += 1; this.stage += 1;
Slimefun.runSync(this, speed); SlimefunPlugin.runSync(this, speed);
} }
private boolean checkLockedItems() { private boolean checkLockedItems() {

View File

@ -112,7 +112,7 @@ public class ArmorTask implements Runnable {
} }
if (item != null && armorpiece.getItem().isPresent()) { if (item != null && armorpiece.getItem().isPresent()) {
Slimefun.runSync(() -> { SlimefunPlugin.runSync(() -> {
SlimefunArmorPiece slimefunArmor = armorpiece.getItem().get(); SlimefunArmorPiece slimefunArmor = armorpiece.getItem().get();
if (Slimefun.hasUnlocked(p, slimefunArmor, true)) { if (Slimefun.hasUnlocked(p, slimefunArmor, true)) {
@ -172,7 +172,7 @@ public class ArmorTask implements Runnable {
// If the item is enabled in the world, then make radioactivity do its job // If the item is enabled in the world, then make radioactivity do its job
SlimefunPlugin.getLocalization().sendMessage(p, "messages.radiation"); SlimefunPlugin.getLocalization().sendMessage(p, "messages.radiation");
Slimefun.runSync(() -> { SlimefunPlugin.runSync(() -> {
p.addPotionEffects(radiationEffects); p.addPotionEffects(radiationEffects);
// if radiative fire is enabled // if radiative fire is enabled

View File

@ -38,6 +38,9 @@ import me.mrCookieSlime.Slimefun.api.Slimefun;
*/ */
public class TickerTask implements Runnable { public class TickerTask implements Runnable {
// This Map holds all currently actively ticking locations
private final Map<String, Set<Location>> activeTickers = new ConcurrentHashMap<>();
// These are "Queues" of blocks that need to be removed or moved // These are "Queues" of blocks that need to be removed or moved
private final Map<Location, Location> movingQueue = new ConcurrentHashMap<>(); private final Map<Location, Location> movingQueue = new ConcurrentHashMap<>();
private final Map<Location, Boolean> deletionQueue = new ConcurrentHashMap<>(); private final Map<Location, Boolean> deletionQueue = new ConcurrentHashMap<>();
@ -90,8 +93,8 @@ public class TickerTask implements Runnable {
} }
if (!halted) { if (!halted) {
for (String chunk : BlockStorage.getTickingChunks()) { for (Map.Entry<String, Set<Location>> entry : activeTickers.entrySet()) {
tickChunk(tickers, chunk); tickChunk(tickers, entry.getKey(), entry.getValue());
} }
} }
@ -116,9 +119,9 @@ public class TickerTask implements Runnable {
} }
} }
private void tickChunk(@Nonnull Set<BlockTicker> tickers, @Nonnull String chunk) { @ParametersAreNonnullByDefault
private void tickChunk(Set<BlockTicker> tickers, String chunk, Set<Location> locations) {
try { try {
Set<Location> locations = BlockStorage.getTickingLocations(chunk);
String[] components = PatternUtils.SEMICOLON.split(chunk); String[] components = PatternUtils.SEMICOLON.split(chunk);
World world = Bukkit.getWorld(components[0]); World world = Bukkit.getWorld(components[0]);
@ -147,7 +150,7 @@ public class TickerTask implements Runnable {
item.getBlockTicker().update(); item.getBlockTicker().update();
// We are inserting a new timestamp because synchronized // We are inserting a new timestamp because synchronized
// actions are always ran with a 50ms delay (1 game tick) // actions are always ran with a 50ms delay (1 game tick)
Slimefun.runSync(() -> { SlimefunPlugin.runSync(() -> {
Block b = l.getBlock(); Block b = l.getBlock();
tickBlock(l, b, item, data, System.nanoTime()); tickBlock(l, b, item, data, System.nanoTime());
}); });
@ -223,13 +226,24 @@ public class TickerTask implements Runnable {
deletionQueue.put(l, destroy); deletionQueue.put(l, destroy);
} }
/**
* This returns the delay between ticks
*
* @return The tick delay
*/
public int getTickRate() { public int getTickRate() {
return tickRate; return tickRate;
} }
@Override /**
public String toString() { * This method returns the {@link Map} of actively ticking locations according to
return "TickerTask {\n" + " HALTED = " + halted + "\n" + " move = " + movingQueue + "\n" + " delete = " + deletionQueue + "}"; * their chunk id.
*
* @return The {@link Map} of active tickers
*/
@Nonnull
public Map<String, Set<Location>> getActiveTickers() {
return activeTickers;
} }
} }

View File

@ -26,6 +26,9 @@ public final class ChestMenuUtils {
private ChestMenuUtils() {} private ChestMenuUtils() {}
private static final ItemStack UI_BACKGROUND = new SlimefunItemStack("_UI_BACKGROUND", Material.GRAY_STAINED_GLASS_PANE, " "); private static final ItemStack UI_BACKGROUND = new SlimefunItemStack("_UI_BACKGROUND", Material.GRAY_STAINED_GLASS_PANE, " ");
private static final ItemStack INPUT_SLOT = new SlimefunItemStack("_UI_INPUT_SLOT", Material.CYAN_STAINED_GLASS_PANE, " ");
private static final ItemStack OUTPUT_SLOT = new SlimefunItemStack("_UI_OUTPUT_SLOT", Material.ORANGE_STAINED_GLASS_PANE, " ");
private static final ItemStack BACK_BUTTON = new SlimefunItemStack("_UI_BACK", Material.ENCHANTED_BOOK, "&7\u21E6 Back", meta -> meta.addItemFlags(ItemFlag.HIDE_ENCHANTS)); private static final ItemStack BACK_BUTTON = new SlimefunItemStack("_UI_BACK", Material.ENCHANTED_BOOK, "&7\u21E6 Back", meta -> meta.addItemFlags(ItemFlag.HIDE_ENCHANTS));
private static final ItemStack MENU_BUTTON = new SlimefunItemStack("_UI_MENU", Material.COMPARATOR, "&eSettings / Info", "", "&7\u21E8 Click to see more"); private static final ItemStack MENU_BUTTON = new SlimefunItemStack("_UI_MENU", Material.COMPARATOR, "&eSettings / Info", "", "&7\u21E8 Click to see more");
private static final ItemStack SEARCH_BUTTON = new SlimefunItemStack("_UI_SEARCH", Material.NAME_TAG, "&bSearch"); private static final ItemStack SEARCH_BUTTON = new SlimefunItemStack("_UI_SEARCH", Material.NAME_TAG, "&bSearch");
@ -43,6 +46,16 @@ public final class ChestMenuUtils {
return UI_BACKGROUND; return UI_BACKGROUND;
} }
@Nonnull
public static ItemStack getInputSlotTexture() {
return INPUT_SLOT;
}
@Nonnull
public static ItemStack getOutputSlotTexture() {
return OUTPUT_SLOT;
}
@Nonnull @Nonnull
public static MenuClickHandler getEmptyClickHandler() { public static MenuClickHandler getEmptyClickHandler() {
return CLICK_HANDLER; return CLICK_HANDLER;

View File

@ -36,7 +36,6 @@ import io.github.thebusybiscuit.slimefun4.utils.itemstack.ItemStackWrapper;
import me.mrCookieSlime.EmeraldEnchants.EmeraldEnchants; import me.mrCookieSlime.EmeraldEnchants.EmeraldEnchants;
import me.mrCookieSlime.EmeraldEnchants.ItemEnchantment; import me.mrCookieSlime.EmeraldEnchants.ItemEnchantment;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.api.Slimefun;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
/** /**
@ -351,7 +350,7 @@ public final class SlimefunUtils {
Validate.notNull(l, "Cannot update a texture for null"); Validate.notNull(l, "Cannot update a texture for null");
Validate.isTrue(capacity > 0, "Capacity must be greater than zero!"); Validate.isTrue(capacity > 0, "Capacity must be greater than zero!");
Slimefun.runSync(() -> { SlimefunPlugin.runSync(() -> {
Block b = l.getBlock(); Block b = l.getBlock();
if (b.getType() == Material.PLAYER_HEAD || b.getType() == Material.PLAYER_WALL_HEAD) { if (b.getType() == Material.PLAYER_HEAD || b.getType() == Material.PLAYER_WALL_HEAD) {

View File

@ -8,7 +8,7 @@ import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import io.github.thebusybiscuit.cscorelib2.chat.ChatColors; import io.github.thebusybiscuit.cscorelib2.chat.ChatColors;
import me.mrCookieSlime.Slimefun.api.Slimefun; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
public final class ReactorHologram { public final class ReactorHologram {
@ -35,7 +35,7 @@ public final class ReactorHologram {
} }
public static void update(@Nonnull Location l, @Nonnull String name) { public static void update(@Nonnull Location l, @Nonnull String name) {
Slimefun.runSync(() -> { SlimefunPlugin.runSync(() -> {
ArmorStand hologram = getArmorStand(l, true); ArmorStand hologram = getArmorStand(l, true);
if (!hologram.isCustomNameVisible()) { if (!hologram.isCustomNameVisible()) {

View File

@ -10,7 +10,7 @@ import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType; import org.bukkit.entity.EntityType;
import io.github.thebusybiscuit.cscorelib2.chat.ChatColors; import io.github.thebusybiscuit.cscorelib2.chat.ChatColors;
import me.mrCookieSlime.Slimefun.api.Slimefun; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
/** /**
* This utility class provides a few static methods for modifying a simple Text-based Hologram. * This utility class provides a few static methods for modifying a simple Text-based Hologram.
@ -23,14 +23,14 @@ public final class SimpleHologram {
private SimpleHologram() {} private SimpleHologram() {}
public static void update(@Nonnull Block b, @Nonnull String name) { public static void update(@Nonnull Block b, @Nonnull String name) {
Slimefun.runSync(() -> { SlimefunPlugin.runSync(() -> {
ArmorStand hologram = getArmorStand(b, true); ArmorStand hologram = getArmorStand(b, true);
hologram.setCustomName(ChatColors.color(name)); hologram.setCustomName(ChatColors.color(name));
}); });
} }
public static void remove(@Nonnull Block b) { public static void remove(@Nonnull Block b) {
Slimefun.runSync(() -> { SlimefunPlugin.runSync(() -> {
ArmorStand hologram = getArmorStand(b, false); ArmorStand hologram = getArmorStand(b, false);
if (hologram != null) { if (hologram != null) {

View File

@ -5,7 +5,6 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import io.github.thebusybiscuit.slimefun4.api.events.AsyncMachineProcessCompleteEvent;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.block.Block; import org.bukkit.block.Block;
@ -16,6 +15,7 @@ import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.cscorelib2.inventory.InvUtils; import io.github.thebusybiscuit.cscorelib2.inventory.InvUtils;
import io.github.thebusybiscuit.cscorelib2.item.CustomItem; import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
import io.github.thebusybiscuit.slimefun4.api.events.AsyncMachineProcessCompleteEvent;
import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetComponent; import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetComponent;
import io.github.thebusybiscuit.slimefun4.core.networks.energy.EnergyNetComponentType; import io.github.thebusybiscuit.slimefun4.core.networks.energy.EnergyNetComponentType;
import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils; import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils;
@ -77,11 +77,11 @@ public abstract class AContainer extends SlimefunItem implements InventoryBlock,
} }
for (int i : BORDER_IN) { for (int i : BORDER_IN) {
preset.addItem(i, new CustomItem(Material.CYAN_STAINED_GLASS_PANE, " "), ChestMenuUtils.getEmptyClickHandler()); preset.addItem(i, ChestMenuUtils.getInputSlotTexture(), ChestMenuUtils.getEmptyClickHandler());
} }
for (int i : BORDER_OUT) { for (int i : BORDER_OUT) {
preset.addItem(i, new CustomItem(Material.ORANGE_STAINED_GLASS_PANE, " "), ChestMenuUtils.getEmptyClickHandler()); preset.addItem(i, ChestMenuUtils.getOutputSlotTexture(), ChestMenuUtils.getEmptyClickHandler());
} }
preset.addItem(22, new CustomItem(Material.BLACK_STAINED_GLASS_PANE, " "), ChestMenuUtils.getEmptyClickHandler()); preset.addItem(22, new CustomItem(Material.BLACK_STAINED_GLASS_PANE, " "), ChestMenuUtils.getEmptyClickHandler());
@ -253,7 +253,7 @@ public abstract class AContainer extends SlimefunItem implements InventoryBlock,
inv.pushItem(output.clone(), getOutputSlots()); inv.pushItem(output.clone(), getOutputSlots());
} }
Bukkit.getPluginManager().callEvent(new AsyncMachineProcessCompleteEvent(b, getProcessing(b))); Bukkit.getPluginManager().callEvent(new AsyncMachineProcessCompleteEvent(b.getLocation(), AContainer.this, getProcessing(b)));
progress.remove(b); progress.remove(b);
processing.remove(b); processing.remove(b);

View File

@ -3,6 +3,7 @@ package me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.block.Block; import org.bukkit.block.Block;
@ -12,6 +13,7 @@ import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.cscorelib2.item.CustomItem; import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction; import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction;
import io.github.thebusybiscuit.slimefun4.api.events.AsyncGeneratorProcessCompleteEvent;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.AbstractEnergyProvider; import io.github.thebusybiscuit.slimefun4.implementation.items.electric.AbstractEnergyProvider;
@ -86,11 +88,11 @@ public abstract class AGenerator extends AbstractEnergyProvider {
} }
for (int i : border_in) { for (int i : border_in) {
preset.addItem(i, new CustomItem(new ItemStack(Material.CYAN_STAINED_GLASS_PANE), " "), ChestMenuUtils.getEmptyClickHandler()); preset.addItem(i, ChestMenuUtils.getInputSlotTexture(), ChestMenuUtils.getEmptyClickHandler());
} }
for (int i : border_out) { for (int i : border_out) {
preset.addItem(i, new CustomItem(new ItemStack(Material.ORANGE_STAINED_GLASS_PANE), " "), ChestMenuUtils.getEmptyClickHandler()); preset.addItem(i, ChestMenuUtils.getOutputSlotTexture(), ChestMenuUtils.getEmptyClickHandler());
} }
for (int i : getOutputSlots()) { for (int i : getOutputSlots()) {
@ -163,6 +165,8 @@ public abstract class AGenerator extends AbstractEnergyProvider {
inv.replaceExistingItem(22, new CustomItem(Material.BLACK_STAINED_GLASS_PANE, " ")); inv.replaceExistingItem(22, new CustomItem(Material.BLACK_STAINED_GLASS_PANE, " "));
Bukkit.getPluginManager().callEvent(new AsyncGeneratorProcessCompleteEvent(l, AGenerator.this, getProcessing(l)));
progress.remove(l); progress.remove(l);
processing.remove(l); processing.remove(l);
return 0; return 0;

View File

@ -15,6 +15,10 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.World; import org.bukkit.World;
@ -56,11 +60,11 @@ public class BlockStorage {
private static int chunkChanges = 0; private static int chunkChanges = 0;
private int changes = 0; private int changes = 0;
public static BlockStorage getStorage(World world) { public static BlockStorage getStorage(@Nonnull World world) {
return SlimefunPlugin.getRegistry().getWorlds().get(world.getName()); return SlimefunPlugin.getRegistry().getWorlds().get(world.getName());
} }
public static BlockStorage getForcedStorage(World world) { public static BlockStorage getForcedStorage(@Nonnull World world) {
return isWorldRegistered(world.getName()) ? SlimefunPlugin.getRegistry().getWorlds().get(world.getName()) : new BlockStorage(world); return isWorldRegistered(world.getName()) ? SlimefunPlugin.getRegistry().getWorlds().get(world.getName()) : new BlockStorage(world);
} }
@ -196,13 +200,9 @@ public class BlockStorage {
storage.put(l, blockInfo); storage.put(l, blockInfo);
if (SlimefunPlugin.getRegistry().getTickerBlocks().contains(file.getName().replace(".sfb", ""))) { if (SlimefunPlugin.getRegistry().getTickerBlocks().contains(file.getName().replace(".sfb", ""))) {
Set<Location> locations = SlimefunPlugin.getRegistry().getActiveTickers().getOrDefault(chunkString, new HashSet<>()); Map<String, Set<Location>> tickers = SlimefunPlugin.getTickerTask().getActiveTickers();
Set<Location> locations = tickers.computeIfAbsent(chunkString, id -> new HashSet<>());
locations.add(l); locations.add(l);
SlimefunPlugin.getRegistry().getActiveTickers().put(chunkString, locations);
if (!SlimefunPlugin.getRegistry().getActiveChunks().contains(chunkString)) {
SlimefunPlugin.getRegistry().getActiveChunks().add(chunkString);
}
} }
} }
} }
@ -377,22 +377,22 @@ public class BlockStorage {
/** /**
* Retrieves the SlimefunItem's ItemStack from the specified Block. * Retrieves the SlimefunItem's ItemStack from the specified Block.
* If the specified Block is registered in BlockStorage, its data will be erased from it, regardless of the returned * If the specified Block is registered in BlockStorage,
* value. * its data will be erased from it, regardless of the returned value.
* *
* @param block * @param block
* the block to retrieve the ItemStack from * the block to retrieve the ItemStack from
* *
* @return the SlimefunItem's ItemStack corresponding to the block if it has one, otherwise null * @return the SlimefunItem's ItemStack corresponding to the block if it has one, otherwise null
*
* @since 4.0
*/ */
@Nullable
public static ItemStack retrieve(Block block) { public static ItemStack retrieve(Block block) {
if (!hasBlockInfo(block)) { if (!hasBlockInfo(block)) {
return null; return null;
} }
else { else {
SlimefunItem item = SlimefunItem.getByID(getLocationInfo(block.getLocation(), "id")); String id = getLocationInfo(block.getLocation(), "id");
SlimefunItem item = SlimefunItem.getByID(id);
clearBlockInfo(block); clearBlockInfo(block);
if (item == null) { if (item == null) {
@ -404,6 +404,7 @@ public class BlockStorage {
} }
} }
@Nonnull
public static Config getLocationInfo(Location l) { public static Config getLocationInfo(Location l) {
BlockStorage storage = getStorage(l.getWorld()); BlockStorage storage = getStorage(l.getWorld());
@ -415,6 +416,7 @@ public class BlockStorage {
return cfg == null ? emptyBlockData : cfg; return cfg == null ? emptyBlockData : cfg;
} }
@Nonnull
private static Map<String, String> parseJSON(String json) { private static Map<String, String> parseJSON(String json) {
Map<String, String> map = new HashMap<>(); Map<String, String> map = new HashMap<>();
@ -608,22 +610,20 @@ public class BlockStorage {
} }
String chunkString = locationToChunkString(l); String chunkString = locationToChunkString(l);
Map<String, Set<Location>> tickers = SlimefunPlugin.getTickerTask().getActiveTickers();
Set<Location> locations = tickers.get(chunkString);
if (SlimefunPlugin.getRegistry().getActiveTickers().containsKey(chunkString)) { if (locations != null) {
Set<Location> locations = SlimefunPlugin.getRegistry().getActiveTickers().get(chunkString);
locations.remove(l); locations.remove(l);
if (locations.isEmpty()) { if (locations.isEmpty()) {
SlimefunPlugin.getRegistry().getActiveTickers().remove(chunkString); tickers.remove(chunkString);
SlimefunPlugin.getRegistry().getActiveChunks().remove(chunkString);
}
else {
SlimefunPlugin.getRegistry().getActiveTickers().put(chunkString, locations);
} }
} }
} }
} }
@ParametersAreNonnullByDefault
public static void moveBlockInfo(Location from, Location to) { public static void moveBlockInfo(Location from, Location to) {
SlimefunPlugin.getTickerTask().queueMove(from, to); SlimefunPlugin.getTickerTask().queueMove(from, to);
} }
@ -637,6 +637,7 @@ public class BlockStorage {
* @param to * @param to
* The destination {@link Location} * The destination {@link Location}
*/ */
@ParametersAreNonnullByDefault
public static void moveLocationInfoUnsafely(Location from, Location to) { public static void moveLocationInfoUnsafely(Location from, Location to) {
if (!hasBlockInfo(from)) { if (!hasBlockInfo(from)) {
return; return;
@ -657,17 +658,14 @@ public class BlockStorage {
storage.storage.remove(from); storage.storage.remove(from);
String chunkString = locationToChunkString(from); String chunkString = locationToChunkString(from);
Map<String, Set<Location>> tickers = SlimefunPlugin.getTickerTask().getActiveTickers();
Set<Location> locations = tickers.get(chunkString);
if (SlimefunPlugin.getRegistry().getActiveTickers().containsKey(chunkString)) { if (locations != null) {
Set<Location> locations = SlimefunPlugin.getRegistry().getActiveTickers().get(chunkString);
locations.remove(from); locations.remove(from);
if (locations.isEmpty()) { if (locations.isEmpty()) {
SlimefunPlugin.getRegistry().getActiveTickers().remove(chunkString); tickers.remove(chunkString);
SlimefunPlugin.getRegistry().getActiveChunks().remove(chunkString);
}
else {
SlimefunPlugin.getRegistry().getActiveTickers().put(chunkString, locations);
} }
} }
} }
@ -689,10 +687,9 @@ public class BlockStorage {
String chunkString = locationToChunkString(l); String chunkString = locationToChunkString(l);
if (value != null) { if (value != null) {
Set<Location> locations = SlimefunPlugin.getRegistry().getActiveTickers().computeIfAbsent(chunkString, c -> new HashSet<>()); Map<String, Set<Location>> tickers = SlimefunPlugin.getTickerTask().getActiveTickers();
Set<Location> locations = tickers.computeIfAbsent(chunkString, id -> new HashSet<>());
locations.add(l); locations.add(l);
SlimefunPlugin.getRegistry().getActiveChunks().add(chunkString);
} }
} }
} }
@ -754,14 +751,6 @@ public class BlockStorage {
return SlimefunPlugin.getRegistry().getWorlds().containsKey(name); return SlimefunPlugin.getRegistry().getWorlds().containsKey(name);
} }
public static Set<String> getTickingChunks() {
return SlimefunPlugin.getRegistry().getActiveChunks();
}
public static Set<Location> getTickingLocations(String chunk) {
return SlimefunPlugin.getRegistry().getActiveTickers().getOrDefault(chunk, new HashSet<>());
}
public BlockMenu loadInventory(Location l, BlockMenuPreset preset) { public BlockMenu loadInventory(Location l, BlockMenuPreset preset) {
if (preset == null) { if (preset == null) {
return null; return null;
@ -799,7 +788,7 @@ public class BlockStorage {
for (HumanEntity human : new ArrayList<>(menu.toInventory().getViewers())) { for (HumanEntity human : new ArrayList<>(menu.toInventory().getViewers())) {
// Prevents "java.lang.IllegalStateException: Asynchronous entity add!" // Prevents "java.lang.IllegalStateException: Asynchronous entity add!"
// when closing the inventory while holding an item // when closing the inventory while holding an item
Slimefun.runSync(human::closeInventory); SlimefunPlugin.runSync(human::closeInventory);
} }
inventories.get(l).delete(l); inventories.get(l).delete(l);

View File

@ -3,12 +3,11 @@ package me.mrCookieSlime.Slimefun.api;
import java.util.Optional; import java.util.Optional;
import java.util.logging.Logger; import java.util.logging.Logger;
import org.bukkit.Bukkit; import javax.annotation.Nonnull;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.scheduler.BukkitTask;
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
import io.github.thebusybiscuit.slimefun4.api.items.ItemState; import io.github.thebusybiscuit.slimefun4.api.items.ItemState;
import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile; import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
@ -26,6 +25,7 @@ public final class Slimefun {
private Slimefun() {} private Slimefun() {}
@Nonnull
public static Logger getLogger() { public static Logger getLogger() {
return SlimefunPlugin.instance().getLogger(); return SlimefunPlugin.instance().getLogger();
} }
@ -180,30 +180,4 @@ public final class Slimefun {
} }
return true; return true;
} }
public static BukkitTask runSync(Runnable r) {
if (SlimefunPlugin.getMinecraftVersion() == MinecraftVersion.UNIT_TEST) {
r.run();
return null;
}
if (SlimefunPlugin.instance() == null || !SlimefunPlugin.instance().isEnabled()) {
return null;
}
return Bukkit.getScheduler().runTask(SlimefunPlugin.instance(), r);
}
public static BukkitTask runSync(Runnable r, long delay) {
if (SlimefunPlugin.getMinecraftVersion() == MinecraftVersion.UNIT_TEST) {
r.run();
return null;
}
if (SlimefunPlugin.instance() == null || !SlimefunPlugin.instance().isEnabled()) {
return null;
}
return Bukkit.getScheduler().runTaskLater(SlimefunPlugin.instance(), r, delay);
}
} }

View File

@ -33,7 +33,7 @@ import io.github.thebusybiscuit.slimefun4.utils.HeadTexture;
import io.github.thebusybiscuit.slimefun4.utils.PatternUtils; import io.github.thebusybiscuit.slimefun4.utils.PatternUtils;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
public class SlimefunItemStack extends CustomItem implements Cloneable { public class SlimefunItemStack extends CustomItem {
private String id; private String id;
private ImmutableItemMeta immutableMeta; private ImmutableItemMeta immutableMeta;

View File

@ -3,17 +3,20 @@ package me.mrCookieSlime.Slimefun.api.inventory;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.apache.commons.lang.Validate; import org.apache.commons.lang.Validate;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryView; import org.bukkit.inventory.InventoryView;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu; import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.api.Slimefun;
import me.mrCookieSlime.Slimefun.api.item_transport.ItemTransportFlow; import me.mrCookieSlime.Slimefun.api.item_transport.ItemTransportFlow;
public abstract class BlockMenuPreset extends ChestMenu { public abstract class BlockMenuPreset extends ChestMenu {
@ -30,13 +33,15 @@ public abstract class BlockMenuPreset extends ChestMenu {
private ItemManipulationEvent event; private ItemManipulationEvent event;
public BlockMenuPreset(String id, String title) { public BlockMenuPreset(@Nonnull String id, @Nonnull String title) {
this(id, title, false); this(id, title, false);
} }
public BlockMenuPreset(String id, String title, boolean universal) { public BlockMenuPreset(@Nonnull String id, @Nonnull String title, boolean universal) {
super(title); super(title);
Validate.notNull(id, "You need to specify an id!");
this.id = id; this.id = id;
this.inventoryTitle = title; this.inventoryTitle = title;
this.universal = universal; this.universal = universal;
@ -53,15 +58,57 @@ public abstract class BlockMenuPreset extends ChestMenu {
public abstract void init(); public abstract void init();
public abstract boolean canOpen(Block b, Player p); /**
* This method returns whether a given {@link Player} is allowed to open the
* {@link BlockMenu} of that {@link Block}.
* Override this as necessary.
*
* @param b
* The {@link Block} trying to be opened
* @param p
* The {@link Player} who wants to open the {@link BlockMenu}
*
* @return Whether that {@link Player} is allowed
*/
public abstract boolean canOpen(@Nonnull Block b, @Nonnull Player p);
public abstract int[] getSlotsAccessedByItemTransport(ItemTransportFlow flow); public abstract int[] getSlotsAccessedByItemTransport(ItemTransportFlow flow);
/**
* This method is deprecated.
*
* @deprecated Override {@link #onItemStackChange(DirtyChestMenu, int, ItemStack, ItemStack)} instead
*
* @param event
* The event
*/
@Deprecated
public void registerEvent(ItemManipulationEvent event) { public void registerEvent(ItemManipulationEvent event) {
this.event = event; this.event = event;
} }
public void newInstance(BlockMenu menu, Block b) { /**
* This method is called whenever an {@link ItemStack} changes.
* You can override this as necessary if you need to listen to these events
*
* @param menu
* The {@link Inventory} affected by this
* @param slot
* The affected slot
* @param previous
* The {@link ItemStack} in that slot before the operation
* @param next
* The {@link ItemStack} that it changes to
*
* @return The new outcome of this operation
*/
@Nullable
protected ItemStack onItemStackChange(@Nonnull DirtyChestMenu menu, int slot, @Nullable ItemStack previous, @Nullable ItemStack next) {
// Override this as necessary
return next;
}
public void newInstance(@Nonnull BlockMenu menu, @Nonnull Block b) {
// This method can optionally be overridden by implementations // This method can optionally be overridden by implementations
} }
@ -76,7 +123,7 @@ public abstract class BlockMenuPreset extends ChestMenu {
} }
@Override @Override
public ChestMenu addItem(int slot, ItemStack item) { public ChestMenu addItem(int slot, @Nullable ItemStack item) {
checkIfLocked(); checkIfLocked();
occupiedSlots.add(slot); occupiedSlots.add(slot);
@ -89,6 +136,7 @@ public abstract class BlockMenuPreset extends ChestMenu {
return super.addMenuClickHandler(slot, handler); return super.addMenuClickHandler(slot, handler);
} }
@Nonnull
public ChestMenu setSize(int size) { public ChestMenu setSize(int size) {
checkIfLocked(); checkIfLocked();
@ -134,10 +182,12 @@ public abstract class BlockMenuPreset extends ChestMenu {
return universal; return universal;
} }
@Nonnull
public Set<Integer> getPresetSlots() { public Set<Integer> getPresetSlots() {
return occupiedSlots; return occupiedSlots;
} }
@Nonnull
public Set<Integer> getInventorySlots() { public Set<Integer> getInventorySlots() {
Set<Integer> emptySlots = new HashSet<>(); Set<Integer> emptySlots = new HashSet<>();
@ -159,7 +209,7 @@ public abstract class BlockMenuPreset extends ChestMenu {
return emptySlots; return emptySlots;
} }
protected void clone(DirtyChestMenu menu) { protected void clone(@Nonnull DirtyChestMenu menu) {
menu.setPlayerInventoryClickable(true); menu.setPlayerInventoryClickable(true);
for (int slot : occupiedSlots) { for (int slot : occupiedSlots) {
@ -186,10 +236,10 @@ public abstract class BlockMenuPreset extends ChestMenu {
menu.registerEvent(event); menu.registerEvent(event);
} }
public void newInstance(BlockMenu menu, Location l) { public void newInstance(@Nonnull BlockMenu menu, @Nonnull Location l) {
Validate.notNull(l, "Cannot create a new BlockMenu without a Location"); Validate.notNull(l, "Cannot create a new BlockMenu without a Location");
Slimefun.runSync(() -> { SlimefunPlugin.runSync(() -> {
locked = true; locked = true;
try { try {
@ -207,6 +257,8 @@ public abstract class BlockMenuPreset extends ChestMenu {
* *
* @return Our identifier * @return Our identifier
*/ */
@Nonnull
public String getID() { public String getID() {
return id; return id;
} }
@ -216,10 +268,13 @@ public abstract class BlockMenuPreset extends ChestMenu {
* *
* @return The associated {@link SlimefunItem} * @return The associated {@link SlimefunItem}
*/ */
@Nonnull
public SlimefunItem getSlimefunItem() { public SlimefunItem getSlimefunItem() {
return SlimefunItem.getByID(id); return SlimefunItem.getByID(id);
} }
@Nullable
public static BlockMenuPreset getPreset(String id) { public static BlockMenuPreset getPreset(String id) {
return id == null ? null : SlimefunPlugin.getRegistry().getMenuPresets().get(id); return id == null ? null : SlimefunPlugin.getRegistry().getMenuPresets().get(id);
} }

View File

@ -2,6 +2,9 @@ package me.mrCookieSlime.Slimefun.api.inventory;
import java.util.ArrayList; import java.util.ArrayList;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.entity.HumanEntity; import org.bukkit.entity.HumanEntity;
@ -21,7 +24,7 @@ public class DirtyChestMenu extends ChestMenu {
protected ItemManipulationEvent event; protected ItemManipulationEvent event;
protected int changes = 1; protected int changes = 1;
public DirtyChestMenu(BlockMenuPreset preset) { public DirtyChestMenu(@Nonnull BlockMenuPreset preset) {
super(preset.getTitle()); super(preset.getTitle());
this.preset = preset; this.preset = preset;
@ -49,6 +52,7 @@ public class DirtyChestMenu extends ChestMenu {
return changes; return changes;
} }
@Nonnull
public BlockMenuPreset getPreset() { public BlockMenuPreset getPreset() {
return preset; return preset;
} }
@ -63,6 +67,15 @@ public class DirtyChestMenu extends ChestMenu {
} }
} }
/**
* This method has been deprecated.
*
* @deprecated The {@link ItemManipulationEvent} has been deprecated.
*
* @param event
* deprecated class
*/
@Deprecated
public void registerEvent(ItemManipulationEvent event) { public void registerEvent(ItemManipulationEvent event) {
this.event = event; this.event = event;
} }
@ -77,15 +90,23 @@ public class DirtyChestMenu extends ChestMenu {
} }
} }
public boolean fits(ItemStack item, int... slots) { public boolean fits(@Nonnull ItemStack item, int... slots) {
if (getItemInSlot(slots[0]) == null) {
// Very small optimization
return true;
}
else {
return InvUtils.fits(toInventory(), new ItemStackWrapper(item), slots); return InvUtils.fits(toInventory(), new ItemStackWrapper(item), slots);
} }
}
@Nullable
public ItemStack pushItem(ItemStack item, int... slots) { public ItemStack pushItem(ItemStack item, int... slots) {
if (item == null || item.getType() == Material.AIR) { if (item == null || item.getType() == Material.AIR) {
throw new IllegalArgumentException("Cannot push null or AIR"); throw new IllegalArgumentException("Cannot push null or AIR");
} }
ItemStackWrapper wrapper = null;
int amount = item.getAmount(); int amount = item.getAmount();
for (int slot : slots) { for (int slot : slots) {
@ -99,11 +120,17 @@ public class DirtyChestMenu extends ChestMenu {
replaceExistingItem(slot, item); replaceExistingItem(slot, item);
return null; return null;
} }
else if (stack.getAmount() < stack.getMaxStackSize() && ItemUtils.canStack(item, stack)) { else if (stack.getAmount() < stack.getMaxStackSize()) {
if (wrapper == null) {
wrapper = new ItemStackWrapper(item);
}
if (ItemUtils.canStack(wrapper, stack)) {
amount -= (stack.getMaxStackSize() - stack.getAmount()); amount -= (stack.getMaxStackSize() - stack.getAmount());
stack.setAmount(Math.min(stack.getAmount() + item.getAmount(), stack.getMaxStackSize())); stack.setAmount(Math.min(stack.getAmount() + item.getAmount(), stack.getMaxStackSize()));
} }
} }
}
if (amount > 0) { if (amount > 0) {
return new CustomItem(item, amount); return new CustomItem(item, amount);
@ -132,11 +159,16 @@ public class DirtyChestMenu extends ChestMenu {
} }
public void replaceExistingItem(int slot, ItemStack item, boolean event) { public void replaceExistingItem(int slot, ItemStack item, boolean event) {
if (event && this.event != null) { if (event) {
ItemStack previous = getItemInSlot(slot); ItemStack previous = getItemInSlot(slot);
if (this.event != null) {
item = this.event.onEvent(slot, previous, item); item = this.event.onEvent(slot, previous, item);
} }
item = preset.onItemStackChange(this, slot, previous, item);
}
super.replaceExistingItem(slot, item); super.replaceExistingItem(slot, item);
markDirty(); markDirty();
} }

View File

@ -2,6 +2,13 @@ package me.mrCookieSlime.Slimefun.api.inventory;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
/**
* @deprecated Please use {@link BlockMenuPreset#onItemStackChange(DirtyChestMenu, int, ItemStack, ItemStack)} instead.
*
* @author TheBusyBiscuit
*
*/
@Deprecated
@FunctionalInterface @FunctionalInterface
public interface ItemManipulationEvent { public interface ItemManipulationEvent {

View File

@ -151,6 +151,7 @@ messages:
knight: '&a&oYour Talisman gave you 5 Seconds of Regeneration' knight: '&a&oYour Talisman gave you 5 Seconds of Regeneration'
whirlwind: '&a&oYour Talisman reflected the Projectile' whirlwind: '&a&oYour Talisman reflected the Projectile'
wizard: '&a&oYour Talisman has given you a better Fortune Level but maybe also lowered some other Enchantment Levels' wizard: '&a&oYour Talisman has given you a better Fortune Level but maybe also lowered some other Enchantment Levels'
caveman: '&a&oYour Talisman gave you haste'
soulbound-rune: soulbound-rune:
fail: '&cYou can only bind one item to your soul at a time.' fail: '&cYou can only bind one item to your soul at a time.'
@ -259,20 +260,23 @@ machines:
finished: '&eYour Industrial Miner has finished! It obtained a total of %ores% ore(s)!' finished: '&eYour Industrial Miner has finished! It obtained a total of %ores% ore(s)!'
anvil: anvil:
not-working: '&4You cannot use Slimefun Items in an anvil!' not-working: '&4You cannot use Slimefun items in an anvil!'
brewing_stand: brewing_stand:
not-working: '&4You cannot use Slimefun Items in a brewing stand!' not-working: '&4You cannot use Slimefun items in a brewing stand!'
cartography_table:
not-working: '&4You cannot use Slimefun items in a cartography table!'
villagers: villagers:
no-trading: '&4You cannot trade Slimefun Items with Villagers!' no-trading: '&4You cannot trade Slimefun items with Villagers!'
backpack: backpack:
already-open: '&cSorry, this Backpack is open somewhere else!' already-open: '&cSorry, this Backpack is open somewhere else!'
no-stack: '&cYou cannot stack Backpacks' no-stack: '&cYou cannot stack Backpacks'
workbench: workbench:
not-enhanced: '&4You cannot use Slimefun Items in a normal workbench' not-enhanced: '&4You cannot use Slimefun items in a normal workbench'
gps: gps:
deathpoint: '&4Deathpoint &7%date%' deathpoint: '&4Deathpoint &7%date%'

View File

@ -61,6 +61,7 @@ slimefun:
water_talisman: Talisman of the Water Breather water_talisman: Talisman of the Water Breather
angel_talisman: Talisman of the Angel angel_talisman: Talisman of the Angel
fire_talisman: Talisman of the Firefighter fire_talisman: Talisman of the Firefighter
caveman_talisman: Talisman of the Caveman
lava_crystal: Firey Situation lava_crystal: Firey Situation
magician_talisman: Talisman of the Magician magician_talisman: Talisman of the Magician
traveller_talisman: Talisman of the Traveller traveller_talisman: Talisman of the Traveller

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