Skip to content

Commit

Permalink
Fixed guild support
Browse files Browse the repository at this point in the history
TODO:
 + Fix conflict between guild and normal channels
 + Fix being able to leave guild channel without leaving guild itself
  • Loading branch information
Erik Schilling committed Apr 4, 2012
1 parent 37adb26 commit 291b739
Show file tree
Hide file tree
Showing 11 changed files with 139 additions and 109 deletions.
1 change: 1 addition & 0 deletions docs/manaserv.xml.example
Expand Up @@ -191,6 +191,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 **************************************** -->

Expand Down
6 changes: 3 additions & 3 deletions src/account-server/storage.cpp
Expand Up @@ -1478,9 +1478,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)
Expand Down
5 changes: 3 additions & 2 deletions src/chat-server/chatclient.h
Expand Up @@ -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;
};
Expand Down
3 changes: 3 additions & 0 deletions src/chat-server/chathandler.cpp
Expand Up @@ -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
Expand Down
5 changes: 4 additions & 1 deletion src/chat-server/chathandler.h
Expand Up @@ -25,7 +25,10 @@
#include <map>
#include <string>

#include "chat-server/guild.h"

#include "net/connectionhandler.h"

#include "utils/tokencollector.h"

class ChatChannel;
Expand Down Expand Up @@ -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);

Expand Down
11 changes: 7 additions & 4 deletions src/chat-server/guild.cpp
Expand Up @@ -42,10 +42,8 @@ void Guild::addMember(int playerId, int permissions)
// add new guild member to guild
mMembers.push_back(member);

if (checkInvited(playerId))
{
mInvited.remove(playerId);
}
// remove from invited list if nessecary
mInvited.remove(playerId);
}

void Guild::removeMember(int playerId)
Expand Down Expand Up @@ -97,6 +95,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;
Expand Down
5 changes: 5 additions & 0 deletions src/chat-server/guild.h
Expand Up @@ -82,6 +82,11 @@ class Guild
*/
void addInvited(int playerId);

/**
* Remove a player from the invite list.
*/
void removeInvited(int playerId);

/**
* Returns the name of the guild.
*/
Expand Down
161 changes: 101 additions & 60 deletions src/chat-server/guildhandler.cpp
Expand Up @@ -31,6 +31,7 @@
#include "net/messagein.h"
#include "net/messageout.h"

#include "common/configuration.h"
#include "common/manaserv_protocol.h"

using namespace ManaServ;
Expand All @@ -53,15 +54,24 @@ void ChatHandler::sendGuildInvite(const std::string &invitedName,
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;
// nothing to do if player is in no guild
if (!guild)
return;

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());
Expand All @@ -76,7 +86,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);
}
}

Expand Down Expand Up @@ -104,30 +115,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);
}
}
}
Expand All @@ -140,8 +147,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);
}
Expand All @@ -154,6 +161,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());
Expand Down Expand Up @@ -186,20 +195,32 @@ void ChatHandler::handleGuildInvite(ChatClient &client, MessageIn &msg)
// and arent someone already in the guild
if (guild->canInvite(client.characterId) &&
(client.characterName != character) &&
!guild->checkInGuild(invitedClient->characterId))
(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
{
Expand All @@ -218,30 +239,40 @@ void ChatHandler::handleGuildAcceptInvite(ChatClient &client,
MessageIn &msg)
{
MessageOut reply(CPMSG_GUILD_ACCEPT_RESPONSE);
std::string guildName = msg.readString();
const int guildID = msg.readInt16();
const bool accepted = msg.readInt8();
bool error = true; // set true by default, and set false only if success

// 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)
if (Guild *guild = guildManager->findById(guildID))
{
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
if (accepted)
{
// 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);

// success! set error to false
}
else
{
guild->removeInvited(client.characterId);
}
error = false;
}
}
Expand Down Expand Up @@ -347,28 +378,38 @@ 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 *guild = guildManager->findById(guildId))
{
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)
// Check if there would be no members left, remove the guild channel
if (guild->memberCount() == 1)
{
chatChannelManager->removeChannel(chatChannelManager->getChannelId(guild->getName()));
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);
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;
}
}
sendGuildListUpdate(guild, client.characterName,
GUILD_EVENT_LEAVING_PLAYER);
}
else
{
Expand Down

0 comments on commit 291b739

Please sign in to comment.