Initial commit: Minecraft Scala Plugin Template

- Complete Scala SpigotMC plugin template
- Docker development environment
- Sample commands (/hello, /info) and event handlers
- Development scripts for easy server management
- Comprehensive README and documentation

🤖 Generated with Claude Code
This commit is contained in:
mii443
2025-06-18 00:40:53 +09:00
commit 4b2e24f6b9
11 changed files with 460 additions and 0 deletions

9
.dockerignore Normal file
View File

@ -0,0 +1,9 @@
target/
project/target/
.git/
.gitignore
*.md
dev-server.sh
docker-compose.yml
server-data/
server-logs/

62
.gitignore vendored Normal file
View File

@ -0,0 +1,62 @@
# Scala/sbt build files
target/
project/target/
project/project/
.bsp/
# IDE files
.idea/
.vscode/
*.iml
*.ipr
*.iws
.metals/
.bloop/
# sbt plugins and cache
.sbt/
.cache-main
.cache-tests
# Logs
*.log
logs/
server-logs/
# Server data (world files)
server-data/
world/
world_nether/
world_the_end/
# Runtime files
eula.txt
server.properties
ops.txt
whitelist.txt
banned-*.txt
usercache.json
usernamecache.json
# Backup files
*.old
*.bak
*~
# OS specific files
.DS_Store
Thumbs.db
Desktop.ini
# Docker volumes
data/
# Temporary files
tmp/
temp/
*.tmp
*.temp
# Environment files
.env
.env.local

33
Dockerfile Normal file
View File

@ -0,0 +1,33 @@
FROM openjdk:21-jdk-slim
WORKDIR /minecraft
# Install wget to download server jar
RUN apt-get update && apt-get install -y wget && rm -rf /var/lib/apt/lists/*
# Download Spigot 1.21.5 server jar
RUN wget -O server.jar https://getbukkit.org/get/cNW08KHVlCEwof2IkXbxXIKeDPbfgMBU
# Create plugins directory
RUN mkdir -p plugins
# Copy server configuration files (optional)
# COPY server-files/ ./
# Accept EULA
RUN echo "eula=true" > eula.txt
# Create basic server.properties
RUN echo "server-port=25565" > server.properties && \
echo "online-mode=false" >> server.properties && \
echo "spawn-protection=0" >> server.properties && \
echo "max-players=10" >> server.properties && \
echo "difficulty=peaceful" >> server.properties && \
echo "gamemode=creative" >> server.properties && \
echo "pvp=false" >> server.properties && \
echo "enable-command-block=true" >> server.properties
EXPOSE 25565
# Start script
CMD ["java", "-Xmx2G", "-Xms1G", "-jar", "server.jar", "nogui"]

119
README.md Normal file
View File

@ -0,0 +1,119 @@
# Minecraft Scala Plugin Template
🎮 ScalaでSpigotMCプラグインを開発するためのテンプレートです。
## 特徴
- 🛠️ **Scala + SpigotMC**: ScalaでMinecraftプラグインを開発
- 🐳 **Docker開発環境**: 簡単にテスト用サーバーを起動
- 🔄 **ホットリロード**: プラグインの変更を即座に反映
- 📦 **完全なビルド環境**: sbtでのビルドとパッケージング
## クイックスタート
1. **テンプレートをクローン**
```bash
git clone https://github.com/yourusername/minecraft-scala-plugin-template.git
cd minecraft-scala-plugin-template
```
2. **開発サーバーを起動**
```bash
./dev-server.sh start
```
3. **Minecraftクライアントで接続**
- サーバーアドレス: `localhost:25565`
- オフラインモードで動作します
## 開発コマンド
```bash
# サーバー起動(プラグインも自動ビルド)
./dev-server.sh start
# プラグイン再ビルド+サーバー再起動
./dev-server.sh restart
# サーバー停止
./dev-server.sh stop
# ログ確認
./dev-server.sh logs
# Minecraftサーバーコンソールにattach
./dev-server.sh attach
# サーバーのbashシェルに接続
./dev-server.sh console
# 完全リビルド
./dev-server.sh rebuild
```
## プロジェクト構造
```
minecraft-scala-plugin-template/
├── src/main/scala/com/example/plugin/
│ └── MinecraftScalaPlugin.scala # メインプラグインクラス
├── src/main/resources/
│ └── plugin.yml # プラグイン設定
├── build.sbt # sbtビルド設定
├── docker-compose.yml # Docker設定
├── Dockerfile # サーバーイメージ
├── dev-server.sh # 開発用スクリプト
└── README.md
```
## サンプル機能
このテンプレートには以下のサンプル機能が含まれています:
### コマンド
- `/hello` - 挨拶メッセージを表示
- `/info` - プレイヤー情報を表示
### イベントハンドラ
- プレイヤー参加時のウェルカムメッセージ
- プレイヤー退出時のログ出力
## カスタマイズ
### プラグイン名を変更
1. `build.sbt` の `name` を変更
2. `src/main/resources/plugin.yml` の `name` と `main` クラス名を変更
3. パッケージ名とクラス名を変更
### 新機能の追加
1. `src/main/scala/com/example/plugin/MinecraftScalaPlugin.scala` を編集
2. 新しいコマンドやイベントハンドラを追加
3. `./dev-server.sh restart` で変更を反映
## ビルド
### 手動ビルド
```bash
sbt clean package
```
### JAR出力場所
```
target/scala-2.13/minecraft-scala-plugin_2.13-1.0.0.jar
```
## 要件
- Docker & Docker Compose
- Java 8以上sbt用
- Minecraft Java Editionテスト用
## ライセンス
このテンプレートは自由に使用・改変できます。
## 参考資料
- [SpigotMC API Documentation](https://hub.spigotmc.org/javadocs/spigot/)
- [Bukkit Plugin Tutorial](https://bukkit.fandom.com/wiki/Plugin_Tutorial)
- [Scala Documentation](https://docs.scala-lang.org/)

20
build.sbt Normal file
View File

@ -0,0 +1,20 @@
ThisBuild / version := "1.0.0"
ThisBuild / scalaVersion := "2.13.12"
lazy val root = (project in file("."))
.settings(
name := "minecraft-scala-plugin",
resolvers ++= Seq(
"spigot-repo" at "https://hub.spigotmc.org/nexus/content/repositories/snapshots/",
"sonatype" at "https://oss.sonatype.org/content/repositories/snapshots/"
),
libraryDependencies ++= Seq(
"org.spigotmc" % "spigot-api" % "1.21.5-R0.1-SNAPSHOT" % "provided"
),
assembly / assemblyMergeStrategy := {
case PathList("META-INF", xs @ _*) => MergeStrategy.discard
case x => MergeStrategy.first
},
assembly / assemblyJarName := s"${name.value}-${version.value}.jar"
)

83
dev-server.sh Executable file
View File

@ -0,0 +1,83 @@
#!/bin/bash
# Minecraft Plugin Development Server Script
set -e
echo "🎮 Minecraft Plugin Development Server"
echo "======================================"
# Function to build plugin
build_plugin() {
echo "📦 Building plugin..."
sbt clean package
# Check if jar exists
if [ ! -f "target/scala-2.13/minecraft-scala-plugin_2.13-1.0.0.jar" ]; then
echo "❌ Plugin jar not found! Build failed."
exit 1
fi
echo "✅ Plugin built successfully!"
}
# Create necessary directories
mkdir -p server-data server-logs
# Start/restart the server
case "${1:-start}" in
"start")
build_plugin
echo "🚀 Starting development server..."
docker compose up -d
echo "✅ Server started! Connect to localhost:25565"
echo "📜 To view logs: docker compose logs -f"
echo "🛑 To stop: ./dev-server.sh stop"
;;
"stop")
echo "🛑 Stopping development server..."
docker compose down
echo "✅ Server stopped!"
;;
"restart")
echo "🔄 Restarting development server..."
build_plugin
docker compose down
docker compose up -d
echo "✅ Server restarted!"
;;
"logs")
echo "📜 Showing server logs..."
docker compose logs -f
;;
"console")
echo "💻 Connecting to server console..."
docker exec -it minecraft-dev-server /bin/bash
;;
"attach")
echo "📎 Attaching to Minecraft server console..."
echo "💡 To detach: Press Ctrl+P then Ctrl+Q"
docker attach minecraft-dev-server
;;
"rebuild")
echo "🔨 Rebuilding everything..."
build_plugin
docker compose down
docker compose build --no-cache
docker compose up -d
echo "✅ Complete rebuild finished!"
;;
*)
echo "Usage: $0 {start|stop|restart|logs|console|attach|rebuild}"
echo ""
echo "Commands:"
echo " start - Build plugin and start server"
echo " stop - Stop the server"
echo " restart - Rebuild plugin and restart server"
echo " logs - View server logs"
echo " console - Connect to server console (bash)"
echo " attach - Attach to Minecraft server console"
echo " rebuild - Complete rebuild (server + plugin)"
exit 1
;;
esac

23
docker-compose.yml Normal file
View File

@ -0,0 +1,23 @@
version: '3.8'
services:
minecraft-server:
build: .
container_name: minecraft-dev-server
ports:
- "25565:25565"
volumes:
- ./target/scala-2.13/minecraft-scala-plugin_2.13-1.0.0.jar:/minecraft/plugins/minecraft-scala-plugin.jar
- ./server-data:/minecraft/world
- ./server-logs:/minecraft/logs
environment:
- JAVA_OPTS=-Xmx2G -Xms1G
stdin_open: true
tty: true
restart: unless-stopped
networks:
- minecraft-net
networks:
minecraft-net:
driver: bridge

1
project/build.properties Normal file
View File

@ -0,0 +1 @@
sbt.version=1.11.2

1
project/plugins.sbt Normal file
View File

@ -0,0 +1 @@
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "2.1.3")

View File

@ -0,0 +1,35 @@
name: MinecraftScalaPlugin
version: 1.0.0
main: com.example.plugin.MinecraftScalaPlugin
api-version: 1.21
author: YourName
description: A Minecraft plugin written in Scala
commands:
hello:
description: Sends a hello message to the player
usage: /hello
permission: scalaplugin.hello
permission-message: You don't have permission to use this command!
info:
description: Shows player information
usage: /info
permission: scalaplugin.info
permission-message: You don't have permission to use this command!
permissions:
scalaplugin.hello:
description: Allows use of the hello command
default: true
scalaplugin.info:
description: Allows use of the info command
default: true
scalaplugin.*:
description: Gives access to all ScalaPlugin commands
children:
scalaplugin.hello: true
scalaplugin.info: true
default: op

View File

@ -0,0 +1,74 @@
package com.example.plugin
import org.bukkit.plugin.java.JavaPlugin
import org.bukkit.event.{EventHandler, Listener}
import org.bukkit.event.player.{PlayerJoinEvent, PlayerQuitEvent}
import org.bukkit.command.{Command, CommandExecutor, CommandSender}
import org.bukkit.entity.Player
import org.bukkit.ChatColor
class MinecraftScalaPlugin extends JavaPlugin with Listener {
override def onEnable(): Unit = {
getLogger.info("Scala Minecraft Plugin has been enabled!")
// Register events
getServer.getPluginManager.registerEvents(this, this)
// Register commands
Option(getCommand("hello")).foreach(_.setExecutor(new HelloCommand))
Option(getCommand("info")).foreach(_.setExecutor(new InfoCommand))
}
override def onDisable(): Unit = {
getLogger.info("Scala Minecraft Plugin has been disabled!")
}
@EventHandler
def onPlayerJoin(event: PlayerJoinEvent): Unit = {
val player = event.getPlayer
val message = s"${ChatColor.GREEN}Welcome ${player.getName} to the server!"
player.sendMessage(message)
getLogger.info(s"Player ${player.getName} joined the server")
}
@EventHandler
def onPlayerQuit(event: PlayerQuitEvent): Unit = {
val player = event.getPlayer
getLogger.info(s"Player ${player.getName} left the server")
}
}
class HelloCommand extends CommandExecutor {
override def onCommand(sender: CommandSender, command: Command, label: String, args: Array[String]): Boolean = {
sender match {
case player: Player =>
player.sendMessage(s"${ChatColor.YELLOW}Hello ${player.getName}! This is a Scala plugin!")
true
case _ =>
sender.sendMessage("This command can only be used by players!")
true
}
}
}
class InfoCommand extends CommandExecutor {
override def onCommand(sender: CommandSender, command: Command, label: String, args: Array[String]): Boolean = {
sender match {
case player: Player =>
val info = Seq(
s"${ChatColor.AQUA}=== Server Info ===",
s"${ChatColor.WHITE}Player: ${player.getName}",
s"${ChatColor.WHITE}World: ${player.getWorld.getName}",
s"${ChatColor.WHITE}Location: ${player.getLocation.getBlockX}, ${player.getLocation.getBlockY}, ${player.getLocation.getBlockZ}",
s"${ChatColor.WHITE}Health: ${player.getHealth}/${player.getMaxHealth}",
s"${ChatColor.WHITE}Food Level: ${player.getFoodLevel}/20"
)
info.foreach(player.sendMessage)
true
case _ =>
sender.sendMessage("This command can only be used by players!")
true
}
}
}