幻兽帕鲁服务器自动重启备份-python

幻兽帕鲁服务器自动重启备份-python

  • 1. 前置知识点
  • 2. 目录结构
  • 3. 代码内容
  • 4. 原理解释
  • 5. 额外备注

基于python编写的服务器全自动管理工具,能够实现自动定时备份存档,以及在检测到服务器崩溃之后自动重新启动,并且整合了对于frp端口转发工具的自动重启。

我受够这个服务器没完没了的崩溃了,别再整天艾特我开服了

如果对你的部署很有用,欢迎评论和点赞~

1. 前置知识点

幻兽帕鲁开服教程——游戏
架设游戏私服——内网穿透工具frp

需要掌握基本python编程知识,知道怎么部署python环境与修改配置路径。

2. 目录结构

|-pal_server_manage.bat
|-pal_server_manage.py

3. 代码内容

pal_server_manage.bat
这就是一个单纯方便双击启动运行的脚本。

python D:\servers\pal_server_manage.py

pal_server_manage.py
包含了初始化启动、自动备份与自动重启的功能。

import os
import time
import zipfile
import socket
import threading
import psutil
import subprocess


# 参数配置
class Config:
    # 服务器路径
    server_path = r"D:\servers\steamcmd\steamapps\common\PalServer\PalServer.exe"

    # 计算服务器应用程序名字
    server_name = os.path.split(server_path)[-1]

    # frp路径
    frp_path = r"D:\servers\frp\client\frpc.exe"
    frp_config = r"D:\servers\frp\client\frpc.ini"
    frp_name = os.path.split(frp_path)[-1]

    # 记录正在运行的服务器
    server = None
    frp = None

    # 是否使用自动重启
    use_auto_restart = True
    # 检测服务器是否在运行的间隔(秒)
    check_server_run_step = 10

    # 是否启动自动备份
    use_auto_backup = True
    # 备份的路径
    save_dir_path = r"D:\servers\steamcmd\steamapps\common\PalServer\Pal\Saved"
    # 备份的时间间隔(秒)
    save_time_step = 900
    # 备份的存档路径
    output_zip_path = r"D:\servers\save_backups\pal_save_backups"
    os.makedirs(os.path.split(output_zip_path)[-1], exist_ok=True)


# 将1个文件夹打包压缩为zip文件
def zip_file(src_dir, zip_path):
    z = zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED)
    count = 0
    for dirpath, _, filenames in os.walk(src_dir):
        fpath = dirpath.replace(src_dir, '')
        fpath = fpath and fpath + os.sep or ''
        length = len(filenames)
        for filename in filenames:
            z.write(os.path.join(dirpath, filename), os.path.split(src_dir)[1] + fpath + filename)
            count += 1
            print(f'\rzip file: {count}/{length}', end='')
    print(f'\nzip {src_dir} success!')
    z.close()


# 检测程序是否在运行
def is_program_running(program_name):
    # 扫描所有的进程id
    for pid in psutil.pids():
        try:
            # 如果进程名与服务器名一致,代表服务器正在运行
            if psutil.Process(pid).name() == program_name:
                return True
        except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
            pass
    # 扫描所有进程后,未找到服务器
    return False


# 获取当前可视化时间信息
def get_local_time():
    local = time.localtime(time.time())
    now = f"{local[0]:04d}_{local[1]:02d}_{local[2]:02d}_{local[3]:02d}_{local[4]:02d}_{local[5]:02d}"
    return now


# 自动备份线程
class auto_server_backup(threading.Thread):
    def __init__(self, threadID, name):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name

    def run(self):
        while True:
            # 压缩存档文件夹到备份路径
            now = get_local_time()
            zip_path = os.path.join(Config.output_zip_path, now + ".zip")
            zip_file(Config.save_dir_path, zip_path)
            print(f"{now}: zip file from {Config.save_dir_path} to {zip_path}")
            # 休眠等待
            time.sleep(Config.save_time_step)


# 自动重启线程
class auto_server_restart(threading.Thread):
    def __init__(self, threadID, name):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name

    def run(self):
        while True:
            # 如果frp没有启动,就启动它
            if not is_program_running(Config.frp_name):
                now = get_local_time()
                Config.frp = subprocess.Popen(["start", Config.frp_path, "-c", Config.frp_config])
                print(f"{now}: Restart frp {Config.frp_path}")

            # 如果服务器没有启动,就启动它
            if not is_program_running(Config.server_name):
                now = get_local_time()
                Config.server = subprocess.Popen([Config.server_path])
                print(f"{now}: Restart Server {Config.server_path}")

            # 休眠等待
            time.sleep(Config.check_server_run_step)


def main():
    # 检查服务器是否启动
    # 如果frp没有启动,就启动它
    if not is_program_running(Config.frp_name):
        Config.frp = subprocess.Popen([Config.frp_path, "-c", Config.frp_config])
        print(f"Start frp {Config.frp_path}")
    # 如果服务器没有启动,就启动它
    if not is_program_running(Config.server_name):
        Config.server = subprocess.Popen([Config.server_path])
        print(f"Start Server {Config.server_path}")

    # 自动保存线程
    if Config.use_auto_backup:
        thread_backup = auto_server_backup(1, "backup")
        thread_backup.start()

    # 自动重启线程
    if Config.use_auto_restart:
        thread_restart = auto_server_restart(2, "restart")
        thread_restart.start()

    # 在子线程结束前不要终止,也就是无限堵塞
    if Config.use_auto_backup:
        thread_backup.join()
    if Config.use_auto_restart:
        thread_restart.join()


if __name__ == "__main__":
    main()
    

4. 原理解释

自动备份:定时压缩服务器存档文件夹到备份路径,非常简单粗暴。
注:因为没有在服务器内部运行保存命令,有极小概率可能出现玩家与世界存档不同步的问题,但是因为发生概率太低而且只要加快保存频率就不是什么大问题(其实是懒得整那么麻烦的东西),所以选择性无视了此问题。

自动保存:定时扫描所有进程,检测服务器是否在运行,发现没有在运行,就重新启动~

5. 额外备注

如果你希望主动定时关闭服务器重启,可以用该代码主动关闭服务器:

Config.server.kill()

祝大家玩得开心呀~上班当帕鲁已经够苦了,下班后都开心点吧!
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/369875.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【高质量精品】2024美赛A题22页word版成品论文+数据+多版本前三问代码及代码讲解+前四问思路模型等(后续会更新)

一定要点击文末的卡片,进入后,即可获取完整资料后续参考论文!! 整体分析:这个题目是一个典型的生态系统建模问题,涉及到动物种群的性比例变化、资源可用性、环境因素、生态系统相互作用等多个方面。这个题目的难点在于如何建立一个合理的数学…

关于Clone

关于Clone 一般情况下,如果使用clone()方法,则需满足以下条件。 1、对任何对象o,都有o.clone() ! o。换言之,克隆对象与原型对象不是同一个对象。 2、对任何对象o,都有o.clone().getClass() o.getClass()。换言之&a…

实景三维技术未来的着力点应该在哪里?

随着社会经济和文化生活的不断发展,公共服务和公共安全就成为政府部门和各行业各部门的一个非常重要的工作,提高政府以及相关部门对紧急事件的快速反应和抗风险能力,建设应急指挥系统为公众提供更便捷的紧急救助服务,已经成为社会…

【GoLang入门教程】Go语言几种标准库介绍(五)

如何解决大模型的「幻觉」问题? 文章目录 如何解决大模型的「幻觉」问题?前言几种库image库 (常见图形格式的访问及生成)关键概念和类型:示例 IO库示例 math库(数学库)常用的函数和常量:示例 总结专栏集锦写在最后 前言 上一篇&a…

计算机毕业设计 | springboot 高校新生报到系统(附源码)

1,绪论 1.1 开发背景 学校新生报到仅仅靠原始的手工管理,面对大量的新生信息,无法有效率地将其中的重要部分提取出来,并做出相应的判断和处理。学校的决策只能依据报表数据,在浪费大量人力、物力的同时无法做到实时监…

图像模板匹配算法(MATLAB)

模板匹配是一种用于在图像中定位和识别对象的技术。它的基本思想是: 提取图像中的一个子图像作为“模板”(template)。这个子图像通常包含我们感兴趣的目标对象。 在整个原始图像上,逐点比较模板和原始图像的相似度。相似度通常用归一化的交叉相关(Normalized Cross Correlati…

Unity | 资源热更(YooAsset AB)

目录 一、AssetBundle 1. 插件AssetBundle Browser 打AB包 (1)Unity(我用的版本是2020.3.8)导入AssetBundle Browser (2)设置Prefab (3)AssetBundleBrowser面板 2. 代码打AB包…

Unity类银河恶魔城学习记录1-9 PlayerWallSilde源代码 P36

Alex教程每一P的教程原代码加上我自己的理解初步理解写的注释,可供学习Alex教程的人参考 【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili Player.cs using System.Collections; using System.Collections.Generic; using Unity.VisualScripting; us…

【30秒看懂大数据】数据指标

公众号:知幽科技 PS:本文属专栏第24篇 简单说 数据指标是指对企业经营数据转化为可量化、可衡量、可对比、可预测的一个度量或者维度同称。 举例理解 你在小区门口开了一家馒头店。 开业第一天你算了下一共卖了50个馒头,一共收款100元&#xff0…

通过手写简易版RPC理解RPC原理

RPC是什么 所谓的RPC其实是为了不同主机的两个进程间通信而产生的,通常不同的主机之间的进程通信,程序编写需要考虑到网络通信的功能,这样程序的编写将会变得复杂。RPC就来解决这一问题的,一台主机上的进程对另外一台主机的进程发…

乐意购项目前端开发 #6

一、商品详情页面 代码模版 创建Detail文件夹, 然后创建index.vue文件 <script setup> import { getDetail } from "/api/goods/index"; import { ref, onMounted } from "vue"; import { useRoute } from "vue-router"; import { useCar…

2024/2/3学习记录

微信小程序 小程序中组件的分类 视图容器 view 普通视图区域&#xff0c;类似于 div 常用来实现页面的布局效果。 scroll-view 可滚动的视图区域&#xff0c;常用来实现滚动列表效果 swiper 和 swiper-item 常用 swiper 组件的常用属性 轮播图容器组件和轮播图item组件 基…

【CSS】常见样式总结

一. 溢出隐藏 1.1 单行文本溢出 .content{max-width:200px; /* 定义容器最大宽度 */overflow:hidden; /* 隐藏溢出的内容 */text-overflow:ellipsis; /* 溢出部分...表示 */white-space: nowrap; /* 确保文本在一行内显示 */ }问题&#xff1a;display:flex 和 ellipsis 冲…

Win7 Python入手教程(超简单)

前言 因为最近想学习AI&#xff0c;所以准备开始用python&#xff0c;所以为了照顾和我一样用win7且认为网上的教程难以操作的人&#xff0c;所以的算水写一篇博客。 正文 安装步骤&#xff1a; 打开python官网。&#xff08;会有一点慢&#xff0c;要耐心。&#xff09; …

回归预测 | Matlab实现CPO-CNN-LSTM-Attention冠豪猪优化卷积长短期记忆神经网络注意力机制多变量回归预测(SE注意力机制)

回归预测 | Matlab实现CPO-CNN-LSTM-Attention冠豪猪优化卷积长短期记忆神经网络注意力机制多变量回归预测&#xff08;SE注意力机制&#xff09; 目录 回归预测 | Matlab实现CPO-CNN-LSTM-Attention冠豪猪优化卷积长短期记忆神经网络注意力机制多变量回归预测&#xff08;SE注…

C#,哥伦布数(Golomb Number)的算法与源代码

1 哥伦布数&#xff08;Golomb Number&#xff09; 哥伦布数&#xff08;Golomb Number&#xff09;是一个自然数的非减量序列&#xff0c;使得n在序列中正好出现G&#xff08;n&#xff09;次。前几个15的G&#xff08;n&#xff09;值为&#xff1a;1 2 2 3 3 4 4 4 5 5 5 6…

线阵相机参数介绍之帧加行触发

要点&#xff1a; 了解行触发与帧触发的区别 了解线阵相机帧行触发的参数设置 目标&#xff1a; 能够独立进行帧行触发的配置 1.帧、行触发的区别 帧触发控制的是一张图像开始拍摄的位置 行触发控制的是图像中每一行开始拍摄的位置。

极速上手:使用Jmeter轻松实现N种参数化

参数化的方式&#xff1a; 一、使用用户自定义变量 一种方式&#xff1a;直接在测试计划中添加用户自定义变量 另外一种方式&#xff1a;配置元件——用户自定义变量 示例&#xff1a;用户自定义变量&#xff0c;登录手机号码 在接口请求的时候&#xff0c;进行引用 请求之后&…

【iOS ARKit】3D 人体姿态估计

与基于屏幕空间的 2D人体姿态估计不同&#xff0c;3D人体姿态估计是尝试还原人体在三维世界中的形状与姿态&#xff0c;包括深度信息。绝大多数的现有3D人体姿态估计方法依赖2D人体姿态估计&#xff0c;通过获取 2D人体姿态后再构建神经网络算法&#xff0c;实现从 2D 到 3D人体…

极速搭建幻兽帕鲁私服,叫上好友春节假期一起联机畅玩帕鲁

文章目录 前言幻兽帕鲁私服详细部署教程查看服务器开始游戏自定义游戏参数配置 前言 行业资讯 《幻兽帕鲁》的火爆对开发商 Pocketpair 来说&#xff0c;代价是巨大的。该游戏的成功让首席执行官沟部拓郎最近在推特上表示&#xff0c;他可能因服务器运营费用而面临破产。据他透…