|  |  | 
 |  |  | #---------------------------------------------------------------------
 | 
 |  |  | from bottle import Bottle, request
 | 
 |  |  | from lib import mylog
 | 
 |  |  | import os
 | 
 |  |  | import os, time
 | 
 |  |  | import md5
 | 
 |  |  | import smtplib
 | 
 |  |  | from email.mime.text import MIMEText
 | 
 |  |  | 
 |  |  | 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')
 | 
 |  |  | #===============================================================================
 | 
 |  |  | 
 |  |  | # 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
 | 
 |  |  | 
 |  |  |     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"D:\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 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
 | 
 |  |  | # 服务器开启的状态汇报
 | 
 |  |  | 
 |  |  |     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   | 
 |  |  |         elif stateType == "GameWarning":
 | 
 |  |  |             # 游戏通用警告邮件使用
 | 
 |  |  |             ServerInfo = "游戏警报:服务器组:%s, dbname:%s, 警告信息:%s"%(
 | 
 |  |  |             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),
 | 
 |  |  |                                                        urllib.unquote_plus(dataDict.get("MsgInfo", 0)))
 | 
 |  |  |             SendEmail(ServerInfo)
 | 
 |  |  |                                                        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"):
 | 
 |  |  | 
 |  |  |                 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']   | 
 |  |  |       | 
 |  |  |     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 "邮件发送成功"
 | 
 |  |  | 
 |