summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mana.cbp2
-rw-r--r--mana.files2
-rw-r--r--src/CMakeLists.txt2
-rw-r--r--src/Makefile.am2
-rw-r--r--src/chatlog.cpp177
-rw-r--r--src/chatlog.h73
-rw-r--r--src/client.cpp11
-rw-r--r--src/client.h1
-rw-r--r--src/gui/serverdialog.cpp3
-rw-r--r--src/gui/setup_players.cpp17
-rw-r--r--src/gui/setup_players.h3
-rw-r--r--src/gui/widgets/chattab.cpp10
-rw-r--r--src/gui/widgets/chattab.h2
-rw-r--r--src/gui/widgets/whispertab.cpp7
-rw-r--r--src/gui/widgets/whispertab.h2
-rw-r--r--src/main.cpp4
-rw-r--r--src/net/tmwa/gui/guildtab.cpp7
-rw-r--r--src/net/tmwa/gui/guildtab.h2
-rw-r--r--src/net/tmwa/gui/partytab.cpp7
-rw-r--r--src/net/tmwa/gui/partytab.h2
20 files changed, 335 insertions, 1 deletions
diff --git a/mana.cbp b/mana.cbp
index 021e15cc..1be2b57e 100644
--- a/mana.cbp
+++ b/mana.cbp
@@ -110,6 +110,8 @@
<Unit filename="src\channel.h" />
<Unit filename="src\channelmanager.cpp" />
<Unit filename="src\channelmanager.h" />
+ <Unit filename="src\chatlog.cpp" />
+ <Unit filename="src\chatlog.h" />
<Unit filename="src\client.cpp" />
<Unit filename="src\client.h" />
<Unit filename="src\commandhandler.cpp" />
diff --git a/mana.files b/mana.files
index f95cd3a9..a0441637 100644
--- a/mana.files
+++ b/mana.files
@@ -54,6 +54,8 @@
./src/channel.h
./src/channelmanager.cpp
./src/channelmanager.h
+./src/chatlog.cpp
+./src/chatlog.h
./src/client.cpp
./src/client.h
./src/CMakeLists.txt
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 3c9e6e82..433a1d3d 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -412,6 +412,8 @@ SET(SRCS
being.h
beingmanager.cpp
beingmanager.h
+ chatlog.cpp
+ chatlog.h
client.cpp
client.h
channel.cpp
diff --git a/src/Makefile.am b/src/Makefile.am
index e46be7f5..a479f70c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -313,6 +313,8 @@ mana_SOURCES = gui/widgets/avatarlistbox.cpp \
being.h \
beingmanager.cpp \
beingmanager.h \
+ chatlog.cpp \
+ chatlog.h \
client.cpp \
client.h \
channel.cpp \
diff --git a/src/chatlog.cpp b/src/chatlog.cpp
new file mode 100644
index 00000000..1c43b403
--- /dev/null
+++ b/src/chatlog.cpp
@@ -0,0 +1,177 @@
+/*
+ * The Mana World
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana World.
+ *
+ * This program 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.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "chatlog.h"
+
+#include <iostream>
+#include <sstream>
+#include <dirent.h>
+
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/time.h>
+
+#ifdef WIN32
+#include <windows.h>
+#elif defined __APPLE__
+#include <Carbon/Carbon.h>
+#endif
+
+#include "log.h"
+#include "configuration.h"
+
+#include "utils/stringutils.h"
+
+ChatLogger::ChatLogger()
+{
+}
+
+ChatLogger::~ChatLogger()
+{
+ if (mLogFile.is_open())
+ mLogFile.close();
+}
+
+void ChatLogger::setLogFile(const std::string &logFilename)
+{
+ if (mLogFile.is_open())
+ mLogFile.close();
+
+ mLogFile.open(logFilename.c_str(), std::ios_base::app);
+
+ if (!mLogFile.is_open())
+ {
+ std::cout << "Warning: error while opening " << logFilename <<
+ " for writing.\n";
+ }
+}
+
+void ChatLogger::setLogDir(const std::string &logDir)
+{
+ mLogDir = logDir;
+
+ if (mLogFile.is_open())
+ mLogFile.close();
+
+ DIR *dir = opendir(mLogDir.c_str());
+ if (!dir)
+ makeDir(mLogDir);
+ else
+ closedir(dir);
+}
+
+void ChatLogger::log(std::string str)
+{
+ std::string dateStr = getDateString();
+ if (!mLogFile.is_open() || dateStr != mLogDate)
+ {
+ mLogDate = dateStr;
+ setLogFile(strprintf("%s/%s/#General_%s.log", mLogDir.c_str(),
+ mServerName.c_str(), dateStr.c_str()));
+ }
+
+ str = removeColors(str);
+ writeTo(mLogFile, str);
+}
+
+void ChatLogger::log(std::string name, std::string str)
+{
+ std::ofstream logFile;
+ logFile.open(strprintf("%s/%s/%s_%s.log", mLogDir.c_str(), mServerName.c_str(),
+ secureName(name).c_str(), getDateString().c_str()).c_str(),
+ std::ios_base::app);
+
+ if (!logFile.is_open())
+ return;
+
+ str = removeColors(str);
+ writeTo(logFile, str);
+
+ if (logFile.is_open())
+ logFile.close();
+}
+
+std::string ChatLogger::getDateString() const
+{
+ std::string date;
+
+ time_t rawtime;
+ struct tm *timeinfo;
+ char buffer [80];
+
+ time (&rawtime);
+ timeinfo = localtime(&rawtime);
+
+ strftime(buffer, 79, "%y-%m-%d", timeinfo);
+ date = buffer;
+ return date;
+}
+
+std::string ChatLogger::secureName(std::string &name) const
+{
+ for (unsigned int f = 0; f < name.length(); f ++)
+ {
+ if (name[f] < '0' && name[f] > '9' && name[f] < 'a' && name[f] > 'z'
+ && name[f] < 'A' && name[f] > 'Z'
+ && name[f] != '-' && name[f] != '+' && name[f] != '='
+ && name[f] != '.' && name[f] != ','&& name[f] != ')'
+ && name[f] != '(' && name[f] != '[' && name[f] != ')')
+ {
+ name[f] = '_';
+ }
+ }
+ return name;
+}
+
+void ChatLogger::writeTo(std::ofstream &file, const std::string &str) const
+{
+ file << str << std::endl;
+}
+
+void ChatLogger::setServerName(const std::string &serverName)
+{
+ mServerName = serverName;
+ if (mServerName == "")
+ mServerName = config.getValue("MostUsedServerName0",
+ "server.themanaworld.org");
+
+ if (mLogFile.is_open())
+ mLogFile.close();
+
+ secureName(mServerName);
+ if (mLogDir != "")
+ {
+ DIR *dir = opendir((mLogDir + "/" + mServerName).c_str());
+ if (!dir)
+ makeDir(mLogDir + "/" + mServerName);
+ else
+ closedir(dir);
+ }
+}
+
+void ChatLogger::makeDir(const std::string &dir)
+{
+#ifdef WIN32
+ mkdir(dir.c_str());
+#else
+ mkdir(dir.c_str(), 0750);
+#endif
+}
diff --git a/src/chatlog.h b/src/chatlog.h
new file mode 100644
index 00000000..c359e953
--- /dev/null
+++ b/src/chatlog.h
@@ -0,0 +1,73 @@
+/*
+ * The Mana World
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana World.
+ *
+ * This program 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.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _CHATLOG_H
+#define _CHATLOG_H
+
+#include <fstream>
+
+class ChatLogger
+{
+ public:
+ /**
+ * Constructor.
+ */
+ ChatLogger();
+
+ /**
+ * Destructor, closes log file.
+ */
+ ~ChatLogger();
+
+ void setLogDir(const std::string &logDir);
+
+ /**
+ * Enters a message in the log. The message will be timestamped.
+ */
+ void log(std::string str);
+
+ void log(std::string name, std::string str);
+
+ std::string getDateString() const;
+
+ std::string secureName(std::string &str) const;
+
+ void setServerName(const std::string &serverName);
+
+ private:
+ /**
+ * Sets the file to log to and opens it
+ */
+ void setLogFile(const std::string &logFilename);
+
+ void writeTo(std::ofstream &file, const std::string &str) const;
+
+ void makeDir(const std::string &dir);
+
+ std::ofstream mLogFile;
+ std::string mLogDir;
+ std::string mServerName;
+ std::string mLogDate;
+};
+
+extern ChatLogger *chatLogger;
+
+#endif
diff --git a/src/client.cpp b/src/client.cpp
index 44df362e..afc1ae1d 100644
--- a/src/client.cpp
+++ b/src/client.cpp
@@ -22,6 +22,7 @@
#include "client.h"
#include "main.h"
+#include "chatlog.h"
#include "configuration.h"
#include "emoteshortcut.h"
#include "game.h"
@@ -110,6 +111,7 @@ LoginData loginData;
Configuration config; /**< XML file configuration reader */
Configuration branding; /**< XML branding information reader */
Logger *logger; /**< Log object */
+ChatLogger *chatLogger; /**< Chat log object */
KeyboardConfig keyboard;
UserPalette *userPalette;
@@ -219,6 +221,12 @@ Client::Client(const Options &options):
initHomeDir();
initConfiguration();
+ chatLogger = new ChatLogger;
+ if (options.chatLogDir == "")
+ chatLogger->setLogDir(mLocalDataDir + std::string("/logs/"));
+ else
+ chatLogger->setLogDir(options.chatLogDir);
+
// Configure logger
logger->setLogFile(mLocalDataDir + std::string("/mana.log"));
logger->setLogToStandardOut(config.getValue("logToStandardOut", 0));
@@ -400,6 +408,9 @@ Client::Client(const Options &options):
branding.getValue("defaultServerType", "eathena"));
}
+ if (chatLogger)
+ chatLogger->setServerName(mCurrentServer.hostname);
+
if (loginData.username.empty() && loginData.remember)
loginData.username = config.getValue("username", "");
diff --git a/src/client.h b/src/client.h
index c120b248..7a3648f4 100644
--- a/src/client.h
+++ b/src/client.h
@@ -142,6 +142,7 @@ public:
std::string brandingPath;
std::string updateHost;
std::string dataPath;
+ std::string chatLogDir;
std::string configDir;
std::string localDataDir;
std::string screenshotDir;
diff --git a/src/gui/serverdialog.cpp b/src/gui/serverdialog.cpp
index 0fba5638..3eeb6f9c 100644
--- a/src/gui/serverdialog.cpp
+++ b/src/gui/serverdialog.cpp
@@ -21,6 +21,7 @@
#include "gui/serverdialog.h"
+#include "chatlog.h"
#include "client.h"
#include "configuration.h"
#include "gui.h"
@@ -344,6 +345,8 @@ void ServerDialog::action(const gcn::ActionEvent &event)
// Save the selected server
mServerInfo->save = true;
+ chatLogger->setServerName(mServerInfo->hostname);
+
saveCustomServers(*mServerInfo);
Client::setState(STATE_CONNECT_SERVER);
diff --git a/src/gui/setup_players.cpp b/src/gui/setup_players.cpp
index 06bae0ef..d92d7917 100644
--- a/src/gui/setup_players.cpp
+++ b/src/gui/setup_players.cpp
@@ -216,6 +216,7 @@ public:
#define ACTION_STRATEGY "strategy"
#define ACTION_WHISPER_TAB "whisper tab"
#define ACTION_SHOW_GENDER "show gender"
+#define ACTION_ENABLE_CHAT_LOG "enable log"
Setup_Players::Setup_Players():
mPlayerTableTitleModel(new StaticTableModel(1, COLUMNS_NR)),
@@ -231,7 +232,9 @@ Setup_Players::Setup_Players():
mWhisperTab(config.getValue("whispertab", false)),
mWhisperTabCheckBox(new CheckBox(_("Put all whispers in tabs"), mWhisperTab)),
mShowGender(config.getValue("showgender", false)),
- mShowGenderCheckBox(new CheckBox(_("Show gender"), mShowGender))
+ mShowGenderCheckBox(new CheckBox(_("Show gender"), mShowGender)),
+ mEnableChatLog(config.getValue("enableChatLog", false)),
+ mEnableChatLogCheckBox(new CheckBox(_("Enable Chat log"), mEnableChatLog))
{
setName(_("Players"));
@@ -281,6 +284,9 @@ Setup_Players::Setup_Players():
mShowGenderCheckBox->setActionEventId(ACTION_SHOW_GENDER);
mShowGenderCheckBox->addActionListener(this);
+ mEnableChatLogCheckBox->setActionEventId(ACTION_ENABLE_CHAT_LOG);
+ mEnableChatLogCheckBox->addActionListener(this);
+
reset();
// Do the layout
@@ -291,6 +297,7 @@ Setup_Players::Setup_Players():
place(0, 1, mPlayerScrollArea, 4, 4).setPadding(2);
place(0, 5, mDeleteButton);
place(0, 6, mShowGenderCheckBox, 2).setPadding(2);
+ place(0, 7, mEnableChatLogCheckBox, 2).setPadding(2);
place(2, 5, ignore_action_label);
place(2, 6, mIgnoreActionChoicesBox, 2).setPadding(2);
place(2, 7, mDefaultTrading);
@@ -349,6 +356,8 @@ void Setup_Players::apply()
if (beingManager && mShowGender != showGender)
beingManager->updatePlayerNames();
+
+ config.setValue("enableChatLog", mEnableChatLog);
}
void Setup_Players::cancel()
@@ -357,6 +366,8 @@ void Setup_Players::cancel()
mWhisperTabCheckBox->setSelected(mWhisperTab);
mShowGender = config.getValue("showgender", false);
mShowGenderCheckBox->setSelected(mShowGender);
+ mEnableChatLog = config.getValue("enableChatLog", false);
+ mEnableChatLogCheckBox->setSelected(mEnableChatLog);
}
void Setup_Players::action(const gcn::ActionEvent &event)
@@ -404,6 +415,10 @@ void Setup_Players::action(const gcn::ActionEvent &event)
{
mShowGender = mShowGenderCheckBox->isSelected();
}
+ else if (event.getId() == ACTION_ENABLE_CHAT_LOG)
+ {
+ mEnableChatLog = mEnableChatLogCheckBox->isSelected();
+ }
}
void Setup_Players::updatedPlayer(const std::string &name)
diff --git a/src/gui/setup_players.h b/src/gui/setup_players.h
index 5337b213..a62ffe1f 100644
--- a/src/gui/setup_players.h
+++ b/src/gui/setup_players.h
@@ -70,6 +70,9 @@ private:
bool mShowGender;
gcn::CheckBox *mShowGenderCheckBox;
+
+ bool mEnableChatLog;
+ gcn::CheckBox *mEnableChatLogCheckBox;
};
#endif
diff --git a/src/gui/widgets/chattab.cpp b/src/gui/widgets/chattab.cpp
index 39ea6887..8c300eca 100644
--- a/src/gui/widgets/chattab.cpp
+++ b/src/gui/widgets/chattab.cpp
@@ -21,6 +21,7 @@
#include "gui/widgets/chattab.h"
+#include "chatlog.h"
#include "commandhandler.h"
#include "configuration.h"
#include "localplayer.h"
@@ -180,6 +181,9 @@ void ChatTab::chatLog(std::string line, int own, bool ignoreRecord)
line = lineColor + timeStr.str() + tmp.nick + tmp.text;
+ if (config.getValue("enableChatLog", false))
+ saveToLogFile(line);
+
// We look if the Vertical Scroll Bar is set at the max before
// adding a row, otherwise the max will always be a row higher
// at comparison.
@@ -275,6 +279,12 @@ void ChatTab::handleCommand(const std::string &msg)
commandHandler->handleCommand(msg, this);
}
+void ChatTab::saveToLogFile(std::string &msg)
+{
+ if (chatLogger)
+ chatLogger->log(msg);
+}
+
void ChatTab::addRow(std::string &line)
{
std::string::size_type idx = 0;
diff --git a/src/gui/widgets/chattab.h b/src/gui/widgets/chattab.h
index 7fd3931e..2189a780 100644
--- a/src/gui/widgets/chattab.h
+++ b/src/gui/widgets/chattab.h
@@ -111,6 +111,8 @@ class ChatTab : public Tab
const std::string &args)
{ return false; }
+ virtual void saveToLogFile(std::string &msg);
+
protected:
friend class ChatWindow;
friend class WhisperWindow;
diff --git a/src/gui/widgets/whispertab.cpp b/src/gui/widgets/whispertab.cpp
index 858a2e6b..89ff72d3 100644
--- a/src/gui/widgets/whispertab.cpp
+++ b/src/gui/widgets/whispertab.cpp
@@ -21,6 +21,7 @@
#include "whispertab.h"
+#include "chatlog.h"
#include "commandhandler.h"
#include "localplayer.h"
@@ -114,3 +115,9 @@ bool WhisperTab::handleCommand(const std::string &type,
return true;
}
+
+void WhisperTab::saveToLogFile(std::string &msg)
+{
+ if (chatLogger)
+ chatLogger->log(getNick(), msg);
+} \ No newline at end of file
diff --git a/src/gui/widgets/whispertab.h b/src/gui/widgets/whispertab.h
index 447a8fe0..20a07449 100644
--- a/src/gui/widgets/whispertab.h
+++ b/src/gui/widgets/whispertab.h
@@ -39,6 +39,8 @@ class WhisperTab : public ChatTab
bool handleCommand(const std::string &type,
const std::string &args);
+ void saveToLogFile(std::string &msg);
+
protected:
friend class ChatWindow;
diff --git a/src/main.cpp b/src/main.cpp
index 56019976..404a1989 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -56,6 +56,7 @@ static void printHelp()
<< _(" -u --skip-update : Skip the update downloads") << endl
<< _(" -d --data : Directory to load game data from") << endl
<< _(" -L --localdata-dir : Directory to use as local data directory") << endl
+ << _(" -l --chat-log-dir : Chat log dir to use") << endl
<< _(" --screenshot-dir : Directory to store screenshots") << endl
#ifdef USE_OPENGL
<< _(" --no-opengl : Disable OpenGL for this session") << endl
@@ -86,6 +87,7 @@ static void parseOptions(int argc, char *argv[], Client::Options &options)
{ "skip-update", no_argument, 0, 'u' },
{ "username", required_argument, 0, 'U' },
{ "no-opengl", no_argument, 0, 'O' },
+ { "chat-log-dir", required_argument, 0, 'l' },
{ "version", no_argument, 0, 'v' },
{ "screenshot-dir", required_argument, 0, 'i' },
{ 0 }
@@ -144,6 +146,8 @@ static void parseOptions(int argc, char *argv[], Client::Options &options)
case 'O':
options.noOpenGL = true;
break;
+ case 'l':
+ options.chatLogDir = std::string(optarg);
case 'i':
options.screenshotDir = optarg;
break;
diff --git a/src/net/tmwa/gui/guildtab.cpp b/src/net/tmwa/gui/guildtab.cpp
index 794ad5cc..8b788bad 100644
--- a/src/net/tmwa/gui/guildtab.cpp
+++ b/src/net/tmwa/gui/guildtab.cpp
@@ -21,6 +21,7 @@
#include "net/tmwa/gui/guildtab.h"
+#include "chatlog.h"
#include "commandhandler.h"
#include "guild.h"
#include "localplayer.h"
@@ -114,4 +115,10 @@ void GuildTab::getAutoCompleteList(std::vector<std::string> &names) const
taGuild->getNames(names);
}
+void GuildTab::saveToLogFile(std::string &msg)
+{
+ if (chatLogger)
+ chatLogger->log("#Guild", msg);
+}
+
} // namespace TmwAthena
diff --git a/src/net/tmwa/gui/guildtab.h b/src/net/tmwa/gui/guildtab.h
index 031c81bf..12e15e16 100644
--- a/src/net/tmwa/gui/guildtab.h
+++ b/src/net/tmwa/gui/guildtab.h
@@ -39,6 +39,8 @@ class GuildTab : public ChatTab
bool handleCommand(const std::string &type, const std::string &args);
+ void saveToLogFile(std::string &msg);
+
protected:
void handleInput(const std::string &msg);
diff --git a/src/net/tmwa/gui/partytab.cpp b/src/net/tmwa/gui/partytab.cpp
index 03dadb04..0f3e8e24 100644
--- a/src/net/tmwa/gui/partytab.cpp
+++ b/src/net/tmwa/gui/partytab.cpp
@@ -21,6 +21,7 @@
#include "net/tmwa/gui/partytab.h"
+#include "chatlog.h"
#include "commandhandler.h"
#include "localplayer.h"
#include "party.h"
@@ -206,4 +207,10 @@ void PartyTab::getAutoCompleteList(std::vector<std::string> &names) const
p->getNames(names);
}
+void PartyTab::saveToLogFile(std::string &msg)
+{
+ if (chatLogger)
+ chatLogger->log("#Party", msg);
+}
+
} // namespace TmwAthena
diff --git a/src/net/tmwa/gui/partytab.h b/src/net/tmwa/gui/partytab.h
index 62027726..4c16ab46 100644
--- a/src/net/tmwa/gui/partytab.h
+++ b/src/net/tmwa/gui/partytab.h
@@ -39,6 +39,8 @@ class PartyTab : public ChatTab
bool handleCommand(const std::string &type, const std::string &args);
+ void saveToLogFile(std::string &msg);
+
protected:
void handleInput(const std::string &msg);