9685 【后台】开服时间整合(开服清档发送邮件通知;优化发送邮件逻辑及配置;)
3个文件已修改
220 ■■■■ 已修改文件
ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldProcess.py 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Tool/RemoteTool/RemoteServer/config.ini 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Tool/RemoteTool/RemoteServer/webapp.py 195 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldProcess.py
@@ -1379,6 +1379,8 @@
    ReadChConfig.ReloadConfig()
    
    AllMapServerInitOK(tick)
    GameWorld.SendGameError("ClearOpenServerOK")
    return
## 服务器开服时是星期几
Tool/RemoteTool/RemoteServer/config.ini
@@ -2,3 +2,26 @@
IsDebug = False
Port = 53009
[Mail]
; 收件人邮箱列表 ['1142397645@qq.com', '305670599@qq.com', '995275190@qq.com']
Receivers=['995275190@qq.com']
; 使用第三方 SMTP 服务  qq  或 gmail, 需要配置对应的节点如 [Mail_qq] 或 [Mail_gmail]
SMTPServer=gmail
; 是否使用SSL
SSL=1
[Mail_qq]
; 邮件服务器
Host=smtp.qq.com
; 用户名
User=2199274165@qq.com
; 开通邮箱的SMTP,短信验证后获取的,非密码
Pass=asmizpysxngtdjic
[Mail_gmail]
; 邮件服务器
Host=smtp.gmail.com
; 用户名
User=swyunwei2022@gmail.com
; 开通邮箱的SMTP,短信验证后获取的,非密码
Pass=yllhfmdqtjwwrmdh
Tool/RemoteTool/RemoteServer/webapp.py
@@ -15,7 +15,7 @@
#---------------------------------------------------------------------
from bottle import Bottle, request
from lib import mylog
import os
import os, time
import md5
import smtplib
from email.mime.text import MIMEText
@@ -23,6 +23,8 @@
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')
#===============================================================================
@@ -32,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
@@ -55,27 +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 C:\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:\ProjectServer\LaunchServerManager\正常开服.bat"
        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 C:\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
# 服务器开启的状态汇报
@@ -85,49 +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 msg:%s"%(stateType,
            mailText = "错误类型:%s 服务器组:%s, dbname:%s 异常信息:%s" % (stateType,
                                                       dataDict.get("groupID", 0),
                                                       dataDict.get("userDBName", 0),
                                                       urllib.unquote_plus(dataDict.get("MsgInfo", "0")))
            SendEmail(ServerInfo)
                                                       urllib.unquote_plus(dataDict.get("MsgInfo", 0)))
            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
        elif stateType == "GameWarning":
            # 游戏通用警告邮件使用
            ServerInfo = "游戏警报:服务器组:%s, dbname:%s, 警告信息:%s"%(
                                                       dataDict.get("groupID", 0),
                                                       dataDict.get("userDBName", 0),
                                                       urllib.unquote_plus(dataDict.get("MsgInfo", 0)))
            SendEmail(ServerInfo)
            SendEmail(mailText, dataDict.get("userDBName", 0))
            return
        elif stateType in ["MapServerRaiseException", "GameServerRaiseException", "RaiseException"]:
            ServerInfo = "%s 抛出Try异常报错:服务器组:%s, dbname:%s, MapID:%s 异常信息:%s"%(
            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", 0)))
            SendEmail(ServerInfo)
            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", 0)))
            SendEmail(mailText, dataDict.get("userDBName", 0))
        elif stateType == "QueryMapOK":
            if g_AllMapCnt == 0:
                if not os.path.exists(".\MapCount.txt"):
@@ -136,41 +201,57 @@
                text = ifile.read()
                ifile.close()
                return "=========上一次记录的开启情况, 请过会再查询========", text
            return "服务器开启完毕,地图数:%s"%g_AllMapCnt
    except Exception, e:
        print e
        ServerInfo = "控制台报错,服务器异常!  %s"%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(ServerInfo)
            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', '305670599@qq.com', '995275190@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 "邮件发送成功"