def clean_operation_log(*args): logger = Logger('clean_operation_log') logger.write("Start") try: for sid in Server.duty_server_ids(): OperationLog.clean(sid) logger.write("Server {0} Done.".format(sid)) except: logger.error(traceback.format_exc()) else: logger.write("Done") finally: logger.close()
def send_notify(self, ids=None): notify = FriendNotify() if ids: projection = {"friends.{0}".format(_id): 1 for _id in ids} act = ACT_UPDATE else: projection = {"friends": 1} act = ACT_INIT notify.act = act notify.max_amount = MAX_FRIEND_AMOUNT doc = MongoFriend.db(self.server_id).find_one({'_id': self.char_id}, projection) friend_ids = [int(i) for i in doc['friends'].keys()] online_char_ids = OperationLog.get_recent_action_char_ids(self.server_id) for f in friend_ids: notify_friend = notify.friends.add() notify_friend.status = FRIEND_STATUS_TABLE[doc['friends'][str(f)]] friend_club = Club(self.server_id, f) notify_friend.club.MergeFrom(friend_club.make_protomsg()) notify_friend.online = f in online_char_ids MessagePipe(self.char_id).put(msg=notify)
def send_notify(self, ids=None): notify = FriendNotify() if ids: projection = {"friends.{0}".format(_id): 1 for _id in ids} act = ACT_UPDATE else: projection = {"friends": 1} act = ACT_INIT notify.act = act notify.max_amount = MAX_FRIEND_AMOUNT doc = MongoFriend.db(self.server_id).find_one({'_id': self.char_id}, projection) friend_ids = [int(i) for i in doc['friends'].keys()] online_char_ids = OperationLog.get_recent_action_char_ids( self.server_id) for f in friend_ids: notify_friend = notify.friends.add() notify_friend.status = FRIEND_STATUS_TABLE[doc['friends'][str(f)]] friend_club = Club(self.server_id, f) notify_friend.club.MergeFrom(friend_club.make_protomsg()) notify_friend.online = f in online_char_ids MessagePipe(self.char_id).put(msg=notify)
def job_of_energy_notification(cls): # 找最近登陆的,并且在多少时间内没操作的(认为已经下线了 connection.close() account_ids = AccountLoginLog.get_recent_login_account_ids(2) action_limit = arrow.utcnow().timestamp - 60 * 30 count = 0 for account_id, server_id in account_ids.iteritems(): try: model_char = ModelCharacter.objects.get(Q(account_id=account_id) & Q(server_id=server_id)) except ModelCharacter.DoesNotExist: continue char_id = model_char.id if OperationLog.get_char_last_action_at(server_id, char_id) > action_limit: continue if not Energy(server_id, char_id).is_full(): continue title = u"体力满了" content = u"您在 {0} 服的角色 {1} 体力满了,赶快上线吧".format(server_id, model_char.name) pushed = GeTui(account_id).push_of_energy(title, content) if pushed: count += 1 return count
def broadcast(self, data): char_ids = OperationLog.get_recent_action_char_ids(self.server_id, recent_minutes=5) if self.char_id not in char_ids: char_ids.append(self.char_id) for _id in char_ids: MessagePipe(_id).put(data=data)
def job_of_energy_notification(cls): # 找最近登陆的,并且在多少时间内没操作的(认为已经下线了 connection.close() account_ids = AccountLoginLog.get_recent_login_account_ids(2) action_limit = arrow.utcnow().timestamp - 60 * 30 count = 0 for account_id, server_id in account_ids.iteritems(): try: model_char = ModelCharacter.objects.get( Q(account_id=account_id) & Q(server_id=server_id)) except ModelCharacter.DoesNotExist: continue char_id = model_char.id if OperationLog.get_char_last_action_at(server_id, char_id) > action_limit: continue if not Energy(server_id, char_id).is_full(): continue title = u"体力满了" content = u"您在 {0} 服的角色 {1} 体力满了,赶快上线吧".format( server_id, model_char.name) pushed = GeTui(account_id).push_of_energy(title, content) if pushed: count += 1 return count
def __call__(self, request): if not request.path.startswith('/game/'): return self.get_response(request) if request.method != 'POST': return HttpResponse(status=403) try: session, proto = self.parse_request_message(request.path, request.body) except: print "==== ERROR ====" traceback.print_exc() return HttpResponse(status=403) request._game_session = session request._proto = proto if not session.char_id: request._operation_log = None else: request._operation_log = OperationLog(session.server_id, session.char_id) print proto print session.kwargs return self.get_response(request)
def totally_reset(server_id, send_notify=False): MongoChampionship.db(server_id).update_many( {}, {'$set': { 'applied': False, 'bet': {}, 'has_bet': False, }}) MongoChampionshipGroup.db(server_id).drop() MongoChampionshipLevel.db(server_id).drop() if send_notify: basic_notify = make_common_basic_notify_msg(server_id) basic_data = MessageFactory.pack(basic_notify) group_notify = make_empty_group_notify_msg() group_data = MessageFactory.pack(group_notify) level_notify = ChampionshipLevel(server_id).make_protomsg() level_data = MessageFactory.pack(level_notify) char_ids = OperationLog.get_recent_action_char_ids(server_id) for cid in char_ids: mp = MessagePipe(cid) mp.put(data=basic_data) mp.put(data=group_data) mp.put(data=level_data)
def set_to_common(self, msg): data = msg.SerializeToString() value = base64.b64encode(data) self.COMMON(self.server_id).set(value) for _cid in OperationLog.get_recent_action_char_ids(self.server_id, recent_minutes=5): MessagePipe(_cid).put(data=data)
def broadcast(args): try: payload = cPickle.loads(args['payload']) server_id = payload['server_id'] exclude_chars = payload['exclude_chars'] data = payload['data'] except: traceback.print_exc() return char_ids = OperationLog.get_recent_action_char_ids(server_id) for cid in char_ids: if cid not in exclude_chars: MessagePipe(cid).put(data=data)
def get_candidates(request): server_id = request._game_session.server_id char_id = request._game_session.char_id fm = FriendManager(server_id, char_id) candidates = fm.get_candidates() response = FriendCandidatesResponse() response.ret = 0 online_char_ids = OperationLog.get_recent_action_char_ids(server_id) for c in candidates: response_friend = response.friends.add() response_friend.status = FRIEND_NOT response_friend.online = c in online_char_ids response_friend.club.MergeFrom(Club(server_id, c).make_protomsg()) return ProtobufResponse(response)
def clean_talent_id(cls, server_id): # 把最近在线的人选出来, 要发送通知, 其他的直接清理 char_ids = OperationLog.get_recent_action_char_ids(server_id) condition = {'$and': [ {'_id': {'$in': char_ids}}, {'talent_id': {'$gt': 0}} ]} docs = MongoParty.db(server_id).find(condition) MongoParty.db(server_id).update_many( {}, {'$set': {'talent_id': 0}} ) for doc in docs: # 天赋过期,删除加成 Club(server_id, doc['_id']).force_load_staffs(send_notify=True)
def before_apply(server_id): MongoChampionshipLevel.db(server_id).drop() MongoChampionship.db(server_id).update_many( {}, {'$set': { 'bet': {}, 'has_bet': False }}) basic_notify = make_common_basic_notify_msg(server_id) basic_data = MessageFactory.pack(basic_notify) level_notify = ChampionshipLevel(server_id).make_protomsg() level_data = MessageFactory.pack(level_notify) char_ids = OperationLog.get_recent_action_char_ids(server_id) for cid in char_ids: mp = MessagePipe(cid) mp.put(data=basic_data) mp.put(data=level_data)
def add(self, for_char_ids, title, content, attachment="", from_id=0, function=0): doc = MongoMail.document_mail() doc['_id'] = make_string_id() doc['for_char_ids'] = for_char_ids doc['from_id'] = from_id doc['title'] = title doc['content'] = content doc['attachment'] = attachment doc['create_at'] = arrow.utcnow().timestamp doc['function'] = function MongoSharedMail.db(self.server_id).insert_one(doc) # 立即给最近登陆操作的人发送通知 recent_char_ids = OperationLog.get_recent_action_char_ids(self.server_id, recent_minutes=30) for cid in recent_char_ids: if cid in for_char_ids: MailManager(self.server_id, cid).send_notify()
def cronjob(cls, sid): from core.club import Club from core.plunder import Plunder notify = cls.NOTIFY() notify.session = "" docs = cls.MONGO_DOCUMENT.db(sid).find({ 'winning': { '$gt': 0 } }).sort('winning', -1).limit(3) if docs.count() == 0: data = notify.SerializeToString() value = None else: for doc in docs: msg_club = Club(sid, doc['_id']).make_protomsg() _plunder = Plunder(sid, doc['_id']) notify_club = notify.clubs.add() notify_club.club.MergeFrom(msg_club) notify_club.point = doc['winning'] for _way_id in [1, 2, 3]: notify_club_formation = notify_club.formation.add() notify_club_formation.MergeFrom( _plunder.get_way_object(_way_id).make_protobuf()) data = notify.SerializeToString() value = base64.b64encode(data) cls.COMMON(sid).set(value) cls.MONGO_DOCUMENT.db(sid).drop() for _cid in OperationLog.get_recent_action_char_ids(sid, recent_minutes=5): MessagePipe(_cid).put(data=data)
def clean_talent_id(cls, server_id): # 把最近在线的人选出来, 要发送通知, 其他的直接清理 char_ids = OperationLog.get_recent_action_char_ids(server_id) condition = { '$and': [{ '_id': { '$in': char_ids } }, { 'talent_id': { '$gt': 0 } }] } docs = MongoParty.db(server_id).find(condition) MongoParty.db(server_id).update_many({}, {'$set': {'talent_id': 0}}) for doc in docs: # 天赋过期,删除加成 Club(server_id, doc['_id']).force_load_staffs(send_notify=True)
def cronjob(cls, sid): from core.club import Club from core.formation import Formation notify = cls.NOTIFY() notify.session = "" docs = cls.MONGO_DOCUMENT.db(sid).find({ 'winning': { '$gt': 0 } }).sort('winning', -1).limit(10) if docs.count() == 0: data = notify.SerializeToString() value = None else: for doc in docs: msg_club = Club(sid, doc['_id']).make_protomsg() msg_slots = Formation(sid, doc['_id']).make_slot_msg() notify_club = notify.clubs.add() notify_club.club.MergeFrom(msg_club) notify_club.point = doc['winning'] for _slot in msg_slots: notify_club_slot = notify_club.slots.add() notify_club_slot.MergeFrom(_slot) data = notify.SerializeToString() value = base64.b64encode(data) cls.COMMON(sid).set(value) cls.MONGO_DOCUMENT.db(sid).drop() for _cid in OperationLog.get_recent_action_char_ids(sid, recent_minutes=5): MessagePipe(_cid).put(data=data)
def start_match(cls, server_id): groups = cls.find_all_groups(server_id) if not groups: return 0 match_times = 0 for g in groups: match_times = g.start_match() if match_times == 7: # 小组赛打完了 # 其实这个drop没必要,不过以防万一 MongoChampionshipLevel.db(server_id).drop() cl = ChampionshipLevel(server_id) cl.initialize() level_notify = cl.make_protomsg() level_data = MessageFactory.pack(level_notify) char_ids = OperationLog.get_recent_action_char_ids(server_id) for cid in char_ids: MessagePipe(cid).put(data=level_data) return match_times - 1
def assign_to_groups(cls, server_id, club_ids): club_amount = len(club_ids) if club_amount < 32: need_npc_amount = 32 - club_amount else: if club_amount % 2 == 0: need_npc_amount = 0 else: need_npc_amount = 1 info = {} if club_ids: club_docs = MongoCharacter.db(server_id).find( {'_id': { '$in': club_ids }}, { 'name': 1, 'flag': 1 }) club_info = {doc['_id']: doc for doc in club_docs} for i in club_ids: info[str(i)] = { 'name': club_info[i]['name'], 'flag': club_info[i]['flag'], } for i in range(need_npc_amount): npc_doc = ConfigPlunderNPC.get(2).to_simple_doc() npc_id = npc_doc.pop('id') info[npc_id] = npc_doc ids = info.keys() random.shuffle(ids) # 把这些ids 随机分配到8个 group 中 groups = [] """:type: list[ChampionshipGroup]""" for i in range(8): g = ChampionshipGroup.new(server_id) groups.append(g) g_index = 0 while True: try: _id = ids.pop(0) except IndexError: break groups[g_index].add_club(_id, info[_id]) g_index += 1 if g_index >= 8: g_index = 0 for g in groups: g.finish() char_ids = OperationLog.get_recent_action_char_ids(server_id) for cid in char_ids: g = ChampionshipGroup(server_id) g.find_by_char_id(cid) msg = g.make_protomsg() MessagePipe(cid).put(msg=msg)
def after_final_match(self): # 已经打完了,但还要得出第三四名,并记录前四名 level_4_member_ids = self.doc['levels']['4']['member_ids'][:] level_2_member_ids = self.doc['levels']['2']['member_ids'][:] for i in level_2_member_ids: level_4_member_ids.remove(i) id_one = level_4_member_ids[0] id_two = level_4_member_ids[1] info_one = self.doc['info'][id_one] info_two = self.doc['info'][id_two] m = Match(self.server_id, id_one, info_one, id_two, info_two) one_way_wins, one_record_ids = m.start() # two_way_wins = [1 - _w for _w in one_way_wins] one_way_wins_count = len([_w for _w in one_way_wins if _w == 1]) if one_way_wins_count >= 2: third = id_one fourth = id_two else: third = id_two fourth = id_one first = self.doc['levels']['1']['member_ids'][0] level_2_member_ids.remove(first) second = level_2_member_ids[0] first_info = self.doc['info'][first] second_info = self.doc['info'][second] third_info = self.doc['info'][third] fourth_info = self.doc['info'][fourth] MongoChampionHistory.db(self.server_id).drop() history_doc = MongoChampionHistory.document() history_doc['member_ids'] = [first, second, third, fourth] history_doc['info'] = { first: first_info, second: second_info, third: third_info, fourth: fourth_info, } MongoChampionHistory.db(self.server_id).insert_one(history_doc) # 清空小组赛 MongoChampionshipGroup.db(self.server_id).drop() group_notify = make_empty_group_notify_msg() group_data = MessageFactory.pack(group_notify) # 清空玩家的报名标识 MongoChampionship.db(self.server_id).update_many( {}, {'$set': { 'applied': False }}) char_ids = OperationLog.get_recent_action_char_ids(self.server_id) basic_notify = make_common_basic_notify_msg(self.server_id) for _cid in char_ids: MessagePipe(_cid).put(data=group_data) Championship(self.server_id, _cid).send_basic_notify(basic_notify=basic_notify) # 设置winning winning_notify = LeaderboardChampionshipNotify() winning_notify.session = "" for __id, __info in [(first, first_info), (second, second_info), (third, third_info)]: __match = Match(self.server_id, None, None, None, None) __clubs, __skill_sequence = __match.make_3_way_clubs(__id, __info) winning_notify_club = winning_notify.clubs.add() winning_notify_club.club.MergeFrom(__clubs[0].make_protomsg()) for __way_id in [1, 2, 3]: winning_notify_club_formation = winning_notify_club.formation.add( ) winning_notify_club_formation.MergeFrom( make_plunder_formation_msg(__clubs[__way_id - 1], __way_id)) WinningChampionship(self.server_id, None).set_to_common(winning_notify)