summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrei Karas <akaras@inbox.ru>2011-06-14 23:23:30 +0300
committerAndrei Karas <akaras@inbox.ru>2011-06-14 23:36:38 +0300
commitbf9bccc30a186e338f96c230a4f63cc924c77bd8 (patch)
treee46dbc2f022842982d89164ee598e1bcf827aa39
parentfb0f86589ae9e2d582383cea43e0a391e8d4739d (diff)
downloadmv-bf9bccc30a186e338f96c230a4f63cc924c77bd8.tar.gz
mv-bf9bccc30a186e338f96c230a4f63cc924c77bd8.tar.bz2
mv-bf9bccc30a186e338f96c230a4f63cc924c77bd8.tar.xz
mv-bf9bccc30a186e338f96c230a4f63cc924c77bd8.zip
Add ability to add comments to any players.
-rw-r--r--src/being.cpp41
-rw-r--r--src/being.h15
-rw-r--r--src/client.cpp17
-rw-r--r--src/client.h5
-rw-r--r--src/gui/beingpopup.cpp26
-rw-r--r--src/gui/beingpopup.h1
-rw-r--r--src/gui/popupmenu.cpp55
-rw-r--r--src/gui/popupmenu.h19
-rw-r--r--src/resources/resourcemanager.cpp51
-rw-r--r--src/resources/resourcemanager.h17
-rw-r--r--src/utils/stringutils.cpp13
-rw-r--r--src/utils/stringutils.h4
12 files changed, 259 insertions, 5 deletions
diff --git a/src/being.cpp b/src/being.cpp
index d45bbcf74..508f56aef 100644
--- a/src/being.cpp
+++ b/src/being.cpp
@@ -216,7 +216,9 @@ Being::Being(int id, Type type, Uint16 subtype, Map *map):
mMinHit(0),
mMaxHit(0),
mCriticalHit(0),
- mPvpRank(0)
+ mPvpRank(0),
+ mComment(""),
+ mGotComment(false)
{
mSpriteRemap = new int[20];
mSpriteHide = new int[20];
@@ -236,6 +238,8 @@ Being::Being(int id, Type type, Uint16 subtype, Map *map):
if (getType() == PLAYER)
mShowName = config.getBoolValue("visiblenames");
+ else
+ mGotComment = true;
config.addListener("visiblenames", this);
@@ -2251,6 +2255,41 @@ void Being::clearCache()
beingInfoCache.clear();
}
+void Being::updateComment()
+{
+ if (mGotComment || mName.empty())
+ return;
+
+ mGotComment = true;
+ mComment = loadComment(mName);
+}
+
+std::string Being::loadComment(const std::string &name)
+{
+ std::string str = Client::getUsersDirectory()
+ + stringToHexPath(name) + "/comment.txt";
+ std::vector<std::string> lines;
+
+ ResourceManager *resman = ResourceManager::getInstance();
+ if (resman->existsLocal(str))
+ {
+ lines = resman->loadTextFileLocal(str);
+ if (lines.size() >= 2)
+ return lines[1];
+ }
+ return "";
+}
+
+void Being::saveComment(const std::string &name,
+ const std::string &comment)
+{
+ std::string dir = Client::getUsersDirectory()
+ + stringToHexPath(name);
+ std::string fileName = dir + "/comment.txt";
+ ResourceManager *resman = ResourceManager::getInstance();
+ resman->saveTextFile(dir, "comment.txt", name + "\n" + comment);
+}
+
BeingEquipBackend::BeingEquipBackend(Being *being):
mBeing(being)
{
diff --git a/src/being.h b/src/being.h
index 652b8a889..ddcef1930 100644
--- a/src/being.h
+++ b/src/being.h
@@ -725,8 +725,21 @@ class Being : public ActorSprite, public ConfigListener
std::string getGenderSignWithSpace() const;
+ void updateComment();
+
+ std::string getComment()
+ { return mComment; }
+
+ void setComment(std::string n)
+ { mComment = n; }
+
static void clearCache();
+ static std::string loadComment(const std::string &name);
+
+ static void saveComment(const std::string &name,
+ const std::string &comment);
+
protected:
/**
* Sets the new path for this being.
@@ -858,6 +871,8 @@ class Being : public ActorSprite, public ConfigListener
unsigned int mPvpRank;
int *mSpriteRemap;
int *mSpriteHide;
+ std::string mComment;
+ bool mGotComment;
};
extern std::list<BeingCacheEntry*> beingInfoCache;
diff --git a/src/client.cpp b/src/client.cpp
index 5e1fca53b..f20c674d9 100644
--- a/src/client.cpp
+++ b/src/client.cpp
@@ -235,6 +235,7 @@ Client *Client::mInstance = 0;
Client::Client(const Options &options):
mOptions(options),
mServerConfigDir(""),
+ mUsersDir(""),
mRootDir(""),
mCurrentDialog(0),
mQuitDialog(0),
@@ -1458,6 +1459,7 @@ void Client::initServerConfig(std::string serverName)
}
initPacketLimiter();
initTradeFilter();
+ initUsersDir();
player_relations.init();
// Initialize the item and emote shortcuts.
@@ -1844,6 +1846,16 @@ void Client::initTradeFilter()
}
}
+void Client::initUsersDir()
+{
+ mUsersDir = Client::getServerConfigDirectory() + "/users/";
+ if (mkdir_r(mUsersDir.c_str()))
+ {
+ logger->error(strprintf(_("%s doesn't exist and can't be created! "
+ "Exiting."), mUsersDir.c_str()));
+ }
+}
+
void Client::initPacketLimiter()
{
//here i setting packet limits. but current server is broken,
@@ -2049,6 +2061,11 @@ const std::string Client::getServerConfigDirectory()
return instance()->mServerConfigDir;
}
+const std::string Client::getUsersDirectory()
+{
+ return instance()->mUsersDir;
+}
+
void Client::setGuiAlpha(float n)
{
instance()->mGuiAlpha = n;
diff --git a/src/client.h b/src/client.h
index f03a213db..dc94bdd93 100644
--- a/src/client.h
+++ b/src/client.h
@@ -224,6 +224,8 @@ public:
static const std::string getServerConfigDirectory();
+ static const std::string getUsersDirectory();
+
static bool getIsMinimized()
{ return instance()->mIsMinimized; }
@@ -262,6 +264,8 @@ public:
void initTradeFilter();
+ void initUsersDir();
+
void initPacketLimiter();
void writePacketLimits(std::string packetLimitsName);
@@ -298,6 +302,7 @@ private:
std::string mUpdatesDir;
std::string mScreenshotDir;
std::string mServerConfigDir;
+ std::string mUsersDir;
std::string mRootDir;
std::string mServerName;
diff --git a/src/gui/beingpopup.cpp b/src/gui/beingpopup.cpp
index 1b32d2b7b..2ba79d1a1 100644
--- a/src/gui/beingpopup.cpp
+++ b/src/gui/beingpopup.cpp
@@ -59,10 +59,14 @@ BeingPopup::BeingPopup():
mBeingRank = new Label("A");
mBeingRank->setPosition(getPadding(), 3 * fontHeight);
+ mBeingComment = new Label("A");
+ mBeingComment->setPosition(getPadding(), 4 * fontHeight);
+
add(mBeingName);
add(mBeingParty);
add(mBeingGuild);
add(mBeingRank);
+ add(mBeingComment);
}
BeingPopup::~BeingPopup()
@@ -80,6 +84,9 @@ void BeingPopup::show(int x, int y, Being *b)
Label *label1 = mBeingParty;
Label *label2 = mBeingGuild;
Label *label3 = mBeingRank;
+ Label *label4 = mBeingComment;
+
+ b->updateComment();
mBeingName->setCaption(b->getName() + b->getGenderSignWithSpace());
if (gui)
@@ -94,6 +101,7 @@ void BeingPopup::show(int x, int y, Being *b)
label1->setCaption("");
label2->setCaption("");
label3->setCaption("");
+ label4->setCaption("");
if (!(b->getPartyName().empty()))
{
@@ -103,6 +111,7 @@ void BeingPopup::show(int x, int y, Being *b)
}
else
{
+ label4 = label3;
label3 = label2;
label2 = label1;
label1 = 0;
@@ -116,6 +125,7 @@ void BeingPopup::show(int x, int y, Being *b)
}
else
{
+ label4 = label3;
label3 = label2;
label2 = 0;
}
@@ -127,9 +137,21 @@ void BeingPopup::show(int x, int y, Being *b)
}
else
{
+ label4 = label3;
label3 = 0;
}
+ if (!b->getComment().empty())
+ {
+ label4->setCaption(strprintf(_("Comment: %s"),
+ b->getComment().c_str()));
+ label4->adjustSize();
+ }
+ else
+ {
+ label4 = 0;
+ }
+
int minWidth = mBeingName->getWidth();
if (label1 && label1->getWidth() > minWidth)
minWidth = label1->getWidth();
@@ -137,6 +159,8 @@ void BeingPopup::show(int x, int y, Being *b)
minWidth = label2->getWidth();
if (label3 && label3->getWidth() > minWidth)
minWidth = label3->getWidth();
+ if (label4 && label4->getWidth() > minWidth)
+ minWidth = label4->getWidth();
int height = getFont()->getHeight();
if (label1)
@@ -145,6 +169,8 @@ void BeingPopup::show(int x, int y, Being *b)
height += getFont()->getHeight();
if (label3)
height += getFont()->getHeight();
+ if (label4)
+ height += getFont()->getHeight();
setContentSize(minWidth + 10, height + 10);
diff --git a/src/gui/beingpopup.h b/src/gui/beingpopup.h
index ea4ece110..2aeb6c20c 100644
--- a/src/gui/beingpopup.h
+++ b/src/gui/beingpopup.h
@@ -55,6 +55,7 @@ class BeingPopup : public Popup
Label *mBeingParty;
Label *mBeingGuild;
Label *mBeingRank;
+ Label *mBeingComment;
};
#endif // BEINGPOPUP_H
diff --git a/src/gui/popupmenu.cpp b/src/gui/popupmenu.cpp
index aaf47f36a..0c5e7a365 100644
--- a/src/gui/popupmenu.cpp
+++ b/src/gui/popupmenu.cpp
@@ -103,6 +103,8 @@ PopupMenu::PopupMenu():
mBrowserBox->setLinkHandler(this);
mRenameListener.setMapItem(0);
mRenameListener.setDialog(0);
+ mPlayerListener.setNick("");
+ mPlayerListener.setDialog(0);
add(mBrowserBox);
}
@@ -240,6 +242,8 @@ void PopupMenu::showPopup(int x, int y, Being *being)
mBrowserBox->addRow(strprintf("@@items|%s@@",
_("Show Items")));
mBrowserBox->addRow(strprintf("@@undress|%s@@", _("Undress")));
+ mBrowserBox->addRow(strprintf(
+ "@@addcomment|%s@@", _("Add comment")));
if (player_relations.getDefault() & PlayerRelation::TRADE)
{
@@ -391,7 +395,7 @@ void PopupMenu::showPlayerPopup(int x, int y, std::string nick)
mBrowserBox->addRow("##3---");
mBrowserBox->addRow(strprintf("@@follow|%s@@", _("Follow")));
mBrowserBox->addRow(strprintf("@@imitation|%s@@", _("Imitation")));
-
+ mBrowserBox->addRow(strprintf("@@addcomment|%s@@", _("Add comment")));
if (player_node->isInParty() && player_node->getParty())
{
@@ -642,6 +646,8 @@ void PopupMenu::showChatPopup(int x, int y, ChatTab *tab)
mBrowserBox->addRow(strprintf("@@move|%s@@", _("Move")));
mBrowserBox->addRow(strprintf("@@items|%s@@", _("Show Items")));
mBrowserBox->addRow(strprintf("@@undress|%s@@", _("Undress")));
+ mBrowserBox->addRow(strprintf(
+ "@@addcomment|%s@@", _("Add comment")));
if (player_relations.getDefault() & PlayerRelation::TRADE)
{
@@ -690,6 +696,12 @@ void PopupMenu::showChatPopup(int x, int y, ChatTab *tab)
}
}
}
+ else
+ {
+ mBrowserBox->addRow(strprintf(
+ "@@addcomment|%s@@", _("Add comment")));
+ mBrowserBox->addRow("##3---");
+ }
}
mBrowserBox->addRow(strprintf("@@cancel|%s@@", _("Cancel")));
@@ -1170,6 +1182,27 @@ void PopupMenu::handleLink(const std::string &link,
{
Net::getBeingHandler()->undress(being);
}
+ else if (link == "addcomment" && !mNick.empty())
+ {
+ // TRANSLATORS: number of chars in string should be near original
+ TextDialog *dialog = new TextDialog(_("Player comment "),
+ // TRANSLATORS: number of chars in string should be near original
+ _("Comment: "));
+ mPlayerListener.setDialog(dialog);
+ mPlayerListener.setNick(mNick);
+
+ if (being)
+ {
+ being->updateComment();
+ dialog->setText(being->getComment());
+ }
+ else
+ {
+ dialog->setText(Being::loadComment(mNick));
+ }
+ dialog->setActionEventId("ok");
+ dialog->addActionListener(&mPlayerListener);
+ }
else if (link == "guild-kick" && !mNick.empty())
{
if (player_node)
@@ -1923,3 +1956,23 @@ void RenameListener::action(const gcn::ActionEvent &event)
}
mDialog = 0;
}
+
+PlayerListener::PlayerListener() :
+ mNick(""),
+ mDialog(0)
+{
+}
+
+void PlayerListener::action(const gcn::ActionEvent &event)
+{
+ if (event.getId() == "ok" && !mNick.empty() && mDialog)
+ {
+ std::string comment = mDialog->getText();
+ Being* being = actorSpriteManager->findBeingByName(
+ mNick, Being::PLAYER);
+ if (being)
+ being->setComment(comment);
+ Being::saveComment(mNick, comment);
+ }
+ mDialog = 0;
+}
diff --git a/src/gui/popupmenu.h b/src/gui/popupmenu.h
index 976e3e5d2..50d86ff37 100644
--- a/src/gui/popupmenu.h
+++ b/src/gui/popupmenu.h
@@ -65,6 +65,24 @@ class RenameListener : public gcn::ActionListener
TextDialog *mDialog;
};
+class PlayerListener : public gcn::ActionListener
+{
+ public:
+ PlayerListener();
+
+ void action(const gcn::ActionEvent &event);
+
+ void setNick(std::string name)
+ { mNick = name; }
+
+ void setDialog(TextDialog *dialog)
+ { mDialog = dialog; }
+
+ private:
+ std::string mNick;
+ TextDialog *mDialog;
+};
+
/**
* Window showing popup menu.
*/
@@ -149,6 +167,7 @@ class PopupMenu : public Popup, public LinkHandler
TextCommand *mSpell;
Window *mWindow;
RenameListener mRenameListener;
+ PlayerListener mPlayerListener;
TextDialog *mDialog;
Button *mButton;
std::string mNick;
diff --git a/src/resources/resourcemanager.cpp b/src/resources/resourcemanager.cpp
index aea598935..96902cb4c 100644
--- a/src/resources/resourcemanager.cpp
+++ b/src/resources/resourcemanager.cpp
@@ -34,11 +34,16 @@
#include "resources/soundeffect.h"
#include "resources/spritedef.h"
+#include "utils/mkdir.h"
+
#include <physfs.h>
#include <SDL_image.h>
#include <cassert>
+#include <fstream>
+#include <iostream>
#include <sstream>
+#include <sys/stat.h>
#include <sys/time.h>
#include "debug.h"
@@ -299,6 +304,17 @@ bool ResourceManager::exists(const std::string &path)
return PHYSFS_exists(path.c_str());
}
+bool ResourceManager::existsLocal(const std::string &path)
+{
+ bool flg(false);
+ std::fstream file;
+ file.open(path.c_str(), std::ios::in);
+ if (file.is_open())
+ flg = true;
+ file.close();
+ return flg;
+}
+
bool ResourceManager::isDirectory(const std::string &path)
{
return PHYSFS_isDirectory(path.c_str());
@@ -644,6 +660,41 @@ std::vector<std::string> ResourceManager::loadTextFile(
return lines;
}
+std::vector<std::string> ResourceManager::loadTextFileLocal(
+ const std::string &fileName)
+{
+ std::ifstream file;
+ char line[501];
+ std::vector<std::string> lines;
+
+ file.open(fileName.c_str(), std::ios::in);
+
+ if (!file.is_open())
+ {
+ logger->log("Couldn't load text file: %s", fileName.c_str());
+ return lines;
+ }
+
+ while (file.getline(line, 500))
+ lines.push_back(line);
+
+ return lines;
+}
+
+void ResourceManager::saveTextFile(std::string path, std::string name,
+ std::string text)
+{
+ if (!mkdir_r(path.c_str()))
+ {
+ std::ofstream file;
+ std::string fileName = path + "/" + name;
+
+ file.open(fileName.c_str(), std::ios::out);
+ file << text << std::endl;
+ file.close();
+ }
+}
+
SDL_Surface *ResourceManager::loadSDLSurface(const std::string &filename)
{
int fileSize;
diff --git a/src/resources/resourcemanager.h b/src/resources/resourcemanager.h
index 71cbdce62..0b73a796e 100644
--- a/src/resources/resourcemanager.h
+++ b/src/resources/resourcemanager.h
@@ -103,10 +103,16 @@ class ResourceManager
/**
* Checks whether the given file or directory exists in the search path
+ * (PhysFS)
*/
bool exists(const std::string &path);
/**
+ * Checks whether the given file or directory exists
+ */
+ bool existsLocal(const std::string &path);
+
+ /**
* Checks whether the given path is a directory.
*/
bool isDirectory(const std::string &path);
@@ -209,11 +215,20 @@ class ResourceManager
void *loadFile(const std::string &fileName, int &fileSize);
/**
- * Retrieves the contents of a text file.
+ * Retrieves the contents of a text file (PhysFS).
*/
std::vector<std::string> loadTextFile(const std::string &fileName);
/**
+ * Retrieves the contents of a text file.
+ */
+ std::vector<std::string> loadTextFileLocal(const std::string
+ &fileName);
+
+ void saveTextFile(std::string path, std::string name,
+ std::string text);
+
+ /**
* Loads the given filename as an SDL surface. The returned surface is
* expected to be freed by the caller using SDL_FreeSurface.
*/
diff --git a/src/utils/stringutils.cpp b/src/utils/stringutils.cpp
index 5e45b6168..dffec3f0c 100644
--- a/src/utils/stringutils.cpp
+++ b/src/utils/stringutils.cpp
@@ -474,7 +474,18 @@ std::string packList(std::list<std::string> &list)
return str;
}
-std::list<std::string> unpackList(const std::string str)
+std::list<std::string> unpackList(const std::string &str)
{
return splitToStringList(str, '|');
}
+
+std::string stringToHexPath(const std::string &str)
+{
+ if (str.empty())
+ return "";
+
+ std::string hex = strprintf("%%%2x/", (int)str[0]);
+ for (unsigned f = 1; f < str.size(); f ++)
+ hex += strprintf("%%%2x", (int)str[f]);
+ return hex;
+}
diff --git a/src/utils/stringutils.h b/src/utils/stringutils.h
index 9d22f8ba8..796df92c5 100644
--- a/src/utils/stringutils.h
+++ b/src/utils/stringutils.h
@@ -182,6 +182,8 @@ std::vector<std::string> getLang();
std::string packList(std::list<std::string> &list);
-std::list<std::string> unpackList(const std::string str);
+std::list<std::string> unpackList(const std::string &str);
+
+std::string stringToHexPath(const std::string &str);
#endif // UTILS_STRINGUTILS_H