def create(self, name): cost = [(money_text_to_item_id('diamond'), GlobalConfig.value("UNION_CREATE_COST"))] rc = ResourceClassification.classify(cost) rc.check_exist(self.server_id, self.char_id) doc = MongoUnion.document() doc['_id'] = make_string_id() doc['create_at'] = arrow.utcnow().timestamp doc['name'] = name doc['owner'] = self.char_id try: MongoUnion.db(self.server_id).insert_one(doc) except DuplicateKeyError: raise GameException( ConfigErrorMessage.get_error_id("UNION_NAME_HAS_TAKEN")) MongoUnionMember.db(self.server_id).update_one({'_id': self.char_id}, { '$set': { 'joined': doc['_id'], 'joined_at': arrow.utcnow().timestamp } }) rc.remove(self.server_id, self.char_id, message="Union.create") Union(self.server_id, self.char_id).send_all_notify()
def got_plundered(self, from_id, win_ways): config = ConfigPlunderIncome.get(win_ways) if win_ways > 0: revenge_item = (make_string_id(), from_id) self.doc['loss_percent'] += config.percent if self.doc['loss_percent'] > PLUNDER_MAX_LOST: self.doc['loss_percent'] = PLUNDER_MAX_LOST self.doc['revenge_list'].append(revenge_item) while len(self.doc['revenge_list']) > 20: self.doc['revenge_list'].pop(0) MongoPlunder.db(self.server_id).update_one({'_id': self.char_id}, { '$set': { 'loss_percent': self.doc['loss_percent'], 'revenge_list': self.doc['revenge_list'], } }) self.send_revenge_notify() self.send_station_notify() config_station = ConfigBaseStationLevel.get(self.doc['product_level']) return config_station.get_product(config.percent)
def got_plundered(self, from_id, win_ways): config = ConfigPlunderIncome.get(win_ways) if win_ways > 0: revenge_item = (make_string_id(), from_id) self.doc['loss_percent'] += config.percent if self.doc['loss_percent'] > PLUNDER_MAX_LOST: self.doc['loss_percent'] = PLUNDER_MAX_LOST self.doc['revenge_list'].append(revenge_item) while len(self.doc['revenge_list']) > 20: self.doc['revenge_list'].pop(0) MongoPlunder.db(self.server_id).update_one( {'_id': self.char_id}, {'$set': { 'loss_percent': self.doc['loss_percent'], 'revenge_list': self.doc['revenge_list'], }} ) self.send_revenge_notify() self.send_station_notify() config_station = ConfigBaseStationLevel.get(self.doc['product_level']) return config_station.get_product(config.percent)
def add(self, staff_original_id, send_notify=True, trig_signal=True): if not ConfigStaffNew.get(staff_original_id): raise GameException( ConfigErrorMessage.get_error_id("STAFF_NOT_EXIST")) unique_id = make_string_id() doc = MongoStaff.document_staff() doc['oid'] = staff_original_id MongoStaff.db(self.server_id).update_one( {'_id': self.char_id}, {'$set': { 'staffs.{0}'.format(unique_id): doc }}, ) if send_notify: self.send_notify(ids=[unique_id]) staff_new_add_signal.send( sender=None, server_id=self.server_id, char_id=self.char_id, staffs_info=[ (staff_original_id, unique_id), ], force_load_staffs=send_notify, ) if trig_signal: self.after_staffs_change_for_trig_signal() return unique_id
def create(self, name): cost = [(money_text_to_item_id('diamond'), GlobalConfig.value("UNION_CREATE_COST"))] rc = ResourceClassification.classify(cost) rc.check_exist(self.server_id, self.char_id) doc = MongoUnion.document() doc['_id'] = make_string_id() doc['create_at'] = arrow.utcnow().timestamp doc['name'] = name doc['owner'] = self.char_id try: MongoUnion.db(self.server_id).insert_one(doc) except DuplicateKeyError: raise GameException(ConfigErrorMessage.get_error_id("UNION_NAME_HAS_TAKEN")) MongoUnionMember.db(self.server_id).update_one( {'_id': self.char_id}, {'$set': { 'joined': doc['_id'], 'joined_at': arrow.utcnow().timestamp }} ) rc.remove(self.server_id, self.char_id, message="Union.create") Union(self.server_id, self.char_id).send_all_notify()
def _add(self, tp, args): doc = MongoNotification.db(self.server_id).find_one( {'_id': self.char_id}, {'notis': 1}) notis = [(k, v['tp'], v['args'], v['timestamp']) for k, v in doc['notis'].iteritems()] notis.sort(key=lambda item: item[3]) remove_ids = [] while len(notis) > NOTIFICATION_MAX_AMOUNT - 1: x = notis.pop(0) remove_ids.append(x[0]) noti_id = make_string_id() data = MongoNotification.document_notification() data['tp'] = tp data['args'] = args data['timestamp'] = arrow.utcnow().timestamp data['opened'] = False updater = {'$set': {'notis.{0}'.format(noti_id): data}} if remove_ids: updater['$unset'] = {'notis.{0}'.format(i): 1 for i in remove_ids} notify = NotificationRemoveNotify() notify.ids.extend(remove_ids) MessagePipe(self.char_id).put(msg=notify) MongoNotification.db(self.server_id).update_one({'_id': self.char_id}, updater) self.send_notify([noti_id]) return noti_id
def try_create_arena_npc(cls, server_id): if MongoArena.db(server_id).count(): return with ArenaLock(server_id, None).lock(hold_seconds=20): # 这里要进行double-check # 考虑这种情况: # 有两个并发的 try_create_arena_npc 调用 # A先进入,B稍晚进入 # B 首先判断到 MongoArena 没有记录 # 然后等待锁, 此时A已经获取了锁,并且最终填充完数据后,B获得锁 # 此时B必须再进行一次检查,否则B就会生成多余数据 # double-check 在 多线程的 单例模式 中,也是必备 if MongoArena.db(server_id).count(): return npcs = [] for _K, v in ConfigArenaNPC.INSTANCES.iteritems(): for _ in range(v.amount): npc_id = random.choice(v.npcs) _id = "npc:{0}:{1}".format(npc_id, make_string_id()) doc = MongoArena.document() doc['_id'] = _id doc['search_index'] = ConfigArenaSearchRange.START_INDEX npcs.append(doc) score = random.randint(v.score_low, v.score_high) ArenaScore(server_id, _id).set_score(score) MongoArena.db(server_id).insert_many(npcs)
def add(self, staff_original_id, send_notify=True, trig_signal=True): if not ConfigStaffNew.get(staff_original_id): raise GameException(ConfigErrorMessage.get_error_id("STAFF_NOT_EXIST")) unique_id = make_string_id() doc = MongoStaff.document_staff() doc['oid'] = staff_original_id MongoStaff.db(self.server_id).update_one( {'_id': self.char_id}, {'$set': {'staffs.{0}'.format(unique_id): doc}}, ) if send_notify: self.send_notify(ids=[unique_id]) staff_new_add_signal.send( sender=None, server_id=self.server_id, char_id=self.char_id, staffs_info=[(staff_original_id, unique_id), ], force_load_staffs=send_notify, ) if trig_signal: self.after_staffs_change_for_trig_signal() return unique_id
def _add(self, tp, args): doc = MongoNotification.db(self.server_id).find_one({'_id': self.char_id}, {'notis': 1}) notis = [(k, v['tp'], v['args'], v['timestamp']) for k, v in doc['notis'].iteritems()] notis.sort(key=lambda item: item[3]) remove_ids = [] while len(notis) > NOTIFICATION_MAX_AMOUNT - 1: x = notis.pop(0) remove_ids.append(x[0]) noti_id = make_string_id() data = MongoNotification.document_notification() data['tp'] = tp data['args'] = args data['timestamp'] = arrow.utcnow().timestamp data['opened'] = False updater = {'$set': { 'notis.{0}'.format(noti_id): data }} if remove_ids: updater['$unset'] = {'notis.{0}'.format(i): 1 for i in remove_ids} notify = NotificationRemoveNotify() notify.ids.extend(remove_ids) MessagePipe(self.char_id).put(msg=notify) MongoNotification.db(self.server_id).update_one( {'_id': self.char_id}, updater ) self.send_notify([noti_id]) return noti_id
def send_reward(self, goods_id): if goods_id == YUEKA_ID: # 月卡买了就立即发送 # 后面的再定时发送 config = ConfigPurchaseYueka.get(YUEKA_ID) got = 0 actual_got = 0 MongoPurchase.db(self.server_id).update_one( {'_id': self.char_id}, {'$set': { 'yueka_remained_days': 29, 'yueka_new': True }} ) self.doc['yueka_remained_days'] = 29 self.doc['yueka_new'] = True rc = ResourceClassification.classify(config.rewards) attachment = rc.to_json() m = MailManager(self.server_id, self.char_id) m.add(config.mail_title, config.mail_content, attachment=attachment) else: config = ConfigPurchaseGoods.get(goods_id) got = config.diamond actual_got = config.diamond + config.diamond_extra if self.get_purchase_times() == 0: # 首充 actual_got = config.diamond * 2 + config.diamond_extra doc = MongoPurchaseLog.document() doc['_id'] = make_string_id() doc['char_id'] = self.char_id doc['goods_id'] = goods_id doc['got'] = got doc['actual_got'] = actual_got doc['timestamp'] = arrow.utcnow().timestamp MongoPurchaseLog.db(self.server_id).insert_one(doc) reward = [ (VIP_EXP_ITEM_ID, config.vip_exp), (money_text_to_item_id('diamond'), actual_got) ] rc = ResourceClassification.classify(reward) rc.add(self.server_id, self.char_id, message="Purchase.send_reward:{0}".format(goods_id)) purchase_done_signal.send( sender=None, server_id=self.server_id, char_id=self.char_id, goods_id=goods_id, got=got, actual_got=actual_got, ) self.send_notify()
def _make_doc(cls, id_one, id_two, club_match, record=''): doc = MongoMatchRecord.document() doc['_id'] = make_string_id() doc['id_one'] = id_one doc['id_two'] = id_two doc['club_match'] = base64.b64encode(club_match) doc['record'] = base64.b64encode(record) doc['create_at'] = arrow.utcnow().timestamp return doc
def _do_error_record(_status): ModelPurchaseIOS.objects.create(id=make_string_id(), transaction_id='', product_id='', quantity=0, status=_status, environment='', application_version='', receipt_data=param)
def to_simple_doc(self): from utils.functional import make_string_id from config import ConfigName from config import ConfigClubFlag return { 'id': 'npc:{0}'.format(make_string_id()), 'name': ConfigName.get_random_name(), 'flag': ConfigClubFlag.get_random_flag_id(), 'ways_npc': self.get_way_info() }
def _do_error_record(_status): ModelPurchaseIOS.objects.create( id=make_string_id(), transaction_id='', product_id='', quantity=0, status=_status, environment='', application_version='', receipt_data=param )
def add_equipment(self, item_id, level, amount): new_state = [] for i in range(amount): slot_id = make_string_id() data = { 'item_id': item_id, 'level': level, } new_state.append((slot_id, data)) return new_state
def add_stack_item(self, item_id, amount): stack_max = ConfigItemNew.get(item_id).stack_max new_state = [] # 先尝试把物品往现有的格子中放 remained_amount = amount for k, v in self.doc['slots'].iteritems(): if not remained_amount: break if v['item_id'] != item_id: continue empty_space = stack_max - v['amount'] if empty_space >= remained_amount: # 这个位置还是可以把这些amount全部装下的 state = { 'item_id': item_id, 'amount': v['amount'] + remained_amount } remained_amount = 0 else: state = { 'item_id': item_id, 'amount': stack_max } remained_amount -= empty_space new_state.append((k, state)) # 把有物品的格子都跑了一遍还是有剩余的数量 # TODO 格子总量 while remained_amount: slot_id = make_string_id() if remained_amount <= stack_max: state = { 'item_id': item_id, 'amount': remained_amount } remained_amount = 0 else: state = { 'item_id': item_id, 'amount': stack_max } remained_amount -= stack_max new_state.append((slot_id, state)) return new_state
def post(self, content): from core.club import get_club_property if self.CD(self.server_id, self.char_id).get_cd_seconds(): raise GameException(ConfigErrorMessage.get_error_id("CHAT_TOO_FAST")) if len(content) > 300: raise GameException(ConfigErrorMessage.get_error_id("CHAT_TOO_LARGE")) try: with self.LOCK(self.server_id, self.char_id).lock(3, 3): now = arrow.utcnow().timestamp message = { 'msg_id': make_string_id(), 'club_id': str(self.char_id), 'name': get_club_property(self.server_id, self.char_id, 'name'), 'content': content, 'post_at': now, 'approval': 0, 'last_update_at': now, } _data = self.make_notify_data(message=message) self.broadcast(_data) self.doc['value'].insert(0, message) if len(self.doc['value']) > 100: self.doc['value'].sort(key=lambda item: -item['last_update_at']) removed = self.doc['value'].pop(-1) remove_notify = self.REMOVE_NOTIFY() remove_notify.msg_id = removed['msg_id'] WinningChatApprovalMark(self.server_id, self.char_id, removed['msg_id']).delete() self.broadcast(MessageFactory.pack(remove_notify)) MongoCommon.db(self.server_id).update_one( {'_id': self.get_id()}, {'$set': { 'value': self.doc['value'] }} ) except LockTimeOut: raise GameException(ConfigErrorMessage.get_error_id("SERVER_BUSY")) self.CD(self.server_id, self.char_id).set(GlobalConfig.value("LEADERBOARD_CHAT_INTERVAL"))
def record(self, sub_id=None, value=1): doc = MongoTimesLog.document() doc['_id'] = make_string_id() doc['key'] = self.make_key(sub_id=sub_id) doc['timestamp'] = arrow.utcnow().timestamp doc['value'] = value MongoTimesLog.db(self.server_id).insert_one(doc) # task trig condition_name = 'core.value_log.{0}'.format(self.__class__.__name__) task_condition_trig_signal.send(sender=None, server_id=self.server_id, char_id=self.char_id, condition_name=condition_name)
def record(self, action, ret): now = arrow.utcnow() end_ms = now.timestamp * 1000 + now.microsecond / 1000 cost = end_ms - self.start_ms doc = MongoOperationLog.document() doc['_id'] = make_string_id() doc['char_id'] = self.char_id doc['action'] = action doc['ret'] = ret doc['timestamp'] = self.start_timestamp doc['cost_millisecond'] = cost MongoOperationLog.db(self.server_id).insert_one(doc)
def record(self, platform, goods_id, amount=1): _id = make_string_id() fee = get_fee(goods_id) * amount ModelPurchase.objects.create( id=_id, server_id=self.server_id, char_id=self.char_id, goods_id=goods_id, platform=platform, fee=fee, verified=False, ) return _id
def add_equipment_object(self, equip): """ :type equip: Equipment """ slot_id = make_string_id() data = equip.to_doc() self.doc['slots'][slot_id] = data MongoBag.db(self.server_id).update_one( {'_id': self.char_id}, {'$set': { 'slots.{0}'.format(slot_id): data }} ) self.send_notify(slot_ids=[slot_id])
def record(self, sub_id=None, value=1): doc = MongoTimesLog.document() doc['_id'] = make_string_id() doc['key'] = self.make_key(sub_id=sub_id) doc['timestamp'] = arrow.utcnow().timestamp doc['value'] = value MongoTimesLog.db(self.server_id).insert_one(doc) # task trig condition_name = 'core.value_log.{0}'.format(self.__class__.__name__) task_condition_trig_signal.send( sender=None, server_id=self.server_id, char_id=self.char_id, condition_name=condition_name )
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 set_login(self): from django.db.models import F from apps.character.models import Character as ModelCharacter now = arrow.utcnow() ModelCharacter.objects.filter(id=self.char_id).update( last_login=now.format("YYYY-MM-DD HH:mm:ssZ"), login_times=F('login_times') + 1, ) MongoCharacter.db(self.server_id).update_one( {'_id': self.char_id}, {'$set': {'last_login': now.timestamp}} ) login_doc = MongoCharacterLoginLog.document() login_doc['_id'] = make_string_id() login_doc['char_id'] = self.char_id login_doc['timestamp'] = now.timestamp MongoCharacterLoginLog.db(self.server_id).insert_one(login_doc)
def batch_add(self, staffs): # [(oid, amount), ...] updater = {} unique_id_list = [] info = [] for oid, amount in staffs: if not ConfigStaffNew.get(oid): raise GameException(ConfigErrorMessage.get_error_id("STAFF_NOT_EXIST")) for i in range(amount): unique_id = make_string_id() doc = MongoStaff.document_staff() doc['oid'] = oid unique_id_list.append(unique_id) updater['staffs.{0}'.format(unique_id)] = doc info.append((oid, unique_id)) MongoStaff.db(self.server_id).update_one( {'_id': self.char_id}, {'$set': updater} ) self.send_notify(ids=unique_id_list) staff_new_add_signal.send( sender=None, server_id=self.server_id, char_id=self.char_id, staffs_info=info, force_load_staffs=True, ) self.after_staffs_change_for_trig_signal()
def add(self, title, content, attachment="", create_at=None, from_id=0, function=0, unique_id='', send_notify=True): if create_at: now = arrow.get(create_at) else: now = arrow.utcnow() doc = MongoMail.document_mail() doc['from_id'] = from_id doc['title'] = title doc['content'] = content doc['attachment'] = attachment doc['create_at'] = now.timestamp doc['function'] = function doc['unique_id'] = unique_id # doc['data'] = base64.b64encode(data) mail_id = make_string_id() MongoMail.db(self.server_id).update_one( {'_id': self.char_id}, {'$set': {'mails.{0}'.format(mail_id): doc}} ) MailHistoryRecord.create( _id=mail_id, from_id=from_id, to_id=self.char_id, title=title, content=content, attachment=attachment, function=function, create_at=now.format("YYYY-MM-DD HH:mm:ssZ") ) if send_notify: self.send_notify(ids=[mail_id])
def batch_add(self, staffs): # [(oid, amount), ...] updater = {} unique_id_list = [] info = [] for oid, amount in staffs: if not ConfigStaffNew.get(oid): raise GameException( ConfigErrorMessage.get_error_id("STAFF_NOT_EXIST")) for i in range(amount): unique_id = make_string_id() doc = MongoStaff.document_staff() doc['oid'] = oid unique_id_list.append(unique_id) updater['staffs.{0}'.format(unique_id)] = doc info.append((oid, unique_id)) MongoStaff.db(self.server_id).update_one({'_id': self.char_id}, {'$set': updater}) self.send_notify(ids=unique_id_list) staff_new_add_signal.send( sender=None, server_id=self.server_id, char_id=self.char_id, staffs_info=info, force_load_staffs=True, ) self.after_staffs_change_for_trig_signal()
def new(cls, server_id): obj = cls(server_id) obj.group_id = make_string_id() return obj
def __init__(self, _id): super(ChallengeNPCStaff, self).__init__() self.id = make_string_id() self.oid = _id self.after_init()
def send_reward(self, goods_id): if goods_id == YUEKA_ID: # 月卡买了就立即发送 # 后面的再定时发送 config = ConfigPurchaseYueka.get(YUEKA_ID) got = 0 actual_got = 0 MongoPurchase.db(self.server_id).update_one( {'_id': self.char_id}, {'$set': { 'yueka_remained_days': 29, 'yueka_new': True }}) self.doc['yueka_remained_days'] = 29 self.doc['yueka_new'] = True rc = ResourceClassification.classify(config.rewards) attachment = rc.to_json() m = MailManager(self.server_id, self.char_id) m.add(config.mail_title, config.mail_content, attachment=attachment) else: config = ConfigPurchaseGoods.get(goods_id) got = config.diamond actual_got = config.diamond + config.diamond_extra if self.get_purchase_times() == 0: # 首充 actual_got = config.diamond * 2 + config.diamond_extra doc = MongoPurchaseLog.document() doc['_id'] = make_string_id() doc['char_id'] = self.char_id doc['goods_id'] = goods_id doc['got'] = got doc['actual_got'] = actual_got doc['timestamp'] = arrow.utcnow().timestamp MongoPurchaseLog.db(self.server_id).insert_one(doc) reward = [(VIP_EXP_ITEM_ID, config.vip_exp), (money_text_to_item_id('diamond'), actual_got)] rc = ResourceClassification.classify(reward) rc.add(self.server_id, self.char_id, message="Purchase.send_reward:{0}".format(goods_id)) purchase_done_signal.send( sender=None, server_id=self.server_id, char_id=self.char_id, goods_id=goods_id, got=got, actual_got=actual_got, ) self.send_notify()
def __init__(self, _id): super(_Staff, self).__init__() from utils.functional import make_string_id self.id = make_string_id() self.oid = _id self.after_init()