RRRRRRRRRRRRRRRR
This commit is contained in:
parent
e5eca44059
commit
245103cf44
103
README.md
103
README.md
@ -1,24 +1,87 @@
|
||||
# 一个服务器在线玩家时间以及服务器状态的简单的mod
|
||||
## 简体中文
|
||||
|
||||
[English](https://git.branulf.top/Branulf/ServerPlayerOnlineTracker/src/branch/master/README_EN.md)
|
||||
|
||||
注意:本mod并不完善,可能会存在些许的bug
|
||||
### 包含功能:
|
||||
* 显示/记录服务器在线玩家时间
|
||||
* 显示服务器状态
|
||||
* 显示服务器在线玩家列表
|
||||
* ~~移除游戏中的Herobrine~~
|
||||
# ServerPlayerOnlineTracker - 服务器玩家在线及状态追踪
|
||||
|
||||
### 使用方法:
|
||||
1. 安装Fabric Loader和Fabric API
|
||||
2. 将最新版本的mod放入mods文件夹
|
||||
3. 首次启动服务器自动生成配置文件
|
||||
4. 修改Web服务器端口(默认60048),语言(目前仅支持zh_cn和en_us),自动保存时间(默认300秒)
|
||||
5. 如需在外部访问请确保端口已开放
|
||||
一个简单的 Fabric 服务器端 Mod,用于追踪玩家在线时长、显示服务器实时状态,并提供一个美观的网页界面。
|
||||
|
||||
### API获取数据:
|
||||
*(也许可以用于机器人?)*
|
||||
* 获取服务器在线玩家列表:【服务器IP+配置的端口】+`/api/online-players`
|
||||
* 获取服务器状态:【服务器IP+配置的端口】+`/api/server-status`
|
||||
* 获取服务器在线玩家时间:【服务器IP+配置的端口】+`/api/stats`
|
||||
* 获取服务器在线玩家数量:【服务器IP+配置的端口】+`/api/player-count`
|
||||
* ~~原始数据文件:【服务器IP+配置的端口】+`/api/playerdata`~~
|
||||
## 主要功能
|
||||
|
||||
* **玩家在线时长追踪**
|
||||
* 记录玩家总在线时长、最近30天和最近7天的在线时长。
|
||||
* 支持仅追踪白名单玩家(可在配置文件中设置)。
|
||||
* 数据自动保存,防止服务器崩溃导致数据丢失。
|
||||
* **服务器状态监控**
|
||||
* 实时显示服务器内存使用情况(已用/可用/使用率)。
|
||||
* 实时显示服务器磁盘使用情况(总量/已用/可用/使用率)。
|
||||
* 实时显示服务器性能指标(TPS/MSPT)。
|
||||
* 显示服务器运行时间、版本、在线玩家数、最大玩家数、MOTD、处理器核心数。
|
||||
* **网页界面**
|
||||
* 提供一个直观、响应式的网页界面,方便查看所有统计数据。
|
||||
* 支持深色/浅色主题切换。
|
||||
* 数据自动刷新。
|
||||
* **游戏内命令**
|
||||
* `/onlineTime [页码]`:在游戏内查看玩家在线时长排行榜。
|
||||
* **多语言支持**
|
||||
* 支持简体中文 (`zh_cn`) 和英文 (`en_us`)。
|
||||
* 可在配置文件中切换语言。
|
||||
* **更新检查**
|
||||
* Mod 启动时自动检查新版本。
|
||||
|
||||
## 安装
|
||||
|
||||
1. 确保您的 Minecraft 服务器已安装 Fabric Loader (推荐 0.15.0+)。
|
||||
2. 下载最新版本的 `ServerPlayerOnlineTracker-*.jar` 文件。
|
||||
3. 将下载的 `.jar` 文件放入服务器的 `mods` 文件夹。
|
||||
4. 启动服务器。
|
||||
|
||||
## 使用方法
|
||||
|
||||
### 网页界面
|
||||
|
||||
Mod 启动后,会自动在您配置的端口(默认 `60048`)启动一个 Web 服务器。
|
||||
|
||||
1. 在浏览器中访问 `http://您的服务器IP:60048` 即可查看所有统计数据。
|
||||
2. 如果端口被占用或您想更改端口,请修改 `config/playertime-config.json` 文件中的 `webPort` 字段。
|
||||
|
||||
### 游戏内命令
|
||||
|
||||
* `/onlineTime`:查看第一页玩家在线时长排行榜。
|
||||
* `/onlineTime <页码>`:查看指定页码的玩家在线时长排行榜。
|
||||
|
||||
## 配置文件
|
||||
|
||||
首次运行 Mod 后,会在服务器根目录的 `config` 文件夹下生成一个 `playertime-config.json` 文件。您可以编辑此文件来调整 Mod 的行为。
|
||||
|
||||
```json
|
||||
{
|
||||
"webPort": 60048, // 网页服务器监听的端口,默认 60048
|
||||
"language": "zh_cn", // 网页和游戏内消息的语言,可选 "zh_cn" 或 "en_us"
|
||||
"whitelistOnly": true, // 是否只追踪和显示白名单玩家的在线时间,默认 true
|
||||
"saveIntervalMinutes": 5 // 自动保存玩家数据的时间间隔(分钟),默认 5 分钟,设置为 0 禁用
|
||||
}
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
[API文档](https://git.branulf.top/Branulf/ServerPlayerOnlineTracker/src/branch/master/README_API.md)
|
||||
|
||||
## 兼容性
|
||||
|
||||
* **Minecraft 版本:** 1.21.4+
|
||||
* **Fabric Loader:** 0.16.10+
|
||||
* **依赖:** Fabric API
|
||||
|
||||
## 许可证
|
||||
|
||||
本项目基于 [GPL3 许可证](https://www.gnu.org/licenses/gpl-3.0.en.html) 开源。
|
||||
|
||||
## 链接
|
||||
|
||||
* **源代码:** [https://git.branulf.top/Branulf/ServerPlayerOnlineTracker](https://git.branulf.top/Branulf/ServerPlayerOnlineTracker)
|
||||
* **主页:** [https://git.branulf.top/Branulf](https://git.branulf.top/Branulf)
|
||||
|
||||
## 鸣谢
|
||||
|
||||
* **作者:** BRanulf
|
230
README_API.md
Normal file
230
README_API.md
Normal file
@ -0,0 +1,230 @@
|
||||
### 可用 API 接口
|
||||
|
||||
本 Mod 提供了一系列 RESTful API 接口,允许外部应用获取服务器的玩家在线数据和实时状态。所有 API 接口均通过 HTTP GET 请求访问。
|
||||
|
||||
**基础 URL:** `http://您的服务器IP:配置的端口` (默认端口为 `60048`)
|
||||
|
||||
---
|
||||
|
||||
#### `GET /api/stats`
|
||||
|
||||
* **描述:** 获取所有玩家的在线时长统计数据。
|
||||
* **响应:** JSON 数组,每个元素代表一个玩家的统计信息。
|
||||
* **响应示例结构:**
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"playerName": "玩家名称",
|
||||
"uuid": "114514-1919810",
|
||||
"totalTimeSeconds": 123456,
|
||||
"totalTimeFormatted": "34h 17m",
|
||||
"last30DaysSeconds": 54321,
|
||||
"last30DaysFormatted": "15h 05m",
|
||||
"last7DaysSeconds": 9876,
|
||||
"last7DaysFormatted": "02h 44m"
|
||||
}
|
||||
// ... 更多玩家
|
||||
]
|
||||
```
|
||||
|
||||
* **字段说明:**
|
||||
* `playerName` (String): 玩家名称。
|
||||
* `uuid` (String): 玩家的 UUID。
|
||||
* `totalTimeSeconds` (long): 总在线时长(秒)。
|
||||
* `totalTimeFormatted` (String): 总在线时长(格式化字符串,例如 "34h 17m")。
|
||||
* `last30DaysSeconds` (long): 最近 30 天在线时长(秒)。
|
||||
* `last30DaysFormatted` (String): 最近 30 天在线时长(格式化字符串)。
|
||||
* `last7DaysSeconds` (long): 最近 7 天在线时长(秒)。
|
||||
* `last7DaysFormatted` (String): 最近 7 天在线时长(格式化字符串)。
|
||||
|
||||
---
|
||||
|
||||
#### `GET /api/lang`
|
||||
|
||||
* **描述:** 获取 Mod 当前加载的本地化语言字符串。
|
||||
* **注意:** 此接口主要用于内部调试和网页前端加载语言,不建议公开暴露。
|
||||
* **响应:** JSON 对象,键为语言字符串的 key,值为对应的翻译文本。
|
||||
* **响应示例结构:**
|
||||
|
||||
```json
|
||||
{
|
||||
"playertime.command.title": "§6===== 玩家在线时长 (第 {0}/{1} 页) =====",
|
||||
"playertime.web.title": "玩家在线及状态统计",
|
||||
// ... 更多语言键值对
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### `GET /api/online-players`
|
||||
|
||||
* **描述:** 获取当前在线玩家的列表,按白名单状态分类。
|
||||
* **响应:** JSON 对象,包含两个列表:`whitelisted` 和 `non_whitelisted`。
|
||||
* **响应示例结构:**
|
||||
|
||||
```json
|
||||
{
|
||||
"whitelisted": [
|
||||
{
|
||||
"name": "WhitelistedPlayer1",
|
||||
"uuid": "114514-1919810"
|
||||
}
|
||||
],
|
||||
"non_whitelisted": [
|
||||
{
|
||||
"name": "NonWhitelistedPlayer1",
|
||||
"uuid": "51121-55555121"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
* **字段说明:**
|
||||
* `whitelisted` (List<Map<String, String>>): 白名单在线玩家列表。每个 Map 包含 `name` (玩家名称) 和 `uuid` (玩家 UUID)。
|
||||
* `non_whitelisted` (List<Map<String, String>>): 非白名单在线玩家列表。每个 Map 包含 `name` (玩家名称) 和 `uuid` (玩家 UUID)。
|
||||
|
||||
---
|
||||
|
||||
#### `GET /api/player-count`
|
||||
|
||||
* **描述:** 获取当前在线玩家的数量统计。
|
||||
* **响应:** JSON 对象,包含总数、白名单玩家数和非白名单玩家数。
|
||||
* **响应示例结构:**
|
||||
|
||||
```json
|
||||
{
|
||||
"total": 10,
|
||||
"whitelisted": 8,
|
||||
"non_whitelisted": 2
|
||||
}
|
||||
```
|
||||
|
||||
* **字段说明:**
|
||||
* `total` (int): 在线玩家总数。
|
||||
* `whitelisted` (int): 在线白名单玩家数。
|
||||
* `non_whitelisted` (int): 在线非白名单玩家数(通常指假人或未在白名单的玩家)。
|
||||
|
||||
---
|
||||
|
||||
#### `GET /api/whitelist`
|
||||
|
||||
* **描述:** 获取服务器的白名单列表。
|
||||
* **响应:** JSON 数组,每个元素代表一个白名单玩家的信息。
|
||||
* **响应示例结构:**
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"name": "BRanulf",
|
||||
"uuid": "114514-1919810",
|
||||
"online": true
|
||||
},
|
||||
{
|
||||
"name": "DarkSharkBee",
|
||||
"uuid": "51121-55555121",
|
||||
"online": false
|
||||
}
|
||||
// ... 更多白名单玩家
|
||||
]
|
||||
```
|
||||
|
||||
* **字段说明:**
|
||||
* `name` (String): 白名单玩家名称。
|
||||
* `uuid` (String): 白名单玩家的 UUID。
|
||||
* `online` (boolean): 该玩家当前是否在线。
|
||||
|
||||
---
|
||||
|
||||
#### `GET /api/server-status`
|
||||
|
||||
* **描述:** 获取服务器的详细运行状态信息。
|
||||
* **响应:** JSON 对象,包含内存、磁盘、处理器、运行时间及服务器自身信息。
|
||||
* **响应示例结构:**
|
||||
|
||||
```json
|
||||
{
|
||||
"memory": {
|
||||
"max": 8589934592,
|
||||
"total": 8589934592,
|
||||
"used": 2147483648,
|
||||
"free": 6442450944,
|
||||
"usage_percentage": 25.0
|
||||
},
|
||||
"disk": {
|
||||
"total": 1073741824000,
|
||||
"free": 536870912000,
|
||||
"usable": 536870912000,
|
||||
"usage_percentage": 50.0
|
||||
},
|
||||
"available_processors": 8,
|
||||
"uptime": 3600,
|
||||
"uptime_formatted": "01小时 00分钟 00秒",
|
||||
"server": {
|
||||
"version": "1.21.4",
|
||||
"motd": "§aWelcome to My Server!",
|
||||
"player_count": 5,
|
||||
"max_players": 20,
|
||||
"average_tick_time_ms": 15.23,
|
||||
"recent_tick_samples_ms": [14.5, 16.1, 15.0, 15.8, ...]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
* **字段说明:**
|
||||
* `memory` (Object): 内存统计信息。
|
||||
* `max` (long): JVM 可用的最大内存(字节)。
|
||||
* `total` (long): JVM 当前分配的总内存(字节)。
|
||||
* `used` (long): JVM 已使用的内存(字节)。
|
||||
* `free` (long): JVM 可用的空闲内存(字节)。
|
||||
* `usage_percentage` (double): 内存使用率(已用 / 最大 * 100)。
|
||||
* `disk` (Object): 磁盘统计信息。
|
||||
* `total` (long): 磁盘总空间(字节)。
|
||||
* `free` (long): 磁盘空闲空间(字节)。
|
||||
* `usable` (long): 磁盘可用空间(字节)。
|
||||
* `usage_percentage` (double): 磁盘使用率((总 - 空闲) / 总 * 100)。
|
||||
* `available_processors` (int): 服务器可用的处理器核心数。
|
||||
* `uptime` (long): 服务器运行时间(秒)。
|
||||
* `uptime_formatted` (String): 服务器运行时间(格式化字符串,例如 "01小时 00分钟 00秒")。
|
||||
* `server` (Object): Minecraft 服务器自身信息。
|
||||
* `version` (String): Minecraft 服务器版本。
|
||||
* `motd` (String): 服务器 MOTD。
|
||||
* `player_count` (int): 当前在线玩家数。
|
||||
* `max_players` (int): 服务器最大玩家容量。
|
||||
* `average_tick_time_ms` (double): 服务器平均 Tick 时间(毫秒,即 MSPT)。
|
||||
* `recent_tick_samples_ms` (List<Double>): 最近的 Tick 时间样本(毫秒)。
|
||||
|
||||
---
|
||||
|
||||
#### `GET /api/playerdata`
|
||||
|
||||
* **描述:** 获取原始的玩家在线时间数据文件内容。
|
||||
* **警告:** 此接口直接暴露服务器的玩家数据文件内容,包含 UUID 和在线时间等敏感信息。**强烈建议不要将此接口公开暴露给外部网络。**
|
||||
* **响应:** JSON 对象,内容与 `player_time_data.json` 文件完全一致。
|
||||
* **响应示例结构:**
|
||||
|
||||
```json
|
||||
{
|
||||
"114514-1919810": {
|
||||
"totalTime": 123456,
|
||||
"lastLogin": 0, // 0 表示离线,非 0 表示上次登录时间戳
|
||||
"rolling30Days": {
|
||||
"days": 30,
|
||||
"entries": [
|
||||
{ "timestamp": 1678886400, "seconds": 3600 },
|
||||
// ...
|
||||
]
|
||||
},
|
||||
"rolling7Days": {
|
||||
"days": 7,
|
||||
"entries": [
|
||||
{ "timestamp": 1678886400, "seconds": 1800 },
|
||||
// ...
|
||||
]
|
||||
}
|
||||
},
|
||||
"51121-55555121": {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
```
|
103
README_EN.md
103
README_EN.md
@ -1,24 +1,87 @@
|
||||
# A simple mod for tracking online player time and server status
|
||||
## English
|
||||
|
||||
[中文简体](https://git.branulf.top/Branulf/ServerPlayerOnlineTracker/src/branch/master/README.md)
|
||||
|
||||
Note: This mod is not perfect and may have some bugs.
|
||||
### Features include:
|
||||
* Display/record server online player time
|
||||
* Show server status
|
||||
* Display a list of online players on the server
|
||||
* ~~Remove Herobrine from the game~~
|
||||
# ServerPlayerOnlineTracker - Server Player Online & Status Tracker
|
||||
|
||||
### How to use:
|
||||
1. Install Fabric Loader and Fabric API.
|
||||
2. Place the latest version of the mod into the mods folder.
|
||||
3. The configuration file will be generated automatically when starting the server for the first time.
|
||||
4. Modify the web server port (default 60048), language (currently only supports zh_cn and en_us), and automatic save interval (default 300 seconds).
|
||||
5. If external access is needed, ensure that the port is open.
|
||||
A simple Fabric server-side mod designed to track player online time, display real-time server status, and provide a beautiful web interface.
|
||||
|
||||
### API data retrieval:
|
||||
*(Maybe can be used for bots?)*
|
||||
* Get a list of online players on the server: [Server IP + configured port] + `/api/online-players`
|
||||
* Get server status: [Server IP + configured port] + `/api/server-status`
|
||||
* Get online player time on the server: [Server IP + configured port] + `/api/stats`
|
||||
* Get number of online players on the server: [Server IP + configured port] + `/api/player-count`
|
||||
* ~~Raw data file: [Server IP + configured port] + `/api/playerdata`~~
|
||||
## Key Features
|
||||
|
||||
* **Player Online Time Tracking**
|
||||
* Records total online time, last 30 days, and last 7 days online time for players.
|
||||
* Supports tracking whitelisted players only (configurable in the config file).
|
||||
* Automatic data saving to prevent data loss from server crashes.
|
||||
* **Server Status Monitoring**
|
||||
* Real-time display of server memory usage (used/available/percentage).
|
||||
* Real-time display of server disk usage (total/used/available/percentage).
|
||||
* Real-time display of server performance metrics (TPS/MSPT).
|
||||
* Shows server uptime, version, current player count, max players, MOTD, and processor cores.
|
||||
* **Web Interface**
|
||||
* Provides an intuitive and responsive web interface for easy viewing of all statistics.
|
||||
* Supports dark/light theme toggling.
|
||||
* Automatic data refresh.
|
||||
* **In-Game Command**
|
||||
* `/onlineTime [page]` to view the player online time leaderboard in-game.
|
||||
* **Multi-language Support**
|
||||
* Supports Simplified Chinese (`zh_cn`) and English (`en_us`).
|
||||
* Language can be switched in the configuration file.
|
||||
* **Update Checker**
|
||||
* Automatically checks for new mod versions on startup.
|
||||
|
||||
## Installation
|
||||
|
||||
1. Ensure you have Fabric Loader installed on your Minecraft server (recommended 0.15.0+).
|
||||
2. Download the latest `ServerPlayerOnlineTracker-*.jar` file.
|
||||
3. Place the downloaded `.jar` file into your server's `mods` folder.
|
||||
4. Start your server.
|
||||
|
||||
## Usage
|
||||
|
||||
### Web Interface
|
||||
|
||||
After the mod starts, a web server will automatically launch on your configured port (default `60048`).
|
||||
|
||||
1. Access it in your browser by navigating to `http://YOUR_SERVER_IP:60048` to view all statistics.
|
||||
2. If the port is occupied or you wish to change it, modify the `webPort` field in the `config/playertime-config.json` file.
|
||||
|
||||
### In-Game Command
|
||||
|
||||
* `/onlineTime`: View the first page of the player online time leaderboard.
|
||||
* `/onlineTime <page>`: View a specific page of the player online time leaderboard.
|
||||
|
||||
## Configuration
|
||||
|
||||
Upon the first run of the mod, a `playertime-config.json` file will be generated in your server's `config` folder. You can edit this file to adjust the mod's behavior.
|
||||
|
||||
```json
|
||||
{
|
||||
"webPort": 60048, // Port for the web server to listen on, default 60048
|
||||
"language": "zh_cn", // Language for web and in-game messages, options: "zh_cn" or "en_us"
|
||||
"whitelistOnly": true, // Whether to track and display online time only for whitelisted players, default true
|
||||
"saveIntervalMinutes": 5 // Interval for automatic player data saving in minutes, default 5 minutes, set to 0 to disable
|
||||
}
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
[API Documentation](https://git.branulf.top/Branulf/ServerPlayerOnlineTracker/src/branch/master/README_API.md)
|
||||
|
||||
## Compatibility
|
||||
|
||||
* **Minecraft Version:** 1.21.4+
|
||||
* **Fabric Loader:** 0.16.10+
|
||||
* **Dependencies:** Fabric API
|
||||
|
||||
## License
|
||||
|
||||
This project is open-source under the [GPL3 License](https://www.gnu.org/licenses/gpl-3.0.en.html).
|
||||
|
||||
## Links
|
||||
|
||||
* **Source Code:** [https://git.branulf.top/Branulf/ServerPlayerOnlineTracker](https://git.branulf.top/Branulf/ServerPlayerOnlineTracker)
|
||||
* **Homepage:** [https://git.branulf.top/Branulf](https://git.branulf.top/Branulf)
|
||||
|
||||
## Credits
|
||||
|
||||
* **Author:** BRanulf
|
110
build.gradle
110
build.gradle
@ -1,96 +1,46 @@
|
||||
plugins {
|
||||
id 'fabric-loom' version '1.9.2'
|
||||
id 'maven-publish'
|
||||
id 'fabric-loom' version '1.10.5' apply false
|
||||
id 'com.replaymod.preprocess' version '9d21b334a7'
|
||||
|
||||
id 'com.github.johnrengelman.shadow' version '8.1.1' apply false
|
||||
}
|
||||
|
||||
version = project.mod_version
|
||||
group = project.maven_group
|
||||
|
||||
base {
|
||||
archivesName = project.archives_base_name
|
||||
preprocess {
|
||||
strictExtraMappings.set(false)
|
||||
def mc12104 = createNode("1.21.4", 1_21_04, "")
|
||||
def mc12105 = createNode("1.21.5", 1_21_05, "")
|
||||
def mc12106 = createNode("1.21.6", 1_21_06, "")
|
||||
def mc12107 = createNode("1.21.7", 1_21_07, "")
|
||||
|
||||
mc12107.link(mc12106, file("versions/mapping_12107_12106.txt"))
|
||||
mc12106.link(mc12105, file("versions/mapping_12106_12105.txt"))
|
||||
mc12105.link(mc12104, file("versions/mapping_12105_12104.txt"))
|
||||
}
|
||||
|
||||
|
||||
repositories {
|
||||
// Add repositories to retrieve artifacts from in here.
|
||||
// You should only use this when depending on other mods because
|
||||
// Loom adds the essential maven repositories to download Minecraft and libraries from automatically.
|
||||
// See https://docs.gradle.org/current/userguide/declaring_repositories.html
|
||||
// for more information about repositories.
|
||||
}
|
||||
|
||||
dependencies {
|
||||
// To change the versions see the gradle.properties file
|
||||
minecraft "com.mojang:minecraft:${project.minecraft_version}"
|
||||
mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2"
|
||||
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
|
||||
|
||||
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
|
||||
implementation 'com.google.code.gson:gson:2.8.9'
|
||||
}
|
||||
|
||||
processResources {
|
||||
inputs.property "version", project.version
|
||||
inputs.property "minecraft_version", project.minecraft_version
|
||||
inputs.property "loader_version", project.loader_version
|
||||
filteringCharset "UTF-8"
|
||||
|
||||
filesMatching("fabric.mod.json") {
|
||||
expand "version": project.version,
|
||||
"minecraft_version": project.minecraft_version,
|
||||
"loader_version": project.loader_version
|
||||
tasks.register('buildAndGather') {
|
||||
subprojects {
|
||||
dependsOn project.tasks.named('build').get()
|
||||
}
|
||||
|
||||
// from(sourceSets.main.resources.srcDirs) {
|
||||
// include "assets/**"
|
||||
// }
|
||||
}
|
||||
|
||||
def targetJavaVersion = 21
|
||||
tasks.withType(JavaCompile).configureEach {
|
||||
// ensure that the encoding is set to UTF-8, no matter what the system default is
|
||||
// this fixes some edge cases with special characters not displaying correctly
|
||||
// see http://yodaconditions.net/blog/fix-for-java-file-encoding-problems-with-gradle.html
|
||||
// If Javadoc is generated, this must be specified in that task too.
|
||||
it.options.encoding = "UTF-8"
|
||||
if (targetJavaVersion >= 10 || JavaVersion.current().isJava10Compatible()) {
|
||||
it.options.release.set(targetJavaVersion)
|
||||
doFirst {
|
||||
println 'Gathering builds'
|
||||
def buildLibs = {
|
||||
p -> p.buildDir.toPath().resolve('libs')
|
||||
}
|
||||
}
|
||||
|
||||
java {
|
||||
def javaVersion = JavaVersion.toVersion(targetJavaVersion)
|
||||
if (JavaVersion.current() < javaVersion) {
|
||||
toolchain.languageVersion = JavaLanguageVersion.of(targetJavaVersion)
|
||||
delete fileTree(buildLibs(rootProject)) {
|
||||
include '*'
|
||||
}
|
||||
// Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task
|
||||
// if it is present.
|
||||
// If you remove this line, sources will not be generated.
|
||||
withSourcesJar()
|
||||
}
|
||||
|
||||
jar {
|
||||
from("LICENSE") {
|
||||
rename { "${it}_${project.archivesBaseName}" }
|
||||
subprojects {
|
||||
copy {
|
||||
from(buildLibs(project)) {
|
||||
include '*.jar'
|
||||
exclude '*-dev.jar', '*-sources.jar', '*-shadow.jar'
|
||||
}
|
||||
}
|
||||
|
||||
// configure the maven publication
|
||||
publishing {
|
||||
publications {
|
||||
create("mavenJava", MavenPublication) {
|
||||
artifactId = project.archives_base_name
|
||||
from components.java
|
||||
into buildLibs(rootProject)
|
||||
duplicatesStrategy DuplicatesStrategy.INCLUDE
|
||||
}
|
||||
}
|
||||
|
||||
// See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing.
|
||||
repositories {
|
||||
// Add repositories to publish to here.
|
||||
// Notice: This block does NOT have the same function as the block in the top level.
|
||||
// The repositories here will be used for publishing your artifact, not for
|
||||
// retrieving dependencies.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
144
common.gradle
Normal file
144
common.gradle
Normal file
@ -0,0 +1,144 @@
|
||||
apply plugin: 'maven-publish'
|
||||
apply plugin: 'com.github.johnrengelman.shadow'
|
||||
apply plugin: 'fabric-loom'
|
||||
apply plugin: 'com.replaymod.preprocess'
|
||||
|
||||
int mcVersion = project.mcVersion
|
||||
|
||||
repositories {
|
||||
maven {
|
||||
url 'https://maven.fabricmc.net/'
|
||||
}
|
||||
maven {
|
||||
url 'https://masa.dy.fi/maven'
|
||||
}
|
||||
maven {
|
||||
url 'https://maven.fallenbreath.me/releases'
|
||||
}
|
||||
maven {
|
||||
url 'https://jitpack.io'
|
||||
}
|
||||
maven {
|
||||
url 'https://www.cursemaven.com'
|
||||
}
|
||||
maven { url "https://maven.shedaniel.me/" }
|
||||
maven {url "https://maven.terraformersmc.com/"}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
minecraft "com.mojang:minecraft:${project.minecraft_version}" // 从子项目
|
||||
mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2" // 从子项目
|
||||
modImplementation "net.fabricmc:fabric-loader:${rootProject.loader_version}" // 从根项目
|
||||
|
||||
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_api_version}"
|
||||
|
||||
implementation 'com.google.code.gson:gson:2.8.9'
|
||||
}
|
||||
|
||||
|
||||
JavaVersion JAVA_COMPATIBILITY
|
||||
if (mcVersion >= 12100) {
|
||||
JAVA_COMPATIBILITY = JavaVersion.VERSION_21
|
||||
} else if (mcVersion >= 11800) {
|
||||
JAVA_COMPATIBILITY = JavaVersion.VERSION_17
|
||||
} else if (mcVersion >= 11700) {
|
||||
JAVA_COMPATIBILITY = JavaVersion.VERSION_16
|
||||
} else {
|
||||
JAVA_COMPATIBILITY = JavaVersion.VERSION_1_8
|
||||
}
|
||||
JavaVersion MIXIN_COMPATIBILITY_LEVEL = JAVA_COMPATIBILITY
|
||||
|
||||
loom {
|
||||
def commonVmArgs = ['-Dmixin.debug.export=true']
|
||||
runConfigs.configureEach {
|
||||
runDir '../../run'
|
||||
vmArgs commonVmArgs
|
||||
ideConfigGenerated true
|
||||
}
|
||||
}
|
||||
|
||||
shadowJar {
|
||||
configurations = [project.configurations.shadow]
|
||||
exclude("META-INF")
|
||||
archiveClassifier.set('shadow')
|
||||
}
|
||||
|
||||
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
||||
|
||||
tasks.withType(ShadowJar).configureEach {
|
||||
enableRelocation true
|
||||
relocationPrefix 'branulf.playertime.libs'
|
||||
}
|
||||
|
||||
remapJar {
|
||||
dependsOn(shadowJar)
|
||||
mustRunAfter(shadowJar)
|
||||
inputFile = shadowJar.archiveFile
|
||||
}
|
||||
|
||||
String modVersionSuffix = ''
|
||||
if (System.getenv("BUILD_RELEASE") != "true") {
|
||||
String buildNumber = System.getenv("BUILD_ID")
|
||||
modVersionSuffix += buildNumber != null ? ('+build.' + buildNumber) : ''
|
||||
}
|
||||
String fullModVersion = rootProject.mod_version + modVersionSuffix
|
||||
|
||||
String fullProjectVersion
|
||||
|
||||
group = rootProject.maven_group
|
||||
if (System.getenv("JITPACK") == "true") {
|
||||
base.archivesName = rootProject.archives_base_name + '-mc' + project.minecraft_version
|
||||
fullProjectVersion = 'v' + rootProject.mod_version + modVersionSuffix
|
||||
} else {
|
||||
base.archivesName = rootProject.archives_base_name
|
||||
fullProjectVersion = 'v' + rootProject.mod_version + '-mc' + project.minecraft_version + modVersionSuffix
|
||||
}
|
||||
version = fullProjectVersion
|
||||
|
||||
processResources {
|
||||
inputs.property "id", rootProject.mod_id
|
||||
inputs.property "name", rootProject.mod_name
|
||||
inputs.property "version", fullModVersion
|
||||
|
||||
filesMatching("fabric.mod.json") {
|
||||
def valueMap = [
|
||||
"id" : rootProject.mod_id,
|
||||
"name" : rootProject.mod_name,
|
||||
"version" : fullModVersion,
|
||||
"minecraft_version": project.minecraft_dependency,
|
||||
"loader_version" : rootProject.loader_version
|
||||
]
|
||||
expand valueMap
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
tasks.withType(JavaCompile).configureEach {
|
||||
options.encoding = "UTF-8"
|
||||
options.compilerArgs << "-Xlint:deprecation" << "-Xlint:unchecked"
|
||||
if (JAVA_COMPATIBILITY <= JavaVersion.VERSION_1_8) {
|
||||
options.compilerArgs << '-Xlint:-options'
|
||||
}
|
||||
}
|
||||
|
||||
java {
|
||||
sourceCompatibility = JAVA_COMPATIBILITY
|
||||
targetCompatibility = JAVA_COMPATIBILITY
|
||||
withSourcesJar()
|
||||
}
|
||||
|
||||
jar {
|
||||
from(rootProject.file('LICENSE')) {
|
||||
rename { "${it}_${rootProject.archives_base_name}" }
|
||||
}
|
||||
}
|
||||
|
||||
//publishing {
|
||||
// publications {
|
||||
// mavenJava(MavenPublication) {
|
||||
// from components.java
|
||||
// }
|
||||
// }
|
||||
// repositories {
|
||||
// }
|
||||
//}
|
@ -6,7 +6,9 @@ minecraft_version=1.21.4
|
||||
yarn_mappings=1.21.4+build.8
|
||||
loader_version=0.16.10
|
||||
# Mod Properties
|
||||
mod_version=1.14.514.141
|
||||
mod_name=Disc Jockey Revive
|
||||
mod_id=disc_jockey_revive
|
||||
mod_version=1.14.514.144
|
||||
maven_group=org.example1
|
||||
archives_base_name=ServerPlayerOnlineTracker
|
||||
# Dependencies
|
||||
|
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,6 +1,6 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https://mirrors.aliyun.com/macports/distfiles/gradle/gradle-8.11.1-bin.zip
|
||||
distributionUrl=https://mirrors.aliyun.com/macports/distfiles/gradle/gradle-8.12.1-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
@ -1,9 +1,35 @@
|
||||
import groovy.json.JsonSlurper
|
||||
|
||||
pluginManagement {
|
||||
repositories {
|
||||
maven {
|
||||
name = 'Fabric'
|
||||
url = 'https://maven.fabricmc.net/'
|
||||
}
|
||||
maven {
|
||||
name = 'Jitpack'
|
||||
url = 'https://jitpack.io'
|
||||
}
|
||||
mavenCentral()
|
||||
gradlePluginPortal()
|
||||
}
|
||||
resolutionStrategy {
|
||||
eachPlugin {
|
||||
switch (requested.id.id) {
|
||||
case "com.replaymod.preprocess": {
|
||||
useModule("com.github.Fallen-Breath:preprocessor:${requested.version}")
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def settings = new JsonSlurper().parseText(file('settings.json').text)
|
||||
for (String version : settings.versions) {
|
||||
include(":$version")
|
||||
|
||||
def proj = project(":$version")
|
||||
proj.projectDir = file("versions/$version")
|
||||
proj.buildFileName = "../../common.gradle"
|
||||
}
|
||||
|
8
settings.json
Normal file
8
settings.json
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"versions": [
|
||||
"1.21.4",
|
||||
"1.21.5",
|
||||
"1.21.6",
|
||||
"1.21.7"
|
||||
]
|
||||
}
|
@ -1,6 +1,5 @@
|
||||
package com.example.playertime;
|
||||
package org.branulf.playertime;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
@ -12,7 +11,7 @@ import java.text.MessageFormat;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
// 这个是gemini写的 (保留原注释,但代码已根据需求调整)
|
||||
// 这个是AI写的 (保留原注释,但代码已根据需求调整)
|
||||
public class LocalizationManager {
|
||||
private final Map<String, String> translations = new HashMap<>();
|
||||
private final String defaultLanguage = "zh_cn"; // 默认语言代码
|
@ -1,4 +1,4 @@
|
||||
package com.example.playertime;
|
||||
package org.branulf.playertime;
|
||||
|
||||
import com.google.gson.*;
|
||||
import java.io.*;
|
@ -1,4 +1,4 @@
|
||||
package com.example.playertime;
|
||||
package org.branulf.playertime;
|
||||
|
||||
import com.mojang.brigadier.arguments.IntegerArgumentType;
|
||||
import net.fabricmc.api.ModInitializer;
|
||||
@ -26,12 +26,10 @@ import org.w3c.dom.NodeList;
|
||||
import org.w3c.dom.Element;
|
||||
import java.net.URL;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class PlayerTimeMod implements ModInitializer {
|
||||
public static final Logger LOGGER = LoggerFactory.getLogger("PlayerTimeTracker");
|
||||
@ -223,11 +221,18 @@ public class PlayerTimeMod implements ModInitializer {
|
||||
|
||||
MutableText footer = Text.literal("");
|
||||
if (currentPage > 1) {
|
||||
//#if MC >= 12105
|
||||
//$ footer.append(Text.literal(localizationManager.getString("playertime.command.prev_page"))
|
||||
//$ .styled(style -> style.withClickEvent(new ClickEvent.RunCommand(
|
||||
//$ "/onlineTime " + (currentPage - 1)
|
||||
//$ )).withColor(Formatting.GREEN)));
|
||||
//#else
|
||||
footer.append(Text.literal(localizationManager.getString("playertime.command.prev_page"))
|
||||
.styled(style -> style.withClickEvent(new ClickEvent(
|
||||
ClickEvent.Action.RUN_COMMAND,
|
||||
"/onlineTime " + (currentPage - 1)
|
||||
)).withColor(Formatting.GREEN)));
|
||||
//#endif
|
||||
}
|
||||
|
||||
if (currentPage > 1 && currentPage < totalPages) {
|
||||
@ -240,11 +245,18 @@ public class PlayerTimeMod implements ModInitializer {
|
||||
if (currentPage > 1 || totalEntries > 0) {
|
||||
footer.append(" ");
|
||||
}
|
||||
//#if MC >= 12105
|
||||
//$ footer.append(Text.literal(localizationManager.getString("playertime.command.next_page"))
|
||||
//$ .styled(style -> style.withClickEvent(new ClickEvent.RunCommand(
|
||||
//$ "/onlineTime " + (currentPage + 1)
|
||||
//$ )).withColor(Formatting.GREEN)));
|
||||
//#else
|
||||
footer.append(Text.literal(localizationManager.getString("playertime.command.next_page"))
|
||||
.styled(style -> style.withClickEvent(new ClickEvent(
|
||||
ClickEvent.Action.RUN_COMMAND,
|
||||
"/onlineTime " + (currentPage + 1)
|
||||
)).withColor(Formatting.GREEN)));
|
||||
//#endif
|
||||
}
|
||||
|
||||
player.sendMessage(footer, false);
|
@ -1,4 +1,4 @@
|
||||
package com.example.playertime;
|
||||
package org.branulf.playertime;
|
||||
|
||||
import com.google.gson.*;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
@ -14,7 +14,6 @@ import java.nio.file.Path;
|
||||
import java.time.Instant;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class PlayerTimeTracker {
|
||||
private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
|
@ -1,18 +1,14 @@
|
||||
package com.example.playertime;
|
||||
package org.branulf.playertime;
|
||||
|
||||
import com.google.gson.*;
|
||||
import com.sun.net.httpserver.HttpServer;
|
||||
import com.sun.net.httpserver.HttpHandler;
|
||||
import com.sun.net.httpserver.HttpExchange;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.PlayerManager;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
|
||||
import java.io.*;
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.*;
|
||||
import java.util.*;
|
||||
@ -20,11 +16,11 @@ import java.util.concurrent.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
// 导入API类,别忘了
|
||||
import com.example.playertime.api.PlayerStatsResponse;
|
||||
import com.example.playertime.api.ServerStatusResponse;
|
||||
import com.example.playertime.api.OnlinePlayersResponse;
|
||||
import com.example.playertime.api.PlayerCountResponse;
|
||||
import com.example.playertime.api.WhitelistResponse;
|
||||
import org.branulf.playertime.api.PlayerStatsResponse;
|
||||
import org.branulf.playertime.api.ServerStatusResponse;
|
||||
import org.branulf.playertime.api.OnlinePlayersResponse;
|
||||
import org.branulf.playertime.api.PlayerCountResponse;
|
||||
import org.branulf.playertime.api.WhitelistResponse;
|
||||
|
||||
|
||||
public class WebServer {
|
@ -1,4 +1,4 @@
|
||||
package com.example.playertime.api;
|
||||
package org.branulf.playertime.api;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
@ -1,4 +1,4 @@
|
||||
package com.example.playertime.api;
|
||||
package org.branulf.playertime.api;
|
||||
|
||||
// 用于 /api/player-count 接口返回的玩家数量数据结构
|
||||
public class PlayerCountResponse {
|
@ -1,4 +1,4 @@
|
||||
package com.example.playertime.api;
|
||||
package org.branulf.playertime.api;
|
||||
|
||||
// 用于 /api/stats 接口返回的玩家统计数据结构
|
||||
public class PlayerStatsResponse {
|
@ -1,4 +1,4 @@
|
||||
package com.example.playertime.api;
|
||||
package org.branulf.playertime.api;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -1,4 +1,4 @@
|
||||
package com.example.playertime.api;
|
||||
package org.branulf.playertime.api;
|
||||
|
||||
// 用于 /api/whitelist 接口返回的白名单列表数据结构
|
||||
public class WhitelistResponse {
|
@ -1,5 +1,6 @@
|
||||
{
|
||||
"webPort": 60048,
|
||||
"language": "zh_cn",
|
||||
"autoSaveSeconds": 60
|
||||
"whitelistOnly": true,
|
||||
"saveIntervalMinutes": 5
|
||||
}
|
@ -16,12 +16,9 @@
|
||||
"environment": "server",
|
||||
"entrypoints": {
|
||||
"main": [
|
||||
"com.example.playertime.PlayerTimeMod"
|
||||
"org.branulf.playertime.PlayerTimeMod"
|
||||
]
|
||||
},
|
||||
"mixins": [
|
||||
"playertime.mixins.json"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=${loader_version}",
|
||||
"fabric": "*",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"required": true,
|
||||
"package": "com.example.playertime.mixins",
|
||||
"package": "org.branulf.playertime.mixins",
|
||||
"compatibilityLevel": "JAVA_21",
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
|
8
versions/1.21.4/gradle.properties
Normal file
8
versions/1.21.4/gradle.properties
Normal file
@ -0,0 +1,8 @@
|
||||
minecraft_version=1.21.4
|
||||
yarn_mappings=1.21.4+build.8
|
||||
|
||||
minecraft_dependency=1.21.4
|
||||
|
||||
game_versions=1.21.4
|
||||
|
||||
fabric_api_version=0.119.2+1.21.4
|
8
versions/1.21.5/gradle.properties
Normal file
8
versions/1.21.5/gradle.properties
Normal file
@ -0,0 +1,8 @@
|
||||
minecraft_version=1.21.5
|
||||
yarn_mappings=1.21.5+build.1
|
||||
|
||||
minecraft_dependency=1.21.5
|
||||
|
||||
game_versions=1.21.5
|
||||
|
||||
fabric_api_version=0.119.5+1.21.5
|
8
versions/1.21.6/gradle.properties
Normal file
8
versions/1.21.6/gradle.properties
Normal file
@ -0,0 +1,8 @@
|
||||
minecraft_version=1.21.6
|
||||
yarn_mappings=1.21.6+build.1
|
||||
|
||||
minecraft_dependency=1.21.6
|
||||
|
||||
game_versions=1.21.6
|
||||
|
||||
fabric_api_version=0.127.0+1.21.6
|
8
versions/1.21.7/gradle.properties
Normal file
8
versions/1.21.7/gradle.properties
Normal file
@ -0,0 +1,8 @@
|
||||
minecraft_version=1.21.7
|
||||
yarn_mappings=1.21.7+build.7
|
||||
|
||||
minecraft_dependency=1.21.7
|
||||
|
||||
game_versions=1.21.7
|
||||
|
||||
fabric_api_version=0.128.1+1.21.7
|
1
versions/mainProject
Normal file
1
versions/mainProject
Normal file
@ -0,0 +1 @@
|
||||
1.21.4
|
0
versions/mapping_12105_12104.txt
Normal file
0
versions/mapping_12105_12104.txt
Normal file
0
versions/mapping_12106_12105.txt
Normal file
0
versions/mapping_12106_12105.txt
Normal file
0
versions/mapping_12107_12106.txt
Normal file
0
versions/mapping_12107_12106.txt
Normal file
Loading…
x
Reference in New Issue
Block a user