def resetAttr(entityID, attrName): from entity.manager import g_entityManager entityID = int(entityID) p = g_entityManager.get_player(entityID) if not p: from player.model import Player, OfflineAttrType Player.add_offline_attr(entityID, Player.getAttributeIDByName(attrName), None, type=OfflineAttrType.Reset) return SUCCESS else: try: f = p.fields[attrName] if callable(f.default): default = f.default() else: default = f.default setattr(p, attrName, default) p.save() p.sync() except: import traceback traceback.print_exc() return FAILURE return SUCCESS
def discredit_offline(manager, entityID, current_floor): now = int(time.time()) floor = manager.avail_floor(current_floor) attrs = ['climb_tower_accredit_earnings', 'climb_tower_floor', 'climb_tower_accredit_stash_time', 'climb_tower_accredit_cd'] p = Player.simple_load(entityID, Player.expend_fields(attrs)) if p: if floor: value = p.climb_tower_accredit_earnings # 结束时间作为 score score = p.climb_tower_accredit_cd p.climb_tower_accredit_stash_earnings += value p.climb_tower_accredit_floor = floor p.climb_tower_accredit_stash_time = now # 取消当前层派驻 manager.floors[current_floor].idx.unregister(p.entityID) manager.floors[floor].idx.register(p.entityID, score) else: p.climb_tower_accredit_cd = now manager.floors[current_floor].idx.unregister(p.entityID) p.save()
def sync_loot_cost_offline(entityID, history): if not history["result"]: # lose if not cost_mats(entityID, history["loot"], history["count"]): return now = int(time.time()) Player.save_attributes(entityID, loot_protect_time=now + 3600) Player.pool.execute("LPUSH", "loot_history_p{%d}" % entityID, Player.fields['loot_history'].encoder(history)) Player.pool.execute("LTRIM", "loot_history_p{%d}" % entityID, 0, 10)
def loot_target(player, power, loot, count): dvalue = 100 + power * 0.06 s, e = int(max(0, power - dvalue)), int(power + dvalue) samples = set(PlayerPowerRanking.get_range_by_score(s, e, count=16)) - set( [player.entityID]) zombies = set(get_zombies_by_power(s, e, count=5)) # s = max(player.level - 12, 1) # e = max(player.level - 6, 1) # samples = set( # PlayerLevelRanking.get_range_by_score( # s, e, count=16) # ) - set([player.entityID]) # zombies = set(reduce( # lambda x, y: x+y, # [get_zombies_by_level(l)[:5] # for l in range(s, e + 1)])) samples = samples.union(zombies) chosen = choice_one(list(samples)) logger.debug("search targets is {}".format(samples)) if not is_zombie(chosen): rest = search_targets_loot([chosen], loot)[0] p = Player.simple_load(chosen, "loot_protect_time") now = int(time.time()) if PlayerLootLock.locked(chosen) or \ now < p.loot_protect_time and rest < 50 and rest < count: chosen = choice_one(list(zombies)) if not chosen: chosen = choice_one(list(get_zombies())) # # NOTE FIXME FOR DEBUG # chosen = player.entityID return get_opponent_detail(chosen)
def get_lineup_info(playerID, attrs, type=None): from player.model import Player from pet.model import Pet from entity.manager import g_entityManager if not type: type = LineupType.ATK p = g_entityManager.get_player(playerID) if p: pets = [p.pets.get(i, None) for i in p.lineups.get(type, [])] else: # p = Player.batch_load([playerID], ['lineups'])[0] # FIXME p = Player.simple_load(playerID, ["entityID", "lineups"]) p.lineups.load() if p: try: pets = Pet.batch_load(p.lineups.get(type, []), Pet.expend_fields(attrs)) except IndexError: pets = [] result = [] for pos, pet in enumerate(pets): if not pet: continue info = {n: getattr(pet, n) for n in attrs} if type == LineupType.Daily: if info.get("daily_restHP", 0): info["restHP"] = info["daily_restHP"] info['posIndex'] = pos info['isTeamLeader'] = (pos == 0) result.append(info) return result
def alter_name(self, msgtype, body): limited, message = self.access_limited() if limited: return fail_msg(msgtype, reason=message) req = poem_pb.AlterNameRequest() req.ParseFromString(body) entityID = req.entityID if not entityID: user = User.load(self.userID) entityIDs = user.roles.get(settings.REGION['ID']) if len(entityIDs) > 1: return fail_msg(msgtype, reason="未指定角色") if entityIDs: entityID = entityIDs[0] if not PlayerDuplicateNamesIndexing.exists(entityID): return fail_msg(msgtype, reason="不可修改名称") session = SessionStore(get_session_pool(), str(req.verify_code)) if not req.userID or session.uid != req.userID: return fail_msg(msgtype, reason="登录超时,请重试") name, error = validate_name(req.name) if error: return fail_msg(msgtype, error) # 名字去重复 try: PlayernameIndexing.register(0, name) # 占位 p = Player.simple_load(entityID, ["name"]) p.name = name p.save() PlayernameIndexing.pool.execute( 'HSET', PlayernameIndexing.key, name, entityID) # 更新 except DuplicateIndexException: return fail_msg(msgtype, reason=_YYTEXT('该名称已存在')) PlayerDuplicateNamesIndexing.unregister(entityID) return success_msg(msgtype, '')
def pay_handler(entityID, username, goodsid, amount=None): goodsid = str(goodsid) # 必须是字符串 label = username2label(username) sdktype = username2type(username) sdkconfigs = get_config(RechargeBySdktypeConfig).get(sdktype, []) labconfigs = get_config(RechargeByLabelConfig).get(label, []) configs = get_config(RechargeConfig) ids = {e.id for e in sdkconfigs} & {e.id for e in labconfigs} good = {configs[e].goodsid: configs[e] for e in ids}.get(goodsid) if not good: logger.error("error goodsid %r", goodsid) return p = g_entityManager.get_player(entityID) if p: level = p.level reward = give_goods(p, good, amount=amount) get_gold = reward.get("gold", 0) else: # patch 离线玩家,需要计算可获得金额 p = Player.simple_load( entityID, ["userID", "level", "bought_recharges", "offline_recharges"]) level = p.level if p.offline_recharges: p.offline_recharges.append([good.id, amount]) else: p.offline_recharges = [[good.id, amount]] is_first = (good.id not in (p.bought_recharges or set())) \ and (good.id not in ({i for i, j in p.offline_recharges} or set())) from reward.manager import open_reward, RewardType reward = open_reward(RewardType.Recharge, good, is_first, amount) rs = reward.apply_after() # 仅计算可获金额,并不发货 get_gold = rs.get("gold", 0) p.save() return {"username": username, "level": level, "get_gold": get_gold}
def sync_rank_offline(entityID, history, fight=None): from player.model import Player FIGHT_HISTORY_LIMIT = 5 pkey = make_key(Player.store_tag, entityID) history['ID'] = '%d:%d' % (history['time'], history['oppID']) if incr_score(entityID, history['score']): from chat.manager import on_news_pvp_first on_news_pvp_first(Player.simple_load(entityID, ["entityID", "name"])) Player.pool.execute('HINCRBY', pkey, 'rank_count', 1) Player.pool.execute("LPUSH", "rank_history_p{%d}" % entityID, Player.fields['rank_history'].encoder(history)) Player.pool.execute("LTRIM", "rank_history_p{%d}" % entityID, 0, 30) if fight: Player.pool.execute("HSET", "rank_fight_history_p{%d}" % entityID, history['ID'], fight) keys = Player.pool.execute('HKEYS', "rank_fight_history_p{%d}" % entityID) if len(keys) > FIGHT_HISTORY_LIMIT: for key in sorted(keys)[:-FIGHT_HISTORY_LIMIT]: Player.pool.execute("HDEL", "rank_fight_history_p{%d}" % entityID, key) if history['isWin']: Player.pool.execute('HINCRBY', pkey, 'rank_win_count', 1) else: Player.pool.execute('HINCRBY', pkey, 'rank_passive_offline_count', 1) return 'FAILURE'
def get_players_info(self, playerIDs, attrs): objs = [] pending = [] playerIDs = list(playerIDs) for playerID in list(playerIDs): p = self.get_player(playerID) if p: objs.append(p) else: pending.append(playerID) from player.model import Player objs.extend(filter(lambda s: s, Player.batch_load(pending, Player.expend_fields(attrs)))) result = [] for p in objs: result.append({n: getattr(p, n) for n in attrs}) return sorted(result, key=lambda s: playerIDs.index(s['entityID']))
def query_player(): value = request.POST.getone('value') type = request.POST.getone('type') regionID = int(request.GET['regionID']) if not type or not value: return FAILURE import settings from player.model import Player from yy.entity.index import UniqueIndexing from user.model import User, UsernameIndexing if type == 'playername': indexing = UniqueIndexing('index_p_name{%d}' % regionID, settings.REDISES['index']) entityID = indexing.get_pk(value) if entityID: entityIDs = [indexing.get_pk(value)] else: entityIDs = [] elif type == 'username': userID = UsernameIndexing.get_pk(value) u = User.load(userID) entityIDs = u.roles[regionID] elif type == 'entityID': entityIDs = [int(value)] attrs = [ 'entityID', 'username', 'name', 'sex', 'career', 'level', 'userID' ] header = ['ID', u'用户名', u'名称', u'性别', u'职业', u'等级', u"用户ID"] rows = [] players = Player.batch_load(entityIDs, attrs) for player in players: ll = [getdisplayattr(player, s) for s in attrs] rows.append(ll) return dict(rows=rows, header=header)
def join_group(entityID, groupID): now = int(time.time()) p = g_entityManager.get_player(entityID) if not p: p = Player.simple_load(entityID, ["groupID", "group_last_kicked_time"]) if p.groupID: return msgTips.FAIL_MSG_GROUP_ALREADY_JOINED if now < p.group_last_kicked_time + ONE_DAY: return msgTips.FAIL_MSG_GROUP_KICKED_RECENTLY g = Group.simple_load(groupID, ["members", "applys"]) g.members.load() g.applys.load() if len(g.members) >= MAX_MEMBERS_COUNT: return msgTips.FAIL_MSG_GROUP_LIMITED_EXCEED if p.entityID in g.members: return msgTips.FAIL_MSG_GROUP_ALREADY_JOINED_THIS g.members[p.entityID] = {"jointime": now, "intimate": 0} if len(g.members) >= MAX_MEMBERS_COUNT: unrecommend(groupID) g.applys.clear() else: recommend(groupID) try: del g.applys[p.entityID] except KeyError: pass g.save() p.groupID = groupID p.save() return SUCCESS
def friend_invite_list(self, msgtype, body): p = self.player if not p.factionID: return success_msg(msgtype, "") req = poem_pb.InviteFriendList() req.ParseFromString(body) logger.debug(req) try: ownerID, fbID = simple_load_friendfb(req.friendfbID, 'ownerID', 'fbID') except DoesNotExistsException: return fail_msg(msgtype, msgTips.FAIL_MSG_FRIENDFB_ALREADY_DISAPPEARED) if p.entityID != ownerID: return fail_msg(msgtype, msgTips.FAIL_MSG_INVALID_REQUEST) invitees = load_friendfb_invitees(req.friendfbID) # invitees 起码会有发现者 assert invitees, "impossible" fields = ['entityID', 'name', 'prototypeID', 'level', "borderID"] # 过滤已经邀请的好友(2016-02-18 改会公会成员) f = Faction.simple_load(p.factionID, ["memberset"]) rs = Player.batch_load(list(set(f.memberset) - invitees), fields) rsp = poem_pb.InviteFriendListResponse() config = get_config(FriendfbConfig)[fbID] for each in rs: info = {} if each.level < config.openlv: continue for f in fields: info[f] = getattr(each, f) info['id'] = info['entityID'] rsp.friends.add(**info) return success_msg(msgtype, rsp)
def quit_group(entityID, groupID): g = Group.simple_load(groupID, ["leaderID", "members", "invites"]) if not g: return msgTips.FAIL_MSG_GROUP_NOT_IN_THIS g.members.load() g.invites.load() p = g_entityManager.get_player(entityID) if not p: p = Player.simple_load(entityID, ["groupID", "group_last_kicked_time"]) if not p.groupID: return msgTips.FAIL_MSG_GROUP_HAS_NOT_JOINED # "未加入同门了" if p.entityID not in g.members: return msgTips.FAIL_MSG_GROUP_NOT_IN_THIS del g.members[p.entityID] if p.entityID in g.invites: g.invites.remove(p.entityID) if p.entityID == g.leaderID: rest = sorted(g.members.items(), key=lambda v: v[1]["jointime"]) if rest: new_leaderID, _ = rest[0] g.leaderID = new_leaderID recommend(groupID) g.save() p.groupID = 0 now = int(time.time()) p.group_last_kicked_time = now p.save() return SUCCESS
def friend_list(self, msgtype, body): p = self.player # 推荐好友 if p.friend_count < p.friend_max_count: recommend(p.entityID) rsp = poem_pb.FriendList() fields = [ 'entityID', 'name', 'prototypeID', 'level', 'credits', 'lastlogin', "groupID", "borderID" ] rs = Player.batch_load(list(p.friendset), fields) for each in rs: info = {} for f in fields: info[f] = getattr(each, f) info['id'] = info['entityID'] if info['lastlogin']: info['time'] = time.mktime(info['lastlogin'].timetuple()) else: info['time'] = 0 info['gifted'] = info['id'] in p.friendgiftedset info['vip'] = get_vip(info['credits'] or 0) info["messages_count"] = len( p.friend_messages.get(info['entityID'], [])) rsp.friends.add(**info) logger.debug(rsp) return success_msg(msgtype, rsp)
def clean_faction(entityID): p = g_entityManager.get_player(entityID) if not p: p = Player.simple_load(entityID, ['factionID', 'applyFactions']) if p.factionID: faction = Faction.simple_load(p.factionID, ['memberset']) if faction: safe_remove(faction.memberset, p.entityID) faction.save() p.last_factionID = p.factionID gm_logger.info({ 'faction': { 'entityID': p.entityID, 'type': 'quit_faction', 'factionID': p.factionID, } }) p.factionID = 0 p.fp = 0 p.faction_name = '' p.faction_level = 0 p.faction_is_leader = False p.applyFactions.clear() # p.applyFactionTime = 0 p.save() if g_entityManager.get_player(entityID): p.sync()
def blocktime(): # userID = int(request.POST.get("userID") or 0) entityID = int(request.POST.get("entityID") or 0) blocktime = int(request.POST.get("blocktime") or 0) if not entityID: return FAILURE now = int(time.time()) if blocktime and blocktime < now: return FAILURE from player.model import Player userID = Player.simple_load(entityID, ['userID']).userID if not userID: return FAILURE from user.model import User user = User.load(userID) user.blocktime = blocktime user.save() for regionID, entityIDs in user.roles.items(): for entityID in entityIDs: spawn(proxy_batch_call, 'chat.manager.clear_blocked_message', regionID, entityID) return SUCCESS
def friend_applys(self, msgtype, body): p = self.player rsp = poem_pb.ApplysList() applys = p.friend_applys or {} fields = [ 'entityID', 'name', 'prototypeID', 'level', 'credits', "borderID" ] now = int(time.time()) pending = [] rs = Player.batch_load(applys.keys(), fields) for each in rs: info = {} applytime = applys.get(each.entityID, {}).get('applytime', 0) if applytime and now > applytime + FRIEND_APPLY_CD: pending.append(each.entityID) continue for f in fields: info[f] = getattr(each, f) info['id'] = info['entityID'] info['time'] = applytime info['vip'] = get_vip(info['credits'] or 0) rsp.applys.add(**info) if pending: for i in pending: del p.friend_applys[i] p.save() p.sync() logger.debug(rsp) return success_msg(msgtype, rsp)
def blockdevice(): entityID = int(request.POST.get("entityID") or 0) block = request.POST["block"] == 'True' if not entityID: return FAILURE from player.model import Player userID = Player.simple_load(entityID, ['userID']).userID if not userID: return FAILURE from user.model import User user = User.load(userID) imsi = user.imsi if not imsi: return FAILURE from session.regions import r_block_devices if block: r_block_devices.sadd(imsi) else: r_block_devices.srem(imsi) if block: for regionID, entityIDs in user.roles.items(): for entityID in entityIDs: spawn(proxy_batch_call, 'chat.manager.clear_blocked_message', regionID, entityID) return SUCCESS
def friend_recommends(self, msgtype, body): p = self.player rsp = poem_pb.RecommendsList() recommends = getrecommends(p, count=10) fields = [ 'entityID', 'name', 'prototypeID', 'level', 'credits', 'friend_applys', 'lastlogin', "borderID" ] rs = Player.batch_load(recommends, fields) for each in rs: if not each: continue each.friend_applys.load() if p.entityID in each.friend_applys: continue info = {} for f in fields: info[f] = getattr(each, f) info['id'] = info['entityID'] info['vip'] = get_vip(info['credits'] or 0) if info['lastlogin']: info['time'] = int(time.mktime(info['lastlogin'].timetuple())) rsp.recommends.add(**info) logger.debug(rsp) return success_msg(msgtype, rsp)
def get_faction_info(factionID): faction = Faction.get(factionID) if not faction: return {} player = Player.simple_load(faction.leaderID, ['prototypeID', 'name']) return dict( factionID=factionID, name=faction.name, level=FactionRankRanking.get_score(faction.factionID) or 1, mcount=len(faction.memberset), acount=len(faction.applyset), totalfp=faction.totalfp, todayfp=faction.todayfp, rank=FactionRankRanking.get_rank(factionID), prototypeID=player.prototypeID, leader=player.name, createtime=faction.createtime, notice=faction.notice, mode=faction.mode, strengthen_hp_level=faction.strengthen_hp_level, strengthen_at_level=faction.strengthen_at_level, strengthen_ct_level=faction.strengthen_ct_level, strengthen_df_level=faction.strengthen_df_level, can_strengthen=get_config(CanStrengthenConfig)[1].can, leaderID=faction.leaderID, dflag=faction.dflag, )
def city_send_mail_offline(entityID, title, content, rewards, key, ID): if not int(Player.pool.execute( "HSET", "city_rewards_recv_p{%d}" % entityID, key, "") or 0): return p = Player.simple_load(entityID, ['factionID']) rank = CityDungeonKillRanking.get_rank(p.factionID) content = content.format(rank) send_mail(entityID, title, content, addition=rewards, configID=ID)
def addAttr(entityID, attrName, value): from entity.manager import g_entityManager entityID = int(entityID) value = int(value) role = g_entityManager.get_player(entityID) if not role: from player.model import Player Player.add_offline_attr(entityID, Player.getAttributeIDByName(attrName), value) return SUCCESS try: if not hasattr(role, attrName): return FAILURE current = getattr(role, attrName) if not isinstance(current, (int or long)): raise TypeError if attrName == "exp": from reward.base import set_exp set_exp(role, value) elif attrName == "level": if value == 0: return FAILURE from config.configs import get_config, LevelupConfig lconfigs = get_config(LevelupConfig) exp = 0 for i in range(role.level + 1, role.level + value + 1): c = lconfigs.get(i) if not c: return FAILURE exp += c.exp from reward.base import set_exp set_exp(role, exp) elif attrName == "totalbp": from pvp.rank import incr_score from player.model import PlayerRankRanking incr_score(entityID, value) PlayerRankRanking.sync_player(role) else: setattr(role, attrName, current + value) role.save() role.sync() except: import traceback traceback.print_exc() return FAILURE return SUCCESS
def load_player(self, userID, entityID, clientVersion='', featureCode='', clientIP=''): player = self.get_player(entityID) if player: return player user = User.get(userID) # 校验entityID if not user or entityID not in user.roles.get(settings.REGION['ID']): logger.error('player crossed failed %d', entityID) return player = Player.load(entityID) if not player: return player.userID = user.userID player.username = user.username player.username_alias = user.username_alias or '' player.channel = user.channel or '' self.set_player(player) if not player.lastlogin: create_player(player) player.totallogin = 1 # 累计登陆 player.seriallogin = 1 # 连续登陆 player.clientVersion = clientVersion player.featureCode = featureCode player.clientIP = clientIP from common.log import role_register role_register.info(player=player) else: player.load_mails() today = datedate.today() if player.lastlogin.date() != today: # 当日重复不计算累计连续登陆 if player.lastlogin.date() < (datedate.today() - timedelta(days=1)): # 昨天没登陆 player.seriallogin = 1 else: player.seriallogin += 1 player.totallogin += 1 # 月卡减去每天登录的天数 if player.monthly_card_30: delta = today - player.lastlogin.date() player.monthly_card_30 = max(player.monthly_card_30 - delta.days + 1, 0) # {{ 新月卡 if player.monthcard1: delta = today - player.lastlogin.date() player.monthcard1 = max(player.monthcard1 - delta.days + 1, 0) if player.monthcard2: delta = today - player.lastlogin.date() player.monthcard2 = max(player.monthcard2 - delta.days + 1, 0) if player.weekscard1: delta = today - player.lastlogin.date() player.weekscard1 = max(player.weekscard1 - delta.days + 1, 0) if player.weekscard2: delta = today - player.lastlogin.date() player.weekscard2 = max(player.weekscard2 - delta.days + 1, 0) # }} player.daily_first_login = True now = int(time.time()) player.lastlogin = datetime.fromtimestamp(now) player.save() return player
def lock_device_and_skip_guide(entityID): from entity.manager import g_entityManager from player.model import Player, OfflineAttrType entityID = int(entityID) deviceID = request.POST.getone('deviceID', '') lock_level = int(request.POST.getone('lock_level', '50')) role = g_entityManager.get_player(entityID) if not role: Player.add_offline_attr(entityID, Player.getAttributeIDByName('skip_guide'), True, OfflineAttrType.Set) Player.add_offline_attr(entityID, Player.getAttributeIDByName('lock_level'), lock_level, OfflineAttrType.Set) else: role.skip_guide = True role.lock_level = lock_level role.save() role.sync() # lock device if not role: userID = Player.simple_load(entityID, ['userID']).userID else: userID = role.userID from user.model import User u = User.simple_load(userID, ['lock_device', 'imsi']) u.lock_device = deviceID or u.imsi u.save() return SUCCESS
def sync_faction_offline(entityID, factionID, level, name): p = Player.simple_load(entityID, ['factionID', 'faction_level', 'faction_name']) if p.factionID == factionID: p.faction_level = level p.faction_name = name p.save() p.sync() return True
def allow_friend_offline(applyID, entityID): p = Player.simple_load(applyID, ["friendset", "level"]) friend_max_count = get_friend_max_count(p.level) if len(p.friendset) >= friend_max_count: return False if len(p.friendset) + 1 >= friend_max_count: unrecommend(entityID) add_friend_offline(applyID, entityID) return True
def remove_friend_offline(entityID, friendID): p = Player.simple_load(entityID, ["friendset"]) try: p.friendset.remove(friendID) recommend(entityID) except KeyError: pass p.save() return True
def get_group_member_across_region(regionID, entityID): assert regionID == settings.REGION["ID"] p = Player.simple_load(entityID, ["name", "prototypeID", "groupID"]) return { "name": p.name, "groupID": p.groupID, "regionID": regionID, "prototypeID": p.prototypeID, "entityID": entityID, }
def sync_daily_rank_offline(entityID, history=None): p = Player.simple_load(entityID, [ "daily_histories", "daily_history_flag"]) p.daily_histories.load() if p: if history: p.daily_histories.appendleft(history) p.daily_histories.ltrim(0, MAX_HIST_LEN - 1) p.daily_history_flag = True p.save()
def ranking_send_mail_offline(entityID, title, content, rewards, key, ID): p = Player.simple_load(entityID, ["rankingreceiveds"]) if p: if key in p.rankingreceiveds: return if not int( Player.pool.execute("HSET", "ranking_receiveds_p{%d}" % entityID, key, "") or 0): return send_mail(entityID, title, content, addition=rewards, configID=ID)