def coin_mine(self, num): n = self.get_coin_mine() if n < num: return False, errcode.EC_TIMES_FULL cost = 0 mcoin3 = self.data.mcoin3 items = [] for i in xrange(num): cost += eval(self.player._game.gem_mgr.mime_cost % (mcoin3 + 1)) if mcoin3 < self.player._game.gem_mgr.mine_reward_coin_num: rid = self.player._game.gem_mgr.mine_reward[1] else: rid = self.player._game.gem_mgr.mine_reward[2] t_rw = self.player._game.reward_mgr.get(rid) if t_rw is None: log.error("gem reward is None rid:%s", rid) continue d = t_rw.reward(params=None) if len(d): items.append(d[0]) mcoin3 += 1 if not self.player.enough_coin(aCoin1=0, aCoin2=cost): return False, errcode.EC_COST_ERR if not self.player.bag.can_add_items(items): return False, errcode.EC_BAG_FULL self.player.cost_coin(aCoin1=0, aCoin2=cost, log_type=COIN_GEM_MINE) self.data.mcoin3 += num bag_items = self.player.bag.add_items(items, log_type=ITEM_ADD_GEM_MINE) return True, bag_items.pack_msg(coin=True)
def _change_duty(self, assist_obj1, name, assist_obj2, duty): #得到该职位的个数 lev_obj = self.res_mgr.ally_levels.get(self.data.level) if duty != ALLY_MEMBER: num = getattr(lev_obj, "dt%sNum"%duty) duty_list = self.duty2objs.get(duty) dt_num = 0 if not duty_list else len(duty_list) #是否已经达到上限 if num <= dt_num: return False, errcode.EC_DUTY_FULL #改变职责 pid2 = assist_obj2.data.pid self.remove_rights(pid2) assist_obj2.data.duty = duty self.build_rights(assist_obj2) assist_obj2.save(self.rpc_store, forced=True) self._add_in_log(ALLY_OP_DUTY, name, pid2, duty, 0) right_obj = self.res_mgr.ally_rights.get(duty, None) if not right_obj: log.error('ResAllyRight duty:%s', duty) cd_dict = dict(n1 = name, n2 = Ally.get_name(pid2), duty = right_obj.name) self.tell_online_members(language.ALLY_CHANGE_DUTY%cd_dict) return True, ALLY_OP_SUCCEED
def add_friend(self, player, pid): """ 添加好友 """ if self.is_black(pid): self.data.bks.remove(pid) rs, err = self.add_check(player, pid) if not rs: return rs, err rpc_player = self._mgr._game.rpc_player_mgr.get_rpc_player(pid) self.data.fds.append(pid) player.pub(MSG_SOCIAL_ADD, len(self.data.fds)) if rpc_player: #对方未加我 if not rpc_player.is_friend(player.data.id): rpc_player.force_add_friend(player.data.id) rpc_player.apply_friend(player.data.name) return True, rpc_player.social_online_info() #对方不在线直接操作数据库 t_d = self._mgr._game.rpc_store.load(self.TABLE_NAME, pid) if not t_d: log.error("database have no this player pid:%s", pid) return False, errcode.EC_PLAYER_EMPTY if player.data.id in t_d['fds']: #对方也加我了 return True, self._node_list(list((pid,)))[0] t_d['fds'].append(player.data.id) #写入数据库中 self._mgr._game.rpc_store.save(self.TABLE_NAME, t_d) fd_mail = Game.res_mgr.reward_mails.get(SOCIAL_MAIL_FRIEND) res_role = Game.res_mgr.roles.get(player.data.rid) color = '#' + Game.item_mgr.get_color(res_role.quality) content = fd_mail.content % dict(name=player.data.name, color=color) self._mgr._game.mail_mgr.send_mails(pid, MAIL_REWARD, fd_mail.title, SOCIAL_MAIL_FRIEND, [], param=content) return True, self._node_list(list((pid,)))[0]
def send_reward(self): res_tbox = Game.res_mgr.tboxs.get(self.bid) if res_tbox is None: log.error('ally_team(%s) res_tbox is None, pids(%s)', self.tid, self.pids) return rw = Game.reward_mgr.get(res_tbox.trid) items = rw.reward(None) if items is None: log.error('ally_team(%s) reward_items is None, pids(%s)', self.tid, self.pids) return rw_mail = Game.res_mgr.reward_mails.get(RW_MAIL_ATBOX) boss = Game.res_mgr.monsters.get(res_tbox.tmid) content = rw_mail.content % dict(name = boss.name) pids = [] for pid in self.pids: player = Game.rpc_player_mgr.get_rpc_player(pid) if player is None: player = Player.load_player(pid) if player is None: continue data = player.get_ally_tbox_data() if not is_today(data['t']): data['bids'] = [] data['cr'] = 0 if len(data['bids']) == 0: data['bids'].append(self.bid) data['t'] = current_time() pids.append(pid) if pid == self.lid: data['cr'] += 1 player.set_ally_tbox_data(data) Game.mail_mgr.send_mails(pids, MAIL_REWARD, rw_mail.title, content, items)
def init_msg_id_map_msg_class(protocol_dir): import sys, glob import os.path import imp from corelib import log # import package first path, mdname = os.path.split(protocol_dir) if path not in sys.path: sys.path.insert(0, path) try: file, filename, description = imp.find_module(mdname) md = imp.load_module(mdname, file, filename, description) except ImportError: log.error('ImportError:%s', mdname) raise pyfiles = glob.glob(os.path.join(protocol_dir, '*.py')) if not pyfiles: pyfiles = glob.glob(os.path.join(protocol_dir, '*.pyc')) for pyfile in pyfiles: name, ext = os.path.splitext(os.path.basename(pyfile)) file, filename, description = imp.find_module(name, [protocol_dir]) mod = imp.load_module('.'.join((mdname, name)), file, filename, description) #修正奇怪问题:from protobuf import xxxx会出现import错误,可能发生在:protobuf未导入之前,执行了上面的代码 setattr(md, name, mod) _init_sub_mod(mod) protocol_modules[pyfile] = mod
def set_glory_rank(self, pid, glory): """由外界调用排序""" try: self.glory_remove(pid) self.glory_add(pid, glory) except Exception as e: log.error(e)
def pre_exchange(self, strcode, uid, pid): """ 领取之前的检测 """ t_lis = Game.rpc_res_store.query_loads(ExchangeCode.TABLE_NAME, dict(code=strcode)) if not t_lis: return False, errcode.EC_CODE_EXCHANGE_INVALID if len(t_lis) > 1: log.error("the exchange code :%s must exit only one but exit %s", strcode, len(t_lis)) #特定服 _obj = ExchangeCode(t_lis[0]) if _obj.data.num <= 0: return False, errcode.EC_CODE_EXCHANGE_INVALID if common.current_time() > _obj.data.et: return False, errcode.EC_CODE_EXCHANGE_PASS if _obj.is_one: lis = CodeLog.find(_obj.data.name, uid, pid) if lis: return False, errcode.EC_CODE_EXCHANGE_NOMORE self.codes[strcode] = _obj rid = _obj.data.rid return True, rid
def add_task(self, aTid, aRid=None, pid=0, forced=False, send_msg=False): """ 创建新任务 aRid:奖励id, 有则是兵符符任务 pid:父任务id send_msg:是否发送,并且用于表示延迟秒数 """ res_task = self.get_res_task(aTid) if not res_task: return task = self.add_task_by_res(res_task, aRid=aRid, forced=forced or bool(pid)) if pid: if not task: log.error(u'(%s)玩家任务(%s)完成后,接后续任务(%s)失败:%s, %s', self.player.data.id, pid, res_task.id, self.tid_bm.to_base64(), self.tids.keys()) else: self.task_active(task) if not task: return if send_msg:#延迟发送,保证先完成任务再发下一任务 if type(send_msg) is bool: self.send_accept_tasks([task]) else: spawn_later(float(send_msg), self.send_accept_tasks, [task]) return task
def update(self, adict): super(ResDeepGuard, self).update(adict) if self.is_boss: #boss self.boss_func = make_lv_regions(self.guard) elif self.guard: self.guard_func = RandomRegion(self.guard) else: log.error(u'深渊怪物配置表(%d)怪物配置缺少', self.id)
def update(self, adict): super(ResBuff, self).update(adict) self.signs = self.buff.strip().split('|') self.rates = self.plan.strip().split('|') slen = len(self.signs) if (self.rates and slen != len(self.rates)): log.error(u'buff表数据(%d)错误:buff=%s, plan1=%s, plan2=%s', self.id, self.buff, self.plan)
def fish_up(self, player, iid, num, qt): """ 起杆 """ max_num = self.fish_max_num(player) if max_num < num: log.error("*******fish_up num:%s, max_num:%s, vip_level:%s*******", num, max_num, player.data.vip) return False, errcode.EC_NO_RIGHT fish = self.init_player(player) return fish.fish_up(player, iid, num, qt)
def add_items(self, items, log_type=None, rid=0): """ 添加待收物品列表、奖励物品列表, 返回: BagItems对象 """ bag_items = BagItems(self) bag_items.reward_items = items rwitems = RewardItems(items) self._add_special_item(rwitems, bag_items=bag_items) item_mgr = self.player._game.item_mgr for _id, counts in rwitems.items.iteritems(): if counts[TRADE_IDX]: add_items = self.add_item(_id, counts[TRADE_IDX], 1) if add_items: bag_items.items.extend(add_items) if counts[NOTRADE_IDX]: add_items = self.add_item(_id, counts[NOTRADE_IDX], 0) if add_items: bag_items.items.extend(add_items) for _id, c, tr in rwitems.equips: for i in xrange(c): equip = item_mgr.new_equip(_id, is_trade=tr) if not equip: continue if self.add_equip(equip) is None: continue bag_items.equips.append(equip) for _id, c, tr in rwitems.fates: for i in xrange(c): fate = item_mgr.new_fate(_id, is_trade=tr) if not fate: continue if self.add_fate(fate) is None: continue bag_items.fates.append(fate) for rid in rwitems.roles: rs, err = self.player.roles.can_add(rid) if not rs: log.error(u'奖励配将失败:%s', err) else: bag_items.roles.append(self.player.roles.add_role(err)) for _id in rwitems.cars: res_car = self.player._game.res_mgr.cars.get(_id) if res_car: t_car = self.add_car(_id) bag_items.cars.append(t_car) else: log.error(u'奖励的坐骑id在资源标表中不存在') for _id, c, lv in rwitems.gem: for i in xrange(c): gem = item_mgr.new_gem(_id, lv) if not gem: continue if self.add_gem(gem) is None: continue bag_items.gem.append(gem) if log_type: self.player.log_items(items, log_type, rid=rid) return bag_items
def handle_pay_back(pid, rid, first_reward, coin): """ 离线支付回调 """ from game.player.player import Player p = Player.load_player(pid) if not p: log.error('******pay_back error:player(%s) not found', pid) return 0, 0 rs = p.pay_back(rid, first_reward, coin) p.save() return rs
def _loop(self): readfunc = self._sock.recv try: while 1: data = readfunc(BUFFER_SIZE) if not data: break self._process(data) except socket.error, e: log.error('[ClientRpc]socket error:%s' % e)
def kill_process(self, pid): if pid in self.pids: popen = self.pids.pop(pid) if isinstance(popen, subprocess.Popen): try: popen.kill() except StandardError, e: if hasattr(e, 'errno') and e.errno == errno.ESRCH: pass else: log.error('kill subprocess error:%s - %s', type(e), e)
def has_pay(self, sns, CooOrderSerial): """ 查询支付结果 """ params = dict(CooOrderSerial=CooOrderSerial) url = self.get_url(sns, URL_HAS_PAY) data = http_post_ex(self.port, self.port, url, params=params) if not data: return 0, EC_NET_ERR rs, code, desc = json.loads(data) if not rs: log.error('SNSClient.has_pay error:%s, %s, %s', rs, code, desc) return 0, (code, desc) return 1, None
def _set_data(func, args, kw): self.set_count += 1 self.set_step_count += 1 while 1: try: return func(*args, **kw) except ConnectionError as e: #链接错误,尝试重新保存,保证数据安全 log.error('_process_set error:%s, will retry:%s', e, (func, args, kw)) except: log.log_except('_process_set:%s', (func, args, kw)) break sleep(0.1)
def raw_unpack(self, tag, data): """ 解一个没有长度的包数据 """ if self.aes_decrypt: data = self.aes_decrypt(data) if self.UNZIP: #log.debug('raw_unpack:%s', repr(data)) try: data = decompress(data) except: log.error('decompress:%s', repr(data[:50])) raise adict = json.loads(data) adict['_tag'] = tag return adict
def _init_res_reward_active(self, objs): """ 活动奖励 """ from game.base.constant import REWARDACTIVE_RECHARGE, REWARDACTIVE_WEPONUP, REWARDACTIVE_RECRUIT self.reward_actives = {REWARDACTIVE_RECHARGE : {}, REWARDACTIVE_WEPONUP : {}, REWARDACTIVE_RECRUIT : {}} for o in objs: if o.t == REWARDACTIVE_RECHARGE: self.reward_actives[REWARDACTIVE_RECHARGE] = o elif o.t == REWARDACTIVE_WEPONUP: self.reward_actives[REWARDACTIVE_WEPONUP][o.val] = o elif o.t == REWARDACTIVE_RECRUIT: self.reward_actives[REWARDACTIVE_RECRUIT][o.val] = o else: log.error(">>>>>>>>>>>>>>>reward_active type:%s or tNum:%s error", o.t, o.tNum) return self.reward_actives
def own(self, pid, m_count = True, duty = True): """ 发送得到玩家自己工会 """ own_dict = dict() if m_count: own_dict['mCount'] = self.member_num if duty: own_dict['duty'] = self.get_duty_by_pid(pid) td = self.data.to_dict().copy() td['pn'] = self.main_name() for ky in KeyRemoveMgr.OWN_REMOVE: if td.has_key(ky): del td[ky] else: log.error("key error:%s in ally.py:", ky) own_dict['ally'] = td return own_dict
def _get_handle(self, msg_name): """ 获取远程函数对象 """ try: func_name = self._names_[msg_name] except KeyError: func_name = self._rpc_attr_pre + msg_name.replace('.', '_') self._names_[msg_name] = func_name try: return self._export_funcs[func_name] except KeyError: func = getattr(self._export, func_name, None) if func is None: log.error(u'对象(%s)中,远程调用本地函数(%s)未找到' % (self._export, msg_name)) self._export_funcs[func_name] = func return func
def grave(self, pid, t, vip): """ 一次铭刻 out_time是玩家上次退出游戏的时间 t是铭刻类型""" assist_obj = self.assist_objs.get(pid) if not assist_obj: return False, errcode.EC_PLAYER_NO #非vip的铭刻 if t in (ALLY_GRAVE1, ALLY_GRAVE2, ALLY_GRAVE3): assist_obj.data.gn1 += 1 assist_obj.data.gt = common.current_time() assist_obj.save(self.rpc_store, forced=True) return True, None #vip的铭刻 if t in (ALLY_VIP_GRAVE1,ALLY_VIP_GRAVE2, ALLY_VIP_GRAVE3): #vip的铭刻 log.error('this function is not open please check allyGrave type') return False, errcode.EC_TIMES_FULL
def pay(cls, porder, pay_id, **kw):#, res_store): """ 主动检查式 """ from game.base import errcode from game.res.shop import PrePay, Pay res_store = cls.res_store pre_pay = PrePay.load_ex(res_store, dict(porder=porder)) if not pre_pay: log.error('[sns]****error: porder(%s) no found', porder) return False, errcode.EC_VALUE sns_type = pre_pay.t log.info('[pay-%d](%s)(%s, %s)', sns_type, pre_pay.pid, porder, pay_id) #检查是否支付成功 sns = snss[pre_pay.t] c = 3 rs, torder, data = False, None, None while c > 0: try: rs, torder, data = sns.pay(pay_id, pre_pay.pd, **kw) if not rs: log.error('[sns(%s)]pay error:%s', pre_pay.t, data) return False, errcode.EC_VALUE break except: log.log_except('[sns(%s)]pay error', pre_pay.t) c -= 1 if not rs: return False, errcode.EC_VALUE #是否已经存在 if Pay.pay_exist(sns_type, torder, res_store): log.info('[sns(%s)]torder(%s) exist!', sns_type, torder) return True, None if not Pay.check(porder, res_store): log.info('[sns(%s)]porder(%s) exist!', sns_type, porder) return False, errcode.EC_VALUE #支付检查成功后,保存数据 pay = Pay() pay.prepare(True, torder, pre_pay, data) pay.save(res_store) log.info('[sns(%s)]save_data(%s) done', pre_pay.t, porder) return True, None
def get_server_id(self): """ 服id """ if not self.server_id: #server id host, port = config.inet_ip, config.player_addr[1] try: servers = Game.rpc_res_store.query_loads(TN_SERVER, dict(host=host, port=port)) if len(servers) != 1: log.error(u'server id error:%s', str(servers)) raise ValueError('server id error') self.server_id = servers[0]['sid'] log.info('server_id:%s', self.server_id) except: if not self.server_id: raise return self.server_id
def contribute(self, pid, name, train, ally = None): main_data = ally.data ally_levels = self.res_mgr.ally_levels #配成从0开始所以判断下一级需要加1 level_obj = ally_levels.get(main_data.level + 1) if level_obj: up_exp = level_obj.exp main_data.exp += train if main_data.exp >= up_exp and main_data.level < len(ally_levels): ally.level_up() self.safe_pub(MSG_ALLY_UP, main_data.id, main_data.level) log.info("contribute ally_id:%s,cur_exp:%s,lev_up_exp:%s", main_data.id, main_data.exp, up_exp) main_data.exp -= up_exp ally.contribute(pid, name, train) return True, None else: log.error('contribute in ally.py level:%s', ally.data.level) return False, None
def grave_have(self, pid, t, vip): """是不是有铭刻""" assist_obj = self.assist_objs.get(pid) if not assist_obj: return False, errcode.EC_PLAYER_NO time = assist_obj.data.gt func = assist_obj.data.day_pass_grave self.handle_pass_day(time, func) #非vip的铭刻 if t in (ALLY_GRAVE1, ALLY_GRAVE2, ALLY_GRAVE3): g_max_num = int(get_max_grave(vip)) if g_max_num > assist_obj.data.gn1: return True, None return False, errcode.EC_TIMES_FULL #vip的铭刻 if t in (ALLY_VIP_GRAVE1, ALLY_VIP_GRAVE2, ALLY_VIP_GRAVE3): #vip的铭刻 log.error('this function is not open please check allyGrave type') return False, errcode.EC_TIMES_FULL
def members(self, is_other = False): """ 获取自己同盟某页成员""" onls = [] dis_onls = [] pids = self.get_member_pids() online_pids = self._mgr.rpc_player_mgr.get_online_ids(pids) p_dicts= dict((data['id'], data) for data in PlayerData.get_players_values( pids, ['name', 'level', 'tLogout'], store=self.rpc_store)) for assist_data in self.members_list: try: t_dit = dict() pid = assist_data.pid if pid not in p_dicts:#玩家不存在 log.error(u'同盟(%s)玩家(%s)不存在', self.data.name, pid) continue p_dic = p_dicts[pid] t_dit['pid'] = pid t_dit['n'] = p_dic['name'] t_dit['lv'] = p_dic['level'] t_dit['duty'] = assist_data.duty t_dit['pvp'] = 2000 pvp = self._mgr._game.rpc_arena_mgr.get_rank(pid) if pvp: t_dit['pvp'] = pvp #是不是查看其他的同盟 是就不加载exp和dt dis_onls.append(t_dit) if not is_other: t_dit['exp'] = assist_data.exp if pid in online_pids: t_dit['dt'] = 0 dis_onls.remove(t_dit) onls.append(t_dit) else: t_dit['dt'] = p_dic['tLogout'] except: log.error("PlayerData.get_values is None pid:%s in ally.py func->members", assist_data.pid) if onls or dis_onls: onls = sor_member(is_other, True, onls) dis_onls = sor_member(is_other, False, dis_onls) mems = onls mems.extend(dis_onls) return mems
def grave_have(self, pid, t, vip): """是不是有铭刻""" assist_obj = self.assist_objs.get(pid) if not assist_obj: return False, errcode.EC_PLAYER_NO time = assist_obj.data.gt func = assist_obj.data.day_pass_grave self.handle_pass_day(time, func) #非vip的铭刻 if t in (ALLY_GRAVE1, ALLY_GRAVE2, ALLY_GRAVE3): g_max_num = int(get_max_grave(vip)) if g_max_num > assist_obj.data.gn1: return True, None return False, errcode.EC_TIMES_FULL #vip的铭刻 if t in (ALLY_VIP_GRAVE1,ALLY_VIP_GRAVE2, ALLY_VIP_GRAVE3): #vip的铭刻 log.error('this function is not open please check allyGrave type') return False, errcode.EC_TIMES_FULL
def http_httplib(host, port, url, params=None, data=None, raise_err=False, con=None, headers=None, ssl=False): """ 用http方式发送数据 """ import httplib if headers is None: headers = {} err_msg = '发送数据到HTTP服务器(%s:%d%s)时出错' % (host, port, url) want_close = (con is None) if want_close: HC = httplib.HTTPConnection if not ssl else httplib.HTTPSConnection con = HC(host, port) try: urls = get_rel_urls(url, params) data = urllib.urlencode(data) con.request('POST' if data is not None else 'GET', urls, body=data, headers=headers) rs = con.getresponse() if rs.status != 200: if raise_err: raise ValueError(rs.status, rs.read()) log.error('%s:%s - %s', err_msg, rs.status, rs.read()) else: return rs.read() except socket.error as e: if raise_err: raise ValueError(e) log.error('%s:%s', err_msg, str(e)) except Exception: if raise_err: raise log.log_except() finally: if want_close: con.close()
def free_mine(self, num): n = self.get_free_mine() if n < num: return False, errcode.EC_TIMES_FULL items = [] for i in xrange(num): rid = self.player._game.gem_mgr.mine_reward[0] t_rw = self.player._game.reward_mgr.get(rid) if t_rw is None: log.error("gem reward is None rid:%s", rid) continue d = t_rw.reward(params=None) if len(d): items.append(d[0]) if not self.player.bag.can_add_items(items): return False, errcode.EC_BAG_FULL bag_items = self.player.bag.add_items(items, log_type=ITEM_ADD_GEM_MINE) self.data.mfree += num return True, bag_items.pack_msg()
def _init_res_reward_active(self, objs): """ 活动奖励 """ from game.base.constant import REWARDACTIVE_RECHARGE, REWARDACTIVE_WEPONUP, REWARDACTIVE_RECRUIT self.reward_actives = { REWARDACTIVE_RECHARGE: {}, REWARDACTIVE_WEPONUP: {}, REWARDACTIVE_RECRUIT: {} } for o in objs: if o.t == REWARDACTIVE_RECHARGE: self.reward_actives[REWARDACTIVE_RECHARGE] = o elif o.t == REWARDACTIVE_WEPONUP: self.reward_actives[REWARDACTIVE_WEPONUP][o.val] = o elif o.t == REWARDACTIVE_RECRUIT: self.reward_actives[REWARDACTIVE_RECRUIT][o.val] = o else: log.error( ">>>>>>>>>>>>>>>reward_active type:%s or tNum:%s error", o.t, o.tNum) return self.reward_actives
def _build_rights(self, assist_data): """ 创建<查看 踢人 改变职责 修改公告>的权限""" duty = assist_data.duty right_dic = self.res_mgr.ally_rights if duty and right_dic: res_right = right_dic[duty] if not res_right: log.error("_build_rights in ally.ally.py duty:%s", duty) return pid = assist_data.pid if res_right.check: self._add_right(self.r_apply, pid) if res_right.kick: self._add_right(self.r_tick_out, pid) if res_right.change: self._add_right(self.r_duty_change, pid) if res_right.post: #设置BOSS的时间和改变公告的权限 self._add_right(self.r_post, pid) self._add_right(self.r_boss_t, pid)
def init(self, url, **dbkw): """ url: mongodb://jhy:[email protected]/jhy """ assert self._conn is None, 'already had server' self.url = url self.dbkw = dbkw self.timeout = dbkw.get('timeout', None) urler = urlparse.urlparse(url) try: self._conn = pymongo.Connection(url, network_timeout=self.timeout, use_greenlets=True) dbname = urler.path[1:] self._db = getattr(self._conn, dbname) if urler.username: self.username = urler.username self.pwd = urler.password except pymongo.errors.AutoReconnect: log.error(u'连接mongoDB(%s:%s)失败', urler.hostname, urler.port) raise
def _build_rights(self, assist_data): """ 创建<查看 踢人 改变职责 修改公告>的权限""" duty = assist_data.duty right_dic = self.res_mgr.ally_rights if duty and right_dic: res_right = right_dic[duty] if not res_right: log.error("_build_rights in ally.ally.py duty:%s", duty) return pid = assist_data.pid if res_right.check: self._add_right(self.r_apply, pid) if res_right.kick: self._add_right(self.r_tick_out, pid) if res_right.change: self._add_right(self.r_duty_change, pid) if res_right.post: #设置BOSS的时间和改变公告的权限 self._add_right(self.r_post, pid) self._add_right(self.r_boss_t, pid)
def rc_login1(self, user, key): """ client登陆到逻辑进程 user: user id """ if self.inited: return resp_f = 'login1' self.inited = 1 log.info(u'账号(%s)登陆', user) self.key = key self.data.id = user if not self.logon(): log.error(u'账号(%s)登陆错误', user) resp = pack_msg(resp_f, 0, err=errcode.EC_LOGIN_ERR) else: #resp.server_time = int(time.time()) resp = pack_msg(resp_f, 1) self.inited = 2 spawn_later(1, self._init_waiter.set) return resp
def init(self, url, **dbkw): """ url: mongodb://jhy:[email protected]/jhy """ assert self._conn is None, 'already had server' self.url = url self.dbkw = dbkw self.timeout = dbkw.get('timeout', None) urler = urlparse.urlparse(url) try: self._conn = pymongo.Connection(url, network_timeout=self.timeout, use_greenlets=True) dbname = urler.path[1:] self._db = getattr(self._conn, dbname) if urler.username: self.username = urler.username self.pwd = urler.password except pymongo.errors.AutoReconnect: log.error(u'连接mongoDB(%s:%s)失败', urler.hostname, urler.port) raise
def load_player(self, pid, p=None): """ 加载玩家对象到alls @result: bool: 是否成功 """ if pid is None: raise ValueError('pid is None') if pid in self.alls: if p is not None and self.alls[pid] != p: log.error( '*******load_player: pid(%s) alls[pid](%s) != player(%s)', pid, id(self.alls[pid]), id(p)) setattr(self.alls[pid], self._STAY_PROP_, current_time()) return True if p is None: p = Player.load_player(pid) if p is None: return False self.alls[pid] = p setattr(self.alls[pid], self._STAY_PROP_, current_time()) return True
def _loop(self): """ 定时保存等处理 """ stime = 30 logout_check_time = current_time() while 1: sleep(stime) try: p = None #定时保存 keys = list(self.players.keys()) for pid in keys: p = self.players.get(pid) if p is None or not p.logined: log.error( '[player_mgr]player(%s) in mgr.players, is None or not logined', pid) self.players.pop(pid, None) continue try: if p.save_time + self._SAVE_TIME_ <= time.time(): p.save() sleep(0.01) except: log.log_except() self.players.pop(pid, None) del p except: log.log_except() #定时清理离线玩家缓存 min_time_out, max_time_out = 2 * 60, 5 * 60 # 10分钟检查一次, ctime = current_time() if (self.len_offline > self.max_logouts and (ctime - logout_check_time >= min_time_out)) or \ (ctime - logout_check_time >= max_time_out): logout_check_time = ctime try: self.logouts_clean() except: log.log_except()
def runtime_init(self, tasks): """ 将解锁条件的字符串的数据转为字典 """ if self.nextId: next_task = tasks.get(self.nextId) if next_task is not None: assert not getattr(next_task, 'parent') next_task.parent = self #level:1:100|role:7:8|tid:1|obj:1:3|equ:5 --> # {level:[1,100], role:[7,8],tid:[1, 3],equ:[5], obj:[1,3]...} #obj的最后一个数量先不管,拥有时判断即可 try: self.unlock = str2dict1(self.unlock) if self.unlock is None: self.unlock = {} except: log.error(u'任务(%d)解锁条件错误:%s', self.id, self.unlock) self.unlock_level = map(int, self.unlock['level']) if 'level' in self.unlock else 0 self.unlock_roles = map(int, self.unlock['role']) if 'role' in self.unlock else None self.unlock_tasks = map(int, self.unlock['tid']) if 'tid' in self.unlock else None self.unlock_objs = map(int, self.unlock['obj']) if 'obj' in self.unlock else None self.unlock_equs = map(int, self.unlock['equ']) if 'equ' in self.unlock else None self.auto = bool(int(self.unlock['auto'][0])) if 'auto' in self.unlock else True
def _spawn_enter(obj, func, *args, **kw): global _globals, _greenlets #防止在game对象stoped后,才运行的微线程启动 if obj is not None and getattr(obj, 'stoped', False): log.error( '******global(%s) have stoped, _spawn_enter(%s) no start*****', obj, func) return cur_let = getcurrent() _greenlets[cur_let] = None if obj is not None: #log.debug('****_spawn_enter.begin:%s-%s-%s', func.func_name, id(cur_let), len(_globals)) reg_global_for_let(obj, let=cur_let) try: func(*args, **kw) except GreenletExit: log.error("[GreenletExit cur_let(%s) obj(%s) func(%s) args(%s) kw(%s)", cur_let, obj, func, args, kw) except Exception: log.log_except() finally: un_reg_global_for_let(cur_let) _greenlets.pop(cur_let, None)
def send_imme(self, msg): """ 立即发送 msg:必须为字符串或者protobuf对象, 在外部将protobuf对象序列化后,直接发送字符串,能优化速度 """ if isinstance(msg, str): if msg.startswith(PRE_MSG): data = msg[PRE_MSG_LEN:] else: raise ValueError, 'can not send str type:%s' % repr(msg) else: data = self._packer.pack(msg) ## length = len(data) #log.debug('[rpc]send:%s-%s' % (self.addr, msg.DESCRIPTOR.full_name)) try: with self._slock: # self._sock.sendall(hb_pkt+data) #TODO: 测试 self._sock.sendall(data) return True except socket.error, e: log.error('[clientRpc]error:(%s)%s' % (id(self), e)) corelib.spawn(self.stop) return False
def send_imme(self, msg): """ 立即发送 msg:必须为字符串或者protobuf对象, 在外部将protobuf对象序列化后,直接发送字符串,能优化速度 """ if isinstance(msg, str): if msg.startswith(PRE_MSG): data = msg[PRE_MSG_LEN:] data, self._w_token, self.adler_value = \ self._packer.safe_pack_raw(data, self._w_token, self.adler_value) else: raise ValueError, 'can not send str type:%s' % repr(msg) else: data, self._w_token, self.adler_value = \ self._packer.safe_pack(msg, self._w_token, self.adler_value) try: with self._slock: self._sock.sendall(data) return True except socket.error, e: log.error('[clientRpc]error:%s' % e) corelib.spawn(self.stop) return False
def add_friend(self, player, pid): """ 添加好友 """ if self.is_black(pid): self.data.bks.remove(pid) rs, err = self.add_check(player, pid) if not rs: return rs, err rpc_player = self._mgr._game.rpc_player_mgr.get_rpc_player(pid) self.data.fds.append(pid) player.pub(MSG_SOCIAL_ADD, len(self.data.fds)) if rpc_player: #对方未加我 if not rpc_player.is_friend(player.data.id): rpc_player.force_add_friend(player.data.id) rpc_player.apply_friend(player.data.name) return True, rpc_player.social_online_info() #对方不在线直接操作数据库 t_d = self._mgr._game.rpc_store.load(self.TABLE_NAME, pid) if not t_d: log.error("database have no this player pid:%s", pid) return False, errcode.EC_PLAYER_EMPTY if player.data.id in t_d['fds']: #对方也加我了 return True, self._node_list(list((pid, )))[0] t_d['fds'].append(player.data.id) #写入数据库中 self._mgr._game.rpc_store.save(self.TABLE_NAME, t_d) fd_mail = Game.res_mgr.reward_mails.get(SOCIAL_MAIL_FRIEND) res_role = Game.res_mgr.roles.get(player.data.rid) color = '#' + Game.item_mgr.get_color(res_role.quality) content = fd_mail.content % dict(name=player.data.name, color=color) self._mgr._game.mail_mgr.send_mails(pid, MAIL_REWARD, fd_mail.title, SOCIAL_MAIL_FRIEND, [], param=content) return True, self._node_list(list((pid, )))[0]
def save_data(cls, porder, torder, status, price, data): """ 保存 """ pre_pay = cls.get_pre_pay(porder) if not pre_pay: log.error('[sns(%s)]****error: porder(%s) no found', cls.SNS_TYPE, porder) return False if not Pay.check(porder, logon_store): log.info('[sns(%s)]porder(%s) torder(%s) existed!', cls.SNS_TYPE, porder, torder) return True #检查 if not pre_pay.check(price): log.error('[sns(%s)]****error: price(%s != %s)', cls.SNS_TYPE, pre_pay.price, price) return False pay = Pay() pay.prepare(status, torder, pre_pay, data) pay.save(logon_store) log.info('[sns(%s)]save_data(%s) done', cls.SNS_TYPE, porder) return True
def _change_duty(self, assist_obj1, name, assist_obj2, duty): #得到该职位的个数 lev_obj = self.res_mgr.ally_levels.get(self.data.level) if duty != ALLY_MEMBER: num = getattr(lev_obj, "dt%sNum" % duty) duty_list = self.duty2objs.get(duty) dt_num = 0 if not duty_list else len(duty_list) #是否已经达到上限 if num <= dt_num: return False, errcode.EC_DUTY_FULL #改变职责 pid2 = assist_obj2.data.pid self.remove_rights(pid2) assist_obj2.data.duty = duty self.build_rights(assist_obj2) assist_obj2.save(self.rpc_store, forced=True) self._add_in_log(ALLY_OP_DUTY, name, pid2, duty, 0) right_obj = self.res_mgr.ally_rights.get(duty, None) if not right_obj: log.error('ResAllyRight duty:%s', duty) cd_dict = dict(n1=name, n2=Ally.get_name(pid2), duty=right_obj.name) self.tell_online_members(language.ALLY_CHANGE_DUTY % cd_dict) return True, ALLY_OP_SUCCEED
def detach_ally(self, pid): try: del self.pid2ally[pid] self.glory_remove(pid) except KeyError: log.error("____dis_all_obj func in all_mgr.py is error pid:%s", pid)
def get_res_guard(gid): guard = Game.res_mgr.deep_guards.get(gid) if not guard: log.error(u'resguard not found:%s', gid) return guard
def on_close(self, rpc=None): """ 网关断开 """ log.error('******网关断开连接,将通知所有Processer') self.stop()