papermc-skill 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/CHANGELOG.md +41 -0
  2. package/README.md +90 -110
  3. package/assets/banner-animated.svg +360 -0
  4. package/assets/banner.svg +360 -0
  5. package/bin/cli.js +199 -0
  6. package/docs/01-modern-paper-architecture.md +48 -51
  7. package/docs/02-adventure-and-minimessage.md +48 -52
  8. package/docs/03-persistent-data-container.md +39 -39
  9. package/docs/04-commands-and-brigadier.md +32 -35
  10. package/docs/05-concurrency-and-folia.md +44 -44
  11. package/docs/06-events-and-listeners.md +30 -31
  12. package/docs/07-best-practices-and-perf.md +39 -40
  13. package/docs/08-gui-and-menus.md +34 -37
  14. package/docs/09-custom-items-and-combat.md +25 -33
  15. package/docs/10-database-and-storage.md +27 -27
  16. package/docs/11-security-and-exploit-prevention.md +233 -0
  17. package/package.json +2 -1
  18. package/skills/paper-plugin-dev/SKILL.md +391 -111
  19. package/templates/paper-modern-template/.gradle/9.7.1/checksums/checksums.lock +0 -0
  20. package/templates/paper-modern-template/.gradle/9.7.1/checksums/md5-checksums.bin +0 -0
  21. package/templates/paper-modern-template/.gradle/9.7.1/checksums/sha1-checksums.bin +0 -0
  22. package/templates/paper-modern-template/.gradle/{9.4.1 → 9.7.1}/executionHistory/executionHistory.bin +0 -0
  23. package/templates/paper-modern-template/.gradle/9.7.1/executionHistory/executionHistory.lock +0 -0
  24. package/templates/paper-modern-template/.gradle/{9.4.1 → 9.7.1}/fileHashes/fileHashes.bin +0 -0
  25. package/templates/paper-modern-template/.gradle/9.7.1/fileHashes/fileHashes.lock +0 -0
  26. package/templates/paper-modern-template/.gradle/{9.4.1 → 9.7.1}/fileHashes/resourceHashesCache.bin +0 -0
  27. package/templates/paper-modern-template/.gradle/{9.4.1/checksums/md5-checksums.bin → 9.7.1/kotlin-dsl-plugin-entries/jar-entries.bin} +0 -0
  28. package/templates/paper-modern-template/.gradle/9.7.1/kotlin-dsl-plugin-entries/kotlin-dsl-plugin-entries.lock +0 -0
  29. package/templates/paper-modern-template/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
  30. package/templates/paper-modern-template/.gradle/buildOutputCleanup/cache.properties +2 -2
  31. package/templates/paper-modern-template/build/classes/java/main/com/example/paperplugin/ExamplePaperPlugin.class +0 -0
  32. package/templates/paper-modern-template/build/classes/java/main/com/example/paperplugin/PaperPluginBootstrap.class +0 -0
  33. package/templates/paper-modern-template/build/classes/java/main/com/example/paperplugin/command/HelloCommand.class +0 -0
  34. package/templates/paper-modern-template/build/classes/java/main/com/example/paperplugin/listener/PlayerEventListener.class +0 -0
  35. package/templates/paper-modern-template/build/classes/java/main/com/example/paperplugin/util/SchedulerAdapter.class +0 -0
  36. package/templates/paper-modern-template/build/tmp/compileJava/previous-compilation-data.bin +0 -0
  37. package/templates/paper-modern-template/build.gradle.kts +10 -10
  38. package/templates/paper-modern-template/gradle/wrapper/gradle-wrapper.jar +0 -0
  39. package/templates/paper-modern-template/gradle/wrapper/gradle-wrapper.properties +1 -1
  40. package/templates/paper-modern-template/gradlew +3 -3
  41. package/templates/paper-modern-template/gradlew.bat +12 -23
  42. package/templates/paper-modern-template/settings.gradle.kts +7 -0
  43. package/templates/paper-modern-template/src/main/java/com/example/paperplugin/ExamplePaperPlugin.java +6 -6
  44. package/templates/paper-modern-template/src/main/java/com/example/paperplugin/PaperPluginBootstrap.java +2 -2
  45. package/templates/paper-modern-template/src/main/java/com/example/paperplugin/command/HelloCommand.java +2 -4
  46. package/templates/paper-modern-template/src/main/java/com/example/paperplugin/data/PluginDataKeys.java +2 -2
  47. package/templates/paper-modern-template/src/main/java/com/example/paperplugin/listener/PlayerEventListener.java +6 -7
  48. package/templates/paper-modern-template/src/main/java/com/example/paperplugin/util/SchedulerAdapter.java +6 -6
  49. package/templates/paper-modern-template/src/main/resources/config.yml +5 -5
  50. package/templates/paper-modern-template/.gradle/9.4.1/checksums/checksums.lock +0 -0
  51. package/templates/paper-modern-template/.gradle/9.4.1/checksums/sha1-checksums.bin +0 -0
  52. package/templates/paper-modern-template/.gradle/9.4.1/executionHistory/executionHistory.lock +0 -0
  53. package/templates/paper-modern-template/.gradle/9.4.1/fileHashes/fileHashes.lock +0 -0
  54. package/templates/paper-modern-template/.gradle/file-system.probe +0 -0
  55. /package/templates/paper-modern-template/.gradle/{9.4.1 → 9.7.1}/fileChanges/last-build.bin +0 -0
  56. /package/templates/paper-modern-template/.gradle/{9.4.1 → 9.7.1}/gc.properties +0 -0
@@ -1,15 +1,15 @@
1
1
  plugins {
2
2
  `java-library`
3
- // Plugin run-paper untuk menjalankan test server Paper/Folia instan
4
- id("xyz.jpenilla.run-paper") version "3.0.2"
3
+ // The run-paper plugin for instant Paper/Folia local test server execution
4
+ id("xyz.jpenilla.run-paper") version "3.1.0"
5
5
 
6
- // Aktifkan paperweight.userdev jika butuh Mojang NMS internals
6
+ // Enable paperweight.userdev if direct Mojang NMS internals access is needed
7
7
  // id("io.papermc.paperweight.userdev") version "2.0.0-beta.21"
8
8
  }
9
9
 
10
10
  group = "com.example"
11
11
  version = "1.0.0-SNAPSHOT"
12
- description = "Template Plugin Paper Minecraft Modern"
12
+ description = "Modern Paper & Folia Minecraft Plugin Starter Template"
13
13
 
14
14
  repositories {
15
15
  mavenCentral()
@@ -24,14 +24,14 @@ java {
24
24
  }
25
25
 
26
26
  dependencies {
27
- // Standar Utama: Paper API (Kyori Adventure, Folia Schedulers, Brigadier, PDC)
28
- compileOnly("io.papermc.paper:paper-api:1.21.4-R0.1-SNAPSHOT")
27
+ // Primary Standard: Paper API (Kyori Adventure, Folia Schedulers, Brigadier, PDC)
28
+ compileOnly("io.papermc.paper:paper-api:1.21.11-R0.1-SNAPSHOT")
29
29
 
30
- // Opsional: Untuk NMS / Mojang mappings internal (aktifkan plugin paperweight di atas jika memakai ini):
30
+ // Optional: For NMS / internal Mojang mappings (enable paperweight plugin above if using this):
31
31
  // paperweight.paperDevBundle("1.21.4.build.+")
32
32
 
33
- // Anotasi nullability
34
- compileOnly("org.jspecify:jspecify:1.0.0")
33
+ // Modern Nullability Annotations
34
+ compileOnly("org.jspecify:jspecify:1.0.1")
35
35
  }
36
36
 
37
37
  tasks {
@@ -50,5 +50,5 @@ tasks {
50
50
  }
51
51
  }
52
52
 
53
- // Menambahkan task './gradlew runFoliaServer' untuk pengujian multi-threaded Folia
53
+ // Registers the './gradlew runFoliaServer' task for multi-threaded Folia local testing
54
54
  runPaper.folia.registerTask()
@@ -1,6 +1,6 @@
1
1
  distributionBase=GRADLE_USER_HOME
2
2
  distributionPath=wrapper/dists
3
- distributionUrl=https\://services.gradle.org/distributions/gradle-9.4.1-bin.zip
3
+ distributionUrl=https\://services.gradle.org/distributions/gradle-9.7.1-bin.zip
4
4
  networkTimeout=10000
5
5
  validateDistributionUrl=true
6
6
  zipStoreBase=GRADLE_USER_HOME
@@ -20,7 +20,7 @@
20
20
 
21
21
  ##############################################################################
22
22
  #
23
- # Gradle start up script for POSIX generated by Gradle.
23
+ # gradlew start up script for POSIX generated by Gradle.
24
24
  #
25
25
  # Important for running:
26
26
  #
@@ -29,7 +29,7 @@
29
29
  # bash, then to run this script, type that shell name before the whole
30
30
  # command line, like:
31
31
  #
32
- # ksh Gradle
32
+ # ksh gradlew
33
33
  #
34
34
  # Busybox and similar reduced shells will NOT work, because this script
35
35
  # requires all of these POSIX shell features:
@@ -57,7 +57,7 @@
57
57
  # Darwin, MinGW, and NonStop.
58
58
  #
59
59
  # (3) This script is generated from the Groovy template
60
- # https://github.com/gradle/gradle/blob/2d6327017519d23b96af35865dc997fcb544fb40/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
60
+ # https://github.com/gradle/gradle/blob/3d91ce3b8caaf77ad09f381f43615b715b53f72c/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
61
61
  # within the Gradle project.
62
62
  #
63
63
  # You can find Gradle at https://github.com/gradle/gradle/.
@@ -19,12 +19,12 @@
19
19
  @if "%DEBUG%"=="" @echo off
20
20
  @rem ##########################################################################
21
21
  @rem
22
- @rem Gradle startup script for Windows
22
+ @rem gradlew startup script for Windows
23
23
  @rem
24
24
  @rem ##########################################################################
25
25
 
26
- @rem Set local scope for the variables with windows NT shell
27
- if "%OS%"=="Windows_NT" setlocal
26
+ @rem Set local scope for the variables, and ensure extensions are enabled
27
+ setlocal EnableExtensions
28
28
 
29
29
  set DIRNAME=%~dp0
30
30
  if "%DIRNAME%"=="" set DIRNAME=.
@@ -51,7 +51,7 @@ echo. 1>&2
51
51
  echo Please set the JAVA_HOME variable in your environment to match the 1>&2
52
52
  echo location of your Java installation. 1>&2
53
53
 
54
- goto fail
54
+ "%COMSPEC%" /c exit 1
55
55
 
56
56
  :findJavaFromJavaHome
57
57
  set JAVA_HOME=%JAVA_HOME:"=%
@@ -65,29 +65,18 @@ echo. 1>&2
65
65
  echo Please set the JAVA_HOME variable in your environment to match the 1>&2
66
66
  echo location of your Java installation. 1>&2
67
67
 
68
- goto fail
68
+ "%COMSPEC%" /c exit 1
69
69
 
70
70
  :execute
71
71
  @rem Setup the command line
72
72
 
73
73
 
74
74
 
75
- @rem Execute Gradle
76
- "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
75
+ @rem Execute gradlew
76
+ @rem endlocal doesn't take effect until after the line is parsed and variables are expanded
77
+ @rem which allows us to clear the local environment before executing the java command
78
+ endlocal & "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* & call :exitWithErrorLevel
77
79
 
78
- :end
79
- @rem End local scope for the variables with windows NT shell
80
- if %ERRORLEVEL% equ 0 goto mainEnd
81
-
82
- :fail
83
- rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
84
- rem the _cmd.exe /c_ return code!
85
- set EXIT_CODE=%ERRORLEVEL%
86
- if %EXIT_CODE% equ 0 set EXIT_CODE=1
87
- if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
88
- exit /b %EXIT_CODE%
89
-
90
- :mainEnd
91
- if "%OS%"=="Windows_NT" endlocal
92
-
93
- :omega
80
+ :exitWithErrorLevel
81
+ @rem Use "%COMSPEC%" /c exit to allow operators to work properly in scripts
82
+ "%COMSPEC%" /c exit %ERRORLEVEL%
@@ -1,3 +1,10 @@
1
+ pluginManagement {
2
+ repositories {
3
+ gradlePluginPortal()
4
+ mavenCentral()
5
+ }
6
+ }
7
+
1
8
  plugins {
2
9
  id("org.gradle.toolchains.foojay-resolver-convention") version "1.0.0"
3
10
  }
@@ -11,25 +11,25 @@ public final class ExamplePaperPlugin extends JavaPlugin {
11
11
 
12
12
  @Override
13
13
  public void onEnable() {
14
- // Simpan default configuration jika belum ada
14
+ // Save default configuration if missing
15
15
  saveDefaultConfig();
16
16
 
17
- // Inisialisasi kunci PersistentDataContainer
17
+ // Initialize PersistentDataContainer keys
18
18
  PluginDataKeys.init(this);
19
19
 
20
- // Registrasi Event Listener
20
+ // Register Event Listeners
21
21
  getServer().getPluginManager().registerEvents(new PlayerEventListener(this), this);
22
22
 
23
- // Logging dengan ComponentLogger bawaan Paper
23
+ // Log startup using Paper's native ComponentLogger
24
24
  getComponentLogger().info(
25
- Component.text("ExamplePaperPlugin aktif! Running on Folia: " + SchedulerAdapter.isFolia(), NamedTextColor.GREEN)
25
+ Component.text("ExamplePaperPlugin enabled! Running on Folia: " + SchedulerAdapter.isFolia(), NamedTextColor.GREEN)
26
26
  );
27
27
  }
28
28
 
29
29
  @Override
30
30
  public void onDisable() {
31
31
  getComponentLogger().info(
32
- Component.text("ExamplePaperPlugin dinonaktifkan.", NamedTextColor.YELLOW)
32
+ Component.text("ExamplePaperPlugin disabled.", NamedTextColor.YELLOW)
33
33
  );
34
34
  }
35
35
  }
@@ -14,14 +14,14 @@ public final class PaperPluginBootstrap implements PluginBootstrap {
14
14
 
15
15
  @Override
16
16
  public void bootstrap(final BootstrapContext context) {
17
- // Registrasi Paper Brigadier Commands via LifecycleEvents
17
+ // Register Paper Brigadier Commands via LifecycleEvents
18
18
  context.getLifecycleManager().registerEventHandler(
19
19
  LifecycleEvents.COMMANDS,
20
20
  event -> {
21
21
  final var registrar = event.registrar();
22
22
  registrar.register(
23
23
  HelloCommand.create(),
24
- "Contoh perintah Paper modern berbasis Brigadier",
24
+ "Example modern Paper command powered by Mojang Brigadier",
25
25
  List.of("phello")
26
26
  );
27
27
  }
@@ -11,8 +11,6 @@ import org.bukkit.Bukkit;
11
11
  import org.bukkit.command.CommandSender;
12
12
  import org.bukkit.entity.Player;
13
13
 
14
- import java.util.List;
15
-
16
14
  public final class HelloCommand {
17
15
 
18
16
  private HelloCommand() {
@@ -24,7 +22,7 @@ public final class HelloCommand {
24
22
  .executes(context -> {
25
23
  final CommandSender sender = context.getSource().getSender();
26
24
  sender.sendMessage(
27
- MiniMessage.miniMessage().deserialize("<green>Halo, <yellow><name></yellow>! Selamat menggunakan Paper Brigadier.</green>",
25
+ MiniMessage.miniMessage().deserialize("<green>Hello, <yellow><name></yellow>! Welcome to modern Paper Brigadier.</green>",
28
26
  Placeholder.unparsed("name", sender.getName())
29
27
  )
30
28
  );
@@ -42,7 +40,7 @@ public final class HelloCommand {
42
40
  final String target = StringArgumentType.getString(context, "target");
43
41
 
44
42
  sender.sendMessage(
45
- MiniMessage.miniMessage().deserialize("<green>Menyapa <gold><target></gold> atas nama <yellow><sender></yellow>!</green>",
43
+ MiniMessage.miniMessage().deserialize("<green>Greetings sent to <gold><target></gold> on behalf of <yellow><sender></yellow>!</green>",
46
44
  Placeholder.unparsed("target", target),
47
45
  Placeholder.unparsed("sender", sender.getName())
48
46
  )
@@ -4,8 +4,8 @@ import org.bukkit.NamespacedKey;
4
4
  import org.bukkit.plugin.Plugin;
5
5
 
6
6
  /**
7
- * Menyimpan konstanta NamespacedKey untuk PersistentDataContainer (PDC).
8
- * Selalu inisialisasi satu kali untuk menghindari alokasi objek berulang.
7
+ * Stores static NamespacedKey identifiers for PersistentDataContainer (PDC).
8
+ * Always initialized once on plugin startup to eliminate repeated heap allocations.
9
9
  */
10
10
  public final class PluginDataKeys {
11
11
 
@@ -2,7 +2,6 @@ package com.example.paperplugin.listener;
2
2
 
3
3
  import com.example.paperplugin.ExamplePaperPlugin;
4
4
  import com.example.paperplugin.data.PluginDataKeys;
5
- import net.kyori.adventure.text.Component;
6
5
  import net.kyori.adventure.text.minimessage.MiniMessage;
7
6
  import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
8
7
  import org.bukkit.entity.Player;
@@ -32,28 +31,28 @@ public final class PlayerEventListener implements Listener {
32
31
  pdc.set(PluginDataKeys.LAST_LOGIN_TIMESTAMP, PersistentDataType.LONG, System.currentTimeMillis());
33
32
 
34
33
  if (currentJoins == 1) {
35
- // Pertama kali bergabung
34
+ // First time player join
36
35
  final String firstJoinFormat = plugin.getConfig().getString(
37
36
  "messages.first_join",
38
- "<rainbow>MEMBER BARU!</rainbow> Sambut <yellow><player></yellow>!"
37
+ "<rainbow>NEW MEMBER!</rainbow> Give a warm welcome to <yellow><player></yellow>!"
39
38
  );
40
39
  event.joinMessage(
41
40
  MiniMessage.miniMessage().deserialize(firstJoinFormat, Placeholder.unparsed("player", player.getName()))
42
41
  );
43
42
  } else {
44
- // Pemain kembali bergabung
43
+ // Returning player join
45
44
  final String welcomeFormat = plugin.getConfig().getString(
46
45
  "messages.welcome",
47
- "<green>Selamat datang kembali, <yellow><player></yellow>!</green>"
46
+ "<green>Welcome back, <yellow><player></yellow>!</green>"
48
47
  );
49
48
  event.joinMessage(
50
49
  MiniMessage.miniMessage().deserialize(welcomeFormat, Placeholder.unparsed("player", player.getName()))
51
50
  );
52
51
  }
53
52
 
54
- // Kirim action bar personal
53
+ // Send personalized action bar
55
54
  player.sendActionBar(
56
- MiniMessage.miniMessage().deserialize("<gray>Kunjungan ke-<gold><count></gold></gray>",
55
+ MiniMessage.miniMessage().deserialize("<gray>Visit #<gold><count></gold></gray>",
57
56
  Placeholder.unparsed("count", String.valueOf(currentJoins))
58
57
  )
59
58
  );
@@ -8,7 +8,7 @@ import org.bukkit.plugin.Plugin;
8
8
  import java.util.concurrent.TimeUnit;
9
9
 
10
10
  /**
11
- * Adapter Scheduler yang secara transparan mendukung arsitektur Paper standar dan Folia (Regionized Threading).
11
+ * Universal Scheduler Adapter providing transparent concurrency across standard Paper and Folia (Threaded Regions).
12
12
  */
13
13
  public final class SchedulerAdapter {
14
14
 
@@ -31,7 +31,7 @@ public final class SchedulerAdapter {
31
31
  }
32
32
 
33
33
  /**
34
- * Menjalankan runnable pada thread region lokasi tertentu.
34
+ * Executes a runnable on the region thread owning the specified location.
35
35
  */
36
36
  public static void runAtLocation(final Plugin plugin, final Location location, final Runnable runnable) {
37
37
  if (IS_FOLIA) {
@@ -42,7 +42,7 @@ public final class SchedulerAdapter {
42
42
  }
43
43
 
44
44
  /**
45
- * Menjalankan runnable pada thread yang memiliki entity tertentu.
45
+ * Executes a runnable on the region thread currently owning the specified entity.
46
46
  */
47
47
  public static void runAtEntity(final Plugin plugin, final Entity entity, final Runnable runnable) {
48
48
  if (IS_FOLIA) {
@@ -53,7 +53,7 @@ public final class SchedulerAdapter {
53
53
  }
54
54
 
55
55
  /**
56
- * Menjalankan runnable secara asynchronous (off-main-thread).
56
+ * Executes a runnable asynchronously (off-main-thread).
57
57
  */
58
58
  public static void runAsync(final Plugin plugin, final Runnable runnable) {
59
59
  if (IS_FOLIA) {
@@ -64,13 +64,13 @@ public final class SchedulerAdapter {
64
64
  }
65
65
 
66
66
  /**
67
- * Menjalankan task delayed secara asynchronous.
67
+ * Executes a delayed task asynchronously.
68
68
  */
69
69
  public static void runAsyncDelayed(final Plugin plugin, final Runnable runnable, final long delay, final TimeUnit timeUnit) {
70
70
  if (IS_FOLIA) {
71
71
  Bukkit.getAsyncScheduler().runDelayed(plugin, task -> runnable.run(), delay, timeUnit);
72
72
  } else {
73
- final long ticks = delay * 20; // Aproksimasi detik ke tick jika detik
73
+ final long ticks = Math.max(1L, timeUnit.toMillis(delay) / 50L);
74
74
  Bukkit.getScheduler().runTaskLaterAsynchronously(plugin, runnable, ticks);
75
75
  }
76
76
  }
@@ -1,10 +1,10 @@
1
- # Konfigurasi Modern Paper Template Plugin
2
- # Format teks menggunakan format Kyori MiniMessage
1
+ # Modern Paper Plugin Template Configuration
2
+ # Formatted using Kyori MiniMessage syntax
3
3
 
4
4
  messages:
5
- welcome: "<gradient:#00c6ff:#0072ff><bold>Selamat datang di server!</bold></gradient> Senang melihatmu bergabung, <yellow><player></yellow>."
6
- first_join: "<rainbow><bold>MEMBER BARU!</bold></rainbow> Mari sambut <yellow><player></yellow> yang baru pertama kali bergabung!"
7
- command_hello: "<green>Halo, <aqua><target></aqua>! Salam dari server Paper modern.</green>"
5
+ welcome: "<gradient:#00c6ff:#0072ff><bold>Welcome back to the server!</bold></gradient> Great to see you again, <yellow><player></yellow>."
6
+ first_join: "<rainbow><bold>NEW MEMBER!</bold></rainbow> Give a warm welcome to <yellow><player></yellow> for joining the server!"
7
+ command_hello: "<green>Hello, <aqua><target></aqua>! Greetings from modern PaperMC.</green>"
8
8
 
9
9
  settings:
10
10
  track_join_count: true