summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDavid Athay <ko2fan@gmail.com>2008-09-19 14:39:49 +0000
committerDavid Athay <ko2fan@gmail.com>2008-09-19 14:39:49 +0000
commit712b197ea0fb305905b4762422fdae1c49008710 (patch)
treea063bac5542f1408283d8150bde5346c2e24640d /src
parent410f448669a2ed843ff0b412924c04c8fbe87458 (diff)
downloadmanaserv-712b197ea0fb305905b4762422fdae1c49008710.tar.gz
manaserv-712b197ea0fb305905b4762422fdae1c49008710.tar.bz2
manaserv-712b197ea0fb305905b4762422fdae1c49008710.tar.xz
manaserv-712b197ea0fb305905b4762422fdae1c49008710.zip
Added post communication between chat and game servers.
Diffstat (limited to 'src')
-rw-r--r--src/account-server/main-account.cpp7
-rw-r--r--src/account-server/serverhandler.cpp92
-rw-r--r--src/chat-server/post.cpp69
-rw-r--r--src/chat-server/post.hpp63
-rw-r--r--src/defines.h43
-rw-r--r--src/game-server/accountconnection.cpp74
-rw-r--r--src/game-server/accountconnection.hpp10
-rw-r--r--src/game-server/gamehandler.cpp25
-rw-r--r--src/game-server/gamehandler.hpp10
-rw-r--r--src/game-server/main-game.cpp6
-rw-r--r--src/game-server/postman.hpp60
11 files changed, 440 insertions, 19 deletions
diff --git a/src/account-server/main-account.cpp b/src/account-server/main-account.cpp
index c4c451ee..f203f363 100644
--- a/src/account-server/main-account.cpp
+++ b/src/account-server/main-account.cpp
@@ -38,6 +38,7 @@
#include "chat-server/chatchannelmanager.hpp"
#include "chat-server/chathandler.hpp"
#include "chat-server/guildmanager.hpp"
+#include "chat-server/post.hpp"
#include "common/configuration.hpp"
#include "net/connectionhandler.hpp"
#include "net/messageout.hpp"
@@ -67,6 +68,9 @@ ChatChannelManager *chatChannelManager;
/** Guild Manager */
GuildManager *guildManager;
+/** Post Manager */
+PostManager *postalManager;
+
/** Callback used when SIGQUIT signal is received. */
static void closeGracefully(int)
{
@@ -151,6 +155,8 @@ static void initialize()
chatChannelManager = new ChatChannelManager;
// Initialise the Guild manager
guildManager = new GuildManager;
+ // Initialise the post manager
+ postalManager = new PostManager;
// --- Initialize the global handlers
// FIXME: Make the global handlers global vars or part of a bigger
@@ -192,6 +198,7 @@ static void deinitialize()
delete stringFilter;
delete chatChannelManager;
delete guildManager;
+ delete postalManager;
// Get rid of persistent data storage
delete storage;
diff --git a/src/account-server/serverhandler.cpp b/src/account-server/serverhandler.cpp
index 7fc81100..db8d2640 100644
--- a/src/account-server/serverhandler.cpp
+++ b/src/account-server/serverhandler.cpp
@@ -31,6 +31,7 @@
#include "account-server/accounthandler.hpp"
#include "account-server/character.hpp"
#include "account-server/dalstorage.hpp"
+#include "chat-server/post.hpp"
#include "net/connectionhandler.hpp"
#include "net/messagein.hpp"
#include "net/messageout.hpp"
@@ -324,6 +325,97 @@ void ServerHandler::processMessage(NetComputer *comp, MessageIn &msg)
}
} break;
+ case GCMSG_REQUEST_POST:
+ {
+ // Retrieve the post for user
+ LOG_DEBUG("GCMSG_REQUEST_POST");
+ result.writeShort(CGMSG_POST_RESPONSE);
+
+ // get the character
+ int characterId = msg.readLong();
+ Character *ptr = storage->getCharacter(characterId, NULL);
+ if (!ptr)
+ {
+ // Invalid character
+ LOG_ERROR("Error finding character id for post");
+ break;
+ }
+
+ // get the post for that character
+ Post *post = postalManager->getPost(ptr);
+
+ // send the character id of receiver
+ result.writeLong(characterId);
+
+ // send the post if valid
+ if (post)
+ {
+ for (unsigned int i = 0; i < post->getNumberOfLetters(); ++i)
+ {
+ // get each letter, send the sender's id,
+ // the contents and any attachments
+ Letter *letter = post->getLetter(i);
+ result.writeLong(letter->getSender()->getDatabaseID());
+ result.writeString(letter->getContents());
+ std::vector<InventoryItem> items = letter->getAttachments();
+ for (unsigned int j = 0; j < items.size(); ++j)
+ {
+ result.writeShort(items[j].itemId);
+ result.writeShort(items[j].amount);
+ }
+ }
+
+ // clean up
+ postalManager->clearPost(ptr);
+ }
+
+ } break;
+
+ case GCMSG_STORE_POST:
+ {
+ // Store the letter for the user
+ LOG_DEBUG("GCMSG_STORE_POST");
+ result.writeShort(CGMSG_STORE_POST_RESPONSE);
+
+ // get the sender and receiver
+ int senderId = msg.readLong();
+ std::string receiverName = msg.readString();
+
+ // get their characters
+ Character *sender = storage->getCharacter(senderId, NULL);
+ Character *receiver = storage->getCharacter(receiverName);
+ if (!sender || !receiver)
+ {
+ // Invalid character
+ LOG_ERROR("Error finding character id for post");
+ result.writeByte(ERRMSG_INVALID_ARGUMENT);
+ break;
+ }
+
+ // get the letter contents
+ std::string contents = msg.readString();
+
+ std::vector< std::pair<int, int> > items;
+ while (msg.getUnreadLength())
+ {
+ items.push_back(std::pair<int, int>(msg.readShort(), msg.readShort()));
+ }
+
+ // save the letter
+ Letter *letter = new Letter(0, sender, receiver);
+ letter->addText(contents);
+ for (unsigned int i = 0; i < items.size(); ++i)
+ {
+ InventoryItem item;
+ item.itemId = items[i].first;
+ item.amount = items[i].second;
+ letter->addAttachment(item);
+ }
+ postalManager->addLetter(letter);
+
+ result.writeByte(ERRMSG_OK);
+ } break;
+
default:
LOG_WARN("ServerHandler::processMessage, Invalid message type: "
<< msg.getId());
diff --git a/src/chat-server/post.cpp b/src/chat-server/post.cpp
index ca5af04a..6fc06e2a 100644
--- a/src/chat-server/post.cpp
+++ b/src/chat-server/post.cpp
@@ -23,6 +23,7 @@
#include "post.hpp"
+#include "../account-server/character.hpp"
#include "../defines.h"
Letter::Letter(int type, Character *sender, Character *receiver)
@@ -31,6 +32,16 @@ Letter::Letter(int type, Character *sender, Character *receiver)
}
+Letter::~Letter()
+{
+ if (mSender)
+ delete mSender;
+
+ if (mReceiver)
+ delete mReceiver;
+
+}
+
void Letter::setExpiry(unsigned long expiry)
{
mExpiry = expiry;
@@ -41,6 +52,16 @@ unsigned long Letter::getExpiry() const
return mExpiry;
}
+void Letter::addText(const std::string &text)
+{
+ mContents = text;
+}
+
+std::string Letter::getContents()
+{
+ return mContents;
+}
+
bool Letter::addAttachment(InventoryItem item)
{
if (mAttachments.size() > MAX_ATTACHMENTS)
@@ -58,6 +79,29 @@ Character* Letter::getReceiver()
return mReceiver;
}
+Character* Letter::getSender()
+{
+ return mSender;
+}
+
+std::vector<InventoryItem> Letter::getAttachments()
+{
+ return mAttachments;
+}
+
+Post::~Post()
+{
+ std::vector<Letter*>::iterator itr_end = mLetters.end();
+ for (std::vector<Letter*>::iterator itr = mLetters.begin();
+ itr != itr_end;
+ ++itr)
+ {
+ delete (*itr);
+ }
+
+ mLetters.clear();
+}
+
bool Post::addLetter(Letter *letter)
{
if (mLetters.size() > MAX_LETTERS)
@@ -70,6 +114,20 @@ bool Post::addLetter(Letter *letter)
return true;
}
+Letter* Post::getLetter(int letter) const
+{
+ if (letter < 0 || letter > mLetters.size())
+ {
+ return NULL;
+ }
+ return mLetters[letter];
+}
+
+unsigned int Post::getNumberOfLetters() const
+{
+ return mLetters.size();
+}
+
void PostManager::addLetter(Letter *letter)
{
std::map<Character*, Post*>::iterator itr =
@@ -99,3 +157,14 @@ Post* PostManager::getPost(Character *player)
return itr->second;
}
+
+void PostManager::clearPost(Character *player)
+{
+ std::map<Character*, Post*>::iterator itr =
+ mPostBox.find(player);
+ if (itr != mPostBox.end())
+ {
+ delete itr->second;
+ mPostBox.erase(itr);
+ }
+}
diff --git a/src/chat-server/post.hpp b/src/chat-server/post.hpp
index f1102b7d..25aefb50 100644
--- a/src/chat-server/post.hpp
+++ b/src/chat-server/post.hpp
@@ -24,8 +24,8 @@
#ifndef _TMWSERV_POST_H_
#define _TMWSERV_POST_H_
-#include <list>
#include <map>
+#include <string>
#include <vector>
#include "../common/inventorydata.hpp"
@@ -38,11 +38,18 @@ class Letter
public:
/**
* Constructor
- * @param type Type of Letter
+ * @param type Type of Letter - unused
+ * @param sender Pointer to character that sent the letter
+ * @param receiver Pointer to character that will receive the letter
*/
Letter(int type, Character *sender, Character *receiver);
/**
+ * Destructor
+ */
+ ~Letter();
+
+ /**
* Set the expiry
*/
void setExpiry(unsigned long expiry);
@@ -53,8 +60,21 @@ public:
unsigned long getExpiry() const;
/**
+ * Add text contents of letter
+ * This overwrites whatever was there previously
+ * @param text The content of the letter to add
+ */
+ void addText(const std::string &text);
+
+ /**
+ * Get the text contents of letter
+ * @return String containing the text
+ */
+ std::string getContents();
+
+ /**
* Add an attachment
- * @param aitem The attachment to add to the letter
+ * @param item The attachment to add to the letter
* @return Returns true if the letter doesnt have too many attachments
*/
bool addAttachment(InventoryItem item);
@@ -65,9 +85,21 @@ public:
*/
Character* getReceiver();
+ /**
+ * Get the character who sent the letter
+ * @return Returns the Character who sent the letter
+ */
+ Character* getSender();
+
+ /**
+ * Get the attachments
+ */
+ std::vector<InventoryItem> getAttachments();
+
private:
unsigned int mType;
unsigned long mExpiry;
+ std::string mContents;
std::vector<InventoryItem> mAttachments;
Character *mSender;
Character *mReceiver;
@@ -77,11 +109,27 @@ class Post
{
public:
/**
+ * Destructor
+ */
+ ~Post();
+
+ /**
* Add letter to post
* @param letter Letter to add
* @return Returns true if post isnt full
*/
- bool addLetter(Letter *letter);
+ bool addLetter(Letter *letter);
+
+ /**
+ * Return next letter
+ */
+ Letter* getLetter(int letter) const;
+
+ /**
+ * Return number of letters in post
+ * @return Returns the size of mLetters
+ */
+ unsigned int getNumberOfLetters() const;
private:
std::vector<Letter*> mLetters;
@@ -103,8 +151,15 @@ public:
*/
Post* getPost(Character *player);
+ /**
+ * Remove the post for character
+ */
+ void clearPost(Character *player);
+
private:
std::map<Character*, Post*> mPostBox;
};
+extern PostManager *postalManager;
+
#endif
diff --git a/src/defines.h b/src/defines.h
index 4538945f..0e7574a9 100644
--- a/src/defines.h
+++ b/src/defines.h
@@ -91,7 +91,7 @@ enum
* - CPMSG_*: from chat server to client
* - PGMSG_*: from client to game server
* - GPMSG_*: from game server to client
- * Components: B byte, W word, D double word, S variable-size string
+ * Components: B byte, W word, L long, S variable-size string
* C tile-based coordinates (B*3)
*/
enum {
@@ -239,20 +239,32 @@ enum {
PCMSG_USER_MODE = 0x0465, // W channel id, S name, B mode
PCMSG_KICK_USER = 0x0466, // W channel id, S name
+ // Post
+ PGMSG_SEND_POST = 0x04A0, // S player, S letter, { W attachment id }
+ GPMSG_SEND_POST_RESPONSE = 0x04A1, // B error
+ PGMSG_GET_POST = 0x04A2, //
+ GPMSG_GET_POST_RESPONSE = 0x04A3, // { L sender id, S letter, { W attachment id } }
+
// Inter-server
- GAMSG_REGISTER = 0x0500, // S address, W port, { W map id }*
- AGMSG_ACTIVE_MAP = 0x0501, // W map id
- AGMSG_PLAYER_ENTER = 0x0510, // B*32 token, L id, S name, serialised character data
- GAMSG_PLAYER_DATA = 0x0520, // L id, serialised character data
- 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_SET_QUEST = 0x0540, // L id, S name, S value
- GAMSG_GET_QUEST = 0x0541, // L id, S name
- AGMSG_GET_QUEST_RESPONSE = 0x0542, // L id, S name, S value
- GAMSG_BAN_PLAYER = 0x550, // L id, W duration
- GAMSG_STATISTICS = 0x560, // { W map id, W thing nb, W monster nb, W player nb, { L character id }* }*
- CGMSG_CHANGED_PARTY = 0x0590, // L character id, L party id
+ GAMSG_REGISTER = 0x0500, // S address, W port, { W map id }*
+ AGMSG_ACTIVE_MAP = 0x0501, // W map id
+ AGMSG_PLAYER_ENTER = 0x0510, // B*32 token, L id, S name, serialised character data
+ GAMSG_PLAYER_DATA = 0x0520, // L id, serialised character data
+ 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_SET_QUEST = 0x0540, // L id, S name, S value
+ GAMSG_GET_QUEST = 0x0541, // L id, S name
+ AGMSG_GET_QUEST_RESPONSE = 0x0542, // L id, S name, S value
+ GAMSG_BAN_PLAYER = 0x0550, // L id, W duration
+ GAMSG_STATISTICS = 0x0560, // { W map id, W thing nb, W monster nb, W player nb, { L character id }* }*
+ CGMSG_CHANGED_PARTY = 0x0590, // L character id, L party id
+ GCMSG_REQUEST_POST = 0x05A0, // L character id
+ CGMSG_POST_RESPONSE = 0x05A1, // L receiver id, { L sender id, S letter, W num attachments { W attachment item id, W quantity } }
+ GCMSG_STORE_POST = 0x05A5, // L sender id, L receiver id, S letter, { W attachment item id, W quantity }
+ CGMSG_STORE_POST_RESPONSE = 0x05A6, // L id, B error
+
+
XXMSG_INVALID = 0x7FFF
};
@@ -269,7 +281,8 @@ enum {
ERRMSG_EMAIL_ALREADY_EXISTS, // The Email Address already exists
ERRMSG_ALREADY_TAKEN, // name used was already taken
ERRMSG_SERVER_FULL, // the server is overloaded
- ERRMSG_TIME_OUT // data failed to arrive in due time
+ ERRMSG_TIME_OUT, // data failed to arrive in due time
+ ERRMSG_TOO_MANY_ATTACHMENTS, // too many attachments in letter
};
// Login specific return values
diff --git a/src/game-server/accountconnection.cpp b/src/game-server/accountconnection.cpp
index 67ea9571..80e65730 100644
--- a/src/game-server/accountconnection.cpp
+++ b/src/game-server/accountconnection.cpp
@@ -30,6 +30,7 @@
#include "game-server/map.hpp"
#include "game-server/mapcomposite.hpp"
#include "game-server/mapmanager.hpp"
+#include "game-server/postman.hpp"
#include "game-server/quest.hpp"
#include "game-server/state.hpp"
#include "net/messagein.hpp"
@@ -112,6 +113,56 @@ void AccountConnection::processMessage(MessageIn &msg)
gameHandler->updateCharacter(charid, partyid);
} break;
+ case CGMSG_POST_RESPONSE:
+ {
+ // get the character
+ Character *character = postMan->getCharacter(msg.readLong());
+
+ // check character is still valid
+ if (!character)
+ {
+ break;
+ }
+
+ // create the message
+ MessageOut out(GPMSG_GET_POST_RESPONSE);
+
+ // get all the post for a character
+ while (msg.getUnreadLength())
+ {
+ // write the sender
+ out.writeLong(msg.readLong());
+
+ // write the contents
+ out.writeString(msg.readString());
+
+ // read the number of attachments then
+ // write the attachments
+ for (int i = 0; i < msg.readShort(); ++i)
+ {
+ // write the id and amount
+ out.writeShort(msg.readShort());
+ out.writeShort(msg.readShort());
+ }
+ }
+
+ // send post to character
+ gameHandler->sendTo(character, out);
+ } break;
+
+ case CGMSG_STORE_POST_RESPONSE:
+ {
+ // get character
+ Character *character = postMan->getCharacter(msg.readLong());
+
+ // create message and put error inside
+ MessageOut out(GPMSG_SEND_POST_RESPONSE);
+ out.writeByte(msg.readByte());
+
+ // send message to character
+ gameHandler->sendTo(character, out);
+ } break;
+
default:
LOG_WARN("Invalid message type");
break;
@@ -196,3 +247,26 @@ void AccountConnection::sendStatistics()
send(msg);
}
+void AccountConnection::sendPost(Character *c, MessageIn &msg)
+{
+ // send message to account server with id of sending player,
+ // the id of receiving player, the letter contents, and attachments
+ MessageOut out(GCMSG_STORE_POST);
+ out.writeLong(c->getDatabaseID());
+ out.writeString(msg.readString());
+ out.writeString(msg.readString());
+ while (msg.getUnreadLength())
+ {
+ // write the item id and amount for each attachment
+ out.writeLong(msg.readShort());
+ out.writeLong(msg.readShort());
+ }
+}
+
+void AccountConnection::getPost(Character *c)
+{
+ // send message to account server with id of retrieving player
+ MessageOut out(GCMSG_REQUEST_POST);
+ out.writeLong(c->getDatabaseID());
+ send(out);
+}
diff --git a/src/game-server/accountconnection.hpp b/src/game-server/accountconnection.hpp
index 6bad4651..2aa981ea 100644
--- a/src/game-server/accountconnection.hpp
+++ b/src/game-server/accountconnection.hpp
@@ -71,6 +71,16 @@ class AccountConnection : public Connection
*/
void sendStatistics();
+ /**
+ * Send letter
+ */
+ void sendPost(Character *, MessageIn &);
+
+ /**
+ * Get post
+ */
+ void getPost(Character *);
+
protected:
/**
* Processes server messages.
diff --git a/src/game-server/gamehandler.cpp b/src/game-server/gamehandler.cpp
index bd5248bd..3540ac51 100644
--- a/src/game-server/gamehandler.cpp
+++ b/src/game-server/gamehandler.cpp
@@ -34,6 +34,7 @@
#include "game-server/map.hpp"
#include "game-server/mapcomposite.hpp"
#include "game-server/npc.hpp"
+#include "game-server/postman.hpp"
#include "game-server/state.hpp"
#include "game-server/trade.hpp"
#include "net/messagein.hpp"
@@ -449,6 +450,16 @@ void GameHandler::processMessage(NetComputer *comp, MessageIn &message)
computer.character->respawn(); // plausibility check is done by character class
} break;
+ case PGMSG_SEND_POST:
+ {
+ handleSendPost(&computer, message);
+ } break;
+
+ case PGMSG_GET_POST:
+ {
+ handleGetPost(&computer, message);
+ } break;
+
default:
LOG_WARN("Invalid message type");
result.writeShort(XXMSG_INVALID);
@@ -585,3 +596,17 @@ void GameHandler::handleWalk(GameClient *client, MessageIn &message)
client->character->setDestination(dst);
}
+
+void GameHandler::handleSendPost(GameClient *client, MessageIn &message)
+{
+ // add the character so that the post man knows them
+ postMan->addCharacter(client->character);
+ accountHandler->sendPost(client->character, message);
+}
+
+void GameHandler::handleGetPost(GameClient *client, MessageIn &message)
+{
+ // add the character so that the post man knows them
+ postMan->addCharacter(client->character);
+ accountHandler->getPost(client->character);
+}
diff --git a/src/game-server/gamehandler.hpp b/src/game-server/gamehandler.hpp
index 77ba8a29..c41cdfd0 100644
--- a/src/game-server/gamehandler.hpp
+++ b/src/game-server/gamehandler.hpp
@@ -139,6 +139,16 @@ class GameHandler: public ConnectionHandler
*/
void handleWalk(GameClient *client, MessageIn &message);
+ /**
+ * Send a letter
+ */
+ void handleSendPost(GameClient *client, MessageIn &message);
+
+ /**
+ * Retrieve a letter
+ */
+ void handleGetPost(GameClient *client, MessageIn &message);
+
private:
/**
diff --git a/src/game-server/main-game.cpp b/src/game-server/main-game.cpp
index 2cf025e7..b1c454e4 100644
--- a/src/game-server/main-game.cpp
+++ b/src/game-server/main-game.cpp
@@ -37,6 +37,7 @@
#include "game-server/itemmanager.hpp"
#include "game-server/mapmanager.hpp"
#include "game-server/monstermanager.hpp"
+#include "game-server/postman.hpp"
#include "game-server/resourcemanager.hpp"
#include "game-server/state.hpp"
#include "net/connectionhandler.hpp"
@@ -66,6 +67,9 @@ GameHandler *gameHandler;
/** Account server message handler */
AccountConnection *accountHandler;
+/** Post Man **/
+PostMan *postMan;
+
/** Callback used when SIGQUIT signal is received. */
void closeGracefully(int)
{
@@ -148,6 +152,7 @@ void initialize()
// singleton or a local variable in the event-loop
gameHandler = new GameHandler;
accountHandler = new AccountConnection;
+ postMan = new PostMan;
// --- Initialize enet.
if (enet_initialize() != 0) {
@@ -183,6 +188,7 @@ void deinitialize()
// Destroy message handlers
delete gameHandler;
delete accountHandler;
+ delete postMan;
// Destroy Managers
delete stringFilter;
diff --git a/src/game-server/postman.hpp b/src/game-server/postman.hpp
new file mode 100644
index 00000000..45963cf9
--- /dev/null
+++ b/src/game-server/postman.hpp
@@ -0,0 +1,60 @@
+/*
+ * The Mana World
+ * Copyright 2008 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 _TMW_POSTMAN_H_
+#define _TMW_POSTMAN_H_
+
+#include <map>
+
+class Character;
+
+class PostMan
+{
+public:
+ Character* getCharacter(int id)
+ {
+ std::map<int, Character*>::iterator itr = mCharacters.find(id);
+ if (itr != mCharacters.end())
+ {
+ return itr->second;
+ }
+
+ return NULL;
+ }
+
+ void addCharacter(Character *player)
+ {
+ std::map<int, Character*>::iterator itr = mCharacters.find(player->getDatabaseID());
+ if (itr == mCharacters.end())
+ {
+ mCharacters.insert(std::pair<int, Character*>(player->getDatabaseID(), player));
+ }
+ }
+
+private:
+ std::map<int, Character*> mCharacters;
+};
+
+extern PostMan *postMan;
+
+#endif