diff options
-rw-r--r-- | mana.cbp | 2 | ||||
-rw-r--r-- | mana.files | 2 | ||||
-rw-r--r-- | src/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/chatlog.cpp | 177 | ||||
-rw-r--r-- | src/chatlog.h | 73 | ||||
-rw-r--r-- | src/client.cpp | 11 | ||||
-rw-r--r-- | src/client.h | 1 | ||||
-rw-r--r-- | src/gui/serverdialog.cpp | 3 | ||||
-rw-r--r-- | src/gui/setup_players.cpp | 17 | ||||
-rw-r--r-- | src/gui/setup_players.h | 3 | ||||
-rw-r--r-- | src/gui/widgets/chattab.cpp | 10 | ||||
-rw-r--r-- | src/gui/widgets/chattab.h | 2 | ||||
-rw-r--r-- | src/gui/widgets/whispertab.cpp | 7 | ||||
-rw-r--r-- | src/gui/widgets/whispertab.h | 2 | ||||
-rw-r--r-- | src/main.cpp | 4 | ||||
-rw-r--r-- | src/net/tmwa/gui/guildtab.cpp | 7 | ||||
-rw-r--r-- | src/net/tmwa/gui/guildtab.h | 2 | ||||
-rw-r--r-- | src/net/tmwa/gui/partytab.cpp | 7 | ||||
-rw-r--r-- | src/net/tmwa/gui/partytab.h | 2 |
20 files changed, 335 insertions, 1 deletions
@@ -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" /> @@ -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); |