Remove scripts from repository - keeping only mods and mod lists
This commit is contained in:
142
README.md
142
README.md
@ -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)
|
||||
|
||||
如需进一步帮助,请联系服务器管理员。
|
||||
216
sync_minimal.py
216
sync_minimal.py
@ -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()
|
||||
140
sync_minimal.sh
140
sync_minimal.sh
@ -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()
|
||||
277
sync_modpack.sh
277
sync_modpack.sh
@ -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 "$@"
|
||||
@ -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 "$@"
|
||||
Reference in New Issue
Block a user