{"id":22207758,"url":"https://github.com/teamkun/peyangpaperutils","last_synced_at":"2026-05-01T10:32:17.451Z","repository":{"id":37459402,"uuid":"476096101","full_name":"TeamKun/PeyangPaperUtils","owner":"TeamKun","description":"ぺやんぐがLabで開発してるときに作ったユーティリティとかをまとめたやつ。","archived":false,"fork":false,"pushed_at":"2024-03-24T20:31:40.000Z","size":1649,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-03-25T04:29:59.663Z","etag":null,"topics":["bukkit","java","java8","minecraft","paper","papermc","papermc-plugin","peyang","spigot"],"latest_commit_sha":null,"homepage":"https://teamkun.github.io/PeyangPaperUtils/","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/TeamKun.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":"2022-03-31T00:32:55.000Z","updated_at":"2025-01-22T05:47:45.000Z","dependencies_parsed_at":"2024-03-24T18:28:31.590Z","dependency_job_id":"204c5493-82b4-4d66-a676-9957fb4a3f51","html_url":"https://github.com/TeamKun/PeyangPaperUtils","commit_stats":null,"previous_names":[],"tags_count":27,"template":false,"template_full_name":null,"purl":"pkg:github/TeamKun/PeyangPaperUtils","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TeamKun%2FPeyangPaperUtils","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TeamKun%2FPeyangPaperUtils/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TeamKun%2FPeyangPaperUtils/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TeamKun%2FPeyangPaperUtils/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/TeamKun","download_url":"https://codeload.github.com/TeamKun/PeyangPaperUtils/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TeamKun%2FPeyangPaperUtils/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32494270,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-30T13:12:12.517Z","status":"online","status_checked_at":"2026-05-01T02:00:05.856Z","response_time":64,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["bukkit","java","java8","minecraft","paper","papermc","papermc-plugin","peyang","spigot"],"created_at":"2024-12-02T19:14:26.467Z","updated_at":"2026-05-01T10:32:17.433Z","avatar_url":"https://github.com/TeamKun.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# PeyangPaperUtils\n\nぺやんぐがLabで開発してるときに作ったユーティリティとかをまとめたやつ。\n\n## [JavaDoc](https://teamkun.github.io/PeyangPaperUtils/)\n\n---\n\n## 注意\n\n+ このライブラリを同梱するときは、**必ずパッケージのリロケート**をしてください。\n\n## 使い方\n\n1. あなたのプラグインのonEnable()に、以下を追加します：\n\n  ```java\n    PeyangPaperUtils.init(this);\n\n  ```\n\n2. あなたのプラグインのonDisable()に、以下を追加します：\n\n  ```java\n    PeyangPaperUtils.dispose();\n\n  ```\n\n---\n\n## いまあるもの\n\n---\n\n### Runner\n\nBukkitRunnableの匿名クラスでタスク作るのが面倒くさい人向けのユーティリティ。  \nまあつまり, BukkitRunnableをプラグイン指定無しで使えるってやつ。  \nあ, あと, Runner.run系のメソッドのラムダは例外を許容する。例外をキャッチするには, (大体) 第ニ引数に例外をキャッチするラムダをつっこむ。\n\n```java\n  Runner.run(() =\u003e {\n      Terminal.ofConsole().info(\"Hello, world!\");\n  });\n  \n  // 1秒毎(20チック)に実行\n  Runner.runTimer(() =\u003e {\n      Terminal.ofConsole().info(\"Hello, world!\");\n  }, 20L);\n  \n  // 1秒毎(20チック)に実行 + カウント\n  Runner.runTimer((long count) =\u003e {\n      Terminal.ofConsole().info(count + \": Hello, world!\");\n  }, 20L);\n  \n  Runner.runTimer(() =\u003e {\n      throw new IOException(\"Hello, exception!\");\n  }, (Exception exception, BukkitTask task) =\u003e {\n      Terminal.ofConsole().error(exception.getMessage());\n      task.cancel();\n  }, 20L);\n```\n\n### ターミナルシステム\n\nプレイヤとコンソールのI/Oを統一するインタフェースとユーティリティをまとめたやつ。   \n↓↓↓ターミナルを初期化↓↓↓\n\n```java\n  Player examplePlayer;\nCommandSender sender;\n  \n  Terminal terminal = Terminals.of(this.examplePlayer);\n  // or\n  Terminal terminal = Terminals.of(this.sender);\n  // or\n  Terminal terminal = Terminals.ofConsole(); \n```\n\n#### ログ出力\n\nログをめちゃくちゃ簡単に吐けるやつ..!!!\n\n```java\n  terminal.info(\"Hello World!\");  // 青色で I: Hello World! と出力\n  terminal.warn(\"Hello World!\");  // 黄色で W: Hello World! と出力\n  terminal.error(\"Hello World!\"); // 赤色で E: Hello World! と出力\n  terminal.success(\"Hello World!\"); // 緑色で S: Hello World! と出力\n  \n  terminal.writeLine(\"Hello World!\"); // Hello World! と出力\n  terminal.write(TextComponent.of(\"Hello World!\")); // Hello World! と出力 (Adventure API)\n```\n\n#### プログレスバー(いまはプレイヤのみ)\n\nプログレスバーを表示するやつ。文字通り。\n\n```java\n  ProgressBar progress = terminal.createProgressbar(\"example_progressbar\");\n  progress.setProgressMax(100);\n  progress.setPrefix(\"Progress: \");\n  progress.setSuffix(\" %\");\n  progress.show();\n  // 別スレッドで実行\n  for(\nint i;\ni\u003c 100;i++){\n      progress.setProgress(i);\n      Thread.sleep(100);\n  }\n  \n  // バリアで待機てきな? ことを? しとく??\n  \n  progress.hide();\n```\n\n### 入力システム\n\nプレイヤ/コンソールに質問を行い, 入力を受け付ける機能。  \n質問の返答は\n\n+ プレイヤ: チャット (prefix/suffixなし)\n+ コンソール: コンソール(コマンド実行する感覚)\n  で行できる。\n\n```java\n  Input input = terminal.getInput();\n\nQuestionResult result = this.input.showYNQuestion(\"Are you sure?\").waitAndGetResult();\n  if (result.test(QuestionAttribute.YES))\n      terminal.info(\"Yes, it is.\");\n  else\n      terminal.info(\"No, it isn't.\");\n  \n  result = input.showYNQuestionCancellable(\"Are you sure?\", QuestionAttribute.APPLY_FOR_ALL).waitAndGetResult();\n  if (result.test(QuestionAttribute.YES))\n      terminal.info(\"Yes, it is.\");\n  else if (result.test(QuestionAttribute.CANCEL))\n      terminal.info(\"Cancelled.\");\n  else\n      terminal.info(\"No, it isn't.\");\n  \n  if (result.test(QuestionAttribute.APPLY_FOR_ALL))\n      terminal.info(\"Applied for all.\");\n```\n\n#### 警告\n\n+ waitうんたら系は, 非同期で使ってください。下手したらメインスレッド止めてサーバ死にます。いや。マジで。\n\n### コマンドシステム\n\nコマンドとか簡単に作ったり, 引数のバリデーションを簡単にできるユーティリティ郡。  \nコマンドのヘルプを自動で構築する。(`/\u003cコマンド名\u003e help [ページ番号]` で使用)\nサブコマンドを使用する場合 `SubCommandable` を継承する。\n\u003cdetails\u003e\n\u003csummary\u003e例\u003c/summary\u003e\n\n  \u003cdetails\u003e\n    \u003csummary\u003eplugin.yml\u003c/summary\u003e\n\n```yml\n  name: ExamplePlugin\n  \n  commands:\n    examplecommand:\n      aliases:\n        - ex\n  permission:\n    examplepermission:\n      default: op\n```\n\n  \u003c/details\u003e\n\n  \u003cdetails\u003e\n    \u003csummary\u003eCommandManagerを管理するクラス(onEnableがあるとこ推奨)\u003c/summary\u003e\n\n```java \n  CommandManager manager;\n\n  // onEnable 内\n\n  this.manager = new CommandManager(this, \"examplecommand\", \"ExamplePlugin\", \"examplepermission\");\n  \n  this.manager.registerCommand(\"dostuff\", new CommandDoStuff(), \"ds\", \"do_stuff\", \"stuff\");\n\n```\n\n  \u003c/details\u003e\n\n  \u003cdetails\u003e\n    \u003csummary\u003eコマンドクラス\u003c/summary\u003e\n\n```java\npublic class CommandDoStuff extends CommandBase\n{\n\n  @Override\n  public void onCommand(@NotNull CommandSender sender, @NotNull Terminal terminal, String[] args)\n  {\n\n    if (this.indicateArgsLengthInvalid(terminal, args, 1, 2)  // 引数の長さが1~2でない場合はエラーを表示して終了\n            || this.indicatePlayer(terminal)  // コンソールから実行された場合はエラーを表示して終了\n    return;\n\n    String stuffName = args[0];\n    Integer repeatCount;\n    if (args.length \u003e= 2 \u0026\u0026 (repeatCount = this.parseInteger(terminal, args[1], 1, 100)) == null)\n      // 引数が2つ以上で, 2番目の引数が1~100の整数でない場合はエラーを表示して終了\n      return;\n    else\n      repeatCount = 1;\n\n    for (int i = 0; i \u003c repeatCount; i++)\n      terminal.info(\"Do stuff: \" + stuffName);\n\n  }\n\n  @Override\n  @Nullable\n  public List\u003cString\u003e onTabComplete(@NotNull CommandSender sender, @NotNull Terminal terminal, String[] args)\n  {\n    return List.of(\"stuff1\", \"stuff2\");\n  }\n\n  @Override\n  @Nullable\n  public String getPermission()\n  {\n    return \"exampleplugin.dostuff\";\n  }\n\n  @Override\n  public TextComponent getHelpOneLine()\n  {\n    return of(\"Do stuff!\");\n  }\n\n  @Override\n  public String[] getArguments()\n  {\n    return new String[]{\n            this.required(\"stuff\"),  // 必須引数\n            this.optional(\"repeat\")  // 任意引数\n    };\n  }\n}\n```\n\n  \u003c/details\u003e\n\n\u003c/details\u003e\n\n### コンフィグシステム\n\nファイルベースのコンフィグを簡単に作れる。\n\n```java\n\n@Getter\nclass ConfigClass\n{\n  @Config(\"Example Value 1\")\n  private final String exampleValue1 = \"example1\";\n  @Config(\"Example Value 2\", min = 1, max = 10)\n  private final int exampleValue2 = 5;\n  @Config(\"Example Ranged Value\", min = 1, max = 10, ranged = true)\n  private final int minExample = 1;\n  @Config(\"Example Ranged Value\", min = 1, max = 10, ranged = true)\n  private final int maxExample = 10;\n  @Config(\"Example string enum\", enums = {\"example1\", \"example2\"})\n  private final String exampleStringEnum = \"example1\";\n}\n\n  ConfigManager\u003cConfigClass\u003e manager = new ConfigManager\u003c\u003e(Paths.get(\"config.json\"), ConfigClass.class);\n```\n\n### サウンドセット\u0026サウンドユーティリティ\n\nたぶんつかうであろうサウンドを予め定義したEnumたち!!!   \nサウンドを定義するEnum用の便利なインタフェース!!!\n\n```java\n  Player player;\n  \n  // クエスト開始時とか?\n  QuestSoundSet.QUEST_START.play(player);\n  \n  // プレイヤリスポーン時とか?\n  PlayerSoundSet.RESPAWN.play(player);\n  \n  @Getter\n  enum MySoundSet implements SoundSet\n  {\n      MY_SOUND_1(Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1.0f, 1.0f),\n      MY_SOUND_2(Sound.BLOCK_NOTE_BLOCK_PLING, 1.0f, 1.0f),\n    \n      ;\n      \n      private final Sound sound;\n      private final SoundCategory source;\n      private final float volume;\n      private final float pitch;\n  }\n  \n  MySoundSet.MY_SOUND_1.play(player, PlayArea.NEARBY_10);  // 付近10m以内のプレイヤのみに再生\n  MySoundSet.MY_SOUND_2.play(player, 1.0f, 0.5f);  // ボリューム1.0, ピッチ0.5で再生\n  // その他, サウンドの再生位置を指定したり, サウンドカテゴリを指定したり, サウンドの再生範囲を指定したりできるやついっぱい。\n  // 多分全部網羅してるはず(してなかったらIssue or PR or なんかで教えてください)\n```\n\n### DBのトランザクションシステム\n\n```java\n  Connection connection;\n  class Employee {\n      int id;\n      String name;\n      int age;\n      String type;\n  }\n\nQueryResult\u003cEmployee\u003e result = Transaction.create(this.connection, \"SELECT * FROM example_table WHERE id = ? AND type = ?\")\n      .set(1, 123456)\n      .set(2, \"EMPLOYEE\")\n      .executeUpdate();\n```\n\n+ DB操作時の自動コミット(すべての実行の最後にコミット)\n  ```java\n    Transaction.create(connection)\n        .doTransaction((Transaction) -\u003e {\n            Connection connection = transaction.getConnection();\n            // ここでDB操作\n        });\n  ```\n+ DB操作時のtry-catchを省略できるように！(非チェック例外にします)\n  =\u003e SQLExceptionが発生した場合は自動的にロールバック！！\n+ close忘れがなくなる\n+ 結果をStream処理できる\n  ```java\n    result.stream().map((ResultRow row) -\u003e {\n        Employee employee = new Employee();\n        employee.id = row.getInt(\"id\");\n        employee.name = row.getString(\"name\");\n        employee.age = row.getInt(\"age\");\n        employee.type = row.getString(\"type\");\n        return employee;\n    }).forEach((Employee employee) -\u003e {\n        System.out.println(employee.name);\n    });\n  ```\n+ 結果をオブジェクトに変換して取得(マッパーを予め定義)\n  ```java\n    result.mapper((ResultRow row) -\u003e {\n        Employee employee = new Employee();\n        employee.id = row.getInt(\"id\");\n        employee.name = row.getString(\"name\");\n        employee.age = row.getInt(\"age\");\n        employee.type = row.getString(\"type\");\n        return employee;\n    });\n  \n    while (result.next()) {\n        Employee employee = result.get();\n        System.out.println(employee.name);\n    }\n  ```\n+ 結果をListで取得(マッパーを引数に突っ込む)\n  ```java\n    ArrayList\u003cEmployee\u003e employees = result.mapToList((ResultSet resultSet) -\u003e {\n        Employee employee = new Employee();\n        employee.id = resultSet.getInt(\"id\");\n        employee.name = resultSet.getString(\"name\");\n        employee.age = resultSet.getInt(\"age\");\n        employee.type = resultSet.getString(\"type\");\n        return employee;\n    });\n  ```\n\n### Component API のテキスト拡張\n\nv3.0.0 より Adventure API の内部仕様を廃止した。  \nこれにより, PaperMC 1.16.5 以下でも使用できるようになったとともに, 一部の機能が削除された。\n\nこれには, Adventure API より提供されていた `TextComponent` も含まれるため, 同等の機能を持つ API を作成する必要があった。\nv3.0.0 より作成された `Text` は Bungeecord による Component API を拡張し、より簡単かつ高度に使用できる API を提供する。\n\n```\nText text = Text.of(\"Hello, world!\")\n    .color(ChatColor.AQUA)  // Component API 系および Bukkit の ChatColor に対応\n    .bold()\n    .runCommandOnClick(\"/say Hello, world!\")  // / の有無は自動で判定し適切に追加\n    .hoverText(\"This is hover text.\")\n    .append(Text.of(\"This is appended text!\")\n        .hoverText(Text.of(\"This is appended hover text.\").color(ChatColor.GRAY))\n        .color(ChatColor.RED)\n    .append(\"This is appended text without Text.of().\")\n   \nTerminal terminal = Terminals.ofConsole();\nterminal.write(text);\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fteamkun%2Fpeyangpaperutils","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fteamkun%2Fpeyangpaperutils","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fteamkun%2Fpeyangpaperutils/lists"}