diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile
index 147541c..f32b714 100644
--- a/.devcontainer/Dockerfile
+++ b/.devcontainer/Dockerfile
@@ -1 +1,10 @@
FROM mcr.microsoft.com/devcontainers/java:21
+
+RUN apt-get update && apt-get install -y \
+ maven \
+ && apt-get clean \
+ && rm -rf /var/lib/apt/lists/*
+
+# .m2ディレクトリの権限を vscode に設定
+RUN mkdir -p /home/vscode/.m2/repository \
+ && chown -R vscode /home/vscode/.m2
diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
index 98b9f44..357e71f 100644
--- a/.devcontainer/devcontainer.json
+++ b/.devcontainer/devcontainer.json
@@ -11,5 +11,5 @@
]
}
},
- "postCreateCommand": "mvn dependency:go-offline"
+ "shutdownAction": "none"
}
diff --git a/.gitignore b/.gitignore
index b8c3a52..abddb0f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
# Maven
target/
+dependency-reduced-pom.xml
\ No newline at end of file
diff --git a/Makefile b/Makefile
index d85c78f..1b6f8dc 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
# Minecraft LogTime Plugin - 開発用Makefile
-.PHONY: help build start stop clean logs test reload
+.PHONY: help build start stop clean logs test reload dev-rebuild dev-logs
# デフォルトターゲット
help:
@@ -12,6 +12,8 @@ help:
@echo " make logs - Paper サーバーのログを表示"
@echo " make test - テストを実行"
@echo " make reload - プラグインをリビルドしてサーバー再起動"
+ @echo " make dev-rebuild - 開発用コマンド: プラグインをリビルドしてサーバー再起動"
+ @echo " make dev-logs - 開発用コマンド: Paper サーバーのログを表示"
# プラグインをビルド
build:
@@ -55,3 +57,13 @@ init:
docker-compose build
make build
@echo "初期化完了!'make start' でサーバーを起動できます。"
+
+# 開発用コマンド
+dev-rebuild:
+ docker-compose build paper
+ docker-compose restart paper
+ @echo "Plugin reloaded!"
+
+# 開発用コマンド
+dev-logs:
+ docker-compose logs -f paper
diff --git a/docker-compose.yml b/docker-compose.yml
index c4f53df..1659d4d 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -12,14 +12,12 @@ services:
build:
context: .
dockerfile: ./paper/Dockerfile
- container_name: mc-plugin-paper
+ target: runtime
ports:
- "25565:25565"
volumes:
- - ./target:/server/plugins
- paper_data:/server
- depends_on:
- - dev
+ - ./target:/server/plugins
volumes:
paper_data:
diff --git a/paper/Dockerfile b/paper/Dockerfile
index d9894eb..9b24900 100644
--- a/paper/Dockerfile
+++ b/paper/Dockerfile
@@ -1,20 +1,17 @@
-# === ビルド用ステージ ===
-FROM debian:stable-slim AS builder
-
-ARG MC_VERSION="1.21"
-ARG BUILD_NUMBER="130"
-
+# === Paperサーバーダウンロード用ステージ ===
+FROM debian:stable-slim AS server-builder
+ARG MC_VERSION="1.21.8"
+ARG BUILD_NUMBER="53"
RUN apt-get update && apt-get install -y wget && rm -rf /var/lib/apt/lists/*
RUN wget -O paper.jar "https://api.papermc.io/v2/projects/paper/versions/${MC_VERSION}/builds/${BUILD_NUMBER}/downloads/paper-${MC_VERSION}-${BUILD_NUMBER}.jar"
-# === 起動用ステージ ===
-FROM eclipse-temurin:21-jre-jammy
-
+# === 実行用ステージ ===
+FROM eclipse-temurin:21-jre-jammy AS runtime
WORKDIR /server
-COPY --from=builder /paper.jar .
+# Paperサーバーをコピー
+COPY --from=server-builder /paper.jar .
COPY paper/eula.txt .
EXPOSE 25565
-
CMD ["java", "-Xms1G", "-Xmx1G", "-jar", "paper.jar", "--nogui"]
diff --git a/pom.xml b/pom.xml
index ef04699..23d3409 100644
--- a/pom.xml
+++ b/pom.xml
@@ -79,6 +79,43 @@
+
+
+ org.apache.maven.plugins
+ maven-shade-plugin
+ 3.4.1
+
+
+ package
+
+ shade
+
+
+
+
+ org.jetbrains.kotlin:kotlin-stdlib
+
+
+
+
+ com.pool25m.logtime.LogTimePlugin
+
+
+ ${project.artifactId}-${project.version}
+
+
+ *:*
+
+ META-INF/*.SF
+ META-INF/*.DSA
+ META-INF/*.RSA
+
+
+
+
+
+
+
diff --git a/src/main/kotlin/com/pool25m/logtime/LogTimePlugin.kt b/src/main/kotlin/com/pool25m/logtime/LogTimePlugin.kt
index e53fa91..f175108 100644
--- a/src/main/kotlin/com/pool25m/logtime/LogTimePlugin.kt
+++ b/src/main/kotlin/com/pool25m/logtime/LogTimePlugin.kt
@@ -4,9 +4,10 @@ import org.bukkit.plugin.java.JavaPlugin
class LogTimePlugin : JavaPlugin() {
override fun onEnable() {
- logger.info("LogTime Plugin has been enabled!")
+ val playerStatsService = PlayerStatsService()
+ getCommand("ranking")?.setExecutor(RankingCommand(playerStatsService))
- getCommand("ranking")?.setExecutor(RankingCommand())
+ logger.info("LogTime Plugin has been enabled!")
}
override fun onDisable() {
diff --git a/src/main/kotlin/com/pool25m/logtime/PlayerStatsService.kt b/src/main/kotlin/com/pool25m/logtime/PlayerStatsService.kt
new file mode 100644
index 0000000..08804b2
--- /dev/null
+++ b/src/main/kotlin/com/pool25m/logtime/PlayerStatsService.kt
@@ -0,0 +1,44 @@
+package com.pool25m.logtime
+
+import org.bukkit.Bukkit
+import org.bukkit.Statistic
+import java.util.concurrent.TimeUnit
+
+data class PlayerRankData(
+ val playerName: String,
+ val playTicks: Long,
+ val formattedPlayTime: String,
+)
+
+class PlayerStatsService {
+ /**
+ * サーバーにログインしたことのある全プレイヤーの総プレイ時間ランキングを取得する
+ */
+ fun getPlayerRankings(): List {
+ return Bukkit
+ .getOfflinePlayers()
+ .map { player ->
+ val playTicks = player.getStatistic(Statistic.PLAY_ONE_MINUTE).toLong()
+
+ PlayerRankData(
+ // OfflinePlayer の場合は name が null になる可能性がある
+ playerName = player.name ?: "Unknown Player",
+ playTicks = playTicks,
+ formattedPlayTime = formatPlayTimeFromTicks(playTicks),
+ )
+ }.sortedByDescending { it.playTicks } // 正確な時間でソート
+ }
+
+ private fun formatPlayTimeFromTicks(ticks: Long): String {
+ val millis = ticks * 50 // 1 tick = 50ms
+ val hours = TimeUnit.MILLISECONDS.toHours(millis)
+ val minutes = TimeUnit.MILLISECONDS.toMinutes(millis) % 60
+ val seconds = TimeUnit.MILLISECONDS.toSeconds(millis) % 60
+
+ return buildString {
+ if (hours > 0) append("${hours}h ")
+ if (minutes > 0) append("${minutes}m ")
+ append("${seconds}s")
+ }.ifEmpty { "0s" }
+ }
+}
diff --git a/src/main/kotlin/com/pool25m/logtime/RankingCommand.kt b/src/main/kotlin/com/pool25m/logtime/RankingCommand.kt
index b942fd7..10666a8 100644
--- a/src/main/kotlin/com/pool25m/logtime/RankingCommand.kt
+++ b/src/main/kotlin/com/pool25m/logtime/RankingCommand.kt
@@ -4,14 +4,27 @@ import org.bukkit.command.Command
import org.bukkit.command.CommandExecutor
import org.bukkit.command.CommandSender
-class RankingCommand : CommandExecutor {
+class RankingCommand(
+ private val playerStatsService: PlayerStatsService,
+) : CommandExecutor {
override fun onCommand(
sender: CommandSender,
command: Command,
label: String,
args: Array,
): Boolean {
- sender.sendMessage("LogTime plugin is working!")
+ val rankedList = playerStatsService.getPlayerRankings()
+
+ if (rankedList.isEmpty()) {
+ sender.sendMessage("No players found.")
+ return true
+ }
+
+ sender.sendMessage("--- 総プレイ時間ランキング ---")
+ rankedList.forEachIndexed { index, rankData ->
+ val rank = index + 1
+ sender.sendMessage("$rank. ${rankData.playerName} - ${rankData.formattedPlayTime}")
+ }
return true
}