diff --git a/common/guild_base.cpp b/common/guild_base.cpp index f56cd3deb..07ba3b040 100644 --- a/common/guild_base.cpp +++ b/common/guild_base.cpp @@ -1225,6 +1225,66 @@ uint32 BaseGuildManager::DoesAccountContainAGuildLeader(uint32 AccountID) return results.RowCount(); } +std::string BaseGuildManager::GetGuildNameByID(uint32 guild_id) const { + if(guild_id == GUILD_NONE) { + return std::string(); + } + std::map::const_iterator res; + res = m_guilds.find(guild_id); + if(res == m_guilds.end()) { + return "Invalid Guild"; + } + return res->second->name; +} +std::string BaseGuildManager::GetGuildRankName(uint32 guild_id, uint8 rank) const +{ + if(rank > GUILD_MAX_RANK) { + return "Invalid Rank"; + } + + std::map::const_iterator res; + res = m_guilds.find(guild_id); + if(res == m_guilds.end()) { + return "Invalid Guild Rank"; + } + + return res->second->ranks[rank].name; +} + +uint32 BaseGuildManager::GetGuildIDByCharacterID(uint32 character_id) +{ + if(!m_db) { + return GUILD_NONE; + } + + std::string query = fmt::format( + "SELECT `guild_id` FROM `guild_members` WHERE char_id = {} LIMIT 1", + character_id + ); + auto results = m_db->QueryDatabase(query); + if(!results.Success() || !results.RowCount()) { + return GUILD_NONE; + } + + auto row = results.begin(); + auto guild_id = std::stoul(row[0]); + return guild_id; +} + +bool BaseGuildManager::IsCharacterInGuild(uint32 character_id, uint32 guild_id) +{ + auto current_guild_id = GetGuildIDByCharacterID(character_id); + + if (current_guild_id == GUILD_NONE) { + return false; + } + + if (guild_id && current_guild_id != guild_id) { + return false; + } + + return true; +} \ No newline at end of file diff --git a/common/guild_base.h b/common/guild_base.h index ac8b1a895..122a9ff2f 100644 --- a/common/guild_base.h +++ b/common/guild_base.h @@ -76,8 +76,12 @@ class BaseGuildManager bool GetGuildChannel(uint32 GuildID, char *ChannelBuffer) const; const char *GetRankName(uint32 guild_id, uint8 rank) const; const char *GetGuildName(uint32 guild_id) const; + std::string GetGuildNameByID(uint32 guild_id) const; + std::string GetGuildRankName(uint32 guild_id, uint8 rank) const; + bool IsCharacterInGuild(uint32 character_id, uint32 guild_id = 0); bool GetGuildNameByID(uint32 guild_id, std::string &into) const; uint32 GetGuildIDByName(const char *GuildName); + uint32 GetGuildIDByCharacterID(uint32 character_id); bool IsGuildLeader(uint32 guild_id, uint32 char_id) const; uint8 GetDisplayedRank(uint32 guild_id, uint8 rank, uint32 char_id) const; bool CheckGMStatus(uint32 guild_id, uint8 status) const; diff --git a/zone/client.cpp b/zone/client.cpp index fbb1ac106..3e56614f0 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -5371,25 +5371,15 @@ void Client::ShowSkillsWindow() // Current Skill Level out of Max Skill Level or a Check Mark for Maxed popup_text += fmt::format( - "{}{}{}", + "{}", ( skill_maxed ? - "" : - "" - ), - ( - skill_maxed ? - "✔" : + "" : fmt::format( "{}/{}", current_skill, max_skill ) - ), - ( - skill_maxed ? - "" : - "" ) ); diff --git a/zone/gm_commands/guild.cpp b/zone/gm_commands/guild.cpp index e76f83965..5eaa7092b 100755 --- a/zone/gm_commands/guild.cpp +++ b/zone/gm_commands/guild.cpp @@ -8,437 +8,544 @@ extern WorldServer worldserver; void command_guild(Client *c, const Seperator *sep) { - int admin = c->Admin(); - Mob *target = c->GetTarget(); - - if (strcasecmp(sep->arg[1], "help") == 0) { - c->Message(Chat::White, "GM Guild commands:"); - c->Message(Chat::White, " #guild list - lists all guilds on the server"); - c->Message(Chat::White, " #guild create {guildleader charname or CharID} guildname"); - c->Message(Chat::White, " #guild delete guildID"); - c->Message(Chat::White, " #guild rename guildID newname"); - c->Message(Chat::White, " #guild set charname guildID (0=no guild)"); - c->Message(Chat::White, " #guild setrank charname rank"); - c->Message(Chat::White, " #guild setleader guildID {guildleader charname or CharID}"); + int arguments = sep->argnum; + if (!arguments) { + c->Message(Chat::White, "#guild create [Character ID|Character Name] [Guild Name]"); + c->Message(Chat::White, "#guild delete [Guild ID]"); + c->Message(Chat::White, "#guild help"); + c->Message(Chat::White, "#guild info [Guild ID]"); + c->Message(Chat::White, "#guild list"); + c->Message(Chat::White, "#guild rename [Guild ID] [New Name]"); + c->Message(Chat::White, "#guild set [Character ID|Character Name] [Guild ID] (Guild ID 0 is Guildless)"); + c->Message(Chat::White, "#guild setleader [Guild ID] [Character ID|Character Name]"); + c->Message(Chat::White, "#guild setrank [Character ID|Character Name] [Rank]"); + c->Message(Chat::White, "#guild status [Character ID|Character Name]"); + return; } - else if (strcasecmp(sep->arg[1], "status") == 0 || strcasecmp(sep->arg[1], "stat") == 0) { - Client *client = 0; - if (sep->arg[2][0] != 0) { - client = entity_list.GetClientByName(sep->argplus[2]); - } - else if (target != 0 && target->IsClient()) { - client = target->CastToClient(); - } - if (client == 0) { - c->Message(Chat::White, "You must target someone or specify a character name"); - } - else if ((client->Admin() >= minStatusToEditOtherGuilds && admin < minStatusToEditOtherGuilds) && - client->GuildID() != c->GuildID()) { // no peeping for GMs, make sure tell message stays the same - c->Message(Chat::White, "You must target someone or specify a character name."); - } - else { - if (client->IsInAGuild()) { - c->Message(Chat::White, "%s is not in a guild.", client->GetName()); - } - else if (guild_mgr.IsGuildLeader(client->GuildID(), client->CharacterID())) { + + auto target = c; + if (c->GetTarget() && c->GetTarget()->IsClient()) { + target = c->GetTarget()->CastToClient(); + } + + bool is_create = !strcasecmp(sep->arg[1], "create"); + bool is_delete = !strcasecmp(sep->arg[1], "delete"); + bool is_help = !strcasecmp(sep->arg[1], "help"); + bool is_info = !strcasecmp(sep->arg[1], "info"); + bool is_list = !strcasecmp(sep->arg[1], "list"); + bool is_rename = !strcasecmp(sep->arg[1], "rename"); + bool is_set = !strcasecmp(sep->arg[1], "set"); + bool is_set_leader = !strcasecmp(sep->arg[1], "setleader"); + bool is_set_rank = !strcasecmp(sep->arg[1], "setrank"); + bool is_status = !strcasecmp(sep->arg[1], "status"); + if ( + !is_create && + !is_delete && + !is_help && + !is_info && + !is_list && + !is_rename && + !is_set && + !is_set_leader && + !is_set_rank && + !is_status + ) { + c->Message(Chat::White, "#guild create [Character ID|Character Name] [Guild Name]"); + c->Message(Chat::White, "#guild delete [Guild ID]"); + c->Message(Chat::White, "#guild help"); + c->Message(Chat::White, "#guild info [Guild ID]"); + c->Message(Chat::White, "#guild list"); + c->Message(Chat::White, "#guild rename [Guild ID] [New Name]"); + c->Message(Chat::White, "#guild set [Character ID|Character Name] [Guild ID] (Guild ID 0 is Guildless)"); + c->Message(Chat::White, "#guild setleader [Guild ID] [Character ID|Character Name]"); + c->Message(Chat::White, "#guild setrank [Character ID|Character Name] [Rank]"); + c->Message(Chat::White, "#guild status [Character ID|Character Name]"); + return; + } + + if (is_create) { + if (arguments != 3) { + c->Message(Chat::White, "Usage: #guild create [Character ID|Character Name] [Guild Name]"); + } else { + auto leader_id = ( + sep->IsNumber(2) ? + std::stoul(sep->arg[2]) : + database.GetCharacterID(sep->arg[2]) + ); + auto leader_name = database.GetCharNameByID(leader_id); + if (!leader_id || leader_name.empty()) { c->Message( Chat::White, - "%s is the leader of <%s> rank: %s", - client->GetName(), - guild_mgr.GetGuildName(client->GuildID()), - guild_mgr.GetRankName(client->GuildID(), client->GuildRank())); + fmt::format( + "Character ID {} could not be found.", + leader_id + ).c_str() + ); + return; } - else { + + auto guild_id = guild_mgr.FindGuildByLeader(leader_id); + if (guild_id != GUILD_NONE) { c->Message( Chat::White, - "%s is a member of <%s> rank: %s", - client->GetName(), - guild_mgr.GetGuildName(client->GuildID()), - guild_mgr.GetRankName(client->GuildID(), client->GuildRank())); - } - } - } - else if (strcasecmp(sep->arg[1], "info") == 0) { - if (sep->arg[2][0] == 0 && c->IsInAGuild()) { - if (admin >= minStatusToEditOtherGuilds) { - c->Message(Chat::White, "Usage: #guildinfo guild_id"); - } - else { - c->Message(Chat::White, "You're not in a guild"); - } - } - else { - uint32 tmp = GUILD_NONE; - if (sep->arg[2][0] == 0) { - tmp = c->GuildID(); - } - else if (admin >= minStatusToEditOtherGuilds) { - tmp = atoi(sep->arg[2]); - } - - if (tmp != GUILD_NONE) { - guild_mgr.DescribeGuild(c, tmp); - } - } - } - else if (strcasecmp(sep->arg[1], "set") == 0) { - if (!sep->IsNumber(3)) { - c->Message(Chat::White, "Usage: #guild set charname guildgbid (0 = clear guildtag)"); - } - else { - uint32 guild_id = atoi(sep->arg[3]); - - if (guild_id == 0) { - guild_id = GUILD_NONE; - } - else if (!guild_mgr.GuildExists(guild_id)) { - c->Message(Chat::Red, "Guild %d does not exist.", guild_id); - return; - } - - uint32 charid = database.GetCharacterID(sep->arg[2]); - if (charid == 0) { - c->Message(Chat::Red, "Unable to find character '%s'", charid); - return; - } - - //we could do the checking we need for guild_mgr.CheckGMStatus, but im lazy right now - if (admin < minStatusToEditOtherGuilds) { - c->Message(Chat::Red, "Access denied."); - return; - } - - if (guild_id == GUILD_NONE) { - LogGuilds("[{}]: Removing [{}] ([{}]) from guild with GM command", c->GetName(), sep->arg[2], charid); - } - else { - LogGuilds("[{}]: Putting [{}] ([{}]) into guild [{}] ([{}]) with GM command", - c->GetName(), - sep->arg[2], - charid, - guild_mgr.GetGuildName(guild_id), - guild_id); - } - - if (!guild_mgr.SetGuild(charid, guild_id, GUILD_MEMBER)) { - c->Message(Chat::Red, "Error putting '%s' into guild %d", sep->arg[2], guild_id); - } - else { - c->Message(Chat::White, "%s has been put into guild %d", sep->arg[2], guild_id); - } - } - } - /*else if (strcasecmp(sep->arg[1], "setdoor") == 0 && admin >= minStatusToEditOtherGuilds) { - - if (!sep->IsNumber(2)) - c->Message(Chat::White, "Usage: #guild setdoor guildEQid (0 = delete guilddoor)"); - else { - // guild doors - if((!guilds[atoi(sep->arg[2])].databaseID) && (atoi(sep->arg[2])!=0) ) - { - - c->Message(Chat::White, "These is no guild with this guildEQid"); - } - else { - c->SetIsSettingGuildDoor(true); - c->Message(Chat::White, "Click on a door you want to become a guilddoor"); - c->SetSetGuildDoorID(atoi(sep->arg[2])); - } - } - }*/ - else if (strcasecmp(sep->arg[1], "setrank") == 0) { - int rank = atoi(sep->arg[3]); - if (!sep->IsNumber(3)) { - c->Message(Chat::White, "Usage: #guild setrank charname rank"); - } - else if (rank < 0 || rank > GUILD_MAX_RANK) { - c->Message(Chat::White, "Error: invalid rank #."); - } - else { - uint32 charid = database.GetCharacterID(sep->arg[2]); - if (charid == 0) { - c->Message(Chat::Red, "Unable to find character '%s'", charid); - return; - } - - //we could do the checking we need for guild_mgr.CheckGMStatus, but im lazy right now - if (admin < minStatusToEditOtherGuilds) { - c->Message(Chat::Red, "Access denied."); - return; - } - - LogGuilds("[{}]: Setting [{}] ([{}])'s guild rank to [{}] with GM command", - c->GetName(), - sep->arg[2], - charid, - rank); - - if (!guild_mgr.SetGuildRank(charid, rank)) { - c->Message(Chat::Red, "Error while setting rank %d on '%s'.", rank, sep->arg[2]); - } - else { - c->Message(Chat::White, "%s has been set to rank %d", sep->arg[2], rank); - } - } - } - else if (strcasecmp(sep->arg[1], "create") == 0) { - if (sep->arg[3][0] == 0) { - c->Message(Chat::White, "Usage: #guild create {guildleader charname or CharID} guild name"); - } - else if (!worldserver.Connected()) { - c->Message(Chat::White, "Error: World server dirconnected"); - } - else { - uint32 leader = 0; - if (sep->IsNumber(2)) { - leader = atoi(sep->arg[2]); - } - else if ((leader = database.GetCharacterID(sep->arg[2])) != 0) { - //got it from the db.. - } - else { - c->Message(Chat::Red, "Unable to find char '%s'", sep->arg[2]); - return; - } - if (leader == 0) { - c->Message(Chat::White, "Guild leader not found."); - return; - } - - uint32 tmp = guild_mgr.FindGuildByLeader(leader); - if (tmp != GUILD_NONE) { - c->Message( - Chat::White, - "Error: %s already is the leader of DB# %i '%s'.", - sep->arg[2], - tmp, - guild_mgr.GetGuildName(tmp)); - } - else { - - if (admin < minStatusToEditOtherGuilds) { - c->Message(Chat::Red, "Access denied."); + fmt::format( + "{} ({}) is already the leader of {} ({}).", + leader_name, + leader_id, + guild_mgr.GetGuildNameByID(guild_id), + guild_id + ).c_str() + ); + } else { + if (c->Admin() < minStatusToEditOtherGuilds) { + c->Message(Chat::White, "You cannot edit other peoples' guilds."); return; } - uint32 id = guild_mgr.CreateGuild(sep->argplus[3], leader); + auto guild_name = sep->argplus[3]; + auto guild_id = guild_mgr.CreateGuild(sep->argplus[3], leader_id); - LogGuilds("[{}]: Creating guild [{}] with leader [{}] with GM command. It was given id [{}]", - c->GetName(), - sep->argplus[3], - leader, - (unsigned long) id); + LogGuilds( + "[{}]: Creating guild [{}] with leader [{}] with GM command. It was given id [{}]", + c->GetName(), + guild_name, + leader_id, + guild_id + ); - if (id == GUILD_NONE) { + if (guild_id == GUILD_NONE) { c->Message(Chat::White, "Guild creation failed."); - } - else { - c->Message(Chat::White, "Guild created: Leader: %i, number %i: %s", leader, id, sep->argplus[3]); + } else { + c->Message( + Chat::White, + fmt::format( + "Guild Created | Name: {} ({}) Leader: {} ({})", + guild_name, + guild_id, + leader_name, + leader_id + ).c_str() + ); - if (!guild_mgr.SetGuild(leader, id, GUILD_LEADER)) { + if (!guild_mgr.SetGuild(leader_id, guild_id, GUILD_LEADER)) { c->Message( Chat::White, - "Unable to set guild leader's guild in the database. Your going to have to run #guild set" + fmt::format( + "Unable to put {} ({}) in to {} ({}) in the database.", + leader_name, + leader_id, + guild_name, + guild_id + ).c_str() ); + + c->Message(Chat::White, "Note: Run #guild set to resolve this."); } } - } } - } - else if (strcasecmp(sep->arg[1], "delete") == 0) { + } else if (is_delete) { if (!sep->IsNumber(2)) { - c->Message(Chat::White, "Usage: #guild delete guildID"); - } - else if (!worldserver.Connected()) { - c->Message(Chat::White, "Error: World server dirconnected"); - } - else { - uint32 id = atoi(sep->arg[2]); - - if (!guild_mgr.GuildExists(id)) { - c->Message(Chat::White, "Guild %d does not exist!", id); + c->Message(Chat::White, "Usage: #guild delete [Guild ID]"); + } else { + auto guild_id = std::stoul(sep->arg[2]); + if (!guild_mgr.GuildExists(guild_id)) { + c->Message( + Chat::White, + fmt::format( + "Guild ID {} could not be found.", + guild_id + ).c_str() + ); return; } - if (admin < minStatusToEditOtherGuilds) { - //this person is not allowed to just edit any guild, check this guild's min status. - if (c->GuildID() != id) { - c->Message(Chat::Red, "Access denied to edit other people's guilds"); + if (c->Admin() < minStatusToEditOtherGuilds) { + if (c->GuildID() != guild_id) { + c->Message(Chat::White, "You cannot edit other peoples' guilds."); return; - } - else if (!guild_mgr.CheckGMStatus(id, admin)) { - c->Message(Chat::Red, "Access denied to edit your guild with GM commands."); + } else if (!guild_mgr.CheckGMStatus(guild_id, c->Admin())) { + c->Message(Chat::White, "You cannot edit your current guild, your status is not high enough."); return; } } - LogGuilds("[{}]: Deleting guild [{}] ([{}]) with GM command", c->GetName(), - guild_mgr.GetGuildName(id), id); + LogGuilds( + "[{}]: Deleting guild [{}] ([{}]) with GM command", + c->GetName(), + guild_mgr.GetGuildNameByID(guild_id), + guild_id + ); - if (!guild_mgr.DeleteGuild(id)) { - c->Message(Chat::White, "Guild delete failed."); + c->Message( + Chat::White, + fmt::format( + "Guild {} Deleted | Name: {} ({})", + guild_mgr.DeleteGuild(guild_id) ? "Successfully" : "Unsuccessfully", + guild_mgr.GetGuildNameByID(guild_id), + guild_id + ).c_str() + ); + } + } else if (is_help) { + c->Message(Chat::White, "#guild create [Character ID|Character Name] [Guild Name]"); + c->Message(Chat::White, "#guild delete [Guild ID]"); + c->Message(Chat::White, "#guild help"); + c->Message(Chat::White, "#guild info [Guild ID]"); + c->Message(Chat::White, "#guild list"); + c->Message(Chat::White, "#guild rename [Guild ID] [New Name]"); + c->Message(Chat::White, "#guild set [Character ID|Character Name] [Guild ID] (Guild ID 0 is Guildless)"); + c->Message(Chat::White, "#guild setleader [Guild ID] [Character ID|Character Name]"); + c->Message(Chat::White, "#guild setrank [Character ID|Character Name] [Rank]"); + c->Message(Chat::White, "#guild status [Character ID|Character Name]"); + } else if (is_info) { + if (arguments != 2 && c->IsInAGuild()) { + if (c->Admin() >= minStatusToEditOtherGuilds) { + c->Message(Chat::White, "#guild info [Guild ID]"); + } else { + c->Message(Chat::White, "You cannot edit other peoples' guilds."); } - else { - c->Message(Chat::White, "Guild %d deleted.", id); + } else { + auto guild_id = GUILD_NONE; + if (arguments != 2 || !sep->IsNumber(2)) { + guild_id = c->GuildID(); + } else if (c->Admin() >= minStatusToEditOtherGuilds) { + guild_id = std::stoul(sep->arg[2]); + } + + if (guild_id != GUILD_NONE) { + guild_mgr.DescribeGuild(c, guild_id); } } - } - else if (strcasecmp(sep->arg[1], "rename") == 0) { - if ((!sep->IsNumber(2)) || sep->arg[3][0] == 0) { - c->Message(Chat::White, "Usage: #guild rename guildID newname"); - } - else if (!worldserver.Connected()) { - c->Message(Chat::White, "Error: World server dirconnected"); - } - else { - uint32 id = atoi(sep->arg[2]); - - if (!guild_mgr.GuildExists(id)) { - c->Message(Chat::White, "Guild %d does not exist!", id); - return; - } - - if (admin < minStatusToEditOtherGuilds) { - //this person is not allowed to just edit any guild, check this guild's min status. - if (c->GuildID() != id) { - c->Message(Chat::Red, "Access denied to edit other people's guilds"); - return; - } - else if (!guild_mgr.CheckGMStatus(id, admin)) { - c->Message(Chat::Red, "Access denied to edit your guild with GM commands."); - return; - } - } - - LogGuilds("[{}]: Renaming guild [{}] ([{}]) to [{}] with GM command", c->GetName(), - guild_mgr.GetGuildName(id), id, sep->argplus[3]); - - if (!guild_mgr.RenameGuild(id, sep->argplus[3])) { - c->Message(Chat::White, "Guild rename failed."); - } - else { - c->Message(Chat::White, "Guild %d renamed to %s", id, sep->argplus[3]); - } - } - } - else if (strcasecmp(sep->arg[1], "setleader") == 0) { - if (sep->arg[3][0] == 0 || !sep->IsNumber(2)) { - c->Message(Chat::White, "Usage: #guild setleader guild_id {guildleader charname or CharID}"); - } - else if (!worldserver.Connected()) { - c->Message(Chat::White, "Error: World server dirconnected"); - } - else { - uint32 leader = 0; - if (sep->IsNumber(2)) { - leader = atoi(sep->arg[2]); - } - else if ((leader = database.GetCharacterID(sep->arg[2])) != 0) { - //got it from the db.. - } - else { - c->Message(Chat::Red, "Unable to find char '%s'", sep->arg[2]); - return; - } - - uint32 tmpdb = guild_mgr.FindGuildByLeader(leader); - if (leader == 0) { - c->Message(Chat::White, "New leader not found."); - } - else if (tmpdb != 0) { - c->Message(Chat::White, "Error: %s already is the leader of guild # %i", sep->arg[2], tmpdb); - } - else { - uint32 id = atoi(sep->arg[2]); - - if (!guild_mgr.GuildExists(id)) { - c->Message(Chat::White, "Guild %d does not exist!", id); - return; - } - - if (admin < minStatusToEditOtherGuilds) { - //this person is not allowed to just edit any guild, check this guild's min status. - if (c->GuildID() != id) { - c->Message(Chat::Red, "Access denied to edit other people's guilds"); - return; - } - else if (!guild_mgr.CheckGMStatus(id, admin)) { - c->Message(Chat::Red, "Access denied to edit your guild with GM commands."); - return; - } - } - - LogGuilds("[{}]: Setting leader of guild [{}] ([{}]) to [{}] with GM command", c->GetName(), - guild_mgr.GetGuildName(id), id, leader); - - if (!guild_mgr.SetGuildLeader(id, leader)) { - c->Message(Chat::White, "Guild leader change failed."); - } - else { - c->Message(Chat::White, "Guild leader changed: guild # %d, Leader: %s", id, sep->argplus[3]); - } - } - } - } - else if (strcasecmp(sep->arg[1], "list") == 0) { - if (admin < minStatusToEditOtherGuilds) { - c->Message(Chat::Red, "Access denied."); + } else if (is_list) { + if (c->Admin() < minStatusToEditOtherGuilds) { + c->Message(Chat::White, "You cannot edit other peoples' guilds."); return; } + guild_mgr.ListGuilds(c); - } - else { - c->Message(Chat::White, "Unknown guild command, try #guild help"); + } else if (is_rename) { + if ( + arguments != 3 || + !sep->IsNumber(2) + ) { + c->Message(Chat::White, "Usage: #guild rename [Guild ID] [New Guild Name]"); + } else { + auto guild_id = std::stoul(sep->arg[2]); + if (!guild_mgr.GuildExists(guild_id)) { + c->Message( + Chat::White, + fmt::format( + "Guild ID {} could not be found.", + guild_id + ).c_str() + ); + return; + } + + if (c->Admin() < minStatusToEditOtherGuilds) { + if (c->GuildID() != guild_id) { + c->Message(Chat::White, "You cannot edit other peoples' guilds."); + return; + } else if (!guild_mgr.CheckGMStatus(guild_id, c->Admin())) { + c->Message(Chat::White, "You cannot edit your current guild, your status is not high enough."); + return; + } + } + + auto new_guild_name = sep->argplus[3]; + LogGuilds( + "[{}]: Renaming guild [{}] ([{}]) to [{}] with GM command", + c->GetName(), + guild_mgr.GetGuildNameByID(guild_id), + guild_id, + new_guild_name + ); + + c->Message( + Chat::White, + fmt::format( + "Guild {} Renamed | Name: {} ({})", + guild_mgr.RenameGuild(guild_id, new_guild_name) ? "Successfully" : "Unsuccessfully", + new_guild_name, + guild_id + ).c_str() + ); + } + } else if (is_set) { + if ( + arguments != 3 || + !sep->IsNumber(3) + ) { + c->Message(Chat::White, "#guild set [Character ID|Character Name] [Guild ID] (Guild ID 0 is Guildless)"); + return; + } else { + auto guild_id = std::stoul(sep->arg[3]); + if (!guild_id) { + guild_id = GUILD_NONE; + } else if (!guild_mgr.GuildExists(guild_id)) { + c->Message( + Chat::White, + fmt::format( + "Guild ID {} could not be found.", + guild_id + ).c_str() + ); + return; + } + + auto character_id = ( + sep->IsNumber(2) ? + std::stoul(sep->arg[2]) : + database.GetCharacterID(sep->arg[2]) + ); + auto character_name = database.GetCharNameByID(character_id); + if (!character_id || character_name.empty()) { + c->Message( + Chat::White, + fmt::format( + "Character ID {} could not be found.", + character_id + ).c_str() + ); + return; + } + + if (c->Admin() < minStatusToEditOtherGuilds && guild_id != c->GuildID()) { + c->Message(Chat::White, "You cannot edit other peoples' guilds."); + return; + } + + if (!guild_id || guild_id == GUILD_NONE) { + LogGuilds( + "[{}]: Removing [{}] ([{}]) from guild with GM command", + c->GetName(), + character_name, + character_id + ); + } else { + LogGuilds( + "[{}]: Putting [{}] ([{}]) into guild [{}] ([{}]) with GM command", + c->GetName(), + character_name, + character_id, + guild_mgr.GetGuildNameByID(guild_id), + guild_id + ); + } + + if (guild_id && guild_id != GUILD_NONE) { + c->Message( + Chat::White, + fmt::format( + "{} ({}) has {} put into {} ({}).", + character_name, + character_id, + guild_mgr.SetGuild(character_id, guild_id, GUILD_MEMBER) ? "been" : "failed to be", + guild_mgr.GetGuildNameByID(guild_id), + guild_id + ).c_str() + ); + } else { + c->Message( + Chat::White, + fmt::format( + "{} ({}) is now Guildless.", + character_name, + character_id + ).c_str() + ); + } + } + } else if (is_set_leader) { + if ( + arguments != 3 || + !sep->IsNumber(2) + ) { + c->Message(Chat::White, "Usage: #guild setleader [Guild ID] [Character ID|Character Name]"); + } else { + auto leader_id = ( + sep->IsNumber(2) ? + std::stoul(sep->arg[2]) : + database.GetCharacterID(sep->arg[2]) + ); + auto leader_name = database.GetCharNameByID(leader_id); + if (!leader_id || leader_name.empty()) { + c->Message( + Chat::White, + fmt::format( + "Character ID {} could not be found.", + leader_id + ).c_str() + ); + return; + } + + auto guild_id = guild_mgr.FindGuildByLeader(leader_id); + if (guild_id != 0) { + c->Message( + Chat::White, + fmt::format( + "{} ({}) is already the leader of {} ({}).", + leader_name, + leader_id, + guild_mgr.GetGuildNameByID(guild_id), + guild_id + ).c_str() + ); + } + else { + auto guild_id = std::stoul(sep->arg[2]); + if (!guild_mgr.GuildExists(guild_id)) { + c->Message( + Chat::White, + fmt::format( + "Guild ID {} could not be found.", + guild_id + ).c_str() + ); + return; + } + + if (c->Admin() < minStatusToEditOtherGuilds) { + if (c->GuildID() != guild_id) { + c->Message(Chat::White, "You cannot edit other peoples' guilds."); + return; + } else if (!guild_mgr.CheckGMStatus(guild_id, c->Admin())) { + c->Message(Chat::White, "You cannot edit your current guild, your status is not high enough."); + return; + } + } + + LogGuilds( + "[{}]: Setting leader of guild [{}] ([{}]) to [{}] with GM command", + c->GetName(), + guild_mgr.GetGuildNameByID(guild_id), + guild_id, + leader_id + ); + + c->Message( + Chat::White, + fmt::format( + "Guild Leader {} Changed | Name: {} ({})", + guild_mgr.SetGuildLeader(guild_id, leader_id) ? "Successfully" : "Unsuccessfully", + guild_mgr.GetGuildNameByID(guild_id), + guild_id + ).c_str() + ); + } + } + } else if (is_set_rank) { + auto rank = static_cast(std::stoul(sep->arg[3])); + if (!sep->IsNumber(3)) { + c->Message(Chat::White, "#guild setrank [Character ID|Character Name] [Rank]"); + } else if (rank < 0 || rank > GUILD_MAX_RANK) { + c->Message( + Chat::White, + fmt::format( + "Guild Ranks are from 0 to {}.", + GUILD_MAX_RANK + ).c_str() + ); + } else { + auto character_id = ( + sep->IsNumber(2) ? + std::stoul(sep->arg[2]) : + database.GetCharacterID(sep->arg[2]) + ); + auto character_name = database.GetCharNameByID(character_id); + if (!character_id || character_name.empty()) { + c->Message( + Chat::White, + fmt::format( + "Character ID {} could not be found.", + character_id + ).c_str() + ); + return; + } + + if (!guild_mgr.IsCharacterInGuild(character_id)) { + c->Message( + Chat::White, + fmt::format( + "{} ({}) is not in a guild.", + character_name, + character_id + ).c_str() + ); + return; + } + + if (c->Admin() < minStatusToEditOtherGuilds && character_id != c->CharacterID()) { + c->Message(Chat::White, "You cannot edit other peoples' guilds."); + return; + } + + LogGuilds( + "[{}]: Setting [{}] ([{}])'s guild rank to [{}] with GM command", + c->GetName(), + sep->arg[2], + character_id, + rank + ); + + c->Message( + Chat::White, + fmt::format( + "{} ({}) has {} to rank {} ({}).", + character_name, + character_id, + guild_mgr.SetGuildRank(character_id, rank) ? "been set" : "failed to be set", + !guild_mgr.GetGuildRankName(guild_mgr.GetGuildIDByCharacterID(character_id), rank).empty() ? guild_mgr.GetGuildRankName(guild_mgr.GetGuildIDByCharacterID(character_id), rank) : "Nameless", + rank + ).c_str() + ); + } + } else if (is_status) { + auto client = ( + target ? + target : + ( + arguments == 2 ? + entity_list.GetClientByName(sep->arg[2]) : + c + ) + ); + if (!client) { + c->Message(Chat::White, "You must target someone or specify a character name."); + } else if (c->Admin() < minStatusToEditOtherGuilds && client->GuildID() != c->GuildID()) { + c->Message(Chat::White, "You cannot edit other peoples' guilds."); + } else { + if (!client->IsInAGuild()) { + c->Message( + Chat::White, + fmt::format( + "{} is not in a guild.", + client->GetCleanName() + ).c_str() + ); + } else if (guild_mgr.IsGuildLeader(client->GuildID(), client->CharacterID())) { + c->Message( + Chat::White, + fmt::format( + "{} is the leader of {}.", + client->GetName(), + guild_mgr.GetGuildNameByID(client->GuildID()) + ).c_str() + ); + } else { + c->Message( + Chat::White, + fmt::format( + "{} is a(n) {} of {}.", + client->GetName(), + guild_mgr.GetRankName(client->GuildID(), client->GuildRank()), + guild_mgr.GetGuildNameByID(client->GuildID()) + ).c_str() + ); + } + } } } -/* -bool helper_guild_edit(Client *c, uint32 dbid, uint32 eqid, uint8 rank, const char* what, const char* value) { - struct GuildRankLevel_Struct grl; - strcpy(grl.rankname, guild_mgr.GetRankName(eqid, rank)); - grl.demote = guilds[eqid].rank[rank].demote; - grl.heargu = guilds[eqid].rank[rank].heargu; - grl.invite = guilds[eqid].rank[rank].invite; - grl.motd = guilds[eqid].rank[rank].motd; - grl.promote = guilds[eqid].rank[rank].promote; - grl.remove = guilds[eqid].rank[rank].remove; - grl.speakgu = guilds[eqid].rank[rank].speakgu; - grl.warpeace = guilds[eqid].rank[rank].warpeace; - - if (strcasecmp(what, "title") == 0) { - if (strlen(value) > 100) - c->Message(Chat::White, "Error: Title has a maxium length of 100 characters."); - else - strcpy(grl.rankname, value); - } - else if (rank == 0) - c->Message(Chat::White, "Error: Rank 0's permissions can not be changed."); - else { - if (!(strlen(value) == 1 && (value[0] == '0' || value[0] == '1'))) - - return false; - if (strcasecmp(what, "demote") == 0) - grl.demote = (value[0] == '1'); - else if (strcasecmp(what, "heargu") == 0) - grl.heargu = (value[0] == '1'); - else if (strcasecmp(what, "invite") == 0) - grl.invite = (value[0] == '1'); - else if (strcasecmp(what, "motd") == 0) - grl.motd = (value[0] == '1'); - else if (strcasecmp(what, "promote") == 0) - grl.promote = (value[0] == '1'); - else if (strcasecmp(what, "remove") == 0) - - grl.remove = (value[0] == '1'); - else if (strcasecmp(what, "speakgu") == 0) - grl.speakgu = (value[0] == '1'); - else if (strcasecmp(what, "warpeace") == 0) - grl.warpeace = (value[0] == '1'); - else - c->Message(Chat::White, "Error: Permission name not recognized."); - } - if (!database.EditGuild(dbid, rank, &grl)) - c->Message(Chat::White, "Error: database.EditGuild() failed"); - return true; -}*/ - diff --git a/zone/guild_mgr.cpp b/zone/guild_mgr.cpp index e3c4e6071..81e221b6b 100644 --- a/zone/guild_mgr.cpp +++ b/zone/guild_mgr.cpp @@ -190,53 +190,123 @@ uint8 *ZoneGuildManager::MakeGuildMembers(uint32 guild_id, const char *prefix_na } void ZoneGuildManager::ListGuilds(Client *c) const { - c->Message(Chat::White, "Listing guilds on the server:"); - char leadername[64]; - std::map::const_iterator cur, end; - cur = m_guilds.begin(); - end = m_guilds.end(); - int r = 0; - for(; cur != end; ++cur) { - leadername[0] = '\0'; - database.GetCharName(cur->second->leader_char_id, leadername); - if (leadername[0] == '\0') - c->Message(Chat::White, " Guild #%i <%s>", cur->first, cur->second->name.c_str()); - else - c->Message(Chat::White, " Guild #%i <%s> Leader: %s", cur->first, cur->second->name.c_str(), leadername); - r++; + if (m_guilds.size()) { + c->Message( + Chat::White, + fmt::format( + "Listing {} Guild{}.", + m_guilds.size(), + m_guilds.size() != 1 ? "s" : "" + ).c_str() + ); + + for (const auto& guild : m_guilds) { + auto leader_name = database.GetCharNameByID(guild.second->leader_char_id); + c->Message( + Chat::White, + fmt::format( + "Guild {} | {}Name: {}", + guild.first, + ( + !leader_name.empty() ? + fmt::format( + "Leader: {} ({}) ", + leader_name, + guild.second->leader_char_id + ) : + "" + ), + guild.second->name + ).c_str() + ); + } + } else { + c->Message(Chat::White, "There are no Guilds to list."); } - c->Message(Chat::White, "%i guilds listed.", r); } void ZoneGuildManager::DescribeGuild(Client *c, uint32 guild_id) const { std::map::const_iterator res; res = m_guilds.find(guild_id); - if(res == m_guilds.end()) { - c->Message(Chat::White, "Guild %d not found.", guild_id); + if (res == m_guilds.end()) { + c->Message( + Chat::White, + fmt::format( + "Guild ID {} could not be found.", + guild_id + ).c_str() + ); return; } const GuildInfo *info = res->second; - c->Message(Chat::White, "Guild info DB# %i <%s>", guild_id, info->name.c_str()); + auto leader_name = database.GetCharNameByID(info->leader_char_id); + std::string popup_text = ""; + popup_text += fmt::format( + "", + info->name, + guild_id + ); + popup_text += fmt::format( + "", + leader_name, + info->leader_char_id + ); + popup_text += "

"; + popup_text += ""; + popup_text += ""; + popup_text += ""; + popup_text += ""; + popup_text += ""; + popup_text += ""; + popup_text += ""; + popup_text += ""; + popup_text += ""; + popup_text += ""; + popup_text += ""; - char leadername[64]; - database.GetCharName(info->leader_char_id, leadername); - c->Message(Chat::White, "Guild Leader: %s", leadername); - - char permbuffer[256]; - uint8 i; - for (i = 0; i <= GUILD_MAX_RANK; i++) { - char *permptr = permbuffer; - uint8 r; - for(r = 0; r < _MaxGuildAction; r++) - permptr += sprintf(permptr, " %s: %c", GuildActionNames[r], info->ranks[i].permissions[r]?'Y':'N'); - - c->Message(Chat::White, "Rank %i: %s", i, info->ranks[i].name.c_str()); - c->Message(Chat::White, "Permissions: %s", permbuffer); + for (uint8 guild_rank = 0; guild_rank <= GUILD_MAX_RANK; guild_rank++) { + auto can_hear_guild_chat = info->ranks[guild_rank].permissions[GUILD_HEAR] ? "" : ""; + auto can_speak_guild_chat = info->ranks[guild_rank].permissions[GUILD_SPEAK] ? "" : ""; + auto can_invite = info->ranks[guild_rank].permissions[GUILD_INVITE] ? "" : ""; + auto can_remove = info->ranks[guild_rank].permissions[GUILD_REMOVE] ? "" : ""; + auto can_promote = info->ranks[guild_rank].permissions[GUILD_PROMOTE] ? "" : ""; + auto can_demote = info->ranks[guild_rank].permissions[GUILD_DEMOTE] ? "" : ""; + auto can_set_motd = info->ranks[guild_rank].permissions[GUILD_MOTD] ? "" : ""; + auto can_war_peace = info->ranks[guild_rank].permissions[GUILD_WARPEACE] ? "" : ""; + popup_text += fmt::format( + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "", + !info->ranks[guild_rank].name.empty() ? info->ranks[guild_rank].name : "Nameless", + guild_rank, + can_demote, + can_hear_guild_chat, + can_invite, + can_promote, + can_remove, + can_set_motd, + can_speak_guild_chat, + can_war_peace + ); } + popup_text += "
Name{}Guild ID{}
Leader{}Character ID{}
RankDemoteHear Guild ChatInvitePromoteRemoveSet MOTDSpeak Guild ChatWar/Peace
{} ({}){}{}{}{}{}{}{}{}
"; + + c->SendPopupToClient( + "Guild Information", + popup_text.c_str() + ); } //in theory, we could get a pile of unused entries in this array, but only if