Tool/RemoteTool/RemoteServer/webapp.py
@@ -15,12 +15,16 @@
#---------------------------------------------------------------------
from bottle import Bottle, request
from lib import mylog
import os
import os, time
import md5
import smtplib
from email.mime.text import MIMEText
from email.header import Header
import datetime
import subprocess
import urllib
from lib import ReadConfig
import traceback
# get: request.query.username request.GET.get('username','')
# post: request.forms.get('username')  request.POST.get('username')
#===============================================================================
@@ -30,12 +34,17 @@
# client_ip = request.environ.get('HTTP_X_FORWARDED_FOR') or request.environ.get('REMOTE_ADDR')
#===============================================================================
cfg = ReadConfig.ReadConfig(os.getcwd() + "\\config.ini")
SSL = cfg.GetInt("Mail", "SSL")
SMTPServer = cfg.GetValue("Mail", "SMTPServer")
Receivers = eval(cfg.GetValue("Mail", "Receivers"))
g_AllMapCnt = 0
myapp = Bottle()
# 可执行固定的远程命令
@myapp.route('/control/openandclose.php', method='POST')
def RemoteCmd():
    dataDict = request.POST
@@ -53,23 +62,76 @@
    ofile = open(r".\key.txt")
    text = ofile.read().strip()
    ofile.close()
    if sign != md5.md5("%s1234666%s"%(result, text)).hexdigest():
        mylog.debug("签名失败")
    if sign != md5.md5("%s1234666%s" % (result, text)).hexdigest():
        mylog.debug("sign failed")
        return
    
    if result == "open":
    if result == "kaifu":
        pResult = os.popen('tasklist /FI "IMAGENAME eq EventServer.exe"')
        pResult = pResult.read()
        if "PID" in pResult or "pid" in pResult:
            return " =======服务器已经开启,请再次确认服务器情况, EventServer.exe运行中"
        os.system(r"call D:\ProjectServer\LaunchServerManager\正常开服.bat")
            return " =======server is opening, EventServer.exe  is running"
        #os.system(r"call c:\ProjectServer\LaunchServerManager\正常开服.bat")
        # system call会导致子进程占用父进程的文件描述符导致端口无法释放, 影响重启使用
        # 如果需要保持子进程持续长期运行的应该调用 subprocess.Popen(cmd, close_fds=True)
        cmd = r"C:\server\LaunchServerManager\start.bat"
        subprocess.Popen(cmd, close_fds=True)
        return "open success"
    elif result == "close":
    elif result == "guanfu":
        # 记得关服后或者重启机器需自动启动服务器控制台
        os.system(r"call D:\ProjectServer\LaunchServerManager\正常关服.bat")
        os.system(r"call C:\server\LaunchServerManager\close.bat")
        return "close success"
    elif result == "xiazai":
        # 记得关服后或者重启机器需自动启动服务器控制台
        os.system(r"call c:\RemoteServer\download.py")
        return "download success"
    elif result == "gengxin":
        # 记得关服后或者重启机器需自动启动服务器控制台
        os.system(r"call c:\RemoteServer\update.py")
        return "update success"
    elif result == "chongqi":
        # 记得关服后或者重启机器需自动启动服务器控制台
        pResult = os.popen('tasklist /FI "IMAGENAME eq ChinGameServer.exe"')
        pResult = pResult.read()
        if "PID" in pResult :
            return "server is opening, restart failed"
        else:
            os.system(r"call c:\RemoteServer\reboot.py")
            return "reboot success"
    elif result == "quxiaochongqi":
        # 记得关服后或者重启机器需自动启动服务器控制台
        os.system(r"call c:\RemoteServer\calreboot.py")
        return "cancel reboot  success"
    elif result == "runscript":
        # 执行脚本 路径固定当前目录script.py
        os.system(r"call c:\RemoteServer\script.py")
        return "run script success"
    elif result == "runtime":
        return CheckUpTime()
    elif result == "restarMain":
        os.system(r"call c:\RemoteServer\restartMain.py")
        return "RestartMain ok"
    return
#获取服务器运行时间
def CheckUpTime():
    cmd = 'systeminfo |findstr "System Boot Time"'
    r = os.popen(cmd)
    text = r.read().replace(',', '')
    text = text.split()
    startTime = text[3] + ' ' + text[4]
    print startTime
    timeArray = time.strptime(startTime, "%Y-%m-%d %H:%M:%S")
    startTimeStamp = int(time.mktime(timeArray))
    nowTimeStamp = time.time()
    print
    upTime = nowTimeStamp - startTimeStamp
    days = int(upTime // (3600 * 24))
    hours = int(upTime % (3600 * 24) // 3600)
    updatetime = "OpenTime:%d Day %d Hours" % (days, hours)
    return updatetime
# OnLogError OnPyError
# 服务器开启的状态汇报
@@ -79,33 +141,58 @@
    try:
        dataDict = request.GET
        stateType = dataDict.get("Type", "")
        if not stateType:
            return
        if stateType == "MapInit":
            # 服务器关闭的时候会重启,此状态只用于开服的时候是否初始化OK
            g_AllMapCnt = dataDict.get("MapCount", 0)
            if g_AllMapCnt:
                ifile = open(".\MapCount.txt", "w")
                ifile.write(str(datetime.datetime.today()) + "\t服务器开启完毕,地图数=%s"%g_AllMapCnt)
                ifile.write(str(datetime.datetime.today()) + "\t服务器开启完毕,地图数=%s" % g_AllMapCnt)
                ifile.close()
            #return "服务器开启完毕,地图数=%s"%dataDict.get("MapCount", 0)
            return
        
        elif stateType == "ClearOpenServerOK":
            mailText = "清档完毕:%s 服务器组:%s, dbname:%s" % (stateType, dataDict.get("groupID", 0), dataDict.get("userDBName", 0))
            SendEmail(mailText, dataDict.get("userDBName", 0), "清档完毕")
            return
        elif stateType in ["MapError", "GameServerError", "PyMongoError"]:
            #groupID=%s&userDBName=%s&Type=PyMongoError
            ServerInfo = "错误类型:%s 服务器组:%s, dbname:%s"%(stateType,
            mailText = "错误类型:%s 服务器组:%s, dbname:%s 异常信息:%s" % (stateType,
                                                       dataDict.get("groupID", 0),
                                                       dataDict.get("userDBName", 0))
            SendEmail(ServerInfo)
                                                       dataDict.get("userDBName", 0),
                                                       urllib.unquote_plus(dataDict.get("MsgInfo", "")))
            SendEmail(mailText, dataDict.get("userDBName", 0))
            return
        elif stateType == "MapDisconnect":
            # 地图5分钟未响应,可以卡了或者闪退 关闭
            #groupID=%s&userDBName=%s&Type=PyMongoError
            ServerInfo = "错误类型:地图被关闭%s 服务器组:%s, dbname:%s"%(stateType,
            mailText = "错误类型:地图被关闭%s 服务器组:%s, dbname:%s" % (stateType,
                                                       dataDict.get("groupID", 0),
                                                       dataDict.get("userDBName", 0))
            SendEmail(ServerInfo)
            return
            SendEmail(mailText, dataDict.get("userDBName", 0))
            return
        elif stateType in ["MapServerRaiseException", "GameServerRaiseException", "RaiseException"]:
            mailText = "%s 抛出Try异常报错:服务器组:%s, dbname:%s, MapID:%s 异常信息:%s" % (
                                                       stateType,
                                                       dataDict.get("groupID", 0),
                                                       dataDict.get("userDBName", 0),
                                                       dataDict.get("mapID", 0),
                                                       urllib.unquote_plus(dataDict.get("MsgInfo", "")))
            SendEmail(mailText, dataDict.get("userDBName", 0))
            return
        elif stateType == "GameWarning":
            # 游戏通用警告邮件使用
            mailText = "游戏警报:服务器组:%s, dbname:%s, 警告信息:%s" % (
                                                       dataDict.get("groupID", 0),
                                                       dataDict.get("userDBName", 0),
                                                       urllib.unquote_plus(dataDict.get("MsgInfo", "")))
            SendEmail(mailText, dataDict.get("userDBName", 0))
        elif stateType == "QueryMapOK":
            if g_AllMapCnt == 0:
                if not os.path.exists(".\MapCount.txt"):
@@ -114,36 +201,57 @@
                text = ifile.read()
                ifile.close()
                return "=========上一次记录的开启情况, 请过会再查询========", text
            return "服务器开启完毕,地图数:%s"%g_AllMapCnt
    except Exception, e:
        print e
            return "服务器开启完毕,地图数:%s" % g_AllMapCnt
        else:
            mailText = "错误类型:%s 服务器组:%s, dbname:%s 异常信息:%s" % (stateType,
                                                       dataDict.get("groupID", 0),
                                                       dataDict.get("userDBName", 0),
                                                       urllib.unquote_plus(dataDict.get("MsgInfo", "")))
            SendEmail(mailText, dataDict.get("userDBName", 0))
            return
    except BaseException:
        errInfo = str(traceback.format_exc())
        print errInfo
        mailText = "邮件控制台报错! %s" % errInfo
        try:
            SendEmail(mailText, dataDict.get("userDBName", 0), "邮件控制台报错")
        except:
            print "无法发送邮件"
# 邮件汇报
def SendEmail(ServerInfo):
    # 第三方 SMTP 服务
    mail_host="smtp.qq.com"  #设置服务器
    mail_user="2199274165@qq.com"    #用户名
    mail_pass="asmizpysxngtdjic"   # 开通QQ邮箱的SMTP,短信验证后获取的,非密码
    sender = '2199274165@qq.com'
def SendEmail(mailText, dbname, subject="游戏服务器异常"):
    
    # 这里可以填写需要接收汇报的邮件地址
    receivers = ['305670599@qq.com']#, '1142397645@qq.com']
    message = MIMEText('异常汇报:%s'%ServerInfo, 'plain', 'gbk')
    message['From'] = Header("游戏服务器异常汇报", 'gbk')
    message['To'] =  Header("运维", 'gbk')    # 不发送的话会被记录为垃圾邮件
    subject = '游戏服务器异常'
    section = "Mail_%s" % SMTPServer
    if not cfg.HasSection(section):
        print "没有配置该邮箱服务器:%s" % section
        return
    # 第三方 SMTP 服务
    mail_host = cfg.GetValue(section, "Host") #设置服务器
    mail_user = cfg.GetValue(section, "User") #用户名
    mail_pass = cfg.GetValue(section, "Pass") #开通邮箱的SMTP,短信验证后获取的,非密码
    sender = mail_user
    serverInfo = dbname.split('GameUser_')[1]
    message = MIMEText('%s' % mailText, 'plain', 'gbk')
    message['From'] = Header("%s %s" % (serverInfo, subject), 'gbk')
    message['To'] = Header("运维", 'gbk')    # 不发送的话会被记录为垃圾邮件
    message['Subject'] = Header(subject, 'gbk')
    smtpObj = smtplib.SMTP()
    smtpObj.connect(mail_host, 25)    # 25 为 SMTP 端口号, 如果用SSL 需要换端口
    smtpObj.login(mail_user,mail_pass)
    smtpObj.sendmail(sender, receivers, message.as_string())
    if SSL == 1:
        smtpObj = smtplib.SMTP_SSL(mail_host)
        smtpObj.connect(mail_host, 465)
        smtpObj.login(mail_user, mail_pass)
        smtpObj.sendmail(sender, Receivers, message.as_string())
    else:
        smtpObj = smtplib.SMTP()
        smtpObj.connect(mail_host, 25)
        smtpObj.login(mail_user, mail_pass)
        smtpObj.sendmail(sender, Receivers, message.as_string())
    print "邮件发送成功"