diff options
author | David Athay <ko2fan@gmail.com> | 2008-08-13 15:31:48 +0000 |
---|---|---|
committer | David Athay <ko2fan@gmail.com> | 2008-08-13 15:31:48 +0000 |
commit | 67cb713c0fcd65f9f842c589c7e1c08f9af597f0 (patch) | |
tree | 408d79af670e143211deb311dc6aa291fbda9034 /src/chat-server | |
parent | 4e800b21494755958b0e30bba9045cee204b1a76 (diff) | |
download | manaserv-67cb713c0fcd65f9f842c589c7e1c08f9af597f0.tar.gz manaserv-67cb713c0fcd65f9f842c589c7e1c08f9af597f0.tar.bz2 manaserv-67cb713c0fcd65f9f842c589c7e1c08f9af597f0.tar.xz manaserv-67cb713c0fcd65f9f842c589c7e1c08f9af597f0.zip |
Added permission levels to guilds, and operator permissions to channels.
Diffstat (limited to 'src/chat-server')
-rw-r--r-- | src/chat-server/chatchannel.cpp | 51 | ||||
-rw-r--r-- | src/chat-server/chatchannel.hpp | 11 | ||||
-rw-r--r-- | src/chat-server/chatclient.hpp | 5 | ||||
-rw-r--r-- | src/chat-server/chathandler.cpp | 102 | ||||
-rw-r--r-- | src/chat-server/chathandler.hpp | 18 | ||||
-rw-r--r-- | src/chat-server/guild.cpp | 6 | ||||
-rw-r--r-- | src/chat-server/guild.hpp | 5 | ||||
-rw-r--r-- | src/chat-server/guildmanager.cpp | 19 | ||||
-rw-r--r-- | src/chat-server/guildmanager.hpp | 9 |
9 files changed, 224 insertions, 2 deletions
diff --git a/src/chat-server/chatchannel.cpp b/src/chat-server/chatchannel.cpp index 96de7335..a0317df9 100644 --- a/src/chat-server/chatchannel.cpp +++ b/src/chat-server/chatchannel.cpp @@ -22,6 +22,7 @@ */ #include <algorithm> +#include <sstream> #include "chat-server/chatchannel.hpp" #include "chat-server/chatclient.hpp" @@ -41,12 +42,31 @@ ChatChannel::ChatChannel(int id, bool ChatChannel::addUser(ChatClient *user) { + // First user is the channel owner + if (mRegisteredUsers.size() < 1) + { + mOwner = user->characterName; + setUserMode(user, 'o'); + } + // Check if the user already exists in the channel ChannelUsers::const_iterator i = mRegisteredUsers.begin(), i_end = mRegisteredUsers.end(); - if (std::find(i, i_end, user) != i_end) return false; + if (std::find(i, i_end, user) != i_end) + return false; + mRegisteredUsers.push_back(user); user->channels.push_back(this); + + // set user as logged in + setUserMode(user, 'l'); + + // if owner has rejoined, give them ops + if (user->characterName == mOwner) + { + setUserMode(user, 'o'); + } + return true; } @@ -58,6 +78,8 @@ bool ChatChannel::removeUser(ChatClient *user) mRegisteredUsers.erase(i); std::vector< ChatChannel * > &channels = user->channels; channels.erase(std::find(channels.begin(), channels.end(), this)); + std::map<ChatChannel*,std::string> &modes = user->userModes; + modes.erase(modes.begin(), modes.end()); return true; } @@ -68,6 +90,8 @@ void ChatChannel::removeAllUsers() { std::vector< ChatChannel * > &channels = (*i)->channels; channels.erase(std::find(channels.begin(), channels.end(), this)); + std::map<ChatChannel*,std::string> &modes = (*i)->userModes; + modes.erase(modes.begin(), modes.end()); } mRegisteredUsers.clear(); } @@ -76,3 +100,28 @@ bool ChatChannel::canJoin() const { return mJoinable; } + +void ChatChannel::setUserMode(ChatClient *user, unsigned char mode) +{ + std::map<ChatChannel*, std::string>::iterator itr = user->userModes.find(this); + if (itr != user->userModes.end()) + { + itr->second += mode; + } + else + { + std::stringstream ss; ss << mode; + user->userModes.insert(std::pair<ChatChannel*, std::string>(this, ss.str())); + } +} + +std::string ChatChannel::getUserMode(ChatClient *user) +{ + std::map<ChatChannel*, std::string>::iterator itr = user->userModes.find(this); + if (itr != user->userModes.end()) + { + return itr->second; + } + + return 0; +} diff --git a/src/chat-server/chatchannel.hpp b/src/chat-server/chatchannel.hpp index 5fce1abb..c0f2ae23 100644 --- a/src/chat-server/chatchannel.hpp +++ b/src/chat-server/chatchannel.hpp @@ -131,6 +131,16 @@ class ChatChannel */ bool canJoin() const; + /** + * Set user mode + */ + void setUserMode(ChatClient *, unsigned char mode); + + /** + * Get user mode + */ + std::string getUserMode(ChatClient *); + private: unsigned short mId; /**< The ID of the channel. */ std::string mName; /**< The name of the channel. */ @@ -138,6 +148,7 @@ class ChatChannel std::string mPassword; /**< The channel password. */ bool mJoinable; /**< Whether anyone can join. */ ChannelUsers mRegisteredUsers; /**< Users in this channel. */ + std::string mOwner; /**< Channel owner character name */ }; #endif diff --git a/src/chat-server/chatclient.hpp b/src/chat-server/chatclient.hpp index 59950577..162e88d1 100644 --- a/src/chat-server/chatclient.hpp +++ b/src/chat-server/chatclient.hpp @@ -24,6 +24,7 @@ #ifndef _TMWSERV_CHATCLIENT_H_ #define _TMWSERV_CHATCLIENT_H_ +#include <map> #include <string> #include <vector> @@ -45,7 +46,8 @@ class ChatClient : public NetComputer */ ChatClient(ENetPeer *peer): NetComputer(peer), - party(0) + party(0), + accountLevel(0) { } @@ -53,6 +55,7 @@ class ChatClient : public NetComputer std::vector< ChatChannel * > channels; Party* party; unsigned char accountLevel; + std::map<ChatChannel*, std::string> userModes; }; #endif diff --git a/src/chat-server/chathandler.cpp b/src/chat-server/chathandler.cpp index 946be36a..43a917ff 100644 --- a/src/chat-server/chathandler.cpp +++ b/src/chat-server/chathandler.cpp @@ -23,6 +23,8 @@ #include <list> #include <algorithm> +#include <string> +#include <sstream> #include "defines.h" #include "account-server/dalstorage.hpp" @@ -157,6 +159,13 @@ void ChatHandler::processMessage(NetComputer *comp, MessageIn &message) handleEnterChannelMessage(computer, message); break; + case PCMSG_USER_MODE: + handleModeChangeMessage(computer, message); + break; + + case PCMSG_KICK_USER: + handleKickUserMessage(computer, message); + case PCMSG_QUIT_CHANNEL: handleQuitChannelMessage(computer, message); break; @@ -193,6 +202,10 @@ void ChatHandler::processMessage(NetComputer *comp, MessageIn &message) handleGuildRetrieveMembers(computer, message); break; + case PCMSG_GUILD_PROMOTE_MEMBER: + handleGuildMemberLevelChange(computer, message); + break; + case PCMSG_GUILD_QUIT: handleGuildQuit(computer, message); break; @@ -361,6 +374,7 @@ void ChatHandler::handleEnterChannelMessage(ChatClient &client, MessageIn &msg) i != i_end; ++i) { reply.writeString((*i)->characterName); + reply.writeString(channel->getUserMode((*i))); } // Send an CPMSG_UPDATE_CHANNEL to warn other clients a user went // in the channel. @@ -378,6 +392,71 @@ void ChatHandler::handleEnterChannelMessage(ChatClient &client, MessageIn &msg) } void +ChatHandler::handleModeChangeMessage(ChatClient &client, MessageIn &msg) +{ + short channelId = msg.readShort(); + ChatChannel *channel = chatChannelManager->getChannel(channelId); + + if (channelId == 0 || !channel) + { + // invalid channel + return; + } + + if (channel->getUserMode(&client).find('o') != std::string::npos) + { + // invalid permissions + return; + } + + // get the user whos mode has been changed + std::string user = msg.readString(); + + // get the mode to change to + unsigned char mode = msg.readByte(); + channel->setUserMode(getClient(user), mode); + + // set the info to pass to all channel clients + std::stringstream info; + info << client.characterName << ":" << user << ":" << mode; + + warnUsersAboutPlayerEventInChat(channel, + info.str(), + CHAT_EVENT_MODE_CHANGE); +} + +void +ChatHandler::handleKickUserMessage(ChatClient &client, MessageIn &msg) +{ + short channelId = msg.readShort(); + ChatChannel *channel = chatChannelManager->getChannel(channelId); + + if (channelId == 0 || !channel) + { + // invalid channel + return; + } + + if (channel->getUserMode(&client).find('o') != std::string::npos) + { + // invalid permissions + return; + } + + // get the user whos being kicked + std::string user = msg.readString(); + + if (channel->removeUser(getClient(user))) + { + std::stringstream ss; + ss << client.characterName << ":" << user; + warnUsersAboutPlayerEventInChat(channel, + ss.str(), + CHAT_EVENT_KICKED_PLAYER); + } +} + +void ChatHandler::handleQuitChannelMessage(ChatClient &client, MessageIn &msg) { MessageOut reply(CPMSG_QUIT_CHANNEL_RESPONSE); @@ -449,6 +528,7 @@ ChatHandler::handleListChannelUsersMessage(ChatClient &client, MessageIn &msg) i = users.begin(), i_end = users.end(); i != i_end; ++i) { reply.writeString((*i)->characterName); + reply.writeString(channel->getUserMode((*i))); } client.send(reply); @@ -632,6 +712,28 @@ ChatHandler::handleGuildRetrieveMembers(ChatClient &client, MessageIn &msg) } void +ChatHandler::handleGuildMemberLevelChange(ChatClient &client, MessageIn &msg) +{ + MessageOut reply(CPMSG_GUILD_PROMOTE_MEMBER_RESPONSE); + short guildId = msg.readShort(); + std::string user = msg.readString(); + short level = msg.readByte(); + Guild *guild = guildManager->findById(guildId); + + if (guild) + { + if (guildManager->changeMemberLevel(&client, guild, user, level) == 0) + { + reply.writeByte(ERRMSG_OK); + client.send(reply); + } + } + + reply.writeByte(ERRMSG_FAILURE); + client.send(reply); +} + +void ChatHandler::handleGuildQuit(ChatClient &client, MessageIn &msg) { MessageOut reply(CPMSG_GUILD_QUIT_RESPONSE); diff --git a/src/chat-server/chathandler.hpp b/src/chat-server/chathandler.hpp index 73ca90cd..42866f77 100644 --- a/src/chat-server/chathandler.hpp +++ b/src/chat-server/chathandler.hpp @@ -162,6 +162,18 @@ class ChatHandler : public ConnectionHandler handleEnterChannelMessage(ChatClient &client, MessageIn &msg); /** + * Deal with player changing mode. + */ + void + handleModeChangeMessage(ChatClient &client, MessageIn &msg); + + /** + * Deal with player kicking other player from channel. + */ + void + handleKickUserMessage(ChatClient &client, MessageIn &msg); + + /** * Deal with player leaving channel. */ void @@ -216,6 +228,12 @@ class ChatHandler : public ConnectionHandler handleGuildRetrieveMembers(ChatClient &client, MessageIn &msg); /** + * Deal with level change of member + */ + void + handleGuildMemberLevelChange(ChatClient &client, MessageIn &msg); + + /** * Deal with leaving a guild. */ void diff --git a/src/chat-server/guild.cpp b/src/chat-server/guild.cpp index 74ca17ea..980c34c4 100644 --- a/src/chat-server/guild.cpp +++ b/src/chat-server/guild.cpp @@ -136,3 +136,9 @@ int Guild::getUserPermissions(const std::string &playerName) GuildMember *member = getMember(playerName); return member->getPermissions(); } + +void Guild::setUserPermissions(const std::string &playerName, int level) +{ + GuildMember *member = getMember(playerName); + member->setPermission(level); +} diff --git a/src/chat-server/guild.hpp b/src/chat-server/guild.hpp index 258d27ac..ae8120f4 100644 --- a/src/chat-server/guild.hpp +++ b/src/chat-server/guild.hpp @@ -160,6 +160,11 @@ class Guild */ int getUserPermissions(const std::string &name); + /** + * Sets a users permissions + */ + void setUserPermissions(const std::string &playerName, int level); + protected: /** * Return a member based on their character name diff --git a/src/chat-server/guildmanager.cpp b/src/chat-server/guildmanager.cpp index 1cc3a4b6..4976eca5 100644 --- a/src/chat-server/guildmanager.cpp +++ b/src/chat-server/guildmanager.cpp @@ -155,3 +155,22 @@ void GuildManager::disconnectPlayer(ChatClient *player) GUILD_EVENT_OFFLINE_PLAYER); } } + +int GuildManager::changeMemberLevel(ChatClient *player, Guild *guild, + const std::string &name, int level) +{ + if (guild->checkInGuild(player->characterName) && guild->checkInGuild(name)) + { + int playerLevel = guild->getUserPermissions(player->characterName); + + if (playerLevel == GuildMember::LEADER) + { + // player can modify anyones permissions + guild->setUserPermissions(name, level); + return 0; + } + } + + return -1; +} + diff --git a/src/chat-server/guildmanager.hpp b/src/chat-server/guildmanager.hpp index 97105fc8..7dd03b42 100644 --- a/src/chat-server/guildmanager.hpp +++ b/src/chat-server/guildmanager.hpp @@ -98,6 +98,15 @@ class GuildManager */ void disconnectPlayer(ChatClient* player); + /** + * Promote a guild member to higher level or + * Demote a guild member to a lower level + * + * @return Returns 0 if successful, -1 otherwise + */ + int changeMemberLevel(ChatClient *player, Guild *guild, + const std::string &name, int level); + private: std::list<Guild*> mGuilds; }; |