mirror of
https://git.themanaworld.org/mana/verse
synced 2026-08-16 04:23:07 -04:00
550 lines
14 KiB
C++
550 lines
14 KiB
C++
/*
|
|
* The ManaPlus Client
|
|
* Copyright (C) 2011-2017 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/resources/notifytypes.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 "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(PacketType::PACKET_WHISPER))
|
|
return;
|
|
send("!info " + toString(tick_time));
|
|
mRequest = true;
|
|
mSentNameRequest = true;
|
|
mRequestTime = cur_time + requestTimeout;
|
|
}
|
|
else if (!mGotInfo && !mSentInfoRequest && !mSentNameRequest)
|
|
{
|
|
if (!PacketLimiter::limitPackets(PacketType::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(PacketType::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(
|
|
fromInt(i, BeingId), 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, Online_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, Online_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, ChatMsgType::BY_SERVER);
|
|
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, ChatMsgType::BY_SERVER);
|
|
}
|
|
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;
|
|
}
|