New file |
| | |
| | | #!/usr/bin/python
|
| | | # -*- coding: GBK -*-
|
| | | #
|
| | | ##@package
|
| | | #
|
| | | # @todo: 渠道测试返利 - 缓存所有未领取数据
|
| | | #
|
| | | # @author: Alee
|
| | | # @date 2019-1-23 下午02:06:50
|
| | | # @version 1.0
|
| | | #
|
| | | # @note: |
| | | #
|
| | | #---------------------------------------------------------------------
|
| | | #导入
|
| | | import GMCommon
|
| | | import ChConfig
|
| | | import GameWorld
|
| | | import GMShell
|
| | | import PyGameData
|
| | | #---------------------------------------------------------------------
|
| | |
|
| | |
|
| | |
|
| | | ## 执行逻辑
|
| | | # @param curPlayer 当前玩家
|
| | | # @param gmCmdDict: 命令字典
|
| | | # @return None
|
| | | # @remarks 函数详细说明.
|
| | | def OnExec(orderId, gmCmdDict):
|
| | | billInfo = gmCmdDict.get('tomap', '')
|
| | | if not billInfo:
|
| | | GMCommon.GMCommandResult(orderId, gmCmdDict, GMCommon.Def_ParamErr)
|
| | | return
|
| | |
|
| | | msgInfo = str([billInfo]) |
| | | GameWorld.DebugLog("GMT_AllDoubleBill : %s"%msgInfo)
|
| | | GameWorld.GetPlayerManager().MapServer_QueryPlayer(0, 0, 0, 10010, "AllDoubleBill", msgInfo, len(msgInfo))
|
| | | GMCommon.GMCommandResult(orderId, gmCmdDict, GMCommon.Def_Success)
|
| | | return
|
| | |
|
New file |
| | |
| | | #!/usr/bin/python
|
| | | # -*- coding: GBK -*-
|
| | | #
|
| | | ##@package
|
| | | #
|
| | | # @todo: 渠道测试返利
|
| | | #
|
| | | # @author: Alee
|
| | | # @date 2019-1-23 下午02:06:50
|
| | | # @version 1.0
|
| | | #
|
| | | # @note: |
| | | #
|
| | | #---------------------------------------------------------------------
|
| | | #导入
|
| | | import GMCommon
|
| | | import ChConfig
|
| | | import GameWorld
|
| | | import GMShell
|
| | | import PyGameData
|
| | | #---------------------------------------------------------------------
|
| | |
|
| | |
|
| | |
|
| | | ## 执行逻辑
|
| | | # @param curPlayer 当前玩家
|
| | | # @param gmCmdDict: 命令字典
|
| | | # @return None
|
| | | # @remarks 函数详细说明.
|
| | | def OnExec(orderId, gmCmdDict):
|
| | | GameWorld.Log("%s"%gmCmdDict)
|
| | | accID = str(gmCmdDict.get('AccID', ''))
|
| | | if not accID:
|
| | | GMCommon.GMCommandResult(orderId, gmCmdDict, GMCommon.Def_ParamErr)
|
| | | return
|
| | | |
| | | gold = int(gmCmdDict.get('GoldState', 0))
|
| | | if not gold:
|
| | | GMCommon.GMCommandResult(orderId, gmCmdDict, GMCommon.Def_ParamErr)
|
| | | return
|
| | | |
| | | playerManager = GameWorld.GetPlayerManager()
|
| | | |
| | | queryType = ChConfig.queryType_sqtPlayerByAccID
|
| | | tagPlayer = playerManager.FindPlayerByAccID(accID)
|
| | | |
| | | if not tagPlayer:
|
| | | # 玩家不在线,先记录,等玩家上线后处理
|
| | | GameWorld.Log("玩家离线,暂存渠道测试返利 %s, 仙玉%s"%(accID, gold))
|
| | | GMShell.AddOfflinePlayerGMTInfo(orderId, queryType, accID, gmCmdDict)
|
| | | return
|
| | | |
| | | GameWorld.Log("发放渠道测试返利 %s, 仙玉%s"%(accID, gold))
|
| | | |
| | | GMCommon.GMTool_MapServer_Query(queryType, orderId, accID, gmCmdDict, 'QDFLDoubleBill', [gold], True)
|
| | | return
|
| | |
|
| | |
|
| | |
|
| | | def OnOfflineCTGInfo(curPlayer, tagMapID, gmCmdDict):
|
| | | gold = int(gmCmdDict.get('GoldState', 0))
|
| | | cmdStr = str([gold])
|
| | | |
| | | GameWorld.GetPlayerManager().MapServer_QueryPlayer(0, 0, curPlayer.GetPlayerID(), tagMapID, 'QDFLDoubleBill', |
| | | cmdStr, len(cmdStr), curPlayer.GetRouteServerIndex())
|
| | | return
|
| | |
|
| | |
| | |
|
| | | # 玩家字典key定义规则, key的长度不能超过29个字节, 注意尽量避免命名重复
|
| | | # 新增参数TYPE 用于字典分类,默认0
|
| | | Def_QuDao_DoubleBillGold = "qddbGold" # 渠道返利的仙玉
|
| | | Def_QuDao_DoubleBillCount = "qddbCount" # 渠道返利的仙玉领取次数 日期+次数组合数字
|
| | | Def_PDict_GeTuiSet = "GetuiSet" # 推送提醒的设置
|
| | | Def_PDict_NoGeTuiTime = "NoGetuiTime" # 推送提醒免打扰时间,将字符串组合数字
|
| | | Def_PlayerKey_TJGNPC = "TJGNPC" # 脱机挂机NPC点
|
| | |
| | | import PlayerGeTui
|
| | | import PlayerDogz
|
| | | import PlayerCoat
|
| | | import PlayerQuDaoDoubleBill
|
| | |
|
| | | import datetime
|
| | | import time
|
| | |
| | | # 如果被禁言的,上线同步前端
|
| | | if curPlayer.GetGMForbidenTalk():
|
| | | curPlayer.SendPropertyRefresh(ShareDefine.CDBPlayerRefresh_ForbidenTalk, curPlayer.GetGMForbidenTalk(), False)
|
| | | |
| | | return
|
| | |
|
| | |
|
| | |
| | |
|
| | | #EndLoadMap需放在最后
|
| | | curPlayer.EndLoadMap()
|
| | | # 渠道返利 |
| | | PlayerQuDaoDoubleBill.OnMapQDDoubleBill(curPlayer)
|
| | | return True
|
| | |
|
| | | ## 切换地图同步一次PK模式
|
New file |
| | |
| | | #!/usr/bin/python
|
| | | # -*- coding: GBK -*-
|
| | | #
|
| | | ##@package
|
| | | #
|
| | | # @todo: 渠道删档测试充值双倍返利
|
| | | #
|
| | | # @author: Alee
|
| | | # @date 2019-1-22 下午08:22:54
|
| | | # @version 1.0
|
| | | #
|
| | | # @note: #总共681条, 含平台['kupai', 'uc', 'gionee', 'xiaomi', 'vivo', 'lenovo', 'meizu', 'yyb', 'oppo', 'qh360']
|
| | | #
|
| | | #---------------------------------------------------------------------
|
| | |
|
| | | import PyGameData
|
| | | import ChConfig
|
| | | import GameWorld
|
| | | import ReadChConfig
|
| | | import datetime
|
| | | import IPY_GameWorld
|
| | | import PlayerControl
|
| | | import math
|
| | |
|
| | | Def_Qudao_DoubleBill = ['kupai', 'uc', 'gionee', 'xiaomi', 'vivo', 'lenovo', 'meizu', 'yyb', 'oppo', 'qh360']
|
| | |
|
| | |
|
| | | def OnMapQDDoubleBill(curPlayer):
|
| | | try:
|
| | | if GameWorld.IsCrossServer():
|
| | | return
|
| | | |
| | | dbBillDict = ReadChConfig.GetEvalChConfig("DoubleBillConfig")
|
| | | if not dbBillDict["IsOpen"]:
|
| | | return
|
| | | |
| | | OnFirstQDDoubleBillQuery(curPlayer)
|
| | | OnOtherQuDaoDoubleBill(curPlayer)
|
| | | except Exception, e:
|
| | | GameWorld.Log("OnMapQDDoubleBill 异常 %s-%s"%(curPlayer.GetID(), e))
|
| | | return
|
| | |
|
| | |
|
| | | # 跨服不处理
|
| | | # 1. 第一次为请求数据, 如果是神决宗则请求总数据
|
| | | # 2. 后续切换地图,判断是否隔天领取
|
| | | def OnFirstQDDoubleBillQuery(curPlayer):
|
| | | # 1 为无充值 2 为已领取 其他数值为具体返利总仙玉
|
| | | spID, accID = GetAccIDInfo(curPlayer.GetAccID())
|
| | | if spID not in Def_Qudao_DoubleBill:
|
| | | # 非渠道的
|
| | | return
|
| | | |
| | | gold = curPlayer.NomalDictGetProperty(ChConfig.Def_QuDao_DoubleBillGold)
|
| | | if gold:
|
| | | # 已请求
|
| | | return
|
| | | |
| | | # {spid:[accID...]}
|
| | | if PyGameData.g_Qudao_DoubleBill:
|
| | | # 有缓存但不在缓存中的
|
| | | if spID not in PyGameData.g_Qudao_DoubleBill:
|
| | | return
|
| | | |
| | | if accID not in PyGameData.g_Qudao_DoubleBill[spID]:
|
| | | return
|
| | | |
| | | centerUrl = "center.2460web.com"
|
| | | #centerUrl = "vm-mobilecom"
|
| | | # 先个人请求
|
| | | getUrl = "http://%s:53004/DoublieBill.php?AccID=%s"%(centerUrl, curPlayer.GetAccID())
|
| | | GameWorld.GetGameWorld().EventReport_EventReport("", "", "", "", 0, getUrl)
|
| | | |
| | | if curPlayer.GetMapID() != 10010:
|
| | | return
|
| | | |
| | | if not PyGameData.g_Qudao_DoubleBill:
|
| | | # 缓存请求
|
| | | getUrl = "http://%s:53004/QueryAllDoubleBill.php?ccccc=fanggongji"%centerUrl
|
| | | GameWorld.GetGameWorld().EventReport_EventReport("", "", "", "", 0, getUrl)
|
| | | |
| | | return
|
| | |
|
| | |
|
| | | # 后续天返回充值比例
|
| | | def OnOtherQuDaoDoubleBill(curPlayer):
|
| | | # 1 为无充值 2 为已领取 其他数值为具体返利总仙玉
|
| | | spID, accID = GetAccIDInfo(curPlayer.GetAccID())
|
| | | if spID not in Def_Qudao_DoubleBill:
|
| | | # 非渠道的
|
| | | return
|
| | | |
| | | gold = curPlayer.NomalDictGetProperty(ChConfig.Def_QuDao_DoubleBillGold)
|
| | | if gold <= 2:
|
| | | #无可领取的
|
| | | return
|
| | | |
| | | CalcDoubleBillByDay(curPlayer)
|
| | | |
| | | return
|
| | |
|
| | |
|
| | | ##获取平台账号 和 spid
|
| | | def GetAccIDInfo(gameAccID):
|
| | | infoList = gameAccID.split('@')
|
| | | return infoList[1], infoList[0]
|
| | |
|
| | | # 每日领取返利
|
| | | def CalcDoubleBillByDay(curPlayer):
|
| | | gold = curPlayer.NomalDictGetProperty(ChConfig.Def_QuDao_DoubleBillGold)
|
| | | if gold <= 2:
|
| | | return
|
| | | dbBillDict = ReadChConfig.GetEvalChConfig("DoubleBillConfig")
|
| | | billDayRate = dbBillDict["BillDayRate"]
|
| | | # 记录返利次数: 时间+次数
|
| | | #count = curDay.year*100000 + curDay.month*1000 + curDay.day*10 + 0
|
| | | count = curPlayer.NomalDictGetProperty(ChConfig.Def_QuDao_DoubleBillCount)
|
| | | realCnt = count%10 # 已领取次数
|
| | | if realCnt >= len(billDayRate):
|
| | | return
|
| | | dateStr = "%d-%02d-%02d"%(count/100000, count%100000/1000, count%1000/10)
|
| | | startDate = GameWorld.GetDateTimeByStr(dateStr, ChConfig.TYPE_Time_Format_Day)
|
| | | curDay = datetime.datetime.today()
|
| | | theDay = curDay - startDate
|
| | | if theDay.days < realCnt:
|
| | | return
|
| | | |
| | | giveGold = int(math.ceil(billDayRate[realCnt]/100.0*gold))
|
| | | |
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_QuDao_DoubleBillCount, count+1)
|
| | | |
| | | title = "系统邮件".decode("gbk").encode("utf8")
|
| | | content = "亲爱的道友:</r><Space=2>欢迎归来,感谢您在付费删档测试期间对我们的大力支持,给您奉上今日份回归大礼。您在付费删档测试期间的充值按照1元=20仙玉的比例共计返还7天,具体每日返还比例请您查看登录公告-删档回归有礼。请您留意每日返利邮件,祝您游戏愉快!".decode("gbk").encode("utf8")
|
| | | |
| | | mailItemInfoList = []
|
| | | if realCnt == 0:
|
| | | mailItemInfoList = [[57, 1, 1]]
|
| | | # 发邮件
|
| | | PlayerControl.SendMail(title, content, 30, [curPlayer.GetPlayerID()], mailItemInfoList, gold=giveGold) |
| | | GameWorld.Log("领取渠道返利 第%s次 仙玉=%s"%(realCnt+1, giveGold))
|
| | | return
|
| | |
|
New file |
| | |
| | | #!/usr/bin/python
|
| | | # -*- coding: GBK -*-
|
| | | #
|
| | | ##@package
|
| | | #
|
| | | # @todo: 渠道返利发放 - 缓存所有未领取数据
|
| | | #
|
| | | # @author: Alee
|
| | | # @date 2019-1-23 下午02:38:15
|
| | | # @version 1.0
|
| | | #
|
| | | # @note: |
| | | #
|
| | | #---------------------------------------------------------------------
|
| | | #导入
|
| | | import GameWorld
|
| | | import ChConfig
|
| | | import PyGameData
|
| | | import json
|
| | | #---------------------------------------------------------------------
|
| | | #全局变量
|
| | | #---------------------------------------------------------------------
|
| | | #---------------------------------------------------------------------
|
| | | #逻辑实现 |
| | | ## 请求逻辑 |
| | | # @param query_Type 请求类型
|
| | | # @param query_ID 玩家ID
|
| | | # @param packCMDList 发包命令 |
| | | # @param tick 当前时间
|
| | | # @return "True" or "False" or ""
|
| | | # @remarks 函数详细说明.
|
| | | def DoLogic(query_Type, query_ID, packCMDList, tick):
|
| | | |
| | | PyGameData.g_Qudao_DoubleBill = json.loads(packCMDList[0])
|
| | | return
|
| | |
|
| | | #---------------------------------------------------------------------
|
| | | #执行结果
|
| | | ## 执行结果
|
| | | # @param curPlayer 发出请求的玩家
|
| | | # @param callFunName 功能名称
|
| | | # @param funResult 查询的结果
|
| | | # @param tick 当前时间
|
| | | # @return None
|
| | | # @remarks 函数详细说明.
|
| | | def DoResult(curPlayer, callFunName, funResult, tick):
|
| | | return
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
New file |
| | |
| | | #!/usr/bin/python
|
| | | # -*- coding: GBK -*-
|
| | | #
|
| | | ##@package
|
| | | #
|
| | | # @todo: 渠道返利发放
|
| | | #
|
| | | # @author: Alee
|
| | | # @date 2019-1-23 下午02:38:15
|
| | | # @version 1.0
|
| | | #
|
| | | # @note: |
| | | #
|
| | | #---------------------------------------------------------------------
|
| | | #导入
|
| | | import PlayerControl
|
| | | import GameWorld
|
| | | import ChConfig
|
| | | import datetime
|
| | | import PlayerQuDaoDoubleBill
|
| | | #---------------------------------------------------------------------
|
| | | #全局变量
|
| | | #---------------------------------------------------------------------
|
| | | #---------------------------------------------------------------------
|
| | | #逻辑实现 |
| | | ## 请求逻辑 |
| | | # @param query_Type 请求类型
|
| | | # @param query_ID 玩家ID
|
| | | # @param packCMDList 发包命令 |
| | | # @param tick 当前时间
|
| | | # @return "True" or "False" or ""
|
| | | # @remarks 函数详细说明.
|
| | | def DoLogic(query_Type, query_ID, packCMDList, tick):
|
| | | curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(query_ID)
|
| | | |
| | | if not curPlayer or curPlayer.IsEmpty():
|
| | | GameWorld.Log("渠道返利无法找到玩家:%s"%query_ID)
|
| | | return
|
| | | |
| | | gold = packCMDList[0]
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_QuDao_DoubleBillGold, gold) |
| | | if gold <= 2:
|
| | | return
|
| | | |
| | | #第一天返利
|
| | | # 记录返利次数: 时间+次数
|
| | | curDay = datetime.datetime.today()
|
| | | count = curDay.year*100000 + curDay.month*1000 + curDay.day*10 + 0
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_QuDao_DoubleBillCount, count)
|
| | | |
| | | GameWorld.Log("渠道返利发放 %s状态%s-%s"%(curPlayer.GetAccID(), count, gold))
|
| | | PlayerQuDaoDoubleBill.CalcDoubleBillByDay(curPlayer)
|
| | | return
|
| | |
|
| | | #---------------------------------------------------------------------
|
| | | #执行结果
|
| | | ## 执行结果
|
| | | # @param curPlayer 发出请求的玩家
|
| | | # @param callFunName 功能名称
|
| | | # @param funResult 查询的结果
|
| | | # @param tick 当前时间
|
| | | # @return None
|
| | | # @remarks 函数详细说明.
|
| | | def DoResult(curPlayer, callFunName, funResult, tick):
|
| | | return
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
| | | g_ZhuXianBossPlayerHurtDict = {} #诛仙BOSS玩家伤害排行信息
|
| | | g_zhuXianSkillAddPerDict = {} # 诛仙装备对技能增强缓存 {playerID:{技能TypeID:数值, ...}, ...}
|
| | | g_zhuXianSkillReducePerDict = {} # 诛仙装备对技能减伤缓存 {playerID:{技能TypeID:数值, ...}, ...}
|
| | |
|
| | | g_Qudao_DoubleBill = {} # 渠道删档充值返利
|
New file |
| | |
| | | vivo 82f3c8552db41cdf 200
|
| | | oppo 152757925 2560
|
| | | vivo 901b6ff023a7e85f 1000
|
| | | uc 8478aeb43a0fd895ead516fce6ae5fc9_ali 200
|
| | | xiaomi 2018122805304069 1600
|
| | | vivo f448a71e25919d70 17520
|
| | | vivo 6abf2c86b779afdf 560
|
| | | oppo 385315489 10000
|
| | | yyb o17pv02u-j2s3qw5tzidlhlaqznw 2760
|
| | | yyb 7f4104d04495d84f4f0fa0cad6e6c50d 200
|
| | | vivo 88b3782e503ac490 200
|
| | | yyb 8d2bc948c3f9c3f05325c0e7bf148341 200
|
| | | xiaomi 164521958 1000
|
| | | oppo 233182438 200
|
| | | uc ee09ed16337641c446398cfb86ca571f_ali 200
|
| | | vivo 7965450c5048a7d7 560
|
| | | vivo 6b26eaf4049c55d1 33200
|
| | | xiaomi 1088670742 1600
|
| | | oppo 269564243 200
|
| | | yyb 6664de5453447fb426126bb22d80ffd1 17280
|
| | | vivo e68d085b7e423f4b 5480
|
| | | meizu 121807453 15960
|
| | | oppo 215951423 16800
|
| | | qh360 1394604735 200
|
| | | oppo 201868216 200
|
| | | oppo 352797806 200
|
| | | oppo 101114083 200
|
| | | vivo 5b6fac2c24679a41 200
|
| | | oppo 262198164 4880
|
| | | uc 8083a292c060cc3460bae6eceedebdf6_ali 200
|
| | | oppo 383472023 200
|
| | | xiaomi 2018122906312482 200
|
| | | vivo 2f861d83776cda6b 200
|
| | | oppo 259507706 200
|
| | | vivo 7dc157390f54ad57 200
|
| | | uc ef4b94b30fb449c90a27a29a77ef82e0_ali 200
|
| | | oppo 342957751 4520
|
| | | vivo 66cdf6014fa3ee36 200
|
| | | oppo 324231784 200
|
| | | yyb dc017ca1da4e7711f67bdecaa4b604db 200
|
| | | vivo 3e0448c023347425 200
|
| | | vivo 4f77b51d4c724ad9 200
|
| | | vivo 07644a06017edf17 200
|
| | | uc eb3c49e72f9c126cec0b6574fe90f455_ali 200
|
| | | vivo 79d96402ffe53254 200
|
| | | oppo 76985310 200
|
| | | uc 970105c9e401e48f833ec4c0ba9f239d_ali 200
|
| | | vivo 7059030e984e5912 200
|
| | | vivo ac2b7e288e7f3534 1200
|
| | | oppo 204838825 200
|
| | | oppo 368200330 2120
|
| | | qh360 2566131193 200
|
| | | oppo 255242979 200
|
| | | vivo ad4abd123f99700e 560
|
| | | oppo 306446247 200
|
| | | qh360 278173472 200
|
| | | uc 9f043b1cbb339816e05a37a9b255f347_ali 200
|
| | | oppo 337754507 200
|
| | | xiaomi 1021445156 1360
|
| | | oppo 353606775 1200
|
| | | oppo 122393461 2560
|
| | | uc ff6cf5061c5764582ab448f8366d701a_ali 3720
|
| | | gionee 1eba5ec5d7df4d2296a970a034b7328f 200
|
| | | uc e0f7b9b141c24e67f37e6e7ed62d9c9b_ali 8400
|
| | | oppo 368830565 200
|
| | | oppo 298784489 2560
|
| | | uc 67088abd72a594d4cb079e943c4c2a03_ali 200
|
| | | qh360 679581332 200
|
| | | uc f91d2368493ea3d1b2cd19dbf2b9d847_ali 2200
|
| | | oppo 277620850 200
|
| | | vivo 06d64003ee7e3f27 7040
|
| | | oppo 247462964 200
|
| | | xiaomi 2018112706993619 4000
|
| | | vivo 3ffa2d2ac585d4e2 1160
|
| | | oppo 237195046 1200
|
| | | yyb o17pv04dpzkksjx6_cbvparvxo50 200
|
| | | oppo 421049782 200
|
| | | uc 3b4004a1e4ebd8d7296e966ea5895861_ali 200
|
| | | oppo 271029371 7480
|
| | | yyb o17pv05heotfv_a__rhzs0lkw3mm 560
|
| | | oppo 352591631 200
|
| | | uc 52c2099bf1931bfc55aef218651ad2e3_ali 200
|
| | | gionee 361e9c1b270442488154e081129d1181 200
|
| | | oppo 289653761 200
|
| | | oppo 147088965 1400
|
| | | xiaomi 169491961 200
|
| | | oppo 153459286 5480
|
| | | vivo 3318439f39aaa145 13560
|
| | | oppo 424197444 200
|
| | | oppo 311257217 600
|
| | | oppo 410517582 560
|
| | | xiaomi 31158624 200
|
| | | oppo 157807373 1000
|
| | | xiaomi 2018122805045079 200
|
| | | oppo 269780646 200
|
| | | oppo 422495211 200
|
| | | oppo 242212251 200
|
| | | oppo 256050937 2920
|
| | | xiaomi 1025597802 1000
|
| | | yyb o17pv07x2wubeze9gztzzqfieady 360
|
| | | kupai 101095640 200
|
| | | vivo 00bcc22a3d6da501 200
|
| | | oppo 301773370 27320
|
| | | yyb o17pv0-oh8dy1omlrjftnht27xr8 200
|
| | | xiaomi 1140040845 200
|
| | | yyb o17pv07rdxx2axyy5tlmdvkvtbwu 4160
|
| | | uc bde23ea768a06320d6a6d20ccd272912_ali 200
|
| | | yyb o17pv0_gmabxyt-svf9ou-kbg-qc 200
|
| | | uc f44fe6520af8bba522ea463f36b8a1cb_ali 200
|
| | | oppo 387199301 200
|
| | | oppo 390352287 200
|
| | | oppo 121393085 200
|
| | | oppo 238380022 200
|
| | | oppo 200151032 800
|
| | | uc e496a67891ff78c88bf93df1be849bc3_ali 200
|
| | | oppo 223083314 200
|
| | | uc 91034274498011a33d9876767523692c_ali 200
|
| | | vivo 54baf0c4e0b5848f 200
|
| | | yyb o17pv04zgixvunfljxqaxepfqplw 200
|
| | | oppo 283800180 4720
|
| | | uc 68d37cd7d8dc47af73474613225fbb0d_ali 560
|
| | | oppo 299750392 200
|
| | | oppo 68792513 20760
|
| | | oppo 143653381 1000
|
| | | uc 356e349241bcd17d233b4a582d55b894_ali 200
|
| | | uc c6ceda1c6685cb7330f738d065425b47_ali 8600
|
| | | oppo 27720822 200
|
| | | uc 11216515c38ca4e7ea35c2c00421d955_ali 200
|
| | | vivo 48a420424411af19 200
|
| | | oppo 147796532 400
|
| | | oppo 125869425 200
|
| | | uc 9a38fec523e3218fdb8020d8babe8fd6_ali 8000
|
| | | vivo ce8aaeb1c805e250 200
|
| | | vivo bec0a887fc77fea6 200
|
| | | uc 2e6d627c9c58ba6adf1c0ff3dfc05ddc_ali 200
|
| | | oppo 272379683 560
|
| | | xiaomi 2018122805077325 200
|
| | | oppo 232077665 200
|
| | | oppo 313628435 200
|
| | | oppo 284489272 200
|
| | | uc 50a6789ca65896369bb0e7ab4d31a7cf_ali 200
|
| | | oppo 399689077 1000
|
| | | yyb o17pv07idcmuh9_nlpuvjo8d5nw4 200
|
| | | vivo 1a4fffb68c33024d 200
|
| | | yyb o17pv00hftagkedjvc69pqr4d60y 200
|
| | | vivo bf78f8e03ea96c42 200
|
| | | uc 1ab709b8c2e6f662260fd5348c76d2b8_ali 200
|
| | | uc 7ccf46ecbb63122b301580d9b2dcf060_ali 200
|
| | | uc 09d9dbc96e4bc1b0c1152c2565648a7c_ali 200
|
| | | xiaomi 2018122604409646 200
|
| | | oppo 355943975 200
|
| | | vivo 1359836bcf7b743a 1160
|
| | | oppo 129122287 200
|
| | | vivo 6a0d5e946919c7bf 200
|
| | | vivo 755781bb21f7154c 1160
|
| | | vivo 65bc25aeeb006c71 200
|
| | | oppo 377117456 1000
|
| | | uc 4c8382c787a720d14d1f110d1f5e42b8_ali 200
|
| | | oppo 252265005 200
|
| | | oppo 278352380 760
|
| | | xiaomi 89110137 400
|
| | | oppo 278577188 200
|
| | | uc bacff785c48717c9dda4f20c1af65df2_ali 200
|
| | | vivo c94ca73dc926d89b 2120
|
| | | oppo 395777068 200
|
| | | oppo 302666356 200
|
| | | xiaomi 1283160716 1720
|
| | | oppo 371783012 200
|
| | | oppo 265343653 400
|
| | | oppo 205359207 2760
|
| | | oppo 252688395 400
|
| | | xiaomi 2018122805041068 200
|
| | | uc 835c2d80940491af0ebc8689d28bd634_ali 2000
|
| | | uc e344828773556b46ff4cf2cd3ef26e67_ali 200
|
| | | uc 17649a91c21a23fd0d73af32d7445beb_ali 200
|
| | | oppo 250425998 21040
|
| | | yyb o17pv0-dsiacpeldxyxst6d_wuki 200
|
| | | yyb bf8be35e45353d5fe8985e4ac776aa11 200
|
| | | oppo 132591008 200
|
| | | oppo 328593376 200
|
| | | qh360 24811316 200
|
| | | oppo 209803204 200
|
| | | uc 7acacd61234cb8acd373051e83617170_ali 4120
|
| | | vivo d097c8e1cb6e9013 2800
|
| | | oppo 424306720 200
|
| | | vivo f5af934dd04aeafc 2000
|
| | | vivo 9a8ecea2eff3a9b5 200
|
| | | uc 0eea4a35fad4211815efed7dc540375d_ali 43320
|
| | | vivo e28581402492b419 1400
|
| | | uc bd4bbda4a4bd3f06f842f41229d64431_ali 200
|
| | | xiaomi 2018122906066879 1000
|
| | | xiaomi 2018122704676451 200
|
| | | qh360 2946645067 200
|
| | | oppo 88734337 200
|
| | | oppo 412584094 360
|
| | | uc 5ec471186df83e4016a3015f3e725e39_ali 200
|
| | | qh360 825858114 200
|
| | | gionee 847e84f0e9014e46af2dd5085f95fb23 200
|
| | | oppo 376928499 200
|
| | | oppo 290512804 400
|
| | | oppo 40929689 1000
|
| | | qh360 380862319 200
|
| | | oppo 123522434 4680
|
| | | oppo 238997465 200
|
| | | oppo 215672006 200
|
| | | oppo 288020097 200
|
| | | vivo c031c32bd18258e7 11640
|
| | | xiaomi 41313962 200
|
| | | meizu 153309418 200
|
| | | vivo 3f88a155d3e9d7e1 20360
|
| | | uc 552d96b4ca5a4e026ccf53bd25911817_ali 1360
|
| | | uc 6ba23ac773471a8caf235d7572595881_ali 200
|
| | | uc e4ec1cf7a140ce33c92aa46590a07187_ali 200
|
| | | yyb c9a8d2474018386bc08cb05c190b6719 200
|
| | | oppo 204047699 7200
|
| | | oppo 271140297 200
|
| | | qh360 3039662638 200
|
| | | oppo 406253936 200
|
| | | oppo 382197009 200
|
| | | vivo d293ac07df6baa99 200
|
| | | oppo 315181044 200
|
| | | xiaomi 1136238005 4320
|
| | | uc 7cd7a91108352326df6789edafa46d7c_ali 4880
|
| | | oppo 210575226 200
|
| | | oppo 130827046 200
|
| | | uc 880c3d6646d492714d6e0006c0826ae7_ali 200
|
| | | oppo 302961513 1160
|
| | | oppo 249136462 200
|
| | | oppo 224051513 200
|
| | | oppo 210801681 200
|
| | | uc d7000487317d03b921e840dbaa975bf0_ali 200
|
| | | xiaomi 1137339007 200
|
| | | oppo 308123618 560
|
| | | uc 117eac4fa731744736e7bb5cbf10a844_ali 200
|
| | | oppo 264724657 200
|
| | | oppo 216305250 200
|
| | | meizu 19662006 200
|
| | | uc 5ee5f28a3efa57bec3e413711636a61d_ali 560
|
| | | uc e39c0c310d601d21b9ac92aa0e0afc06_ali 200
|
| | | oppo 297913707 800
|
| | | uc 7e4ea43c033370df4cab0eab208ae7b2_ali 200
|
| | | oppo 95894423 200
|
| | | vivo c07d26a033a0b341 200
|
| | | gionee 1c5f1e0332424db3986cbd8e8751cf78 200
|
| | | oppo 353941326 200
|
| | | vivo 1db8027efa603427 200
|
| | | oppo 155723526 200
|
| | | oppo 237226552 200
|
| | | oppo 320653836 200
|
| | | uc 6dfca86c77cf31ca9726cea887b996cf_ali 200
|
| | | vivo d92c0a100c80a6f8 2720
|
| | | yyb o17pv06qxn7usfxyw8jp7toruojk 360
|
| | | oppo 382110852 1000
|
| | | yyb o17pv05wrwpyp7dzzrlsz86gcumy 12200
|
| | | vivo 91b35270051b7ffb 3560
|
| | | oppo 39921681 200
|
| | | uc 79e404f6d9b5d03b3db47a149f78eed9_ali 200
|
| | | oppo 405986640 7840
|
| | | oppo 247011825 200
|
| | | oppo 311546293 200
|
| | | vivo 92810d623e6754fc 200
|
| | | oppo 141482197 560
|
| | | oppo 336722288 200
|
| | | oppo 390790962 1120
|
| | | uc d00368441137cb46d3f9e313cc00ce52_ali 2560
|
| | | oppo 337088025 2760
|
| | | oppo 352260205 1000
|
| | | uc 9a18ffa893d1f4e5d1ce636c8f362a40_ali 6240
|
| | | uc 5c07ec726a95db5cfe686b3155f61051_ali 1160
|
| | | uc c3b0be984b9b98b1baba4ac8dd796ce4_ali 200
|
| | | oppo 231114389 200
|
| | | uc d5ca6808d754433ab55446e62a63b094_ali 200
|
| | | uc 2fc866d2afce71953525afcb5db1d4af_ali 7240
|
| | | uc af65d2ec937dbf64fb4874b7bd067127_ali 1360
|
| | | oppo 364107878 10760
|
| | | oppo 339950423 200
|
| | | oppo g251809013099056411 200
|
| | | oppo 21242152 200
|
| | | oppo 202074663 200
|
| | | vivo 9872706a903e168a 1000
|
| | | oppo 309331847 200
|
| | | oppo 130268810 200
|
| | | oppo 120721221 200
|
| | | uc e56e4a15e85e63aee76b2c2be80643dd_ali 1000
|
| | | vivo 8c5fab1e421efdb6 200
|
| | | uc a18ab4b623861283cbf947e868114955_ali 200
|
| | | oppo 120464069 200
|
| | | vivo e0fbffd171c6d60e 200
|
| | | qh360 2815384078 200
|
| | | oppo 229036022 200
|
| | | uc b7b52246f318467c52525284ce2367d0_ali 200
|
| | | uc bc94dd481ba8089c63e3767de77591c5_ali 200
|
| | | uc 3e43d868a78dd54e5ce2072831b736e2_ali 6880
|
| | | oppo 316702827 2360
|
| | | oppo 120930066 200
|
| | | oppo 229781711 200
|
| | | yyb 0747ad7ac9d2df7763199d11f9833c4c 200
|
| | | uc 2daae5d057ef49674baca6b020d9bdfb_ali 1160
|
| | | oppo 205063029 200
|
| | | uc 0d9c8fdb22aedfd2a4a18c98af0ceea9_ali 2160
|
| | | uc 037c588306aef1ba882e38ebdb46166b_ali 200
|
| | | uc 679da6dbed489b97dc2ba8517ffed256_ali 3720
|
| | | gionee 4c15bcd4c42f4730a9d3b1ddc17d74a0 200
|
| | | xiaomi 63569047 400
|
| | | vivo 8a2330ed17bbb3f4 1160
|
| | | oppo 376626045 200
|
| | | xiaomi 1131966296 200
|
| | | uc 58f4f4228b62f6f69ce88eefb46ad3b4_ali 200
|
| | | oppo 215614201 200
|
| | | vivo 72fc51e202b6995d 200
|
| | | qh360 130454715 200
|
| | | uc 88024214331b58ffaaabf2aba8c69391_ali 4320
|
| | | oppo 263406896 200
|
| | | uc 27358a4969deafa8a45d7a97c14d297e_ali 200
|
| | | oppo 308260086 10040
|
| | | oppo 377739486 200
|
| | | gionee 7043592a6f3647f58f0c2a98c02096bc 200
|
| | | vivo 67aa714cef3b7a93 200
|
| | | vivo e85054243135050c 200
|
| | | oppo 231372879 200
|
| | | uc c2e9575c409a581c1aa66813cb2b1cfa_ali 200
|
| | | oppo 283771428 200
|
| | | qh360 3104791211 1160
|
| | | vivo ccd98d30a47e84c0 200
|
| | | oppo 47545084 800
|
| | | oppo 385937122 800
|
| | | gionee e574dec776a04ce9b9ae50f1588328f0 2960
|
| | | oppo 360346913 1000
|
| | | xiaomi 133068086 200
|
| | | oppo 59435983 600
|
| | | vivo d3efa55478df5da3 3560
|
| | | xiaomi 176814433 200
|
| | | meizu 147573331 2760
|
| | | vivo 98b2805dc2d15d56 2720
|
| | | oppo 109039959 1160
|
| | | uc dc4d65cab19a8bc41c45af16ffacb422_ali 200
|
| | | vivo 0a45b35472bf39ea 560
|
| | | oppo 360183897 3160
|
| | | oppo 227039780 3920
|
| | | oppo 207023781 25720
|
| | | oppo 157597203 200
|
| | | xiaomi 2018122905977745 560
|
| | | oppo 416621295 200
|
| | | uc dce51d5642c293a1c800d483ce2c9787_ali 44920
|
| | | uc 111be28d4e2914c5533cc9977e1cd97d_ali 200
|
| | | uc 5036a358b5ca64ec5fc5f0659f6bca1d_ali 200
|
| | | uc 24149f294a205fd24f5ab26f7811a8d8_ali 200
|
| | | oppo 356398218 200
|
| | | xiaomi 1012326175 1760
|
| | | oppo 297034994 200
|
| | | qh360 19945587 4520
|
| | | uc d86962171353c14514c602c155e1d825_ali 200
|
| | | xiaomi 65553669 200
|
| | | vivo c15711a66fbf7d9d 200
|
| | | yyb o17pv08ewtvefflefropb2u9rc60 200
|
| | | uc feab3fce1ddf3710239f1e0f139aabcb_ali 360
|
| | | oppo 106051020 200
|
| | | oppo 259025772 200
|
| | | oppo 146917783 200
|
| | | qh360 635599801 2760
|
| | | oppo 413322528 6040
|
| | | vivo 4ee9454fcee2324b 600
|
| | | yyb o17pv055pmmp_jmgdnwjxluovgpi 200
|
| | | vivo 57570cc9b4873259 24160
|
| | | oppo 82103626 6720
|
| | | yyb o17pv0wx5kkz5awdyzqgo2iprojw 200
|
| | | qh360 2993812756 200
|
| | | oppo 295618964 560
|
| | | gionee 917fbe758848449298c83aa283a2c329 200
|
| | | oppo 42404837 200
|
| | | oppo 364830466 200
|
| | | yyb 672400e8343dbdd22f057ded0a455de3 44000
|
| | | oppo 212115480 1160
|
| | | uc ab37354f3d629cc33c84b21e9e012423_ali 200
|
| | | vivo 740933f3cf9c8af6 600
|
| | | xiaomi 48816775 200
|
| | | yyb o17pv0-dakzdfhu9aipv8le6evb8 21560
|
| | | vivo 2a0474385188c369 200
|
| | | xiaomi 2018122805277795 200
|
| | | oppo 390227594 200
|
| | | vivo bb3a1fcc77c4a621 200
|
| | | xiaomi 97882714 6640
|
| | | uc fcfb555c0df5ba967a0584d68d69378a_ali 1160
|
| | | xiaomi 142357422 200
|
| | | oppo 62793498 2160
|
| | | oppo 63527031 200
|
| | | oppo 273084300 200
|
| | | vivo ef27eb5708c0ee2e 200
|
| | | oppo 156757168 200
|
| | | oppo 203702472 200
|
| | | uc abae09bd4dc2947037dba3bbb39f653a_ali 800
|
| | | xiaomi 71831495 200
|
| | | oppo 314778495 200
|
| | | uc 042e3e0b159d70708313d86d87c91f81_ali 200
|
| | | oppo 230545944 3360
|
| | | uc a955f7743371dcf51e4d87cff8310b7f_ali 200
|
| | | oppo 247924712 200
|
| | | uc c1e51083160f23138001f1b0cdf0f430_ali 200
|
| | | vivo 0945c1821925b0b9 200
|
| | | uc 7b25e102846cba5ae4fa4b6d94b00da1_ali 200
|
| | | xiaomi 2018122704956901 200
|
| | | oppo 102105723 200
|
| | | uc 3a10d50e110e8a7649b12e3c08d2f0fe_ali 6520
|
| | | oppo 346806770 200
|
| | | oppo 374205568 200
|
| | | vivo 89971ba63000ff6f 200
|
| | | vivo cdd27a7159bdbfc1 1160
|
| | | oppo 216711417 6040
|
| | | uc 782a1edec92bdb7a2c4207b12437648f_ali 1000
|
| | | oppo 140011394 200
|
| | | vivo 84a56c8d9d4351eb 4520
|
| | | vivo 56389ddd8f9ac854 2320
|
| | | yyb a412504e2a32bece362f3840ffd18d26 1400
|
| | | uc 01e5707733b63729b41ec9b334909936_ali 4920
|
| | | oppo 374836678 4320
|
| | | oppo 248291697 2560
|
| | | vivo ef545a90bf2f7342 8040
|
| | | vivo 77e464a85f459714 200
|
| | | oppo 79077961 200
|
| | | uc 41399f4bc8fdcc9ffc737282f8f08b77_ali 2160
|
| | | oppo 362346452 8800
|
| | | oppo 268996224 4280
|
| | | oppo 137826947 200
|
| | | oppo 240815153 2960
|
| | | oppo 326118066 200
|
| | | oppo 31032838 200
|
| | | qh360 366904668 200
|
| | | oppo 128951275 200
|
| | | vivo 003f70fa2bb0ebd4 2560
|
| | | oppo 406604500 200
|
| | | yyb o17pv08eno5fnria4y_xlkvrormg 200
|
| | | uc f9e1ec6ef76f743cf416c64164e51555_ali 1000
|
| | | yyb o17pv09fudw12dfwtzi68mhqnzlk 200
|
| | | oppo 125078260 200
|
| | | yyb o17pv0_m69hgfrckfaactgzagkoa 6840
|
| | | vivo ff78057a4fea1649 200
|
| | | oppo 159418910 200
|
| | | oppo 401482477 800
|
| | | xiaomi 98477450 200
|
| | | oppo 244384729 200
|
| | | oppo 229992458 1160
|
| | | oppo 358821834 2160
|
| | | oppo 224671375 200
|
| | | oppo 68178327 960
|
| | | oppo 232536326 200
|
| | | yyb o17pv04pel53btzkf5grx-6igwiy 200
|
| | | yyb 9ad3021502676fd519591fa9345b2ad2 200
|
| | | uc b21d5c1f8e656fbdd464fd76cbd39534_ali 200
|
| | | uc a9be827fcd91c31cfeab18409b138956_ali 7160
|
| | | oppo 396051888 7240
|
| | | oppo 402065291 21960
|
| | | vivo b6f9ecbf2a30d20b 20120
|
| | | uc 3cdd90b4e15e622d1c49534e5261b584_ali 200
|
| | | oppo 304571639 9320
|
| | | oppo 278470659 360
|
| | | oppo 256595603 200
|
| | | yyb o17pv00iuvmk5-uog97qptpg2j-m 10160
|
| | | uc ccf6bc72fdd23cebc4eae87b39e60444_ali 600
|
| | | vivo 1ec67d4b7793791a 1000
|
| | | xiaomi 1130042911 200
|
| | | uc 69624290d46dd718cc2f9e2f24e4bc7f_ali 200
|
| | | oppo 369420484 1320
|
| | | xiaomi 258717 200
|
| | | oppo 261622394 560
|
| | | yyb o17pv04ygr-bf2uhteqgqn5p58qw 2560
|
| | | uc 1f2a8901ce41aaa7df309e7284b728b8_ali 1160
|
| | | vivo 780041c02376ef8e 760
|
| | | oppo 360602356 200
|
| | | meizu 147201109 200
|
| | | oppo 358126871 4360
|
| | | vivo d4e82a32234f2ee6 360
|
| | | yyb o17pv0978bb1_qv3miap74nckqye 400
|
| | | oppo 132459730 1000
|
| | | vivo 4f74d6ed74437579 200
|
| | | vivo 77931b89e09a975b 200
|
| | | oppo 30684126 3280
|
| | | oppo 28511315 200
|
| | | vivo 0e4377f03e84a103 200
|
| | | uc a544f0029a6defe8358cfb4d72d22d4c_ali 200
|
| | | xiaomi 2018122704593835 200
|
| | | oppo 320705464 200
|
| | | oppo 157729500 800
|
| | | oppo 219160323 10200
|
| | | oppo 279464953 2160
|
| | | oppo 167301532 200
|
| | | oppo 46294593 1160
|
| | | vivo 8b116d7e0bf2af95 200
|
| | | uc e52aa50989f07bf169a6cceefbefde80_ali 2400
|
| | | uc 86f6c6a1280c3519c657ea314b1a15f0_ali 200
|
| | | oppo 253812822 200
|
| | | lenovo 10134826973 200
|
| | | oppo 421876249 5840
|
| | | oppo 336330244 200
|
| | | yyb o17pv086vcrezjd5seqfbgrvnr6k 200
|
| | | oppo 266845715 200
|
| | | uc 37190d122f726522415204529536dc0a_ali 200
|
| | | oppo 117223374 4720
|
| | | yyb o17pv0w31yot7m_z6nbuwuvf6aua 200
|
| | | yyb o17pv08gombsjkp6akybicqk4k_k 17160
|
| | | oppo 364525962 200
|
| | | oppo 212429318 200
|
| | | oppo 388209982 2920
|
| | | oppo 201108752 2360
|
| | | vivo a08b3f3d6243fcce 200
|
| | | lenovo 10134409050 200
|
| | | xiaomi 1131095509 2160
|
| | | xiaomi 93979584 1000
|
| | | uc db8724f34ce8af171f4ef86ad4e53985_ali 200
|
| | | oppo 149057284 200
|
| | | qh360 3043505919 200
|
| | | uc 556bef15ee922ca26b20ea965ad8311e_ali 9400
|
| | | xiaomi 66948764 200
|
| | | xiaomi 6878019 200
|
| | | uc c9aca2c70a222db5283584c1db013ce6_ali 5480
|
| | | oppo 242271147 200
|
| | | oppo 210652692 6880
|
| | | vivo d2df5b9b7b1a7f59 200
|
| | | oppo 82798699 200
|
| | | uc 84441ddff236aeec519edc57bf0df0f3_ali 20320
|
| | | yyb o17pv05gjpuxfg4ncc22udladxao 200
|
| | | oppo 147694212 1560
|
| | | oppo 157975820 560
|
| | | oppo 399246639 600
|
| | | uc 0475a7d172af0626638da2ef0490ea21_ali 200
|
| | | vivo c04becbc83823adc 200
|
| | | oppo 415525735 200
|
| | | uc 329f12bfea0b75b0f86d3036b07c9f68_ali 4160
|
| | | yyb o17pv03hkdftct_xhcyezm-d6yni 200
|
| | | qh360 543535500 800
|
| | | xiaomi 1049901775 200
|
| | | xiaomi 140253855 2520
|
| | | oppo 282307700 360
|
| | | uc 3c718aef876a52f3dffd5223716851c6_ali 200
|
| | | xiaomi 162239035 200
|
| | | oppo 406073690 200
|
| | | oppo 302888081 960
|
| | | oppo 425227108 200
|
| | | oppo 323485732 200
|
| | | uc 1c9768fa84def80b9662e7af94ad5fc8_ali 200
|
| | | meizu 162038018 200
|
| | | vivo cae9d41e94a4db0b 200
|
| | | oppo 331130471 200
|
| | | vivo cc71bf226be738a3 760
|
| | | oppo 336108133 1720
|
| | | oppo 365369216 2160
|
| | | xiaomi 1109575422 200
|
| | | oppo 65412945 200
|
| | | oppo 303306435 200
|
| | | yyb o17pv016-xbntfnto8dmnujr73l8 9160
|
| | | oppo 217895166 200
|
| | | oppo 391869516 12360
|
| | | oppo 341528078 200
|
| | | vivo d9f7992ef8c0f11c 200
|
| | | oppo 275666431 200
|
| | | lenovo 10134474718 200
|
| | | oppo 150069409 200
|
| | | uc efec018b2f5a84fa406573616d1da7eb_ali 800
|
| | | oppo 303030396 400
|
| | | yyb 6ab7a4b6759bae392c30c7620730da0c 200
|
| | | uc db24e1c9a4bee5c3d4e325ec0462399e_ali 200
|
| | | oppo 378612954 560
|
| | | oppo 156878963 200
|
| | | vivo 1f528e22e8433aef 200
|
| | | oppo 48225126 200
|
| | | xiaomi 14035931 200
|
| | | oppo 326266516 200
|
| | | uc 94d3395c3df6efc6d5044cb95f3416d5_ali 200
|
| | | vivo d6132fdc476f223a 200
|
| | | yyb o17pv0xvt-kduk4ezkogx_y5mzhs 200
|
| | | oppo 226895056 200
|
| | | xiaomi 72705931 200
|
| | | oppo 273624232 800
|
| | | oppo 277873367 200
|
| | | uc 2e9d8b5d9f979dff0ceaef9ce74129d4_ali 200
|
| | | yyb adb828e92716e338ac44dc08b9ea1483 200
|
| | | vivo 1690760fe3257af0 7440
|
| | | oppo 146865973 67920
|
| | | xiaomi 127562084 1200
|
| | | xiaomi 78126528 200
|
| | | yyb o17pv07snqkcmbkhp8aclisujfvk 200
|
| | | xiaomi 1039857212 1360
|
| | | yyb o17pv0wt9vcjvdnk1jaenxvpwzpk 200
|
| | | vivo 82dc39e0c671993b 200
|
| | | oppo 279042369 200
|
| | | vivo 8734fb0770881000 200
|
| | | oppo 205007669 61880
|
| | | xiaomi 75701888 1160
|
| | | meizu 119626606 200
|
| | | uc 5dc0b3b52c9ae75f343698e03032cd98_ali 200
|
| | | oppo 378369013 200
|
| | | vivo 692695aa3545fb5e 200
|
| | | oppo 311363738 1160
|
| | | yyb o17pv0-x2dsuc-jz4ht-kij0qqk4 200
|
| | | uc e69d4f85dbfb45999c6abb43911d6aad_ali 200
|
| | | vivo 7545aa944a768c3e 2960
|
| | | vivo 979413bc418b5188 200
|
| | | vivo 4bf70d50dbeb733c 200
|
| | | oppo 157556500 1000
|
| | | oppo 318639885 1360
|
| | | vivo c9b33a7c46a4237a 200
|
| | | oppo 409456093 1160
|
| | | vivo c95636c643441606 200
|
| | | xiaomi 1125426384 5040
|
| | | yyb o17pv08k5cphm8wpe_g5oryz4r60 200
|
| | | oppo 408755028 14120
|
| | | vivo ccac2b0bcc7f4bf5 200
|
| | | yyb o17pv09hcor5doyzxrw8iua6cmxu 200
|
| | | vivo c4ff8fec48ffbbc4 73680
|
| | | oppo 332769083 920
|
| | | uc f2a59dd63891ebf485f68d14b35b75c0_ali 200
|
| | | oppo 129360630 200
|
| | | xiaomi 105171138 1000
|
| | | oppo 292125878 200
|
| | | qh360 396814834 200
|
| | | oppo 139064637 1160
|
| | | uc 8673e952fd8a5647dbbad3d986d19ed4_ali 1360
|
| | | oppo 411383567 144200
|
| | | uc 54a9ddc19da32a87118bf2a41a686bf8_ali 200
|
| | | oppo 284237868 200
|
| | | uc 0c02faf559e63f78293bc87c458c383a_ali 9040
|
| | | oppo 362447552 200
|
| | | oppo 235469516 200
|
| | | oppo 232635618 200
|
| | | oppo 118702614 44960
|
| | | oppo 157103866 2560
|
| | | oppo 154828437 560
|
| | | vivo 56018b58393a3ff7 4120
|
| | | vivo 27418491e561e881 200
|
| | | uc a07681488f70c9ca60c5424ec80fdd36_ali 200
|
| | | oppo 111193819 800
|
| | | meizu 17097398 4080
|
| | | oppo 327117491 2760
|
| | | vivo 9c09420af8300727 200
|
| | | uc c3b69e197837c8e260ab429c0b11f0ff_ali 200
|
| | | uc 800e24a59f529bb53cecbae82dd43b75_ali 7280
|
| | | uc 4b2e1171944e5bacd2856a4abff1dea3_ali 200
|
| | | yyb o17pv06ygejzfv9-hsvlo0fsq8ey 800
|
| | | vivo c726b1caa009878b 2760
|
| | | uc 5e81fecb4ac9762587705df1543255dd_ali 200
|
| | | oppo 245522252 200
|
| | | yyb o17pv09uths5umpykvwd47wasfwg 200
|
| | | xiaomi 1051049514 200
|
| | | oppo 424009396 200
|
| | | yyb o17pv0-d9hx3ymwagycvy1kaoutw 200
|
| | | oppo 387588449 200
|
| | | vivo 7e9e81990fc2e7d5 200
|
| | | meizu 145311380 200
|
| | | oppo 253381574 200
|
| | | oppo 251115270 200
|
| | | gionee cd7e9fe4cfc44ec19ce4bc17afcea973 5160
|
| | | oppo 76574434 200
|
| | | vivo e5c963e639cbe4fe 1160
|
| | | yyb o17pv03j8kgr-qcddftkri6hilqo 200
|
| | | oppo 28511331 200
|
| | | uc 1f128dad77d929d14b0deab2324146b2_ali 200
|
| | | uc 98aeabce757a38e5aa774525f4d2fc8a_ali 200
|
| | | vivo c08ed942738c05e2 200
|
| | | oppo 341853907 200
|
| | | oppo 307629707 200
|
| | | oppo 415411792 15360
|
| | | oppo 286603484 200
|
| | | oppo 294092776 200
|
| | | oppo 266170227 600
|
| | | vivo b2a2d652b82cbcec 2560
|
| | | vivo e8cd15a99e1dfb24 1000
|
| | | uc 3f69d43bec189b1f5dfe2873d70ad1bb_ali 200
|
| | | vivo d018afc4d853d493 1960
|
| | | qh360 13458383 6280
|
| | | vivo a4e4d305cf2c9594 1360
|
| | | oppo 290685531 4920
|
| | | uc 685148381997c887f5dc997124f0621c_ali 200
|
| | | oppo 301890935 10560
|
| | | oppo 271345808 200
|
| | | vivo 97b3adcdf8b3671b 200
|
| | | vivo f072c062e1ab0ef6 200
|
| | | oppo 128264104 200
|
| | | oppo 323026143 200
|
| | | uc 89de4d67ccfbdca0578c25fe72f66350_ali 200
|
| | | meizu 140734701 200
|
| | | oppo 44631391 200
|
| | | xiaomi 929140 200
|
New file |
| | |
| | | #!/usr/bin/python
|
| | | # -*- coding: GBK -*-
|
| | | #
|
| | | ##@package
|
| | | #
|
| | | # @todo: 数据库-录入传统渠道删档玩家的充值返利 1元=20仙玉
|
| | | #
|
| | | # @author: Alee
|
| | | # @date 2019-1-22 下午03:13:42
|
| | | # @version 1.0
|
| | | #
|
| | | # @note: |
| | | #
|
| | | #---------------------------------------------------------------------
|
| | | from lib import DBController
|
| | | from lib import mylog
|
| | |
|
| | | g_dbController = None
|
| | |
|
| | |
|
| | | def InitDB():
|
| | | global g_dbController
|
| | | |
| | | if not g_dbController:
|
| | | IP = "127.0.0.1"
|
| | | Port = 27017
|
| | | User = "sa"
|
| | | Pwd = "sa"
|
| | | DBName = "DoubleBillDB"
|
| | | g_dbController = DBController.DBController(IP, Port, DBName, User, Pwd, None)
|
| | | |
| | | mylog.debug('获取新的数据库链接')
|
| | | |
| | | if not g_dbController.connected:
|
| | | mylog.debug('无法链接数据库')
|
| | | return False
|
| | | |
| | | return True
|
| | |
|
| | | def GetDBEventCon():
|
| | | global g_dbController
|
| | | if not InitDB():
|
| | | return None
|
| | | return g_dbController
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
New file |
| | |
| | | #!/usr/bin/python
|
| | | # -*- coding: GBK -*-
|
| | | #
|
| | | ##@package
|
| | | #
|
| | | # @todo: 录入返利 # 数据库字段 渠道spid 账号accid 仙玉gold 兑换所在服serverid
|
| | | #
|
| | | # @author: Alee
|
| | | # @date 2019-1-22 下午03:23:30
|
| | | # @version 1.0
|
| | | #
|
| | | # @note: |
| | | #
|
| | | #---------------------------------------------------------------------
|
| | |
|
| | | import pymongo
|
| | | from pymongo.son_manipulator import SONManipulator
|
| | | import base64
|
| | | from functools import wraps
|
| | | from time import (sleep)
|
| | |
|
| | | from lib import CommFunc
|
| | |
|
| | |
|
| | | class ObjectIdRemover(SONManipulator):
|
| | | def transform_outgoing(self, son, collection):
|
| | | if '_id' in son:
|
| | | del son['_id']
|
| | | return son
|
| | |
|
| | | class EncodeStringManipulator(SONManipulator):
|
| | | def __init__(self, encoding):
|
| | | self.encoding = encoding
|
| | | def transform_incoming(self, son, collection):
|
| | | |
| | | def transform_value(value):
|
| | | if isinstance(value, dict):
|
| | | return transform_dict(value)
|
| | | elif isinstance(value, list):
|
| | | return [transform_value(v) for v in value]
|
| | | elif isinstance(value, basestring):
|
| | | result, value = CommFunc.EncodingToUnicode(self.encoding, value)
|
| | | return value
|
| | | return value
|
| | | |
| | | def transform_dict(object):
|
| | | for (key, value) in object.items():
|
| | | object[key] = transform_value(value)
|
| | | return object
|
| | | |
| | | def transform_list(container):
|
| | | for item in container:
|
| | | transform_dict(item)
|
| | | return container
|
| | | |
| | | if isinstance(son, dict):
|
| | | return transform_dict(son)
|
| | | elif isinstance(son, list):
|
| | | return transform_list(son)
|
| | | return son
|
| | | |
| | | def transform_outgoing(self, son, collection):
|
| | | |
| | | def transform_value(value):
|
| | | if isinstance(value, dict):
|
| | | return transform_dict(value)
|
| | | elif isinstance(value, list):
|
| | | return [transform_value(v) for v in value]
|
| | | elif isinstance(value, basestring):
|
| | | result, value =CommFunc.UnicodeToEncoding(self.encoding, value)
|
| | | return value
|
| | | return value
|
| | | |
| | | def transform_dict(object):
|
| | | for (key, value) in object.items():
|
| | | object[key] = transform_value(value)
|
| | | return object
|
| | | |
| | | def transform_list(container):
|
| | | for item in container:
|
| | | transform_dict(item)
|
| | | return container
|
| | | |
| | | if isinstance(son, dict):
|
| | | return transform_dict(son)
|
| | | elif isinstance(son, list):
|
| | | return transform_list(son)
|
| | | return son
|
| | | |
| | | class Base64StringManipulator(SONManipulator):
|
| | | |
| | | def transform_incoming(self, son, collection):
|
| | | |
| | | def transform_value(value):
|
| | | if isinstance(value, dict):
|
| | | return transform_dict(value)
|
| | | elif isinstance(value, list):
|
| | | return [transform_value(v) for v in value]
|
| | | elif isinstance(value, basestring):
|
| | | return base64.b64encode(value)
|
| | | return value
|
| | | |
| | | def transform_dict(object):
|
| | | for (key, value) in object.items():
|
| | | object[key] = transform_value(value)
|
| | | return object
|
| | | |
| | | def transform_list(container):
|
| | | for item in container:
|
| | | transform_dict(item)
|
| | | return container
|
| | | |
| | | if isinstance(son, dict):
|
| | | return transform_dict(son)
|
| | | elif isinstance(son, list):
|
| | | return transform_list(son)
|
| | | return son
|
| | | |
| | | def transform_outgoing(self, son, collection):
|
| | | |
| | | def transform_value(value):
|
| | | if isinstance(value, dict):
|
| | | return transform_dict(value)
|
| | | elif isinstance(value, list):
|
| | | return [transform_value(v) for v in value]
|
| | | elif isinstance(value, basestring):
|
| | | return base64.b64decode(value)
|
| | | return value
|
| | | |
| | | def transform_dict(object):
|
| | | for (key, value) in object.items():
|
| | | object[key] = transform_value(value)
|
| | | return object
|
| | | |
| | | def transform_list(container):
|
| | | for item in container:
|
| | | transform_dict(item)
|
| | | return container
|
| | | |
| | | if isinstance(son, dict):
|
| | | return transform_dict(son)
|
| | | elif isinstance(son, list):
|
| | | return transform_list(son)
|
| | | return son
|
| | | |
| | | #用于修饰DBController的数据库操作函数
|
| | | #断线自动重试
|
| | | def reconnect_decorator(func):
|
| | | @wraps(func)
|
| | | def wrapper(*args, **kwds):
|
| | | MAX_RECONNECT = 10
|
| | | RECONNECT_INTERVAL = 0.1
|
| | | failCnt = 0
|
| | | while True:
|
| | | try:
|
| | | #去掉self
|
| | | return func(*args, **kwds)
|
| | | except pymongo.errors.AutoReconnect, e:
|
| | | failCnt += 1
|
| | | sleep(RECONNECT_INTERVAL)
|
| | | if failCnt > MAX_RECONNECT:
|
| | | raise e
|
| | | |
| | | return wrapper
|
| | |
|
| | | class DBController:
|
| | | def __init__(self, host, port, dbName, user, pwd, encoding):
|
| | | self.host = host
|
| | | self.port = port
|
| | | self.dbName = dbName
|
| | | self.user = user
|
| | | self.pwd = pwd
|
| | | |
| | | self.connected = False
|
| | | self.con = None
|
| | | self.db = None
|
| | | self.lastError = None
|
| | | self.translator = None
|
| | | #===========================================================================================
|
| | | # if encoding == 'base64':
|
| | | # self.translator = Base64StringManipulator()
|
| | | # else:
|
| | | # self.translator = EncodeStringManipulator(encoding)
|
| | | #===========================================================================================
|
| | | self.initialize()
|
| | | |
| | | def initialize(self):
|
| | | if not self.connected:
|
| | | if not self.doConnect(self.host, self.port):
|
| | | return False
|
| | | authResult = self.doAuthentication(self.dbName, self.user, self.pwd)
|
| | | if self.db:
|
| | | self.db.add_son_manipulator(ObjectIdRemover())
|
| | | return authResult
|
| | | return True
|
| | | |
| | | def doConnect(self, ip, port):
|
| | | try:
|
| | | self.con = pymongo.Connection(ip, port)
|
| | | except TypeError, typeError:
|
| | | raise
|
| | | except pymongo.errors.ConnectionFailure, failure:
|
| | | self.lastError = failure
|
| | | return False
|
| | | except Exception, e:
|
| | | self.lastError = e
|
| | | return False
|
| | | except:
|
| | | self.lastError = 'Unknown exception occur!'
|
| | | return False
|
| | | self.connected = True
|
| | | return True
|
| | | |
| | | def doAuthentication(self, dbName, user, pwd):
|
| | | if not self.connected or not self.con:
|
| | | self.lastError = 'Not connected yet!'
|
| | | return False
|
| | | self.db = self.con[dbName]
|
| | | authDB = self.con['admin']
|
| | | try:
|
| | | return authDB.authenticate(user, pwd)
|
| | | # return self.db.authenticate(user, pwd)
|
| | | except TypeError, typeError:
|
| | | self.lastError = typeError
|
| | | return False
|
| | | except Exception, e:
|
| | | self.lastError = e
|
| | | return False
|
| | | except:
|
| | | self.lastError = 'Unknown exception occur!'
|
| | | return False
|
| | | |
| | | def find_one(self, colName, spec, filter = None):
|
| | | result, recList = self.find(colName, spec, filter, 1)
|
| | | if not result:
|
| | | return False, None
|
| | | for rec in recList:
|
| | | return True, rec
|
| | | return True, None
|
| | | |
| | | @reconnect_decorator
|
| | | def find(self, colName, spec = None, filter = None, maxCnt = 0, sortBy = None):
|
| | | if not self.connected:
|
| | | if not self.initialize():
|
| | | return False, []
|
| | | |
| | | result = False
|
| | | resultDictList = []
|
| | | col = self.db[colName]
|
| | | if self.translator:
|
| | | spec = self.translator.transform_incoming(spec, None)
|
| | | try:
|
| | | resultCollection = col.find(spec, filter, limit = maxCnt, sort = sortBy)
|
| | | if self.translator:
|
| | | resultDictList = self.translator.transform_outgoing(list(resultCollection), None)
|
| | | else:
|
| | | resultDictList = list(resultCollection)
|
| | | return True, resultDictList
|
| | | except TypeError, typeError:
|
| | | self.lastError = typeError
|
| | | return result, resultDictList
|
| | | except pymongo.errors.OperationFailure, err:
|
| | | self.lastError = err
|
| | | return result, resultDictList
|
| | | except Exception, e:
|
| | | self.lastError = e
|
| | | return result, resultDictList
|
| | | except:
|
| | | self.lastError = 'Unknown exception occur!'
|
| | | return result, resultDictList |
| | | |
| | | @reconnect_decorator
|
| | | def insert(self, colName, doc_or_docs, isSafe = True):
|
| | | if not self.connected:
|
| | | if not self.initialize():
|
| | | return False
|
| | | |
| | | col = self.db[colName]
|
| | | if self.translator:
|
| | | doc_or_docs = self.translator.transform_incoming(doc_or_docs, None)
|
| | | try:
|
| | | col.insert(doc_or_docs, safe = isSafe)
|
| | | except pymongo.errors.OperationFailure, err:
|
| | | self.lastError = err
|
| | | return False
|
| | | except Exception, e:
|
| | | self.lastError = e
|
| | | return False
|
| | | except:
|
| | | self.lastError = 'Unknown exception occur!'
|
| | | return False
|
| | | return True
|
| | | |
| | | @reconnect_decorator
|
| | | def update(self, colName, spec, doc, isUpsert = False, isSafe = True, isMulti = False):
|
| | | if not self.connected:
|
| | | if not self.initialize():
|
| | | return False
|
| | | |
| | | col = self.db[colName]
|
| | | #需要先对doc进行处理,但由不能开启collection.update的manipulate,因为那会应用所有处理
|
| | | if self.translator:
|
| | | spec = self.translator.transform_incoming(spec, None)
|
| | | doc = self.translator.transform_incoming(doc, None)
|
| | | try:
|
| | | col.update(spec, doc, upsert = isUpsert, safe = isSafe, multi = isMulti)
|
| | | except TypeError, typeError:
|
| | | self.lastError = typeError
|
| | | return False
|
| | | except pymongo.errors.OperationFailure, err:
|
| | | self.lastError = err
|
| | | return False
|
| | | except Exception, e:
|
| | | self.lastError = e
|
| | | return False
|
| | | except:
|
| | | self.lastError = 'Unknown exception occur!'
|
| | | return False
|
| | | return True
|
| | | |
| | | @reconnect_decorator
|
| | | def save(self, colName, doc, isSafe = True):
|
| | | if not self.connected:
|
| | | if not self.initialize():
|
| | | return False
|
| | | |
| | | col = self.db[colName]
|
| | | if self.translator:
|
| | | doc = self.translator.transform_incoming(doc, None)
|
| | | try:
|
| | | col.save(doc, safe = isSafe)
|
| | | except TypeError, typeError:
|
| | | self.lastError = typeError
|
| | | return False
|
| | | except pymongo.errors.OperationFailure, err:
|
| | | self.lastError = err
|
| | | return False
|
| | | except Exception, e:
|
| | | self.lastError = e
|
| | | return False
|
| | | except:
|
| | | self.lastError = 'Unknown exception occur!'
|
| | | return False
|
| | | return True
|
| | | |
| | | @reconnect_decorator
|
| | | def remove(self, colName, spec = None, isSafe = True):
|
| | | if not self.connected:
|
| | | if not self.initialize():
|
| | | return False
|
| | | |
| | | col = self.db[colName]
|
| | | if self.translator:
|
| | | spec = self.translator.transform_incoming(spec, None)
|
| | | try:
|
| | | col.remove(spec, safe = isSafe)
|
| | | except pymongo.errors.OperationFailure, err:
|
| | | self.lastError = err
|
| | | return False
|
| | | except Exception, e:
|
| | | self.lastError = e
|
| | | return False
|
| | | except:
|
| | | self.lastError = 'Unknown exception occur!'
|
| | | return False
|
| | | return True
|
| | | |
| | | @reconnect_decorator
|
| | | def drop(self, colName):
|
| | | if not self.connected:
|
| | | if not self.initialize():
|
| | | return False
|
| | | |
| | | col = self.db[colName]
|
| | | try:
|
| | | col.drop()
|
| | | except TypeError, typeError:
|
| | | self.lastError = typeError
|
| | | return False
|
| | | except Exception, e:
|
| | | self.lastError = e
|
| | | return False
|
| | | except:
|
| | | self.lastError = 'Unknown exception occur!'
|
| | | return False
|
| | | return True
|
| | | |
| | | @reconnect_decorator
|
| | | def count(self, colName):
|
| | | if not self.connected:
|
| | | if not self.initialize():
|
| | | return False, 0
|
| | | |
| | | col = self.db[colName]
|
| | | try:
|
| | | cnt = col.count()
|
| | | except pymongo.errors.OperationFailure, err:
|
| | | self.lastError = err
|
| | | return False, 0
|
| | | except Exception, e:
|
| | | self.lastError = e
|
| | | return False, 0
|
| | | except:
|
| | | self.lastError = 'Unknown exception occur!'
|
| | | return False, 0
|
| | | return True, cnt
|
| | | |
| | |
|
| | |
|
| | | |
| | | def test_DBController():
|
| | | fileIO = open("Bill.txt")
|
| | | # spid accid gold
|
| | | testColName = 'tagDoubleBill'
|
| | | dbController = DBController('localhost', 27017, "DoubleBillDB", 'sa', 'sa', None)
|
| | | |
| | | print "开始录入数据"
|
| | | cnt = 0 |
| | | spidDict= {}
|
| | | #渠道SpID 账号AccID 仙玉Gold 兑换所在服ServerID
|
| | | for line in fileIO.readlines():
|
| | | try:
|
| | | spID, accID, gold = line.strip().split()
|
| | | except:
|
| | | print "Error:", line
|
| | | continue
|
| | | result, recs = dbController.find(testColName, {"SpID":spID, "AccID":accID})
|
| | | if recs:
|
| | | print "重复插入", spID, accID, gold |
| | | continue
|
| | | |
| | | doc = {"SpID":spID, "AccID":accID, "Gold":gold, "ServerID":""}
|
| | | result = dbController.insert(testColName, doc)
|
| | | if not result:
|
| | | print "插入失败", spID, accID, gold
|
| | | continue
|
| | | |
| | | |
| | | spidDict[spID] = 0
|
| | | cnt += 1
|
| | | |
| | | print "录入渠道返利结束,总共%s条, 含平台%s"%(cnt, spidDict.keys())
|
| | | |
| | | |
| | | #开始录入数据
|
| | | #录入渠道返利结束,总共681条, 含平台['kupai', 'uc', 'gionee', 'xiaomi', 'vivo', 'lenovo', 'meizu', 'yyb', 'oppo', 'qh360']
|
| | | |
| | | |
| | | def test():
|
| | |
|
| | | test_DBController()
|
| | | print 'test ok!'
|
| | |
|
| | | if __name__ == '__main__':
|
| | | test()
|
| | | import os
|
| | | os.system("pause")
|
New file |
| | |
| | | #!/usr/bin/python
|
| | | # -*- coding: GBK -*-
|
| | | #
|
| | | ##@package
|
| | | #
|
| | | # @todo: |
| | | #
|
| | | # @author: Alee
|
| | | # @date 2018-7-18 上午11:22:43
|
| | | # @version 1.0
|
| | | #
|
| | | # @note: |
| | | #
|
| | | #---------------------------------------------------------------------
|
| | |
|
| | | import struct
|
| | | import string
|
| | | import datetime
|
| | | import os
|
| | | import binascii
|
| | | import socket
|
| | | import sys
|
| | |
|
| | |
|
| | | #python的读取/写入库
|
| | | #要进行反转高低位的话,可使用!符号,如struct.unpack_from('!B', buf, pos)
|
| | |
|
| | | #------------------------读取 |
| | | def ReadBYTE(buf, pos):
|
| | | curValue = struct.unpack_from('b', buf, pos)
|
| | | pos += 1
|
| | | return curValue[0], pos
|
| | |
|
| | | def ReadWORD(buf, pos):
|
| | | curValue = struct.unpack_from('H', buf, pos)
|
| | | pos += 2 |
| | | return curValue[0], pos
|
| | |
|
| | | def ReadDWORD(buf, pos):
|
| | | curValue = struct.unpack_from('i', buf, pos) |
| | | pos += 4
|
| | | return curValue[0], pos
|
| | |
|
| | | def ReadFloat(buf, pos):
|
| | | curValue = struct.unpack_from('f', buf, pos) |
| | | pos += 4
|
| | | return curValue[0], pos
|
| | |
|
| | | def ReadDouble(buf, pos):
|
| | | curValue = struct.unpack_from('d', buf, pos) |
| | | pos += 8
|
| | | return curValue[0], pos
|
| | |
|
| | | def ReadString(buf, pos, _len):
|
| | | curValue = struct.unpack_from('%ds'%_len, buf, pos)
|
| | | pos += _len |
| | | return curValue[0], pos
|
| | |
|
| | |
|
| | | #----------------------写入
|
| | | def WriteBYTE(buf, value):
|
| | | buf += struct.pack('b', value)
|
| | | return buf
|
| | |
|
| | | def WriteWORD(buf, value):
|
| | | buf += struct.pack('H', value)
|
| | | return buf
|
| | |
|
| | | def WriteDWORD(buf, value):
|
| | | buf += struct.pack('i', value)
|
| | | return buf
|
| | |
|
| | | def WriteFloat(buf, value):
|
| | | buf += struct.pack('f', value)
|
| | | return buf
|
| | |
|
| | | def WriteDouble(buf, value):
|
| | | buf += struct.pack('d', value)
|
| | | return buf
|
| | |
|
| | | def WriteString(buf, len, value):
|
| | | buf += struct.pack('%ds'%len, value)
|
| | | return buf
|
| | |
|
| | |
|
| | |
|
| | | #获得当前系统时间
|
| | | def GetCurrentDataTimeStr():
|
| | | curTime = datetime.datetime.today()
|
| | | curTimeStr = str(curTime)
|
| | | curTimeStr = curTimeStr.split(".")[0]
|
| | | return curTimeStr
|
| | |
|
| | | #获得系统时间(参数 -> 时间列表)
|
| | | def GetDateTimeByStr(timeStr):
|
| | | timeStr = timeStr.split(".")[0]
|
| | | return datetime.datetime.strptime(timeStr, "%Y-%m-%d %H:%M:%S")
|
| | | |
| | | |
| | | |
| | | #字符串转换为整型, 如果不能转换, 返回默认值
|
| | | def ToIntDef(input, defValue = 0):
|
| | | try:
|
| | | result = int(input)
|
| | | return result
|
| | | except ValueError:
|
| | | return defValue
|
| | | |
| | | |
| | | #字符串转换为整型, 如果不能转换, 返回False,原值
|
| | | def StrToInt(input):
|
| | | try:
|
| | | result = int(input)
|
| | | return True,result
|
| | | except ValueError:
|
| | | return False,input
|
| | | |
| | | |
| | | #16进制颜色转换
|
| | | #"#FFFFFF"--"255,255,255"
|
| | | def HcToSc(h):
|
| | | h="0x"+h[1:7]
|
| | | red=string.atoi(h[:2]+h[2:4], base=16)
|
| | | green=string.atoi(h[:2]+h[4:6], base=16)
|
| | | blue=string.atoi(h[:2]+h[6:8], base=16)
|
| | | cStr=str(red)+","+str(green)+","+str(blue)
|
| | | return cStr
|
| | |
|
| | | #"255,255,255"--"#FFFFFF"
|
| | | def ScToHc(s):
|
| | | red=hex(string.atoi(s.split(",")[0]))[2:]
|
| | | green=hex(string.atoi(s.split(",")[1]))[2:]
|
| | | blue=hex(string.atoi(s.split(",")[2]))[2:]
|
| | | hStr="#"+str(red+green+blue)
|
| | | return hStr
|
| | |
|
| | | #16进制转换
|
| | | #"0xFFFFFF"--"255,255,255"
|
| | | def HdToSd(h):
|
| | | red=string.atoi(h[0:2]+h[2:4], base=16)
|
| | | green=string.atoi(h[0:2]+h[4:6], base=16)
|
| | | blue=string.atoi(h[0:2]+h[6:8], base=16)
|
| | | cStr=str(red)+","+str(green)+","+str(blue)
|
| | | return cStr
|
| | |
|
| | | #"255,255,255"--"0xFFFFFF"
|
| | | def SdToHd(s):
|
| | | red=hex(string.atoi(s.split(",")[0]))[2:]
|
| | | green=hex(string.atoi(s.split(",")[1]))[2:]
|
| | | blue=hex(string.atoi(s.split(",")[2]))[2:]
|
| | | hStr="0x"+str(red+green+blue)
|
| | | return hStr
|
| | |
|
| | | def GetPercent(value1, value2):
|
| | | if value2 == 0:
|
| | | return 0
|
| | | return int(float(value1) / float(value2) * 100)
|
| | |
|
| | |
|
| | |
|
| | | def OpenFileForWrite(fileName):
|
| | | dirName = os.path.dirname(fileName)
|
| | | if not os.path.isdir(dirName):
|
| | | os.makedirs(dirName)
|
| | | |
| | | if os.path.isfile(fileName):
|
| | | return open(fileName, 'w')
|
| | | return open(fileName, 'a')
|
| | |
|
| | |
|
| | |
|
| | |
|
| | | #函数调用
|
| | | def ParseNameGetObj(curCallObj, callName):
|
| | | callList = callName.split(".")
|
| | | if len(callList) <= 1:
|
| | | return None
|
| | | |
| | | for curCallName in callList:
|
| | | if hasattr(curCallObj, curCallName) != True:
|
| | | #无此属性
|
| | | return None
|
| | | curCallObj = getattr(curCallObj, curCallName)
|
| | | return curCallObj
|
| | |
|
| | | #获得执行函数
|
| | | def GetExecFunc(curCallObj, callName):
|
| | | curCallObj = ParseNameGetObj(curCallObj, callName)
|
| | | if curCallObj == None:
|
| | | return None
|
| | | |
| | | if callable(curCallObj) != True:
|
| | | #不可调用
|
| | | return None
|
| | | |
| | | return curCallObj
|
| | |
|
| | | #字符串异或处理
|
| | | def str_xor(astring, xornum=150):
|
| | | a=[]
|
| | | for x in astring:
|
| | | a.append(chr(ord(x)^xornum))
|
| | | return ''.join(a)
|
| | |
|
| | | #解析封包
|
| | | def ParseBuff(buff):
|
| | | result=''
|
| | | for i in range(len(buff)):
|
| | | if i%2==0 and i!=0:
|
| | | result=result + ' ' + buff[i]
|
| | | else: |
| | | result = result + buff[i] |
| | | return result
|
| | |
|
| | | def b2a_hex(data):
|
| | | return ParseBuff(binascii.b2a_hex(data))
|
| | |
|
| | | def GetHostName():
|
| | | return socket.gethostname()
|
| | |
|
| | | def GetHostIP():
|
| | | return socket.gethostbyname(GetHostName()) |
| | |
|
| | |
|
| | | def compact_traceback():
|
| | | t, v, tb = sys.exc_info()
|
| | | tbinfo = []
|
| | | if not tb: # Must have a traceback
|
| | | raise AssertionError("traceback does not exist")
|
| | | while tb:
|
| | | tbinfo.append((
|
| | | tb.tb_frame.f_code.co_filename,
|
| | | tb.tb_frame.f_code.co_name,
|
| | | str(tb.tb_lineno)
|
| | | ))
|
| | | tb = tb.tb_next
|
| | |
|
| | | # just to be safe
|
| | | del tb
|
| | |
|
| | | info = ' '.join(['[%s|%s|%s]' % x for x in tbinfo])
|
| | | return t, v, info
|
| | |
|
| | | import base64
|
| | | import urllib
|
| | | import urllib2
|
| | |
|
| | | #---------------------------------------------------------------------
|
| | | ## 加密算法需要的定义
|
| | | Def_NumEncodeCnt = 3 # 加密的次数
|
| | | Def_NumXorKey = 151 # 异或的key
|
| | |
|
| | | ## 公司内部解密算法
|
| | | def GetDecodePwd(strPwd):
|
| | | strResult = strPwd
|
| | | for index in xrange(Def_NumEncodeCnt):
|
| | | strResult = base64.b64decode(strResult)
|
| | |
|
| | | tempResult = ""
|
| | | for index in xrange(len(strResult)):
|
| | | tempResult += chr(ord(strResult[index])^Def_NumXorKey)
|
| | |
|
| | | return tempResult
|
| | |
|
| | |
|
| | | ## 公司内部加密算法
|
| | | def GetEncodePwd(strPwd):
|
| | | strResult = ""
|
| | | for index in xrange(len(strPwd)):
|
| | | strResult += chr(ord(strPwd[index])^Def_NumXorKey)
|
| | |
|
| | | for index in xrange(Def_NumEncodeCnt):
|
| | | strResult = base64.b64encode(strResult)
|
| | |
|
| | | return strResult
|
| | |
|
| | |
|
| | |
|
| | | #---------------------------------------------------------------------
|
| | | ## UTF-8 <==> GBK
|
| | | def gbk2utf8(content):
|
| | | if type( content ) is not str:
|
| | | content = str(content)
|
| | |
|
| | | try:
|
| | | return content.decode('gbk').encode('utf-8')
|
| | | except:
|
| | | return content
|
| | |
|
| | |
|
| | | def utf82gbk(content):
|
| | | if type( content ) is not str:
|
| | | content = str(content)
|
| | |
|
| | | try:
|
| | | return content.decode('utf-8').encode('gbk')
|
| | | except:
|
| | | return content
|
| | |
|
| | |
|
| | | ## GET请求
|
| | | def DoGet(url, data=None, headers={}): |
| | | if data: |
| | | request = urllib2.Request(url + "?" + urllib.urlencode(data), None, headers)
|
| | | else:
|
| | | request = urllib2.Request(url, None, headers)
|
| | | response = urllib2.urlopen(request, timeout=5)
|
| | | content = response.read()
|
| | | response.close()
|
| | | return content
|
| | |
|
| | |
|
| | | ## POST请求
|
| | | def DoPost(url, data, headers={}):
|
| | | try:
|
| | | data = urllib.urlencode(data)
|
| | | except:
|
| | | pass
|
| | | |
| | | request = urllib2.Request(url, data, headers)
|
| | | try:
|
| | | response = urllib2.urlopen(request, timeout=30)
|
| | | content = response.read()
|
| | | response.close()
|
| | | except:
|
| | | content = "error timeout"
|
| | | return content
|
| | |
|
| | |
|
| | | FileTypeDict = {
|
| | | '.txt':'text/html',
|
| | | '.html':'text/html',
|
| | | '.htm':'text/html',
|
| | | '.bmp':'application/x-bmp',
|
| | | '.ico':'image/x-icon',
|
| | | '.jpe':'image/jpeg',
|
| | | '.jpeg':'image/jpeg',
|
| | | '.jpg':'application/x-jpg',
|
| | | '.png':'application/x-png',
|
| | | '.gif':'image/gif',
|
| | | '.bin':'application/octet-stream',
|
| | | '.*':'application/octet-stream'
|
| | | }
|
| | |
|
| | | def GetHttpContentType(strType):
|
| | | return FileTypeDict[strType]
|
| | |
|
| | |
|
| | |
|
| | | ## 编码
|
| | | # @param srcEncoding 编码格式
|
| | | # @param input 字符串
|
| | | # @return None
|
| | | def EncodingToUnicode(srcEncoding, msg):
|
| | | try:
|
| | | result = unicode(msg, srcEncoding) #translate to utf-8
|
| | | except:
|
| | | return "EncodingToUnicode error"
|
| | | return result
|
| | |
|
| | |
|
| | | ## 编码
|
| | | # @param srcEncoding 编码格式
|
| | | # @param input 字符串
|
| | | # @return None
|
| | | def UnicodeToEncoding(dstEncoding, msg):
|
| | | try:
|
| | | result = msg.encode(dstEncoding)
|
| | | except:
|
| | | return "UnicodeToEncoding error"
|
| | | return result
|
New file |
| | |
| | | #!/usr/bin/python
|
| | | # -*- coding: GBK -*-
|
| | | #-------------------------------------------------------------------------------
|
| | | #
|
| | | #-------------------------------------------------------------------------------
|
| | | #
|
| | |
|
| | | import pymongo
|
| | | from pymongo.son_manipulator import SONManipulator
|
| | | import base64
|
| | | from functools import wraps
|
| | | from time import (sleep)
|
| | |
|
| | | import CommFunc
|
| | |
|
| | | #模拟SQL的IDENT
|
| | | def seq(db, collectionName, fieldName, feed, increment):
|
| | | try:
|
| | | result = 0
|
| | | collection = db['%s_seq'%collectionName]
|
| | | resultObj = collection.find_and_modify(query={'_id':fieldName}, update={'$inc':{'seq':increment}}, new=True)
|
| | | if resultObj:
|
| | | result = resultObj['seq']
|
| | | else:
|
| | | resultObj = collection.find_and_modify(query={'_id':fieldName}, update={'$set':{'seq':feed}}, new=True,
|
| | | upsert=True)
|
| | | if resultObj:
|
| | | result = resultObj['seq']
|
| | | else:
|
| | | return False, None
|
| | | except Exception, e:
|
| | | return False, None
|
| | | return True, result
|
| | |
|
| | | class ObjectIdRemover(SONManipulator):
|
| | | def transform_outgoing(self, son, collection):
|
| | | if '_id' in son:
|
| | | del son['_id']
|
| | | return son
|
| | |
|
| | | class EncodeStringManipulator(SONManipulator):
|
| | | def __init__(self, encoding):
|
| | | self.encoding = encoding
|
| | | def transform_incoming(self, son, collection):
|
| | | |
| | | def transform_value(value):
|
| | | if isinstance(value, dict):
|
| | | return transform_dict(value)
|
| | | elif isinstance(value, list):
|
| | | return [transform_value(v) for v in value]
|
| | | elif isinstance(value, basestring):
|
| | | result, value = CommFunc.EncodingToUnicode(self.encoding, value)
|
| | | return value
|
| | | return value
|
| | | |
| | | def transform_dict(object):
|
| | | for (key, value) in object.items():
|
| | | object[key] = transform_value(value)
|
| | | return object
|
| | | |
| | | def transform_list(container):
|
| | | for item in container:
|
| | | transform_dict(item)
|
| | | return container
|
| | | |
| | | if isinstance(son, dict):
|
| | | return transform_dict(son)
|
| | | elif isinstance(son, list):
|
| | | return transform_list(son)
|
| | | return son
|
| | | |
| | | def transform_outgoing(self, son, collection):
|
| | | |
| | | def transform_value(value):
|
| | | if isinstance(value, dict):
|
| | | return transform_dict(value)
|
| | | elif isinstance(value, list):
|
| | | return [transform_value(v) for v in value]
|
| | | elif isinstance(value, basestring):
|
| | | result, value =CommFunc.UnicodeToEncoding(self.encoding, value)
|
| | | return value
|
| | | return value
|
| | | |
| | | def transform_dict(object):
|
| | | for (key, value) in object.items():
|
| | | object[key] = transform_value(value)
|
| | | return object
|
| | | |
| | | def transform_list(container):
|
| | | for item in container:
|
| | | transform_dict(item)
|
| | | return container
|
| | | |
| | | if isinstance(son, dict):
|
| | | return transform_dict(son)
|
| | | elif isinstance(son, list):
|
| | | return transform_list(son)
|
| | | return son
|
| | | |
| | | class Base64StringManipulator(SONManipulator):
|
| | | |
| | | def transform_incoming(self, son, collection):
|
| | | |
| | | def transform_value(value):
|
| | | if isinstance(value, dict):
|
| | | return transform_dict(value)
|
| | | elif isinstance(value, list):
|
| | | return [transform_value(v) for v in value]
|
| | | elif isinstance(value, basestring):
|
| | | return base64.b64encode(value)
|
| | | return value
|
| | | |
| | | def transform_dict(object):
|
| | | for (key, value) in object.items():
|
| | | object[key] = transform_value(value)
|
| | | return object
|
| | | |
| | | def transform_list(container):
|
| | | for item in container:
|
| | | transform_dict(item)
|
| | | return container
|
| | | |
| | | if isinstance(son, dict):
|
| | | return transform_dict(son)
|
| | | elif isinstance(son, list):
|
| | | return transform_list(son)
|
| | | return son
|
| | | |
| | | def transform_outgoing(self, son, collection):
|
| | | |
| | | def transform_value(value):
|
| | | if isinstance(value, dict):
|
| | | return transform_dict(value)
|
| | | elif isinstance(value, list):
|
| | | return [transform_value(v) for v in value]
|
| | | elif isinstance(value, basestring):
|
| | | return base64.b64decode(value)
|
| | | return value
|
| | | |
| | | def transform_dict(object):
|
| | | for (key, value) in object.items():
|
| | | object[key] = transform_value(value)
|
| | | return object
|
| | | |
| | | def transform_list(container):
|
| | | for item in container:
|
| | | transform_dict(item)
|
| | | return container
|
| | | |
| | | if isinstance(son, dict):
|
| | | return transform_dict(son)
|
| | | elif isinstance(son, list):
|
| | | return transform_list(son)
|
| | | return son
|
| | | |
| | | #用于修饰DBController的数据库操作函数
|
| | | #断线自动重试
|
| | | def reconnect_decorator(func):
|
| | | @wraps(func)
|
| | | def wrapper(*args, **kwds):
|
| | | MAX_RECONNECT = 10
|
| | | RECONNECT_INTERVAL = 0.1
|
| | | failCnt = 0
|
| | | while True:
|
| | | try:
|
| | | #去掉self
|
| | | return func(*args, **kwds)
|
| | | except pymongo.errors.AutoReconnect, e:
|
| | | failCnt += 1
|
| | | sleep(RECONNECT_INTERVAL)
|
| | | if failCnt > MAX_RECONNECT:
|
| | | raise e
|
| | | |
| | | return wrapper
|
| | |
|
| | | class DBController:
|
| | | def __init__(self, host, port, dbName, user, pwd, encoding):
|
| | | self.host = host
|
| | | self.port = port
|
| | | self.dbName = dbName
|
| | | self.user = user
|
| | | self.pwd = pwd
|
| | | |
| | | self.connected = False
|
| | | self.con = None
|
| | | self.db = None
|
| | | self.lastError = None
|
| | | self.translator = None
|
| | | #===========================================================================================
|
| | | # if encoding == 'base64':
|
| | | # self.translator = Base64StringManipulator()
|
| | | # else:
|
| | | # self.translator = EncodeStringManipulator(encoding)
|
| | | #===========================================================================================
|
| | | self.initialize()
|
| | | |
| | | def initialize(self):
|
| | | if not self.connected:
|
| | | if not self.doConnect(self.host, self.port):
|
| | | return False
|
| | | authResult = self.doAuthentication(self.dbName, self.user, self.pwd)
|
| | | if self.db:
|
| | | self.db.add_son_manipulator(ObjectIdRemover())
|
| | | return authResult
|
| | | return True
|
| | | |
| | | def doConnect(self, ip, port):
|
| | | try:
|
| | | self.con = pymongo.Connection(ip, port)
|
| | | except TypeError, typeError:
|
| | | raise
|
| | | except pymongo.errors.ConnectionFailure, failure:
|
| | | self.lastError = failure
|
| | | return False
|
| | | except Exception, e:
|
| | | self.lastError = e
|
| | | return False
|
| | | except:
|
| | | self.lastError = 'Unknown exception occur!'
|
| | | return False
|
| | | self.connected = True
|
| | | return True
|
| | | |
| | | def doAuthentication(self, dbName, user, pwd):
|
| | | if not self.connected or not self.con:
|
| | | self.lastError = 'Not connected yet!'
|
| | | return False
|
| | | self.db = self.con[dbName]
|
| | | authDB = self.con['admin']
|
| | | try:
|
| | | return authDB.authenticate(user, pwd)
|
| | | # return self.db.authenticate(user, pwd)
|
| | | except TypeError, typeError:
|
| | | self.lastError = typeError
|
| | | return False
|
| | | except Exception, e:
|
| | | self.lastError = e
|
| | | return False
|
| | | except:
|
| | | self.lastError = 'Unknown exception occur!'
|
| | | return False
|
| | | |
| | | def find_one(self, colName, spec, filter = None):
|
| | | result, recList = self.find(colName, spec, filter, 1)
|
| | | if not result:
|
| | | return False, None
|
| | | for rec in recList:
|
| | | return True, rec
|
| | | return True, None
|
| | | |
| | | @reconnect_decorator
|
| | | def find(self, colName, spec = None, filter = None, maxCnt = 0, sortBy = None):
|
| | | if not self.connected:
|
| | | if not self.initialize():
|
| | | return False, []
|
| | | |
| | | result = False
|
| | | resultDictList = []
|
| | | col = self.db[colName]
|
| | | if self.translator:
|
| | | spec = self.translator.transform_incoming(spec, None)
|
| | | try:
|
| | | resultCollection = col.find(spec, filter, limit = maxCnt, sort = sortBy)
|
| | | if self.translator:
|
| | | resultDictList = self.translator.transform_outgoing(list(resultCollection), None)
|
| | | else:
|
| | | resultDictList = list(resultCollection)
|
| | | return True, resultDictList
|
| | | except TypeError, typeError:
|
| | | self.lastError = typeError
|
| | | return result, resultDictList
|
| | | except pymongo.errors.OperationFailure, err:
|
| | | self.lastError = err
|
| | | return result, resultDictList
|
| | | except Exception, e:
|
| | | self.lastError = e
|
| | | return result, resultDictList
|
| | | except:
|
| | | self.lastError = 'Unknown exception occur!'
|
| | | return result, resultDictList |
| | | |
| | | @reconnect_decorator
|
| | | def insert(self, colName, doc_or_docs, isSafe = True):
|
| | | if not self.connected:
|
| | | if not self.initialize():
|
| | | return False
|
| | | |
| | | col = self.db[colName]
|
| | | if self.translator:
|
| | | doc_or_docs = self.translator.transform_incoming(doc_or_docs, None)
|
| | | try:
|
| | | col.insert(doc_or_docs, safe = isSafe)
|
| | | except pymongo.errors.OperationFailure, err:
|
| | | self.lastError = err
|
| | | return False
|
| | | except Exception, e:
|
| | | self.lastError = e
|
| | | return False
|
| | | except:
|
| | | self.lastError = 'Unknown exception occur!'
|
| | | return False
|
| | | return True
|
| | | |
| | | @reconnect_decorator
|
| | | def update(self, colName, spec, doc, isUpsert = False, isSafe = True, isMulti = False):
|
| | | if not self.connected:
|
| | | if not self.initialize():
|
| | | return False
|
| | | |
| | | col = self.db[colName]
|
| | | #需要先对doc进行处理,但由不能开启collection.update的manipulate,因为那会应用所有处理
|
| | | if self.translator:
|
| | | spec = self.translator.transform_incoming(spec, None)
|
| | | doc = self.translator.transform_incoming(doc, None)
|
| | | try:
|
| | | col.update(spec, doc, upsert = isUpsert, safe = isSafe, multi = isMulti)
|
| | | except TypeError, typeError:
|
| | | self.lastError = typeError
|
| | | return False
|
| | | except pymongo.errors.OperationFailure, err:
|
| | | self.lastError = err
|
| | | return False
|
| | | except Exception, e:
|
| | | self.lastError = e
|
| | | return False
|
| | | except:
|
| | | self.lastError = 'Unknown exception occur!'
|
| | | return False
|
| | | return True
|
| | | |
| | | @reconnect_decorator
|
| | | def save(self, colName, doc, isSafe = True):
|
| | | if not self.connected:
|
| | | if not self.initialize():
|
| | | return False
|
| | | |
| | | col = self.db[colName]
|
| | | if self.translator:
|
| | | doc = self.translator.transform_incoming(doc, None)
|
| | | try:
|
| | | col.save(doc, safe = isSafe)
|
| | | except TypeError, typeError:
|
| | | self.lastError = typeError
|
| | | return False
|
| | | except pymongo.errors.OperationFailure, err:
|
| | | self.lastError = err
|
| | | return False
|
| | | except Exception, e:
|
| | | self.lastError = e
|
| | | return False
|
| | | except:
|
| | | self.lastError = 'Unknown exception occur!'
|
| | | return False
|
| | | return True
|
| | | |
| | | @reconnect_decorator
|
| | | def remove(self, colName, spec = None, isSafe = True):
|
| | | if not self.connected:
|
| | | if not self.initialize():
|
| | | return False
|
| | | |
| | | col = self.db[colName]
|
| | | if self.translator:
|
| | | spec = self.translator.transform_incoming(spec, None)
|
| | | try:
|
| | | col.remove(spec, safe = isSafe)
|
| | | except pymongo.errors.OperationFailure, err:
|
| | | self.lastError = err
|
| | | return False
|
| | | except Exception, e:
|
| | | self.lastError = e
|
| | | return False
|
| | | except:
|
| | | self.lastError = 'Unknown exception occur!'
|
| | | return False
|
| | | return True
|
| | | |
| | | @reconnect_decorator
|
| | | def drop(self, colName):
|
| | | if not self.connected:
|
| | | if not self.initialize():
|
| | | return False
|
| | | |
| | | col = self.db[colName]
|
| | | try:
|
| | | col.drop()
|
| | | except TypeError, typeError:
|
| | | self.lastError = typeError
|
| | | return False
|
| | | except Exception, e:
|
| | | self.lastError = e
|
| | | return False
|
| | | except:
|
| | | self.lastError = 'Unknown exception occur!'
|
| | | return False
|
| | | return True
|
| | | |
| | | @reconnect_decorator
|
| | | def count(self, colName):
|
| | | if not self.connected:
|
| | | if not self.initialize():
|
| | | return False, 0
|
| | | |
| | | col = self.db[colName]
|
| | | try:
|
| | | cnt = col.count()
|
| | | except pymongo.errors.OperationFailure, err:
|
| | | self.lastError = err
|
| | | return False, 0
|
| | | except Exception, e:
|
| | | self.lastError = e
|
| | | return False, 0
|
| | | except:
|
| | | self.lastError = 'Unknown exception occur!'
|
| | | return False, 0
|
| | | return True, cnt
|
| | | |
| | | def test_seq():
|
| | | con = pymongo.Connection()
|
| | | db = con.admin
|
| | | if not db.authenticate('sa', 'sa'):
|
| | | print 'auth failed!'
|
| | | return
|
| | | colName = 'tagSeqTest'
|
| | | fieldName = 'ID'
|
| | | db = con['test']
|
| | | db.drop_collection(colName)
|
| | | db.drop_collection('%s_seq'%colName)
|
| | | |
| | | result, ID = seq(db, colName, fieldName, 1, 1)
|
| | | assert (result and ID == 1)
|
| | | result, ID = seq(db, colName, fieldName, 1, 1)
|
| | | assert (result and ID == 2)
|
| | | |
| | | def test_StringManipulator():
|
| | | translator = Base64StringManipulator()
|
| | | |
| | | son = []
|
| | | result = translator.transform_incoming(son, None)
|
| | | assert (son == result)
|
| | | result = translator.transform_outgoing(son, None)
|
| | | assert (son == result)
|
| | | |
| | | son = [{'a':1}]
|
| | | result = translator.transform_incoming(son, None)
|
| | | assert (son == result)
|
| | | result = translator.transform_outgoing(son, None)
|
| | | assert (son == result)
|
| | | |
| | | son = [{'a':'a'}]
|
| | | result = translator.transform_incoming(son, None)
|
| | | assert (result and result == [{'a':base64.b64encode('a')}])
|
| | | result = translator.transform_outgoing(result, None)
|
| | | assert (result and result == son)
|
| | | |
| | | son = [{'a':[{'b':'b'}, {'c':'c'}]}]
|
| | | result = translator.transform_incoming(son, None)
|
| | | assert (result and result == [{'a':[{'b':base64.b64encode('b')}, {'c':base64.b64encode('c')}]}])
|
| | | result = translator.transform_outgoing(result, None)
|
| | | assert (result and result == son)
|
| | | |
| | | def test_DBController():
|
| | | testColName = 'tagTestController'
|
| | | dbController = DBController('localhost', 27017, 'test', 'test', '1')
|
| | | result = dbController.drop(testColName)
|
| | | assert result
|
| | | |
| | | result, cnt = dbController.count(testColName)
|
| | | assert (result and cnt == 0)
|
| | | |
| | | doc = {'a':1}
|
| | | result = dbController.insert(testColName, doc)
|
| | | assert result
|
| | | |
| | | result, recs = dbController.find(testColName)
|
| | | assert (result and len(recs) == 1)
|
| | | rec = recs[0]
|
| | | # del rec['_id']
|
| | | # print 'rec = %s\r\ndoc = %s'%(rec, doc)
|
| | | assert (rec == doc)
|
| | | |
| | | spec = {'a':1}
|
| | | updateDoc = {'a':2}
|
| | | updateDocWithModifier = {'$set':updateDoc}
|
| | | result = dbController.update(testColName, spec, updateDocWithModifier)
|
| | | assert result
|
| | | result, recs = dbController.find(testColName)
|
| | | assert (result and len(recs) == 1)
|
| | | rec = recs[0]
|
| | | del rec['_id']
|
| | | # print 'rec = %s\r\nupdateDoc = %s'%(rec, updateDoc)
|
| | | assert (rec == updateDoc)
|
| | | |
| | | result = dbController.remove(testColName)
|
| | | assert result
|
| | | result, recs = dbController.find(testColName)
|
| | | assert (result and recs == [])
|
| | | |
| | | saveDoc = {'b':3}
|
| | | result = dbController.save(testColName, saveDoc)
|
| | | assert result
|
| | | result, recs = dbController.find(testColName)
|
| | | assert (result and len(recs) == 1)
|
| | | rec = recs[0]
|
| | | # del rec['_id']
|
| | | assert (rec == saveDoc)
|
| | | |
| | | def test():
|
| | | test_seq()
|
| | | test_StringManipulator()
|
| | | test_DBController()
|
| | | print 'test ok!'
|
| | |
|
| | | if __name__ == '__main__':
|
| | | test()
|
| | | |
New file |
| | |
| | | #!/usr/bin/python
|
| | | # -*- coding: GBK -*-
|
| | | #
|
| | | ##@package
|
| | | #
|
| | | # @todo: |
| | | #
|
| | | # @author: Alee
|
| | | # @date 2018-6-5 下午08:20:53
|
| | | # @version 1.0
|
| | | #
|
| | | # @note: |
| | | #
|
| | | #---------------------------------------------------------------------
|
| | | import ConfigParser
|
| | |
|
| | |
|
| | | class ReadConfig():
|
| | | def __init__(self, filePath):
|
| | | self.__config = ConfigParser.ConfigParser()
|
| | | self.__config.read(filePath)
|
| | |
|
| | | def GetValue(self, section, option, default=None, isThrowException=False):
|
| | | try:
|
| | | return self.__config.get(section, option);
|
| | | except Exception, err:
|
| | | if not isThrowException:
|
| | | return default;
|
| | | raise Exception, "Error:配置问题,%s"%err;
|
| | |
|
| | | get = GetValue;
|
| | |
|
| | | def GetInt(self, section, option, default = 0, isThrowException=False):
|
| | | try:
|
| | | return self.__config.getint(section, option);
|
| | | except Exception, err:
|
| | | if not isThrowException:
|
| | | return default;
|
| | | raise Exception, "Error:配置问题,%s"%err;
|
| | |
|
| | | getint = GetInt;
|
| | |
|
| | | def GetBoolean(self, section, option, default = False):
|
| | | try:
|
| | | return self.__config.getboolean(section, option);
|
| | | except ValueError:
|
| | | default = str(default).lower();
|
| | | if default not in self.__config._boolean_states:
|
| | | return False;
|
| | | else:
|
| | | return self.__config._boolean_states[default];
|
| | |
|
| | | getboolean = GetBoolean;
|
| | |
|
| | | def HasSection(self, section):
|
| | | return self.__config.has_section(section)
|
| | |
|
| | | def HasOption(self, section, option):
|
| | | return self.__config.has_option(section, option)
|
| | | |
| | |
|
| | | #===============================================================================
|
| | | # ## 读取Eval的值
|
| | | # def GetEvalConfig(path):
|
| | | # with open(path, "r") as file:
|
| | | # content = file.read()
|
| | | # try:
|
| | | # value = eval(content)
|
| | | # except:
|
| | | # value = None
|
| | | # |
| | | # return value
|
| | | #===============================================================================
|
| | | |
New file |
| | |
| | | #!/usr/bin/python
|
| | | # -*- coding: GBK -*-
|
| | | #
|
| | | ##@package
|
| | | #
|
| | | # @todo: |
| | | #
|
| | | # @author: Alee
|
| | | # @date 2018-7-18 上午11:40:53
|
| | | # @version 1.0
|
| | | #
|
| | | # @note: |
| | | #
|
| | | #---------------------------------------------------------------------
|
| | |
|
| | | #根据时间切换目录和文件的文件处理器
|
| | |
|
| | | from logging.handlers import *
|
| | |
|
| | | class TimeRotatingPathFileHandler(TimedRotatingFileHandler):
|
| | | def __init__(self, root, filename, when = 'h', interval = 1, backupCount = 0, encoding = None, delay = False, utc = False):
|
| | | #创建输出目录数
|
| | | t = int(time.time())
|
| | | if utc:
|
| | | timeTup = time.gmtime(t)
|
| | | else:
|
| | | timeTup = time.localtime(t)
|
| | | year = timeTup[0]
|
| | | month = timeTup[1]
|
| | | day = timeTup[2]
|
| | | self.root = root
|
| | | self.filename = filename
|
| | | self.baseFilename = self.getBaseFileName(self.root, year, month, day, self.filename)
|
| | | |
| | | #print 'baseFileName = %s'%self.baseFilename
|
| | | filepath = os.path.dirname(self.baseFilename)
|
| | | self.ensurePath(filepath)
|
| | | #改变当前工作目录
|
| | | #if not (os.getcwd() == filepath):
|
| | | # os.chdir(filepath)
|
| | | TimedRotatingFileHandler.__init__(self, self.baseFilename, when, interval, backupCount, encoding, delay, utc)
|
| | | #self.suffix = ''#不指定后缀
|
| | | |
| | | def getBaseFileName(self, root, year, month, day, filename):
|
| | | filenameWithoutExt = filename.split('.')[0]
|
| | | return os.path.join(root, '%04d-%02d\\%s\\%02d\\%s'%(year, month, filenameWithoutExt, day, filename))
|
| | | |
| | | def ensurePath(self, filepath):
|
| | | if not os.path.exists(filepath):
|
| | | os.makedirs(filepath)
|
| | | |
| | | def doRollover(self):
|
| | | lastRolloverTime = self.rolloverAt
|
| | | #TimedRotatingFileHandler.doRollover(self)
|
| | | if self.stream:
|
| | | self.stream.close()
|
| | | self.stream = None
|
| | | #获取上一次切换的时间
|
| | | t = self.rolloverAt - self.interval
|
| | | if self.utc:
|
| | | timeTuple = time.gmtime(t)
|
| | | else:
|
| | | timeTuple = time.localtime(t)
|
| | | filenameTuple = self.filename.split('.')
|
| | | filename = ''
|
| | | if len(filenameTuple) == 1:
|
| | | filename = '%s-%s'%(filenameTuple[0], time.strftime(self.suffix, timeTuple))
|
| | | else:
|
| | | filename = '%s-%s.%s'%(filenameTuple[0], time.strftime(self.suffix, timeTuple), filenameTuple[len(filenameTuple) - 1])
|
| | | dfn = os.path.join(self.root, '%04d-%02d\\%s\\%02d\\%s'%(timeTuple[0], timeTuple[1], filenameTuple[0], timeTuple[2], filename))
|
| | | #dfn = self.baseFilename + "." + time.strftime(self.suffix, timeTuple)
|
| | | if os.path.exists(dfn):
|
| | | os.remove(dfn)
|
| | | # print 'dfn = %s baseFilename = %s'%(dfn, self.baseFilename)
|
| | | #可能由于改系统时间或其他人为原因造成文件找不到
|
| | | if os.path.exists(self.baseFilename):
|
| | | os.rename(self.baseFilename, dfn)
|
| | | if self.backupCount > 0:
|
| | | # find the oldest log file and delete it
|
| | | #s = glob.glob(self.baseFilename + ".20*")
|
| | | #if len(s) > self.backupCount:
|
| | | # s.sort()
|
| | | # os.remove(s[0])
|
| | | for s in self.getFilesToDelete():
|
| | | os.remove(s)
|
| | | |
| | | currentTime = int(time.time())
|
| | | newRolloverAt = self.computeRollover(currentTime)
|
| | | while newRolloverAt <= currentTime:
|
| | | newRolloverAt = newRolloverAt + self.interval
|
| | | #If DST changes and midnight or weekly rollover, adjust for this.
|
| | | if (self.when == 'MIDNIGHT' or self.when.startswith('W')) and not self.utc:
|
| | | dstNow = time.localtime(currentTime)[-1]
|
| | | dstAtRollover = time.localtime(newRolloverAt)[-1]
|
| | | if dstNow != dstAtRollover:
|
| | | if not dstNow: # DST kicks in before next rollover, so we need to deduct an hour
|
| | | newRolloverAt = newRolloverAt - 3600
|
| | | else: # DST bows out before next rollover, so we need to add an hour
|
| | | newRolloverAt = newRolloverAt + 3600
|
| | | self.rolloverAt = newRolloverAt
|
| | | |
| | | #判断是否需要切换文件夹
|
| | | nextRolloverTime = self.rolloverAt
|
| | | if self.utc:
|
| | | lastRolloverTimeTup = time.gmtime(lastRolloverTime)
|
| | | nextRolloverTimeTup = time.gmtime(nextRolloverTime)
|
| | | else:
|
| | | lastRolloverTimeTup = time.localtime(lastRolloverTime)
|
| | | nextRolloverTimeTup = time.localtime(nextRolloverTime)
|
| | | lastRolloverYear = lastRolloverTimeTup[0]
|
| | | lastRolloverMonth = lastRolloverTimeTup[1]
|
| | | lastRolloverDay = lastRolloverTimeTup[2]
|
| | | nextRolloverYear = nextRolloverTimeTup[0]
|
| | | nextRolloverMonth = nextRolloverTimeTup[1]
|
| | | nextRolloverDay = nextRolloverTimeTup[2]
|
| | | if lastRolloverYear != nextRolloverYear or lastRolloverMonth != nextRolloverMonth or lastRolloverDay != nextRolloverDay:
|
| | | #年或月改变,更换文件夹
|
| | | self.baseFilename = self.getBaseFileName(self.root, nextRolloverYear, nextRolloverMonth, nextRolloverDay, self.filename)
|
| | | # print 'need to rollove path:%s-%s -> %s-%s'%(lastRolloverYear, lastRolloverMonth,
|
| | | # nextRolloverYear, nextRolloverMonth)
|
| | | filepath = os.path.dirname(self.baseFilename)
|
| | | self.ensurePath(filepath)
|
| | | else:
|
| | | pass
|
| | | |
| | | self.mode = 'w'
|
| | | self.stream = self._open()
|
| | | |
| | | def test():
|
| | | import logging
|
| | | |
| | | mylogger = logging.getLogger('test')
|
| | | mylogger.setLevel(logging.DEBUG)
|
| | | hdlr = TimeRotatingPathFileHandler('d:\\ServerLog\\', 'AD.txt')
|
| | | fs = '%(asctime)s\t%(levelname)-8s\t%(message)s'
|
| | | dfs = '%Y-%m-%dT%H:%M:%S'
|
| | | fmt = logging.Formatter(fs, dfs)
|
| | | hdlr.setLevel(logging.DEBUG)
|
| | | hdlr.setFormatter(fmt)
|
| | | mylogger.addHandler(hdlr)
|
| | | |
| | | # mylogger.info('test')
|
| | | # os.system('pause')
|
| | | |
| | | exit = False
|
| | | cnt = 0
|
| | | lastTime = time.time()
|
| | | while not exit:
|
| | | curTime = time.time()
|
| | | if curTime - lastTime >= 60:
|
| | | lastTime = curTime
|
| | | mylogger.info('test')
|
| | |
|
| | | if __name__ == "__main__":
|
| | | test()
|
New file |
| | |
| | | #!/usr/bin/python
|
| | | # -*- coding: GBK -*-
|
| | | #
|
| | | ##@package
|
| | | #
|
| | | # @todo: |
| | | #
|
| | | # @author: Alee
|
| | | # @date 2018-7-18 上午11:40:23
|
| | | # @version 1.0
|
| | | #
|
| | | # @note: |
| | | #
|
| | | #---------------------------------------------------------------------\
|
| | |
|
| | | import logging
|
| | | from time import localtime
|
| | | import TimeRotatingPathFileHandler
|
| | | import CommFunc
|
| | |
|
| | | __gLogger = None
|
| | |
|
| | | def InitLog( LogPath, LogName, printToConsole = True, isDebug = True, mode = 'H' ):
|
| | | global __gLogger
|
| | | logLevel = logging.INFO
|
| | | if isDebug:
|
| | | logLevel = logging.DEBUG
|
| | | |
| | | #设置日志的过滤等级
|
| | | __gLogger = logging.getLogger(LogName)
|
| | | __gLogger.setLevel(logLevel)
|
| | | |
| | | |
| | | hdlr = TimeRotatingPathFileHandler.TimeRotatingPathFileHandler(LogPath, LogName, mode)
|
| | | fs = '%(asctime)s\t%(levelname)-8s\t%(message)s'
|
| | | dfs = '%Y-%m-%dT%H:%M:%S'
|
| | | fmt = logging.Formatter(fs, dfs)
|
| | | hdlr.suffix = "%Y-%m-%d_%H-%M-%S"
|
| | | hdlr.setLevel(logLevel)
|
| | | hdlr.setFormatter(fmt)
|
| | | __gLogger.addHandler(hdlr)
|
| | | |
| | | if printToConsole:
|
| | | console = logging.StreamHandler()
|
| | | console.setFormatter(fmt)
|
| | | __gLogger.addHandler(console)
|
| | | console.setLevel(logLevel)
|
| | |
|
| | | __WARN_COUNT = 0
|
| | | __ERR_COUNT = 0
|
| | | __FATAL_COUNT = 0
|
| | |
|
| | | __LastWarnInfo = ""
|
| | | __LastWarnTime = ""
|
| | | __LastErrInfo = ""
|
| | | __LastErrTime = ""
|
| | | __LastFatalInfo = ""
|
| | | __LastFatalTime = ""
|
| | |
|
| | | def GetLastWarnInfo():
|
| | | global __LastWarnInfo
|
| | | return __LastWarnInfo
|
| | |
|
| | | def GetLastWarnTime():
|
| | | global __LastWarnTime
|
| | | return __LastWarnTime
|
| | |
|
| | | def GetLastErrInfo():
|
| | | global __LastErrInfo
|
| | | return __LastErrInfo
|
| | |
|
| | | def GetLastErrTime():
|
| | | global __LastErrTime
|
| | | return __LastErrTime
|
| | |
|
| | | def GetLastFatalInfo():
|
| | | global __LastFatalInfo
|
| | | return __LastFatalInfo
|
| | |
|
| | | def GetLastFatalTime():
|
| | | global __LastFatalTime
|
| | | return __LastFatalTime
|
| | |
|
| | | def Get_Warn_Count():
|
| | | global __WARN_COUNT
|
| | | return __WARN_COUNT
|
| | |
|
| | | def Get_Err_Count():
|
| | | global __ERR_COUNT
|
| | | return __ERR_COUNT
|
| | |
|
| | | def Get_Fatal_Count():
|
| | | global __FATAL_COUNT
|
| | | return __FATAL_COUNT
|
| | |
|
| | | def debug(msg):
|
| | | global __gLogger
|
| | | __gLogger.debug(msg)
|
| | | |
| | | def info(msg):
|
| | | global __gLogger
|
| | | __gLogger.info(msg)
|
| | | |
| | | def warn(msg):
|
| | | global __WARN_COUNT
|
| | | global __LastWarnInfo
|
| | | global __LastWarnTime
|
| | | global __gLogger
|
| | | __WARN_COUNT += 1
|
| | | __LastWarnInfo = msg
|
| | | __LastWarnTime = CommFunc.GetCurrentDataTimeStr()
|
| | | __gLogger.warning(msg)
|
| | | |
| | | __ErrInfoList = []
|
| | | __OnErr = None
|
| | |
|
| | | def OnErr(onErr):
|
| | | global __OnErr
|
| | | __OnErr = onErr
|
| | |
|
| | | def error(msg):
|
| | | global __ERR_COUNT
|
| | | global __LastErrInfo
|
| | | global __LastErrTime
|
| | | global __gLogger
|
| | | global __ErrInfoList
|
| | | global __OnErr
|
| | | __ERR_COUNT += 1
|
| | | __LastErrInfo = msg
|
| | | __LastErrTime = CommFunc.GetCurrentDataTimeStr()
|
| | | if msg not in __ErrInfoList:
|
| | | __ErrInfoList.append(msg)
|
| | | if __OnErr:
|
| | | errInfo = ""
|
| | | for info in __ErrInfoList:
|
| | | errInfo += "%s\r\n"%info
|
| | | __OnErr(errInfo[:-2]) |
| | | __gLogger.error(msg)
|
| | | |
| | | def fatal(msg):
|
| | | global __FATAL_COUNT
|
| | | global __LastFatalInfo
|
| | | global __LastFatalTime
|
| | | global __gLogger
|
| | | __FATAL_COUNT += 1
|
| | | __LastFatalInfo = msg
|
| | | __LastFatalTime = CommFunc.GetCurrentDataTimeStr()
|
| | | __gLogger.critical(msg)
|
| | |
|
| | | def test():
|
| | | import os
|
| | | InitLog(os.getcwd(), "AD")
|
| | | info('test')
|
| | |
|
| | |
|
| | | if __name__ == '__main__':
|
| | | test()
|
| | |
|
New file |
| | |
| | | #!/usr/bin/python
|
| | | # -*- coding: GBK -*-
|
| | | #
|
| | | ##@package
|
| | | #
|
| | | # @todo: 渠道删档测试的充值返利
|
| | | #
|
| | | # @author: Alee
|
| | | # @date 2019-1-22 上午11:40:21
|
| | | # @version 1.0
|
| | | #
|
| | | # @note: |
| | | #
|
| | | #---------------------------------------------------------------------
|
| | | #需要安装第三方库
|
| | | #waitress-1.1.0.tar.gz
|
| | | #requests-2.18.4.tar.gz
|
| | | #---------------------------------------------------------------------
|
| | | import webapp
|
| | | from bottle import run
|
| | | from lib import mylog
|
| | | import time
|
| | | import os
|
| | | import datetime
|
| | |
|
| | | Def_Debug = True
|
| | |
|
| | | # 测试步骤 1. 双击DoubleBillTool.py 导入数据Bill.txt, 可配测试账号
|
| | | # 2. PHP增加普通GM命令 ,GMT_AllDoubleBill,GMT_QDFLDoubleBill
|
| | | # 2. 登录有充值的账号,即可获得第一天返利,
|
| | | # 3. 后续天,在线切换地图或者登录即可获得返利邮件
|
| | | #
|
| | | #
|
| | | #
|
| | |
|
| | | #center.secondworld.net.cn
|
| | | def main():
|
| | | time.sleep(1) |
| | | os.system("title DoubleBill-%s"%datetime.datetime.today())
|
| | | mylog.InitLog(r".\ServerLog", "DoubleBill.txt", False, Def_Debug)
|
| | | |
| | | CenterPort = 53004 # 端口原头条SDK使用已废弃
|
| | | |
| | | run(host='0.0.0.0', port=CenterPort, app=webapp.myapp, server='waitress')
|
| | | return
|
| | |
|
| | | if __name__ == '__main__':
|
| | | main()
|
New file |
| | |
| | | #!/usr/bin/python
|
| | | # -*- coding: GBK -*-
|
| | | #
|
| | | ##@package
|
| | | #
|
| | | # @todo: |
| | | #
|
| | | # @author: Alee
|
| | | # @date 2019-1-22 上午11:50:11
|
| | | # @version 1.0
|
| | | #
|
| | | # @note: |
| | | #
|
| | | #---------------------------------------------------------------------
|
| | |
|
| | | from bottle import Bottle, request
|
| | | import md5
|
| | | import urllib2
|
| | | import urllib
|
| | | import json
|
| | | from lib import mylog
|
| | | import DoubleBillDB
|
| | |
|
| | | myapp = Bottle()
|
| | |
|
| | | DoubleBillColName = 'tagDoubleBill'
|
| | | GMPort = 80
|
| | |
|
| | |
|
| | | @myapp.route('/DoublieBill.php')
|
| | | def OnDoubleBill():
|
| | | # 玩家登录从服务器请求兑换返利,必须记录兑换结果,用于复查;通过访问IP,查找GM通道返回结果30001
|
| | | # 参数:玩家账号,查询是否有充值返利
|
| | | # 返回1:无充值,2:已兑换(只能一个服),其他额度为仙玉
|
| | | # 数据库字段 渠道SpID 账号AccID 仙玉Gold 兑换所在服ServerID
|
| | | dataDict = request.GET
|
| | | |
| | | gameAccID = dataDict.get("AccID", "") # 运营提供的APPID,即渠道
|
| | | if not gameAccID:
|
| | | print "accID Error", gameAccID
|
| | | return
|
| | | |
| | | try:
|
| | | accID, spID, sid = gameAccID.split("@")
|
| | | except:
|
| | | print "accID Error", gameAccID
|
| | | return
|
| | | |
| | | if not sid:
|
| | | return
|
| | | |
| | | dbController = DoubleBillDB.GetDBEventCon()
|
| | | if not dbController:
|
| | | # 无法获取数据库
|
| | | mylog.debug("no dbController")
|
| | | return
|
| | | result, data = dbController.find(DoubleBillColName, {"SpID":spID, "AccID":accID})
|
| | | if not data:
|
| | | # 无记录不能领取,GM返回1, 减少反复查询
|
| | | SendGm(gameAccID, 1)
|
| | | return
|
| | | |
| | | rec = data[0]
|
| | | if not rec["Gold"]:
|
| | | # 无仙玉
|
| | | return
|
| | | |
| | | if rec["ServerID"]:
|
| | | # 已领取,GM返回2, 减少反复查询
|
| | | SendGm(gameAccID, 2)
|
| | | return
|
| | | |
| | | updateDoc = {"SpID":spID, "AccID":accID, "Gold":rec["Gold"], "ServerID":sid}
|
| | | dbController.update(DoubleBillColName, {"SpID":spID, "AccID":accID}, updateDoc)
|
| | | |
| | | mylog.info("OnDoubleBill:%s-%s"%(gameAccID, updateDoc))
|
| | | SendGm(gameAccID, rec["Gold"])
|
| | | return
|
| | |
|
| | | def SendGm(gameAccID, dbState):
|
| | | try:
|
| | | serverIP = request.environ.get("REMOTE_ADDR", "0.0.0.0")
|
| | | # GM推送地址
|
| | | #GMToolPage = http://s1.yhlz.09ge.com:30001/Server/Tool.php
|
| | | gmurl = "http://%s:%s/Server/Tool.php"%(serverIP, GMPort)
|
| | | gmkey = "Y25GVFoyOVFjbWtyTDJJckt5OU1OQ3RtUFQxPV"
|
| | | if not gmkey or not gmurl:
|
| | | return
|
| | | |
| | | pack_data = {}
|
| | | pack_data["AccID"] = gameAccID
|
| | | # 返回1:无充值,2:已兑换(只能一个服),其他额度为仙玉
|
| | | pack_data["GoldState"] = str(dbState)
|
| | |
|
| | | pack_data["pack_type"] = "GMT_QDFLDoubleBill"
|
| | | pack_data["key"] = gmkey;
|
| | | pack_data['coding'] = "utf8"
|
| | | |
| | | #使用key加密
|
| | | pack_data_dict = json.dumps(pack_data)
|
| | |
|
| | | mylog.debug("OnDoubleBill SendGm:%s-%s"%(gmurl, pack_data_dict))
|
| | | sign = md5.md5(pack_data_dict+gmkey).hexdigest()
|
| | | post = {}
|
| | | post['pack'] = pack_data_dict;
|
| | | post['sign'] = sign;
|
| | | result = urllib2.urlopen(gmurl, urllib.urlencode(post), 10)
|
| | |
|
| | | content = result.read()
|
| | | result.close()
|
| | |
|
| | | mylog.info("推送结果 GMT_QDFLDoubleBill:%s"%(content))
|
| | | return content
|
| | | except Exception, e:
|
| | | mylog.debug("gm error %s"%e)
|
| | | return
|
| | |
|
| | |
|
| | | # 查询所有的数据,只在第一张地图处理,缓存避免请求过于频繁
|
| | | @myapp.route('/QueryAllDoubleBill.php')
|
| | | def QueryAllDoubleBill():
|
| | | dataDict = request.GET
|
| | | |
| | | checkInfo = dataDict.get("ccccc", "")
|
| | | if not checkInfo:
|
| | | return
|
| | | if checkInfo != "fanggongji":
|
| | | return
|
| | | |
| | | dbController = DoubleBillDB.GetDBEventCon()
|
| | | if not dbController:
|
| | | # 无法获取数据库
|
| | | mylog.debug("no dbController")
|
| | | return
|
| | | # 返回未领取的
|
| | | result, data = dbController.find(DoubleBillColName, {"ServerID":""})
|
| | | if not data:
|
| | | return
|
| | | |
| | | recDict = {}
|
| | | for rec in data:
|
| | | spID = rec["SpID"]
|
| | | if spID not in recDict:
|
| | | recDict[spID] = [rec["AccID"]]
|
| | | else:
|
| | | recDict[spID].append(rec["AccID"])
|
| | | |
| | | if not recDict:
|
| | | return
|
| | | try:
|
| | | serverIP = request.environ.get("REMOTE_ADDR", "0.0.0.0")
|
| | | # GM推送地址
|
| | | #GMToolPage = http://s1.yhlz.09ge.com:30001/Server/Tool.php
|
| | | gmurl = "http://%s:%s/Server/Tool.php"%(serverIP, GMPort)
|
| | | gmkey = "Y25GVFoyOVFjbWtyTDJJckt5OU1OQ3RtUFQxPV"
|
| | | if not gmkey or not gmurl:
|
| | | return
|
| | | |
| | | mylog.debug("SendGm:%s"%gmurl)
|
| | | pack_data = {}
|
| | | pack_data["tomap"] = json.dumps(recDict)
|
| | | pack_data["pack_type"] = "GMT_AllDoubleBill"
|
| | | pack_data["key"] = gmkey;
|
| | | pack_data['coding'] = "utf8"
|
| | | |
| | | #使用key加密
|
| | | pack_data_dict = json.dumps(pack_data)
|
| | | |
| | | mylog.debug("QueryAllDoubleBill SendGm:%s-%s"%(gmurl, pack_data_dict))
|
| | | sign = md5.md5(pack_data_dict+gmkey).hexdigest()
|
| | | post = {}
|
| | | post['pack'] = pack_data_dict;
|
| | | post['sign'] = sign;
|
| | | result = urllib2.urlopen(gmurl, urllib.urlencode(post), 10)
|
| | |
|
| | | result.close()
|
| | |
|
| | | except Exception, e:
|
| | | mylog.debug("gm error %s"%e)
|
| | | |
| | | |
| | | # 1.查询
|
| | | @myapp.route('/QueryDoubleBill.php')
|
| | | def QueryDoubleBill():
|
| | | # 玩家登录从服务器请求兑换返利,必须记录兑换结果,用于复查;通过访问IP,查找GM通道返回结果30001
|
| | | # 参数:玩家账号,查询是否有充值返利
|
| | | # 返回1:无充值,2:已兑换(只能一个服),其他额度为仙玉
|
| | | # 数据库字段 渠道SpID 账号AccID 仙玉Gold 兑换所在服ServerID
|
| | | dataDict = request.GET
|
| | | |
| | | gameAccID = dataDict.get("AccID", "") # 运营提供的APPID,即渠道
|
| | | if not gameAccID:
|
| | | print "accID Error", gameAccID
|
| | | return
|
| | | |
| | | try:
|
| | | accID, spID, sid = gameAccID.split("@")
|
| | | except:
|
| | | print "accID Error", gameAccID
|
| | | return
|
| | | |
| | | if not sid:
|
| | | return
|
| | | |
| | | dbController = DoubleBillDB.GetDBEventCon()
|
| | | if not dbController:
|
| | | # 无法获取数据库
|
| | | mylog.debug("no dbController")
|
| | | return
|
| | | result, data = dbController.find(DoubleBillColName, {"SpID":spID, "AccID":accID})
|
| | | if not data:
|
| | | # 无记录不能领取,GM返回1, 减少反复查询
|
| | | return
|
| | | |
| | | return data[0]
|