summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Athay <ko2fan@gmail.com>2007-06-26 19:50:02 +0000
committerDavid Athay <ko2fan@gmail.com>2007-06-26 19:50:02 +0000
commit301ffe1048fb23548f72759b6ed0ca98e9109ff4 (patch)
treec765b6df9a83227b1d40bb59949b768fbc4c1574
parent99263173738dfd6ca4ba822e0a112f1c7c17661c (diff)
downloadmanaserv-301ffe1048fb23548f72759b6ed0ca98e9109ff4.tar.gz
manaserv-301ffe1048fb23548f72759b6ed0ca98e9109ff4.tar.bz2
manaserv-301ffe1048fb23548f72759b6ed0ca98e9109ff4.tar.xz
manaserv-301ffe1048fb23548f72759b6ed0ca98e9109ff4.zip
Merged guilds-and-parties branch to trunk
-rw-r--r--ChangeLog83
-rw-r--r--src/Makefile.am4
-rw-r--r--src/account-server/accounthandler.cpp2
-rw-r--r--src/account-server/accounthandler.hpp7
-rw-r--r--src/account-server/characterdata.hpp9
-rw-r--r--src/account-server/dalstorage.cpp268
-rw-r--r--src/account-server/dalstorage.hpp46
-rw-r--r--src/account-server/dalstoragesql.hpp49
-rw-r--r--src/account-server/guild.cpp107
-rw-r--r--src/account-server/guild.hpp109
-rw-r--r--src/account-server/guildmanager.cpp136
-rw-r--r--src/account-server/guildmanager.hpp76
-rw-r--r--src/account-server/main-account.cpp7
-rw-r--r--src/account-server/serverhandler.cpp221
-rw-r--r--src/account-server/serverhandler.hpp19
-rw-r--r--src/account-server/storage.hpp45
-rw-r--r--src/chat-server/chathandler.cpp147
-rw-r--r--src/chat-server/chathandler.hpp43
-rw-r--r--src/defines.h34
-rw-r--r--src/game-server/accountconnection.cpp162
-rw-r--r--src/game-server/accountconnection.hpp24
-rw-r--r--src/game-server/gamehandler.cpp42
-rw-r--r--src/game-server/gamehandler.hpp6
-rw-r--r--src/game-server/mapmanager.cpp5
-rw-r--r--src/game-server/mapmanager.hpp5
-rw-r--r--src/net/netcomputer.cpp9
26 files changed, 1648 insertions, 17 deletions
diff --git a/ChangeLog b/ChangeLog
index b156de6a..36ebddc7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -9,11 +9,38 @@
aliasing and sped up sqrt.
* src/game-server/character.cpp: Fixed initial attribute status.
+2007-04-28 David Athay <ko2fan@gmail.com>
+
+ * src/chat-server/chathandler.cpp,
+ src/account-server/guildmanager.cpp: Fixed bug where
+ the guild creator was never added to the guild.
+
+2007-04-22 David Athay <ko2fan@gmail.com>
+
+ * src/chat-server/chathandler.cpp,
+ src/account-server/guildmanager.cpp,
+ src/account-server/guildmanager.hpp,
+ src/account-server/serverhandler.cpp,
+ src/account-server/storage.hpp, src/account-server/dalstorage.cpp,
+ src/account-server/dalstorage.hpp, src/defines.h,
+ src/game-server/gamehandler.cpp,
+ src/game-server/accountconnection.cpp,
+ src/game-server/accountconnection.hpp: Added quitting guilds.
+
2007-04-11 Philipp Sehmisch <tmw@crushnet.org>
* src/game-server/being.cpp: Using effective attributes instead of base
attributes for damage calculation.
+2007-04-05 David Athay <ko2fan@gmail.com>
+
+ * src/chat-server/chathandler.hpp,
+ src/chat-server/chathandler.cpp,
+ src/account-server/guildmanager.cpp,
+ src/account-server/guildmanager.hpp, src/defines.h:
+ Added user joining and leaving, plus stopped non guild members
+ joining guild channels.
+
2007-03-31 Bjørn Lindeijer <bjorn@lindeijer.nl>
* src/Makefile.am, src/game-server/testing.cpp,
@@ -52,10 +79,42 @@
src/Makefile.am: Renamed "Controlled" to "Monster" and moved it into
the game-server directory.
+2007-03-30 David Athay <ko2fan@gmail.com>
+
+ * src/chat-server/chathandler.cpp,
+ src/chat-server/chathandler.hpp,
+ src/account-server/accounthandler.hpp,
+ src/account-server/guildmanager.cpp,
+ src/account-server/guildmanager.hpp,
+ src/account-server/guild.cpp, src/account-server/guild.hpp,
+ src/account-server/serverhandler.cpp,
+ src/account-server/serverhandler.hpp,
+ src/account-server/storage.hpp, src/account-server/storage.cpp,
+ src/account-server/characterdata.hpp,
+ src/game-server/accountconnection.cpp,
+ src/defines: Added rejoining guilds the player belongs to.
+ * src/account-server/serverhandler.hpp,
+ src/chat-server/chathandler.cpp: Player now joins guild channels
+ upon connecting to the chat server.
+ * src/acccount-server/dalstorage.cpp: Fixed bug with creating
+ guilds.
+
+2007-03-25 David Athay <ko2fan@gmail.com>
+
+ * src/chat-server/chathandler.cpp,
+ src/chat-server/chathandler.hpp,
+ src/account-server/serverhandler.cpp,
+ src/account-server/serverhandler.hpp,
+ src/account-server/dalstorage.cpp,
+ src/account-server/dalstorage.hpp,
+ src/defines.h, src/game-server/gamehandler.cpp,
+ src/game-server/gamehandler.hpp,
+ src/game-server/accountconnection.cpp: Implemented inviting
+ users to guilds.
+
2007-03-23 Eugenio Favalli <elvenprogrammer@gmail.com>
- * accountserver.cbp, gameserver.cbp: Updated and fixed Code::Blocks
- project files.
+ * tmw.cbp: Updated and fixed Code::Blocks project files.
2007-03-23 Bjørn Lindeijer <bjorn@lindeijer.nl>
@@ -101,6 +160,26 @@
src/account-server/accounthandler.cpp: Fixed two compiler warnings
and corrected a spelling error.
+2007-03-19 David Athay <ko2fan@gmail.com>
+
+ * src/Makefile.am, src/account-server/accounthandler.cpp,
+ src/account-server/characterdata.hpp,
+ src/account-server/dalstorage.cpp,
+ src/account-server/dalstorage.hpp,
+ src/account-server/main-account.cpp,
+ src/account-server/serverhandler.cpp,
+ src/account-server/serverhandler.hpp,
+ src/account-server/storage.hpp, src/chat-server/chathandler.cpp,
+ src/account-server/guild.cpp, src/account-server/guild.h,
+ src/account-server/guildmanager.cpp,
+ src/account-server/guildmanager.hpp,
+ src/chat-server/chathandler.hpp, src/defines.h,
+ src/game-server/accountconnection.cpp,
+ src/game-server/accountconnection.hpp,
+ src/game-server/gamehandler.cpp, src/game-server/gamehandler.hpp,
+ src/game-server/mapmanager.cpp, src/game-server/mapmanager.hpp,
+ src/net/netcomputer.cpp : Add first stage of guild system.
+
2007-03-18 Rogier Polak <rogier.l.a.polak@gmail.com>
* src/net/netcomputer.cpp: Corrected the debug message for big-endian
diff --git a/src/Makefile.am b/src/Makefile.am
index fbf488a8..69ff347e 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -27,6 +27,10 @@ tmwserv_account_SOURCES = \
account-server/dalstorage.hpp \
account-server/dalstorage.cpp \
account-server/dalstoragesql.hpp \
+ account-server/guild.cpp \
+ account-server/guild.h \
+ account-server/guildmanager.cpp \
+ account-server/guildmanager.h \
account-server/serverhandler.hpp \
account-server/serverhandler.cpp \
account-server/storage.hpp \
diff --git a/src/account-server/accounthandler.cpp b/src/account-server/accounthandler.cpp
index 52ea2b33..c86d06de 100644
--- a/src/account-server/accounthandler.cpp
+++ b/src/account-server/accounthandler.cpp
@@ -29,6 +29,8 @@
#include "account-server/account.hpp"
#include "account-server/accountclient.hpp"
#include "account-server/characterdata.hpp"
+#include "account-server/guild.hpp"
+#include "account-server/guildmanager.hpp"
#include "account-server/serverhandler.hpp"
#include "account-server/storage.hpp"
#include "chat-server/chathandler.hpp"
diff --git a/src/account-server/accounthandler.hpp b/src/account-server/accounthandler.hpp
index 1c0de2e4..d7058906 100644
--- a/src/account-server/accounthandler.hpp
+++ b/src/account-server/accounthandler.hpp
@@ -28,6 +28,7 @@
#include "utils/tokencollector.hpp"
class AccountClient;
+class CharacterData;
/**
* Manages the data stored in user accounts and provides a reliable interface
@@ -126,6 +127,12 @@ class AccountHandler : public ConnectionHandler
void
handleCharacterDeleteMessage(AccountClient &computer, MessageIn &msg);
+
+ /**
+ * Send guild join for each guild the player belongs to
+ */
+ void
+ handleGuildJoining(AccountClient &computer, CharacterData *character);
};
extern AccountHandler * accountHandler;
diff --git a/src/account-server/characterdata.hpp b/src/account-server/characterdata.hpp
index c7ac3dea..8d7e2599 100644
--- a/src/account-server/characterdata.hpp
+++ b/src/account-server/characterdata.hpp
@@ -154,6 +154,13 @@ class CharacterData: public AbstractCharacterData
/** Adds an inventory item to the inventory. */
void
addItemToInventory(const InventoryItem& item);
+
+ /** Add a guild to the character */
+ void addGuild(const std::string &name) { mGuilds.push_back(name); }
+
+ /** Returns a list of guilds the player belongs to */
+ std::vector<std::string>
+ getGuilds() const { return mGuilds; }
private:
CharacterData(CharacterData const &);
@@ -175,6 +182,8 @@ class CharacterData: public AbstractCharacterData
Point mPos; //!< Position the being is at.
std::vector< InventoryItem > mInventory; //!< All the possesions of
//!< the character.
+ std::vector<std::string> mGuilds; //!< All the guilds the player
+ //!< belongs to.
};
// Utility typedefs
diff --git a/src/account-server/dalstorage.cpp b/src/account-server/dalstorage.cpp
index 8ae497e1..fd6c8419 100644
--- a/src/account-server/dalstorage.cpp
+++ b/src/account-server/dalstorage.cpp
@@ -27,6 +27,8 @@
#include "configuration.h"
#include "point.h"
#include "account-server/characterdata.hpp"
+#include "account-server/guild.hpp"
+#include "account-server/guildmanager.hpp"
#include "account-server/dalstoragesql.hpp"
#include "dal/dalexcept.h"
#include "dal/dataproviderfactory.h"
@@ -67,6 +69,22 @@ class character_by_id
int mID; /**< the ID to look for */
};
+/**
+* Functor used to search a character by name in Characters.
+ */
+class character_by_name
+{
+public:
+ character_by_name(const std::string &name)
+ : mName(name)
+ {}
+
+ bool operator()(CharacterPtr const &elem) const
+ { return elem->getName() == mName; }
+
+private:
+ std::string mName; /**< the name to look for */
+};
/**
* Constructor.
@@ -168,6 +186,8 @@ DALStorage::open(void)
createTable(WORLD_ITEMS_TBL_NAME, SQL_WORLD_ITEMS_TABLE);
createTable(INVENTORIES_TBL_NAME, SQL_INVENTORIES_TABLE);
createTable(CHANNELS_TBL_NAME, SQL_CHANNELS_TABLE);
+ createTable(GUILDS_TBL_NAME, SQL_GUILDS_TABLE);
+ createTable(GUILD_MEMBERS_TBL_NAME, SQL_GUILD_MEMBERS_TABLE);
}
catch (const DbConnectionFailure& e) {
LOG_ERROR("(DALStorage::open #1) Unable to connect to the database: "
@@ -429,6 +449,81 @@ CharacterPtr DALStorage::getCharacter(int id)
}
}
+/**
+* Gets a character by character name.
+ */
+CharacterPtr DALStorage::getCharacter(const std::string &name)
+{
+ // connect to the database (if not connected yet).
+ open();
+
+ // look for the character in the list first.
+ Characters::iterator it_end = mCharacters.end(),
+ it = std::find_if(mCharacters.begin(), it_end, character_by_name(name));
+
+ if (it != it_end)
+ return *it;
+
+ using namespace dal;
+
+ // the account was not in the list, look for it in the database.
+ try {
+ std::ostringstream sql;
+ sql << "select * from " << CHARACTERS_TBL_NAME << " where name = '"
+ << name << "';";
+ RecordSet const &charInfo = mDb->execSql(sql.str());
+
+ // if the character is not even in the database then
+ // we have no choice but to return nothing.
+ if (charInfo.isEmpty())
+ {
+ return CharacterPtr(NULL);
+ }
+
+ // specialize the string_to functor to convert
+ // a string to an unsigned int.
+ string_to< unsigned > toUint;
+
+ // specialize the string_to functor to convert
+ // a string to an unsigned short.
+ string_to< unsigned short > toUshort;
+
+ CharacterData *character = new CharacterData(charInfo(0, 2),
+ toUint(charInfo(0, 0)));
+ character->setAccountID(toUint(charInfo(0, 1)));
+ character->setGender(toUshort(charInfo(0, 3)));
+ character->setHairStyle(toUshort(charInfo(0, 4)));
+ character->setHairColor(toUshort(charInfo(0, 5)));
+ character->setLevel(toUshort(charInfo(0, 6)));
+ character->setMoney(toUint(charInfo(0, 7)));
+ Point pos(toUshort(charInfo(0, 8)), toUshort(charInfo(0, 9)));
+ character->setPosition(pos);
+ for (int i = 0; i < NB_BASE_ATTRIBUTES; ++i)
+ {
+ character->setBaseAttribute(i, toUshort(charInfo(0, 11 + i)));
+ }
+
+ int mapId = toUint(charInfo(0, 10));
+ if (mapId > 0)
+ {
+ character->setMapId(mapId);
+ }
+ else
+ {
+ // Set character to default map and one of the default location
+ // Default map is to be 1, as not found return value will be 0.
+ character->setMapId((int)config.getValue("defaultMap", 1));
+ }
+
+ CharacterPtr ptr(character);
+ mCharacters.push_back(ptr);
+ return ptr;
+ }
+ catch (const DbSqlQueryExecFailure& e)
+ {
+ return CharacterPtr(NULL); // TODO: Throw exception here
+ }
+}
/**
* Return the list of all Emails addresses.
@@ -640,6 +735,7 @@ DALStorage::updateCharacter(CharacterPtr character)
return false;
}
}
+
return true;
}
@@ -1028,3 +1124,175 @@ void DALStorage::unloadAccount(AccountPtr const &account)
flush(account);
mAccounts.erase(account->getID());
}
+
+/**
+ * Add a guild
+ */
+void DALStorage::addGuild(Guild* guild)
+{
+#if defined (SQLITE_SUPPORT)
+ // Reopen the db in this thread for sqlite, to avoid
+ // Library Call out of sequence problem due to thread safe.
+ close();
+#endif
+ open();
+
+ std::ostringstream insertSql;
+ insertSql << "insert into " << GUILDS_TBL_NAME
+ << " (name) "
+ << " values (\""
+ << guild->getName() << "\");";
+ mDb->execSql(insertSql.str());
+
+ std::ostringstream selectSql;
+ selectSql << "select id from " << GUILDS_TBL_NAME
+ << " where name = \"" << guild->getName() << "\";";
+ const dal::RecordSet& guildInfo = mDb->execSql(selectSql.str());
+ string_to<unsigned int> toUint;
+ unsigned id = toUint(guildInfo(0, 0));
+ guild->setId(id);
+}
+
+/**
+ * Remove guild
+ */
+void DALStorage::removeGuild(Guild* guild)
+{
+#if defined (SQLITE_SUPPORT)
+ // Reopen the db in this thread for sqlite, to avoid
+ // Library Call out of sequence problem due to thread safe.
+ close();
+#endif
+ open();
+
+ std::ostringstream sql;
+ sql << "delete from " << GUILDS_TBL_NAME
+ << " where id = '"
+ << guild->getId() << "';";
+ mDb->execSql(sql.str());
+}
+
+/**
+ * add a member to a guild
+ */
+void DALStorage::addGuildMember(int guildId, const std::string &memberName)
+{
+#if defined (SQLITE_SUPPORT)
+ // Reopen the db in this thread for sqlite, to avoid
+ // Library Call out of sequence problem due to thread safe.
+ close();
+#endif
+ open();
+
+ std::ostringstream sql;
+
+ try
+ {
+ sql << "insert into " << GUILD_MEMBERS_TBL_NAME
+ << " (guild_id, member_name)"
+ << " values ("
+ << guildId << ", \""
+ << memberName << "\");";
+ mDb->execSql(sql.str());
+ }
+ catch (const dal::DbSqlQueryExecFailure& e) {
+ // TODO: throw an exception.
+ LOG_ERROR("SQL query failure: " << e.what());
+ }
+}
+
+/**
+* remove a member from a guild
+ */
+void DALStorage::removeGuildMember(int guildId, const std::string &memberName)
+{
+#if defined (SQLITE_SUPPORT)
+ // Reopen the db in this thread for sqlite, to avoid
+ // Library Call out of sequence problem due to thread safe.
+ close();
+#endif
+ open();
+
+ std::ostringstream sql;
+
+ try
+ {
+ sql << "delete from " << GUILD_MEMBERS_TBL_NAME
+ << " where member_name = \""
+ << memberName << "\" and guild_id = '"
+ << guildId << "';";
+ mDb->execSql(sql.str());
+ }
+ catch (const dal::DbSqlQueryExecFailure& e) {
+ // TODO: throw an exception.
+ LOG_ERROR("SQL query failure: " << e.what());
+ }
+}
+
+/**
+ * get a list of guilds
+ */
+std::list<Guild*> DALStorage::getGuildList()
+{
+#if defined (SQLITE_SUPPORT)
+ // Reopen the db in this thread for sqlite, to avoid
+ // Library Call out of sequence problem due to thread safe.
+ close();
+#endif
+ open();
+
+ std::list<Guild*> guilds;
+ std::stringstream sql;
+ string_to<short> toShort;
+
+ /**
+ * Get the guilds stored in the db.
+ */
+
+ try
+ {
+ sql << "select id, name from " << GUILDS_TBL_NAME << ";";
+ const dal::RecordSet& guildInfo = mDb->execSql(sql.str());
+
+ // check that at least 1 guild was returned
+ if(guildInfo.isEmpty())
+ {
+ return guilds;
+ }
+
+ // loop through every row in the table and assign it to a guild
+ for ( unsigned int i = 0; i < guildInfo.rows(); ++i)
+ {
+ Guild* guild = new Guild(guildInfo(i,1));
+ guild->setId(toShort(guildInfo(i,0)));
+ guilds.push_back(guild);
+ }
+
+ /**
+ * Add the members to the guilds.
+ */
+
+ for (std::list<Guild*>::iterator itr = guilds.begin();
+ itr != guilds.end();
+ ++itr)
+ {
+ std::ostringstream memberSql;
+ memberSql << "select member_name from " << GUILD_MEMBERS_TBL_NAME
+ << " where guild_id = '" << (*itr)->getId() << "';";
+ const dal::RecordSet& memberInfo = mDb->execSql(memberSql.str());
+
+ for (unsigned int j = 0; j < memberInfo.rows(); ++j)
+ {
+ CharacterPtr character = getCharacter(memberInfo(j,0));
+ character->addGuild((*itr)->getName());
+ (*itr)->addMember(character.get());
+ }
+ }
+ }
+ catch (const dal::DbSqlQueryExecFailure& e) {
+ // TODO: throw an exception.
+ LOG_ERROR("SQL query failure: " << e.what());
+ }
+
+ return guilds;
+}
diff --git a/src/account-server/dalstorage.hpp b/src/account-server/dalstorage.hpp
index e6f6d185..a99bc5d2 100644
--- a/src/account-server/dalstorage.hpp
+++ b/src/account-server/dalstorage.hpp
@@ -28,6 +28,8 @@
#include "account-server/storage.hpp"
#include "dal/dataprovider.h"
+class Guild;
+
/**
* A storage class that relies on DAL.
*
@@ -84,6 +86,15 @@ class DALStorage: public Storage
* @return the character associated to the ID.
*/
CharacterPtr getCharacter(int id);
+
+ /**
+ * Gets a character by character name.
+ *
+ * @param name of the character
+ *
+ * @return the character associated to the name
+ */
+ CharacterPtr getCharacter(const std::string &name);
/**
* Add a new account.
@@ -152,6 +163,41 @@ class DALStorage: public Storage
updateChannels(std::map<short, ChatChannel>& channelList);
/**
+ * Add a new guild
+ *
+ */
+ void
+ addGuild(Guild* guild);
+
+ /**
+ * Delete a guild
+ *
+ */
+ void
+ removeGuild(Guild* guild);
+
+ /**
+ * Add member to guild
+ *
+ */
+ void
+ addGuildMember(int guild_id, const std::string &member_name);
+
+ /*
+ * Remove member from guild
+ */
+ void
+ removeGuildMember(int guildId, const std::string &memberName);
+
+ /**
+ * Get guild list
+ *@return a list of guilds
+ *
+ */
+ std::list<Guild*>
+ getGuildList();
+
+ /**
* Save changes to the database permanently.
*
* @exception tmwserv::dal::DbSqlQueryExecFailure.
diff --git a/src/account-server/dalstoragesql.hpp b/src/account-server/dalstoragesql.hpp
index c4a433af..df141f69 100644
--- a/src/account-server/dalstoragesql.hpp
+++ b/src/account-server/dalstoragesql.hpp
@@ -334,6 +334,55 @@ const std::string SQL_CHANNELS_TABLE(
");"
);
+/**
+ * TABLE: tmw_guilds.
+ * Store player guilds
+ */
+const std::string GUILDS_TBL_NAME("tmw_guilds");
+const std::string SQL_GUILDS_TABLE(
+ "CREATE TABLE tmw_guilds ("
+#if defined (MYSQL_SUPPORT)
+ "id INTEGER PRIMARY KEY AUTO_INCREMENT,"
+ "name VARCHAR(32) NOT NULL UNIQUE,"
+ "FOREIGN KEY (name) REFERENCES tmw_characters(name)"
+#elif defined (SQLITE_SUPPORT)
+ "id INTEGER PRIMARY KEY,"
+ "name TEXT NOT NULL UNIQUE,"
+ "FOREIGN KEY (name) REFERENCES tmw_characters(name)"
+#elif defined (POSTGRESQL_SUPPORT)
+ "id SERIAL PRIMARY KEY,"
+ "name TEXT NOT NULL UNIQUE,"
+ "FOREIGN KEY (name) REFERENCES tmw_characters(name)"
+#endif
+ ");"
+);
+
+/**
+ * TABLE: tmw_guild_members.
+ * Store guild members
+ */
+const std::string GUILD_MEMBERS_TBL_NAME("tmw_guild_members");
+const std::string SQL_GUILD_MEMBERS_TABLE(
+ "CREATE TABLE tmw_guild_members ("
+#if defined (MYSQL_SUPPORT)
+ "guild_id INTEGER NOT NULL,"
+ "member_name VARCHAR(32) NOT NULL,"
+ "FOREIGN KEY (guild_id) REFERENCES tmw_guilds(id),"
+ "FOREIGN KEY (member_name) REFERENCES tmw_characters(name)"
+#elif defined (SQLITE_SUPPORT)
+ "guild_id INTEGER NOT NULL,"
+ "member_name TEXT NOT NULL,"
+ "FOREIGN KEY (guild_id) REFERENCES tmw_guilds(id),"
+ "FOREIGN KEY (member_name) REFERENCES tmw_characters(name)"
+#elif defined (POSTGRESQL_SUPPORT)
+ "guild_id INTEGER NOT NULL,"
+ "member_name TEXT NOT NULL,"
+ "FOREIGN KEY (guild_id) REFERENCES tmw_guilds(id),"
+ "FOREIGN KEY (member_name) REFERENCES tmw_characters(name)"
+#endif
+ ");"
+);
+
} // anonymous namespace
diff --git a/src/account-server/guild.cpp b/src/account-server/guild.cpp
new file mode 100644
index 00000000..2e339ec1
--- /dev/null
+++ b/src/account-server/guild.cpp
@@ -0,0 +1,107 @@
+/*
+ * guild.cpp
+ * A file part of The Mana World
+ *
+ * Created by David Athay on 01/03/2007.
+ *
+ * Copyright (c) 2007, The Mana World Development Team
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * My name may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
+ *
+ * $Id$
+ */
+
+#include "guild.hpp"
+
+#include "account-server/characterdata.hpp"
+#include "account-server/storage.hpp"
+
+Guild::Guild(const std::string &name) :
+mName(name)
+{
+
+}
+
+Guild::~Guild()
+{
+
+}
+
+void Guild::addMember(CharacterData* player)
+{
+ mMembers.push_back(player);
+}
+
+void Guild::removeMember(CharacterData* player)
+{
+ mMembers.remove(player);
+}
+
+bool Guild::checkLeader(CharacterData* player)
+{
+ CharacterData* leader = mMembers.front();
+ if(leader == player)
+ return true;
+ return false;
+}
+
+bool Guild::checkInvited(const std::string &name)
+{
+ return (std::find(mInvited.begin(), mInvited.end(), name) != mInvited.end());
+}
+
+void Guild::addInvited(const std::string &name)
+{
+ mInvited.push_back(name);
+}
+
+const std::string& Guild::getName() const
+{
+ return mName;
+}
+
+std::string Guild::getMember(int i) const
+{
+ int x = 0;
+ for(guildMembers::const_iterator itr = mMembers.begin();
+ itr != mMembers.end();
+ ++itr, ++x)
+ {
+ if(x == i)
+ {
+ CharacterData *player = (*itr);
+ return player->getName();
+ }
+ }
+ return "";
+}
+
+bool Guild::checkInGuild(const std::string &name)
+{
+ for(guildMembers::iterator itr = mMembers.begin(); itr != mMembers.end(); ++itr)
+ {
+ CharacterData *player = (*itr);
+ if(player->getName() == name)
+ {
+ return true;
+ }
+ }
+ return false;
+}
diff --git a/src/account-server/guild.hpp b/src/account-server/guild.hpp
new file mode 100644
index 00000000..c91b6467
--- /dev/null
+++ b/src/account-server/guild.hpp
@@ -0,0 +1,109 @@
+/*
+ * The Mana World Server
+ * Copyright 2004 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * The Mana World is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or any later version.
+ *
+ * The Mana World is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with The Mana World; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * $Id$
+ */
+
+#ifndef _TMWSERV_ACCOUNTSERVER_GUILD_H_
+#define _TMWSERV_ACCOUNTSERVER_GUILD_H_
+
+#include <string>
+#include <list>
+
+class CharacterData;
+
+class Guild
+{
+public:
+ typedef std::list<CharacterData*> guildMembers;
+ Guild(const std::string &name);
+ ~Guild();
+
+ /**
+ * Add a member to the guild.
+ */
+ void addMember(CharacterData* player);
+
+ /**
+ * Remove a member from the guild.
+ */
+ void removeMember(CharacterData* player);
+
+ /**
+ * Check player is the leader of the guild.
+ */
+ bool checkLeader(CharacterData* player);
+
+ /**
+ * Set the ID of the guild.
+ */
+ void setId(short id)
+ {
+ mId = id;
+ }
+
+ /**
+ * Check if player has been invited to the guild.
+ */
+ bool checkInvited(const std::string &name);
+
+ /**
+ * Add a player to the invite list.
+ */
+ void addInvited(const std::string &name);
+
+ /**
+ * Returns the name of the guild.
+ */
+ const std::string& getName() const;
+
+ /**
+ * Returns the ID of the guild.
+ */
+ short getId() const
+ {
+ return mId;
+ }
+
+ /**
+ * Returns the total number of members in the guild.
+ */
+ short totalMembers() const
+ {
+ return mMembers.size();
+ }
+
+ /**
+ * Get a member in the guild
+ */
+ std::string getMember(int i) const;
+
+ /**
+ * Find member by name
+ */
+ bool checkInGuild(const std::string &name);
+
+private:
+ short mId;
+ std::string mName;
+ std::list<CharacterData*> mMembers;
+ std::list<std::string> mInvited;
+};
+
+#endif
diff --git a/src/account-server/guildmanager.cpp b/src/account-server/guildmanager.cpp
new file mode 100644
index 00000000..9fbec8c1
--- /dev/null
+++ b/src/account-server/guildmanager.cpp
@@ -0,0 +1,136 @@
+/*
+ * guildmanager.cpp
+ * A file part of The Mana World
+ *
+ * Created by David Athay on 01/03/2007.
+ *
+ * Copyright (c) 2007, The Mana World Development Team
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * My name may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
+ *
+ * $Id$
+ */
+
+#include "guildmanager.hpp"
+
+#include "account-server/characterdata.hpp"
+#include "account-server/guild.hpp"
+#include "account-server/storage.hpp"
+
+GuildManager::GuildManager()
+{
+ // Load stored guilds from db
+ Storage &store = Storage::instance("tmw");
+ mGuilds = store.getGuildList();
+}
+
+GuildManager::~GuildManager()
+{
+ for(std::list<Guild*>::iterator itr = mGuilds.begin(); itr != mGuilds.end(); ++itr)
+ {
+ Guild *guild = (*itr);
+ delete guild;
+ }
+}
+
+short GuildManager::createGuild(const std::string &name, CharacterData* player)
+{
+ Guild *guild = new Guild(name);
+ // Add guild to db
+ Storage &store = Storage::instance("tmw");
+ store.addGuild(guild);
+
+ // Make sure to add guild to mGuilds before searching for it
+ // to add the player
+ mGuilds.push_back(guild);
+ addGuildMember(guild->getId(), player);
+
+ return guild->getId();
+}
+
+void GuildManager::removeGuild(short guildId)
+{
+ Guild *guild = findById(guildId);
+ if(!guild)
+ return;
+ Storage &store = Storage::instance("tmw");
+ store.removeGuild(guild);
+}
+
+void GuildManager::addGuildMember(short guildId, CharacterData *player)
+{
+ Guild *guild = findById(guildId);
+ if(!guild)
+ return;
+ Storage &store = Storage::instance("tmw");
+ store.addGuildMember(guildId, player->getName());
+ guild->addMember(player);
+}
+
+void GuildManager::removeGuildMember(short guildId, CharacterData *player)
+{
+ Guild *guild = findById(guildId);
+ if(!guild)
+ return;
+ Storage &store = Storage::instance("tmw");
+ store.removeGuildMember(guildId, player->getName());
+ guild->removeMember(player);
+ if(guild->totalMembers() == 0)
+ {
+ removeGuild(guildId);
+ }
+}
+
+Guild *GuildManager::findById(short id)
+{
+ for(std::list<Guild*>::iterator itr = mGuilds.begin(); itr != mGuilds.end(); ++itr)
+ {
+ Guild *guild = (*itr);
+ if(guild->getId() == id)
+ {
+ return guild;
+ }
+ }
+ return NULL;
+}
+
+Guild *GuildManager::findByName(const std::string &name)
+{
+ std::list<Guild*>::iterator itr = mGuilds.begin();
+ for(; itr != mGuilds.end(); ++itr)
+ {
+ Guild *guild = (*itr);
+ if(guild->getName() == name)
+ {
+ return guild;
+ }
+ }
+ return NULL;
+}
+
+bool GuildManager::doesExist(const std::string &name)
+{
+ Guild *guild = findByName(name);
+ if(guild)
+ {
+ return true;
+ }
+ return false;
+}
diff --git a/src/account-server/guildmanager.hpp b/src/account-server/guildmanager.hpp
new file mode 100644
index 00000000..97ec87c3
--- /dev/null
+++ b/src/account-server/guildmanager.hpp
@@ -0,0 +1,76 @@
+/*
+ * guildmanager.hpp
+ * A file part of The Mana World
+ *
+ * Created by David Athay on 05/03/2007.
+ *
+ * Copyright (c) 2007, The Mana World Development Team
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * My name may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
+ *
+ * $Id$
+ */
+
+#include <list>
+
+class Guild;
+class CharacterData;
+
+class GuildManager
+{
+public:
+ /*
+ * Constructor/Destructor
+ */
+ GuildManager();
+ ~GuildManager();
+
+ /*
+ * Create/Remove guild
+ */
+ short createGuild(const std::string &name, CharacterData *player);
+ void removeGuild(short guildId);
+
+ /*
+ * Add member to guild
+ */
+ void addGuildMember(short guildId, CharacterData *player);
+
+ /*
+ * Remove member from guild
+ */
+ void removeGuildMember(short guildId, CharacterData *player);
+
+ /*
+ * Search for guilds
+ */
+ Guild *findById(short id);
+ Guild *findByName(const std::string &name);
+
+ /*
+ * Check if guild exists
+ */
+ bool doesExist(const std::string &name);
+
+private:
+ std::list<Guild*> mGuilds;
+};
+
+extern GuildManager *guildManager;
diff --git a/src/account-server/main-account.cpp b/src/account-server/main-account.cpp
index fd3037b2..70cde480 100644
--- a/src/account-server/main-account.cpp
+++ b/src/account-server/main-account.cpp
@@ -35,6 +35,7 @@
#include "resourcemanager.h"
#include "skill.h"
#include "account-server/accounthandler.hpp"
+#include "account-server/guildmanager.hpp"
#include "account-server/serverhandler.hpp"
#include "account-server/storage.hpp"
#include "chat-server/chatchannelmanager.hpp"
@@ -69,6 +70,9 @@ ServerHandler *serverHandler;
/** Chat Channels Manager */
ChatChannelManager *chatChannelManager;
+
+/** Guild Manager */
+GuildManager *guildManager;
/** Callback used when SIGQUIT signal is received. */
void closeGracefully(int dummy)
@@ -147,6 +151,8 @@ void initialize()
stringFilter = new StringFilter(&config);
// Initialize the Chat channels manager
chatChannelManager = new ChatChannelManager();
+ // Initialise the guild manager
+ guildManager = new GuildManager();
// --- Initialize the global handlers
// FIXME: Make the global handlers global vars or part of a bigger
@@ -204,6 +210,7 @@ void deinitialize()
// Destroy Managers
delete chatChannelManager;
+ delete guildManager;
// Get rid of persistent data storage
Storage::destroy();
diff --git a/src/account-server/serverhandler.cpp b/src/account-server/serverhandler.cpp
index b1fba564..47c23966 100644
--- a/src/account-server/serverhandler.cpp
+++ b/src/account-server/serverhandler.cpp
@@ -24,9 +24,13 @@
#include <cassert>
#include <sstream>
+#include "account-server/accountclient.hpp"
#include "account-server/characterdata.hpp"
+#include "account-server/guildmanager.hpp"
#include "account-server/serverhandler.hpp"
#include "account-server/storage.hpp"
+#include "chat-server/chathandler.hpp"
+#include "chat-server/chatchannelmanager.hpp"
#include "net/messagein.hpp"
#include "net/messageout.hpp"
#include "net/netcomputer.hpp"
@@ -175,6 +179,167 @@ void ServerHandler::processMessage(NetComputer *comp, MessageIn &msg)
mTokenCollector.addPendingConnect(magic_token, accountID);
} break;
+
+ case GAMSG_GUILD_CREATE:
+ {
+ LOG_DEBUG("GAMSG_GUILD_CREATE");
+
+ result.writeShort(AGMSG_GUILD_CREATE_RESPONSE);
+ // Check if the guild name is taken already
+ int playerId = msg.readLong();
+ std::string guildName = msg.readString();
+ if (guildManager->findByName(guildName) != NULL)
+ {
+ result.writeByte(ERRMSG_ALREADY_TAKEN);
+ break;
+ }
+ result.writeByte(ERRMSG_OK);
+
+ Storage &store = Storage::instance("tmw");
+ CharacterPtr ptr = store.getCharacter(playerId);
+
+ // Add guild to character data.
+ ptr->addGuild(guildName);
+
+ // Who to send data to at the other end
+ result.writeLong(playerId);
+
+ short guildId = guildManager->createGuild(guildName, ptr.get());
+ result.writeShort(guildId);
+ result.writeString(guildName);
+ result.writeShort(1);
+ enterChannel(guildName, ptr.get());
+ } break;
+
+ case GAMSG_GUILD_INVITE:
+ {
+ // Add Inviting member to guild here
+ LOG_DEBUG("Received msg ... GAMSG_GUILD_INVITE");
+ result.writeShort(AGMSG_GUILD_INVITE_RESPONSE);
+ // Check if user can invite users
+ int playerId = msg.readLong();
+ short id = msg.readShort();
+ std::string member = msg.readString();
+ Guild *guild = guildManager->findById(id);
+
+ Storage &store = Storage::instance("tmw");
+ CharacterPtr ptr = store.getCharacter(playerId);
+
+ if (!guild->checkLeader(ptr.get()))
+ {
+ // Return that the user doesnt have the rights to invite.
+ result.writeByte(ERRMSG_INSUFFICIENT_RIGHTS);
+ break;
+ }
+
+ if (guild->checkInGuild(member))
+ {
+ // Return that invited member already in guild.
+ result.writeByte(ERRMSG_ALREADY_TAKEN);
+ break;
+ }
+
+ // Send invite to player using chat server
+ if (store.doesCharacterNameExist(member))
+ {
+ sendInvite(member, ptr->getName(), guild->getName());
+ }
+
+ guild->addInvited(member);
+ result.writeByte(ERRMSG_OK);
+ } break;
+
+ case GAMSG_GUILD_ACCEPT:
+ {
+ // Add accepting into guild
+ LOG_DEBUG("Received msg ... GAMSG_GUILD_ACCEPT");
+ result.writeShort(AGMSG_GUILD_ACCEPT_RESPONSE);
+ int playerId = msg.readLong();
+ std::string guildName = msg.readString();
+ Guild *guild = guildManager->findByName(guildName);
+ if (!guild)
+ {
+ // Return the guild does not exist.
+ result.writeByte(ERRMSG_INVALID_ARGUMENT);
+ break;
+ }
+
+ Storage &store = Storage::instance("tmw");
+ CharacterPtr ptr = store.getCharacter(playerId);
+
+ if (!guild->checkInvited(ptr->getName()))
+ {
+ // Return the user was not invited.
+ result.writeByte(ERRMSG_INSUFFICIENT_RIGHTS);
+ break;
+ }
+
+ if (guild->checkInGuild(ptr->getName()))
+ {
+ // Return that the player is already in the guild.
+ result.writeByte(ERRMSG_ALREADY_TAKEN);
+ break;
+ }
+
+ result.writeByte(ERRMSG_OK);
+
+ // Who to send data to at the other end
+ result.writeLong(playerId);
+
+ // The guild id and guild name they have joined
+ result.writeShort(guild->getId());
+ result.writeString(guildName);
+
+ // Add member to guild
+ guildManager->addGuildMember(guild->getId(), ptr.get());
+
+ // Add guild to character
+ ptr->addGuild(guildName);
+
+ // Enter Guild Channel
+ enterChannel(guildName, ptr.get());
+ } break;
+
+ case GAMSG_GUILD_GET_MEMBERS:
+ {
+ LOG_DEBUG("Received msg ... GAMSG_GUILD_GET_MEMBERS");
+ result.writeShort(AGMSG_GUILD_GET_MEMBERS_RESPONSE);
+ int playerId = msg.readLong();
+ short guildId = msg.readShort();
+ Guild *guild = guildManager->findById(guildId);
+ if (!guild)
+ {
+ result.writeByte(ERRMSG_INVALID_ARGUMENT);
+ break;
+ }
+ result.writeByte(ERRMSG_OK);
+ result.writeLong(playerId);
+ result.writeShort(guildId);
+ for (int i = 0; i < guild->totalMembers(); ++i)
+ {
+ result.writeString(guild->getMember(i));
+ }
+ } break;
+
+ case GAMSG_GUILD_QUIT:
+ {
+ LOG_DEBUG("Received msg ... GAMSG_GUILD_QUIT");
+ result.writeShort(AGMSG_GUILD_QUIT_RESPONSE);
+ int playerId = msg.readLong();
+ short guildId = msg.readShort();
+ Guild *guild = guildManager->findById(guildId);
+ if (!guild)
+ {
+ result.writeByte(ERRMSG_INVALID_ARGUMENT);
+ break;
+ }
+ Storage &store = Storage::instance("tmw");
+ CharacterPtr ptr = store.getCharacter(playerId);
+ guildManager->removeGuildMember(guildId, ptr.get());
+ result.writeByte(ERRMSG_OK);
+ result.writeLong(playerId);
+ result.writeShort(guildId);
+ } break;
default:
LOG_WARN("ServerHandler::processMessage, Invalid message type: "
@@ -187,3 +352,59 @@ void ServerHandler::processMessage(NetComputer *comp, MessageIn &msg)
if (result.getLength() > 0)
comp->send(result);
}
+
+void ServerHandler::enterChannel(const std::string &name, CharacterData *player)
+{
+ MessageOut result(CPMSG_ENTER_CHANNEL_RESPONSE);
+ short channelId = chatChannelManager->getChannelId(name);
+ if (!chatChannelManager->isChannelRegistered(channelId))
+ {
+ // Channel doesnt exist yet so create one
+ channelId = chatChannelManager->registerPrivateChannel(
+ name,
+ "Guild Channel",
+ "");
+ }
+
+ if (chatChannelManager->addUserInChannel(player->getName(), channelId))
+ {
+ result.writeByte(ERRMSG_OK);
+
+ // The user entered the channel, now give him the channel id, the announcement string
+ // and the user list.
+ result.writeShort(channelId);
+ result.writeString(name);
+ result.writeString(chatChannelManager->getChannelAnnouncement(channelId));
+ std::vector< std::string > const &userList =
+ chatChannelManager->getUserListInChannel(channelId);
+ for (std::vector< std::string >::const_iterator i = userList.begin(),
+ i_end = userList.end();
+ i != i_end; ++i)
+ {
+ result.writeString(*i);
+ }
+
+ // Send an CPMSG_UPDATE_CHANNEL to warn other clients a user went
+ // in the channel.
+ chatHandler->warnUsersAboutPlayerEventInChat(channelId,
+ player->getName(),
+ CHAT_EVENT_NEW_PLAYER);
+
+ }
+
+ chatHandler->sendGuildEnterChannel(result, player->getName());
+}
+
+void ServerHandler::sendInvite(const std::string &invitedName, const std::string &inviterName,
+ const std::string &guildName)
+{
+ // TODO: Separate account and chat server
+ chatHandler->sendGuildInvite(invitedName, inviterName, guildName);
+}
+
+CharacterPtr ServerHandler::getCharacter(const std::string &name)
+{
+ Storage &store = Storage::instance("tmw");
+ CharacterPtr character = store.getCharacter(name);
+ return character;
+}
diff --git a/src/account-server/serverhandler.hpp b/src/account-server/serverhandler.hpp
index 9de15a89..5c57f03b 100644
--- a/src/account-server/serverhandler.hpp
+++ b/src/account-server/serverhandler.hpp
@@ -30,6 +30,8 @@
#include "net/connectionhandler.hpp"
#include "utils/countedptr.h"
+class AccountClient;
+
/**
* Manages communications with all the game servers. This class also keeps
* track of the maps each game server supports.
@@ -52,6 +54,16 @@ class ServerHandler: public ConnectionHandler
* Sends a magic token and character data to the relevant game server.
*/
void registerGameClient(std::string const &, CharacterPtr);
+
+ /**
+ * Get character (temp used by chat server).
+ */
+ CharacterPtr getCharacter(const std::string &name);
+
+ /**
+ * Make client join the specified guild channel
+ */
+ void enterChannel(const std::string &guildName, CharacterData *player);
protected:
/**
@@ -71,6 +83,13 @@ class ServerHandler: public ConnectionHandler
void computerDisconnected(NetComputer *comp);
private:
+
+ /**
+ * Send invite to user
+ */
+ void sendInvite(const std::string &invitedName, const std::string &inviterName,
+ const std::string &guildName);
+
struct Server
{
std::string address;
diff --git a/src/account-server/storage.hpp b/src/account-server/storage.hpp
index 15f0a5ff..c0abf004 100644
--- a/src/account-server/storage.hpp
+++ b/src/account-server/storage.hpp
@@ -29,6 +29,7 @@
#include "account-server/account.hpp"
#include "account-server/characterdata.hpp"
+#include "account-server/guild.hpp"
#include "chat-server/chatchannel.hpp"
/**
@@ -191,6 +192,15 @@ class Storage
* @return the character associated to the ID.
*/
virtual CharacterPtr getCharacter(int id) = 0;
+
+ /**
+ * Gets a character by name.
+ *
+ * @param name the name of the character.
+ *
+ * @return the character associated to the name.
+ */
+ virtual CharacterPtr getCharacter(const std::string &name) = 0;
/**
* Add a new account.
@@ -265,6 +275,41 @@ class Storage
updateChannels(std::map<short, ChatChannel>& channelList) = 0;
/**
+ * Add a new guild
+ *
+ */
+ virtual void
+ addGuild(Guild* guild) = 0;
+
+ /**
+ * Delete a guild
+ *
+ */
+ virtual void
+ removeGuild(Guild* guild) = 0;
+
+ /**
+ * Add member to guild
+ *
+ */
+ virtual void
+ addGuildMember(int guild_id, const std::string &member_name) = 0;
+
+ /**
+ * Remove member from guild
+ */
+ virtual void
+ removeGuildMember(int guildId, const std::string &memberName) = 0;
+
+ /**
+ * Get guild list
+ *@return a list of guilds
+ *
+ */
+ virtual std::list<Guild*>
+ getGuildList() = 0;
+
+ /**
* Saves the changes to all the accounts permanently.
*/
virtual void flushAll() = 0;
diff --git a/src/chat-server/chathandler.cpp b/src/chat-server/chathandler.cpp
index 75c8d915..d9c2360f 100644
--- a/src/chat-server/chathandler.cpp
+++ b/src/chat-server/chathandler.cpp
@@ -22,6 +22,10 @@
*/
#include "defines.h"
+#include "account-server/characterdata.hpp"
+#include "account-server/guild.hpp"
+#include "account-server/guildmanager.hpp"
+#include "account-server/serverhandler.hpp"
#include "chat-server/chatchannelmanager.hpp"
#include "chat-server/chathandler.hpp"
#include "net/connectionhandler.hpp"
@@ -155,12 +159,14 @@ void ChatHandler::processMessage(NetComputer *comp, MessageIn &message)
pendingClients.insert(std::make_pair(magic_token, &computer));
return;
}
+
computer.characterName = i->second.character;
computer.accountLevel = i->second.level;
pendingLogins.erase(i);
result.writeShort(CPMSG_CONNECT_RESPONSE);
result.writeByte(ERRMSG_OK);
computer.send(result);
+ sendGuildRejoin(computer);
return;
}
@@ -274,6 +280,12 @@ void ChatHandler::processMessage(NetComputer *comp, MessageIn &message)
result.writeByte(ERRMSG_INVALID_ARGUMENT);
break;
}
+
+ if(guildManager->doesExist(channelName))
+ {
+ result.writeByte(ERRMSG_INVALID_ARGUMENT);
+ break;
+ }
// If it's slang's free.
if (stringFilter->filterContent(channelName) &&
@@ -327,6 +339,11 @@ void ChatHandler::processMessage(NetComputer *comp, MessageIn &message)
result.writeShort(CPMSG_UNREGISTER_CHANNEL_RESPONSE);
short channelId = message.readShort();
+ std::string channelName = chatChannelManager->getChannelName(channelId);
+
+ // Get character based on name.
+ CharacterPtr character = serverHandler->getCharacter(computer.characterName);
+
if (!chatChannelManager->isChannelRegistered(channelId))
{
result.writeByte(ERRMSG_INVALID_ARGUMENT);
@@ -342,6 +359,16 @@ void ChatHandler::processMessage(NetComputer *comp, MessageIn &message)
else
result.writeByte(ERRMSG_FAILURE);
}
+ else if (guildManager->doesExist(channelName))
+ {
+ Guild *guild = guildManager->findByName(channelName);
+ if (guild->checkLeader(character.get()))
+ {
+ chatChannelManager->removeChannel(channelId);
+ guildManager->removeGuild(guild->getId());
+ result.writeByte(ERRMSG_OK);
+ }
+ }
else
{
result.writeByte(ERRMSG_INSUFFICIENT_RIGHTS);
@@ -392,6 +419,17 @@ void ChatHandler::processMessage(NetComputer *comp, MessageIn &message)
break;
}
}
+
+ if (guildManager->doesExist(channelName))
+ {
+ Guild *guild = guildManager->findByName(channelName);
+ if (!guild->checkInGuild(computer.characterName))
+ {
+ result.writeByte(ERRMSG_INVALID_ARGUMENT);
+ break;
+ }
+ sendUserJoined(channelId, computer.characterName);
+ }
if (chatChannelManager->addUserInChannel(computer.characterName, channelId))
{
result.writeByte(ERRMSG_OK);
@@ -400,8 +438,10 @@ void ChatHandler::processMessage(NetComputer *comp, MessageIn &message)
result.writeShort(channelId);
result.writeString(channelName);
result.writeString(chatChannelManager->getChannelAnnouncement(channelId));
- std::vector< std::string > const &userList = chatChannelManager->getUserListInChannel(channelId);
- for (std::vector< std::string >::const_iterator i = userList.begin(), i_end = userList.end();
+ std::vector< std::string > const &userList =
+ chatChannelManager->getUserListInChannel(channelId);
+ for (std::vector< std::string >::const_iterator i = userList.begin(),
+ i_end = userList.end();
i != i_end; ++i) {
result.writeString(*i);
}
@@ -427,6 +467,8 @@ void ChatHandler::processMessage(NetComputer *comp, MessageIn &message)
{
result.writeShort(CPMSG_QUIT_CHANNEL_RESPONSE);
short channelId = message.readShort();
+ std::string channelName = chatChannelManager->getChannelName(channelId);
+
if (channelId != 0 && chatChannelManager->isChannelRegistered(channelId))
{
if (chatChannelManager->removeUserFromChannel(computer.characterName, channelId))
@@ -438,6 +480,11 @@ void ChatHandler::processMessage(NetComputer *comp, MessageIn &message)
warnUsersAboutPlayerEventInChat(channelId,
computer.characterName,
CHAT_EVENT_LEAVING_PLAYER);
+ if(guildManager->doesExist(channelName))
+ {
+ // Send a user left message
+ sendUserLeft(channelId, computer.characterName);
+ }
}
else
{
@@ -456,7 +503,8 @@ void ChatHandler::processMessage(NetComputer *comp, MessageIn &message)
result.writeShort(CPMSG_LIST_CHANNELS_RESPONSE);
short numberOfPublicChannels;
- std::istringstream channels(chatChannelManager->getPublicChannelNames(&numberOfPublicChannels));
+ std::istringstream channels(chatChannelManager->getPublicChannelNames(
+ &numberOfPublicChannels));
for(int i = 0; i < numberOfPublicChannels; ++i)
{
@@ -468,6 +516,27 @@ void ChatHandler::processMessage(NetComputer *comp, MessageIn &message)
}
}
break;
+
+ case PCMSG_LIST_CHANNELUSERS:
+ {
+ result.writeShort(CPMSG_LIST_CHANNELUSERS_RESPONSE);
+
+ std::string channelName = message.readString();
+
+ result.writeString(channelName);
+
+ // get user list
+ std::vector<std::string> channelList;
+ channelList = chatChannelManager->getUserListInChannel(
+ chatChannelManager->getChannelId(channelName));
+
+ // add a user at a time
+ for(int i = 0; i < channelList.size(); ++i)
+ {
+ result.writeString(channelList[i]);
+ }
+
+ } break;
case PCMSG_DISCONNECT:
{
@@ -597,3 +666,75 @@ void ChatHandler::sendInChannel(short channelId, MessageOut &msg)
}
}
}
+
+void ChatHandler::sendGuildEnterChannel(const MessageOut &msg, const std::string &name)
+{
+ for (NetComputers::iterator i = clients.begin(), i_end = clients.end();
+ i != i_end; ++i) {
+ if (static_cast< ChatClient * >(*i)->characterName == name)
+ {
+ (*i)->send(msg);
+ break;
+ }
+ }
+}
+
+void ChatHandler::sendGuildInvite(const std::string &invitedName, const std::string &inviterName,
+ const std::string &guildName)
+{
+ MessageOut msg(CPMSG_GUILD_INVITED);
+ msg.writeString(inviterName);
+ msg.writeString(guildName);
+ for (NetComputers::iterator i = clients.begin(), i_end = clients.end();
+ i != i_end; ++i) {
+ if (static_cast< ChatClient * >(*i)->characterName == invitedName)
+ {
+ (*i)->send(msg);
+ break;
+ }
+ }
+}
+
+void ChatHandler::sendGuildRejoin(ChatClient &computer)
+{
+ // Get character based on name.
+ CharacterPtr character = serverHandler->getCharacter(computer.characterName);
+
+ // Get list of guilds and check what rights they have.
+ std::vector<std::string> guilds = character->getGuilds();
+ for(unsigned int i = 0; i != guilds.size(); ++i)
+ {
+ Guild *guild = guildManager->findByName(guilds[i]);
+ short leader = 0;
+ if(!guild)
+ {
+ return;
+ }
+ if(guild->checkLeader(character.get()))
+ {
+ leader = 1;
+ }
+ MessageOut msg(CPMSG_GUILD_REJOIN);
+ msg.writeString(guild->getName());
+ msg.writeShort(guild->getId());
+ msg.writeShort(leader);
+ computer.send(msg);
+ serverHandler->enterChannel(guild->getName(), character.get());
+ }
+}
+
+void ChatHandler::sendUserJoined(short channelId, const std::string &name)
+{
+ MessageOut msg(CPMSG_USERJOINED);
+ msg.writeShort(channelId);
+ msg.writeString(name);
+ sendInChannel(channelId, msg);
+}
+
+void ChatHandler::sendUserLeft(short channelId, const std::string &name)
+{
+ MessageOut msg(CPMSG_USERLEFT);
+ msg.writeShort(channelId);
+ msg.writeString(name);
+ sendInChannel(channelId, msg);
+}
diff --git a/src/chat-server/chathandler.hpp b/src/chat-server/chathandler.hpp
index 19c5f464..cda3f27e 100644
--- a/src/chat-server/chathandler.hpp
+++ b/src/chat-server/chathandler.hpp
@@ -49,6 +49,25 @@ class ChatHandler : public ConnectionHandler
*/
bool
startListen(enet_uint16 port);
+
+ /**
+ * Tell a list of user about an event in a chatchannel about a player.
+ */
+ void warnUsersAboutPlayerEventInChat(short channelId,
+ std::string const &userName,
+ char eventId);
+
+ /**
+ * Send Chat and Guild Info to chat client, so that they can
+ * join the correct channels.
+ */
+ void sendGuildEnterChannel(const MessageOut &msg, const std::string &name);
+
+ /**
+ * Send guild invite.
+ */
+ void sendGuildInvite(const std::string &invitedName, const std::string &inviterName,
+ const std::string &guildName);
protected:
/**
@@ -57,6 +76,11 @@ class ChatHandler : public ConnectionHandler
void processMessage(NetComputer *computer, MessageIn &message);
NetComputer *computerConnected(ENetPeer *);
void computerDisconnected(NetComputer *);
+
+ /**
+ * Send messages for each guild the character belongs to.
+ */
+ void sendGuildRejoin(ChatClient &computer);
private:
/**
@@ -92,17 +116,20 @@ class ChatHandler : public ConnectionHandler
void sendInChannel(short channelId, MessageOut &);
/**
- * Tell a list of user about an event in a chatchannel about a player.
- */
- void warnUsersAboutPlayerEventInChat(short channelId,
- std::string const &userName,
- char eventId);
-
- /**
* Removes outdated pending logins. These are connected clients that
* still haven't sent in their magic token.
*/
void removeOutdatedPending();
+
+ /**
+ * Send user joined message.
+ */
+ void sendUserJoined(short channelId, const std::string &name);
+
+ /**
+ * Send user left message.
+ */
+ void sendUserLeft(short channelId, const std::string &name);
};
/**
@@ -110,4 +137,6 @@ class ChatHandler : public ConnectionHandler
*/
void registerChatClient(std::string const &, std::string const &, int);
+extern ChatHandler *chatHandler;
+
#endif
diff --git a/src/defines.h b/src/defines.h
index ccd4a191..73e50ed3 100644
--- a/src/defines.h
+++ b/src/defines.h
@@ -165,6 +165,23 @@ enum {
PGMSG_USE_ITEM = 0x0300, // L item id
GPMSG_USE_RESPONSE = 0x0301, // B error
GPMSG_BEINGS_DAMAGE = 0x0310, // { W being id, W amount }*
+
+ // Guild
+ PGMSG_GUILD_CREATE = 0x0350, // S name
+ GPMSG_GUILD_CREATE_RESPONSE = 0x0351, // B error, W id
+ PGMSG_GUILD_INVITE = 0x0352, // W id, S name
+ GPMSG_GUILD_INVITE_RESPONSE = 0x0353, // B error
+ PGMSG_GUILD_ACCEPT = 0x0354, // S name
+ GPMSG_GUILD_ACCEPT_RESPONSE = 0x0355, // B error
+ PGMSG_GUILD_GET_MEMBERS = 0x0356, // W id
+ GPMSG_GUILD_GET_MEMBERS_RESPONSE = 0x0357, // S names
+ GPMSG_GUILD_JOINED = 0x0358, // W id, S name
+ GPMSG_GUILD_LEFT = 0x0359, // W id
+ PGMSG_GUILD_QUIT = 0x0360, // W id
+ GPMSG_GUILD_QUIT_RESPONSE = 0x0361, // B error, W id
+
+ CPMSG_GUILD_INVITED = 0x0370, // S name, S name
+ CPMSG_GUILD_REJOIN = 0x0371, // S name, W id, W rights
// Chat
CPMSG_ERROR = 0x0401, // B error
@@ -186,6 +203,10 @@ enum {
CPMSG_QUIT_CHANNEL_RESPONSE = 0x0422, // B error
PCMSG_LIST_CHANNELS = 0x0423, // -
CPMSG_LIST_CHANNELS_RESPONSE = 0x0424, // W number of channels, S channels
+ CPMSG_USERJOINED = 0x0425, // W channel, S name
+ CPMSG_USERLEFT = 0x0426, // W channel, S name
+ PCMSG_LIST_CHANNELUSERS = 0x0427, // S channel
+ CPMSG_LIST_CHANNELUSERS_RESPONSE = 0x0428, // S users
// Inter-server
GAMSG_REGISTER = 0x0500, // S address, W port, { W map id }*
@@ -195,6 +216,16 @@ enum {
GAMSG_REDIRECT = 0x0530, // L id
AGMSG_REDIRECT_RESPONSE = 0x0531, // L id, B*32 token, S game address, W game port
GAMSG_PLAYER_RECONNECT = 0x0532, // L id, B*32 token
+ GAMSG_GUILD_CREATE = 0x0550, // S name
+ AGMSG_GUILD_CREATE_RESPONSE = 0x0551, // B error, W id
+ GAMSG_GUILD_INVITE = 0x0552, // W id, S name
+ AGMSG_GUILD_INVITE_RESPONSE = 0x0553, // B error
+ GAMSG_GUILD_ACCEPT = 0x0554, // S name
+ AGMSG_GUILD_ACCEPT_RESPONSE = 0x0555, // B error
+ GAMSG_GUILD_GET_MEMBERS = 0x0556, // W id
+ AGMSG_GUILD_GET_MEMBERS_RESPONSE = 0x0557, // S names
+ GAMSG_GUILD_QUIT = 0x0558, // W id
+ AGMSG_GUILD_QUIT_RESPONSE = 0x0559, // B error
XXMSG_INVALID = 0x7FFF
};
@@ -207,7 +238,8 @@ enum {
ERRMSG_NO_LOGIN, // the user is not yet logged
ERRMSG_NO_CHARACTER_SELECTED, // the user needs a character
ERRMSG_INSUFFICIENT_RIGHTS, // the user is not privileged
- ERRMSG_INVALID_ARGUMENT // part of the received message was invalid
+ ERRMSG_INVALID_ARGUMENT, // part of the received message was invalid
+ ERRMSG_ALREADY_TAKEN // name used was already taken
};
// Login specific return values
diff --git a/src/game-server/accountconnection.cpp b/src/game-server/accountconnection.cpp
index e54605ff..e9ea2256 100644
--- a/src/game-server/accountconnection.cpp
+++ b/src/game-server/accountconnection.cpp
@@ -25,8 +25,11 @@
#include "defines.h"
#include "game-server/accountconnection.hpp"
#include "game-server/gamehandler.hpp"
+#include "game-server/map.hpp"
+#include "game-server/mapcomposite.hpp"
#include "game-server/mapmanager.hpp"
#include "game-server/character.hpp"
+#include "game-server/state.hpp"
#include "net/messagein.hpp"
#include "net/messageout.hpp"
#include "utils/logger.h"
@@ -86,6 +89,119 @@ void AccountConnection::processMessage(MessageIn &msg)
int port = msg.readShort();
gameHandler->completeServerChange(id, token, address, port);
} break;
+
+ case AGMSG_GUILD_CREATE_RESPONSE:
+ {
+ if(msg.readByte() == ERRMSG_OK)
+ {
+ int playerId = msg.readLong();
+
+ MessageOut result(GPMSG_GUILD_CREATE_RESPONSE);
+ result.writeByte(ERRMSG_OK);
+
+ /* Create a message that the player has joined the guild
+ * Output the guild ID and guild name
+ * Send a 1 if the player has rights
+ * to invite users, otherwise 0.
+ */
+ MessageOut out(GPMSG_GUILD_JOINED);
+ out.writeShort(msg.readShort());
+ out.writeString(msg.readString());
+ out.writeShort(msg.readShort());
+
+ Character *player = gameHandler->messageMap[playerId];
+ if(player)
+ {
+ gameHandler->sendTo(player, result);
+ gameHandler->sendTo(player, out);
+ }
+ }
+ } break;
+
+ case AGMSG_GUILD_INVITE_RESPONSE:
+ {
+ if(msg.readByte() == ERRMSG_OK)
+ {
+ int playerId = msg.readLong();
+
+ MessageOut result(GPMSG_GUILD_INVITE_RESPONSE);
+ result.writeByte(ERRMSG_OK);
+
+ Character *player = gameHandler->messageMap[playerId];
+ if(player)
+ {
+ gameHandler->sendTo(player, result);
+ }
+ }
+ } break;
+
+ case AGMSG_GUILD_ACCEPT_RESPONSE:
+ {
+ if(msg.readByte() == ERRMSG_OK)
+ {
+ int playerId = msg.readLong();
+
+ MessageOut result(GPMSG_GUILD_ACCEPT_RESPONSE);
+ result.writeByte(ERRMSG_OK);
+
+ /* Create a message that the player has joined the guild
+ * Output the guild ID and guild name
+ * Send a 0 for invite rights, since player has been invited
+ * they wont have any rights to invite other users yet.
+ */
+ MessageOut out(GPMSG_GUILD_JOINED);
+ out.writeShort(msg.readShort());
+ out.writeString(msg.readString());
+ out.writeShort(0);
+
+ Character *player = gameHandler->messageMap[playerId];
+ if(player)
+ {
+ gameHandler->sendTo(player, result);
+ gameHandler->sendTo(player, out);
+ }
+ }
+ } break;
+
+ case AGMSG_GUILD_GET_MEMBERS_RESPONSE:
+ {
+ if(msg.readByte() != ERRMSG_OK)
+ break;
+ int playerId = msg.readLong();
+ short guildId = msg.readShort();
+
+ MessageOut result(GPMSG_GUILD_GET_MEMBERS_RESPONSE);
+ result.writeByte(ERRMSG_OK);
+ result.writeShort(guildId);
+ while(msg.getUnreadLength())
+ {
+ result.writeString(msg.readString());
+ }
+
+ Character *player = gameHandler->messageMap[playerId];
+ if(player)
+ {
+ gameHandler->sendTo(player, result);
+ }
+ } break;
+
+ case AGMSG_GUILD_QUIT_RESPONSE:
+ {
+ if(msg.readByte() != ERRMSG_OK)
+ break;
+ int playerId = msg.readLong();
+ short guildId = msg.readShort();
+
+ MessageOut result(GPMSG_GUILD_QUIT_RESPONSE);
+ result.writeByte(ERRMSG_OK);
+ result.writeShort(guildId);
+
+ Character *player = gameHandler->messageMap[playerId];
+ if(player)
+ {
+ gameHandler->sendTo(player, result);
+ }
+ } break;
default:
LOG_WARN("Invalid message type");
@@ -101,3 +217,49 @@ void AccountConnection::playerReconnectAccount(int id, const std::string magic_t
msg.writeString(magic_token, MAGIC_TOKEN_LENGTH);
send(msg);
}
+
+void AccountConnection::playerCreateGuild(int id, const std::string &guildName)
+{
+ LOG_INFO("Send GAMSG_GUILD_CREATE");
+ MessageOut msg(GAMSG_GUILD_CREATE);
+ msg.writeLong(id);
+ msg.writeString(guildName);
+ send(msg);
+}
+
+void AccountConnection::playerInviteToGuild(int id, short guildId, const std::string &member)
+{
+ LOG_INFO("Send GAMSG_GUILD_INVITE");
+ MessageOut msg(GAMSG_GUILD_INVITE);
+ msg.writeLong(id);
+ msg.writeShort(guildId);
+ msg.writeString(member);
+ send(msg);
+}
+
+void AccountConnection::playerAcceptInvite(int id, const std::string &guildName)
+{
+ LOG_INFO("Send GAMSG_GUILD_ACCEPT");
+ MessageOut msg(GAMSG_GUILD_ACCEPT);
+ msg.writeLong(id);
+ msg.writeString(guildName);
+ send(msg);
+}
+
+void AccountConnection::getGuildMembers(int id, short guildId)
+{
+ LOG_INFO("Send GAMSG_GUILD_GET_MEMBERS");
+ MessageOut msg(GAMSG_GUILD_GET_MEMBERS);
+ msg.writeLong(id);
+ msg.writeShort(guildId);
+ send(msg);
+}
+
+void AccountConnection::quitGuild(int id, short guildId)
+{
+ LOG_INFO("Send GAMSG_GUILD_QUIT");
+ MessageOut msg(GAMSG_GUILD_QUIT);
+ msg.writeLong(id);
+ msg.writeShort(guildId);
+ send(msg);
+}
diff --git a/src/game-server/accountconnection.hpp b/src/game-server/accountconnection.hpp
index 24ee1598..700a85ca 100644
--- a/src/game-server/accountconnection.hpp
+++ b/src/game-server/accountconnection.hpp
@@ -50,6 +50,30 @@ class AccountConnection: public Connection
*/
void playerReconnectAccount(int id, const std::string magic_token);
+ /**
+ * Sends create guild message
+ */
+ void playerCreateGuild(int id, const std::string &guildName);
+
+ /**
+ * Sends invite message
+ */
+ void playerInviteToGuild(int id, short guildId, const std::string &name);
+
+ /**
+ * Sends accept message
+ */
+ void playerAcceptInvite(int id, const std::string &name);
+
+ /**
+ * Sends get guild members message.
+ */
+ void getGuildMembers(int id, short guildId);
+
+ /**
+ * Sends quit guild message.
+ */
+ void quitGuild(int id, short guildId);
protected:
/**
diff --git a/src/game-server/gamehandler.cpp b/src/game-server/gamehandler.cpp
index 81f7a1e5..1ca4f756 100644
--- a/src/game-server/gamehandler.cpp
+++ b/src/game-server/gamehandler.cpp
@@ -258,6 +258,48 @@ void GameHandler::processMessage(NetComputer *comp, MessageIn &message)
computer.character = NULL;
computer.status = CLIENT_LOGIN;
} break;
+
+ case PGMSG_GUILD_CREATE:
+ {
+ std::string name = message.readString();
+ int characterId = computer.character->getDatabaseID();
+ messageMap[characterId] = computer.character;
+ accountHandler->playerCreateGuild(characterId, name);
+ } break;
+
+ case PGMSG_GUILD_INVITE:
+ {
+ short guildId = message.readShort();
+ std::string member = message.readString();
+ int characterId = computer.character->getDatabaseID();
+ messageMap[characterId] = computer.character;
+ accountHandler->playerInviteToGuild(characterId, guildId, member);
+ } break;
+
+ case PGMSG_GUILD_ACCEPT:
+ {
+ std::string guildName = message.readString();
+ int characterId = computer.character->getDatabaseID();
+ messageMap[characterId] = computer.character;
+ accountHandler->playerAcceptInvite(characterId, guildName);
+ } break;
+
+ case PGMSG_GUILD_GET_MEMBERS:
+ {
+ short guildId = message.readShort();
+ int characterId = computer.character->getDatabaseID();
+ messageMap[characterId] = computer.character;
+ accountHandler->getGuildMembers(characterId, guildId);
+ } break;
+
+ case PGMSG_GUILD_QUIT:
+ {
+ short guildId = message.readShort();
+ int characterId = computer.character->getDatabaseID();
+ messageMap[characterId] = computer.character;
+ accountHandler->quitGuild(characterId, guildId);
+ } break;
+
default:
LOG_WARN("Invalid message type");
result.writeShort(XXMSG_INVALID);
diff --git a/src/game-server/gamehandler.hpp b/src/game-server/gamehandler.hpp
index 1e39e750..85a38674 100644
--- a/src/game-server/gamehandler.hpp
+++ b/src/game-server/gamehandler.hpp
@@ -85,6 +85,12 @@ class GameHandler: public ConnectionHandler
*/
void completeServerChange(int id, std::string const &token,
std::string const &address, int port);
+
+ /**
+ * Map of character's and their id used for getting which character to
+ * forward account server messages back to.
+ */
+ std::map<int, Character*> messageMap;
/**
* Combines a client with it's character.
diff --git a/src/game-server/mapmanager.cpp b/src/game-server/mapmanager.cpp
index dcb91363..dac57cac 100644
--- a/src/game-server/mapmanager.cpp
+++ b/src/game-server/mapmanager.cpp
@@ -130,3 +130,8 @@ bool MapManager::isActive(int mapId) const
assert(i != maps.end());
return i->second.isActive;
}
+
+short MapManager::numberOfMaps() const
+{
+ return maps.size();
+}
diff --git a/src/game-server/mapmanager.hpp b/src/game-server/mapmanager.hpp
index 1ba7c8c7..8693dbfe 100644
--- a/src/game-server/mapmanager.hpp
+++ b/src/game-server/mapmanager.hpp
@@ -73,6 +73,11 @@ class MapManager
* Gets the activity status of the map.
*/
bool isActive(int) const;
+
+ /**
+ * Gets the number of maps
+ */
+ short numberOfMaps() const;
/**
* Destructor.
diff --git a/src/net/netcomputer.cpp b/src/net/netcomputer.cpp
index 47d7ea1a..345b408d 100644
--- a/src/net/netcomputer.cpp
+++ b/src/net/netcomputer.cpp
@@ -92,10 +92,11 @@ operator <<(std::ostream &os, const NetComputer &comp)
<< ((comp.mPeer->address.host & 0xff000000) >> 24);
else
// big-endian
- os << ((comp.mPeer->address.host & 0xff000000) >> 24) << "."
- << ((comp.mPeer->address.host & 0x00ff0000) >> 16) << "."
- << ((comp.mPeer->address.host & 0x0000ff00) >> 8) << "."
- << ((comp.mPeer->address.host & 0x000000ff) >> 0);
+ // TODO: test this
+ os << ((comp.mPeer->address.host & 0xff000000) >> 24) << "."
+ << ((comp.mPeer->address.host & 0x00ff0000) >> 16) << "."
+ << ((comp.mPeer->address.host & 0x0000ff00) >> 8) << "."
+ << ((comp.mPeer->address.host & 0x000000ff));
return os;
}