diff options
Diffstat (limited to 'src/net')
-rw-r--r-- | src/net/tmwa/beinghandler.cpp | 2 | ||||
-rw-r--r-- | src/net/tmwa/chathandler.cpp | 2 | ||||
-rw-r--r-- | src/net/tmwa/guildmanager.cpp | 551 | ||||
-rw-r--r-- | src/net/tmwa/guildmanager.h | 106 |
4 files changed, 659 insertions, 2 deletions
diff --git a/src/net/tmwa/beinghandler.cpp b/src/net/tmwa/beinghandler.cpp index 8277e4805..20ab2cffa 100644 --- a/src/net/tmwa/beinghandler.cpp +++ b/src/net/tmwa/beinghandler.cpp @@ -25,7 +25,6 @@ #include "actormanager.h" #include "effectmanager.h" #include "guild.h" -#include "guildmanager.h" #include "party.h" #include "being/localplayer.h" @@ -39,6 +38,7 @@ #include "net/serverfeatures.h" +#include "net/tmwa/guildmanager.h" #include "net/tmwa/messageout.h" #include "net/tmwa/protocol.h" #include "net/tmwa/sprite.h" diff --git a/src/net/tmwa/chathandler.cpp b/src/net/tmwa/chathandler.cpp index 4a4810c58..e870ba563 100644 --- a/src/net/tmwa/chathandler.cpp +++ b/src/net/tmwa/chathandler.cpp @@ -24,7 +24,6 @@ #include "actormanager.h" #include "configuration.h" -#include "guildmanager.h" #include "being/localplayer.h" #include "being/playerrelations.h" @@ -38,6 +37,7 @@ #include "net/serverfeatures.h" +#include "net/tmwa/guildmanager.h" #include "net/tmwa/messageout.h" #include "net/tmwa/protocol.h" diff --git a/src/net/tmwa/guildmanager.cpp b/src/net/tmwa/guildmanager.cpp new file mode 100644 index 000000000..0e7b7a43a --- /dev/null +++ b/src/net/tmwa/guildmanager.cpp @@ -0,0 +1,551 @@ +/* + * The ManaPlus Client + * Copyright (C) 2011-2015 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * 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, see <http://www.gnu.org/licenses/>. + */ + +#include "net/tmwa/guildmanager.h" + +#include "actormanager.h" +#include "client.h" +#include "configuration.h" +#include "guild.h" +#include "notifymanager.h" + +#include "being/localplayer.h" + +#include "enums/net/packettypes.h" + +#include "gui/windows/chatwindow.h" +#include "gui/windows/socialwindow.h" + +#include "gui/widgets/tabs/chat/emulateguildtab.h" + +#include "net/chathandler.h" +#include "net/packetlimiter.h" +#include "net/serverfeatures.h" + +#include "utils/delete2.h" +#include "utils/timer.h" + +#include "resources/notifytypes.h" + +#include "debug.h" + +GuildManager *guildManager = nullptr; + +static const int requestTimeout = 5; + +bool GuildManager::mEnableGuildBot = false; + +GuildManager::GuildManager() : + mGotInfo(false), + mGotName(false), + mSentInfoRequest(false), + mSentNameRequest(false), + mHavePower(false), + mTempList(), + mTab(nullptr), + mRequest(false), + mRequestTime(cur_time + 3), + mGotOnlineInfo(false) +{ +} + +GuildManager::~GuildManager() +{ + delete2(mTab); +} + +void GuildManager::init() +{ + if (serverFeatures->haveNativeGuilds()) + { + mEnableGuildBot = false; + } + else + { + int val = serverConfig.getValue("enableGuildBot", -1); + if (val == -1) + { + if (client->isTmw()) + val = 1; + else + val = 0; + serverConfig.setValue("enableGuildBot", val); + } + mEnableGuildBot = val; + } + if (mEnableGuildBot) + { + if (!guildManager) + guildManager = new GuildManager(); + else + guildManager->reload(); + } + else if (guildManager) + { + delete2(guildManager); + } +} + +void GuildManager::reload() +{ + mGotInfo = false; + mGotName = false; + mHavePower = false; + mRequest = false; + mSentNameRequest = false; + mSentInfoRequest = false; + mGotOnlineInfo = false; + mRequestTime = 0; + mTempList.clear(); + + if (socialWindow) + { + Guild *const guild = Guild::getGuild(1); + if (guild && socialWindow) + socialWindow->removeTab(guild); + } + delete2(mTab); +} + +void GuildManager::send(const std::string &msg) +{ + chatHandler->privateMessage("guild", msg); +} + +void GuildManager::chat(const std::string &msg) +{ + if (!localPlayer || !mTab) + return; + + chatHandler->privateMessage("guild", msg); + mTab->chatLog(localPlayer->getName(), msg); +} + +void GuildManager::getNames(StringVect &names) const +{ + const Guild *const guild = createGuild(); + if (guild) + guild->getNames(names); +} + +void GuildManager::requestGuildInfo() +{ + if (mRequest && mRequestTime + 15 < cur_time) + return; + + if (!mGotName && !mSentNameRequest) + { + if (!PacketLimiter::limitPackets(PACKET_WHISPER)) + return; + send("!info " + toString(tick_time)); + mRequest = true; + mSentNameRequest = true; + mRequestTime = cur_time + requestTimeout; + } + else if (!mGotInfo && !mSentInfoRequest && !mSentNameRequest) + { + if (!PacketLimiter::limitPackets(PACKET_WHISPER)) + return; + send("!getonlineinfo " + toString(tick_time)); + mRequest = true; + mSentInfoRequest = true; + mRequestTime = cur_time + requestTimeout; + } +} + +void GuildManager::slowLogic() +{ + if (!mGotOnlineInfo && mGotName && mRequestTime < cur_time) + { + if (!PacketLimiter::limitPackets(PACKET_WHISPER)) + return; + send("!getonlineinfo " + toString(tick_time)); + mRequest = true; + mSentInfoRequest = true; + mRequestTime = cur_time + requestTimeout; + } +} + +void GuildManager::updateList() +{ + Guild *const guild = Guild::getGuild(1); + if (guild) + { + guild->setServerGuild(false); + StringVectCIter it = mTempList.begin(); + const StringVectCIter it_end = mTempList.end(); + int i = 0; + while (it != it_end) + { + std::string name = *it; + const size_t sz = name.size(); + if (sz > 1) + { + const int status = atoi(name.substr(sz - 1).c_str()); + + name = name.substr(0, sz - 1); + GuildMember *const m = guild->addMember(i, 0, name); + if (m) + { + m->setOnline(status & 1); + m->setGender(Gender::UNSPECIFIED); + if (status & 2) + m->setPos(10); + else + m->setPos(0); + if (localPlayer && name == localPlayer->getName()) + { + mHavePower = (status & 2); + m->setOnline(true); + } + } + } + ++ it; + i ++; + } + guild->sort(); + createTab(guild); + if (actorManager) + { + actorManager->updatePlayerGuild(); + actorManager->updatePlayerColors(); + } + if (socialWindow) + socialWindow->updateGuildCounter(); + } + mTempList.clear(); + mSentInfoRequest = false; + mGotInfo = true; +} + +void GuildManager::createTab(Guild *const guild) +{ + if (!mTab) + { + mTab = new EmulateGuildTab(chatWindow); + if (config.getBoolValue("showChatHistory")) + mTab->loadFromLogFile("#Guild"); + if (localPlayer) + localPlayer->addGuild(guild); + } +} + +Guild *GuildManager::createGuild() const +{ + Guild *const guild = Guild::getGuild(1); + if (!guild) + return nullptr; + + guild->setServerGuild(false); + return guild; +} + +bool GuildManager::processGuildMessage(const std::string &msg) +{ + const bool res = process(msg); + + if (!mRequest) + requestGuildInfo(); + + return res; +} + +bool GuildManager::process(std::string msg) +{ + if (msg.size() > 4 && msg[0] == '#' && msg[1] == '#') + msg = msg.substr(3); + + const bool haveNick = (msg.find(": ") != std::string::npos); + + if (!haveNick && findCutLast(msg, " is now Offline.")) + { + Guild *const guild = createGuild(); + if (!guild) + return false; + if (msg.size() < 4) + return false; + if (msg[0] == '#' && msg[1] == '#') + msg = msg.substr(3); + + GuildMember *const m = guild->addMember(msg); + if (m) + m->setOnline(false); + guild->sort(); + mRequest = false; + if (mTab) + mTab->showOnline(msg, false); + if (socialWindow) + socialWindow->updateGuildCounter(); + return true; + } + else if (!haveNick && findCutLast(msg, " is now Online.")) + { + Guild *const guild = createGuild(); + if (!guild) + return false; + if (msg.size() < 4) + return false; + if (msg[0] == '#' && msg[1] == '#') + msg = msg.substr(3); + GuildMember *const m = guild->addMember(msg); + if (m) + m->setOnline(true); + guild->sort(); + mRequest = false; + if (mTab) + mTab->showOnline(msg, true); + if (socialWindow) + socialWindow->updateGuildCounter(); + return true; + } + else if (findCutFirst(msg, "Welcome to the ")) + { + Guild *const guild = createGuild(); + if (!guild) + return false; +// logger->log("welcome message: %s", msg.c_str()); + const size_t pos = msg.find("! ("); + if (pos == std::string::npos) + return false; + msg = msg.substr(0, pos); + guild->setName(msg); + if (localPlayer) + localPlayer->setGuildName(msg); + mGotName = true; + mSentNameRequest = false; + mRequest = false; + return true; + } + else if (findCutFirst(msg, "Player name: ")) + { + Guild *const guild = createGuild(); + if (!guild) + return false; + size_t pos = msg.find("Access Level: "); + if (pos == std::string::npos) + return false; + + msg = msg.substr(pos); + if (!findCutFirst(msg, "Access Level: ")) + return false; + + pos = msg.find(", Guild:"); + if (pos == std::string::npos) + return false; + + const int level = atoi(msg.substr(0, pos).c_str()); + if (level >= 10) + mHavePower = true; + else + mHavePower = false; + + msg = msg.substr(pos + strlen(", Guild:")); + pos = msg.find(", No. Of Online Players: "); + if (pos == std::string::npos) + return false; + + msg = msg.substr(0, pos); +// logger->log("guild name: %s", msg.c_str()); + + guild->setName(msg); + if (localPlayer) + localPlayer->setGuildName(msg); + mGotName = true; + mSentNameRequest = false; + mRequest = false; + return true; + } + else if (findCutFirst(msg, "OL#")) + { +// logger->log("OL"); + mTempList.clear(); + splitToStringVector(mTempList, msg, '#'); + if (msg.empty() || msg[msg.size() - 1] != '#') + updateList(); + mRequest = false; + mGotOnlineInfo = true; + return true; + } + else if (findCutFirst(msg, "oL#")) + { +// logger->log("oL"); + splitToStringVector(mTempList, msg, '#'); + if (msg.empty() || msg[msg.size() - 1] != '#') + updateList(); + mRequest = false; + mGotOnlineInfo = true; + return true; + } + else if (msg == "You are currently not in a guild. For more information " + "or to discuss the possibility of adding you own guild " + "please contact Jero.") + { + mRequest = true; + return true; + } + else if (findCutFirst(msg, "You have been invited to the ") + && findCutLast(msg, " guild chat. If you would like to accept " + "this invitation please reply \"yes\" and if not then \"no\" .")) + { + if (socialWindow) + socialWindow->showGuildInvite(msg, 1, ""); + return true; + } + else if (!haveNick && (findCutLast(msg, " has been removed " + "from the Guild.") || findCutLast(msg, " has left the Guild."))) + { + Guild *const guild = createGuild(); + if (!guild) + return false; + if (msg.size() < 4) + return false; + if (msg[0] == '#' && msg[1] == '#') + msg = msg.substr(3); + + if (actorManager) + { + Being *const b = actorManager->findBeingByName( + msg, ActorType::Player); + + if (b) + { + b->clearGuilds(); + b->setGuildName(""); + b->updateColors(); + } + } + + guild->removeMember(msg); + return true; + } + else if (msg == "You have been removed from the Guild" + || msg == "You have left the Guild") + { + return afterRemove(); + } + else + { + Guild *const guild = createGuild(); + if (!guild) + return false; + if (!mTab) + { + createTab(guild); + } + if (mTab) + { + const size_t pos = msg.find(": ", 0); + if (pos != std::string::npos) + { + const std::string sender_name = msg.substr(0, pos); + if (!guild->getMember(sender_name)) + { + mTab->chatLog(msg); + return true; + } + + msg.erase(0, pos + 2); + if (msg.size() > 3 && msg[0] == '#' && msg[1] == '#') + msg.erase(0, 3); + + trim(msg); + mTab->chatLog(sender_name, msg); + } + else + { + mTab->chatLog(msg); + } + return true; + } + } + return false; +} + +void GuildManager::kick(const std::string &msg) +{ + send("!remove " + msg); +} + +void GuildManager::invite(const std::string &msg) +{ + send("!invite " + msg); +} + +void GuildManager::leave() +{ + send("!leave"); +} + +void GuildManager::notice(const std::string &msg) +{ + if (msg.empty()) + send("!removemotd"); + else + send("!setmotd " + msg); +} + +void GuildManager::clear() +{ + if (socialWindow) + { + Guild *const guild = Guild::getGuild(1); + if (guild) + socialWindow->removeTab(guild); + } +} + +void GuildManager::inviteResponse(const bool response) +{ + if (response) + send("yes"); + else + send("no"); +} + +bool GuildManager::afterRemove() +{ + Guild *const guild = createGuild(); + if (!guild) + return false; + guild->removeFromMembers(); + guild->clearMembers(); + if (localPlayer) + { + localPlayer->setGuildName(""); + localPlayer->clearGuilds(); + } + NotifyManager::notify(NotifyTypes::GUILD_LEFT); + delete2(mTab); + + if (socialWindow) + socialWindow->removeTab(guild); + if (actorManager) + { + actorManager->updatePlayerGuild(); + actorManager->updatePlayerColors(); + } + reload(); + return true; +} + +ChatTab *GuildManager::getTab() +{ + return mTab; +} diff --git a/src/net/tmwa/guildmanager.h b/src/net/tmwa/guildmanager.h new file mode 100644 index 000000000..2fa6b2df8 --- /dev/null +++ b/src/net/tmwa/guildmanager.h @@ -0,0 +1,106 @@ +/* + * The ManaPlus Client + * Copyright (C) 2011-2015 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * 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, see <http://www.gnu.org/licenses/>. + */ + +#ifndef GUILDMANAGER_H +#define GUILDMANAGER_H + +#ifdef TMWA_SUPPORT + +#include "utils/stringvector.h" + +#include "localconsts.h" + +class ChatTab; +class Guild; +class EmulateGuildTab; + +class GuildManager final +{ + public: + GuildManager(); + + A_DELETE_COPY(GuildManager) + + ~GuildManager(); + + static void init(); + + void chat(const std::string &msg); + + static void send(const std::string &msg); + + bool processGuildMessage(const std::string &msg); + + void getNames(StringVect &names) const; + + void requestGuildInfo(); + + void updateList(); + + static bool getEnableGuildBot() A_WARN_UNUSED + { return mEnableGuildBot; } + + static void kick(const std::string &msg); + + static void invite(const std::string &msg); + + static void leave(); + + static void notice(const std::string &msg); + + void createTab(Guild *const guild); + + Guild *createGuild() const A_WARN_UNUSED; + + static void clear(); + + void reload(); + + static void inviteResponse(const bool response); + + bool afterRemove(); + + void slowLogic(); + + bool havePower() const A_WARN_UNUSED + { return mHavePower; } + + ChatTab *getTab(); + + private: + bool process(std::string msg); + + static bool mEnableGuildBot; + bool mGotInfo; + bool mGotName; + bool mSentInfoRequest; + bool mSentNameRequest; + bool mHavePower; + StringVect mTempList; + EmulateGuildTab *mTab; + bool mRequest; + int mRequestTime; + bool mGotOnlineInfo; +}; + +extern GuildManager *guildManager; + +#endif // TMWA_SUPPORT +#endif // GUILDMANAGER_H |