diff --git a/.gitmodules b/.gitmodules index ce08b16..e7634f2 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,9 @@ [submodule "third_party/phpcommon"] path = third_party/phpcommon url = git@git.kingsome.cn:server_common/phpcommon.git +[submodule "third_party/f7"] + path = third_party/f7 + url = git@git.kingsome.cn:server_common/f7.git +[submodule "third_party/q7"] + path = third_party/q7 + url = git@git.kingsome.cn:server_common/q7.git diff --git a/third_party/f7 b/third_party/f7 new file mode 160000 index 0000000..1d7840b --- /dev/null +++ b/third_party/f7 @@ -0,0 +1 @@ +Subproject commit 1d7840b984d20261df241e39db0d8089a831f5b3 diff --git a/third_party/phpcommon b/third_party/phpcommon index 1e3bb4d..c1eb6b3 160000 --- a/third_party/phpcommon +++ b/third_party/phpcommon @@ -1 +1 @@ -Subproject commit 1e3bb4df855f6d11df75545d10b0c2aacea34a06 +Subproject commit c1eb6b3006cca677b7e7a06b2e2ac0e9d0108fd4 diff --git a/third_party/q7 b/third_party/q7 new file mode 160000 index 0000000..4af43d5 --- /dev/null +++ b/third_party/q7 @@ -0,0 +1 @@ +Subproject commit 4af43d56490d566c38021d9687975dae17d9e7ad diff --git a/tools/rankserver/__init__.py b/tools/rankserver/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tools/rankserver/__pycache__/app.cpython-36.pyc b/tools/rankserver/__pycache__/app.cpython-36.pyc new file mode 100644 index 0000000..d3ad398 Binary files /dev/null and b/tools/rankserver/__pycache__/app.cpython-36.pyc differ diff --git a/tools/rankserver/app.py b/tools/rankserver/app.py index 0041d49..8cb0013 100644 --- a/tools/rankserver/app.py +++ b/tools/rankserver/app.py @@ -1,27 +1,42 @@ # -*- coding: utf-8 -*- #!/usr/bin/python +import sys +sys.path.append('../local_packages') +import q7 +import f7 + import pymysql import hashlib import json import urllib.request import base64 -import tornado.ioloop -import tornado.web import time import datetime import redis import os +import functools -CONFIG_DIR = '' -def IsOnlineEnv(): - return os.getenv("SERVER_ENV"); +CONFIG_DIR = '../config' if f7.isOnlineEnv() else '/var/data/conf_test/game2001api_rankserver/config' + +def _take_pass(elem): + return elem[3] + +def _getRedis(): + redis_conf = json.loads(open(CONFIG_DIR + '/rankserver.redis.cluster.json', 'r').read()) + for conf in redis_conf: + r = redis.Redis(host = conf['host'], + port = conf['port'], + password = conf['passwd'], + charset = 'utf8' + ) + return r; + +def getRedisConf(): + redis_conf = json.loads(open(CONFIG_DIR + '/rankserver.redis.cluster.json', 'r').read()) + return redis_conf; -if (IsOnlineEnv()): - CONFIG_DIR = '/var/data/conf_test/game2001api_rankserver/config' -else: - CONFIG_DIR = '../config' def info(msg): print(str(datetime.datetime.now()) + '[INFO] ' + msg) @@ -41,33 +56,22 @@ def safeDiv(a, b): else: return a / b -def getRedis(): - redis_conf = json.loadsmysql_conf = json.loads(open(CONFIG_DIR + '/rankserver.redis.cluster.json', 'r').read()) - for conf in redis_conf: - r = redis.Redis(host = conf['host'], - port = conf['port'], - password = conf['passwd'], - charset = 'utf8' - ) - return r; - def getDaySeconds(time_val, incdays): time_zone = 8 dayseconds = int((time_val + time_zone * 3600)/3600/24 + incdays) * 3600 * 24 - 3600 * time_zone; return dayseconds #数据去重 -def delRepeatData(row, data_list): +def _delRepeatData(row, data_list): temp_list = [] for data in data_list: if data[0] == row[0]: temp_list.append(data) for temp_data in temp_list: data_list.remove(temp_data) - #print(data_list) #刷新数据 -def refreshData(row, data_list, data_info): +def _refreshData(row, data_list, data_info): key_info = data_info kill = safeDiv(row[3], row[7]) alive_time = safeDiv(row[4], row[7]) @@ -82,33 +86,33 @@ def refreshData(row, data_list, data_info): del data_list[50:] #更新排行榜 -def updateRank(r, kill_list, win_list ,integral_list): +def _updateKillRank(r, channel, kill_list): kill_list.sort(key=take_kills, reverse=True) kill_rank = [] for kill_index in range(min(50, len(kill_list))): kill_rank.append(kill_list[kill_index]) - r.set("game2001api: kill_rank", json.dumps(kill_rank)) + r.set("game2001api:kill_rank_" + channel, json.dumps(kill_rank)) +def _updateWinRank(r, channel, win_list): win_list.sort(key=take_game_times, reverse=True) win_rank = [] for win_index in range(min(50, len(win_list))): win_rank.append(win_list[win_index]) - r.set("game2001api: win_rank", json.dumps(win_rank)) + r.set("game2001api:win_rank_" + channel, json.dumps(win_rank)) +def _updateScoreRank(r, channel, integral_list): integral_list.sort(key=take_integral_times, reverse=True) integral_rank = [] for integral_index in range(min(50, len(integral_list))): integral_rank.append(integral_list[integral_index]) - r.set("game2001api: integral_rank", json.dumps(integral_rank)) + r.set("game2001api:integral_rank_" + channel, json.dumps(integral_rank)) -def internalDayReadMysqlData(): +def fullUpdateRank(): + f7.udplog.info('fullUpdateRank begin') mysql_conf = json.loads(open(CONFIG_DIR + '/rankserver.mysql.cluster.json', 'r').read()) - kill_list = [] - alive_list = [] - harm_list = [] - rate_list = [] - win_list = [] - integral_list = [] + kill_hash = {} + win_hash = {} + integral_hash = {} for conf in mysql_conf: conn = pymysql.connect(host = conf['host'], port = conf['port'], @@ -123,55 +127,53 @@ def internalDayReadMysqlData(): while 1: cursor.execute('SELECT accountid, user_name, avatar_url, kills, alive_time,' ' harm, win_times, game_times, idx, integral, season_time FROM user WHERE idx > %s LIMIT 0, 1000' % (last_idx)) - has_data = False for row in cursor: has_data = True #更新击杀榜 - refreshData(row, kill_list, take_kills) + channel = f7.getChannelByAccountId(row[0]) + if channel not in kill_hash: + kill_hash[channel] = [] + _refreshData(row, kill_hash[channel], take_kills) #更新胜场榜 - refreshData(row, win_list, take_game_times) + channel = f7.getChannelByAccountId(row[0]) + if channel not in win_hash: + win_hash[channel] = [] + _refreshData(row, win_hash[channel], take_game_times) #更新积分榜 - refreshData(row, integral_list, take_integral_times) - temp_idx = int(row[8]) - if (temp_idx > last_idx) : - last_idx = int(row[8]) - + channel = f7.getChannelByAccountId(row[0]) + if channel not in integral_hash: + integral_hash[channel] = [] + _refreshData(row, integral_hash[channel], take_integral_times) + last_idx = max(row[8], last_idx) + time.sleep(0.001); if not has_data: break - r = getRedis() - updateRank(r, kill_list, win_list, integral_list) + r = _getRedis() + for channel in kill_hash: + _updateKillRank(r, channel, kill_hash[channel]) + for channel in win_hash: + _updateWinRank(r, channel, win_hash[channel]) + for channel in integral_hash: + _updateScoreRank(r, channel, integral_hash[channel]) + f7.udplog.info('fullUpdateRank end') #每日定时读取mysql里的数据生成排行榜写入redis后php读取redis返回客户端显示 -def dayReadMysqlData(rushtime): - internalDayReadMysqlData() - tornado.ioloop.IOLoop.current().call_at(getDaySeconds(time.time(), 1) + rushtime, - lambda : dayReadMysqlData(rushtime) - ) +def _fullUpdateRank(rushtime): + def done_callback(): + f7.timer.callAt(q7.getDaySeconds(time.time(), 1) + rushtime, + lambda : _fullUpdateRank(rushtime)) + f7.app.createAsyncTask(done_callback, fullUpdateRank, ()) + #每5分钟读取mysql里发生改变过的数据更新排行榜 -def readMysqlData(rushtime): +def incrementUpdateRank(rushtime): mysql_conf = json.loads(open(CONFIG_DIR + '/rankserver.mysql.cluster.json', 'r').read()) - r = getRedis() - kill_list_str = r.get("game2001api: kill_rank") - if (not kill_list_str): - kill_list = [] - else: - kill_list = json.loads(kill_list_str) - - win_list_str = r.get("game2001api: win_rank") - if (not win_list_str): - win_list = [] - else: - win_list = json.loads(win_list_str) - - integral_list_str = r.get("game2001api: integral_rank") - if (not integral_list_str): - integral_list = [] - else: - integral_list = json.loads(integral_list_str) - + r = _getRedis() + kill_hash = {} + win_hash = {} + integral_hash = {} for conf in mysql_conf: conn = pymysql.connect(host = conf['host'], port = conf['port'], @@ -190,83 +192,59 @@ def readMysqlData(rushtime): has_data = False for row in cursor: has_data = True + channel = f7.getChannelByAccountId(row[0]) #更新击杀榜 - delRepeatData(row, kill_list) - refreshData(row, kill_list, take_kills) - temp_idx = int(row[8]) - if (temp_idx > last_idx) : - last_idx = int(row[8]) - if not has_data: - break - - last_idx = 0 - temp_idx = 0 - while 1: - cursor.execute('SELECT accountid, user_name, avatar_url, kills, alive_time,' - ' harm, win_times, game_times, idx, integral, season_time, win_modifytime FROM user ' - ' WHERE win_modifytime > %s AND idx > %s LIMIT 0, 1000' % (time.time() - 300, last_idx)) - has_data = False - for row in cursor: - has_data = True + if channel not in kill_hash: + kill_list = r.get('game2001api:kill_rank_' + channel) + kill_hash[channel] = [] if not kill_list else json.loads(kill_list) + _delRepeatData(row, kill_hash[channel]) + _refreshData(row, kill_hash[channel], take_kills) #更新胜场榜 - delRepeatData(row, win_list) - refreshData(row, win_list, take_game_times) - temp_idx = int(row[8]) - if (temp_idx > last_idx) : - last_idx = int(row[8]) - if not has_data: - break - - last_idx = 0 - temp_idx = 0 - while 1: - cursor.execute('SELECT accountid, user_name, avatar_url, kills, alive_time,' - ' harm, win_times, game_times, idx, integral, season_time, rank_modifytime FROM user ' - ' WHERE rank_modifytime > %s AND idx > %s LIMIT 0, 1000' % (time.time() - 300, last_idx)) - - has_data = False - for row in cursor: - has_data = True + if channel not in win_hash: + win_list = r.get('game2001api:win_rank_' + channel) + win_hash[channel] = [] if not win_list else json.loads(win_list) + _delRepeatData(row, win_hash[channel]) + _refreshData(row, win_hash[channel], take_game_times) #更新积分榜 - delRepeatData(row, integral_list) - refreshData(row, integral_list, take_integral_times) - temp_idx = int(row[8]) - if (temp_idx > last_idx) : - last_idx = int(row[8]) + if channel not in integral_hash: + integral_list = r.get('game2001api:integral_rank_' + channel) + integral_hash[channel] = [] if not integral_list else json.loads(integral_list) + _delRepeatData(row, integral_hash[channel]) + _refreshData(row, integral_hash[channel], take_integral_times) + last_idx = max(row[8], last_idx) + time.sleep(0.001); if not has_data: break - updateRank(r, kill_list, win_list, integral_list) - tornado.ioloop.IOLoop.current().call_later(rushtime, - lambda : readMysqlData(rushtime) - ) -class SelfCheckingHandler(tornado.web.RequestHandler): + for channel in kill_hash: + _updateKillRank(r, channel, kill_hash[channel]) + for channel in win_hash: + _updateWinRank(r, channel, win_hash[channel]) + for channel in integral_hash: + _updateScoreRank(r, channel, integral_hash[channel]) + f7.udplog.info('incrementUpdateRank end') - def get(self): - self.write(json.dumps({ - 'errcode': 0, - 'errmsg': '', - 'healthy': 1, - 'max_rundelay': 10 - })) - -def make_app(): - return tornado.web.Application([ - (r"/webapp/index[\.]php", SelfCheckingHandler), - ]) +#每5分钟读取mysql里发生改变过的数据更新排行榜 +def _incrementUpdateRank(rushtime): + def done_callback(): + f7.timer.callLater(rushtime, + lambda : _incrementUpdateRank(rushtime)) + f7.app.createAsyncTask(done_callback, incrementUpdateRank, ()) if __name__ == "__main__": + q7.xPrint('pid %d' % os.getpid()) + f7.app.init('/data/logs/game2001_rankserver/logs') + f7.udplog.info('rankserver start pid:' + str(os.getpid())) + conf = json.loads(open(CONFIG_DIR + '/rankserver.json', 'r').read()) - app = make_app() - app.listen(conf['listen_port']) conf['rushtime'] = 300 - tornado.ioloop.IOLoop.current().call_later(conf['rushtime'], - lambda : readMysqlData(conf['rushtime']) - ) + f7.timer.callLater(conf['rushtime'], + lambda : _incrementUpdateRank(conf['rushtime'])) conf['day_rushtime'] = 5 * 3600 - tornado.ioloop.IOLoop.current().call_at(getDaySeconds(time.time(), 1) + conf['day_rushtime'], - lambda : dayReadMysqlData(conf['day_rushtime']) - ) - tornado.ioloop.IOLoop.current().start() + f7.timer.callAt(q7.getDaySeconds(time.time(), 1) + conf['day_rushtime'], + lambda : _fullUpdateRank(conf['day_rushtime'])) + + f7.app.listen(conf['listen_port']) + f7.app.start() diff --git a/tools/rankserver/rankserver_cmd.py b/tools/rankserver/rankserver_cmd.py new file mode 100644 index 0000000..7db1f46 --- /dev/null +++ b/tools/rankserver/rankserver_cmd.py @@ -0,0 +1,70 @@ +# -*- coding: utf-8 -*- +#!/usr/bin/python + +import sys +sys.path.append('../local_packages') +import q7 +import f7 + +import pymysql +import hashlib +import json +import time +import datetime +import redis +import os + +import app + +def _updateRank_cmd(debug_info): + app.fullUpdateRank() + +def _clearRank_cmd(debug_info): + for conf in app.getRedisConf(): + r = redis.Redis(host = conf['host'], + port = conf['port'], + password = conf['passwd'], + charset = 'utf8' + ) + kill_keys = f7.scanRedisKey(r, "game2001api:kill_rank_*") + win_keys = f7.scanRedisKey(r, "game2001api:win_rank_*") + integral_keys = f7.scanRedisKey(r, "game2001api:integral_rank_*") + for key in kill_keys : + r.delete(key) + for key in win_keys : + r.delete(key) + for key in integral_keys : + r.delete(key) + +def processCmdLine(cmd): + cmd_hash = { + 'updateRank': _updateRank_cmd, + 'clearRank': _clearRank_cmd, + } + precmd_hash = { + } + postcmd_hash = { + } + debug_info = { + 'record_count': 0, + 'param1': 0, + 'param2': 0, + 'param3': 0, + 'param4': 0 + } + if cmd in precmd_hash: + precmd_hash[cmd](debug_info) + if cmd in cmd_hash: + cmd_hash[cmd](debug_info) + if cmd in postcmd_hash: + postcmd_hash[cmd](debug_info) + +if __name__ == "__main__": + if len(sys.argv) <= 1: + pass + else: + q7.xPrint('pid:' + str(os.getpid())) + f7.app.init('/data/logs/game2001_rankserver_cmd/logs') + f7.udplog.info('game2001_rankserver_cmd start pid:' + str(os.getpid())) + processCmdLine(sys.argv[1]) + f7.app.start() diff --git a/webapp/controller/RankController.class.php b/webapp/controller/RankController.class.php index 2738ae2..419cd8b 100644 --- a/webapp/controller/RankController.class.php +++ b/webapp/controller/RankController.class.php @@ -97,7 +97,7 @@ class RankController{ $myname = $row['user_name']; $myavatar_url = $row['avatar_url']; } - + $myavatar_url = urldecode($myavatar_url); array_push($user_list, array( 'account_id' => $account_id, 'name' => $myname, @@ -114,7 +114,8 @@ class RankController{ ini_set('memory_limit','3072M'); //击杀榜 $r = $this->getRedis(); - $kill_rank_db = $r->get("game2001api: kill_rank"); + $channel = phpcommon\extractChannel($account_id); + $kill_rank_db = $r->get("game2001api:kill_rank_" . $channel); $kill_db = json_decode($kill_rank_db); $i = 0; foreach ($kill_db as $kill) { @@ -147,10 +148,11 @@ class RankController{ $name = $kill_db[$i][1]; $avatar_url = $kill_db[$i][2]; } + $url = urldecode($avatar_url); array_push($kill_list, array( 'account_id' => $kill_db[$i][0], 'name' => $name, - 'avatar_url' => $avatar_url, + 'avatar_url' => $url, 'kill' => $kill_db[$i][3], 'alive'=> $kill_db[$i][4], 'harm' => $kill_db[$i][5], @@ -162,7 +164,8 @@ class RankController{ } //胜场榜 - $win_rank_db = $r->get("game2001api: win_rank"); + $channel = phpcommon\extractChannel($account_id); + $win_rank_db = $r->get("game2001api:win_rank_" . $channel); $win_db = json_decode($win_rank_db); $i = 0; foreach ($win_db as $win) { @@ -195,10 +198,11 @@ class RankController{ $name = $win_db[$i][1]; $avatar_url = $win_db[$i][2]; } + $url = urldecode($avatar_url); array_push($win_list, array( 'account_id' => $win_db[$i][0], 'name' => $name, - 'avatar_url' => $avatar_url, + 'avatar_url' => $url, 'kill' => $win_db[$i][3], 'alive'=> $win_db[$i][4], 'harm' => $win_db[$i][5], @@ -209,7 +213,8 @@ class RankController{ } //积分榜 - $integral_rank_db = $r->get("game2001api: integral_rank"); + $channel = phpcommon\extractChannel($account_id); + $integral_rank_db = $r->get("game2001api:integral_rank_" . $channel); $integral_db = json_decode($integral_rank_db); $i = 0; foreach ($integral_db as $integral) { @@ -254,10 +259,11 @@ class RankController{ $name = $integral_db[$i][1]; $avatar_url = $integral_db[$i][2]; } + $url = urldecode($avatar_url); array_push($integral_list, array( 'account_id' => $integral_db[$i][0], 'name' => $name, - 'avatar_url' => $avatar_url, + 'avatar_url' => $url, 'kill' => $integral_db[$i][3], 'alive'=> $integral_db[$i][4], 'harm' => $integral_db[$i][5], diff --git a/webapp/controller/ShopController.class.php b/webapp/controller/ShopController.class.php index c39646a..5fe5908 100644 --- a/webapp/controller/ShopController.class.php +++ b/webapp/controller/ShopController.class.php @@ -373,13 +373,6 @@ class ShopController{ phpcommon\sendError(ERR_USER_BASE + 1,'session失效'); return; } - if ($_REQUEST['type'] == 3) { - $p = $this->getParameter(RAND_SHOP_GOLD); - if ($shop_type == 2) { - $p = $this->getParameter(RAND_DIAMONDSHOP_GOLD); - } - $this->SubCoin($p['param_value'], $account_id, $_REQUEST['type']); - } unset($user_db['shop_list']); $shop_list = $this->randomShop($shop_type); $user_db['shop_list'] = $shop_list;