/* * 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 "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 "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() { 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; }