{"id":19468168,"url":"https://github.com/multipaper/multilib","last_synced_at":"2026-02-19T12:02:56.221Z","repository":{"id":104159759,"uuid":"436586423","full_name":"MultiPaper/MultiLib","owner":"MultiPaper","description":"Plugin Library for interfacing with MultiPaper Specific API's with graceful fallback that maintains Spigot Compatibility, such as External Player Detection.","archived":false,"fork":false,"pushed_at":"2024-08-24T04:27:59.000Z","size":83,"stargazers_count":30,"open_issues_count":0,"forks_count":7,"subscribers_count":3,"default_branch":"main","last_synced_at":"2024-08-24T05:30:26.467Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/MultiPaper.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-12-09T11:10:46.000Z","updated_at":"2024-08-24T04:28:02.000Z","dependencies_parsed_at":null,"dependency_job_id":"1c3721e7-e067-4357-8fd6-f488f4b8d652","html_url":"https://github.com/MultiPaper/MultiLib","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MultiPaper%2FMultiLib","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MultiPaper%2FMultiLib/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MultiPaper%2FMultiLib/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MultiPaper%2FMultiLib/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/MultiPaper","download_url":"https://codeload.github.com/MultiPaper/MultiLib/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223999567,"owners_count":17238973,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-10T18:38:58.504Z","updated_at":"2026-02-19T12:02:56.214Z","avatar_url":"https://github.com/MultiPaper.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# MultiLib\nMultiLib is a plugin library for interfacing with MultiPaper specific APIs (such as external player detection), with graceful fallbacks maintaining compatibility with both the Bukkit and Spigot API's.\n\n## API\nAll API calls can be found as static util methods in the `MultiLib` class.\n\n### Chunks\n```java\nboolean isChunkExternal(World world, int cx, int cz);\nboolean isChunkExternal(Location location);\nboolean isChunkExternal(Entity entity);\nboolean isChunkExternal(Block block);\nboolean isChunkExternal(Chunk chunk);\nboolean isChunkLocal(World world, int cx, int cz);\nboolean isChunkLocal(Location location);\nboolean isChunkLocal(Entity entity);\nboolean isChunkLocal(Block block);\nboolean isChunkLocal(Chunk chunk);\n```\nOn MultiPaper, an external chunk is one being ticked on an external server, with this server simply containing a copy of the chunk.\nOn Bukkit, all chunks are local.\n\n### Players\n```java\nboolean isExternalPlayer(Player player);\nboolean isLocalPlayer(Player player);\nString getExternalServerName(Player player);\nString getLocalServerName();\n```\nOn MultiPaper, an external player is a player connected to another server.\nEven if the player is an external player, it may still be in local chunks.\nThe same can be said for local players, they can be in external chunks.\nOn Bukkit, all players are local, and the server's local name will always be\n\"bukkit\".\n\n```java\n@Nullable String getExternalServerName(Player player);\n```\nOn MultiPaper, an external player will return the name of the server that the\nplayer is on. A local player has no external server, and will return null.\nOn Bukkit, all players are local, and will always return null.\n\n```java\nCollection\u003c? extends Player\u003e getAllOnlinePlayers();\nCollection\u003c? extends Player\u003e getLocalOnlinePlayers();\n```\nOn MultiPaper, all online players will return all players across all MultiPaper\ninstances. Local online players will return the players on your single local\nMultiPaper instance.\nOn Bukkit, both these methods return the same collection of players.\n\n### Sharing data\n```java\nString getData(Player player, String key);\nvoid setData(Player player, String key, String value);\nString getPersistentData(Player player, String key);\nvoid setPersistentData(Player player, String key, String value);\n```\nOn MultiPaper, data stored with these methods will be available on all servers.\nPersistent data will be saved to the disk while non-persistent data will be lost when the player disconnects.\nOn Bukkit, this data will only be available on the one server, and persistent data will be stored in a yaml file under `multilib-data`.\n\n### Notifying other servers\n```java\nvoid on(Plugin plugin, String channel, Consumer\u003cbyte[]\u003e callback);\nvoid onString(Plugin plugin, String channel, Consumer\u003cString\u003e callback);\nvoid on(Plugin plugin, String channel, BiConsumer\u003cbyte[], BiConsumer\u003cString, byte[]\u003e\u003e callbackWithReply);\nvoid onString(Plugin plugin, String channel, BiConsumer\u003cString, BiConsumer\u003cString, String\u003e\u003e callbackWithReply);\nvoid notify(String channel, byte[] data);\nvoid notify(String channel, String data);\nvoid notify(Chunk chunk, String channel, byte[] data);\nvoid notify(Chunk chunk, String channel, String data);\n```\nOn MultiPaper, plugins running on other servers can be notified with a data payload.\nYou can also notify only certain server with a specified chunk loaded.\nOn Bukkit, these methods will do nothing as there are no other servers.\n\n### Running commands on other servers\n```java\nvoid chatOnOtherServers(Player player, String message);\n```\nOn MultiPaper, the specified player will say a chat message (or run a command)\non all other servers. On Bukkit, this method will do nothing as there are no\nother servers.\n\n### Simple key-value data storage\n```java\nMultiLib.getDataStorage();\nCompletableFuture\u003cString\u003e get(String key);\nCompletableFuture\u003cMap\u003cString, String\u003e\u003e list(String keyPrefix);\nCompletableFuture\u003cString\u003e set(String key, String value);\nCompletableFuture\u003cInteger\u003e add(String key, int increment);\nCompletableFuture\u003cDouble\u003e add(String key, double increment);\nMultiLib.getDataStorage().createCache(Plugin plugin, String keyPrefix);\n```\nAn async key-value data storage. This should not be used for large data as the\nbacking database is in-memory and utilises an inefficient file storage format.\nAdding is an atomic operation. Any changes on one server will instantly be\nreflected across all other servers.\n\n### ShreddedPaper / Folia methods\n```java\nRegionizedScheduler getRegionScheduler();\nEntityScheduler getEntityScheduler(Entity entity);\nboolean isOwnedByCurrentRegion(Location location);\nboolean isOwnedByCurrentRegion(Entity entity);\nCompletableFuture\u003cChunk\u003e getChunkAtAsync(Location location);\nCompletableFuture\u003cBoolean\u003e teleportAsync(Entity entity, Location location, PlayerTeleportEvent.TeleportCause cause);\n```\n\n## Example Plugin\n\n```java\nimport com.github.puregero.multilib.MultiLib;\n\npublic class MyPlugin extends JavaPlugin {\n    public void onEnable() {\n        MultiLib.onString(this, \"myplugin:testchannel\", (data, reply) -\u003e {\n            getLogger().info(\"Received \" + data);\n            reply.accept(\"myplugin:testchannelreply\", \"Replying to \" + data);\n        });\n\n        MultiLib.onString(this, \"myplugin:testchannelreply\", data -\u003e {\n            getLogger().info(\"Received the reply \" + data);\n        });\n\n        MultiLib.notify(\"myplugin:testchannel\", \"Hello!\");\n    }\n\n    public void doSomething(Player player) {\n        if (MultiLib.isExternalPlayer(player)) {\n            getLogger().info(\"Not our player! Let's not actually do this!\");\n        } else {\n            actuallyDoTheSomething(player);\n        }\n    }\n}\n```\n\n## Build Script Setup\nAdd the Clojars repository and the MultiLib dependency, then shade and relocate it to your own package.\nRelocation helps avoid version conflicts with other plugins using MultiLib. \n\n### Gradle\n\nRepo:\n```groovy\nrepositories {\n  maven {\n    url \"https://repo.clojars.org/\"\n  }\n}\n```\n\nDependency:\n```groovy\ndependencies {\n    implementation \"com.github.puregero:multilib:1.2.5\"\n}\n```\n\nShadow Jar and Relocate (Groovy Syntax):\n```groovy\nplugins {\n  id \"com.gradleup.shadow\" version \"8.3.5\"\n  // Make sure to always use the latest version (https://plugins.gradle.org/plugin/com.gradleup.shadow)\n}\nshadowJar {\n   relocate \"com.github.puregero.multilib\", \"[YOUR PLUGIN PACKAGE].multilib\"\n}\n```\n\n### Maven\nRepo:\n```xml\n\u003crepositories\u003e\n    \u003crepository\u003e\n        \u003cid\u003eclojars\u003c/id\u003e\n        \u003curl\u003ehttps://repo.clojars.org\u003c/url\u003e\n    \u003c/repository\u003e\n\u003c/repositories\u003e\n```\nDependency:\n```xml\n\u003cdependencies\u003e\n    \u003cdependency\u003e\n        \u003cgroupId\u003ecom.github.puregero\u003c/groupId\u003e\n        \u003cartifactId\u003emultilib\u003c/artifactId\u003e\n        \u003cversion\u003e1.2.5\u003c/version\u003e\n        \u003cscope\u003ecompile\u003c/scope\u003e\n     \u003c/dependency\u003e\n \u003c/dependencies\u003e\n ```\n \nShade \u0026 Relocate:\n```xml\n\u003cbuild\u003e\n    \u003cplugins\u003e\n        \u003cplugin\u003e\n            \u003cgroupId\u003eorg.apache.maven.plugins\u003c/groupId\u003e\n            \u003cartifactId\u003emaven-shade-plugin\u003c/artifactId\u003e\n            \u003cversion\u003e3.4.0\u003c/version\u003e \u003c!-- Make sure to always use the latest version (https://maven.apache.org/plugins/maven-shade-plugin/) --\u003e\n            \u003cconfiguration\u003e\n                \u003cdependencyReducedPomLocation\u003e${project.build.directory}/dependency-reduced-pom.xml\u003c/dependencyReducedPomLocation\u003e\n                \u003crelocations\u003e\n                    \u003crelocation\u003e\n                        \u003cpattern\u003ecom.github.puregero.multilib\u003c/pattern\u003e\n                        \u003cshadedPattern\u003e[YOUR PLUGIN PACKAGE].multilib\u003c/shadedPattern\u003e \u003c!-- Replace this --\u003e\n                    \u003c/relocation\u003e\n                \u003c/relocations\u003e\n            \u003c/configuration\u003e\n            \u003cexecutions\u003e\n                \u003cexecution\u003e\n                    \u003cphase\u003epackage\u003c/phase\u003e\n                    \u003cgoals\u003e\n                        \u003cgoal\u003eshade\u003c/goal\u003e\n                    \u003c/goals\u003e\n                \u003c/execution\u003e\n            \u003c/executions\u003e\n        \u003c/plugin\u003e\n    \u003c/plugins\u003e\n\u003c/build\u003e\n```\n\n## Compiling\nMultiPaper is compiled using maven:\n```\nmvn\n```\n\n## License\nMultiLib is licensed under the [MIT license](LICENSE)\n\n## PaperLib\nMultiLib is inspired by PaperMC's [PaperLib](https://github.com/PaperMC/PaperLib)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmultipaper%2Fmultilib","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmultipaper%2Fmultilib","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmultipaper%2Fmultilib/lists"}