最近开minecraft服务器,总担心存档爆炸,又不想冷备份,又不想加插件(这么多不想
所以开发了这样一款基于python和mcrcon的备份系统,只要搭配定时任务就可以啦,还有存档定时清理功能,
源码贴这里
import os
import shutil
import time
from datetime import datetime, timedelta
from mcrcon import MCRcon
# RCON配置
RCON_HOST = "127.0.0.1"
RCON_PORT = 25566 #改为你服务器rcon的端口
RCON_PASSWORD = "test" # 改成你设置的密码
# 目录配置
SERVER_DIR = r"D:\server" # 服务器目录
BACKUP_DIR = r"E:\backups" # 备份存放目录
WORLD_NAME = "world" # 世界文件夹名
# 备份保留策略
KEEP_DAYS = 30 # 保留最近30天的备份
def send_rcon(command):
try:
with MCRcon(RCON_HOST, RCON_PASSWORD, port=RCON_PORT) as mcr:
response = mcr.command(command)
print(f"[RCON] {command} -> {response}")
return response
except Exception as e:
print(f"[ERROR] RCON连接失败: {e}")
return None
def clean_old_backups():
if not os.path.exists(BACKUP_DIR):
return
cutoff = datetime.now() - timedelta(days=KEEP_DAYS)
deleted_count = 0
for item in os.listdir(BACKUP_DIR):
item_path = os.path.join(BACKUP_DIR, item)
if os.path.isdir(item_path):
try:
date_str = item.split("_")[0]
folder_date = datetime.strptime(date_str, "%Y-%m-%d")
if folder_date < cutoff:
shutil.rmtree(item_path)
deleted_count += 1
print(f"[CLEAN] 删除旧备份: {item}")
except (ValueError, IndexError):
continue
if deleted_count > 0:
print(f"[CLEAN] 共删除 {deleted_count} 个旧备份")
else:
print(f"[CLEAN] 没有超过 {KEEP_DAYS} 天的备份需要清理")
def backup():
print(f"\n{'='*50}")
print(f"[START] 备份开始: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
send_rcon("save-off")
time.sleep(1)
send_rcon("save-all")
time.sleep(3)
timestamp = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
backup_path = os.path.join(BACKUP_DIR, timestamp)
os.makedirs(backup_path, exist_ok=True)
world_path = os.path.join(SERVER_DIR, WORLD_NAME)
if not os.path.exists(world_path):
print(f"[ERROR] 世界目录不存在: {world_path}")
send_rcon("save-on")
return
print(f"[COPY] 正在复制世界存档...")
dest_path = os.path.join(backup_path, WORLD_NAME)
shutil.copytree(world_path, dest_path, ignore=shutil.ignore_patterns('session.lock'))
print(f"[COPY] 复制完成 -> {dest_path}")
send_rcon("save-on")
clean_old_backups()
print(f"[DONE] 备份完成: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
print(f"[DONE] 备份位置: {backup_path}")
print(f"{'='*50}\n")
if __name__ == "__main__":
try:
backup()
except Exception as e:
print(f"[ERROR] 备份过程中出现异常: {e}")
try:
send_rcon("save-on")
except:
pass
|