diff --git a/README.md b/README.md deleted file mode 100644 index d8b09fd..0000000 --- a/README.md +++ /dev/null @@ -1,142 +0,0 @@ -# 服务器整合包使用指南 - -本仓库存放自动生成的最小客户端整合包,用于连接到 jianfgit.xyz Minecraft 服务器。 - -## 如何获取和使用此整合包 - -此整合包采用 Modrinth 格式,包含连接服务器所需的所有模组和 TACZ 弹药包。 - -### 前置条件 - -1. **Minecraft Java Edition 1.20.1** -2. **Forge 加载器** (1.20.1 版本) -3. 支持 Modrinth 整合包格式的启动器: - - Prism 启动器 (推荐) - - Modrinth 应用程序 - - PolyMC - - ATLauncher - - 或任何支持 Modrinth 索引文件的启动器 - -### 获取整合包的方法 - -#### 方法 1:通过服务器管理员获取(推荐) - -由于这是一个私有仓库,普通用户无法直接访问。请按照以下步骤操作: - -1. 联系服务器管理员获取最新的整合包文件 -2. 管理员会提供: - - `modrinth.index.json` 文件(整合包索引) - - `truemods/` 目录中的所有模组文件(.jar) - - `truegunpacks/` 目录中的所有 TACZ 弹药包文件(.zip) - -#### 方法 2:自行克隆仓库(如果有权限) - -如果您被授予了仓库访问权限: - -1. 克隆私有仓库: - ```bash - git clone ssh://git@jianfgit.xyz:220/jianf/servermods.git - ``` - -2. 导航到仓库目录: - ```bash - cd servermods - ``` - -3. 您将看到以下目录和文件: - - `modpack/modrinth.index.json` - 整合包索引文件 - - `truemods/` - 所有必需的模组文件(.jar) - - `truegunpacks/` - 所有必需的 TACZ 弹药包文件(.zip) - -### 安装整合包 - -一旦您获得了整合包文件: - -1. **创建整合包文件夹结构** - ``` - minimal-client-modpack/ - ├── mods/ - └── tacz/ - ``` - -2. **复制所需文件** - - 将 `truemods/` 目录中的所有 .jar 文件复制到 `mods/` 文件夹 - - 将 `truegunpacks/` 目录中的所有 .zip 文件复制到 `tacz/` 文件夹 - -3. **安装 Forge** - - 从 https://files.minecraftforge.net/ 下载 Forge 1.20.1 - - 运行安装程序并选择 "安装客户端" - -4. **启动 Minecraft** - - 在您的 Minecraft 启动器中,创建一个新安装 - - 选择您安装的 Forge 版本 (1.20.1) - - 将游戏目录设置为您的 `minimal-client-modpack` 文件夹 - - 启动游戏 - -### 使用 Prism 启动器的一键导入(如果可用) - -如果您能够访问仓库且启动器支持自定义索引位置: - -1. 在 Prism 启动器中创建新实例 -2. 选择 "Modrinth" 作为源类型 -3. 在索引URL字段中指向您获得的 `modrinth.index.json` 文件的本地路径 -4. 启动器将自动处理文件下载和安装 - -## 重要提示 - -### 版本匹配 -- 整合包版本 **必须** 完全匹配服务器期望的版本 -- 如果您看到 "服务器握手失败" 或 "无效会话" 错误,这通常表示版本不匹配 -- 请始终确保您拥有最新版本通过定期更新整合包 - -### 更新整合包 -- 服务器上的整合包每 12 小时自动更新一次 -- 获取更新的方法: - 1. 向服务器管理员请求最新的整合包文件 - 2. 如果有仓库访问权限:执行 `git pull` 然后重新获取文件 - 3. 重复上述安装步骤以更新文件 - -## 故障排除 - -### "缺失模组" 错误 -1. 验证 `modrinth.index.json` 中列出的所有文件都存在于您的 `mods/` 和 `tacz/` 文件夹中 -2. 检查文件名是否完全匹配(区分大小写) -3. 验证您下载了正确的版本(高级用户可检查 SHA1 哈希值) - -### "模组加载错误" 或崩溃 -1. 确保您使用的是 Forge 1.20.1,而不是其他版本 -2. 检查是否有与整合包冲突的其他模组安装在外部 -3. 尝试删除所有模组,然后从零开始使用索引重新安装 - -### 连接问题 -1. 确认服务器地址正确 -2. 验证您的互联网连接 -3. 检查服务器是否在线且未维护 -4. 确保您的整合包版本与服务器当前版本匹配 - -## 技术细节 - -此整合包采用官方 Modrinth 索引格式版本 1: -- `formatVersion`: 1 -- `game.type`: "forge" -- `game.version`: "1.20.1" -- `versionId`: 十进制版本(例如:"0.0.12") -- `files.array`: 包含对象的列表,每个对象包含: - - `path`: 模组包内文件位置(`mods/` 或 `tacz/`) - - `hashes.sha1`: 用于文件验证的 SHA1 哈希值 - - `env.client`: ["required"] - 客户端必需 - - `env.server`: ["unsupported"] - 服务器端不需要/不允许 - - `downloads`: [] - 空数组,因为文件分发方式由用户自行处理 - -TACZ(弹药)包被视为常规模组,但为了组织目的存储在 `tacz/` 子文件夹中。它们对于在此服务器上获得完整游戏体验是必需的。 - -系统会自动: -1. 监控 `/tmp/server_mods.txt` 变化 -2. 生成 Modrinth 格式索引 (`modpack/modrinth.index.json`) -3. 将实际模组文件复制到 `truemods/` 目录(排除客户端-only 视觉mod) -4. 将实际 TACZ 弹药包复制到 `truegunpacks/` 目录 -5. 提交并推送更改到 git 仓库 -6. 使用十进制版本号递增(0.0.1, 0.0.2, etc.) -7. **通过 QQ 机器人自动推送更新公告到群**(群号: 814734369) - -如需进一步帮助,请联系服务器管理员。 \ No newline at end of file diff --git a/sync_minimal.py b/sync_minimal.py deleted file mode 100755 index 6c7385b..0000000 --- a/sync_minimal.py +++ /dev/null @@ -1,216 +0,0 @@ -#!/usr/bin/env python3 -import os -import re -import shutil -import hashlib -import json -import urllib.request -from datetime import datetime - -REPO_DIR = "/tmp/mod_repo" -SERVER_MODS_FILE = "/tmp/server_mods.txt" -MINECRAFT_MODS_DIR = "/home/minecraft/mods" -TACZ_DIR = "/home/minecraft/tacz" -STATE_DIR = f"{REPO_DIR}/state" -MODPACK_DIR = f"{REPO_DIR}/modpack" -VERSION_FILE = f"{REPO_DIR}/VERSION" -TRUEMODS_DIR = f"{REPO_DIR}/truemods" -TRUEGUNPACKS_DIR = f"{REPO_DIR}/truegunpacks" -QQ_GROUP_ID = "814734369" # Minecraft group -QQ_API_URL = "http://192.168.2.106:25570" - -CLIENT_ONLY_MODS = [ - "xaero", "ambient", "apple", "inventoryprofiles", - "chunky", "patchouli", "worldedit", "spark", "customskinloader", "gd656killicon" -] - -def log(msg): - ts = datetime.now().strftime("%Y-%m-%d %H:%M:%S") - print(f"[{ts}] {msg}") - -def get_mod_name(jar_path): - basename = os.path.basename(jar_path) - name = re.sub(r'-\d+.*\.jar$', '', basename) - name = re.sub(r'^\[.*?\]\s*', '', name) - return name - -def is_client_only(mod_name): - mod_lower = mod_name.lower() - for client_mod in CLIENT_ONLY_MODS: - if client_mod in mod_lower: - return True - return False - -def get_hash(path): - with open(path, 'rb') as f: - return hashlib.sha1(f.read()).hexdigest() - -def load_previous_state(): - prev_mods = [] - prev_excluded = [] - if os.path.exists(f"{STATE_DIR}/mods.json"): - with open(f"{STATE_DIR}/mods.json", 'r') as f: - prev_mods = [line.strip() for line in f if line.strip()] - if os.path.exists(f"{STATE_DIR}/excluded_mods.json"): - with open(f"{STATE_DIR}/excluded_mods.json", 'r') as f: - prev_excluded = json.load(f) - return prev_mods, prev_excluded - -def sync_minimal_pack(): - for d in [TRUEMODS_DIR, TRUEGUNPACKS_DIR]: - if os.path.exists(d): - shutil.rmtree(d) - os.makedirs(d) - - with open(SERVER_MODS_FILE, 'r') as f: - server_mods = [line.strip() for line in f if line.strip() and not line.startswith('disabled')] - - included, excluded = [], [] - - for mod in server_mods: - base_name = re.sub(r'-\d+.*$', '', mod) - jar_file = None - for f in os.listdir(MINECRAFT_MODS_DIR): - if f.startswith(base_name) and f.endswith('.jar'): - jar_file = os.path.join(MINECRAFT_MODS_DIR, f) - break - - if jar_file: - mod_name = get_mod_name(jar_file) - filename = os.path.basename(jar_file) - if is_client_only(mod_name): - excluded.append(filename) - else: - shutil.copy(jar_file, TRUEMODS_DIR) - included.append(filename) - - if os.path.exists(TACZ_DIR): - for f in os.listdir(TACZ_DIR): - if f.endswith('.zip'): - shutil.copy(os.path.join(TACZ_DIR, f), TRUEGUNPACKS_DIR) - - return sorted(included), sorted(excluded), sorted(os.listdir(TRUEGUNPACKS_DIR)) - -def create_index(version, mods, gunpacks): - lines = ['{', ' "formatVersion": 1,', ' "game": {', ' "type": "forge",', - ' "version": "1.20.1"', ' },', f' "versionId": "{version}",', - ' "name": "minimal-client-modpack",', - ' "summary": "Minimal client modpack for connecting to the server"', ' "files": ['] - - first = True - for mod in mods: - path = f"{TRUEMODS_DIR}/{mod}" - if os.path.exists(path): - h = get_hash(path) - if not first: lines.append(',') - first = False - lines.append(f' {{"path": "mods/{mod}", "hashes": {{"sha1": "{h}"}}, "env": {{"client": ["required"], "server": ["unsupported"]}}, "downloads": []}}') - - for gp in gunpacks: - path = f"{TRUEGUNPACKS_DIR}/{gp}" - if os.path.exists(path): - h = get_hash(path) - if not first: lines.append(',') - first = False - lines.append(f' {{"path": "tacz/{gp}", "hashes": {{"sha1": "{h}"}}, "env": {{"client": ["required"], "server": ["unsupported"]}}, "downloads": []}}') - - lines.extend([' ]', '}']) - os.makedirs(MODPACK_DIR, exist_ok=True) - with open(f"{MODPACK_DIR}/modrinth.index.json", 'w') as f: - f.write('\n'.join(lines)) - -def send_qq_message(message): - try: - url = f"{QQ_API_URL}/send_group_msg" - data = json.dumps({ - "group_id": int(QQ_GROUP_ID), - "message": message - }).encode('utf-8') - req = urllib.request.Request(url, data=data, headers={'Content-Type': 'application/json'}) - with urllib.request.urlopen(req, timeout=10) as response: - result = json.loads(response.read().decode('utf-8')) - if result.get('status') == 'ok': - log("QQ notification sent successfully") - else: - log(f"QQ notification failed: {result}") - except Exception as e: - log(f"Failed to send QQ message: {e}") - -def main(): - log("Starting minimal modpack synchronization") - os.makedirs(STATE_DIR, exist_ok=True) - - prev_mods, prev_excluded = load_previous_state() - included, excluded, gunpacks = sync_minimal_pack() - - current = open(VERSION_FILE).read().strip() if os.path.exists(VERSION_FILE) else "0.0.0" - parts = current.split('.') - new_version = f"{parts[0]}.{parts[1]}.{int(parts[2]) + 1}" - - # Check for changes - mods_changed = set(included) != set(prev_mods) if prev_mods else True - - if mods_changed: - log(f"Mod changes detected: {len(included)} mods now") - - # Find added and removed mods - prev_set = set(prev_mods) if prev_mods else set() - curr_set = set(included) - added_mods = curr_set - prev_set - removed_mods = prev_set - curr_set - - # Create change summary - change_summary = [] - if added_mods: - change_summary.append(f"新增模组 ({len(added_mods)}):\n" + "\n".join([f" + {m}" for m in list(added_mods)[:5]])) - if len(added_mods) > 5: - change_summary.append(f" ... 及其他 {len(added_mods) - 5} 个") - if removed_mods: - change_summary.append(f"移除模组 ({len(removed_mods)}):\n" + "\n".join([f" - {m}" for m in list(removed_mods)[:5]])) - if len(removed_mods) > 5: - change_summary.append(f" ... 及其他 {len(removed_mods) - 5} 个") - - # Send QQ notification - qq_message = f"""📦 整合包更新公告 -━━━━━━━━━━━━━━━━━━━━━━ -版本: v{new_version} -模组数量: {len(included)} 个 (+{len(added_mods) if added_mods else 0} -{len(removed_mods) if removed_mods else 0}) -枪包数量: {len(gunpacks)} 个 -━━━━━━━━━━━━━━━━━━━━━━ -""" - if change_summary: - qq_message += "\n".join(change_summary) + "\n" - qq_message += """━━━━━━━━━━━━━━━━━━━━━━ -📥 下载地址: ssh://git@192.168.2.106:220/jianf/servermods.git -或联系管理员获取最新整合包""" - - send_qq_message(qq_message) - - create_index(new_version, included, gunpacks) - open(VERSION_FILE, 'w').write(new_version) - - with open(f"{STATE_DIR}/mods.json", 'w') as f: - f.write('\n'.join(included)) - with open(f"{STATE_DIR}/excluded_mods.json", 'w') as f: - json.dump(excluded, f) - with open(f"{STATE_DIR}/gunpacks.json", 'w') as f: - f.write('\n'.join(gunpacks)) - - log(f"Version: {new_version}") - log(f"Mods: {len(included)} included, {len(excluded)} excluded (client-only)") - log(f"Gunpacks: {len(gunpacks)}") - - log("Updating git repository") - os.system("cd /tmp/mod_repo && git add -A >/dev/null 2>&1") - result = os.popen("cd /tmp/mod_repo && git commit -m 'Update minimal modpack to version " + new_version + "' 2>&1").read() - if "nothing to commit" not in result: - log("Pushing to remote") - os.system("cd /tmp/mod_repo && git push origin main >/dev/null 2>&1 &") - log(f"Successfully pushed version {new_version}") - else: - log("No changes to commit") - - log("Synchronization completed") - -if __name__ == "__main__": - main() diff --git a/sync_minimal.sh b/sync_minimal.sh deleted file mode 100755 index fe73ae3..0000000 --- a/sync_minimal.sh +++ /dev/null @@ -1,140 +0,0 @@ -#!/usr/bin/env python3 -import os -import re -import shutil -import hashlib - -REPO_DIR = "/tmp/mod_repo" -SERVER_MODS_FILE = "/tmp/server_mods.txt" -MINECRAFT_MODS_DIR = "/home/minecraft/mods" -TACZ_DIR = "/home/minecraft/tacz" -STATE_DIR = f"{REPO_DIR}/state" -MODPACK_DIR = f"{REPO_DIR}/modpack" -VERSION_FILE = f"{REPO_DIR}/VERSION" -TRUEMODS_DIR = f"{REPO_DIR}/truemods" -TRUEGUNPACKS_DIR = f"{REPO_DIR}/truegunpacks" - -CLIENT_ONLY_MODS = [ - "jei", "xaero", "ambient", "apple", "inventoryprofiles", - "chunky", "patchouli", "worldedit", "spark", "customskinloader", "gd656killicon" -] - -def log(msg): - print(f"[{os.popen('date \"+%Y-%m-%d %H:%M:%S\"').read().strip()}] {msg}") - -def get_mod_name(jar_path): - basename = os.path.basename(jar_path) - name = re.sub(r'-\d+.*\.jar$', '', basename) - name = re.sub(r'^\[.*?\]\s*', '', name) - return name - -def is_client_only(mod_name): - mod_lower = mod_name.lower() - for client_mod in CLIENT_ONLY_MODS: - if client_mod in mod_lower: - return True - return False - -def get_hash(path): - with open(path, 'rb') as f: - return hashlib.sha1(f.read()).hexdigest() - -def sync_minimal_pack(): - for d in [TRUEMODS_DIR, TRUEGUNPACKS_DIR]: - if os.path.exists(d): - shutil.rmtree(d) - os.makedirs(d) - - with open(SERVER_MODS_FILE, 'r') as f: - server_mods = [line.strip() for line in f if line.strip() and not line.startswith('disabled')] - - included, excluded = [], [] - - for mod in server_mods: - base_name = re.sub(r'-\d+.*$', '', mod) - jar_file = None - for f in os.listdir(MINECRAFT_MODS_DIR): - if f.startswith(base_name) and f.endswith('.jar'): - jar_file = os.path.join(MINECRAFT_MODS_DIR, f) - break - - if jar_file: - mod_name = get_mod_name(jar_file) - filename = os.path.basename(jar_file) - if is_client_only(mod_name): - excluded.append(filename) - else: - shutil.copy(jar_file, TRUEMODS_DIR) - included.append(filename) - - if os.path.exists(TACZ_DIR): - for f in os.listdir(TACZ_DIR): - if f.endswith('.zip'): - shutil.copy(os.path.join(TACZ_DIR, f), TRUEGUNPACKS_DIR) - - return sorted(included), sorted(excluded), sorted(os.listdir(TRUEGUNPACKS_DIR)) - -def create_index(version, mods, gunpacks): - lines = ['{', ' "formatVersion": 1,', ' "game": {', ' "type": "forge",', - ' "version": "1.20.1"', ' },', f' "versionId": "{version}",', - ' "name": "minimal-client-modpack",', - ' "summary": "Minimal client modpack for connecting to the server"', ' "files": ['] - - first = True - for mod in mods: - path = f"{TRUEMODS_DIR}/{mod}" - if os.path.exists(path): - h = get_hash(path) - if not first: lines.append(',') - first = False - lines.append(f' {{"path": "mods/{mod}", "hashes": {{"sha1": "{h}"}}, "env": {{"client": ["required"], "server": ["unsupported"]}}, "downloads": []}}') - - for gp in gunpacks: - path = f"{TRUEGUNPACKS_DIR}/{gp}" - if os.path.exists(path): - h = get_hash(path) - if not first: lines.append(',') - first = False - lines.append(f' {{"path": "tacz/{gp}", "hashes": {{"sha1": "{h}"}}, "env": {{"client": ["required"], "server": ["unsupported"]}}, "downloads": []}}') - - lines.extend([' ]', '}']) - os.makedirs(MODPACK_DIR, exist_ok=True) - with open(f"{MODPACK_DIR}/modrinth.index.json", 'w') as f: - f.write('\n'.join(lines)) - -def main(): - log("Starting minimal modpack synchronization") - os.makedirs(STATE_DIR, exist_ok=True) - - included, excluded, gunpacks = sync_minimal_pack() - - current = open(VERSION_FILE).read().strip() if os.path.exists(VERSION_FILE) else "0.0.0" - parts = current.split('.') - new_version = f"{parts[0]}.{parts[1]}.{int(parts[2]) + 1}" - open(VERSION_FILE, 'w').write(new_version) - - create_index(new_version, included, gunpacks) - - with open(f"{STATE_DIR}/mods.json", 'w') as f: - f.write('\n'.join(included)) - with open(f"{STATE_DIR}/gunpacks.json", 'w') as f: - f.write('\n'.join(gunpacks)) - - log(f"Version: {new_version}") - log(f"Mods included: {len(included)} (excluded {len(excluded)} client-only)") - log(f"Gunpacks: {len(gunpacks)}") - - log("Updating git repository") - os.system("cd /tmp/mod_repo && git add -A >/dev/null 2>&1") - result = os.popen("cd /tmp/mod_repo && git commit -m 'Update minimal modpack to version {0}' 2>&1".format(new_version)).read() - if "nothing to commit" not in result: - log("Pushing to remote") - os.system("cd /tmp/mod_repo && git push origin main >/dev/null 2>&1 &") - log(f"Successfully pushed version {new_version}") - else: - log("No changes to commit") - - log("Synchronization completed") - -if __name__ == "__main__": - main() diff --git a/sync_modpack.sh b/sync_modpack.sh deleted file mode 100755 index 6084e6d..0000000 --- a/sync_modpack.sh +++ /dev/null @@ -1,277 +0,0 @@ -#!/bin/bash - -set -euo pipefail - -REPO_DIR="/tmp/mod_repo" -SERVER_MODS_FILE="/tmp/server_mods.txt" -MINECRAFT_MODS_DIR="/home/minecraft/mods" -TACCZ_DIR="/home/minecraft/tacz" -STATE_DIR="$REPO_DIR/state" -MODPACK_DIR="$REPO_DIR/modpack" -VERSION_FILE="$REPO_DIR/VERSION" -GIT_REPO="ssh://git@jianfgit.xyz:220/jianf/servermods.git" -MODRINTH_INDEX="$MODPACK_DIR/modrinth.index.json" -TRUEMODS_DIR="$REPO_DIR/truemods" -TRUEGUNPACKS_DIR="$REPO_DIR/truegunpacks" - -log() { - echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" -} - -get_current_version() { - if [[ -f "$VERSION_FILE" ]]; then - cat "$VERSION_FILE" - else - echo "0.0.0" - fi -} - -increment_version() { - local version="$1" - IFS='.' read -r major minor patch <<< "$version" - patch=$((patch + 1)) - echo "$major.$minor.$patch" -} - -get_file_hash() { - local file_path="$1" - if [[ -f "$file_path" ]]; then - sha1sum "$file_path" | awk '{print $1}' - else - echo "0000000000000000000000000000000000000000" - fi -} - -find_mod_file() { - local base_name="$1" - local mod_file - mod_file=$(find "$MINECRAFT_MODS_DIR" -name "${base_name}-*.jar" | head -1 || echo "") - if [[ -z "$mod_file" ]]; then - mod_file="$MINECRAFT_MODS_DIR/${base_name}.jar" - if [[ ! -f "$mod_file" ]]; then - echo "" - else - echo "$mod_file" - fi - else - echo "$mod_file" - fi -} - -find_gunpack_file() { - local base_name="$1" - local gunpack_file - gunpack_file=$(find "$TACCZ_DIR" -name "${base_name}*" | head -1 || echo "") - if [[ -z "$gunpack_file" ]]; then - gunpack_file="$TACCZ_DIR/${base_name}" - if [[ ! -f "$gunpack_file" ]]; then - echo "" - else - echo "$gunpack_file" - fi - else - echo "$gunpack_file" - fi -} - -create_modrinth_index() { - local version="$1" - local mods_json="$2" - local gunpacks_json="$3" - - { - echo '{' - echo ' "formatVersion": 1,' - echo ' "game": {' - echo ' "type": "forge",' - echo ' "version": "1.20.1"' - echo ' },' - echo " \"versionId\": \"$version\"," - echo ' "name": "minimal-client-modpack",' - echo ' "summary": "Minimal client modpack for connecting to the server",' - echo ' "files": [' - } > "$MODRINTH_INDEX" - - local first=true - while IFS= read -r mod; do - if [[ -n "$mod" ]]; then - local mod_path - mod_path=$(find_mod_file "$mod") - - if [[ -n "$mod_path" && -f "$mod_path" ]]; then - local mod_filename - mod_filename=$(basename "$mod_path") - local hash - hash=$(get_file_hash "$mod_path") - if [[ "$first" == true ]]; then - first=false - else - echo ',' >> "$MODRINTH_INDEX" - fi - { - echo ' {' - echo ' "path": "mods/'"$mod_filename"'",' - echo ' "hashes": {' - echo " \"sha1\": \"$hash\"" - echo ' },' - echo ' "env": {' - echo ' "client": ["required"],' - echo ' "server": ["unsupported"]' - echo ' },' - echo ' "downloads": []' - echo ' }' - } >> "$MODRINTH_INDEX" - fi - fi - done < "$mods_json" - - while IFS= read -r gunpack; do - if [[ -n "$gunpack" ]]; then - gunpack=$(echo "$gunpack" | sed 's/^"//' | sed 's/"$//') - local gunpack_path - gunpack_path=$(find_gunpack_file "$gunpack") - - if [[ -n "$gunpack_path" && -f "$gunpack_path" ]]; then - local gunpack_filename - gunpack_filename=$(basename "$gunpack_path") - local hash - hash=$(get_file_hash "$gunpack_path") - echo ',' >> "$MODRINTH_INDEX" - { - echo ' {' - echo ' "path": "tacz/'"$gunpack_filename"'",' - echo ' "hashes": {' - echo " \"sha1\": \"$hash\"" - echo ' },' - echo ' "env": {' - echo ' "client": ["required"],' - echo ' "server": ["unsupported"]' - echo ' },' - echo ' "downloads": []' - echo ' }' - } >> "$MODRINTH_INDEX" - fi - fi - done < "$gunpacks_json" - - { - echo ' ]' - echo '}' - } >> "$MODRINTH_INDEX" -} - -sync_mods() { - mkdir -p "$TRUEMODS_DIR" - while IFS= read -r mod; do - if [[ -n "$mod" ]]; then - local mod_path - mod_path=$(find_mod_file "$mod") - if [[ -n "$mod_path" && -f "$mod_path" ]]; then - cp "$mod_path" "$TRUEMODS_DIR/" - log "Copied $mod_path to $TRUEMODS_DIR/" - fi - fi - done < "$1" -} - -sync_gunpacks() { - mkdir -p "$TRUEGUNPACKS_DIR" - while IFS= read -r gunpack; do - if [[ -n "$gunpack" ]]; then - gunpack=$(echo "$gunpack" | sed 's/^"//' | sed 's/"$//') - local gunpack_path - gunpack_path=$(find_gunpack_file "$gunpack") - if [[ -n "$gunpack_path" && -f "$gunpack_path" ]]; then - cp "$gunpack_path" "$TRUEGUNPACKS_DIR/" - log "Copied $gunpack_path to $TRUEGUNPACKS_DIR/" - fi - fi - done < "$1" -} - -main() { - log "Starting modpack synchronization" - - mkdir -p "$STATE_DIR" - mkdir -p "$MODPACK_DIR" - mkdir -p "$REPO_DIR/tacz" - mkdir -p "$TRUEMODS_DIR" - mkdir -p "$TRUEGUNPACKS_DIR" - - if [[ ! -f "$SERVER_MODS_FILE" ]]; then - log "ERROR: Server mods file not found: $SERVER_MODS_FILE" - exit 1 - fi - - if [[ ! -d "$MINECRAFT_MODS_DIR" ]]; then - log "ERROR: Minecraft mods directory not found: $MINECRAFT_MODS_DIR" - exit 1 - fi - - if [[ ! -d "$TACCZ_DIR" ]]; then - log "ERROR: TACCZ directory not found: $TACCZ_DIR" - exit 1 - fi - - grep -v "^disabled$" "$SERVER_MODS_FILE" | sed 's/-[0-9].*$//' | sort > "$STATE_DIR/current_mods_sorted.txt" - - local has_changes=false - if [[ -f "$STATE_DIR/mods.json" && -f "$STATE_DIR/gunpacks.json" ]]; then - if ! cmp -s "$STATE_DIR/current_mods_sorted.txt" "$STATE_DIR/mods.json"; then - log "Mod list has changed" - has_changes=true - else - log "Mod list unchanged" - fi - log "Checking gunpacks for changes" - has_changes=true - else - log "No previous state found, treating as initial run" - has_changes=true - fi - - if [[ "$has_changes" == true ]]; then - log "Changes detected, updating modpack" - - cp "$STATE_DIR/current_mods_sorted.txt" "$STATE_DIR/mods.json" 2>/dev/null || true - - ls -1 "$TACCZ_DIR"/*.zip 2>/dev/null | xargs -I{} basename {} > "$STATE_DIR/gunpacks.json" || echo "" > "$STATE_DIR/gunpacks.json" - - local current_version - current_version=$(get_current_version) - local new_version - new_version=$(increment_version "$current_version") - log "Version update: $current_version -> $new_version" - - # Sync actual files to truemods and truegunpacks directories - log "Syncing mod files to truemods directory" - sync_mods "$STATE_DIR/mods.json" - - log "Syncing gunpack files to truegunpacks directory" - sync_gunpacks "$STATE_DIR/gunpacks.json" - - # Create Modrinth index - create_modrinth_index "$new_version" "$STATE_DIR/mods.json" "$STATE_DIR/gunpacks.json" - - echo "$new_version" > "$VERSION_FILE" - - log "Updating git repository" - git add "$MODRINTH_INDEX" "$VERSION_FILE" "$STATE_DIR/mods.json" "$STATE_DIR/gunpacks.json" - git add "$TRUEMODS_DIR/"* "$TRUEGUNPACKS_DIR/"* 2>/dev/null || true - - if ! git diff --cached --quiet; then - git commit -m "Update modpack to version $new_version" - log "Pushing to remote repository" - git push origin main - log "Successfully pushed version $new_version" - else - log "No changes to commit" - fi - else - log "No changes detected, skipping update" - fi - - log "Modpack synchronization completed" -} - -main "$@" diff --git a/sync_modpack.sh.backup b/sync_modpack.sh.backup deleted file mode 100755 index 79b1d22..0000000 --- a/sync_modpack.sh.backup +++ /dev/null @@ -1,217 +0,0 @@ -#!/bin/bash - -set -euo pipefail - -REPO_DIR="/tmp/mod_repo" -SERVER_MODS_FILE="/tmp/server_mods.txt" -MINECRAFT_MODS_DIR="/home/minecraft/mods" -STATE_DIR="$REPO_DIR/state" -MODPACK_DIR="$REPO_DIR/modpack" -VERSION_FILE="$REPO_DIR/VERSION" -GIT_REPO="ssh://git@jianfgit.xyz:220/jianf/servermods.git" -MODRINTH_INDEX="$MODPACK_DIR/modrinth.index.json" - -log() { - echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" -} - -get_current_version() { - if [[ -f "$VERSION_FILE" ]]; then - cat "$VERSION_FILE" - else - echo "0.0.0" - fi -} - -increment_version() { - local version="$1" - IFS='.' read -r major minor patch <<< "$version" - patch=$((patch + 1)) - echo "$major.$minor.$patch" -} - -get_file_hash() { - local file_path="$1" - if [[ -f "$file_path" ]]; then - sha1sum "$file_path" | awk '{print $1}' - else - echo "0000000000000000000000000000000000000000" - fi -} - -find_mod_file() { - local base_name="$1" - # Find the actual mod file that starts with the base name - local mod_file - mod_file=$(find "$MINECRAFT_MODS_DIR" -name "${base_name}-*.jar" | head -1 || echo "") - if [[ -z "$mod_file" ]]; then - # Try exact match as fallback - mod_file="$MINECRAFT_MODS_DIR/${base_name}.jar" - if [[ ! -f "$mod_file" ]]; then - echo "" - else - echo "$mod_file" - fi - else - echo "$mod_file" - fi -} - -create_modrinth_index() { - local version="$1" - local mods_json="$2" - local gunpacks_json="$3" - - # Start building the JSON - { - echo '{' - echo ' "formatVersion": 1,' - echo ' "game": {' - echo ' "type": "forge",' - echo ' "version": "1.20.1"' - echo ' },' - echo " \"versionId\": \"$version\"," - echo ' "name": "minimal-client-modpack",' - echo ' "summary": "Minimal client modpack for connecting to the server",' - echo ' "files": [' - } > "$MODRINTH_INDEX" - - local first=true - # Process mods - while IFS= read -r mod; do - if [[ -n "$mod" ]]; then - local mod_path - mod_path=$(find_mod_file "$mod") - - if [[ -n "$mod_path" && -f "$mod_path" ]]; then - local mod_filename - mod_filename=$(basename "$mod_path") - local hash - hash=$(get_file_hash "$mod_path") - if [[ "$first" == true ]]; then - first=false - else - echo ',' >> "$MODRINTH_INDEX" - fi - { - echo ' {' - echo ' "path": "mods/'"$mod_filename"'",' - echo ' "hashes": {' - echo " \"sha1\": \"$hash\"" - echo ' },' - echo ' "env": {' - echo ' "client": ["required"],' - echo ' "server": ["unsupported"]' - echo ' },' - echo ' "downloads": []' - echo ' }' - } >> "$MODRINTH_INDEX" - fi - fi - done < "$mods_json" - - # Process gunpacks - while IFS= read -r gunpack; do - if [[ -n "$gunpack" ]]; then - gunpack=$(echo "$gunpack" | sed 's/^"//' | sed 's/"$//') - local gunpack_path - gunpack_path=$(find "$REPO_DIR/tacz" -name "$gunpack" -type f | head -1 || echo "") - - if [[ -n "$gunpack_path" && -f "$gunpack_path" ]]; then - local hash - hash=$(get_file_hash "$gunpack_path") - echo ',' >> "$MODRINTH_INDEX" - { - echo ' {' - echo ' "path": "tacz/'"$gunpack"'",' - echo ' "hashes": {' - echo " \"sha1\": \"$hash\"" - echo ' },' - echo ' "env": {' - echo ' "client": ["required"],' - echo ' "server": ["unsupported"]' - echo ' },' - echo ' "downloads": []' - echo ' }' - } >> "$MODRINTH_INDEX" - fi - fi - done < "$gunpacks_json" - - # Close the JSON array and object - { - echo ' ]' - echo '}' - } >> "$MODRINTH_INDEX" -} - -main() { - log "Starting modpack synchronization" - - mkdir -p "$STATE_DIR" - mkdir -p "$MODPACK_DIR" - mkdir -p "$REPO_DIR/tacz" # Ensure tacz directory exists - - if [[ ! -f "$SERVER_MODS_FILE" ]]; then - log "ERROR: Server mods file not found: $SERVER_MODS_FILE" - exit 1 - fi - - if [[ ! -d "$MINECRAFT_MODS_DIR" ]]; then - log "ERROR: Minecraft mods directory not found: $MINECRAFT_MODS_DIR" - exit 1 - fi - - grep -v "^disabled$" "$SERVER_MODS_FILE" | sed 's/-[0-9].*$//' | sort > "$STATE_DIR/current_mods_sorted.txt" - - local has_changes=false - if [[ -f "$STATE_DIR/mods.json" && -f "$STATE_DIR/gunpacks.json" ]]; then - if ! cmp -s "$STATE_DIR/current_mods_sorted.txt" "$STATE_DIR/mods.json"; then - log "Mod list has changed" - has_changes=true - else - log "Mod list unchanged" - fi - log "Checking gunpacks for changes" - has_changes=true - else - log "No previous state found, treating as initial run" - has_changes=true - fi - - if [[ "$has_changes" == true ]]; then - log "Changes detected, updating modpack" - - cp "$STATE_DIR/current_mods_sorted.txt" "$STATE_DIR/mods.json" 2>/dev/null || true - - ls -1 "$REPO_DIR/tacz"/*.zip 2>/dev/null | xargs -I{} basename {} > "$STATE_DIR/gunpacks.json" || echo "" > "$STATE_DIR/gunpacks.json" - - local current_version - current_version=$(get_current_version) - local new_version - new_version=$(increment_version "$current_version") - log "Version update: $current_version -> $new_version" - - create_modrinth_index "$new_version" "$STATE_DIR/mods.json" "$STATE_DIR/gunpacks.json" - - echo "$new_version" > "$VERSION_FILE" - - log "Updating git repository" - git add "$MODRINTH_INDEX" "$VERSION_FILE" "$STATE_DIR/mods.json" "$STATE_DIR/gunpacks.json" - - if ! git diff --cached --quiet; then - git commit -m "Update modpack to version $new_version" - log "Pushing to remote repository" - git push origin main - log "Successfully pushed version $new_version" - else - log "No changes to commit" - fi - else - log "No changes detected, skipping update" - fi - - log "Modpack synchronization completed" -} - -main "$@" \ No newline at end of file