diff options
author | Andrei Karas <akaras@inbox.ru> | 2013-09-30 14:03:48 +0300 |
---|---|---|
committer | Andrei Karas <akaras@inbox.ru> | 2013-09-30 14:03:48 +0300 |
commit | 25d77892d72d455f8a89372687db45aefbc61cec (patch) | |
tree | de03cb1af09eebf6db853a6585b953884bcca3b2 /src/gui/whoisonline.cpp | |
parent | 05c22dd1a69fe90da67188c74a6995ee3747e937 (diff) | |
download | manaverse-25d77892d72d455f8a89372687db45aefbc61cec.tar.gz manaverse-25d77892d72d455f8a89372687db45aefbc61cec.tar.bz2 manaverse-25d77892d72d455f8a89372687db45aefbc61cec.tar.xz manaverse-25d77892d72d455f8a89372687db45aefbc61cec.zip |
move windows classes to windows directory.
Diffstat (limited to 'src/gui/whoisonline.cpp')
-rw-r--r-- | src/gui/whoisonline.cpp | 865 |
1 files changed, 0 insertions, 865 deletions
diff --git a/src/gui/whoisonline.cpp b/src/gui/whoisonline.cpp deleted file mode 100644 index 4fd630a46..000000000 --- a/src/gui/whoisonline.cpp +++ /dev/null @@ -1,865 +0,0 @@ -/* - * The ManaPlus Client - * Copyright (C) 2009 The Mana World Development Team - * Copyright (C) 2009-2010 Andrei Karas - * Copyright (C) 2011-2013 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 "gui/whoisonline.h" - -#include "guild.h" -#include "party.h" - -#include "gui/chatwindow.h" -#include "gui/socialwindow.h" -#include "gui/viewport.h" - -#include "gui/widgets/button.h" -#include "gui/widgets/browserbox.h" -#include "gui/widgets/scrollarea.h" - -#include "actorspritemanager.h" -#include "client.h" -#include "configuration.h" -#include "main.h" - -#include "being/localplayer.h" -#include "being/playerrelations.h" - -#include "net/download.h" -#include "net/net.h" -#include "net/playerhandler.h" - -#include "utils/gettext.h" -#include "utils/sdlhelper.h" - -#include <SDL_thread.h> -#include <vector> -#include <algorithm> - -// Curl should be included after Guichan to avoid Windows redefinitions -#include <curl/curl.h> - -#include "debug.h" - -#ifdef free -#undef free -#endif - -#ifdef malloc -#undef malloc -#endif - -class NameFunctuator final -{ - public: - bool operator()(const OnlinePlayer *left, - const OnlinePlayer *right) const - { - return (compareStrI(left->getNick(), right->getNick()) < 0); - } -} nameCompare; - -WhoIsOnline::WhoIsOnline() : - // TRANSLATORS: who is online window name - Window(_("Who Is Online - Updating"), false, nullptr, "whoisonline.xml"), - mThread(nullptr), - mDownloadStatus(UPDATE_LIST), - mDownloadComplete(true), - mDownloadedBytes(0), - mMemoryBuffer(nullptr), - mCurlError(new char[CURL_ERROR_SIZE]), - mBrowserBox(new BrowserBox(this)), - mScrollArea(new ScrollArea(mBrowserBox, false)), - mUpdateTimer(0), - mOnlinePlayers(), - mOnlineNicks(), - // TRANSLATORS: who is online. button. - mUpdateButton(new Button(this, _("Update"), "update", this)), - mAllowUpdate(true), - mShowLevel(false), - mUpdateOnlineList(config.getBoolValue("updateOnlineList")), - - mGroupFriends(true) -{ - mCurlError[0] = 0; - setWindowName("WhoIsOnline"); - - const int h = 350; - const int w = 200; - setDefaultSize(w, h, ImageRect::CENTER); - setVisible(false); - setCloseButton(true); - setResizable(true); - setStickyButtonLock(true); - setSaveVisible(true); - - mUpdateButton->setEnabled(false); - mUpdateButton->setDimension(gcn::Rectangle(5, 5, w - 10, 20 + 5)); - - mBrowserBox->setOpaque(false); - mBrowserBox->setHighlightMode(BrowserBox::BACKGROUND); - mScrollArea->setDimension(gcn::Rectangle(5, 20 + 10, w - 10, h - 10 - 30)); - mScrollArea->setSize(w - 10, h - 10 - 30); - mBrowserBox->setLinkHandler(this); - - add(mUpdateButton); - add(mScrollArea); - - setLocationRelativeTo(getParent()); - - loadWindowState(); - enableVisibleSound(true); - - download(); - - widgetResized(gcn::Event(nullptr)); - config.addListener("updateOnlineList", this); - config.addListener("groupFriends", this); - mGroupFriends = config.getBoolValue("groupFriends"); -} - -WhoIsOnline::~WhoIsOnline() -{ - config.removeListeners(this); - - if (mThread && SDL_GetThreadID(mThread)) - SDL_WaitThread(mThread, nullptr); - - free(mMemoryBuffer); - mMemoryBuffer = nullptr; - - // Remove possibly leftover temporary download - delete []mCurlError; - - FOR_EACH (std::set<OnlinePlayer*>::iterator, itd, mOnlinePlayers) - delete *itd; - mOnlinePlayers.clear(); - mOnlineNicks.clear(); -} - -void WhoIsOnline::handleLink(const std::string& link, gcn::MouseEvent *event) -{ - if (!event || event->getButton() == gcn::MouseEvent::LEFT) - { - if (chatWindow) - { - const std::string text = decodeLinkText(link); - if (config.getBoolValue("whispertab")) - { - chatWindow->localChatInput("/q " + text); - } - else - { - chatWindow->addInputText(std::string("/w \"").append( - text).append("\" ")); - } - } - } - else if (event->getButton() == gcn::MouseEvent::RIGHT) - { - if (player_node && link == player_node->getName()) - return; - - if (viewport) - { - if (actorSpriteManager) - { - const std::string text = decodeLinkText(link); - Being *const being = actorSpriteManager->findBeingByName( - text, Being::PLAYER); - - if (being && viewport) - { - viewport->showPopup(being); - return; - } - } - viewport->showPlayerPopup(link); - } - } -} - -void WhoIsOnline::updateWindow(std::vector<OnlinePlayer*> &friends, - std::vector<OnlinePlayer*> &neutral, - std::vector<OnlinePlayer*> &disregard, - std::vector<OnlinePlayer*> enemy, - size_t numOnline) -{ - // Set window caption - // TRANSLATORS: who is online window name - setCaption(_("Who Is Online - ") + toString(numOnline)); - - // List the online people - std::sort(friends.begin(), friends.end(), nameCompare); - std::sort(neutral.begin(), neutral.end(), nameCompare); - std::sort(disregard.begin(), disregard.end(), nameCompare); - bool addedFromSection(false); - FOR_EACH (std::vector<OnlinePlayer*>::const_iterator, it, friends) - { - mBrowserBox->addRow((*it)->getText()); - addedFromSection = true; - } - if (addedFromSection == true) - { - mBrowserBox->addRow("---"); - addedFromSection = false; - } - FOR_EACH (std::vector<OnlinePlayer*>::const_iterator, it, enemy) - { - mBrowserBox->addRow((*it)->getText()); - addedFromSection = true; - } - if (addedFromSection == true) - { - mBrowserBox->addRow("---"); - addedFromSection = false; - } - FOR_EACH (std::vector<OnlinePlayer*>::const_iterator, it, neutral) - { - mBrowserBox->addRow((*it)->getText()); - addedFromSection = true; - } - if (addedFromSection == true && !disregard.empty()) - mBrowserBox->addRow("---"); - - FOR_EACH (std::vector<OnlinePlayer*>::const_iterator, it, disregard) - mBrowserBox->addRow((*it)->getText()); - - if (mScrollArea->getVerticalMaxScroll() < - mScrollArea->getVerticalScrollAmount()) - { - mScrollArea->setVerticalScrollAmount( - mScrollArea->getVerticalMaxScroll()); - } -} - -void WhoIsOnline::loadList(std::vector<OnlinePlayer*> &list) -{ - mBrowserBox->clearRows(); - const size_t numOnline = list.size(); - std::vector<OnlinePlayer*> friends; - std::vector<OnlinePlayer*> neutral; - std::vector<OnlinePlayer*> disregard; - std::vector<OnlinePlayer*> enemy; - - FOR_EACH (std::set<OnlinePlayer*>::iterator, itd, mOnlinePlayers) - delete *itd; - mOnlinePlayers.clear(); - mOnlineNicks.clear(); - - mShowLevel = config.getBoolValue("showlevel"); - - FOR_EACH (std::vector<OnlinePlayer*>::const_iterator, it, list) - { - OnlinePlayer *player = *it; - const std::string nick = player->getNick(); - mOnlinePlayers.insert(player); - mOnlineNicks.insert(nick); - - if (!mShowLevel) - player->setLevel(0); - - switch (player_relations.getRelation(nick)) - { - case PlayerRelation::NEUTRAL: - default: - setNeutralColor(player); - neutral.push_back(player); - break; - - case PlayerRelation::FRIEND: - player->setText("2"); - if (mGroupFriends) - friends.push_back(player); - else - neutral.push_back(player); - break; - - case PlayerRelation::DISREGARDED: - case PlayerRelation::BLACKLISTED: - player->setText("8"); - disregard.push_back(player); - break; - - case PlayerRelation::ENEMY2: - player->setText("1"); - enemy.push_back(player); - break; - - case PlayerRelation::IGNORED: - case PlayerRelation::ERASED: - // Ignore the ignored. - break; - } - } - - updateWindow(friends, neutral, disregard, enemy, numOnline); - if (!mOnlineNicks.empty()) - { - if (chatWindow) - chatWindow->updateOnline(mOnlineNicks); - if (socialWindow) - socialWindow->updateActiveList(); - } - updateSize(); -} - -void WhoIsOnline::loadWebList() -{ - if (!mMemoryBuffer) - return; - - // Reallocate and include terminating 0 character - mMemoryBuffer = static_cast<char*>( - realloc(mMemoryBuffer, mDownloadedBytes + 1)); - mMemoryBuffer[mDownloadedBytes] = '\0'; - - mBrowserBox->clearRows(); - bool listStarted(false); - std::string lineStr; - int numOnline(0); - std::vector<OnlinePlayer*> friends; - std::vector<OnlinePlayer*> neutral; - std::vector<OnlinePlayer*> disregard; - std::vector<OnlinePlayer*> enemy; - - // Tokenize and add each line separately - char *line = strtok(mMemoryBuffer, "\n"); - const std::string gmText("(GM)"); - - FOR_EACH (std::set<OnlinePlayer*>::iterator, itd, mOnlinePlayers) - delete *itd; - - mOnlinePlayers.clear(); - mOnlineNicks.clear(); - - mShowLevel = config.getBoolValue("showlevel"); - - while (line) - { - std::string nick; - lineStr = line; - trim(lineStr); - if (listStarted == true) - { - if (lineStr.find(" users are online.") == std::string::npos) - { - if (lineStr.length() > 24) - { - nick = lineStr.substr(0, 24); - lineStr = lineStr.substr(25); - } - else - { - nick = lineStr; - lineStr.clear(); - } - trim(nick); - - bool isGM(false); - size_t pos = lineStr.find(gmText, 0); - if (pos != std::string::npos) - { - lineStr = lineStr.substr(pos + gmText.length()); - isGM = true; - } - - trim(lineStr); - pos = lineStr.find("/", 0); - - if (pos != std::string::npos) - lineStr = lineStr.substr(0, pos); - - int level = 0; - if (!lineStr.empty()) - level = atoi(lineStr.c_str()); - - if (actorSpriteManager) - { - Being *const being = actorSpriteManager->findBeingByName( - nick, Being::PLAYER); - if (being) - { - if (level > 0) - { - being->setLevel(level); - being->updateName(); - } - else - { - if (being->getLevel() > 1) - level = being->getLevel(); - } - } - } - - if (!mShowLevel) - level = 0; - - OnlinePlayer *const player = new OnlinePlayer(nick, - static_cast<signed char>(255), level, - GENDER_UNSPECIFIED, -1); - mOnlinePlayers.insert(player); - mOnlineNicks.insert(nick); - - if (isGM) - player->setIsGM(true); - - numOnline++; - switch (player_relations.getRelation(nick)) - { - case PlayerRelation::NEUTRAL: - default: - setNeutralColor(player); - neutral.push_back(player); - break; - - case PlayerRelation::FRIEND: - player->setText("2"); - if (mGroupFriends) - friends.push_back(player); - else - neutral.push_back(player); - break; - - case PlayerRelation::DISREGARDED: - case PlayerRelation::BLACKLISTED: - player->setText("8"); - disregard.push_back(player); - break; - - case PlayerRelation::ENEMY2: - player->setText("1"); - enemy.push_back(player); - break; - - case PlayerRelation::IGNORED: - case PlayerRelation::ERASED: - // Ignore the ignored. - break; - } - } - } - else if (lineStr.find("------------------------------") - != std::string::npos) - { - listStarted = true; - } - line = strtok(nullptr, "\n"); - } - - updateWindow(friends, neutral, disregard, enemy, numOnline); - - // Free the memory buffer now that we don't need it anymore - free(mMemoryBuffer); - mMemoryBuffer = nullptr; -} - -size_t WhoIsOnline::memoryWrite(void *ptr, size_t size, - size_t nmemb, FILE *stream) -{ - if (!stream) - return 0; - - WhoIsOnline *const wio = reinterpret_cast<WhoIsOnline *>(stream); - const size_t totalMem = size * nmemb; - wio->mMemoryBuffer = static_cast<char*>(realloc(wio->mMemoryBuffer, - wio->mDownloadedBytes + totalMem)); - if (wio->mMemoryBuffer) - { - memcpy(&(wio->mMemoryBuffer[wio->mDownloadedBytes]), ptr, totalMem); - wio->mDownloadedBytes += static_cast<int>(totalMem); - } - - return totalMem; -} - -int WhoIsOnline::downloadThread(void *ptr) -{ - int attempts = 0; - WhoIsOnline *const wio = reinterpret_cast<WhoIsOnline *>(ptr); - CURLcode res; - const std::string url(client->getOnlineUrl() + "/online.txt"); - - while (attempts < 1 && !wio->mDownloadComplete) - { - CURL *curl = curl_easy_init(); - if (curl) - { - if (!wio->mAllowUpdate) - { - curl_easy_cleanup(curl); - curl = nullptr; - break; - } - wio->mDownloadedBytes = 0; - curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, - WhoIsOnline::memoryWrite); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, ptr); - - curl_easy_setopt(curl, CURLOPT_USERAGENT, - strprintf(PACKAGE_EXTENDED_VERSION, - branding.getStringValue("appName").c_str()).c_str()); - - curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, wio->mCurlError); - curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); - curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1); - curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, ptr); - curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); - curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 7); - curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30); - Net::Download::addProxy(curl); - Net::Download::secureCurl(curl); - - // Make sure the resources2.txt and news.txt aren't cached, - // in order to always get the latest version. - struct curl_slist *pHeaders = nullptr; - pHeaders = curl_slist_append( - pHeaders, "pragma: no-cache"); - pHeaders = curl_slist_append(pHeaders, - "Cache-Control: no-cache"); - curl_easy_setopt(curl, CURLOPT_HTTPHEADER, pHeaders); - - if ((res = curl_easy_perform(curl)) != 0) - { - wio->mDownloadStatus = UPDATE_ERROR; - switch (res) - { - case CURLE_COULDNT_CONNECT: - default: - std::cerr << "curl error " - << static_cast<unsigned>(res) << ": " - << wio->mCurlError << " host: " - << url.c_str() << std::endl; - break; - } - attempts++; - curl_easy_cleanup(curl); - curl_slist_free_all(pHeaders); - curl = nullptr; - continue; - } - - curl_easy_cleanup(curl); - curl_slist_free_all(pHeaders); - - // It's stored in memory, we're done - wio->mDownloadComplete = true; - } - if (!wio->mAllowUpdate) - break; - attempts++; - } - - if (!wio->mDownloadComplete) - wio->mDownloadStatus = UPDATE_ERROR; - return 0; -} - -void WhoIsOnline::download() -{ - if (serverVersion < 3) - { - mDownloadComplete = true; - if (mThread && SDL_GetThreadID(mThread)) - SDL_WaitThread(mThread, nullptr); - - mDownloadComplete = false; - mThread = SDL::createThread(WhoIsOnline::downloadThread, - "whoisonline", this); - if (mThread == nullptr) - mDownloadStatus = UPDATE_ERROR; - } - else - { - if (client->limitPackets(PACKET_ONLINELIST)) - Net::getPlayerHandler()->requestOnlineList(); - } -} - -void WhoIsOnline::logic() -{ - BLOCK_START("WhoIsOnline::logic") - mScrollArea->logic(); - BLOCK_END("WhoIsOnline::logic") -} - -void WhoIsOnline::slowLogic() -{ - if (!mAllowUpdate) - return; - - BLOCK_START("WhoIsOnline::slowLogic") - if (mUpdateTimer == 0) - mUpdateTimer = cur_time; - - const double timeDiff = difftime(cur_time, mUpdateTimer); - const int timeLimit = isWindowVisible() ? 20 : 120; - - if (mUpdateOnlineList && timeDiff >= timeLimit - && mDownloadStatus != UPDATE_LIST) - { - if (mDownloadComplete == true) - { - // TRANSLATORS: who is online window name - setCaption(_("Who Is Online - Updating")); - mUpdateTimer = 0; - mDownloadStatus = UPDATE_LIST; - download(); - } - } - - switch (mDownloadStatus) - { - case UPDATE_ERROR: - mBrowserBox->clearRows(); - mBrowserBox->addRow("##1Failed to fetch the online list!"); - mBrowserBox->addRow(mCurlError); - mDownloadStatus = UPDATE_COMPLETE; - // TRANSLATORS: who is online window name - setCaption(_("Who Is Online - error")); - mUpdateButton->setEnabled(true); - mUpdateTimer = cur_time + 240; - mDownloadComplete = true; - updateSize(); - break; - case UPDATE_LIST: - if (mDownloadComplete == true) - { - loadWebList(); - mDownloadStatus = UPDATE_COMPLETE; - mUpdateButton->setEnabled(true); - mUpdateTimer = 0; - updateSize(); - if (!mOnlineNicks.empty()) - { - if (chatWindow) - chatWindow->updateOnline(mOnlineNicks); - if (socialWindow) - socialWindow->updateActiveList(); - } - } - break; - case UPDATE_COMPLETE: - default: - break; - } - BLOCK_END("WhoIsOnline::slowLogic") -} - -void WhoIsOnline::action(const gcn::ActionEvent &event) -{ - if (event.getId() == "update") - { - if (serverVersion < 3) - { - if (mDownloadStatus == UPDATE_COMPLETE) - { - mUpdateTimer = cur_time - 20; - if (mUpdateButton) - mUpdateButton->setEnabled(false); - // TRANSLATORS: who is online window name - setCaption(_("Who Is Online - Update")); - if (mThread && SDL_GetThreadID(mThread)) - { - SDL_WaitThread(mThread, nullptr); - mThread = nullptr; - } - mDownloadComplete = true; - } - } - else - { - if (client->limitPackets(PACKET_ONLINELIST)) - { - mUpdateTimer = cur_time; - Net::getPlayerHandler()->requestOnlineList(); - } - } - } -} - -void WhoIsOnline::widgetResized(const gcn::Event &event) -{ - Window::widgetResized(event); - updateSize(); -} - -void WhoIsOnline::updateSize() -{ - const gcn::Rectangle area = getChildrenArea(); - if (mUpdateButton) - mUpdateButton->setWidth(area.width - 10); - - if (mScrollArea) - mScrollArea->setSize(area.width - 10, area.height - 10 - 30); - if (mBrowserBox) - mBrowserBox->setWidth(area.width - 10); -} - -const std::string WhoIsOnline::prepareNick(const std::string &nick, - const int level, - const std::string &color) const -{ - const std::string text = encodeLinkText(nick); - if (mShowLevel && level > 1) - { - return strprintf("@@%s|##%s%s (%d)@@", text.c_str(), - color.c_str(), text.c_str(), level); - } - else - { - return strprintf("@@%s|##%s%s@@", text.c_str(), - color.c_str(), text.c_str()); - } -} - -void WhoIsOnline::optionChanged(const std::string &name) -{ - if (name == "updateOnlineList") - mUpdateOnlineList = config.getBoolValue("updateOnlineList"); - else if (name == "groupFriends") - mGroupFriends = config.getBoolValue("groupFriends"); -} - -void WhoIsOnline::setNeutralColor(OnlinePlayer *const player) -{ - if (!player) - return; - - if (actorSpriteManager && player_node) - { - const std::string &nick = player->getNick(); - if (nick == player_node->getName()) - { - player->setText("s"); - return; - } - if (player_node->isInParty()) - { - const Party *const party = player_node->getParty(); - if (party) - { - if (party->getMember(nick)) - { - player->setText("P"); - return; - } - } - } - - const Being *const being = actorSpriteManager->findBeingByName(nick); - if (being) - { - const Guild *const guild2 = player_node->getGuild(); - if (guild2) - { - const Guild *const guild1 = being->getGuild(); - if (guild1) - { - if (guild1->getId() == guild2->getId() - || guild2->getMember(nick)) - { - player->setText("U"); - return; - } - } - else if (guild2->isMember(nick)) - { - player->setText("U"); - return; - } - } - } - const Guild *const guild3 = Guild::getGuild(1); - if (guild3 && guild3->isMember(nick)) - { - player->setText("U"); - return; - } - } - player->setText("0"); -} - -void WhoIsOnline::getPlayerNames(StringVect &names) -{ - names.clear(); - FOR_EACH (std::set<std::string>::const_iterator, it, mOnlineNicks) - names.push_back(*it); -} - -void OnlinePlayer::setText(std::string color) -{ - mText.clear(); - - if (mStatus != 255 && actorSpriteManager) - { - Being *const being = actorSpriteManager->findBeingByName( - mNick, Being::PLAYER); - if (being) - { - being->setState(mStatus); - // for now highlight versions > 3 - if (mVersion > 3) - being->setAdvanced(true); - } - } - - if ((mStatus != 255 && mStatus & Being::FLAG_GM) || mIsGM) - mText.append("(GM) "); - - if (mLevel > 0) - mText.append(strprintf("%d", mLevel)); - - if (mGender == GENDER_FEMALE) - mText.append("\u2640"); - else if (mGender == GENDER_MALE) - mText.append("\u2642"); - - if (mStatus > 0 && mStatus != 255) - { - if (mStatus & Being::FLAG_SHOP) - mText.append("$"); - if (mStatus & Being::FLAG_AWAY) - { - // TRANSLATORS: this away status writed in player nick - mText.append(_("A")); - } - if (mStatus & Being::FLAG_INACTIVE) - { - // TRANSLATORS: this inactive status writed in player nick - mText.append(_("I")); - } - - if (mStatus & Being::FLAG_GM && color == "0") - color = "2"; - } - else if (mIsGM && color == "0") - { - color = "2"; - } - - if (mVersion > 0) - mText.append(strprintf(" - %d", mVersion)); - - const std::string text = encodeLinkText(mNick); - mText = strprintf("@@%s|##%s%s %s@@", text.c_str(), color.c_str(), - text.c_str(), mText.c_str()); -} |