def command_dispatch(cmd, id, client): if cmd[0] == "!status": room.send_message( "Name: %s\n Map: %s\n Players: %d/%d (%d bots)\n Tags: %s" % (server.server.name, server.server.map_name, server.server.num_clients, server.server.max_clients, server.server.num_fake_clients, cvar.find_var("sv_tags").get_string())) elif cmd[0] == "!players": msg = "\n".join("%s: %s" % (p.name, p.kills) for p in PlayerIter()) room.send_message(msg if msg else "No players.") elif cmd[0] == "!abuse": room.send_message("mod abuse: " + str(mod_abuse) + "/11") elif cmd[0] == "!rcon": if id in elevated: server.queue_command_string(cmd[1]) else: room.send_message("You do not have permission to do that.") elif cmd[0] == "!rm": if id in elevated: msg = client.get_message(int(cmd[1])) msg.delete() else: room.send_message("You do not have permission to do that.") elif cmd[0] == "!trash": if id in elevated: msg = client.get_message(int(cmd[1])) msg.move("19718") else: room.send_message("You do not have permission to do that.") else: room.send_message("No such command.")
def set_next_game_mode(self): """Set the next game mode.""" current = database.get(self.game_mode) if current is not None: queue_command_string(f'exec {current}') self.game_mode = None self.clear()
def wcs_ulti_roots(): userid = int(es.ServerVar('wcs_userid')) player = Player.from_userid(userid) if player.team >= 2: count = 0 wcs_commands.fade(userid, 10, 55, 5, 200, 1) radius = float(es.ServerVar('wcs_radius')) time = float(es.ServerVar('wcs_duration')) atk_origin = player.origin for play in PlayerIter('alive'): if play.team != player.team: vic_origin = play.origin if vic_origin.get_distance(atk_origin) <= radius: if not wcsgroup.getUser(play.userid, 'ulti_immunity'): play.move_type = MoveType.NONE count += 1 Delay(time, remove_freeze, (play, )) es.emitsound('player', play.userid, 'wcs/root.wav', 1.0, 0.6) queue_command_string( 'es est_effect_06 #a 0 sprites/laser.vmt "%s,%s,%s" "%s,%s,%s" 10 1 5 5 10 4 0 160 0 155 2' % (atk_origin[0], atk_origin[1], atk_origin[2] + 35, vic_origin[0], vic_origin[1], vic_origin[2] + 35)) queue_command_string( 'es est_effect_06 #a 0 sprites/laser.vmt "%s,%s,%s" "%s,%s,%s" 10 1 4 4 10 2 0 108 0 180 2' % (atk_origin[0], atk_origin[1], atk_origin[2] + 35, vic_origin[0], vic_origin[1], vic_origin[2] + 35)) queue_command_string( 'es est_effect_06 #a 0 sprites/laser.vmt "%s,%s,%s" "%s,%s,%s" 10 1 5 5 10 4 0 80 0 190 2' % (atk_origin[0], atk_origin[1], atk_origin[2] + 35, vic_origin[0], vic_origin[1], vic_origin[2] + 35)) queue_command_string( 'es est_effect 10 #a 0 sprites/laser.vmt %s %s %s 60 20 1 3 3 5 0 80 0 155 0 255 2' % (vic_origin[0], vic_origin[1], vic_origin[2] + 10)) queue_command_string( 'es est_effect 10 #a 0 sprites/laser.vmt %s %s %s 75 35 1 3 3 6 0 108 0 190 0 255 2' % (vic_origin[0], vic_origin[1], vic_origin[2] + 25)) else: es.tell( player.userid, '#multi', '#lightgreenYour ultimate was blocked, the enemy is #greenimmune.' ) es.tell( play.userid, '#multi', '#lightgreenYou #greenblocked #lightgreenan ultimate skill.' ) if count > 0: es.centertell(userid, 'Entangling Roots: %s' % (count)) else: es.tell( userid, '#multi', '#lightgreenEntangling Roots #greenfailed#lightgreen, because no enemy is close enough.' ) cancel(userid, 'player_ultimate')
def _centermessage_command(command): message = command.arg_string for player in PlayerIter(): if SOURCE_ENGINE_BRANCH == "css": queue_command_string("es_centertell %s %s" % (player.userid, message)) else: HudMsg(message, -1, 0.35, hold_time=5.0).send(player.index)
def _doteleport_command(command): userid = int(command[1]) if exists(userid): player = Player.from_userid(userid) view_vector = player.view_coordinates queue_command_string( 'wcs_teleport %s %s %s %s' % (userid, view_vector[0], view_vector[1], view_vector[2]))
def rule_menu_callback(_menu, _index, _option): choice = _option.value if choice: userid = userid_from_index(_index) if choice == 'No': queue_command_string('kickid %s You have to accept the rules!' % (userid)) elif choice == 'Yes': SayText2('\x04Thank you for accepting the rules and have fun!').send(_index)
def unload(): """Clean up GunGame.""" # Start the cleanup process GunGameStatus.MATCH = GunGameMatchStatus.UNLOADING current = 1 total = len([x for x in _base_strings if x.startswith('Clean:')]) gg_logger.log_message( _base_strings['Start:Clean'].get_string() ) # Remove gungame from sv_tags gg_logger.log_message( _base_strings['Clean:Tag'].get_string( current=current, total=total, ) ) current += 1 sv_tags.remove(info.name) # Clean GunGame plugins gg_logger.log_message( _base_strings['Clean:Plugins'].get_string( current=current, total=total, ) ) current += 1 gg_command_manager.unload_all_plugins() # Clean GunGame commands/menus gg_logger.log_message( _base_strings['Clean:Commands'].get_string( current=current, total=total, ) ) current += 1 from .core.commands.commands import unregister_all_commands unregister_all_commands() # Re-enable buyzones gg_logger.log_message( _base_strings['Clean:BuyZones'].get_string( current=current, total=total, ) ) current += 1 for entity in EntityIter('func_buyzone'): entity.enable() # Restart the match gg_logger.log_message( _base_strings['End:Clean'].get_string() ) queue_command_string('mp_restartgame 1')
def load_all_configs(): """Load all GunGame configs.""" for file in Path(__file__).parent.files('*.py'): if file.namebase in ('__init__', Path(__file__).namebase): continue import_module( 'gungame.core.config.{file_name}'.format( file_name=file.namebase, ) ) for plugin_name in valid_plugins.all: plugin_type = valid_plugins.get_plugin_type(plugin_name) if not GUNGAME_PLUGINS_PATH.joinpath( plugin_type, plugin_name, 'configuration.py', ).isfile(): continue try: import_module( 'gungame.plugins.{plugin_type}.{plugin_name}.' 'configuration'.format( plugin_type=plugin_type, plugin_name=plugin_name, ) ) except Exception: warn( 'Unable to import configuration for {plugin} due to error:' '\n\n\t{error}'.format( plugin=plugin_name, error=sys.exc_info()[1] ) ) always_loaded = GUNGAME_CFG_PATH / 'gg_plugins.cfg' if not always_loaded.isfile(): strings = LangStrings('gungame/plugins') with always_loaded.open('w') as open_file: wrapper = TextWrapper( width=79, initial_indent='// ', subsequent_indent='// ', ) text = strings['Plugins:Loaded:Always'].get_string( plugins=', '.join(sorted(valid_plugins.all)) ) for line in text.splitlines(keepends=True): if line == '\n': open_file.write(line) continue for output in wrapper.wrap(line): open_file.write(output + '\n') exec_path = always_loaded.replace( always_loaded.parent.parent.parent, '', )[1:~3].replace('\\', '/') queue_command_string('exec {config}'.format(config=exec_path))
def load_all_configs(): """Load all GunGame configs.""" for file in Path(__file__).parent.files('*.py'): if file.namebase in ('__init__', Path(__file__).namebase): continue import_module(f'gungame.core.config.{file.namebase}') for plugin_name in valid_plugins.all: plugin_path = valid_plugins.get_plugin_path(plugin_name) plugin_type = str(plugin_path.parent.namebase) config_path = plugin_path / 'configuration.py' if not config_path.isfile(): continue try: import_module( f'gungame.plugins.{plugin_type}.{plugin_name}.configuration' ) # pylint: disable=broad-except except Exception: warn( f'Unable to import configuration for {plugin_name} due to ' f'error:\n\n\t{sys.exc_info()[1]}' ) always_loaded = GUNGAME_CFG_PATH / 'gg_plugins.cfg' contents = [] if always_loaded.isfile(): with always_loaded.open() as open_file: contents = open_file.read() contents = [ line for line in contents.splitlines() if line and not line.startswith('// ') ] strings = LangStrings('gungame/plugins') with always_loaded.open('w') as open_file: wrapper = TextWrapper( width=79, initial_indent='// ', subsequent_indent='// ', ) text = strings['Plugins:Loaded:Always'].get_string( plugins=', '.join(sorted(valid_plugins.all)) ) for line in text.splitlines(keepends=True): if line == '\n': open_file.write(line) continue for output in wrapper.wrap(line): open_file.write(output + '\n') for line in contents: open_file.write(line + '\n') exec_path = always_loaded.replace( always_loaded.parent.parent.parent, '', )[1:~3].replace('\\', '/') queue_command_string(f'exec {exec_path}')
def _restart_game(self): """Restart the match.""" self._restart_delay = None GunGameStatus.MATCH = GunGameMatchStatus.INACTIVE # Clear the player dictionary from ..players.dictionary import player_dictionary player_dictionary.clear() # Restart the match queue_command_string('mp_restartgame 1')
def execute(self): """Execute the config file.""" # Does the file exist? if not self.fullpath.isfile(): raise FileNotFoundError( 'Cannot execute file "{0}", file not found'.format( self.fullpath)) # Open/close the file with self.fullpath.open(encoding=self._encoding) as open_file: # Loop through all lines in the file for line in open_file.readlines(): # Strip the line line = line.strip() # Is the line a command or cvar? if line.startswith('//') or not line: continue # Get the command's or cvar's name name = line.split(' ', 1)[0] # Is the command/cvar valid if name not in self._commands | self._cvars: continue # Does the command/cvar have any value/arguments? if not line.count(' '): continue # Is this a command? if name in self._commands: # Execute the line queue_command_string(line) # Is this a cvar else: # Get the cvar's value value = line.split(' ', 1)[1] # Do quotes need removed? if value.startswith('"') and line.count('"') >= 2: # Remove the quotes value = value.split('"')[1] # Set the cvar's value ConVar(name).set_string(value)
def execute(self): """Execute the config file.""" # Does the file exist? if not self.fullpath.isfile(): raise FileNotFoundError( 'Cannot execute file "{0}", file not found'.format( self.fullpath)) # Open/close the file with self.fullpath.open() as open_file: # Loop through all lines in the file for line in open_file.readlines(): # Strip the line line = line.strip() # Is the line a command or cvar? if line.startswith('//') or not line: continue # Get the command's or cvar's name name = line.split(' ', 1)[0] # Is the command/cvar valid if name not in self._commands | self._cvars: continue # Does the command/cvar have any value/arguments? if not line.count(' '): continue # Is this a command? if name in self._commands: # Execute the line queue_command_string(line) # Is this a cvar else: # Get the cvar's value value = line.split(' ', 1)[1] # Do quotes need removed? if value.startswith('"') and line.count('"') >= 2: # Remove the quotes value = value.split('"')[1] # Set the cvar's value ConVar(name).set_string(value)
def start_match(ending_warmup=False): """Start the match if not already started or on hold.""" # Is warmup supposed to happen? if not ending_warmup and warmup_enabled.get_bool(): warmup_manager.start_warmup() return # Is the match supposed to start? if GunGameStatus.MATCH is not GunGameMatchStatus.INACTIVE: return queue_command_string('mp_restartgame 1') GG_Start().fire()
def _speed_ulti(command): userid = int(command[1]) speed = float(command[2]) delay = float(command[3]) if exists(userid): player = Player.from_userid(userid) player.speed += speed queue_command_string('es_delayed %s playerset speed %s %s' % (delay, userid, player.speed - speed)) wcs.wcs.tell( player.userid, '\x04[WCS] \x05You got \x04%s%% Extra Speed \x05for \x04%s Seconds!' % (speed * 100.0, delay))
def _gg_win(game_event): """Increase the win total for the winner and end the map.""" # Set the match status GunGameStatus.MATCH = GunGameMatchStatus.POST # Get the winner winner = player_dictionary[game_event['winner']] # Increase the winner's win total if they are not a bot if not winner.is_fake_client(): winner.wins += 1 # Send the winner messages message_manager.chat_message( message='Winner:Long', index=winner.index, winner=winner.name, ) for second in range(4): Delay( delay=second, callback=message_manager.center_message, kwargs={ 'message': 'Winner:Short', 'winner': winner.name, }, cancel_on_level_end=True, ) color = {2: RED, 3: BLUE}.get(winner.team_index, WHITE) message_manager.top_message( message='Winner:Short', color=color, winner=winner.name ) # Play the winner sound winner_sound = sound_manager.play_sound('winner') # Set the dynamic chat time, if needed if dynamic_chat_time.get_bool() and winner_sound is not None: with suppress(MutagenError): ConVar('mp_chattime').set_float(winner_sound.duration) # End the match to move to the next map entity = Entity.find_or_create('game_end') entity.end_game() # Do not remove! This fixes a lot of console spam and hanging on map end. queue_command_string('bot_kick')
def wcs_leech(command): userid = int(command[1]) victim_uid = int(command[2]) amount = int(command[3]) player = Player.from_userid(userid) victim = Player.from_userid(victim_uid) if victim.health - amount < 0: player.health += victim.health queue_command_string("es wcs_dealdamage %s %s %s" % (victim_uid, userid, amount)) else: player.health += amount queue_command_string("es wcs_dealdamage %s %s %s" % (victim_uid, userid, amount)) print(victim.armor)
def _centertell(command): userid = command[1] if userid != '': userid = int(userid) else: return if exists(userid): command_string = command.arg_string command_string = command_string.replace(str(userid) + " ", '') index = index_from_userid(userid) if SOURCE_ENGINE_BRANCH == "css": queue_command_string("es_centertell %s %s" % (userid, command_string)) else: HudMsg(command_string, -1, 0.35, hold_time=5.0).send(index)
def _end_match(game_event): # Set the match status GunGameStatus.MATCH = GunGameMatchStatus.POST # Get the winning team information winning_team = teamwork_manager[game_event['winner']] # Send the winner messages message_manager.chat_message( index=winning_team.index, message='TeamWork:Winner:Long', team_name=winning_team.name, ) for second in range(4): Delay( delay=second, callback=message_manager.center_message, kwargs={ 'message': 'TeamWork:Winner:Short', 'team_name': winning_team.name, }, cancel_on_level_end=True, ) color = {2: RED, 3: BLUE}.get(winning_team, WHITE) message_manager.top_message( message='TeamWork:Winner:Short', color=color, team_name=winning_team.name, ) # Play the winner sound winner_sound = sound_manager.play_sound('winner') # Set the dynamic chat time, if needed if dynamic_chat_time.get_bool() and winner_sound is not None: with suppress(MutagenError): ConVar('mp_chattime').set_float(winner_sound.duration) # End the match to move to the next map entity = Entity.find_or_create('game_end') entity.end_game() # Do not remove! This fixes a lot of console spam and hanging on map end. queue_command_string('bot_kick') # Reset the teams _clear_team_dictionary()
def expshop_menu_select(menu, index, choice): player = Player(index) if player.cash >= int(choice.value[1]): player.cash -= int(choice.value[1]) queue_command_string('wcs_givexp %s %s' % (player.userid, choice.value[0])) if SOURCE_ENGINE_BRANCH == 'css': SayText2("\x04[WCS] \x03You bought \x04%s XP \x03for \x04%s$." % (choice.value[0], choice.value[1])).send(index) else: SayText2("\x04[WCS] \x05You bought \x04%s XP \x05for \x04%s$." % (choice.value[0], choice.value[1])).send(index) else: if SOURCE_ENGINE_BRANCH == 'css': SayText2("\x04[WCS] \x03You don't have enough cash.").send(index) else: SayText2("\x04[WCS] \x05You don't have enough cash.").send(index)
def wcs_aoe(command): userid = int(command[1]) attacker_userid = int(command[2]) radius = float(command[3]) damage = int(command[4]) if exists(userid): victim = Player.from_userid(userid) else: return if exists(attacker_userid): attacker = Player.from_userid(attacker_userid) else: return for player in PlayerIter('alive'): if player.team == victim.team: if player.origin.get_distance(victim.origin) <= radius: queue_command_string("es wcs_dealdamage %s %s %s" % (player.userid, attacker_userid, damage))
def _wcs_explode_command(command): userid = int(command[1]) range = float(command[2]) damage = int(command[3]) if exists(userid): player_ent = Player.from_userid(userid) for player in PlayerIter(): if player.team != player_ent.team: distance = player_ent.origin.get_distance(player.origin) if distance <= range: if not player.isdead: queue_command_string( 'wcs_dealdamage %s %s %s' % (player.userid, player_ent.userid, damage)) wcs.wcs.tell( player.userid, "\x04[WCS] \x05You were hit by \x04%s's Suicide Explosion!" % player_ent.name) wcs.wcs.tell( player_ent.userid, '\x04[WCS] \x05You hit \x04%s \x05with your \x04Suicide Explosion' % player.name)
def wcs_ulti_chain(): userid = int(es.ServerVar('wcs_userid')) player = Player.from_userid(userid) if player.team >= 2: count = 0 wcs_commands.fade(userid, 10, 55, 5, 200, 1) radius = float(es.ServerVar('wcs_radius')) atk_origin = player.origin for play in PlayerIter('alive'): if play.team != player.team: vic_origin = play.origin if vic_origin.get_distance(atk_origin) <= radius: if not wcsgroup.getUser(play.userid, 'ulti_immunity'): wcs_commands.damage(play.userid, 32, userid, solo=1) count += 1 es.emitsound('player', play.userid, 'wcs/lightning.wav', 1.0, 0.6) queue_command_string( 'es est_effect_06 #a 0 sprites/lgtning.vmt "%s,%s,%s" "%s,%s,%s" 10 .2 10 1 1 13 160 160 230 255 11' % (atk_origin[0], atk_origin[1], atk_origin[2] + 35, vic_origin[0], vic_origin[1], vic_origin[2] + 35)) queue_command_string( 'es est_effect_06 #a 0 sprites/lgtning.vmt "%s,%s,%s" "%s,%s,%s" 10 .2 10 2 2 12 150 150 255 220 8' % (atk_origin[0], atk_origin[1], atk_origin[2] + 35, vic_origin[0], vic_origin[1], vic_origin[2] + 35)) queue_command_string( 'es est_effect_06 #a 0 sprites/lgtning.vmt "%s,%s,%s" "%s,%s,%s" 10 .2 10 1 1 14 200 200 255 235 10' % (atk_origin[0], atk_origin[1], atk_origin[2] + 35, vic_origin[0], vic_origin[1], vic_origin[2] + 35)) else: es.tell( userid, '#multi', '#lightgreenYour ultimate was blocked, the enemy is #greenimmune.' ) es.tell( play.userid, '#multi', '#lightgreenYou #greenblocked #lightgreenan ultimate skill.' ) if count > 0: es.centertell(userid, 'Chain Lightning: %s players damaged' % (count)) else: es.tell( userid, '#multi', '#lightgreenChain Lightning #greenfailed#lightgreen, because no enemy is close enough to be damaged.' ) cancel(userid, 'player_ultimate')
def damage(victim, dmg, attacker=None, armor=False, weapon=None, solo=None): queue_command_string("wcs_dealdamage %s %s %s" % (victim, attacker, dmg))
def command_dispatch(cmd, sender): id = sender.id if sender else 0 if cmd[0] == "!status": send_command_response( "Name: %s\nMap: %s\nPlayers: %d/%d (%d bots)\nTags: %s" % (server.server.name, server.server.map_name, server.server.num_clients, server.server.max_clients, server.server.num_fake_clients, cvar.find_var("sv_tags").get_string()), sender, True) elif cmd[0] == "!players": msg = "\n".join( "%s%s - %s (http://steamcommunity.com/profiles/%s): %s kills/%s deaths" % ("*DEAD* " if p.playerinfo.is_dead() else "", "RED" if p.team == 2 else "BLU" if p.team == 3 else "SPEC", p.name, SteamID.parse(p.steamid if p.steamid != "BOT" else "[U:1:22202]" ).to_uint64(), p.kills, p.deaths) for p in PlayerIter()) send_command_response(msg if msg else "No players.", sender, True) elif cmd[0] == "!abuse": send_command_response("Admin abuse: " + str(mod_abuse) + "/11", sender, False) elif cmd[0] == "!rcon": if id in elevated: server.queue_command_string(cmd[1]) else: send_command_response("You do not have permission to do that.", sender, False) elif cmd[0] == "!rm": if id in elevated: msg = client.get_message(int(cmd[1])) msg.delete() else: send_command_response("You do not have permission to do that.", sender, False) elif cmd[0] == "!trash": if id in elevated: msg = client.get_message(int(cmd[1])) msg.move("19718") else: send_command_response("You do not have permission to do that.", sender, False) elif cmd[0] == "!pull": if id in elevated: result = run([ "git", "-C", PLUGIN_PATH + "/tf2goat/", "pull", "origin", branch, "-X", "theirs", "--no-edit" ]) if result.returncode == 0: send_command_response("Pulled; restarting in 5 seconds...", sender, False) sleep(5) _core_command.reload_plugin("tf2goat") else: send_command_response( "Pull failed. Return code: %d" % result.returncode, sender, False) else: send_command_response("You do not have permission to do that.", sender, False) elif cmd[0] == "!curl": if id in elevated: url, path = cmd[1].split(" ", 1) try: urlretrieve(url, filename=GAME_PATH + path) send_command_response("Curl successful.", sender, False) except: send_command_response("Curl failed.", sender, False) else: send_command_response("You do not have permission to do that.", sender, False) else: send_command_response("No such command.", sender, False)
def on_close_checkpoints_menu(menu, index): queue_command_string('kickid %s You have to accept the rules!' % (userid))
def player_activate(event): userid = event.get_int('userid') queue_command_string('mp_disable_autokick %s' % userid)