├── .gitignore
├── LICENSE
├── README.md
├── pom.xml
└── src
└── main
├── java
└── org
│ └── lins
│ └── mmmjjkx
│ └── rykenslimefuncustomizer
│ ├── ProjectAddonManager.java
│ ├── RykenSlimefunCustomizer.java
│ ├── bulit_in
│ └── JavaScriptEval.java
│ ├── commands
│ └── MainCommand.java
│ ├── factories
│ └── SimpleMachineFactory.java
│ ├── libraries
│ ├── colors
│ │ ├── CMIChatColor.java
│ │ ├── CMIColors.java
│ │ └── CMICustomColors.java
│ └── version
│ │ ├── MinecraftPlatform.java
│ │ └── Version.java
│ ├── listeners
│ ├── BlockListener.java
│ ├── ScriptableEventListener.java
│ └── SingleItemRecipeGuideListener.java
│ ├── objects
│ ├── ProjectAddon.java
│ ├── ProjectAddonLoader.java
│ ├── customs
│ │ ├── CustomAddonConfig.java
│ │ ├── CustomMenu.java
│ │ ├── LinkedOutput.java
│ │ ├── item
│ │ │ ├── CustomArmorPiece.java
│ │ │ ├── CustomDefaultItem.java
│ │ │ ├── CustomFood.java
│ │ │ ├── CustomGeoResource.java
│ │ │ ├── CustomUnplaceableItem.java
│ │ │ ├── RSCItemStack.java
│ │ │ └── exts
│ │ │ │ ├── CustomEnergyItem.java
│ │ │ │ ├── CustomMobDrop.java
│ │ │ │ └── CustomRainbowBlock.java
│ │ ├── machine
│ │ │ ├── CustomEnergyGenerator.java
│ │ │ ├── CustomGenerator.java
│ │ │ ├── CustomLinkedRecipeMachine.java
│ │ │ ├── CustomMachine.java
│ │ │ ├── CustomMaterialGenerator.java
│ │ │ ├── CustomMultiBlockMachine.java
│ │ │ ├── CustomNoEnergyMachine.java
│ │ │ ├── CustomRecipeMachine.java
│ │ │ ├── CustomSolarGenerator.java
│ │ │ ├── CustomTemplateMachine.java
│ │ │ ├── CustomWorkbench.java
│ │ │ └── sf
│ │ │ │ ├── AdvancedAnimalGrowthAccelerator.java
│ │ │ │ ├── AdvancedAutoAnvil.java
│ │ │ │ ├── AdvancedAutoBrewer.java
│ │ │ │ ├── AdvancedCropGrowthAccelerator.java
│ │ │ │ ├── AdvancedProduceCollector.java
│ │ │ │ └── AdvancedTreeGrowthAccelerator.java
│ │ └── parent
│ │ │ ├── AbstractEmptyMachine.java
│ │ │ └── CustomItem.java
│ ├── global
│ │ ├── DropFromBlock.java
│ │ └── RecipeTypeMap.java
│ ├── machine
│ │ ├── CustomCraftingOperation.java
│ │ ├── CustomLinkedMachineOperation.java
│ │ ├── CustomLinkedMachineRecipe.java
│ │ ├── CustomMachineRecipe.java
│ │ ├── CustomTemplateCraftingOperation.java
│ │ ├── MachineInfo.java
│ │ ├── MachineRecord.java
│ │ ├── MachineTemplate.java
│ │ ├── ScriptedEvalBreakHandler.java
│ │ ├── SimpleMachineType.java
│ │ └── SmallerMachineInfo.java
│ ├── script
│ │ ├── ScriptEval.java
│ │ ├── ban
│ │ │ └── CommandSafe.java
│ │ ├── enhanced
│ │ │ └── NBTAPIIntegration.java
│ │ └── lambda
│ │ │ ├── CiConsumer.java
│ │ │ ├── CiFunction.java
│ │ │ └── RSCClickHandler.java
│ ├── slimefun
│ │ ├── AdvancedNestedItemGroup.java
│ │ ├── AsyncChanceRecipeTask.java
│ │ ├── ItemGroupButton.java
│ │ └── WitherProofBlockImpl.java
│ └── yaml
│ │ ├── ItemGroupReader.java
│ │ ├── MenuReader.java
│ │ ├── RecipeTypesReader.java
│ │ ├── ResearchReader.java
│ │ ├── YamlReader.java
│ │ ├── item
│ │ ├── ArmorReader.java
│ │ ├── CapacitorsReader.java
│ │ ├── FoodReader.java
│ │ ├── GeoResourceReader.java
│ │ ├── ItemReader.java
│ │ └── MobDropsReader.java
│ │ └── machine
│ │ ├── GeneratorReader.java
│ │ ├── LinkedRecipeMachineReader.java
│ │ ├── MachineReader.java
│ │ ├── MaterialGeneratorReader.java
│ │ ├── MultiBlockMachineReader.java
│ │ ├── RecipeMachineReader.java
│ │ ├── SimpleMachineReader.java
│ │ ├── SolarGeneratorReader.java
│ │ ├── SuperReader.java
│ │ ├── TemplateMachineReader.java
│ │ └── WorkbenchReader.java
│ ├── update
│ ├── GitHubRelease.java
│ └── GithubUpdater.java
│ └── utils
│ ├── BlockMenuUtil.java
│ ├── ClassUtils.java
│ ├── CommonUtils.java
│ ├── Constants.java
│ ├── ExceptionHandler.java
│ ├── ItemUtils.java
│ ├── ReflectionUtils.java
│ └── StackUtils.java
└── resources
├── addons
└── example
│ ├── README.md
│ └── info.yml
├── config.yml
└── plugin.yml
/.gitignore:
--------------------------------------------------------------------------------
1 | # User-specific stuff
2 | .idea/
3 |
4 | *.iml
5 | *.ipr
6 | *.iws
7 |
8 | # IntelliJ
9 | out/
10 |
11 | # Compiled class file
12 | *.class
13 |
14 | # Log file
15 | *.log
16 |
17 | # BlueJ files
18 | *.ctxt
19 |
20 | # Package Files #
21 | *.jar
22 | *.war
23 | *.nar
24 | *.ear
25 | *.zip
26 | *.tar.gz
27 | *.rar
28 |
29 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
30 | hs_err_pid*
31 |
32 | *~
33 |
34 | # temporary files which can be created if a process still has a handle open of a deleted file
35 | .fuse_hidden*
36 |
37 | # KDE directory preferences
38 | .directory
39 |
40 | # Linux trash folder which might appear on any partition or disk
41 | .Trash-*
42 |
43 | # .nfs files are created when an open file is removed but is still being accessed
44 | .nfs*
45 |
46 | # General
47 | .DS_Store
48 | .AppleDouble
49 | .LSOverride
50 |
51 | # Icon must end with two \r
52 | Icon
53 |
54 | # Thumbnails
55 | ._*
56 |
57 | # Files that might appear in the root of a volume
58 | .DocumentRevisions-V100
59 | .fseventsd
60 | .Spotlight-V100
61 | .TemporaryItems
62 | .Trashes
63 | .VolumeIcon.icns
64 | .com.apple.timemachine.donotpresent
65 |
66 | # Directories potentially created on remote AFP share
67 | .AppleDB
68 | .AppleDesktop
69 | Network Trash Folder
70 | Temporary Items
71 | .apdisk
72 |
73 | # Windows thumbnail cache files
74 | Thumbs.db
75 | Thumbs.db:encryptable
76 | ehthumbs.db
77 | ehthumbs_vista.db
78 |
79 | # Dump file
80 | *.stackdump
81 |
82 | # Folder config file
83 | [Dd]esktop.ini
84 |
85 | # Recycle Bin used on file shares
86 | $RECYCLE.BIN/
87 |
88 | # Windows Installer files
89 | *.cab
90 | *.msi
91 | *.msix
92 | *.msm
93 | *.msp
94 |
95 | # Windows shortcuts
96 | *.lnk
97 |
98 | target/
99 |
100 | pom.xml.tag
101 | pom.xml.releaseBackup
102 | pom.xml.versionsBackup
103 | pom.xml.next
104 |
105 | release.properties
106 | dependency-reduced-pom.xml
107 | buildNumber.properties
108 | .mvn/timing.properties
109 | .mvn/wrapper/maven-wrapper.jar
110 | .flattened-pom.xml
111 |
112 | # Common working directory
113 | run/
114 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # RykenSlimeCustomizer
2 |
3 | 一款更高级的粘液自定义附属插件
4 |
5 | Wiki:
6 | QQ群: 811756705
7 |
8 |
9 |
10 | 此附属已完善,基本不会有任何更新!
11 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | org.lins.mmmjjkx
8 | RykenSlimefunCustomizer
9 | 20
10 | jar
11 |
12 | RykenSlimefunCustomizer
13 | An advanced slimefun customize plugin
14 |
15 | 17
16 | UTF-8
17 |
18 |
19 |
20 | clean package
21 |
22 |
23 | org.apache.maven.plugins
24 | maven-compiler-plugin
25 | 3.8.1
26 |
27 | ${java.version}
28 | ${java.version}
29 |
30 |
31 | org.projectlombok
32 | lombok
33 | 1.18.34
34 |
35 |
36 |
37 |
38 |
39 | org.apache.maven.plugins
40 | maven-shade-plugin
41 | 3.4.1
42 |
43 |
44 |
45 | shade
46 |
47 | package
48 |
49 |
50 |
51 |
52 |
53 | net.byteflux.libby
54 | org.lins.mmmjjkx.rykenslimefuncustomizer.libraries.libby
55 |
56 |
57 |
58 |
59 |
60 | com.diffplug.spotless
61 | spotless-maven-plugin
62 | 2.43.0
63 |
64 |
65 |
66 | 2.38.0
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 | src/main/resources
79 | true
80 |
81 | /**/*.zip
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 | central
90 | https://repo1.maven.org/maven2/
91 |
92 |
93 | AlessioDP
94 | https://repo.alessiodp.com/releases/
95 |
96 |
97 | jitpack
98 | https://jitpack.io
99 |
100 |
101 | minebench-repo
102 | https://repo.minebench.de/
103 |
104 |
105 | codemc-repo
106 | https://repo.codemc.org/repository/maven-public/
107 |
108 |
109 | placeholderapi
110 | https://repo.extendedclip.com/content/repositories/placeholderapi/
111 |
112 |
113 | papermc-repo
114 | https://repo.papermc.io/repository/maven-public/
115 |
116 |
117 | sonatype
118 | https://oss.sonatype.org/content/groups/public/
119 |
120 |
121 |
122 |
123 |
124 | net.byteflux
125 | libby-bukkit
126 | 1.3.1
127 |
128 |
129 |
130 | org.graalvm.js
131 | js
132 | 24.1.2
133 | provided
134 | pom
135 |
136 |
137 |
138 | net.guizhanss
139 | GuizhanLibPlugin
140 | 1.7.6
141 | provided
142 |
143 |
144 |
145 | me.clip
146 | placeholderapi
147 | 2.11.5
148 | provided
149 |
150 |
151 |
152 | net.bytebuddy
153 | byte-buddy
154 | 1.14.6
155 | provided
156 |
157 |
158 | io.papermc.paper
159 | paper-api
160 | 1.18.2-R0.1-SNAPSHOT
161 | provided
162 |
163 |
164 | com.github.SlimefunGuguProject
165 | Slimefun4
166 | 2024.3
167 | provided
168 |
169 |
170 | org.projectlombok
171 | lombok
172 | 1.18.34
173 | provided
174 |
175 |
176 | de.tr7zw
177 | item-nbt-api-plugin
178 | 2.14.1
179 | provided
180 |
181 |
182 |
183 |
--------------------------------------------------------------------------------
/src/main/java/org/lins/mmmjjkx/rykenslimefuncustomizer/ProjectAddonManager.java:
--------------------------------------------------------------------------------
1 | package org.lins.mmmjjkx.rykenslimefuncustomizer;
2 |
3 | import io.github.thebusybiscuit.slimefun4.libraries.commons.lang.Validate;
4 | import java.io.File;
5 | import java.util.ArrayList;
6 | import java.util.HashMap;
7 | import java.util.List;
8 | import java.util.Map;
9 | import lombok.Getter;
10 | import org.bukkit.configuration.file.YamlConfiguration;
11 | import org.bukkit.plugin.Plugin;
12 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.ProjectAddon;
13 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.ProjectAddonLoader;
14 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.global.RecipeTypeMap;
15 | import org.lins.mmmjjkx.rykenslimefuncustomizer.utils.Constants;
16 | import org.lins.mmmjjkx.rykenslimefuncustomizer.utils.ExceptionHandler;
17 |
18 | public final class ProjectAddonManager {
19 | public static File ADDONS_DIRECTORY;
20 | public static File CONFIGS_DIRECTORY;
21 |
22 | private final Map projectAddons = new HashMap<>();
23 |
24 | @Getter
25 | private final Map projectIds = new HashMap<>();
26 |
27 | public ProjectAddonManager() {
28 | ADDONS_DIRECTORY = new File(RykenSlimefunCustomizer.INSTANCE.getDataFolder(), "addons");
29 | CONFIGS_DIRECTORY = new File(RykenSlimefunCustomizer.INSTANCE.getDataFolder(), "addon_configs");
30 |
31 | if (!CONFIGS_DIRECTORY.exists()) {
32 | CONFIGS_DIRECTORY.mkdirs();
33 | }
34 | }
35 |
36 | public void pushProjectAddon(ProjectAddon addon) {
37 | Validate.notNull(addon, "addon");
38 | if (!projectAddons.containsKey(addon.getAddonId())) {
39 | projectIds.put(addon.getAddonId(), addon.getFolder());
40 | projectAddons.put(addon.getAddonId(), addon);
41 | }
42 | }
43 |
44 | public void removeProjectAddon(ProjectAddon addon) {
45 | Validate.notNull(addon, "addon");
46 |
47 | projectIds.remove(addon.getAddonId());
48 | projectAddons.remove(addon.getAddonId());
49 | }
50 |
51 | public void setup(Plugin inst) {
52 | File addons = new File(inst.getDataFolder(), "addons");
53 | if (!addons.exists()) {
54 | addons.mkdirs();
55 | return;
56 | }
57 |
58 | File[] folders = addons.listFiles();
59 | if (folders == null) return;
60 |
61 | List skip = new ArrayList<>();
62 |
63 | for (File folder : folders) {
64 | if (folder.isFile()) {
65 | ExceptionHandler.handleError(folder.getName() + " 不是文件夹!无法加载此附属!");
66 | continue;
67 | }
68 |
69 | File info = new File(folder, Constants.INFO_FILE);
70 | if (!info.exists()) {
71 | ExceptionHandler.handleError("在名称为 " + folder.getName() + "的文件夹中有无效的附属信息,导致此附属无法加载!");
72 | skip.add(folder.getName());
73 | continue;
74 | }
75 | YamlConfiguration infoConfig = YamlConfiguration.loadConfiguration(info);
76 | String id = infoConfig.getString("id");
77 | if (id == null || id.isBlank()) {
78 | ExceptionHandler.handleError("在名称为 " + folder.getName() + "的文件夹中有无效的附属ID,导致此附属无法加载!");
79 | skip.add(folder.getName());
80 | continue;
81 | }
82 |
83 | if (projectIds.containsKey(id)) {
84 | ProjectAddon addon = projectAddons.get(id);
85 | if (addon == null) {
86 | ExceptionHandler.handleError("无法正常加载附属 " + id + "!请检查所有附属内容!");
87 | continue;
88 | }
89 |
90 | if (addon.isMarkAsDepend()) {
91 | continue;
92 | }
93 |
94 | ExceptionHandler.handleError("在名称为 " + folder.getName() + "的文件夹中有重复的附属ID,导致此附属无法加载!");
95 | skip.add(folder.getName());
96 | continue;
97 | }
98 |
99 | projectIds.put(id, folder);
100 | }
101 |
102 | for (File folder : folders) {
103 | if (skip.contains(folder.getName())) continue;
104 |
105 | YamlConfiguration infoConfig = YamlConfiguration.loadConfiguration(new File(folder, Constants.INFO_FILE));
106 | String id = infoConfig.getString("id");
107 | if (projectAddons.containsKey(id)) {
108 | continue;
109 | }
110 |
111 | try {
112 | ProjectAddonLoader loader = new ProjectAddonLoader(folder, projectIds);
113 | ProjectAddon addon = loader.load();
114 | if (addon != null) {
115 | projectAddons.put(addon.getAddonId(), addon);
116 | }
117 | } catch (Exception e) {
118 | if (folder.isFile()) {
119 | ExceptionHandler.handleError(folder.getName() + " 不是文件夹!无法加载此附属!");
120 | continue;
121 | }
122 | e.printStackTrace();
123 | }
124 | }
125 | }
126 |
127 | public void reload(Plugin plugin) {
128 | for (ProjectAddon addon : projectAddons.values()) {
129 | addon.unregister();
130 | }
131 |
132 | projectAddons.clear();
133 | projectIds.clear();
134 |
135 | RecipeTypeMap.clearRecipeTypes();
136 |
137 | setup(plugin);
138 | }
139 |
140 | public boolean isLoaded(String id) {
141 | return projectAddons.containsKey(id);
142 | }
143 |
144 | public boolean isLoaded(String... ids) {
145 | for (String id : ids) {
146 | if (!isLoaded(id)) {
147 | return false;
148 | }
149 | }
150 | return true;
151 | }
152 |
153 | public ProjectAddon get(String id) {
154 | return projectAddons.get(id);
155 | }
156 |
157 | public List getAllValues() {
158 | return new ArrayList<>(projectAddons.values());
159 | }
160 |
161 | public File getAddonFolder(String id) {
162 | return projectIds.get(id);
163 | }
164 | }
165 |
--------------------------------------------------------------------------------
/src/main/java/org/lins/mmmjjkx/rykenslimefuncustomizer/bulit_in/JavaScriptEval.java:
--------------------------------------------------------------------------------
1 | package org.lins.mmmjjkx.rykenslimefuncustomizer.bulit_in;
2 |
3 | import com.google.errorprone.annotations.CanIgnoreReturnValue;
4 | import com.oracle.truffle.api.TruffleFile;
5 | import com.oracle.truffle.api.TruffleLanguage;
6 | import com.oracle.truffle.js.lang.JavaScriptLanguage;
7 | import com.oracle.truffle.js.runtime.JSRealm;
8 | import com.oracle.truffle.js.runtime.objects.JSAttributes;
9 | import com.oracle.truffle.js.runtime.objects.JSObject;
10 | import com.oracle.truffle.js.runtime.objects.JSObjectUtil;
11 | import com.xzavier0722.mc.plugin.slimefun4.storage.util.StorageCacheUtils;
12 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem;
13 | import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile;
14 | import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
15 | import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
16 | import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
17 | import java.io.File;
18 | import java.io.IOException;
19 | import java.util.HashSet;
20 | import java.util.Objects;
21 | import java.util.Set;
22 | import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
23 | import org.graalvm.polyglot.*;
24 | import org.graalvm.polyglot.io.IOAccess;
25 | import org.jetbrains.annotations.NotNull;
26 | import org.jetbrains.annotations.Nullable;
27 | import org.lins.mmmjjkx.rykenslimefuncustomizer.RykenSlimefunCustomizer;
28 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.ProjectAddon;
29 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.script.ScriptEval;
30 | import org.lins.mmmjjkx.rykenslimefuncustomizer.utils.BlockMenuUtil;
31 | import org.lins.mmmjjkx.rykenslimefuncustomizer.utils.ExceptionHandler;
32 |
33 | public class JavaScriptEval extends ScriptEval {
34 | private static final File PLUGINS_FOLDER =
35 | RykenSlimefunCustomizer.INSTANCE.getDataFolder().getParentFile();
36 | private final Set failed_functions = new HashSet<>();
37 |
38 | private Context jsEngine;
39 |
40 | public JavaScriptEval(@NotNull File js, ProjectAddon addon) {
41 | super(js, addon);
42 | reSetup();
43 |
44 | setup();
45 |
46 | contextInit();
47 |
48 | addon.getScriptEvals().add(this);
49 | }
50 |
51 | private void advancedSetup() {
52 | JSRealm realm = JavaScriptLanguage.getJSRealm(jsEngine);
53 | TruffleLanguage.Env env = realm.getEnv();
54 | addThing("SlimefunItems", env.asHostSymbol(SlimefunItems.class));
55 | addThing("SlimefunItem", env.asHostSymbol(SlimefunItem.class));
56 | addThing("StorageCacheUtils", env.asHostSymbol(StorageCacheUtils.class));
57 | addThing("SlimefunUtils", env.asHostSymbol(SlimefunUtils.class));
58 | addThing("BlockMenu", env.asHostSymbol(BlockMenu.class));
59 | addThing("BlockMenuUtil", env.asHostSymbol(BlockMenuUtil.class));
60 | addThing("PlayerProfile", env.asHostSymbol(PlayerProfile.class));
61 | addThing("Slimefun", env.asHostSymbol(Slimefun.class));
62 |
63 | for (File file : Objects.requireNonNull(PLUGINS_FOLDER.listFiles())) {
64 | TruffleFile truffleFile = env.getPublicTruffleFile(file.toURI());
65 | if (!truffleFile.isDirectory() && truffleFile.getName().endsWith(".jar")) {
66 | env.addToHostClassPath(truffleFile);
67 | }
68 | }
69 |
70 | JSObject java = JSObjectUtil.createOrdinaryPrototypeObject(realm);
71 | JSObjectUtil.putToStringTag(java, JSRealm.JAVA_CLASS_NAME);
72 |
73 | JSObjectUtil.putDataProperty(realm.getGlobalObject(), "Java", java, JSAttributes.getDefaultNotEnumerable());
74 |
75 | jsEngine.enter();
76 | }
77 |
78 | @Override
79 | public void close() {
80 | try {
81 | jsEngine.leave();
82 | jsEngine.close();
83 | } catch (IllegalStateException ignored) {
84 | }
85 | }
86 |
87 | @Override
88 | public void addThing(String name, Object value) {
89 | jsEngine.getBindings("js").putMember(name, value);
90 | }
91 |
92 | @Override
93 | public String key() {
94 | return "js";
95 | }
96 |
97 | protected final void contextInit() {
98 | super.contextInit();
99 | if (jsEngine != null) {
100 | try {
101 | jsEngine.eval(
102 | Source.newBuilder("js", getFileContext(), "JavaScript").build());
103 | } catch (IOException e) {
104 | e.printStackTrace();
105 | }
106 | }
107 | }
108 |
109 | @Nullable @CanIgnoreReturnValue
110 | @Override
111 | public Object evalFunction(String funName, Object... args) {
112 | if (getFileContext() == null || getFileContext().isBlank()) {
113 | contextInit();
114 | }
115 |
116 | // a simple fix for the optimization
117 | if (failed_functions.contains(funName)) {
118 | return null;
119 | }
120 |
121 | Value member = jsEngine.getBindings("js").getMember(funName);
122 | if (member == null) {
123 | failed_functions.add(funName);
124 | return null;
125 | }
126 |
127 | try {
128 | Object result = member.execute(args);
129 | ExceptionHandler.debugLog(
130 | "运行了 " + getAddon().getAddonName() + "的脚本" + getFile().getName() + "中的函数 " + funName);
131 | return result;
132 | } catch (IllegalStateException e) {
133 | String message = e.getMessage();
134 | if (!message.contains("Multi threaded access")) {
135 | ExceptionHandler.handleError(
136 | "在运行附属" + getAddon().getAddonName() + "的脚本" + getFile().getName() + "时发生错误");
137 | e.printStackTrace();
138 | }
139 | } catch (Throwable e) {
140 | ExceptionHandler.handleError(
141 | "在运行" + getAddon().getAddonName() + "的脚本" + getFile().getName() + "时发生意外错误");
142 | e.printStackTrace();
143 | }
144 |
145 | return null;
146 | }
147 |
148 | private void reSetup() {
149 | jsEngine = Context.newBuilder("js")
150 | .hostClassLoader(RykenSlimefunCustomizer.class.getClassLoader())
151 | .allowAllAccess(true)
152 | .allowHostAccess(UNIVERSAL_HOST_ACCESS)
153 | .allowNativeAccess(false)
154 | .allowExperimentalOptions(true)
155 | .allowPolyglotAccess(PolyglotAccess.ALL)
156 | .allowCreateProcess(true)
157 | .allowValueSharing(true)
158 | .allowIO(IOAccess.ALL)
159 | .allowHostClassLookup(s -> true)
160 | .allowHostClassLoading(true)
161 | .engine(Engine.newBuilder("js").allowExperimentalOptions(true).build())
162 | .currentWorkingDirectory(getAddon().getScriptsFolder().toPath().toAbsolutePath())
163 | .build();
164 |
165 | advancedSetup();
166 | }
167 | }
168 |
--------------------------------------------------------------------------------
/src/main/java/org/lins/mmmjjkx/rykenslimefuncustomizer/factories/SimpleMachineFactory.java:
--------------------------------------------------------------------------------
1 | package org.lins.mmmjjkx.rykenslimefuncustomizer.factories;
2 |
3 | import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
4 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem;
5 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
6 | import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
7 | import io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.*;
8 | import io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.enchanting.AutoDisenchanter;
9 | import io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.enchanting.AutoEnchanter;
10 | import io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.enchanting.BookBinder;
11 | import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AContainer;
12 | import org.bukkit.inventory.ItemStack;
13 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.customs.machine.sf.*;
14 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.machine.SimpleMachineType;
15 |
16 | public class SimpleMachineFactory {
17 | public static SlimefunItem create(
18 | ItemGroup group,
19 | SlimefunItemStack slimefunItemStack,
20 | RecipeType recipeType,
21 | ItemStack[] recipe,
22 | SimpleMachineType machineType,
23 | int capacity,
24 | int consumption,
25 | int speed,
26 | int radius,
27 | int repairFactor) {
28 | SlimefunItem instance =
29 | switch (machineType) {
30 | case ELECTRIC_FURNACE -> new ElectricFurnace(group, slimefunItemStack, recipeType, recipe);
31 | case ELECTRIC_GOLD_PAN -> new ElectricGoldPan(group, slimefunItemStack, recipeType, recipe);
32 | case ELECTRIC_SMELTERY -> new ElectricSmeltery(group, slimefunItemStack, recipeType, recipe);
33 | case ELECTRIC_DUST_WASHER -> new ElectricDustWasher(group, slimefunItemStack, recipeType, recipe);
34 | case ELECTRIC_ORE_GRINDER -> new ElectricOreGrinder(group, slimefunItemStack, recipeType, recipe);
35 | case ELECTRIC_INGOT_FACTORY -> new ElectricIngotFactory(
36 | group, slimefunItemStack, recipeType, recipe);
37 | case ELECTRIC_INGOT_PULVERIZER -> new ElectricIngotPulverizer(
38 | group, slimefunItemStack, recipeType, recipe);
39 | case CHARGING_BENCH -> new ChargingBench(group, slimefunItemStack, recipeType, recipe);
40 | case FREEZER -> new Freezer(group, slimefunItemStack, recipeType, recipe);
41 | case CARBON_PRESS -> new CarbonPress(group, slimefunItemStack, recipeType, recipe);
42 | case ELECTRIC_PRESS -> new ElectricPress(group, slimefunItemStack, recipeType, recipe);
43 | case ELECTRIC_CRUCIBLE -> new ElectrifiedCrucible(group, slimefunItemStack, recipeType, recipe);
44 | case FOOD_FABRICATOR -> new FoodFabricator(group, slimefunItemStack, recipeType, recipe);
45 | case HEATED_PRESSURE_CHAMBER -> new HeatedPressureChamber(
46 | group, slimefunItemStack, recipeType, recipe);
47 | case BOOK_BINDER -> new BookBinder(group, slimefunItemStack, recipeType, recipe);
48 | case AUTO_ENCHANTER -> new AutoEnchanter(group, slimefunItemStack, recipeType, recipe);
49 | case AUTO_DISENCHANTER -> new AutoDisenchanter(group, slimefunItemStack, recipeType, recipe);
50 | case AUTO_DRIER -> new AutoDrier(group, slimefunItemStack, recipeType, recipe);
51 | case AUTO_BREWER -> new AdvancedAutoBrewer(group, slimefunItemStack, recipeType, recipe, speed);
52 | case REFINERY -> new Refinery(group, slimefunItemStack, recipeType, recipe);
53 | case PRODUCE_COLLECTOR -> new AdvancedProduceCollector(
54 | group, slimefunItemStack, recipeType, recipe, speed);
55 | case TREE_GROWTH_ACCELERATOR -> new AdvancedTreeGrowthAccelerator(
56 | group, slimefunItemStack, recipeType, recipe, capacity, radius, consumption);
57 | case ANIMAL_GROWTH_ACCELERATOR -> new AdvancedAnimalGrowthAccelerator(
58 | group, slimefunItemStack, recipeType, recipe, capacity, radius, consumption);
59 | case CROP_GROWTH_ACCELERATOR -> new AdvancedCropGrowthAccelerator(
60 | group, slimefunItemStack, recipeType, recipe, capacity, radius, consumption, speed);
61 | case AUTO_ANVIL -> new AdvancedAutoAnvil(
62 | group, repairFactor, slimefunItemStack, recipeType, recipe, speed);
63 | };
64 |
65 | if (instance instanceof AContainer aContainer) {
66 | aContainer.setCapacity(capacity);
67 | aContainer.setEnergyConsumption(consumption);
68 | aContainer.setProcessingSpeed(speed);
69 | }
70 |
71 | return instance;
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/src/main/java/org/lins/mmmjjkx/rykenslimefuncustomizer/libraries/colors/CMIColors.java:
--------------------------------------------------------------------------------
1 | package org.lins.mmmjjkx.rykenslimefuncustomizer.libraries.colors;
2 |
3 | import java.awt.*;
4 | import lombok.Getter;
5 | import org.bukkit.Material;
6 |
7 | @Getter
8 | public enum CMIColors {
9 | White(0, "White", Material.WHITE_DYE, new Color(249, 255, 254)),
10 | Orange(1, "Orange", Material.ORANGE_DYE, new Color(249, 128, 29)),
11 | Magenta(2, "Magenta", Material.MAGENTA_DYE, new Color(199, 78, 189)),
12 | Light_Blue(3, "Light Blue", Material.LIGHT_BLUE_DYE, new Color(58, 179, 218)),
13 | Yellow(4, "Yellow", Material.YELLOW_DYE, new Color(254, 216, 61)),
14 | Lime(5, "Lime", Material.LIME_DYE, new Color(128, 199, 31)),
15 | Pink(6, "Pink", Material.PINK_DYE, new Color(243, 139, 170)),
16 | Gray(7, "Gray", Material.GRAY_DYE, new Color(71, 79, 82)),
17 | Light_Gray(8, "Light Gray", Material.LIGHT_GRAY_DYE, new Color(157, 157, 151)),
18 | Cyan(9, "Cyan", Material.CYAN_DYE, new Color(22, 156, 156)),
19 | Purple(10, "Purple", Material.PURPLE_DYE, new Color(137, 50, 184)),
20 | Blue(11, "Blue", Material.BLUE_DYE, new Color(60, 68, 170)),
21 | Brown(12, "Brown", Material.BROWN_DYE, new Color(131, 84, 50)),
22 | Green(13, "Green", Material.GREEN_DYE, new Color(94, 124, 22)),
23 | Red(14, "Red", Material.RED_DYE, new Color(176, 46, 38)),
24 | Black(15, "Black", Material.BLACK_DYE, new Color(29, 29, 33));
25 |
26 | private final int id;
27 | private final String name;
28 | private final Material material;
29 |
30 | private Color color;
31 |
32 | CMIColors(int id, String name, Material material, Color color) {
33 | this.id = id;
34 | this.name = name;
35 | this.material = material;
36 | this.color = color;
37 | }
38 |
39 | CMIColors(int id, String name, Material material) {
40 | this.id = id;
41 | this.name = name;
42 | this.material = material;
43 | }
44 |
45 | public static CMIColors getById(int id) {
46 | for (CMIColors one : CMIColors.values()) {
47 | if (one.getId() == id) return one;
48 | }
49 | return CMIColors.White;
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/main/java/org/lins/mmmjjkx/rykenslimefuncustomizer/libraries/version/MinecraftPlatform.java:
--------------------------------------------------------------------------------
1 | package org.lins.mmmjjkx.rykenslimefuncustomizer.libraries.version;
2 |
3 | public enum MinecraftPlatform {
4 | paper,
5 | pufferfish,
6 | folia,
7 | purpur,
8 | mohist,
9 | arclight
10 | }
11 |
--------------------------------------------------------------------------------
/src/main/java/org/lins/mmmjjkx/rykenslimefuncustomizer/listeners/BlockListener.java:
--------------------------------------------------------------------------------
1 | package org.lins.mmmjjkx.rykenslimefuncustomizer.listeners;
2 |
3 | import java.util.List;
4 | import java.util.Random;
5 | import org.bukkit.Bukkit;
6 | import org.bukkit.block.Block;
7 | import org.bukkit.event.EventHandler;
8 | import org.bukkit.event.Listener;
9 | import org.bukkit.event.block.BlockBreakEvent;
10 | import org.lins.mmmjjkx.rykenslimefuncustomizer.RykenSlimefunCustomizer;
11 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.global.DropFromBlock;
12 |
13 | public class BlockListener implements Listener {
14 | public BlockListener() {
15 | Bukkit.getPluginManager().registerEvents(this, RykenSlimefunCustomizer.INSTANCE);
16 | }
17 |
18 | @EventHandler
19 | public void onBlockBreak(BlockBreakEvent e) {
20 | Block block = e.getBlock();
21 | List drops = DropFromBlock.getDrops(block.getType());
22 | List matchedDrops =
23 | drops.stream().filter(drop -> matchChance(drop.dropChance())).toList();
24 | if (matchedDrops.isEmpty()) return;
25 |
26 | for (DropFromBlock.Drop drop : matchedDrops) {
27 | block.getWorld().dropItemNaturally(e.getBlock().getLocation(), drop.itemStack());
28 | }
29 | }
30 |
31 | private static boolean matchChance(int chance) {
32 | if (chance >= 100) return true;
33 |
34 | Random rand = new Random();
35 | return rand.nextInt(100) < chance;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/java/org/lins/mmmjjkx/rykenslimefuncustomizer/objects/customs/CustomAddonConfig.java:
--------------------------------------------------------------------------------
1 | package org.lins.mmmjjkx.rykenslimefuncustomizer.objects.customs;
2 |
3 | import java.io.File;
4 | import org.bukkit.configuration.file.YamlConfiguration;
5 | import org.jetbrains.annotations.Nullable;
6 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.script.ScriptEval;
7 |
8 | public record CustomAddonConfig(File configFile, YamlConfiguration config, ScriptEval onReloadHandler) {
9 | public CustomAddonConfig(File configFile, YamlConfiguration config, @Nullable ScriptEval onReloadHandler) {
10 | this.configFile = configFile;
11 | this.config = config;
12 | this.onReloadHandler = onReloadHandler;
13 | }
14 |
15 | public void tryReload() {
16 | try {
17 | config.load(configFile);
18 | if (onReloadHandler != null) {
19 | onReloadHandler.evalFunction("onConfigReload", config);
20 | }
21 | } catch (Exception e) {
22 | e.printStackTrace();
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/java/org/lins/mmmjjkx/rykenslimefuncustomizer/objects/customs/LinkedOutput.java:
--------------------------------------------------------------------------------
1 | package org.lins.mmmjjkx.rykenslimefuncustomizer.objects.customs;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 | import java.util.Map;
6 | import lombok.Getter;
7 | import org.bukkit.inventory.ItemStack;
8 | import org.lins.mmmjjkx.rykenslimefuncustomizer.utils.ExceptionHandler;
9 |
10 | @Getter
11 | public class LinkedOutput {
12 | private final ItemStack[] freeOutput;
13 | private final Map linkedOutput;
14 | private final int[] freeChances;
15 | private final Map linkedChances;
16 |
17 | public LinkedOutput(
18 | ItemStack[] freeOutput,
19 | Map linkedOutput,
20 | int[] freeChances,
21 | Map linkedChances) {
22 | this.freeOutput = freeOutput;
23 | this.linkedOutput = linkedOutput;
24 | this.freeChances = freeChances;
25 | this.linkedChances = linkedChances;
26 | }
27 |
28 | public ItemStack[] toArray() {
29 | ItemStack[] result = new ItemStack[freeOutput.length + linkedOutput.size()];
30 | System.arraycopy(freeOutput, 0, result, 0, freeOutput.length);
31 | int i = freeOutput.length;
32 | for (ItemStack item : linkedOutput.values()) {
33 | result[i] = item;
34 | i++;
35 | }
36 |
37 | return result;
38 | }
39 |
40 | public List chancesToArray() {
41 | List result = new ArrayList<>(freeChances.length + linkedChances.size());
42 | for (int chance : freeChances) {
43 | result.add(chance);
44 | }
45 | result.addAll(linkedChances.values());
46 | return result;
47 | }
48 |
49 | public void log() {
50 | // log free output & linked output
51 | for (int i = 0; i < freeOutput.length; i++) {
52 | ItemStack item = freeOutput[i];
53 | ExceptionHandler.info("FreeOutput: " + i + " 物品: " + item);
54 | }
55 |
56 | for (int slot : linkedOutput.keySet()) {
57 | ItemStack item = linkedOutput.get(slot);
58 | ExceptionHandler.info("LinkedOutput: " + slot + " 物品: " + item + " 位置: " + slot);
59 | }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/src/main/java/org/lins/mmmjjkx/rykenslimefuncustomizer/objects/customs/item/CustomArmorPiece.java:
--------------------------------------------------------------------------------
1 | package org.lins.mmmjjkx.rykenslimefuncustomizer.objects.customs.item;
2 |
3 | import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
4 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
5 | import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
6 | import io.github.thebusybiscuit.slimefun4.core.attributes.ProtectionType;
7 | import io.github.thebusybiscuit.slimefun4.core.attributes.ProtectiveArmor;
8 | import io.github.thebusybiscuit.slimefun4.implementation.items.armor.SlimefunArmorPiece;
9 | import org.bukkit.NamespacedKey;
10 | import org.bukkit.inventory.ItemStack;
11 | import org.bukkit.potion.PotionEffect;
12 | import org.jetbrains.annotations.NotNull;
13 | import org.jetbrains.annotations.Nullable;
14 | import org.lins.mmmjjkx.rykenslimefuncustomizer.RykenSlimefunCustomizer;
15 |
16 | public class CustomArmorPiece extends SlimefunArmorPiece implements ProtectiveArmor {
17 | private final String armorKey;
18 | private final boolean fullSet;
19 | private final ProtectionType[] protectionTypes;
20 | private final String projectId;
21 |
22 | public CustomArmorPiece(
23 | ItemGroup itemGroup,
24 | SlimefunItemStack item,
25 | RecipeType recipeType,
26 | ItemStack[] recipe,
27 | @Nullable PotionEffect[] effects,
28 | boolean fullSet,
29 | String armorKey,
30 | ProtectionType[] protectionTypes,
31 | String projectId) {
32 | super(itemGroup, item, recipeType, recipe, effects);
33 |
34 | this.armorKey = armorKey;
35 | this.fullSet = fullSet;
36 | this.protectionTypes = protectionTypes;
37 | this.projectId = projectId;
38 |
39 | register(RykenSlimefunCustomizer.INSTANCE);
40 | }
41 |
42 | @Override
43 | public @NotNull ProtectionType[] getProtectionTypes() {
44 | return protectionTypes;
45 | }
46 |
47 | @Override
48 | public boolean isFullSetRequired() {
49 | return fullSet;
50 | }
51 |
52 | @Nullable @Override
53 | public NamespacedKey getArmorSetId() {
54 | return new NamespacedKey(RykenSlimefunCustomizer.INSTANCE, projectId + "_" + armorKey);
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/main/java/org/lins/mmmjjkx/rykenslimefuncustomizer/objects/customs/item/CustomDefaultItem.java:
--------------------------------------------------------------------------------
1 | package org.lins.mmmjjkx.rykenslimefuncustomizer.objects.customs.item;
2 |
3 | import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
4 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
5 | import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
6 | import org.bukkit.inventory.ItemStack;
7 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.customs.parent.CustomItem;
8 |
9 | public class CustomDefaultItem extends CustomItem {
10 | private final Object[] constructorArgs;
11 |
12 | public CustomDefaultItem(ItemGroup itemGroup, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe, ItemStack recipeOutput) {
13 | super(itemGroup, item, recipeType, recipe, recipeOutput);
14 |
15 | constructorArgs = new Object[] {itemGroup, item, recipeType, recipe, recipeOutput};
16 | }
17 |
18 | @Override
19 | public Object[] constructorArgs() {
20 | return constructorArgs;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/main/java/org/lins/mmmjjkx/rykenslimefuncustomizer/objects/customs/item/CustomFood.java:
--------------------------------------------------------------------------------
1 | package org.lins.mmmjjkx.rykenslimefuncustomizer.objects.customs.item;
2 |
3 | import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
4 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
5 | import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
6 | import io.github.thebusybiscuit.slimefun4.core.handlers.ItemConsumptionHandler;
7 | import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
8 | import org.bukkit.inventory.ItemStack;
9 | import org.jetbrains.annotations.NotNull;
10 | import org.jetbrains.annotations.Nullable;
11 | import org.lins.mmmjjkx.rykenslimefuncustomizer.RykenSlimefunCustomizer;
12 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.script.ScriptEval;
13 |
14 | public class CustomFood extends SimpleSlimefunItem {
15 | private final ScriptEval eval;
16 |
17 | public CustomFood(
18 | ItemGroup itemGroup,
19 | SlimefunItemStack item,
20 | RecipeType recipeType,
21 | ItemStack[] recipe,
22 | @Nullable ScriptEval eval,
23 | ItemStack recipeOutput) {
24 | super(itemGroup, item, recipeType, recipe, recipeOutput);
25 |
26 | this.eval = eval;
27 |
28 | register(RykenSlimefunCustomizer.INSTANCE);
29 | }
30 |
31 | @NotNull @Override
32 | public ItemConsumptionHandler getItemHandler() {
33 | return (e, p, i) -> {
34 | if (eval != null) {
35 | eval.evalFunction("onEat", e, p, i);
36 | }
37 | };
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/org/lins/mmmjjkx/rykenslimefuncustomizer/objects/customs/item/CustomGeoResource.java:
--------------------------------------------------------------------------------
1 | package org.lins.mmmjjkx.rykenslimefuncustomizer.objects.customs.item;
2 |
3 | import io.github.thebusybiscuit.slimefun4.api.geo.GEOResource;
4 | import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
5 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
6 | import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
7 | import io.github.thebusybiscuit.slimefun4.implementation.items.blocks.UnplaceableBlock;
8 | import java.util.function.BiFunction;
9 | import org.bukkit.NamespacedKey;
10 | import org.bukkit.World;
11 | import org.bukkit.block.Biome;
12 | import org.bukkit.inventory.ItemStack;
13 | import org.jetbrains.annotations.NotNull;
14 | import org.lins.mmmjjkx.rykenslimefuncustomizer.RykenSlimefunCustomizer;
15 |
16 | public class CustomGeoResource extends UnplaceableBlock implements GEOResource {
17 | private final BiFunction supply;
18 | private final int maxDeviation;
19 | private final boolean obtainableFromGEOMiner;
20 | private final String name;
21 |
22 | public CustomGeoResource(
23 | ItemGroup itemGroup,
24 | SlimefunItemStack item,
25 | RecipeType type,
26 | ItemStack[] recipe,
27 | BiFunction supply,
28 | int maxDeviation,
29 | boolean obtainableFromGEOMiner,
30 | String name) {
31 | super(itemGroup, item, type, recipe);
32 |
33 | this.supply = supply;
34 | this.maxDeviation = maxDeviation;
35 | this.obtainableFromGEOMiner = obtainableFromGEOMiner;
36 | this.name = name;
37 |
38 | register();
39 | register(RykenSlimefunCustomizer.INSTANCE);
40 | }
41 |
42 | @Override
43 | public int getDefaultSupply(@NotNull World.Environment environment, @NotNull Biome biome) {
44 | return supply.apply(environment, biome);
45 | }
46 |
47 | @Override
48 | public int getMaxDeviation() {
49 | return maxDeviation;
50 | }
51 |
52 | @NotNull @Override
53 | public String getName() {
54 | return name;
55 | }
56 |
57 | @Override
58 | public boolean isObtainableFromGEOMiner() {
59 | return obtainableFromGEOMiner;
60 | }
61 |
62 | @Override
63 | public @NotNull NamespacedKey getKey() {
64 | return new NamespacedKey(RykenSlimefunCustomizer.INSTANCE, getId());
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/main/java/org/lins/mmmjjkx/rykenslimefuncustomizer/objects/customs/item/CustomUnplaceableItem.java:
--------------------------------------------------------------------------------
1 | package org.lins.mmmjjkx.rykenslimefuncustomizer.objects.customs.item;
2 |
3 | import io.github.thebusybiscuit.slimefun4.api.events.PlayerRightClickEvent;
4 | import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
5 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
6 | import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
7 | import io.github.thebusybiscuit.slimefun4.core.attributes.NotPlaceable;
8 | import io.github.thebusybiscuit.slimefun4.core.handlers.ItemUseHandler;
9 | import io.github.thebusybiscuit.slimefun4.core.handlers.ToolUseHandler;
10 | import io.github.thebusybiscuit.slimefun4.core.handlers.WeaponUseHandler;
11 | import org.bukkit.inventory.ItemStack;
12 | import org.jetbrains.annotations.Nullable;
13 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.customs.parent.CustomItem;
14 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.script.ScriptEval;
15 |
16 | public class CustomUnplaceableItem extends CustomItem implements NotPlaceable {
17 | private final Object[] constructorArgs;
18 |
19 | public CustomUnplaceableItem(
20 | ItemGroup itemGroup,
21 | SlimefunItemStack item,
22 | RecipeType recipeType,
23 | ItemStack[] recipe,
24 | @Nullable ScriptEval eval,
25 | ItemStack recipeOutput) {
26 | super(itemGroup, item, recipeType, recipe, recipeOutput);
27 |
28 | if (eval != null) {
29 | eval.doInit();
30 |
31 | this.addItemHandler((ItemUseHandler) e -> {
32 | eval.evalFunction("onUse", e);
33 | e.cancel();
34 | });
35 |
36 | this.addItemHandler((WeaponUseHandler) (e, p, it) -> eval.evalFunction("onWeaponHit", e, p, it));
37 | this.addItemHandler((ToolUseHandler) (e, it, i, drops) -> eval.evalFunction("onToolUse", e, it, i, drops));
38 | } else {
39 | this.addItemHandler((ItemUseHandler) PlayerRightClickEvent::cancel);
40 | }
41 |
42 | this.constructorArgs = new Object[] {itemGroup, item, recipeType, recipe, eval, recipeOutput};
43 | }
44 |
45 | @Override
46 | public Object[] constructorArgs() {
47 | return constructorArgs;
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/main/java/org/lins/mmmjjkx/rykenslimefuncustomizer/objects/customs/item/RSCItemStack.java:
--------------------------------------------------------------------------------
1 | package org.lins.mmmjjkx.rykenslimefuncustomizer.objects.customs.item;
2 |
3 | import io.github.thebusybiscuit.slimefun4.libraries.dough.items.CustomItemStack;
4 | import java.util.List;
5 | import org.bukkit.inventory.ItemStack;
6 |
7 | @SuppressWarnings("deprecation")
8 | public class RSCItemStack extends CustomItemStack {
9 | public RSCItemStack(ItemStack item, String name, List lore) {
10 | super(item, meta -> {
11 | if (name != null && !name.isBlank()) {
12 | meta.setDisplayName(name);
13 | }
14 |
15 | if (lore != null && !lore.isEmpty()) {
16 | meta.setLore(lore);
17 | }
18 | });
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/java/org/lins/mmmjjkx/rykenslimefuncustomizer/objects/customs/item/exts/CustomEnergyItem.java:
--------------------------------------------------------------------------------
1 | package org.lins.mmmjjkx.rykenslimefuncustomizer.objects.customs.item.exts;
2 |
3 | import io.github.thebusybiscuit.slimefun4.api.events.PlayerRightClickEvent;
4 | import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
5 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
6 | import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
7 | import io.github.thebusybiscuit.slimefun4.core.attributes.NotPlaceable;
8 | import io.github.thebusybiscuit.slimefun4.core.attributes.Rechargeable;
9 | import io.github.thebusybiscuit.slimefun4.core.handlers.ItemUseHandler;
10 | import io.github.thebusybiscuit.slimefun4.core.handlers.ToolUseHandler;
11 | import io.github.thebusybiscuit.slimefun4.core.handlers.WeaponUseHandler;
12 | import org.bukkit.inventory.ItemStack;
13 | import org.jetbrains.annotations.Nullable;
14 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.customs.parent.CustomItem;
15 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.script.ScriptEval;
16 |
17 | public class CustomEnergyItem extends CustomItem implements Rechargeable, NotPlaceable {
18 | private final float capacity;
19 |
20 | private final Object[] constructorArgs;
21 |
22 | public CustomEnergyItem(
23 | ItemGroup itemGroup,
24 | SlimefunItemStack item,
25 | RecipeType recipeType,
26 | ItemStack[] recipe,
27 | float capacity,
28 | @Nullable ScriptEval eval,
29 | ItemStack recipeOutput) {
30 | super(itemGroup, item, recipeType, recipe, recipeOutput);
31 |
32 | this.capacity = capacity;
33 |
34 | if (eval != null) {
35 | eval.doInit();
36 |
37 | this.addItemHandler((ItemUseHandler) e -> {
38 | eval.evalFunction("onUse", e, this);
39 | e.cancel();
40 | });
41 |
42 | this.addItemHandler((WeaponUseHandler) (e, p, it) -> eval.evalFunction("onWeaponHit", e, p, it));
43 | this.addItemHandler((ToolUseHandler) (e, it, i, drops) -> eval.evalFunction("onToolUse", e, it, i, drops));
44 | } else {
45 | this.addItemHandler((ItemUseHandler) PlayerRightClickEvent::cancel);
46 | }
47 |
48 | this.constructorArgs = new Object[] {itemGroup, item, recipeType, recipe, capacity, eval, recipeOutput};
49 | }
50 |
51 | public void setItemCharge(ItemStack item, int charge) {
52 | Rechargeable.super.setItemCharge(item, charge);
53 | }
54 |
55 | public void setItemCharge(ItemStack item, double charge) {
56 | Rechargeable.super.setItemCharge(item, (float) charge);
57 | }
58 |
59 | public void addItemCharge(ItemStack item, int charge) {
60 | Rechargeable.super.addItemCharge(item, charge);
61 | }
62 |
63 | public void addItemCharge(ItemStack item, double charge) {
64 | Rechargeable.super.addItemCharge(item, (float) charge);
65 | }
66 |
67 | public void removeItemCharge(ItemStack item, int charge) {
68 | Rechargeable.super.removeItemCharge(item, charge);
69 | }
70 |
71 | public void removeItemCharge(ItemStack item, double charge) {
72 | Rechargeable.super.addItemCharge(item, (float) charge);
73 | }
74 |
75 | public float getItemCharge(ItemStack item) {
76 | return Rechargeable.super.getItemCharge(item);
77 | }
78 |
79 | @Override
80 | public float getMaxItemCharge(ItemStack itemStack) {
81 | return capacity;
82 | }
83 |
84 | @Override
85 | public Object[] constructorArgs() {
86 | return constructorArgs;
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/src/main/java/org/lins/mmmjjkx/rykenslimefuncustomizer/objects/customs/item/exts/CustomMobDrop.java:
--------------------------------------------------------------------------------
1 | package org.lins.mmmjjkx.rykenslimefuncustomizer.objects.customs.item.exts;
2 |
3 | import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
4 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
5 | import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
6 | import io.github.thebusybiscuit.slimefun4.core.attributes.RandomMobDrop;
7 | import lombok.Getter;
8 | import org.bukkit.entity.EntityType;
9 | import org.bukkit.inventory.ItemStack;
10 | import org.lins.mmmjjkx.rykenslimefuncustomizer.RykenSlimefunCustomizer;
11 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.customs.item.CustomUnplaceableItem;
12 |
13 | public class CustomMobDrop extends CustomUnplaceableItem implements RandomMobDrop {
14 | private final int chance;
15 |
16 | @Getter
17 | private final EntityType entityType;
18 |
19 | public CustomMobDrop(ItemGroup itemGroup, SlimefunItemStack item, ItemStack[] recipe, int chance, EntityType type, ItemStack recipeOutput) {
20 | super(itemGroup, item, RecipeType.MOB_DROP, recipe, null, recipeOutput);
21 | this.chance = chance;
22 | this.entityType = type;
23 |
24 | register(RykenSlimefunCustomizer.INSTANCE);
25 | }
26 |
27 | @Override
28 | public int getMobDropChance() {
29 | return chance >= 100 ? 100 : Math.max(chance, 1);
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/java/org/lins/mmmjjkx/rykenslimefuncustomizer/objects/customs/item/exts/CustomRainbowBlock.java:
--------------------------------------------------------------------------------
1 | package org.lins.mmmjjkx.rykenslimefuncustomizer.objects.customs.item.exts;
2 |
3 | import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
4 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
5 | import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
6 | import io.github.thebusybiscuit.slimefun4.core.handlers.RainbowTickHandler;
7 | import io.github.thebusybiscuit.slimefun4.utils.ColoredMaterial;
8 | import java.util.List;
9 | import org.bukkit.Material;
10 | import org.bukkit.inventory.ItemStack;
11 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.customs.parent.CustomItem;
12 |
13 | public class CustomRainbowBlock extends CustomItem {
14 | private final Object[] constructorArgs;
15 |
16 | public CustomRainbowBlock(
17 | ItemGroup itemGroup,
18 | SlimefunItemStack item,
19 | RecipeType recipeType,
20 | ItemStack[] recipe,
21 | RainbowTickHandler ticker,
22 | ItemStack recipeOutput) {
23 | super(itemGroup, item, recipeType, recipe, recipeOutput);
24 |
25 | addItemHandler(ticker);
26 |
27 | constructorArgs = new Object[] {itemGroup, item, recipeType, recipe, ticker, recipeOutput};
28 | }
29 |
30 | public CustomRainbowBlock(
31 | ItemGroup itemGroup,
32 | SlimefunItemStack item,
33 | RecipeType recipeType,
34 | ItemStack[] recipe,
35 | ColoredMaterial materialType,
36 | ItemStack recipeOutput) {
37 | this(itemGroup, item, recipeType, recipe, new RainbowTickHandler(materialType), recipeOutput);
38 | }
39 |
40 | public CustomRainbowBlock(
41 | ItemGroup itemGroup,
42 | SlimefunItemStack item,
43 | RecipeType recipeType,
44 | ItemStack[] recipe,
45 | List materials,
46 | ItemStack recipeOutput) {
47 | this(itemGroup, item, recipeType, recipe, new RainbowTickHandler(materials), recipeOutput);
48 | }
49 |
50 | @Override
51 | public Object[] constructorArgs() {
52 | return constructorArgs;
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/main/java/org/lins/mmmjjkx/rykenslimefuncustomizer/objects/customs/machine/CustomEnergyGenerator.java:
--------------------------------------------------------------------------------
1 | package org.lins.mmmjjkx.rykenslimefuncustomizer.objects.customs.machine;
2 |
3 | import com.xzavier0722.mc.plugin.slimefun4.storage.controller.SlimefunBlockData;
4 | import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
5 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
6 | import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
7 | import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetProvider;
8 | import io.github.thebusybiscuit.slimefun4.core.networks.energy.EnergyNetComponentType;
9 | import java.util.List;
10 | import org.bukkit.Location;
11 | import org.bukkit.inventory.ItemStack;
12 | import org.jetbrains.annotations.NotNull;
13 | import org.jetbrains.annotations.Nullable;
14 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.customs.CustomMenu;
15 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.machine.MachineRecord;
16 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.script.ScriptEval;
17 | import org.lins.mmmjjkx.rykenslimefuncustomizer.utils.ExceptionHandler;
18 |
19 | public class CustomEnergyGenerator extends CustomMachine implements EnergyNetProvider {
20 | private final ScriptEval eval;
21 | private final int defaultOutput;
22 |
23 | public CustomEnergyGenerator(
24 | ItemGroup itemGroup,
25 | SlimefunItemStack item,
26 | RecipeType recipeType,
27 | ItemStack[] recipe,
28 | @Nullable CustomMenu menu,
29 | List input,
30 | List output,
31 | MachineRecord record,
32 | EnergyNetComponentType type,
33 | @Nullable ScriptEval eval,
34 | int defaultOutput) {
35 | super(itemGroup, item, recipeType, recipe, menu, input, output, record, type, eval);
36 |
37 | this.eval = eval;
38 | this.defaultOutput = defaultOutput;
39 | }
40 |
41 | @Override
42 | public int getGeneratedOutput(@NotNull Location l, @NotNull SlimefunBlockData data) {
43 | if (eval == null) {
44 | return defaultOutput;
45 | } else {
46 | try {
47 | Object result = eval.evalFunction("getGeneratedOutput", l, data);
48 | if (result instanceof Integer i) {
49 | return i;
50 | } else {
51 | ExceptionHandler.handleWarning(
52 | "getGeneratedOutput() 返回了一个非整数值: " + result + " 导致自定义发电机的默认输出值将被使用, 请找附属对应作者修复此问题!");
53 | return defaultOutput;
54 | }
55 | } catch (Exception e) {
56 | return defaultOutput;
57 | }
58 | }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/main/java/org/lins/mmmjjkx/rykenslimefuncustomizer/objects/customs/machine/CustomMachine.java:
--------------------------------------------------------------------------------
1 | package org.lins.mmmjjkx.rykenslimefuncustomizer.objects.customs.machine;
2 |
3 | import com.xzavier0722.mc.plugin.slimefun4.storage.controller.SlimefunBlockData;
4 | import com.xzavier0722.mc.plugin.slimefun4.storage.util.StorageCacheUtils;
5 | import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
6 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem;
7 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
8 | import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
9 | import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetComponent;
10 | import io.github.thebusybiscuit.slimefun4.core.handlers.BlockBreakHandler;
11 | import io.github.thebusybiscuit.slimefun4.core.handlers.BlockPlaceHandler;
12 | import io.github.thebusybiscuit.slimefun4.core.handlers.BlockUseHandler;
13 | import io.github.thebusybiscuit.slimefun4.core.machines.MachineOperation;
14 | import io.github.thebusybiscuit.slimefun4.core.machines.MachineProcessor;
15 | import io.github.thebusybiscuit.slimefun4.core.networks.energy.EnergyNetComponentType;
16 | import java.util.List;
17 | import lombok.Getter;
18 | import me.mrCookieSlime.Slimefun.Objects.handlers.BlockTicker;
19 | import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
20 | import org.bukkit.block.Block;
21 | import org.bukkit.event.block.BlockBreakEvent;
22 | import org.bukkit.event.block.BlockPlaceEvent;
23 | import org.bukkit.inventory.ItemStack;
24 | import org.jetbrains.annotations.NotNull;
25 | import org.jetbrains.annotations.Nullable;
26 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.customs.CustomMenu;
27 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.customs.parent.AbstractEmptyMachine;
28 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.machine.MachineInfo;
29 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.machine.MachineRecord;
30 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.machine.ScriptedEvalBreakHandler;
31 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.script.ScriptEval;
32 |
33 | public class CustomMachine extends AbstractEmptyMachine implements EnergyNetComponent {
34 | private final MachineRecord theRecord;
35 | private final List input;
36 | private final List output;
37 | private final EnergyNetComponentType type;
38 | private final MachineProcessor processor;
39 | private final @Nullable ScriptEval eval;
40 |
41 | @Getter
42 | private final CustomMenu menu;
43 |
44 | public CustomMachine(
45 | ItemGroup itemGroup,
46 | SlimefunItemStack item,
47 | RecipeType recipeType,
48 | ItemStack[] recipe,
49 | @Nullable CustomMenu menu,
50 | List input,
51 | List output,
52 | MachineRecord record,
53 | EnergyNetComponentType type,
54 | @Nullable ScriptEval eval) {
55 | super(itemGroup, item, recipeType, recipe);
56 |
57 | this.input = input;
58 | this.output = output;
59 | this.theRecord = record;
60 | this.menu = menu;
61 |
62 | this.type = type;
63 | this.eval = eval;
64 | this.processor = new MachineProcessor<>(this);
65 |
66 | if (eval != null) {
67 | eval.doInit();
68 |
69 | addItemHandler(
70 | new BlockPlaceHandler(false) {
71 | @Override
72 | public void onPlayerPlace(@NotNull BlockPlaceEvent e) {
73 | CustomMachine.this.eval.evalFunction("onPlace", e);
74 | }
75 | },
76 | (BlockUseHandler) e -> CustomMachine.this.eval.evalFunction("onUse", e),
77 | new BlockBreakHandler(false, false) {
78 | @Override
79 | public void onPlayerBreak(
80 | @NotNull BlockBreakEvent e, @NotNull ItemStack item, @NotNull List drops) {
81 | MachineOperation operation = getMachineProcessor().getOperation(e.getBlock());
82 | if (operation != null) {
83 | getMachineProcessor().endOperation(e.getBlock());
84 | }
85 |
86 | CustomMachine.this.eval.evalFunction("onBreak", e, item, drops);
87 | }
88 | });
89 | }
90 |
91 | addItemHandler(new ScriptedEvalBreakHandler(this, eval));
92 |
93 | if (menu != null) {
94 | this.processor.setProgressBar(menu.getProgressBarItem());
95 |
96 | createPreset(this, menu::apply);
97 | }
98 | }
99 |
100 | @Override
101 | public void preRegister() {
102 | super.preRegister();
103 | this.addItemHandler(getBlockTicker());
104 | }
105 |
106 | protected void tick(Block b, SlimefunItem item, SlimefunBlockData data) {
107 | if (eval != null) {
108 | BlockMenu blockMenu = StorageCacheUtils.getMenu(b.getLocation());
109 | MachineInfo info = new MachineInfo(blockMenu, data, item, b, processor, null, this);
110 | eval.evalFunction("tick", info);
111 | }
112 | }
113 |
114 | @Override
115 | public BlockTicker getBlockTicker() {
116 | return new BlockTicker() {
117 | @Override
118 | public boolean isSynchronized() {
119 | return true;
120 | }
121 |
122 | @Override
123 | public void tick(Block b, SlimefunItem item, SlimefunBlockData data) {
124 | CustomMachine.this.tick(b, item, data);
125 | }
126 | };
127 | }
128 |
129 | @Override
130 | public int[] getInputSlots() {
131 | return input.stream().mapToInt(i -> i).toArray();
132 | }
133 |
134 | @Override
135 | public int[] getOutputSlots() {
136 | return output.stream().mapToInt(i -> i).toArray();
137 | }
138 |
139 | @NotNull @Override
140 | public EnergyNetComponentType getEnergyComponentType() {
141 | return type;
142 | }
143 |
144 | @Override
145 | public int getCapacity() {
146 | return theRecord.capacity();
147 | }
148 |
149 | @NotNull @Override
150 | public MachineProcessor getMachineProcessor() {
151 | return processor;
152 | }
153 | }
154 |
--------------------------------------------------------------------------------
/src/main/java/org/lins/mmmjjkx/rykenslimefuncustomizer/objects/customs/machine/CustomNoEnergyMachine.java:
--------------------------------------------------------------------------------
1 | package org.lins.mmmjjkx.rykenslimefuncustomizer.objects.customs.machine;
2 |
3 | import com.xzavier0722.mc.plugin.slimefun4.storage.controller.SlimefunBlockData;
4 | import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
5 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem;
6 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
7 | import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
8 | import io.github.thebusybiscuit.slimefun4.core.handlers.BlockBreakHandler;
9 | import io.github.thebusybiscuit.slimefun4.core.handlers.BlockPlaceHandler;
10 | import io.github.thebusybiscuit.slimefun4.core.handlers.BlockUseHandler;
11 | import io.github.thebusybiscuit.slimefun4.core.machines.MachineOperation;
12 | import io.github.thebusybiscuit.slimefun4.core.machines.MachineProcessor;
13 | import java.util.Collections;
14 | import java.util.List;
15 | import java.util.function.Consumer;
16 | import lombok.Getter;
17 | import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu;
18 | import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ClickAction;
19 | import me.mrCookieSlime.Slimefun.Objects.handlers.BlockTicker;
20 | import org.bukkit.block.Block;
21 | import org.bukkit.entity.Player;
22 | import org.bukkit.event.block.BlockBreakEvent;
23 | import org.bukkit.event.block.BlockPlaceEvent;
24 | import org.bukkit.inventory.ItemStack;
25 | import org.jetbrains.annotations.NotNull;
26 | import org.jetbrains.annotations.Nullable;
27 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.customs.CustomMenu;
28 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.customs.parent.AbstractEmptyMachine;
29 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.machine.ScriptedEvalBreakHandler;
30 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.machine.SmallerMachineInfo;
31 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.script.ScriptEval;
32 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.script.lambda.RSCClickHandler;
33 |
34 | @SuppressWarnings("deprecation")
35 | public class CustomNoEnergyMachine extends AbstractEmptyMachine {
36 | private final List input;
37 | private final List output;
38 | private final @Nullable ScriptEval eval;
39 | private final MachineProcessor processor;
40 |
41 | @Getter
42 | private final CustomMenu menu;
43 |
44 | public CustomNoEnergyMachine(
45 | ItemGroup itemGroup,
46 | SlimefunItemStack item,
47 | RecipeType recipeType,
48 | ItemStack[] recipe,
49 | CustomMenu menu,
50 | List input,
51 | List output,
52 | @Nullable ScriptEval eval,
53 | int work) {
54 | this(itemGroup, item, recipeType, recipe, menu, input, output, eval, Collections.singletonList(work));
55 | }
56 |
57 | public CustomNoEnergyMachine(
58 | ItemGroup itemGroup,
59 | SlimefunItemStack item,
60 | RecipeType recipeType,
61 | ItemStack[] recipe,
62 | CustomMenu menu,
63 | List input,
64 | List output,
65 | @Nullable ScriptEval eval,
66 | List work) {
67 | super(itemGroup, item, recipeType, recipe);
68 |
69 | this.input = input;
70 | this.output = output;
71 | this.eval = eval;
72 | this.processor = new MachineProcessor<>(this);
73 | this.menu = menu;
74 |
75 | if (eval != null) {
76 | eval.addThing("setWorking", (Consumer) b -> eval.addThing("working", b));
77 | eval.addThing("working", false);
78 |
79 | eval.doInit();
80 |
81 | addItemHandler(
82 | new BlockPlaceHandler(false) {
83 | @Override
84 | public void onPlayerPlace(@NotNull BlockPlaceEvent e) {
85 | CustomNoEnergyMachine.this.eval.evalFunction("onPlace", e);
86 | }
87 | },
88 | (BlockUseHandler) e -> CustomNoEnergyMachine.this.eval.evalFunction("onUse", e),
89 | new BlockBreakHandler(false, false) {
90 | @Override
91 | public void onPlayerBreak(
92 | @NotNull BlockBreakEvent e, @NotNull ItemStack item, @NotNull List drops) {
93 | MachineOperation operation = getMachineProcessor().getOperation(e.getBlock());
94 | if (operation != null) {
95 | getMachineProcessor().endOperation(e.getBlock());
96 | }
97 |
98 | CustomNoEnergyMachine.this.eval.evalFunction("onBreak", e, item, drops);
99 | }
100 | });
101 | }
102 |
103 | addItemHandler(new ScriptedEvalBreakHandler(this, eval));
104 | addItemHandler(getBlockTicker());
105 |
106 | if (this.menu != null) {
107 | for (int workSlot : work) {
108 | if (workSlot > -1 && workSlot < 54) {
109 | ChestMenu.MenuClickHandler mcl = this.menu.getMenuClickHandler(workSlot);
110 | this.menu.addMenuClickHandler(workSlot, new RSCClickHandler() {
111 | @Override
112 | public void mainFunction(Player player, int slot, ItemStack itemStack, ClickAction action) {
113 | if (eval != null) {
114 | eval.addThing("working", true);
115 | }
116 | }
117 |
118 | @Override
119 | public void andThen(Player player, int slot, ItemStack itemStack, ClickAction action) {
120 | if (mcl != null) {
121 | mcl.onClick(player, slot, itemStack, action);
122 | }
123 | }
124 | });
125 | }
126 | this.processor.setProgressBar(menu.getProgressBarItem());
127 | }
128 |
129 | createPreset(this, this.menu::apply);
130 | }
131 | }
132 |
133 | @Override
134 | public void preRegister() {
135 | super.preRegister();
136 | this.addItemHandler(getBlockTicker());
137 | }
138 |
139 | protected void tick(Block b, SlimefunItem item, SlimefunBlockData data) {
140 | if (eval != null) {
141 | SmallerMachineInfo info = new SmallerMachineInfo(data.getBlockMenu(), data, this, item, b, processor);
142 | eval.evalFunction("tick", info);
143 | }
144 | }
145 |
146 | @Override
147 | public int[] getInputSlots() {
148 | return input.stream().mapToInt(i -> i).toArray();
149 | }
150 |
151 | @Override
152 | public int[] getOutputSlots() {
153 | return output.stream().mapToInt(i -> i).toArray();
154 | }
155 |
156 | @Override
157 | public BlockTicker getBlockTicker() {
158 | return new BlockTicker() {
159 | @Override
160 | public boolean isSynchronized() {
161 | return true;
162 | }
163 |
164 | @Override
165 | public void tick(Block b, SlimefunItem item, SlimefunBlockData data) {
166 | CustomNoEnergyMachine.this.tick(b, item, data);
167 | }
168 | };
169 | }
170 |
171 | @NotNull @Override
172 | public MachineProcessor getMachineProcessor() {
173 | return processor;
174 | }
175 | }
176 |
--------------------------------------------------------------------------------
/src/main/java/org/lins/mmmjjkx/rykenslimefuncustomizer/objects/customs/machine/CustomSolarGenerator.java:
--------------------------------------------------------------------------------
1 | package org.lins.mmmjjkx.rykenslimefuncustomizer.objects.customs.machine;
2 |
3 | import com.xzavier0722.mc.plugin.slimefun4.storage.controller.SlimefunBlockData;
4 | import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
5 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
6 | import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
7 | import io.github.thebusybiscuit.slimefun4.implementation.items.electric.generators.SolarGenerator;
8 | import org.bukkit.Location;
9 | import org.bukkit.World;
10 | import org.bukkit.inventory.ItemStack;
11 | import org.lins.mmmjjkx.rykenslimefuncustomizer.RykenSlimefunCustomizer;
12 |
13 | public class CustomSolarGenerator extends SolarGenerator {
14 | private final int lightLevel;
15 |
16 | public CustomSolarGenerator(
17 | ItemGroup itemGroup,
18 | int dayEnergy,
19 | int nightEnergy,
20 | SlimefunItemStack item,
21 | RecipeType recipeType,
22 | ItemStack[] recipe,
23 | int capacity,
24 | int lightLevel) {
25 | super(itemGroup, dayEnergy, nightEnergy, item, recipeType, recipe, capacity);
26 |
27 | if (lightLevel > 15 || lightLevel < 0) {
28 | lightLevel = 15;
29 | }
30 |
31 | this.lightLevel = lightLevel;
32 |
33 | register(RykenSlimefunCustomizer.INSTANCE);
34 | }
35 |
36 | public int getGeneratedOutput(Location l, SlimefunBlockData data) {
37 | World world = l.getWorld();
38 |
39 | if (world.getEnvironment() != World.Environment.NORMAL) {
40 | return 0;
41 | } else {
42 | boolean isDaytime = isDaytime(world);
43 |
44 | if (!isDaytime && getNightEnergy() < 1) {
45 | return 0;
46 | } else if (!world.isChunkLoaded(l.getBlockX() >> 4, l.getBlockZ() >> 4)
47 | || l.getBlock().getRelative(0, 1, 0).getLightFromSky() < (byte) lightLevel) {
48 | return 0;
49 | } else {
50 | return isDaytime ? getDayEnergy() : getNightEnergy();
51 | }
52 | }
53 | }
54 |
55 | private boolean isDaytime(World world) {
56 | long time = world.getTime();
57 | return !world.hasStorm() && !world.isThundering() && (time < 12300L || time > 23850L);
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/main/java/org/lins/mmmjjkx/rykenslimefuncustomizer/objects/customs/machine/sf/AdvancedAnimalGrowthAccelerator.java:
--------------------------------------------------------------------------------
1 | package org.lins.mmmjjkx.rykenslimefuncustomizer.objects.customs.machine.sf;
2 |
3 | import com.xzavier0722.mc.plugin.slimefun4.storage.util.StorageCacheUtils;
4 | import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
5 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
6 | import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
7 | import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
8 | import io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.accelerators.AbstractGrowthAccelerator;
9 | import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
10 | import io.github.thebusybiscuit.slimefun4.utils.itemstack.ItemStackWrapper;
11 | import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
12 | import org.bukkit.Particle;
13 | import org.bukkit.block.Block;
14 | import org.bukkit.entity.Ageable;
15 | import org.bukkit.entity.Entity;
16 | import org.bukkit.entity.LivingEntity;
17 | import org.bukkit.inventory.ItemStack;
18 |
19 | public class AdvancedAnimalGrowthAccelerator extends AbstractGrowthAccelerator {
20 | private static final ItemStack organicFood = ItemStackWrapper.wrap(SlimefunItems.ORGANIC_FOOD);
21 |
22 | private final int capacity;
23 | private final int radius;
24 | private final int energy_consumption;
25 |
26 | public AdvancedAnimalGrowthAccelerator(
27 | ItemGroup itemGroup,
28 | SlimefunItemStack item,
29 | RecipeType recipeType,
30 | ItemStack[] recipe,
31 | int capacity,
32 | int radius,
33 | int energy_consumption) {
34 | super(itemGroup, item, recipeType, recipe);
35 |
36 | this.capacity = capacity;
37 | this.radius = radius;
38 | this.energy_consumption = energy_consumption;
39 | }
40 |
41 | protected void tick(Block b) {
42 | BlockMenu inv = StorageCacheUtils.getMenu(b.getLocation());
43 |
44 | if (inv != null) {
45 | for (Entity n :
46 | b.getWorld().getNearbyEntities(b.getLocation(), radius, radius, radius, this::isReadyToGrow)) {
47 | int[] var5 = this.getInputSlots();
48 | int var6 = var5.length;
49 |
50 | for (int slot : var5) {
51 | if (SlimefunUtils.isItemSimilar(inv.getItemInSlot(slot), organicFood, false, false)) {
52 | if (this.getCharge(b.getLocation()) < energy_consumption) {
53 | return;
54 | }
55 |
56 | Ageable ageable = (Ageable) n;
57 | this.removeCharge(b.getLocation(), energy_consumption);
58 | inv.consumeItem(slot);
59 | ageable.setAge(ageable.getAge() + 2000);
60 | if (ageable.getAge() > 0) {
61 | ageable.setAge(0);
62 | }
63 |
64 | n.getWorld()
65 | .spawnParticle(
66 | Particle.VILLAGER_HAPPY,
67 | ((LivingEntity) n).getEyeLocation(),
68 | 8,
69 | 0.20000000298023224,
70 | 0.20000000298023224,
71 | 0.20000000298023224);
72 | return;
73 | }
74 | }
75 | }
76 | }
77 | }
78 |
79 | private boolean isReadyToGrow(Entity n) {
80 | if (n instanceof Ageable ageable) {
81 | return n.isValid() && !ageable.isAdult();
82 | }
83 |
84 | return false;
85 | }
86 |
87 | @Override
88 | public int getCapacity() {
89 | return capacity;
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/src/main/java/org/lins/mmmjjkx/rykenslimefuncustomizer/objects/customs/machine/sf/AdvancedAutoAnvil.java:
--------------------------------------------------------------------------------
1 | package org.lins.mmmjjkx.rykenslimefuncustomizer.objects.customs.machine.sf;
2 |
3 | import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
4 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
5 | import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
6 | import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
7 | import io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.AutoAnvil;
8 | import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
9 | import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.MachineRecipe;
10 | import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
11 | import org.bukkit.inventory.ItemStack;
12 | import org.bukkit.inventory.meta.Damageable;
13 | import org.bukkit.inventory.meta.ItemMeta;
14 |
15 | public class AdvancedAutoAnvil extends AutoAnvil {
16 | private final int repairFactor;
17 | private final int speed;
18 |
19 | public AdvancedAutoAnvil(
20 | ItemGroup itemGroup,
21 | int repairFactor,
22 | SlimefunItemStack item,
23 | RecipeType recipeType,
24 | ItemStack[] recipe,
25 | int speed) {
26 | super(itemGroup, repairFactor, item, recipeType, recipe);
27 |
28 | this.repairFactor = repairFactor;
29 | this.speed = speed;
30 | }
31 |
32 | protected MachineRecipe findNextRecipe(BlockMenu menu) {
33 | for (int slot : this.getInputSlots()) {
34 | ItemStack ductTape = menu.getItemInSlot(
35 | slot == this.getInputSlots()[0] ? this.getInputSlots()[1] : this.getInputSlots()[0]);
36 | ItemStack item = menu.getItemInSlot(slot);
37 | if (item != null
38 | && item.getType().getMaxDurability() > 0
39 | && ((Damageable) item.getItemMeta()).getDamage() > 0) {
40 | if (SlimefunUtils.isItemSimilar(ductTape, SlimefunItems.DUCT_TAPE, true, false)) {
41 | ItemStack repairedItem = this.repair(item);
42 | if (!menu.fits(repairedItem, this.getOutputSlots())) {
43 | return null;
44 | }
45 |
46 | for (int inputSlot : this.getInputSlots()) {
47 | menu.consumeItem(inputSlot);
48 | }
49 |
50 | return new MachineRecipe(
51 | 30 / this.speed, new ItemStack[] {ductTape, item}, new ItemStack[] {repairedItem});
52 | }
53 | break;
54 | }
55 | }
56 |
57 | return null;
58 | }
59 |
60 | private ItemStack repair(ItemStack item) {
61 | ItemStack repaired = item.clone();
62 | ItemMeta meta = repaired.getItemMeta();
63 | short maxDurability = item.getType().getMaxDurability();
64 | int repairPercentage = 100 / this.repairFactor;
65 | short durability = (short) (((Damageable) meta).getDamage() - maxDurability / repairPercentage);
66 | if (durability < 0) {
67 | durability = 0;
68 | }
69 |
70 | ((Damageable) meta).setDamage(durability);
71 | repaired.setItemMeta(meta);
72 | return repaired;
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/src/main/java/org/lins/mmmjjkx/rykenslimefuncustomizer/objects/customs/machine/sf/AdvancedAutoBrewer.java:
--------------------------------------------------------------------------------
1 | package org.lins.mmmjjkx.rykenslimefuncustomizer.objects.customs.machine.sf;
2 |
3 | import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
4 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
5 | import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
6 | import io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.AutoBrewer;
7 | import io.github.thebusybiscuit.slimefun4.libraries.dough.inventory.InvUtils;
8 | import java.util.EnumMap;
9 | import java.util.Map;
10 | import javax.annotation.Nonnull;
11 | import javax.annotation.Nullable;
12 | import javax.annotation.ParametersAreNonnullByDefault;
13 | import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.MachineRecipe;
14 | import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
15 | import org.bukkit.Material;
16 | import org.bukkit.inventory.ItemStack;
17 | import org.bukkit.inventory.meta.PotionMeta;
18 | import org.bukkit.potion.PotionData;
19 | import org.bukkit.potion.PotionType;
20 |
21 | public class AdvancedAutoBrewer extends AutoBrewer {
22 | private static final Map potionRecipes = new EnumMap<>(Material.class);
23 | private static final Map fermentations = new EnumMap<>(PotionType.class);
24 |
25 | private final int speed;
26 |
27 | public AdvancedAutoBrewer(
28 | ItemGroup itemGroup, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe, int speed) {
29 | super(itemGroup, item, recipeType, recipe);
30 |
31 | this.speed = speed;
32 | }
33 |
34 | @Nullable protected MachineRecipe findNextRecipe(BlockMenu menu) {
35 | ItemStack input1 = menu.getItemInSlot(this.getInputSlots()[0]);
36 | ItemStack input2 = menu.getItemInSlot(this.getInputSlots()[1]);
37 | if (input1 != null && input2 != null) {
38 | if (!this.isPotion(input1.getType()) && !this.isPotion(input2.getType())) {
39 | return null;
40 | } else {
41 | boolean isPotionInFirstSlot = this.isPotion(input1.getType());
42 | ItemStack ingredient = isPotionInFirstSlot ? input2 : input1;
43 | if (ingredient.hasItemMeta()) {
44 | return null;
45 | } else {
46 | ItemStack potionItem = isPotionInFirstSlot ? input1 : input2;
47 | PotionMeta potion = (PotionMeta) potionItem.getItemMeta();
48 | ItemStack output = this.brew(ingredient.getType(), potionItem.getType(), potion);
49 | if (output == null) {
50 | return null;
51 | } else {
52 | output.setItemMeta(potion);
53 | if (!InvUtils.fits(menu.toInventory(), output, this.getOutputSlots())) {
54 | return null;
55 | } else {
56 | for (int slot : this.getInputSlots()) {
57 | menu.consumeItem(slot);
58 | }
59 |
60 | return new MachineRecipe(
61 | 30 / speed, new ItemStack[] {input1, input2}, new ItemStack[] {output});
62 | }
63 | }
64 | }
65 | }
66 | } else {
67 | return null;
68 | }
69 | }
70 |
71 | @ParametersAreNonnullByDefault
72 | @Nullable private ItemStack brew(Material input, Material potionType, PotionMeta potion) {
73 | PotionData data = potion.getBasePotionData();
74 | PotionType type = data.getType();
75 | if (type == PotionType.WATER) {
76 | if (input == Material.FERMENTED_SPIDER_EYE) {
77 | potion.setBasePotionData(new PotionData(PotionType.WEAKNESS, false, false));
78 | return new ItemStack(potionType);
79 | }
80 |
81 | if (input == Material.NETHER_WART) {
82 | potion.setBasePotionData(new PotionData(PotionType.AWKWARD, false, false));
83 | return new ItemStack(potionType);
84 | }
85 |
86 | if (potionType == Material.POTION && input == Material.GUNPOWDER) {
87 | return new ItemStack(Material.SPLASH_POTION);
88 | }
89 |
90 | if (potionType == Material.SPLASH_POTION && input == Material.DRAGON_BREATH) {
91 | return new ItemStack(Material.LINGERING_POTION);
92 | }
93 | } else if (input == Material.FERMENTED_SPIDER_EYE) {
94 | PotionType fermented = fermentations.get(type);
95 | if (fermented != null) {
96 | potion.setBasePotionData(new PotionData(fermented, data.isExtended(), data.isUpgraded()));
97 | return new ItemStack(potionType);
98 | }
99 | } else {
100 | if (input == Material.REDSTONE && type.isExtendable() && !data.isUpgraded()) {
101 | potion.setBasePotionData(new PotionData(type, true, false));
102 | return new ItemStack(potionType);
103 | }
104 |
105 | if (input == Material.GLOWSTONE_DUST && type.isUpgradeable() && !data.isExtended()) {
106 | potion.setBasePotionData(new PotionData(type, false, true));
107 | return new ItemStack(potionType);
108 | }
109 |
110 | if (type == PotionType.AWKWARD) {
111 | PotionType potionRecipe = potionRecipes.get(input);
112 | if (potionRecipe != null) {
113 | potion.setBasePotionData(new PotionData(potionRecipe, false, false));
114 | return new ItemStack(potionType);
115 | }
116 | }
117 | }
118 |
119 | return null;
120 | }
121 |
122 | private boolean isPotion(@Nonnull Material mat) {
123 | return mat == Material.POTION || mat == Material.SPLASH_POTION || mat == Material.LINGERING_POTION;
124 | }
125 |
126 | static {
127 | potionRecipes.put(Material.SUGAR, PotionType.SPEED);
128 | potionRecipes.put(Material.RABBIT_FOOT, PotionType.JUMP);
129 | potionRecipes.put(Material.BLAZE_POWDER, PotionType.STRENGTH);
130 | potionRecipes.put(Material.GLISTERING_MELON_SLICE, PotionType.INSTANT_HEAL);
131 | potionRecipes.put(Material.SPIDER_EYE, PotionType.POISON);
132 | potionRecipes.put(Material.GHAST_TEAR, PotionType.REGEN);
133 | potionRecipes.put(Material.MAGMA_CREAM, PotionType.FIRE_RESISTANCE);
134 | potionRecipes.put(Material.PUFFERFISH, PotionType.WATER_BREATHING);
135 | potionRecipes.put(Material.GOLDEN_CARROT, PotionType.NIGHT_VISION);
136 | potionRecipes.put(Material.TURTLE_HELMET, PotionType.TURTLE_MASTER);
137 | potionRecipes.put(Material.PHANTOM_MEMBRANE, PotionType.SLOW_FALLING);
138 | fermentations.put(PotionType.SPEED, PotionType.SLOWNESS);
139 | fermentations.put(PotionType.JUMP, PotionType.SLOWNESS);
140 | fermentations.put(PotionType.INSTANT_HEAL, PotionType.INSTANT_DAMAGE);
141 | fermentations.put(PotionType.POISON, PotionType.INSTANT_DAMAGE);
142 | fermentations.put(PotionType.NIGHT_VISION, PotionType.INVISIBILITY);
143 | }
144 | }
145 |
--------------------------------------------------------------------------------
/src/main/java/org/lins/mmmjjkx/rykenslimefuncustomizer/objects/customs/machine/sf/AdvancedCropGrowthAccelerator.java:
--------------------------------------------------------------------------------
1 | package org.lins.mmmjjkx.rykenslimefuncustomizer.objects.customs.machine.sf;
2 |
3 | import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
4 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
5 | import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
6 | import io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.accelerators.CropGrowthAccelerator;
7 | import org.bukkit.inventory.ItemStack;
8 |
9 | public class AdvancedCropGrowthAccelerator extends CropGrowthAccelerator {
10 | private final int capacity;
11 | private final int radius;
12 | private final int energy_consumption;
13 | private final int speed;
14 |
15 | public AdvancedCropGrowthAccelerator(
16 | ItemGroup itemGroup,
17 | SlimefunItemStack item,
18 | RecipeType recipeType,
19 | ItemStack[] recipe,
20 | int capacity,
21 | int radius,
22 | int energy_consumption,
23 | int speed) {
24 | super(itemGroup, item, recipeType, recipe);
25 |
26 | this.capacity = capacity;
27 | this.radius = radius;
28 | this.energy_consumption = energy_consumption;
29 | this.speed = speed;
30 | }
31 |
32 | @Override
33 | public int getEnergyConsumption() {
34 | return energy_consumption;
35 | }
36 |
37 | @Override
38 | public int getRadius() {
39 | return radius;
40 | }
41 |
42 | @Override
43 | public int getSpeed() {
44 | return speed;
45 | }
46 |
47 | @Override
48 | public int getCapacity() {
49 | return capacity;
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/main/java/org/lins/mmmjjkx/rykenslimefuncustomizer/objects/customs/machine/sf/AdvancedProduceCollector.java:
--------------------------------------------------------------------------------
1 | package org.lins.mmmjjkx.rykenslimefuncustomizer.objects.customs.machine.sf;
2 |
3 | import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
4 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
5 | import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
6 | import io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.entities.AnimalProduce;
7 | import io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.entities.ProduceCollector;
8 | import org.bukkit.inventory.ItemStack;
9 | import org.jetbrains.annotations.NotNull;
10 |
11 | public class AdvancedProduceCollector extends ProduceCollector {
12 | private final int speed;
13 |
14 | public AdvancedProduceCollector(
15 | ItemGroup itemGroup, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe, int speed) {
16 | super(itemGroup, item, recipeType, recipe);
17 |
18 | this.speed = speed;
19 | }
20 |
21 | @Override
22 | public void addProduce(@NotNull AnimalProduce produce) {
23 | produce.setTicks(produce.getTicks() / speed);
24 | super.addProduce(produce);
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/main/java/org/lins/mmmjjkx/rykenslimefuncustomizer/objects/customs/machine/sf/AdvancedTreeGrowthAccelerator.java:
--------------------------------------------------------------------------------
1 | package org.lins.mmmjjkx.rykenslimefuncustomizer.objects.customs.machine.sf;
2 |
3 | import com.xzavier0722.mc.plugin.slimefun4.storage.util.StorageCacheUtils;
4 | import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
5 | import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
6 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
7 | import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
8 | import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
9 | import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
10 | import io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.accelerators.AbstractGrowthAccelerator;
11 | import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
12 | import io.github.thebusybiscuit.slimefun4.utils.itemstack.ItemStackWrapper;
13 | import javax.annotation.Nonnull;
14 | import javax.annotation.Nullable;
15 | import javax.annotation.ParametersAreNonnullByDefault;
16 | import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
17 | import org.bukkit.Particle;
18 | import org.bukkit.Tag;
19 | import org.bukkit.block.Block;
20 | import org.bukkit.block.BlockFace;
21 | import org.bukkit.block.data.type.Sapling;
22 | import org.bukkit.inventory.ItemStack;
23 |
24 | public class AdvancedTreeGrowthAccelerator extends AbstractGrowthAccelerator {
25 | private static final ItemStack organicFertilizer = ItemStackWrapper.wrap(SlimefunItems.FERTILIZER);
26 |
27 | private final int capacity;
28 | private final int radius;
29 | private final int energy_consumption;
30 |
31 | public AdvancedTreeGrowthAccelerator(
32 | ItemGroup itemGroup,
33 | SlimefunItemStack item,
34 | RecipeType recipeType,
35 | ItemStack[] recipe,
36 | int capacity,
37 | int radius,
38 | int energy_consumption) {
39 | super(itemGroup, item, recipeType, recipe);
40 |
41 | this.capacity = capacity;
42 | this.radius = radius;
43 | this.energy_consumption = energy_consumption;
44 | }
45 |
46 | @Override
47 | public int getCapacity() {
48 | return capacity;
49 | }
50 |
51 | protected void tick(@Nonnull Block b) {
52 | BlockMenu inv = StorageCacheUtils.getMenu(b.getLocation());
53 | if (inv != null) {
54 | if (this.getCharge(b.getLocation()) >= energy_consumption) {
55 | for (int x = -radius; x <= radius; ++x) {
56 | for (int z = -radius; z <= radius; ++z) {
57 | Block block = b.getRelative(x, 0, z);
58 | if (Tag.SAPLINGS.isTagged(block.getType())) {
59 | boolean isGrowthBoosted = this.tryToBoostGrowth(b, inv, block);
60 | if (isGrowthBoosted) {
61 | return;
62 | }
63 | }
64 | }
65 | }
66 | }
67 | }
68 | }
69 |
70 | @ParametersAreNonnullByDefault
71 | private boolean tryToBoostGrowth(Block machine, BlockMenu inv, Block sapling) {
72 | if (Slimefun.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_17)) {
73 | return this.applyBoneMeal(machine, sapling, inv);
74 | } else {
75 | Sapling saplingData = (Sapling) sapling.getBlockData();
76 | return saplingData.getStage() < saplingData.getMaximumStage()
77 | && this.updateSaplingData(machine, sapling, inv, saplingData);
78 | }
79 | }
80 |
81 | @ParametersAreNonnullByDefault
82 | private boolean applyBoneMeal(Block machine, Block sapling, BlockMenu inv) {
83 | int[] var4 = this.getInputSlots();
84 |
85 | for (int slot : var4) {
86 | if (this.isFertilizer(inv.getItemInSlot(slot))) {
87 | this.removeCharge(machine.getLocation(), energy_consumption);
88 | sapling.applyBoneMeal(BlockFace.UP);
89 | inv.consumeItem(slot);
90 | sapling.getWorld()
91 | .spawnParticle(
92 | Particle.VILLAGER_HAPPY,
93 | sapling.getLocation().add(0.5, 0.5, 0.5),
94 | 4,
95 | 0.10000000149011612,
96 | 0.10000000149011612,
97 | 0.10000000149011612);
98 | return true;
99 | }
100 | }
101 |
102 | return false;
103 | }
104 |
105 | @ParametersAreNonnullByDefault
106 | private boolean updateSaplingData(Block machine, Block block, BlockMenu inv, Sapling sapling) {
107 | int[] var5 = this.getInputSlots();
108 |
109 | for (int slot : var5) {
110 | if (this.isFertilizer(inv.getItemInSlot(slot))) {
111 | this.removeCharge(machine.getLocation(), 24);
112 | sapling.setStage(sapling.getStage() + 1);
113 | block.setBlockData(sapling, false);
114 | inv.consumeItem(slot);
115 | block.getWorld()
116 | .spawnParticle(
117 | Particle.VILLAGER_HAPPY,
118 | block.getLocation().add(0.5, 0.5, 0.5),
119 | 4,
120 | 0.10000000149011612,
121 | 0.10000000149011612,
122 | 0.10000000149011612);
123 | return true;
124 | }
125 | }
126 |
127 | return false;
128 | }
129 |
130 | protected boolean isFertilizer(@Nullable ItemStack item) {
131 | return SlimefunUtils.isItemSimilar(item, organicFertilizer, false, false);
132 | }
133 | }
134 |
--------------------------------------------------------------------------------
/src/main/java/org/lins/mmmjjkx/rykenslimefuncustomizer/objects/customs/parent/AbstractEmptyMachine.java:
--------------------------------------------------------------------------------
1 | package org.lins.mmmjjkx.rykenslimefuncustomizer.objects.customs.parent;
2 |
3 | import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
4 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem;
5 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
6 | import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
7 | import io.github.thebusybiscuit.slimefun4.core.attributes.MachineProcessHolder;
8 | import io.github.thebusybiscuit.slimefun4.core.machines.MachineOperation;
9 | import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.interfaces.InventoryBlock;
10 | import me.mrCookieSlime.Slimefun.Objects.handlers.BlockTicker;
11 | import org.bukkit.inventory.ItemStack;
12 |
13 | @SuppressWarnings("deprecation")
14 | public abstract class AbstractEmptyMachine extends SlimefunItem
15 | implements InventoryBlock, MachineProcessHolder {
16 | public AbstractEmptyMachine(
17 | ItemGroup itemGroup, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
18 | super(itemGroup, item, recipeType, recipe);
19 | }
20 |
21 | @Override
22 | public abstract BlockTicker getBlockTicker();
23 | }
24 |
--------------------------------------------------------------------------------
/src/main/java/org/lins/mmmjjkx/rykenslimefuncustomizer/objects/customs/parent/CustomItem.java:
--------------------------------------------------------------------------------
1 | package org.lins.mmmjjkx.rykenslimefuncustomizer.objects.customs.parent;
2 |
3 | import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
4 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem;
5 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
6 | import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
7 | import org.bukkit.inventory.ItemStack;
8 |
9 | public abstract class CustomItem extends SlimefunItem {
10 | public CustomItem(ItemGroup itemGroup, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe, ItemStack recipeOutput) {
11 | super(itemGroup, item, recipeType, recipe, recipeOutput);
12 | }
13 |
14 | public abstract Object[] constructorArgs();
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/org/lins/mmmjjkx/rykenslimefuncustomizer/objects/global/DropFromBlock.java:
--------------------------------------------------------------------------------
1 | package org.lins.mmmjjkx.rykenslimefuncustomizer.objects.global;
2 |
3 | import java.util.*;
4 | import org.bukkit.Material;
5 | import org.bukkit.inventory.ItemStack;
6 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.ProjectAddon;
7 |
8 | public class DropFromBlock {
9 | private static final Map> drops;
10 |
11 | static {
12 | drops = new HashMap<>();
13 | }
14 |
15 | public static void addDrop(Material material, Drop drop) {
16 | drops.computeIfAbsent(material, k -> new ArrayList<>()).add(drop);
17 | }
18 |
19 | public static List getDrops(Material material) {
20 | return drops.getOrDefault(material, Collections.emptyList());
21 | }
22 |
23 | public static void removeDrop(Material material, Drop drop) {
24 | List dropsList = getDrops(material);
25 | dropsList.remove(drop);
26 | if (dropsList.isEmpty()) {
27 | drops.remove(material);
28 | }
29 | }
30 |
31 | public static void unregisterAddonDrops(ProjectAddon addon) {
32 | for (Material material : new ArrayList<>(drops.keySet())) {
33 | List dropsList = getDrops(material);
34 | dropsList.removeIf(drop -> drop.owner.equals(addon));
35 | if (dropsList.isEmpty()) {
36 | drops.remove(material);
37 | }
38 | }
39 | }
40 |
41 | public record Drop(ItemStack itemStack, int dropChance, ProjectAddon owner, int minDropAmount, int maxDropAmount) {
42 | public Drop(ItemStack itemStack, int dropChance, ProjectAddon owner) {
43 | this(itemStack, dropChance, owner, itemStack.getAmount(), itemStack.getAmount());
44 | }
45 |
46 | @Override
47 | public ItemStack itemStack() {
48 | ItemStack itemStack = this.itemStack.clone();
49 | itemStack.setAmount(randomDropAmount());
50 | return itemStack;
51 | }
52 |
53 | private int randomDropAmount() {
54 | Random random = new Random();
55 | int min = Math.min(minDropAmount, maxDropAmount);
56 | int max = Math.max(minDropAmount, maxDropAmount);
57 | return random.nextInt(max - min + 1) + min;
58 | }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/main/java/org/lins/mmmjjkx/rykenslimefuncustomizer/objects/global/RecipeTypeMap.java:
--------------------------------------------------------------------------------
1 | package org.lins.mmmjjkx.rykenslimefuncustomizer.objects.global;
2 |
3 | import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
4 | import java.util.HashMap;
5 | import java.util.List;
6 | import java.util.Map;
7 | import org.bukkit.Bukkit;
8 | import org.jetbrains.annotations.Nullable;
9 |
10 | public class RecipeTypeMap {
11 | private static final Map recipeTypes;
12 |
13 | static {
14 | recipeTypes = new HashMap<>();
15 |
16 | RecipeTypeExpandIntegration.registerRecipeTypes();
17 | }
18 |
19 | public static void removeRecipeTypes(String... keys) {
20 | for (String key : keys) {
21 | recipeTypes.remove(key);
22 | }
23 | }
24 |
25 | public static void pushRecipeType(RecipeType type) {
26 | recipeTypes.put(type.getKey().getKey().toUpperCase(), type);
27 | }
28 |
29 | public static void pushRecipeType(List types) {
30 | types.forEach(RecipeTypeMap::pushRecipeType);
31 | }
32 |
33 | public static void clearRecipeTypes() {
34 | recipeTypes.clear();
35 | }
36 |
37 | @Nullable public static RecipeType getRecipeType(String s) {
38 | return recipeTypes.get(s);
39 | }
40 |
41 | private enum RecipeTypeExpandIntegration {
42 | INFINITY_EXPANSION("io.github.mooy1.infinityexpansion.items.blocks.InfinityWorkbench", "TYPE", true),
43 | SLIME_TINKER("io.github.sefiraat.slimetinker.items.workstations.workbench.Workbench", "TYPE", true);
44 |
45 | private final String clazz;
46 | private final String fieldName;
47 | private final boolean isStatic;
48 |
49 | RecipeTypeExpandIntegration(String clazz, String fieldName, boolean isStatic) {
50 | this.clazz = clazz;
51 | this.fieldName = fieldName;
52 | this.isStatic = isStatic;
53 | }
54 |
55 | static void registerRecipeTypes() {
56 | for (RecipeTypeExpandIntegration integration : values()) {
57 | String className = integration.clazz;
58 | String fieldName = integration.fieldName;
59 | try {
60 | Class> clazz = Class.forName(className);
61 | Object instance;
62 | if (integration.isStatic) {
63 | instance = clazz.getField(fieldName).get(null);
64 | } else {
65 | instance = clazz.newInstance(); // or something sus
66 | }
67 | if (instance instanceof RecipeType) {
68 | RecipeTypeMap.pushRecipeType((RecipeType) instance);
69 | }
70 | } catch (Exception e) {
71 | Bukkit.getLogger()
72 | .warning("Failed to get external recipe type from " + className + "#" + fieldName + ": "
73 | + e.getMessage());
74 | }
75 | }
76 | }
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/src/main/java/org/lins/mmmjjkx/rykenslimefuncustomizer/objects/machine/CustomCraftingOperation.java:
--------------------------------------------------------------------------------
1 | package org.lins.mmmjjkx.rykenslimefuncustomizer.objects.machine;
2 |
3 | import io.github.thebusybiscuit.slimefun4.implementation.operations.CraftingOperation;
4 | import io.github.thebusybiscuit.slimefun4.libraries.commons.lang.Validate;
5 | import javax.annotation.Nonnull;
6 | import lombok.Getter;
7 |
8 | @Getter
9 | public class CustomCraftingOperation extends CraftingOperation {
10 | private final CustomMachineRecipe recipe;
11 |
12 | public CustomCraftingOperation(@Nonnull CustomMachineRecipe recipe) {
13 | super(recipe.getInput(), recipe.getOutput(), recipe.getTicks());
14 | Validate.isTrue(
15 | recipe.getTicks() >= 0,
16 | "The amount of total ticks must be a positive integer or zero, received: " + recipe.getTicks());
17 | this.recipe = recipe;
18 | }
19 |
20 | public int getTotalTicks() {
21 | return recipe.getTicks();
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/main/java/org/lins/mmmjjkx/rykenslimefuncustomizer/objects/machine/CustomLinkedMachineOperation.java:
--------------------------------------------------------------------------------
1 | package org.lins.mmmjjkx.rykenslimefuncustomizer.objects.machine;
2 |
3 | import io.github.thebusybiscuit.slimefun4.implementation.operations.CraftingOperation;
4 | import io.github.thebusybiscuit.slimefun4.libraries.commons.lang.Validate;
5 | import javax.annotation.Nonnull;
6 | import lombok.Getter;
7 |
8 | @Getter
9 | public class CustomLinkedMachineOperation extends CraftingOperation {
10 | private final CustomLinkedMachineRecipe recipe;
11 |
12 | public CustomLinkedMachineOperation(@Nonnull CustomLinkedMachineRecipe recipe) {
13 | super(recipe.getInput(), recipe.getOutput(), recipe.getTicks());
14 | Validate.isTrue(
15 | recipe.getTicks() >= 0,
16 | "The amount of total ticks must be a positive integer or zero, received: " + recipe.getTicks());
17 | this.recipe = recipe;
18 | }
19 |
20 | public int getTotalTicks() {
21 | return recipe.getTicks();
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/main/java/org/lins/mmmjjkx/rykenslimefuncustomizer/objects/machine/CustomLinkedMachineRecipe.java:
--------------------------------------------------------------------------------
1 | package org.lins.mmmjjkx.rykenslimefuncustomizer.objects.machine;
2 |
3 | import java.util.Map;
4 | import lombok.Getter;
5 | import org.bukkit.inventory.ItemStack;
6 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.customs.LinkedOutput;
7 |
8 | @Getter
9 | public class CustomLinkedMachineRecipe extends CustomMachineRecipe {
10 | private final Map linkedInput;
11 | private final LinkedOutput linkedOutput;
12 |
13 | public CustomLinkedMachineRecipe(
14 | int seconds,
15 | Map input,
16 | LinkedOutput linkedOutput,
17 | boolean chooseOneIfHas,
18 | boolean forDisplay,
19 | boolean hide) {
20 | super(
21 | seconds,
22 | input.values().toArray(new ItemStack[0]),
23 | linkedOutput.toArray(),
24 | linkedOutput.chancesToArray(),
25 | chooseOneIfHas,
26 | forDisplay,
27 | hide);
28 | this.linkedInput = input;
29 | this.linkedOutput = linkedOutput;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/java/org/lins/mmmjjkx/rykenslimefuncustomizer/objects/machine/CustomMachineRecipe.java:
--------------------------------------------------------------------------------
1 | package org.lins.mmmjjkx.rykenslimefuncustomizer.objects.machine;
2 |
3 | import java.security.SecureRandom;
4 | import java.util.ArrayList;
5 | import java.util.List;
6 | import lombok.Getter;
7 | import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.MachineRecipe;
8 | import org.bukkit.inventory.ItemStack;
9 |
10 | @Getter
11 | public class CustomMachineRecipe extends MachineRecipe {
12 | private final List chances;
13 |
14 | private final boolean chooseOneIfHas;
15 | private final boolean forDisplay;
16 | private final boolean hide;
17 |
18 | public CustomMachineRecipe(
19 | int seconds,
20 | ItemStack[] input,
21 | ItemStack[] output,
22 | List chances,
23 | boolean chooseOneIfHas,
24 | boolean forDisplay,
25 | boolean hide) {
26 | super(seconds, input.clone(), output.clone());
27 |
28 | this.chances = chances;
29 | this.chooseOneIfHas = chooseOneIfHas;
30 | this.forDisplay = forDisplay;
31 | this.hide = hide;
32 | }
33 |
34 | public List getMatchChanceResult() {
35 | List itemStacks = new ArrayList<>();
36 |
37 | for (int i = 0; i < getOutput().length; i++) {
38 | ItemStack output = getOutput()[i];
39 | int chance = chances.get(i);
40 | if (matchChance(chance)) {
41 | itemStacks.add(output);
42 | }
43 | }
44 |
45 | return itemStacks;
46 | }
47 |
48 | private boolean matchChance(Integer chance) {
49 | if (chance == null) return false;
50 | if (chance >= 100) return true;
51 | if (chance < 1) return false;
52 |
53 | int result = new SecureRandom().nextInt(100);
54 | return result < chance;
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/main/java/org/lins/mmmjjkx/rykenslimefuncustomizer/objects/machine/CustomTemplateCraftingOperation.java:
--------------------------------------------------------------------------------
1 | package org.lins.mmmjjkx.rykenslimefuncustomizer.objects.machine;
2 |
3 | import io.github.thebusybiscuit.slimefun4.core.machines.MachineOperation;
4 | import io.github.thebusybiscuit.slimefun4.libraries.commons.lang.Validate;
5 | import lombok.Getter;
6 |
7 | public class CustomTemplateCraftingOperation implements MachineOperation {
8 | @Getter
9 | private final CustomMachineRecipe recipe;
10 |
11 | @Getter
12 | private final MachineTemplate template;
13 |
14 | private final int ticks;
15 | private int currentTicks;
16 |
17 | public CustomTemplateCraftingOperation(MachineTemplate template, CustomMachineRecipe recipe, int totalTicks) {
18 | this.currentTicks = 0;
19 | Validate.isTrue(recipe.getOutput().length != 0, "The recipe must have at least one output.");
20 | Validate.isTrue(
21 | totalTicks >= 0,
22 | "The amount of total ticks must be a positive integer or zero, received: " + totalTicks);
23 | this.recipe = recipe;
24 | this.ticks = totalTicks;
25 | this.template = template;
26 | }
27 |
28 | public void addProgress(int num) {
29 | Validate.isTrue(num > 0, "Progress must be positive.");
30 | this.currentTicks += num;
31 | }
32 |
33 | public int getProgress() {
34 | return this.currentTicks;
35 | }
36 |
37 | public int getTotalTicks() {
38 | return ticks;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/java/org/lins/mmmjjkx/rykenslimefuncustomizer/objects/machine/MachineInfo.java:
--------------------------------------------------------------------------------
1 | package org.lins.mmmjjkx.rykenslimefuncustomizer.objects.machine;
2 |
3 | import com.xzavier0722.mc.plugin.slimefun4.storage.controller.SlimefunBlockData;
4 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem;
5 | import io.github.thebusybiscuit.slimefun4.core.machines.MachineOperation;
6 | import io.github.thebusybiscuit.slimefun4.core.machines.MachineProcessor;
7 | import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
8 | import org.bukkit.block.Block;
9 | import org.bukkit.inventory.Inventory;
10 | import org.jetbrains.annotations.Nullable;
11 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.customs.machine.CustomMachine;
12 |
13 | /**
14 | * This data class provides access to machine data for JavaScript integration.
15 | *
16 | * @param blockMenu the menu of the machine, may be null if the machine has no GUI.
17 | * @param data the persistent data of the machine.
18 | * @param machineItem the {@link SlimefunItem} instance of the machine.
19 | * @param block the physical {@link Block} instance of the machine.
20 | * @param processor the {@link MachineProcessor} handling the machine's logic.
21 | * @param operation the current {@link MachineOperation}, ALWAYS be null so far...
22 | * @param machine the {@link CustomMachine} instance defining the machine's behavior.
23 | * @author lijinhong11
24 | *
25 | * JavaScript Usage Example:
26 | * {@code
27 | * function tick(info) {
28 | * // May be null
29 | * var menu = info.blockMenu();
30 | * // Access Java fields in JavaScript should like this:
31 | * // var yourObjectName = info.();
32 | * // For example:
33 | * // var block = info.block();
34 | *
35 | * if (menu !== null) {
36 | * // See Slimefun API for more details
37 | * var item = blockMenu.getItemInSlot(0);
38 | * }
39 | *
40 | * // Displayed name
41 | * var itemName = info.machineItem().getItemName();
42 | * }
43 | * }
44 | */
45 | public record MachineInfo(
46 | @Nullable BlockMenu blockMenu,
47 | SlimefunBlockData data,
48 | SlimefunItem machineItem,
49 | Block block,
50 | MachineProcessor> processor,
51 | MachineOperation operation,
52 | CustomMachine machine) {
53 |
54 | public Inventory getInventory() {
55 | if (blockMenu == null) {
56 | return null;
57 | }
58 | return blockMenu.getInventory();
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/main/java/org/lins/mmmjjkx/rykenslimefuncustomizer/objects/machine/MachineRecord.java:
--------------------------------------------------------------------------------
1 | package org.lins.mmmjjkx.rykenslimefuncustomizer.objects.machine;
2 |
3 | public record MachineRecord(int capacity) {}
4 |
--------------------------------------------------------------------------------
/src/main/java/org/lins/mmmjjkx/rykenslimefuncustomizer/objects/machine/MachineTemplate.java:
--------------------------------------------------------------------------------
1 | package org.lins.mmmjjkx.rykenslimefuncustomizer.objects.machine;
2 |
3 | import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
4 | import java.util.List;
5 | import org.bukkit.inventory.ItemStack;
6 |
7 | public record MachineTemplate(ItemStack template, List recipes) {
8 | public boolean isItemSimilar(ItemStack item) {
9 | return SlimefunUtils.isItemSimilar(item, template, true);
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/main/java/org/lins/mmmjjkx/rykenslimefuncustomizer/objects/machine/ScriptedEvalBreakHandler.java:
--------------------------------------------------------------------------------
1 | package org.lins.mmmjjkx.rykenslimefuncustomizer.objects.machine;
2 |
3 | import com.xzavier0722.mc.plugin.slimefun4.storage.util.StorageCacheUtils;
4 | import io.github.thebusybiscuit.slimefun4.core.handlers.BlockBreakHandler;
5 | import java.util.List;
6 | import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.interfaces.InventoryBlock;
7 | import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
8 | import org.bukkit.Location;
9 | import org.bukkit.block.Block;
10 | import org.bukkit.event.block.BlockBreakEvent;
11 | import org.bukkit.inventory.ItemStack;
12 | import org.jetbrains.annotations.NotNull;
13 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.script.ScriptEval;
14 |
15 | @SuppressWarnings("deprecation")
16 | public class ScriptedEvalBreakHandler extends BlockBreakHandler {
17 | private final ScriptEval eval;
18 | private final InventoryBlock machine;
19 |
20 | public ScriptedEvalBreakHandler(InventoryBlock machine, ScriptEval eval) {
21 | super(false, false);
22 |
23 | this.eval = eval;
24 | this.machine = machine;
25 | }
26 |
27 | @Override
28 | public void onPlayerBreak(
29 | BlockBreakEvent blockBreakEvent, @NotNull ItemStack itemStack, @NotNull List list) {
30 | Block block = blockBreakEvent.getBlock();
31 | Location loc = block.getLocation();
32 | BlockMenu bm = StorageCacheUtils.getMenu(loc);
33 | if (bm != null) {
34 | if (machine.getInputSlots().length > 0) {
35 | bm.dropItems(loc, machine.getInputSlots());
36 | }
37 | if (machine.getOutputSlots().length > 0) {
38 | bm.dropItems(loc, machine.getOutputSlots());
39 | }
40 | }
41 |
42 | if (eval != null) {
43 | eval.evalFunction("onBreak", blockBreakEvent, itemStack, list);
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/main/java/org/lins/mmmjjkx/rykenslimefuncustomizer/objects/machine/SimpleMachineType.java:
--------------------------------------------------------------------------------
1 | package org.lins.mmmjjkx.rykenslimefuncustomizer.objects.machine;
2 |
3 | import lombok.Getter;
4 |
5 | @Getter
6 | public enum SimpleMachineType {
7 | ELECTRIC_SMELTERY(true),
8 | ELECTRIC_FURNACE(true),
9 | ELECTRIC_GOLD_PAN(true),
10 | ELECTRIC_DUST_WASHER(true),
11 | ELECTRIC_ORE_GRINDER(true),
12 | ELECTRIC_INGOT_FACTORY(true),
13 | ELECTRIC_INGOT_PULVERIZER(true),
14 | CHARGING_BENCH(true),
15 | ANIMAL_GROWTH_ACCELERATOR(true),
16 | TREE_GROWTH_ACCELERATOR(true),
17 | CROP_GROWTH_ACCELERATOR(true),
18 | FREEZER(true),
19 | CARBON_PRESS(true),
20 | ELECTRIC_PRESS(true),
21 | ELECTRIC_CRUCIBLE(true),
22 | FOOD_FABRICATOR(true),
23 | HEATED_PRESSURE_CHAMBER(true),
24 | AUTO_ENCHANTER(true),
25 | AUTO_DISENCHANTER(true),
26 | BOOK_BINDER(true),
27 | AUTO_ANVIL(true),
28 | AUTO_DRIER(true),
29 | AUTO_BREWER(true),
30 | REFINERY(true),
31 | PRODUCE_COLLECTOR(true);
32 |
33 | private final boolean energy;
34 |
35 | SimpleMachineType(boolean energy) {
36 | this.energy = energy;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/org/lins/mmmjjkx/rykenslimefuncustomizer/objects/machine/SmallerMachineInfo.java:
--------------------------------------------------------------------------------
1 | package org.lins.mmmjjkx.rykenslimefuncustomizer.objects.machine;
2 |
3 | import com.xzavier0722.mc.plugin.slimefun4.storage.controller.SlimefunBlockData;
4 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem;
5 | import io.github.thebusybiscuit.slimefun4.core.machines.MachineProcessor;
6 | import javax.annotation.Nullable;
7 | import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
8 | import org.bukkit.block.Block;
9 | import org.bukkit.inventory.Inventory;
10 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.customs.machine.CustomNoEnergyMachine;
11 |
12 | public record SmallerMachineInfo(
13 | @Nullable BlockMenu blockMenu,
14 | SlimefunBlockData data,
15 | CustomNoEnergyMachine machine,
16 | SlimefunItem machineItem,
17 | Block block,
18 | MachineProcessor> processor) {
19 |
20 | public Inventory getInventory() {
21 | if (blockMenu == null) {
22 | return null;
23 | }
24 | return blockMenu.getInventory();
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/main/java/org/lins/mmmjjkx/rykenslimefuncustomizer/objects/script/ban/CommandSafe.java:
--------------------------------------------------------------------------------
1 | package org.lins.mmmjjkx.rykenslimefuncustomizer.objects.script.ban;
2 |
3 | import java.util.List;
4 |
5 | public class CommandSafe {
6 | private static final List badCommands = List.of(
7 | "stop",
8 | "restart",
9 | "op",
10 | "deop",
11 | "whitelist",
12 | "ban-ip",
13 | "banlist",
14 | "pardon",
15 | "kick",
16 | "ban",
17 | "pardon-ip",
18 | "save-all",
19 | "unban",
20 | "luckperms",
21 | "lp",
22 | "cmi:ban",
23 | "cmi:pardon",
24 | "cmi:banlist",
25 | "cmi:unban",
26 | "essentials:ban",
27 | "essentials:pardon",
28 | "essentials:banlist",
29 | "essentials:unban",
30 | "essentials:mute",
31 | "essentials:unmute",
32 | "essentials:jail",
33 | "essentials:unjail",
34 | "cmi:jail",
35 | "cmi:unjail",
36 | "cmi:mute",
37 | "cmi:unmute",
38 | "essentials:sudo",
39 | "cmi:sudo");
40 |
41 | public static boolean isBadCommand(String command) {
42 | return badCommands.contains(command.toLowerCase());
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/main/java/org/lins/mmmjjkx/rykenslimefuncustomizer/objects/script/enhanced/NBTAPIIntegration.java:
--------------------------------------------------------------------------------
1 | package org.lins.mmmjjkx.rykenslimefuncustomizer.objects.script.enhanced;
2 |
3 | import de.tr7zw.nbtapi.*;
4 | import de.tr7zw.nbtapi.iface.ReadWriteNBT;
5 | import org.bukkit.block.Block;
6 | import org.bukkit.entity.Entity;
7 | import org.bukkit.inventory.ItemStack;
8 |
9 | public class NBTAPIIntegration {
10 | public static NBTAPIIntegration instance = new NBTAPIIntegration();
11 |
12 | private NBTAPIIntegration() {}
13 |
14 | public ReadWriteNBT readItem(ItemStack item) {
15 | return NBT.itemStackToNBT(item);
16 | }
17 |
18 | public NBTCompound getOrCreateCompound(NBTCompound parent, String name) {
19 | return parent.getOrCreateCompound(name);
20 | }
21 |
22 | public NBTCompound readBlock(Block block) {
23 | return new NBTBlock(block).getData();
24 | }
25 |
26 | public ReadWriteNBT readEntity(Entity entity) {
27 | ReadWriteNBT entityNbt = NBT.createNBTObject();
28 | NBT.get(entity, entityNbt::mergeCompound);
29 | return entityNbt;
30 | }
31 |
32 | public ReadWriteNBT createCompound() {
33 | return NBT.createNBTObject();
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/org/lins/mmmjjkx/rykenslimefuncustomizer/objects/script/lambda/CiConsumer.java:
--------------------------------------------------------------------------------
1 | package org.lins.mmmjjkx.rykenslimefuncustomizer.objects.script.lambda;
2 |
3 | @FunctionalInterface
4 | public interface CiConsumer {
5 | void accept(A a, B b, C c);
6 | }
7 |
--------------------------------------------------------------------------------
/src/main/java/org/lins/mmmjjkx/rykenslimefuncustomizer/objects/script/lambda/CiFunction.java:
--------------------------------------------------------------------------------
1 | package org.lins.mmmjjkx.rykenslimefuncustomizer.objects.script.lambda;
2 |
3 | @FunctionalInterface
4 | public interface CiFunction {
5 | R apply(A a, B b, C c);
6 | }
7 |
--------------------------------------------------------------------------------
/src/main/java/org/lins/mmmjjkx/rykenslimefuncustomizer/objects/script/lambda/RSCClickHandler.java:
--------------------------------------------------------------------------------
1 | package org.lins.mmmjjkx.rykenslimefuncustomizer.objects.script.lambda;
2 |
3 | import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu;
4 | import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ClickAction;
5 | import org.bukkit.entity.Player;
6 | import org.bukkit.inventory.ItemStack;
7 |
8 | @SuppressWarnings("deprecation")
9 | @FunctionalInterface
10 | public interface RSCClickHandler extends ChestMenu.MenuClickHandler {
11 | void mainFunction(Player player, int slot, ItemStack itemStack, ClickAction action);
12 |
13 | default boolean onClick(Player var1, int var2, ItemStack var3, ClickAction var4) {
14 | mainFunction(var1, var2, var3, var4);
15 | andThen(var1, var2, var3, var4);
16 | return false;
17 | }
18 |
19 | default void andThen(Player player, int slot, ItemStack itemStack, ClickAction action) {}
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/java/org/lins/mmmjjkx/rykenslimefuncustomizer/objects/slimefun/AdvancedNestedItemGroup.java:
--------------------------------------------------------------------------------
1 | package org.lins.mmmjjkx.rykenslimefuncustomizer.objects.slimefun;
2 |
3 | import io.github.thebusybiscuit.slimefun4.api.items.groups.NestedItemGroup;
4 | import io.github.thebusybiscuit.slimefun4.api.items.groups.SubItemGroup;
5 | import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile;
6 | import io.github.thebusybiscuit.slimefun4.core.guide.GuideHistory;
7 | import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuide;
8 | import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideMode;
9 | import io.github.thebusybiscuit.slimefun4.core.services.sounds.SoundEffect;
10 | import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
11 | import io.github.thebusybiscuit.slimefun4.implementation.guide.SurvivalSlimefunGuide;
12 | import io.github.thebusybiscuit.slimefun4.libraries.dough.items.CustomItemStack;
13 | import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils;
14 | import java.util.ArrayList;
15 | import java.util.List;
16 | import java.util.Objects;
17 | import javax.annotation.Nonnull;
18 | import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu;
19 | import org.bukkit.ChatColor;
20 | import org.bukkit.NamespacedKey;
21 | import org.bukkit.entity.Player;
22 | import org.bukkit.inventory.ItemStack;
23 | import org.lins.mmmjjkx.rykenslimefuncustomizer.utils.ExceptionHandler;
24 |
25 | public class AdvancedNestedItemGroup extends NestedItemGroup {
26 | private final List subGroups;
27 |
28 | public AdvancedNestedItemGroup(NamespacedKey key, ItemStack item, int tier) {
29 | super(key, item, tier);
30 |
31 | ExceptionHandler.debugLog("创建物品组: " + key);
32 |
33 | subGroups = new ArrayList<>();
34 | }
35 |
36 | @Override
37 | public void open(Player p, PlayerProfile profile, SlimefunGuideMode mode) {
38 | setup(p, profile, mode, 1);
39 | }
40 |
41 | public void addSubGroup(@Nonnull SubItemGroup group) {
42 | super.addSubGroup(group);
43 |
44 | this.subGroups.add(group);
45 | }
46 |
47 | public void removeSubGroup(@Nonnull SubItemGroup group) {
48 | super.removeSubGroup(group);
49 |
50 | this.subGroups.remove(group);
51 | }
52 |
53 | @SuppressWarnings("deprecation")
54 | private void setup(Player p, PlayerProfile profile, SlimefunGuideMode mode, int page) {
55 | GuideHistory history = profile.getGuideHistory();
56 | if (mode == SlimefunGuideMode.SURVIVAL_MODE) {
57 | history.add(this, page);
58 | }
59 |
60 | ChestMenu menu = new ChestMenu(Slimefun.getLocalization().getMessage(p, "guide.title.main"));
61 | SurvivalSlimefunGuide guide =
62 | (SurvivalSlimefunGuide) Slimefun.getRegistry().getSlimefunGuide(mode);
63 | menu.setEmptySlotsClickable(false);
64 | SoundEffect var10001 = SoundEffect.GUIDE_BUTTON_CLICK_SOUND;
65 | Objects.requireNonNull(var10001);
66 | menu.addMenuOpeningHandler(var10001::playFor);
67 | guide.createHeader(p, profile, menu);
68 | menu.addItem(
69 | 1,
70 | new CustomItemStack(ChestMenuUtils.getBackButton(
71 | p, "", ChatColor.GRAY + Slimefun.getLocalization().getMessage(p, "guide.back.guide"))));
72 | menu.addMenuClickHandler(1, (pl, s, is, action) -> {
73 | SlimefunGuide.openMainMenu(profile, mode, history.getMainMenuPage());
74 | return false;
75 | });
76 |
77 | int index = 9;
78 | int target = 36 * (page - 1) - 1;
79 |
80 | while (target < this.subGroups.size() - 1 && index < 45) {
81 | ++target;
82 | SubItemGroup itemGroup = this.subGroups.get(target);
83 | if (itemGroup.isVisibleInNested(p)) {
84 | menu.addItem(index, itemGroup.getItem(p));
85 | menu.addMenuClickHandler(index, (pl, slot, item, action) -> {
86 | if (itemGroup instanceof ItemGroupButton button) {
87 | button.run(p, slot, item, action, mode);
88 | return false;
89 | }
90 | SlimefunGuide.openItemGroup(profile, itemGroup, mode, 1);
91 | return false;
92 | });
93 | ++index;
94 | }
95 | }
96 |
97 | int pages = target == this.subGroups.size() - 1 ? page : (this.subGroups.size() - 1) / 36 + 1;
98 | menu.addItem(46, ChestMenuUtils.getPreviousButton(p, page, pages));
99 | menu.addMenuClickHandler(46, (pl, slot, item, action) -> {
100 | int next = page - 1;
101 | if (next > 0) {
102 | setup(p, profile, mode, next);
103 | }
104 |
105 | return false;
106 | });
107 | menu.addItem(52, ChestMenuUtils.getNextButton(p, page, pages));
108 | menu.addMenuClickHandler(52, (pl, slot, item, action) -> {
109 | int next = page + 1;
110 | if (next <= pages) {
111 | setup(p, profile, mode, next);
112 | }
113 |
114 | return false;
115 | });
116 | menu.open(p);
117 | }
118 | }
119 |
--------------------------------------------------------------------------------
/src/main/java/org/lins/mmmjjkx/rykenslimefuncustomizer/objects/slimefun/AsyncChanceRecipeTask.java:
--------------------------------------------------------------------------------
1 | package org.lins.mmmjjkx.rykenslimefuncustomizer.objects.slimefun;
2 |
3 | import io.github.thebusybiscuit.slimefun4.libraries.commons.lang.Validate;
4 | import io.github.thebusybiscuit.slimefun4.libraries.dough.collections.LoopIterator;
5 | import java.util.HashMap;
6 | import java.util.List;
7 | import java.util.Map;
8 | import java.util.concurrent.locks.ReadWriteLock;
9 | import java.util.concurrent.locks.ReentrantReadWriteLock;
10 | import javax.annotation.Nonnull;
11 | import org.bukkit.Bukkit;
12 | import org.bukkit.inventory.Inventory;
13 | import org.bukkit.inventory.ItemStack;
14 | import org.lins.mmmjjkx.rykenslimefuncustomizer.RykenSlimefunCustomizer;
15 |
16 | public class AsyncChanceRecipeTask implements Runnable {
17 | private static final int UPDATE_INTERVAL = 15;
18 | private final Map> iterators = new HashMap<>();
19 | private final ReadWriteLock lock = new ReentrantReadWriteLock();
20 | private Inventory inventory;
21 | private int id;
22 |
23 | public AsyncChanceRecipeTask() {}
24 |
25 | public void start(@Nonnull Inventory inv) {
26 | Validate.notNull(inv, "Inventory must not be null");
27 | this.inventory = inv;
28 | this.id = Bukkit.getScheduler()
29 | .runTaskTimerAsynchronously(RykenSlimefunCustomizer.INSTANCE, this, 0L, 14L)
30 | .getTaskId();
31 | }
32 |
33 | public void add(int slot, @Nonnull List item) {
34 | Validate.notNull(item, "Cannot add a null list of ItemStacks");
35 | this.lock.writeLock().lock();
36 |
37 | try {
38 | this.iterators.put(slot, new LoopIterator<>(item));
39 | } finally {
40 | this.lock.writeLock().unlock();
41 | }
42 | }
43 |
44 | public boolean isEmpty() {
45 | this.lock.readLock().lock();
46 |
47 | boolean var1;
48 | try {
49 | var1 = this.iterators.isEmpty();
50 | } finally {
51 | this.lock.readLock().unlock();
52 | }
53 |
54 | return var1;
55 | }
56 |
57 | public void clear() {
58 | this.lock.writeLock().lock();
59 |
60 | try {
61 | this.iterators.clear();
62 | } finally {
63 | this.lock.writeLock().unlock();
64 | }
65 | }
66 |
67 | public void run() {
68 | if (this.inventory.getViewers().isEmpty()) {
69 | Bukkit.getScheduler().cancelTask(this.id);
70 | } else {
71 | this.lock.readLock().lock();
72 |
73 | try {
74 | for (Map.Entry> entry : this.iterators.entrySet()) {
75 | this.inventory.setItem(entry.getKey(), entry.getValue().next());
76 | }
77 | } finally {
78 | this.lock.readLock().unlock();
79 | }
80 | }
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/src/main/java/org/lins/mmmjjkx/rykenslimefuncustomizer/objects/slimefun/WitherProofBlockImpl.java:
--------------------------------------------------------------------------------
1 | package org.lins.mmmjjkx.rykenslimefuncustomizer.objects.slimefun;
2 |
3 | import io.github.thebusybiscuit.slimefun4.core.attributes.WitherProof;
4 | import javax.annotation.Nonnull;
5 | import org.bukkit.block.Block;
6 | import org.bukkit.entity.Wither;
7 |
8 | public interface WitherProofBlockImpl extends WitherProof {
9 | default void onAttack(@Nonnull Block var1, @Nonnull Wither var2) {}
10 | }
11 |
--------------------------------------------------------------------------------
/src/main/java/org/lins/mmmjjkx/rykenslimefuncustomizer/objects/yaml/ItemGroupReader.java:
--------------------------------------------------------------------------------
1 | package org.lins.mmmjjkx.rykenslimefuncustomizer.objects.yaml;
2 |
3 | import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
4 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
5 | import io.github.thebusybiscuit.slimefun4.api.items.groups.LockedItemGroup;
6 | import io.github.thebusybiscuit.slimefun4.api.items.groups.NestedItemGroup;
7 | import io.github.thebusybiscuit.slimefun4.api.items.groups.SeasonalItemGroup;
8 | import io.github.thebusybiscuit.slimefun4.api.items.groups.SubItemGroup;
9 | import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
10 | import java.time.Month;
11 | import java.util.ArrayList;
12 | import java.util.List;
13 | import org.bukkit.NamespacedKey;
14 | import org.bukkit.configuration.ConfigurationSection;
15 | import org.bukkit.configuration.file.YamlConfiguration;
16 | import org.bukkit.inventory.ItemStack;
17 | import org.lins.mmmjjkx.rykenslimefuncustomizer.RykenSlimefunCustomizer;
18 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.ProjectAddon;
19 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.slimefun.AdvancedNestedItemGroup;
20 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.slimefun.ItemGroupButton;
21 | import org.lins.mmmjjkx.rykenslimefuncustomizer.utils.CommonUtils;
22 | import org.lins.mmmjjkx.rykenslimefuncustomizer.utils.ExceptionHandler;
23 |
24 | public class ItemGroupReader extends YamlReader {
25 | public ItemGroupReader(YamlConfiguration config, ProjectAddon addon) {
26 | super(config, addon);
27 | }
28 |
29 | @Override
30 | public ItemGroup readEach(String s) {
31 | ConfigurationSection section = configuration.getConfigurationSection(s);
32 | if (section == null) return null;
33 | ExceptionHandler.HandleResult conflict = ExceptionHandler.handleGroupIdConflict(s);
34 |
35 | if (conflict == ExceptionHandler.HandleResult.FAILED) return null;
36 |
37 | ConfigurationSection item = section.getConfigurationSection("item");
38 | ItemStack stack = CommonUtils.readItem(item, false, addon);
39 | if (stack == null) {
40 | ExceptionHandler.handleError("在附属" + addon.getAddonId() + "中加载物品组" + s + "时遇到了问题: " + "物品为空或格式错误导致无法加载");
41 | return null;
42 | }
43 |
44 | String type = section.getString("type", "");
45 | NamespacedKey key = new NamespacedKey(RykenSlimefunCustomizer.INSTANCE, s);
46 |
47 | int tier = section.getInt("tier", 3);
48 |
49 | ItemGroup group =
50 | switch (type) {
51 | default -> new ItemGroup(key, stack, tier);
52 | case "sub" -> {
53 | NamespacedKey parent = new NamespacedKey(
54 | RykenSlimefunCustomizer.INSTANCE,
55 | section.getString("parent", "").toLowerCase());
56 | ItemGroup raw = CommonUtils.getIf(Slimefun.getRegistry().getAllItemGroups(), ig -> ig.getKey()
57 | .equals(parent));
58 | if (raw == null) {
59 | ExceptionHandler.handleError("在附属" + addon.getAddonId() + "中加载物品组" + s + "时遇到了问题: "
60 | + "无法找到父物品组" + parent.getKey());
61 | yield null;
62 | }
63 | if (!(raw instanceof NestedItemGroup nig)) {
64 | ExceptionHandler.handleError("在附属" + addon.getAddonId() + "中加载物品组" + s + "时遇到了问题: " + "物品组"
65 | + parent.getKey() + "不是一个嵌套物品组");
66 | yield null;
67 | }
68 |
69 | yield new SubItemGroup(key, nig, stack, tier);
70 | }
71 | case "locked" -> {
72 | List parents = new ArrayList<>();
73 | for (String ig : section.getStringList("parents")) {
74 | NamespacedKey nk = NamespacedKey.fromString(ig);
75 | if (nk == null) {
76 | ExceptionHandler.handleWarning("在附属" + addon.getAddonId() + "中加载物品组" + s + "时遇到了问题: "
77 | + ig + "不是一个有效的NamespacedKey");
78 | continue;
79 | }
80 | parents.add(nk);
81 | }
82 |
83 | yield new LockedItemGroup(key, stack, tier, parents.toArray(new NamespacedKey[] {}));
84 | }
85 | case "nested", "parent" -> new AdvancedNestedItemGroup(key, stack, tier);
86 | case "seasonal" -> {
87 | Month month = Month.of(section.getInt("month", 1));
88 | yield new SeasonalItemGroup(key, month, tier, stack);
89 | }
90 | case "button" -> {
91 | NamespacedKey parent = new NamespacedKey(
92 | RykenSlimefunCustomizer.INSTANCE,
93 | section.getString("parent", "").toLowerCase());
94 | ItemGroup raw = CommonUtils.getIf(Slimefun.getRegistry().getAllItemGroups(), ig -> ig.getKey()
95 | .equals(parent));
96 | if (raw == null) {
97 | ExceptionHandler.handleError("在附属" + addon.getAddonId() + "中加载物品组" + s + "时遇到了问题: "
98 | + "无法找到父物品组" + parent.getKey());
99 | yield null;
100 | }
101 |
102 | if (!(raw instanceof AdvancedNestedItemGroup nig)) {
103 | ExceptionHandler.handleError("在附属" + addon.getAddonId() + "中加载物品组" + s + "时遇到了问题: " + "物品组"
104 | + parent.getKey() + "不是一个来自RSC的嵌套物品组");
105 | yield null;
106 | }
107 |
108 | List actions = section.getStringList("actions");
109 |
110 | yield new ItemGroupButton(addon, key, nig, stack, tier, actions);
111 | }
112 | };
113 |
114 | if (group != null) {
115 | group.register(RykenSlimefunCustomizer.INSTANCE);
116 | }
117 |
118 | return group;
119 | }
120 |
121 | // 物品组不需要预加载物品
122 | @Override
123 | public List preloadItems(String s) {
124 | return List.of();
125 | }
126 | }
127 |
--------------------------------------------------------------------------------
/src/main/java/org/lins/mmmjjkx/rykenslimefuncustomizer/objects/yaml/RecipeTypesReader.java:
--------------------------------------------------------------------------------
1 | package org.lins.mmmjjkx.rykenslimefuncustomizer.objects.yaml;
2 |
3 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
4 | import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
5 | import java.util.List;
6 | import org.bukkit.NamespacedKey;
7 | import org.bukkit.configuration.ConfigurationSection;
8 | import org.bukkit.configuration.file.YamlConfiguration;
9 | import org.bukkit.inventory.ItemStack;
10 | import org.lins.mmmjjkx.rykenslimefuncustomizer.RykenSlimefunCustomizer;
11 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.ProjectAddon;
12 | import org.lins.mmmjjkx.rykenslimefuncustomizer.utils.CommonUtils;
13 | import org.lins.mmmjjkx.rykenslimefuncustomizer.utils.ExceptionHandler;
14 |
15 | public class RecipeTypesReader extends YamlReader {
16 | public RecipeTypesReader(YamlConfiguration config, ProjectAddon addon) {
17 | super(config, addon);
18 | }
19 |
20 | @Override
21 | public RecipeType readEach(String s) {
22 | ConfigurationSection configurationSection = configuration.getConfigurationSection(s);
23 | if (configurationSection == null) return null;
24 |
25 | ItemStack item = CommonUtils.readItem(configurationSection, false, addon);
26 | if (item == null) {
27 | ExceptionHandler.handleError("在附属" + addon.getAddonId() + "中加载配方类型" + s + "时遇到了问题: " + "物品为空或格式错误导致无法加载");
28 | return null;
29 | }
30 |
31 | return new RecipeType(new NamespacedKey(RykenSlimefunCustomizer.INSTANCE, s.toLowerCase()), item);
32 | }
33 |
34 | // 配方类型不需要预加载物品
35 | @Override
36 | public List preloadItems(String s) {
37 | return List.of();
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/org/lins/mmmjjkx/rykenslimefuncustomizer/objects/yaml/ResearchReader.java:
--------------------------------------------------------------------------------
1 | package org.lins.mmmjjkx.rykenslimefuncustomizer.objects.yaml;
2 |
3 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem;
4 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
5 | import io.github.thebusybiscuit.slimefun4.api.researches.Research;
6 | import java.util.List;
7 | import java.util.regex.Pattern;
8 | import org.bukkit.NamespacedKey;
9 | import org.bukkit.configuration.ConfigurationSection;
10 | import org.bukkit.configuration.file.YamlConfiguration;
11 | import org.lins.mmmjjkx.rykenslimefuncustomizer.RykenSlimefunCustomizer;
12 | import org.lins.mmmjjkx.rykenslimefuncustomizer.libraries.colors.CMIChatColor;
13 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.ProjectAddon;
14 | import org.lins.mmmjjkx.rykenslimefuncustomizer.utils.ExceptionHandler;
15 |
16 | public class ResearchReader extends YamlReader {
17 | private static final Pattern VALID_KEY = Pattern.compile("[a-z0-9/._-]+");
18 |
19 | public ResearchReader(YamlConfiguration config, ProjectAddon addon) {
20 | super(config, addon);
21 | }
22 |
23 | @Override
24 | public Research readEach(String s) {
25 | ConfigurationSection section = configuration.getConfigurationSection(s);
26 | if (section == null) return null;
27 |
28 | if (!VALID_KEY.matcher(s).matches()) {
29 | ExceptionHandler.handleError(
30 | "在附属" + addon.getAddonId() + "中加载研究" + s + "时遇到了问题: " + "研究" + s + " 的ID无效,只能使用[a-z0-9._-]这些字符。");
31 | return null;
32 | }
33 |
34 | int researchId = section.getInt("id");
35 | String name = section.getString("name");
36 | int cost = section.getInt("levelCost");
37 | List items = section.getStringList("items");
38 |
39 | if (researchId <= 0) {
40 | ExceptionHandler.handleError("在附属" + addon.getAddonId() + "中加载研究" + s + "时遇到了问题: " + "id必须大于0!");
41 | return null;
42 | }
43 | if (cost <= 0) {
44 | ExceptionHandler.handleError("在附属" + addon.getAddonId() + "中加载研究" + s + "时遇到了问题: " + "等级花费必须大于0!");
45 | return null;
46 | }
47 | if (name == null || name.isBlank()) {
48 | ExceptionHandler.handleError("在附属" + addon.getAddonId() + "中加载研究" + s + "时遇到了问题: " + "名称不能为空!");
49 | return null;
50 | }
51 |
52 | name = CMIChatColor.translate(name);
53 |
54 | boolean hasCurrency = section.contains("currencyCost");
55 | double currency = 0;
56 | if (hasCurrency) {
57 | currency = section.getDouble("currencyCost");
58 | if (currency < 0) {
59 | ExceptionHandler.handleWarning(
60 | "在附属" + addon.getAddonId() + "中加载研究" + s + "时遇到了问题: " + "货币花费不能小于0! 已忽略.");
61 | hasCurrency = false;
62 | }
63 | }
64 |
65 | Research research;
66 | if (hasCurrency) {
67 | research = new Research(
68 | new NamespacedKey(RykenSlimefunCustomizer.INSTANCE, s), researchId, name, cost, currency);
69 | } else {
70 | research = new Research(new NamespacedKey(RykenSlimefunCustomizer.INSTANCE, s), researchId, name, cost);
71 | }
72 |
73 | for (String item : items) {
74 | SlimefunItem sfItem = SlimefunItem.getById(item);
75 | if (sfItem == null) {
76 | ExceptionHandler.handleWarning(
77 | "在附属" + addon.getAddonId() + "中加载研究" + s + "时遇到了问题: " + item + " 不是粘液科技物品! 已跳过.");
78 | continue;
79 | }
80 | research.addItems(sfItem);
81 | }
82 |
83 | research.register();
84 |
85 | return research;
86 | }
87 |
88 | // 研究不需要预加载物品
89 | @Override
90 | public List preloadItems(String s) {
91 | return List.of();
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/src/main/java/org/lins/mmmjjkx/rykenslimefuncustomizer/objects/yaml/item/ArmorReader.java:
--------------------------------------------------------------------------------
1 | package org.lins.mmmjjkx.rykenslimefuncustomizer.objects.yaml.item;
2 |
3 | import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
4 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
5 | import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
6 | import io.github.thebusybiscuit.slimefun4.core.attributes.ProtectionType;
7 | import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
8 | import io.github.thebusybiscuit.slimefun4.libraries.dough.collections.Pair;
9 | import java.util.ArrayList;
10 | import java.util.List;
11 | import org.bukkit.configuration.ConfigurationSection;
12 | import org.bukkit.configuration.file.YamlConfiguration;
13 | import org.bukkit.inventory.ItemStack;
14 | import org.bukkit.potion.PotionEffect;
15 | import org.bukkit.potion.PotionEffectType;
16 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.ProjectAddon;
17 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.customs.item.CustomArmorPiece;
18 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.yaml.YamlReader;
19 | import org.lins.mmmjjkx.rykenslimefuncustomizer.utils.CommonUtils;
20 | import org.lins.mmmjjkx.rykenslimefuncustomizer.utils.ExceptionHandler;
21 |
22 | public class ArmorReader extends YamlReader> {
23 | private final List CHECKS = List.of("helmet", "chestplate", "leggings", "boots");
24 |
25 | public ArmorReader(YamlConfiguration config, ProjectAddon addon) {
26 | super(config, addon);
27 | }
28 |
29 | @Override
30 | public List readEach(String s) {
31 | ConfigurationSection section = configuration.getConfigurationSection(s);
32 | if (section == null) return null;
33 |
34 | boolean fullSet = section.getBoolean("fullSet", false);
35 |
36 | Pair group =
37 | ExceptionHandler.handleItemGroupGet(addon, section.getString("item_group", ""));
38 | if (group.getFirstValue() == ExceptionHandler.HandleResult.FAILED) return null;
39 |
40 | List pt = section.getStringList("protection_types");
41 | List protectionTypes = new ArrayList<>();
42 | for (String type : pt) {
43 | Pair result = ExceptionHandler.handleEnumValueOf(
44 | "在附属" + addon.getAddonId() + "中加载盔甲套" + s + "时遇到了问题: " + "错误的盔甲保护类型: " + type,
45 | ProtectionType.class,
46 | type);
47 | if (result.getFirstValue() == ExceptionHandler.HandleResult.FAILED) return null;
48 | protectionTypes.add(result.getSecondValue());
49 | }
50 |
51 | List pieces = new ArrayList<>();
52 | for (String check : CHECKS) {
53 | ConfigurationSection pieceSection = section.getConfigurationSection(check);
54 | if (pieceSection == null) continue;
55 |
56 | String pieceId = addon.getId(
57 | s + "_" + check.toUpperCase(), section.getString("id_alias", pieceSection.getString("id", "")));
58 |
59 | ExceptionHandler.HandleResult result = ExceptionHandler.handleIdConflict(pieceId);
60 | if (result == ExceptionHandler.HandleResult.FAILED) return null;
61 |
62 | String recipeType = pieceSection.getString("recipe_type", "NULL");
63 |
64 | Pair rt = ExceptionHandler.getRecipeType(
65 | "在附属" + addon.getAddonId() + "中加载盔甲套" + s + "的" + check + "时遇到了问题: " + "错误的配方类型" + recipeType + "!",
66 | recipeType);
67 | if (rt.getFirstValue() == ExceptionHandler.HandleResult.FAILED) return null;
68 |
69 | SlimefunItemStack sfis = getPreloadItem(pieceId);
70 | if (sfis == null) return null;
71 |
72 | ConfigurationSection recipeSection = pieceSection.getConfigurationSection("recipe");
73 | ItemStack[] recipe = CommonUtils.readRecipe(recipeSection, addon);
74 |
75 | List potionEffects = new ArrayList<>();
76 | List effects = pieceSection.getStringList("potion_effects");
77 |
78 | for (String effect : effects) {
79 | String[] split = effect.split(" ");
80 | if (split.length != 2) {
81 | ExceptionHandler.handleError("在附属" + addon.getAddonId() + "中加载盔甲套" + s + "的" + check + "时遇到了问题: "
82 | + "错误的药水效果格式: " + effect);
83 | return null;
84 | }
85 | String effectName = split[0];
86 | int amplifier = Integer.parseInt(split[1]);
87 |
88 | PotionEffectType type = PotionEffectType.getByName(effectName);
89 | if (type == null) {
90 | ExceptionHandler.handleError("在附属" + addon.getAddonId() + "中加载盔甲套" + s + "的" + check + "时遇到了问题: "
91 | + "错误的药水效果类型: " + effectName);
92 | return null;
93 | }
94 |
95 | if (amplifier < 0) {
96 | ExceptionHandler.handleError("在附属" + addon.getAddonId() + "中加载盔甲套" + s + "的" + check + "时遇到了问题: "
97 | + "药水效果等级不能为负数: " + effect + ", 但你设置了" + amplifier);
98 | return null;
99 | }
100 |
101 | potionEffects.add(new PotionEffect(
102 | type, (Slimefun.getCfg().getInt("options.armor-update-interval") + 3) * 20, amplifier));
103 | }
104 |
105 | pieces.add(new CustomArmorPiece(
106 | group.getSecondValue(),
107 | sfis,
108 | rt.getSecondValue(),
109 | recipe,
110 | potionEffects.toArray(new PotionEffect[] {}),
111 | fullSet,
112 | s,
113 | protectionTypes.toArray(new ProtectionType[] {}),
114 | addon.getAddonId()));
115 | }
116 |
117 | if (pieces.isEmpty()) {
118 | ExceptionHandler.handleError("在附属" + addon.getAddonId() + "中加载盔甲套" + s + "时遇到了问题: " + "没有找到任何盔甲部分");
119 | return null;
120 | }
121 |
122 | return pieces;
123 | }
124 |
125 | @Override
126 | public List preloadItems(String s) {
127 | List items = new ArrayList<>(4);
128 | ConfigurationSection section = configuration.getConfigurationSection(s);
129 | if (section == null) return null;
130 |
131 | for (String check : CHECKS) {
132 | ConfigurationSection pieceSection = section.getConfigurationSection(check);
133 | if (pieceSection == null) continue;
134 |
135 | ItemStack stack = CommonUtils.readItem(pieceSection, false, addon);
136 | if (stack == null) {
137 | ExceptionHandler.handleError(
138 | "在附属" + addon.getAddonId() + "中加载盔甲套" + s + "的" + check + "时遇到了问题: " + "物品为空或格式错误导致无法加载,已跳过");
139 | continue;
140 | }
141 |
142 | SlimefunItemStack sfis = new SlimefunItemStack(
143 | addon.getId(
144 | s + "_" + check.toUpperCase(),
145 | section.getString("id_alias", pieceSection.getString("id", ""))),
146 | stack);
147 | items.add(sfis);
148 | }
149 |
150 | return items;
151 | }
152 | }
153 |
--------------------------------------------------------------------------------
/src/main/java/org/lins/mmmjjkx/rykenslimefuncustomizer/objects/yaml/item/CapacitorsReader.java:
--------------------------------------------------------------------------------
1 | package org.lins.mmmjjkx.rykenslimefuncustomizer.objects.yaml.item;
2 |
3 | import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
4 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
5 | import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
6 | import io.github.thebusybiscuit.slimefun4.implementation.items.electric.Capacitor;
7 | import io.github.thebusybiscuit.slimefun4.libraries.dough.collections.Pair;
8 | import java.util.List;
9 | import java.util.Objects;
10 | import org.bukkit.configuration.ConfigurationSection;
11 | import org.bukkit.configuration.file.YamlConfiguration;
12 | import org.bukkit.inventory.ItemStack;
13 | import org.lins.mmmjjkx.rykenslimefuncustomizer.RykenSlimefunCustomizer;
14 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.ProjectAddon;
15 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.yaml.YamlReader;
16 | import org.lins.mmmjjkx.rykenslimefuncustomizer.utils.CommonUtils;
17 | import org.lins.mmmjjkx.rykenslimefuncustomizer.utils.ExceptionHandler;
18 |
19 | public class CapacitorsReader extends YamlReader {
20 | public CapacitorsReader(YamlConfiguration config, ProjectAddon addon) {
21 | super(config, addon);
22 | }
23 |
24 | @Override
25 | public Capacitor readEach(String s) {
26 | ConfigurationSection section = configuration.getConfigurationSection(s);
27 | if (section == null) return null;
28 |
29 | String id = addon.getId(s, section.getString("id_alias"));
30 | ExceptionHandler.HandleResult result = ExceptionHandler.handleIdConflict(id);
31 |
32 | if (result == ExceptionHandler.HandleResult.FAILED) return null;
33 |
34 | String igId = section.getString("item_group");
35 |
36 | Pair group = ExceptionHandler.handleItemGroupGet(addon, igId);
37 | if (group.getFirstValue() == ExceptionHandler.HandleResult.FAILED) return null;
38 |
39 | SlimefunItemStack sfis = getPreloadItem(id);
40 | if (sfis == null) return null;
41 |
42 | ItemStack[] recipe = CommonUtils.readRecipe(section.getConfigurationSection("recipe"), addon);
43 | String recipeType = section.getString("recipe_type", "NULL");
44 |
45 | Pair rt = ExceptionHandler.getRecipeType(
46 | "在附属" + addon.getAddonId() + "中加载电容" + s + "时遇到了问题: " + "错误的配方类型" + recipeType + "!", recipeType);
47 |
48 | if (rt.getFirstValue() == ExceptionHandler.HandleResult.FAILED) return null;
49 |
50 | int capacity = section.getInt("capacity");
51 | if (capacity < 1) {
52 | ExceptionHandler.handleError("在附属" + addon.getAddonId() + "中加载电容" + s + "时遇到了问题: " + "容量不能小于1");
53 | return null;
54 | }
55 |
56 | Capacitor instance = new Capacitor(
57 | Objects.requireNonNull(group.getSecondValue()),
58 | capacity,
59 | sfis,
60 | Objects.requireNonNull(rt.getSecondValue()),
61 | recipe);
62 |
63 | instance.register(RykenSlimefunCustomizer.INSTANCE);
64 | return instance;
65 | }
66 |
67 | @Override
68 | public List preloadItems(String id) {
69 | ConfigurationSection section = configuration.getConfigurationSection(id);
70 | if (section == null) return null;
71 |
72 | ConfigurationSection item = section.getConfigurationSection("item");
73 | ItemStack stack = CommonUtils.readItem(item, false, addon);
74 |
75 | if (stack == null) {
76 | ExceptionHandler.handleError("在附属" + addon.getAddonId() + "中加载电容" + id + "时遇到了问题: " + "物品为空或格式错误导致无法加载");
77 | return null;
78 | }
79 |
80 | if (!stack.getType().isBlock()) {
81 | ExceptionHandler.handleError("在附属" + addon.getAddonId() + "中加载电容" + id + "时遇到了问题: " + "物品的材料类型必须是可放置的方块");
82 | return null;
83 | }
84 |
85 | return List.of(new SlimefunItemStack(addon.getId(id, section.getString("id_alias")), stack));
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/src/main/java/org/lins/mmmjjkx/rykenslimefuncustomizer/objects/yaml/item/FoodReader.java:
--------------------------------------------------------------------------------
1 | package org.lins.mmmjjkx.rykenslimefuncustomizer.objects.yaml.item;
2 |
3 | import de.tr7zw.nbtapi.NBT;
4 | import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
5 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
6 | import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
7 | import io.github.thebusybiscuit.slimefun4.libraries.dough.collections.Pair;
8 | import java.io.File;
9 | import java.util.List;
10 | import org.bukkit.Bukkit;
11 | import org.bukkit.configuration.ConfigurationSection;
12 | import org.bukkit.configuration.file.YamlConfiguration;
13 | import org.bukkit.inventory.ItemStack;
14 | import org.lins.mmmjjkx.rykenslimefuncustomizer.bulit_in.JavaScriptEval;
15 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.ProjectAddon;
16 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.customs.item.CustomFood;
17 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.yaml.YamlReader;
18 | import org.lins.mmmjjkx.rykenslimefuncustomizer.utils.CommonUtils;
19 | import org.lins.mmmjjkx.rykenslimefuncustomizer.utils.ExceptionHandler;
20 |
21 | public class FoodReader extends YamlReader {
22 | public FoodReader(YamlConfiguration config, ProjectAddon addon) {
23 | super(config, addon);
24 | }
25 |
26 | @Override
27 | public CustomFood readEach(String s) {
28 | ConfigurationSection section = configuration.getConfigurationSection(s);
29 | if (section == null) return null;
30 |
31 | String id = addon.getId(s, section.getString("id_alias"));
32 |
33 | ExceptionHandler.HandleResult result = ExceptionHandler.handleIdConflict(id);
34 |
35 | if (result == ExceptionHandler.HandleResult.FAILED) return null;
36 |
37 | String igId = section.getString("item_group");
38 |
39 | Pair group = ExceptionHandler.handleItemGroupGet(addon, igId);
40 | if (group.getFirstValue() == ExceptionHandler.HandleResult.FAILED) return null;
41 |
42 | SlimefunItemStack sfis = getPreloadItem(id);
43 | if (sfis == null) return null;
44 |
45 | ItemStack[] itemStacks = CommonUtils.readRecipe(section.getConfigurationSection("recipe"), addon);
46 | String recipeType = section.getString("recipe_type", "NULL");
47 |
48 | Pair rt = ExceptionHandler.getRecipeType(
49 | "在附属" + addon.getAddonId() + "中加载食物" + s + "时遇到了问题: " + "错误的配方类型" + recipeType + "!", recipeType);
50 |
51 | if (rt.getFirstValue() == ExceptionHandler.HandleResult.FAILED) return null;
52 |
53 | JavaScriptEval eval = null;
54 | if (section.contains("script")) {
55 | String script = section.getString("script", "");
56 | File file = new File(addon.getScriptsFolder(), script + ".js");
57 | if (!file.exists()) {
58 | ExceptionHandler.handleWarning(
59 | "在附属" + addon.getAddonId() + "中加载食物" + s + "时遇到了问题: " + "找不到脚本文件 " + file.getName());
60 | } else {
61 | eval = new JavaScriptEval(file, addon);
62 | }
63 | }
64 |
65 | if (CommonUtils.versionToCode(Bukkit.getMinecraftVersion()) >= 1205) {
66 | if (Bukkit.getPluginManager().isPluginEnabled("NBTAPI")) {
67 | sfis = nbtApply(id, section, sfis);
68 | }
69 | }
70 |
71 | return new CustomFood(group.getSecondValue(), sfis, rt.getSecondValue(), itemStacks, eval, sfis);
72 | }
73 |
74 | private SlimefunItemStack nbtApply(String s, ConfigurationSection section, SlimefunItemStack sfis) {
75 | int nutrition = section.getInt("nutrition");
76 | float saturation = section.getInt("saturation");
77 | boolean alwaysEatable = section.getBoolean("always_eatable", false);
78 | float eatseconds = section.getInt("eat_seconds", 0);
79 | if (nutrition < 1) {
80 | ExceptionHandler.handleError(
81 | "在附属" + addon.getAddonId() + "中加载食物" + s + "时遇到了问题: " + "饥饿值 " + nutrition + "小于1! 已转为1");
82 | nutrition = 1;
83 | }
84 | if (saturation < 0f) {
85 | ExceptionHandler.handleError(
86 | "在附属" + addon.getAddonId() + "中加载食物" + s + "时遇到了问题: " + "饱和度 " + saturation + "小于0! 已转为0");
87 | saturation = 0f;
88 | }
89 | if (eatseconds < 0) {
90 | ExceptionHandler.handleError(
91 | "在附属" + addon.getAddonId() + "中加载食物" + s + "时遇到了问题: " + "食用时间 " + eatseconds + "小于0! 已转为1.6");
92 | eatseconds = 1.6f;
93 | }
94 |
95 | int finalNutrition = nutrition;
96 | float finalSaturation = saturation;
97 | float finalEatSeconds = eatseconds;
98 | NBT.modify(sfis, c -> {
99 | c.setInteger("nutrition", finalNutrition);
100 | c.setFloat("saturation", finalSaturation);
101 | c.setBoolean("can_always_eat", alwaysEatable);
102 | c.setFloat("eat_seconds", finalEatSeconds);
103 | });
104 |
105 | return sfis;
106 | }
107 |
108 | @Override
109 | public List preloadItems(String id) {
110 | ConfigurationSection section = configuration.getConfigurationSection(id);
111 |
112 | if (section == null) return null;
113 |
114 | ConfigurationSection item = section.getConfigurationSection("item");
115 | ItemStack stack = CommonUtils.readItem(item, false, addon);
116 | if (stack == null) {
117 | ExceptionHandler.handleError("在附属" + addon.getAddonId() + "中加载食物" + id + "时遇到了问题: " + "物品为空或格式错误导致无法加载");
118 | return null;
119 | }
120 |
121 | return List.of(new SlimefunItemStack(addon.getId(id, section.getString("id_alias")), stack));
122 | }
123 | }
124 |
--------------------------------------------------------------------------------
/src/main/java/org/lins/mmmjjkx/rykenslimefuncustomizer/objects/yaml/item/MobDropsReader.java:
--------------------------------------------------------------------------------
1 | package org.lins.mmmjjkx.rykenslimefuncustomizer.objects.yaml.item;
2 |
3 | import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
4 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
5 | import io.github.thebusybiscuit.slimefun4.libraries.dough.collections.Pair;
6 | import io.github.thebusybiscuit.slimefun4.libraries.dough.items.CustomItemStack;
7 | import java.util.List;
8 | import net.kyori.adventure.text.Component;
9 | import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
10 | import org.bukkit.Material;
11 | import org.bukkit.configuration.ConfigurationSection;
12 | import org.bukkit.configuration.file.YamlConfiguration;
13 | import org.bukkit.entity.EntityType;
14 | import org.bukkit.inventory.ItemStack;
15 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.ProjectAddon;
16 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.customs.item.exts.CustomMobDrop;
17 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.yaml.YamlReader;
18 | import org.lins.mmmjjkx.rykenslimefuncustomizer.utils.CommonUtils;
19 | import org.lins.mmmjjkx.rykenslimefuncustomizer.utils.ExceptionHandler;
20 |
21 | @SuppressWarnings("deprecation")
22 | public class MobDropsReader extends YamlReader {
23 | public MobDropsReader(YamlConfiguration config, ProjectAddon addon) {
24 | super(config, addon);
25 | }
26 |
27 | @Override
28 | public CustomMobDrop readEach(String s) {
29 | ConfigurationSection section = configuration.getConfigurationSection(s);
30 | if (section != null) {
31 | String id = addon.getId(s, section.getString("id_alias"));
32 |
33 | ExceptionHandler.HandleResult result = ExceptionHandler.handleIdConflict(id);
34 | if (result == ExceptionHandler.HandleResult.FAILED) return null;
35 |
36 | String igId = section.getString("item_group");
37 |
38 | Pair group = ExceptionHandler.handleItemGroupGet(addon, igId);
39 | if (group.getFirstValue() == ExceptionHandler.HandleResult.FAILED) return null;
40 |
41 | SlimefunItemStack sfis = getPreloadItem(id);
42 | if (sfis == null) return null;
43 |
44 | String type = section.getString("entity");
45 |
46 | Pair entity = ExceptionHandler.handleEnumValueOf(
47 | "在附属" + addon.getAddonId() + "中加载生物掉落物" + s + "时遇到了问题: " + "错误的生物类型", EntityType.class, type);
48 | if (entity.getFirstValue() == ExceptionHandler.HandleResult.FAILED) {
49 | return null;
50 | }
51 |
52 | Material eggMaterial;
53 | EntityType entityType = entity.getSecondValue();
54 | if (entityType == null) return null;
55 |
56 | Pair egg =
57 | ExceptionHandler.handleEnumValueOf("", Material.class, entityType + "_SPAWN_EGG");
58 | if (egg.getFirstValue() == ExceptionHandler.HandleResult.SUCCESS && egg.getSecondValue() != null) {
59 | eggMaterial = egg.getSecondValue();
60 | } else {
61 | eggMaterial = Material.EGG;
62 | }
63 |
64 | int chance = section.getInt("chance");
65 |
66 | if (chance < 1 || chance > 100) {
67 | ExceptionHandler.handleError(
68 | "在附属" + addon.getAddonId() + "中加载生物掉落物" + s + "时遇到了问题: " + "掉落概率未设置或不应该小于1或大于100,已转换为1或100");
69 | chance = chance >= 100 ? 100 : 1;
70 | }
71 |
72 | Component lore = LegacyComponentSerializer.legacyAmpersand()
73 | .deserialize("&a击杀 ")
74 | .append(LegacyComponentSerializer.legacyAmpersand().deserialize("&b"))
75 | .append(Component.translatable(entityType.translationKey()))
76 | .append(LegacyComponentSerializer.legacyAmpersand().deserialize(" &a时会有"))
77 | .append(LegacyComponentSerializer.legacyAmpersand().deserialize(" &b " + chance + "%"))
78 | .append(LegacyComponentSerializer.legacyAmpersand().deserialize(" &a的概率掉落"));
79 |
80 | ItemStack itemStack = new CustomItemStack(eggMaterial, meta -> {
81 | meta.setDisplayName(entityType.toString());
82 | meta.lore(List.of(lore));
83 | });
84 | ItemStack[] recipe = new ItemStack[] {null, null, null, null, itemStack};
85 |
86 | return new CustomMobDrop(group.getSecondValue(), sfis, recipe, chance, entityType, sfis);
87 | }
88 | return null;
89 | }
90 |
91 | @Override
92 | public List preloadItems(String id) {
93 | ConfigurationSection section = configuration.getConfigurationSection(id);
94 |
95 | if (section == null) return null;
96 |
97 | ConfigurationSection item = section.getConfigurationSection("item");
98 | ItemStack stack = CommonUtils.readItem(item, false, addon);
99 | if (stack == null) {
100 | ExceptionHandler.handleError("在附属" + addon.getAddonId() + "中加载生物掉落物" + id + "时遇到了问题: " + "物品为空或格式错误导致无法加载");
101 | return null;
102 | }
103 |
104 | return List.of(new SlimefunItemStack(addon.getId(id, section.getString("id_alias")), stack));
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/src/main/java/org/lins/mmmjjkx/rykenslimefuncustomizer/objects/yaml/machine/GeneratorReader.java:
--------------------------------------------------------------------------------
1 | package org.lins.mmmjjkx.rykenslimefuncustomizer.objects.yaml.machine;
2 |
3 | import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
4 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
5 | import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
6 | import io.github.thebusybiscuit.slimefun4.libraries.dough.collections.Pair;
7 | import java.util.ArrayList;
8 | import java.util.List;
9 | import lombok.SneakyThrows;
10 | import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.MachineFuel;
11 | import org.bukkit.configuration.ConfigurationSection;
12 | import org.bukkit.configuration.file.YamlConfiguration;
13 | import org.bukkit.inventory.ItemStack;
14 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.ProjectAddon;
15 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.customs.CustomMenu;
16 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.customs.machine.CustomGenerator;
17 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.yaml.YamlReader;
18 | import org.lins.mmmjjkx.rykenslimefuncustomizer.utils.CommonUtils;
19 | import org.lins.mmmjjkx.rykenslimefuncustomizer.utils.ExceptionHandler;
20 |
21 | public class GeneratorReader extends YamlReader {
22 | public GeneratorReader(YamlConfiguration config, ProjectAddon addon) {
23 | super(config, addon);
24 | }
25 |
26 | @SneakyThrows
27 | @Override
28 | public CustomGenerator readEach(String s) {
29 | ConfigurationSection section = configuration.getConfigurationSection(s);
30 | if (section == null) return null;
31 | String id = addon.getId(s, section.getString("id_alias"));
32 |
33 | ExceptionHandler.HandleResult result = ExceptionHandler.handleIdConflict(id);
34 |
35 | if (result == ExceptionHandler.HandleResult.FAILED) return null;
36 |
37 | String igId = section.getString("item_group");
38 |
39 | SlimefunItemStack sfis = getPreloadItem(id);
40 | if (sfis == null) return null;
41 |
42 | Pair group = ExceptionHandler.handleItemGroupGet(addon, igId);
43 | if (group.getFirstValue() == ExceptionHandler.HandleResult.FAILED) return null;
44 | ItemStack[] recipe = CommonUtils.readRecipe(section.getConfigurationSection("recipe"), addon);
45 | String recipeType = section.getString("recipe_type", "NULL");
46 |
47 | Pair rt = ExceptionHandler.getRecipeType(
48 | "在附属" + addon.getAddonId() + "中加载发电机" + s + "时遇到了问题: " + "错误的配方类型" + recipeType + "!", recipeType);
49 |
50 | if (rt.getFirstValue() == ExceptionHandler.HandleResult.FAILED) return null;
51 |
52 | CustomMenu menu = CommonUtils.getIf(addon.getMenus(), m -> m.getID().equalsIgnoreCase(id));
53 |
54 | List input = section.getIntegerList("input");
55 | List output = section.getIntegerList("output");
56 |
57 | ConfigurationSection fuelsSection = section.getConfigurationSection("fuels");
58 | List fuels = readFuels(s, fuelsSection, addon);
59 | int capacity = section.getInt("capacity", 0);
60 | int production = section.getInt("production");
61 |
62 | if (production < 1) {
63 | ExceptionHandler.handleError("在附属" + addon.getAddonId() + "中加载发电机" + s + "时遇到了问题: " + "产电量不能小于1");
64 | return null;
65 | }
66 |
67 | return new CustomGenerator(
68 | group.getSecondValue(),
69 | sfis,
70 | rt.getSecondValue(),
71 | recipe,
72 | menu,
73 | capacity,
74 | input,
75 | output,
76 | production,
77 | fuels);
78 | }
79 |
80 | @Override
81 | public List preloadItems(String id) {
82 | ConfigurationSection section = configuration.getConfigurationSection(id);
83 | if (section == null) return null;
84 |
85 | ConfigurationSection item = section.getConfigurationSection("item");
86 | ItemStack stack = CommonUtils.readItem(item, false, addon);
87 |
88 | if (stack == null) {
89 | ExceptionHandler.handleError("在附属" + addon.getAddonId() + "中加载发电机" + id + "时遇到了问题: " + "物品为空或格式错误导致无法加载");
90 | return null;
91 | }
92 | return List.of(new SlimefunItemStack(addon.getId(id, section.getString("id_alias")), stack));
93 | }
94 |
95 | private List readFuels(String s, ConfigurationSection section, ProjectAddon addon) {
96 | List fuels = new ArrayList<>();
97 |
98 | if (section == null) return fuels;
99 |
100 | for (String key : section.getKeys(false)) {
101 | ConfigurationSection section1 = section.getConfigurationSection(key);
102 | if (section1 == null) continue;
103 | ConfigurationSection item = section1.getConfigurationSection("item");
104 | ItemStack stack = CommonUtils.readItem(item, true, addon);
105 | if (stack == null) {
106 | ExceptionHandler.handleError(
107 | "在附属" + addon.getAddonId() + "中加载发电机" + s + "的燃料" + key + "时遇到了问题: " + "输入物品为空或格式错误,已跳过加载");
108 | continue;
109 | }
110 | int seconds = section1.getInt("seconds");
111 |
112 | if (seconds < 1) {
113 | ExceptionHandler.handleError(
114 | "在附属" + addon.getAddonId() + "中加载发电机" + s + "的燃料" + key + "时遇到了问题: " + "秒数不能小于1,已跳过加载");
115 | continue;
116 | }
117 |
118 | ItemStack output = null;
119 | if (section1.contains("output")) {
120 | ConfigurationSection outputSet = section1.getConfigurationSection("output");
121 | output = CommonUtils.readItem(outputSet, true, addon);
122 | if (output == null) {
123 | ExceptionHandler.handleError(
124 | "在附属" + addon.getAddonId() + "中加载发电机" + s + "的燃料" + key + "时遇到了问题: " + "输出物品为空或格式错误,已转为空");
125 | }
126 | }
127 |
128 | MachineFuel fuel = new MachineFuel(seconds, stack, output);
129 | fuels.add(fuel);
130 | }
131 | return fuels;
132 | }
133 | }
134 |
--------------------------------------------------------------------------------
/src/main/java/org/lins/mmmjjkx/rykenslimefuncustomizer/objects/yaml/machine/MaterialGeneratorReader.java:
--------------------------------------------------------------------------------
1 | package org.lins.mmmjjkx.rykenslimefuncustomizer.objects.yaml.machine;
2 |
3 | import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
4 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
5 | import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
6 | import io.github.thebusybiscuit.slimefun4.libraries.dough.collections.Pair;
7 | import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils;
8 | import java.util.ArrayList;
9 | import java.util.Arrays;
10 | import java.util.List;
11 | import org.bukkit.configuration.ConfigurationSection;
12 | import org.bukkit.configuration.file.YamlConfiguration;
13 | import org.bukkit.inventory.ItemStack;
14 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.ProjectAddon;
15 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.customs.CustomMenu;
16 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.customs.machine.CustomMaterialGenerator;
17 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.yaml.YamlReader;
18 | import org.lins.mmmjjkx.rykenslimefuncustomizer.utils.CommonUtils;
19 | import org.lins.mmmjjkx.rykenslimefuncustomizer.utils.ExceptionHandler;
20 |
21 | public class MaterialGeneratorReader extends YamlReader {
22 | public MaterialGeneratorReader(YamlConfiguration config, ProjectAddon addon) {
23 | super(config, addon);
24 | }
25 |
26 | @Override
27 | public CustomMaterialGenerator readEach(String s) {
28 | ConfigurationSection section = configuration.getConfigurationSection(s);
29 | if (section == null) return null;
30 | String id = addon.getId(s, section.getString("id_alias"));
31 |
32 | ExceptionHandler.HandleResult result = ExceptionHandler.handleIdConflict(id);
33 |
34 | if (result == ExceptionHandler.HandleResult.FAILED) return null;
35 |
36 | String igId = section.getString("item_group");
37 |
38 | SlimefunItemStack slimefunItemStack = getPreloadItem(id);
39 | if (slimefunItemStack == null) return null;
40 |
41 | Pair group = ExceptionHandler.handleItemGroupGet(addon, igId);
42 | if (group.getFirstValue() == ExceptionHandler.HandleResult.FAILED) return null;
43 | ItemStack[] recipe = CommonUtils.readRecipe(section.getConfigurationSection("recipe"), addon);
44 | String recipeType = section.getString("recipe_type", "NULL");
45 |
46 | Pair rt = ExceptionHandler.getRecipeType(
47 | "在附属" + addon.getAddonId() + "中加载材料生成器" + s + "时遇到了问题: " + "错误的配方类型" + recipeType + "!", recipeType);
48 |
49 | if (rt.getFirstValue() == ExceptionHandler.HandleResult.FAILED) return null;
50 |
51 | CustomMenu menu = CommonUtils.getIf(addon.getMenus(), m -> m.getID().equalsIgnoreCase(id));
52 | if (menu == null) {
53 | ExceptionHandler.handleError("在附属" + addon.getAddonId() + "中加载材料生成器" + s + "时遇到了问题: " + "对应菜单不存在");
54 | return null;
55 | }
56 |
57 | List output = section.getIntegerList("output");
58 | int capacity = section.getInt("capacity", 0);
59 | ConfigurationSection outputItems = section.getConfigurationSection("outputs");
60 | ItemStack[] out = CommonUtils.readRecipe(outputItems, addon, output.size());
61 | List chances = new ArrayList<>();
62 | boolean chooseOne = section.getBoolean("chooseOne", false);
63 |
64 | if (out.length == 0) {
65 | ConfigurationSection outputItem = section.getConfigurationSection("outputItem");
66 | ItemStack outItem = CommonUtils.readItem(outputItem, true, addon);
67 | if (outItem == null) {
68 | ExceptionHandler.handleError(
69 | "在附属" + addon.getAddonId() + "中加载材料生成器" + s + "时遇到了问题: " + "输出物品为空或格式错误导致无法加载");
70 | return null;
71 | } else {
72 | out = new ItemStack[] {outItem};
73 | chances = List.of(outputItem.getInt("chance", 100));
74 | }
75 | }
76 |
77 | if (out.length > 1) {
78 | for (String key : outputItems.getKeys(false)) {
79 | ConfigurationSection chanceItem = outputItems.getConfigurationSection(key);
80 | if (CommonUtils.readItem(chanceItem, true, addon) == null) {
81 | continue;
82 | }
83 | chances.add(chanceItem.getInt("chance", 100));
84 | }
85 | }
86 |
87 | out = CommonUtils.removeNulls(out);
88 |
89 | int tickRate = section.getInt("tickRate");
90 | if (tickRate < 1) {
91 | ExceptionHandler.handleError(
92 | "在附属" + addon.getAddonId() + "中加载材料生成器" + s + "时遇到了问题: " + "tickRate未设置或不能小于1");
93 | return null;
94 | }
95 |
96 | int per = section.getInt("per");
97 | if (per < 1) {
98 | ExceptionHandler.handleError(
99 | "在附属" + addon.getAddonId() + "中加载材料生成器" + s + "时遇到了问题: " + "单次生成能量花费未设置或不能小于1");
100 | return null;
101 | }
102 |
103 | int status = -1;
104 | if (section.contains("status")) {
105 | status = section.getInt("status");
106 | }
107 |
108 | CustomMaterialGenerator cmg = new CustomMaterialGenerator(
109 | group.getSecondValue(),
110 | slimefunItemStack,
111 | rt.getSecondValue(),
112 | recipe,
113 | capacity,
114 | output,
115 | status,
116 | tickRate,
117 | Arrays.asList(out),
118 | menu,
119 | per,
120 | chances,
121 | chooseOne);
122 |
123 | menu.addMenuClickHandler(status, ChestMenuUtils.getEmptyClickHandler());
124 |
125 | return cmg;
126 | }
127 |
128 | @Override
129 | public List preloadItems(String s) {
130 | ConfigurationSection section = configuration.getConfigurationSection(s);
131 | if (section == null) return null;
132 |
133 | ConfigurationSection item = section.getConfigurationSection("item");
134 | ItemStack stack = CommonUtils.readItem(item, false, addon);
135 |
136 | if (stack == null) {
137 | ExceptionHandler.handleError("在附属" + addon.getAddonId() + "中加载材料生成器" + s + "时遇到了问题: " + "物品为空或格式错误导致无法加载");
138 | return null;
139 | }
140 |
141 | return List.of(new SlimefunItemStack(addon.getId(s, section.getString("id_alias")), stack));
142 | }
143 | }
144 |
--------------------------------------------------------------------------------
/src/main/java/org/lins/mmmjjkx/rykenslimefuncustomizer/objects/yaml/machine/MultiBlockMachineReader.java:
--------------------------------------------------------------------------------
1 | package org.lins.mmmjjkx.rykenslimefuncustomizer.objects.yaml.machine;
2 |
3 | import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
4 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
5 | import io.github.thebusybiscuit.slimefun4.core.services.sounds.SoundEffect;
6 | import io.github.thebusybiscuit.slimefun4.libraries.dough.collections.Pair;
7 | import java.io.File;
8 | import java.util.HashMap;
9 | import java.util.List;
10 | import java.util.Map;
11 | import org.bukkit.Material;
12 | import org.bukkit.configuration.ConfigurationSection;
13 | import org.bukkit.configuration.file.YamlConfiguration;
14 | import org.bukkit.inventory.ItemStack;
15 | import org.lins.mmmjjkx.rykenslimefuncustomizer.bulit_in.JavaScriptEval;
16 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.ProjectAddon;
17 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.customs.machine.CustomMultiBlockMachine;
18 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.yaml.YamlReader;
19 | import org.lins.mmmjjkx.rykenslimefuncustomizer.utils.CommonUtils;
20 | import org.lins.mmmjjkx.rykenslimefuncustomizer.utils.ExceptionHandler;
21 |
22 | public class MultiBlockMachineReader extends YamlReader {
23 | public MultiBlockMachineReader(YamlConfiguration config, ProjectAddon addon) {
24 | super(config, addon);
25 | }
26 |
27 | @Override
28 | public CustomMultiBlockMachine readEach(String s) {
29 | ConfigurationSection section = configuration.getConfigurationSection(s);
30 | if (section == null) return null;
31 | String id = addon.getId(s, section.getString("id_alias"));
32 |
33 | ExceptionHandler.HandleResult result = ExceptionHandler.handleIdConflict(id);
34 |
35 | if (result == ExceptionHandler.HandleResult.FAILED) return null;
36 |
37 | String igId = section.getString("item_group");
38 |
39 | Pair group = ExceptionHandler.handleItemGroupGet(addon, igId);
40 | if (group.getFirstValue() == ExceptionHandler.HandleResult.FAILED) return null;
41 |
42 | SlimefunItemStack slimefunItemStack = getPreloadItem(id);
43 | if (slimefunItemStack == null) return null;
44 |
45 | ItemStack[] recipe = CommonUtils.readRecipe(section.getConfigurationSection("recipe"), addon);
46 |
47 | ConfigurationSection recipesSection = section.getConfigurationSection("recipes");
48 |
49 | int workSlot = section.getInt("work");
50 | if (workSlot < 1) {
51 | ExceptionHandler.handleError("在附属" + addon.getAddonId() + "中加载多方块机器" + s + "时遇到了问题: " + "没有设置工作槽");
52 | return null;
53 | }
54 |
55 | if (recipe == null) {
56 | ExceptionHandler.handleError("在附属" + addon.getAddonId() + "中加载多方块机器" + s + "时遇到了问题: " + "放置配方为空");
57 | return null;
58 | }
59 |
60 | boolean hasDispenser = false;
61 |
62 | for (ItemStack is : recipe) {
63 | if (is != null) {
64 | if (is.getType() == Material.DISPENSER) {
65 | hasDispenser = true;
66 | break;
67 | }
68 | }
69 | }
70 |
71 | if (!hasDispenser) {
72 | ExceptionHandler.handleError("在附属" + addon.getAddonId() + "中加载多方块机器" + s + "时遇到了问题: " + "放置配方里没有发射器");
73 | return null;
74 | }
75 |
76 | if (recipe[workSlot - 1] == null) {
77 | ExceptionHandler.handleError("在附属" + addon.getAddonId() + "中加载多方块机器" + s + "时遇到了问题: " + "对应工作方块不存在");
78 | return null;
79 | }
80 |
81 | Map recipes = readRecipes(s, recipesSection, addon);
82 | SoundEffect sound = null;
83 | if (section.contains("sound")) {
84 | String soundString = section.getString("sound");
85 | Pair soundEffectPair = ExceptionHandler.handleEnumValueOf(
86 | "在附属" + addon.getAddonId() + "中加载多方块机器" + s + "无法获取声音类型" + soundString,
87 | SoundEffect.class,
88 | soundString);
89 | ExceptionHandler.HandleResult result1 = soundEffectPair.getFirstValue();
90 | if (result1 != ExceptionHandler.HandleResult.FAILED && soundEffectPair.getSecondValue() != null) {
91 | sound = soundEffectPair.getSecondValue();
92 | }
93 | }
94 |
95 | JavaScriptEval eval = null;
96 | if (section.contains("script")) {
97 | String script = section.getString("script", "");
98 | File file = new File(addon.getScriptsFolder(), script + ".js");
99 | if (!file.exists()) {
100 | ExceptionHandler.handleWarning(
101 | "在附属" + addon.getAddonId() + "中加载多方块机器" + s + "时遇到了问题: " + "找不到脚本文件 " + file.getName());
102 | } else {
103 | eval = new JavaScriptEval(file, addon);
104 | }
105 | }
106 |
107 | return new CustomMultiBlockMachine(
108 | group.getSecondValue(), slimefunItemStack, recipe, recipes, workSlot, sound, eval);
109 | }
110 |
111 | @Override
112 | public List preloadItems(String s) {
113 | ConfigurationSection section = configuration.getConfigurationSection(s);
114 | if (section == null) return null;
115 |
116 | ConfigurationSection item = section.getConfigurationSection("item");
117 | ItemStack stack = CommonUtils.readItem(item, false, addon);
118 |
119 | if (stack == null) {
120 | ExceptionHandler.handleError("在附属" + addon.getAddonId() + "中加载多方块机器" + s + "时遇到了问题: " + "物品为空或格式错误导致无法加载");
121 | return null;
122 | }
123 |
124 | return List.of(new SlimefunItemStack(addon.getId(s, section.getString("id_alias")), stack));
125 | }
126 |
127 | private Map readRecipes(String s, ConfigurationSection section, ProjectAddon addon) {
128 | Map map = new HashMap<>();
129 | if (section == null) return map;
130 |
131 | for (String key : section.getKeys(false)) {
132 | ConfigurationSection recipe = section.getConfigurationSection(key);
133 | if (recipe == null) continue;
134 | ConfigurationSection inputs = recipe.getConfigurationSection("input");
135 | if (inputs == null) {
136 | ExceptionHandler.handleError(
137 | "在附属" + addon.getAddonId() + "中加载多方块机器" + s + "的工作配方" + key + "时遇到了问题: " + "没有输入物品");
138 | continue;
139 | }
140 | ItemStack[] input = CommonUtils.readRecipe(inputs, addon);
141 | if (input == null) {
142 | ExceptionHandler.handleError(
143 | "在附属" + addon.getAddonId() + "中加载多方块机器" + s + "的工作配方" + key + "时遇到了问题: " + "输入物品为空或格式错误");
144 | continue;
145 | }
146 | ConfigurationSection outputs = recipe.getConfigurationSection("output");
147 | if (outputs == null) {
148 | ExceptionHandler.handleError(
149 | "在附属" + addon.getAddonId() + "中加载多方块机器" + s + "的工作配方" + key + "时遇到了问题: " + "没有输出物品");
150 | continue;
151 | }
152 | ItemStack output = CommonUtils.readItem(outputs, true, addon);
153 | if (output == null) {
154 | ExceptionHandler.handleError(
155 | "在附属" + addon.getAddonId() + "中加载多方块机器" + s + "的工作配方" + key + "时遇到了问题: " + "输出物品为空或格式错误");
156 | continue;
157 | }
158 | map.put(input, output);
159 | }
160 | return map;
161 | }
162 | }
163 |
--------------------------------------------------------------------------------
/src/main/java/org/lins/mmmjjkx/rykenslimefuncustomizer/objects/yaml/machine/SimpleMachineReader.java:
--------------------------------------------------------------------------------
1 | package org.lins.mmmjjkx.rykenslimefuncustomizer.objects.yaml.machine;
2 |
3 | import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
4 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem;
5 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
6 | import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
7 | import io.github.thebusybiscuit.slimefun4.libraries.dough.collections.Pair;
8 | import java.util.List;
9 | import org.bukkit.configuration.ConfigurationSection;
10 | import org.bukkit.configuration.file.YamlConfiguration;
11 | import org.bukkit.inventory.ItemStack;
12 | import org.lins.mmmjjkx.rykenslimefuncustomizer.RykenSlimefunCustomizer;
13 | import org.lins.mmmjjkx.rykenslimefuncustomizer.factories.SimpleMachineFactory;
14 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.ProjectAddon;
15 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.machine.SimpleMachineType;
16 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.yaml.YamlReader;
17 | import org.lins.mmmjjkx.rykenslimefuncustomizer.utils.CommonUtils;
18 | import org.lins.mmmjjkx.rykenslimefuncustomizer.utils.ExceptionHandler;
19 |
20 | public class SimpleMachineReader extends YamlReader {
21 | public SimpleMachineReader(YamlConfiguration config, ProjectAddon addon) {
22 | super(config, addon);
23 | }
24 |
25 | @Override
26 | public SlimefunItem readEach(String s) {
27 | ConfigurationSection section = configuration.getConfigurationSection(s);
28 | if (section == null) return null;
29 | String id = addon.getId(s, section.getString("id_alias"));
30 |
31 | ExceptionHandler.HandleResult result = ExceptionHandler.handleIdConflict(id);
32 |
33 | if (result == ExceptionHandler.HandleResult.FAILED) return null;
34 |
35 | String igId = section.getString("item_group");
36 |
37 | SlimefunItemStack slimefunItemStack = getPreloadItem(id);
38 | if (slimefunItemStack == null) return null;
39 |
40 | Pair itemGroupPair = ExceptionHandler.handleItemGroupGet(addon, igId);
41 | if (itemGroupPair.getFirstValue() == ExceptionHandler.HandleResult.FAILED
42 | || itemGroupPair.getSecondValue() == null) return null;
43 | ItemStack[] recipe = CommonUtils.readRecipe(section.getConfigurationSection("recipe"), addon);
44 | String recipeType = section.getString("recipe_type", "NULL");
45 |
46 | Pair resultRecipeTypePair = ExceptionHandler.getRecipeType(
47 | "在附属" + addon.getAddonId() + "中加载简单机器" + s + "时遇到了问题: " + "错误的配方类型" + recipeType + "!", recipeType);
48 |
49 | if (resultRecipeTypePair.getFirstValue() == ExceptionHandler.HandleResult.FAILED
50 | || resultRecipeTypePair.getSecondValue() == null) return null;
51 |
52 | String machineTypeStr = section.getString("type");
53 |
54 | Pair machineTypePair = ExceptionHandler.handleEnumValueOf(
55 | "错误的简单机器类型 " + machineTypeStr, SimpleMachineType.class, machineTypeStr);
56 | if (machineTypePair.getFirstValue() == ExceptionHandler.HandleResult.FAILED
57 | || machineTypePair.getSecondValue() == null) {
58 | return null;
59 | }
60 |
61 | SimpleMachineType machineType = machineTypePair.getSecondValue();
62 | ConfigurationSection settings = section.getConfigurationSection("settings");
63 |
64 | if (settings == null) {
65 | ExceptionHandler.handleError("在附属" + addon.getAddonId() + "中加载简单机器" + s + "时遇到了问题: " + "机器没有设置");
66 | return null;
67 | }
68 |
69 | int capacity = 0;
70 | int consumption = 0;
71 | int speed = 1;
72 | int radius = 1;
73 | int repairFactor = 10;
74 |
75 | if (machineType.isEnergy()) {
76 | capacity = settings.getInt("capacity");
77 | if (capacity < 1) {
78 | ExceptionHandler.handleError("在附属" + addon.getAddonId() + "中加载简单机器" + s + "时遇到了问题: " + "容量小于1");
79 | return null;
80 | }
81 |
82 | consumption = settings.getInt("consumption");
83 | if (consumption < 1) {
84 | ExceptionHandler.handleError("在附属" + addon.getAddonId() + "中加载简单机器" + s + "时遇到了问题: " + "消耗能量小于1");
85 | return null;
86 | }
87 |
88 | if (!isAccelerator(machineType)) {
89 | speed = settings.getInt("speed", 1);
90 | if (speed < 1) {
91 | ExceptionHandler.handleError("在附属" + addon.getAddonId() + "中加载简单机器" + s + "时遇到了问题: " + "处理速度小于1");
92 | return null;
93 | }
94 | } else {
95 | radius = settings.getInt("radius", 1);
96 | if (radius < 1) {
97 | ExceptionHandler.handleError("在附属" + addon.getAddonId() + "中加载简单机器" + s + "时遇到了问题: " + "范围小于1");
98 | return null;
99 | }
100 |
101 | if (machineType == SimpleMachineType.CROP_GROWTH_ACCELERATOR) {
102 | speed = settings.getInt("speed", 1);
103 | if (speed < 1) {
104 | ExceptionHandler.handleError(
105 | "在附属" + addon.getAddonId() + "中加载简单机器" + s + "时遇到了问题: " + "处理速度小于1");
106 | return null;
107 | }
108 | }
109 | }
110 |
111 | if (machineType == SimpleMachineType.AUTO_ANVIL) {
112 | repairFactor = settings.getInt("repair_factor", 10);
113 | if (repairFactor < 1) {
114 | ExceptionHandler.handleError("在附属" + addon.getAddonId() + "中加载简单机器" + s + "时遇到了问题: " + "修理因子小于1");
115 | return null;
116 | }
117 | }
118 | }
119 |
120 | SlimefunItem instance = SimpleMachineFactory.create(
121 | itemGroupPair.getSecondValue(),
122 | slimefunItemStack,
123 | resultRecipeTypePair.getSecondValue(),
124 | recipe,
125 | machineType,
126 | capacity,
127 | consumption,
128 | speed,
129 | radius,
130 | repairFactor);
131 |
132 | instance.register(RykenSlimefunCustomizer.INSTANCE);
133 |
134 | return instance;
135 | }
136 |
137 | @Override
138 | public List preloadItems(String s) {
139 | ConfigurationSection section = configuration.getConfigurationSection(s);
140 | if (section == null) return null;
141 |
142 | ConfigurationSection item = section.getConfigurationSection("item");
143 | ItemStack stack = CommonUtils.readItem(item, false, addon);
144 |
145 | if (stack == null) {
146 | ExceptionHandler.handleError("在附属" + addon.getAddonId() + "中加载简单机器" + s + "时遇到了问题: " + "物品为空或格式错误导致无法加载");
147 | return null;
148 | }
149 |
150 | return List.of(new SlimefunItemStack(addon.getId(s, section.getString("id_alias")), stack));
151 | }
152 |
153 | private boolean isAccelerator(SimpleMachineType type) {
154 | return type == SimpleMachineType.TREE_GROWTH_ACCELERATOR
155 | || type == SimpleMachineType.CROP_GROWTH_ACCELERATOR
156 | || type == SimpleMachineType.ANIMAL_GROWTH_ACCELERATOR;
157 | }
158 | }
159 |
--------------------------------------------------------------------------------
/src/main/java/org/lins/mmmjjkx/rykenslimefuncustomizer/objects/yaml/machine/SolarGeneratorReader.java:
--------------------------------------------------------------------------------
1 | package org.lins.mmmjjkx.rykenslimefuncustomizer.objects.yaml.machine;
2 |
3 | import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
4 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
5 | import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
6 | import io.github.thebusybiscuit.slimefun4.libraries.dough.collections.Pair;
7 | import java.util.List;
8 | import java.util.Objects;
9 | import org.bukkit.configuration.ConfigurationSection;
10 | import org.bukkit.configuration.file.YamlConfiguration;
11 | import org.bukkit.inventory.ItemStack;
12 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.ProjectAddon;
13 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.customs.machine.CustomSolarGenerator;
14 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.yaml.YamlReader;
15 | import org.lins.mmmjjkx.rykenslimefuncustomizer.utils.CommonUtils;
16 | import org.lins.mmmjjkx.rykenslimefuncustomizer.utils.ExceptionHandler;
17 |
18 | public class SolarGeneratorReader extends YamlReader {
19 | public SolarGeneratorReader(YamlConfiguration config, ProjectAddon addon) {
20 | super(config, addon);
21 | }
22 |
23 | @Override
24 | public CustomSolarGenerator readEach(String s) {
25 | ConfigurationSection section = configuration.getConfigurationSection(s);
26 | if (section == null) return null;
27 | String id = addon.getId(s, section.getString("id_alias"));
28 |
29 | ExceptionHandler.HandleResult result = ExceptionHandler.handleIdConflict(id);
30 |
31 | if (result == ExceptionHandler.HandleResult.FAILED) return null;
32 |
33 | String igId = section.getString("item_group");
34 |
35 | Pair group = ExceptionHandler.handleItemGroupGet(addon, igId);
36 | if (group.getFirstValue() == ExceptionHandler.HandleResult.FAILED) return null;
37 |
38 | SlimefunItemStack slimefunItemStack = getPreloadItem(id);
39 | if (slimefunItemStack == null) return null;
40 |
41 | ItemStack[] recipe = CommonUtils.readRecipe(section.getConfigurationSection("recipe"), addon);
42 | String recipeType = section.getString("recipe_type", "NULL");
43 |
44 | Pair rt = ExceptionHandler.getRecipeType(
45 | "在附属" + addon.getAddonId() + "中加载太阳能发电机" + s + "时遇到了问题: " + "错误的配方类型" + recipeType + "!", recipeType);
46 |
47 | if (rt.getFirstValue() == ExceptionHandler.HandleResult.FAILED) return null;
48 |
49 | int dayEnergy = section.getInt("dayEnergy");
50 | int nightEnergy = section.getInt("nightEnergy");
51 |
52 | if (dayEnergy < 1) {
53 | ExceptionHandler.handleError("在附属" + addon.getAddonId() + "中加载太阳能发电机" + s + "时遇到了问题: " + "白天产电量不能小于1");
54 | return null;
55 | }
56 |
57 | if (nightEnergy < 1) {
58 | ExceptionHandler.handleError("在附属" + addon.getAddonId() + "中加载太阳能发电机" + s + "时遇到了问题: " + "夜晚产电量不能小于1");
59 | return null;
60 | }
61 |
62 | int capacity = section.getInt("capacity", 0);
63 | int lightLevel = section.getInt("lightLevel", 15);
64 |
65 | if (lightLevel < 0 || lightLevel > 15) {
66 | ExceptionHandler.handleError(
67 | "在附属" + addon.getAddonId() + "中加载太阳能发电机" + s + "时遇到了问题: " + "所需光照等级不能小于0或大于15,已转为15");
68 | lightLevel = 15;
69 | }
70 |
71 | return new CustomSolarGenerator(
72 | Objects.requireNonNull(group.getSecondValue()),
73 | dayEnergy,
74 | nightEnergy,
75 | slimefunItemStack,
76 | Objects.requireNonNull(rt.getSecondValue()),
77 | recipe,
78 | capacity,
79 | lightLevel);
80 | }
81 |
82 | @Override
83 | public List preloadItems(String s) {
84 | ConfigurationSection section = configuration.getConfigurationSection(s);
85 | if (section == null) return null;
86 |
87 | ConfigurationSection item = section.getConfigurationSection("item");
88 | ItemStack stack = CommonUtils.readItem(item, false, addon);
89 |
90 | if (stack == null) {
91 | ExceptionHandler.handleError("在附属" + addon.getAddonId() + "中加载太阳能发电机" + s + "时遇到了问题: " + "物品为空或格式错误导致无法加载");
92 | return null;
93 | }
94 |
95 | return List.of(new SlimefunItemStack(addon.getId(s, section.getString("id_alias")), stack));
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/src/main/java/org/lins/mmmjjkx/rykenslimefuncustomizer/update/GitHubRelease.java:
--------------------------------------------------------------------------------
1 | package org.lins.mmmjjkx.rykenslimefuncustomizer.update;
2 |
3 | import java.util.List;
4 | import lombok.Getter;
5 |
6 | @Getter
7 | public class GitHubRelease {
8 | private String url;
9 | private String html_url;
10 | private String assets_url;
11 | private String upload_url;
12 | private String tarball_url;
13 | private String zipball_url;
14 | private int id;
15 | private String node_id;
16 | private String tag_name;
17 | private String target_commitish;
18 | private String name;
19 | private String body;
20 | private boolean draft;
21 | private boolean prerelease;
22 | private String created_at;
23 | private String published_at;
24 | private Author author;
25 | private List assets;
26 |
27 | @Getter
28 | public static class Author {
29 | private String login;
30 | private int id;
31 | private String node_id;
32 | private String avatar_url;
33 | private String gravatar_id;
34 | private String url;
35 | private String html_url;
36 | private String followers_url;
37 | private String following_url;
38 | private String gists_url;
39 | private String starred_url;
40 | private String subscriptions_url;
41 | private String organizations_url;
42 | private String repos_url;
43 | private String events_url;
44 | private String received_events_url;
45 | private String type;
46 | private boolean site_admin;
47 | }
48 |
49 | @Getter
50 | public static class Asset {
51 | private String url;
52 | private String browser_download_url;
53 | private int id;
54 | private String node_id;
55 | private String name;
56 | private String label;
57 | private String state;
58 | private String content_type;
59 | private int size;
60 | private int download_count;
61 | private String created_at;
62 | private String updated_at;
63 | private Author uploader;
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/src/main/java/org/lins/mmmjjkx/rykenslimefuncustomizer/utils/ClassUtils.java:
--------------------------------------------------------------------------------
1 | package org.lins.mmmjjkx.rykenslimefuncustomizer.utils;
2 |
3 | import java.util.HashMap;
4 | import java.util.Map;
5 | import java.util.function.Function;
6 | import net.bytebuddy.ByteBuddy;
7 | import net.bytebuddy.dynamic.DynamicType;
8 | import org.jetbrains.annotations.Nullable;
9 |
10 | public class ClassUtils {
11 | private static final Map> cache = new HashMap<>();
12 |
13 | public static Class> generateClass(
14 | Class> extendClass,
15 | String centerName,
16 | String nameReplacement,
17 | Class>[] interfaces,
18 | @Nullable Function, DynamicType.Builder>> delegation) {
19 |
20 | String finalClassName = extendClass.getSimpleName().replace(nameReplacement, "") + centerName + nameReplacement;
21 | if (cache.containsKey(finalClassName)) {
22 | return cache.get(finalClassName);
23 | }
24 |
25 | DynamicType.Builder> builder = new ByteBuddy().subclass(extendClass);
26 |
27 | if (delegation != null) {
28 | builder = delegation.apply(builder);
29 | }
30 |
31 | builder = builder.implement(interfaces).name(finalClassName);
32 |
33 | Class> clazz;
34 | try (DynamicType.Unloaded> unloaded = builder.make()) {
35 | clazz = unloaded.load(extendClass.getClassLoader()).getLoaded();
36 | }
37 | cache.put(finalClassName, clazz);
38 | return clazz;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/java/org/lins/mmmjjkx/rykenslimefuncustomizer/utils/Constants.java:
--------------------------------------------------------------------------------
1 | package org.lins.mmmjjkx.rykenslimefuncustomizer.utils;
2 |
3 | public class Constants {
4 | public static final String INFO_FILE = "info.yml";
5 | public static final String MENUS_FILE = "menus.yml";
6 | public static final String ITEMS_FILE = "items.yml";
7 | public static final String GROUPS_FILE = "groups.yml";
8 | public static final String GEO_RES_FILE = "geo_resources.yml";
9 | public static final String RESEARCHES_FILE = "researches.yml";
10 | public static final String MACHINES_FILE = "machines.yml";
11 | public static final String GENERATORS_FILE = "generators.yml";
12 | public static final String MATERIAL_GENERATORS_FILE = "mat_generators.yml";
13 | public static final String RECIPE_MACHINES_FILE = "recipe_machines.yml";
14 | public static final String MULTI_BLOCK_MACHINES_FILE = "mb_machines.yml";
15 | public static final String SOLAR_GENERATORS_FILE = "solar_generators.yml";
16 | public static final String MOB_DROPS_FILE = "mob_drops.yml";
17 | public static final String RECIPE_TYPES_FILE = "recipe_types.yml";
18 | public static final String CAPACITORS_FILE = "capacitors.yml";
19 | public static final String SIMPLE_MACHINES_FILE = "simple_machines.yml";
20 | public static final String FOODS_FILE = "foods.yml";
21 | public static final String ARMORS_FILE = "armors.yml";
22 | public static final String SUPERS_FILE = "supers.yml";
23 | public static final String TEMPLATE_MACHINES_FILE = "template_machines.yml";
24 | public static final String LINKED_RECIPE_MACHINES_FILE = "linked_recipe_machines.yml";
25 | public static final String WORKBENCHES_FILE = "workbenches.yml";
26 | public static final String ADDON_CONFIG_FILE = "default_config.yml";
27 | }
28 |
--------------------------------------------------------------------------------
/src/main/java/org/lins/mmmjjkx/rykenslimefuncustomizer/utils/ExceptionHandler.java:
--------------------------------------------------------------------------------
1 | package org.lins.mmmjjkx.rykenslimefuncustomizer.utils;
2 |
3 | import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
4 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem;
5 | import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
6 | import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
7 | import io.github.thebusybiscuit.slimefun4.libraries.dough.collections.Pair;
8 | import java.lang.reflect.Field;
9 | import org.bukkit.Bukkit;
10 | import org.bukkit.command.ConsoleCommandSender;
11 | import org.jetbrains.annotations.NotNull;
12 | import org.lins.mmmjjkx.rykenslimefuncustomizer.RykenSlimefunCustomizer;
13 | import org.lins.mmmjjkx.rykenslimefuncustomizer.libraries.colors.CMIChatColor;
14 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.ProjectAddon;
15 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.customs.CustomMenu;
16 | import org.lins.mmmjjkx.rykenslimefuncustomizer.objects.global.RecipeTypeMap;
17 |
18 | public class ExceptionHandler {
19 | private static final @NotNull ConsoleCommandSender console = Bukkit.getConsoleSender();
20 |
21 | public static HandleResult handleIdConflict(String id) {
22 | SlimefunItem i = SlimefunItem.getById(id);
23 | if (i != null) {
24 | console.sendMessage(CMIChatColor.translate(
25 | "&4ERROR | ID冲突:" + id + "与" + i.getAddon().getName() + "中的物品发生了ID冲突"));
26 | return HandleResult.FAILED;
27 | }
28 | return HandleResult.SUCCESS;
29 | }
30 |
31 | public static HandleResult handleMenuConflict(String id, ProjectAddon addon) {
32 | CustomMenu menu = CommonUtils.getIf(addon.getMenus(), m -> m.getID().equalsIgnoreCase(id));
33 | if (menu != null) {
34 | console.sendMessage(CMIChatColor.translate("&4ERROR | ID冲突:已存在菜单ID为" + id + "的菜单"));
35 | return HandleResult.FAILED;
36 | }
37 | return HandleResult.SUCCESS;
38 | }
39 |
40 | public static HandleResult handleGroupIdConflict(String id) {
41 | ItemGroup ig = CommonUtils.getIf(
42 | Slimefun.getRegistry().getAllItemGroups(),
43 | i -> i.getKey().getKey().equalsIgnoreCase(id));
44 | if (ig != null) {
45 | if (ig.getAddon() != null) {
46 | if (ig.getAddon().getClass() == RykenSlimefunCustomizer.class) {
47 | console.sendMessage(CMIChatColor.translate(
48 | "&4ERROR | ID冲突:" + id + "与物品组 " + ig.getKey().getKey() + "发生ID冲突"));
49 | return HandleResult.FAILED;
50 | }
51 | return HandleResult.SUCCESS;
52 | }
53 | console.sendMessage(CMIChatColor.translate(
54 | "&4ERROR | ID冲突:" + id + "与物品组 " + ig.getKey().getKey() + "发生ID冲突"));
55 | return HandleResult.FAILED;
56 | }
57 | return HandleResult.SUCCESS;
58 | }
59 |
60 | public static void handleWarning(String message) {
61 | if (message == null || message.isBlank()) return;
62 |
63 | console.sendMessage(CMIChatColor.translate("&eWARNING | " + message));
64 | }
65 |
66 | public static void handleError(String message) {
67 | if (message == null || message.isBlank()) return;
68 |
69 | console.sendMessage(CMIChatColor.translate("&4ERROR | " + message));
70 | }
71 |
72 | public static void handleError(String message, Throwable e) {
73 | if (message == null || message.isBlank()) return;
74 |
75 | if (e != null) {
76 | console.sendMessage(CMIChatColor.translate("&4ERROR | " + message));
77 | e.printStackTrace();
78 | } else {
79 | handleError(message);
80 | }
81 | }
82 |
83 | public static void debugLog(String message) {
84 | if (RykenSlimefunCustomizer.INSTANCE.getConfig().getBoolean("debug")) {
85 | if (message == null || message.isBlank()) return;
86 |
87 | console.sendMessage(CMIChatColor.translate("&6DEBUG | " + message));
88 | }
89 | }
90 |
91 | /**
92 | * 检测后门等
93 | * @param message the message
94 | */
95 | public static void handleDanger(String message) {
96 | if (message == null || message.isBlank()) return;
97 |
98 | console.sendMessage(CMIChatColor.translate("&c&u&l&bD&4&lA&c&lN&b&lG&4&lE&c&lR | " + message));
99 | }
100 |
101 | public static void info(String message) {
102 | if (message == null || message.isBlank()) return;
103 |
104 | console.sendMessage(CMIChatColor.translate("&aINFO | " + message));
105 | }
106 |
107 | public static > Pair handleEnumValueOf(
108 | String msg, Class enumClass, String name) {
109 | try {
110 | return new Pair<>(HandleResult.SUCCESS, Enum.valueOf(enumClass, name.toUpperCase()));
111 | } catch (NullPointerException | IllegalArgumentException e) {
112 | handleError(msg);
113 | }
114 | return new Pair<>(HandleResult.FAILED, null);
115 | }
116 |
117 | public static Pair handleItemGroupGet(ProjectAddon addon, String id) {
118 | ItemGroup ig = CommonUtils.getIf(
119 | addon.getItemGroups(), i -> i.getKey().getKey().equalsIgnoreCase(id));
120 | if (ig == null) {
121 | ItemGroup ig2 = CommonUtils.getIf(
122 | Slimefun.getRegistry().getAllItemGroups(),
123 | i -> i.getKey().toString().equalsIgnoreCase(id));
124 | if (ig2 == null) {
125 | handleError("无法在附属" + addon.getAddonName() + "中找到该物品组 " + id);
126 | return new Pair<>(HandleResult.FAILED, null);
127 | }
128 | return new Pair<>(HandleResult.SUCCESS, ig2);
129 | }
130 | return new Pair<>(HandleResult.SUCCESS, ig);
131 | }
132 |
133 | public static Pair getRecipeType(String msg, String fieldName) {
134 | try {
135 | Field field = RecipeType.class.getDeclaredField(fieldName);
136 | return new Pair<>(HandleResult.SUCCESS, (RecipeType) field.get(null));
137 | } catch (NoSuchFieldException e) {
138 | RecipeType recipeType = RecipeTypeMap.getRecipeType(fieldName);
139 | if (recipeType == null) {
140 | handleError(msg);
141 | return new Pair<>(HandleResult.FAILED, null);
142 | }
143 | return new Pair<>(HandleResult.SUCCESS, recipeType);
144 | } catch (IllegalAccessException ignored) {
145 | // it doesn't happen
146 | }
147 | return new Pair<>(HandleResult.FAILED, null);
148 | }
149 |
150 | public enum HandleResult {
151 | SUCCESS,
152 | FAILED
153 | }
154 | }
155 |
--------------------------------------------------------------------------------
/src/main/java/org/lins/mmmjjkx/rykenslimefuncustomizer/utils/ItemUtils.java:
--------------------------------------------------------------------------------
1 | package org.lins.mmmjjkx.rykenslimefuncustomizer.utils;
2 |
3 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem;
4 | import java.util.HashSet;
5 | import java.util.Set;
6 | import javax.annotation.Nonnull;
7 | import org.bukkit.Material;
8 | import org.bukkit.inventory.ItemStack;
9 |
10 | public class ItemUtils {
11 | /**
12 | * @param itemStacks original item array
13 | * @return how many items there are in total
14 | */
15 | public static int getAllItemAmount(@Nonnull ItemStack... itemStacks) {
16 | int amount = 0;
17 | for (ItemStack itemStack : itemStacks) {
18 | if (itemStack == null || itemStack.getType().isAir()) {
19 | continue;
20 | }
21 |
22 | amount += itemStack.getAmount();
23 | }
24 |
25 | return amount;
26 | }
27 |
28 | /**
29 | * @param itemStacks original item array
30 | * @return how many kinds of item there are in total
31 | */
32 | public static int getAllItemTypeAmount(@Nonnull ItemStack... itemStacks) {
33 | Set sfItems = new HashSet<>();
34 | Set materials = new HashSet<>();
35 |
36 | for (ItemStack itemStack : itemStacks) {
37 |
38 | if (itemStack == null || itemStack.getType().isAir()) {
39 | continue;
40 | }
41 |
42 | SlimefunItem sfItem = SlimefunItem.getByItem(itemStack);
43 | if (sfItem != null) {
44 | sfItems.add(sfItem);
45 | } else {
46 | materials.add(itemStack.getType());
47 | }
48 | }
49 |
50 | return sfItems.size() + materials.size();
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/main/java/org/lins/mmmjjkx/rykenslimefuncustomizer/utils/ReflectionUtils.java:
--------------------------------------------------------------------------------
1 | package org.lins.mmmjjkx.rykenslimefuncustomizer.utils;
2 |
3 | import java.lang.reflect.Field;
4 | import java.lang.reflect.Method;
5 | import java.util.ArrayList;
6 | import java.util.Arrays;
7 | import java.util.List;
8 | import javax.annotation.Nonnull;
9 | import javax.annotation.Nullable;
10 |
11 | public class ReflectionUtils {
12 | @Nullable public static T getField(@Nonnull Object object, @Nonnull String fieldName)
13 | throws NoSuchFieldException, IllegalAccessException {
14 | Field[] fields = getAllFields(object);
15 | Field field = null;
16 | for (Field f : fields) {
17 | if (f.getName().equals(fieldName)) {
18 | field = f;
19 | break;
20 | }
21 | }
22 | if (field == null) throw new NoSuchFieldException(fieldName);
23 | field.setAccessible(true);
24 | return (T) field.get(object);
25 | }
26 |
27 | public static void setField(@Nonnull Object object, @Nonnull String fieldName, @Nullable T value)
28 | throws NoSuchFieldException, IllegalAccessException {
29 | Field[] fields = getAllFields(object);
30 | Field field = null;
31 | for (Field f : fields) {
32 | if (f.getName().equals(fieldName)) {
33 | field = f;
34 | break;
35 | }
36 | }
37 | if (field == null) throw new NoSuchFieldException(fieldName);
38 | field.setAccessible(true);
39 | field.set(object, value);
40 | }
41 |
42 | @Nonnull
43 | public static Field[] getAllFields(@Nonnull Object object) {
44 | Class> clazz = object.getClass();
45 | List fieldList = new ArrayList<>();
46 | while (clazz != null) {
47 | fieldList.addAll(new ArrayList<>(Arrays.asList(clazz.getDeclaredFields())));
48 | clazz = clazz.getSuperclass();
49 | }
50 | Field[] fields = new Field[fieldList.size()];
51 | fieldList.toArray(fields);
52 | return fields;
53 | }
54 |
55 | @Nonnull
56 | public static Method[] getAllMethods(@Nonnull Object object) {
57 | Class> clazz = object.getClass();
58 | List methodList = new ArrayList<>();
59 | while (clazz != null) {
60 | methodList.addAll(new ArrayList<>(Arrays.asList(clazz.getDeclaredMethods())));
61 | clazz = clazz.getSuperclass();
62 | }
63 | Method[] methods = new Method[methodList.size()];
64 | methodList.toArray(methods);
65 | return methods;
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/src/main/resources/addons/example/README.md:
--------------------------------------------------------------------------------
1 | ## 此处不再会放入示例
2 | ## 如需获取示例(最新),请前往
3 | ##
--------------------------------------------------------------------------------
/src/main/resources/addons/example/info.yml:
--------------------------------------------------------------------------------
1 | id: example
2 | name: "示例附属"
3 | depends: []
4 | pluginDepends: []
5 | version: "1.0"
6 | description: "RSC示例附属"
7 | authors: ["mmmjjkx"]
8 | repo: "SlimefunReloadingProject/rsc-example"
--------------------------------------------------------------------------------
/src/main/resources/config.yml:
--------------------------------------------------------------------------------
1 | # 是否自动获取示例
2 | saveExample: false
3 | # 是否获取调试日志,如果插件没有意外错误时,可以关闭该选项
4 | debug: false
5 | # 是否是否启用插件更新(需要GuizhanLibPlugin)
6 | pluginUpdate: true
7 | # 附属更新配置
8 | update:
9 | # 是否更新附属为预发布版本(一般这些版本很不稳定!)
10 | pre-releases: false
11 | # 自动更新附属
12 | auto: true
13 | # 禁止更新的附属
14 | # 请填写附属ID,而不是附属名字
15 | blocks:
16 | - ""
17 | #依赖下载仓库
18 | repositories:
19 | - https://maven.aliyun.com/repository/public
20 | - https://repo1.maven.org/maven2
--------------------------------------------------------------------------------
/src/main/resources/plugin.yml:
--------------------------------------------------------------------------------
1 | name: RykenSlimefunCustomizer
2 | version: '${project.version}'
3 | main: org.lins.mmmjjkx.rykenslimefuncustomizer.RykenSlimefunCustomizer
4 | api-version: '1.19'
5 | depend: [Slimefun]
6 | softdepend:
7 | - GuizhanLibPlugin
8 | - SlimeGlue
9 | - ColoredEnderChests
10 | - DyedBackpacks
11 | - EnderCargo
12 | - EcoPower
13 | - ElectricSpawners
14 | - ExoticGarden
15 | - ExtraGear
16 | - ExtraHeads
17 | - HotbarPets
18 | - luckyblocks-sf
19 | - RedstoneConnector
20 | - PrivateStorage
21 | - SlimefunOreChunks
22 | - SlimyTreeTaps
23 | - SoulJars
24 | - CommandOverride
25 | - EmeraldEnchants2
26 | - QuickMarket
27 | - QuickSell
28 | - RankPrefixPlus
29 | - MoreTools
30 | - LiteXpansion
31 | - MobCapturer
32 | - SoundMuffler
33 | - ExtraTools
34 | - TranscEndence
35 | - Liquid
36 | - SFCalc
37 | - SlimefunWarfare
38 | - Slimy-Power-Suits
39 | - InfernalExpansion
40 | - FluffyMachines
41 | - SlimyRepair
42 | - InfinityExpansion
43 | - FoxyMachines
44 | - GlobalWarming
45 | - GlobiaMachines
46 | - DynaTech
47 | - GeneticChickengineering
48 | - HeadLimiter
49 | - BlockLimiter
50 | - SlimeXpansion
51 | - Barrels
52 | #- ClayTech
53 | - FNAmplifications
54 | - SimpleMaterialGenerators
55 | - Netheopoiesis
56 | - Networks
57 | - EMC2
58 | - Nexcavate
59 | - SimpleStorage
60 | - SimpleUtils
61 | - AlchimiaVitae
62 | - SlimeTinker
63 | - PotionExpansion
64 | - FlowerPower
65 | - Galactifun
66 | - ElementManipulation
67 | - CrystamaeHistoria
68 | - DankTech
69 | - DankTech2
70 | - Networks-Changed
71 | - VillagerUtil
72 | - MissileWarfare
73 | - SensibleToolbox
74 | - Endrex
75 | - Bump
76 | - FinalTech # For build 29- (included)
77 | - FinalTECH # For build 29+
78 | - SlimefunLuckyBlocks
79 | - FutureTech
80 | - DemonicExpansion
81 | - BedrockTechnology
82 | - SlimefunItemExpansion
83 | - SupplementalServiceableness
84 | - GuizhanCraft
85 | - Magmanimous
86 | - UltimateGenerators-RC27 # 不确定是否存在这个版本
87 | - UltimateGenerators # 构建站有
88 | - UltimateGenerators2 # 同上
89 | - CrispyMachine
90 | - DimensionTraveler
91 | - Chocohills
92 | - draconic # 疑似新版
93 | - DracFun # 疑似旧版(?
94 | - EzSFAddon # 疑似旧版
95 | - EzTech # 疑似新版
96 | - RandomExpansion
97 | - ExLimus
98 | - MoneyAndThings
99 | - VoidHarvesters
100 | - SlimyBees
101 | - GeneticManipulation
102 | - ObsidianExpansion
103 | - NotEnoughAddons
104 | - SlimeSec
105 | - EMCTech
106 | - RelicsOfCthonia
107 | - Supreme
108 | - DyeBench
109 | - MiniBlocks
110 | - SlimeHUD
111 | - SpiritsUnchained
112 | - Cultivation
113 | - Gastronomicon
114 | - SmallSpace
115 | - BetterReactor
116 | - BetterGenerator
117 | - VillagerTrade
118 | - SlimeFrame
119 | - AdvancedTech
120 | - Quaptics
121 | - CompressionCraft
122 | - CringleBosses
123 | - ThermalFun
124 | - FastMachines
125 | - MomoTech
126 | - OreGeneration
127 | - Huolaiy
128 | - EnchanterLimit
129 | - LogicTech
130 | - LogiTech
131 | - LogicTECH
132 | - LogiTECH
133 | - SlimeAE
134 | - SlimeChem
135 | - WilderNether
136 | - MapJammers
137 | - Cakecraft
138 | - SFMobDrops
139 | - Drugfun
140 | - SlimefunNukes
141 | - SlimeCustomizer
142 | - HardcoreSlimefun
143 | - SfChunkInfo
144 | - SlimefunTranslation
145 | - FinalTECH-Changed
146 | - Blueprint
147 | - SlimefunMobDrops
148 | - BearFluidTanks
149 | - SCrafter
150 | - EquivalencyTech
151 | - LuckyPandas
152 | - FasterTools
153 | - Beyond_Horizons
154 | - BloodAlchemy
155 | - ExtraUtils
156 | - BlueSlime
157 | - XpCreator
158 | - BetterFarming
159 | - Automation
160 | - Ex-Limus
161 | - EzMiner
162 | - NetherEnough
163 | - magic-powder
164 | - BoxOfChocolates
165 | - AdditionalWeaponry
166 | - DisguiseCookies
167 | - MagicXpansion
168 | - Tofu-Addons
169 | - IDreamOfEasy
170 | # Other plugins
171 | - PlaceholderAPI
172 | - NBTAPI
173 | loadBefore:
174 | - SaneCrafting
175 | - SlimefunAdvancements
176 | authors: [mmmjjkx]
177 | description: An advanced Slimefun customize plugin
178 | commands:
179 | rykenslimecustomizer:
180 | aliases: ["rsc"]
181 | permission: rsc.command.help
182 | permissions:
183 | rsc.command:
184 | default: op
185 | children:
186 | rsc.command.help: true
187 | rsc.command.reload: true
188 | rsc.command.list: true
189 | rsc.command.reloadPlugin: true
190 | rsc.command.saveitem: true
191 | rsc.command.enable: true
192 | rsc.command.disable: true
193 | rsc.command.menupreview: true
194 | rsc.command.info: true
195 | rsc.command.help:
196 | default: op
197 | rsc.command.reload:
198 | default: op
199 | rsc.command.list:
200 | default: op
201 | rsc.command.reloadPlugin:
202 | default: op
203 | rsc.command.saveitem:
204 | default: op
205 | rsc.command.enable:
206 | default: op
207 | rsc.command.disable:
208 | default: op
209 | rsc.command.menupreview:
210 | default: op
211 | rsc.command.info:
212 | default: op
213 |
--------------------------------------------------------------------------------