def check_bankrupt(cls, uid, gid): benefit_times, bankrupt_ts = Context.Daily.get_daily_data( uid, gid, 'benefit_times', 'bankrupt_ts') benefit_times = Tool.to_int(benefit_times, 0) wait, which = None, None if bankrupt_ts: # 已经在破产状态, 未领取 which = benefit_times + 1 wait = int(bankrupt_ts) - Time.current_ts() if wait < 0: wait = 0 else: conf = Context.Configure.get_game_item_json(gid, 'benefit.config') if benefit_times < len(conf['reward']): reward = conf['reward'][benefit_times] bankrupt_ts = Time.current_ts() + reward['wait'] Context.Daily.set_daily_data(uid, gid, 'bankrupt_ts', bankrupt_ts) wait = reward['wait'] which = benefit_times + 1 mo = MsgPack(Message.FISH_MSG_BANKRUPT | Message.ID_NTF) mo.set_param('userId', uid) if wait is not None: mo.set_param('wait', wait) if which is not None: mo.set_param('which', which) # 可以领取哪一次 return mo
def set_location_status(self, uid, gid, status, fresh_time=None): key = 'location:%d:%d' % (gid, uid) if not fresh_time: fresh_time = Time.current_ts() self.ctx.RedisCache.hash_mset(key, 'status', status, 'fresh_ts', fresh_time) return True
def __pub_raffle_led(self, uid, gid, level, reward_info): if 'reward' in reward_info: reward = reward_info['reward'] name = None if 'chip' in reward: Context.Data.hincr_game(uid, gid, 'chip_pool', -reward['chip']) elif 'coupon' in reward: name = u'%d鱼券' % reward['coupon'] elif 'diamond' in reward: name = u'%d钻石' % reward['diamond'] elif 'props' in reward: props = reward['props'] for one in props: name = FishProps.get_props_desc(one['id']) break if name: nick = Context.Data.get_attr(uid, 'nick') if nick: led = u'恭喜%s玩家,在%s中抽中%s' % (nick.decode('utf-8'), level, name) mo = MsgPack(Message.MSG_SYS_LED | Message.ID_NTF) mo.set_param('game', { 'list': [led], 'ts': Time.current_ts() }) Context.GData.broadcast_to_system(mo)
def on_exchange(self, uid, gid, mi): mo = MsgPack(Message.MSG_SYS_EXCHANGE | Message.ID_ACK) _id = mi.get_param('id') if not isinstance(_id, int): return mo.set_error(1, 'error param') conf = Context.Configure.get_game_item_json(gid, 'exchange.config') if _id >= len(conf): return mo.set_error(1, 'error id') info = conf[_id] to_type = info['type'] if to_type not in ('diamond', 'props', 'phone'): raise Exception( str(to_type) + '<----error type, please check config') real, final = Context.UserAttr.incr_coupon(uid, gid, -info['cost'], 'exchange.' + to_type) if real != -info['cost']: return mo.set_error(2, 'not enough') mo.set_param('coupon', final) record = { 'uid': uid, 'type': 'exchange', 'ts': Time.current_ts(), 'from': 'coupon', 'to': to_type, 'cost': info['cost'], 'count': info['count'], 'desc': info['desc'] } if info['type'] == 'diamond': # 兑换钻石 real, final = Context.UserAttr.incr_diamond( uid, gid, info['count'], 'exchange.diamond') mo.set_param('diamond', final) state = 1 elif info['type'] == 'props': # 兑换道具 real, final = FishProps.incr_props(uid, gid, info['id'], info['count'], 'exchange.props') mo.set_param('id', info['id']) mo.set_param('count', final) state = 1 record['id'] = info['id'] elif info['type'] == 'phone': state = 0 record['phone'] = mi.get_param('phone') else: raise Exception('something error, please check config') seq_num = Context.RedisMix.hash_incrby('game.%d.info.hash' % gid, 'exchange.history.seq', 1) Context.RedisCluster.hash_set(uid, 'history:%d:%d' % (gid, uid), seq_num, state) record = Context.json_dumps(record) Context.RedisMix.hash_mset('game.%d.exchange.record' % gid, seq_num, record) fmt = Time.current_time('%Y-%m-%d') Context.RedisStat.hash_set('history:%d:%s' % (gid, fmt), seq_num, uid) return mo
def check_forbidden(cls, uid, gid, token): Context.Log.info('gameId =', gid, 'userId =', uid, 'session =', token) if gid not in Context.GData.game_list: return 2, 'error gameId' if not token: return 1, 'error session' redis_session = Context.RedisCache.hash_get('token:%d' % uid, 'session') if redis_session != token: Context.Log.error('verify session failed', token, redis_session) return 1, 'error session' forbidden = Context.RedisMix.set_ismember('forbidden.user', uid) if forbidden: Context.Log.info('user is forbidden login', uid) return Enum.login_failed_forbidden, 'forbidden' disable = Context.RedisMix.set_ismember('game.%d.disable.user' % gid, uid) if disable: Context.Log.info('user is disable login', uid) return Enum.login_failed_forbidden, u'您的账号已被封停,如有疑问请联系客服' end_ts = Context.RedisMix.hash_get_int('game.%d.freeze.user' % gid, uid, 0) if end_ts: if end_ts > Time.current_ts(): Context.Log.info('user is freeze login', uid) when = Time.timestamp_to_str(end_ts, '%Y-%m-%d %H:%M') return Enum.login_failed_freeze, u'您的账号已被冻结,%s解封,如有疑问请联系客服' % when else: Context.RedisMix.hash_del('game.%d.freeze.user' % gid, uid) return Enum.login_success, ''
def on_join_table(self, gid, msg): ack = MsgPack(Message.MSG_SYS_JOIN_TABLE | Message.ID_ACK) tid = msg.get_param('tableId') self._info('player req to join table', tid) self.offline = False if self.tid > 0 and self.tid != tid: self.offline = True return ack.set_error(Enum.join_table_failed_multi) registry = Context.get_module(gid, 'registry') table = registry.create_table(gid, tid) if not table: self.offline = True return ack.set_error(Enum.join_table_failed_id) result = table.join_table(self.uid) if result != 0: self.offline = True return ack.set_error(result) self.table = table self.online_ts = Time.current_ts() sid = msg.get_param('seatId') if sid is not None: return self.on_sit_down(msg) return result
def deliverOrder(self, mi, request): gid = mi.get_param('gameId') order_list = mi.get_param('orders') if not Entity.logined(request): return MsgPack.Error(0, Const.E_NOT_LOGIN, Const.ES_NOT_LOGIN) uid = request.getSession().userId orders = [] for orderId in order_list: orderInfo = self.getOrderInfo(orderId) if not orderInfo: continue userId = int(orderInfo['userId']) gameId = int(orderInfo['gameId']) state = int(orderInfo['state']) if userId != uid: Context.Log.warn('userId not match', userId, uid, orderId) continue if gameId != gid: Context.Log.warn('gameId not match', gameId, gid, orderId) continue if state == self.state_create: create_ts = Time.str_to_timestamp(orderInfo['createTime'], '%Y-%m-%d %X.%f') now_ts = Time.current_ts() if now_ts - create_ts > 3600: state = self.state_timeout orders.append({'id': orderId, 'state': state}) return MsgPack(0, {'orders': orders})
def gm_push_led(self, gid, mi, request): msg = mi.get_param('msg') if not msg: # 清除led Context.RedisCache.delete('game.%d.led.list' % gid) else: led = Context.json_dumps({'led': msg, 'ts': Time.current_ts()}) Context.RedisCache.list_lpush('game.%d.led.list' % gid, led) return MsgPack(0)
def global_unlock(cls, uid, gid): lock = Context.RedisCache.hash_get_json('global.playing.lock', uid) if lock and lock['gid'] != gid: now_ts = Time.current_ts() if now_ts < lock['ts']: return False Context.RedisCache.hash_del('global.playing.lock', uid) return True
def on_server_heart_beat(self): now_ts = Time.current_ts() rc_del = [] for uid in Context.GData.map_client_connect: connection = Context.GData.map_client_connect[uid] if now_ts - connection.access_ts >= 60: rc_del.append(connection) for connection in rc_del: Context.Log.info('too long time no msg, terminate', connection.userId, connection.access_ts) connection.terminate_connection()
def getLoginInfo(cls, request, cmd, uid, gid, param, userInfo, freshAccessToken, openid=None, open_token=None): session = Algorithm.md5_encode(Time.asctime() + request.getClientIP() + userInfo['userName']) Account.setUserToken(uid, gid, session) conn_server = Context.json_loads( Context.RedisCache.get('connect.server')) internet = conn_server[uid % len(conn_server)] dictInfo = { "session": session, "userId": uid, "sex": int(userInfo['sex']), "nick": userInfo['nick'], "avatar": userInfo['avatar'], "host": internet["domain"], "port": internet["port"], } if openid: dictInfo['openid'] = openid if open_token: dictInfo['open_token'] = open_token if freshAccessToken: data = '{"uid":%d,"ct":%d}' % (uid, Time.current_ts()) accessToken = Entity.encrypt(data) Account.updateUserInfo(uid, accessToken=accessToken) dictInfo['accessToken'] = accessToken kvs = { 'session_platform': param['platform'] or 'android', 'session_channel': param['channel'] or 'jiyu', 'session_ver': param['releaseVer'] or '1.0.1' } Context.Data.set_game_attrs_dict(uid, gid, kvs) Context.Log.report('user.login:', [uid, gid, kvs]) # 登录成功设置session值 session = request.getSession() session.setLogined(uid) return MsgPack(cmd, dictInfo)
def check_benefit(cls, uid, gid): conf = Context.Configure.get_game_item_json(gid, 'benefit.config') total_times = len(conf['reward']) benefit_times, bankrupt_ts = Context.Daily.get_daily_data( uid, gid, 'benefit_times', 'bankrupt_ts') benefit_times = Tool.to_int(benefit_times, 0) if benefit_times >= total_times: return total_times, total_times, 0, conf now_ts = Time.current_ts() if bankrupt_ts and bankrupt_ts >= now_ts: return total_times, benefit_times, 0, conf else: return total_times, benefit_times, now_ts - bankrupt_ts, conf
def gm_notice_global(self, gid, mi, request): led = mi.get_param('led') start = mi.get_param('start') end = mi.get_param('end') now_ts = Time.current_ts() if now_ts > end: return MsgPack(0) Context.RedisCache.hash_mset('global.notice', 'led', led, 'start', start, 'end', end) if now_ts >= start: self._do_notice(led, end) return MsgPack(0) TaskManager.set_timeout(self.do_notice, start-now_ts, led, end) return MsgPack(0)
def leave_table(self): now_ts = Time.current_ts() if self.online_ts and self.uid > 0 and self.gid > 0: Context.Daily.incr_daily_data(self.uid, self.gid, 'online_sec', now_ts - self.online_ts) self.online_ts = 0 self.user_info = None self.game_info = None self.gid = None self.sid = None self.tid = None self.owner = None self.leave_ts = now_ts self.offline = True
def dataReceived(self, data): self._data += data while len(self._data) > 8: cmd, msg_len = struct.unpack('II', self._data[:8]) if msg_len > len(self._data) - 8: return body_data = self._data[8:8 + msg_len] self._data = self._data[8 + msg_len:] try: self.access_ts = Time.current_ts() tasklet = self.makeTasklet(cmd, body_data, self) TaskManager.add_task(tasklet.run, peer=self.peer_key) except Exception, e: Logger.exception(body_data) self.transport.loseConnection()
def get_benefit_config(self, uid, gid): conf = Context.Configure.get_game_item_json(gid, 'benefit.config') benefit_times, bankrupt_ts = Context.Daily.get_daily_data( uid, gid, 'benefit_times', 'bankrupt_ts') benefit_times = int(benefit_times) if benefit_times else 0 _info = { 'which': benefit_times, # 已领取几次 'conf': conf['reward'] } if bankrupt_ts is not None: now_ts = Time.current_ts() bankrupt_ts = int(bankrupt_ts) if now_ts > bankrupt_ts: _info['wait'] = 0 else: _info['wait'] = bankrupt_ts - now_ts return _info
def onGameInfo(self, uid, gid, mi): gid = mi.get_param('gameId') mo = MsgPack(Message.MSG_SYS_GAME_INFO | Message.ID_ACK) account = Context.get_module(gid, 'account', Account) is_new, data = account.get_game_info(uid, gid) if not data: mo.set_error(-1, 'no game info') else: mo.update_param(data) if is_new: mo.set_param('new', 1) info = Context.RedisCache.hash_mget('global.notice', 'led', 'start', 'end') led = info[0] if led: now_ts = Time.current_ts() start = int(info[1]) end = int(info[2]) if start < now_ts < end: mo.set_param('global_notice', { 'list': [led], 'end': end, 'now_ts': now_ts }) Context.GData.send_to_connect(uid, mo) if is_new: account.on_create_user(uid, gid) if account.auto_issue_benefit: benefit_config = Context.Configure.get_game_item_json( gid, 'benefit.config') if benefit_config and benefit_config['limit'] > data['chip']: benefit = Context.Daily.issue_benefit(uid, gid) mo = MsgPack(Message.MSG_SYS_BENEFIT | Message.ID_NTF) if not benefit: benefit = { 'which': 0, 'total': 0, 'reward': 0, 'chip': data['chip'], } mo.update_param(benefit) Context.GData.send_to_connect(uid, mo)
def onLed(self, uid, gid, mi): mo = MsgPack(Message.MSG_SYS_LED | Message.ID_ACK) action = mi.get_param('action', 'get') if action == 'get': last_ts = mi.get_param('last_ts', 0) led_list = Context.RedisCache.list_range('global.led.list', 0, 9) _list, ts = [], 0 for led in led_list: led = Context.json_loads(led) if led['ts'] > last_ts: _list.append(led['led']) ts = led['ts'] if _list: mo.set_param('global', {'ts': ts, 'list': _list}) led_list = Context.RedisCache.list_range('game.%d.led.list' % gid, 0, 9) _list, ts = [], 0 for led in led_list: led = Context.json_loads(led) if led['ts'] > last_ts: _list.append(led['led']) ts = led['ts'] if _list: mo.set_param('game', {'ts': ts, 'list': _list}) elif action == 'put': conf = Context.Configure.get_game_item_json(gid, 'led.config') if not conf or not conf.get('enable'): mo.set_error(101, 'led not available') else: msg = mi.get_param('msg') cost = conf['cost'] real, final = Context.UserAttr.incr_diamond( uid, gid, -cost, 'led.put') if real != -cost: mo.set_error(102, 'no enough diamond') else: led = Context.json_dumps({ 'led': msg, 'ts': Time.current_ts() }) Context.RedisCache.list_lpush('game.%d.led.list' % gid, led) return Context.GData.send_to_connect(uid, mo)
def on_benefit(self, uid, gid, mi): mo = MsgPack(Message.MSG_SYS_BENEFIT | Message.ID_ACK) conf = Context.Configure.get_game_item_json(gid, 'benefit.config') total_times = len(conf['reward']) benefit_times, bankrupt_ts = Context.Daily.get_daily_data( uid, gid, 'benefit_times', 'bankrupt_ts') benefit_times = Tool.to_int(benefit_times, 0) if benefit_times >= total_times: return mo.set_error(1, 'none') now_ts = Time.current_ts() if not bankrupt_ts or int(bankrupt_ts) > now_ts: return mo.set_error(2, 'wait') result = Context.Daily.issue_benefit(uid, gid) if not result: return mo.set_error(3, 'failed') Context.Daily.del_daily_data(uid, gid, 'bankrupt_ts') mo.update_param(result) return mo
def __init__(self): BasicTcpProtocol.__init__(self) self._data = '' self.access_ts = Time.current_ts()
def __on_quick_start(self, uid, gid, mi): Context.Log.info(uid, 'req quick start with', mi) mo = MsgPack(Message.MSG_SYS_QUICK_START | Message.ID_ACK) result, location = Context.Online.get_location(uid, gid) if not result: return mo.set_error(Enum.quick_start_failed_unknown, 'info illegal') now_ts = Time.current_ts() if location: mo.set_param('serverId', location['serverId']) mo.set_param('roomType', location['room_type']) mo.set_param('tableId', location['table_id']) mo.set_param('seatId', location['seat_id']) return mo room_type = mi.get_param('roomType', 0) chip = Context.UserAttr.get_chip(uid, gid, 0) room_type, desc = self.__find_available_room(uid, gid, chip, room_type) if room_type not in (201, 202, 203): return mo.set_error(room_type, desc) play_mode = mi.get_param('playMode', Enum.play_mode_common) if play_mode != Enum.play_mode_common: return mo.set_error(110, 'error play mode') # 分配玩家 for num in (3, 2, 1): table_list = self.__get_table_list(gid, room_type, play_mode, num) for table_id in table_list: key = 'table:%d:%d' % (gid, table_id) attrs = ['status', 'fresh_ts', 'serverId'] kvs = Context.RedisCache.hash_mget_as_dict(key, *attrs) if len(attrs) != len(kvs): Context.Log.error('get table info failed', uid, gid, room_type, table_id, num, kvs) continue server_id = int(kvs['serverId']) if server_id < 0: Context.Log.info('table server_id error', uid, gid, room_type, table_id, num, server_id) continue seat_id = self.__join_table(uid, gid, room_type, play_mode, table_id) if seat_id < 0: Context.Log.error('join_table failed!', uid, gid, room_type, table_id) continue Context.Online.set_location(uid, gid, server_id, room_type, table_id, seat_id, 0, now_ts, play_mode=play_mode) mo.set_param('serverId', server_id) mo.set_param('roomType', room_type) mo.set_param('tableId', table_id) mo.set_param('seatId', seat_id) Context.Log.info('join table', uid, gid, server_id, room_type, table_id, server_id, play_mode) return mo # new table table_id = self.get_free_table(gid) server_id = self.__select_server(uid, gid, table_id, room_type) if not server_id: Context.Log.error('select server failed', uid, gid, room_type) return mo.set_error(Enum.quick_start_failed_unknown, 'no server found') self.__create_table(gid, room_type, play_mode, table_id, server_id, now_ts) seat_id = self.__join_table(uid, gid, room_type, play_mode, table_id) if seat_id < 0: Context.Log.error('join_table failed!', uid, gid, room_type, table_id) return mo.set_error(Enum.quick_start_failed_unknown, 'json table failed') Context.Online.set_location(uid, gid, server_id, room_type, table_id, seat_id, 0, now_ts, play_mode=play_mode) mo.set_param('serverId', server_id) mo.set_param('roomType', room_type) mo.set_param('tableId', table_id) mo.set_param('seatId', seat_id) Context.Log.info('create location info', uid, gid, server_id, room_type, table_id, seat_id, play_mode) return mo
def set_recycle_flag(self): self.recycle_ts = Time.current_ts() return 0
def update_table_status(self, status): key = 'table:%d:%d' % (self.gid, self.tid) Context.RedisCache.hash_mset(key, 'status', status, 'fresh_ts', Time.current_ts())
def _do_notice(self, led, end): now_ts = Time.current_ts() mo = MsgPack(Message.MSG_SYS_LED | Message.ID_NTF) mo.set_param('global', {'list': [led], 'end': end, 'now_ts': now_ts}) Context.GData.broadcast_to_system(mo)