From 7c6621108b54fd66fbb7aa87be067a34abcc3ced Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Wed, 30 Nov 2011 18:13:03 +0300 Subject: Add server side online players list support. --- src/gui/whoisonline.cpp | 211 +++++++++++++++++++++++++------------ src/gui/whoisonline.h | 17 ++- src/net/manaserv/playerhandler.cpp | 5 + src/net/manaserv/playerhandler.h | 2 + src/net/messagein.cpp | 25 +++++ src/net/messagein.h | 2 + src/net/playerhandler.h | 2 + src/net/tmwa/network.cpp | 2 +- src/net/tmwa/playerhandler.cpp | 41 +++++++ src/net/tmwa/playerhandler.h | 2 + src/net/tmwa/protocol.h | 2 + 11 files changed, 242 insertions(+), 69 deletions(-) (limited to 'src') diff --git a/src/gui/whoisonline.cpp b/src/gui/whoisonline.cpp index e0fa4ebcf..fde0f08da 100644 --- a/src/gui/whoisonline.cpp +++ b/src/gui/whoisonline.cpp @@ -41,6 +41,9 @@ #include "playerrelations.h" #include "main.h" +#include "net/net.h" +#include "net/playerhandler.h" + #include "gui/chatwindow.h" #include "utils/gettext.h" @@ -181,7 +184,113 @@ void WhoIsOnline::handleLink(const std::string& link, gcn::MouseEvent *event) } } -void WhoIsOnline::loadList() +void WhoIsOnline::updateWindow(std::vector &friends, + std::vector &neutral, + std::vector &disregard, + std::vector enemy, + int numOnline) +{ + //Set window caption + setCaption(_("Who Is Online - ") + toString(numOnline)); + + //List the online people + sort(friends.begin(), friends.end(), nameCompare); + sort(neutral.begin(), neutral.end(), nameCompare); + sort(disregard.begin(), disregard.end(), nameCompare); + bool addedFromSection(false); + for (int i = 0; i < static_cast(friends.size()); i++) + { + mBrowserBox->addRow(friends.at(i)); + addedFromSection = true; + } + if (addedFromSection == true) + { + mBrowserBox->addRow("---"); + addedFromSection = false; + } + for (int i = 0; i < static_cast(enemy.size()); i++) + { + mBrowserBox->addRow(enemy.at(i)); + addedFromSection = true; + } + if (addedFromSection == true) + { + mBrowserBox->addRow("---"); + addedFromSection = false; + } + for (int i = 0; i < static_cast(neutral.size()); i++) + { + mBrowserBox->addRow(neutral.at(i)); + addedFromSection = true; + } + if (addedFromSection == true && !disregard.empty()) + { + mBrowserBox->addRow("---"); + addedFromSection = false; + } + for (int i = 0; i < static_cast(disregard.size()); i++) + { + mBrowserBox->addRow(disregard.at(i)); + } + + if (mScrollArea->getVerticalMaxScroll() < + mScrollArea->getVerticalScrollAmount()) + { + mScrollArea->setVerticalScrollAmount( + mScrollArea->getVerticalMaxScroll()); + } +} + +void WhoIsOnline::loadList(std::vector &list) +{ + mBrowserBox->clearRows(); + int numOnline = list.size(); + std::vector friends; + std::vector neutral; + std::vector disregard; + std::vector enemy; + + mOnlinePlayers.clear(); + mShowLevel = config.getBoolValue("showlevel"); + + std::vector::const_iterator it = list.begin(); + std::vector::const_iterator it_end = list.end(); + for (; it != it_end; ++ it) + { + std::string nick = *it; + mOnlinePlayers.insert(nick); + + switch (player_relations.getRelation(nick)) + { + case PlayerRelation::NEUTRAL: + default: + neutral.push_back(prepareNick(nick, 0, "0")); + break; + + case PlayerRelation::FRIEND: + friends.push_back(prepareNick(nick, 0, "2")); + break; + + case PlayerRelation::DISREGARDED: + case PlayerRelation::BLACKLISTED: + disregard.push_back(prepareNick(nick, 0, "8")); + break; + + case PlayerRelation::ENEMY2: + enemy.push_back(prepareNick(nick, 0, "1")); + break; + + case PlayerRelation::IGNORED: + case PlayerRelation::ERASED: + //Ignore the ignored. + break; + } + } + + updateWindow(friends, neutral, disregard, enemy, numOnline); +} + +void WhoIsOnline::loadWebList() { if (!mMemoryBuffer) return; @@ -303,59 +412,11 @@ void WhoIsOnline::loadList() line = strtok(nullptr, "\n"); } - //Set window caption - setCaption(_("Who Is Online - ") + toString(numOnline)); - - //List the online people - sort(friends.begin(), friends.end(), nameCompare); - sort(neutral.begin(), neutral.end(), nameCompare); - sort(disregard.begin(), disregard.end(), nameCompare); - bool addedFromSection(false); - for (int i = 0; i < static_cast(friends.size()); i++) - { - mBrowserBox->addRow(friends.at(i)); - addedFromSection = true; - } - if (addedFromSection == true) - { - mBrowserBox->addRow("---"); - addedFromSection = false; - } - for (int i = 0; i < static_cast(enemy.size()); i++) - { - mBrowserBox->addRow(enemy.at(i)); - addedFromSection = true; - } - if (addedFromSection == true) - { - mBrowserBox->addRow("---"); - addedFromSection = false; - } - for (int i = 0; i < static_cast(neutral.size()); i++) - { - mBrowserBox->addRow(neutral.at(i)); - addedFromSection = true; - } - if (addedFromSection == true && !disregard.empty()) - { - mBrowserBox->addRow("---"); - addedFromSection = false; - } - for (int i = 0; i < static_cast(disregard.size()); i++) - { - mBrowserBox->addRow(disregard.at(i)); - } + updateWindow(friends, neutral, disregard, enemy, numOnline); // Free the memory buffer now that we don't need it anymore free(mMemoryBuffer); mMemoryBuffer = nullptr; - - if (mScrollArea->getVerticalMaxScroll() < - mScrollArea->getVerticalScrollAmount()) - { - mScrollArea->setVerticalScrollAmount( - mScrollArea->getVerticalMaxScroll()); - } } size_t WhoIsOnline::memoryWrite(void *ptr, size_t size, @@ -461,15 +522,22 @@ int WhoIsOnline::downloadThread(void *ptr) void WhoIsOnline::download() { - mDownloadComplete = true; - if (mThread && SDL_GetThreadID(mThread)) - SDL_WaitThread(mThread, nullptr); + if (serverVersion < 3) + { + mDownloadComplete = true; + if (mThread && SDL_GetThreadID(mThread)) + SDL_WaitThread(mThread, nullptr); - mDownloadComplete = false; - mThread = SDL_CreateThread(WhoIsOnline::downloadThread, this); + mDownloadComplete = false; + mThread = SDL_CreateThread(WhoIsOnline::downloadThread, this); - if (mThread == nullptr) - mDownloadStatus = UPDATE_ERROR; + if (mThread == nullptr) + mDownloadStatus = UPDATE_ERROR; + } + else + { + Net::getPlayerHandler()->requestOnlineList(); + } } void WhoIsOnline::logic() @@ -513,7 +581,7 @@ void WhoIsOnline::logic() case UPDATE_LIST: if (mDownloadComplete == true) { - loadList(); + loadWebList(); mDownloadStatus = UPDATE_COMPLETE; mUpdateButton->setEnabled(true); mUpdateTimer = 0; @@ -532,18 +600,27 @@ void WhoIsOnline::action(const gcn::ActionEvent &event) { if (event.getId() == "update") { - if (mDownloadStatus == UPDATE_COMPLETE) + if (serverVersion < 3) { - mUpdateTimer = cur_time - 20; - if (mUpdateButton) - mUpdateButton->setEnabled(false); - setCaption(_("Who Is Online - Update")); - if (mThread && SDL_GetThreadID(mThread)) + if (mDownloadStatus == UPDATE_COMPLETE) { - SDL_WaitThread(mThread, nullptr); - mThread = nullptr; + mUpdateTimer = cur_time - 20; + if (mUpdateButton) + mUpdateButton->setEnabled(false); + setCaption(_("Who Is Online - Update")); + if (mThread && SDL_GetThreadID(mThread)) + { + SDL_WaitThread(mThread, nullptr); + mThread = nullptr; + } + mDownloadComplete = true; } - mDownloadComplete = true; + } + else + { + mUpdateTimer = cur_time - 20; + Net::getPlayerHandler()->requestOnlineList(); + setCaption(_("Who Is Online - Update")); } } } diff --git a/src/gui/whoisonline.h b/src/gui/whoisonline.h index 72063b183..112ad35ba 100644 --- a/src/gui/whoisonline.h +++ b/src/gui/whoisonline.h @@ -65,7 +65,9 @@ class WhoIsOnline : public Window, /** * Loads and display online list from the memory buffer. */ - void loadList(); + void loadWebList(); + + void loadList(std::vector &list); void handleLink(const std::string& link, gcn::MouseEvent *event); @@ -83,6 +85,10 @@ class WhoIsOnline : public Window, void optionChanged(const std::string &name); + void updateList(std::vector &list); + + void readFromWeb(); + private: void download(); @@ -101,6 +107,13 @@ private: const std::string prepareNick(std::string nick, int level, std::string color) const; + + void updateWindow(std::vector &friends, + std::vector &neutral, + std::vector &disregard, + std::vector enemy, + int numOnline); + enum DownloadStatus { UPDATE_ERROR = 0, @@ -137,4 +150,6 @@ private: bool mUpdateOnlineList; }; +extern WhoIsOnline *whoIsOnline; + #endif diff --git a/src/net/manaserv/playerhandler.cpp b/src/net/manaserv/playerhandler.cpp index da8958044..925938161 100644 --- a/src/net/manaserv/playerhandler.cpp +++ b/src/net/manaserv/playerhandler.cpp @@ -443,4 +443,9 @@ Vector PlayerHandler::getDefaultWalkSpeed() const return ManaServ::BeingHandler::giveSpeedInPixelsPerTicks(6.0f); } +void PlayerHandler::requestOnlineList() +{ + +} + } // namespace ManaServ diff --git a/src/net/manaserv/playerhandler.h b/src/net/manaserv/playerhandler.h index 21bbac516..c33eddc84 100644 --- a/src/net/manaserv/playerhandler.h +++ b/src/net/manaserv/playerhandler.h @@ -70,6 +70,8 @@ class PlayerHandler : public MessageHandler, public Net::PlayerHandler int getJobLocation() const; int getAttackLocation() const; + void requestOnlineList(); + Vector getDefaultWalkSpeed() const; private: diff --git a/src/net/messagein.cpp b/src/net/messagein.cpp index 0fbf7162b..19453b745 100644 --- a/src/net/messagein.cpp +++ b/src/net/messagein.cpp @@ -241,4 +241,29 @@ std::string MessageIn::readRawString(int length) return str; } +char *MessageIn::readBytes(int length) +{ + // Get string length + if (length < 0) + length = readInt16(); + + // Make sure the string isn't erroneous + if (length < 0 || mPos + length > mLength) + { + mPos = mLength + 1; + DEBUGLOG("readBytesString error"); + return nullptr; + } + + char *buf = new char[length + 2]; + + memcpy (buf, mData + mPos, length); + buf[length] = 0; + buf[length + 1] = 0; + mPos += length; + + PacketCounters::incInBytes(length); + return buf; +} + } diff --git a/src/net/messagein.h b/src/net/messagein.h index 6d7038d4a..ed143a213 100644 --- a/src/net/messagein.h +++ b/src/net/messagein.h @@ -95,6 +95,8 @@ class MessageIn virtual std::string readRawString(int length); + char *readBytes(int length); + virtual ~MessageIn() { } diff --git a/src/net/playerhandler.h b/src/net/playerhandler.h index 47d666036..4f1ed8f00 100644 --- a/src/net/playerhandler.h +++ b/src/net/playerhandler.h @@ -71,6 +71,8 @@ class PlayerHandler virtual int getAttackLocation() const = 0; virtual Vector getDefaultWalkSpeed() const = 0; + + virtual void requestOnlineList() = 0; }; } // namespace Net diff --git a/src/net/tmwa/network.cpp b/src/net/tmwa/network.cpp index 3181ec898..db006c5c0 100644 --- a/src/net/tmwa/network.cpp +++ b/src/net/tmwa/network.cpp @@ -83,7 +83,7 @@ short packet_lengths[] = -1, -1, 20, 10, 32, 9, 34, 14, 2, 6, 48, 56, -1, 4, 5, 10, // #0x0200 26, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 19, 10, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 122, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; diff --git a/src/net/tmwa/playerhandler.cpp b/src/net/tmwa/playerhandler.cpp index c34c661e8..20156d8cb 100644 --- a/src/net/tmwa/playerhandler.cpp +++ b/src/net/tmwa/playerhandler.cpp @@ -30,6 +30,8 @@ #include "net/tmwa/npchandler.h" #include "net/tmwa/inventoryhandler.h" +#include "gui/whoisonline.h" + #include "debug.h" extern Net::PlayerHandler *playerHandler; @@ -50,6 +52,7 @@ PlayerHandler::PlayerHandler() SMSG_PLAYER_STAT_UPDATE_5, SMSG_PLAYER_STAT_UPDATE_6, SMSG_PLAYER_ARROW_MESSAGE, + SMSG_ONLINE_LIST, 0 }; handledMessages = _messages; @@ -97,6 +100,9 @@ void PlayerHandler::handleMessage(Net::MessageIn &msg) processPlayerArrowMessage(msg); break; + case SMSG_ONLINE_LIST: + processOnlineList(msg); + default: break; } @@ -201,4 +207,39 @@ void PlayerHandler::respawn() outMsg.writeInt8(0); } +void PlayerHandler::requestOnlineList() +{ + MessageOut outMsg(CMSG_ONLINE_LIST); +} + +void PlayerHandler::processOnlineList(Net::MessageIn &msg) +{ + if (!whoIsOnline) + return; + + int size = msg.readInt16() - 4; + std::vector arr; + + if (!size) + { + if (whoIsOnline) + whoIsOnline->loadList(arr); + return; + } + + const char *start = msg.readBytes(size); + const char *buf = start; + + while (buf - start + 1 < size && *(buf + 1)) + { + char status = *buf; // now unused + buf ++; + arr.push_back(buf); + buf += strlen(buf) + 1; + } + + if (whoIsOnline) + whoIsOnline->loadList(arr); +} + } // namespace TmwAthena diff --git a/src/net/tmwa/playerhandler.h b/src/net/tmwa/playerhandler.h index bf8e861ff..898bdae3d 100644 --- a/src/net/tmwa/playerhandler.h +++ b/src/net/tmwa/playerhandler.h @@ -51,6 +51,8 @@ class PlayerHandler : public MessageHandler, public Ea::PlayerHandler void setDirection(char direction); void setDestination(int x, int y, int direction = -1); void changeAction(Being::Action action); + void processOnlineList(Net::MessageIn &msg); + void requestOnlineList(); void respawn(); }; diff --git a/src/net/tmwa/protocol.h b/src/net/tmwa/protocol.h index caf3c8e53..37f036ca8 100644 --- a/src/net/tmwa/protocol.h +++ b/src/net/tmwa/protocol.h @@ -333,5 +333,7 @@ enum #define SMSG_PVP_SET 0x019a #define CMSG_IGNORE_ALL 0x00d0 #define SMSG_IGNORE_ALL_RESPONSE 0x00d2 +#define CMSG_ONLINE_LIST 0x0210 +#define SMSG_ONLINE_LIST 0x0211 #endif -- cgit v1.2.3-60-g2f50