def __init__(self): self.socket = None self.cursor = None self.connect() self.queue = Queue() self.queue_lock = Lock() self.queue_queries = {} t = GameThread(target=self.queueworker, args=()) t.start()
def execute(self, callback, values): if callback in self.callbacks: for key, func in self.callbacks[callback].items(): t = GameThread(target=func, args=(values,)) t.daemon = True t.start() ### list of available callbacks ## player_is_spawned # When a player is definately read to spawn (e.G. after choosing class, weapon, ... and is ready to play) needed for make sure that a player choose a weapon and class before starts to play / getting attacked
def prepare_player(player): """Prepare the player.""" # Perform setting the player's spawn location on another thread spawn_location_dispatch_thread = GameThread(target=SpawnLocationDispatcher.perform_action, args=(player,)) spawn_location_dispatch_thread.start() # Set health and armor spawn values player.health = int(cvar_health_spawn) player.armor = int(cvar_armor_spawn) # Equip the player equip_player(player) # Enable spawn protection enable_damage_protection(player) # Disable spawn protection later player.delay(abs(int(cvar_spawn_protection_time)), disable_damage_protection, (player.index,))
def __init__(self, db, callbacks, downloads): self.db = db self.callbacks = callbacks self.downloads = downloads self.color_ct = Color(0, 200, 255) self.color_n = Color(255, 255, 255) self.color_t = Color(255, 0, 0) self.ranks = {} self.players = {} self.classes = {} self.weapons = {} self.skins = {} self.get_ranks() self.get_classes() self.get_weapons() self.get_skins() self.player_data_lock = Lock() self.is_round = False self.queue = Queue() t = GameThread(target=self.queueworker, args=()) t.start()
class ThreadedMySQL: def __init__(self): # Is the thread running? self.thread_status = False # Regular Queue self._r_queue = Queue() # Prioitized Queue self._p_queue = Queue() self.connection_method = 0 # Issue with print for WINDOWS user set the variable to 'echo_console' self.error_handling = 'print' # Show print messages? self._debug = True self.wait = 0 def wait(self, delay): """ If you for some reason want to delay the queue :param delay: The delay in seconds :return: """ self.wait = delay def execute(self, query, args=None, callback=None, data_pack=None, prioritize=False, get_info=False): """ This function cannot pass fetched data to the callback! :param query: The SQL query that you want to execute :param args: If the SQL query have any args :param callback: The callback for the query :param data_pack: If you want to pass special information to the callback :param prioritize: If you have large queues, prioritizing the query can make it skip the queue before the rest of the queue is finished :param get_info: If you want information about the query passed to the callback (such as timestamp, query and prioritized) :return: """ # We need this later query_type = 0 # If callback = None assuming no data returned needed if get_info: get_info = { 'query': query, 'time': timestamp(), 'prioritized': prioritize } if not prioritize: self._r_queue.put( [query, args, callback, data_pack, get_info, query_type]) else: self._p_queue.put( [query, args, callback, data_pack, get_info, query_type]) def fetchone(self, query, args=None, callback=None, data_pack=None, prioritize=False, get_info=False): """ This function both execute and fetch data, no need to execute before using this! :param query: The SQL query that you want to execute :param args: If the SQL query have any args :param callback: The callback for the query :param data_pack: If you want to pass special information to the callback :param prioritize: If you have large queues, prioritizing the query can make it skip the queue before the rest of the queue is finished :param get_info: If you want information about the query passed to the callback (such as timestamp, query and prioritized) :return: """ query_type = 1 if get_info: get_info = { 'query': query, 'time': timestamp(), 'prioritized': prioritize } # If callback = None assuming no data returned needed if not prioritize: self._r_queue.put( [query, args, callback, data_pack, get_info, query_type]) else: self._p_queue.put( [query, args, callback, data_pack, get_info, query_type]) def fetchall(self, query, args=None, callback=None, data_pack=None, prioritize=False, get_info=False): """ This function both execute and fetch data, no need to execute before using this! :param query: The SQL query that you want to execute :param args: If the SQL query have any args :param callback: The callback for the query :param data_pack: If you want to pass special information to the callback :param prioritize: If you have large queues, prioritizing the query can make it skip the queue before the rest of the queue is finished :param get_info: If you want information about the query passed to the callback (such as timestamp, query and prioritized) :return: """ query_type = 2 if get_info: get_info = { 'query': query, 'time': timestamp(), 'prioritized': prioritize } # If callback = None assuming no data returned needed if not prioritize: self._r_queue.put( [query, args, callback, data_pack, get_info, query_type]) else: self._p_queue.put( [query, args, callback, data_pack, get_info, query_type]) def complete_task(self, worker, prio=None): query = worker[0] args = worker[1] callback = worker[2] data_pack = worker[3] get_info = worker[4] query_type = worker[5] try: if get_info: get_info['time'] = timestamp() - get_info['time'] if args: self.cursor.execute(query, args) else: self.cursor.execute(query) if query_type == 0: if get_info: if callback: if data_pack: callback(data_pack, get_info) else: callback(get_info) else: if callback: if data_pack: callback(data_pack) else: callback() if query_type == 1: data = self.cursor.fetchone() if get_info: if callback: if data_pack: callback(data, data_pack, get_info) else: callback(data, get_info) else: if callback: if data_pack: callback(data, data_pack) else: callback(data) if query_type == 2: data = self.cursor.fetchall() if get_info: if callback: if data_pack: callback(data, data_pack, get_info) else: callback(data, get_info) else: if callback: if data_pack: callback(data, data_pack) else: callback(data) if prio: self._p_queue.task_done() else: self._r_queue.task_done() except Exception as SQL_ERROR: # Possible errors class_error, actual_error, traceback = exc_info() format_error = '-' * 64 + '\nExceptions probable cause (SQL Query: {0})\n{1}\nActual Error:\n{2}'.format( query, class_error, SQL_ERROR) if self.error_handling == 'print': print(format_error) print('-' * 64) else: echo_console(format_error) echo_console('-' * 64) logging_error(traceback_format_exc()) def _threader(self): while self.thread_status: if self.wait: sleep(self.wait) if self._p_queue.empty(): worker = self._r_queue.get() self.complete_task(worker, prio=False) else: worker = self._p_queue.get() self.complete_task(worker, prio=True) def _start_thread(self): # Creates the thread self.t = GameThread(target=self._threader) self.t.daemon = True self.t.start() def handlequeue_start(self): """ This handles the queue, should be stopped on unload :return: """ # Starts the queue self.thread_status = True # This must be true before the thread can loop self._start_thread() def handlequeue_stop(self): """ This stops the queue for being processed, while a connection still might be open no queries can be executed. :return: """ self.thread_status = False def queue_size(self): """ :return: Returns the size of the queue """ return self._r_queue.qsize() + self._p_queue.qsize() def connect(self, host, user, password, db, charset, cursorclass=pymysql.cursors.DictCursor): """ Checkout PyMYSQL documentation for complete walkthrough """ try: self.connection = pymysql.connect(host=host, user=user, password=password, db=db, charset=charset, cursorclass=cursorclass) self.cursor = self.connection.cursor() if self._debug: if self.error_handling == 'print': print( 'threaded_mysql: [SUCCES] connection was succesfully established.' ) else: echo_console( 'threaded_mysql: [SUCCES] connection was succesfully established.' ) self.connection_method = 1 except: if self._debug: if self.error_handling == 'print': print( 'threaded_mysql: [ERROR] Not possible to make a connection.' ) else: echo_console( 'threaded_mysql: [ERROR] Not possible to make a connection.' ) def connect_use(self, connection): """ If you created your connection elsewhere in your code, you can pass it to Threaded MySQL :param connection: Your connection socket :return: """ try: self.connection = connection self.cursor = self.connection.cursor() if self._debug: if self.error_handling == 'print': print( 'threaded_mysql: [SUCCES] Cursor created succesfully for your connection.' ) else: echo_console( 'threaded_mysql: [SUCCES] Cursor created succesfully for your connection.' ) self.connection_method = 2 except: if self._debug: if self.error_handling == 'print': print( 'threaded_mysql: [ERROR] Not possible to create cursor.' ) else: echo_console( 'threaded_mysql: [ERROR] Not possible to create cursor.' ) def commit(self): """ Regular pymysql commit :return: """ self.connection.commit() def close(self, finish_queue_before_close=False): """ Closes the mysql connection :param finish_queue_before_close: Finishes the queue before it terminates the connection :return: """ if finish_queue_before_close: while self.queue_size() > 0: pass else: self.connection.close() else: self.connection.close()
def wrapper(*args, **kwargs): thread = GameThread(target=fn, args=args, kwargs=kwargs) thread.daemon = True thread.start()
def listener_on_level_init(map_name): logger.log_debug( "Entered OnLevelInit listener (map_name={})...".format(map_name)) # Reset MCPlayer instances mcplayers.reset_all() # Clear SessionPlayerManager session_players.clear() # Cancel delays if any if delay_scheduled_vote is not None and delay_scheduled_vote.running: delay_scheduled_vote.cancel() global delay_changelevel # We will assign to this a few lines later if delay_changelevel is not None and delay_changelevel.running: delay_changelevel.cancel() if delay_end_vote is not None and delay_end_vote.running: delay_end_vote.cancel() if delay_likemap_survey is not None and delay_likemap_survey.running: delay_likemap_survey.cancel() # Reset Status status.vote_status = VoteStatus.NOT_STARTED status.next_map = None status.map_start_time = time() status.used_extends = 0 # Update database GameThread(target=save_maps_to_db).start() # Reload maps reload_maps_from_mapcycle() # Set current map in Status status.current_map = server_map_manager.get(map_name.lower()) if status.current_map is None: logger.log_debug("Current map '{}' is not " "from mapcycle.json!".format(map_name)) # Unsend popups main_popup.close() # Add current map names to recent_map_names server_map_manager.recent_map_names.append(map_name) # And then cap recent_map_names server_map_manager.cap_recent_maps() logger.log_debug( "Recent map names: {}".format(','.join( server_map_manager.recent_map_names))) # Schedule regular vote schedule_vote(was_extended=False) # Schedule level changing - this can be later cancelled by map extensions schedule_change_level(was_extended=False)
def _start_thread(self): # Creates the thread self.t = GameThread(target=self._threader) self.t.daemon = True self.t.start()
def spawn_flag(self, options = {}, spawnflag = True): # spawn flag in extra thread (independent from server tick) t = GameThread(target=self._spawn_flag, args=(options,spawnflag, )) t.start()
def player_say(self, userid, text): t = GameThread(target=self._player_say, args=(userid,text, )) t.start()
def player_death(self, userid, attacker): t = GameThread(target=self._player_death, args=(userid, attacker, )) t.start()
def player_connect_full(self, userid): # initialize player data t = GameThread(target=self.get_player_data, args=(userid, )) t.start()