├── .github ├── ISSUE_TEMPLATE │ ├── bug-report.yml │ ├── config.yml │ └── feature-request.yml ├── dependabot.yml ├── pull-request.md └── workflows │ ├── docs.yml │ └── publish.yml ├── .gitignore ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── api ├── build.gradle.kts └── src │ └── main │ └── java │ └── de │ └── skyslycer │ └── hmcwraps │ ├── HMCWraps.java │ ├── actions │ ├── Action.java │ ├── ActionHandler.java │ ├── ActionMethod.java │ └── information │ │ ├── ActionInformation.java │ │ ├── BasicActionInformation.java │ │ ├── GuiActionInformation.java │ │ ├── WrapActionInformation.java │ │ └── WrapGuiActionInformation.java │ ├── events │ ├── ItemPreviewEvent.java │ ├── ItemUnwrapEvent.java │ └── ItemWrapEvent.java │ ├── itemhook │ ├── DefaultItemHook.java │ ├── HookAccessor.java │ └── ItemHook.java │ ├── messages │ ├── MessageHandler.java │ └── Messages.java │ ├── pool │ ├── ObjectPool.java │ └── PoolMethod.java │ ├── preview │ ├── Preview.java │ ├── PreviewManager.java │ ├── floating │ │ ├── FloatingPreview.java │ │ └── RotateRunnable.java │ └── hand │ │ └── HandPreview.java │ ├── serialization │ ├── Config.java │ ├── Toggleable.java │ ├── files │ │ ├── CollectionFile.java │ │ └── WrapFile.java │ ├── filter │ │ └── FilterSettings.java │ ├── globaldisable │ │ └── GlobalDisable.java │ ├── inventory │ │ ├── Inventory.java │ │ ├── InventoryItem.java │ │ └── ShortcutSettings.java │ ├── item │ │ └── SerializableItem.java │ ├── permission │ │ └── PermissionSettings.java │ ├── preservation │ │ ├── PreservationSettings.java │ │ └── ValuePreservationSettings.java │ ├── preview │ │ ├── Bobbing.java │ │ ├── PreviewSettings.java │ │ ├── PreviewType.java │ │ └── SneakCancel.java │ ├── updater │ │ └── UpdaterSettings.java │ ├── wrap │ │ ├── PhysicalWrap.java │ │ ├── Wrap.java │ │ ├── WrappableItem.java │ │ └── range │ │ │ ├── RangeSettings.java │ │ │ └── ValueRangeSettings.java │ └── wrapping │ │ ├── RewrapSettings.java │ │ └── WrappingSettings.java │ ├── storage │ └── Storage.java │ ├── updater │ ├── CheckResult.java │ ├── PluginPlatform.java │ ├── PluginUpdater.java │ └── version │ │ └── PluginVersion.java │ ├── util │ ├── ColorUtil.java │ ├── ListUtil.java │ ├── MaterialUtil.java │ ├── MathUtil.java │ ├── PermissionUtil.java │ ├── PlayerUtil.java │ ├── StringUtil.java │ ├── VectorUtil.java │ ├── VersionUtil.java │ └── WrapNBTUtil.java │ └── wrap │ ├── ArmorModifiers.java │ ├── CollectionHelper.java │ ├── Wrapper.java │ ├── WrapsLoader.java │ └── modifiers │ ├── WrapModifier.java │ ├── WrapModifiers.java │ ├── minecraft │ ├── ArmorImitationModifier.java │ ├── ColorModifier.java │ ├── EquippableModifier.java │ ├── FlagsModifier.java │ ├── GlintOverrideModifier.java │ ├── ItemModelModifier.java │ ├── LoreModifier.java │ ├── ModelDataModifier.java │ ├── NBTModifier.java │ ├── NameModifier.java │ └── TrimModifier.java │ └── plugin │ ├── ExecutableItemsModifier.java │ ├── ItemsAdderModifier.java │ ├── MythicModifier.java │ ├── NexoModifier.java │ └── OraxenModifier.java ├── build.gradle.kts ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle.kts └── src └── main ├── java └── de │ └── skyslycer │ └── hmcwraps │ ├── HMCWrapsPlugin.java │ ├── actions │ └── register │ │ └── DefaultActionRegister.java │ ├── commands │ ├── CommandRegister.java │ ├── DebugCommand.java │ ├── TestCommand.java │ ├── WrapCommand.java │ └── annotations │ │ ├── AnyPermission.java │ │ ├── AnyPermissionReader.java │ │ └── NoHelp.java │ ├── converter │ ├── FileConverter.java │ └── ItemSkinsFile.java │ ├── debug │ └── DebugCreator.java │ ├── gui │ ├── GuiBuilder.java │ ├── ItemComparator.java │ └── WrapItemCombination.java │ ├── itemhook │ ├── ItemsAdderItemHook.java │ ├── MythicItemHook.java │ ├── NexoItemHook.java │ └── OraxenItemHook.java │ ├── listener │ ├── DispenserArmorListener.java │ ├── DurabilityChangeListener.java │ ├── InventoryClickListener.java │ ├── ItemBurnListener.java │ ├── PlayerDropListener.java │ ├── PlayerHitEntityListener.java │ ├── PlayerInteractListener.java │ ├── PlayerJoinListener.java │ ├── PlayerOffHandSwitchListener.java │ ├── PlayerPickupListener.java │ └── PlayerShiftListener.java │ ├── messages │ └── MessageHandlerImpl.java │ ├── metrics │ └── PluginMetrics.java │ ├── nbtapi │ └── logger │ │ └── NoInfoLogger.java │ ├── placeholderapi │ └── HMCWrapsPlaceholders.java │ ├── pool │ ├── MessagePool.java │ └── MessagePoolEntry.java │ ├── serialization │ └── debug │ │ ├── DebugConfig.java │ │ ├── DebugInformation.java │ │ ├── DebugItemData.java │ │ ├── DebugPlayer.java │ │ ├── DebugWrap.java │ │ ├── DebugWraps.java │ │ └── Debuggable.java │ ├── storage │ ├── FavoriteWrapStorage.java │ └── PlayerFilterStorage.java │ ├── transformation │ ├── ConfigFileTransformations.java │ ├── FileTransformations.java │ └── WrapFileTransformations.java │ ├── updater │ ├── ContinuousUpdateChecker.java │ ├── PolymartPluginUpdater.java │ └── SpigotPluginUpdater.java │ └── wrap │ ├── CollectionHelperImpl.java │ ├── WrapperImpl.java │ └── WrapsLoaderImpl.java └── resources ├── config.yml ├── emerald_wraps.yml ├── messages.properties ├── silver_wraps.yml └── some_collections.yml /.github/ISSUE_TEMPLATE/bug-report.yml: -------------------------------------------------------------------------------- 1 | name: Bug Report 2 | description: Create a bug report to help us keep track of all bugs that have to be fixed 3 | title: "[BUG] " 4 | labels: [ bug ] 5 | 6 | body: 7 | - type: "checkboxes" 8 | id: "i-have-checked" 9 | attributes: 10 | label: "I have checked that..." 11 | options: 12 | - label: "...I am using the latest version of HMCWraps" 13 | required: true 14 | - label: "...I have checked if any similar bug reports exist" 15 | required: true 16 | - label: "...I have checked if I am using a supported Minecraft version" 17 | required: true 18 | - type: "textarea" 19 | id: "description" 20 | attributes: 21 | label: "Description" 22 | description: "A full description of the bug" 23 | validations: 24 | required: true 25 | - type: "textarea" 26 | id: "reproduce" 27 | attributes: 28 | label: "Steps to reproduce" 29 | description: "Explain how to reproduce this issue step-by-step, in as much detail as possible." 30 | validations: 31 | required: true 32 | - type: "textarea" 33 | id: "hmcw-version" 34 | attributes: 35 | label: "Plugin Version" 36 | description: "Run `version HMCWraps` in your console and paste the output" 37 | validations: 38 | required: true 39 | - type: "textarea" 40 | id: "server-version" 41 | attributes: 42 | label: "Server Version" 43 | description: "Run `version` in your console and paste the output." 44 | validations: 45 | required: true 46 | - type: "dropdown" 47 | id: "type" 48 | attributes: 49 | label: "How breaking is the bug?" 50 | options: 51 | - "Breaking Bug - Plugin unusable" 52 | - "Non-breaking Bug - Plugin still usable, but certain features unavailable" 53 | - "Minor Bug - Plugin completely functional, but features have non-working aspects" 54 | validations: 55 | required: true 56 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: "Discord Support" 4 | url: "https://discord.gg/pcm8kWrdNt" 5 | about: "You receive support here" 6 | - name: "Spigot Page" 7 | url: "https://www.coming-soon.com/" 8 | about: "The plugin page on SpigotMC" 9 | - name: "Polymart Page" 10 | url: "https://www.coming-soon.com/" 11 | about: "The plugin page on Polymart" 12 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature-request.yml: -------------------------------------------------------------------------------- 1 | name: Feature Request 2 | description: Create a feature request to help us keep track of all features you want to be added 3 | title: "[FEATURE] <title>" 4 | labels: [ feature ] 5 | 6 | body: 7 | - type: "checkboxes" 8 | id: "i-have-checked" 9 | attributes: 10 | label: "I have checked that..." 11 | options: 12 | - label: "...such a feature does not exist already" 13 | required: true 14 | - label: "...such a feature request has not been submitted already" 15 | required: true 16 | - type: "textarea" 17 | id: "description" 18 | attributes: 19 | label: "Description" 20 | description: "A full description of the feature" 21 | validations: 22 | required: true 23 | - type: "textarea" 24 | id: "config-changes" 25 | attributes: 26 | label: "Config Changes" 27 | description: "The configuration changes your feature should have" 28 | validations: 29 | required: true 30 | - type: "dropdown" 31 | id: "type" 32 | attributes: 33 | label: "How significant is the feature?" 34 | options: 35 | - "Huge - Requires many changes in the current structure" 36 | - "Moderate - Needs moderate changes to the current structure" 37 | - "Meerly Significant - Small feature fitting perfectly into the current structure" 38 | validations: 39 | required: true 40 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "gradle" 4 | directory: "/" 5 | labels: 6 | - "dependabot" 7 | schedule: 8 | interval: "weekly" 9 | - package-ecosystem: "gradle" 10 | directory: "/api/" 11 | labels: 12 | - "dependabot" 13 | schedule: 14 | interval: "weekly" -------------------------------------------------------------------------------- /.github/pull-request.md: -------------------------------------------------------------------------------- 1 | **Pull Request**: <feature/bug-fix> 2 | 3 | **I have checked that...** 4 | 5 | - [ ] ...there are no such pull requests already 6 | - [ ] ...there are no similar features planned by the dev team 7 | 8 | **This pull request includes or changes:** <br> 9 | _Extensive description of your pull request._ 10 | 11 | **Critical changes:** <br> 12 | _Are any critical changes included we should consider?_ 13 | -------------------------------------------------------------------------------- /.github/workflows/docs.yml: -------------------------------------------------------------------------------- 1 | name: Build and deploy documentation to GitHub Pages 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | 8 | permissions: 9 | contents: read 10 | pages: write 11 | id-token: write 12 | 13 | jobs: 14 | build: 15 | if: "!contains(github.event.head_commit.message, 'dependabot') && !contains(github.event.head_commit.message, 'nodocs')" 16 | runs-on: ubuntu-latest 17 | steps: 18 | - uses: actions/checkout@v4 19 | - name: Bypass Cloudflare for GitHub Action 20 | uses: xiaotianxt/bypass-cloudflare-for-github-action@v1.1.1 21 | with: 22 | cf_zone_id: ${{ secrets.CF_ZONE_ID }} 23 | cf_api_token: ${{ secrets.CF_API_TOKEN }} 24 | - uses: actions/setup-java@v4 25 | with: 26 | distribution: 'temurin' 27 | java-version: 17 28 | - uses: gradle/gradle-build-action@v2 29 | - name: Build HTML 30 | run: ./gradlew api:dokkaHtml --no-daemon --stacktrace 31 | - name: Upload artifact 32 | uses: actions/upload-pages-artifact@v3 33 | with: 34 | path: 'api/build/dokka/html' 35 | 36 | deploy: 37 | if: "!contains(github.event.head_commit.message, 'dependabot')" 38 | environment: 39 | name: github-pages 40 | url: 'https://hibiscusmc.github.io/HMCWraps/' 41 | runs-on: ubuntu-latest 42 | needs: build 43 | steps: 44 | - name: Deploy to GitHub Pages 45 | id: deployment 46 | uses: actions/deploy-pages@v4 -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: Publish to Skyslycer Repository 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | 8 | jobs: 9 | build: 10 | if: "!contains(github.event.head_commit.message, 'dependabot') && !contains(github.event.head_commit.message, 'nopush')" 11 | environment: build 12 | runs-on: ubuntu-latest 13 | env: 14 | HAS_TOKEN: ${{ secrets.REPO_PASSWORD != '' }} 15 | steps: 16 | - uses: actions/checkout@v2.3.4 17 | - name: Bypass Cloudflare for GitHub Action 18 | uses: xiaotianxt/bypass-cloudflare-for-github-action@v1.1.1 19 | with: 20 | cf_zone_id: ${{ secrets.CF_ZONE_ID }} 21 | cf_api_token: ${{ secrets.CF_API_TOKEN }} 22 | - name: Set up Java 23 | uses: actions/setup-java@v2 24 | with: 25 | distribution: 'temurin' 26 | java-version: 17 27 | - name: Build with Gradle 28 | run: ./gradlew api:clean api:build --no-daemon --stacktrace 29 | - name: Publish to Nexus 30 | if: ${{ env.HAS_TOKEN == 'true' }} 31 | run: ./gradlew api:publishMavenPublicationToHibiscusMCRepository 32 | env: 33 | REPO_USERNAME: ${{ secrets.REPO_USERNAME }} 34 | REPO_PASSWORD: ${{ secrets.REPO_PASSWORD }} -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | .idea 3 | build 4 | api/build 5 | run 6 | bin 7 | api/bin -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | When contributing to this repository, please first discuss the change you wish to make via issue, 4 | email, or any other method with the owners of this repository before making a change. 5 | 6 | Please note we have a code of conduct, please follow it in all your interactions with the project. 7 | 8 | ## Process of Contributing 9 | 10 | 1. Clone the project and open it in your desired IDE. 11 | 2. Make your changes. Please follow 12 | the [Google Style Guide](https://google.github.io/styleguide/javaguide.html). 13 | 3. Bump versions in **all** `build.gradle.kts` files. We use the [SemVer](http://semver.org/) scheme. (`M`.`M` 14 | .`P`) 15 | 4. Commit your changes with a descriptive message to a separate branch. Name it appropriately. 16 | 5. Build the project and test your changes extensively. 17 | 5. Create a pull using our template. 18 | 6. Wait for approval. Answer upcoming questions. 19 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/HMCWraps.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps; 2 | 3 | import com.tcoded.folialib.FoliaLib; 4 | import de.skyslycer.hmcwraps.actions.ActionHandler; 5 | import de.skyslycer.hmcwraps.itemhook.HookAccessor; 6 | import de.skyslycer.hmcwraps.messages.MessageHandler; 7 | import de.skyslycer.hmcwraps.pool.ObjectPool; 8 | import de.skyslycer.hmcwraps.preview.PreviewManager; 9 | import de.skyslycer.hmcwraps.serialization.Config; 10 | import de.skyslycer.hmcwraps.serialization.wrap.Wrap; 11 | import de.skyslycer.hmcwraps.storage.Storage; 12 | import de.skyslycer.hmcwraps.wrap.CollectionHelper; 13 | import de.skyslycer.hmcwraps.wrap.Wrapper; 14 | import de.skyslycer.hmcwraps.wrap.WrapsLoader; 15 | import net.kyori.adventure.text.Component; 16 | import org.bukkit.entity.Player; 17 | import org.bukkit.plugin.Plugin; 18 | 19 | import java.nio.file.Path; 20 | import java.util.List; 21 | import java.util.UUID; 22 | 23 | public interface HMCWraps extends Plugin { 24 | 25 | Path PLUGIN_PATH = Path.of("plugins", "HMCWraps"); 26 | Path CONFIG_PATH = PLUGIN_PATH.resolve("config.yml"); 27 | Path WRAP_FILES_PATH = PLUGIN_PATH.resolve("wraps"); 28 | Path MESSAGES_PATH = PLUGIN_PATH.resolve("messages.properties"); 29 | Path CONVERT_PATH = PLUGIN_PATH.resolve("convert"); 30 | Path COMMAND_PATH = WRAP_FILES_PATH.resolve("command"); 31 | Path COLLECTION_FILES_PATH = PLUGIN_PATH.resolve("collections"); 32 | 33 | /** 34 | * Load the plugin. Used for reload. 35 | * 36 | * @return If the plugin was able to load 37 | */ 38 | boolean load(); 39 | 40 | /** 41 | * Unload the plugin. Used for reload. 42 | */ 43 | void unload(); 44 | 45 | /** 46 | * Log an error that stands out from other system messages. 47 | * 48 | * @param message The message to display 49 | * @param thrown The exception that was thrown (null if none) 50 | */ 51 | void logSevere(String message, Throwable thrown); 52 | 53 | /** 54 | * Log an error that stands out from other system messages. 55 | * 56 | * @param message The message to display 57 | */ 58 | void logSevere(String message); 59 | 60 | /** 61 | * Get the config. 62 | * 63 | * @return The config 64 | */ 65 | Config getConfiguration(); 66 | 67 | /** 68 | * Get the message handler. 69 | * 70 | * @return The message handler 71 | */ 72 | MessageHandler getMessageHandler(); 73 | 74 | /** 75 | * Get the wrapper. 76 | * 77 | * @return The wrapper 78 | */ 79 | Wrapper getWrapper(); 80 | 81 | /** 82 | * Get the preview manager. 83 | * 84 | * @return The preview manager 85 | */ 86 | PreviewManager getPreviewManager(); 87 | 88 | /** 89 | * Get the collection helper. 90 | * 91 | * @return The collection helper. 92 | */ 93 | CollectionHelper getCollectionHelper(); 94 | 95 | /** 96 | * Get the action handler. 97 | * 98 | * @return The action handler 99 | */ 100 | ActionHandler getActionHandler(); 101 | 102 | /** 103 | * Get the message pool. 104 | * 105 | * @return The message pool 106 | */ 107 | ObjectPool<UUID, Component> getMessagePool(); 108 | 109 | /** 110 | * Get the storage storing the state of the filter. 111 | * 112 | * @return The filter storage 113 | */ 114 | Storage<Player, Boolean> getFilterStorage(); 115 | 116 | /** 117 | * Get the storage storing the favorite wraps of a player. 118 | * 119 | * @return The filter storage 120 | */ 121 | Storage<Player, List<Wrap>> getFavoriteWrapStorage(); 122 | 123 | /** 124 | * Get the wraps loader. 125 | * 126 | * @return The wraps loader 127 | */ 128 | WrapsLoader getWrapsLoader(); 129 | 130 | /** 131 | * Get the hook accessor. 132 | * 133 | * @return The hook accessor 134 | */ 135 | HookAccessor getHookAccessor(); 136 | 137 | /** 138 | * Get the FoliaLib instance. 139 | * 140 | * @return The FoliaLib instance 141 | */ 142 | FoliaLib getFoliaLib(); 143 | 144 | } 145 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/actions/Action.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.actions; 2 | 3 | public enum Action { 4 | 5 | PARTICLE, 6 | PARTICLE_MULTI, 7 | SOUND, 8 | TITLE, 9 | SUBTITLE, 10 | ACTIONBAR, 11 | MESSAGE, 12 | COMMAND, 13 | CONSOLE_COMMAND, 14 | SCROLL_FORTH, 15 | SCROLL_BACK, 16 | NEXT_PAGE, 17 | PREVIOUS_PAGE, 18 | UNWRAP, 19 | CLOSE_INVENTORY, 20 | TOGGLE_FILTER, 21 | CLEAR_FAVORITES, 22 | SET_FAVORITE, 23 | WRAP, 24 | PREVIEW 25 | 26 | } 27 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/actions/ActionMethod.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.actions; 2 | 3 | import de.skyslycer.hmcwraps.actions.information.ActionInformation; 4 | 5 | public interface ActionMethod { 6 | 7 | /** 8 | * This method is called when this action is pushed. 9 | * 10 | * @param information The pushed information 11 | */ 12 | void execute(ActionInformation information); 13 | 14 | } 15 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/actions/information/ActionInformation.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.actions.information; 2 | 3 | import org.bukkit.entity.Player; 4 | 5 | public interface ActionInformation { 6 | 7 | Player getPlayer(); 8 | 9 | String getArguments(); 10 | 11 | void setPlayer(Player player); 12 | 13 | void setArguments(String arguments); 14 | 15 | } 16 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/actions/information/BasicActionInformation.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.actions.information; 2 | 3 | import org.bukkit.entity.Player; 4 | 5 | public class BasicActionInformation implements ActionInformation { 6 | 7 | private Player player; 8 | private String arguments; 9 | 10 | public BasicActionInformation(Player player, String arguments) { 11 | this.player = player; 12 | this.arguments = arguments; 13 | } 14 | 15 | @Override 16 | public Player getPlayer() { 17 | return player; 18 | } 19 | 20 | @Override 21 | public String getArguments() { 22 | return arguments; 23 | } 24 | 25 | @Override 26 | public void setPlayer(Player player) { 27 | this.player = player; 28 | } 29 | 30 | @Override 31 | public void setArguments(String arguments) { 32 | this.arguments = arguments; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/actions/information/GuiActionInformation.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.actions.information; 2 | 3 | import dev.triumphteam.gui.guis.PaginatedGui; 4 | import org.bukkit.entity.Player; 5 | 6 | public class GuiActionInformation implements ActionInformation { 7 | 8 | private PaginatedGui gui; 9 | private Player player; 10 | private String arguments; 11 | private int slot; 12 | 13 | public GuiActionInformation(Player player, String arguments, PaginatedGui gui, int slot) { 14 | this.player = player; 15 | this.arguments = arguments; 16 | this.gui = gui; 17 | this.slot = slot; 18 | } 19 | 20 | @Override 21 | public Player getPlayer() { 22 | return player; 23 | } 24 | 25 | @Override 26 | public String getArguments() { 27 | return arguments; 28 | } 29 | 30 | public PaginatedGui getGui() { 31 | return gui; 32 | } 33 | 34 | public int getSlot() { 35 | return slot; 36 | } 37 | 38 | public void setSlot(int slot) { 39 | this.slot = slot; 40 | } 41 | 42 | @Override 43 | public void setPlayer(Player player) { 44 | this.player = player; 45 | } 46 | 47 | @Override 48 | public void setArguments(String arguments) { 49 | this.arguments = arguments; 50 | } 51 | 52 | public void setGui(PaginatedGui gui) { 53 | this.gui = gui; 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/actions/information/WrapActionInformation.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.actions.information; 2 | 3 | import de.skyslycer.hmcwraps.serialization.wrap.Wrap; 4 | import org.bukkit.entity.Player; 5 | 6 | public class WrapActionInformation implements ActionInformation { 7 | 8 | private Wrap wrap; 9 | private Player player; 10 | private String arguments; 11 | 12 | public WrapActionInformation(Wrap wrap, Player player, String arguments) { 13 | this.wrap = wrap; 14 | this.player = player; 15 | this.arguments = arguments; 16 | } 17 | 18 | public Wrap getWrap() { 19 | return wrap; 20 | } 21 | 22 | @Override 23 | public Player getPlayer() { 24 | return player; 25 | } 26 | 27 | @Override 28 | public String getArguments() { 29 | return arguments; 30 | } 31 | 32 | public void setWrap(Wrap wrap) { 33 | this.wrap = wrap; 34 | } 35 | 36 | @Override 37 | public void setPlayer(Player player) { 38 | this.player = player; 39 | } 40 | 41 | @Override 42 | public void setArguments(String arguments) { 43 | this.arguments = arguments; 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/actions/information/WrapGuiActionInformation.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.actions.information; 2 | 3 | import de.skyslycer.hmcwraps.serialization.wrap.Wrap; 4 | import dev.triumphteam.gui.guis.PaginatedGui; 5 | import org.bukkit.entity.Player; 6 | 7 | public class WrapGuiActionInformation implements ActionInformation { 8 | 9 | private PaginatedGui gui; 10 | private Wrap wrap; 11 | private Player player; 12 | private String arguments; 13 | private int slot; 14 | 15 | public WrapGuiActionInformation(PaginatedGui gui, Wrap wrap, Player player, int slot, String arguments) { 16 | this.gui = gui; 17 | this.wrap = wrap; 18 | this.player = player; 19 | this.arguments = arguments; 20 | this.slot = slot; 21 | } 22 | 23 | public PaginatedGui getGui() { 24 | return gui; 25 | } 26 | 27 | public void setGui(PaginatedGui gui) { 28 | this.gui = gui; 29 | } 30 | 31 | public Wrap getWrap() { 32 | return wrap; 33 | } 34 | 35 | public void setWrap(Wrap wrap) { 36 | this.wrap = wrap; 37 | } 38 | 39 | public int getSlot() { 40 | return slot; 41 | } 42 | 43 | public void setSlot(int slot) { 44 | this.slot = slot; 45 | } 46 | 47 | @Override 48 | public Player getPlayer() { 49 | return player; 50 | } 51 | 52 | @Override 53 | public void setPlayer(Player player) { 54 | this.player = player; 55 | } 56 | 57 | @Override 58 | public String getArguments() { 59 | return arguments; 60 | } 61 | 62 | @Override 63 | public void setArguments(String arguments) { 64 | this.arguments = arguments; 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/events/ItemPreviewEvent.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.events; 2 | 3 | import de.skyslycer.hmcwraps.serialization.wrap.Wrap; 4 | import org.bukkit.entity.Player; 5 | import org.bukkit.event.Cancellable; 6 | import org.bukkit.event.Event; 7 | import org.bukkit.event.HandlerList; 8 | import org.bukkit.inventory.ItemStack; 9 | import org.jetbrains.annotations.NotNull; 10 | 11 | import java.util.function.Consumer; 12 | 13 | public class ItemPreviewEvent extends Event implements Cancellable { 14 | 15 | private static final HandlerList HANDLERS = new HandlerList(); 16 | 17 | boolean isCancelled = false; 18 | 19 | private Player player; 20 | private ItemStack item; 21 | private Consumer<Player> onClose; 22 | private final Wrap wrap; 23 | 24 | public ItemPreviewEvent(Player player, ItemStack item, Consumer<Player> onClose, Wrap wrap) { 25 | this.player = player; 26 | this.item = item; 27 | this.onClose = onClose; 28 | this.wrap = wrap; 29 | } 30 | 31 | @Override 32 | public boolean isCancelled() { 33 | return isCancelled; 34 | } 35 | 36 | @Override 37 | public void setCancelled(boolean cancel) { 38 | isCancelled = cancel; 39 | } 40 | 41 | @NotNull 42 | @Override 43 | public HandlerList getHandlers() { 44 | return HANDLERS; 45 | } 46 | 47 | public static HandlerList getHandlerList() { 48 | return HANDLERS; 49 | } 50 | 51 | public Player getPlayer() { 52 | return player; 53 | } 54 | 55 | public ItemStack getItem() { 56 | return item; 57 | } 58 | 59 | public Wrap getWrap() { 60 | return wrap; 61 | } 62 | 63 | public Consumer<Player> getOnClose() { 64 | return onClose; 65 | } 66 | 67 | public ItemPreviewEvent setPlayer(Player player) { 68 | this.player = player; 69 | return this; 70 | } 71 | 72 | public ItemPreviewEvent setItem(ItemStack item) { 73 | this.item = item; 74 | return this; 75 | } 76 | 77 | public ItemPreviewEvent setOnClose(Consumer<Player> onClose) { 78 | this.onClose = onClose; 79 | return this; 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/events/ItemUnwrapEvent.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.events; 2 | 3 | import de.skyslycer.hmcwraps.serialization.wrap.Wrap; 4 | import org.bukkit.entity.Player; 5 | import org.bukkit.event.Cancellable; 6 | import org.bukkit.event.Event; 7 | import org.bukkit.event.HandlerList; 8 | import org.bukkit.inventory.ItemStack; 9 | import org.jetbrains.annotations.NotNull; 10 | import org.jetbrains.annotations.Nullable; 11 | 12 | public class ItemUnwrapEvent extends Event implements Cancellable { 13 | 14 | private static final HandlerList HANDLERS = new HandlerList(); 15 | 16 | boolean isCancelled = false; 17 | 18 | private Player player; 19 | private ItemStack item; 20 | private final Wrap wrap; 21 | 22 | public ItemUnwrapEvent(ItemStack item, Player player, Wrap wrap) { 23 | this.item = item; 24 | this.player = player; 25 | this.wrap = wrap; 26 | } 27 | 28 | @Override 29 | public boolean isCancelled() { 30 | return isCancelled; 31 | } 32 | 33 | @Override 34 | public void setCancelled(boolean cancel) { 35 | isCancelled = cancel; 36 | } 37 | 38 | @NotNull 39 | @Override 40 | public HandlerList getHandlers() { 41 | return HANDLERS; 42 | } 43 | 44 | public static HandlerList getHandlerList() { 45 | return HANDLERS; 46 | } 47 | 48 | public Player getPlayer() { 49 | return player; 50 | } 51 | 52 | public ItemStack getItem() { 53 | return item; 54 | } 55 | 56 | @Nullable 57 | public Wrap getWrap() { 58 | return wrap; 59 | } 60 | 61 | public void setPlayer(Player player) { 62 | this.player = player; 63 | } 64 | 65 | public void setItem(ItemStack item) { 66 | this.item = item; 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/events/ItemWrapEvent.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.events; 2 | 3 | import de.skyslycer.hmcwraps.serialization.wrap.Wrap; 4 | import org.bukkit.entity.Player; 5 | import org.bukkit.event.Cancellable; 6 | import org.bukkit.event.Event; 7 | import org.bukkit.event.HandlerList; 8 | import org.bukkit.inventory.ItemStack; 9 | import org.jetbrains.annotations.NotNull; 10 | 11 | public class ItemWrapEvent extends Event implements Cancellable { 12 | 13 | private static final HandlerList HANDLERS = new HandlerList(); 14 | 15 | boolean isCancelled = false; 16 | 17 | private Wrap wrap; 18 | private Player player; 19 | private ItemStack item; 20 | private boolean physical; 21 | 22 | public ItemWrapEvent(Wrap wrap, ItemStack item, boolean physical, Player player) { 23 | this.wrap = wrap; 24 | this.item = item; 25 | this.physical = physical; 26 | this.player = player; 27 | } 28 | 29 | @Override 30 | public boolean isCancelled() { 31 | return isCancelled; 32 | } 33 | 34 | @Override 35 | public void setCancelled(boolean cancel) { 36 | isCancelled = cancel; 37 | } 38 | 39 | @NotNull 40 | @Override 41 | public HandlerList getHandlers() { 42 | return HANDLERS; 43 | } 44 | 45 | public static HandlerList getHandlerList() { 46 | return HANDLERS; 47 | } 48 | 49 | public Wrap getWrap() { 50 | return wrap; 51 | } 52 | 53 | public Player getPlayer() { 54 | return player; 55 | } 56 | 57 | public ItemStack getItem() { 58 | return item; 59 | } 60 | 61 | public boolean isPhysical() { 62 | return physical; 63 | } 64 | 65 | public void setWrap(Wrap wrap) { 66 | this.wrap = wrap; 67 | } 68 | 69 | public void setPlayer(Player player) { 70 | this.player = player; 71 | } 72 | 73 | public void setItem(ItemStack item) { 74 | this.item = item; 75 | } 76 | 77 | public void setPhysical(boolean physical) { 78 | this.physical = physical; 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/itemhook/DefaultItemHook.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.itemhook; 2 | 3 | import org.bukkit.Color; 4 | import org.bukkit.Material; 5 | import org.bukkit.NamespacedKey; 6 | import org.bukkit.inventory.EquipmentSlot; 7 | import org.bukkit.inventory.ItemStack; 8 | import org.jetbrains.annotations.Nullable; 9 | 10 | public class DefaultItemHook extends ItemHook { 11 | 12 | @Override 13 | @Nullable 14 | public String getPrefix() { 15 | return null; 16 | } 17 | 18 | @Override 19 | @Nullable 20 | public ItemStack get(String id) { 21 | if (Material.getMaterial(id) != null) { 22 | return new ItemStack(Material.getMaterial(id)); 23 | } 24 | return null; 25 | } 26 | 27 | @Override 28 | public int getModelId(String id) { 29 | return -1; 30 | } 31 | 32 | @Override 33 | @Nullable 34 | public Color getColor(String id) { 35 | return null; 36 | } 37 | 38 | @Override 39 | @Nullable 40 | public String getTrimPattern(String id) { 41 | return null; 42 | } 43 | 44 | @Override 45 | @Nullable 46 | public String getTrimMaterial(String id) { 47 | return null; 48 | } 49 | 50 | @Override 51 | @Nullable 52 | public EquipmentSlot getEquippableSlot(String id) { 53 | return null; 54 | } 55 | 56 | @Override 57 | @Nullable 58 | public NamespacedKey getEquippableModel(String id) { 59 | return null; 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/itemhook/HookAccessor.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.itemhook; 2 | 3 | import org.bukkit.Color; 4 | import org.bukkit.NamespacedKey; 5 | import org.bukkit.inventory.EquipmentSlot; 6 | import org.bukkit.inventory.ItemStack; 7 | import org.jetbrains.annotations.Nullable; 8 | 9 | import java.util.List; 10 | import java.util.Set; 11 | 12 | public class HookAccessor { 13 | 14 | private final DefaultItemHook defaultHook = new DefaultItemHook(); 15 | private final Set<ItemHook> hooks; 16 | 17 | public HookAccessor(Set<ItemHook> hooks) { 18 | this.hooks = hooks; 19 | } 20 | 21 | /** 22 | * Get an item stack based on the input. 23 | * 24 | * @param id The input 25 | * @return The item stack 26 | */ 27 | @Nullable 28 | public ItemStack getItemFromHook(String id) { 29 | var possible = hooks.stream().filter(it -> id.startsWith(it.getPrefix())).findFirst(); 30 | if (possible.isEmpty()) { 31 | return this.defaultHook.get(id); 32 | } else { 33 | return possible.get().get(id.replace(possible.get().getPrefix(), "")); 34 | } 35 | } 36 | 37 | /** 38 | * Get the model id corresponding to the input. 39 | * 40 | * @param id The input 41 | * @return The model id, may return -1 when none is available 42 | */ 43 | public int getModelIdFromHook(String id) { 44 | try { 45 | return Integer.parseInt(id); 46 | } catch (NumberFormatException ignored) { 47 | var possible = hooks.stream().filter(it -> id.startsWith(it.getPrefix())).findFirst(); 48 | return possible.map(itemHook -> itemHook.getModelId(id.replace(possible.get().getPrefix(), ""))).orElse(-1); 49 | } 50 | } 51 | 52 | /** 53 | * Get the color corresponding to the input. 54 | * 55 | * @param id The input 56 | * @return The color, may return null when none is available 57 | */ 58 | @Nullable 59 | public Color getColorFromHook(String id) { 60 | var possible = hooks.stream().filter(it -> id.startsWith(it.getPrefix())).findFirst(); 61 | return possible.map(itemHook -> itemHook.getColor(id.replace(possible.get().getPrefix(), ""))).orElse(null); 62 | } 63 | 64 | @Nullable 65 | public String getTrimPatternFromHook(String id) { 66 | var possible = hooks.stream().filter(it -> id.startsWith(it.getPrefix())).findFirst(); 67 | return possible.map(itemHook -> itemHook.getTrimPattern(id.replace(possible.get().getPrefix(), ""))).orElse(null); 68 | } 69 | 70 | @Nullable 71 | public String getTrimMaterialFromHook(String id) { 72 | var possible = hooks.stream().filter(it -> id.startsWith(it.getPrefix())).findFirst(); 73 | return possible.map(itemHook -> itemHook.getTrimMaterial(id.replace(possible.get().getPrefix(), ""))).orElse(null); 74 | } 75 | 76 | @Nullable 77 | public EquipmentSlot getEquippableSlotFromHook(String id) { 78 | var possible = hooks.stream().filter(it -> id.startsWith(it.getPrefix())).findFirst(); 79 | return possible.map(itemHook -> itemHook.getEquippableSlot(id.replace(possible.get().getPrefix(), ""))).orElse(null); 80 | } 81 | 82 | @Nullable 83 | public NamespacedKey getEquippableModelFromHook(String id) { 84 | var possible = hooks.stream().filter(it -> id.startsWith(it.getPrefix())).findFirst(); 85 | return possible.map(itemHook -> itemHook.getEquippableModel(id.replace(possible.get().getPrefix(), ""))).orElse(null); 86 | } 87 | 88 | @Nullable 89 | public NamespacedKey getItemModelFromHook(String id) { 90 | var possible = hooks.stream().filter(it -> id.startsWith(it.getPrefix())).findFirst(); 91 | return possible.map(itemHook -> itemHook.getItemModel(id.replace(possible.get().getPrefix(), ""))).orElse(null); 92 | } 93 | 94 | @Nullable 95 | public String getNameFromHook(String id) { 96 | var possible = hooks.stream().filter(it -> id.startsWith(it.getPrefix())).findFirst(); 97 | return possible.map(itemHook -> itemHook.getName(id.replace(possible.get().getPrefix(), ""))).orElse(null); 98 | } 99 | 100 | @Nullable 101 | public List<String> getLoreFromHook(String id) { 102 | var possible = hooks.stream().filter(it -> id.startsWith(it.getPrefix())).findFirst(); 103 | return possible.map(itemHook -> itemHook.getLore(id.replace(possible.get().getPrefix(), ""))).orElse(null); 104 | } 105 | 106 | } 107 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/messages/MessageHandler.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.messages; 2 | 3 | import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver.Single; 4 | import org.bukkit.command.CommandSender; 5 | 6 | import java.nio.file.Path; 7 | 8 | public interface MessageHandler { 9 | 10 | /** 11 | * Load messages from a path. 12 | * 13 | * @param path The path to load from 14 | * @return If it was successful 15 | */ 16 | boolean load(Path path); 17 | 18 | /** 19 | * Get a message based on its key. 20 | * 21 | * @param key The message key 22 | * @return The message 23 | */ 24 | String get(Messages key); 25 | 26 | /** 27 | * Try to update the given .properties file by adding missing messages, which are present in the internal .properties file 28 | * 29 | * @param path The file to update 30 | */ 31 | void update(Path path); 32 | 33 | /** 34 | * Send a message to a sender with replacing placeholders. 35 | * 36 | * @param sender The receiver 37 | * @param key The message key 38 | * @param placeholders The placeholders to replace 39 | */ 40 | void send(CommandSender sender, Messages key, Single... placeholders); 41 | 42 | } 43 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/messages/Messages.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.messages; 2 | 3 | import org.jetbrains.annotations.NotNull; 4 | 5 | public enum Messages { 6 | 7 | NO_PERMISSION("no-permission"), 8 | NO_PERMISSION_FOR_WRAP("no-permission-for-wrap"), 9 | APPLY_WRAP("apply-wrap"), 10 | REMOVE_WRAP("remove-wrap"), 11 | NO_ITEM("no-item"), 12 | NO_WRAPS("no-wraps"), 13 | NO_REWRAP("no-rewrap"), 14 | ARMOR_IMITATION_FORBIDDEN_INVENTORY("armor-imitation.forbidden-inventory"), 15 | INVENTORY_FILTER_ACTIVE("inventory.filter.active"), 16 | INVENTORY_FILTER_INACTIVE("inventory.filter.inactive"), 17 | PREVIEW_DISABLED("preview.disabled"), 18 | PREVIEW_BAR("preview.bar"), 19 | FAVORITES_SET("favorites.set"), 20 | FAVORITES_CLEAR("favorites.clear"), 21 | COMMAND_MISSING_ARGUMENT("command.missing-argument"), 22 | COMMAND_PLAYER_ONLY("command.player-only"), 23 | COMMAND_INVALID_WRAP("command.invalid-wrap"), 24 | COMMAND_INVALID_PHYSICAL("command.invalid-physical"), 25 | COMMAND_GIVEN_PHYSICAL("command.given-physical"), 26 | COMMAND_GIVEN_UNWRAPPER("command.given-unwrapper"), 27 | COMMAND_RELOAD("command.reload"), 28 | COMMAND_NEED_ITEM("command.need-item"), 29 | COMMAND_ITEM_NOT_FOR_WRAP("command.item-not-for-wrap"), 30 | COMMAND_WRAP_WRAPPED("command.wrap.wrapped"), 31 | COMMAND_NO_MATCHING_ITEM("command.no-matching-item"), 32 | COMMAND_PREVIEW_CREATED("command.preview-created"), 33 | COMMAND_HELP_HEADER("command.help.header"), 34 | COMMAND_HELP_FORMAT("command.help.format"), 35 | COMMAND_HELP_NO_PERMISSION("command.help.no-permission"), 36 | COMMAND_LIST_HEADER("command.list.header"), 37 | COMMAND_LIST_COLLECTIONS("command.list.collections"), 38 | COMMAND_LIST_WRAPS("command.list.wraps"), 39 | COMMAND_LIST_COLLECTIONS_FORMAT("command.list.collections-format"), 40 | COMMAND_LIST_WRAPS_FORMAT("command.list.wraps-format"), 41 | COMMAND_LIST_KEY_FORMAT("command.list.key-format"), 42 | COMMAND_ITEM_NOT_WRAPPED("command.item-not-wrapped"), 43 | COMMAND_UNWRAP_UNWRAPPED("command.unwrap.unwrapped"), 44 | COMMAND_CONVERT_SUCCESS("command.convert.success"), 45 | COMMAND_CONVERT_CONFIRM("command.convert.confirm"), 46 | COMMAND_CONVERT_NO_CONFIRM("command.convert.no-confirm"), 47 | COMMAND_CONVERT_FAILED("command.convert.failed"), 48 | COMMAND_CREATE_FAILED("command.create.failed"), 49 | COMMAND_CREATE_SUCCESS("command.create.success"), 50 | COMMAND_OPEN("command.open"), 51 | PLACEHOLDER_EQUIPPED("placeholder.equipped"), 52 | PLACEHOLDER_NOT_EQUIPPED("placeholder.not-equipped"); 53 | 54 | private final String key; 55 | 56 | Messages(String key) { 57 | this.key = key; 58 | } 59 | 60 | /** 61 | * Get the properties key based on an enum value. 62 | * 63 | * @return The key 64 | */ 65 | @NotNull 66 | public String getKey() { 67 | return key; 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/pool/ObjectPool.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.pool; 2 | 3 | public interface ObjectPool<K, V> { 4 | 5 | void insert(K key, V value); 6 | 7 | void remove(K key); 8 | 9 | void execute(K key, V value, PoolMethod consumer); 10 | 11 | } 12 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/pool/PoolMethod.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.pool; 2 | 3 | public interface PoolMethod { 4 | 5 | /** 6 | * This method is called when a pool action has been approved. 7 | */ 8 | void execute(); 9 | 10 | } 11 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/preview/Preview.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.preview; 2 | 3 | public interface Preview { 4 | 5 | /** 6 | * Start the preview. 7 | */ 8 | void preview(); 9 | 10 | /** 11 | * Cancel the preview. 12 | * 13 | * @param open If the inventory should open again 14 | */ 15 | void cancel(boolean open); 16 | 17 | } 18 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/preview/PreviewManager.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.preview; 2 | 3 | import com.google.common.base.Optional; 4 | import de.skyslycer.hmcwraps.HMCWraps; 5 | import de.skyslycer.hmcwraps.events.ItemPreviewEvent; 6 | import de.skyslycer.hmcwraps.preview.floating.FloatingPreview; 7 | import de.skyslycer.hmcwraps.preview.hand.HandPreview; 8 | import de.skyslycer.hmcwraps.serialization.preview.PreviewType; 9 | import de.skyslycer.hmcwraps.serialization.wrap.Wrap; 10 | import org.bukkit.Bukkit; 11 | import org.bukkit.entity.Player; 12 | import org.bukkit.inventory.ItemStack; 13 | 14 | import java.util.Map; 15 | import java.util.UUID; 16 | import java.util.concurrent.ConcurrentHashMap; 17 | import java.util.function.Consumer; 18 | 19 | public class PreviewManager { 20 | 21 | private final HMCWraps plugin; 22 | 23 | private final Map<UUID, Preview> previews = new ConcurrentHashMap<>(); 24 | 25 | public PreviewManager(HMCWraps plugin) { 26 | this.plugin = plugin; 27 | } 28 | 29 | /** 30 | * Remove and stop a preview. 31 | * 32 | * @param uuid The UUID of the player 33 | * @param open If the inventory should open up again 34 | */ 35 | public void remove(UUID uuid, boolean open) { 36 | if (previews.containsKey(uuid)) { 37 | previews.get(uuid).cancel(open); 38 | previews.remove(uuid); 39 | } 40 | } 41 | 42 | /** 43 | * Create a preview. 44 | * 45 | * @param player The player 46 | * @param onClose The consumer to run when the GUI should be opened again 47 | * @param wrap The wrap to preview 48 | */ 49 | public void create(Player player, Consumer<Player> onClose, Wrap wrap) { 50 | var wrapType = plugin.getCollectionHelper().getMaterial(wrap); 51 | var item = plugin.getWrapper().setWrap(wrap, new ItemStack(wrapType), false, player); 52 | var event = new ItemPreviewEvent(player, item, onClose, wrap); 53 | Bukkit.getPluginManager().callEvent(event); 54 | if (event.isCancelled()) { 55 | return; 56 | } 57 | createPrivate(event.getPlayer(), event.getItem(), wrap, event.getOnClose()); 58 | } 59 | 60 | 61 | private void createPrivate(Player player, ItemStack item, Wrap wrap, Consumer<Player> onClose) { 62 | this.remove(player.getUniqueId(), false); 63 | Preview preview; 64 | if (plugin.getConfiguration().getPreview().getType() == PreviewType.HAND) { 65 | preview = new HandPreview(player, item, onClose, plugin); 66 | } else { 67 | preview = new FloatingPreview(player, item, Optional.fromNullable(wrap.isUpsideDownPreview()).or(false), onClose, plugin); 68 | } 69 | previews.put(player.getUniqueId(), preview); 70 | preview.preview(); 71 | } 72 | 73 | /** 74 | * Remove and stop all running previews. 75 | * 76 | * @param open If the inventory should open up again 77 | */ 78 | public void removeAll(boolean open) { 79 | previews.keySet().forEach(uuid -> this.remove(uuid, open)); 80 | } 81 | 82 | /** 83 | * Check if a player is previewing. 84 | * 85 | * @param player The player 86 | * @return If the player is previewing 87 | */ 88 | public boolean isPreviewing(Player player) { 89 | return previews.containsKey(player.getUniqueId()); 90 | } 91 | 92 | } 93 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/preview/floating/RotateRunnable.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.preview.floating; 2 | 3 | import com.github.retrooper.packetevents.PacketEvents; 4 | import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityRelativeMoveAndRotation; 5 | import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityRotation; 6 | import de.skyslycer.hmcwraps.HMCWraps; 7 | import de.skyslycer.hmcwraps.messages.Messages; 8 | import de.skyslycer.hmcwraps.util.MathUtil; 9 | import de.skyslycer.hmcwraps.util.StringUtil; 10 | import net.md_5.bungee.api.ChatMessageType; 11 | import org.bukkit.entity.Player; 12 | 13 | public class RotateRunnable implements Runnable { 14 | 15 | private final Player player; 16 | private final int entityId; 17 | private final HMCWraps plugin; 18 | 19 | private int currentSinAngle = 0; 20 | private float currentAngle = 0; 21 | private double oldHeight = 0; 22 | 23 | public RotateRunnable(Player player, int entityId, HMCWraps plugin) { 24 | this.player = player; 25 | this.entityId = entityId; 26 | this.plugin = plugin; 27 | } 28 | 29 | @Override 30 | public void run() { 31 | if (plugin.getConfiguration().getPreview().getSneakCancel().isActionBar() && plugin.getConfiguration().getPreview().getSneakCancel().isEnabled()) { 32 | player.spigot().sendMessage(ChatMessageType.ACTION_BAR, StringUtil.parse(player, plugin.getMessageHandler().get(Messages.PREVIEW_BAR))); 33 | } 34 | if (plugin.getConfiguration().getPreview().getBobbing().isEnabled()) { 35 | var newHeight = MathUtil.sin(currentSinAngle) * plugin.getConfiguration().getPreview().getBobbing() 36 | .getIntensity(); 37 | var difference = newHeight - oldHeight; 38 | oldHeight = newHeight; 39 | PacketEvents.getAPI().getPlayerManager().sendPacket(player, 40 | new WrapperPlayServerEntityRelativeMoveAndRotation( 41 | entityId, 0, difference, 0, currentAngle, 90f, false) 42 | ); 43 | currentSinAngle += plugin.getConfiguration().getPreview().getBobbing().getSpeed(); 44 | if (currentSinAngle > 360) { 45 | currentSinAngle = 0; 46 | } 47 | } else { 48 | PacketEvents.getAPI().getPlayerManager().sendPacket(player, new WrapperPlayServerEntityRotation(entityId, currentAngle, 90f, false)); 49 | } 50 | currentAngle += plugin.getConfiguration().getPreview().getRotation(); 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/preview/hand/HandPreview.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.preview.hand; 2 | 3 | import com.github.retrooper.packetevents.PacketEvents; 4 | import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSetSlot; 5 | import com.tcoded.folialib.wrapper.task.WrappedTask; 6 | import de.skyslycer.hmcwraps.HMCWraps; 7 | import de.skyslycer.hmcwraps.messages.Messages; 8 | import de.skyslycer.hmcwraps.preview.Preview; 9 | import de.skyslycer.hmcwraps.util.StringUtil; 10 | import io.github.retrooper.packetevents.util.SpigotReflectionUtil; 11 | import net.md_5.bungee.api.ChatMessageType; 12 | import net.md_5.bungee.api.chat.TextComponent; 13 | import org.bukkit.entity.Player; 14 | import org.bukkit.inventory.ItemStack; 15 | 16 | import java.util.Optional; 17 | import java.util.function.Consumer; 18 | 19 | public class HandPreview implements Preview { 20 | 21 | private final Player player; 22 | private final ItemStack item; 23 | private final Consumer<Player> onClose; 24 | private final HMCWraps plugin; 25 | private WrappedTask task; 26 | private WrappedTask cancelTask; 27 | private ItemStack oldItem; 28 | private int slot = 0; 29 | 30 | public HandPreview(Player player, ItemStack item, Consumer<Player> onClose, HMCWraps plugin) { 31 | this.player = player; 32 | this.item = item; 33 | this.onClose = onClose; 34 | this.plugin = plugin; 35 | } 36 | 37 | public void preview() { 38 | player.closeInventory(); 39 | 40 | oldItem = player.getInventory().getItemInMainHand(); 41 | slot = 36 + player.getInventory().getHeldItemSlot(); 42 | sendFakeItem(item); 43 | 44 | task = plugin.getFoliaLib().getScheduler().runTimerAsync(() -> { 45 | if (plugin.getConfiguration().getPreview().getSneakCancel().isActionBar() && plugin.getConfiguration().getPreview().getSneakCancel().isEnabled()) { 46 | player.spigot().sendMessage(ChatMessageType.ACTION_BAR, StringUtil.parse(player, plugin.getMessageHandler().get(Messages.PREVIEW_BAR))); 47 | } 48 | }, 3, 1); 49 | cancelTask = plugin.getFoliaLib().getScheduler().runAtEntityLater(player, () -> plugin.getPreviewManager().remove(player.getUniqueId(), true), 50 | plugin.getConfiguration().getPreview().getDuration() * 20L); 51 | } 52 | 53 | public void cancel(boolean open) { 54 | Optional.of(task).ifPresent(WrappedTask::cancel); 55 | Optional.of(cancelTask).ifPresent(WrappedTask::cancel); 56 | if (open && onClose != null) { 57 | onClose.accept(player); 58 | } 59 | plugin.getFoliaLib().getScheduler().runAtEntityLater(player, () -> { 60 | sendFakeItem(oldItem); 61 | if (plugin.getConfiguration().getPreview().getSneakCancel().isActionBar()) { 62 | player.spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacy(" ")); 63 | } 64 | }, 1L); 65 | } 66 | 67 | private void sendFakeItem(ItemStack item) { 68 | PacketEvents.getAPI().getPlayerManager().sendPacket(player, 69 | new WrapperPlayServerSetSlot(0, -1, slot, SpigotReflectionUtil.decodeBukkitItemStack(item))); 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/serialization/Config.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.serialization; 2 | 3 | import de.skyslycer.hmcwraps.serialization.filter.FilterSettings; 4 | import de.skyslycer.hmcwraps.serialization.globaldisable.GlobalDisable; 5 | import de.skyslycer.hmcwraps.serialization.inventory.Inventory; 6 | import de.skyslycer.hmcwraps.serialization.item.SerializableItem; 7 | import de.skyslycer.hmcwraps.serialization.permission.PermissionSettings; 8 | import de.skyslycer.hmcwraps.serialization.preservation.PreservationSettings; 9 | import de.skyslycer.hmcwraps.serialization.preview.PreviewSettings; 10 | import de.skyslycer.hmcwraps.serialization.updater.UpdaterSettings; 11 | import de.skyslycer.hmcwraps.serialization.wrap.WrappableItem; 12 | import de.skyslycer.hmcwraps.serialization.wrapping.WrappingSettings; 13 | import org.spongepowered.configurate.objectmapping.ConfigSerializable; 14 | 15 | import java.util.HashMap; 16 | import java.util.List; 17 | import java.util.Map; 18 | 19 | @ConfigSerializable 20 | public class Config { 21 | 22 | private UpdaterSettings updater; 23 | private WrappingSettings wrapping; 24 | private PermissionSettings permissions; 25 | private PreviewSettings preview; 26 | private Toggleable favorites; 27 | private FilterSettings filter; 28 | private Inventory inventory; 29 | private SerializableItem unwrapper; 30 | private PreservationSettings preservation; 31 | private GlobalDisable globalDisable; 32 | private Map<String, WrappableItem> items = new HashMap<>(); 33 | private Map<String, List<String>> collections = new HashMap<>(); 34 | private Integer config = 1; 35 | 36 | public Config(UpdaterSettings updater, PermissionSettings permissions, PreviewSettings preview, Toggleable favorites, 37 | Inventory inventory, SerializableItem unwrapper, PreservationSettings preservation, Map<String, WrappableItem> items, 38 | Map<String, List<String>> collections, FilterSettings filter, WrappingSettings wrapping) { 39 | this.updater = updater; 40 | this.permissions = permissions; 41 | this.preview = preview; 42 | this.favorites = favorites; 43 | this.inventory = inventory; 44 | this.unwrapper = unwrapper; 45 | this.preservation = preservation; 46 | this.items = items; 47 | this.collections = collections; 48 | this.filter = filter; 49 | this.wrapping = wrapping; 50 | } 51 | 52 | public Config() { 53 | } 54 | 55 | public Inventory getInventory() { 56 | return inventory; 57 | } 58 | 59 | public WrappingSettings getWrapping() { 60 | return wrapping; 61 | } 62 | 63 | public SerializableItem getUnwrapper() { 64 | return unwrapper; 65 | } 66 | 67 | public Map<String, WrappableItem> getItems() { 68 | return items; 69 | } 70 | 71 | public PreviewSettings getPreview() { 72 | return preview; 73 | } 74 | 75 | public UpdaterSettings getUpdater() { 76 | return updater; 77 | } 78 | 79 | public Map<String, List<String>> getCollections() { 80 | return collections; 81 | } 82 | 83 | public PermissionSettings getPermissions() { 84 | return permissions; 85 | } 86 | 87 | public PreservationSettings getPreservation() { 88 | return preservation; 89 | } 90 | 91 | public Toggleable getFavorites() { 92 | return favorites; 93 | } 94 | 95 | public FilterSettings getFilter() { 96 | return filter; 97 | } 98 | 99 | public GlobalDisable getGlobalDisable() { 100 | return globalDisable; 101 | } 102 | 103 | } 104 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/serialization/Toggleable.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.serialization; 2 | 3 | import org.spongepowered.configurate.objectmapping.ConfigSerializable; 4 | 5 | @ConfigSerializable 6 | public class Toggleable { 7 | 8 | private boolean enabled; 9 | 10 | public Toggleable(boolean enabled) { 11 | this.enabled = enabled; 12 | } 13 | 14 | public Toggleable() { 15 | } 16 | 17 | public boolean isEnabled() { 18 | return enabled; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/serialization/files/CollectionFile.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.serialization.files; 2 | 3 | import de.skyslycer.hmcwraps.serialization.Toggleable; 4 | import org.spongepowered.configurate.objectmapping.ConfigSerializable; 5 | 6 | import java.util.List; 7 | import java.util.Map; 8 | 9 | @ConfigSerializable 10 | public class CollectionFile extends Toggleable { 11 | 12 | private Map<String, List<String>> collections; 13 | 14 | public CollectionFile(Map<String, List<String>> collections, boolean enabled) { 15 | super(enabled); 16 | this.collections = collections; 17 | } 18 | 19 | public CollectionFile() { 20 | } 21 | 22 | public Map<String, List<String>> getCollections() { 23 | return collections; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/serialization/files/WrapFile.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.serialization.files; 2 | 3 | import de.skyslycer.hmcwraps.serialization.Toggleable; 4 | import de.skyslycer.hmcwraps.serialization.wrap.WrappableItem; 5 | import org.spongepowered.configurate.objectmapping.ConfigSerializable; 6 | 7 | import java.util.HashMap; 8 | import java.util.Map; 9 | 10 | @ConfigSerializable 11 | public class WrapFile extends Toggleable { 12 | 13 | private Map<String, WrappableItem> items = new HashMap<>(); 14 | 15 | private int config = 1; 16 | 17 | public WrapFile(Map<String, WrappableItem> items, boolean enabled) { 18 | super(enabled); 19 | this.items = items; 20 | } 21 | 22 | public WrapFile() { 23 | } 24 | 25 | public Map<String, WrappableItem> getItems() { 26 | return items; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/serialization/filter/FilterSettings.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.serialization.filter; 2 | 3 | import de.skyslycer.hmcwraps.serialization.Toggleable; 4 | import org.spongepowered.configurate.objectmapping.ConfigSerializable; 5 | import org.spongepowered.configurate.objectmapping.meta.Setting; 6 | 7 | @ConfigSerializable 8 | public class FilterSettings extends Toggleable { 9 | 10 | @Setting("default") 11 | private boolean defaultFilter; 12 | 13 | public boolean getDefault() { 14 | return defaultFilter; 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/serialization/globaldisable/GlobalDisable.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.serialization.globaldisable; 2 | 3 | import org.spongepowered.configurate.objectmapping.ConfigSerializable; 4 | 5 | import java.util.List; 6 | 7 | @ConfigSerializable 8 | public class GlobalDisable { 9 | 10 | private List<Integer> modelId; 11 | private List<String> color; 12 | private List<String> oraxen; 13 | private List<String> itemsadder; 14 | private List<String> mythic; 15 | private List<String> nexo; 16 | private List<String> executableItems; 17 | 18 | public List<Integer> getModelId() { 19 | return modelId; 20 | } 21 | 22 | public List<String> getColor() { 23 | return color; 24 | } 25 | 26 | public List<String> getOraxenId() { 27 | return oraxen; 28 | } 29 | 30 | public List<String> getItemsAdderId() { 31 | return itemsadder; 32 | } 33 | 34 | public List<String> getMythicId() { 35 | return mythic; 36 | } 37 | 38 | public List<String> getNexoId() { 39 | return nexo; 40 | } 41 | 42 | public List<String> getExecutableItemsId() { 43 | return executableItems; 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/serialization/inventory/Inventory.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.serialization.inventory; 2 | 3 | import org.jetbrains.annotations.Nullable; 4 | import org.spongepowered.configurate.objectmapping.ConfigSerializable; 5 | 6 | import java.util.HashMap; 7 | import java.util.List; 8 | import java.util.Map; 9 | 10 | @ConfigSerializable 11 | public class Inventory { 12 | 13 | private List<String> sortOrder; 14 | private ShortcutSettings shortcut; 15 | private boolean itemChangeEnabled; 16 | private boolean openWithoutItemEnabled; 17 | private String title; 18 | private @Nullable String noItemTitle; 19 | private Type type; 20 | private int rows; 21 | private int targetItemSlot; 22 | private Map<String, InventoryItem> items; 23 | private @Nullable HashMap<String, HashMap<String, List<String>>> actions; 24 | private @Nullable HashMap<String, HashMap<String, List<String>>> lockedActions; 25 | 26 | public String getTitle() { 27 | return title; 28 | } 29 | 30 | public int getRows() { 31 | return rows; 32 | } 33 | 34 | public int getTargetItemSlot() { 35 | return targetItemSlot; 36 | } 37 | 38 | public Map<String, InventoryItem> getItems() { 39 | return items; 40 | } 41 | 42 | public Type getType() { 43 | return type; 44 | } 45 | 46 | public ShortcutSettings getShortcut() { 47 | return shortcut; 48 | } 49 | 50 | @Nullable 51 | public HashMap<String, HashMap<String, List<String>>> getActions() { 52 | return actions; 53 | } 54 | 55 | @Nullable 56 | public HashMap<String, HashMap<String, List<String>>> getLockedActions() { 57 | return lockedActions; 58 | } 59 | 60 | public boolean isItemChangeEnabled() { 61 | return itemChangeEnabled; 62 | } 63 | 64 | public boolean isOpenWithoutItemEnabled() { 65 | return openWithoutItemEnabled; 66 | } 67 | 68 | @Nullable 69 | public String getNoItemTitle() { 70 | return noItemTitle; 71 | } 72 | 73 | public List<String> getSortOrder() { 74 | return sortOrder; 75 | } 76 | 77 | public enum Type { 78 | 79 | PAGINATED, 80 | SCROLLING 81 | 82 | } 83 | 84 | } 85 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/serialization/inventory/InventoryItem.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.serialization.inventory; 2 | 3 | import de.skyslycer.hmcwraps.serialization.item.SerializableItem; 4 | import org.jetbrains.annotations.Nullable; 5 | import org.spongepowered.configurate.objectmapping.ConfigSerializable; 6 | 7 | import java.util.HashMap; 8 | import java.util.List; 9 | import java.util.Map; 10 | 11 | @ConfigSerializable 12 | public class InventoryItem extends SerializableItem { 13 | 14 | private @Nullable HashMap<String, HashMap<String, List<String>>> actions; 15 | private @Nullable List<Integer> fills; 16 | 17 | public InventoryItem(String id, String name, @Nullable Boolean glow, @Nullable List<String> lore, @Nullable List<String> flags, 18 | @Nullable Integer modelId, @Nullable Map<String, Integer> enchantments, @Nullable Integer amount, 19 | @Nullable String color, @Nullable String nbt, @Nullable Integer durability, @Nullable String skullOwner, @Nullable String skullTexture, 20 | @Nullable String trim, @Nullable String trimMaterial, @Nullable String equippableSlot, @Nullable String equippableModel, @Nullable String itemModel) { 21 | super(id, name, glow, lore, flags, modelId, enchantments, amount, color, nbt, durability, skullOwner, skullTexture, trim, trimMaterial, equippableSlot, equippableModel, itemModel); 22 | } 23 | 24 | public InventoryItem() { 25 | } 26 | 27 | @Nullable 28 | public HashMap<String, HashMap<String, List<String>>> getActions() { 29 | return actions; 30 | } 31 | 32 | @Nullable 33 | public List<Integer> getFills() { 34 | return fills; 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/serialization/inventory/ShortcutSettings.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.serialization.inventory; 2 | 3 | import de.skyslycer.hmcwraps.serialization.Toggleable; 4 | import org.spongepowered.configurate.objectmapping.ConfigSerializable; 5 | 6 | import java.util.List; 7 | 8 | @ConfigSerializable 9 | public class ShortcutSettings extends Toggleable { 10 | 11 | private List<String> exclude; 12 | 13 | public List<String> getExclude() { 14 | return exclude; 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/serialization/permission/PermissionSettings.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.serialization.permission; 2 | 3 | import org.spongepowered.configurate.objectmapping.ConfigSerializable; 4 | 5 | @ConfigSerializable 6 | public class PermissionSettings { 7 | 8 | private boolean checkPermissionPhysical; 9 | private boolean checkPermissionVirtual; 10 | private boolean permissionPhysical; 11 | private boolean permissionVirtual; 12 | private boolean inventoryPermission; 13 | private boolean previewPermission; 14 | private int inventoryCheckInterval; 15 | 16 | public boolean isCheckPermissionPhysical() { 17 | return checkPermissionPhysical; 18 | } 19 | 20 | public boolean isCheckPermissionVirtual() { 21 | return checkPermissionVirtual; 22 | } 23 | 24 | public boolean isPermissionPhysical() { 25 | return permissionPhysical; 26 | } 27 | 28 | public boolean isPermissionVirtual() { 29 | return permissionVirtual; 30 | } 31 | 32 | public boolean isInventoryPermission() { 33 | return inventoryPermission; 34 | } 35 | 36 | public boolean isPreviewPermission() { 37 | return previewPermission; 38 | } 39 | 40 | public int getInventoryCheckInterval() { 41 | return inventoryCheckInterval; 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/serialization/preservation/PreservationSettings.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.serialization.preservation; 2 | 3 | import org.spongepowered.configurate.objectmapping.ConfigSerializable; 4 | 5 | import java.util.List; 6 | 7 | @ConfigSerializable 8 | public class PreservationSettings { 9 | 10 | private ValuePreservationSettings<Integer> modelId; 11 | private ValuePreservationSettings<String> color; 12 | private ValuePreservationSettings<String> name; 13 | private ValuePreservationSettings<List<String>> lore; 14 | private ValuePreservationSettings<List<String>> flags; 15 | 16 | public ValuePreservationSettings<Integer> getModelId() { 17 | return modelId; 18 | } 19 | 20 | public ValuePreservationSettings<String> getColor() { 21 | return color; 22 | } 23 | 24 | public ValuePreservationSettings<String> getName() { 25 | return name; 26 | } 27 | 28 | public ValuePreservationSettings<List<String>> getLore() { 29 | return lore; 30 | } 31 | 32 | public ValuePreservationSettings<List<String>> getFlags() { 33 | return flags; 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/serialization/preservation/ValuePreservationSettings.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.serialization.preservation; 2 | 3 | import org.spongepowered.configurate.objectmapping.ConfigSerializable; 4 | 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | 8 | @ConfigSerializable 9 | public class ValuePreservationSettings<T> { 10 | 11 | private boolean defaultEnabled; 12 | private boolean originalEnabled; 13 | private Map<String, T> defaults = new HashMap<>(); 14 | 15 | public Map<String, T> getDefaults() { 16 | return defaults; 17 | } 18 | 19 | public boolean isDefaultEnabled() { 20 | return defaultEnabled; 21 | } 22 | 23 | public boolean isOriginalEnabled() { 24 | return originalEnabled; 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/serialization/preview/Bobbing.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.serialization.preview; 2 | 3 | import de.skyslycer.hmcwraps.serialization.Toggleable; 4 | import org.spongepowered.configurate.objectmapping.ConfigSerializable; 5 | 6 | @ConfigSerializable 7 | public class Bobbing extends Toggleable { 8 | 9 | private double speed; 10 | private double intensity; 11 | 12 | public double getSpeed() { 13 | return speed; 14 | } 15 | 16 | public double getIntensity() { 17 | return intensity; 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/serialization/preview/PreviewSettings.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.serialization.preview; 2 | 3 | import org.spongepowered.configurate.objectmapping.ConfigSerializable; 4 | 5 | @ConfigSerializable 6 | public class PreviewSettings { 7 | 8 | private PreviewType type; 9 | private int duration; 10 | private int rotation; 11 | private SneakCancel sneakCancel; 12 | private Bobbing bobbing; 13 | 14 | public PreviewType getType() { 15 | return type; 16 | } 17 | 18 | public int getDuration() { 19 | return duration; 20 | } 21 | 22 | public int getRotation() { 23 | return rotation; 24 | } 25 | 26 | public SneakCancel getSneakCancel() { 27 | return sneakCancel; 28 | } 29 | 30 | public Bobbing getBobbing() { 31 | return bobbing; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/serialization/preview/PreviewType.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.serialization.preview; 2 | 3 | public enum PreviewType { 4 | 5 | FLOATING, 6 | HAND 7 | 8 | } 9 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/serialization/preview/SneakCancel.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.serialization.preview; 2 | 3 | import de.skyslycer.hmcwraps.serialization.Toggleable; 4 | import org.spongepowered.configurate.objectmapping.ConfigSerializable; 5 | 6 | @ConfigSerializable 7 | public class SneakCancel extends Toggleable { 8 | 9 | private boolean actionBar; 10 | 11 | public boolean isActionBar() { 12 | return actionBar; 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/serialization/updater/UpdaterSettings.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.serialization.updater; 2 | 3 | import de.skyslycer.hmcwraps.serialization.Toggleable; 4 | import de.skyslycer.hmcwraps.updater.PluginPlatform; 5 | import org.spongepowered.configurate.objectmapping.ConfigSerializable; 6 | 7 | @ConfigSerializable 8 | public class UpdaterSettings extends Toggleable { 9 | 10 | private String frequency; 11 | private PluginPlatform platform; 12 | 13 | public PluginPlatform getPlatform() { 14 | return platform; 15 | } 16 | 17 | public String getFrequency() { 18 | return frequency; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/serialization/wrap/PhysicalWrap.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.serialization.wrap; 2 | 3 | import de.skyslycer.hmcwraps.serialization.item.SerializableItem; 4 | import org.jetbrains.annotations.Nullable; 5 | import org.spongepowered.configurate.objectmapping.ConfigSerializable; 6 | 7 | import java.util.List; 8 | 9 | @ConfigSerializable 10 | public class PhysicalWrap extends SerializableItem { 11 | 12 | private boolean keepAfterUnwrap; 13 | 14 | public PhysicalWrap(String id, String name, @Nullable Boolean glow, 15 | @Nullable List<String> lore, @Nullable Integer modelId) { 16 | super(id, name, glow, lore, null, modelId, null, null, null); 17 | this.keepAfterUnwrap = true; 18 | } 19 | 20 | public PhysicalWrap() { 21 | } 22 | 23 | public boolean isKeepAfterUnwrap() { 24 | return keepAfterUnwrap; 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/serialization/wrap/WrappableItem.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.serialization.wrap; 2 | 3 | import org.spongepowered.configurate.objectmapping.ConfigSerializable; 4 | 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | 8 | @ConfigSerializable 9 | public class WrappableItem { 10 | 11 | private Map<String, Wrap> wraps = new HashMap<>(); 12 | 13 | public WrappableItem(Map<String, Wrap> wraps) { 14 | this.wraps = wraps; 15 | } 16 | 17 | public WrappableItem() { 18 | } 19 | 20 | public Map<String, Wrap> getWraps() { 21 | return wraps; 22 | } 23 | 24 | public void putWrap(String name, Wrap wrap) { 25 | wraps.put(name, wrap); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/serialization/wrap/range/RangeSettings.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.serialization.wrap.range; 2 | 3 | import org.spongepowered.configurate.objectmapping.ConfigSerializable; 4 | 5 | @ConfigSerializable 6 | public class RangeSettings { 7 | 8 | private ValueRangeSettings<Integer> modelId; 9 | private ValueRangeSettings<String> color; 10 | private ValueRangeSettings<String> itemsadder; 11 | private ValueRangeSettings<String> oraxen; 12 | private ValueRangeSettings<String> mythic; 13 | private ValueRangeSettings<String> nexo; 14 | private ValueRangeSettings<String> executableItems; 15 | 16 | public RangeSettings(ValueRangeSettings<Integer> modelId, ValueRangeSettings<String> color, ValueRangeSettings<String> itemsAdder, 17 | ValueRangeSettings<String> oraxen, ValueRangeSettings<String> mythic, ValueRangeSettings<String> nexo, ValueRangeSettings<String> executableItems) { 18 | this.modelId = modelId; 19 | this.color = color; 20 | this.itemsadder = itemsAdder; 21 | this.oraxen = oraxen; 22 | this.mythic = mythic; 23 | this.nexo = nexo; 24 | this.executableItems = executableItems; 25 | } 26 | 27 | public RangeSettings() {} 28 | 29 | public ValueRangeSettings<Integer> getModelId() { 30 | return modelId; 31 | } 32 | 33 | public ValueRangeSettings<String> getColor() { 34 | return color; 35 | } 36 | 37 | public ValueRangeSettings<String> getItemsAdder() { 38 | return itemsadder; 39 | } 40 | 41 | public ValueRangeSettings<String> getOraxen() { 42 | return oraxen; 43 | } 44 | 45 | public ValueRangeSettings<String> getMythic() { 46 | return mythic; 47 | } 48 | 49 | public ValueRangeSettings<String> getNexo() { 50 | return nexo; 51 | } 52 | 53 | public ValueRangeSettings<String> getExecutableItems() { 54 | return executableItems; 55 | } 56 | 57 | public static RangeSettings empty() { 58 | return new RangeSettings(new ValueRangeSettings<>(), new ValueRangeSettings<>(), new ValueRangeSettings<>(), 59 | new ValueRangeSettings<>(), new ValueRangeSettings<>(), new ValueRangeSettings<>(), new ValueRangeSettings<>()); 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/serialization/wrap/range/ValueRangeSettings.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.serialization.wrap.range; 2 | 3 | import org.jetbrains.annotations.Nullable; 4 | import org.spongepowered.configurate.objectmapping.ConfigSerializable; 5 | 6 | import java.util.List; 7 | 8 | @ConfigSerializable 9 | public class ValueRangeSettings<T> { 10 | 11 | private @Nullable List<T> include; 12 | private @Nullable List<T> exclude; 13 | 14 | public ValueRangeSettings() { } 15 | 16 | @Nullable 17 | public List<T> getInclude() { 18 | return include; 19 | } 20 | 21 | @Nullable 22 | public List<T> getExclude() { 23 | return exclude; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/serialization/wrapping/RewrapSettings.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.serialization.wrapping; 2 | 3 | import org.spongepowered.configurate.objectmapping.ConfigSerializable; 4 | 5 | @ConfigSerializable 6 | public class RewrapSettings { 7 | 8 | private boolean virtualEnabled = true; 9 | private boolean physicalEnabled = true; 10 | private boolean sameVirtualEnabled = true; 11 | private boolean samePhysicalEnabled = true; 12 | 13 | public boolean isVirtualEnabled() { 14 | return virtualEnabled; 15 | } 16 | 17 | public boolean isPhysicalEnabled() { 18 | return physicalEnabled; 19 | } 20 | 21 | public boolean isSameVirtualEnabled() { 22 | return sameVirtualEnabled; 23 | } 24 | 25 | public boolean isSamePhysicalEnabled() { 26 | return samePhysicalEnabled; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/serialization/wrapping/WrappingSettings.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.serialization.wrapping; 2 | 3 | import org.spongepowered.configurate.objectmapping.ConfigSerializable; 4 | 5 | @ConfigSerializable 6 | public class WrappingSettings { 7 | 8 | private RewrapSettings rewrap; 9 | 10 | public RewrapSettings getRewrap() { 11 | return rewrap; 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/storage/Storage.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.storage; 2 | 3 | public interface Storage<O, T> { 4 | 5 | T get(O source); 6 | 7 | void set(O source, T value); 8 | 9 | } 10 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/updater/CheckResult.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.updater; 2 | 3 | public record CheckResult(String version, String url, PluginPlatform platform, boolean latest) { 4 | 5 | /** 6 | * Create a new check result. 7 | * 8 | * @param version The latest version of the plugin. 9 | * @param url The url to the resource 10 | * @param platform The platform of the resource 11 | * @param latest If the plugin is the latest version 12 | */ 13 | public CheckResult { 14 | } 15 | 16 | /** 17 | * Get the new version. 18 | * 19 | * @return The new version 20 | */ 21 | @Override 22 | public String version() { 23 | return version; 24 | } 25 | 26 | /** 27 | * Get the plugin url. 28 | * 29 | * @return The plugin url 30 | */ 31 | @Override 32 | public String url() { 33 | return url; 34 | } 35 | 36 | /** 37 | * Get the update platform. 38 | * 39 | * @return The update platform 40 | */ 41 | @Override 42 | public PluginPlatform platform() { 43 | return platform; 44 | } 45 | 46 | /** 47 | * Check if the plugin is the latest version. 48 | * 49 | * @return If the plugin is the latest version 50 | */ 51 | @Override 52 | public boolean latest() { 53 | return latest; 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/updater/PluginPlatform.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.updater; 2 | 3 | public enum PluginPlatform { 4 | 5 | /** 6 | * The base for plugins on SpigotMC. 7 | */ 8 | SPIGOT_MC("SpigotMC", "https://www.spigotmc.org/resources/%d", "https://api.spiget.org/v2/resources/%d/versions/latest"), 9 | /** 10 | * The base for plugins on Polymart. 11 | */ 12 | POLYMART("Polymart", "https://polymart.org/resource/%d", "https://api.polymart.org/v1/getResourceInfoSimple?resource_id=%d&key=version"); 13 | 14 | private final String name; 15 | private final String url; 16 | private final String apiUrl; 17 | 18 | /** 19 | * Create a new plugin platform. 20 | * 21 | * @param name The name of the platform 22 | * @param url The URL of the platform 23 | * @param apiUrl The API URL of the platform 24 | */ 25 | PluginPlatform(String name, String url, String apiUrl) { 26 | this.name = name; 27 | this.url = url; 28 | this.apiUrl = apiUrl; 29 | } 30 | 31 | /** 32 | * Get the platform name. 33 | * 34 | * @return The platform name 35 | */ 36 | public String platformName() { 37 | return name; 38 | } 39 | 40 | /** 41 | * Get the plugin url. 42 | * 43 | * @return The plugin url 44 | */ 45 | public String url() { 46 | return url; 47 | } 48 | 49 | /** 50 | * Get the API url. 51 | * 52 | * @return The API url 53 | */ 54 | public String apiUrl() { 55 | return apiUrl; 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/updater/PluginUpdater.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.updater; 2 | 3 | import de.skyslycer.hmcwraps.HMCWraps; 4 | import de.skyslycer.hmcwraps.updater.version.PluginVersion; 5 | 6 | import java.net.URI; 7 | import java.net.http.HttpClient; 8 | import java.net.http.HttpRequest; 9 | import java.net.http.HttpResponse; 10 | import java.nio.charset.StandardCharsets; 11 | 12 | public abstract class PluginUpdater { 13 | 14 | private static final HttpClient CLIENT = HttpClient.newHttpClient(); 15 | 16 | private final int pluginId; 17 | private final PluginPlatform platform; 18 | 19 | /** 20 | * Create a new plugin updater. 21 | * 22 | * @param pluginId The plugin id 23 | * @param platform The platform 24 | */ 25 | protected PluginUpdater(int pluginId, PluginPlatform platform) { 26 | this.pluginId = pluginId; 27 | this.platform = platform; 28 | } 29 | 30 | /** 31 | * Get the plugin id for the platform. 32 | * 33 | * @return The platform plugin id 34 | */ 35 | public int pluginId() { 36 | return pluginId; 37 | } 38 | 39 | /** 40 | * Get the updater platform. 41 | * 42 | * @return The platform 43 | */ 44 | public PluginPlatform platform() { 45 | return platform; 46 | } 47 | 48 | /** 49 | * Check if there is a new update. 50 | * 51 | * @param plugin The plugin 52 | * @return The new version or, if no new version is available, null 53 | */ 54 | public CheckResult check(HMCWraps plugin) { 55 | try { 56 | var request = CLIENT.send(HttpRequest.newBuilder() 57 | .header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.72 Safari/537.36 Edg/90.0.818.42") 58 | .uri(URI.create(String.format(platform().apiUrl(), pluginId()))) 59 | .build(), HttpResponse.BodyHandlers.ofInputStream()); 60 | try (var body = request.body()) { 61 | var version = parse(new String(body.readAllBytes(), StandardCharsets.UTF_8).trim()); 62 | var pluginVersion = plugin.getDescription().getVersion(); 63 | if (pluginVersion.split("-").length > 1) { 64 | pluginVersion = pluginVersion.split("-")[0]; 65 | } 66 | if (version != null) { 67 | if (PluginVersion.fromString(pluginVersion).isOlderThan(PluginVersion.fromString(version))) { 68 | return new CheckResult(version, String.format(platform().url(), pluginId()), platform(), false); 69 | } else { 70 | return new CheckResult(version, String.format(platform().url(), pluginId()), platform(), true); 71 | } 72 | } 73 | } 74 | } catch (Exception exception) { 75 | plugin.logSevere("Failed to check for updates. Report this error to the developers, but you can continue using this plugin without restrictions. Error: ", exception); 76 | } 77 | return null; 78 | } 79 | 80 | /** 81 | * Parse the returned body into the latest version. 82 | * 83 | * @param body The body of the response 84 | * @return A usable version 85 | */ 86 | public abstract String parse(String body); 87 | 88 | } 89 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/updater/version/PluginVersion.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.updater.version; 2 | 3 | import java.util.regex.Pattern; 4 | 5 | public class PluginVersion { 6 | 7 | private static final Pattern PATTERN = Pattern.compile("(\\d+)\\.(\\d+)\\.(\\d+)+"); 8 | 9 | private final int major; 10 | private final int minor; 11 | private final int patch; 12 | 13 | /** 14 | * Create a new plugin version. 15 | * 16 | * @param major The major 17 | * @param minor The minor 18 | * @param patch The patch 19 | */ 20 | public PluginVersion(int major, int minor, int patch) { 21 | this.major = major; 22 | this.minor = minor; 23 | this.patch = patch; 24 | } 25 | 26 | /** 27 | * Check if this version is older than the other. 28 | * 29 | * @param other The version to compare 30 | * @return If this one is older 31 | */ 32 | public boolean isOlderThan(PluginVersion other) { 33 | if (major < other.major) { 34 | return true; 35 | } else if (minor < other.minor && major <= other.major) { 36 | return true; 37 | } else return patch < other.patch && minor <= other.minor && major <= other.major; 38 | } 39 | 40 | /** 41 | * Get the matched version from a string. 42 | * 43 | * @param version The version string 44 | * @return The matched version or in case of no match null 45 | */ 46 | public static PluginVersion fromString(String version) { 47 | var matcher = PATTERN.matcher(version); 48 | if (matcher.matches()) { 49 | return new PluginVersion(Integer.parseInt(matcher.group(1)), Integer.parseInt(matcher.group(2)), Integer.parseInt(matcher.group(3))); 50 | } 51 | return null; 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/util/ColorUtil.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.util; 2 | 3 | import org.bukkit.Color; 4 | 5 | public class ColorUtil { 6 | 7 | /** 8 | * Converts a color to a hex string. 9 | * 10 | * @param color The color 11 | * @return The hex string 12 | */ 13 | public static String colorToHex(Color color) { 14 | if (color == null) { 15 | return null; 16 | } 17 | return String.format("#%02x%02x%02x", color.getRed(), color.getGreen(), color.getBlue()); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/util/ListUtil.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.util; 2 | 3 | import java.util.List; 4 | 5 | public class ListUtil { 6 | 7 | /** 8 | * Checks if a list contains any element of another list. 9 | * 10 | * @param list The list to check 11 | * @param other The list to check for 12 | * @param <T> The type of the lists 13 | * @return true If the list contains any element of the other list 14 | */ 15 | public static <T> boolean containsAny(List<T> list, List<T> other) { 16 | for (T t : list) { 17 | if (other.contains(t)) { 18 | return true; 19 | } 20 | } 21 | return false; 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/util/MaterialUtil.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.util; 2 | 3 | import org.bukkit.Material; 4 | 5 | import java.util.Map; 6 | 7 | public class MaterialUtil { 8 | 9 | private static final Map<String, Material[]> TYPE_ARMOR_MAPPING = Map.of( 10 | "LEATHER", new Material[]{Material.LEATHER_HELMET, Material.LEATHER_CHESTPLATE, Material.LEATHER_LEGGINGS, Material.LEATHER_BOOTS}, 11 | "CHAINMAIL", new Material[]{Material.CHAINMAIL_HELMET, Material.CHAINMAIL_CHESTPLATE, Material.CHAINMAIL_LEGGINGS, Material.CHAINMAIL_BOOTS}, 12 | "IRON", new Material[]{Material.IRON_HELMET, Material.IRON_CHESTPLATE, Material.IRON_LEGGINGS, Material.IRON_BOOTS}, 13 | "GOLD", new Material[]{Material.GOLDEN_HELMET, Material.GOLDEN_CHESTPLATE, Material.GOLDEN_LEGGINGS, Material.GOLDEN_BOOTS}, 14 | "DIAMOND", new Material[]{Material.DIAMOND_HELMET, Material.DIAMOND_CHESTPLATE, Material.DIAMOND_LEGGINGS, Material.DIAMOND_BOOTS}, 15 | "NETHERITE", new Material[]{Material.NETHERITE_HELMET, Material.NETHERITE_CHESTPLATE, Material.NETHERITE_LEGGINGS, Material.NETHERITE_BOOTS} 16 | ); 17 | 18 | /** 19 | * Get the alternate piece of an armor item 20 | * 21 | * @param type The new type 22 | * @param material The armor piece 23 | * @return The alternative 24 | */ 25 | public static Material getAlternative(String type, Material material) { 26 | if (type != null && TYPE_ARMOR_MAPPING.containsKey(type)) { 27 | Material[] materials = TYPE_ARMOR_MAPPING.get(type); 28 | var split = material.toString().split("_"); 29 | if (split.length != 2) { 30 | return material; 31 | } 32 | for (Material m : materials) { 33 | if (m.toString().contains(split[1])) { 34 | return m; 35 | } 36 | } 37 | } 38 | return material; 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/util/MathUtil.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.util; 2 | 3 | import java.util.stream.IntStream; 4 | 5 | public class MathUtil { 6 | 7 | private static final double[] SIN_TABLE = IntStream.rangeClosed(0, 360).mapToDouble(i -> Math.sin(Math.toRadians(i))).toArray(); 8 | 9 | /** 10 | * Get the corresponding sin value from an angle. 11 | * 12 | * @param angle The angle for the sin 13 | * @return The sin of the angle 14 | */ 15 | public static double sin(int angle) { 16 | return SIN_TABLE[angle]; 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/util/PlayerUtil.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.util; 2 | 3 | import org.bukkit.Location; 4 | import org.bukkit.entity.Player; 5 | import org.bukkit.inventory.ItemStack; 6 | 7 | public class PlayerUtil { 8 | 9 | /** 10 | * Give a player an item and drop what doesn't fit. 11 | * 12 | * @param player The player 13 | * @param item The item to give 14 | */ 15 | public static void give(Player player, ItemStack item) { 16 | var drops = player.getInventory().addItem(item); 17 | drops.values().forEach(left -> player.getLocation().getWorld().dropItemNaturally(player.getLocation(), left)); 18 | } 19 | 20 | /** 21 | * Get the block a player is looking at. Max distance is 2 blocks and min distance is 0 blocks. 22 | * 23 | * @param player The player 24 | * @return The block the player is looking at 25 | */ 26 | public static Location getLookBlock(Player player) { 27 | var twoBlocks = fixLocation(player.getEyeLocation().add(player.getLocation().getDirection().clone().multiply(2)).subtract(0, 0.5, 0), player); 28 | var oneBlock = fixLocation(player.getEyeLocation().add(player.getLocation().getDirection().clone()).subtract(0, 0.5, 0), player); 29 | if (oneBlock.getWorld().getBlockAt(oneBlock).getType().isAir()) { 30 | if (twoBlocks.getWorld().getBlockAt(twoBlocks).getType().isAir()) { 31 | return twoBlocks; 32 | } 33 | return oneBlock; 34 | } 35 | return fixLocation(player.getLocation(), player); 36 | } 37 | 38 | /** 39 | * Get the block location on the opposite side of the player 40 | * 41 | * @param player The player 42 | * @return The opposite location 43 | */ 44 | public static Location getOpposite(Player player) { 45 | var facing = player.getFacing().getOppositeFace(); 46 | var location = player.getLocation().clone(); 47 | location.add(facing.getModX(), facing.getModY(), facing.getModZ()); 48 | var block = player.getLocation().getWorld().getBlockAt(location); 49 | return block.getLocation(); 50 | } 51 | 52 | /** 53 | * Sets the Y-coordinate of the location to 1 higher than the players Y-level 54 | * 55 | * @param location The location to edit 56 | * @param player The player 57 | * @return The changed location 58 | */ 59 | private static Location fixLocation(Location location, Player player) { 60 | location.setY(player.getLocation().getY() + 1); 61 | return location; 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/util/VectorUtil.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.util; 2 | 3 | import com.github.retrooper.packetevents.util.Vector3d; 4 | import org.bukkit.Location; 5 | 6 | public class VectorUtil { 7 | 8 | /** 9 | * Convert a Bukkit Location to a PacketEvents Vector3d. 10 | * 11 | * @param location The Bukkit location 12 | * @return The Vector3d 13 | */ 14 | public static Vector3d fromLocation(Location location) { 15 | return new Vector3d(location.getX(), location.getY(), location.getZ()); 16 | } 17 | 18 | /** 19 | * Return a Vector3d with all 0s. 20 | * 21 | * @return The zero Vector3d 22 | */ 23 | public static Vector3d zeroVector() { 24 | return new Vector3d(0d, 0d, 0d); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/wrap/ArmorModifiers.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.wrap; 2 | 3 | import de.skyslycer.hmcwraps.util.VersionUtil; 4 | import org.bukkit.inventory.EquipmentSlot; 5 | import org.bukkit.inventory.ItemStack; 6 | 7 | public enum ArmorModifiers { 8 | 9 | LEATHER(0, 0, new ArmorValues(1, 2, 3, 1), new ArmorValues(15, 40, 30, 15)), 10 | CHAINMAIL(0, 0, new ArmorValues(2, 5, 4, 1), new ArmorValues(45, 120, 90, 45)), 11 | IRON(0, 0, new ArmorValues(2, 5, 6, 2), new ArmorValues(45, 120, 90, 45)), 12 | GOLD(0, 0, new ArmorValues(2, 5, 3, 1), new ArmorValues(21, 56, 42, 21)), 13 | DIAMOND(2, 0, new ArmorValues(3, 8, 6, 3), new ArmorValues(99, 264, 198, 99)), 14 | TURTLE(0, 0, new ArmorValues(2, 6, 5, 2), new ArmorValues(75, 200, 150, 75)), 15 | NETHERITE(3, 1, new ArmorValues(3, 8, 6, 3), new ArmorValues(111, 296, 222, 111)); 16 | 17 | private final int toughness; 18 | private final int knockback; 19 | private final ArmorValues defense; 20 | private final ArmorValues durability; 21 | 22 | ArmorModifiers(int toughness, int knockback, ArmorValues defense, ArmorValues durability) { 23 | this.toughness = toughness; 24 | this.knockback = knockback; 25 | this.defense = defense; 26 | this.durability = durability; 27 | } 28 | 29 | public record ArmorValues(int helmet, int chestplate, int leggings, int boots) { } 30 | 31 | public static ArmorModifiers getFromMaterial(String material) { 32 | if (material.contains("CHAINMAIL")) return CHAINMAIL; 33 | if (material.contains("IRON")) return IRON; 34 | if (material.contains("GOLD")) return GOLD; 35 | if (material.contains("DIAMOND")) return DIAMOND; 36 | if (material.contains("TURTLE")) return TURTLE; 37 | if (material.contains("NETHERITE")) return NETHERITE; 38 | if (material.contains("LEATHER")) return LEATHER; 39 | return null; 40 | } 41 | 42 | public static void applyAttributes(ItemStack item, EquipmentSlot slot, int toughness, int knockback, int defense) { 43 | var meta = item.getItemMeta(); 44 | VersionUtil.Attribute.removeAttributeModifier(meta, VersionUtil.Attribute.ARMOR_TOUGHNESS); 45 | VersionUtil.Attribute.addAttributeModifier(meta, slot, VersionUtil.Attribute.ARMOR_TOUGHNESS, toughness); 46 | VersionUtil.Attribute.removeAttributeModifier(meta, VersionUtil.Attribute.ARMOR); 47 | VersionUtil.Attribute.addAttributeModifier(meta, slot, VersionUtil.Attribute.ARMOR, defense); 48 | if (knockback != 0) { 49 | VersionUtil.Attribute.removeAttributeModifier(meta, VersionUtil.Attribute.KNOCKBACK_RESISTANCE); 50 | VersionUtil.Attribute.addAttributeModifier(meta, slot, VersionUtil.Attribute.KNOCKBACK_RESISTANCE, knockback / 10d); // divided by 10 because Minecraft decided so 51 | } 52 | item.setItemMeta(meta); 53 | } 54 | 55 | public static ItemStack removeAttributes(ItemStack item) { 56 | var meta = item.getItemMeta(); 57 | VersionUtil.Attribute.removeAttributeModifier(meta, VersionUtil.Attribute.ARMOR_TOUGHNESS); 58 | VersionUtil.Attribute.removeAttributeModifier(meta, VersionUtil.Attribute.KNOCKBACK_RESISTANCE); 59 | VersionUtil.Attribute.removeAttributeModifier(meta, VersionUtil.Attribute.ARMOR); 60 | if (!meta.hasAttributeModifiers() && VersionUtil.hasDataComponents()) { 61 | meta.setAttributeModifiers(null); 62 | } 63 | item.setItemMeta(meta); 64 | return item; 65 | } 66 | 67 | public int getToughness() { 68 | return toughness; 69 | } 70 | 71 | public int getKnockback() { 72 | return knockback; 73 | } 74 | 75 | public ArmorValues getDefense() { 76 | return defense; 77 | } 78 | 79 | public ArmorValues getDurability() { 80 | return durability; 81 | } 82 | 83 | } 84 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/wrap/CollectionHelper.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.wrap; 2 | 3 | 4 | import de.skyslycer.hmcwraps.serialization.wrap.Wrap; 5 | import org.bukkit.Material; 6 | 7 | import java.util.List; 8 | 9 | public interface CollectionHelper { 10 | 11 | /** 12 | * Get all wraps for a material. 13 | * 14 | * @param material The material to search for 15 | * @return A list of all wraps 16 | */ 17 | List<Wrap> getItems(Material material); 18 | 19 | /** 20 | * Get all materials in a collection. 21 | * 22 | * @param collection The collection 23 | * @return All materials in the collection 24 | */ 25 | List<Material> getMaterials(String collection); 26 | 27 | /** 28 | * Get a possible material from a wrap. 29 | * 30 | * @param wrap The wrap to get the material from 31 | * @return One possible material 32 | */ 33 | Material getMaterial(Wrap wrap); 34 | 35 | /** 36 | * Get the collection or material name of a wrap. 37 | * 38 | * @param wrap The wrap to get the collection from 39 | * @return The collection or material name 40 | */ 41 | String getCollection(Wrap wrap); 42 | 43 | } 44 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/wrap/WrapsLoader.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.wrap; 2 | 3 | import de.skyslycer.hmcwraps.serialization.wrap.Wrap; 4 | 5 | import java.util.List; 6 | import java.util.Map; 7 | 8 | public interface WrapsLoader { 9 | 10 | /** 11 | * Load all collection files and wrap files. 12 | */ 13 | void load(); 14 | 15 | /** 16 | * Unload all collection files and wrap files. 17 | */ 18 | void unload(); 19 | 20 | /** 21 | * Get all currently loaded collections. 22 | * 23 | * @return All currently loaded collections 24 | */ 25 | Map<String, List<String>> getCollections(); 26 | 27 | /** 28 | * The amount of currently loaded collection files, this includes disabled ones. 29 | * 30 | * @return The amount of currently loaded collection files 31 | */ 32 | int getCollectionFileCount(); 33 | 34 | /** 35 | * The amount of currently loaded wrap files, this includes disabled ones. 36 | * 37 | * @return The amount of currently loaded wrap files 38 | */ 39 | int getWrapFileCount(); 40 | 41 | /** 42 | * All wraps currently configured. 43 | * 44 | * @return All wraps 45 | */ 46 | Map<String, Wrap> getWraps(); 47 | 48 | /** 49 | * All wrap UUIDs for a certain material or collection. 50 | * 51 | * @return All wrap UUIDs mapped to a material or collection 52 | */ 53 | Map<String, List<String>> getTypeWraps(); 54 | 55 | } 56 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/wrap/modifiers/WrapModifier.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.wrap.modifiers; 2 | 3 | import de.skyslycer.hmcwraps.serialization.wrap.Wrap; 4 | import org.bukkit.entity.Player; 5 | import org.bukkit.inventory.ItemStack; 6 | 7 | import javax.annotation.Nullable; 8 | 9 | public interface WrapModifier { 10 | 11 | String SEPARATOR = ";!;"; 12 | 13 | void wrap(@Nullable Wrap wrap, @Nullable Wrap currentWrap, ItemStack item, Player player); 14 | 15 | } 16 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/wrap/modifiers/WrapModifiers.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.wrap.modifiers; 2 | 3 | import de.skyslycer.hmcwraps.HMCWraps; 4 | import de.skyslycer.hmcwraps.wrap.modifiers.minecraft.*; 5 | import de.skyslycer.hmcwraps.wrap.modifiers.plugin.*; 6 | 7 | /** 8 | * This class contains instances of all available modifiers. 9 | */ 10 | public class WrapModifiers { 11 | 12 | private final ModelDataModifier modelData; 13 | private final ColorModifier color; 14 | private final ArmorImitationModifier armorImitation; 15 | private final EquippableModifier equippable; 16 | private final FlagsModifier flags; 17 | private final GlintOverrideModifier glintOverride; 18 | private final ItemModelModifier itemModel; 19 | private final LoreModifier lore; 20 | private final NameModifier name; 21 | private final NBTModifier nbt; 22 | private final TrimModifier trim; 23 | private final ItemsAdderModifier itemsAdder; 24 | private final MythicModifier mythic; 25 | private final NexoModifier nexo; 26 | private final OraxenModifier oraxen; 27 | private final ExecutableItemsModifier executableItems; 28 | 29 | public WrapModifiers(HMCWraps plugin) { 30 | this.modelData = new ModelDataModifier(plugin); 31 | this.color = new ColorModifier(plugin); 32 | this.armorImitation = new ArmorImitationModifier(plugin); 33 | this.equippable = new EquippableModifier(plugin); 34 | this.flags = new FlagsModifier(plugin); 35 | this.glintOverride = new GlintOverrideModifier(plugin); 36 | this.itemModel = new ItemModelModifier(plugin); 37 | this.lore = new LoreModifier(plugin); 38 | this.name = new NameModifier(plugin); 39 | this.nbt = new NBTModifier(); 40 | this.trim = new TrimModifier(plugin); 41 | this.itemsAdder = new ItemsAdderModifier(plugin); 42 | this.mythic = new MythicModifier(plugin); 43 | this.nexo = new NexoModifier(plugin); 44 | this.oraxen = new OraxenModifier(plugin); 45 | this.executableItems = new ExecutableItemsModifier(plugin); 46 | } 47 | 48 | public ModelDataModifier modelData() { 49 | return modelData; 50 | } 51 | 52 | public ColorModifier color() { 53 | return color; 54 | } 55 | 56 | public ArmorImitationModifier armorImitation() { 57 | return armorImitation; 58 | } 59 | 60 | public EquippableModifier equippable() { 61 | return equippable; 62 | } 63 | 64 | public FlagsModifier flags() { 65 | return flags; 66 | } 67 | 68 | public GlintOverrideModifier glintOverride() { 69 | return glintOverride; 70 | } 71 | 72 | public ItemModelModifier itemModel() { 73 | return itemModel; 74 | } 75 | 76 | public LoreModifier lore() { 77 | return lore; 78 | } 79 | 80 | public NameModifier name() { 81 | return name; 82 | } 83 | 84 | public NBTModifier nbt() { 85 | return nbt; 86 | } 87 | 88 | public TrimModifier trim() { 89 | return trim; 90 | } 91 | 92 | public ItemsAdderModifier itemsAdder() { 93 | return itemsAdder; 94 | } 95 | 96 | public MythicModifier mythic() { 97 | return mythic; 98 | } 99 | 100 | public NexoModifier nexo() { 101 | return nexo; 102 | } 103 | 104 | public OraxenModifier oraxen() { 105 | return oraxen; 106 | } 107 | 108 | public ExecutableItemsModifier executableItems() { 109 | return executableItems; 110 | } 111 | 112 | } 113 | 114 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/wrap/modifiers/minecraft/ColorModifier.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.wrap.modifiers.minecraft; 2 | 3 | import de.skyslycer.hmcwraps.HMCWraps; 4 | import de.skyslycer.hmcwraps.serialization.wrap.Wrap; 5 | import de.skyslycer.hmcwraps.util.StringUtil; 6 | import de.skyslycer.hmcwraps.wrap.modifiers.WrapModifier; 7 | import org.bukkit.Color; 8 | import org.bukkit.NamespacedKey; 9 | import org.bukkit.entity.Player; 10 | import org.bukkit.inventory.ItemFlag; 11 | import org.bukkit.inventory.ItemStack; 12 | import org.bukkit.inventory.meta.LeatherArmorMeta; 13 | import org.bukkit.persistence.PersistentDataType; 14 | 15 | public class ColorModifier implements WrapModifier { 16 | 17 | private final HMCWraps plugin; 18 | 19 | private final NamespacedKey originalColorKey; 20 | 21 | public ColorModifier(HMCWraps plugin) { 22 | this.plugin = plugin; 23 | this.originalColorKey = new NamespacedKey(plugin, "original-color"); 24 | } 25 | 26 | @Override 27 | public void wrap(Wrap wrap, Wrap currentWrap, ItemStack item, Player player) { 28 | Color currentColor = null; 29 | Color originalColor = getOriginalColor(item); 30 | if (wrap != null) { 31 | if (wrap.getColor() != null && item.getItemMeta() instanceof LeatherArmorMeta leatherMeta) { 32 | currentColor = leatherMeta.getColor(); 33 | leatherMeta.setColor(wrap.getColor()); 34 | if (wrap.getArmorImitationType() != null && wrap.getArmorImitationType().equalsIgnoreCase("LEATHER")) { 35 | leatherMeta.addItemFlags(ItemFlag.HIDE_DYE); 36 | } 37 | item.setItemMeta(leatherMeta); 38 | } 39 | } else { 40 | if (item.getItemMeta() instanceof LeatherArmorMeta leatherMeta) { 41 | leatherMeta.setColor(originalColor); 42 | item.setItemMeta(leatherMeta); 43 | } 44 | var newMeta = item.getItemMeta(); 45 | newMeta.getPersistentDataContainer().remove(originalColorKey); 46 | item.setItemMeta(newMeta); 47 | } 48 | if (wrap != null && currentWrap == null) { 49 | setOriginalColor(item, currentColor); 50 | } 51 | } 52 | 53 | /** 54 | * Get the original color of the item. 55 | * 56 | * @param item The item 57 | * @return The original color 58 | */ 59 | public Color getOriginalColor(ItemStack item) { 60 | var colorSettings = plugin.getConfiguration().getPreservation().getColor(); 61 | Color color = null; 62 | var meta = item.getItemMeta(); 63 | if (colorSettings.isOriginalEnabled()) { 64 | var data = meta.getPersistentDataContainer().get(originalColorKey, PersistentDataType.INTEGER); 65 | if (data != null) { 66 | color = Color.fromRGB(data); 67 | } 68 | } else if (colorSettings.isDefaultEnabled()) { 69 | var map = colorSettings.getDefaults(); 70 | if (map.containsKey(item.getType().toString())) { 71 | color = StringUtil.colorFromString(map.get(item.getType().toString())); 72 | } 73 | for (String key : map.keySet()) { 74 | if (plugin.getCollectionHelper().getMaterials(key).contains(item.getType())) { 75 | color = StringUtil.colorFromString(map.get(key)); 76 | } 77 | } 78 | } 79 | return color; 80 | } 81 | 82 | private void setOriginalColor(ItemStack item, Color color) { 83 | var meta = item.getItemMeta(); 84 | if (color != null) { 85 | meta.getPersistentDataContainer().set(originalColorKey, PersistentDataType.INTEGER, color.asRGB()); 86 | } else { 87 | meta.getPersistentDataContainer().remove(originalColorKey); 88 | } 89 | item.setItemMeta(meta); 90 | } 91 | 92 | /** 93 | * Get the real color of the item. If the item is wrapped, the original color will be returned. 94 | * If it isn't wrapped, the current color will be returned. 95 | * 96 | * @param item The item 97 | * @return The real color 98 | */ 99 | public Color getRealColor(ItemStack item) { 100 | Color color = null; 101 | if (plugin.getWrapper().getWrap(item) != null) { 102 | color = getOriginalColor(item); 103 | } else if (item.getItemMeta() instanceof LeatherArmorMeta meta) { 104 | color = meta.getColor(); 105 | } 106 | return color; 107 | } 108 | 109 | } 110 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/wrap/modifiers/minecraft/FlagsModifier.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.wrap.modifiers.minecraft; 2 | 3 | import de.skyslycer.hmcwraps.HMCWraps; 4 | import de.skyslycer.hmcwraps.serialization.wrap.Wrap; 5 | import de.skyslycer.hmcwraps.wrap.modifiers.WrapModifier; 6 | import org.bukkit.NamespacedKey; 7 | import org.bukkit.entity.Player; 8 | import org.bukkit.inventory.ItemFlag; 9 | import org.bukkit.inventory.ItemStack; 10 | import org.bukkit.persistence.PersistentDataType; 11 | import org.jetbrains.annotations.Nullable; 12 | 13 | import java.util.ArrayList; 14 | import java.util.List; 15 | import java.util.stream.Collectors; 16 | 17 | public class FlagsModifier implements WrapModifier { 18 | 19 | private final NamespacedKey originalFlagsKey; 20 | 21 | private final HMCWraps plugin; 22 | 23 | public FlagsModifier(HMCWraps plugin) { 24 | this.plugin = plugin; 25 | this.originalFlagsKey = new NamespacedKey(plugin, "original-flags"); 26 | } 27 | 28 | @Override 29 | public void wrap(@Nullable Wrap wrap, @Nullable Wrap currentWrap, ItemStack item, Player player) { 30 | var meta = item.getItemMeta(); 31 | var originalFlags = getOriginalFlags(item); 32 | var currentFlags = meta.getItemFlags().stream().toList(); 33 | if (currentWrap != null) { 34 | meta.removeItemFlags(meta.getItemFlags().toArray(ItemFlag[]::new)); 35 | if (originalFlags != null) { 36 | meta.addItemFlags(originalFlags.toArray(ItemFlag[]::new)); 37 | } 38 | } 39 | if (wrap != null && wrap.getWrapFlags() != null) { 40 | for (String flag : wrap.getWrapFlags()) { 41 | try { 42 | meta.addItemFlags(ItemFlag.valueOf(flag)); 43 | } catch (IllegalArgumentException ignored) { } 44 | } 45 | } 46 | if (wrap == null) { 47 | meta.getPersistentDataContainer().remove(originalFlagsKey); 48 | } 49 | item.setItemMeta(meta); 50 | if (wrap != null && currentWrap == null) { 51 | setOriginalFlags(item, currentFlags); 52 | } 53 | } 54 | 55 | private void setOriginalFlags(ItemStack item, List<ItemFlag> flags) { 56 | var meta = item.getItemMeta(); 57 | if (flags != null) { 58 | meta.getPersistentDataContainer().set(originalFlagsKey, PersistentDataType.STRING, 59 | flags.stream().map(ItemFlag::toString).collect(Collectors.joining(SEPARATOR))); 60 | } else { 61 | meta.getPersistentDataContainer().remove(originalFlagsKey); 62 | } 63 | item.setItemMeta(meta); 64 | } 65 | 66 | /** 67 | * Get the original flags of an item. 68 | * 69 | * @param item The item 70 | * @return The original flags 71 | */ 72 | public List<ItemFlag> getOriginalFlags(ItemStack item) { 73 | var settings = plugin.getConfiguration().getPreservation().getFlags(); 74 | var list = new ArrayList<ItemFlag>(); 75 | var meta = item.getItemMeta(); 76 | if (settings.isOriginalEnabled()) { 77 | var data = meta.getPersistentDataContainer().get(originalFlagsKey, PersistentDataType.STRING); 78 | if (data != null) { 79 | var flags = data.split(SEPARATOR); 80 | for (String flag : flags) { 81 | try { 82 | list.add(ItemFlag.valueOf(flag)); 83 | } catch (IllegalArgumentException ignored) { } 84 | } 85 | } 86 | return list; 87 | } else if (settings.isDefaultEnabled()) { 88 | var map = settings.getDefaults(); 89 | if (map.containsKey(item.getType().toString())) { 90 | for (String flag : map.get(item.getType().toString())) { 91 | try { 92 | list.add(ItemFlag.valueOf(flag)); 93 | } catch (IllegalArgumentException ignored) { } 94 | } 95 | } 96 | for (String key : map.keySet()) { 97 | if (plugin.getCollectionHelper().getMaterials(key).contains(item.getType())) { 98 | for (String flag : map.get(key)) { 99 | try { 100 | list.add(ItemFlag.valueOf(flag)); 101 | } catch (IllegalArgumentException ignored) { } 102 | } 103 | } 104 | } 105 | return list; 106 | } 107 | return item.getItemMeta().getItemFlags().stream().toList(); 108 | } 109 | 110 | } 111 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/wrap/modifiers/minecraft/GlintOverrideModifier.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.wrap.modifiers.minecraft; 2 | 3 | import de.skyslycer.hmcwraps.HMCWraps; 4 | import de.skyslycer.hmcwraps.serialization.wrap.Wrap; 5 | import de.skyslycer.hmcwraps.util.VersionUtil; 6 | import de.skyslycer.hmcwraps.wrap.modifiers.WrapModifier; 7 | import org.bukkit.NamespacedKey; 8 | import org.bukkit.entity.Player; 9 | import org.bukkit.inventory.ItemStack; 10 | import org.bukkit.persistence.PersistentDataContainer; 11 | import org.bukkit.persistence.PersistentDataType; 12 | import org.jetbrains.annotations.Nullable; 13 | 14 | public class GlintOverrideModifier implements WrapModifier { 15 | 16 | private final NamespacedKey originalGlintKey; 17 | 18 | private final HMCWraps plugin; 19 | 20 | public GlintOverrideModifier(HMCWraps plugin) { 21 | this.plugin = plugin; 22 | this.originalGlintKey = new NamespacedKey(plugin, "original-glint"); 23 | } 24 | 25 | @Override 26 | public void wrap(@Nullable Wrap wrap, @Nullable Wrap currentWrap, ItemStack item, Player player) { 27 | var meta = item.getItemMeta(); 28 | var originalGlint = getOriginalGlint(item); 29 | var currentGlint = VersionUtil.hasDataComponents() && meta.hasEnchantmentGlintOverride() ? meta.getEnchantmentGlintOverride() : null; 30 | if (currentWrap != null && VersionUtil.hasDataComponents()) { 31 | meta.setEnchantmentGlintOverride(originalGlint); 32 | } 33 | if (VersionUtil.hasDataComponents()) { 34 | if (wrap != null) { 35 | if (wrap.isGlintOverride() != null) { 36 | meta.setEnchantmentGlintOverride(wrap.isGlintOverride()); 37 | } 38 | } else { 39 | meta.setEnchantmentGlintOverride(originalGlint); 40 | meta.getPersistentDataContainer().remove(originalGlintKey); 41 | } 42 | } 43 | item.setItemMeta(meta); 44 | if (wrap != null && currentWrap == null) { 45 | setOriginalGlint(item, currentGlint); 46 | } 47 | } 48 | 49 | private void setOriginalGlint(ItemStack item, Boolean glint) { 50 | var meta = item.getItemMeta(); 51 | if (glint != null) { 52 | meta.getPersistentDataContainer().set(originalGlintKey, PersistentDataType.BOOLEAN, glint); 53 | } else { 54 | meta.getPersistentDataContainer().remove(originalGlintKey); 55 | } 56 | item.setItemMeta(meta); 57 | } 58 | 59 | /** 60 | * Get the original glint override of the item. 61 | * 62 | * @param item The item 63 | * @return The original glint override 64 | */ 65 | public Boolean getOriginalGlint(ItemStack item) { 66 | PersistentDataContainer container = item.getItemMeta().getPersistentDataContainer(); 67 | return container.get(originalGlintKey, PersistentDataType.BOOLEAN); 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/wrap/modifiers/minecraft/ItemModelModifier.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.wrap.modifiers.minecraft; 2 | 3 | import de.skyslycer.hmcwraps.HMCWraps; 4 | import de.skyslycer.hmcwraps.serialization.wrap.Wrap; 5 | import de.skyslycer.hmcwraps.util.VersionUtil; 6 | import de.skyslycer.hmcwraps.wrap.modifiers.WrapModifier; 7 | import org.bukkit.NamespacedKey; 8 | import org.bukkit.entity.Player; 9 | import org.bukkit.inventory.ItemStack; 10 | import org.bukkit.persistence.PersistentDataContainer; 11 | import org.bukkit.persistence.PersistentDataType; 12 | import org.jetbrains.annotations.Nullable; 13 | 14 | public class ItemModelModifier implements WrapModifier { 15 | 16 | private final HMCWraps plugin; 17 | 18 | private final NamespacedKey originalItemModelKey; 19 | 20 | public ItemModelModifier(HMCWraps plugin) { 21 | this.plugin = plugin; 22 | this.originalItemModelKey = new NamespacedKey(plugin, "original-item-model"); 23 | } 24 | 25 | @Override 26 | public void wrap(@Nullable Wrap wrap, @Nullable Wrap currentWrap, ItemStack item, Player player) { 27 | var originalItemModel = getOriginalItemModel(item); 28 | NamespacedKey currentItemModel = null; 29 | if (VersionUtil.itemModelSupported() && item.getItemMeta().hasItemModel()) { 30 | currentItemModel = item.getItemMeta().getItemModel(); 31 | } 32 | if (VersionUtil.itemModelSupported()) { 33 | var meta = item.getItemMeta(); 34 | if (wrap != null) { 35 | if (wrap.getItemModel() != null) { 36 | meta.setItemModel(wrap.getItemModel()); 37 | } 38 | } else { 39 | meta.setItemModel(originalItemModel); 40 | meta.getPersistentDataContainer().remove(originalItemModelKey); 41 | } 42 | item.setItemMeta(meta); 43 | } 44 | if (wrap != null && currentWrap == null) { 45 | setOriginalItemModel(item, currentItemModel); 46 | } 47 | } 48 | 49 | /** 50 | * Get the original item model of the item. 51 | * 52 | * @param item The item 53 | * @return The original item model 54 | */ 55 | public NamespacedKey getOriginalItemModel(ItemStack item) { 56 | PersistentDataContainer container = item.getItemMeta().getPersistentDataContainer(); 57 | var data = container.get(originalItemModelKey, PersistentDataType.STRING); 58 | if (data == null) { 59 | return null; 60 | } 61 | return NamespacedKey.fromString(data); 62 | } 63 | 64 | private void setOriginalItemModel(ItemStack item, NamespacedKey itemModel) { 65 | var meta = item.getItemMeta(); 66 | if (itemModel != null) { 67 | meta.getPersistentDataContainer().set(originalItemModelKey, PersistentDataType.STRING, itemModel.toString()); 68 | } else { 69 | meta.getPersistentDataContainer().remove(originalItemModelKey); 70 | } 71 | item.setItemMeta(meta); 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/wrap/modifiers/minecraft/LoreModifier.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.wrap.modifiers.minecraft; 2 | 3 | import de.skyslycer.hmcwraps.HMCWraps; 4 | import de.skyslycer.hmcwraps.serialization.wrap.Wrap; 5 | import de.skyslycer.hmcwraps.util.StringUtil; 6 | import de.skyslycer.hmcwraps.wrap.modifiers.WrapModifier; 7 | import org.bukkit.ChatColor; 8 | import org.bukkit.NamespacedKey; 9 | import org.bukkit.entity.Player; 10 | import org.bukkit.inventory.ItemStack; 11 | import org.bukkit.persistence.PersistentDataType; 12 | import org.jetbrains.annotations.Nullable; 13 | 14 | import java.util.ArrayList; 15 | import java.util.Arrays; 16 | import java.util.List; 17 | import java.util.stream.Collectors; 18 | 19 | public class LoreModifier implements WrapModifier { 20 | 21 | private final NamespacedKey originalLoreKey; 22 | 23 | private final HMCWraps plugin; 24 | 25 | public LoreModifier(HMCWraps plugin) { 26 | this.plugin = plugin; 27 | this.originalLoreKey = new NamespacedKey(plugin, "original-lore"); 28 | } 29 | 30 | @Override 31 | public void wrap(@Nullable Wrap wrap, @Nullable Wrap currentWrap, ItemStack item, Player player) { 32 | var meta = item.getItemMeta(); 33 | var originalLore = getOriginalLore(item); 34 | var currentLore = meta.getLore(); 35 | if (currentWrap != null) { 36 | meta.setLore(originalLore); 37 | } 38 | if (wrap != null && wrap.getWrapLore() != null) { 39 | var lore = wrap.getWrapLore().stream().map(entry -> StringUtil.LEGACY_SERIALIZER.serialize(StringUtil.parseComponent(player, entry))).toList(); 40 | meta.setLore(lore); 41 | } 42 | if (wrap == null) { 43 | meta.getPersistentDataContainer().remove(originalLoreKey); 44 | } 45 | item.setItemMeta(meta); 46 | if (wrap != null && currentWrap == null) { 47 | setOriginalLore(item, currentLore); 48 | } 49 | } 50 | 51 | private void setOriginalLore(ItemStack item, List<String> lore) { 52 | var meta = item.getItemMeta(); 53 | if (lore != null) { 54 | meta.getPersistentDataContainer().set(originalLoreKey, PersistentDataType.STRING, 55 | lore.stream().map(entry -> entry.replace("§", "&")).collect(Collectors.joining(SEPARATOR))); 56 | } else { 57 | meta.getPersistentDataContainer().remove(originalLoreKey); 58 | } 59 | item.setItemMeta(meta); 60 | } 61 | 62 | /** 63 | * Get the original lore of the item. 64 | * 65 | * @param item The item 66 | * @return The original lore 67 | */ 68 | public List<String> getOriginalLore(ItemStack item) { 69 | var meta = item.getItemMeta(); 70 | var lore = new ArrayList<String>(); 71 | var loreSettings = plugin.getConfiguration().getPreservation().getLore(); 72 | if (loreSettings.isOriginalEnabled()) { 73 | var data = meta.getPersistentDataContainer().get(originalLoreKey, PersistentDataType.STRING); 74 | if (data != null) { 75 | Arrays.stream(data.split(SEPARATOR)).map(entry -> ChatColor.translateAlternateColorCodes('&', entry)).forEach(lore::add); 76 | } 77 | return lore; 78 | } else if (loreSettings.isDefaultEnabled()) { 79 | var map = loreSettings.getDefaults(); 80 | if (map.containsKey(item.getType().toString())) { 81 | map.get(item.getType().toString()).stream().map(entry -> ChatColor.translateAlternateColorCodes('&', entry)).forEach(lore::add); 82 | } 83 | for (String key : map.keySet()) { 84 | if (plugin.getCollectionHelper().getMaterials(key).contains(item.getType())) { 85 | map.get(key).stream().map(entry -> ChatColor.translateAlternateColorCodes('&', entry)).forEach(lore::add); 86 | } 87 | } 88 | return lore; 89 | } 90 | return item.getItemMeta().getLore(); 91 | } 92 | 93 | } 94 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/wrap/modifiers/minecraft/ModelDataModifier.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.wrap.modifiers.minecraft; 2 | 3 | import de.skyslycer.hmcwraps.HMCWraps; 4 | import de.skyslycer.hmcwraps.serialization.wrap.Wrap; 5 | import de.skyslycer.hmcwraps.wrap.modifiers.WrapModifier; 6 | import org.bukkit.NamespacedKey; 7 | import org.bukkit.entity.Player; 8 | import org.bukkit.inventory.ItemStack; 9 | import org.bukkit.persistence.PersistentDataType; 10 | 11 | import javax.annotation.Nullable; 12 | 13 | public class ModelDataModifier implements WrapModifier { 14 | 15 | private final NamespacedKey originalModelIdKey; 16 | 17 | private final HMCWraps plugin; 18 | 19 | public ModelDataModifier(HMCWraps plugin) { 20 | this.plugin = plugin; 21 | this.originalModelIdKey = new NamespacedKey(plugin, "original-model-id"); 22 | } 23 | 24 | @Override 25 | public void wrap(@Nullable Wrap wrap, @Nullable Wrap currentWrap, ItemStack item, Player player) { 26 | var originalModleId = getOriginalModelId(item); 27 | Integer currentModelId = null; 28 | var meta = item.getItemMeta(); 29 | if (meta.hasCustomModelData()) { 30 | currentModelId = meta.getCustomModelData(); 31 | } 32 | meta.setCustomModelData(wrap == null ? originalModleId : wrap.getModelId()); 33 | if (wrap == null) { 34 | meta.getPersistentDataContainer().remove(originalModelIdKey); 35 | } 36 | item.setItemMeta(meta); 37 | if (wrap != null && currentWrap == null) { 38 | setOriginalModelId(item, currentModelId); 39 | } 40 | } 41 | 42 | private void setOriginalModelId(ItemStack item, Integer modelData) { 43 | var meta = item.getItemMeta(); 44 | if (modelData != null) { 45 | meta.getPersistentDataContainer().set(originalModelIdKey, PersistentDataType.INTEGER, modelData); 46 | } else { 47 | meta.getPersistentDataContainer().remove(originalModelIdKey); 48 | } 49 | item.setItemMeta(meta); 50 | } 51 | 52 | /** 53 | * Get the original model id of the item. 54 | * 55 | * @param item The item 56 | * @return The original model id 57 | */ 58 | public Integer getOriginalModelId(ItemStack item) { 59 | var meta = item.getItemMeta(); 60 | var modelData = -1; 61 | var modelDataSettings = plugin.getConfiguration().getPreservation().getModelId(); 62 | if (modelDataSettings.isOriginalEnabled()) { 63 | var data = meta.getPersistentDataContainer().get(originalModelIdKey, PersistentDataType.INTEGER); 64 | if (data != null) { 65 | modelData = data; 66 | } 67 | } else if (modelDataSettings.isDefaultEnabled()) { 68 | var map = modelDataSettings.getDefaults(); 69 | if (map.containsKey(item.getType().toString())) { 70 | modelData = map.get(item.getType().toString()); 71 | } 72 | for (String key : map.keySet()) { 73 | if (plugin.getCollectionHelper().getMaterials(key).contains(item.getType())) { 74 | modelData = map.get(key); 75 | } 76 | } 77 | } 78 | return modelData; 79 | } 80 | 81 | /** 82 | * Get the real model id of the item. If the item is wrapped, the original model id will be returned. 83 | * If it isn't wrapped, the current model id will be returned. 84 | * 85 | * @param item The item 86 | * @return The real model id 87 | */ 88 | public int getRealModelId(ItemStack item) { 89 | var modelData = -1; 90 | if (plugin.getWrapper().getWrap(item) != null) { 91 | modelData = getOriginalModelId(item); 92 | } else if (item.getItemMeta().hasCustomModelData()) { 93 | try { // Added to prevent error with racking datapack 94 | modelData = item.getItemMeta().getCustomModelData(); 95 | } catch (Exception ignored) { } 96 | } 97 | return modelData; 98 | } 99 | 100 | } 101 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/wrap/modifiers/minecraft/NBTModifier.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.wrap.modifiers.minecraft; 2 | 3 | import de.skyslycer.hmcwraps.serialization.wrap.Wrap; 4 | import de.skyslycer.hmcwraps.util.StringUtil; 5 | import de.skyslycer.hmcwraps.util.WrapNBTUtil; 6 | import de.skyslycer.hmcwraps.wrap.modifiers.WrapModifier; 7 | import org.bukkit.entity.Player; 8 | import org.bukkit.inventory.ItemStack; 9 | import org.jetbrains.annotations.Nullable; 10 | 11 | public class NBTModifier implements WrapModifier { 12 | 13 | @Override 14 | public void wrap(@Nullable Wrap wrap, @Nullable Wrap currentWrap, ItemStack item, Player player) { 15 | if (wrap != null) { 16 | if (wrap.getWrapNbt() != null) { 17 | WrapNBTUtil.wrap(item, StringUtil.replacePlaceholders(player, wrap.getWrapNbt())); 18 | } 19 | } else { 20 | WrapNBTUtil.unwrap(item); 21 | } 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/wrap/modifiers/minecraft/NameModifier.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.wrap.modifiers.minecraft; 2 | 3 | import de.skyslycer.hmcwraps.HMCWraps; 4 | import de.skyslycer.hmcwraps.serialization.wrap.Wrap; 5 | import de.skyslycer.hmcwraps.util.StringUtil; 6 | import de.skyslycer.hmcwraps.wrap.modifiers.WrapModifier; 7 | import org.bukkit.ChatColor; 8 | import org.bukkit.NamespacedKey; 9 | import org.bukkit.entity.Player; 10 | import org.bukkit.inventory.ItemStack; 11 | import org.bukkit.persistence.PersistentDataType; 12 | import org.jetbrains.annotations.Nullable; 13 | 14 | public class NameModifier implements WrapModifier { 15 | 16 | private final NamespacedKey originalNameKey; 17 | 18 | private final HMCWraps plugin; 19 | 20 | public NameModifier(HMCWraps plugin) { 21 | this.plugin = plugin; 22 | this.originalNameKey = new NamespacedKey(plugin, "original-name"); 23 | } 24 | 25 | @Override 26 | public void wrap(@Nullable Wrap wrap, @Nullable Wrap currentWrap, ItemStack item, Player player) { 27 | var meta = item.getItemMeta(); 28 | var originalName = getOriginalName(item); 29 | var currentName = meta.getDisplayName(); 30 | if (currentWrap != null && (currentWrap.getWrapName() != null && (!Boolean.TRUE.equals(currentWrap.isApplyNameOnlyEmpty()) || 31 | StringUtil.LEGACY_SERIALIZER.serialize(StringUtil.parseComponent(player, currentWrap.getWrapName())).equals(meta.getDisplayName())))) { 32 | meta.setDisplayName(originalName); 33 | } 34 | if (wrap != null) { 35 | var originalActualName = currentWrap == null ? currentName : originalName; 36 | if (wrap.getWrapName() != null && (!Boolean.TRUE.equals(wrap.isApplyNameOnlyEmpty()) || originalActualName == null || originalActualName.isBlank())) { 37 | meta.setDisplayName(StringUtil.LEGACY_SERIALIZER.serialize(StringUtil.parseComponent(player, wrap.getWrapName())).replace("%originalname%", originalActualName == null ? "" : originalActualName)); 38 | } 39 | } else { 40 | meta.getPersistentDataContainer().remove(originalNameKey); 41 | } 42 | item.setItemMeta(meta); 43 | if (wrap != null && currentWrap == null) { 44 | setOriginalName(item, currentName); 45 | } 46 | } 47 | 48 | private void setOriginalName(ItemStack item, String name) { 49 | var meta = item.getItemMeta(); 50 | if (name != null) { 51 | meta.getPersistentDataContainer().set(originalNameKey, PersistentDataType.STRING, name.replace("§", "&")); 52 | } else { 53 | meta.getPersistentDataContainer().remove(originalNameKey); 54 | } 55 | item.setItemMeta(meta); 56 | } 57 | 58 | /** 59 | * Get the original name of the item. 60 | * 61 | * @param item The item 62 | * @return The original name 63 | */ 64 | public String getOriginalName(ItemStack item) { 65 | var meta = item.getItemMeta(); 66 | String name = null; 67 | var nameSettings = plugin.getConfiguration().getPreservation().getName(); 68 | if (nameSettings.isOriginalEnabled()) { 69 | var data = meta.getPersistentDataContainer().get(originalNameKey, PersistentDataType.STRING); 70 | if (data != null) { 71 | name = ChatColor.translateAlternateColorCodes('&', data); 72 | } 73 | return name; 74 | } else if (nameSettings.isDefaultEnabled()) { 75 | var map = nameSettings.getDefaults(); 76 | if (map.containsKey(item.getType().toString())) { 77 | name = StringUtil.LEGACY_SERIALIZER_AMPERSAND.serialize(StringUtil.parseComponent(map.get(item.getType().toString()))); 78 | } 79 | for (String key : map.keySet()) { 80 | if (plugin.getCollectionHelper().getMaterials(key).contains(item.getType())) { 81 | name = StringUtil.LEGACY_SERIALIZER_AMPERSAND.serialize(StringUtil.parseComponent(map.get(key))); 82 | } 83 | } 84 | return name; 85 | } 86 | return item.getItemMeta().getDisplayName(); 87 | } 88 | 89 | } 90 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/wrap/modifiers/plugin/ExecutableItemsModifier.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.wrap.modifiers.plugin; 2 | 3 | import com.ssomar.score.api.executableitems.ExecutableItemsAPI; 4 | import de.skyslycer.hmcwraps.HMCWraps; 5 | import de.skyslycer.hmcwraps.serialization.wrap.Wrap; 6 | import de.skyslycer.hmcwraps.wrap.modifiers.WrapModifier; 7 | import org.bukkit.Bukkit; 8 | import org.bukkit.NamespacedKey; 9 | import org.bukkit.entity.Player; 10 | import org.bukkit.inventory.ItemStack; 11 | import org.bukkit.persistence.PersistentDataContainer; 12 | import org.bukkit.persistence.PersistentDataType; 13 | import org.jetbrains.annotations.Nullable; 14 | 15 | public class ExecutableItemsModifier implements WrapModifier { 16 | 17 | private final HMCWraps plugin; 18 | 19 | private final NamespacedKey originalEIKey; 20 | 21 | public ExecutableItemsModifier(HMCWraps plugin) { 22 | this.plugin = plugin; 23 | this.originalEIKey = new NamespacedKey(plugin, "original-ei-id"); 24 | } 25 | 26 | @Override 27 | public void wrap(@Nullable Wrap wrap, @Nullable Wrap currentWrap, ItemStack item, Player player) { 28 | if (currentWrap != null) { 29 | setOriginalEIId(item, getRealEIId(item)); 30 | } 31 | } 32 | 33 | /** 34 | * Get the original Mythic ID of the item. 35 | * 36 | * @param item The item 37 | * @return The original mythic ID 38 | */ 39 | public String getOriginalEIId(ItemStack item) { 40 | PersistentDataContainer container = item.getItemMeta().getPersistentDataContainer(); 41 | return container.get(originalEIKey, PersistentDataType.STRING); 42 | } 43 | 44 | private void setOriginalEIId(ItemStack item, String mythicId) { 45 | var meta = item.getItemMeta(); 46 | if (mythicId != null) { 47 | meta.getPersistentDataContainer().set(originalEIKey, PersistentDataType.STRING, mythicId); 48 | } else { 49 | meta.getPersistentDataContainer().remove(originalEIKey); 50 | } 51 | item.setItemMeta(meta); 52 | } 53 | 54 | /** 55 | * Get the real Mythic ID of the item. If the item is wrapped, the original ID will be returned. 56 | * If it isn't wrapped, the current ID will be returned. 57 | * 58 | * @param item The item 59 | * @return The real mythic ID 60 | */ 61 | public String getRealEIId(ItemStack item) { 62 | String eiId = null; 63 | if (plugin.getWrapper().getWrap(item) != null) { 64 | eiId = getOriginalEIId(item); 65 | } else if (Bukkit.getPluginManager().getPlugin("ExecutableItems") != null) { 66 | var eiItem = ExecutableItemsAPI.getExecutableItemsManager().getExecutableItem(item); 67 | if (eiItem.isPresent()) { 68 | eiId = eiItem.get().getId(); 69 | } 70 | } 71 | return eiId; 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/wrap/modifiers/plugin/ItemsAdderModifier.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.wrap.modifiers.plugin; 2 | 3 | import de.skyslycer.hmcwraps.HMCWraps; 4 | import de.skyslycer.hmcwraps.serialization.wrap.Wrap; 5 | import de.skyslycer.hmcwraps.wrap.modifiers.WrapModifier; 6 | import de.tr7zw.changeme.nbtapi.NBT; 7 | import dev.lone.itemsadder.api.CustomStack; 8 | import org.bukkit.Bukkit; 9 | import org.bukkit.NamespacedKey; 10 | import org.bukkit.entity.Player; 11 | import org.bukkit.inventory.ItemStack; 12 | import org.bukkit.persistence.PersistentDataContainer; 13 | import org.bukkit.persistence.PersistentDataType; 14 | import org.jetbrains.annotations.Nullable; 15 | 16 | public class ItemsAdderModifier implements WrapModifier { 17 | 18 | private final HMCWraps plugin; 19 | 20 | private final NamespacedKey originalItemsAdderKey; 21 | 22 | public ItemsAdderModifier(HMCWraps plugin) { 23 | this.plugin = plugin; 24 | this.originalItemsAdderKey = new NamespacedKey(plugin, "original-itemsadder-id"); 25 | } 26 | 27 | @Override 28 | public void wrap(@Nullable Wrap wrap, @Nullable Wrap currentWrap, ItemStack item, Player player) { 29 | var originalItemsAdderId = getOriginalItemsAdderId(item); 30 | if (currentWrap != null) { 31 | setOriginalItemsAdderId(item, getRealItemsAdderId(item)); 32 | } 33 | if (wrap != null) { 34 | if (wrap.getId().startsWith("itemsadder:")) { 35 | setItemsAdderNBT(item, wrap.getId().substring(11)); 36 | } 37 | } else { 38 | if (originalItemsAdderId != null || (currentWrap != null && currentWrap.getId() != null && currentWrap.getId().startsWith("itemsadder:"))) { 39 | setItemsAdderNBT(item, originalItemsAdderId); 40 | } 41 | } 42 | } 43 | 44 | private void setItemsAdderNBT(ItemStack item, String id) { 45 | NBT.modify(item, nbt -> { 46 | var split = id != null ? id.split(":") : new String[0]; 47 | var iaCompound = nbt.getCompound("itemsadder"); 48 | if (iaCompound != null) { 49 | iaCompound.removeKey("namespace"); 50 | iaCompound.removeKey("id"); 51 | if (iaCompound.getKeys().isEmpty()) { 52 | nbt.removeKey("itemsadder"); 53 | } 54 | } 55 | if (split.length == 2) { 56 | iaCompound = nbt.getOrCreateCompound("itemsadder"); 57 | iaCompound.setString("namespace", split[0]); 58 | iaCompound.setString("id", split[1]); 59 | } 60 | }); 61 | } 62 | 63 | /** 64 | * Get the original ItemsAdder ID of the item. 65 | * 66 | * @param item The item 67 | * @return The original ItemsAdder ID 68 | */ 69 | public String getOriginalItemsAdderId(ItemStack item) { 70 | PersistentDataContainer container = item.getItemMeta().getPersistentDataContainer(); 71 | return container.get(originalItemsAdderKey, PersistentDataType.STRING); 72 | } 73 | 74 | private void setOriginalItemsAdderId(ItemStack item, String id) { 75 | var meta = item.getItemMeta(); 76 | if (id != null) { 77 | meta.getPersistentDataContainer().set(originalItemsAdderKey, PersistentDataType.STRING, id); 78 | } else { 79 | meta.getPersistentDataContainer().remove(originalItemsAdderKey); 80 | } 81 | item.setItemMeta(meta); 82 | } 83 | 84 | /** 85 | * Get the real ItemsAdder ID of the item. If the item is wrapped, the original ID will be returned. 86 | * If it isn't wrapped, the current ID will be returned. 87 | * @param item The item 88 | * @return The real ItemsAdder ID 89 | */ 90 | public String getRealItemsAdderId(ItemStack item) { 91 | String itemsAdderId = null; 92 | if (plugin.getWrapper().getWrap(item) != null) { 93 | itemsAdderId = getOriginalItemsAdderId(item); 94 | } else if (Bukkit.getPluginManager().getPlugin("ItemsAdder") != null) { 95 | var id = CustomStack.byItemStack(item); 96 | if (id != null) { 97 | itemsAdderId = id.getNamespacedID(); 98 | } 99 | } 100 | return itemsAdderId; 101 | } 102 | 103 | } 104 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/wrap/modifiers/plugin/MythicModifier.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.wrap.modifiers.plugin; 2 | 3 | import de.skyslycer.hmcwraps.HMCWraps; 4 | import de.skyslycer.hmcwraps.serialization.wrap.Wrap; 5 | import de.skyslycer.hmcwraps.wrap.modifiers.WrapModifier; 6 | import io.lumine.mythic.bukkit.MythicBukkit; 7 | import org.bukkit.Bukkit; 8 | import org.bukkit.NamespacedKey; 9 | import org.bukkit.entity.Player; 10 | import org.bukkit.inventory.ItemStack; 11 | import org.bukkit.persistence.PersistentDataContainer; 12 | import org.bukkit.persistence.PersistentDataType; 13 | import org.jetbrains.annotations.Nullable; 14 | 15 | public class MythicModifier implements WrapModifier { 16 | 17 | private final HMCWraps plugin; 18 | 19 | private final NamespacedKey originalMythicKey; 20 | 21 | public MythicModifier(HMCWraps plugin) { 22 | this.plugin = plugin; 23 | this.originalMythicKey = new NamespacedKey(plugin, "original-mythic-id"); 24 | } 25 | 26 | @Override 27 | public void wrap(@Nullable Wrap wrap, @Nullable Wrap currentWrap, ItemStack item, Player player) { 28 | if (currentWrap != null) { 29 | setOriginalMythicId(item, getRealMythicId(item)); 30 | } 31 | } 32 | 33 | /** 34 | * Get the original Mythic ID of the item. 35 | * 36 | * @param item The item 37 | * @return The original mythic ID 38 | */ 39 | public String getOriginalMythicId(ItemStack item) { 40 | PersistentDataContainer container = item.getItemMeta().getPersistentDataContainer(); 41 | return container.get(originalMythicKey, PersistentDataType.STRING); 42 | } 43 | 44 | private void setOriginalMythicId(ItemStack item, String mythicId) { 45 | var meta = item.getItemMeta(); 46 | if (mythicId != null) { 47 | meta.getPersistentDataContainer().set(originalMythicKey, PersistentDataType.STRING, mythicId); 48 | } else { 49 | meta.getPersistentDataContainer().remove(originalMythicKey); 50 | } 51 | item.setItemMeta(meta); 52 | } 53 | 54 | /** 55 | * Get the real Mythic ID of the item. If the item is wrapped, the original ID will be returned. 56 | * If it isn't wrapped, the current ID will be returned. 57 | * 58 | * @param item The item 59 | * @return The real mythic ID 60 | */ 61 | public String getRealMythicId(ItemStack item) { 62 | String mythicId = null; 63 | if (plugin.getWrapper().getWrap(item) != null) { 64 | mythicId = getOriginalMythicId(item); 65 | } else if (Bukkit.getPluginManager().getPlugin("MythicMobs") != null) { 66 | var id = MythicBukkit.inst().getItemManager().getMythicTypeFromItem(item); 67 | if (id != null) { 68 | mythicId = id; 69 | } 70 | } 71 | return mythicId; 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/wrap/modifiers/plugin/NexoModifier.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.wrap.modifiers.plugin; 2 | 3 | import com.nexomc.nexo.api.NexoItems; 4 | import de.skyslycer.hmcwraps.HMCWraps; 5 | import de.skyslycer.hmcwraps.serialization.wrap.Wrap; 6 | import de.skyslycer.hmcwraps.wrap.modifiers.WrapModifier; 7 | import org.bukkit.Bukkit; 8 | import org.bukkit.NamespacedKey; 9 | import org.bukkit.entity.Player; 10 | import org.bukkit.inventory.ItemStack; 11 | import org.bukkit.persistence.PersistentDataContainer; 12 | import org.bukkit.persistence.PersistentDataType; 13 | import org.jetbrains.annotations.Nullable; 14 | 15 | public class NexoModifier implements WrapModifier { 16 | 17 | private final HMCWraps plugin; 18 | 19 | private final NamespacedKey originalNexoKey; 20 | 21 | public NexoModifier(HMCWraps plugin) { 22 | this.plugin = plugin; 23 | this.originalNexoKey = new NamespacedKey(plugin, "original-nexo-id"); 24 | } 25 | 26 | @Override 27 | public void wrap(@Nullable Wrap wrap, @Nullable Wrap currentWrap, ItemStack item, Player player) { 28 | if (currentWrap != null) { 29 | setOriginalNexoId(item, getRealNexoId(item)); 30 | } 31 | } 32 | 33 | /** 34 | * Get the original Nexo ID of the item. 35 | * 36 | * @param item The item 37 | * @return The original Nexo ID 38 | */ 39 | public String getOriginalNexoId(ItemStack item) { 40 | PersistentDataContainer container = item.getItemMeta().getPersistentDataContainer(); 41 | return container.get(originalNexoKey, PersistentDataType.STRING); 42 | } 43 | 44 | private void setOriginalNexoId(ItemStack item, String nexoId) { 45 | var meta = item.getItemMeta(); 46 | if (nexoId != null) { 47 | meta.getPersistentDataContainer().set(originalNexoKey, PersistentDataType.STRING, nexoId); 48 | } else { 49 | meta.getPersistentDataContainer().remove(originalNexoKey); 50 | } 51 | item.setItemMeta(meta); 52 | } 53 | 54 | /** 55 | * Get the real Nexo ID of the item. If the item is wrapped, the original color will be returned. 56 | * If it isn't wrapped, the current color will be returned. 57 | * 58 | * @param item The item 59 | * @return The real Nexo ID 60 | */ 61 | public String getRealNexoId(ItemStack item) { 62 | String nexoId = null; 63 | if (plugin.getWrapper().getWrap(item) != null) { 64 | nexoId = getOriginalNexoId(item); 65 | } else if (Bukkit.getPluginManager().getPlugin("Nexo") != null) { 66 | var id = NexoItems.idFromItem(item); 67 | if (id != null) { 68 | nexoId = id; 69 | } 70 | } 71 | return nexoId; 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /api/src/main/java/de/skyslycer/hmcwraps/wrap/modifiers/plugin/OraxenModifier.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.wrap.modifiers.plugin; 2 | 3 | import de.skyslycer.hmcwraps.HMCWraps; 4 | import de.skyslycer.hmcwraps.serialization.wrap.Wrap; 5 | import de.skyslycer.hmcwraps.wrap.modifiers.WrapModifier; 6 | import io.th0rgal.oraxen.api.OraxenItems; 7 | import org.bukkit.Bukkit; 8 | import org.bukkit.NamespacedKey; 9 | import org.bukkit.entity.Player; 10 | import org.bukkit.inventory.ItemStack; 11 | import org.bukkit.persistence.PersistentDataContainer; 12 | import org.bukkit.persistence.PersistentDataType; 13 | import org.jetbrains.annotations.Nullable; 14 | 15 | public class OraxenModifier implements WrapModifier { 16 | 17 | private final HMCWraps plugin; 18 | 19 | private final NamespacedKey originalOraxenKey; 20 | 21 | public OraxenModifier(HMCWraps plugin) { 22 | this.plugin = plugin; 23 | this.originalOraxenKey = new NamespacedKey(plugin, "original-oraxen-id"); 24 | } 25 | 26 | @Override 27 | public void wrap(@Nullable Wrap wrap, @Nullable Wrap currentWrap, ItemStack item, Player player) { 28 | if (currentWrap != null) { 29 | setOriginalOraxenId(item, getRealOraxenId(item)); 30 | } 31 | } 32 | 33 | /** 34 | * Get the original Oraxen ID of the item. 35 | * 36 | * @param item The item 37 | * @return The original Oraxen ID 38 | */ 39 | public String getOriginalOraxenId(ItemStack item) { 40 | PersistentDataContainer container = item.getItemMeta().getPersistentDataContainer(); 41 | return container.get(originalOraxenKey, PersistentDataType.STRING); 42 | } 43 | 44 | private void setOriginalOraxenId(ItemStack item, String oraxenId) { 45 | var meta = item.getItemMeta(); 46 | if (oraxenId != null) { 47 | meta.getPersistentDataContainer().set(originalOraxenKey, PersistentDataType.STRING, oraxenId); 48 | } else { 49 | meta.getPersistentDataContainer().remove(originalOraxenKey); 50 | } 51 | item.setItemMeta(meta); 52 | } 53 | 54 | /** 55 | * Get the real Oraxen ID of the item. If the item is wrapped, the original ID will be returned. 56 | * If it isn't wrapped, the current ID will be returned. 57 | * @param item The item 58 | * @return The real Oraxen ID 59 | */ 60 | public String getRealOraxenId(ItemStack item) { 61 | String oraxenId = null; 62 | if (plugin.getWrapper().getWrap(item) != null) { 63 | oraxenId = getOriginalOraxenId(item); 64 | } else if (Bukkit.getPluginManager().getPlugin("Oraxen") != null) { 65 | var id = OraxenItems.getIdByItem(item); 66 | if (id != null) { 67 | oraxenId = id; 68 | } 69 | } 70 | return oraxenId; 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HibiscusMC/HMCWraps/521c4fb20e0fd44418e97ee82c0b163534890e5d/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip 4 | networkTimeout=10000 5 | zipStoreBase=GRADLE_USER_HOME 6 | zipStorePath=wrapper/dists 7 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%"=="" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%"=="" set DIRNAME=. 29 | @rem This is normally unused 30 | set APP_BASE_NAME=%~n0 31 | set APP_HOME=%DIRNAME% 32 | 33 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 34 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 35 | 36 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 37 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 38 | 39 | @rem Find java.exe 40 | if defined JAVA_HOME goto findJavaFromJavaHome 41 | 42 | set JAVA_EXE=java.exe 43 | %JAVA_EXE% -version >NUL 2>&1 44 | if %ERRORLEVEL% equ 0 goto execute 45 | 46 | echo. 47 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 48 | echo. 49 | echo Please set the JAVA_HOME variable in your environment to match the 50 | echo location of your Java installation. 51 | 52 | goto fail 53 | 54 | :findJavaFromJavaHome 55 | set JAVA_HOME=%JAVA_HOME:"=% 56 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 57 | 58 | if exist "%JAVA_EXE%" goto execute 59 | 60 | echo. 61 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 62 | echo. 63 | echo Please set the JAVA_HOME variable in your environment to match the 64 | echo location of your Java installation. 65 | 66 | goto fail 67 | 68 | :execute 69 | @rem Setup the command line 70 | 71 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 72 | 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if %ERRORLEVEL% equ 0 goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | set EXIT_CODE=%ERRORLEVEL% 85 | if %EXIT_CODE% equ 0 set EXIT_CODE=1 86 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% 87 | exit /b %EXIT_CODE% 88 | 89 | :mainEnd 90 | if "%OS%"=="Windows_NT" endlocal 91 | 92 | :omega 93 | -------------------------------------------------------------------------------- /settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "HMCWraps" 2 | include("api") 3 | 4 | dependencyResolutionManagement { 5 | versionCatalogs { 6 | create("depends") { 7 | library("spigot", "org.spigotmc:spigot-api:1.21.4-R0.1-SNAPSHOT") 8 | library("placeholderapi", "me.clip:placeholderapi:2.11.6") 9 | library("nexo", "com.nexomc:nexo:1.6.0") 10 | library("oraxen", "com.github.oraxen:oraxen:-SNAPSHOT") 11 | library("itemsadder", "com.github.LoneDev6:API-ItemsAdder:3.6.1") 12 | library("mythicmobs", "io.lumine:Mythic-Dist:5.8.0") 13 | library("annotations", "org.jetbrains:annotations:26.0.1") 14 | library("executableitems", "com.github.Ssomar-Developement:SCore:5.25.3.9") 15 | } 16 | create("libs") { 17 | library("packets", "com.github.retrooper:packetevents-spigot:2.8.0") 18 | library("particles", "com.owen1212055:particlehelper:1.5.0-SNAPSHOT") 19 | library("configupdater", "com.github.BG-Software-LLC:CommentedConfiguration:-SNAPSHOT") 20 | library("bstats", "org.bstats:bstats-bukkit:3.0.2") 21 | library("gui", "dev.triumphteam:triumph-gui:3.2.0-SNAPSHOT") 22 | library("configurate", "org.spongepowered:configurate-yaml:4.1.2") 23 | library("mclogs", "gs.mclo:java:2.2.1") 24 | library("nbtapi", "de.tr7zw:item-nbt-api:2.15.0") 25 | library("folialib", "com.tcoded:FoliaLib:0.4.2") 26 | 27 | library("adventure-api", "net.kyori", "adventure-api").versionRef("adventure") 28 | library("minimessage", "net.kyori", "adventure-text-minimessage").versionRef("adventure") 29 | library("adventure-bukkit", "net.kyori:adventure-platform-bukkit:4.3.4") 30 | version("adventure", "4.17.0") 31 | bundle("adventure", listOf("adventure-api", "minimessage", "adventure-bukkit")) 32 | 33 | library("lamp-common", "com.github.Revxrsal.Lamp", "common").versionRef("lamp") 34 | library("lamp-bukkit", "com.github.Revxrsal.Lamp", "bukkit").versionRef("lamp") 35 | version("lamp", "3.3.4") 36 | bundle("lamp", listOf("lamp-common", "lamp-bukkit")) 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/de/skyslycer/hmcwraps/commands/annotations/AnyPermission.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.commands.annotations; 2 | 3 | import revxrsal.commands.annotation.DistributeOnMethods; 4 | 5 | import java.lang.annotation.ElementType; 6 | import java.lang.annotation.Retention; 7 | import java.lang.annotation.RetentionPolicy; 8 | import java.lang.annotation.Target; 9 | 10 | @DistributeOnMethods 11 | @Target({ElementType.METHOD, ElementType.TYPE, ElementType.PARAMETER}) 12 | @Retention(RetentionPolicy.RUNTIME) 13 | public @interface AnyPermission { 14 | String[] value(); 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/de/skyslycer/hmcwraps/commands/annotations/AnyPermissionReader.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.commands.annotations; 2 | 3 | import org.jetbrains.annotations.NotNull; 4 | import org.jetbrains.annotations.Nullable; 5 | import revxrsal.commands.bukkit.BukkitCommandActor; 6 | import revxrsal.commands.command.trait.CommandAnnotationHolder; 7 | import revxrsal.commands.process.PermissionReader; 8 | 9 | public class AnyPermissionReader implements PermissionReader { 10 | 11 | @Override public @Nullable revxrsal.commands.command.CommandPermission getPermission(@NotNull CommandAnnotationHolder command) { 12 | var annotation = command.getAnnotation(AnyPermission.class); 13 | if (annotation == null) return null; 14 | var permissions = annotation.value(); 15 | return actor -> { 16 | var sender = ((BukkitCommandActor) actor).getSender(); 17 | for (var permission : permissions) { 18 | if (sender.hasPermission(permission)) return true; 19 | } 20 | return false; 21 | }; 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/de/skyslycer/hmcwraps/commands/annotations/NoHelp.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.commands.annotations; 2 | 3 | import revxrsal.commands.annotation.DistributeOnMethods; 4 | 5 | import java.lang.annotation.ElementType; 6 | import java.lang.annotation.Retention; 7 | import java.lang.annotation.RetentionPolicy; 8 | import java.lang.annotation.Target; 9 | 10 | @DistributeOnMethods 11 | @Target(ElementType.TYPE) 12 | @Retention(RetentionPolicy.RUNTIME) 13 | public @interface NoHelp { 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/de/skyslycer/hmcwraps/converter/ItemSkinsFile.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.converter; 2 | 3 | import de.skyslycer.hmcwraps.serialization.inventory.InventoryItem; 4 | import org.jetbrains.annotations.Nullable; 5 | import org.spongepowered.configurate.objectmapping.ConfigSerializable; 6 | 7 | import java.util.List; 8 | 9 | @ConfigSerializable 10 | public class ItemSkinsFile { 11 | 12 | private List<String> material; 13 | private int customModelData; 14 | private @Nullable String permission; 15 | private Item availableItem; 16 | private @Nullable Item unavailableItem; 17 | private @Nullable Item physicalItem; 18 | 19 | public List<String> getMaterial() { 20 | return material; 21 | } 22 | 23 | public int getCustomModelData() { 24 | return customModelData; 25 | } 26 | 27 | @Nullable 28 | public String getPermission() { 29 | return permission; 30 | } 31 | 32 | public Item getAvailableItem() { 33 | return availableItem; 34 | } 35 | 36 | @Nullable 37 | public Item getUnavailableItem() { 38 | return unavailableItem; 39 | } 40 | 41 | @Nullable 42 | public Item getPhysicalItem() { 43 | return physicalItem; 44 | } 45 | 46 | @ConfigSerializable 47 | public static class Item { 48 | 49 | private String material; 50 | private String displayName; 51 | private @Nullable Integer customModelData; 52 | private @Nullable Boolean glowing; 53 | private @Nullable List<String> lore; 54 | 55 | public String getMaterial() { 56 | return material; 57 | } 58 | 59 | public String getDisplayName() { 60 | return displayName; 61 | } 62 | 63 | @Nullable 64 | public Integer getCustomModelData() { 65 | return customModelData; 66 | } 67 | 68 | @Nullable 69 | public Boolean getGlowing() { 70 | return glowing; 71 | } 72 | 73 | @Nullable 74 | public List<String> getLore() { 75 | return lore; 76 | } 77 | 78 | public InventoryItem toItem() { 79 | return new InventoryItem(material, displayName, glowing, lore, null, customModelData, null, 80 | 1, null, null, null, null, null, null, null, null, null, null); 81 | } 82 | 83 | } 84 | 85 | } 86 | -------------------------------------------------------------------------------- /src/main/java/de/skyslycer/hmcwraps/gui/ItemComparator.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.gui; 2 | 3 | import de.skyslycer.hmcwraps.serialization.inventory.Inventory; 4 | import org.bukkit.entity.Player; 5 | 6 | import java.util.Comparator; 7 | 8 | public class ItemComparator implements Comparator<WrapItemCombination> { 9 | 10 | private final Inventory inventorySettings; 11 | private final Player player; 12 | 13 | public ItemComparator(Inventory inventorySettings, Player player) { 14 | this.inventorySettings = inventorySettings; 15 | this.player = player; 16 | } 17 | 18 | @Override 19 | public int compare(WrapItemCombination wrap1, WrapItemCombination wrap2) { 20 | for (String sortType : inventorySettings.getSortOrder()) { 21 | switch (sortType.toUpperCase()) { 22 | case "PERMISSION" -> { 23 | var permissionCompare = Boolean.compare(wrap2.wrap().hasPermission(player), wrap1.wrap().hasPermission(player)); 24 | if (permissionCompare != 0) { 25 | return permissionCompare; 26 | } 27 | } 28 | case "SORT_ID" -> { 29 | var sortId1 = wrap1.wrap().getSort() != null ? wrap1.wrap().getSort() : Integer.MAX_VALUE; 30 | var sortId2 = wrap2.wrap().getSort() != null ? wrap2.wrap().getSort() : Integer.MAX_VALUE; 31 | var sortCompare = Integer.compare(sortId1, sortId2); 32 | if (sortCompare != 0) { 33 | return sortCompare; 34 | } 35 | } 36 | case "MODEL_ID" -> { 37 | int modelData1 = wrap1.item().getItemMeta().hasCustomModelData() ? wrap1.item().getItemMeta().getCustomModelData() : Integer.MAX_VALUE; 38 | int modelData2 = wrap2.item().getItemMeta().hasCustomModelData() ? wrap2.item().getItemMeta().getCustomModelData() : Integer.MAX_VALUE; 39 | var modelComapre = Integer.compare(modelData1, modelData2); 40 | if (modelComapre != 0) { 41 | return modelComapre; 42 | } 43 | } 44 | } 45 | } 46 | return 0; 47 | } 48 | 49 | } 50 | 51 | -------------------------------------------------------------------------------- /src/main/java/de/skyslycer/hmcwraps/gui/WrapItemCombination.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.gui; 2 | 3 | import de.skyslycer.hmcwraps.serialization.wrap.Wrap; 4 | import org.bukkit.inventory.ItemStack; 5 | 6 | public record WrapItemCombination(Wrap wrap, ItemStack item) { } 7 | -------------------------------------------------------------------------------- /src/main/java/de/skyslycer/hmcwraps/itemhook/ItemsAdderItemHook.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.itemhook; 2 | 3 | import dev.lone.itemsadder.api.CustomStack; 4 | import org.bukkit.inventory.ItemStack; 5 | 6 | 7 | public class ItemsAdderItemHook extends ItemHook { 8 | 9 | @Override 10 | public String getPrefix() { 11 | return "itemsadder:"; 12 | } 13 | 14 | @Override 15 | public ItemStack get(String id) { 16 | final CustomStack stack = CustomStack.getInstance(id); 17 | if (stack == null) { 18 | return null; 19 | } 20 | return stack.getItemStack().clone(); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/de/skyslycer/hmcwraps/itemhook/MythicItemHook.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.itemhook; 2 | 3 | import io.lumine.mythic.bukkit.MythicBukkit; 4 | import org.bukkit.inventory.ItemStack; 5 | 6 | public class MythicItemHook extends ItemHook { 7 | 8 | @Override 9 | public String getPrefix() { 10 | return "mythic:"; 11 | } 12 | 13 | @Override 14 | public ItemStack get(String id) { 15 | if (MythicBukkit.inst().getItemManager().getItem(id).isEmpty()) { 16 | return null; 17 | } 18 | return MythicBukkit.inst().getItemManager().getItemStack(id); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/de/skyslycer/hmcwraps/itemhook/NexoItemHook.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.itemhook; 2 | 3 | import com.nexomc.nexo.api.NexoItems; 4 | import org.bukkit.inventory.ItemStack; 5 | 6 | public class NexoItemHook extends ItemHook { 7 | 8 | @Override 9 | public String getPrefix() { 10 | return "nexo:"; 11 | } 12 | 13 | @Override 14 | public ItemStack get(String id) { 15 | if (NexoItems.itemFromId(id) == null) { 16 | return null; 17 | } 18 | return NexoItems.itemFromId(id).build(); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/de/skyslycer/hmcwraps/itemhook/OraxenItemHook.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.itemhook; 2 | 3 | import io.th0rgal.oraxen.api.OraxenItems; 4 | import org.bukkit.inventory.ItemStack; 5 | import org.jetbrains.annotations.Nullable; 6 | 7 | public class OraxenItemHook extends ItemHook { 8 | 9 | @Override 10 | public String getPrefix() { 11 | return "oraxen:"; 12 | } 13 | 14 | @Override 15 | public ItemStack get(String id) { 16 | if (OraxenItems.getItemById(id) == null) { 17 | return null; 18 | } 19 | return OraxenItems.getItemById(id).build(); 20 | } 21 | 22 | @Override 23 | @Nullable 24 | public String getTrimMaterial(String id) { 25 | return "minecraft:redstone"; 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/de/skyslycer/hmcwraps/listener/DispenserArmorListener.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.listener; 2 | 3 | import de.skyslycer.hmcwraps.HMCWrapsPlugin; 4 | import de.skyslycer.hmcwraps.util.PermissionUtil; 5 | import org.bukkit.entity.Player; 6 | import org.bukkit.event.EventHandler; 7 | import org.bukkit.event.Listener; 8 | import org.bukkit.event.block.BlockDispenseArmorEvent; 9 | 10 | public class DispenserArmorListener implements Listener { 11 | 12 | private final HMCWrapsPlugin plugin; 13 | 14 | public DispenserArmorListener(HMCWrapsPlugin plugin) { 15 | this.plugin = plugin; 16 | } 17 | 18 | @EventHandler 19 | public void onArmorEquip(BlockDispenseArmorEvent event) { 20 | if (!(event.getTargetEntity() instanceof Player player)){ 21 | return; 22 | } 23 | plugin.getFoliaLib().getScheduler().runAtEntityLater(player, () -> PermissionUtil.loopThroughInventory(plugin, player, player.getInventory()), 1L); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/de/skyslycer/hmcwraps/listener/DurabilityChangeListener.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.listener; 2 | 3 | import de.skyslycer.hmcwraps.HMCWrapsPlugin; 4 | import org.bukkit.event.EventHandler; 5 | import org.bukkit.event.EventPriority; 6 | import org.bukkit.event.Listener; 7 | import org.bukkit.event.player.PlayerItemDamageEvent; 8 | import org.bukkit.event.player.PlayerItemMendEvent; 9 | import org.bukkit.inventory.ItemStack; 10 | import org.bukkit.inventory.meta.Damageable; 11 | 12 | public class DurabilityChangeListener implements Listener { 13 | 14 | private final HMCWrapsPlugin plugin; 15 | 16 | public DurabilityChangeListener(HMCWrapsPlugin plugin) { 17 | this.plugin = plugin; 18 | } 19 | 20 | @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) 21 | public void onItemDamage(PlayerItemDamageEvent event) { 22 | if (updateDurability(event.getItem(), -event.getDamage())) { 23 | event.setDamage(0); 24 | } 25 | } 26 | 27 | @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) 28 | public void onItemMend(PlayerItemMendEvent event) { 29 | if (updateDurability(event.getItem(), event.getRepairAmount())) { 30 | event.setRepairAmount(0); 31 | } 32 | } 33 | 34 | private boolean updateDurability(ItemStack item, int changed) { 35 | var durability = plugin.getWrapper().getModifiers().armorImitation().getFakeDurability(item); 36 | var maxDurability = plugin.getWrapper().getModifiers().armorImitation().getFakeMaxDurability(item); 37 | if (plugin.getWrapper().getWrap(item) == null || plugin.getWrapper().getModifiers().armorImitation().getFakeDurability(item) == -1 || durability == -1) { 38 | return false; 39 | } 40 | var newDurability = Math.min(durability + changed, maxDurability); 41 | var modelDurability = ((double) newDurability / maxDurability) * item.getType().getMaxDurability(); 42 | if (modelDurability == 0 && newDurability > 0) { 43 | modelDurability = 1; 44 | } 45 | plugin.getWrapper().getModifiers().armorImitation().setFakeDurability(item, newDurability); 46 | var meta = (Damageable) item.getItemMeta(); 47 | meta.setDamage((int) (item.getType().getMaxDurability() - Math.round(modelDurability))); 48 | item.setItemMeta(meta); 49 | if (newDurability <= 0) { 50 | item.setAmount(0); 51 | } 52 | return true; 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/de/skyslycer/hmcwraps/listener/ItemBurnListener.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.listener; 2 | 3 | import de.skyslycer.hmcwraps.HMCWrapsPlugin; 4 | import org.bukkit.entity.Item; 5 | import org.bukkit.event.EventHandler; 6 | import org.bukkit.event.EventPriority; 7 | import org.bukkit.event.Listener; 8 | import org.bukkit.event.entity.EntityCombustEvent; 9 | import org.bukkit.event.entity.EntityDamageEvent; 10 | 11 | public class ItemBurnListener implements Listener { 12 | 13 | private final HMCWrapsPlugin plugin; 14 | 15 | public ItemBurnListener(HMCWrapsPlugin plugin) { 16 | this.plugin = plugin; 17 | } 18 | 19 | @EventHandler(priority = EventPriority.HIGH) 20 | public void onItemBurn(EntityCombustEvent event) { 21 | if (!(event.getEntity() instanceof Item item)) { 22 | return; 23 | } 24 | var originalMaterial = plugin.getWrapper().getModifiers().armorImitation().getOriginalMaterial(item.getItemStack()); 25 | if (plugin.getWrapper().getWrap(item.getItemStack()) != null && originalMaterial != null && !originalMaterial.isBlank() && originalMaterial.contains("NETHERITE")) { 26 | event.setCancelled(true); 27 | } 28 | } 29 | 30 | @EventHandler(priority = EventPriority.HIGH) 31 | public void onEntityBurn(EntityDamageEvent event) { 32 | if (!(event.getEntity() instanceof Item item)) { 33 | return; 34 | } 35 | if (event.getCause() != EntityDamageEvent.DamageCause.FIRE && event.getCause() != EntityDamageEvent.DamageCause.LAVA) { 36 | return; 37 | } 38 | var originalMaterial = plugin.getWrapper().getModifiers().armorImitation().getOriginalMaterial(item.getItemStack()); 39 | if (plugin.getWrapper().getWrap(item.getItemStack()) != null && originalMaterial != null && !originalMaterial.isBlank() && originalMaterial.contains("NETHERITE")) { 40 | event.setCancelled(true); 41 | } 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/de/skyslycer/hmcwraps/listener/PlayerDropListener.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.listener; 2 | 3 | import de.skyslycer.hmcwraps.HMCWrapsPlugin; 4 | import de.skyslycer.hmcwraps.util.PermissionUtil; 5 | import org.bukkit.event.EventHandler; 6 | import org.bukkit.event.Listener; 7 | import org.bukkit.event.player.PlayerDropItemEvent; 8 | 9 | public class PlayerDropListener implements Listener { 10 | 11 | private final HMCWrapsPlugin plugin; 12 | 13 | public PlayerDropListener(HMCWrapsPlugin plugin) { 14 | this.plugin = plugin; 15 | } 16 | 17 | @EventHandler 18 | public void onItemDrop(PlayerDropItemEvent event) { 19 | if (plugin.getPreviewManager().isPreviewing(event.getPlayer())) { 20 | plugin.getPreviewManager().remove(event.getPlayer().getUniqueId(), false); 21 | } 22 | var result = PermissionUtil.hasPermission(plugin, event.getItemDrop().getItemStack(), event.getPlayer()); 23 | if (result != null) { 24 | event.getItemDrop().setItemStack(result); 25 | } 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/de/skyslycer/hmcwraps/listener/PlayerHitEntityListener.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.listener; 2 | 3 | import de.skyslycer.hmcwraps.HMCWrapsPlugin; 4 | import de.skyslycer.hmcwraps.actions.information.WrapActionInformation; 5 | import org.bukkit.entity.Player; 6 | import org.bukkit.event.EventHandler; 7 | import org.bukkit.event.Listener; 8 | import org.bukkit.event.entity.EntityDamageByEntityEvent; 9 | 10 | public class PlayerHitEntityListener implements Listener { 11 | 12 | private final HMCWrapsPlugin plugin; 13 | 14 | public PlayerHitEntityListener(HMCWrapsPlugin plugin) { 15 | this.plugin = plugin; 16 | } 17 | 18 | @EventHandler 19 | public void onHit(EntityDamageByEntityEvent event) { 20 | if (!(event.getDamager() instanceof Player player)) { 21 | return; 22 | } 23 | if (plugin.getPreviewManager().isPreviewing(player)) { 24 | plugin.getPreviewManager().remove(player.getUniqueId(), false); 25 | } 26 | var weapon = player.getInventory().getItemInMainHand(); 27 | if (weapon == null || weapon.getType().isAir()) { 28 | return; 29 | } 30 | var wrap = plugin.getWrapper().getWrap(weapon); 31 | if (wrap == null || wrap.getActions() == null) { 32 | return; 33 | } 34 | if (wrap.getActions().get("hit-any") != null) { 35 | plugin.getActionHandler().pushFromConfig(wrap.getActions().get("hit-any"), new WrapActionInformation(wrap, player, "")); 36 | } 37 | if (event.getEntity() instanceof Player && wrap.getActions().get("hit-player") != null) { 38 | plugin.getActionHandler().pushFromConfig(wrap.getActions().get("hit-player"), new WrapActionInformation(wrap, player, "")); 39 | } else if (wrap.getActions().get("hit-entity") != null) { 40 | plugin.getActionHandler().pushFromConfig(wrap.getActions().get("hit-entity"), new WrapActionInformation(wrap, player, "")); 41 | } 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/de/skyslycer/hmcwraps/listener/PlayerInteractListener.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.listener; 2 | 3 | import de.skyslycer.hmcwraps.HMCWrapsPlugin; 4 | import de.skyslycer.hmcwraps.commands.WrapCommand; 5 | import de.skyslycer.hmcwraps.gui.GuiBuilder; 6 | import de.skyslycer.hmcwraps.util.ListUtil; 7 | import de.skyslycer.hmcwraps.util.PermissionUtil; 8 | import org.bukkit.Material; 9 | import org.bukkit.event.EventHandler; 10 | import org.bukkit.event.Listener; 11 | import org.bukkit.event.block.Action; 12 | import org.bukkit.event.player.PlayerInteractEvent; 13 | 14 | import java.util.List; 15 | 16 | public class PlayerInteractListener implements Listener { 17 | 18 | private final HMCWrapsPlugin plugin; 19 | 20 | public PlayerInteractListener(HMCWrapsPlugin plugin) { 21 | this.plugin = plugin; 22 | } 23 | 24 | @EventHandler 25 | public void onInteract(PlayerInteractEvent event) { 26 | var player = event.getPlayer(); 27 | if (event.getAction() == Action.LEFT_CLICK_BLOCK && plugin.getPreviewManager().isPreviewing(player)) { 28 | plugin.getPreviewManager().remove(player.getUniqueId(), false); 29 | } 30 | if (player.getInventory().getItemInMainHand().getType().isAir()) { 31 | return; 32 | } 33 | var currentItem = player.getInventory().getItemInMainHand(); 34 | var newItem = PermissionUtil.check(plugin, player, currentItem); 35 | if (!currentItem.equals(newItem)) { 36 | player.getInventory().setItemInMainHand(newItem); 37 | if (newItem.getType().toString().contains("DISC") && event.getClickedBlock() != null && event.getClickedBlock().getType().equals(Material.JUKEBOX)) { 38 | event.setCancelled(true); 39 | return; 40 | } 41 | } 42 | 43 | if (plugin.getWrapper().isGloballyDisabled(newItem)) { 44 | return; 45 | } 46 | 47 | var excludes = plugin.getConfiguration().getInventory().getShortcut().getExclude(); 48 | var type = newItem.getType(); 49 | if (plugin.getWrapper().getWrap(newItem) != null && !plugin.getWrapper().getModifiers().armorImitation().getOriginalMaterial(newItem).isEmpty()) { 50 | type = Material.valueOf(plugin.getWrapper().getModifiers().armorImitation().getOriginalMaterial(newItem)); 51 | } 52 | if (event.getAction() != Action.RIGHT_CLICK_AIR && event.getAction() != Action.RIGHT_CLICK_BLOCK 53 | || plugin.getCollectionHelper().getItems(type).isEmpty() || !player.isSneaking() 54 | || !plugin.getConfiguration().getInventory().getShortcut().isEnabled() 55 | || ListUtil.containsAny(List.of(type.toString(), 56 | player.getInventory().getItemInOffHand().getType().toString()), excludes) 57 | || (plugin.getConfiguration().getPermissions().isInventoryPermission() 58 | && !player.hasPermission(WrapCommand.WRAPS_PERMISSION)) 59 | || (player.hasPermission("hmcwraps.shortcut.disable") && !player.isOp())) { 60 | return; 61 | } 62 | event.setCancelled(true); 63 | GuiBuilder.open(plugin, player, newItem, player.getInventory().getHeldItemSlot()); 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/de/skyslycer/hmcwraps/listener/PlayerJoinListener.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.listener; 2 | 3 | import de.skyslycer.hmcwraps.HMCWrapsPlugin; 4 | import de.skyslycer.hmcwraps.util.PermissionUtil; 5 | import org.bukkit.event.EventHandler; 6 | import org.bukkit.event.Listener; 7 | import org.bukkit.event.player.PlayerJoinEvent; 8 | 9 | public class PlayerJoinListener implements Listener { 10 | 11 | private final HMCWrapsPlugin plugin; 12 | 13 | public PlayerJoinListener(HMCWrapsPlugin plugin) { 14 | this.plugin = plugin; 15 | } 16 | 17 | @EventHandler 18 | public void onPlayerJoin(PlayerJoinEvent event) { 19 | plugin.getFoliaLib().getScheduler().runAtEntityLater(event.getPlayer(), () -> PermissionUtil.loopThroughInventory(plugin, event.getPlayer(), event.getPlayer().getInventory()), 1); 20 | plugin.getFoliaLib().getScheduler().runLaterAsync(() -> plugin.getUpdateChecker().checkPlayer(event.getPlayer()), 5); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/de/skyslycer/hmcwraps/listener/PlayerOffHandSwitchListener.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.listener; 2 | 3 | import de.skyslycer.hmcwraps.HMCWraps; 4 | import de.skyslycer.hmcwraps.util.PermissionUtil; 5 | import org.bukkit.event.EventHandler; 6 | import org.bukkit.event.Listener; 7 | import org.bukkit.event.player.PlayerSwapHandItemsEvent; 8 | 9 | public class PlayerOffHandSwitchListener implements Listener { 10 | 11 | private final HMCWraps plugin; 12 | 13 | public PlayerOffHandSwitchListener(HMCWraps plugin) { 14 | this.plugin = plugin; 15 | } 16 | 17 | @EventHandler 18 | public void onSwitch(PlayerSwapHandItemsEvent event) { 19 | var offHand = PermissionUtil.hasPermission(plugin, event.getOffHandItem(), event.getPlayer()); 20 | var mainHand = PermissionUtil.hasPermission(plugin, event.getMainHandItem(), event.getPlayer()); 21 | if (offHand != null) { 22 | event.setOffHandItem(offHand); 23 | } 24 | if (mainHand != null) { 25 | event.setMainHandItem(mainHand); 26 | } 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/de/skyslycer/hmcwraps/listener/PlayerPickupListener.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.listener; 2 | 3 | import de.skyslycer.hmcwraps.HMCWrapsPlugin; 4 | import de.skyslycer.hmcwraps.util.PermissionUtil; 5 | import org.bukkit.entity.Player; 6 | import org.bukkit.event.EventHandler; 7 | import org.bukkit.event.EventPriority; 8 | import org.bukkit.event.Listener; 9 | import org.bukkit.event.entity.EntityPickupItemEvent; 10 | 11 | public class PlayerPickupListener implements Listener { 12 | 13 | private final HMCWrapsPlugin plugin; 14 | 15 | public PlayerPickupListener(HMCWrapsPlugin plugin) { 16 | this.plugin = plugin; 17 | } 18 | 19 | @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) 20 | public void onItemPickup(EntityPickupItemEvent event) { 21 | if (!(event.getEntity() instanceof Player player)) { 22 | return; 23 | } 24 | plugin.getFoliaLib().getScheduler().runAtEntityLater(player, () -> PermissionUtil.loopThroughInventory(plugin, player, player.getInventory()), 1L); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/de/skyslycer/hmcwraps/listener/PlayerShiftListener.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.listener; 2 | 3 | import de.skyslycer.hmcwraps.HMCWrapsPlugin; 4 | import org.bukkit.event.EventHandler; 5 | import org.bukkit.event.Listener; 6 | import org.bukkit.event.player.PlayerToggleSneakEvent; 7 | 8 | public class PlayerShiftListener implements Listener { 9 | 10 | private final HMCWrapsPlugin plugin; 11 | 12 | public PlayerShiftListener(HMCWrapsPlugin plugin) { 13 | this.plugin = plugin; 14 | } 15 | 16 | @EventHandler 17 | public void onShift(PlayerToggleSneakEvent event) { 18 | if (event.isSneaking() && plugin.getConfiguration().getPreview().getSneakCancel().isEnabled()) { 19 | plugin.getPreviewManager().remove(event.getPlayer().getUniqueId(), true); 20 | } 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/de/skyslycer/hmcwraps/messages/MessageHandlerImpl.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.messages; 2 | 3 | import de.skyslycer.hmcwraps.HMCWrapsPlugin; 4 | import de.skyslycer.hmcwraps.util.StringUtil; 5 | import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver.Single; 6 | import org.bukkit.command.CommandSender; 7 | import org.bukkit.entity.Player; 8 | 9 | import java.io.BufferedReader; 10 | import java.io.IOException; 11 | import java.io.InputStreamReader; 12 | import java.nio.charset.StandardCharsets; 13 | import java.nio.file.Files; 14 | import java.nio.file.Path; 15 | import java.nio.file.StandardOpenOption; 16 | import java.util.PropertyResourceBundle; 17 | 18 | public class MessageHandlerImpl implements MessageHandler { 19 | 20 | private final HMCWrapsPlugin plugin; 21 | private PropertyResourceBundle bundle; 22 | private PropertyResourceBundle fallback; 23 | 24 | public MessageHandlerImpl(HMCWrapsPlugin plugin) { 25 | this.plugin = plugin; 26 | } 27 | 28 | @Override 29 | public boolean load(Path path) { 30 | try { 31 | fallback = new PropertyResourceBundle(HMCWrapsPlugin.class.getClassLoader().getResource("messages.properties").openStream()); 32 | } catch (IOException | NullPointerException exception) { 33 | plugin.logSevere("An error occurred while trying to load the fallback messages (please report this to the developers):", exception); 34 | } 35 | 36 | try { 37 | bundle = new PropertyResourceBundle(Files.newInputStream(path)); 38 | } catch (IOException exception) { 39 | plugin.logSevere("An error occurred while trying to load the messages (please report this to the developers):", exception); 40 | } 41 | 42 | if (bundle == null && fallback == null) { 43 | plugin.logSevere("Could not load any messages (please report this to the developers)! The plugin will shut down now."); 44 | return false; 45 | } 46 | return true; 47 | } 48 | 49 | @Override 50 | public String get(Messages key) { 51 | if (bundle.containsKey(key.getKey())) { 52 | return bundle.getString(key.getKey()); 53 | } else if (fallback.containsKey(key.getKey())) { 54 | return fallback.getString(key.getKey()); 55 | } else { 56 | return "Invalid key: " + key; 57 | } 58 | } 59 | 60 | @Override 61 | public void update(Path path) { 62 | try { 63 | var stream = HMCWrapsPlugin.class.getClassLoader().getResource("messages.properties").openStream(); 64 | var lines = new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8)).lines(); 65 | var checkLines = Files.readAllLines(path); 66 | lines.forEach(line -> { 67 | var split = line.split("="); 68 | if (split.length > 1 && checkLines.stream().filter(it -> it.startsWith(split[0])).findFirst().isEmpty()) { 69 | try { 70 | Files.writeString(path, '\n' + line, StandardOpenOption.APPEND); 71 | } catch (IOException exception) { 72 | plugin.logSevere("Could not append the following line: \n" + line, exception); 73 | } 74 | } 75 | }); 76 | } catch (Exception exception) { 77 | plugin.logSevere("Could not load the message files to update them!", exception); 78 | } 79 | } 80 | 81 | @Override 82 | public void send(CommandSender sender, Messages key, Single... placeholders) { 83 | var messageFromConfig = get(key); 84 | if (messageFromConfig.isBlank()) { 85 | return; 86 | } 87 | var message = StringUtil.parseComponent(sender, messageFromConfig, placeholders); 88 | if (sender instanceof Player player) { 89 | plugin.getMessagePool().execute(player.getUniqueId(), message, () -> StringUtil.sendComponent(sender, message)); 90 | return; 91 | } 92 | StringUtil.sendComponent(sender, message); 93 | } 94 | 95 | } 96 | -------------------------------------------------------------------------------- /src/main/java/de/skyslycer/hmcwraps/metrics/PluginMetrics.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.metrics; 2 | 3 | import de.skyslycer.hmcwraps.HMCWrapsPlugin; 4 | import org.bstats.bukkit.Metrics; 5 | import org.bstats.charts.SimplePie; 6 | 7 | public class PluginMetrics { 8 | 9 | private static final int PLUGIN_ID = 14554; 10 | 11 | private final HMCWrapsPlugin plugin; 12 | private final Metrics metrics; 13 | 14 | public PluginMetrics(HMCWrapsPlugin plugin) { 15 | this.plugin = plugin; 16 | this.metrics = new Metrics(plugin, PLUGIN_ID); 17 | } 18 | 19 | public void init() { 20 | metrics.addCustomChart(new SimplePie("wraps", () -> String.valueOf(plugin.getWrapsLoader().getWraps().size()))); 21 | metrics.addCustomChart(new SimplePie("wrapfiles", () -> String.valueOf(plugin.getWrapsLoader().getWrapFileCount()))); 22 | metrics.addCustomChart(new SimplePie("collectionfiles", () -> String.valueOf(plugin.getWrapsLoader().getCollectionFileCount()))); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/de/skyslycer/hmcwraps/nbtapi/logger/NoInfoLogger.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.nbtapi.logger; 2 | 3 | import java.util.logging.Level; 4 | import java.util.logging.Logger; 5 | 6 | public class NoInfoLogger extends Logger { 7 | 8 | public NoInfoLogger(String name, String resourceBundleName) { 9 | super(name, resourceBundleName); 10 | } 11 | 12 | @Override 13 | public void info(String msg) { 14 | } 15 | 16 | @Override 17 | public void log(Level level, String msg) { 18 | if (level == Level.INFO) { 19 | return; 20 | } 21 | super.log(level, msg); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/de/skyslycer/hmcwraps/placeholderapi/HMCWrapsPlaceholders.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.placeholderapi; 2 | 3 | import de.skyslycer.hmcwraps.HMCWrapsPlugin; 4 | import de.skyslycer.hmcwraps.messages.Messages; 5 | import de.skyslycer.hmcwraps.util.ColorUtil; 6 | import de.skyslycer.hmcwraps.util.StringUtil; 7 | import me.clip.placeholderapi.expansion.PlaceholderExpansion; 8 | 9 | import java.util.Map; 10 | 11 | public class HMCWrapsPlaceholders extends PlaceholderExpansion { 12 | 13 | private final HMCWrapsPlugin plugin; 14 | 15 | public HMCWrapsPlaceholders(HMCWrapsPlugin plugin) { 16 | this.plugin = plugin; 17 | } 18 | 19 | @Override 20 | public String getIdentifier() { 21 | return "hmcwraps"; 22 | } 23 | 24 | @Override 25 | public String getAuthor() { 26 | return "Skyslycer"; 27 | } 28 | 29 | @Override 30 | public String getVersion() { 31 | return plugin.getDescription().getVersion(); 32 | } 33 | 34 | @Override 35 | public String onPlaceholderRequest(org.bukkit.entity.Player player, String identifier) { 36 | if (identifier.equals("mainhand") && player != null) { 37 | var wrap = plugin.getWrapper().getWrap(player.getInventory().getItemInMainHand()); 38 | if (wrap == null) { 39 | return null; 40 | } 41 | return wrap.getUuid(); 42 | } else if (identifier.equals("filter") && player != null) { 43 | if (plugin.getFilterStorage().get(player)) { 44 | return StringUtil.LEGACY_SERIALIZER.serialize(StringUtil.parseComponent(player, plugin.getMessageHandler().get(Messages.INVENTORY_FILTER_ACTIVE))); 45 | } else { 46 | return StringUtil.LEGACY_SERIALIZER.serialize(StringUtil.parseComponent(player, plugin.getMessageHandler().get(Messages.INVENTORY_FILTER_INACTIVE))); 47 | } 48 | } else if (identifier.split("_").length >= 2) { 49 | var action = identifier.substring(0, identifier.indexOf("_")); 50 | var wrapUuid = identifier.substring(identifier.indexOf("_") + 1); 51 | var wrap = plugin.getWrapsLoader().getWraps().get(wrapUuid); 52 | switch (action) { 53 | case "equipped" -> { // Check if the specified wrap is the one equipped on the item the player is wrapping in the virtual inventory 54 | if (player == null) { 55 | return null; 56 | } 57 | var equipped = plugin.getWrapGui().get(player.getUniqueId()); 58 | return wrapUuid.equals(equipped) ? 59 | StringUtil.LEGACY_SERIALIZER.serialize(StringUtil.parseComponent(player, plugin.getMessageHandler().get(Messages.PLACEHOLDER_EQUIPPED))) 60 | : StringUtil.LEGACY_SERIALIZER.serialize(StringUtil.parseComponent(player, plugin.getMessageHandler().get(Messages.PLACEHOLDER_NOT_EQUIPPED))); 61 | } 62 | case "modelid" -> { 63 | if (wrap == null) { 64 | return null; 65 | } 66 | return String.valueOf(wrap.getModelId()); 67 | } 68 | case "color" -> { 69 | if (wrap == null || wrap.getColor() == null) { 70 | return null; 71 | } 72 | return ColorUtil.colorToHex(wrap.getColor()); 73 | } 74 | case "type" -> { 75 | return plugin.getWrapsLoader().getTypeWraps().entrySet().stream().filter(it -> it.getValue().contains(wrapUuid)) 76 | .findFirst().map(Map.Entry::getKey).orElse(null); 77 | } 78 | } 79 | } 80 | return null; 81 | } 82 | 83 | } 84 | -------------------------------------------------------------------------------- /src/main/java/de/skyslycer/hmcwraps/pool/MessagePool.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.pool; 2 | 3 | import net.kyori.adventure.text.Component; 4 | 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | import java.util.UUID; 8 | 9 | public class MessagePool implements ObjectPool<UUID, Component> { 10 | 11 | private static final int COOLDOWN = 1000; 12 | 13 | private final Map<UUID, MessagePoolEntry> pool = new HashMap<>(); 14 | 15 | @Override 16 | public void insert(UUID key, Component value) { 17 | pool.put(key, new MessagePoolEntry(value, System.currentTimeMillis())); 18 | } 19 | 20 | @Override 21 | public void remove(UUID key) { 22 | pool.remove(key); 23 | } 24 | 25 | @Override 26 | public void execute(UUID key, Component value, PoolMethod consumer) { 27 | if (pool.containsKey(key) && pool.get(key).message().equals(value) && (System.currentTimeMillis() - pool.get(key).time() < COOLDOWN)) { 28 | return; 29 | } 30 | consumer.execute(); 31 | insert(key, value); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/de/skyslycer/hmcwraps/pool/MessagePoolEntry.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.pool; 2 | 3 | import net.kyori.adventure.text.Component; 4 | 5 | public record MessagePoolEntry(Component message, long time) { 6 | } 7 | -------------------------------------------------------------------------------- /src/main/java/de/skyslycer/hmcwraps/serialization/debug/DebugConfig.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.serialization.debug; 2 | 3 | import de.skyslycer.hmcwraps.serialization.Config; 4 | 5 | public class DebugConfig extends Config implements Debuggable { 6 | 7 | public DebugConfig(Config config) { 8 | super(config.getUpdater(), config.getPermissions(), config.getPreview(), config.getFavorites(), config.getInventory(), config.getUnwrapper(), 9 | config.getPreservation(), null, null, config.getFilter(), config.getWrapping()); 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/de/skyslycer/hmcwraps/serialization/debug/DebugInformation.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.serialization.debug; 2 | 3 | public class DebugInformation implements Debuggable { 4 | 5 | private final String version; 6 | private final String latestVersion; 7 | private final String protocolLibVersion; 8 | private final String serverVersion; 9 | private final String serverSoftware; 10 | private final String iaVersion; 11 | private final String oraxenVersion; 12 | private final String mythicMobsVersion; 13 | private final String crucibleVersion; 14 | 15 | public DebugInformation(String version, String latestVersion, String protocolLibVersion, String serverVersion, 16 | String serverSoftware, String iaVersion, String oraxenVersion, 17 | String mythicMobsVersion, String crucibleVersion) { 18 | this.version = version; 19 | this.latestVersion = latestVersion; 20 | this.protocolLibVersion = protocolLibVersion; 21 | this.serverVersion = serverVersion; 22 | this.serverSoftware = serverSoftware; 23 | this.iaVersion = iaVersion; 24 | this.oraxenVersion = oraxenVersion; 25 | this.mythicMobsVersion = mythicMobsVersion; 26 | this.crucibleVersion = crucibleVersion; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/de/skyslycer/hmcwraps/serialization/debug/DebugItemData.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.serialization.debug; 2 | 3 | import de.skyslycer.hmcwraps.serialization.wrap.Wrap; 4 | 5 | import java.util.UUID; 6 | 7 | public class DebugItemData implements Debuggable { 8 | 9 | private String material; 10 | private boolean physical; 11 | private String wrap; 12 | private UUID owningPlayer; 13 | private boolean physicalUnwrapper; 14 | private String physicalWrapper; 15 | private Wrap.WrapValues wrapValues; 16 | private int fakeDurability; 17 | private int fakeMaxDurability; 18 | private String nbt; 19 | 20 | public DebugItemData(String material, boolean physical, String wrap, UUID owningPlayer, boolean physicalUnwrapper, 21 | String physicalWrapper, Wrap.WrapValues wrapValues, int fakeDurability, int fakeMaxDurability, String nbt) { 22 | this.material = material; 23 | this.physical = physical; 24 | this.wrap = wrap; 25 | this.owningPlayer = owningPlayer; 26 | this.physicalUnwrapper = physicalUnwrapper; 27 | this.physicalWrapper = physicalWrapper; 28 | this.wrapValues = wrapValues; 29 | this.fakeDurability = fakeDurability; 30 | this.fakeMaxDurability = fakeMaxDurability; 31 | this.nbt = nbt; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/de/skyslycer/hmcwraps/serialization/debug/DebugPlayer.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.serialization.debug; 2 | 3 | import java.util.List; 4 | 5 | public class DebugPlayer implements Debuggable { 6 | 7 | private final List<String> favorites; 8 | private final boolean filter; 9 | private final DebugItemData wrapInHand; 10 | 11 | public DebugPlayer(List<String> favorites, boolean filter, DebugItemData wrapInHand) { 12 | this.favorites = favorites; 13 | this.filter = filter; 14 | this.wrapInHand = wrapInHand; 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/de/skyslycer/hmcwraps/serialization/debug/DebugWrap.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.serialization.debug; 2 | 3 | import de.skyslycer.hmcwraps.serialization.wrap.Wrap; 4 | import org.bukkit.Material; 5 | import org.spongepowered.configurate.objectmapping.ConfigSerializable; 6 | 7 | import java.util.List; 8 | 9 | @ConfigSerializable 10 | public class DebugWrap implements Debuggable { 11 | 12 | private final String collection; 13 | private final List<Material> materials; 14 | private final Wrap wrap; 15 | 16 | public DebugWrap(Wrap wrap, String collection, List<Material> materials) { 17 | this.collection = collection; 18 | this.materials = materials; 19 | this.wrap = wrap; 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/de/skyslycer/hmcwraps/serialization/debug/DebugWraps.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.serialization.debug; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | public class DebugWraps implements Debuggable { 7 | 8 | private final Map<String, List<String>> collections; 9 | private final Map<String, String> wraps; 10 | 11 | public DebugWraps(Map<String, List<String>> collections, Map<String, String> wraps) { 12 | this.collections = collections; 13 | this.wraps = wraps; 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/de/skyslycer/hmcwraps/serialization/debug/Debuggable.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.serialization.debug; 2 | 3 | public interface Debuggable { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/de/skyslycer/hmcwraps/storage/FavoriteWrapStorage.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.storage; 2 | 3 | import de.skyslycer.hmcwraps.HMCWrapsPlugin; 4 | import de.skyslycer.hmcwraps.serialization.wrap.Wrap; 5 | import org.bukkit.NamespacedKey; 6 | import org.bukkit.entity.Player; 7 | import org.bukkit.persistence.PersistentDataType; 8 | 9 | import java.util.ArrayList; 10 | import java.util.Arrays; 11 | import java.util.List; 12 | import java.util.stream.Collectors; 13 | 14 | public class FavoriteWrapStorage implements Storage<Player, List<Wrap>> { 15 | 16 | private static final String SEPARATOR = ";!;"; 17 | 18 | private final NamespacedKey key; 19 | private final HMCWrapsPlugin plugin; 20 | 21 | public FavoriteWrapStorage(HMCWrapsPlugin plugin) { 22 | this.key = new NamespacedKey(plugin, "favorites"); 23 | this.plugin = plugin; 24 | } 25 | 26 | @Override 27 | public List<Wrap> get(Player source) { 28 | var pdc = source.getPersistentDataContainer().get(key, PersistentDataType.STRING); 29 | if (pdc == null) { 30 | return new ArrayList<>(); 31 | } 32 | return Arrays.stream(pdc.split(SEPARATOR)) 33 | .filter(uuid -> plugin.getWrapsLoader().getWraps().containsKey(uuid)).map(uuid -> plugin.getWrapsLoader().getWraps().get(uuid)).collect(Collectors.toList()); 34 | } 35 | 36 | @Override 37 | public void set(Player source, List<Wrap> value) { 38 | var newValue = String.join(SEPARATOR, value.stream().map(Wrap::getUuid).toList()); 39 | source.getPersistentDataContainer().set(key, PersistentDataType.STRING, newValue); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/de/skyslycer/hmcwraps/storage/PlayerFilterStorage.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.storage; 2 | 3 | import de.skyslycer.hmcwraps.HMCWrapsPlugin; 4 | import org.bukkit.NamespacedKey; 5 | import org.bukkit.entity.Player; 6 | import org.bukkit.persistence.PersistentDataType; 7 | 8 | public class PlayerFilterStorage implements Storage<Player, Boolean> { 9 | 10 | private final NamespacedKey key; 11 | private final HMCWrapsPlugin plugin; 12 | 13 | public PlayerFilterStorage(HMCWrapsPlugin plugin) { 14 | this.key = new NamespacedKey(plugin, "filterEnabled"); 15 | this.plugin = plugin; 16 | } 17 | 18 | 19 | @Override 20 | public Boolean get(Player source) { 21 | if (!plugin.getConfiguration().getFilter().isEnabled()) { 22 | return false; 23 | } 24 | var pdc = source.getPersistentDataContainer().get(key, PersistentDataType.BYTE); 25 | if (pdc == null) { 26 | return plugin.getConfiguration().getFilter().getDefault(); 27 | } 28 | return pdc == 1; 29 | } 30 | 31 | @Override 32 | public void set(Player source, Boolean value) { 33 | source.getPersistentDataContainer().set(key, PersistentDataType.BYTE, value ? (byte) 1 : (byte) 0); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/de/skyslycer/hmcwraps/transformation/ConfigFileTransformations.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.transformation; 2 | 3 | import java.io.IOException; 4 | import java.nio.file.Files; 5 | import java.nio.file.Path; 6 | 7 | public class ConfigFileTransformations extends FileTransformations { 8 | 9 | public ConfigFileTransformations() { 10 | setLatest(1); 11 | addUpdateMethod(0, this::zeroToOne); 12 | } 13 | 14 | private void zeroToOne(Path path) throws IOException { 15 | var config = Files.readString(path); 16 | config = config.replace(" nbt: ", " wrap-nbt: "); 17 | config = config.replace("permission-settings:", "permissions:"); 18 | config = config + "\nconfig: 1"; 19 | Files.writeString(path, config); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/de/skyslycer/hmcwraps/transformation/FileTransformations.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.transformation; 2 | 3 | import org.bukkit.Bukkit; 4 | 5 | import java.io.IOException; 6 | import java.nio.file.Files; 7 | import java.nio.file.Path; 8 | import java.util.HashMap; 9 | import java.util.Map; 10 | import java.util.regex.Pattern; 11 | 12 | public class FileTransformations { 13 | 14 | private static final Pattern VERSION_PATTERN = Pattern.compile("config: (?<ver>\\d)"); 15 | 16 | private int latest = -1; 17 | private final Map<Integer, UpdateMethod> updateMethods = new HashMap<>(); 18 | 19 | @FunctionalInterface 20 | protected interface UpdateMethod { 21 | void update(Path path) throws IOException; 22 | } 23 | 24 | private int getConfigVersion(Path path) throws IOException { 25 | var config = Files.readString(path); 26 | var matcher = VERSION_PATTERN.matcher(config); 27 | if (matcher.find()) { 28 | return Integer.parseInt(matcher.group("ver")); 29 | } else { 30 | return 0; 31 | } 32 | } 33 | 34 | public void updateToLatest(Path path) throws IOException { 35 | var currentVersion = getConfigVersion(path); 36 | while (currentVersion < latest) { 37 | var method = updateMethods.get(currentVersion); 38 | if (method != null) { 39 | method.update(path); 40 | currentVersion = getConfigVersion(path); 41 | } else { 42 | Bukkit.getLogger().severe("Could not find update method for config version " + currentVersion + "! Please report this to the developers!"); 43 | } 44 | } 45 | } 46 | 47 | protected void addUpdateMethod(int version, UpdateMethod method) { 48 | updateMethods.put(version, method); 49 | } 50 | 51 | protected void setLatest(int latest) { 52 | this.latest = latest; 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/de/skyslycer/hmcwraps/transformation/WrapFileTransformations.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.transformation; 2 | 3 | import java.io.IOException; 4 | import java.nio.file.Files; 5 | import java.nio.file.Path; 6 | 7 | public class WrapFileTransformations extends FileTransformations { 8 | 9 | public WrapFileTransformations() { 10 | setLatest(1); 11 | addUpdateMethod(0, this::zeroToOne); 12 | } 13 | 14 | private void zeroToOne(Path path) throws IOException { 15 | var config = Files.readString(path); 16 | config = config.replace(" nbt: ", " wrap-nbt: "); 17 | config = config + "\nconfig: 1"; 18 | Files.writeString(path, config); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/de/skyslycer/hmcwraps/updater/ContinuousUpdateChecker.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.updater; 2 | 3 | import com.tcoded.folialib.wrapper.task.WrappedTask; 4 | import de.skyslycer.hmcwraps.HMCWrapsPlugin; 5 | import de.skyslycer.hmcwraps.util.StringUtil; 6 | import org.bukkit.Bukkit; 7 | import org.bukkit.entity.Player; 8 | 9 | public class ContinuousUpdateChecker { 10 | 11 | private static final int SPIGOT_ID = 107099; 12 | private static final int POLYMART_ID = 3216; 13 | 14 | private final HMCWrapsPlugin plugin; 15 | 16 | private PluginUpdater updater; 17 | private long lastResultTime = 0; 18 | private CheckResult lastResult; 19 | private WrappedTask task; 20 | 21 | public ContinuousUpdateChecker(HMCWrapsPlugin plugin) { 22 | this.plugin = plugin; 23 | } 24 | 25 | public void check() { 26 | resetUpdater(); 27 | if (task != null) { 28 | task.cancel(); 29 | } 30 | task = plugin.getFoliaLib().getScheduler().runTimerAsync(() -> { 31 | var result = updater.check(plugin); 32 | lastResultTime = System.currentTimeMillis(); 33 | lastResult = result; 34 | if (result != null && !result.latest()) { 35 | plugin.getLogger().warning(String.format( 36 | """ 37 | 38 | ++++++++++++++++++++++++++++++ 39 | + There is a new update for HMCWraps available! 40 | + Please download it as soon as possible for possible fixes and new features. 41 | + Current version: %s | Latest version: %s 42 | + SpigotMC: %s 43 | + Polymart: %s 44 | ++++++++++++++++++++++++++++++""", 45 | plugin.getDescription().getVersion(), result.version(), 46 | String.format(PluginPlatform.SPIGOT_MC.url(), SPIGOT_ID), String.format(PluginPlatform.POLYMART.url(), POLYMART_ID))); 47 | Bukkit.getOnlinePlayers().forEach(player -> checkPlayer(player, result)); 48 | } 49 | }, 20, StringUtil.shortTimeToSeconds(plugin.getConfiguration().getUpdater().getFrequency(), 50 | 60 * 5, 60 * 60 * 3) * 20); // 5 minutes minimum, 3 hours default 51 | } 52 | 53 | private void resetUpdater() { 54 | if (plugin.getConfiguration().getUpdater().getPlatform() == PluginPlatform.SPIGOT_MC) { 55 | updater = new SpigotPluginUpdater(SPIGOT_ID); 56 | } else if (plugin.getConfiguration().getUpdater().getPlatform() == PluginPlatform.POLYMART) { 57 | updater = new PolymartPluginUpdater(POLYMART_ID); 58 | } 59 | } 60 | 61 | public void checkPlayer(Player player) { 62 | checkPlayer(player, null); 63 | } 64 | 65 | private void checkPlayer(Player player, CheckResult defaultResult) { 66 | if ((!player.isOp() && !player.hasPermission("*")) || !plugin.getConfiguration().getUpdater().isEnabled()) { 67 | return; 68 | } 69 | CheckResult result; 70 | if (defaultResult != null) { 71 | result = defaultResult; 72 | } else { 73 | result = getLatest(); 74 | } 75 | if (result == null || result.latest()) { 76 | return; 77 | } 78 | var component = StringUtil.parseComponent(player, String.format( 79 | """ 80 | 81 | <gray>There is a new version of <green><bold>HMCWraps</bold></green> available! 82 | <gray>Current version: <red>%s</red> | Latest version: <green>%s</green> 83 | <gray>Download it on <gold><hover:show_text:"<blue>Click to open!"><click:open_url:%s>SpigotMC</gold> or <gold><hover:show_text:"<blue>Click to open!"><click:open_url:%s>Polymart</gold>! 84 | """, plugin.getDescription().getVersion(), result.version(), 85 | String.format(PluginPlatform.SPIGOT_MC.url(), SPIGOT_ID), String.format(PluginPlatform.POLYMART.url(), POLYMART_ID))); 86 | StringUtil.sendComponent(player, component); 87 | } 88 | 89 | public CheckResult getLatest() { 90 | if (System.currentTimeMillis() - lastResultTime < 1000 * 60 * 10 && lastResult != null) { 91 | return lastResult; 92 | } else { 93 | return updater.check(plugin); 94 | } 95 | } 96 | 97 | } 98 | -------------------------------------------------------------------------------- /src/main/java/de/skyslycer/hmcwraps/updater/PolymartPluginUpdater.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.updater; 2 | 3 | public class PolymartPluginUpdater extends PluginUpdater { 4 | 5 | /** 6 | * Create a new Polymart plugin updater. 7 | * 8 | * @param pluginId The plugin id 9 | */ 10 | public PolymartPluginUpdater(int pluginId) { 11 | super(pluginId, PluginPlatform.POLYMART); 12 | } 13 | 14 | @Override 15 | public String parse(String body) { 16 | return body; 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/de/skyslycer/hmcwraps/updater/SpigotPluginUpdater.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.updater; 2 | 3 | import com.google.gson.Gson; 4 | import com.google.gson.GsonBuilder; 5 | import com.google.gson.JsonObject; 6 | 7 | public class SpigotPluginUpdater extends PluginUpdater { 8 | 9 | private static final Gson GSON = new GsonBuilder().create(); 10 | 11 | /** 12 | * Create a new Spigot plugin updater. 13 | * 14 | * @param pluginId The plugin id 15 | */ 16 | public SpigotPluginUpdater(int pluginId) { 17 | super(pluginId, PluginPlatform.SPIGOT_MC); 18 | } 19 | 20 | @Override 21 | public String parse(String body) { 22 | var object = GSON.fromJson(body, JsonObject.class); 23 | return object.getAsJsonPrimitive("name").getAsString(); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/de/skyslycer/hmcwraps/wrap/CollectionHelperImpl.java: -------------------------------------------------------------------------------- 1 | package de.skyslycer.hmcwraps.wrap; 2 | 3 | import de.skyslycer.hmcwraps.HMCWrapsPlugin; 4 | import de.skyslycer.hmcwraps.serialization.wrap.Wrap; 5 | import org.bukkit.Material; 6 | 7 | import java.util.*; 8 | 9 | public class CollectionHelperImpl implements CollectionHelper { 10 | 11 | private final HMCWrapsPlugin plugin; 12 | 13 | public CollectionHelperImpl(HMCWrapsPlugin plugin) { 14 | this.plugin = plugin; 15 | } 16 | 17 | @Override 18 | public List<Wrap> getItems(Material material) { 19 | var list = new HashSet<String>(); 20 | if (plugin.getWrapsLoader().getTypeWraps().containsKey(material.toString())) { 21 | list.addAll(plugin.getWrapsLoader().getTypeWraps().get(material.toString())); 22 | } 23 | plugin.getWrapsLoader().getCollections().entrySet().stream().filter(items -> items.getValue().contains(material.toString())).forEach(it -> { 24 | if (plugin.getWrapsLoader().getTypeWraps().containsKey(it.getKey())) { 25 | list.addAll(plugin.getWrapsLoader().getTypeWraps().get(it.getKey())); 26 | } 27 | }); 28 | return list.stream().map(plugin.getWrapsLoader().getWraps()::get).filter(Objects::nonNull).toList(); 29 | } 30 | 31 | @Override 32 | public List<Material> getMaterials(String collection) { 33 | if (!plugin.getWrapsLoader().getCollections().containsKey(collection)) { 34 | if (Material.getMaterial(collection) != null) { 35 | return List.of(Material.getMaterial(collection)); 36 | } else { 37 | return List.of(); 38 | } 39 | } 40 | var list = new ArrayList<Material>(); 41 | for (String materialName : plugin.getWrapsLoader().getCollections().get(collection)) { 42 | if (Material.getMaterial(materialName) != null) { 43 | list.add(Material.getMaterial(materialName)); 44 | } 45 | } 46 | return list; 47 | } 48 | 49 | @Override 50 | public Material getMaterial(Wrap wrap) { 51 | var currentCollection = getCollection(wrap); 52 | var itemMaterial = Material.AIR; 53 | if (Material.getMaterial(currentCollection) != null) { 54 | itemMaterial = Material.getMaterial(currentCollection); 55 | } else if (plugin.getCollectionHelper().getMaterials(currentCollection).stream().findFirst().isPresent()) { 56 | itemMaterial = plugin.getCollectionHelper().getMaterials(currentCollection).stream().findFirst().get(); 57 | } else { 58 | return null; 59 | } 60 | return itemMaterial; 61 | } 62 | 63 | @Override 64 | public String getCollection(Wrap wrap) { 65 | return plugin.getWrapsLoader().getTypeWraps().entrySet().stream().filter(it -> it.getValue().contains(wrap.getUuid())) 66 | .findFirst().map(Map.Entry::getKey).orElse(null); 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /src/main/resources/emerald_wraps.yml: -------------------------------------------------------------------------------- 1 | # Wrap files are YAML files which are stored in plugins/HMCWraps/wraps/ and contain wraps for easy drag & drop 2 | # operations. These can be nested up to 10 folders deep, so you can sort them by folder too. 3 | # The file name doesn't matter, the plugin loads everything in the above-mentioned folder. 4 | 5 | # If this particular file is enabled 6 | enabled: true 7 | # All the wraps in this file 8 | # The configuration is exactly the same as in config.yml 9 | items: 10 | DIAMOND_SWORD: 11 | wraps: 12 | 1: 13 | permission: 'hmcwraps.emerald_sword' 14 | uuid: 'emerald_sword' 15 | id: '3' 16 | name: '<green>Emerald <gray>Wrap' 17 | lore: 18 | - '<gray>Apply this wrap to make your sword look emerald!' 19 | flags: 20 | - 'HIDE_ATTRIBUTES' 21 | DIAMOND_PICKAXE: 22 | wraps: 23 | 1: 24 | permission: 'hmcwraps.emerald_pickaxe' 25 | uuid: 'emerald_pickaxe' 26 | id: '3' 27 | name: '<green>Emerald <gray>Wrap' 28 | lore: 29 | - '<gray>Apply this wrap to make your pickaxe look emerald!' 30 | flags: 31 | - 'HIDE_ATTRIBUTES' 32 | DIAMOND_AXE: 33 | wraps: 34 | 1: 35 | permission: 'hmcwraps.emerald_axe' 36 | uuid: 'emerald_axe' 37 | id: '2' 38 | name: '<green>Emerald <gray>Wrap' 39 | lore: 40 | - '<gray>Apply this wrap to make your axe look emerald!' 41 | flags: 42 | - 'HIDE_ATTRIBUTES' 43 | DIAMOND_SHOVEL: 44 | wraps: 45 | 1: 46 | permission: 'hmcwraps.emerald_shovel' 47 | uuid: 'emerald_shovel' 48 | id: '2' 49 | name: '<green>Emerald <gray>Wrap' 50 | lore: 51 | - '<gray>Apply this wrap to make your shovel look emerald!' 52 | flags: 53 | - 'HIDE_ATTRIBUTES' 54 | DIAMOND_HOE: 55 | wraps: 56 | 1: 57 | permission: 'hmcwraps.emerald_hoe' 58 | uuid: 'emerald_hoe' 59 | id: '2' 60 | name: '<green>Emerald <gray>Wrap' 61 | lore: 62 | - '<gray>Apply this wrap to make your hoe look emerald!' 63 | flags: 64 | - 'HIDE_ATTRIBUTES' 65 | 66 | # DON'T TOUCH THIS 67 | config: 1 68 | # DON'T TOUCH THIS -------------------------------------------------------------------------------- /src/main/resources/messages.properties: -------------------------------------------------------------------------------- 1 | no-permission=<red>Insufficient permission! 2 | no-permission-for-wrap=<red>You don't have permission to use this wrap! 3 | apply-wrap=<gray>Successfully <green>applied <gray>the wrap to the item! 4 | remove-wrap=<gray>Successfully <red>removed <gray>your current wrap! 5 | no-item=<red>You need to have an item in your main hand! 6 | no-wraps=<red>There are no wraps for this item! 7 | no-rewrap=<red>You have to unwrap this item before you can wrap it! 8 | preview.disabled=<red>You can't preview this wrap! 9 | preview.bar=<green>Press <key:key.sneak> to cancel the preview 10 | favorites.set=<gray>You have successfully <green>set <gray>your favorite wrap! 11 | favorites.clear=<gray>You have successfully <green>cleared <gray>your favorite wrap! 12 | armor-imitation.forbidden-inventory=<red>You can't use this with a wrapped item! Please unwrap it first. 13 | inventory.filter.active=<gray>Filtering <green>enabled! 14 | inventory.filter.inactive=<gray>Filtering <red>disabled! 15 | command.missing-argument=<red>You have to specify the <argument>! 16 | command.invalid-wrap=<red><uuid> <gray>is not a valid wrap UUID! 17 | command.invalid-physical=<red><uuid> <gray>doesn't have a valid physical item configured! 18 | command.given-physical=<gray>Successfully gave the <green><uuid> wrap! 19 | command.given-unwrapper=<gray>Successfully gave the <green>unwrapper! 20 | command.reload=<green>Successfully reloaded <gray>the plugin in <green><time>ms! \n<gray>(Loaded <green><wraps> wraps <gray>and <green><collections> collections<gray>) 21 | command.player-only=<red>You have to be a player to execute this command! 22 | command.need-item=<red>The player has to have an item in their main hand! 23 | command.item-not-for-wrap=<red>The wrap you have chosen does not apply to the one the player is holding! 24 | command.item-not-wrapped=<red>The item the player is holding is not wrapped! 25 | command.wrap.wrapped=<gray>Successfully <green>wrapped <gray>the <green>item! 26 | command.unwrap.unwrapped=<gray>Successfully <red>unwrapped <gray>the <green>item! 27 | command.no-matching-item=<red>There is no item applicable to this wrap! 28 | command.preview-created=<gray>Successfully <green>created <gray>the <green>preview! 29 | command.help.header=<gray>=======\> <green>HMCWraps commands <gray>\<======= 30 | command.help.format=<green>/<command> <red><usage> <gray>- <description> 31 | command.help.no-permission=<red>There are no commands available at your permission level. 32 | command.list.header=<gray>=======\> <green>HMCWraps wraps <gray>\<======= 33 | command.list.collections=<green>Collections: 34 | command.list.wraps=<green>Wraps: 35 | command.list.key-format=<gray> <value>: 36 | command.list.collections-format=<gray> - <green><value> 37 | command.list.wraps-format=<gray> <hover:show_text:"<gray>Permission: <green><permission>\n<gray>Model ID: <green><modelid>\n<gray>Click to apply to current item">- <click:run_command:/wraps preview <player> <value>><green><value> 38 | command.list.permission=<gray>Permission: <green><permission> 39 | command.list.custom-model-id=<gray>Model ID: <green><modelid> 40 | command.convert.success=<gray>Successfully <green>converted <gray>all <green>ItemSkins files! <gray>The new files are located in <green>wraps/generated/ <gray>and <green>collections/generated/! 41 | command.convert.confirm=<gray>In order to <green>confirm <gray>this action, please run <green>/wraps convert confirm. <gray>NOTE: <red>This should be safe, but please have a backup of your files! 42 | command.convert.no-confirm=<red>You currently don't have anything to confirm! <gray>In order to start the process, run <red>/wraps convert. 43 | command.convert.failed=<red>Some or all files failed to convert! <gray>Please <red>check <gray>the console for more information, <red>delete <gray>the folders <red>wraps/generated/ <gray>and <red>collections/generated/, and <red>try again! 44 | command.create.failed=<red>An error occurred while generating the wrap file! Please report the error in the console to the developers. 45 | command.create.success=<gray>Successfully <green>created <gray>the <green>wrap <gray>file! You can find it at: <green><path>! <gray>Type <green>/wraps reload <gray>once you want the new wrap to be loaded. 46 | command.open=<gray>Successfully <green>opened <gray>the wraps inventory for <green><player>! 47 | placeholder.equipped=<green>Equipped 48 | placeholder.not-equipped=<red>Not equipped -------------------------------------------------------------------------------- /src/main/resources/silver_wraps.yml: -------------------------------------------------------------------------------- 1 | # Wrap files are YAML files which are stored in plugins/HMCWraps/wraps/ and contain wraps for easy drag & drop 2 | # operations. These can be nested up to 10 folders deep, so you can sort them by folder too. 3 | # The file name doesn't matter, the plugin loads everything in the above-mentioned folder. 4 | 5 | # If this particular file is enabled 6 | enabled: true 7 | # All the wraps in this file 8 | # The configuration is exactly the same as in config.yml 9 | items: 10 | IRON_SWORD: 11 | wraps: 12 | 1: 13 | permission: 'hmcwraps.silver_sword' 14 | uuid: 'silver_sword' 15 | id: '2' 16 | name: '<aqua>Silver <gray>Wrap' 17 | lore: 18 | - '<gray>Apply this wrap to make your sword look silver!' 19 | flags: 20 | - 'HIDE_ATTRIBUTES' 21 | IRON_PICKAXE: 22 | wraps: 23 | 1: 24 | permission: 'hmcwraps.silver_pickaxe' 25 | uuid: 'silver_pickaxe' 26 | id: '2' 27 | name: '<aqua>Silver <gray>Wrap' 28 | lore: 29 | - '<gray>Apply this wrap to make your pickaxe look silver!' 30 | flags: 31 | - 'HIDE_ATTRIBUTES' 32 | IRON_AXE: 33 | wraps: 34 | 1: 35 | permission: 'hmcwraps.silver_axe' 36 | uuid: 'silver_axe' 37 | id: '1' 38 | name: '<aqua>Silver <gray>Wrap' 39 | lore: 40 | - '<gray>Apply this wrap to make your axe look silver!' 41 | flags: 42 | - 'HIDE_ATTRIBUTES' 43 | IRON_SHOVEL: 44 | wraps: 45 | 1: 46 | permission: 'hmcwraps.silver_shovel' 47 | uuid: 'silver_shovel' 48 | id: '1' 49 | name: '<aqua>Silver <gray>Wrap' 50 | lore: 51 | - '<gray>Apply this wrap to make your shovel look silver!' 52 | flags: 53 | - 'HIDE_ATTRIBUTES' 54 | IRON_HOE: 55 | wraps: 56 | 1: 57 | permission: 'hmcwraps.silver_hoe' 58 | uuid: 'silver_hoe' 59 | id: '1' 60 | name: '<aqua>Silver <gray>Wrap' 61 | lore: 62 | - '<gray>Apply this wrap to make your hoe look silver!' 63 | flags: 64 | - 'HIDE_ATTRIBUTES' 65 | 66 | # DON'T TOUCH THIS 67 | config: 1 68 | # DON'T TOUCH THIS -------------------------------------------------------------------------------- /src/main/resources/some_collections.yml: -------------------------------------------------------------------------------- 1 | # If this collections file should be enabled 2 | enabled: true 3 | 4 | # The collections 5 | collections: 6 | # This is just an example collection, it isn't being used yet 7 | SOME_RANDOM_COLLECTION: 8 | - 'DIAMOND_CHESTPLATE' --------------------------------------------------------------------------------