306 lines
13 KiB
Python
306 lines
13 KiB
Python
# -*- coding:utf-8 -*-
|
||
import ast
|
||
import configparser
|
||
import pathlib
|
||
import re
|
||
import subprocess
|
||
|
||
import psutil
|
||
import time
|
||
from subprocess import Popen
|
||
import sys
|
||
|
||
from PyQt5.QtCore import pyqtSignal, QThread
|
||
from PyQt5.QtGui import QTextCursor
|
||
from PyQt5.QtWidgets import QApplication, QMainWindow, QMessageBox
|
||
from configparser import ExtendedInterpolation
|
||
|
||
# 界面文件为 mainui.py
|
||
from mainui import *
|
||
import requests
|
||
import os
|
||
|
||
configFile = 'config.ini'
|
||
# 创建配置文件对象
|
||
config = configparser.ConfigParser(interpolation=ExtendedInterpolation(), inline_comment_prefixes=['#', ';'], allow_no_value=True)
|
||
# 读取配置文件
|
||
config.read(configFile, encoding='utf-8')
|
||
|
||
|
||
class MainWindow(QMainWindow, Ui_MainWindow):
|
||
def __init__(self, parent=None):
|
||
super(MainWindow, self).__init__(parent)
|
||
self.setupUi(self)
|
||
|
||
self.apktool_path = config['TOOL_PATH']['apktool_path']
|
||
self.android_name = config['CLIENT_PATH']['client_path'] + config['CLIENT_PATH']['android_name']
|
||
self.android_path = config['CLIENT_PATH']['android_path']
|
||
self.tmp_android_name = config['CLIENT_PATH']['client_path'] + config['CLIENT_PATH']['tmp_android_name']
|
||
self.new_android_name = config['CLIENT_PATH']['client_path'] + config['CLIENT_PATH']['new_android_name']
|
||
|
||
# 初始赋值
|
||
self.nowIpLabel.setText(config['GAME_SET']['now_ip'])
|
||
self.newIpInput.setText(config['GAME_SET']['new_ip'])
|
||
self.nowGameLabel.setText(config['GAME_SET']['game_name'])
|
||
self.newGameInput.setText(config['GAME_SET']['game_name'])
|
||
if isinstance(checkprocess("nginx.exe"), int):
|
||
self.nginxButton.setText("关闭Nginx")
|
||
else:
|
||
self.nginxButton.setText("启动Nginx")
|
||
|
||
def saveSet(self, event):
|
||
print('保存设置,按钮被单击')
|
||
# print(config['GAME_PATH']['game'])
|
||
# tinydict = ast.literal_eval(config['GAME_PATH']['game'])
|
||
# print("字典值 : %s" %tinydict.items())
|
||
# # 遍历字典列表
|
||
# for key, values in tinydict.items():
|
||
# print(key, values)
|
||
# for key, value in config['GAME_PATH'].items():
|
||
# print(key, value)
|
||
# print(config.options('GAME_PATH'))
|
||
# return
|
||
message = QMessageBox.information(self, "提示信息", "确定要保存设置吗?", QMessageBox.Ok | QMessageBox.No, QMessageBox.No)
|
||
if message == QMessageBox.No:
|
||
return
|
||
now_ip = config['GAME_SET']['now_ip']
|
||
new_ip = self.newIpInput.text()
|
||
now_game = config['GAME_SET']['game_name']
|
||
new_game = self.newGameInput.text()
|
||
compile_ip = re.compile('^(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|[1-9])\.(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)\.(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)\.(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)$')
|
||
# 验证IP地址格式
|
||
if (new_ip == "") or new_game == "" or not (compile_ip.match(new_ip)):
|
||
QMessageBox.information(self, "提示信息", "IP地址、游戏名称为空或有误,请正确填写IPv4地址或游戏名称!")
|
||
return
|
||
dirname = config['SERVER_PATH']['mod_file_path']
|
||
sum = 0
|
||
for filedir in dirname.split("|"):
|
||
# 执行文本替换
|
||
if len(filedir.split(",")) < 2:
|
||
isencoding = config['DEFAULT']['file_encoding']
|
||
else:
|
||
isencoding = filedir.split(",")[1]
|
||
filename = filedir.split(",")[0]
|
||
|
||
try:
|
||
with open(filename, 'rt+', encoding=isencoding) as f:
|
||
t = f.read()
|
||
t = t.replace(now_ip, new_ip)
|
||
t = t.replace(now_game, new_game)
|
||
# 读写偏移位置移到最开始处
|
||
f.seek(0, 0)
|
||
f.write(t)
|
||
# 设置文件结尾 EOF
|
||
f.truncate()
|
||
sum = sum + 1
|
||
except:
|
||
QMessageBox.information(self, "提示信息", "替换“" + filename + "”出错,可能文件不存在或编码不对,请检查需要替换的文件编码与配置文件编码是否相符!")
|
||
return
|
||
# 写入配置文件
|
||
config.set('GAME_SET', 'game_name', new_game)
|
||
config.set('GAME_SET', 'now_ip', new_ip)
|
||
config.set('GAME_SET', 'new_ip', new_ip)
|
||
saveconfig = open(configFile, 'wt', encoding=config['DEFAULT']['file_encoding'])
|
||
config.write(saveconfig) # 把要修改的节点的内容写到文件中
|
||
saveconfig.close()
|
||
# 设置界面显示
|
||
self.nowGameLabel.setText(new_game)
|
||
self.nowIpLabel.setText(new_ip)
|
||
# 成功提示
|
||
QMessageBox.information(self, "提示信息", "配置保存成功!重启游戏后生效!<br>游戏名称:" + new_game + "----游戏IP:" + new_ip + "<br>共配置了" + str(sum) + "个文件")
|
||
print('修改完成:' + new_game + ':' + new_ip)
|
||
return
|
||
# TODO 待完成数据库配置修改
|
||
|
||
def nginx(self, event):
|
||
if self.nginxButton.text() == '启动Nginx':
|
||
Popen('start .\\nginx.exe',
|
||
shell=True,
|
||
cwd=config['SERVER_PATH']['nginx_path'],
|
||
# encoding='utf-8'
|
||
)
|
||
Popen(
|
||
config['SERVER_PATH']['php_spawner_path'] + 'php-cgi-spawner.exe "' + config['SERVER_PATH']['php_path'] + 'php-cgi.exe -c ' + config['SERVER_PATH']['php_path'] + 'php.ini" ' + config['SERVER_PATH']['php_cgi_port'] + ' 1+16',
|
||
shell=True,
|
||
# cwd=config['DEFAULT']['dir'] + 'phpstudy_pro',
|
||
# encoding='utf-8'
|
||
)
|
||
self.nginxButton.setText("关闭Nginx")
|
||
else:
|
||
nginx_process = Popen('.\\nginx.exe -s stop',
|
||
shell=True,
|
||
cwd=config['SERVER_PATH']['nginx_path'],
|
||
# encoding='utf-8'
|
||
)
|
||
spawner_process = Popen('taskkill /f /t /im php-cgi-spawner.exe',
|
||
shell=True,
|
||
# encoding='utf-8'
|
||
)
|
||
PHP_process = Popen('taskkill /f /t /im php-cgi.exe',
|
||
shell=True,
|
||
# encoding='utf-8'
|
||
)
|
||
self.nginxButton.setText("启动Nginx")
|
||
# print(process)
|
||
# os.chdir("D:\\LYserver\\phpstudy_pro\\Extensions\\Nginx1.15.11")
|
||
# nginxtype = os.system('start .\\nginx.exe') # 不弹出界面
|
||
# if nginxtype
|
||
# os.system('start .\\nginx.exe') #弹出界面
|
||
print('启动Nginx,按钮被单击')
|
||
|
||
def mysql(self, event):
|
||
if self.mysqlButton.text() == '启动MySql':
|
||
Popen('.\\mysqld.exe',
|
||
shell=True,
|
||
cwd=config['SERVER_PATH']['mysql_path'] + 'bin',
|
||
# encoding='utf-8'
|
||
)
|
||
self.mysqlButton.setText("关闭MySql")
|
||
else:
|
||
Popen('taskkill /f /t /im mysqld.exe',
|
||
shell=True,
|
||
# encoding='utf-8'
|
||
)
|
||
self.mysqlButton.setText("启动MySql")
|
||
print('启动MySql,按钮被单击')
|
||
|
||
def game(self, event):
|
||
if self.gameButton.text() == '启动游戏':
|
||
game_path = config['SERVER_PATH']['game_path'].split("|")
|
||
# 遍历字典列表
|
||
for f in game_path:
|
||
print(f)
|
||
# 执行文本替换
|
||
if len(f.split(",")) < 2:
|
||
sleeptime = 0
|
||
else:
|
||
sleeptime = float(f.split(",")[1])
|
||
game_file = f.split(",")[0]
|
||
try:
|
||
Popen('start ' + game_file,
|
||
shell=True,
|
||
# cwd=values,
|
||
# encoding='utf-8'
|
||
)
|
||
time.sleep(float(sleeptime)) # 延迟时间
|
||
except:
|
||
QMessageBox.information(self, "提示信息", "启动“" + game_file + "”出错,可能文件不存在或配置不对!")
|
||
return
|
||
self.gameButton.setText("关闭游戏")
|
||
else:
|
||
Popen(
|
||
'taskkill /f /t /im LocalLogServer64_R.exe & taskkill /f /t /im LoggerServer64_R.exe & taskkill /f /t /im SessionServer64_R.exe & taskkill /f /t /im NameServer64_R.exe & taskkill /f /t /im LogicServerCQ64_R.exe & taskkill /f /t /im GateServer64_R.exe & taskkill /f /t /im DBCenterServer64_R.exe & taskkill /f /t /im DBServer64_R.exe & taskkill /f /t /im BackStageServer64_R.exe & taskkill /f /t /im AMServer64_R.exe',
|
||
shell=True,
|
||
# encoding='utf-8'
|
||
)
|
||
self.gameButton.setText("启动游戏")
|
||
print('启动游戏,按钮被单击')
|
||
|
||
def fanbianyi(self, event):
|
||
obj = self.fanbianyiButton
|
||
# obj.setText('运行中')
|
||
title = obj.text()
|
||
cmd = 'apktool d ' + self.android_name + ' -f -o ' + self.android_path
|
||
cwd = self.apktool_path
|
||
code = "gbk"
|
||
path = self.android_path
|
||
self.add_cmd_msg(cmd, cwd, title, obj, path, code)
|
||
print('反编译APK,按钮被单击')
|
||
|
||
def shengcheng(self, event):
|
||
obj = self.shengchengButton
|
||
# obj.setText('运行中')
|
||
title = obj.text()
|
||
cmd = 'apktool b ' + self.android_path + ' -o ' + self.tmp_android_name
|
||
cwd = self.apktool_path
|
||
code = "gbk"
|
||
path = self.tmp_android_name
|
||
self.add_cmd_msg(cmd, cwd, title, obj, path, code)
|
||
print('生成APK,按钮被单击')
|
||
|
||
def qianming(self, event):
|
||
obj = self.qianmingButton
|
||
# obj.setText('运行中')
|
||
title = obj.text()
|
||
cmd = 'jarsigner -verbose -keystore key.keystore -storepass 123456 -signedjar ' + self.new_android_name + ' ' + self.tmp_android_name + ' key.keystore'
|
||
cwd = self.apktool_path
|
||
code = "gbk"
|
||
path = self.new_android_name
|
||
self.add_cmd_msg(cmd, cwd, title, obj, path, code)
|
||
print('APK签名,按钮被单击')
|
||
|
||
# 利用新线程进行脚本执行回显
|
||
def add_cmd_msg(self, cmd, cwd="", title="", obj="", path="", code="utf8"):
|
||
obj.setEnabled(False)
|
||
self.CMDtextEdit.clear()
|
||
self.CMDtextEdit.append(title + "脚本开始执行!")
|
||
self.work = Thread(cmd, cwd, title, obj, path, code)
|
||
self.work.trigger.connect(self.show_msg) # 线程中的trigger与主类中的方法进行绑定
|
||
self.work.daemon = True # 主进程退出则该线程也退出
|
||
self.work.start() # 开启线程
|
||
|
||
# 更新UI方法
|
||
def show_msg(self, str):
|
||
self.CMDtextEdit.moveCursor(QTextCursor.End)
|
||
self.CMDtextEdit.append(str)
|
||
# self.CMDtextEdit.insertPlainText(str)
|
||
# self.CMDtextEdit.insertHtml(str)
|
||
|
||
|
||
# 线程类
|
||
class Thread(QThread):
|
||
trigger = pyqtSignal(str) # 注意pyqtSignal一定要实例到__init__前面
|
||
|
||
def __init__(self, cmd, cwd="", title="", obj="", path="", code="utf8"):
|
||
super(Thread, self).__init__()
|
||
# 定义的变量
|
||
self.cmd = cmd
|
||
self.cwd = cwd
|
||
self.title = title
|
||
self.obj = obj
|
||
self.path = path
|
||
self.code = code
|
||
self.state = True
|
||
|
||
# 执行耗时操作
|
||
def run(self):
|
||
process = subprocess.Popen(self.cmd, shell=True, cwd=self.cwd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||
while process.poll() is None:
|
||
line = process.stdout.readline()
|
||
line = line.strip()
|
||
if line:
|
||
self.trigger.emit(line.decode(self.code, 'ignore'))
|
||
print(line.decode(self.code, 'ignore'))
|
||
self.trigger.emit(self.title + '脚本执行结束!')
|
||
self.obj.setEnabled(True)
|
||
# self.obj.setText(self.title)
|
||
# print(self.obj)
|
||
# self.fanbianyiButton.setEnabled(False)
|
||
# self.fanbianyiButton.setText('运行中')
|
||
if self.path != "":
|
||
self.trigger.emit('文件路径:' + self.path)
|
||
startfile(self.path)
|
||
|
||
|
||
# 进程判断,返回进程ID
|
||
def checkprocess(processname):
|
||
pl = psutil.pids()
|
||
for pid in pl:
|
||
if psutil.Process(pid).name() == processname:
|
||
return pid
|
||
|
||
|
||
# 打开文件或文件夹
|
||
def startfile(filename):
|
||
try:
|
||
os.startfile(f'explorer /select, "{pathlib.Path(filename)}')
|
||
except:
|
||
subprocess.Popen(f'explorer /select, "{pathlib.Path(filename)}')
|
||
|
||
|
||
if __name__ == '__main__':
|
||
app = QApplication(sys.argv)
|
||
myWin = MainWindow()
|
||
myWin.show()
|
||
sys.exit(app.exec_())
|