def help(world_session, args): total_number = 0 def _split_command_text(commands, n=8): command_list = list(commands) for i in range(0, len(command_list), n): yield command_list[i:i + n] # If player is GM, send GM commands first. if world_session.player_mgr.is_gm: ChatManager.send_system_message(world_session, '[GM Commands]') for commands_chunk in _split_command_text( GM_COMMAND_DEFINITIONS.keys()): total_number += len(commands_chunk) gm_commands = ' | '.join([k for k in commands_chunk]) ChatManager.send_system_message(world_session, gm_commands) ChatManager.send_system_message(world_session, '\n') # Send Player commands. ChatManager.send_system_message(world_session, '[Player Commands]') for commands_chunk in _split_command_text( PLAYER_COMMAND_DEFINITIONS.keys()): total_number += len(commands_chunk) player_commands = ' | '.join([k for k in commands_chunk]) ChatManager.send_system_message(world_session, player_commands) return 0, f'{total_number} commands found.'
def sspell(world_session, args): spell_name = args.strip() if not spell_name: return -1, 'please specify a spell name to start searching.' spells = DbcDatabaseManager.spell_get_by_name(spell_name) for spell in spells: spell_name = spell.Name_enUS.replace('\\', '') spell_text = f'{spell.ID} - |cFF00FFFF[{spell_name}]|r' if spell.NameSubtext_enUS: spell_text += f' ({spell.NameSubtext_enUS})' learned_spells = [] if spell.Effect_1 == SpellEffects.SPELL_EFFECT_LEARN_SPELL: learned_spells.append(spell.EffectTriggerSpell_1) if spell.Effect_2 == SpellEffects.SPELL_EFFECT_LEARN_SPELL: learned_spells.append(spell.EffectTriggerSpell_2) if spell.Effect_3 == SpellEffects.SPELL_EFFECT_LEARN_SPELL: learned_spells.append(spell.EffectTriggerSpell_3) if learned_spells: learned_spells_text = ', '.join([str(spell_id) for spell_id in learned_spells]) spell_text += f' [Teaches: {learned_spells_text}]' ChatManager.send_system_message(world_session, spell_text) return 0, f'{len(spells)} spells found.'
def gobject_info(world_session, args): try: if args: max_distance = int(args) else: max_distance = 10 found_count = 0 for guid, gobject in list( MapManager.get_surrounding_gameobjects( world_session.player_mgr).items()): distance = world_session.player_mgr.location.distance( gobject.location) if distance <= max_distance: found_count += 1 ChatManager.send_system_message( world_session, f'[{gobject.gobject_template.name}] - Guid: {gobject.guid & ~HighGuid.HIGHGUID_GAMEOBJECT}, ' f'Entry: {gobject.gobject_template.entry}, ' f'Display ID: {gobject.current_display_id}, ' f'X: {gobject.location.x}, ' f'Y: {gobject.location.y}, ' f'Z: {gobject.location.z}, ' f'O: {gobject.location.o}, ' f'Map: {gobject.map_}, ' f'Distance: {distance}') return 0, f'{found_count} game objects found within {max_distance} distance units.' except ValueError: return -1, 'please specify a valid distance.'
def ann(world_session, args): ann = str(args) for session in WorldSessionStateHandler.get_world_sessions(): if session.player_mgr and session.player_mgr.online: ChatManager.send_system_message(session, f'[SERVER] {ann}') return 0, ''
def tickets(world_session, args): tickets = RealmDatabaseManager.ticket_get_all() for ticket in tickets: ticket_color = '|cFFFF0000' if ticket.is_bug else '|cFF00FFFF' ticket_title = 'Bug report' if ticket.is_bug else 'Suggestion' ticket_text = f'{ticket_color}[{ticket.id}]|r {ticket.submit_time}: {ticket_title} from {ticket.character_name}.' ChatManager.send_system_message(world_session, ticket_text) return 0, f'{len(tickets)} tickets shown.'
def sskill(world_session, args): skill_name = args.strip() if not skill_name: return -1, 'please specify a skill name to start searching.' skills = DbcDatabaseManager.skill_get_by_name(skill_name) for skill in skills: skill_name = skill.DisplayName_enUS.replace('\\', '') skill_text = f'{skill.ID} - |cFF00FFFF[{skill_name}]|r' ChatManager.send_system_message(world_session, skill_text) return 0, f'{len(skills)} skills found.'
def sitem(world_session, args): item_name = args.strip() if not item_name: return -1, 'please specify an item name to start searching.' items = WorldDatabaseManager.item_template_get_by_name(item_name, return_all=True) for item in items: item_link = GameTextFormatter.generate_item_link(item.entry, item.name, item.quality) item_text = f'{item.entry} - {item_link}' ChatManager.send_system_message(world_session, item_text) return 0, f'{len(items)} items found.'
def stel(world_session, args): try: tel_name = args.split()[0] except IndexError: return -1, 'please specify a location name to start searching.' locations = WorldDatabaseManager.worldport_get_by_name(tel_name, return_all=True) for location in locations: port_text = f'|cFF00FFFF[Map {location.map}]|r - {location.name}' ChatManager.send_system_message(world_session, port_text) return 0, f'{len(locations)} worldports found.'
def handle_add_mod(world_session, socket, reader): channel = PacketReader.read_string(reader.data, 0).strip().capitalize() offset = len(channel) + 1 has_player = len(reader.data) == offset + 1 player_name = '' if has_player else PacketReader.read_string(reader.data, offset, 0).strip()[:-1] target_player_mgr = WorldSessionStateHandler.find_player_by_name(player_name) if target_player_mgr: ChannelManager.add_mod(channel, world_session.player_mgr, target_player_mgr) else: ChatManager.send_system_message(world_session, f'No player named [{player_name}] is currently playing.') return 0
def help(world_session, args): total_number = 0 # If player is GM, send GM commands first. if world_session.player_mgr.is_gm: total_number += len(GM_COMMAND_DEFINITIONS) ChatManager.send_system_message(world_session, '|cFFFFFFFF[GM Commands]|r') for command in GM_COMMAND_DEFINITIONS: ChatManager.send_system_message(world_session, f'|cFF00FFFF{command}|r: ' f'{GM_COMMAND_DEFINITIONS[command][1]}') ChatManager.send_system_message(world_session, '\n') ChatManager.send_system_message(world_session, '|cFFFFFFFF[Player Commands]|r\n') total_number += len(PLAYER_COMMAND_DEFINITIONS) for command in PLAYER_COMMAND_DEFINITIONS: ChatManager.send_system_message(world_session, f'|cFF00FFFF{command}|r: ' f'{PLAYER_COMMAND_DEFINITIONS[command][1]}') return 0, f'{total_number} commands found.'
def handle(world_session, socket, reader: PacketReader) -> int: player_mgr = world_session.player_mgr if not player_mgr: return 0 if not player_mgr.is_gm: Logger.anticheat( f'Player {player_mgr.player.name} ({player_mgr.guid}) tried to give himself Beastmaster.' ) return 0 if len(reader.data) >= 1: # Avoid handling empty beast master packet. # Client sends `0` if you type `beastmaster off`, and `1` if you type `beastmaster`. player_mgr.beast_master = unpack('<B', reader.data[:1])[0] >= 1 ChatManager.send_system_message( world_session, f'Beastmaster ' f'{"enabled" if player_mgr.beast_master else "disabled"}') return 0
def handle(world_session, socket, reader): if len(reader.data) >= 4: # Avoid handling empty area trigger packet. trigger_id = unpack('<I', reader.data[:4])[0] location = WorldDatabaseManager.area_trigger_teleport_get_by_id(trigger_id) if location: if world_session.player_mgr.level >= location.required_level or world_session.player_mgr.is_gm: world_session.player_mgr.teleport(location.target_map, Vector(location.target_position_x, location.target_position_y, location.target_position_z, location.target_orientation)) else: # SMSG_AREA_TRIGGER_MESSAGE in 1.x, but this OpCode seems to be missing in 0.5.3 ChatManager.send_system_message(world_session, f'You must be at least level {location.required_level} to enter.') return 0 world_session.player_mgr.quest_manager.reward_exploration_completion(trigger_id) return 0
def handle(world_session, socket, reader: PacketReader) -> int: player_mgr = world_session.player_mgr if not player_mgr: return 0 if not player_mgr.is_gm: Logger.anticheat( f'Player {player_mgr.player.name} ({player_mgr.guid}) tried to set god mode.' ) return 0 if len(reader.data) >= 1: # Avoid handling empty god mode packet. # Client sends `0` if you type `godmode`, and `1` if you type `godmode 1` (or a number greater than 1). player_mgr.is_god = unpack('<B', reader.data[:1])[0] >= 1 world_session.enqueue_packet( PacketWriter.get_packet(OpCode.SMSG_GODMODE, reader.data[:1])) ChatManager.send_system_message( world_session, f'Godmode ' f'{"enabled" if player_mgr.is_god else "disabled"}') return 0
def handle_command(world_session, command_msg): terminator_index = command_msg.find(' ') if ' ' in command_msg else len(command_msg) command = command_msg[1:terminator_index].strip() args = command_msg[terminator_index:].strip() if command in PLAYER_COMMAND_DEFINITIONS: command_func = PLAYER_COMMAND_DEFINITIONS[command][0] elif command in GM_COMMAND_DEFINITIONS and world_session.player_mgr.is_gm: command_func = GM_COMMAND_DEFINITIONS[command][0] else: ChatManager.send_system_message(world_session, 'Command not found, type .help for help.') return if command_func: code, res = command_func(world_session, args) if code != 0: ChatManager.send_system_message(world_session, f'Wrong arguments for <{command}> command: {res}') elif res: ChatManager.send_system_message(world_session, res)
def handle(world_session, socket, reader: PacketReader) -> int: if len(reader.data) < 8: # Avoid handling wrong player login packet. return -1 guid = unpack('<Q', reader.data[:8])[0] world_session.player_mgr = PlayerManager( RealmDatabaseManager.character_get_by_guid(guid), world_session) if not world_session.player_mgr.player: Logger.anticheat( f'Character with wrong guid ({guid}) tried to login.') return -1 else: WorldSessionStateHandler.push_active_player_session(world_session) # Disabled race & class checks (only if not a GM). if not world_session.player_mgr.is_gm: disabled_race_mask = config.Server.General.disabled_race_mask disabled = disabled_race_mask & world_session.player_mgr.race_mask == world_session.player_mgr.race_mask if not disabled: disabled_class_mask = config.Server.General.disabled_class_mask disabled = disabled_class_mask & world_session.player_mgr.class_mask == world_session.player_mgr.class_mask if disabled: # Not 100% sure if CHAR_LOGIN_DISABLED matters here, but I don't know where else to send it. data = pack('<B', CharLogin.CHAR_LOGIN_DISABLED) world_session.enqueue_packet( PacketWriter.get_packet(OpCode.SMSG_CHARACTER_LOGIN_FAILED, data)) return 0 # Class & race allowed, continue with the login process. world_session.enqueue_packet( PacketWriter.get_packet(OpCode.SMSG_LOGIN_SETTIMESPEED, PlayerLoginHandler._get_login_timespeed())) world_session.player_mgr.skill_manager.load_proficiencies() world_session.player_mgr.skill_manager.load_skills() world_session.player_mgr.spell_manager.load_spells() world_session.player_mgr.deathbind = RealmDatabaseManager.character_get_deathbind( world_session.player_mgr.guid) world_session.player_mgr.friends_manager.load_from_db( RealmDatabaseManager.character_get_social( world_session.player_mgr.guid)) # Only send the deathbind packet if it's a Binder NPC what bound the player. if world_session.player_mgr.deathbind.creature_binder_guid > 0: world_session.enqueue_packet( world_session.player_mgr.get_deathbind_packet()) # Tutorials aren't implemented in 0.5.3. # world_session.enqueue_packet(world_session.player_mgr.get_tutorial_packet()) world_session.enqueue_packet( world_session.player_mgr.spell_manager.get_initial_spells()) world_session.enqueue_packet( world_session.player_mgr.get_action_buttons()) # MotD. ChatManager.send_system_message(world_session, config.Server.General.motd) world_session.player_mgr.inventory.load_items() # Initialize stats first to have existing base stats for further calculations. world_session.player_mgr.stat_manager.init_stats() # Passive spells contain skill and proficiency learning. # Perform passive spell casts after loading skills to avoid duplicate database entries. world_session.player_mgr.spell_manager.cast_passive_spells() world_session.player_mgr.spell_manager.apply_cast_when_learned_spells() world_session.player_mgr.skill_manager.init_proficiencies() world_session.player_mgr.quest_manager.load_quests() world_session.player_mgr.reputation_manager.load_reputations() GuildManager.set_character_guild(world_session.player_mgr) GroupManager.set_character_group(world_session.player_mgr) PetitionManager.load_petition(world_session.player_mgr) first_login = world_session.player_mgr.player.totaltime == 0 # Send cinematic. if first_login: PlayerLoginHandler._send_cinematic(world_session, world_session.player_mgr.player, socket) world_session.player_mgr.complete_login(first_login=first_login) return 0