summaryrefslogtreecommitdiff
path: root/src/chat-server
diff options
context:
space:
mode:
authorStefan Dombrowski <stefan@uni-bonn.de>2011-06-19 23:00:58 +0200
committerStefan Dombrowski <stefan@uni-bonn.de>2011-06-19 23:00:58 +0200
commitbb7033e0247ab1d3a526a5d68f9c482f6ff01ba7 (patch)
tree236c0a9b8c57952f854b2156e9b88c0a6a71d913 /src/chat-server
parent5d3104147fd5c3392751b3c3e5cd9644a83335a7 (diff)
downloadmanaserv-bb7033e0247ab1d3a526a5d68f9c482f6ff01ba7.tar.gz
manaserv-bb7033e0247ab1d3a526a5d68f9c482f6ff01ba7.tar.bz2
manaserv-bb7033e0247ab1d3a526a5d68f9c482f6ff01ba7.tar.xz
manaserv-bb7033e0247ab1d3a526a5d68f9c482f6ff01ba7.zip
Making party invite functional
* An invite expires after 60 seconds. * For protection of the server memory each player can invite a maximum of 10 characters within the 60 second timeframe. Reviewed-by: Bjorn
Diffstat (limited to 'src/chat-server')
-rw-r--r--src/chat-server/chatclient.h1
-rw-r--r--src/chat-server/chathandler.cpp8
-rw-r--r--src/chat-server/chathandler.h49
-rw-r--r--src/chat-server/party.cpp18
-rw-r--r--src/chat-server/party.h3
-rw-r--r--src/chat-server/partyhandler.cpp244
6 files changed, 137 insertions, 186 deletions
diff --git a/src/chat-server/chatclient.h b/src/chat-server/chatclient.h
index e1aa4b04..dc077321 100644
--- a/src/chat-server/chatclient.h
+++ b/src/chat-server/chatclient.h
@@ -51,7 +51,6 @@ class ChatClient : public NetComputer
Party* party;
unsigned char accountLevel;
std::map<ChatChannel*, std::string> userModes;
- int numInvites;
};
#endif
diff --git a/src/chat-server/chathandler.cpp b/src/chat-server/chathandler.cpp
index 1f6cfdbd..3f11d71d 100644
--- a/src/chat-server/chathandler.cpp
+++ b/src/chat-server/chathandler.cpp
@@ -227,18 +227,14 @@ void ChatHandler::processMessage(NetComputer *comp, MessageIn &message)
handleGuildQuit(computer, message);
break;
- case PCMSG_PARTY_ACCEPT_INVITE:
- handlePartyAcceptInvite(computer, message);
+ case PCMSG_PARTY_INVITE_ANSWER:
+ handlePartyInviteAnswer(computer, message);
break;
case PCMSG_PARTY_QUIT:
handlePartyQuit(computer);
break;
- case PCMSG_PARTY_REJECT_INVITE:
- handlePartyRejectInvite(computer, message);
- break;
-
default:
LOG_WARN("ChatHandler::processMessage, Invalid message type"
<< message.getId());
diff --git a/src/chat-server/chathandler.h b/src/chat-server/chathandler.h
index c969a9ae..9796bf78 100644
--- a/src/chat-server/chathandler.h
+++ b/src/chat-server/chathandler.h
@@ -21,9 +21,9 @@
#ifndef CHATHANDLER_H
#define CHATHANDLER_H
+#include <deque>
#include <map>
#include <string>
-#include <vector>
#include "net/connectionhandler.h"
#include "utils/tokencollector.h"
@@ -53,13 +53,22 @@ class ChatHandler : public ConnectionHandler
struct PartyInvite
{
+ PartyInvite(std::string inviterName, std::string inviteeName)
+ : mInviter(inviterName)
+ , mInvitee(inviteeName)
+ {
+ const int validTimeframe = 60;
+ mExpireTime = time(NULL) + validTimeframe;
+ }
+
std::string mInviter;
- std::string mInvited;
- int mPartyId;
+ std::string mInvitee;
+ time_t mExpireTime;
};
std::map<std::string, ChatClient*> mPlayerMap;
- std::vector<PartyInvite> mPartyInvitedUsers;
+ std::deque<PartyInvite> mInvitations;
+ std::map<std::string, int> mNumInvites;
public:
ChatHandler();
@@ -103,6 +112,13 @@ class ChatHandler : public ConnectionHandler
void handlePartyInvite(MessageIn &msg);
+ /**
+ * Returns ChatClient from the Player Map
+ * @param The name of the character
+ * @return The Chat Client
+ */
+ ChatClient *getClient(const std::string &name) const;
+
protected:
/**
* Process chat related messages.
@@ -164,18 +180,9 @@ class ChatHandler : public ConnectionHandler
void handleGuildKickMember(ChatClient &client, MessageIn &msg);
void handleGuildQuit(ChatClient &client, MessageIn &msg);
- void handlePartyAcceptInvite(ChatClient &client, MessageIn &msg);
+ void handlePartyInviteAnswer(ChatClient &client, MessageIn &msg);
void handlePartyQuit(ChatClient &client);
- // TODO: Merge with handlePartyAcceptInvite?
- void handlePartyRejectInvite(ChatClient &client, MessageIn &msg);
-
- /**
- * Deal with a player joining a party.
- * @return Whether player successfully joined the party
- */
- bool handlePartyJoin(const std::string &invited,
- const std::string &inviter);
-
+ void removeExpiredPartyInvites();
void removeUserFromParty(ChatClient &client);
/**
@@ -184,11 +191,6 @@ class ChatHandler : public ConnectionHandler
void informPartyMemberQuit(ChatClient &client);
/**
- * Tell all the party members a member has joined
- */
- void informPartyMemberJoined(ChatClient &client);
-
- /**
* Tell the player to be more polite.
*/
void warnPlayerAboutBadWords(ChatClient &computer);
@@ -218,13 +220,6 @@ class ChatHandler : public ConnectionHandler
ChatClient &client);
/**
- * Returns ChatClient from the Player Map
- * @param The name of the character
- * @return The Chat Client
- */
- ChatClient *getClient(const std::string &name) const;
-
- /**
* Set the topic of a guild channel
*/
void guildChannelTopicChange(ChatChannel *channel, int playerId,
diff --git a/src/chat-server/party.cpp b/src/chat-server/party.cpp
index 0719e8ff..e665ad1b 100644
--- a/src/chat-server/party.cpp
+++ b/src/chat-server/party.cpp
@@ -20,6 +20,13 @@
#include "party.h"
+#include "chatclient.h"
+#include "chathandler.h"
+
+#include "common/manaserv_protocol.h"
+
+#include "net/messageout.h"
+
#include <algorithm>
Party::Party()
@@ -29,11 +36,16 @@ Party::Party()
mId = id;
}
-void Party::addUser(const std::string &name)
+void Party::addUser(const std::string &name, const std::string &inviter)
{
- if (std::find(mUsers.begin(), mUsers.end(), name) == mUsers.end())
+ mUsers.push_back(name);
+
+ for (size_t i = 0; i < userCount(); ++i)
{
- mUsers.push_back(name);
+ MessageOut out(ManaServ::CPMSG_PARTY_NEW_MEMBER);
+ out.writeString(name);
+ out.writeString(inviter);
+ chatHandler->getClient(mUsers[i])->send(out);
}
}
diff --git a/src/chat-server/party.h b/src/chat-server/party.h
index f003c0b1..da8755b3 100644
--- a/src/chat-server/party.h
+++ b/src/chat-server/party.h
@@ -37,7 +37,8 @@ public:
/**
* Add user to party
*/
- void addUser(const std::string &name);
+ void addUser(const std::string &name,
+ const std::string &inviter = std::string());
/**
* Remove user from party
diff --git a/src/chat-server/partyhandler.cpp b/src/chat-server/partyhandler.cpp
index 40862755..16d43e68 100644
--- a/src/chat-server/partyhandler.cpp
+++ b/src/chat-server/partyhandler.cpp
@@ -25,12 +25,10 @@
#include "account-server/storage.h"
#include "account-server/serverhandler.h"
-#include "net/messagein.h"
-#include "net/messageout.h"
-
#include "common/manaserv_protocol.h"
-#include <algorithm>
+#include "net/messagein.h"
+#include "net/messageout.h"
using namespace ManaServ;
@@ -40,51 +38,17 @@ void updateInfo(ChatClient *client, int partyId)
GameServerHandler::sendPartyChange(character, partyId);
}
-bool ChatHandler::handlePartyJoin(const std::string &invited, const std::string &inviter)
+void ChatHandler::removeExpiredPartyInvites()
{
- // Get inviting client
- ChatClient *c1 = getClient(inviter);
- if (c1)
+ time_t now = time(NULL);
+ while (!mInvitations.empty() && mInvitations.front().mExpireTime < now)
{
- // if party doesnt exist, create it
- if (!c1->party)
- {
- c1->party = new Party();
- // add inviter to the party
- c1->party->addUser(inviter);
- MessageOut out(CPMSG_PARTY_NEW_MEMBER);
- out.writeInt32(c1->characterId);
- out.writeString(inviter);
- c1->send(out);
- // tell game server to update info
- updateInfo(c1, c1->party->getId());
- }
-
- // Get invited client
- ChatClient *c2 = getClient(invited);
- if (c2)
- {
- // add invited to the party
- c1->party->addUser(invited);
- c2->party = c1->party;
- // was successful so return success to inviter
- MessageOut out(CPMSG_PARTY_INVITE_RESPONSE);
- out.writeString(invited);
- out.writeInt8(ERRMSG_OK);
- c1->send(out);
-
- // tell everyone a player joined
- informPartyMemberJoined(*c2);
-
- // tell game server to update info
- updateInfo(c2, c2->party->getId());
- return true;
- }
+ std::map<std::string, int>::iterator itr;
+ itr = mNumInvites.find(mInvitations.front().mInviter);
+ if (--itr->second <= 0)
+ mNumInvites.erase(itr);
+ mInvitations.pop_front();
}
-
- // there was an error, return false
- return false;
-
}
void ChatHandler::handlePartyInvite(MessageIn &msg)
@@ -92,80 +56,120 @@ void ChatHandler::handlePartyInvite(MessageIn &msg)
std::string inviterName = msg.readString();
std::string inviteeName = msg.readString();
ChatClient *inviter = getClient(inviterName);
+ ChatClient *invitee = getClient(inviteeName);
- if (!inviter)
+ if (!inviter || !invitee)
return;
- ChatClient *invitee = getClient(inviteeName);
-
- if (!invitee)
+ removeExpiredPartyInvites();
+ const int maxInvitesPerTimeframe = 10;
+ int &num = mNumInvites[inviterName];
+ if (num >= maxInvitesPerTimeframe)
{
- // TODO: Send error message
+ MessageOut out(CPMSG_PARTY_REJECTED);
+ out.writeString(inviterName);
+ out.writeInt8(ERRMSG_LIMIT_REACHED);
+ inviter->send(out);
return;
}
+ ++num;
- ++invitee->numInvites;
- // TODO: Check number of invites
- // and do something if too many in a short time
-
- // store the invite
- PartyInvite invite;
- invite.mInvited = inviteeName;
- invite.mInviter = inviterName;
- if (inviter->party)
- invite.mPartyId = inviter->party->getId();
- else
- invite.mPartyId = 0;
+ if (invitee->party)
+ {
+ MessageOut out(CPMSG_PARTY_REJECTED);
+ out.writeString(inviterName);
+ out.writeInt8(ERRMSG_FAILURE);
+ inviter->send(out);
+ return;
+ }
- mPartyInvitedUsers.push_back(invite);
+ mInvitations.push_back(PartyInvite(inviterName, inviteeName));
MessageOut out(CPMSG_PARTY_INVITED);
out.writeString(inviterName);
invitee->send(out);
}
-void ChatHandler::handlePartyAcceptInvite(ChatClient &client, MessageIn &msg)
+void ChatHandler::handlePartyInviteAnswer(ChatClient &client, MessageIn &msg)
{
- MessageOut out(CPMSG_PARTY_ACCEPT_INVITE_RESPONSE);
+ if (client.party)
+ return;
- std::string inviter = msg.readString();
+ MessageOut outInvitee(CPMSG_PARTY_INVITE_ANSWER_RESPONSE);
- // Check that the player was invited
- std::vector<PartyInvite>::iterator itr, itr_end;
- itr = mPartyInvitedUsers.begin();
- itr_end = mPartyInvitedUsers.end();
+ std::string inviter = msg.readString();
- bool found = false;
+ // check if the invite is still valid
+ bool valid = false;
+ removeExpiredPartyInvites();
+ const size_t size = mInvitations.size();
+ for (size_t i = 0; i < size; ++i)
+ {
+ if (mInvitations[i].mInviter == inviter &&
+ mInvitations[i].mInvitee == client.characterName)
+ {
+ valid = true;
+ }
+ }
- while (itr != itr_end)
+ // the invitee did not accept the invitation
+ if (!msg.readInt8())
{
- if ((*itr).mInvited == client.characterName &&
- (*itr).mInviter == inviter)
+ if (!valid)
+ return;
+
+ // send rejection to inviter
+ ChatClient *inviterClient = getClient(inviter);
+ if (inviterClient)
{
- // make them join the party
- if (handlePartyJoin(client.characterName, inviter))
- {
- out.writeInt8(ERRMSG_OK);
- Party::PartyUsers users = client.party->getUsers();
- const unsigned usersSize = users.size();
- for (unsigned i = 0; i < usersSize; i++)
- out.writeString(users[i]);
-
- mPartyInvitedUsers.erase(itr);
- found = true;
- break;
- }
+ MessageOut out(CPMSG_PARTY_REJECTED);
+ out.writeString(inviter);
+ out.writeInt8(ERRMSG_OK);
+ inviterClient->send(out);
}
+ return;
+ }
- ++itr;
+ // if the invitation has expired, tell the inivtee about it
+ if (!valid)
+ {
+ outInvitee.writeInt8(ERRMSG_TIME_OUT);
+ client.send(outInvitee);
+ return;
}
- if (!found)
+ // check that the inviter is still in the game
+ ChatClient *c1 = getClient(inviter);
+ if (!c1)
{
- out.writeInt8(ERRMSG_FAILURE);
+ outInvitee.writeInt8(ERRMSG_FAILURE);
+ client.send(outInvitee);
+ return;
}
- client.send(out);
+ // if party doesnt exist, create it
+ if (!c1->party)
+ {
+ c1->party = new Party();
+ c1->party->addUser(inviter);
+ // tell game server to update info
+ updateInfo(c1, c1->party->getId());
+ }
+
+ outInvitee.writeInt8(ERRMSG_OK);
+ Party::PartyUsers users = c1->party->getUsers();
+ const unsigned usersSize = users.size();
+ for (unsigned i = 0; i < usersSize; i++)
+ outInvitee.writeString(users[i]);
+
+ client.send(outInvitee);
+
+ // add invitee to the party
+ c1->party->addUser(client.characterName, inviter);
+ client.party = c1->party;
+
+ // tell game server to update info
+ updateInfo(&client, client.party->getId());
}
void ChatHandler::handlePartyQuit(ChatClient &client)
@@ -179,45 +183,6 @@ void ChatHandler::handlePartyQuit(ChatClient &client)
updateInfo(&client, 0);
}
-void ChatHandler::handlePartyRejectInvite(ChatClient &client, MessageIn &msg)
-{
- MessageOut out(CPMSG_PARTY_REJECTED);
-
- std::string inviter = msg.readString();
-
-
- std::vector<PartyInvite>::iterator itr, itr_end;
-
- itr = mPartyInvitedUsers.begin();
- itr_end = mPartyInvitedUsers.end();
- bool found = false;
-
- while (itr != itr_end)
- {
- // Check that the player was invited
- if ((*itr).mInvited == client.characterName &&
- (*itr).mInviter == inviter)
- {
- // remove them from invited users list
- mPartyInvitedUsers.erase(itr);
- found = true;
- break;
- }
-
- ++itr;
- }
-
- if (!found)
- {
- out.writeInt8(ERRMSG_FAILURE);
- }
-
- // send rejection to inviter
- ChatClient *inviterClient = getClient(inviter);
-
- inviterClient->send(out);
-}
-
void ChatHandler::removeUserFromParty(ChatClient &client)
{
if (client.party)
@@ -249,20 +214,3 @@ void ChatHandler::informPartyMemberQuit(ChatClient &client)
}
}
}
-
-void ChatHandler::informPartyMemberJoined(ChatClient &client)
-{
- std::map<std::string, ChatClient*>::iterator itr;
- std::map<std::string, ChatClient*>::const_iterator itr_end = mPlayerMap.end();
-
- for (itr = mPlayerMap.begin(); itr != itr_end; ++itr)
- {
- if (itr->second->party == client.party)
- {
- MessageOut out(CPMSG_PARTY_NEW_MEMBER);
- out.writeInt32(client.characterId);
- out.writeString(client.characterName);
- itr->second->send(out);
- }
- }
-}