├── .github ├── ISSUE_TEMPLATE │ ├── bug-report.md │ └── compatibility-issue--------.md └── workflows │ └── maven.yml ├── .gitignore ├── LICENSE ├── README.md ├── pom.xml ├── renovate.json └── src └── main ├── java └── com │ └── xzavier0722 │ └── mc │ └── plugin │ └── slimeglue │ ├── GlueLogger.java │ ├── SlimeGlue.java │ ├── api │ ├── ACompatibilityModule.java │ ├── listener │ │ ├── IListener.java │ │ ├── ISlimefunBlockListener.java │ │ └── SubscriptionType.java │ └── protection │ │ ├── IBlockProtectionHandler.java │ │ ├── IPlayerProtectionHandler.java │ │ └── IProtectionHandler.java │ ├── listener │ ├── BlockListener.java │ ├── PluginListener.java │ ├── SlimefunCompListener.java │ └── SlimefunListener.java │ ├── manager │ └── CompatibilityModuleManager.java │ ├── module │ ├── KingdomsXModule.java │ ├── LocketteProModule.java │ ├── MagicModule.java │ ├── QuickShopHikariModule.java │ └── QuickShopModule.java │ └── slimefun │ └── GlueProtectionModule.java └── resources └── plugin.yml /.github/ISSUE_TEMPLATE/bug-report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Report a bug 4 | title: "[BUG]" 5 | labels: ":exclamation: Bug" 6 | assignees: '' 7 | 8 | --- 9 | 10 | ## Description / 描述 11 | Please describe the issue in detail. 12 | 请详细描述遇到的问题。 13 | 14 | ## Environment / 环境 15 | Slimefun version / 粘液科技版本: 16 | Plugin version / 插件版本: 17 | OS / 操作系统: 18 | Server brand / 服务器核心 (Spigot/Paper/etc.): 19 | Server version / 服务器版本: 20 | Plugin list / 插件列表: 21 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/compatibility-issue--------.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Compatibility issue / 兼容性问题 3 | about: Issue about compatibility issue between Slimefun and other plugins. 4 | title: "[Compatibility]" 5 | labels: ":dna: Compatibility issue 兼容问题" 6 | assignees: '' 7 | 8 | --- 9 | 10 | ## Description / 描述 11 | Please describe the issue in detail. 12 | 请详细描述遇到的问题。 13 | 14 | ## Incompatible plugin information / 不兼容插件信息 15 | Plugin name / 插件名称: 16 | Plugin version / 插件版本: 17 | Publish website / 发布网址: 18 | Source code / 源码地址: 19 | 20 | ## Environment / 环境 21 | Slimefun version / 粘液科技版本: 22 | OS / 操作系统: 23 | Server brand / 服务器核心 (Spigot/Paper/etc.): 24 | Server version / 服务器版本: 25 | Plugin list / 插件列表: 26 | -------------------------------------------------------------------------------- /.github/workflows/maven.yml: -------------------------------------------------------------------------------- 1 | # This workflow will build a Java project with Maven, and cache/restore any dependencies to improve the workflow execution time 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven 3 | 4 | name: Auto build & release 5 | 6 | on: 7 | workflow_dispatch: 8 | push: 9 | branches: 10 | - master 11 | paths: 12 | - 'src/**' 13 | - 'pom.xml' 14 | - '.github/workflows/**' 15 | 16 | jobs: 17 | build: 18 | 19 | runs-on: ubuntu-latest 20 | 21 | steps: 22 | - uses: actions/checkout@v3 23 | - name: Set up JDK 8 24 | uses: actions/setup-java@v3 25 | with: 26 | java-version: '17' 27 | distribution: 'zulu' 28 | cache: maven 29 | - name: Build with Maven 30 | run: mvn -B package --file pom.xml 31 | - run: mkdir staging && cp target/*.jar staging 32 | - uses: actions/cache@v3 33 | if: github.event_name != 'pull_request' 34 | with: 35 | path: ~/.m2 36 | key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} 37 | restore-keys: ${{ runner.os }}-m2 38 | - uses: actions/upload-artifact@v4 39 | if: github.event_name != 'pull_request' 40 | with: 41 | name: SlimeGlue.jar 42 | path: staging 43 | - name: Automatic Releases 44 | uses: marvinpinto/action-automatic-releases@v1.2.1 45 | if: github.event_name != 'pull_request' 46 | with: 47 | repo_token: "${{ secrets.GITHUB_TOKEN }}" 48 | automatic_release_tag: "exp" 49 | prerelease: true 50 | title: "SlimeGlue exp version" 51 | files: | 52 | target/SlimeGlue-*.jar 53 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Xzavier0722 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SlimeGlue 2 | 3 | SlimeGlue is a [Slimefun](https://github.com/Slimefun/Slimefun4) addon which target to improve the compatibility with other plugins. 4 | 5 | 粘液胶是一个为提升[粘液科技](https://github.com/StarWishsama/Slimefun4)与其它插件兼容性的附属插件。 6 | 7 | 8 | _ 9 | 10 | If you found any plugin or any function cannot work well with Slimefun, please post an issue under this repository. 11 | 12 | 如果您发现任何不兼容的插件或功能,请在本仓库提交issue。 13 | 14 | You may be requested to verify the issue you posted. Thanks for your efforts! 15 | 16 | 您可能需要协助验证您提交的issue,非常感谢您的付出! 17 | 18 | 19 | _ 20 | 21 | ## Fixed compatibilities 已修复的问题 22 | 23 | ### [KingdomsX](https://github.com/CryptoMorin/KingdomsX/) 24 | - Fix Slimefun androids can break the blocks in unpermitted kingdom. [#3](https://github.com/Xzavier0722/SlimeGlue/issues/3) 25 | - Fix Slimefun androids can break structures/turrets blocks. [#3](https://github.com/Xzavier0722/SlimeGlue/issues/3) 26 | 27 | ### [Magic](https://github.com/elBukkit/MagicPlugin/) 28 | - Fix Slimefun androids can break fake block generated by spell to dupe items. [MagicPlugin#1172](https://github.com/elBukkit/MagicPlugin/issues/1172) 29 | 30 | ### [Quickshop-Reremake](https://github.com/PotatoCraft-Studio/QuickShop-Reremake) 31 | - Fix Slimefun androids can break chest QuickShop. 32 | 33 | ### [LockettePro](https://github.com/Soldier233/LockettePro) 34 | - Fix Slimefun androids can break the protected blocks. [#25](https://github.com/Xzavier0722/SlimeGlue/issues/25) -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.xzavier0722.mc.plugin 8 | SlimeGlue 9 | 1.0.2-${git.commit.id.abbrev} 10 | jar 11 | 12 | SlimeGlue 13 | 14 | A Slimefun addon, target to improve the compatibility with other plugins 15 | 16 | 16 17 | UTF-8 18 | 19 | https://github.com/Xzavier0722/SlimeGlue 20 | 21 | 22 | ${project.name}-exp-${git.commit.id.abbrev} 23 | 24 | 25 | org.apache.maven.plugins 26 | maven-compiler-plugin 27 | 3.11.0 28 | 29 | ${java.version} 30 | ${java.version} 31 | 32 | 33 | 34 | org.apache.maven.plugins 35 | maven-shade-plugin 36 | 3.4.1 37 | 38 | 39 | package 40 | 41 | shade 42 | 43 | 44 | false 45 | 46 | 47 | 48 | 49 | 50 | io.github.git-commit-id 51 | git-commit-id-maven-plugin 52 | 5.0.0 53 | 54 | 55 | 56 | revision 57 | 58 | initialize 59 | 60 | 61 | 62 | 63 | 64 | 65 | src/main/resources 66 | true 67 | 68 | 69 | 70 | 71 | 72 | 73 | spigotmc-repo 74 | https://hub.spigotmc.org/nexus/content/repositories/snapshots 75 | 76 | 77 | jitpack.io 78 | https://jitpack.io 79 | 80 | 81 | 82 | elmakers-repo 83 | https://maven.elmakers.com/repository/ 84 | 85 | 86 | codemc-repo 87 | https://repo.codemc.io/repository/maven-public/ 88 | 89 | 90 | lss233-mirror 91 | https://lss233.littleservice.cn/repositories/minecraft 92 | 93 | 94 | 95 | 96 | 97 | org.spigotmc 98 | spigot-api 99 | 1.19-R0.1-SNAPSHOT 100 | provided 101 | 102 | 103 | com.github.Slimefun 104 | Slimefun4 105 | RC-37 106 | provided 107 | 108 | 109 | com.github.cryptomorin 110 | kingdoms 111 | 1.13.9 112 | provided 113 | 114 | 115 | com.ghostchu 116 | quickshop-bukkit 117 | 6.2.0.8 118 | provided 119 | shaded 120 | 121 | 122 | org.maxgamer 123 | QuickShop 124 | 5.1.1.2 125 | provided 126 | 127 | 128 | * 129 | * 130 | 131 | 132 | 133 | 134 | com.elmakers.mine.bukkit 135 | MagicAPI 136 | 10.2 137 | provided 138 | 139 | 140 | * 141 | * 142 | 143 | 144 | 145 | 146 | com.github.Soldier233 147 | LockettePro 148 | 5505be4 149 | provided 150 | 151 | 152 | com.github.Xzavier0722 153 | SlimefunCompLib 154 | b7a2bd8 155 | provided 156 | 157 | 158 | 159 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "config:base", 4 | ":disableDependencyDashboard" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /src/main/java/com/xzavier0722/mc/plugin/slimeglue/GlueLogger.java: -------------------------------------------------------------------------------- 1 | package com.xzavier0722.mc.plugin.slimeglue; 2 | 3 | import java.util.logging.Level; 4 | import java.util.logging.Logger; 5 | 6 | public class GlueLogger { 7 | 8 | private final Logger logger; 9 | private boolean verbose = false; 10 | 11 | public GlueLogger(Logger logger) { 12 | this.logger = logger; 13 | } 14 | 15 | public void i(String msg) { 16 | logger.log(Level.INFO, msg); 17 | } 18 | 19 | public void w(String msg) { 20 | logger.log(Level.WARNING, msg); 21 | } 22 | 23 | public void e(String msg) { 24 | logger.log(Level.SEVERE, msg); 25 | } 26 | 27 | public void v(String msg) { 28 | if (!verbose) { 29 | return; 30 | } 31 | logger.log(Level.INFO, msg); 32 | } 33 | 34 | void setVerbose(boolean verbose) { 35 | // TODO: config this in somewhere.... 36 | this.verbose = verbose; 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/com/xzavier0722/mc/plugin/slimeglue/SlimeGlue.java: -------------------------------------------------------------------------------- 1 | package com.xzavier0722.mc.plugin.slimeglue; 2 | 3 | import com.xzavier0722.mc.plugin.slimefuncomplib.ICompatibleSlimefun; 4 | import com.xzavier0722.mc.plugin.slimeglue.listener.BlockListener; 5 | import com.xzavier0722.mc.plugin.slimeglue.listener.PluginListener; 6 | import com.xzavier0722.mc.plugin.slimeglue.listener.SlimefunCompListener; 7 | import com.xzavier0722.mc.plugin.slimeglue.listener.SlimefunListener; 8 | import com.xzavier0722.mc.plugin.slimeglue.manager.CompatibilityModuleManager; 9 | import com.xzavier0722.mc.plugin.slimeglue.module.KingdomsXModule; 10 | import com.xzavier0722.mc.plugin.slimeglue.module.QuickShopHikariModule; 11 | import com.xzavier0722.mc.plugin.slimeglue.module.LocketteProModule; 12 | import com.xzavier0722.mc.plugin.slimeglue.module.MagicModule; 13 | import com.xzavier0722.mc.plugin.slimeglue.module.QuickShopModule; 14 | import com.xzavier0722.mc.plugin.slimeglue.slimefun.GlueProtectionModule; 15 | import io.github.thebusybiscuit.slimefun4.api.SlimefunAddon; 16 | import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; 17 | import io.github.thebusybiscuit.slimefun4.libraries.dough.protection.ProtectionManager; 18 | import org.bukkit.plugin.java.JavaPlugin; 19 | 20 | import javax.annotation.Nonnull; 21 | import java.util.concurrent.atomic.AtomicInteger; 22 | 23 | public final class SlimeGlue extends JavaPlugin implements SlimefunAddon { 24 | 25 | private static SlimeGlue instance; 26 | private static GlueLogger logger; 27 | private static CompatibilityModuleManager moduleManager; 28 | 29 | @Override 30 | public void onEnable() { 31 | instance = this; 32 | logger = new GlueLogger(getLogger()); 33 | logger.i("====SlimeGlue Start===="); 34 | moduleManager = new CompatibilityModuleManager(); 35 | 36 | logger.i("- Loading modules..."); 37 | registerModules(); 38 | moduleManager().load(); 39 | 40 | logger.i("- Registering listeners..."); 41 | getServer().getPluginManager().registerEvents(new PluginListener(), this); 42 | getServer().getPluginManager().registerEvents(new BlockListener(), this); 43 | getServer().getPluginManager().registerEvents(new SlimefunListener(), this); 44 | if (isCompSlimefun()) { 45 | logger.i("- Compatible Slimefun detected, enabling advanced features..."); 46 | loadCompOnlyFeatures(); 47 | } 48 | 49 | logger.i("- Registering protection module..."); 50 | if (!registerSfProtectionModule()) { 51 | logger.w("- Failed to register protection module, schedule the retry task after the server started."); 52 | AtomicInteger counter = new AtomicInteger(); 53 | getServer().getScheduler().runTaskTimer(this, task -> { 54 | if (registerSfProtectionModule()) { 55 | logger.i("Protection module is registered!"); 56 | task.cancel(); 57 | return; 58 | } 59 | if (counter.getAndIncrement() >= 10) { 60 | logger.e("Failed to register the slimefun protection module, some function may not work properly"); 61 | task.cancel(); 62 | } 63 | }, 1, 20); 64 | } 65 | 66 | logger.i("- SlimeGlue Started!"); 67 | logger.i("======================="); 68 | } 69 | 70 | @Override 71 | public void onDisable() { 72 | // Plugin shutdown logic 73 | } 74 | 75 | @Nonnull 76 | @Override 77 | public JavaPlugin getJavaPlugin() { 78 | return this; 79 | } 80 | 81 | @Override 82 | public String getBugTrackerURL() { 83 | return "https://github.com/Xzavier0722/SlimeGlue/issues"; 84 | } 85 | 86 | public static SlimeGlue instance() { 87 | return instance; 88 | } 89 | 90 | public static GlueLogger logger() { 91 | return logger; 92 | } 93 | 94 | public static CompatibilityModuleManager moduleManager() { 95 | return moduleManager; 96 | } 97 | 98 | private void registerModules() { 99 | moduleManager().register(new KingdomsXModule()); 100 | moduleManager().register(new MagicModule()); 101 | moduleManager().register(new QuickShopModule()); 102 | moduleManager().register(new QuickShopHikariModule()); 103 | moduleManager().register(new LocketteProModule()); 104 | } 105 | 106 | private boolean registerSfProtectionModule() { 107 | ProtectionManager pm = Slimefun.getProtectionManager(); 108 | if (pm == null) { 109 | return false; 110 | } 111 | pm.registerModule(getServer().getPluginManager(), "SlimeGlue", (p) -> new GlueProtectionModule()); 112 | return true; 113 | } 114 | 115 | private boolean isCompSlimefun() { 116 | try { 117 | return ICompatibleSlimefun.class.isInstance(Slimefun.instance()); 118 | } catch (Throwable _ignore) { 119 | return false; 120 | } 121 | } 122 | 123 | private void loadCompOnlyFeatures() { 124 | getServer().getPluginManager().registerEvents(new SlimefunCompListener(), this); 125 | } 126 | 127 | } 128 | -------------------------------------------------------------------------------- /src/main/java/com/xzavier0722/mc/plugin/slimeglue/api/ACompatibilityModule.java: -------------------------------------------------------------------------------- 1 | package com.xzavier0722.mc.plugin.slimeglue.api; 2 | 3 | import com.xzavier0722.mc.plugin.slimeglue.SlimeGlue; 4 | import com.xzavier0722.mc.plugin.slimeglue.api.listener.IListener; 5 | import com.xzavier0722.mc.plugin.slimeglue.api.protection.IProtectionHandler; 6 | import org.bukkit.plugin.Plugin; 7 | 8 | import java.util.HashSet; 9 | import java.util.Set; 10 | 11 | public abstract class ACompatibilityModule { 12 | 13 | private final Set listeners; 14 | private final Set protectionHandlers; 15 | 16 | public ACompatibilityModule() { 17 | listeners = new HashSet<>(); 18 | protectionHandlers = new HashSet<>(); 19 | } 20 | 21 | public Set getListeners() { 22 | return listeners; 23 | } 24 | 25 | public Set getProtectionHandlers() { 26 | return protectionHandlers; 27 | } 28 | 29 | protected void addListener(IListener listener) { 30 | listeners.add(listener); 31 | } 32 | 33 | protected void removeListener(IListener listener) { 34 | listeners.remove(listener); 35 | } 36 | 37 | protected void addProtectionHandler(IProtectionHandler handler) { 38 | protectionHandlers.add(handler); 39 | } 40 | 41 | protected void removeProtectionHandler(IProtectionHandler handler) { 42 | protectionHandlers.remove(handler); 43 | } 44 | 45 | protected void verbose(String msg) { 46 | SlimeGlue.logger().v("[" + getClass().getSimpleName() + "]: " + msg); 47 | } 48 | 49 | protected T verbose(String msg, T para) { 50 | verbose(msg + para); 51 | return para; 52 | } 53 | 54 | /** 55 | * 56 | * Define the compatible target plugin name 57 | * 58 | * @return name of the plugin 59 | */ 60 | abstract public String getCompatibilityPluginName(); 61 | 62 | /** 63 | * 64 | * Fired when the plugin specified in {@link #getCompatibilityPluginName()} is present 65 | * 66 | * @param plugin: the {@link Plugin} instance of the specific plugin 67 | */ 68 | abstract public void enable(Plugin plugin) throws Exception; 69 | 70 | /** 71 | * 72 | * Fired when the plugin specified in {@link #getCompatibilityPluginName()} is disabled 73 | * 74 | */ 75 | abstract public void disable(); 76 | 77 | } 78 | -------------------------------------------------------------------------------- /src/main/java/com/xzavier0722/mc/plugin/slimeglue/api/listener/IListener.java: -------------------------------------------------------------------------------- 1 | package com.xzavier0722.mc.plugin.slimeglue.api.listener; 2 | 3 | import java.util.HashSet; 4 | import java.util.Set; 5 | 6 | public interface IListener { 7 | 8 | /** 9 | * 10 | * Define the subscription type of the listener 11 | * 12 | * @see SubscriptionType 13 | * @return the subscription type 14 | */ 15 | default SubscriptionType getSubscriptionType() { 16 | return SubscriptionType.SUBSCRIBE_TYPE_ALL; 17 | } 18 | 19 | /** 20 | * 21 | * Define the subscribed id. 22 | * If the subscription type is ALL, the result of this will be ignored. 23 | * 24 | * @return Set of subscribed id 25 | */ 26 | default Set getSubscribedId() { 27 | return new HashSet<>(); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/xzavier0722/mc/plugin/slimeglue/api/listener/ISlimefunBlockListener.java: -------------------------------------------------------------------------------- 1 | package com.xzavier0722.mc.plugin.slimeglue.api.listener; 2 | 3 | import org.bukkit.Location; 4 | import org.bukkit.entity.Player; 5 | 6 | public interface ISlimefunBlockListener extends IListener{ 7 | /** 8 | * 9 | * Fired when a slimefun block is placing, the cancelled event will be ignored. 10 | * 11 | * @param sfId: the placing slimefun item id 12 | * @param player: the player who placed this block 13 | * @param location: the location of this placing 14 | * @return if allowed placing 15 | */ 16 | default boolean onPlaceEvent(String sfId, Player player, Location location) { 17 | return true; 18 | } 19 | 20 | /** 21 | * 22 | * Fired when a slimefun block is breaking, the cancelled event will be ignored. 23 | * 24 | * @param sfId: the breaking slimefun item id 25 | * @param player: the player who broke this block 26 | * @param location: the location of this breaking 27 | * @return if allowed breaking 28 | */ 29 | default boolean onBreakEvent(String sfId, Player player, Location location) { 30 | return true; 31 | } 32 | 33 | /** 34 | * 35 | * Fired after place event, you can monitor the result of the event. 36 | * 37 | * @see #onPlaceEvent 38 | * @param isCancelled: if the event cancelled 39 | */ 40 | default void afterPlaceEvent(String sfId, Player player, Location location, boolean isCancelled) { } 41 | 42 | /** 43 | * 44 | * Fired after break event, you can monitor the result of the event. 45 | * 46 | * @see #onBreakEvent 47 | * @param isCancelled: fi the event cancelled 48 | */ 49 | default void afterBreakEvent(String sfId, Player player, Location location, boolean isCancelled) { } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/com/xzavier0722/mc/plugin/slimeglue/api/listener/SubscriptionType.java: -------------------------------------------------------------------------------- 1 | package com.xzavier0722.mc.plugin.slimeglue.api.listener; 2 | 3 | public enum SubscriptionType { 4 | 5 | /** 6 | * Subscribe all events 7 | */ 8 | SUBSCRIBE_TYPE_ALL, 9 | 10 | /** 11 | * Subscribe the event with specific id only 12 | */ 13 | SUBSCRIBE_TYPE_SPECIFIED 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/xzavier0722/mc/plugin/slimeglue/api/protection/IBlockProtectionHandler.java: -------------------------------------------------------------------------------- 1 | package com.xzavier0722.mc.plugin.slimeglue.api.protection; 2 | 3 | import org.bukkit.Location; 4 | import org.bukkit.OfflinePlayer; 5 | 6 | public interface IBlockProtectionHandler extends IProtectionHandler { 7 | 8 | default boolean canPlaceBlock(OfflinePlayer player, Location location) { 9 | return true; 10 | } 11 | 12 | default boolean canBreakBlock(OfflinePlayer player, Location location) { 13 | return true; 14 | } 15 | 16 | default boolean canInteractBlock(OfflinePlayer player, Location location) { 17 | return true; 18 | } 19 | 20 | default boolean canCargoAccessBlock(Location location) { 21 | return true; 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/xzavier0722/mc/plugin/slimeglue/api/protection/IPlayerProtectionHandler.java: -------------------------------------------------------------------------------- 1 | package com.xzavier0722.mc.plugin.slimeglue.api.protection; 2 | 3 | import org.bukkit.Location; 4 | import org.bukkit.OfflinePlayer; 5 | 6 | public interface IPlayerProtectionHandler extends IProtectionHandler { 7 | 8 | default boolean canAttackPlayer(OfflinePlayer player, Location location) { 9 | return true; 10 | } 11 | 12 | default boolean canAttackEntity(OfflinePlayer player, Location location) { 13 | return true; 14 | } 15 | 16 | default boolean canInteractEntity(OfflinePlayer player, Location location) { 17 | return true; 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/xzavier0722/mc/plugin/slimeglue/api/protection/IProtectionHandler.java: -------------------------------------------------------------------------------- 1 | package com.xzavier0722.mc.plugin.slimeglue.api.protection; 2 | 3 | import org.bukkit.Location; 4 | import org.bukkit.OfflinePlayer; 5 | 6 | public interface IProtectionHandler { 7 | 8 | default boolean bypassCheck(OfflinePlayer player, Location location) { 9 | return false; 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/com/xzavier0722/mc/plugin/slimeglue/listener/BlockListener.java: -------------------------------------------------------------------------------- 1 | package com.xzavier0722.mc.plugin.slimeglue.listener; 2 | 3 | import com.xzavier0722.mc.plugin.slimeglue.SlimeGlue; 4 | import com.xzavier0722.mc.plugin.slimeglue.api.listener.IListener; 5 | import com.xzavier0722.mc.plugin.slimeglue.api.listener.ISlimefunBlockListener; 6 | import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem; 7 | import io.github.thebusybiscuit.slimefun4.core.attributes.NotPlaceable; 8 | import me.mrCookieSlime.Slimefun.api.BlockStorage; 9 | import org.bukkit.Location; 10 | import org.bukkit.event.EventHandler; 11 | import org.bukkit.event.EventPriority; 12 | import org.bukkit.event.Listener; 13 | import org.bukkit.event.block.BlockBreakEvent; 14 | import org.bukkit.event.block.BlockPlaceEvent; 15 | 16 | public class BlockListener implements Listener { 17 | 18 | @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) 19 | public void onBlockBreak(BlockBreakEvent e) { 20 | Location loc = e.getBlock().getLocation(); 21 | SlimefunItem sfItem = BlockStorage.check(loc); 22 | if (sfItem == null) { 23 | return; 24 | } 25 | 26 | String sfId = sfItem.getId(); 27 | for (IListener l : SlimeGlue.moduleManager().getListeners(sfId)) { 28 | if (l instanceof ISlimefunBlockListener) { 29 | if (!((ISlimefunBlockListener) l).onBreakEvent(sfId, e.getPlayer(), loc)) { 30 | e.setCancelled(true); 31 | return; 32 | } 33 | } 34 | } 35 | } 36 | 37 | @EventHandler(priority = EventPriority.MONITOR) 38 | public void afterBlockBreak(BlockBreakEvent e) { 39 | Location loc = e.getBlock().getLocation(); 40 | SlimefunItem sfItem = BlockStorage.check(loc); 41 | if (sfItem == null) { 42 | return; 43 | } 44 | 45 | String sfId = sfItem.getId(); 46 | for (IListener l : SlimeGlue.moduleManager().getListeners(sfId)) { 47 | if (l instanceof ISlimefunBlockListener) { 48 | ((ISlimefunBlockListener) l).afterBreakEvent(sfId, e.getPlayer(), loc, e.isCancelled()); 49 | } 50 | } 51 | } 52 | 53 | @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) 54 | public void onBlockPlace(BlockPlaceEvent e) { 55 | SlimefunItem sfItem = SlimefunItem.getByItem(e.getItemInHand()); 56 | if (sfItem == null || sfItem instanceof NotPlaceable) { 57 | return; 58 | } 59 | 60 | String sfId = sfItem.getId(); 61 | for (IListener l : SlimeGlue.moduleManager().getListeners(sfId)) { 62 | if (l instanceof ISlimefunBlockListener) { 63 | if (!((ISlimefunBlockListener) l).onPlaceEvent(sfId, e.getPlayer(), e.getBlock().getLocation())) { 64 | e.setCancelled(true); 65 | return; 66 | } 67 | } 68 | } 69 | } 70 | 71 | @EventHandler(priority = EventPriority.MONITOR) 72 | public void afterBlockPlace(BlockPlaceEvent e) { 73 | SlimefunItem sfItem = SlimefunItem.getByItem(e.getItemInHand()); 74 | if (sfItem == null || sfItem instanceof NotPlaceable) { 75 | return; 76 | } 77 | 78 | String sfId = sfItem.getId(); 79 | for (IListener l : SlimeGlue.moduleManager().getListeners(sfId)) { 80 | if (l instanceof ISlimefunBlockListener) { 81 | ((ISlimefunBlockListener) l).afterPlaceEvent(sfId, e.getPlayer(), e.getBlock().getLocation(), e.isCancelled()); 82 | } 83 | } 84 | } 85 | 86 | } 87 | -------------------------------------------------------------------------------- /src/main/java/com/xzavier0722/mc/plugin/slimeglue/listener/PluginListener.java: -------------------------------------------------------------------------------- 1 | package com.xzavier0722.mc.plugin.slimeglue.listener; 2 | 3 | import com.xzavier0722.mc.plugin.slimeglue.SlimeGlue; 4 | import org.bukkit.event.EventHandler; 5 | import org.bukkit.event.Listener; 6 | import org.bukkit.event.server.PluginDisableEvent; 7 | import org.bukkit.event.server.PluginEnableEvent; 8 | 9 | public class PluginListener implements Listener { 10 | 11 | @EventHandler 12 | public void onPluginEnable(PluginEnableEvent e) { 13 | SlimeGlue.moduleManager().load(e.getPlugin().getName()); 14 | } 15 | 16 | @EventHandler 17 | public void onPluginDisable(PluginDisableEvent e) { 18 | SlimeGlue.moduleManager().unload(e.getPlugin().getName()); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/xzavier0722/mc/plugin/slimeglue/listener/SlimefunCompListener.java: -------------------------------------------------------------------------------- 1 | package com.xzavier0722.mc.plugin.slimeglue.listener; 2 | 3 | import com.xzavier0722.mc.plugin.slimefuncomplib.event.cargo.CargoOperationEvent; 4 | import com.xzavier0722.mc.plugin.slimeglue.SlimeGlue; 5 | import com.xzavier0722.mc.plugin.slimeglue.api.protection.IBlockProtectionHandler; 6 | import org.bukkit.event.EventHandler; 7 | import org.bukkit.event.EventPriority; 8 | import org.bukkit.event.Listener; 9 | 10 | public class SlimefunCompListener implements Listener { 11 | 12 | @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) 13 | public void onCargoOperation(CargoOperationEvent e) { 14 | var l = e.getTarget().getLocation(); 15 | v("onCargoOperation: " + l); 16 | for (var each : SlimeGlue.moduleManager().getProtectionHandlers()) { 17 | if (each instanceof IBlockProtectionHandler handler && !handler.canCargoAccessBlock(l)) { 18 | e.setCancelled(true); 19 | return; 20 | } 21 | } 22 | } 23 | 24 | private void v(String msg) { 25 | SlimeGlue.logger().v("[SlimefunCompListener]: " + msg); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/xzavier0722/mc/plugin/slimeglue/listener/SlimefunListener.java: -------------------------------------------------------------------------------- 1 | package com.xzavier0722.mc.plugin.slimeglue.listener; 2 | 3 | import com.xzavier0722.mc.plugin.slimeglue.SlimeGlue; 4 | import com.xzavier0722.mc.plugin.slimeglue.api.protection.IBlockProtectionHandler; 5 | import io.github.thebusybiscuit.slimefun4.api.events.BlockPlacerPlaceEvent; 6 | import me.mrCookieSlime.Slimefun.api.BlockStorage; 7 | import org.bukkit.Bukkit; 8 | import org.bukkit.event.EventHandler; 9 | import org.bukkit.event.EventPriority; 10 | import org.bukkit.event.Listener; 11 | 12 | import java.util.UUID; 13 | 14 | public class SlimefunListener implements Listener { 15 | 16 | @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) 17 | public void onBlockPlacerPlace(BlockPlacerPlaceEvent e) { 18 | var l = e.getBlockPlacer().getLocation(); 19 | var ownerUuid = BlockStorage.getLocationInfo(l, "owner"); 20 | if (ownerUuid == null) { 21 | return; 22 | } 23 | 24 | var owner = Bukkit.getOfflinePlayer(UUID.fromString(ownerUuid)); 25 | for (var each : SlimeGlue.moduleManager().getProtectionHandlers()) { 26 | if (each instanceof IBlockProtectionHandler handler) { 27 | if (!handler.canPlaceBlock(owner, e.getBlock().getLocation())) { 28 | e.setCancelled(true); 29 | return; 30 | } 31 | } 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/com/xzavier0722/mc/plugin/slimeglue/manager/CompatibilityModuleManager.java: -------------------------------------------------------------------------------- 1 | package com.xzavier0722.mc.plugin.slimeglue.manager; 2 | 3 | import com.xzavier0722.mc.plugin.slimeglue.SlimeGlue; 4 | import com.xzavier0722.mc.plugin.slimeglue.api.ACompatibilityModule; 5 | import com.xzavier0722.mc.plugin.slimeglue.api.listener.IListener; 6 | import com.xzavier0722.mc.plugin.slimeglue.api.listener.SubscriptionType; 7 | import com.xzavier0722.mc.plugin.slimeglue.api.protection.IProtectionHandler; 8 | import org.bukkit.plugin.Plugin; 9 | 10 | import java.util.HashMap; 11 | import java.util.HashSet; 12 | import java.util.Map; 13 | import java.util.Set; 14 | 15 | public class CompatibilityModuleManager { 16 | 17 | private final Map disabledModules; 18 | private final Map enabledModules; 19 | 20 | public CompatibilityModuleManager() { 21 | disabledModules = new HashMap<>(); 22 | enabledModules = new HashMap<>(); 23 | } 24 | 25 | public void register(ACompatibilityModule module) { 26 | disabledModules.put(module.getCompatibilityPluginName(), module); 27 | } 28 | 29 | public void load() { 30 | disabledModules.values().removeIf(this::load); 31 | } 32 | 33 | public void load(String pluginName) { 34 | ACompatibilityModule module = disabledModules.get(pluginName); 35 | if (module == null) { 36 | return; 37 | } 38 | 39 | load(module); 40 | } 41 | 42 | public void unload(String pluginName) { 43 | ACompatibilityModule module = enabledModules.remove(pluginName); 44 | if (module == null) { 45 | return; 46 | } 47 | 48 | module.disable(); 49 | disabledModules.put(module.getCompatibilityPluginName(), module); 50 | } 51 | 52 | public Set getListeners(String sfId) { 53 | Set re = new HashSet<>(); 54 | enabledModules.values().forEach(module -> module.getListeners().forEach(l -> { 55 | if (l.getSubscriptionType() == SubscriptionType.SUBSCRIBE_TYPE_ALL || l.getSubscribedId().contains(sfId)) { 56 | re.add(l); 57 | } 58 | })); 59 | return re; 60 | } 61 | 62 | public Set getProtectionHandlers() { 63 | Set re = new HashSet<>(); 64 | enabledModules.values().forEach(module -> re.addAll(module.getProtectionHandlers())); 65 | return re; 66 | } 67 | 68 | private boolean load(ACompatibilityModule module) { 69 | String name = module.getCompatibilityPluginName(); 70 | SlimeGlue.logger().i("Loading compatibility module for " + name); 71 | Plugin plugin = SlimeGlue.instance().getServer().getPluginManager().getPlugin(name); 72 | 73 | if (plugin == null || !plugin.isEnabled()) { 74 | SlimeGlue.logger().w("Plugin " + name + " is not installed or enabled, module ignored."); 75 | return false; 76 | } 77 | 78 | try { 79 | module.enable(plugin); 80 | enabledModules.put(name, module); 81 | return true; 82 | } catch (Throwable e) { 83 | SlimeGlue.logger().e("Exception thrown while loading the compatibility module for " + name); 84 | e.printStackTrace(); 85 | } 86 | return false; 87 | } 88 | 89 | } 90 | -------------------------------------------------------------------------------- /src/main/java/com/xzavier0722/mc/plugin/slimeglue/module/KingdomsXModule.java: -------------------------------------------------------------------------------- 1 | package com.xzavier0722.mc.plugin.slimeglue.module; 2 | 3 | import com.xzavier0722.mc.plugin.slimeglue.api.ACompatibilityModule; 4 | import com.xzavier0722.mc.plugin.slimeglue.api.protection.IBlockProtectionHandler; 5 | import com.xzavier0722.mc.plugin.slimeglue.api.protection.IPlayerProtectionHandler; 6 | import org.bukkit.Location; 7 | import org.bukkit.OfflinePlayer; 8 | import org.bukkit.plugin.Plugin; 9 | import org.kingdoms.constants.group.Kingdom; 10 | import org.kingdoms.constants.land.Land; 11 | import org.kingdoms.constants.land.location.SimpleChunkLocation; 12 | 13 | public class KingdomsXModule extends ACompatibilityModule { 14 | 15 | public KingdomsXModule() { 16 | addProtectionHandler(new IBlockProtectionHandler() { 17 | @Override 18 | public boolean canPlaceBlock(OfflinePlayer player, Location location) { 19 | verbose("canPlaceBlock: player=" + player.getName() + ", loc=" + location); 20 | return canAccess(player, location); 21 | } 22 | 23 | @Override 24 | public boolean canBreakBlock(OfflinePlayer player, Location location) { 25 | verbose("canBreakBlock: player=" + player.getName() + ", loc=" + location); 26 | return canAccess(player, location); 27 | } 28 | 29 | @Override 30 | public boolean canInteractBlock(OfflinePlayer player, Location location) { 31 | verbose("canInteractBlock: player=" + player.getName() + ", loc=" + location); 32 | return canAccess(player, location); 33 | } 34 | }); 35 | 36 | addProtectionHandler(new IPlayerProtectionHandler() { 37 | @Override 38 | public boolean canAttackPlayer(OfflinePlayer player, Location location) { 39 | verbose("canAttackPlayer: player=" + player.getName() + ", loc=" + location); 40 | return canAccess(player, location); 41 | } 42 | 43 | @Override 44 | public boolean canAttackEntity(OfflinePlayer player, Location location) { 45 | verbose("canAttackEntity: player=" + player.getName() + ", loc=" + location); 46 | return canAccess(player, location); 47 | } 48 | 49 | @Override 50 | public boolean canInteractEntity(OfflinePlayer player, Location location) { 51 | verbose("canInteractEntity: player=" + player.getName() + ", loc=" + location); 52 | return canAccess(player, location); 53 | } 54 | }); 55 | } 56 | 57 | private boolean canAccess(OfflinePlayer p, Location l) { 58 | Land land = SimpleChunkLocation.of(l).getLand(); 59 | verbose("canAccess: " + land); 60 | if (land == null || !land.isClaimed()) { 61 | return true; 62 | } 63 | 64 | Kingdom kingdom = land.getKingdom(); 65 | return verbose( 66 | "canAccess: ret=", 67 | kingdom == null || p.getUniqueId().equals(kingdom.getKingId()) || kingdom.isMember(p) 68 | ); 69 | } 70 | 71 | @Override 72 | public String getCompatibilityPluginName() { 73 | return "Kingdoms"; 74 | } 75 | 76 | @Override 77 | public void enable(Plugin plugin) { 78 | 79 | } 80 | 81 | @Override 82 | public void disable() { 83 | 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/main/java/com/xzavier0722/mc/plugin/slimeglue/module/LocketteProModule.java: -------------------------------------------------------------------------------- 1 | package com.xzavier0722.mc.plugin.slimeglue.module; 2 | 3 | import com.xzavier0722.mc.plugin.slimeglue.api.ACompatibilityModule; 4 | import com.xzavier0722.mc.plugin.slimeglue.api.protection.IBlockProtectionHandler; 5 | import me.crafter.mc.lockettepro.LocketteProAPI; 6 | import org.bukkit.Location; 7 | import org.bukkit.OfflinePlayer; 8 | import org.bukkit.plugin.Plugin; 9 | 10 | public class LocketteProModule extends ACompatibilityModule { 11 | 12 | public LocketteProModule() { 13 | addProtectionHandler(new IBlockProtectionHandler() { 14 | @Override 15 | public boolean canCargoAccessBlock(Location location) { 16 | return verbose("canCargoAccessBlock: ", !LocketteProAPI.isProtected(location.getBlock())); 17 | } 18 | 19 | @Override 20 | public boolean canBreakBlock(OfflinePlayer player, Location location) { 21 | verbose("canBreakBlock: p=" + player.getName() + ", l=" + location); 22 | return false; 23 | } 24 | 25 | @Override 26 | public boolean canInteractBlock(OfflinePlayer player, Location location) { 27 | verbose("canInteractBlock: p=" + player.getName() + ", l=" + location); 28 | var p = player.getPlayer(); 29 | return verbose("canInteractBlock: ", p != null && LocketteProAPI.isUser(location.getBlock(), p)); 30 | } 31 | 32 | @Override 33 | public boolean bypassCheck(OfflinePlayer player, Location location) { 34 | var b = location.getBlock(); 35 | if (player.isOp()) { 36 | return true; 37 | } 38 | 39 | if (!LocketteProAPI.isProtected(b)) { 40 | return true; 41 | } 42 | 43 | var p = player.getPlayer(); 44 | return p != null && LocketteProAPI.isOwner(b, p); 45 | } 46 | }); 47 | } 48 | 49 | @Override 50 | public String getCompatibilityPluginName() { 51 | return "LockettePro"; 52 | } 53 | 54 | @Override 55 | public void enable(Plugin plugin) throws Exception { 56 | 57 | } 58 | 59 | @Override 60 | public void disable() { 61 | 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/com/xzavier0722/mc/plugin/slimeglue/module/MagicModule.java: -------------------------------------------------------------------------------- 1 | package com.xzavier0722.mc.plugin.slimeglue.module; 2 | 3 | import com.elmakers.mine.bukkit.api.block.BlockData; 4 | import com.xzavier0722.mc.plugin.slimeglue.SlimeGlue; 5 | import com.xzavier0722.mc.plugin.slimeglue.api.ACompatibilityModule; 6 | import com.xzavier0722.mc.plugin.slimeglue.api.protection.IBlockProtectionHandler; 7 | import org.bukkit.Location; 8 | import org.bukkit.OfflinePlayer; 9 | import org.bukkit.plugin.Plugin; 10 | 11 | import javax.annotation.Nonnull; 12 | import java.lang.reflect.Method; 13 | import java.util.Objects; 14 | 15 | public class MagicModule extends ACompatibilityModule { 16 | private Method magicBlockDataMethod = null; 17 | 18 | public MagicModule() { 19 | addProtectionHandler(new IBlockProtectionHandler() { 20 | @Override 21 | public boolean canBreakBlock(OfflinePlayer player, Location location) { 22 | verbose("canBreakBlock: player=" + player.getName() + ", loc=" + location); 23 | return !isMagicBlock(location); 24 | } 25 | }); 26 | } 27 | 28 | @Override 29 | public String getCompatibilityPluginName() { 30 | return "Magic"; 31 | } 32 | 33 | @Override 34 | public void enable(Plugin plugin) throws Exception { 35 | if (plugin != null && magicBlockDataMethod == null) { 36 | magicBlockDataMethod = Class.forName("com.elmakers.mine.bukkit.block.UndoList") 37 | .getDeclaredMethod("getBlockData", Location.class); 38 | 39 | Objects.requireNonNull(magicBlockDataMethod, "Unable to get method from Magic"); 40 | 41 | magicBlockDataMethod.setAccessible(true); 42 | } 43 | } 44 | 45 | private boolean isMagicBlock(@Nonnull Location location) { 46 | try { 47 | var blockData = magicBlockDataMethod.invoke(null, location); 48 | verbose("isMagicBlock: " + blockData); 49 | if (blockData instanceof BlockData) { 50 | return true; 51 | } 52 | } catch (Exception e) { 53 | SlimeGlue.logger().w("Unable to check magic BlockData"); 54 | e.printStackTrace(); 55 | return true; 56 | } 57 | 58 | return false; 59 | } 60 | 61 | @Override 62 | public void disable() { 63 | magicBlockDataMethod = null; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/main/java/com/xzavier0722/mc/plugin/slimeglue/module/QuickShopHikariModule.java: -------------------------------------------------------------------------------- 1 | package com.xzavier0722.mc.plugin.slimeglue.module; 2 | 3 | import com.ghostchu.quickshop.api.QuickShopAPI; 4 | import com.ghostchu.quickshop.api.shop.Shop; 5 | import com.xzavier0722.mc.plugin.slimeglue.api.ACompatibilityModule; 6 | import com.xzavier0722.mc.plugin.slimeglue.api.protection.IBlockProtectionHandler; 7 | import org.bukkit.Location; 8 | import org.bukkit.OfflinePlayer; 9 | import org.bukkit.plugin.Plugin; 10 | 11 | import javax.annotation.Nonnull; 12 | import java.util.UUID; 13 | 14 | public class QuickShopHikariModule extends ACompatibilityModule { 15 | 16 | public QuickShopHikariModule() { 17 | addProtectionHandler(new IBlockProtectionHandler() { 18 | @Override 19 | public boolean canBreakBlock(OfflinePlayer player, Location location) { 20 | return !isQuickshop(location); 21 | } 22 | 23 | @Override 24 | public boolean canInteractBlock(OfflinePlayer player, Location location) { 25 | return !isQuickshop(location); 26 | } 27 | 28 | @Override 29 | public boolean bypassCheck(OfflinePlayer player, Location location) { 30 | return player.getUniqueId().equals(getQuickshopOwner(location)); 31 | } 32 | 33 | @Override 34 | public boolean canCargoAccessBlock(Location location) { 35 | return !isQuickshop(location); 36 | } 37 | }); 38 | } 39 | 40 | private UUID getQuickshopOwner(@Nonnull Location l) { 41 | Shop shop = QuickShopAPI.getInstance().getShopManager().getShop(l); 42 | if (shop != null) { 43 | return shop.getOwner().getUniqueId(); 44 | } 45 | return null; 46 | 47 | } 48 | 49 | private boolean isQuickshop(@Nonnull Location l) { 50 | return QuickShopAPI.getInstance().getShopManager().getShop(l) != null; 51 | 52 | } 53 | 54 | @Override 55 | public String getCompatibilityPluginName() { 56 | return "QuickShop-Hikari"; 57 | } 58 | 59 | @Override 60 | public void enable(Plugin plugin) throws Exception { 61 | 62 | } 63 | 64 | @Override 65 | public void disable() { 66 | 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/com/xzavier0722/mc/plugin/slimeglue/module/QuickShopModule.java: -------------------------------------------------------------------------------- 1 | package com.xzavier0722.mc.plugin.slimeglue.module; 2 | 3 | import com.xzavier0722.mc.plugin.slimeglue.SlimeGlue; 4 | import com.xzavier0722.mc.plugin.slimeglue.api.ACompatibilityModule; 5 | import com.xzavier0722.mc.plugin.slimeglue.api.protection.IBlockProtectionHandler; 6 | import org.bukkit.Bukkit; 7 | import org.bukkit.Location; 8 | import org.bukkit.OfflinePlayer; 9 | import org.bukkit.plugin.Plugin; 10 | import org.maxgamer.quickshop.api.QuickShopAPI; 11 | 12 | import javax.annotation.Nonnull; 13 | import java.lang.reflect.InvocationTargetException; 14 | import java.lang.reflect.Method; 15 | import java.util.Optional; 16 | import java.util.UUID; 17 | 18 | public class QuickShopModule extends ACompatibilityModule { 19 | private static Object shopAPI = null; 20 | private static Method qsMethod = null; 21 | 22 | public QuickShopModule() { 23 | addProtectionHandler(new IBlockProtectionHandler() { 24 | @Override 25 | public boolean canBreakBlock(OfflinePlayer player, Location location) { 26 | return !isQuickshop(location); 27 | } 28 | 29 | @Override 30 | public boolean canInteractBlock(OfflinePlayer player, Location location) { 31 | return !isQuickshop(location); 32 | } 33 | 34 | @Override 35 | public boolean bypassCheck(OfflinePlayer player, Location location) { 36 | return player.getUniqueId().equals(getQuickshopOwner(location)); 37 | } 38 | 39 | @Override 40 | public boolean canCargoAccessBlock(Location location) { 41 | return !isQuickshop(location); 42 | } 43 | }); 44 | } 45 | 46 | private UUID getQuickshopOwner(@Nonnull Location l) { 47 | var qsPlugin = Bukkit.getPluginManager().getPlugin("QuickShop"); 48 | 49 | if (qsPlugin == null) { 50 | return null; 51 | } 52 | 53 | if (qsMethod != null) { 54 | // no support for old version 55 | return null; 56 | } 57 | 58 | if (qsPlugin instanceof QuickShopAPI qsAPI) { 59 | var shop = qsAPI.getShopManager().getShop(l); 60 | return shop == null ? null : shop.getOwner(); 61 | } else { 62 | SlimeGlue.logger().w("Unable to check QuickShop"); 63 | return null; 64 | } 65 | } 66 | 67 | private boolean isQuickshop(@Nonnull Location l) { 68 | var qsPlugin = Bukkit.getPluginManager().getPlugin("QuickShop"); 69 | 70 | if (qsPlugin == null) { 71 | return false; 72 | } 73 | 74 | if (qsMethod != null) { 75 | try { 76 | if (shopAPI == null) { 77 | return false; 78 | } 79 | 80 | var result = qsMethod.invoke(shopAPI, l); 81 | 82 | if (result instanceof Optional optional) { 83 | return optional.isPresent(); 84 | } else { 85 | return false; 86 | } 87 | } catch (IllegalAccessException | InvocationTargetException e) { 88 | SlimeGlue.logger().w("Unable to check Quickshop"); 89 | e.printStackTrace(); 90 | return false; 91 | } 92 | } 93 | 94 | if (qsPlugin instanceof QuickShopAPI qsAPI) { 95 | return qsAPI.getShopManager().getShop(l) != null; 96 | } else { 97 | SlimeGlue.logger().w("Unable to check Quickshop"); 98 | return false; 99 | } 100 | } 101 | 102 | @Override 103 | public String getCompatibilityPluginName() { 104 | return "Quickshop"; 105 | } 106 | 107 | @Override 108 | public void enable(Plugin plugin) throws Exception { 109 | var version = plugin.getDescription().getVersion(); 110 | var splitVersion = version.split("-")[0].split("\\."); 111 | 112 | try { 113 | var major = Integer.parseInt(splitVersion[0]); 114 | var sub = Integer.parseInt(splitVersion[2]); 115 | var last = Integer.parseInt(splitVersion[3]); 116 | 117 | if (major < 5) { 118 | SlimeGlue.logger().w("Your QuickShop-Reremake is outdated! Please update to latest version for better performance on checking QuickShop."); 119 | 120 | try { 121 | var shopAPIMethod = Class.forName("org.maxgamer.quickshop.QuickShopAPI").getDeclaredMethod("getShopAPI"); 122 | shopAPIMethod.setAccessible(true); 123 | shopAPI = shopAPIMethod.invoke(null); 124 | } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException | 125 | InvocationTargetException e) { 126 | SlimeGlue.logger().w("Unable to integrate Quickshop-Reremake " + version + ", Please update to latest version!"); 127 | throw e; 128 | } 129 | 130 | if (sub >= 8 && last >= 2) { 131 | // For 5.0.0- 132 | try { 133 | qsMethod = Class.forName("org.maxgamer.quickshop.api.ShopAPI").getDeclaredMethod("getShop", Location.class); 134 | qsMethod.setAccessible(true); 135 | } catch (ClassNotFoundException | NoSuchMethodException e) { 136 | SlimeGlue.logger().w("Unable to integrate Quickshop-Reremake " + version + ", Please update to latest version!"); 137 | throw e; 138 | } 139 | } else { 140 | // For 4.0.8- 141 | try { 142 | qsMethod = Class.forName("org.maxgamer.quickshop.api.ShopAPI").getDeclaredMethod("getShopWithCaching", Location.class); 143 | qsMethod.setAccessible(true); 144 | } catch (ClassNotFoundException | NoSuchMethodException e) { 145 | SlimeGlue.logger().w("Unable to integrate Quickshop-Reremake " + version + ", Please update to latest version!"); 146 | throw e; 147 | } 148 | } 149 | } 150 | } catch (ArrayIndexOutOfBoundsException e) { 151 | SlimeGlue.logger().w("Unable to parse version code of Quickshop-Reremake " + version); 152 | throw e; 153 | } 154 | } 155 | 156 | @Override 157 | public void disable() { 158 | qsMethod = null; 159 | shopAPI = null; 160 | } 161 | } 162 | -------------------------------------------------------------------------------- /src/main/java/com/xzavier0722/mc/plugin/slimeglue/slimefun/GlueProtectionModule.java: -------------------------------------------------------------------------------- 1 | package com.xzavier0722.mc.plugin.slimeglue.slimefun; 2 | 3 | import com.xzavier0722.mc.plugin.slimeglue.SlimeGlue; 4 | import com.xzavier0722.mc.plugin.slimeglue.api.protection.IBlockProtectionHandler; 5 | import com.xzavier0722.mc.plugin.slimeglue.api.protection.IPlayerProtectionHandler; 6 | import io.github.thebusybiscuit.slimefun4.libraries.dough.protection.Interaction; 7 | import io.github.thebusybiscuit.slimefun4.libraries.dough.protection.ProtectionModule; 8 | import org.bukkit.Location; 9 | import org.bukkit.OfflinePlayer; 10 | import org.bukkit.plugin.Plugin; 11 | 12 | public class GlueProtectionModule implements ProtectionModule { 13 | 14 | @Override 15 | public void load() { 16 | 17 | } 18 | 19 | @Override 20 | public Plugin getPlugin() { 21 | return SlimeGlue.instance(); 22 | } 23 | 24 | @Override 25 | public boolean hasPermission(OfflinePlayer p, Location l, Interaction interaction) { 26 | switch (interaction) { 27 | case BREAK_BLOCK: 28 | for (var each : SlimeGlue.moduleManager().getProtectionHandlers()) { 29 | if (each instanceof IBlockProtectionHandler handler) { 30 | if (handler.bypassCheck(p, l)) { 31 | continue; 32 | } 33 | if (!handler.canBreakBlock(p, l)) { 34 | return false; 35 | } 36 | } 37 | } 38 | break; 39 | case PLACE_BLOCK: 40 | for (var each : SlimeGlue.moduleManager().getProtectionHandlers()) { 41 | if (each instanceof IBlockProtectionHandler handler) { 42 | if (handler.bypassCheck(p, l)) { 43 | continue; 44 | } 45 | if (!handler.canPlaceBlock(p, l)) { 46 | return false; 47 | } 48 | } 49 | } 50 | break; 51 | case ATTACK_ENTITY: 52 | for (var each : SlimeGlue.moduleManager().getProtectionHandlers()) { 53 | if (each instanceof IPlayerProtectionHandler handler) { 54 | if (handler.bypassCheck(p, l)) { 55 | continue; 56 | } 57 | if (!handler.canAttackEntity(p, l)) { 58 | return false; 59 | } 60 | } 61 | } 62 | break; 63 | case ATTACK_PLAYER: 64 | for (var each : SlimeGlue.moduleManager().getProtectionHandlers()) { 65 | if (each instanceof IPlayerProtectionHandler handler) { 66 | if (handler.bypassCheck(p, l)) { 67 | continue; 68 | } 69 | if (!handler.canAttackPlayer(p, l)) { 70 | return false; 71 | } 72 | } 73 | } 74 | break; 75 | case INTERACT_BLOCK: 76 | for (var each : SlimeGlue.moduleManager().getProtectionHandlers()) { 77 | if (each instanceof IBlockProtectionHandler handler) { 78 | if (handler.bypassCheck(p, l)) { 79 | continue; 80 | } 81 | if (!handler.canInteractBlock(p, l)) { 82 | return false; 83 | } 84 | } 85 | } 86 | break; 87 | case INTERACT_ENTITY: 88 | for (var each : SlimeGlue.moduleManager().getProtectionHandlers()) { 89 | if (each instanceof IPlayerProtectionHandler handler) { 90 | if (handler.bypassCheck(p, l)) { 91 | continue; 92 | } 93 | if (!handler.canInteractEntity(p, l)) { 94 | return false; 95 | } 96 | } 97 | } 98 | break; 99 | default: 100 | return true; 101 | } 102 | return true; 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /src/main/resources/plugin.yml: -------------------------------------------------------------------------------- 1 | name: SlimeGlue 2 | version: '${project.version}' 3 | main: com.xzavier0722.mc.plugin.slimeglue.SlimeGlue 4 | api-version: 1.13 5 | depend: [ Slimefun ] 6 | softdepend: 7 | - Kingdoms 8 | - Quickshop 9 | - QuickShop-Hikari 10 | - Magic 11 | - LockettePro 12 | authors: [ Xzavier0722 ] 13 | description: A Slimefun addon, target to improve the compatibility with other plugins 14 | website: https://github.com/Xzavier0722/SlimeGlue 15 | --------------------------------------------------------------------------------