{"id":14973042,"url":"https://github.com/kylepls/mcspring","last_synced_at":"2025-08-29T17:11:28.692Z","repository":{"id":45160267,"uuid":"202392360","full_name":"kylepls/mcspring","owner":"kylepls","description":"Add Spring Boot to any Bukkit plugin","archived":false,"fork":false,"pushed_at":"2022-02-20T23:50:34.000Z","size":36777,"stargazers_count":23,"open_issues_count":10,"forks_count":4,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-02-01T00:26:31.484Z","etag":null,"topics":["minecraft","spring","spring-boot","springframework","springframework5"],"latest_commit_sha":null,"homepage":"","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/kylepls.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}},"created_at":"2019-08-14T17:01:57.000Z","updated_at":"2025-01-05T21:26:38.000Z","dependencies_parsed_at":"2022-09-07T17:21:04.416Z","dependency_job_id":null,"html_url":"https://github.com/kylepls/mcspring","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kylepls%2Fmcspring","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kylepls%2Fmcspring/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kylepls%2Fmcspring/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kylepls%2Fmcspring/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kylepls","download_url":"https://codeload.github.com/kylepls/mcspring/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":238397234,"owners_count":19465140,"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":["minecraft","spring","spring-boot","springframework","springframework5"],"created_at":"2024-09-24T13:48:00.013Z","updated_at":"2025-02-12T01:33:21.790Z","avatar_url":"https://github.com/kylepls.png","language":"Java","readme":"# mcspring [![Build Status](https://travis-ci.org/kylepls/mcspring.svg?branch=master)](https://travis-ci.org/kylepls/mcspring) ![Maven Central](https://img.shields.io/maven-central/v/in.kyle.mcspring/mcspring-starter) [![Coverage Status](https://coveralls.io/repos/github/kylepls/mcspring/badge.svg)](https://coveralls.io/github/kylepls/mcspring)\n\nWriting Bukkit plugins is a nightmare. I often lay awake in my bed late at night unable to sleep\n because Bukkit made events an annotation but commands are created by implementing a class. \n The plugin.yml is useless and main classes that extend JavaPlugin are cluttered piles of shit. \n \n {insert your horror story/gripe here}\n  \nThese are solved problems. Spring Boot took care of this issue ages ago. \nSo how about we ditch this ridiculous programming model and hop on the Spring train.\n\n```java\n@Component\nclass Test { // We don't have to extend JavaPlugin. The plugin.yml is also generated for us.\n    \n    @Command(\"test\")\n    String playerSender(Player sender, String command) {\n        // parameters are automatically injected\n        // injects: Player, Label, String[] args (no specific order required)\n        // also injects any Spring beans such as Plugin (no specific order required)\n        return command + \" works!\";\n    }\n    \n    @Scheduled(fixedDelay = 10000)\n    void interval() { // runs every 10 seconds\n        Bukkit.broadcastMessage(\"REMEMBER TO DONATE\");\n    }\n    \n    @EventHandler\n    void onMove(PlayerMoveEvent e) { // Events automatically registered\n        getLogger().info(e.getPlayer().getName() + \" moved\");\n    }\n    \n    // sub-commands example\n    // first we define the structure of the command (how it's parsed)\n    // then we define the execution of the command (how it runs)\n    // structure `/plot tp 10 20`\n    @Command(\"plot\")\n    void plot(PluginCommand command) {\n        command.on(\"tp\", this::plotTp); // calls this method when \"tp\" is passed\n        command.otherwise(\"Usage: plot \u003ctp\u003e\"); // if no methods were called, fallback to this message\n    }\n    \n    private void tp(PluginCommand command) {\n        command.withInt(\"Parameter must be an integer\"); // parse 1 integer from the command, otherwise show the message parameter\n        command.withInt(\"Parameter must be an integer\"); // parse 1 integer from the command, otherwise show the message parameter\n        command.then(this::executeTp); // if everything is okay so far, run the executor\n        command.otherwise(\"Usage: plot tp \u003cx\u003e \u003cy\u003e\"); // if not enough args (or too many) were passed, show this message\n    }\n\n    // parameters are injected from the #with arguments\n    // injects the CommandSender, Label, and String[] args\n    // Spring beans are also injected    \n    private void executeTp(Player sender, int x, int y) {\n        // sender corresponds to the player that sent the command, the argument position doesn't matter\n        // x and y correspond to the 2 parameters that were parsed using the #withInt method\n        sender.teleportToPlot(x, y);\n    }    \n}\n```\n\n---\n\n## What's in the sauce?\n* Main plugin class is generated automatically, you don't need to interact with it.\n* The `plugin.yml` is also a thing of the past. May it rest in peace.\n* Have two plugins? Want to share a Bean or two? Go for it. It's all taken care of.\n* Commands are now registered with `@Command`. Put it anywhere and forget about it.\n* Schedulers are defined with `@Scheduler`. Another thing to schlep away somewhere.\n* `@EventHandler` now registers itself. About damn time.\n* Like money? Vault support is in the box `in.kyle.mcspring.economy.EconomyService`\n* Want my hot take on sub-command handing? We've got you covered (see the wiki)\n\n## Getting Started\nI went ahead and wrote a full tutorial series for you newcomers. Get started [here](https://github.com/kylepls/mcspring/wiki/Getting-Setup)\n\nIf you think you're too smart for the beginner tutorial; go to the \n[wiki](https://github.com/kylepls/mcspring/wiki) and piece it together.\n\nIf you're really really smart; check out the example plugins in the `mcspring-example` folder.\n\n---\n\n##### Final Notes\nThanks to https://github.com/Alan-Gomes/mcspring-boot/ for the inspiration of this project!\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkylepls%2Fmcspring","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkylepls%2Fmcspring","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkylepls%2Fmcspring/lists"}