From f666fd38beefb554d90503811e5a43d504a18345 Mon Sep 17 00:00:00 2001 From: David Athay Date: Tue, 27 Jan 2009 17:14:09 +0000 Subject: Changed guild member permissions. Restricted players to owning only 1 guild. --- src/account-server/dalstorage.cpp | 2 +- src/account-server/dalstorage.hpp | 2 +- src/chat-server/chathandler.cpp | 3 ++ src/chat-server/chathandler.hpp | 5 +++ src/chat-server/guild.cpp | 35 ++++++++++++--------- src/chat-server/guild.hpp | 19 +++--------- src/chat-server/guildhandler.cpp | 65 ++++++++++++++++++++++++++++++--------- src/chat-server/guildmanager.cpp | 54 ++++++++++++++++++++++++++++---- src/chat-server/guildmanager.hpp | 11 +++++++ src/defines.h | 25 +++++++++++++-- 10 files changed, 167 insertions(+), 54 deletions(-) (limited to 'src') diff --git a/src/account-server/dalstorage.cpp b/src/account-server/dalstorage.cpp index 6547d84a..55a31d30 100644 --- a/src/account-server/dalstorage.cpp +++ b/src/account-server/dalstorage.cpp @@ -996,7 +996,7 @@ void DALStorage::removeGuildMember(int guildId, int memberId) } } -void DALStorage::setMemberRights(int memberId, int rights) +void DALStorage::setMemberRights(int guildId, int memberId, int rights) { std::ostringstream sql; diff --git a/src/account-server/dalstorage.hpp b/src/account-server/dalstorage.hpp index 71c3dfa3..fb8ae138 100644 --- a/src/account-server/dalstorage.hpp +++ b/src/account-server/dalstorage.hpp @@ -250,7 +250,7 @@ class DALStorage * Save guild member rights */ void - setMemberRights(int memberId, int rights); + setMemberRights(int guildId, int memberId, int rights); /** * Get guild list diff --git a/src/chat-server/chathandler.cpp b/src/chat-server/chathandler.cpp index 0fa39400..9240d957 100644 --- a/src/chat-server/chathandler.cpp +++ b/src/chat-server/chathandler.cpp @@ -214,6 +214,9 @@ void ChatHandler::processMessage(NetComputer *comp, MessageIn &message) handleGuildMemberLevelChange(computer, message); break; + case PCMSG_GUILD_KICK_MEMBER: + handleGuildMemberKick(computer, message); + case PCMSG_GUILD_QUIT: handleGuildQuit(computer, message); break; diff --git a/src/chat-server/chathandler.hpp b/src/chat-server/chathandler.hpp index efd80320..f1a84484 100644 --- a/src/chat-server/chathandler.hpp +++ b/src/chat-server/chathandler.hpp @@ -233,6 +233,11 @@ class ChatHandler : public ConnectionHandler void handleGuildMemberLevelChange(ChatClient &client, MessageIn &msg); + /** + * Deal with kicking a member + */ + void handleGuildMemberKick(ChatClient &client, MessageIn &msg); + /** * Deal with leaving a guild. */ diff --git a/src/chat-server/guild.cpp b/src/chat-server/guild.cpp index 46fa6cb9..6637ead0 100644 --- a/src/chat-server/guild.cpp +++ b/src/chat-server/guild.cpp @@ -19,6 +19,7 @@ */ #include "guild.hpp" +#include "defines.h" #include @@ -49,39 +50,43 @@ void Guild::addMember(int playerId, int permissions) void Guild::removeMember(int playerId) { - if (checkLeader(playerId)) + if (getOwner() == playerId) { // if the leader is leaving, assign next member as leader std::list::iterator itr = mMembers.begin(); ++itr; if (itr != mMembers.end()) - setLeader((*itr)->mId); + setOwner((*itr)->mId); } GuildMember *member = getMember(playerId); if (member) mMembers.remove(member); } -bool Guild::checkLeader(int playerId) +int Guild::getOwner() { - int leader = 0; - GuildMember *member = getMember(playerId); - // check member exists - if (member) - leader = member->mPermissions; - // check permissions - if (leader == GuildMember::LEADER) - return true; - return false; + std::list::iterator itr = mMembers.begin(); + std::list::iterator itr_end = mMembers.end(); + + while (itr != itr_end) + { + if ((*itr)->mPermissions == GAL_OWNER) + { + return (*itr)->mId; + } + + ++itr; + } + return 0; } -void Guild::setLeader(int playerId) +void Guild::setOwner(int playerId) { GuildMember *member = getMember(playerId); if (member) { - member->mPermissions = GuildMember::LEADER; + member->mPermissions = GAL_OWNER; } } @@ -122,7 +127,7 @@ bool Guild::canInvite(int playerId) // Guild members with permissions above NONE can invite // Check that guild members permissions are not NONE GuildMember *member = getMember(playerId); - if (member->mPermissions > GuildMember::NONE) + if (member->mPermissions & GAL_INVITE) return true; return false; } diff --git a/src/chat-server/guild.hpp b/src/chat-server/guild.hpp index 330c275f..26387382 100644 --- a/src/chat-server/guild.hpp +++ b/src/chat-server/guild.hpp @@ -31,15 +31,6 @@ struct GuildMember { public: - /** - * Permissions - * Members with NONE cannot invite users or set permissions - * Members with COMMANDER can invite other users but - * cannot set permissions - * Members with LEADER can invite users and set permissions - */ - enum { NONE = 0, COMMANDER, LEADER }; - int mId; std::string mName; int mPermissions; @@ -66,7 +57,7 @@ class Guild * Add a member to the guild. * Removes a user from invite list if on it */ - void addMember(int playerId, int permissions = GuildMember::NONE); + void addMember(int playerId, int permissions = 0); /** * Remove a member from the guild. @@ -74,14 +65,14 @@ class Guild void removeMember(int playerId); /** - * Check player is the leader of the guild. + * Return owner id */ - bool checkLeader(int playerId); + int getOwner(); /** - * Set player as leader of the guild. + * Set player as owner of the guild. */ - void setLeader(int playerId); + void setOwner(int playerId); /** * Set the ID of the guild. diff --git a/src/chat-server/guildhandler.cpp b/src/chat-server/guildhandler.cpp index 8873988d..9d2c159e 100644 --- a/src/chat-server/guildhandler.cpp +++ b/src/chat-server/guildhandler.cpp @@ -146,16 +146,24 @@ ChatHandler::handleGuildCreation(ChatClient &client, MessageIn &msg) std::string guildName = msg.readString(); if (!guildManager->doesExist(guildName)) { - // Guild doesnt already exist so create it - Guild *guild = guildManager->createGuild(guildName, client.characterId); - reply.writeByte(ERRMSG_OK); - reply.writeString(guildName); - reply.writeShort(guild->getId()); - reply.writeShort(guild->getUserPermissions(client.characterId)); - - // Send autocreated channel id - ChatChannel* channel = joinGuildChannel(guildName, client); - reply.writeShort(channel->getId()); + // check the player hasnt already created a guild + if (guildManager->alreadyOwner(client.characterId)) + { + reply.writeByte(ERRMSG_LIMIT_REACHED); + } + else + { + // Guild doesnt already exist so create it + Guild *guild = guildManager->createGuild(guildName, client.characterId); + reply.writeByte(ERRMSG_OK); + reply.writeString(guildName); + reply.writeShort(guild->getId()); + reply.writeShort(guild->getUserPermissions(client.characterId)); + + // Send autocreated channel id + ChatChannel* channel = joinGuildChannel(guildName, client); + reply.writeShort(channel->getId()); + } } else { @@ -303,7 +311,8 @@ ChatHandler::handleGuildMemberLevelChange(ChatClient &client, MessageIn &msg) if (guild && c) { - if (guildManager->changeMemberLevel(&client, guild, c->getDatabaseID(), level) == 0) + int rights = guild->getUserPermissions(c->getDatabaseID()) | level; + if (guildManager->changeMemberLevel(&client, guild, c->getDatabaseID(), rights) == 0) { reply.writeByte(ERRMSG_OK); client.send(reply); @@ -314,6 +323,34 @@ ChatHandler::handleGuildMemberLevelChange(ChatClient &client, MessageIn &msg) client.send(reply); } +void ChatHandler::handleGuildMemberKick(ChatClient &client, MessageIn &msg) +{ + MessageOut reply(CPMSG_GUILD_KICK_MEMBER_RESPONSE); + short guildId = msg.readShort(); + std::string user = msg.readString(); + + Guild *guild = guildManager->findById(guildId); + Character *c = storage->getCharacter(user); + + if (guild && c) + { + if (guild->getUserPermissions(c->getDatabaseID()) & GAL_KICK) + { + reply.writeByte(ERRMSG_OK); + } + else + { + reply.writeByte(ERRMSG_INSUFFICIENT_RIGHTS); + } + } + else + { + reply.writeByte(ERRMSG_INVALID_ARGUMENT); + } + + client.send(reply); +} + void ChatHandler::handleGuildQuit(ChatClient &client, MessageIn &msg) { @@ -331,8 +368,8 @@ ChatHandler::handleGuildQuit(ChatClient &client, MessageIn &msg) reply.writeByte(ERRMSG_OK); reply.writeShort(guildId); - // Check if they are the leader, and if so, remove the guild channel - if (guild->checkLeader(client.characterId)) + // Check if there are no members left, remove the guild channel + if (guild->totalMembers() == 0) { chatChannelManager->removeChannel(chatChannelManager->getChannelId(guild->getName())); } @@ -361,7 +398,7 @@ ChatHandler::guildChannelTopicChange(ChatChannel *channel, int playerId, const s Guild *guild = guildManager->findByName(channel->getName()); if (guild) { - if(guild->checkLeader(playerId)) + if(guild->getUserPermissions(playerId) & GAL_TOPIC_CHANGE) { chatChannelManager->setChannelTopic(channel->getId(), topic); } diff --git a/src/chat-server/guildmanager.cpp b/src/chat-server/guildmanager.cpp index 1a61588c..cf4ceef6 100644 --- a/src/chat-server/guildmanager.cpp +++ b/src/chat-server/guildmanager.cpp @@ -47,15 +47,17 @@ Guild* GuildManager::createGuild(const std::string &name, int playerId) // Add guild to db storage->addGuild(guild); - // Make sure to add guild to mGuilds before searching for it to add the - // player + // Add guild, and add owner mGuilds.push_back(guild); + mOwners.push_back(playerId); + + // put the owner in the guild addGuildMember(guild, playerId); // Set and save the member rights - storage->setMemberRights(playerId, GuildMember::LEADER); + storage->setMemberRights(guild->getId(), playerId, GAL_OWNER); - guild->setLeader(playerId); + guild->setOwner(playerId); return guild; } @@ -65,6 +67,7 @@ void GuildManager::removeGuild(Guild *guild) if (!guild) return; storage->removeGuild(guild); + mOwners.remove(guild->getOwner()); mGuilds.remove(guild); delete guild; } @@ -81,12 +84,27 @@ void GuildManager::removeGuildMember(Guild *guild, int playerId) { if (!guild) return; + + // remove the user from the guild storage->removeGuildMember(guild->getId(), playerId); guild->removeMember(playerId); + + // if theres no more members left delete the guild if(guild->totalMembers() == 0) { removeGuild(guild); } + + // remove the user from owners list + std::list::iterator itr = mOwners.begin(); + std::list::iterator itr_end = mOwners.end(); + while (itr != itr_end) + { + if ((*itr) == playerId) + mOwners.remove(playerId); + + ++itr; + } } Guild *GuildManager::findById(short id) @@ -161,10 +179,10 @@ int GuildManager::changeMemberLevel(ChatClient *player, Guild *guild, { int playerLevel = guild->getUserPermissions(player->characterId); - if (playerLevel == GuildMember::LEADER) + if (playerLevel == GAL_OWNER) { // player can modify anyones permissions - guild->setUserPermissions(playerId, level); + setUserRights(guild, playerId, level); return 0; } } @@ -172,3 +190,27 @@ int GuildManager::changeMemberLevel(ChatClient *player, Guild *guild, return -1; } +bool GuildManager::alreadyOwner(int playerId) +{ + std::list::iterator itr = mOwners.begin(); + std::list::iterator itr_end = mOwners.end(); + + for (itr; itr != itr_end; ++itr) + { + if ((*itr) == playerId) + { + return true; + } + } + + return false; +} + +void GuildManager::setUserRights(Guild *guild, int playerId, int rights) +{ + // Set and save the member rights + storage->setMemberRights(guild->getId(), playerId, rights); + + // Set with guild + guild->setUserPermissions(playerId, rights); +} diff --git a/src/chat-server/guildmanager.hpp b/src/chat-server/guildmanager.hpp index 1471fe8e..0fb51460 100644 --- a/src/chat-server/guildmanager.hpp +++ b/src/chat-server/guildmanager.hpp @@ -106,8 +106,19 @@ class GuildManager int changeMemberLevel(ChatClient *player, Guild *guild, int playerId, int level); + /** + * Check if the player already owns a guild + */ + bool alreadyOwner(int playerId); + + /** + * Set user rights + */ + void setUserRights(Guild *guild, int playerId, int rights); + private: std::list mGuilds; + std::list mOwners; }; extern GuildManager *guildManager; diff --git a/src/defines.h b/src/defines.h index b722e0d1..e9f5b7b8 100644 --- a/src/defines.h +++ b/src/defines.h @@ -39,6 +39,23 @@ enum AL_ADMIN = 128 /**< User can perform administrator tasks. */ }; +/** + * Guild member permissions + * Members with NONE cannot invite users or set permissions + * Members with TOPIC_CHANGE can change the guild channel topic + * Members with INVIT can invite other users + * Memeber with KICK can remove other users + * Members with OWNER can invite users and set permissions + */ +enum +{ + GAL_NONE = 0, + GAL_TOPIC_CHANGE = 1, + GAL_INVITE = 2, + GAL_KICK = 4, + GAL_OWNER = 255 +}; + enum { // Network related @@ -223,9 +240,11 @@ enum { CPMSG_GUILD_QUIT_RESPONSE = 0x0361, // B error PCMSG_GUILD_PROMOTE_MEMBER = 0x0365, // W guild, S name, B rights CPMSG_GUILD_PROMOTE_MEMBER_RESPONSE = 0x0366, // B error + PCMSG_GUILD_KICK_MEMBER = 0x0370, // W guild, S name + CPMSG_GUILD_KICK_MEMBER_RESPONSE = 0x0371, // B error - CPMSG_GUILD_INVITED = 0x0370, // S char name, S guild name, W id - CPMSG_GUILD_REJOIN = 0x0371, // S name, W guild, W rights, W channel, S announce + CPMSG_GUILD_INVITED = 0x0388, // S char name, S guild name, W id + CPMSG_GUILD_REJOIN = 0x0389, // S name, W guild, W rights, W channel, S announce // Party PCMSG_PARTY_INVITE = 0x03A0, // S name @@ -300,7 +319,7 @@ enum { ERRMSG_ALREADY_TAKEN, // name used was already taken ERRMSG_SERVER_FULL, // the server is overloaded ERRMSG_TIME_OUT, // data failed to arrive in due time - ERRMSG_TOO_MANY_ATTACHMENTS // too many attachments in letter + ERRMSG_LIMIT_REACHED // limit reached }; // used in AGMSG_REGISTER_RESPONSE to show state of item db -- cgit v1.2.3-70-g09d2