summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog9
-rw-r--r--src/chat-server/chatchannel.cpp51
-rw-r--r--src/chat-server/chatchannel.hpp11
-rw-r--r--src/chat-server/chatclient.hpp5
-rw-r--r--src/chat-server/chathandler.cpp102
-rw-r--r--src/chat-server/chathandler.hpp18
-rw-r--r--src/chat-server/guild.cpp6
-rw-r--r--src/chat-server/guild.hpp5
-rw-r--r--src/chat-server/guildmanager.cpp19
-rw-r--r--src/chat-server/guildmanager.hpp9
-rw-r--r--src/defines.h11
11 files changed, 242 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index 4bf60b0b..00c857b0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2008-08-13 David Athay <ko2fan@gmail.com>
+
+ * src/chat-server/guildmanager.cpp, src/chat-server/chathandler.hpp,
+ src/chat-server/chatclient.hpp, src/chat-server/guild.cpp,
+ src/chat-server/guildmanager.hpp, src/chat-server/chatchannel.cpp,
+ src/chat-server/guild.hpp, src/chat-server/chatchannel.hpp,
+ src/chat-server/chathandler.cpp, src/defines.h: Added permission levels
+ to guilds and operator permissions to channels.
+
2008-08-10 Philipp Sehmisch <tmw@crushnet.org>
* src/game-server/character.cpp: Corrected the way weapon skills is taken into
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;
};
diff --git a/src/defines.h b/src/defines.h
index 7e819c35..eb6bc052 100644
--- a/src/defines.h
+++ b/src/defines.h
@@ -197,6 +197,8 @@ enum {
CPMSG_GUILD_UPDATE_LIST = 0x0358, // W id, S name, B event
PCMSG_GUILD_QUIT = 0x0360, // W id
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
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
@@ -227,8 +229,11 @@ enum {
PCMSG_LIST_CHANNELS = 0x0445, // -
CPMSG_LIST_CHANNELS_RESPONSE = 0x0446, // S names, W number of users
PCMSG_LIST_CHANNELUSERS = 0x0460, // S channel
- CPMSG_LIST_CHANNELUSERS_RESPONSE = 0x0461, // S channel, S users
+ CPMSG_LIST_CHANNELUSERS_RESPONSE = 0x0461, // S channel, { S user, B mode }
PCMSG_TOPIC_CHANGE = 0x0462, // W channel id, S topic
+ // -- User modes
+ PCMSG_USER_MODE = 0x0465, // W channel id, S name, B mode
+ PCMSG_KICK_USER = 0x0466, // W channel id, S name
// Inter-server
GAMSG_REGISTER = 0x0500, // S address, W port, { W map id }*
@@ -311,7 +316,9 @@ enum {
enum {
CHAT_EVENT_NEW_PLAYER = 0,
CHAT_EVENT_LEAVING_PLAYER,
- CHAT_EVENT_TOPIC_CHANGE
+ CHAT_EVENT_TOPIC_CHANGE,
+ CHAT_EVENT_MODE_CHANGE,
+ CHAT_EVENT_KICKED_PLAYER
};
// Guild member event values