#!/usr/bin/python # -*- coding: GBK -*- """ ¿Í»§¶Ë¹ÜÀíÆ÷ ÓÃÓÚ¹ÜÀí¿Í»§¶ËÁ¬½Ó״̬ºÍµÇ¼״̬ """ import threading from protocol import LOGIN_MAGIC_CODE from packet_logger import packet_logger # ¿Í»§¶Ë״̬¶¨Òå CLIENT_STATUS_NOT_CONNECT = 0 CLIENT_STATUS_NOT_LOGIN = 1 CLIENT_STATUS_LOGIN = 2 class ClientsMgr: """¿Í»§¶Ë¹ÜÀíÆ÷µ¥ÀýÀà""" _instance = None _lock = threading.Lock() def __new__(cls): if cls._instance is None: with cls._lock: if cls._instance is None: cls._instance = super(ClientsMgr, cls).__new__(cls) cls._instance._initialized = False return cls._instance @classmethod def instance(cls): """»ñÈ¡µ¥ÀýʵÀý""" if cls._instance is None: cls._instance = cls() return cls._instance def __init__(self): if getattr(self, '_initialized', False): return self._initialized = True self.status_map = {} # cid -> status self.server_id_map = {} # cid -> server_id self.map_lock = threading.Lock() def set_client_status(self, cid, status): """ÉèÖÿͻ§¶Ë״̬""" with self.map_lock: self.status_map[cid] = status def get_client_status(self, cid): """»ñÈ¡¿Í»§¶Ë״̬""" with self.map_lock: return self.status_map.get(cid, CLIENT_STATUS_NOT_CONNECT) def set_client_server_id(self, cid, server_id): """ÉèÖÿͻ§¶Ë¶ÔÓ¦µÄServer ID""" with self.map_lock: self.server_id_map[cid] = server_id def get_client_server_id(self, cid): """»ñÈ¡¿Í»§¶Ë¶ÔÓ¦µÄServer ID""" with self.map_lock: return self.server_id_map.get(cid, 0) def del_client_cache(self, cid): """ɾ³ý¿Í»§¶Ë»º´æÊý¾Ý""" with self.map_lock: if cid in self.status_map: del self.status_map[cid] if cid in self.server_id_map: del self.server_id_map[cid] def on_client_disconnect(self, cid): """¿Í»§¶Ë¶Ï¿ªÁ¬½Óʱµ÷ÓÃ""" self.del_client_cache(cid) def get_logged_in_clients(self): """»ñÈ¡ËùÓÐÒѵǼµÄ¿Í»§¶ËIDÁбí""" with self.map_lock: return [cid for cid, status in self.status_map.items() if status == CLIENT_STATUS_LOGIN] def clear(self): """Çå¿ÕËùÓпͻ§¶ËÊý¾Ý""" with self.map_lock: self.status_map.clear() self.server_id_map.clear() def handle_login(cid, packet): """´¦Àí¿Í»§¶ËµÇ¼ÇëÇó""" clients_mgr = ClientsMgr.instance() if packet.magic_code != LOGIN_MAGIC_CODE: packet_logger.log_text('Invalid magic code from client %d, expected 0x%08X, got 0x%08X' % (cid, LOGIN_MAGIC_CODE, packet.magic_code), 'ERROR') return False clients_mgr.set_client_server_id(cid, packet.server_id) clients_mgr.set_client_status(cid, CLIENT_STATUS_LOGIN) packet_logger.log_text('Client %d logged in - Server: %d' % (cid, packet.server_id), 'INFO') return True def handle_logout(cid, packet): """´¦Àí¿Í»§¶ËµÇ³öÇëÇó""" clients_mgr = ClientsMgr.instance() clients_mgr.on_client_disconnect(cid) packet_logger.log_text('Client %d logged out' % cid, 'INFO') def handle_heartbeat(cid, packet): """´¦Àí¿Í»§¶ËÐÄÌø°ü""" clients_mgr = ClientsMgr.instance() status = clients_mgr.get_client_status(cid) if status == CLIENT_STATUS_LOGIN: # ÒѵǼ¿Í»§¶ËµÄÐÄÌø´¦Àí£¬¿ÉÒÔÀ©Õ¹ pass else: # δµÇ¼¿Í»§¶ËµÄÐÄÌø´¦Àí£¬¿ÉÒÔÀ©Õ¹ pass