ManaPlus
whoisonline.cpp
Go to the documentation of this file.
1 /*
2  * The ManaPlus Client
3  * Copyright (C) 2009 The Mana World Development Team
4  * Copyright (C) 2011-2019 The ManaPlus Developers
5  * Copyright (C) 2009-2021 Andrei Karas
6  *
7  * This file is part of The ManaPlus Client.
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program. If not, see <http://www.gnu.org/licenses/>.
21  */
22 
24 
25 #include "actormanager.h"
26 #include "configuration.h"
27 #include "guild.h"
28 #include "party.h"
29 #ifdef TMWA_SUPPORT
30 #include "settings.h"
31 #endif // TMWA_SUPPORT
32 
33 #include "gui/onlineplayer.h"
34 #include "gui/popupmanager.h"
35 #include "gui/viewport.h"
36 
37 #include "gui/popups/popupmenu.h"
38 
39 #include "gui/windows/chatwindow.h"
42 
43 #include "gui/widgets/button.h"
44 #include "gui/widgets/scrollarea.h"
46 
47 #include "being/beingflag.h"
48 #include "being/localplayer.h"
49 #include "being/playerrelations.h"
50 
51 #ifdef TMWA_SUPPORT
52 #include "net/download.h"
53 #endif // TMWA_SUPPORT
54 #include "net/packetlimiter.h"
55 #include "net/playerhandler.h"
56 #include "net/serverfeatures.h"
57 
58 #ifdef TMWA_SUPPORT
59 #include "resources/db/groupdb.h"
60 #endif // TMWA_SUPPORT
61 
62 #include "utils/foreach.h"
63 #include "utils/gettext.h"
64 #include "utils/sdlhelper.h"
65 
66 #ifdef TMWA_SUPPORT
67 #include "net/net.h"
68 #else // TMWA_SUPPORT
69 #include <curl/curl.h>
70 #endif // TMWA_SUPPORT
71 
72 #include "debug.h"
73 
74 #ifdef free
75 #undef free
76 #endif // free
77 
78 #ifdef malloc
79 #undef malloc
80 #endif // malloc
81 
83 
84 namespace
85 {
87  {
88  public:
90 
91  bool operator()(const OnlinePlayer *left,
92  const OnlinePlayer *right) const
93  {
94  return (compareStrI(left->getNick(), right->getNick()) < 0);
95  }
97 } // namespace
98 
100  // TRANSLATORS: who is online window name
101  Window(_("Who Is Online - Updating"),
102  Modal_false,
103  nullptr,
104  "whoisonline.xml"),
105  mUpdateTimer(0),
106  mThread(nullptr),
107  mMemoryBuffer(nullptr),
108  mCurlError(new char[CURL_ERROR_SIZE]),
109  mBrowserBox(new StaticBrowserBox(this, Opaque_true,
110  "onlinebrowserbox.xml")),
111  mScrollArea(new ScrollArea(this,
112  mBrowserBox, Opaque_false, std::string())),
113  // TRANSLATORS: who is online. button.
114  mUpdateButton(new Button(this, _("Update"), "update", BUTTON_SKIN, this)),
115  mOnlinePlayers(),
116  mOnlineNicks(),
117  mFriends(),
118  mNeutral(),
119  mDisregard(),
120  mEnemy(),
121  mDownloadedBytes(0),
122  mDownloadStatus(UPDATE_LIST),
123  mDownloadComplete(true),
124  mAllowUpdate(true),
125  mShowLevel(false),
126  mUpdateOnlineList(config.getBoolValue("updateOnlineList")),
127  mGroupFriends(true),
128 #ifdef TMWA_SUPPORT
129  mWebList(Net::getNetworkType() == ServerType::TMWATHENA),
130 #endif
131  mServerSideList(serverFeatures->haveServerOnlineList())
132 {
133  mCurlError[0] = 0;
134  setWindowName("WhoIsOnline");
135 }
136 
138 {
140  const int h = 350;
141  const int w = 200;
143 
145  setCloseButton(true);
146  setResizable(true);
147  setStickyButtonLock(true);
148  setSaveVisible(true);
149 
150  if (setupWindow != nullptr)
152 
153  mUpdateButton->setEnabled(false);
154  mUpdateButton->setDimension(Rect(5, 5, w - 10, 20 + 5));
155 
157  mScrollArea->setDimension(Rect(5, 20 + 10, w - 10, h - 10 - 30));
158  mScrollArea->setSize(w - 10, h - 10 - 30);
159  mScrollArea->setSelectable(false);
161 
163  add(mScrollArea);
164 
166 
167  loadWindowState();
168  enableVisibleSound(true);
169 
170  download();
171 
172  widgetResized(Event(nullptr));
173  config.addListener("updateOnlineList", this);
174  config.addListener("groupFriends", this);
175  mGroupFriends = config.getBoolValue("groupFriends");
176 }
177 
179 {
180  config.removeListeners(this);
182 
184  mThread = nullptr;
185  free(mMemoryBuffer);
186  mMemoryBuffer = nullptr;
187 
188  // Remove possibly leftover temporary download
189  delete []mCurlError;
190 
191  FOR_EACH (std::set<OnlinePlayer*>::iterator, itd, mOnlinePlayers)
192  delete *itd;
193  mOnlinePlayers.clear();
194  mOnlineNicks.clear();
195 }
196 
197 void WhoIsOnline::handleLink(const std::string& link, MouseEvent *event)
198 {
199  if ((event == nullptr) || event->getButton() == MouseButton::LEFT)
200  {
201  if (chatWindow != nullptr)
202  {
203  const std::string text = decodeLinkText(link);
204  if (config.getBoolValue("whispertab"))
205  {
206  chatWindow->localChatInput("/q " + text);
207  }
208  else
209  {
211  std::string("/w \"").append(text).append("\" "),
212  true);
213  }
214  }
215  }
216  else if (event->getButton() == MouseButton::RIGHT)
217  {
218  if ((localPlayer != nullptr) && link == localPlayer->getName())
219  return;
220 
221  if (popupMenu != nullptr)
222  {
223  if (actorManager != nullptr)
224  {
225  const std::string text = decodeLinkText(link);
226  Being *const being = actorManager->findBeingByName(
227  text, ActorType::Player);
228 
229  if ((being != nullptr) && (popupManager != nullptr))
230  {
232  viewport->mMouseY,
233  being);
234  return;
235  }
236  }
237  popupMenu->showPlayerPopup(link);
238  }
239  }
240 }
241 
242 void WhoIsOnline::updateWindow(size_t numOnline)
243 {
244  // Set window caption
245  // TRANSLATORS: who is online window name
246  setCaption(_("Who Is Online - ") + toString(CAST_U32(numOnline)));
247 
248  // List the online people
249  std::sort(mFriends.begin(), mFriends.end(), nameCompare);
250  std::sort(mNeutral.begin(), mNeutral.end(), nameCompare);
251  std::sort(mDisregard.begin(), mDisregard.end(), nameCompare);
252  bool addedFromSection(false);
253  FOR_EACH (STD_VECTOR<OnlinePlayer*>::const_iterator, it, mFriends)
254  {
255  mBrowserBox->addRow((*it)->getText(), false);
256  addedFromSection = true;
257  }
258  if (addedFromSection == true)
259  {
260  mBrowserBox->addRow("---", false);
261  addedFromSection = false;
262  }
263  FOR_EACH (STD_VECTOR<OnlinePlayer*>::const_iterator, it, mEnemy)
264  {
265  mBrowserBox->addRow((*it)->getText(), false);
266  addedFromSection = true;
267  }
268  if (addedFromSection == true)
269  {
270  mBrowserBox->addRow("---", false);
271  addedFromSection = false;
272  }
273  FOR_EACH (STD_VECTOR<OnlinePlayer*>::const_iterator, it, mNeutral)
274  {
275  mBrowserBox->addRow((*it)->getText(), false);
276  addedFromSection = true;
277  }
278  if (addedFromSection == true && !mDisregard.empty())
279  mBrowserBox->addRow("---", false);
280 
281  FOR_EACH (STD_VECTOR<OnlinePlayer*>::const_iterator, it, mDisregard)
282  mBrowserBox->addRow((*it)->getText(), false);
283 
286  {
289  }
291 }
292 
293 void WhoIsOnline::handlerPlayerRelation(const std::string &nick,
294  OnlinePlayer *const player)
295 {
296  if (player == nullptr)
297  return;
298  switch (playerRelations.getRelation(nick))
299  {
300  case Relation::NEUTRAL:
301  default:
302  setNeutralColor(player);
303  mNeutral.push_back(player);
304  break;
305 
306  case Relation::FRIEND:
307  player->setText("2");
308  if (mGroupFriends)
309  mFriends.push_back(player);
310  else
311  mNeutral.push_back(player);
312  break;
313 
316  player->setText("8");
317  mDisregard.push_back(player);
318  break;
319 
320  case Relation::ENEMY2:
321  player->setText("1");
322  mEnemy.push_back(player);
323  break;
324 
325  case Relation::IGNORED:
326  case Relation::ERASED:
327  // Ignore the ignored.
328  break;
329  }
330 }
331 
332 void WhoIsOnline::loadList(const STD_VECTOR<OnlinePlayer*> &list)
333 {
335  const size_t numOnline = list.size();
336 
337  FOR_EACH (std::set<OnlinePlayer*>::iterator, itd, mOnlinePlayers)
338  delete *itd;
339  mOnlinePlayers.clear();
340  mOnlineNicks.clear();
341 
342  mShowLevel = config.getBoolValue("showlevel");
343 
344  FOR_EACH (STD_VECTOR<OnlinePlayer*>::const_iterator, it, list)
345  {
346  OnlinePlayer *player = *it;
347  const std::string nick = player->getNick();
348  mOnlinePlayers.insert(player);
349  mOnlineNicks.insert(nick);
350 
351  if (!mShowLevel)
352  player->setLevel(0);
353 
354  handlerPlayerRelation(nick, player);
355  }
356 
357  updateWindow(numOnline);
358  if (!mOnlineNicks.empty())
359  {
360  if (chatWindow != nullptr)
362  if (socialWindow != nullptr)
364  if (actorManager != nullptr)
366  }
367  updateSize();
368  mFriends.clear();
369  mNeutral.clear();
370  mDisregard.clear();
371  mEnemy.clear();
372 }
373 
374 #ifdef TMWA_SUPPORT
376 {
377  if (mMemoryBuffer == nullptr)
378  return;
379 
380  // Reallocate and include terminating 0 character
381  mMemoryBuffer = static_cast<char*>(
382  realloc(mMemoryBuffer, mDownloadedBytes + 1));
383  if (mMemoryBuffer == nullptr)
384  return;
385 
387 
389  bool listStarted(false);
390  std::string lineStr;
391  size_t numOnline(0U);
392 
393  // Tokenize and add each line separately
394  char *line = strtok(mMemoryBuffer, "\n");
395  const std::string gmText("(GM)");
396  const std::string gmText2("(gm)");
397 
398  FOR_EACH (std::set<OnlinePlayer*>::iterator, itd, mOnlinePlayers)
399  delete *itd;
400 
401  mOnlinePlayers.clear();
402  mOnlineNicks.clear();
403 
404  mShowLevel = config.getBoolValue("showlevel");
405 
406  while (line != nullptr)
407  {
408  std::string nick;
409  lineStr = line;
410  trim(lineStr);
411  if (listStarted == true)
412  {
413  if (lineStr.find(" users are online.") == std::string::npos)
414  {
415  if (lineStr.length() > 24)
416  {
417  nick = lineStr.substr(0, 24);
418  lineStr = lineStr.substr(25);
419  }
420  else
421  {
422  nick = lineStr;
423  lineStr.clear();
424  }
425  trim(nick);
426 
427  bool isGM(false);
428  size_t pos = lineStr.find(gmText, 0);
429  if (pos != std::string::npos)
430  {
431  lineStr = lineStr.substr(pos + gmText.length());
432  isGM = true;
433  }
434  else
435  {
436  pos = lineStr.find(gmText2, 0);
437  if (pos != std::string::npos)
438  {
439  lineStr = lineStr.substr(pos + gmText.length());
440  isGM = true;
441  }
442  }
443 
444  trim(lineStr);
445  pos = lineStr.find('/', 0);
446 
447  if (pos != std::string::npos)
448  lineStr = lineStr.substr(0, pos);
449 
450  int level = 0;
451  if (!lineStr.empty())
452  level = atoi(lineStr.c_str());
453 
454  if (actorManager != nullptr)
455  {
456  Being *const being = actorManager->findBeingByName(
457  nick, ActorType::Player);
458  if (being != nullptr)
459  {
460  if (level > 0)
461  {
462  being->setLevel(level);
463  being->updateName();
464  }
465  else
466  {
467  if (being->getLevel() > 1)
468  level = being->getLevel();
469  }
470  }
471  }
472 
473  if (!mShowLevel)
474  level = 0;
475 
476  OnlinePlayer *const player = new OnlinePlayer(nick,
477  CAST_U8(255), level,
478  Gender::UNSPECIFIED, -1, -1);
479  mOnlinePlayers.insert(player);
480  mOnlineNicks.insert(nick);
481 
482  if (isGM)
483  player->setIsGM(true);
484 
485  numOnline++;
486  handlerPlayerRelation(nick, player);
487  }
488  }
489  else if (lineStr.find("------------------------------")
490  != std::string::npos)
491  {
492  listStarted = true;
493  }
494  line = strtok(nullptr, "\n");
495  }
496 
497  updateWindow(numOnline);
499 
500  // Free the memory buffer now that we don't need it anymore
501  free(mMemoryBuffer);
502  mMemoryBuffer = nullptr;
503  mFriends.clear();
504  mNeutral.clear();
505  mDisregard.clear();
506  mEnemy.clear();
507 }
508 
510  size_t size,
511  size_t nmemb,
512  FILE *restrict stream)
513 {
514  if (stream == nullptr)
515  return 0;
516 
517  WhoIsOnline *restrict const wio =
518  reinterpret_cast<WhoIsOnline *restrict>(stream);
519  const size_t totalMem = size * nmemb;
520  wio->mMemoryBuffer = static_cast<char*>(realloc(wio->mMemoryBuffer,
521  CAST_SIZE(wio->mDownloadedBytes) + totalMem));
522  if (wio->mMemoryBuffer != nullptr)
523  {
524  memcpy(&(wio->mMemoryBuffer[wio->mDownloadedBytes]), ptr, totalMem);
525  wio->mDownloadedBytes += CAST_S32(totalMem);
526  }
527 
528  return totalMem;
529 }
530 
532 {
533  int attempts = 0;
534  WhoIsOnline *const wio = reinterpret_cast<WhoIsOnline *>(ptr);
535  if (wio == nullptr)
536  return 0;
537  CURLcode res;
538  const std::string url(settings.onlineListUrl + "/online.txt");
539 
540  while (attempts < 1 && !wio->mDownloadComplete)
541  {
542  CURL *curl = curl_easy_init();
543  if (curl != nullptr)
544  {
545  if (!wio->mAllowUpdate)
546  {
547  curl_easy_cleanup(curl);
548  curl = nullptr;
549  break;
550  }
551  wio->mDownloadedBytes = 0;
552  curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
553  curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1);
554  curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION,
556  curl_easy_setopt(curl, CURLOPT_WRITEDATA, ptr);
557 
558  curl_easy_setopt(curl,
559  CURLOPT_USERAGENT,
560  settings.userAgent.c_str());
561 
562  curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, wio->mCurlError);
563  curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
564  curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
565  curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, ptr);
566 
567 #if LIBCURL_VERSION_NUM >= 0x070a00
568  curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
569 #endif // LIBCURL_VERSION_NUM >= 0x070a00
570  curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 7);
571  curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30);
576 
577  // Make sure the resources2.txt and news.txt aren't cached,
578  // in order to always get the latest version.
579  curl_slist *pHeaders = nullptr;
580  pHeaders = curl_slist_append(
581  pHeaders, "pragma: no-cache");
582  pHeaders = curl_slist_append(pHeaders,
583  "Cache-Control: no-cache");
584  curl_easy_setopt(curl, CURLOPT_HTTPHEADER, pHeaders);
585 
586  if ((res = curl_easy_perform(curl)) != 0)
587  {
589  PRAGMA45(GCC diagnostic push)
590  PRAGMA45(GCC diagnostic ignored "-Wswitch-enum")
591  switch (res)
592  {
593  case CURLE_COULDNT_CONNECT:
594  default:
595  std::cerr << "curl error "
596  << CAST_U32(res) << ": "
597  << wio->mCurlError << " host: "
598  << url.c_str() << std::endl;
599  break;
600  }
601  PRAGMA45(GCC diagnostic pop)
602  attempts++;
603  curl_easy_cleanup(curl);
604  curl_slist_free_all(pHeaders);
605  curl = nullptr;
606  continue;
607  }
608 
609  curl_easy_cleanup(curl);
610  curl_slist_free_all(pHeaders);
611 
612  // It's stored in memory, we're done
613  wio->mDownloadComplete = true;
614  }
615  if (!wio->mAllowUpdate)
616  break;
617  attempts++;
618  }
619 
620  if (!wio->mDownloadComplete)
622  return 0;
623 }
624 #endif // TMWA_SUPPORT
625 
627 {
628  if (mServerSideList)
629  {
632  }
633 #ifdef TMWA_SUPPORT
634  else if (mWebList)
635  {
636  mDownloadComplete = true;
638  mThread = nullptr;
639  mDownloadComplete = false;
641  "whoisonline", this);
642  if (mThread == nullptr)
644  }
645 #endif // TMWA_SUPPORT
646 }
647 
649 {
650  BLOCK_START("WhoIsOnline::logic")
651  mScrollArea->logic();
652  BLOCK_END("WhoIsOnline::logic")
653 }
654 
656 {
657  if (!mAllowUpdate)
658  return;
659 
660  BLOCK_START("WhoIsOnline::slowLogic")
661  if (mUpdateTimer == 0)
663 
664  const double timeDiff = difftime(cur_time, mUpdateTimer);
665  const int timeLimit = isWindowVisible() ? 20 : 120;
666 
667  if (mUpdateOnlineList && timeDiff >= timeLimit
669  {
670  if (mDownloadComplete == true)
671  {
672  // TRANSLATORS: who is online window name
673  setCaption(_("Who Is Online - Updating"));
674  mUpdateTimer = 0;
676  download();
677  }
678  }
679 
680 #ifdef TMWA_SUPPORT
681  switch (mDownloadStatus)
682  {
683  case UPDATE_ERROR:
684  logger->assertLog("Failed to fetch the online list:");
685  if (mCurlError != nullptr)
686  logger->assertLog("%s", mCurlError);
688  // TRANSLATORS: who is online window name
689  setCaption(_("Who Is Online - error"));
690  mUpdateButton->setEnabled(true);
691  mUpdateTimer = cur_time + 240;
692  mDownloadComplete = true;
693  updateSize();
694  break;
695  case UPDATE_LIST:
696  if (mDownloadComplete == true)
697  {
698  loadWebList();
700  mUpdateButton->setEnabled(true);
701  mUpdateTimer = 0;
702  updateSize();
703  if (!mOnlineNicks.empty())
704  {
705  if (chatWindow != nullptr)
707  if (socialWindow != nullptr)
709  if (actorManager != nullptr)
711  }
712  }
713  break;
714  case UPDATE_COMPLETE:
715  default:
716  break;
717  }
718 #endif // TMWA_SUPPORT
719 
720  BLOCK_END("WhoIsOnline::slowLogic")
721 }
722 
724 {
725  if (event.getId() == "update")
726  {
727 #ifdef TMWA_SUPPORT
728  if (!mServerSideList)
729  {
731  {
732  mUpdateTimer = cur_time - 20;
733  if (mUpdateButton != nullptr)
734  mUpdateButton->setEnabled(false);
735  // TRANSLATORS: who is online window name
736  setCaption(_("Who Is Online - Update"));
738  mThread = nullptr;
739  mDownloadComplete = true;
740  }
741  }
742  else
743 #endif // TMWA_SUPPORT
744  {
746  {
749  }
750  }
751  }
752 }
753 
755 {
756  Window::widgetResized(event);
757  updateSize();
758 }
759 
761 {
762  const Rect area = getChildrenArea();
763  if (mUpdateButton != nullptr)
764  mUpdateButton->setWidth(area.width - 10);
765 
766  if (mScrollArea != nullptr)
767  mScrollArea->setSize(area.width - 10, area.height - 10 - 30);
768 }
769 
770 const std::string WhoIsOnline::prepareNick(const std::string &restrict nick,
771  const int level,
772  const std::string &restrict
773  color) const
774 {
775  const std::string text = encodeLinkText(nick);
776  if (mShowLevel && level > 1)
777  {
778  return strprintf("@@%s|##%s%s (%d)@@", text.c_str(),
779  color.c_str(), text.c_str(), level);
780  }
781  return strprintf("@@%s|##%s%[email protected]@", text.c_str(),
782  color.c_str(), text.c_str());
783 }
784 
785 void WhoIsOnline::optionChanged(const std::string &name)
786 {
787  if (name == "updateOnlineList")
788  mUpdateOnlineList = config.getBoolValue("updateOnlineList");
789  else if (name == "groupFriends")
790  mGroupFriends = config.getBoolValue("groupFriends");
791 }
792 
794 {
795  if (player == nullptr)
796  return;
797 
798  if ((actorManager != nullptr) && (localPlayer != nullptr))
799  {
800  const std::string &nick = player->getNick();
801  if (nick == localPlayer->getName())
802  {
803  player->setText("s");
804  return;
805  }
806  if (localPlayer->isInParty())
807  {
808  const Party *const party = localPlayer->getParty();
809  if (party != nullptr)
810  {
811  if (party->getMember(nick) != nullptr)
812  {
813  player->setText("P");
814  return;
815  }
816  }
817  }
818 
819  const Being *const being = actorManager->findBeingByName(nick,
821  if (being != nullptr)
822  {
823  const Guild *const guild2 = localPlayer->getGuild();
824  if (guild2 != nullptr)
825  {
826  const Guild *const guild1 = being->getGuild();
827  if (guild1 != nullptr)
828  {
829  if (guild1->getId() == guild2->getId()
830  || (guild2->getMember(nick) != nullptr))
831  {
832  player->setText("U");
833  return;
834  }
835  }
836  else if (guild2->isMember(nick))
837  {
838  player->setText("U");
839  return;
840  }
841  }
842  }
843  const Guild *const guild3 = Guild::getGuild(1);
844  if ((guild3 != nullptr) && guild3->isMember(nick))
845  {
846  player->setText("U");
847  return;
848  }
849  }
850  player->setText("0");
851 }
852 
854 {
855  names.clear();
856  FOR_EACH (std::set<std::string>::const_iterator, it, mOnlineNicks)
857  names.push_back(*it);
858 }
859 
860 void OnlinePlayer::setText(std::string color)
861 {
862  mText.clear();
863 
864  if (mStatus != 255 && (actorManager != nullptr))
865  {
866  Being *const being = actorManager->findBeingByName(
868  if (being != nullptr)
869  {
870  being->setState(mStatus);
871  // for now highlight versions > 3
872  if (mVersion > 3)
873  being->setAdvanced(true);
874  }
875  }
876 
877 #ifdef TMWA_SUPPORT
878  if (mGroup != -1 && GroupDb::getShowBadge(mGroup))
879  {
880  const std::string &name = GroupDb::getName(mGroup);
881  mText.append(strprintf("(%s) ", name.c_str()));
882  }
883  else
884 #endif
885  {
886  if ((mStatus != 255 && ((mStatus & BeingFlag::GM) != 0)) || mIsGM)
887  mText.append("(GM) ");
888  }
889 
890  if (mLevel > 0)
891  mText.append(strprintf("%d", mLevel));
892 
893  if (mGender == Gender::FEMALE)
894  mText.append("\u2640");
895  else if (mGender == Gender::MALE)
896  mText.append("\u2642");
897 
898 #ifdef TMWA_SUPPORT
899  if (mGroup != -1 && GroupDb::getHighlightName(mGroup) && color == "0")
900  color = "2";
901 #endif
902 
903  if (mStatus > 0 && mStatus != 255)
904  {
905  if ((mStatus & BeingFlag::SHOP) != 0)
906  mText.append("$");
907  if ((mStatus & BeingFlag::AWAY) != 0)
908  {
909  // TRANSLATORS: this away status writed in player nick
910  mText.append(_("A"));
911  }
912  if ((mStatus & BeingFlag::INACTIVE) != 0)
913  {
914  // TRANSLATORS: this inactive status writed in player nick
915  mText.append(_("I"));
916  }
917 
918  if (((mStatus & BeingFlag::GM) != 0) && color == "0")
919  color = "2";
920  }
921  else if (mIsGM && color == "0")
922  {
923  color = "2";
924  }
925 
926  if (mVersion > 0)
927  mText.append(strprintf(" - %d", mVersion));
928 
929  const std::string text = encodeLinkText(mNick);
930  mText = strprintf("@@%s|##%s%s %[email protected]@", text.c_str(), color.c_str(),
931  text.c_str(), mText.c_str());
932 }
ActorManager * actorManager
volatile time_t cur_time
Definition: timer.cpp:58
const std::string BUTTON_SKIN
Definition: button.h:89
#define CAST_S32
Definition: cast.h:30
#define CAST_U32
Definition: cast.h:31
#define CAST_SIZE
Definition: cast.h:34
#define CAST_U8
Definition: cast.h:27
ChatWindow * chatWindow
Definition: chatwindow.cpp:94
const std::string & getId() const
Definition: actionevent.h:122
Being * findBeingByName(const std::string &name, const ActorTypeT type) const
void updateSeenPlayers(const std::set< std::string > &onlinePlayers)
virtual void add(Widget *const widget)
Definition: being.h:96
Party * getParty() const
Definition: being.h:330
const Guild * getGuild(const std::string &guildName) const
Definition: being.cpp:1258
virtual int getLevel() const
Definition: being.h:604
void updateName()
Definition: being.cpp:3425
void setLevel(const int n)
Definition: being.h:601
const std::string & getName() const
Definition: being.h:232
void setState(const uint8_t state)
Definition: being.cpp:4803
bool isInParty() const
Definition: being.h:321
void setAdvanced(const bool n)
Definition: being.h:831
Definition: button.h:102
void updateOnline(const std::set< std::string > &onlinePlayers) const
void localChatInput(const std::string &msg) const
Definition: chatwindow.cpp:691
void addInputText(const std::string &text, const bool space)
bool getBoolValue(const std::string &key) const
void addListener(const std::string &key, ConfigListener *const listener)
void removeListeners(ConfigListener *const listener)
Definition: event.h:79
Definition: guild.h:70
bool isMember(const GuildMember *const member) const
Definition: guild.cpp:304
static Guild * getGuild(const int16_t id)
Definition: guild.cpp:374
int16_t getId() const
Definition: guild.h:135
GuildMember * getMember(const BeingId id) const
Definition: guild.cpp:140
void assertLog(const char *const log_text,...)
Definition: logger.cpp:316
MouseButtonT getButton() const
Definition: mouseevent.h:116
static void addCommonFlags(CURL *const curl)
Definition: download.cpp:613
static void secureCurl(CURL *const curl)
Definition: download.cpp:574
static void addProxy(CURL *const curl)
Definition: download.cpp:509
static void addHeaders(CURL *const curl)
Definition: download.cpp:608
virtual void requestOnlineList() const =0
const std::string getNick() const
Definition: onlineplayer.h:53
void setIsGM(const bool b)
Definition: onlineplayer.h:59
std::string mText
Definition: onlineplayer.h:79
void setText(std::string str)
std::string mNick
Definition: onlineplayer.h:77
unsigned char mStatus
Definition: onlineplayer.h:83
signed char mLevel
Definition: onlineplayer.h:85
signed char mVersion
Definition: onlineplayer.h:87
void setLevel(const char level)
Definition: onlineplayer.h:73
GenderT mGender
Definition: onlineplayer.h:89
Definition: party.h:63
RelationT getRelation(const std::string &name) const
void showPlayerPopup(const std::string &nick)
Definition: popupmenu.cpp:606
void showPopup(const int x, const int y, const Being *const being)
Definition: popupmenu.cpp:203
Definition: rect.h:74
int width
Definition: rect.h:219
int height
Definition: rect.h:224
void setVerticalScrollAmount(const int vScroll)
int getVerticalMaxScroll()
int getVerticalScrollAmount() const
Definition: scrollarea.h:274
void logic()
Definition: scrollarea.cpp:273
void setDimension(const Rect &dimension)
std::string onlineListUrl
Definition: settings.h:116
std::string userAgent
Definition: settings.h:128
void registerWindowForReset(Window *const window)
void updateActiveList()
void addRow(const std::string &row, const bool atTop)
void setOpaque(Opaque opaque)
void setLinkHandler(LinkHandler *linkHandler)
int mMouseX
Definition: viewport.h:154
int mMouseY
Definition: viewport.h:155
int mDownloadedBytes
Definition: whoisonline.h:163
void getPlayerNames(StringVect &names)
bool mDownloadComplete
Definition: whoisonline.h:169
std::set< std::string > mOnlineNicks
Definition: whoisonline.h:155
static size_t memoryWrite(void *ptr, size_t size, size_t nmemb, FILE *stream)
bool mShowLevel
Definition: whoisonline.h:171
time_t mUpdateTimer
Definition: whoisonline.h:139
Button * mUpdateButton
Definition: whoisonline.h:152
const std::string prepareNick(const std::string &nick, const int level, const std::string &color) const
void loadList(const std::vector< OnlinePlayer * > &list)
std::set< OnlinePlayer * > mOnlinePlayers
Definition: whoisonline.h:154
bool mAllowUpdate
Definition: whoisonline.h:170
std::vector< OnlinePlayer * > mNeutral
Definition: whoisonline.h:158
char * mMemoryBuffer
Definition: whoisonline.h:145
void updateSize()
void handlerPlayerRelation(const std::string &nick, OnlinePlayer *const player)
static int downloadThread(void *ptr)
ScrollArea * mScrollArea
Definition: whoisonline.h:151
bool mGroupFriends
Definition: whoisonline.h:173
void slowLogic()
StaticBrowserBox * mBrowserBox
Definition: whoisonline.h:150
static void setNeutralColor(OnlinePlayer *const player)
std::vector< OnlinePlayer * > mFriends
Definition: whoisonline.h:157
void widgetResized(const Event &event)
char * mCurlError
Definition: whoisonline.h:148
std::vector< OnlinePlayer * > mEnemy
Definition: whoisonline.h:160
SDL_Thread * mThread
Definition: whoisonline.h:142
void postInit()
void optionChanged(const std::string &name)
void loadWebList()
void action(const ActionEvent &event)
WhoIsOnline::DownloadStatus mDownloadStatus
Definition: whoisonline.h:166
void handleLink(const std::string &link, MouseEvent *event)
void updateWindow(size_t numOnline)
std::vector< OnlinePlayer * > mDisregard
Definition: whoisonline.h:159
void download()
bool mUpdateOnlineList
Definition: whoisonline.h:172
bool mServerSideList
Definition: whoisonline.h:177
void setWidth(const int width)
Definition: widget.cpp:133
void setSize(const int width, const int height)
Definition: widget.cpp:367
void setEnabled(const bool enabled)
Definition: widget.h:352
void setDimension(const Rect &dimension)
Definition: widget.cpp:169
void setSelectable(const bool selectable)
Definition: widget.h:948
Widget * getParent() const
Definition: widget.h:202
Definition: window.h:102
void setSaveVisible(const bool save)
Definition: window.h:300
void setResizable(const bool resize)
Definition: window.cpp:627
virtual void setVisible(Visible visible)
Definition: window.cpp:778
bool isWindowVisible() const
Definition: window.h:484
void setWindowName(const std::string &name)
Definition: window.h:355
void setCaption(const std::string &caption)
Definition: window.h:531
void postInit()
Definition: window.cpp:249
void enableVisibleSound(bool b)
Definition: window.h:481
void widgetResized(const Event &event)
Definition: window.cpp:655
Rect getChildrenArea()
Definition: window.cpp:1473
void setCloseButton(const bool flag)
Definition: window.cpp:749
void setStickyButtonLock(const bool sticky)
Definition: window.cpp:772
void setDefaultSize()
Definition: window.cpp:1198
void setLocationRelativeTo(const Widget *const widget)
Definition: window.cpp:509
void loadWindowState()
Definition: window.cpp:1087
Configuration config
#define new
Definition: debug_new.h:147
Viewport * viewport
Definition: viewport.cpp:36
#define FOR_EACH(type, iter, array)
Definition: foreach.h:25
#define _(s)
Definition: gettext.h:35
const Image *restrict const left
const Image *restrict const right
PRAGMA45(GCC diagnostic push) PRAGMA45(GCC diagnostic ignored "-Wredundant-decls") PRAGMA45(GCC diagnostic pop) class TestMain
#define restrict
Definition: localconsts.h:165
#define final
Definition: localconsts.h:46
#define nullptr
Definition: localconsts.h:45
#define CHECKLISTENERS
Definition: localconsts.h:277
#define A_DEFAULT_COPY(func)
Definition: localconsts.h:41
LocalPlayer * localPlayer
Logger * logger
Definition: logger.cpp:89
uint32_t party
const bool Modal_false
Definition: modal.h:30
bool url(InputEvent &event)
Definition: commands.cpp:64
@ INACTIVE
Definition: beingflag.h:31
std::string trim(std::string const &str)
std::string toString(T const &value)
converts any type to a string
Definition: catch.hpp:1774
int size()
Definition: emotedb.cpp:306
@ UNSPECIFIED
Definition: gender.h:33
@ MALE
Definition: gender.h:31
@ FEMALE
Definition: gender.h:32
bool getShowBadge(const int id)
Definition: groupdb.cpp:366
bool getHighlightName(const int id)
Definition: groupdb.cpp:377
const std::string & getName(const int id)
Definition: groupdb.cpp:344
ServerTypeT getNetworkType()
Definition: net.cpp:189
bool limitPackets(const PacketTypeT type)
@ PACKET_ONLINELIST
Definition: packettype.h:40
@ DISREGARDED
Definition: relation.h:33
@ ENEMY2
Definition: relation.h:37
@ IGNORED
Definition: relation.h:34
@ FRIEND
Definition: relation.h:32
@ ERASED
Definition: relation.h:35
@ NEUTRAL
Definition: relation.h:31
@ BLACKLISTED
Definition: relation.h:36
SDL_Thread * createThread(int(*fn)(void *), const char *const name, void *const data)
Definition: sdlhelper.cpp:118
void WaitThread(SDL_Thread *const thread)
Definition: sdlhelper.cpp:195
class anonymous_namespace{whoisonline.cpp}::NameFunctuator nameCompare
Net::ServerFeatures * serverFeatures
Definition: net.cpp:101
Net::PlayerHandler * playerHandler
Definition: net.cpp:96
const bool Opaque_false
Definition: opaque.h:30
const bool Opaque_true
Definition: opaque.h:30
#define BLOCK_END(name)
Definition: perfomance.h:80
#define BLOCK_START(name)
Definition: perfomance.h:79
PlayerRelationsManager playerRelations
PopupManager * popupManager
PopupMenu * popupMenu
Definition: popupmenu.cpp:103
Settings settings
Definition: settings.cpp:32
SetupWindow * setupWindow
Definition: setupwindow.cpp:64
SocialWindow * socialWindow
std::string strprintf(const char *const format,...)
int compareStrI(const std::string &a, const std::string &b)
std::string decodeLinkText(std::string data)
std::string encodeLinkText(std::string data)
std::vector< std::string > StringVect
Definition: stringvector.h:29
const bool Visible_false
Definition: visible.h:30
WhoIsOnline * whoIsOnline
Definition: whoisonline.cpp:82