summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErik Schilling <ablu.erikschilling@googlemail.com>2012-03-21 21:01:53 +0100
committerErik Schilling <ablu.erikschilling@googlemail.com>2012-04-19 19:10:50 +0200
commit67a608b1d13780d19271fedec004bf49b2b2b908 (patch)
treea5b90dc8f650ebe99185650629bddf3f6c424a19
parenta8d65824ea87d5c52ad662530b699650195e83ce (diff)
downloadmanaserv-67a608b1d13780d19271fedec004bf49b2b2b908.tar.gz
manaserv-67a608b1d13780d19271fedec004bf49b2b2b908.tar.bz2
manaserv-67a608b1d13780d19271fedec004bf49b2b2b908.tar.xz
manaserv-67a608b1d13780d19271fedec004bf49b2b2b908.zip
Fixed guild support
List of things fixed: - fixed having multiple guild support everywhere - implemented kick code (untested due to missing kick possiblity in client) - fixed giving owner rights to next member when owner leaves guild - fixed potentional segmention fault when trying to access deleted guild after all members left - fixed saving right changes to database - made searching for guilds faster a bit (at least when having many guilds) TODO: + Fix conflict between guild and normal channels + Fix being able to leave guild channel without leaving guild itself + Add kick possiblity to client Reviewed-by: bjorn.
-rw-r--r--docs/manaserv.xml.example1
-rw-r--r--src/account-server/storage.cpp30
-rw-r--r--src/account-server/storage.h9
-rw-r--r--src/chat-server/chatclient.h5
-rw-r--r--src/chat-server/chathandler.cpp3
-rw-r--r--src/chat-server/chathandler.h12
-rw-r--r--src/chat-server/guild.cpp35
-rw-r--r--src/chat-server/guild.h5
-rw-r--r--src/chat-server/guildhandler.cpp237
-rw-r--r--src/chat-server/guildmanager.cpp63
-rw-r--r--src/chat-server/guildmanager.h12
-rw-r--r--src/common/manaserv_protocol.h6
12 files changed, 251 insertions, 167 deletions
diff --git a/docs/manaserv.xml.example b/docs/manaserv.xml.example
index 75331b65..17dc4909 100644
--- a/docs/manaserv.xml.example
+++ b/docs/manaserv.xml.example
@@ -197,6 +197,7 @@
<option name="account_minPasswordLength" value="6" />
<option name="account_maxPasswordLength" value="25" />
<option name="account_maxCharacters" value="3" />
+ <option name="account_maxGuildsPerCharacter" value="1" />
<!-- end of accounts configuration **************************************** -->
diff --git a/src/account-server/storage.cpp b/src/account-server/storage.cpp
index 8876cd4b..c39bfc5d 100644
--- a/src/account-server/storage.cpp
+++ b/src/account-server/storage.cpp
@@ -591,6 +591,30 @@ Character *Storage::getCharacter(const std::string &name)
return 0;
}
+unsigned int Storage::getCharacterId(const std::string &name)
+{
+ std::ostringstream sql;
+ sql << "SELECT id FROM " << CHARACTERS_TBL_NAME << " WHERE name = ?";
+ if (!mDb->prepareSql(sql.str()))
+ return 0;
+ try
+ {
+ mDb->bindValue(1, name);
+ const dal::RecordSet &charInfo = mDb->processSql();
+ if (charInfo.isEmpty())
+ return 0;
+
+ string_to< unsigned > toUint;
+ return toUint(charInfo(0, 0));
+ }
+ catch (const dal::DbSqlQueryExecFailure &e)
+ {
+ utils::throwError("DALStorage::getCharacterId #1) SQL query failure: ",
+ e);
+ }
+ return 0;
+}
+
bool Storage::doesUserNameExist(const std::string &name)
{
try
@@ -1478,9 +1502,9 @@ void Storage::setMemberRights(int guildId, int memberId, int rights)
{
std::ostringstream sql;
sql << "UPDATE " << GUILD_MEMBERS_TBL_NAME
- << " SET rights = '" << rights << "'"
- << " WHERE member_id = '" << memberId << "'"
- << " AND guild_id = '" << guildId << "'';";
+ << " SET rights = " << rights
+ << " WHERE member_id = " << memberId
+ << " AND guild_id = " << guildId << ";";
mDb->execSql(sql.str());
}
catch (const dal::DbSqlQueryExecFailure& e)
diff --git a/src/account-server/storage.h b/src/account-server/storage.h
index d6fb3ed8..b71be22f 100644
--- a/src/account-server/storage.h
+++ b/src/account-server/storage.h
@@ -95,6 +95,15 @@ class Storage
Character *getCharacter(const std::string &name);
/**
+ * Gets the id of a character by its name.
+ *
+ * @param name the name of the character.
+ *
+ * @return the id of the character
+ */
+ unsigned int getCharacterId(const std::string &name);
+
+ /**
* Add an account to the database.
*
* @param account the new account.
diff --git a/src/chat-server/chatclient.h b/src/chat-server/chatclient.h
index dc077321..a0812a30 100644
--- a/src/chat-server/chatclient.h
+++ b/src/chat-server/chatclient.h
@@ -47,8 +47,9 @@ class ChatClient : public NetComputer
std::string characterName;
unsigned int characterId;
- std::vector< ChatChannel * > channels;
- Party* party;
+ std::vector<ChatChannel *> channels;
+ std::vector<Guild *> guilds;
+ Party *party;
unsigned char accountLevel;
std::map<ChatChannel*, std::string> userModes;
};
diff --git a/src/chat-server/chathandler.cpp b/src/chat-server/chathandler.cpp
index 9c74cc30..0446fa30 100644
--- a/src/chat-server/chathandler.cpp
+++ b/src/chat-server/chathandler.cpp
@@ -127,6 +127,9 @@ void ChatHandler::computerDisconnected(NetComputer *comp)
// Remove user from party
removeUserFromParty(*computer);
+ // Notify guilds about him leaving
+ guildManager->disconnectPlayer(computer);
+
// Remove the character from the player map
// need to do this after removing them from party
// as that uses the player map
diff --git a/src/chat-server/chathandler.h b/src/chat-server/chathandler.h
index af22e453..06d72513 100644
--- a/src/chat-server/chathandler.h
+++ b/src/chat-server/chathandler.h
@@ -25,7 +25,10 @@
#include <map>
#include <string>
+#include "chat-server/guild.h"
+
#include "net/connectionhandler.h"
+
#include "utils/tokencollector.h"
class ChatChannel;
@@ -106,7 +109,7 @@ class ChatHandler : public ConnectionHandler
/**
* Send information about a change in the guild list to guild members.
*/
- void sendGuildListUpdate(const std::string &guildName,
+ void sendGuildListUpdate(Guild *guild,
const std::string &characterName,
char eventId);
@@ -182,6 +185,7 @@ class ChatHandler : public ConnectionHandler
void handleGuildAcceptInvite(ChatClient &client, MessageIn &msg);
void handleGuildGetMembers(ChatClient &client, MessageIn &msg);
void handleGuildMemberLevelChange(ChatClient &client, MessageIn &msg);
+ void removeCharacterFormGuild(ChatClient &client, Guild *guild);
void handleGuildKickMember(ChatClient &client, MessageIn &msg);
void handleGuildQuit(ChatClient &client, MessageIn &msg);
@@ -207,6 +211,12 @@ class ChatHandler : public ConnectionHandler
const std::string &text);
/**
+ * Finds out the name of a character by its id. Either searches it
+ * in the list of online characters or otherwise gets it from the db.
+ */
+ unsigned int getIdOfChar(const std::string &name);
+
+ /**
* Sends a message to every client in a registered channel.
*
* @param channel the channel to send the message in, must not be NULL
diff --git a/src/chat-server/guild.cpp b/src/chat-server/guild.cpp
index 8ec2c8cc..47ace46e 100644
--- a/src/chat-server/guild.cpp
+++ b/src/chat-server/guild.cpp
@@ -19,6 +19,9 @@
*/
#include "guild.h"
+
+#include "chat-server/guildmanager.h"
+
#include "common/defines.h"
#include <algorithm>
@@ -42,10 +45,7 @@ void Guild::addMember(int playerId, int permissions)
// add new guild member to guild
mMembers.push_back(member);
- if (checkInvited(playerId))
- {
- mInvited.remove(playerId);
- }
+ mInvited.remove(playerId);
}
void Guild::removeMember(int playerId)
@@ -53,10 +53,16 @@ void Guild::removeMember(int playerId)
if (getOwner() == playerId)
{
// if the leader is leaving, assign next member as leader
- std::list<GuildMember*>::iterator itr = mMembers.begin();
- ++itr;
- if (itr != mMembers.end())
- setOwner((*itr)->mId);
+ for (std::list<GuildMember*>::iterator it = mMembers.begin(),
+ it_end = mMembers.end(); it != it_end; ++it)
+ {
+ GuildMember *member = *it;
+ if (member->mId != playerId)
+ {
+ setOwner(member->mId);
+ break;
+ }
+ }
}
GuildMember *member = getMember(playerId);
if (member)
@@ -80,11 +86,7 @@ int Guild::getOwner() const
void Guild::setOwner(int playerId)
{
- GuildMember *member = getMember(playerId);
- if (member)
- {
- member->mPermissions = GAL_OWNER;
- }
+ guildManager->setUserRights(this, playerId, GAL_OWNER);
}
bool Guild::checkInvited(int playerId) const
@@ -97,6 +99,11 @@ void Guild::addInvited(int playerId)
mInvited.push_back(playerId);
}
+void Guild::removeInvited(int playerId)
+{
+ mInvited.remove(playerId);
+}
+
bool Guild::checkInGuild(int playerId) const
{
return getMember(playerId) != 0;
@@ -129,7 +136,7 @@ bool Guild::canInvite(int playerId) const
int Guild::getUserPermissions(int playerId) const
{
GuildMember *member = getMember(playerId);
- return member->mPermissions;
+ return member ? member->mPermissions : 0;
}
void Guild::setUserPermissions(int playerId, int level)
diff --git a/src/chat-server/guild.h b/src/chat-server/guild.h
index 21b1b2e7..9cff757e 100644
--- a/src/chat-server/guild.h
+++ b/src/chat-server/guild.h
@@ -83,6 +83,11 @@ class Guild
void addInvited(int playerId);
/**
+ * Remove a player from the invite list.
+ */
+ void removeInvited(int playerId);
+
+ /**
* Returns the name of the guild.
*/
std::string getName() const
diff --git a/src/chat-server/guildhandler.cpp b/src/chat-server/guildhandler.cpp
index 110727cf..949728c2 100644
--- a/src/chat-server/guildhandler.cpp
+++ b/src/chat-server/guildhandler.cpp
@@ -31,6 +31,7 @@
#include "net/messagein.h"
#include "net/messageout.h"
+#include "common/configuration.h"
#include "common/manaserv_protocol.h"
using namespace ManaServ;
@@ -43,25 +44,31 @@ void ChatHandler::sendGuildInvite(const std::string &invitedName,
msg.writeString(inviterName);
msg.writeString(guildName);
- std::map<std::string, ChatClient*>::iterator itr = mPlayerMap.find(invitedName);
- if (itr == mPlayerMap.end())
+ ChatClient *client = getClient(invitedName);
+ if (client)
{
- itr->second->send(msg);
+ client->send(msg);
}
}
void ChatHandler::sendGuildRejoin(ChatClient &client)
{
// Get list of guilds and check what rights they have.
- std::vector<Guild*> guilds = guildManager->getGuildsForPlayer(client.characterId);
- for (unsigned int i = 0; i != guilds.size(); ++i)
+ std::vector<Guild *> guilds =
+ guildManager->getGuildsForPlayer(client.characterId);
+
+ client.guilds = guilds;
+
+ for (std::vector<Guild *>::iterator it = guilds.begin(),
+ it_end = guilds.end(); it != it_end; ++it)
{
- const Guild *guild = guilds[i];
+ Guild *guild = *it;
const int permissions = guild->getUserPermissions(client.characterId);
const std::string guildName = guild->getName();
- // Tell the client what guilds the character belongs to and their permissions
+ // Tell the client what guilds the character belongs to
+ // and their permissions
MessageOut msg(CPMSG_GUILD_REJOIN);
msg.writeString(guildName);
msg.writeInt16(guild->getId());
@@ -76,7 +83,8 @@ void ChatHandler::sendGuildRejoin(ChatClient &client)
client.send(msg);
- sendGuildListUpdate(guildName, client.characterName, GUILD_EVENT_ONLINE_PLAYER);
+ sendGuildListUpdate(guild, client.characterName,
+ GUILD_EVENT_ONLINE_PLAYER);
}
}
@@ -104,30 +112,26 @@ ChatChannel *ChatHandler::joinGuildChannel(const std::string &guildName, ChatCli
return channel;
}
-void ChatHandler::sendGuildListUpdate(const std::string &guildName,
+void ChatHandler::sendGuildListUpdate(Guild *guild,
const std::string &characterName,
char eventId)
{
- Guild *guild = guildManager->findByName(guildName);
- if (guild)
- {
- MessageOut msg(CPMSG_GUILD_UPDATE_LIST);
+ MessageOut msg(CPMSG_GUILD_UPDATE_LIST);
- msg.writeInt16(guild->getId());
- msg.writeString(characterName);
- msg.writeInt8(eventId);
- std::map<std::string, ChatClient*>::const_iterator chr;
- std::list<GuildMember*> members = guild->getMembers();
+ msg.writeInt16(guild->getId());
+ msg.writeString(characterName);
+ msg.writeInt8(eventId);
+ std::map<std::string, ChatClient*>::const_iterator chr;
+ std::list<GuildMember*> members = guild->getMembers();
- for (std::list<GuildMember*>::const_iterator itr = members.begin();
- itr != members.end(); ++itr)
+ for (std::list<GuildMember*>::const_iterator itr = members.begin();
+ itr != members.end(); ++itr)
+ {
+ Character *c = storage->getCharacter((*itr)->mId, NULL);
+ chr = mPlayerMap.find(c->getName());
+ if (chr != mPlayerMap.end())
{
- Character *c = storage->getCharacter((*itr)->mId, NULL);
- chr = mPlayerMap.find(c->getName());
- if (chr != mPlayerMap.end())
- {
- chr->second->send(msg);
- }
+ chr->second->send(msg);
}
}
}
@@ -140,8 +144,8 @@ void ChatHandler::handleGuildCreate(ChatClient &client, MessageIn &msg)
std::string guildName = msg.readString();
if (!guildManager->doesExist(guildName))
{
- // check the player hasnt already created a guild
- if (guildManager->alreadyOwner(client.characterId))
+ if ((int)client.guilds.size() >=
+ Configuration::getValue("account_maxGuildsPerCharacter", 1))
{
reply.writeInt8(ERRMSG_LIMIT_REACHED);
}
@@ -154,6 +158,8 @@ void ChatHandler::handleGuildCreate(ChatClient &client, MessageIn &msg)
reply.writeInt16(guild->getId());
reply.writeInt16(guild->getUserPermissions(client.characterId));
+ client.guilds.push_back(guild);
+
// Send autocreated channel id
ChatChannel* channel = joinGuildChannel(guildName, client);
reply.writeInt16(channel->getId());
@@ -177,7 +183,7 @@ void ChatHandler::handleGuildInvite(ChatClient &client, MessageIn &msg)
std::string character = msg.readString();
// get the chat client and the guild
- ChatClient *invitedClient = mPlayerMap[character];
+ ChatClient *invitedClient = getClient(character);
Guild *guild = guildManager->findById(guildId);
if (invitedClient && guild)
@@ -185,21 +191,33 @@ void ChatHandler::handleGuildInvite(ChatClient &client, MessageIn &msg)
// check permissions of inviter, and that they arent inviting themself,
// and arent someone already in the guild
if (guild->canInvite(client.characterId) &&
- (client.characterName != character) &&
- !guild->checkInGuild(invitedClient->characterId))
+ client.characterName != character &&
+ guild->checkInGuild(client.characterId))
{
- // send the name of the inviter and the name of the guild
- // that the character has been invited to join
- std::string senderName = client.characterName;
- std::string guildName = guild->getName();
- invite.writeString(senderName);
- invite.writeString(guildName);
- invite.writeInt16(guildId);
- invitedClient->send(invite);
- reply.writeInt8(ERRMSG_OK);
-
- // add member to list of invited members to the guild
- guild->addInvited(invitedClient->characterId);
+ if ((int)invitedClient->guilds.size() >=
+ Configuration::getValue("account_maxGuildsPerCharacter", 1))
+ {
+ reply.writeInt8(ERRMSG_LIMIT_REACHED);
+ }
+ else if (guild->checkInGuild(invitedClient->characterId))
+ {
+ reply.writeInt8(ERRMSG_ALREADY_MEMBER);
+ }
+ else
+ {
+ // send the name of the inviter and the name of the guild
+ // that the character has been invited to join
+ std::string senderName = client.characterName;
+ std::string guildName = guild->getName();
+ invite.writeString(senderName);
+ invite.writeString(guildName);
+ invite.writeInt16(guildId);
+ invitedClient->send(invite);
+ reply.writeInt8(ERRMSG_OK);
+
+ // add member to list of invited members to the guild
+ guild->addInvited(invitedClient->characterId);
+ }
}
else
{
@@ -218,37 +236,38 @@ void ChatHandler::handleGuildAcceptInvite(ChatClient &client,
MessageIn &msg)
{
MessageOut reply(CPMSG_GUILD_ACCEPT_RESPONSE);
- std::string guildName = msg.readString();
- bool error = true; // set true by default, and set false only if success
+ const int guildId = msg.readInt16();
+ const bool accepted = msg.readInt8();
// check guild exists and that member was invited
// then add them as guild member
// and remove from invite list
- Guild *guild = guildManager->findByName(guildName);
- if (guild)
+ Guild *guild = guildManager->findById(guildId);
+ if (!(guild && guild->checkInvited(client.characterId)))
{
- if (guild->checkInvited(client.characterId))
- {
- // add user to guild
- guildManager->addGuildMember(guild, client.characterId);
- reply.writeInt8(ERRMSG_OK);
- reply.writeString(guild->getName());
- reply.writeInt16(guild->getId());
- reply.writeInt16(guild->getUserPermissions(client.characterId));
-
- // have character join guild channel
- ChatChannel *channel = joinGuildChannel(guild->getName(), client);
- reply.writeInt16(channel->getId());
- sendGuildListUpdate(guildName, client.characterName, GUILD_EVENT_NEW_PLAYER);
- // success! set error to false
- error = false;
- }
+ reply.writeInt8(ERRMSG_FAILURE);
}
-
- if (error)
+ else if (accepted)
{
- reply.writeInt8(ERRMSG_FAILURE);
+ // add user to guild
+ guildManager->addGuildMember(guild, client.characterId);
+ client.guilds.push_back(guild);
+ reply.writeInt8(ERRMSG_OK);
+ reply.writeString(guild->getName());
+ reply.writeInt16(guild->getId());
+ reply.writeInt16(guild->getUserPermissions(client.characterId));
+
+ // have character join guild channel
+ ChatChannel *channel = joinGuildChannel(guild->getName(), client);
+ reply.writeInt16(channel->getId());
+ sendGuildListUpdate(guild, client.characterName,
+ GUILD_EVENT_NEW_PLAYER);
+ }
+ else
+ {
+ guild->removeInvited(client.characterId);
+ reply.writeInt8(ERRMSG_OK);
}
client.send(reply);
@@ -304,7 +323,8 @@ void ChatHandler::handleGuildMemberLevelChange(ChatClient &client,
if (guild && c)
{
int rights = guild->getUserPermissions(c->getDatabaseID()) | level;
- if (guildManager->changeMemberLevel(&client, guild, c->getDatabaseID(), rights) == 0)
+ if (guildManager->changeMemberLevel(&client, guild, c->getDatabaseID(),
+ rights) == 0)
{
reply.writeInt8(ERRMSG_OK);
client.send(reply);
@@ -319,27 +339,50 @@ void ChatHandler::handleGuildKickMember(ChatClient &client, MessageIn &msg)
{
MessageOut reply(CPMSG_GUILD_KICK_MEMBER_RESPONSE);
short guildId = msg.readInt16();
- std::string user = msg.readString();
+ std::string otherCharName = msg.readString();
Guild *guild = guildManager->findById(guildId);
- Character *c = storage->getCharacter(user);
- if (guild && c)
+ if (!guild)
{
- if (guild->getUserPermissions(c->getDatabaseID()) & GAL_KICK)
- {
- reply.writeInt8(ERRMSG_OK);
- }
- else
- {
- reply.writeInt8(ERRMSG_INSUFFICIENT_RIGHTS);
- }
+ reply.writeInt8(ERRMSG_INVALID_ARGUMENT);
+ client.send(reply);
+ return;
}
+ ChatClient *otherClient = getClient(otherCharName);
+ unsigned int otherCharId;
+ if (otherClient)
+ otherCharId = otherClient->characterId;
else
+ otherCharId = storage->getCharacterId(otherCharName);
+
+ if (otherCharId == 0)
{
reply.writeInt8(ERRMSG_INVALID_ARGUMENT);
+ client.send(reply);
+ return;
+ }
+
+ if (!((guild->getUserPermissions(client.characterId) & GAL_KICK) &&
+ guild->checkInGuild(otherCharId) &&
+ otherCharId != client.characterId))
+ {
+ reply.writeInt8(ERRMSG_INSUFFICIENT_RIGHTS);
+ client.send(reply);
+ return;
+ }
+ if (otherClient)
+ {
+ // Client is online. Inform him about that he got kicked
+ MessageOut kickMsg(CPMSG_GUILD_KICK_NOTIFICATION);
+ kickMsg.writeInt16(guild->getId());
+ kickMsg.writeString(client.characterName);
+ otherClient->send(kickMsg);
}
+ guildManager->removeGuildMember(guild, otherCharId, otherCharName,
+ otherClient);
+ reply.writeInt8(ERRMSG_OK);
client.send(reply);
}
@@ -347,40 +390,22 @@ void ChatHandler::handleGuildQuit(ChatClient &client, MessageIn &msg)
{
MessageOut reply(CPMSG_GUILD_QUIT_RESPONSE);
short guildId = msg.readInt16();
- Guild *guild = guildManager->findById(guildId);
- // check for valid guild
- // check the member is in the guild
- // remove the member from the guild
- if (guild)
- {
- if (guild->checkInGuild(client.characterId))
- {
- reply.writeInt8(ERRMSG_OK);
- reply.writeInt16(guildId);
-
- // Check if there are no members left, remove the guild channel
- if (guild->memberCount() == 0)
- {
- chatChannelManager->removeChannel(chatChannelManager->getChannelId(guild->getName()));
- }
-
- // guild manager checks if the member is the last in the guild
- // and removes the guild if so
- guildManager->removeGuildMember(guild, client.characterId);
- sendGuildListUpdate(guild->getName(), client.characterName, GUILD_EVENT_LEAVING_PLAYER);
- }
- else
- {
- reply.writeInt8(ERRMSG_FAILURE);
- }
- }
- else
+ Guild *guild = guildManager->findById(guildId);
+ if (!guild || !guild->checkInGuild(client.characterId))
{
reply.writeInt8(ERRMSG_FAILURE);
+ client.send(reply);
+ return;
}
+ guildManager->removeGuildMember(guild, client.characterId,
+ client.characterName, &client);
+ reply.writeInt8(ERRMSG_OK);
+ reply.writeInt16(guildId);
client.send(reply);
+
+
}
void ChatHandler::guildChannelTopicChange(ChatChannel *channel, int playerId,
diff --git a/src/chat-server/guildmanager.cpp b/src/chat-server/guildmanager.cpp
index 51254862..39b0bdbb 100644
--- a/src/chat-server/guildmanager.cpp
+++ b/src/chat-server/guildmanager.cpp
@@ -24,6 +24,7 @@
#include "common/manaserv_protocol.h"
#include "account-server/storage.h"
#include "chat-server/chatclient.h"
+#include "chat-server/chatchannelmanager.h"
#include "chat-server/chathandler.h"
using namespace ManaServ;
@@ -49,9 +50,8 @@ Guild* GuildManager::createGuild(const std::string &name, int playerId)
// Add guild to db
storage->addGuild(guild);
- // Add guild, and add owner
+ // Add guild
mGuilds[guild->getId()] = guild;
- mOwners.push_back(playerId);
// put the owner in the guild
addGuildMember(guild, playerId);
@@ -67,7 +67,6 @@ Guild* GuildManager::createGuild(const std::string &name, int playerId)
void GuildManager::removeGuild(Guild *guild)
{
storage->removeGuild(guild);
- mOwners.remove(guild->getOwner());
mGuilds.erase(guild->getId());
delete guild;
}
@@ -78,17 +77,37 @@ void GuildManager::addGuildMember(Guild *guild, int playerId)
guild->addMember(playerId);
}
-void GuildManager::removeGuildMember(Guild *guild, int playerId)
+void GuildManager::removeGuildMember(Guild *guild, int playerId,
+ const std::string &characterName,
+ ChatClient *client)
{
// remove the user from the guild
storage->removeGuildMember(guild->getId(), playerId);
guild->removeMember(playerId);
+ chatHandler->sendGuildListUpdate(guild, characterName,
+ GUILD_EVENT_LEAVING_PLAYER);
+
// if theres no more members left delete the guild
if (guild->memberCount() == 0)
+ {
+ chatChannelManager->removeChannel(
+ chatChannelManager->getChannelId(guild->getName()));
removeGuild(guild);
+ }
- mOwners.remove(playerId);
+ if (client)
+ {
+ for (std::vector<Guild *>::iterator it = client->guilds.begin(),
+ it_end = client->guilds.end(); it != it_end; ++it)
+ {
+ if (*it == guild)
+ {
+ client->guilds.erase(it);
+ break;
+ }
+ }
+ }
}
Guild *GuildManager::findById(short id) const
@@ -115,29 +134,26 @@ bool GuildManager::doesExist(const std::string &name) const
return findByName(name) != 0;
}
-std::vector<Guild*> GuildManager::getGuildsForPlayer(int playerId) const
+std::vector<Guild *> GuildManager::getGuildsForPlayer(int playerId) const
{
- std::vector<Guild*> guildList;
-
+ std::vector<Guild *> guilds;
for (std::map<int, Guild*>::const_iterator it = mGuilds.begin();
it != mGuilds.end(); ++it)
{
if (it->second->checkInGuild(playerId))
{
- guildList.push_back(it->second);
+ guilds.push_back(it->second);
}
}
- return guildList;
+ return guilds;
}
void GuildManager::disconnectPlayer(ChatClient *player)
{
- std::vector<Guild*> guildList = getGuildsForPlayer(player->characterId);
-
- for (std::vector<Guild*>::const_iterator it = guildList.begin();
- it != guildList.end(); ++it)
+ for (std::vector<Guild *>::iterator it = player->guilds.begin(),
+ it_end = player->guilds.end(); it != it_end; ++it)
{
- chatHandler->sendGuildListUpdate((*it)->getName(),
+ chatHandler->sendGuildListUpdate(*it,
player->characterName,
GUILD_EVENT_OFFLINE_PLAYER);
}
@@ -146,7 +162,7 @@ void GuildManager::disconnectPlayer(ChatClient *player)
int GuildManager::changeMemberLevel(ChatClient *player, Guild *guild,
int playerId, int level)
{
- if (guild->checkInGuild(player->characterId) && guild->checkInGuild(playerId))
+ if (guild->checkInGuild(playerId))
{
int playerLevel = guild->getUserPermissions(player->characterId);
@@ -161,21 +177,6 @@ int GuildManager::changeMemberLevel(ChatClient *player, Guild *guild,
return -1;
}
-bool GuildManager::alreadyOwner(int playerId) const
-{
- std::list<int>::const_iterator it = mOwners.begin();
- std::list<int>::const_iterator it_end = mOwners.end();
-
- while (it != it_end)
- {
- if (*it == playerId)
- return true;
- ++it;
- }
-
- return false;
-}
-
void GuildManager::setUserRights(Guild *guild, int playerId, int rights)
{
// Set and save the member rights
diff --git a/src/chat-server/guildmanager.h b/src/chat-server/guildmanager.h
index 43085746..06a0e5a4 100644
--- a/src/chat-server/guildmanager.h
+++ b/src/chat-server/guildmanager.h
@@ -56,7 +56,9 @@ class GuildManager
/**
* Removes a member from a guild.
*/
- void removeGuildMember(Guild *guild, int playerId);
+ void removeGuildMember(Guild *guild, int playerId,
+ const std::string &characterName,
+ ChatClient *client = 0);
/**
* Returns the guild with the given id. O(n)
@@ -80,7 +82,7 @@ class GuildManager
/**
* Return the guilds a character is in
*/
- std::vector<Guild*> getGuildsForPlayer(int playerId) const;
+ std::vector<Guild *> getGuildsForPlayer(int playerId) const;
/**
* Inform guild members that a player has disconnected.
@@ -97,18 +99,12 @@ class GuildManager
int playerId, int level);
/**
- * Check if the player already owns a guild
- */
- bool alreadyOwner(int playerId) const;
-
- /**
* Set user rights
*/
void setUserRights(Guild *guild, int playerId, int rights);
private:
std::map<int, Guild*> mGuilds;
- std::list<int> mOwners;
};
extern GuildManager *guildManager;
diff --git a/src/common/manaserv_protocol.h b/src/common/manaserv_protocol.h
index a4dc71e3..885d7d27 100644
--- a/src/common/manaserv_protocol.h
+++ b/src/common/manaserv_protocol.h
@@ -180,7 +180,7 @@ enum {
CPMSG_GUILD_CREATE_RESPONSE = 0x0351, // B error, W guild, B rights, W channel
PCMSG_GUILD_INVITE = 0x0352, // W id, S name
CPMSG_GUILD_INVITE_RESPONSE = 0x0353, // B error
- PCMSG_GUILD_ACCEPT = 0x0354, // W id
+ PCMSG_GUILD_ACCEPT = 0x0354, // W id, B accepted (0 if false, 1 if true)
CPMSG_GUILD_ACCEPT_RESPONSE = 0x0355, // B error, W guild, B rights, W channel
PCMSG_GUILD_GET_MEMBERS = 0x0356, // W id
CPMSG_GUILD_GET_MEMBERS_RESPONSE = 0x0357, // S names, B online
@@ -191,6 +191,7 @@ enum {
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_KICK_NOTIFICATION = 0x0372, // W guild, S player that kicked
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
@@ -283,7 +284,8 @@ enum {
ERRMSG_SERVER_FULL, // the server is overloaded
ERRMSG_TIME_OUT, // data failed to arrive in due time
ERRMSG_LIMIT_REACHED, // limit reached
- ERRMSG_ADMINISTRATIVE_LOGOFF // kicked by server administrator
+ ERRMSG_ADMINISTRATIVE_LOGOFF, // kicked by server administrator
+ ERRMSG_ALREADY_MEMBER // is already member of guild/party
};
// used in AGMSG_REGISTER_RESPONSE to show state of item db