summaryrefslogtreecommitdiff
path: root/src/net
diff options
context:
space:
mode:
Diffstat (limited to 'src/net')
-rw-r--r--src/net/abilityhandler.h (renamed from src/net/specialhandler.h)19
-rw-r--r--src/net/adminhandler.h5
-rw-r--r--src/net/charhandler.h5
-rw-r--r--src/net/chathandler.h5
-rw-r--r--src/net/download.cpp298
-rw-r--r--src/net/download.h92
-rw-r--r--src/net/gamehandler.h5
-rw-r--r--src/net/generalhandler.h7
-rw-r--r--src/net/guildhandler.h5
-rw-r--r--src/net/inventoryhandler.h51
-rw-r--r--src/net/logindata.h9
-rw-r--r--src/net/loginhandler.h5
-rw-r--r--src/net/manaserv/abilityhandler.cpp (renamed from src/net/manaserv/specialhandler.cpp)29
-rw-r--r--src/net/manaserv/abilityhandler.h (renamed from src/net/manaserv/specialhandler.h)17
-rw-r--r--src/net/manaserv/adminhandler.cpp6
-rw-r--r--src/net/manaserv/adminhandler.h5
-rw-r--r--src/net/manaserv/beinghandler.cpp153
-rw-r--r--src/net/manaserv/beinghandler.h10
-rw-r--r--src/net/manaserv/buysellhandler.h5
-rw-r--r--src/net/manaserv/charhandler.cpp83
-rw-r--r--src/net/manaserv/charhandler.h16
-rw-r--r--src/net/manaserv/chathandler.h5
-rw-r--r--src/net/manaserv/connection.cpp5
-rw-r--r--src/net/manaserv/connection.h5
-rw-r--r--src/net/manaserv/defines.h5
-rw-r--r--src/net/manaserv/effecthandler.h5
-rw-r--r--src/net/manaserv/gamehandler.cpp4
-rw-r--r--src/net/manaserv/gamehandler.h5
-rw-r--r--src/net/manaserv/generalhandler.cpp35
-rw-r--r--src/net/manaserv/generalhandler.h9
-rw-r--r--src/net/manaserv/guildhandler.h5
-rw-r--r--src/net/manaserv/internal.h5
-rw-r--r--src/net/manaserv/inventoryhandler.cpp288
-rw-r--r--src/net/manaserv/inventoryhandler.h38
-rw-r--r--src/net/manaserv/itemhandler.cpp2
-rw-r--r--src/net/manaserv/itemhandler.h5
-rw-r--r--src/net/manaserv/loginhandler.cpp2
-rw-r--r--src/net/manaserv/loginhandler.h5
-rw-r--r--src/net/manaserv/manaserv_protocol.h212
-rw-r--r--src/net/manaserv/messagehandler.h5
-rw-r--r--src/net/manaserv/messagein.h5
-rw-r--r--src/net/manaserv/messageout.h5
-rw-r--r--src/net/manaserv/network.cpp4
-rw-r--r--src/net/manaserv/network.h5
-rw-r--r--src/net/manaserv/npchandler.cpp6
-rw-r--r--src/net/manaserv/npchandler.h5
-rw-r--r--src/net/manaserv/partyhandler.h5
-rw-r--r--src/net/manaserv/playerhandler.cpp82
-rw-r--r--src/net/manaserv/playerhandler.h5
-rw-r--r--src/net/manaserv/tradehandler.h5
-rw-r--r--src/net/messagehandler.h10
-rw-r--r--src/net/net.cpp53
-rw-r--r--src/net/net.h9
-rw-r--r--src/net/npchandler.h5
-rw-r--r--src/net/partyhandler.h5
-rw-r--r--src/net/playerhandler.h5
-rw-r--r--src/net/serverinfo.h43
-rw-r--r--src/net/tmwa/abilityhandler.cpp (renamed from src/net/tmwa/specialhandler.cpp)50
-rw-r--r--src/net/tmwa/abilityhandler.h (renamed from src/net/tmwa/specialhandler.h)17
-rw-r--r--src/net/tmwa/adminhandler.cpp3
-rw-r--r--src/net/tmwa/adminhandler.h5
-rw-r--r--src/net/tmwa/beinghandler.cpp146
-rw-r--r--src/net/tmwa/beinghandler.h5
-rw-r--r--src/net/tmwa/buysellhandler.cpp2
-rw-r--r--src/net/tmwa/buysellhandler.h5
-rw-r--r--src/net/tmwa/charserverhandler.cpp29
-rw-r--r--src/net/tmwa/charserverhandler.h7
-rw-r--r--src/net/tmwa/chathandler.cpp7
-rw-r--r--src/net/tmwa/chathandler.h5
-rw-r--r--src/net/tmwa/gamehandler.cpp2
-rw-r--r--src/net/tmwa/gamehandler.h5
-rw-r--r--src/net/tmwa/generalhandler.cpp17
-rw-r--r--src/net/tmwa/generalhandler.h9
-rw-r--r--src/net/tmwa/gui/guildtab.h5
-rw-r--r--src/net/tmwa/gui/partytab.cpp3
-rw-r--r--src/net/tmwa/gui/partytab.h5
-rw-r--r--src/net/tmwa/guildhandler.cpp5
-rw-r--r--src/net/tmwa/guildhandler.h5
-rw-r--r--src/net/tmwa/inventoryhandler.cpp5
-rw-r--r--src/net/tmwa/inventoryhandler.h10
-rw-r--r--src/net/tmwa/itemhandler.h5
-rw-r--r--src/net/tmwa/loginhandler.cpp12
-rw-r--r--src/net/tmwa/loginhandler.h5
-rw-r--r--src/net/tmwa/messagehandler.h5
-rw-r--r--src/net/tmwa/messagein.cpp43
-rw-r--r--src/net/tmwa/messagein.h5
-rw-r--r--src/net/tmwa/messageout.cpp3
-rw-r--r--src/net/tmwa/messageout.h5
-rw-r--r--src/net/tmwa/network.cpp24
-rw-r--r--src/net/tmwa/network.h7
-rw-r--r--src/net/tmwa/npchandler.h5
-rw-r--r--src/net/tmwa/partyhandler.h5
-rw-r--r--src/net/tmwa/playerhandler.h5
-rw-r--r--src/net/tmwa/protocol.h19
-rw-r--r--src/net/tmwa/token.h7
-rw-r--r--src/net/tmwa/tradehandler.cpp6
-rw-r--r--src/net/tmwa/tradehandler.h5
-rw-r--r--src/net/tradehandler.h5
-rw-r--r--src/net/worldinfo.h5
99 files changed, 1053 insertions, 1207 deletions
diff --git a/src/net/specialhandler.h b/src/net/abilityhandler.h
index fb8ffdfd..8e61d0c5 100644
--- a/src/net/specialhandler.h
+++ b/src/net/abilityhandler.h
@@ -19,25 +19,22 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef SPECIALHANDLER_H
-#define SPECIALHANDLER_H
-
-#include <iosfwd>
+#pragma once
namespace Net {
-class SpecialHandler
+
+class AbilityHandler
{
public:
- virtual ~SpecialHandler () {}
+ virtual ~AbilityHandler () {}
virtual void use(int id) = 0;
- virtual void use(int id, int level, int beingId) = 0;
+ virtual void useOn(int id, int beingId) = 0;
- virtual void use(int id, int level, int x, int y) = 0;
+ virtual void useAt(int id, int x, int y) = 0;
- virtual void use(int id, const std::string &map) = 0;
+ virtual void useInDirection(int id, int direction) = 0;
};
-}
-#endif // SPECIALHANDLER_H
+} // namespace Net
diff --git a/src/net/adminhandler.h b/src/net/adminhandler.h
index 492918a7..87853317 100644
--- a/src/net/adminhandler.h
+++ b/src/net/adminhandler.h
@@ -19,8 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef ADMINHANDLER_H
-#define ADMINHANDLER_H
+#pragma once
#include <string>
@@ -39,5 +38,3 @@ class AdminHandler
};
} // namespace Net
-
-#endif // ADMINHANDLER_H
diff --git a/src/net/charhandler.h b/src/net/charhandler.h
index 72e67739..3f0c096f 100644
--- a/src/net/charhandler.h
+++ b/src/net/charhandler.h
@@ -19,8 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef CHARHANDLER_H
-#define CHARHANDLER_H
+#pragma once
#include "localplayer.h"
#include "playerinfo.h"
@@ -111,5 +110,3 @@ class CharHandler
};
} // namespace Net
-
-#endif // CHARHANDLER_H
diff --git a/src/net/chathandler.h b/src/net/chathandler.h
index 382ac39a..5524f458 100644
--- a/src/net/chathandler.h
+++ b/src/net/chathandler.h
@@ -19,8 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef CHATHANDLER_H
-#define CHATHANDLER_H
+#pragma once
#include <string>
@@ -62,5 +61,3 @@ class ChatHandler
virtual void requestOnlineList() = 0;
};
}
-
-#endif // CHATHANDLER_H
diff --git a/src/net/download.cpp b/src/net/download.cpp
index 8a41ebfa..7aab3b2f 100644
--- a/src/net/download.cpp
+++ b/src/net/download.cpp
@@ -31,7 +31,7 @@
#include <zlib.h>
-const char *DOWNLOAD_ERROR_MESSAGE_THREAD = "Could not create download thread!";
+constexpr char DOWNLOAD_ERROR_MESSAGE_THREAD[] = "Could not create download thread!";
namespace Net {
@@ -59,32 +59,26 @@ unsigned long Download::fadler32(FILE *file)
return adler;
}
-
-Download::Download(void *ptr, const std::string &url,
- DownloadUpdate updateFunction):
- mPtr(ptr),
- mUrl(url),
- mUpdateFunction(updateFunction)
+Download::Download(const std::string &url)
+ : mUrl(url)
{
- mError = (char*) malloc(CURL_ERROR_SIZE);
mError[0] = 0;
-
- mOptions.cancel = false;
}
Download::~Download()
{
- if (mHeaders)
- curl_slist_free_all(mHeaders);
+ mCancel = true;
+ SDL_WaitThread(mThread, nullptr);
- int status;
- SDL_WaitThread(mThread, &status);
- free(mError);
+ curl_slist_free_all(mHeaders);
+ free(mBuffer);
}
-void Download::addHeader(const std::string &header)
+void Download::addHeader(const char *header)
{
- mHeaders = curl_slist_append(mHeaders, header.c_str());
+ assert(!mThread); // Cannot add headers after starting download
+
+ mHeaders = curl_slist_append(mHeaders, header);
}
void Download::noCache()
@@ -96,19 +90,24 @@ void Download::noCache()
void Download::setFile(const std::string &filename,
std::optional<unsigned long> adler32)
{
- mOptions.memoryWrite = false;
+ assert(!mThread); // Cannot set file after starting download
+
+ mMemoryWrite = false;
mFileName = filename;
mAdler = adler32;
}
-void Download::setWriteFunction(WriteFunction write)
+void Download::setUseBuffer()
{
- mOptions.memoryWrite = true;
- mWriteFunction = write;
+ assert(!mThread); // Cannot set write function after starting download
+
+ mMemoryWrite = true;
}
bool Download::start()
{
+ assert(!mThread); // Download already started
+
logger->log("Starting download: %s", mUrl.c_str());
mThread = SDL_CreateThread(downloadThread, "Download", this);
@@ -116,9 +115,8 @@ bool Download::start()
if (!mThread)
{
logger->log("%s", DOWNLOAD_ERROR_MESSAGE_THREAD);
- strcpy(mError, DOWNLOAD_ERROR_MESSAGE_THREAD);
- mUpdateFunction(mPtr, DOWNLOAD_STATUS_THREAD_ERROR, 0, 0);
-
+ strncpy(mError, DOWNLOAD_ERROR_MESSAGE_THREAD, CURL_ERROR_SIZE - 1);
+ mState.lock()->status = DownloadStatus::Error;
return false;
}
@@ -128,196 +126,186 @@ bool Download::start()
void Download::cancel()
{
logger->log("Canceling download: %s", mUrl.c_str());
-
- mOptions.cancel = true;
- if (mThread && SDL_GetThreadID(mThread) != 0)
- {
- SDL_WaitThread(mThread, nullptr);
- mThread = nullptr;
- }
+ mCancel = true;
}
-const char *Download::getError() const
+std::string_view Download::getBuffer() const
{
- return mError;
+ assert(mMemoryWrite); // Buffer not used
+ return std::string_view(mBuffer, mDownloadedBytes);
}
+/**
+ * A libcurl callback for reporting progress.
+ */
int Download::downloadProgress(void *clientp,
curl_off_t dltotal, curl_off_t dlnow,
curl_off_t ultotal, curl_off_t ulnow)
{
auto *d = reinterpret_cast<Download*>(clientp);
- if (d->mOptions.cancel)
+ auto state = d->mState.lock();
+ state->status = DownloadStatus::InProgress;
+ state->progress = 0.0f;
+ if (dltotal > 0)
+ state->progress = static_cast<float>(dlnow) / dltotal;
+
+ return d->mCancel;
+}
+
+/**
+ * A libcurl callback for writing to memory.
+ */
+size_t Download::writeBuffer(char *ptr, size_t size, size_t nmemb, void *stream)
+{
+ auto *d = reinterpret_cast<Download *>(stream);
+
+ const size_t totalMem = size * nmemb;
+ d->mBuffer = (char *) realloc(d->mBuffer, d->mDownloadedBytes + totalMem);
+ if (d->mBuffer)
{
- return d->mUpdateFunction(d->mPtr, DOWNLOAD_STATUS_CANCELLED,
- (size_t) dltotal, (size_t) dlnow);
- return -5;
+ memcpy(d->mBuffer + d->mDownloadedBytes, ptr, totalMem);
+ d->mDownloadedBytes += totalMem;
}
- return d->mUpdateFunction(d->mPtr, DOWNLOAD_STATUS_IDLE,
- (size_t) dltotal, (size_t) dlnow);
+ return totalMem;
}
int Download::downloadThread(void *ptr)
{
- int attempts = 0;
- bool complete = false;
auto *d = reinterpret_cast<Download*>(ptr);
- CURLcode res;
+ bool complete = false;
std::string outFilename;
- if (!d)
- {
- return 0;
- }
- if (!d->mOptions.memoryWrite)
- {
+ if (!d->mMemoryWrite)
outFilename = d->mFileName + ".part";
- }
- while (attempts < 3 && !complete && !d->mOptions.cancel)
+ for (int attempts = 0; attempts < 3 && !complete && !d->mCancel; ++attempts)
{
- FILE *file = nullptr;
+ CURL *curl = curl_easy_init();
+ if (!curl)
+ break;
- d->mUpdateFunction(d->mPtr, DOWNLOAD_STATUS_STARTING, 0, 0);
+ logger->log("Downloading: %s", d->mUrl.c_str());
- if (d->mOptions.cancel)
- {
- d->mThread = nullptr;
- return 0;
- }
+ curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
+ curl_easy_setopt(curl, CURLOPT_HTTPHEADER, d->mHeaders);
- d->mCurl = curl_easy_init();
+ FILE *file = nullptr;
- if (d->mCurl && !d->mOptions.cancel)
+ if (d->mMemoryWrite)
+ {
+ curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &Download::writeBuffer);
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, ptr);
+ }
+ else
{
- logger->log("Downloading: %s", d->mUrl.c_str());
+ file = fopen(outFilename.c_str(), "w+b");
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, file);
+ }
- curl_easy_setopt(d->mCurl, CURLOPT_FOLLOWLOCATION, 1);
- curl_easy_setopt(d->mCurl, CURLOPT_HTTPHEADER, d->mHeaders);
+ const std::string appShort = branding.getStringValue("appShort");
+ const std::string userAgent =
+ strprintf(PACKAGE_EXTENDED_VERSION, appShort.c_str());
- if (d->mOptions.memoryWrite)
- {
- curl_easy_setopt(d->mCurl, CURLOPT_FAILONERROR, 1);
- curl_easy_setopt(d->mCurl, CURLOPT_WRITEFUNCTION, d->mWriteFunction);
- curl_easy_setopt(d->mCurl, CURLOPT_WRITEDATA, d->mPtr);
- }
- else
- {
- file = fopen(outFilename.c_str(), "w+b");
- curl_easy_setopt(d->mCurl, CURLOPT_WRITEDATA, file);
- }
+ curl_easy_setopt(curl, CURLOPT_USERAGENT, userAgent.c_str());
+ curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, d->mError);
+ curl_easy_setopt(curl, CURLOPT_URL, d->mUrl.c_str());
+ curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0);
+ curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, &Download::downloadProgress);
+ curl_easy_setopt(curl, CURLOPT_XFERINFODATA, ptr);
+ curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
+ curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 15);
- const std::string appShort = branding.getStringValue("appShort");
- const std::string userAgent =
- strprintf(PACKAGE_EXTENDED_VERSION, appShort.c_str());
+ const CURLcode res = curl_easy_perform(curl);
+ curl_easy_cleanup(curl);
- curl_easy_setopt(d->mCurl, CURLOPT_USERAGENT, userAgent.c_str());
- curl_easy_setopt(d->mCurl, CURLOPT_ERRORBUFFER, d->mError);
- curl_easy_setopt(d->mCurl, CURLOPT_URL, d->mUrl.c_str());
- curl_easy_setopt(d->mCurl, CURLOPT_NOPROGRESS, 0);
- curl_easy_setopt(d->mCurl, CURLOPT_XFERINFOFUNCTION, downloadProgress);
- curl_easy_setopt(d->mCurl, CURLOPT_XFERINFODATA, ptr);
- curl_easy_setopt(d->mCurl, CURLOPT_NOSIGNAL, 1);
- curl_easy_setopt(d->mCurl, CURLOPT_CONNECTTIMEOUT, 15);
+ if (res == CURLE_ABORTED_BY_CALLBACK)
+ {
+ d->mCancel = true;
- if ((res = curl_easy_perform(d->mCurl)) != 0 && !d->mOptions.cancel)
+ if (file)
{
- switch (res)
- {
- case CURLE_ABORTED_BY_CALLBACK:
- d->mOptions.cancel = true;
- break;
- case CURLE_COULDNT_CONNECT:
- default:
- logger->log("curl error %d: %s host: %s",
- res, d->mError, d->mUrl.c_str());
- break;
- }
+ fclose(file);
+ ::remove(outFilename.c_str());
+ }
- if (d->mOptions.cancel)
- {
- break;
- }
+ break;
+ }
- d->mUpdateFunction(d->mPtr, DOWNLOAD_STATUS_ERROR, 0, 0);
+ if (res != CURLE_OK)
+ {
+ logger->log("curl error %d: %s host: %s",
+ res, d->mError, d->mUrl.c_str());
- if (!d->mOptions.memoryWrite)
- {
- fclose(file);
- ::remove(outFilename.c_str());
- }
- attempts++;
- continue;
+ if (file)
+ {
+ fclose(file);
+ ::remove(outFilename.c_str());
}
- curl_easy_cleanup(d->mCurl);
+ break;
+ }
- if (!d->mOptions.memoryWrite)
+ if (!d->mMemoryWrite)
+ {
+ // Check the checksum if available
+ if (d->mAdler)
{
- // Don't check resources.xml checksum
- if (d->mAdler)
- {
- unsigned long adler = fadler32(file);
+ unsigned long adler = fadler32(file);
- if (d->mAdler != adler)
- {
+ if (d->mAdler != adler)
+ {
+ if (file)
fclose(file);
- // Remove the corrupted file
- ::remove(d->mFileName.c_str());
- logger->log("Checksum for file %s failed: (%lx/%lx)",
- d->mFileName.c_str(),
- adler, *d->mAdler);
- attempts++;
- continue; // Bail out here to avoid the renaming
- }
+ // Remove the corrupted file
+ ::remove(outFilename.c_str());
+ logger->log("Checksum for file %s failed: (%lx/%lx)",
+ d->mFileName.c_str(),
+ adler, *d->mAdler);
+
+ continue; // Bail out here to avoid the renaming
}
+ }
+
+ if (file)
fclose(file);
- // Any existing file with this name is deleted first, otherwise
- // the rename will fail on Windows.
- ::remove(d->mFileName.c_str());
- ::rename(outFilename.c_str(), d->mFileName.c_str());
+ // Any existing file with this name is deleted first, otherwise
+ // the rename will fail on Windows.
+ ::remove(d->mFileName.c_str());
+ ::rename(outFilename.c_str(), d->mFileName.c_str());
- // Check if we can open it and no errors were encountered
- // during renaming
- file = fopen(d->mFileName.c_str(), "rb");
- if (file)
- {
- fclose(file);
- complete = true;
- }
- }
- else
+ // Check if we can open it and no errors were encountered
+ // during renaming
+ file = fopen(d->mFileName.c_str(), "rb");
+ if (file)
{
- // It's stored in memory, we're done
+ fclose(file);
+ file = nullptr;
complete = true;
}
}
- if (d->mOptions.cancel)
+ else
{
- d->mThread = nullptr;
- return 0;
+ // It's stored in memory, we're done
+ complete = true;
}
- attempts++;
- }
- if (d->mOptions.cancel)
- {
- // Nothing to do...
- }
- else if (!complete || attempts >= 3)
- {
- d->mUpdateFunction(d->mPtr, DOWNLOAD_STATUS_ERROR, 0, 0);
+ if (file)
+ fclose(file);
}
+
+ auto state = d->mState.lock();
+ if (d->mCancel)
+ state->status = DownloadStatus::Canceled;
+ else if (complete)
+ state->status = DownloadStatus::Complete;
else
- {
- d->mUpdateFunction(d->mPtr, DOWNLOAD_STATUS_COMPLETE, 0, 0);
- }
+ state->status = DownloadStatus::Error;
- d->mThread = nullptr;
return 0;
}
diff --git a/src/net/download.h b/src/net/download.h
index 0ce8cc8a..e9483fa5 100644
--- a/src/net/download.h
+++ b/src/net/download.h
@@ -18,44 +18,41 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <cstdlib> // pulls in int64_t
+#include "utils/mutex.h"
+
#include <cstdio>
-#include <string>
#include <optional>
+#include <string>
#include <curl/curl.h>
-#ifndef NET_DOWNLOAD_H
-#define NET_DOWNLOAD_H
+#pragma once
-enum DownloadStatus
+enum class DownloadStatus
{
- DOWNLOAD_STATUS_CANCELLED = -3,
- DOWNLOAD_STATUS_THREAD_ERROR = -2,
- DOWNLOAD_STATUS_ERROR = -1,
- DOWNLOAD_STATUS_STARTING = 0,
- DOWNLOAD_STATUS_IDLE,
- DOWNLOAD_STATUS_COMPLETE
+ InProgress,
+ Canceled,
+ Error,
+ Complete
};
-using DownloadUpdate = int (*)(void *, DownloadStatus, size_t, size_t);
-
-// Matches what CURL expects
-using WriteFunction = size_t (*)(void *, size_t, size_t, void *);
-
struct SDL_Thread;
-using CURL = void;
-struct curl_slist;
namespace Net {
+
class Download
{
public:
- Download(void *ptr, const std::string &url, DownloadUpdate updateFunction);
+ struct State
+ {
+ DownloadStatus status = DownloadStatus::InProgress;
+ float progress = 0.0f;
+ };
+ Download(const std::string &url);
~Download();
- void addHeader(const std::string &header);
+ void addHeader(const char *header);
/**
* Convience method for adding no-cache headers.
@@ -65,47 +62,66 @@ class Download
void setFile(const std::string &filename,
std::optional<unsigned long> adler32 = {});
- void setWriteFunction(WriteFunction write);
+ void setUseBuffer();
/**
* Starts the download thread.
- * @returns true if thread was created
- * false if the thread could not be made or download wasn't
- * properly setup
+ * @returns whether the thread could be created
*/
bool start();
/**
- * Cancels the download. Returns immediately, the cancelled status will
- * be noted in the next avialable update call.
+ * Cancels the download. Returns immediately, the canceled status will
+ * be noted in the next available update call.
*/
void cancel();
+ /**
+ * Returns a view on the downloaded data.
+ */
+ std::string_view getBuffer() const;
+
+ State getState();
+
const char *getError() const;
static unsigned long fadler32(FILE *file);
private:
- static int downloadThread(void *ptr);
static int downloadProgress(void *clientp,
curl_off_t dltotal, curl_off_t dlnow,
curl_off_t ultotal, curl_off_t ulnow);
- void *mPtr;
+
+ static size_t writeBuffer(char *ptr, size_t size, size_t nmemb,
+ void *stream);
+
+ static int downloadThread(void *ptr);
+
+ ThreadSafe<State> mState;
std::string mUrl;
- struct {
- unsigned cancel : 1;
- unsigned memoryWrite: 1;
- } mOptions;
+ bool mCancel = false;
+ bool mMemoryWrite = false;
std::string mFileName;
- WriteFunction mWriteFunction = nullptr;
std::optional<unsigned long> mAdler;
- DownloadUpdate mUpdateFunction;
SDL_Thread *mThread = nullptr;
- CURL *mCurl = nullptr;
curl_slist *mHeaders = nullptr;
- char *mError;
+ char mError[CURL_ERROR_SIZE];
+
+ /** Byte count currently downloaded in mMemoryBuffer. */
+ size_t mDownloadedBytes = 0;
+
+ /** Buffer for files downloaded to memory. */
+ char *mBuffer = nullptr;
};
-} // namespace Net
+inline Download::State Download::getState()
+{
+ return *mState.lock();
+}
-#endif // NET_DOWNLOAD_H
+inline const char *Download::getError() const
+{
+ return mError;
+}
+
+} // namespace Net
diff --git a/src/net/gamehandler.h b/src/net/gamehandler.h
index 3f47aba5..08c6c33f 100644
--- a/src/net/gamehandler.h
+++ b/src/net/gamehandler.h
@@ -19,8 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef MAPHANDLER_H
-#define MAPHANDLER_H
+#pragma once
#include <iosfwd>
@@ -58,5 +57,3 @@ class GameHandler
};
} // namespace Net
-
-#endif // MAPHANDLER_H
diff --git a/src/net/generalhandler.h b/src/net/generalhandler.h
index 76cde7ce..93d76421 100644
--- a/src/net/generalhandler.h
+++ b/src/net/generalhandler.h
@@ -19,8 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef GENERALHANDLER_H
-#define GENERALHANDLER_H
+#pragma once
namespace Net {
@@ -36,10 +35,6 @@ class GeneralHandler
virtual void unload() = 0;
virtual void flushNetwork() = 0;
-
- virtual void clearHandlers() = 0;
};
} // namespace Net
-
-#endif // GENERALHANDLER_H
diff --git a/src/net/guildhandler.h b/src/net/guildhandler.h
index 00eae99c..37127599 100644
--- a/src/net/guildhandler.h
+++ b/src/net/guildhandler.h
@@ -19,8 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef GUILDHANDLER_H
-#define GUILDHANDLER_H
+#pragma once
#include "guild.h"
@@ -64,5 +63,3 @@ class GuildHandler
};
}
-
-#endif // GUILDHANDLER_H
diff --git a/src/net/inventoryhandler.h b/src/net/inventoryhandler.h
index 8a67a7db..995e54d9 100644
--- a/src/net/inventoryhandler.h
+++ b/src/net/inventoryhandler.h
@@ -19,20 +19,17 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef INVENTORYHANDLER_H
-#define INVENTORYHANDLER_H
+#pragma once
#include "equipment.h"
-#include "inventory.h"
-#include "item.h"
#include "position.h"
-#include <iosfwd>
+#include <string>
namespace Net {
// Default positions of the boxes, 2nd dimension is X and Y respectively.
-const int fallBackBoxesPosition[][2] = {
+constexpr Position fallBackBoxPositions[] = {
{ 90, 40 }, // EQUIP_TORSO_SLOT
{ 8, 78 }, // EQUIP_GLOVES_SLOT
{ 70, 0 }, // EQUIP_HEAD_SLOT
@@ -46,29 +43,27 @@ const int fallBackBoxesPosition[][2] = {
{ 129, 78 } // EQUIP_PROJECTILE_SLOT
};
-const std::string fallBackBoxesBackground[] = {
- "equip-box-chest.png",
- "equip-box-hands.png",
- "equip-box-head.png",
- "equip-box-legs.png",
- "equip-box-feet.png",
- "equip-box-ring.png",
- "equip-box-ring.png",
- "equip-box-neck.png",
- "equip-box-weapon.png",
- "equip-box-shield.png",
- "equip-box-ammo.png"
+const std::string fallBackBoxIcons[] = {
+ "equip-box-chest",
+ "equip-box-hands",
+ "equip-box-head",
+ "equip-box-legs",
+ "equip-box-feet",
+ "equip-box-ring",
+ "equip-box-ring",
+ "equip-box-neck",
+ "equip-box-weapon",
+ "equip-box-shield",
+ "equip-box-ammo"
};
-static const std::string empty = std::string();
+static const std::string empty;
class InventoryHandler
{
public:
virtual ~InventoryHandler() {}
- virtual bool canSplit(const Item *item) = 0;
-
// TODO: fix/remove me
virtual size_t getSize(int type) const = 0;
@@ -83,21 +78,17 @@ class InventoryHandler
virtual Position getBoxPosition(unsigned int slotIndex) const
{
- if (slotIndex < (sizeof(fallBackBoxesPosition)
- / sizeof(fallBackBoxesPosition[0][0])))
- return Position(fallBackBoxesPosition[slotIndex][0],
- fallBackBoxesPosition[slotIndex][1]);
+ if (slotIndex < sizeof(fallBackBoxPositions) / sizeof(fallBackBoxPositions[0]))
+ return fallBackBoxPositions[slotIndex];
return Position(0,0);
}
- virtual const std::string& getBoxBackground(unsigned int slotIndex) const
+ virtual const std::string& getBoxIcon(unsigned int slotIndex) const
{
- if (slotIndex < sizeof(fallBackBoxesBackground))
- return fallBackBoxesBackground[slotIndex];
+ if (slotIndex < sizeof(fallBackBoxIcons) / sizeof(fallBackBoxIcons[0]))
+ return fallBackBoxIcons[slotIndex];
return empty; // The empty string
}
};
} // namespace Net
-
-#endif // INVENTORYHANDLER_H
diff --git a/src/net/logindata.h b/src/net/logindata.h
index 34b259fb..4af402ec 100644
--- a/src/net/logindata.h
+++ b/src/net/logindata.h
@@ -19,8 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef LOGINDATA_H
-#define LOGINDATA_H
+#pragma once
#include "being.h"
@@ -40,7 +39,7 @@ public:
std::string email;
std::string captchaResponse;
- Gender gender = Gender::UNSPECIFIED;
+ Gender gender = Gender::Unspecified;
bool remember; /**< Whether to store the username. */
bool registerLogin; /**< Whether an account is being registered. */
@@ -64,9 +63,7 @@ public:
updateHost.clear();
email.clear();
captchaResponse.clear();
- gender = Gender::UNSPECIFIED;
+ gender = Gender::Unspecified;
resetCharacterSlots();
}
};
-
-#endif // LOGINDATA_H
diff --git a/src/net/loginhandler.h b/src/net/loginhandler.h
index 43d15b77..992e0709 100644
--- a/src/net/loginhandler.h
+++ b/src/net/loginhandler.h
@@ -19,8 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef LOGINHANDLER_H
-#define LOGINHANDLER_H
+#pragma once
#include "net/logindata.h"
#include "net/serverinfo.h"
@@ -98,5 +97,3 @@ class LoginHandler
};
} // namespace Net
-
-#endif // LOGINHANDLER_H
diff --git a/src/net/manaserv/specialhandler.cpp b/src/net/manaserv/abilityhandler.cpp
index 0a477ff8..a9ce8e37 100644
--- a/src/net/manaserv/specialhandler.cpp
+++ b/src/net/manaserv/abilityhandler.cpp
@@ -19,57 +19,60 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "net/manaserv/specialhandler.h"
+#include "net/manaserv/abilityhandler.h"
#include "net/manaserv/connection.h"
#include "net/manaserv/messagein.h"
#include "net/manaserv/messageout.h"
#include "net/manaserv/manaserv_protocol.h"
-extern Net::SpecialHandler *specialHandler;
+extern Net::AbilityHandler *abilityHandler;
namespace ManaServ {
extern Connection *gameServerConnection;
-SpecialHandler::SpecialHandler()
+AbilityHandler::AbilityHandler()
{
- specialHandler = this;
+ abilityHandler = this;
}
-void SpecialHandler::handleMessage(MessageIn &msg)
+void AbilityHandler::handleMessage(MessageIn &msg)
{
// TODO
}
-void SpecialHandler::use(int id)
+void AbilityHandler::use(int id)
{
- MessageOut msg(PGMSG_USE_SPECIAL_ON_BEING);
+ MessageOut msg(PGMSG_USE_ABILITY_ON_BEING);
msg.writeInt8(id);
msg.writeInt16(0);
gameServerConnection->send(msg);
}
-void SpecialHandler::use(int id, int level, int beingId)
+void AbilityHandler::useOn(int id, int beingId)
{
- MessageOut msg(PGMSG_USE_SPECIAL_ON_BEING);
+ MessageOut msg(PGMSG_USE_ABILITY_ON_BEING);
msg.writeInt8(id);
msg.writeInt16(beingId);
gameServerConnection->send(msg);
}
-void SpecialHandler::use(int id, int level, int x, int y)
+void AbilityHandler::useAt(int id, int x, int y)
{
- MessageOut msg(PGMSG_USE_SPECIAL_ON_POINT);
+ MessageOut msg(PGMSG_USE_ABILITY_ON_POINT);
msg.writeInt8(id);
msg.writeInt16(x);
msg.writeInt16(y);
gameServerConnection->send(msg);
}
-void SpecialHandler::use(int id, const std::string &map)
+void AbilityHandler::useInDirection(int id, int direction)
{
- // TODO
+ MessageOut msg(PGMSG_USE_ABILITY_ON_DIRECTION);
+ msg.writeInt8(id);
+ msg.writeInt8(direction);
+ gameServerConnection->send(msg);
}
} // namespace ManaServ
diff --git a/src/net/manaserv/specialhandler.h b/src/net/manaserv/abilityhandler.h
index dbd203d8..e8263989 100644
--- a/src/net/manaserv/specialhandler.h
+++ b/src/net/manaserv/abilityhandler.h
@@ -19,31 +19,28 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef NET_MANASERV_SKILLHANDLER_H
-#define NET_MANASERV_SKILLHANDLER_H
+#pragma once
-#include "net/specialhandler.h"
+#include "net/abilityhandler.h"
#include "net/manaserv/messagehandler.h"
namespace ManaServ {
-class SpecialHandler final : public MessageHandler, public Net::SpecialHandler
+class AbilityHandler final : public MessageHandler, public Net::AbilityHandler
{
public:
- SpecialHandler();
+ AbilityHandler();
void handleMessage(MessageIn &msg) override;
void use(int id) override;
- void use(int id, int level, int beingId) override;
+ void useOn(int id, int beingId) override;
- void use(int id, int level, int x, int y) override;
+ void useAt(int id, int x, int y) override;
- void use(int id, const std::string &map) override;
+ void useInDirection(int id, int direction) override;
};
} // namespace ManaServ
-
-#endif // NET_MANASERV_SKILLHANDLER_H
diff --git a/src/net/manaserv/adminhandler.cpp b/src/net/manaserv/adminhandler.cpp
index 78e6acb2..ef155a38 100644
--- a/src/net/manaserv/adminhandler.cpp
+++ b/src/net/manaserv/adminhandler.cpp
@@ -31,17 +31,11 @@ extern Connection *chatServerConnection;
AdminHandler::AdminHandler()
{
- static const uint16_t _messages[] =
- {
- 0
- };
- handledMessages = _messages;
adminHandler = this;
}
void AdminHandler::handleMessage(MessageIn &msg)
{
-
}
void AdminHandler::kick(const std::string &name)
diff --git a/src/net/manaserv/adminhandler.h b/src/net/manaserv/adminhandler.h
index fd0c7de0..bc92872b 100644
--- a/src/net/manaserv/adminhandler.h
+++ b/src/net/manaserv/adminhandler.h
@@ -19,8 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef NET_MANASERV_ADMINHANDLER_H
-#define NET_MANASERV_ADMINHANDLER_H
+#pragma once
#include "net/adminhandler.h"
@@ -43,5 +42,3 @@ class AdminHandler final : public Net::AdminHandler, public MessageHandler
};
} // namespace ManaServ
-
-#endif
diff --git a/src/net/manaserv/beinghandler.cpp b/src/net/manaserv/beinghandler.cpp
index 186239c1..9bb52ac1 100644
--- a/src/net/manaserv/beinghandler.cpp
+++ b/src/net/manaserv/beinghandler.cpp
@@ -23,6 +23,7 @@
#include "actorspritemanager.h"
#include "being.h"
+#include "effectmanager.h"
#include "localplayer.h"
#include "gui/okdialog.h"
@@ -34,6 +35,9 @@
#include "net/manaserv/playerhandler.h"
#include "net/manaserv/manaserv_protocol.h"
+#include "playerrelations.h"
+#include "resources/abilitydb.h"
+#include "resources/emotedb.h"
#include "resources/hairdb.h"
#include "utils/gettext.h"
@@ -45,10 +49,13 @@ namespace ManaServ {
BeingHandler::BeingHandler()
{
static const Uint16 _messages[] = {
- GPMSG_BEING_ATTACK,
GPMSG_BEING_ENTER,
GPMSG_BEING_LEAVE,
+ GPMSG_BEING_EMOTE,
GPMSG_BEINGS_MOVE,
+ GPMSG_BEING_ABILITY_POINT,
+ GPMSG_BEING_ABILITY_BEING,
+ GPMSG_BEING_ABILITY_DIRECTION,
GPMSG_BEINGS_DAMAGE,
GPMSG_BEING_ACTION_CHANGE,
GPMSG_BEING_LOOKS_CHANGE,
@@ -68,11 +75,20 @@ void BeingHandler::handleMessage(MessageIn &msg)
case GPMSG_BEING_LEAVE:
handleBeingLeaveMessage(msg);
break;
+ case GPMSG_BEING_EMOTE:
+ handleBeingEmoteMessage(msg);
+ break;
case GPMSG_BEINGS_MOVE:
handleBeingsMoveMessage(msg);
break;
- case GPMSG_BEING_ATTACK:
- handleBeingAttackMessage(msg);
+ case GPMSG_BEING_ABILITY_POINT:
+ handleBeingAbilityPointMessage(msg);
+ break;
+ case GPMSG_BEING_ABILITY_BEING:
+ handleBeingAbilityBeingMessage(msg);
+ break;
+ case GPMSG_BEING_ABILITY_DIRECTION:
+ handleBeingAbilityDirectionMessage(msg);
break;
case GPMSG_BEINGS_DAMAGE:
handleBeingsDamageMessage(msg);
@@ -91,17 +107,40 @@ void BeingHandler::handleMessage(MessageIn &msg)
static void handleLooks(Being *being, MessageIn &msg)
{
- int lookChanges = msg.readInt8();
+ const int hairStyle = msg.readInt8();
+ const int hairColor = msg.readInt8();
+ being->setSprite(SPRITE_LAYER_HAIR, hairStyle * -1,
+ hairDB.getHairColor(hairColor));
+
+ std::map<unsigned, int> equippedSlots;
+
+ if (msg.getUnreadLength() > 1) {
+ int equippedSlotCount = msg.readInt8();
+ while (equippedSlotCount-- > 0) {
+ unsigned slot = msg.readInt8();
+ int itemId = msg.readInt16();
+ equippedSlots[slot] = itemId;
+ }
+ }
- if (lookChanges <= 0)
- return;
+ unsigned endSlot = equippedSlots.empty() ? 0 : equippedSlots.rbegin()->first + 1;
+ if (being->getSpriteCount() > endSlot + FIXED_SPRITE_LAYER_SIZE)
+ endSlot = being->getSpriteCount() - FIXED_SPRITE_LAYER_SIZE;
- while (lookChanges-- > 0)
+ for (unsigned slot = 0; slot < endSlot; ++slot)
{
- unsigned int slotTypeId = msg.readInt8();
- being->setSprite(slotTypeId + FIXED_SPRITE_LAYER_SIZE,
- msg.readInt16(), "",
- Net::getInventoryHandler()->isWeaponSlot(slotTypeId));
+ auto it = equippedSlots.find(slot);
+ if (it == equippedSlots.end())
+ {
+ being->setSprite(slot + FIXED_SPRITE_LAYER_SIZE, 0);
+ }
+ else
+ {
+ being->setSprite(slot + FIXED_SPRITE_LAYER_SIZE,
+ it->second,
+ std::string(),
+ Net::getInventoryHandler()->isWeaponSlot(slot));
+ }
}
}
@@ -113,14 +152,19 @@ void BeingHandler::handleBeingEnterMessage(MessageIn &msg)
int px = msg.readInt16();
int py = msg.readInt16();
auto direction = (BeingDirection)msg.readInt8();
- Gender gender;
- int genderAsInt = msg.readInt8();
- if (genderAsInt == GENDER_FEMALE)
- gender = Gender::FEMALE;
- else if (genderAsInt == GENDER_MALE)
- gender = Gender::MALE;
- else
- gender = Gender::UNSPECIFIED;
+
+ Gender gender = Gender::Unspecified;
+ switch (getGender(msg.readInt8())) {
+ case GENDER_MALE:
+ gender = Gender::Male;
+ break;
+ case GENDER_FEMALE:
+ gender = Gender::Female;
+ break;
+ case GENDER_UNSPECIFIED:
+ break;
+ }
+
Being *being;
switch (type)
@@ -139,9 +183,7 @@ void BeingHandler::handleBeingEnterMessage(MessageIn &msg)
ActorSprite::PLAYER, 0);
being->setName(name);
}
- int hs = msg.readInt8(), hc = msg.readInt8();
- being->setSprite(SPRITE_LAYER_HAIR, hs * -1,
- hairDB.getHairColor(hc));
+
handleLooks(being, msg);
} break;
@@ -152,7 +194,8 @@ void BeingHandler::handleBeingEnterMessage(MessageIn &msg)
being = actorSpriteManager->createBeing(id, type == OBJECT_MONSTER
? ActorSprite::MONSTER : ActorSprite::NPC, subtype);
std::string name = msg.readString();
- if (name.length() > 0) being->setName(name);
+ if (!name.empty())
+ being->setName(name);
} break;
default:
@@ -175,6 +218,19 @@ void BeingHandler::handleBeingLeaveMessage(MessageIn &msg)
actorSpriteManager->destroyActor(being);
}
+void BeingHandler::handleBeingEmoteMessage(MessageIn &msg)
+{
+ Being *being = actorSpriteManager->findBeing(msg.readInt16());
+ if (!being)
+ return;
+
+ if (player_relations.hasPermission(being, PlayerPermissions::EMOTE))
+ {
+ const int fx = EmoteDB::get(msg.readInt8() - 1).effectId;
+ effectManager->trigger(fx, being);
+ }
+}
+
void BeingHandler::handleBeingsMoveMessage(MessageIn &msg)
{
while (msg.getUnreadLength())
@@ -235,18 +291,51 @@ void BeingHandler::handleBeingsMoveMessage(MessageIn &msg)
}
}
-void BeingHandler::handleBeingAttackMessage(MessageIn &msg)
+void BeingHandler::handleBeingAbilityPointMessage(MessageIn &msg)
{
Being *being = actorSpriteManager->findBeing(msg.readInt16());
- const auto direction = (BeingDirection) msg.readInt8();
- const int attackId = msg.readInt8();
+ if (!being)
+ return;
+
+ const int abilityId = msg.readInt8();
+ const int x = msg.readInt16();
+ const int y = msg.readInt16();
+
+ being->lookAt(Vector(x, y));
+
+ if (auto ability = AbilityDB::get(abilityId))
+ being->setAction(ability->useAction);
+}
+void BeingHandler::handleBeingAbilityBeingMessage(MessageIn &msg)
+{
+ Being *being = actorSpriteManager->findBeing(msg.readInt16());
if (!being)
return;
+ const int abilityId = msg.readInt8();
+ const int targetId = msg.readInt16();
+
+ if (Being *target = actorSpriteManager->findBeing(targetId))
+ being->lookAt(target->getPosition());
+
+ if (auto ability = AbilityDB::get(abilityId))
+ being->setAction(ability->useAction);
+}
+
+void BeingHandler::handleBeingAbilityDirectionMessage(MessageIn &msg)
+{
+ Being *being = actorSpriteManager->findBeing(msg.readInt16());
+ if (!being)
+ return;
+
+ const int abilityId = msg.readInt8();
+ const int direction = msg.readInt8();
+
being->setDirection(direction);
- being->setAction(Being::ATTACK, attackId);
+ if (auto ability = AbilityDB::get(abilityId))
+ being->setAction(ability->useAction);
}
void BeingHandler::handleBeingsDamageMessage(MessageIn &msg)
@@ -256,9 +345,7 @@ void BeingHandler::handleBeingsDamageMessage(MessageIn &msg)
Being *being = actorSpriteManager->findBeing(msg.readInt16());
int damage = msg.readInt16();
if (being)
- {
being->takeDamage(nullptr, damage, Being::HIT);
- }
}
}
@@ -306,14 +393,8 @@ void BeingHandler::handleBeingLooksChangeMessage(MessageIn &msg)
Being *being = actorSpriteManager->findBeing(msg.readInt16());
if (!being || being->getType() != ActorSprite::PLAYER)
return;
+
handleLooks(being, msg);
- if (msg.getUnreadLength())
- {
- int style = msg.readInt16();
- int color = msg.readInt16();
- being->setSprite(SPRITE_LAYER_HAIR, style * -1,
- hairDB.getHairColor(color));
- }
}
void BeingHandler::handleBeingDirChangeMessage(MessageIn &msg)
diff --git a/src/net/manaserv/beinghandler.h b/src/net/manaserv/beinghandler.h
index 63424de9..9580c284 100644
--- a/src/net/manaserv/beinghandler.h
+++ b/src/net/manaserv/beinghandler.h
@@ -19,8 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef NET_MANASERV_BEINGHANDLER_H
-#define NET_MANASERV_BEINGHANDLER_H
+#pragma once
#include "net/manaserv/messagehandler.h"
@@ -44,10 +43,13 @@ class BeingHandler final : public MessageHandler
void handleMessage(MessageIn &msg) override;
private:
- void handleBeingAttackMessage(MessageIn &msg);
void handleBeingEnterMessage(MessageIn &msg);
void handleBeingLeaveMessage(MessageIn &msg);
+ void handleBeingEmoteMessage(MessageIn &msg);
void handleBeingsMoveMessage(MessageIn &msg);
+ void handleBeingAbilityPointMessage(MessageIn &msg);
+ void handleBeingAbilityBeingMessage(MessageIn &msg);
+ void handleBeingAbilityDirectionMessage(MessageIn &msg);
void handleBeingsDamageMessage(MessageIn &msg);
void handleBeingActionChangeMessage(MessageIn &msg);
void handleBeingLooksChangeMessage(MessageIn &msg);
@@ -55,5 +57,3 @@ class BeingHandler final : public MessageHandler
};
} // namespace ManaServ
-
-#endif
diff --git a/src/net/manaserv/buysellhandler.h b/src/net/manaserv/buysellhandler.h
index 0629bd7b..c19090e1 100644
--- a/src/net/manaserv/buysellhandler.h
+++ b/src/net/manaserv/buysellhandler.h
@@ -19,8 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef NET_MANASERV_BUYSELLHANDLER_H
-#define NET_MANASERV_BUYSELLHANDLER_H
+#pragma once
#include "net/manaserv/messagehandler.h"
@@ -35,5 +34,3 @@ class BuySellHandler final : public MessageHandler
};
} // namespace ManaServ
-
-#endif
diff --git a/src/net/manaserv/charhandler.cpp b/src/net/manaserv/charhandler.cpp
index 8a922e70..98591669 100644
--- a/src/net/manaserv/charhandler.cpp
+++ b/src/net/manaserv/charhandler.cpp
@@ -44,6 +44,7 @@
#include "utils/dtor.h"
#include "utils/gettext.h"
+#include "utils/stringutils.h"
extern Net::CharHandler *charHandler;
extern ManaServ::GameHandler *gameHandler;
@@ -99,28 +100,44 @@ void CharHandler::handleMessage(MessageIn &msg)
void CharHandler::handleCharacterInfo(MessageIn &msg)
{
- CachedCharacterInfo info;
- info.slot = msg.readInt8();
- info.name = msg.readString();
- info.gender = msg.readInt8() == ManaServ::GENDER_MALE ? Gender::MALE
- : Gender::FEMALE;
- info.hairStyle = msg.readInt8();
- info.hairColor = msg.readInt8();
- info.level = msg.readInt16();
- info.characterPoints = msg.readInt16();
- info.correctionPoints = msg.readInt16();
-
while (msg.getUnreadLength() > 0)
{
- int id = msg.readInt32();
- CachedAttrbiute attr;
- attr.base = msg.readInt32() / 256.0;
- attr.mod = msg.readInt32() / 256.0;
+ CachedCharacterInfo &info = mCachedCharacterInfos.emplace_back();
- info.attribute[id] = attr;
- }
+ info.slot = msg.readInt8();
+ info.name = msg.readString();
+ switch (getGender(msg.readInt8())) {
+ case GENDER_MALE:
+ info.gender = Gender::Male;
+ break;
+ case GENDER_FEMALE:
+ info.gender = Gender::Female;
+ break;
+ case GENDER_UNSPECIFIED:
+ info.gender = Gender::Unspecified;
+ break;
+ }
+ info.hairStyle = msg.readInt8();
+ info.hairColor = msg.readInt8();
+ info.characterPoints = msg.readInt16();
+ info.correctionPoints = msg.readInt16();
- mCachedCharacterInfos.push_back(info);
+ int equipmentCount = msg.readInt8();
+ while (equipmentCount--)
+ {
+ auto &slot = info.equipment.emplace_back();
+ slot.id = msg.readInt16();
+ slot.itemId = msg.readInt16();
+ }
+
+ int attributeCount = msg.readInt8();
+ while (attributeCount--)
+ {
+ CachedAttribute &attr = info.attributes[msg.readInt32()];
+ attr.base = msg.readInt32() / 256.0;
+ attr.mod = msg.readInt32() / 256.0;
+ }
+ }
updateCharacters();
}
@@ -182,6 +199,8 @@ void CharHandler::handleCharacterCreateResponse(MessageIn &msg)
}
else
{
+ handleCharacterInfo(msg);
+
// Close the character create dialog
if (mCharCreateDialog)
{
@@ -380,10 +399,8 @@ void CharHandler::updateCharacters()
return;
// Create new characters and initialize them from the cached infos
- for (unsigned i = 0; i < mCachedCharacterInfos.size(); ++i)
+ for (const auto &info : mCachedCharacterInfos)
{
- const CachedCharacterInfo &info = mCachedCharacterInfos.at(i);
-
auto *character = new Net::Character;
character->slot = info.slot;
LocalPlayer *player = character->dummy = new LocalPlayer;
@@ -391,14 +408,30 @@ void CharHandler::updateCharacters()
player->setGender(info.gender);
player->setSprite(SPRITE_LAYER_HAIR, info.hairStyle * -1,
hairDB.getHairColor(info.hairColor));
- character->data.mAttributes[LEVEL] = info.level;
+
+ for (auto &slot : info.equipment)
+ {
+ player->setSprite(slot.id + FIXED_SPRITE_LAYER_SIZE,
+ slot.itemId,
+ std::string(),
+ Net::getInventoryHandler()->isWeaponSlot(slot.id));
+ }
+
character->data.mAttributes[CHAR_POINTS] = info.characterPoints;
character->data.mAttributes[CORR_POINTS] = info.correctionPoints;
- for (const auto &it : info.attribute)
+ for (const auto &[id, attr] : info.attributes)
{
- character->data.mStats[i].base = it.second.base;
- character->data.mStats[i].mod = it.second.mod;
+ int playerInfoId = Attributes::getPlayerInfoIdFromAttrId(id);
+ if (playerInfoId > -1)
+ {
+ character->data.mAttributes[playerInfoId] = attr.mod;
+ }
+ else
+ {
+ character->data.mStats[id].base = attr.base;
+ character->data.mStats[id].mod = attr.mod;
+ }
}
mCharacters.push_back(character);
diff --git a/src/net/manaserv/charhandler.h b/src/net/manaserv/charhandler.h
index 9ec5cdbb..e962bdfa 100644
--- a/src/net/manaserv/charhandler.h
+++ b/src/net/manaserv/charhandler.h
@@ -19,8 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef NET_MANASERV_CHARSERVERHANDLER_H
-#define NET_MANASERV_CHARSERVERHANDLER_H
+#pragma once
#include "gui/charselectdialog.h"
@@ -89,12 +88,15 @@ class CharHandler final : public MessageHandler, public Net::CharHandler
* we have loaded the dynamic data, so we can't resolve load any
* sprites yet.
*/
- struct CachedAttrbiute {
+ struct CachedAttribute {
double base;
double mod;
};
- using CachedAttributes = std::map<int, CachedAttrbiute>;
+ struct EquipmentSlot {
+ int id;
+ int itemId;
+ };
struct CachedCharacterInfo {
int slot;
@@ -102,10 +104,10 @@ class CharHandler final : public MessageHandler, public Net::CharHandler
Gender gender;
int hairStyle;
int hairColor;
- int level;
int characterPoints;
int correctionPoints;
- CachedAttributes attribute;
+ std::vector<EquipmentSlot> equipment;
+ std::map<int, CachedAttribute> attributes;
};
void handleCharacterInfo(MessageIn &msg);
@@ -120,5 +122,3 @@ class CharHandler final : public MessageHandler, public Net::CharHandler
};
} // namespace ManaServ
-
-#endif
diff --git a/src/net/manaserv/chathandler.h b/src/net/manaserv/chathandler.h
index f17883ae..6099fe93 100644
--- a/src/net/manaserv/chathandler.h
+++ b/src/net/manaserv/chathandler.h
@@ -19,8 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef NET_MANASERV_CHATHANDLER_H
-#define NET_MANASERV_CHATHANDLER_H
+#pragma once
#include "net/chathandler.h"
@@ -127,5 +126,3 @@ class ChatHandler final : public MessageHandler, public Net::ChatHandler
};
} // namespace ManaServ
-
-#endif
diff --git a/src/net/manaserv/connection.cpp b/src/net/manaserv/connection.cpp
index 896d86ad..1b6f757a 100644
--- a/src/net/manaserv/connection.cpp
+++ b/src/net/manaserv/connection.cpp
@@ -45,6 +45,8 @@ Connection::~Connection()
bool Connection::connect(const std::string &address, enet_uint16 port)
{
logger->log("Net::Connection::connect(%s, %i)", address.c_str(), port);
+ if (mConnection)
+ disconnect();
if (address.empty())
{
@@ -87,8 +89,7 @@ void Connection::disconnect()
bool Connection::isConnected()
{
- return (mConnection) ?
- (mConnection->state == ENET_PEER_STATE_CONNECTED) : false;
+ return mConnection && mConnection->state == ENET_PEER_STATE_CONNECTED;
}
void Connection::send(const ManaServ::MessageOut &msg)
diff --git a/src/net/manaserv/connection.h b/src/net/manaserv/connection.h
index dfd45e31..196d034b 100644
--- a/src/net/manaserv/connection.h
+++ b/src/net/manaserv/connection.h
@@ -19,8 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef NET_MANASERV_CONNECTION_H
-#define NET_MANASERV_CONNECTION_H
+#pragma once
#include <enet/enet.h>
#include "net/manaserv/network.h"
@@ -76,5 +75,3 @@ namespace ManaServ
State mState = OK;
};
}
-
-#endif // NET_MANASERV_CONNECTION_H
diff --git a/src/net/manaserv/defines.h b/src/net/manaserv/defines.h
index f1d12339..e224c045 100644
--- a/src/net/manaserv/defines.h
+++ b/src/net/manaserv/defines.h
@@ -19,8 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef MANASERV_DEFINES_H
-#define MANASERV_DEFINES_H
+#pragma once
/**
* Attributes used during combat. Available to all the beings.
@@ -72,5 +71,3 @@ enum
NB_CHARACTER_ATTRIBUTES = CHAR_ATTR_END
};
-
-#endif // MANASERV_DEFINES_H
diff --git a/src/net/manaserv/effecthandler.h b/src/net/manaserv/effecthandler.h
index 4ba711d7..9b4e7adf 100644
--- a/src/net/manaserv/effecthandler.h
+++ b/src/net/manaserv/effecthandler.h
@@ -19,8 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef NET_MANASERV_EFFECTSHANDLER_H
-#define NET_MANASERV_EFFECTSHANDLER_H
+#pragma once
#include "net/manaserv/messagehandler.h"
@@ -41,5 +40,3 @@ class EffectHandler final : public MessageHandler
};
} // namespace ManaServ
-
-#endif // NET_MANASERV_EFFECTSHANDLER_H
diff --git a/src/net/manaserv/gamehandler.cpp b/src/net/manaserv/gamehandler.cpp
index 1bf4d69f..3dae5640 100644
--- a/src/net/manaserv/gamehandler.cpp
+++ b/src/net/manaserv/gamehandler.cpp
@@ -44,6 +44,7 @@ extern ServerInfo chatServer;
GameHandler::GameHandler()
{
static const Uint16 _messages[] = {
+ GPMSG_CONNECT_RESPONSE,
GPMSG_DISCONNECT_RESPONSE,
0
};
@@ -55,6 +56,9 @@ void GameHandler::handleMessage(MessageIn &msg)
{
switch (msg.getId())
{
+ case GPMSG_CONNECT_RESPONSE:
+ break;
+
case GPMSG_DISCONNECT_RESPONSE:
{
int errMsg = msg.readInt8();
diff --git a/src/net/manaserv/gamehandler.h b/src/net/manaserv/gamehandler.h
index 019c2dfa..4db8a9ee 100644
--- a/src/net/manaserv/gamehandler.h
+++ b/src/net/manaserv/gamehandler.h
@@ -19,8 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef NET_MANASERV_MAPHANDLER_H
-#define NET_MANASERV_MAPHANDLER_H
+#pragma once
#include "net/gamehandler.h"
@@ -62,5 +61,3 @@ class GameHandler final : public MessageHandler, public Net::GameHandler
};
} // namespace ManaServ
-
-#endif // NET_MANASERV_MAPHANDLER_H
diff --git a/src/net/manaserv/generalhandler.cpp b/src/net/manaserv/generalhandler.cpp
index 0692ee82..32141c29 100644
--- a/src/net/manaserv/generalhandler.cpp
+++ b/src/net/manaserv/generalhandler.cpp
@@ -23,7 +23,6 @@
#include "client.h"
-#include "gui/inventorywindow.h"
#include "gui/skilldialog.h"
#include "net/manaserv/adminhandler.h"
@@ -42,13 +41,11 @@
#include "net/manaserv/npchandler.h"
#include "net/manaserv/partyhandler.h"
#include "net/manaserv/playerhandler.h"
-#include "net/manaserv/specialhandler.h"
+#include "net/manaserv/abilityhandler.h"
#include "net/manaserv/tradehandler.h"
#include "resources/attributes.h"
-extern Net::GeneralHandler *generalHandler;
-
extern ManaServ::LoginHandler *loginHandler;
namespace ManaServ {
@@ -76,7 +73,7 @@ GeneralHandler::GeneralHandler():
mPartyHandler(new PartyHandler),
mPlayerHandler(new PlayerHandler),
mTradeHandler(new TradeHandler),
- mSpecialHandler(new SpecialHandler)
+ mAbilityHandler(new AbilityHandler)
{
initialize();
@@ -84,8 +81,6 @@ GeneralHandler::GeneralHandler():
gameServerConnection = getConnection();
chatServerConnection = getConnection();
- generalHandler = this;
-
listen(Event::ClientChannel);
listen(Event::GameChannel);
}
@@ -129,18 +124,28 @@ void GeneralHandler::reload()
void GeneralHandler::unload()
{
- clearHandlers();
+ clearNetworkHandlers();
if (accountServerConnection)
+ {
accountServerConnection->disconnect();
+ delete accountServerConnection;
+ accountServerConnection = nullptr;
+ }
+
if (gameServerConnection)
+ {
gameServerConnection->disconnect();
+ delete gameServerConnection;
+ gameServerConnection = nullptr;
+ }
+
if (chatServerConnection)
+ {
chatServerConnection->disconnect();
-
- delete accountServerConnection;
- delete gameServerConnection;
- delete chatServerConnection;
+ delete chatServerConnection;
+ chatServerConnection = nullptr;
+ }
finalize();
}
@@ -157,11 +162,6 @@ void GeneralHandler::flushNetwork()
}
}
-void GeneralHandler::clearHandlers()
-{
- clearNetworkHandlers();
-}
-
void GeneralHandler::event(Event::Channel channel,
const Event &event)
{
@@ -182,7 +182,6 @@ void GeneralHandler::event(Event::Channel channel,
{
if (event.getType() == Event::GuiWindowsLoaded)
{
- inventoryWindow->setSplitAllowed(true);
skillDialog->loadSkills();
PlayerInfo::setAttribute(EXP_NEEDED, 100);
diff --git a/src/net/manaserv/generalhandler.h b/src/net/manaserv/generalhandler.h
index 582c1796..de0e3138 100644
--- a/src/net/manaserv/generalhandler.h
+++ b/src/net/manaserv/generalhandler.h
@@ -19,8 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef NET_MANASERV_GENERALHANDLER_H
-#define NET_MANASERV_GENERALHANDLER_H
+#pragma once
#include "eventlistener.h"
@@ -44,8 +43,6 @@ class GeneralHandler : public Net::GeneralHandler, public EventListener
void flushNetwork() override;
- void clearHandlers() override;
-
void event(Event::Channel channel, const Event &event) override;
protected:
@@ -64,9 +61,7 @@ class GeneralHandler : public Net::GeneralHandler, public EventListener
MessageHandlerPtr mPartyHandler;
MessageHandlerPtr mPlayerHandler;
MessageHandlerPtr mTradeHandler;
- MessageHandlerPtr mSpecialHandler;
+ MessageHandlerPtr mAbilityHandler;
};
} // namespace ManaServ
-
-#endif // NET_MANASERV_GENERALHANDLER_H
diff --git a/src/net/manaserv/guildhandler.h b/src/net/manaserv/guildhandler.h
index 666ae862..d7eb798c 100644
--- a/src/net/manaserv/guildhandler.h
+++ b/src/net/manaserv/guildhandler.h
@@ -19,8 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef NET_MANASERV_GUILDHANDLER_H
-#define NET_MANASERV_GUILDHANDLER_H
+#pragma once
#include "net/guildhandler.h"
@@ -67,5 +66,3 @@ protected:
};
} // namespace ManaServ
-
-#endif
diff --git a/src/net/manaserv/internal.h b/src/net/manaserv/internal.h
index 2961f4bb..701c9ee6 100644
--- a/src/net/manaserv/internal.h
+++ b/src/net/manaserv/internal.h
@@ -19,12 +19,9 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef NET_MANASERV_INTERNAL_H
-#define NET_MANASERV_INTERNAL_H
+#pragma once
namespace ManaServ
{
extern int connections;
}
-
-#endif
diff --git a/src/net/manaserv/inventoryhandler.cpp b/src/net/manaserv/inventoryhandler.cpp
index 9754beb0..58a495af 100644
--- a/src/net/manaserv/inventoryhandler.cpp
+++ b/src/net/manaserv/inventoryhandler.cpp
@@ -43,16 +43,6 @@ extern Net::InventoryHandler *inventoryHandler;
namespace ManaServ {
-struct EquipItemInfo
-{
-
- EquipItemInfo(int itemId, int slotTypeId, int amountUsed):
- mItemId(itemId), mSlotTypeId(slotTypeId), mAmountUsed(amountUsed)
- {}
-
- int mItemId, mSlotTypeId, mAmountUsed;
-};
-
extern Connection *gameServerConnection;
EquipBackend::EquipBackend()
@@ -61,15 +51,13 @@ EquipBackend::EquipBackend()
mVisibleSlots = 0;
}
-EquipBackend::~EquipBackend()
-{
- clear();
-}
-
Item *EquipBackend::getEquipment(int slotIndex) const
{
auto it = mSlots.find(slotIndex);
- return it == mSlots.end() ? nullptr : it->second.item;
+ if (it == mSlots.end())
+ return nullptr;
+
+ return PlayerInfo::getInventory()->getItem(it->second.inventorySlot);
}
std::string EquipBackend::getSlotName(int slotIndex) const
@@ -80,111 +68,55 @@ std::string EquipBackend::getSlotName(int slotIndex) const
void EquipBackend::triggerUnequip(int slotIndex) const
{
- // First get the itemInstance
- auto it = mSlots.find(slotIndex);
-
- if (it == mSlots.end() || it->second.itemInstance == 0 || !it->second.item)
+ auto item = getEquipment(slotIndex);
+ if (!item)
return;
Event event(Event::DoUnequip);
- event.setItem("item", it->second.item);
- event.setInt("itemInstance", it->second.itemInstance);
+ event.setItem("item", item);
event.trigger(Event::ItemChannel);
}
-
void EquipBackend::clear()
{
- for (auto &slot : mSlots)
- {
- if (slot.second.item)
- {
- delete slot.second.item;
- slot.second.item = nullptr;
- }
- }
- mSlots.clear();
+ for (auto &[_, slot] : mSlots)
+ slot.inventorySlot = -1;
}
-void EquipBackend::equip(int itemId, int slotTypeId, int amountUsed,
- int itemInstance)
+void EquipBackend::equip(int inventorySlot, int equipmentSlot)
{
- if (itemInstance <= 0)
- {
- logger->log("ManaServ::EquipBackend: Equipment slot %i"
- " has an invalid item instance.", slotTypeId);
- return;
- }
-
- auto it = mSlots.begin();
- auto it_end = mSlots.end();
- bool slotTypeFound = false;
- for (; it != it_end; ++it)
- if (it->second.slotTypeId == (unsigned)slotTypeId)
- slotTypeFound = true;
-
- if (!slotTypeFound)
+ auto slotIt = mSlots.find(equipmentSlot);
+ if (slotIt == mSlots.end())
{
logger->log("ManaServ::EquipBackend: Equipment slot %i"
- " is not existing.", slotTypeId);
+ " is not existing.",
+ equipmentSlot);
return;
}
- if (!itemDb->exists(itemId))
- {
- logger->log("ManaServ::EquipBackend: No item with id %d",
- itemId);
- return;
- }
+ slotIt->second.inventorySlot = inventorySlot;
- // Place the item in the slots with corresponding id until
- // the capacity requested has been reached
- for (it = mSlots.begin(); it != it_end && amountUsed > 0; ++it)
- {
- // If we're on the right slot type and that its unit
- // isn't already equipped, we can equip there.
- // The slots are already sorted by id, and subId anyway.
- if (it->second.slotTypeId == (unsigned)slotTypeId
- && (!it->second.itemInstance) && (!it->second.item))
- {
- it->second.itemInstance = itemInstance;
- it->second.item = new Item(itemId, 1, true);
- --amountUsed;
- }
- }
+ if (auto item = PlayerInfo::getInventory()->getItem(inventorySlot))
+ item->setEquipped(true);
}
-void EquipBackend::unequip(int itemInstance)
+void EquipBackend::unequip(int inventorySlot)
{
- auto it = mSlots.begin();
- auto it_end = mSlots.end();
- bool itemInstanceFound = false;
- for (; it != it_end; ++it)
- if (it->second.itemInstance == (unsigned)itemInstance)
- itemInstanceFound = true;
-
- if (!itemInstanceFound)
+ for (auto &[_, slot] : mSlots)
{
- logger->log("ManaServ::EquipBackend: Equipment item instance %i"
- " is not existing. The item couldn't be unequipped!",
- itemInstance);
- return;
- }
+ if (slot.inventorySlot == inventorySlot)
+ {
+ slot.inventorySlot = -1;
- for (it = mSlots.begin(); it != it_end; ++it)
- {
- if (it->second.itemInstance != (unsigned)itemInstance)
- continue;
+ if (auto item = PlayerInfo::getInventory()->getItem(inventorySlot))
+ item->setEquipped(false);
- // We remove the item
- it->second.itemInstance = 0;
- // We also delete the item objects
- if (it->second.item)
- {
- delete it->second.item;
- it->second.item = nullptr;
+ return;
}
}
+
+ logger->log("ManaServ::EquipBackend: No equipped item found at inventory "
+ "slot %i!", inventorySlot);
}
void EquipBackend::event(Event::Channel, const Event &event)
@@ -195,7 +127,7 @@ void EquipBackend::event(Event::Channel, const Event &event)
void EquipBackend::readEquipFile()
{
- clear();
+ mSlots.clear();
XML::Document doc(EQUIP_FILE);
XML::Node rootNode = doc.rootNode();
@@ -245,7 +177,7 @@ void EquipBackend::readEquipFile()
}
slot.subId = i;
- mSlots.insert(std::make_pair(slotIndex, slot));
+ mSlots.insert(std::make_pair(slotIndex, std::move(slot)));
++slotIndex;
}
}
@@ -262,14 +194,13 @@ void EquipBackend::readBoxNode(XML::Node slotNode)
if (boxNode.name() != "box")
continue;
- int x = boxNode.getProperty("x" , 0);
- int y = boxNode.getProperty("y" , 0);
+ const int x = boxNode.getProperty("x" , 0);
+ const int y = boxNode.getProperty("y" , 0);
- mBoxesPositions.push_back(Position(x, y));
+ mBoxPositions.emplace_back(x, y);
- std::string backgroundFile =
- boxNode.getProperty("background" , std::string());
- mBoxesBackgroundFile.push_back(backgroundFile);
+ const auto icon = boxNode.getProperty("icon", std::string());
+ mBoxIcons.push_back(icon);
}
}
@@ -295,15 +226,15 @@ bool EquipBackend::isAmmoSlot(int slotTypeId) const
Position EquipBackend::getBoxPosition(unsigned int slotIndex) const
{
- if (slotIndex < mBoxesPositions.size())
- return mBoxesPositions.at(slotIndex);
+ if (slotIndex < mBoxPositions.size())
+ return mBoxPositions.at(slotIndex);
return Position(0, 0);
}
-const std::string &EquipBackend::getBoxBackground(unsigned int slotIndex) const
+const std::string &EquipBackend::getBoxIcon(unsigned int slotIndex) const
{
- if (slotIndex < mBoxesBackgroundFile.size())
- return mBoxesBackgroundFile.at(slotIndex);
+ if (slotIndex < mBoxIcons.size())
+ return mBoxIcons.at(slotIndex);
return Net::empty;
}
@@ -313,6 +244,7 @@ InventoryHandler::InventoryHandler()
GPMSG_INVENTORY_FULL,
GPMSG_INVENTORY,
GPMSG_EQUIP,
+ GPMSG_UNEQUIP,
0
};
handledMessages = _messages;
@@ -331,87 +263,43 @@ void InventoryHandler::handleMessage(MessageIn &msg)
int count = msg.readInt16();
while (count--)
{
- int slot = msg.readInt16();
- int id = msg.readInt16();
- int amount = msg.readInt16();
- PlayerInfo::setInventoryItem(slot, id, amount);
+ const int slot = msg.readInt16();
+ const int itemId = msg.readInt16();
+ const int amount = msg.readInt16();
+ const int equipmentSlot = msg.readInt16();
+ PlayerInfo::setInventoryItem(slot, itemId, amount);
+
+ if (equipmentSlot > 0)
+ mEquipBackend.equip(slot, equipmentSlot);
}
- // A map of { item instance, {slot type id, item id, amount used}}
- std::map<int, EquipItemInfo> equipItemsInfo;
- std::map<int, EquipItemInfo>::iterator it;
- while (msg.getUnreadLength())
- {
- int slotTypeId = msg.readInt16();
- int itemId = msg.readInt16();
- int itemInstance = msg.readInt16();
-
- // Turn the data received into a usable format
- it = equipItemsInfo.find(itemInstance);
- if (it == equipItemsInfo.end())
- {
- // Add a new entry
- equipItemsInfo.insert(std::make_pair(itemInstance,
- EquipItemInfo(itemId, slotTypeId, 1)));
- }
- else
- {
- // Add amount to the existing entry
- it->second.mAmountUsed++;
- }
- }
-
- for (it = equipItemsInfo.begin(); it != equipItemsInfo.end();
- ++it)
- {
- mEquipBackend.equip(it->second.mItemId,
- it->second.mSlotTypeId,
- it->second.mAmountUsed,
- it->first);
- }
+ inventoryWindow->updateButtons();
}
break;
case GPMSG_INVENTORY:
while (msg.getUnreadLength())
{
- unsigned int slot = msg.readInt16();
- int id = msg.readInt16();
- unsigned int amount = id ? msg.readInt16() : 0;
+ const unsigned int slot = msg.readInt16();
+ const int id = msg.readInt16();
+ const unsigned int amount = id ? msg.readInt16() : 0;
PlayerInfo::setInventoryItem(slot, id, amount);
}
break;
case GPMSG_EQUIP:
{
- int itemId = msg.readInt16();
- int equipSlotCount = msg.readInt16();
-
- if (equipSlotCount <= 0)
- break;
-
- // Otherwise equip the item in the given slots
- while (equipSlotCount--)
- {
- unsigned int parameter = msg.readInt16();
- unsigned int amountUsed = msg.readInt16();
-
- if (amountUsed == 0)
- {
- // No amount means to unequip this item
- // Note that in that case, the parameter is
- // in fact the itemInstanceId
- mEquipBackend.unequip(parameter);
- }
- else
- {
- int itemInstance = msg.readInt16();
- // The parameter is in that case the slot type id.
- mEquipBackend.equip(itemId, parameter,
- amountUsed, itemInstance);
- }
- }
+ const int inventorySlot = msg.readInt16();
+ const int equipmentSlot = msg.readInt16();
+ mEquipBackend.equip(inventorySlot, equipmentSlot);
+ inventoryWindow->updateButtons();
+ }
+ case GPMSG_UNEQUIP:
+ {
+ const int inventorySlot = msg.readInt16();
+ mEquipBackend.unequip(inventorySlot);
+ inventoryWindow->updateButtons();
}
break;
}
@@ -423,9 +311,7 @@ void InventoryHandler::event(Event::Channel channel,
if (channel == Event::ItemChannel)
{
Item *item = event.getItem("item");
- int itemInstance = event.getInt("itemInstance", 0);
-
- if (!item && itemInstance == 0)
+ if (!item)
return;
int index = item->getInvIndex();
@@ -439,7 +325,7 @@ void InventoryHandler::event(Event::Channel channel,
else if (event.getType() == Event::DoUnequip)
{
MessageOut msg(PGMSG_UNEQUIP);
- msg.writeInt16(itemInstance);
+ msg.writeInt16(index);
gameServerConnection->send(msg);
}
else if (event.getType() == Event::DoUse)
@@ -457,53 +343,9 @@ void InventoryHandler::event(Event::Channel channel,
msg.writeInt16(amount);
gameServerConnection->send(msg);
}
- else if (event.getType() == Event::DoSplit)
- {
- int amount = event.getInt("amount", 1);
-
- int newIndex = PlayerInfo::getInventory()->getFreeSlot();
- if (newIndex > Inventory::NO_SLOT_INDEX)
- {
- MessageOut msg(PGMSG_MOVE_ITEM);
- msg.writeInt16(index);
- msg.writeInt16(newIndex);
- msg.writeInt16(amount);
- gameServerConnection->send(msg);
- }
- }
- else if (event.getType() == Event::DoMove)
- {
- int newIndex = event.getInt("newIndex", -1);
-
- if (newIndex >= 0)
- {
- if (index == newIndex)
- return;
-
- MessageOut msg(PGMSG_MOVE_ITEM);
- msg.writeInt16(index);
- msg.writeInt16(newIndex);
- msg.writeInt16(item->getQuantity());
- gameServerConnection->send(msg);
- }
- else
- {
- /*int source = event.getInt("source");
- int destination = event.getInt("destination");
- int amount = event.getInt("amount", 1);*/
-
- // TODO Support drag'n'drop to the map ground, or with other
- // windows.
- }
- }
}
}
-bool InventoryHandler::canSplit(const Item *item)
-{
- return item && item->getQuantity() > 1;
-}
-
size_t InventoryHandler::getSize(int type) const
{
switch (type)
diff --git a/src/net/manaserv/inventoryhandler.h b/src/net/manaserv/inventoryhandler.h
index e01bb5d8..b72922b3 100644
--- a/src/net/manaserv/inventoryhandler.h
+++ b/src/net/manaserv/inventoryhandler.h
@@ -19,8 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef NET_MANASERV_INVENTORYHANDLER_H
-#define NET_MANASERV_INVENTORYHANDLER_H
+#pragma once
#include "eventlistener.h"
@@ -28,6 +27,9 @@
#include "net/manaserv/messagehandler.h"
+#include "utils/xml.h"
+
+#include <map>
#include <vector>
namespace ManaServ {
@@ -37,15 +39,12 @@ class EquipBackend final : public Equipment::Backend, public EventListener
public:
EquipBackend();
- ~EquipBackend() override;
-
Item *getEquipment(int slotIndex) const override;
std::string getSlotName(int slotIndex) const override;
void clear() override;
- void equip(int itemId, int slotTypeId, int amountUsed = 1,
- int itemInstance = 0);
- void unequip(int slotTypeId);
+ void equip(int inventorySlot, int equipmentSlot);
+ void unequip(int inventorySlot);
void event(Event::Channel channel, const Event &event) override;
@@ -62,7 +61,7 @@ class EquipBackend final : public Equipment::Backend, public EventListener
Position getBoxPosition(unsigned int slotIndex) const;
- const std::string &getBoxBackground(unsigned int slotIndex) const;
+ const std::string &getBoxIcon(unsigned int slotIndex) const;
private:
void readEquipFile() override;
@@ -73,9 +72,7 @@ class EquipBackend final : public Equipment::Backend, public EventListener
// Generic info
std::string name;
- // The Item reference, used for graphical representation
- // and info.
- Item *item = nullptr;
+ int inventorySlot = 0;
// Manaserv specific info
@@ -89,10 +86,6 @@ class EquipBackend final : public Equipment::Backend, public EventListener
// This is used to sort the multimap along with the slot id.
unsigned int subId = 0;
- // This is the (per character) unique item Id, used especially when
- // equipping the same item multiple times on the same slot type.
- unsigned int itemInstance = 0;
-
// Tell whether the slot is a weapon slot
bool weaponSlot = false;
@@ -103,10 +96,9 @@ class EquipBackend final : public Equipment::Backend, public EventListener
unsigned int mVisibleSlots;
// slot client index, slot info
- using Slots = std::map<unsigned int, Slot>;
- Slots mSlots;
- std::vector<Position> mBoxesPositions;
- std::vector<std::string> mBoxesBackgroundFile;
+ std::map<unsigned int, Slot> mSlots;
+ std::vector<Position> mBoxPositions;
+ std::vector<std::string> mBoxIcons;
};
class InventoryHandler final : public MessageHandler, Net::InventoryHandler,
@@ -119,8 +111,6 @@ class InventoryHandler final : public MessageHandler, Net::InventoryHandler,
void event(Event::Channel channel, const Event &event) override;
- bool canSplit(const Item *item) override;
-
size_t getSize(int type) const override;
bool isWeaponSlot(unsigned int slotTypeId) const override
@@ -138,13 +128,11 @@ class InventoryHandler final : public MessageHandler, Net::InventoryHandler,
Position getBoxPosition(unsigned int slotIndex) const override
{ return mEquipBackend.getBoxPosition(slotIndex); }
- const std::string& getBoxBackground(unsigned int slotIndex) const override
- { return mEquipBackend.getBoxBackground(slotIndex); }
+ const std::string& getBoxIcon(unsigned int slotIndex) const override
+ { return mEquipBackend.getBoxIcon(slotIndex); }
private:
EquipBackend mEquipBackend;
};
} // namespace ManaServ
-
-#endif // NET_MANASERV_INVENTORYHANDLER_H
diff --git a/src/net/manaserv/itemhandler.cpp b/src/net/manaserv/itemhandler.cpp
index de5b36fa..870e7a9f 100644
--- a/src/net/manaserv/itemhandler.cpp
+++ b/src/net/manaserv/itemhandler.cpp
@@ -26,8 +26,6 @@
#include "net/manaserv/manaserv_protocol.h"
#include "net/manaserv/messagein.h"
-#include "log.h"
-
namespace ManaServ {
ItemHandler::ItemHandler()
diff --git a/src/net/manaserv/itemhandler.h b/src/net/manaserv/itemhandler.h
index 22adf8fb..c15d4638 100644
--- a/src/net/manaserv/itemhandler.h
+++ b/src/net/manaserv/itemhandler.h
@@ -19,8 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef NET_MANASERV_ITEMHANDLER_H
-#define NET_MANASERV_ITEMHANDLER_H
+#pragma once
#include "net/manaserv/messagehandler.h"
@@ -35,5 +34,3 @@ class ItemHandler final : public MessageHandler
};
} // namespace ManaServ
-
-#endif // NET_MANASERV_ITEMHANDLER_H
diff --git a/src/net/manaserv/loginhandler.cpp b/src/net/manaserv/loginhandler.cpp
index b9a56834..1c398990 100644
--- a/src/net/manaserv/loginhandler.cpp
+++ b/src/net/manaserv/loginhandler.cpp
@@ -399,8 +399,6 @@ void LoginHandler::loginAccount(LoginData *loginData)
mTmpPassword = loginData->password;
MessageOut msg(PAMSG_LOGIN_RNDTRGR);
- msg.writeString(mLoginData->username);
-
accountServerConnection->send(msg);
}
diff --git a/src/net/manaserv/loginhandler.h b/src/net/manaserv/loginhandler.h
index 87fbe9bc..e8d40835 100644
--- a/src/net/manaserv/loginhandler.h
+++ b/src/net/manaserv/loginhandler.h
@@ -19,8 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef NET_MANASERV_LOGINHANDLER_H
-#define NET_MANASERV_LOGINHANDLER_H
+#pragma once
#include "net/loginhandler.h"
@@ -91,5 +90,3 @@ class LoginHandler final : public MessageHandler, public Net::LoginHandler
};
} // namespace ManaServ
-
-#endif // NET_MANASERV_LOGINHANDLER_H
diff --git a/src/net/manaserv/manaserv_protocol.h b/src/net/manaserv/manaserv_protocol.h
index 760fe655..cb27d6f4 100644
--- a/src/net/manaserv/manaserv_protocol.h
+++ b/src/net/manaserv/manaserv_protocol.h
@@ -19,14 +19,14 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef MANASERV_PROTOCOL_H
-#define MANASERV_PROTOCOL_H
+#pragma once
namespace ManaServ {
enum {
- PROTOCOL_VERSION = 3,
- SUPPORTED_DB_VERSION = 21
+ PROTOCOL_VERSION = 9,
+ MIN_PROTOCOL_VERSION = 9,
+ SUPPORTED_DB_VERSION = 27
};
/**
@@ -69,19 +69,22 @@ enum {
PAMSG_REQUEST_REGISTER_INFO = 0x0005, //
APMSG_REGISTER_INFO_RESPONSE = 0x0006, // B byte registration Allowed, byte minNameLength, byte maxNameLength, string captchaURL, string captchaInstructions
PAMSG_LOGIN = 0x0010, // D version, S username, S password
- APMSG_LOGIN_RESPONSE = 0x0012, // B error, S updatehost, S Client data URL, B Character slots
+ APMSG_LOGIN_RESPONSE = 0x0012, // B error, S updatehost, S Client data URL, B Character slots, {content of APMSG_CHAR_CREATE_RESPONSE (without error code)}*
PAMSG_LOGOUT = 0x0013, // -
APMSG_LOGOUT_RESPONSE = 0x0014, // B error
- PAMSG_LOGIN_RNDTRGR = 0x0015, // S username
+ PAMSG_LOGIN_RNDTRGR = 0x0015, // -
APMSG_LOGIN_RNDTRGR_RESPONSE = 0x0016, // S random seed
+ PAMSG_STELLAR_LOGIN = 0x0017, // D version
+ APMSG_STELLAR_LOGIN_RESPONSE = 0x0018, // B error, S token, S url
PAMSG_CHAR_CREATE = 0x0020, // S name, B hair style, B hair color, B gender, B slot, {W stats}*
- APMSG_CHAR_CREATE_RESPONSE = 0x0021, // B error
+ APMSG_CHAR_CREATE_RESPONSE = 0x0021, // B error, on success: B slot, S name, B gender, B hair style, B hair color,
+ // W character points, W correction points, B amount of items equipped,
+ // { W slot, W itemId }*
+ // B attributeCount,
+ // {D attr id, D base value (in 1/256ths) D mod value (in 256ths) }*
PAMSG_CHAR_DELETE = 0x0022, // B slot
APMSG_CHAR_DELETE_RESPONSE = 0x0023, // B error
- // B slot, S name, B gender, B hair style, B hair color, W level,
- // W character points, W correction points,
- // {D attr id, D base value (in 1/256ths) D mod value (in 256ths) }*
- APMSG_CHAR_INFO = 0x0024, // ^
+ APMSG_CHAR_INFO = 0x0024, // {content of APMSG_CHAR_CREATE_RESPONSE (without error code)}*
PAMSG_CHAR_SELECT = 0x0026, // B slot
APMSG_CHAR_SELECT_RESPONSE = 0x0027, // B error, B*32 token, S game address, W game port, S chat address, W chat port
PAMSG_EMAIL_CHANGE = 0x0030, // S email
@@ -109,26 +112,28 @@ enum {
PGMSG_DROP = 0x0111, // W slot, W amount
PGMSG_EQUIP = 0x0112, // W inventory slot
PGMSG_UNEQUIP = 0x0113, // W item Instance id
- PGMSG_MOVE_ITEM = 0x0114, // W slot1, W slot2, W amount
GPMSG_INVENTORY = 0x0120, // { W slot, W item id [, W amount] (if item id is nonzero) }*
- GPMSG_INVENTORY_FULL = 0x0121, // W inventory slot count { W slot, W itemId, W amount }, { W equip slot, W item Id, W item Instance}*
- GPMSG_EQUIP = 0x0122, // W item Id, W equip slot type count //{ W equip slot, W capacity used}*//<- When equipping, //{ W item instance, W 0}*//<- When unequipping
+ GPMSG_INVENTORY_FULL = 0x0121, // W inventory slot count { W slot, W itemId, W amount, W equipmentSlot }
+ GPMSG_EQUIP = 0x0122, // W equipped inventory slot, W slot equipmentSlot
+ GPMSG_EQUIP_RESPONSE = 0x0123, // B error, W slot
+ GPMSG_UNEQUIP = 0x0124, // W equipped inventory slot
+ GPMSG_UNEQUIP_RESPONSE = 0x0125, // B error, W slot
GPMSG_PLAYER_ATTRIBUTE_CHANGE = 0x0130, // { W attribute, D base value (in 1/256ths), D modified value (in 1/256ths)}*
- GPMSG_PLAYER_EXP_CHANGE = 0x0140, // { W skill, D exp got, D exp needed, W skill level }*
- GPMSG_LEVELUP = 0x0150, // W new level, W character points, W correction points
- GPMSG_LEVEL_PROGRESS = 0x0151, // B percent completed to next levelup
+ GPMSG_ATTRIBUTE_POINTS_STATUS = 0x0140, // W character points, W correction points
PGMSG_RAISE_ATTRIBUTE = 0x0160, // W attribute
GPMSG_RAISE_ATTRIBUTE_RESPONSE = 0x0161, // B error, W attribute
PGMSG_LOWER_ATTRIBUTE = 0x0170, // W attribute
GPMSG_LOWER_ATTRIBUTE_RESPONSE = 0x0171, // B error, W attribute
PGMSG_RESPAWN = 0x0180, // -
GPMSG_BEING_ENTER = 0x0200, // B type, W being id, B action, W*2 position, B direction, B gender
- // character: S name, B hair style, B hair color, B sprite layers changed, { B slot type, W item id }*
+ // character: S name, B hair style, B hair color [, B sprite layers changed, { B slot type, W item id }*]
// monster: W type id
// npc: W type id
GPMSG_BEING_LEAVE = 0x0201, // W being id
GPMSG_ITEM_APPEAR = 0x0202, // W item id, W*2 position
- GPMSG_BEING_LOOKS_CHANGE = 0x0210, // B sprite layers changed, { B slot type, W item id }*
+ GPMSG_BEING_LOOKS_CHANGE = 0x0210, // B hairstyle, B haircolor [, B sprite layers changed, { B slot type, W item id }*]
+ GPMSG_BEING_EMOTE = 0x0211, // W being id, W emote id
+ PGMSG_BEING_EMOTE = 0x0212, // W emoticon id
PGMSG_WALK = 0x0260, // W*2 destination
PGMSG_ACTION_CHANGE = 0x0270, // B Action
GPMSG_BEING_ACTION_CHANGE = 0x0271, // W being id, B action
@@ -137,45 +142,50 @@ enum {
GPMSG_BEING_HEALTH_CHANGE = 0x0274, // W being id, W hp, W max hp
GPMSG_BEINGS_MOVE = 0x0280, // { W being id, B flags [, [W*2 position,] W*2 destination, B speed] }*
GPMSG_ITEMS = 0x0281, // { W item id, W*2 position }*
- PGMSG_ATTACK = 0x0290, // W being id
- GPMSG_BEING_ATTACK = 0x0291, // W being id, B direction, B attack Id
- PGMSG_USE_SPECIAL_ON_BEING = 0x0292, // B specialID, W being id
- GPMSG_SPECIAL_STATUS = 0x0293, // { B specialID, D current, D max, D recharge }
- PGMSG_USE_SPECIAL_ON_POINT = 0x0294, // B specialID, W*2 position
- PGMSG_SAY = 0x02A0, // S text
- GPMSG_SAY = 0x02A1, // W being id, S text
- GPMSG_NPC_CHOICE = 0x02B0, // W being id, { S text }*
- GPMSG_NPC_MESSAGE = 0x02B1, // W being id, B* text
- PGMSG_NPC_TALK = 0x02B2, // W being id
- PGMSG_NPC_TALK_NEXT = 0x02B3, // W being id
- PGMSG_NPC_SELECT = 0x02B4, // W being id, B choice
- GPMSG_NPC_BUY = 0x02B5, // W being id, { W item id, W amount, W cost }*
- GPMSG_NPC_SELL = 0x02B6, // W being id, { W item id, W amount, W cost }*
- PGMSG_NPC_BUYSELL = 0x02B7, // W item id, W amount
- GPMSG_NPC_ERROR = 0x02B8, // B error
- GPMSG_NPC_CLOSE = 0x02B9, // W being id
+ GPMSG_BEING_ABILITY_POINT = 0x0282, // W being id, B abilityId, W*2 point
+ GPMSG_BEING_ABILITY_BEING = 0x0283, // W being id, B abilityId, W target being id
+ GPMSG_BEING_ABILITY_DIRECTION = 0x0284, // W being id, B abilityId, B direction
+ PGMSG_USE_ABILITY_ON_BEING = 0x0290, // B abilityID, W being id
+ PGMSG_USE_ABILITY_ON_POINT = 0x0291, // B abilityID, W*2 position
+ PGMSG_USE_ABILITY_ON_DIRECTION = 0x0292, // B abilityID, B direction
+ GPMSG_ABILITY_STATUS = 0x02A0, // { B abilityID, D remainingTicks }
+ GPMSG_ABILITY_REMOVED = 0x02A1, // B abilityID
+ GPMSG_ABILITY_COOLDOWN = 0x02A2, // W ticks to wait
+ PGMSG_SAY = 0x02B0, // S text
+ GPMSG_SAY = 0x02B1, // W being id, S text
+ GPMSG_NPC_CHOICE = 0x02C0, // W being id, { S text }*
+ GPMSG_NPC_MESSAGE = 0x02C1, // W being id, B* text
+ PGMSG_NPC_TALK = 0x02C2, // W being id
+ PGMSG_NPC_TALK_NEXT = 0x02C3, // W being id
+ PGMSG_NPC_SELECT = 0x02C4, // W being id, B choice
+ GPMSG_NPC_BUY = 0x02C5, // W being id, { W item id, W amount, W cost }*
+ GPMSG_NPC_SELL = 0x02C6, // W being id, { W item id, W amount, W cost }*
+ PGMSG_NPC_BUYSELL = 0x02C7, // W item id, W amount
+ GPMSG_NPC_ERROR = 0x02C8, // B error
+ GPMSG_NPC_CLOSE = 0x02C9, // W being id
GPMSG_NPC_POST = 0x02D0, // W being id
PGMSG_NPC_POST_SEND = 0x02D1, // W being id, { S name, S text, W item id }
GPMSG_NPC_POST_GET = 0x02D2, // W being id, { S name, S text, W item id }
PGMSG_NPC_NUMBER = 0x02D3, // W being id, D number
PGMSG_NPC_STRING = 0x02D4, // W being id, S string
- GPMSG_NPC_NUMBER = 0x02D5, // W being id, D max, D min, D default
+ GPMSG_NPC_NUMBER = 0x02D5, // W being id, D min, D max, D default
GPMSG_NPC_STRING = 0x02D6, // W being id
- PGMSG_TRADE_REQUEST = 0x02C0, // W being id
- GPMSG_TRADE_REQUEST = 0x02C1, // W being id
- GPMSG_TRADE_START = 0x02C2, // -
- GPMSG_TRADE_COMPLETE = 0x02C3, // -
- PGMSG_TRADE_CANCEL = 0x02C4, // -
- GPMSG_TRADE_CANCEL = 0x02C5, // -
- PGMSG_TRADE_AGREED = 0x02C6, // -
- GPMSG_TRADE_AGREED = 0x02C7, // -
- PGMSG_TRADE_CONFIRM = 0x02C8, // -
- GPMSG_TRADE_CONFIRM = 0x02C9, // -
- PGMSG_TRADE_ADD_ITEM = 0x02CA, // B slot, B amount
- GPMSG_TRADE_ADD_ITEM = 0x02CB, // W item id, B amount
- PGMSG_TRADE_SET_MONEY = 0x02CC, // D amount
- GPMSG_TRADE_SET_MONEY = 0x02CD, // D amount
- GPMSG_TRADE_BOTH_CONFIRM = 0x02CE, // -
+ GPMSG_NPC_BUYSELL_RESPONSE = 0x02D7, // B error, W item id, W amount
+ PGMSG_TRADE_REQUEST = 0x02E0, // W being id
+ GPMSG_TRADE_REQUEST = 0x02E1, // W being id
+ GPMSG_TRADE_START = 0x02E2, // -
+ GPMSG_TRADE_COMPLETE = 0x02E3, // -
+ PGMSG_TRADE_CANCEL = 0x02E4, // -
+ GPMSG_TRADE_CANCEL = 0x02E5, // -
+ PGMSG_TRADE_AGREED = 0x02E6, // -
+ GPMSG_TRADE_AGREED = 0x02E7, // -
+ PGMSG_TRADE_CONFIRM = 0x02E8, // -
+ GPMSG_TRADE_CONFIRM = 0x02E9, // -
+ PGMSG_TRADE_ADD_ITEM = 0x02EA, // B slot, B amount
+ GPMSG_TRADE_ADD_ITEM = 0x02EB, // W item id, B amount
+ PGMSG_TRADE_SET_MONEY = 0x02EC, // D amount
+ GPMSG_TRADE_SET_MONEY = 0x02ED, // D amount
+ GPMSG_TRADE_BOTH_CONFIRM = 0x02EE, // -
PGMSG_USE_ITEM = 0x0300, // B slot
GPMSG_USE_RESPONSE = 0x0301, // B error
GPMSG_BEINGS_DAMAGE = 0x0310, // { W being id, W amount }*
@@ -243,8 +253,11 @@ enum {
PCMSG_USER_MODE = 0x0465, // W channel id, S name, B mode
PCMSG_KICK_USER = 0x0466, // W channel id, S name
+ // -- Questlog
+ GPMSG_QUESTLOG_STATUS = 0x0470, // {W quest id, B flags, [B status], [S questname], [S questdescription]}*
+
// Inter-server
- GAMSG_REGISTER = 0x0500, // S address, W port, S password, D items db revision, { W map id }*
+ GAMSG_REGISTER = 0x0500, // S address, W port, S password, D items db revision
AGMSG_REGISTER_RESPONSE = 0x0501, // W item version, W password response, { S globalvar_key, S globalvar_value }
AGMSG_ACTIVE_MAP = 0x0502, // W map id, W Number of mapvar_key mapvar_value sent, { S mapvar_key, S mapvar_value }, W Number of map items, { D item Id, W amount, W posX, W posY }
AGMSG_PLAYER_ENTER = 0x0510, // B*32 token, D id, S name, serialised character data
@@ -263,7 +276,6 @@ enum {
GAMSG_SET_VAR_WORLD = 0x0547, // S name, S value
AGMSG_SET_VAR_WORLD = 0x0548, // S name, S value
GAMSG_BAN_PLAYER = 0x0550, // D id, W duration
- GAMSG_CHANGE_PLAYER_LEVEL = 0x0555, // D id, W level
GAMSG_CHANGE_ACCOUNT_LEVEL = 0x0556, // D id, W level
GAMSG_STATISTICS = 0x0560, // { W map id, W entity nb, W monster nb, W player nb, { D character id }* }*
CGMSG_CHANGED_PARTY = 0x0590, // D character id, D party id
@@ -295,7 +307,8 @@ enum {
ERRMSG_TIME_OUT, // data failed to arrive in due time
ERRMSG_LIMIT_REACHED, // limit reached
ERRMSG_ADMINISTRATIVE_LOGOFF, // kicked by server administrator
- ERRMSG_ALREADY_MEMBER // is already member of guild/party
+ ERRMSG_ALREADY_MEMBER, // is already member of guild/party
+ ERRMSG_LOGIN_WAS_TAKEN_OVER // a different connection took over
};
// used in AGMSG_REGISTER_RESPONSE to show state of item db
@@ -314,7 +327,6 @@ enum {
enum {
SYNC_CHARACTER_POINTS = 0x01, // D charId, D charPoints, D corrPoints
SYNC_CHARACTER_ATTRIBUTE = 0x02, // D charId, D attrId, DF base, DF mod
- SYNC_CHARACTER_SKILL = 0x03, // D charId, B skillId, D skill value
SYNC_ONLINE_STATUS = 0x04 // D charId, B 0 = offline, 1 = online
};
@@ -358,21 +370,18 @@ enum AttribmodResponseCode {
enum EntityType
{
// A simple item.
- OBJECT_ITEM = 0,
- // An item that toggle map/quest actions (doors, switchs, ...)
- // and can speak (map panels).
- OBJECT_ACTOR,
+ OBJECT_ITEM = 0,
// Non-Playable-Character is an actor capable of movement and maybe actions.
- OBJECT_NPC,
+ OBJECT_NPC = 2,
// A monster (moving actor with AI. Should be able to toggle map/quest
// actions, too).
- OBJECT_MONSTER,
+ OBJECT_MONSTER = 3,
// A normal being.
- OBJECT_CHARACTER,
+ OBJECT_CHARACTER = 4,
// A effect to be shown.
- OBJECT_EFFECT,
+ OBJECT_EFFECT = 5,
// Server-only object.
- OBJECT_OTHER
+ OBJECT_OTHER = 6
};
// Moving object flags
@@ -406,6 +415,13 @@ enum {
GUILD_EVENT_OFFLINE_PLAYER
};
+enum {
+ QUESTLOG_UPDATE_STATE = 1,
+ QUESTLOG_UPDATE_TITLE = 2,
+ QUESTLOG_UPDATE_DESCRIPTION = 4,
+ QUESTLOG_SHOW_NOTIFICATION = 8
+};
+
/**
* Moves enum for beings and actors for others players vision.
* WARNING: Has to be in sync with the same enum in the Being class
@@ -415,27 +431,12 @@ enum BeingAction
{
STAND,
WALK,
- ATTACK,
SIT,
DEAD,
HURT
};
/**
- * Moves enum for beings and actors for others players attack types.
- * WARNING: Has to be in sync with the same enum in the Being class
- * of the client!
- */
-enum AttackType
-{
- HIT = 0x00,
- CRITICAL = 0x0a,
- MULTI = 0x08,
- REFLECT = 0x04,
- FLEE = 0x0b
-};
-
-/**
* Beings and actors directions
* WARNING: Has to be in sync with the same enum in the Being class
* of the client!
@@ -458,6 +459,55 @@ enum BeingGender
GENDER_UNSPECIFIED
};
+// Helper functions for gender
+
+/**
+* Helper function for getting gender by int
+*/
+inline ManaServ::BeingGender getGender(int gender)
+{
+ switch (gender)
+ {
+ case 0:
+ return ManaServ::GENDER_MALE;
+ case 1:
+ return ManaServ::GENDER_FEMALE;
+ default:
+ return ManaServ::GENDER_UNSPECIFIED;
+ }
+}
+
+/**
+ * Quest states
+ */
+enum QuestStatus
+{
+ STATUS_OPEN = 0,
+ STATUS_STARTED,
+ STATUS_FINISHED,
+ STATUS_INVALID
+};
+
+/**
+ * Helper function for getting quest status by id
+ * @param status id of the status
+ * @return the status as enum value
+ */
+inline ManaServ::QuestStatus getQuestStatus(int status)
+{
+ switch (status)
+ {
+ case 0:
+ return ManaServ::STATUS_OPEN;
+ case 1:
+ return ManaServ::STATUS_STARTED;
+ case 2:
+ return ManaServ::STATUS_FINISHED;
+ default:
+ return ManaServ::STATUS_INVALID;
+ }
+}
+
/** The permited range to pick up an item */
const int PICKUP_RANGE = 32 + 16;
@@ -465,5 +515,3 @@ const int PICKUP_RANGE = 32 + 16;
const int NPC_TALK_RANGE = 32 * 7;
} // namespace ManaServ
-
-#endif // MANASERV_PROTOCOL_H
diff --git a/src/net/manaserv/messagehandler.h b/src/net/manaserv/messagehandler.h
index f9ee09ab..2c68cde5 100644
--- a/src/net/manaserv/messagehandler.h
+++ b/src/net/manaserv/messagehandler.h
@@ -19,8 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef NET_MANASERV_MESSAGEHANDLER_H
-#define NET_MANASERV_MESSAGEHANDLER_H
+#pragma once
#include "net/messagehandler.h"
@@ -44,5 +43,3 @@ class MessageHandler : public Net::MessageHandler
using MessageHandlerPtr = const std::unique_ptr<MessageHandler>;
} // namespace ManaServ
-
-#endif // NET_MANASERV_MESSAGEHANDLER_H
diff --git a/src/net/manaserv/messagein.h b/src/net/manaserv/messagein.h
index 1edc4fe7..cd072fe0 100644
--- a/src/net/manaserv/messagein.h
+++ b/src/net/manaserv/messagein.h
@@ -19,8 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef NET_MANASERV_MESSAGEIN_H
-#define NET_MANASERV_MESSAGEIN_H
+#pragma once
#include "net/manaserv/manaserv_protocol.h"
@@ -95,5 +94,3 @@ class MessageIn
};
} // namespace ManaServ
-
-#endif // NET_MANASERV_MESSAGEIN_H
diff --git a/src/net/manaserv/messageout.h b/src/net/manaserv/messageout.h
index d452f784..d9d2e68a 100644
--- a/src/net/manaserv/messageout.h
+++ b/src/net/manaserv/messageout.h
@@ -19,8 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef NET_MANASERV_MESSAGEOUT_H
-#define NET_MANASERV_MESSAGEOUT_H
+#pragma once
#include "net/manaserv/manaserv_protocol.h"
@@ -91,5 +90,3 @@ class MessageOut
};
} // namespace ManaServ
-
-#endif // NET_MANASERV_MESSAGEOUT_H
diff --git a/src/net/manaserv/network.cpp b/src/net/manaserv/network.cpp
index b8d3fa93..d69d3397 100644
--- a/src/net/manaserv/network.cpp
+++ b/src/net/manaserv/network.cpp
@@ -88,17 +88,13 @@ Connection *getConnection()
void registerHandler(MessageHandler *handler)
{
for (const uint16_t *i = handler->handledMessages; *i; i++)
- {
mMessageHandlers[*i] = handler;
- }
}
void unregisterHandler(MessageHandler *handler)
{
for (const uint16_t *i = handler->handledMessages; *i; i++)
- {
mMessageHandlers.erase(*i);
- }
}
void clearNetworkHandlers()
diff --git a/src/net/manaserv/network.h b/src/net/manaserv/network.h
index f484d54d..a51a8168 100644
--- a/src/net/manaserv/network.h
+++ b/src/net/manaserv/network.h
@@ -19,8 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef NET_MANASERV_NETWORK_H
-#define NET_MANASERV_NETWORK_H
+#pragma once
#include <iosfwd>
@@ -71,5 +70,3 @@ namespace ManaServ
*/
void flush();
} // namespace ManaServ
-
-#endif
diff --git a/src/net/manaserv/npchandler.cpp b/src/net/manaserv/npchandler.cpp
index f19bf134..df139d23 100644
--- a/src/net/manaserv/npchandler.cpp
+++ b/src/net/manaserv/npchandler.cpp
@@ -47,6 +47,7 @@ NpcHandler::NpcHandler()
GPMSG_NPC_CLOSE,
GPMSG_NPC_NUMBER,
GPMSG_NPC_STRING,
+ GPMSG_NPC_BUYSELL_RESPONSE,
0
};
handledMessages = _messages;
@@ -100,7 +101,7 @@ void NpcHandler::handleMessage(MessageIn &msg)
break;
case GPMSG_NPC_ERROR:
- event = new Event(Event::End);
+ event = new Event(Event::CloseDialog);
event->setInt("id", npcId);
event->trigger(Event::NpcChannel);
break;
@@ -122,6 +123,9 @@ void NpcHandler::handleMessage(MessageIn &msg)
event->setInt("id", npcId);
event->trigger(Event::NpcChannel);
break;
+
+ case GPMSG_NPC_BUYSELL_RESPONSE:
+ break;
}
delete event;
diff --git a/src/net/manaserv/npchandler.h b/src/net/manaserv/npchandler.h
index ee3a9a12..6c485650 100644
--- a/src/net/manaserv/npchandler.h
+++ b/src/net/manaserv/npchandler.h
@@ -19,8 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef NET_MANASERV_NPCHANDLER_H
-#define NET_MANASERV_NPCHANDLER_H
+#pragma once
#include "net/npchandler.h"
@@ -65,5 +64,3 @@ class NpcHandler final : public MessageHandler, public Net::NpcHandler
};
} // namespace ManaServ
-
-#endif // NET_MANASERV_NPCHANDLER_H
diff --git a/src/net/manaserv/partyhandler.h b/src/net/manaserv/partyhandler.h
index ac4249a9..ab5aad9a 100644
--- a/src/net/manaserv/partyhandler.h
+++ b/src/net/manaserv/partyhandler.h
@@ -19,8 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef NET_MANASERV_PARTYHANDLER_H
-#define NET_MANASERV_PARTYHANDLER_H
+#pragma once
#include "net/partyhandler.h"
@@ -70,5 +69,3 @@ private:
};
} // namespace ManaServ
-
-#endif // NET_MANASERV_PARTYHANDLER_H
diff --git a/src/net/manaserv/playerhandler.cpp b/src/net/manaserv/playerhandler.cpp
index bf5694c6..8ee9ed80 100644
--- a/src/net/manaserv/playerhandler.cpp
+++ b/src/net/manaserv/playerhandler.cpp
@@ -29,17 +29,18 @@
#include "log.h"
#include "particle.h"
#include "playerinfo.h"
-#include "configuration.h"
#include "gui/viewport.h"
#include "net/net.h"
+#include "net/abilityhandler.h"
#include "net/manaserv/connection.h"
#include "net/manaserv/messagein.h"
#include "net/manaserv/messageout.h"
#include "net/manaserv/manaserv_protocol.h"
+#include "resources/abilitydb.h"
#include "resources/attributes.h"
/**
@@ -50,6 +51,7 @@
const int MAP_TELEPORT_SCROLL_DISTANCE = 256;
extern Net::PlayerHandler *playerHandler;
+extern Net::AbilityHandler *abilityHandler;
namespace ManaServ {
@@ -70,12 +72,11 @@ PlayerHandler::PlayerHandler()
GPMSG_PLAYER_MAP_CHANGE,
GPMSG_PLAYER_SERVER_CHANGE,
GPMSG_PLAYER_ATTRIBUTE_CHANGE,
- GPMSG_PLAYER_EXP_CHANGE,
- GPMSG_LEVELUP,
- GPMSG_LEVEL_PROGRESS,
+ GPMSG_ATTRIBUTE_POINTS_STATUS,
GPMSG_RAISE_ATTRIBUTE_RESPONSE,
GPMSG_LOWER_ATTRIBUTE_RESPONSE,
- GPMSG_SPECIAL_STATUS,
+ GPMSG_ABILITY_STATUS,
+ GPMSG_ABILITY_REMOVED,
0
};
handledMessages = _messages;
@@ -129,39 +130,10 @@ void PlayerHandler::handleMessage(MessageIn &msg)
}
} break;
- case GPMSG_PLAYER_EXP_CHANGE:
- {
- logger->log("EXP Update");
- while (msg.getUnreadLength())
- {
- int skill = msg.readInt16();
- int current = msg.readInt32();
- int next = msg.readInt32();
- int level = msg.readInt16();
-
- PlayerInfo::setStatExperience(skill, current, next);
- PlayerInfo::setStatBase(skill, level);
- }
- } break;
-
- case GPMSG_LEVELUP:
- {
- PlayerInfo::setAttribute(LEVEL, msg.readInt16());
+ case GPMSG_ATTRIBUTE_POINTS_STATUS:
PlayerInfo::setAttribute(CHAR_POINTS, msg.readInt16());
PlayerInfo::setAttribute(CORR_POINTS, msg.readInt16());
- Particle* effect = particleEngine->addEffect(
- paths.getStringValue("particles")
- + paths.getStringValue("levelUpEffectFile")
- ,0, 0);
- local_player->controlParticle(effect);
- } break;
-
-
- case GPMSG_LEVEL_PROGRESS:
- {
- PlayerInfo::setAttribute(EXP, msg.readInt8());
- } break;
-
+ break;
case GPMSG_RAISE_ATTRIBUTE_RESPONSE:
{
@@ -243,19 +215,24 @@ void PlayerHandler::handleMessage(MessageIn &msg)
} break;
- case GPMSG_SPECIAL_STATUS :
+ case GPMSG_ABILITY_STATUS:
{
- PlayerInfo::clearSpecialStatus();
while (msg.getUnreadLength())
{
- // { B specialID, L current, L max, L recharge }
int id = msg.readInt8();
int current = msg.readInt32();
int max = msg.readInt32();
int recharge = msg.readInt32();
- PlayerInfo::setSpecialStatus(id, current, max, recharge);
+ PlayerInfo::setAbilityStatus(id, current, max, recharge);
}
} break;
+
+ case GPMSG_ABILITY_REMOVED:
+ {
+ int id = msg.readInt8();
+ PlayerInfo::clearAbilityStatus(id);
+ } break;
+
/*
case SMSG_PLAYER_ARROW_MESSAGE:
{
@@ -315,14 +292,31 @@ void PlayerHandler::handleMapChangeMessage(MessageIn &msg)
void PlayerHandler::attack(int id)
{
- MessageOut msg(PGMSG_ATTACK);
- msg.writeInt16(id);
- gameServerConnection->send(msg);
+ auto ability = AbilityDB::find("Strike");
+ if (!ability)
+ {
+ logger->log("PlayerHandler::attack: 'Strike' ability not found.");
+ return;
+ }
+
+ switch (ability->targetMode) {
+ case AbilityInfo::TARGET_BEING:
+ abilityHandler->useOn(ability->id, id);
+ break;
+ case AbilityInfo::TARGET_POINT:
+ logger->log("PlayerHandler::attack: Unsupported target mode 'point' for 'Strike' ability.");
+ break;
+ case AbilityInfo::TARGET_DIRECTION:
+ abilityHandler->useInDirection(ability->id, local_player->getDirection());
+ break;
+ }
}
void PlayerHandler::emote(int emoteId)
{
- // TODO
+ MessageOut msg(PGMSG_BEING_EMOTE);
+ msg.writeInt8(emoteId);
+ gameServerConnection->send(msg);
}
void PlayerHandler::increaseAttribute(int attr)
diff --git a/src/net/manaserv/playerhandler.h b/src/net/manaserv/playerhandler.h
index a6839112..134b449c 100644
--- a/src/net/manaserv/playerhandler.h
+++ b/src/net/manaserv/playerhandler.h
@@ -19,8 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef NET_MANASERV_PLAYERHANDLER_H
-#define NET_MANASERV_PLAYERHANDLER_H
+#pragma once
#include "net/playerhandler.h"
@@ -77,5 +76,3 @@ class PlayerHandler final : public MessageHandler, public Net::PlayerHandler
};
} // namespace ManaServ
-
-#endif // NET_MANASERV_PLAYERHANDLER_H
diff --git a/src/net/manaserv/tradehandler.h b/src/net/manaserv/tradehandler.h
index 928a62d9..374dde16 100644
--- a/src/net/manaserv/tradehandler.h
+++ b/src/net/manaserv/tradehandler.h
@@ -19,8 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef NET_MANASERV_TRADEHANDLER_H
-#define NET_MANASERV_TRADEHANDLER_H
+#pragma once
#include "net/tradehandler.h"
@@ -72,5 +71,3 @@ class TradeHandler final : public MessageHandler, public Net::TradeHandler
};
} // namespace ManaServ
-
-#endif // NET_MANASERV_TRADEHANDLER_H
diff --git a/src/net/messagehandler.h b/src/net/messagehandler.h
index 3bf6c419..21973fa9 100644
--- a/src/net/messagehandler.h
+++ b/src/net/messagehandler.h
@@ -19,8 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef NET_MESSAGEHANDLER_H
-#define NET_MESSAGEHANDLER_H
+#pragma once
#include <cstdint>
@@ -32,11 +31,12 @@ namespace Net {
class MessageHandler
{
public:
- const uint16_t *handledMessages;
+ const uint16_t *handledMessages = _no_messages;
virtual ~MessageHandler() {}
+
+ private:
+ static constexpr uint16_t _no_messages[] = { 0 };
};
} // namespace Net
-
-#endif // NET_MESSAGEHANDLER_H
diff --git a/src/net/net.cpp b/src/net/net.cpp
index 3a389db2..1d157b3d 100644
--- a/src/net/net.cpp
+++ b/src/net/net.cpp
@@ -34,7 +34,7 @@
#include "net/npchandler.h"
#include "net/partyhandler.h"
#include "net/playerhandler.h"
-#include "net/specialhandler.h"
+#include "net/abilityhandler.h"
#include "net/tradehandler.h"
#include "net/tmwa/generalhandler.h"
@@ -54,7 +54,7 @@ Net::GuildHandler *guildHandler = nullptr;
Net::NpcHandler *npcHandler = nullptr;
Net::PartyHandler *partyHandler = nullptr;
Net::PlayerHandler *playerHandler = nullptr;
-Net::SpecialHandler *specialHandler = nullptr;
+Net::AbilityHandler *abilityHandler = nullptr;
Net::TradeHandler *tradeHandler = nullptr;
Net::AdminHandler *Net::getAdminHandler()
@@ -112,9 +112,9 @@ Net::PlayerHandler *Net::getPlayerHandler()
return playerHandler;
}
-Net::SpecialHandler *Net::getSpecialHandler()
+Net::AbilityHandler *Net::getAbilityHandler()
{
- return specialHandler;
+ return abilityHandler;
}
Net::TradeHandler *Net::getTradeHandler()
@@ -124,18 +124,19 @@ Net::TradeHandler *Net::getTradeHandler()
namespace Net
{
-ServerType networkType = ServerType::UNKNOWN;
+
+static ServerType networkType = ServerType::Unknown;
void connectToServer(ServerInfo &server)
{
- if (server.type == ServerType::UNKNOWN)
+ if (server.type == ServerType::Unknown)
{
// TODO: Query the server about itself and choose the netcode based on
// that
if (server.port == 6901)
- server.type = ServerType::TMWATHENA;
+ server.type = ServerType::TmwAthena;
else if (server.port == 9601)
- server.type = ServerType::MANASERV;
+ server.type = ServerType::ManaServ;
else
logger->error(_("Unknown Server Type! Exiting."));
}
@@ -146,20 +147,17 @@ void connectToServer(ServerInfo &server)
}
else
{
- if (networkType != ServerType::UNKNOWN && getGeneralHandler() != nullptr)
- {
- getGeneralHandler()->unload();
- }
+ unload();
switch (server.type)
{
#ifdef MANASERV_SUPPORT
- case ServerType::MANASERV:
- new ManaServ::GeneralHandler;
+ case ServerType::ManaServ:
+ generalHandler = new ManaServ::GeneralHandler;
break;
#endif
- case ServerType::TMWATHENA:
- new TmwAthena::GeneralHandler;
+ case ServerType::TmwAthena:
+ generalHandler = new TmwAthena::GeneralHandler;
break;
default:
logger->error(_("Server protocol unsupported"));
@@ -178,10 +176,25 @@ void connectToServer(ServerInfo &server)
void unload()
{
- if (GeneralHandler *handler = getGeneralHandler())
- {
- handler->unload();
- }
+ if (!generalHandler)
+ return;
+
+ generalHandler->unload();
+ delete generalHandler;
+
+ adminHandler = nullptr;
+ charHandler = nullptr;
+ chatHandler = nullptr;
+ generalHandler = nullptr;
+ inventoryHandler = nullptr;
+ loginHandler = nullptr;
+ gameHandler = nullptr;
+ guildHandler = nullptr;
+ npcHandler = nullptr;
+ partyHandler = nullptr;
+ playerHandler = nullptr;
+ abilityHandler = nullptr;
+ tradeHandler = nullptr;
}
ServerType getNetworkType()
diff --git a/src/net/net.h b/src/net/net.h
index 135f2cb7..ced0f7ba 100644
--- a/src/net/net.h
+++ b/src/net/net.h
@@ -19,8 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef NET_H
-#define NET_H
+#pragma once
/**
* \namespace Net
@@ -45,7 +44,7 @@ class LoginHandler;
class NpcHandler;
class PartyHandler;
class PlayerHandler;
-class SpecialHandler;
+class AbilityHandler;
class TradeHandler;
AdminHandler *getAdminHandler();
@@ -59,7 +58,7 @@ LoginHandler *getLoginHandler();
NpcHandler *getNpcHandler();
PartyHandler *getPartyHandler();
PlayerHandler *getPlayerHandler();
-SpecialHandler *getSpecialHandler();
+AbilityHandler *getAbilityHandler();
TradeHandler *getTradeHandler();
ServerType getNetworkType();
@@ -72,5 +71,3 @@ void connectToServer(ServerInfo &server);
void unload();
} // namespace Net
-
-#endif // NET_H
diff --git a/src/net/npchandler.h b/src/net/npchandler.h
index ac575605..7eeb54f1 100644
--- a/src/net/npchandler.h
+++ b/src/net/npchandler.h
@@ -19,8 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef NPCHANDLER_H
-#define NPCHANDLER_H
+#pragma once
#include <iosfwd>
@@ -61,5 +60,3 @@ class NpcHandler
};
} // namespace Net
-
-#endif // NPCHANDLER_H
diff --git a/src/net/partyhandler.h b/src/net/partyhandler.h
index 4e14ddbd..58871358 100644
--- a/src/net/partyhandler.h
+++ b/src/net/partyhandler.h
@@ -19,8 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef PARTYHANDLER_H
-#define PARTYHANDLER_H
+#pragma once
#include <string>
@@ -74,5 +73,3 @@ class PartyHandler
};
} // namespace Net
-
-#endif // PARTYHANDLER_H
diff --git a/src/net/playerhandler.h b/src/net/playerhandler.h
index 6187da2a..b9cf1abf 100644
--- a/src/net/playerhandler.h
+++ b/src/net/playerhandler.h
@@ -19,8 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef PLAYERHANDLER_H
-#define PLAYERHANDLER_H
+#pragma once
#include "being.h"
#include "flooritem.h"
@@ -84,5 +83,3 @@ class PlayerHandler
};
} // namespace Net
-
-#endif // PLAYERHANDLER_H
diff --git a/src/net/serverinfo.h b/src/net/serverinfo.h
index fd66c676..ad862427 100644
--- a/src/net/serverinfo.h
+++ b/src/net/serverinfo.h
@@ -19,10 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef SERVERINFO_H
-#define SERVERINFO_H
-
-#include "utils/stringutils.h"
+#pragma once
#include <cstdint>
#include <deque>
@@ -30,9 +27,9 @@
enum class ServerType
{
- UNKNOWN,
- MANASERV,
- TMWATHENA
+ Unknown,
+ ManaServ,
+ TmwAthena
};
class ServerInfo
@@ -40,7 +37,7 @@ class ServerInfo
public:
using VersionString = std::pair<int, std::string>;
- ServerType type = ServerType::UNKNOWN;
+ ServerType type = ServerType::Unknown;
std::string name;
std::string hostname;
uint16_t port = 0;
@@ -53,7 +50,7 @@ public:
bool isValid() const
{
- return !hostname.empty() && port != 0 && type != ServerType::UNKNOWN;
+ return !hostname.empty() && port != 0 && type != ServerType::Unknown;
}
void clear()
@@ -75,14 +72,14 @@ public:
static ServerType parseType(const std::string &type)
{
- if (compareStrI(type, "tmwathena") == 0)
- return ServerType::TMWATHENA;
+ if (type == "tmwathena")
+ return ServerType::TmwAthena;
// Used for backward compatibility
- if (compareStrI(type, "eathena") == 0)
- return ServerType::TMWATHENA;
- if (compareStrI(type, "manaserv") == 0)
- return ServerType::MANASERV;
- return ServerType::UNKNOWN;
+ if (type == "eathena")
+ return ServerType::TmwAthena;
+ if (type == "manaserv")
+ return ServerType::ManaServ;
+ return ServerType::Unknown;
}
static uint16_t defaultPortForServerType(ServerType type)
@@ -90,11 +87,11 @@ public:
switch (type)
{
default:
- case ServerType::UNKNOWN:
+ case ServerType::Unknown:
return 0;
- case ServerType::TMWATHENA:
+ case ServerType::TmwAthena:
return 6901;
- case ServerType::MANASERV:
+ case ServerType::ManaServ:
return 9601;
}
}
@@ -102,13 +99,11 @@ public:
static ServerType defaultServerTypeForPort(uint16_t port)
{
if (port == 6901)
- return ServerType::TMWATHENA;
+ return ServerType::TmwAthena;
if (port == 9601)
- return ServerType::MANASERV;
- return ServerType::UNKNOWN;
+ return ServerType::ManaServ;
+ return ServerType::Unknown;
}
};
using ServerInfos = std::deque<ServerInfo>;
-
-#endif // SERVERINFO_H
diff --git a/src/net/tmwa/specialhandler.cpp b/src/net/tmwa/abilityhandler.cpp
index 2e22b00a..ab891b40 100644
--- a/src/net/tmwa/specialhandler.cpp
+++ b/src/net/tmwa/abilityhandler.cpp
@@ -19,7 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "net/tmwa/specialhandler.h"
+#include "net/tmwa/abilityhandler.h"
#include "event.h"
#include "log.h"
@@ -64,11 +64,11 @@
/** should always be zero if failed */
#define SKILL_FAILED 0x00
-extern Net::SpecialHandler *specialHandler;
+extern Net::AbilityHandler *abilityHandler;
namespace TmwAthena {
-SpecialHandler::SpecialHandler()
+AbilityHandler::AbilityHandler()
{
static const Uint16 _messages[] = {
SMSG_PLAYER_SKILLS,
@@ -77,23 +77,20 @@ SpecialHandler::SpecialHandler()
0
};
handledMessages = _messages;
- specialHandler = this;
+ abilityHandler = this;
}
-void SpecialHandler::handleMessage(MessageIn &msg)
+void AbilityHandler::handleMessage(MessageIn &msg)
{
- int skillCount;
- int skillId;
-
switch (msg.getId())
{
- case SMSG_PLAYER_SKILLS:
+ case SMSG_PLAYER_SKILLS: {
msg.readInt16(); // length
- skillCount = (msg.getLength() - 4) / 37;
+ const int skillCount = (msg.getLength() - 4) / 37;
for (int k = 0; k < skillCount; k++)
{
- skillId = msg.readInt16();
+ int skillId = msg.readInt16();
msg.readInt16(); // target type
msg.skip(2); // unused
int level = msg.readInt16();
@@ -107,10 +104,11 @@ void SpecialHandler::handleMessage(MessageIn &msg)
skillDialog->setModifiable(skillId, up);
}
break;
+ }
case SMSG_PLAYER_SKILL_UP:
{
- skillId = msg.readInt16();
+ int skillId = msg.readInt16();
int level = msg.readInt16();
msg.readInt16(); // sp
msg.readInt16(); // range
@@ -124,20 +122,20 @@ void SpecialHandler::handleMessage(MessageIn &msg)
case SMSG_SKILL_FAILED:
// Action failed (ex. sit because you have not reached the
// right level)
- skillId = msg.readInt16();
- short bskill = msg.readInt16();
- msg.readInt16(); // unknown
- char success = msg.readInt8();
- char reason = msg.readInt8();
- if (success != SKILL_FAILED && bskill == BSKILL_EMOTE)
+ int skillId = msg.readInt16();
+ auto btype = msg.readInt16();
+ msg.readInt16(); // zero1
+ msg.readInt8(); // zero2
+ auto type = msg.readInt8();
+ if (btype == BSKILL_EMOTE)
{
- logger->log("Action: %d/%d", bskill, success);
+ logger->log("Action: %d", btype);
}
std::string msg;
- if (success == SKILL_FAILED && skillId == SKILL_BASIC)
+ if (skillId == SKILL_BASIC)
{
- switch (bskill)
+ switch (btype)
{
case BSKILL_TRADE:
msg = _("Trade failed!");
@@ -161,7 +159,7 @@ void SpecialHandler::handleMessage(MessageIn &msg)
msg += " ";
- switch (reason)
+ switch (type)
{
case RFAIL_SKILLDEP:
msg += _("You have not yet reached a high enough lvl!");
@@ -219,19 +217,19 @@ void SpecialHandler::handleMessage(MessageIn &msg)
}
}
-void SpecialHandler::use(int id)
+void AbilityHandler::use(int id)
{
}
-void SpecialHandler::use(int id, int level, int beingId)
+void AbilityHandler::useOn(int id, int beingId)
{
}
-void SpecialHandler::use(int id, int level, int x, int y)
+void AbilityHandler::useAt(int id, int x, int y)
{
}
-void SpecialHandler::use(int id, const std::string &map)
+void AbilityHandler::useInDirection(int id, int direction)
{
}
diff --git a/src/net/tmwa/specialhandler.h b/src/net/tmwa/abilityhandler.h
index 09b6ce8d..171f7d41 100644
--- a/src/net/tmwa/specialhandler.h
+++ b/src/net/tmwa/abilityhandler.h
@@ -19,32 +19,29 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef NET_TA_SKILLHANDLER_H
-#define NET_TA_SKILLHANDLER_H
+#pragma once
#include "net/net.h"
-#include "net/specialhandler.h"
+#include "net/abilityhandler.h"
#include "net/tmwa/messagehandler.h"
namespace TmwAthena {
-class SpecialHandler final : public MessageHandler, public Net::SpecialHandler
+class AbilityHandler final : public MessageHandler, public Net::AbilityHandler
{
public:
- SpecialHandler();
+ AbilityHandler();
void handleMessage(MessageIn &msg) override;
void use(int id) override;
- void use(int id, int level, int beingId) override;
+ void useOn(int id, int beingId) override;
- void use(int id, int level, int x, int y) override;
+ void useAt(int id, int x, int y) override;
- void use(int id, const std::string &map) override;
+ void useInDirection(int id, int direction) override;
};
} // namespace TmwAthena
-
-#endif // NET_TA_SKILLHANDLER_H
diff --git a/src/net/tmwa/adminhandler.cpp b/src/net/tmwa/adminhandler.cpp
index c60050bd..4c4ecdad 100644
--- a/src/net/tmwa/adminhandler.cpp
+++ b/src/net/tmwa/adminhandler.cpp
@@ -68,10 +68,7 @@ void AdminHandler::handleMessage(MessageIn &msg)
id = msg.readInt32();
int ip = msg.readInt32();
if (Being *player = actorSpriteManager->findBeing(id))
- {
player->setIp(ip);
- player->updateName();
- }
break;
}
}
diff --git a/src/net/tmwa/adminhandler.h b/src/net/tmwa/adminhandler.h
index 17d547a8..6a233823 100644
--- a/src/net/tmwa/adminhandler.h
+++ b/src/net/tmwa/adminhandler.h
@@ -19,8 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef NET_TA_ADMINHANDLER_H
-#define NET_TA_ADMINHANDLER_H
+#pragma once
#include "net/adminhandler.h"
#include "net/net.h"
@@ -44,5 +43,3 @@ class AdminHandler final : public MessageHandler, public Net::AdminHandler
};
} // namespace TmwAthena
-
-#endif // NET_TA_ADMINHANDLER_H
diff --git a/src/net/tmwa/beinghandler.cpp b/src/net/tmwa/beinghandler.cpp
index e2c4f158..c5979e9f 100644
--- a/src/net/tmwa/beinghandler.cpp
+++ b/src/net/tmwa/beinghandler.cpp
@@ -40,6 +40,7 @@
#include "resources/emotedb.h"
#include "resources/hairdb.h"
+#include "resources/statuseffectdb.h"
#include <cmath>
@@ -78,29 +79,51 @@ BeingHandler::BeingHandler(bool enableSync):
handledMessages = _messages;
}
-static Being *createBeing(int id, short job)
+static ActorSprite::Type typeFromJob(short job)
{
- ActorSprite::Type type = ActorSprite::UNKNOWN;
if (job <= 25 || (job >= 4001 && job <= 4049))
- type = ActorSprite::PLAYER;
- else if (job >= 46 && job <= 1000)
- type = ActorSprite::NPC;
- else if (job > 1000 && job <= 2000)
- type = ActorSprite::MONSTER;
- else if (job == 45)
+ return ActorSprite::PLAYER;
+ if (job >= 46 && job <= 1000)
+ return ActorSprite::NPC;
+ if (job > 1000 && job <= 2000)
+ return ActorSprite::MONSTER;
+ if (job == 45)
+ return ActorSprite::PORTAL;
+
+ return ActorSprite::UNKNOWN;
+}
+
+static Being *createBeing(int id, short job)
+{
+ const auto type = typeFromJob(job);
+ if (type == ActorSprite::PORTAL)
return nullptr; // Skip portals
Being *being = actorSpriteManager->createBeing(id, type, job);
if (type == ActorSprite::PLAYER || type == ActorSprite::NPC)
{
- MessageOut outMsg(0x0094);
- outMsg.writeInt32(id);//readLong(2));
+ MessageOut outMsg(CMSG_NAME_REQUEST);
+ outMsg.writeInt32(id);
}
return being;
}
+static void updateBeingType(Being *being, short job)
+{
+ const auto type = typeFromJob(job);
+ const bool typeChanged = being->getType() != type;
+
+ being->setType(type, job);
+
+ if (typeChanged && type == ActorSprite::PLAYER)
+ {
+ MessageOut outMsg(CMSG_NAME_REQUEST);
+ outMsg.writeInt32(being->getId());
+ }
+}
+
static void handleMoveMessage(Map *map, Being *dstBeing,
Uint16 srcX, Uint16 srcY,
Uint16 dstX, Uint16 dstY)
@@ -146,6 +169,42 @@ static void handlePosMessage(Map *map, Being *dstBeing, Uint16 x, Uint16 y,
}
}
+static void applyStatusEffectsByOption1(Being *being,
+ const StatusEffectDB::OptionsMap &map,
+ uint16_t option)
+{
+ for (auto &[opt, id] : map)
+ being->setStatusEffect(id, option == opt);
+}
+
+static void applyStatusEffectsByOption(Being *being,
+ const StatusEffectDB::OptionsMap &map,
+ uint16_t option)
+{
+ for (auto &[opt, id] : map)
+ {
+ const bool enabled = (option & opt) != 0;
+ being->setStatusEffect(id, enabled);
+ }
+}
+
+/**
+ * Maps flags or indexes to their corresponding status effect index and
+ * updates the state of the given being. This is tmwAthena-specific.
+ */
+static void applyStatusEffects(Being *being,
+ uint16_t opt0,
+ uint16_t opt1,
+ uint16_t opt2,
+ std::optional<uint16_t> opt3 = {})
+{
+ applyStatusEffectsByOption(being, StatusEffectDB::opt0ToIdMap(), opt0);
+ applyStatusEffectsByOption1(being, StatusEffectDB::opt1ToIdMap(), opt1);
+ applyStatusEffectsByOption(being, StatusEffectDB::opt2ToIdMap(), opt2);
+ if (opt3)
+ applyStatusEffectsByOption(being, StatusEffectDB::opt3ToIdMap(), *opt3);
+}
+
void BeingHandler::handleMessage(MessageIn &msg)
{
if (!actorSpriteManager)
@@ -159,8 +218,10 @@ void BeingHandler::handleMessage(MessageIn &msg)
Uint16 weapon, shield;
Uint16 gmstatus;
int param1;
- int stunMode;
- Uint32 statusEffects;
+ uint16_t opt0;
+ uint16_t opt1;
+ uint16_t opt2;
+ uint16_t opt3;
int type, guild;
Uint16 status;
Being *srcBeing, *dstBeing;
@@ -176,9 +237,9 @@ void BeingHandler::handleMessage(MessageIn &msg)
// Information about a being in range
id = msg.readInt32();
speed = (float)msg.readInt16();
- stunMode = msg.readInt16(); // opt1
- statusEffects = msg.readInt16(); // opt2
- statusEffects |= ((Uint32)msg.readInt16()) << 16; // option
+ opt1 = msg.readInt16();
+ opt2 = msg.readInt16();
+ opt0 = msg.readInt16();
job = msg.readInt16(); // class
dstBeing = actorSpriteManager->findBeing(id);
@@ -209,7 +270,7 @@ void BeingHandler::handleMessage(MessageIn &msg)
speed = 150.0f; // In ticks per tile * 10
dstBeing->setMoveSpeed(Vector(speed / 10, speed / 10));
- dstBeing->setSubtype(job);
+ updateBeingType(dstBeing, job);
hairStyle = msg.readInt16();
weapon = msg.readInt16();
headBottom = msg.readInt16();
@@ -236,14 +297,14 @@ void BeingHandler::handleMessage(MessageIn &msg)
}
msg.readInt16(); // guild emblem
msg.readInt16(); // manner
- dstBeing->setStatusEffectBlock(32, msg.readInt16()); // opt3
+ opt3 = msg.readInt16();
msg.readInt8(); // karma
gender = msg.readInt8();
if (dstBeing->getType() == ActorSprite::PLAYER)
{
- dstBeing->setGender(gender == 0 ? Gender::FEMALE
- : Gender::MALE);
+ dstBeing->setGender(gender == 0 ? Gender::Female
+ : Gender::Male);
// Set these after the gender, as the sprites may be gender-specific
dstBeing->setSprite(SPRITE_HAIR, hairStyle * -1,
hairDB.getHairColor(hairColor));
@@ -274,9 +335,7 @@ void BeingHandler::handleMessage(MessageIn &msg)
msg.readInt8(); // unknown
msg.readInt8(); // unknown / sit
- dstBeing->setStunMode(stunMode);
- dstBeing->setStatusEffectBlock(0, (statusEffects >> 16) & 0xffff);
- dstBeing->setStatusEffectBlock(16, statusEffects & 0xffff);
+ applyStatusEffects(dstBeing, opt0, opt1, opt2, opt3);
break;
case SMSG_BEING_SPAWN:
@@ -417,6 +476,9 @@ void BeingHandler::handleMessage(MessageIn &msg)
switch (type)
{
+ case LOOK::BASE:
+ updateBeingType(dstBeing, id);
+ break;
case LOOK::HAIR:
{
// const int look = id / 256;
@@ -505,10 +567,9 @@ void BeingHandler::handleMessage(MessageIn &msg)
// An update about a player, potentially including movement.
id = msg.readInt32();
speed = msg.readInt16();
- stunMode = msg.readInt16(); // opt1; Aethyra use this as cape
- statusEffects = msg.readInt16(); // opt2; Aethyra use this as misc1
- statusEffects |= ((Uint32) msg.readInt16())
- << 16; // status.options; Aethyra uses this as misc2
+ opt1 = msg.readInt16();
+ opt2 = msg.readInt16();
+ opt0 = msg.readInt16();
job = msg.readInt16();
dstBeing = actorSpriteManager->findBeing(id);
@@ -531,7 +592,7 @@ void BeingHandler::handleMessage(MessageIn &msg)
else
dstBeing->setMoveSpeed(Net::getPlayerHandler()->getDefaultMoveSpeed());
- dstBeing->setSubtype(job);
+ updateBeingType(dstBeing, job);
hairStyle = msg.readInt16();
weapon = msg.readInt16();
shield = msg.readInt16();
@@ -545,15 +606,16 @@ void BeingHandler::handleMessage(MessageIn &msg)
headTop = msg.readInt16();
headMid = msg.readInt16();
hairColor = msg.readInt16();
- shoes = msg.readInt16();
- gloves = msg.readInt16();
+ msg.readInt16(); // clothes_color
+ msg.readInt8(); // head_dir
+ msg.readInt8(); // unused2
msg.readInt32(); // guild
msg.readInt16(); // emblem
msg.readInt16(); // manner
- dstBeing->setStatusEffectBlock(32, msg.readInt16()); // opt3
+ opt3 = msg.readInt16();
msg.readInt8(); // karma
- dstBeing->setGender(msg.readInt8() == 0 ? Gender::FEMALE
- : Gender::MALE);
+ dstBeing->setGender(msg.readInt8() == 0 ? Gender::Female
+ : Gender::Male);
// Set these after the gender, as the sprites may be gender-specific
dstBeing->setSprite(SPRITE_WEAPON, weapon, "", true);
dstBeing->setSprite(SPRITE_SHIELD, shield);
@@ -601,15 +663,13 @@ void BeingHandler::handleMessage(MessageIn &msg)
}
else if (msg.getId() == SMSG_PLAYER_MOVE)
{
- msg.readInt8(); // unknown
+ msg.readInt8(); // five
}
msg.readInt8(); // Lv
- msg.readInt8(); // unknown
+ msg.readInt8(); // unused
- dstBeing->setStunMode(stunMode);
- dstBeing->setStatusEffectBlock(0, (statusEffects >> 16) & 0xffff);
- dstBeing->setStatusEffectBlock(16, statusEffects & 0xffff);
+ applyStatusEffects(dstBeing, opt0, opt1, opt2, opt3);
break;
case SMSG_PLAYER_STOP:
@@ -654,14 +714,12 @@ void BeingHandler::handleMessage(MessageIn &msg)
if (!dstBeing)
break;
- stunMode = msg.readInt16();
- statusEffects = msg.readInt16();
- statusEffects |= ((Uint32) msg.readInt16()) << 16;
- msg.readInt8(); // Unused?
+ opt1 = msg.readInt16();
+ opt2 = msg.readInt16();
+ opt0 = msg.readInt16();
+ msg.readInt8(); // zero
- dstBeing->setStunMode(stunMode);
- dstBeing->setStatusEffectBlock(0, (statusEffects >> 16) & 0xffff);
- dstBeing->setStatusEffectBlock(16, statusEffects & 0xffff);
+ applyStatusEffects(dstBeing, opt0, opt1, opt2);
break;
case SMSG_BEING_STATUS_CHANGE:
diff --git a/src/net/tmwa/beinghandler.h b/src/net/tmwa/beinghandler.h
index f1c8887f..fd8f08f5 100644
--- a/src/net/tmwa/beinghandler.h
+++ b/src/net/tmwa/beinghandler.h
@@ -19,8 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef NET_TA_BEINGHANDLER_H
-#define NET_TA_BEINGHANDLER_H
+#pragma once
#include "net/tmwa/messagehandler.h"
@@ -39,5 +38,3 @@ class BeingHandler final : public MessageHandler
};
} // namespace TmwAthena
-
-#endif // NET_TA_BEINGHANDLER_H
diff --git a/src/net/tmwa/buysellhandler.cpp b/src/net/tmwa/buysellhandler.cpp
index 1fdf1ffe..d7acd674 100644
--- a/src/net/tmwa/buysellhandler.cpp
+++ b/src/net/tmwa/buysellhandler.cpp
@@ -99,7 +99,7 @@ void BuySellHandler::handleMessage(MessageIn &msg)
Item *item = PlayerInfo::getInventory()->getItem(index);
- if (item && !(item->isEquipped()))
+ if (item && !item->isEquipped())
dialog->addItem(item, value);
}
}
diff --git a/src/net/tmwa/buysellhandler.h b/src/net/tmwa/buysellhandler.h
index 8f7a324f..cad9f943 100644
--- a/src/net/tmwa/buysellhandler.h
+++ b/src/net/tmwa/buysellhandler.h
@@ -19,8 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef NET_TA_BUYSELLHANDLER_H
-#define NET_TA_BUYSELLHANDLER_H
+#pragma once
#include "net/tmwa/messagehandler.h"
@@ -41,5 +40,3 @@ class BuySellHandler final : public MessageHandler
};
} // namespace TmwAthena
-
-#endif // NET_TA_BUYSELLHANDLER_H
diff --git a/src/net/tmwa/charserverhandler.cpp b/src/net/tmwa/charserverhandler.cpp
index 636b58ce..0ecbb135 100644
--- a/src/net/tmwa/charserverhandler.cpp
+++ b/src/net/tmwa/charserverhandler.cpp
@@ -28,7 +28,6 @@
#include "gui/charcreatedialog.h"
#include "gui/okdialog.h"
-#include "net/logindata.h"
#include "net/net.h"
#include "net/tmwa/gamehandler.h"
@@ -210,21 +209,20 @@ void CharServerHandler::readPlayerData(MessageIn &msg, Net::Character *character
const Token &token =
static_cast<LoginHandler*>(Net::getLoginHandler())->getToken();
- auto *tempPlayer = new LocalPlayer(msg.readInt32(), 0);
- tempPlayer->setGender(token.sex);
+ const int id = msg.readInt32();
character->data.mAttributes[EXP] = msg.readInt32();
character->data.mAttributes[MONEY] = msg.readInt32();
character->data.mStats[JOB].exp = msg.readInt32();
- int temp = msg.readInt32();
+ const int temp = msg.readInt32();
character->data.mStats[JOB].base = temp;
character->data.mStats[JOB].mod = temp;
- tempPlayer->setSprite(SPRITE_SHOE, msg.readInt16());
- tempPlayer->setSprite(SPRITE_GLOVES, msg.readInt16());
- tempPlayer->setSprite(SPRITE_CAPE, msg.readInt16());
- tempPlayer->setSprite(SPRITE_MISC1, msg.readInt16());
+ const int shoe = msg.readInt16();
+ const int gloves = msg.readInt16();
+ const int cape = msg.readInt16();
+ const int misc1 = msg.readInt16();
msg.readInt32(); // option
msg.readInt32(); // karma
@@ -240,8 +238,15 @@ void CharServerHandler::readPlayerData(MessageIn &msg, Net::Character *character
const uint16_t race = msg.readInt16(); // class (used for race)
int hairStyle = msg.readInt8();
msg.readInt8(); // look
- tempPlayer->setSubtype(race);
- Uint16 weapon = msg.readInt16();
+ const uint16_t weapon = msg.readInt16();
+
+ auto *tempPlayer = new LocalPlayer(id, race);
+ tempPlayer->setGender(token.sex);
+
+ tempPlayer->setSprite(SPRITE_SHOE, shoe);
+ tempPlayer->setSprite(SPRITE_GLOVES, gloves);
+ tempPlayer->setSprite(SPRITE_CAPE, cape);
+ tempPlayer->setSprite(SPRITE_MISC1, misc1);
tempPlayer->setSprite(SPRITE_WEAPON, weapon, "", true);
character->data.mAttributes[LEVEL] = msg.readInt16();
@@ -263,7 +268,7 @@ void CharServerHandler::readPlayerData(MessageIn &msg, Net::Character *character
character->slot = msg.readInt8(); // character slot
const uint8_t sex = msg.readInt8();
- tempPlayer->setGender(sex ? Gender::MALE : Gender::FEMALE);
+ tempPlayer->setGender(sex ? Gender::Male : Gender::Female);
}
void CharServerHandler::setCharSelectDialog(CharSelectDialog *window)
@@ -395,7 +400,7 @@ void CharServerHandler::connect()
// [Fate] The next word is unused by the old char server, so we squeeze in
// mana client version information
outMsg.writeInt16(CLIENT_PROTOCOL_VERSION);
- outMsg.writeInt8(token.sex == Gender::MALE ? 1 : 0);
+ outMsg.writeInt8(token.sex == Gender::Male ? 1 : 0);
// We get 4 useless bytes before the real answer comes in (what are these?)
mNetwork->skip(4);
diff --git a/src/net/tmwa/charserverhandler.h b/src/net/tmwa/charserverhandler.h
index 9633c8d9..b0d3e970 100644
--- a/src/net/tmwa/charserverhandler.h
+++ b/src/net/tmwa/charserverhandler.h
@@ -19,8 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef NET_TA_CHARSERVERHANDLER_H
-#define NET_TA_CHARSERVERHANDLER_H
+#pragma once
#include "net/charhandler.h"
@@ -75,9 +74,7 @@ class CharServerHandler final : public MessageHandler, public Net::CharHandler
void connect();
private:
- void readPlayerData(MessageIn &msg, Net::Character *character);
+ static void readPlayerData(MessageIn &msg, Net::Character *character);
};
} // namespace TmwAthena
-
-#endif // NET_TA_CHARSERVERHANDLER_H
diff --git a/src/net/tmwa/chathandler.cpp b/src/net/tmwa/chathandler.cpp
index 4f998922..cce5a41d 100644
--- a/src/net/tmwa/chathandler.cpp
+++ b/src/net/tmwa/chathandler.cpp
@@ -193,7 +193,10 @@ void ChatHandler::handleMessage(MessageIn &msg)
trim(chatMsg);
std::string reducedMessage = chatMsg;
- chatMsg = removeColors(sender_name) + " : " + reducedMessage;
+ chatMsg = sender_name;
+ removeColors(chatMsg);
+ chatMsg += " : ";
+ chatMsg += reducedMessage;
Event event(Event::Being);
event.setString("message", chatMsg);
@@ -271,7 +274,7 @@ void ChatHandler::handleMessage(MessageIn &msg)
msg.readInt8(); // gm level
msg.readInt8(); // gender
- Avatar *avatar = new Avatar(nick);
+ auto *avatar = new Avatar(nick);
avatar->setOnline(true);
players.push_back(avatar);
}
diff --git a/src/net/tmwa/chathandler.h b/src/net/tmwa/chathandler.h
index d545b221..b16b3dc4 100644
--- a/src/net/tmwa/chathandler.h
+++ b/src/net/tmwa/chathandler.h
@@ -19,8 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef NET_TA_CHATHANDLER_H
-#define NET_TA_CHATHANDLER_H
+#pragma once
#include "net/chathandler.h"
#include "net/net.h"
@@ -73,5 +72,3 @@ class ChatHandler final : public MessageHandler, public Net::ChatHandler
};
} // namespace TmwAthena
-
-#endif // NET_TA_CHATHANDLER_H
diff --git a/src/net/tmwa/gamehandler.cpp b/src/net/tmwa/gamehandler.cpp
index abc9c73c..0a3bb9d9 100644
--- a/src/net/tmwa/gamehandler.cpp
+++ b/src/net/tmwa/gamehandler.cpp
@@ -140,7 +140,7 @@ void GameHandler::connect()
outMsg.writeInt32(mCharID);
outMsg.writeInt32(token.session_ID1);
outMsg.writeInt32(token.session_ID2);
- outMsg.writeInt8(token.sex == Gender::MALE ? 1 : 0);
+ outMsg.writeInt8(token.sex == Gender::Male ? 1 : 0);
// We get 4 useless bytes before the real answer comes in (what are these?)
mNetwork->skip(4);
diff --git a/src/net/tmwa/gamehandler.h b/src/net/tmwa/gamehandler.h
index ecd8df2d..2f876b82 100644
--- a/src/net/tmwa/gamehandler.h
+++ b/src/net/tmwa/gamehandler.h
@@ -19,8 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef NET_TA_MAPHANDLER_H
-#define NET_TA_MAPHANDLER_H
+#pragma once
#include "eventlistener.h"
@@ -74,5 +73,3 @@ class GameHandler final : public MessageHandler, public Net::GameHandler,
};
} // namespace TmwAthena
-
-#endif // NET_TA_MAPHANDLER_H
diff --git a/src/net/tmwa/generalhandler.cpp b/src/net/tmwa/generalhandler.cpp
index e1b1a9ea..d6eb3b34 100644
--- a/src/net/tmwa/generalhandler.cpp
+++ b/src/net/tmwa/generalhandler.cpp
@@ -25,7 +25,6 @@
#include "configuration.h"
#include "log.h"
-#include "gui/inventorywindow.h"
#include "gui/skilldialog.h"
#include "gui/socialwindow.h"
#include "gui/statuswindow.h"
@@ -49,7 +48,7 @@
#include "net/tmwa/playerhandler.h"
#include "net/tmwa/protocol.h"
#include "net/tmwa/tradehandler.h"
-#include "net/tmwa/specialhandler.h"
+#include "net/tmwa/abilityhandler.h"
#include "net/tmwa/gui/guildtab.h"
#include "net/tmwa/gui/partytab.h"
@@ -60,8 +59,6 @@
#include <list>
-extern Net::GeneralHandler *generalHandler;
-
namespace TmwAthena {
ServerInfo charServer;
@@ -84,7 +81,7 @@ GeneralHandler::GeneralHandler():
mNpcHandler(new NpcHandler),
mPartyHandler(new PartyHandler),
mPlayerHandler(new PlayerHandler),
- mSpecialHandler(new SpecialHandler),
+ mAbilityHandler(new AbilityHandler),
mTradeHandler(new TradeHandler)
{
static const Uint16 _messages[] = {
@@ -92,7 +89,6 @@ GeneralHandler::GeneralHandler():
0
};
handledMessages = _messages;
- generalHandler = this;
std::list<ItemStat> stats;
stats.emplace_back("str", _("Strength %+d"));
@@ -155,6 +151,7 @@ void GeneralHandler::handleMessage(MessageIn &msg)
void GeneralHandler::load()
{
+ // This sets mNetwork to the created Network instance
(new Network)->registerHandler(this);
mNetwork->registerHandler(mAdminHandler.get());
@@ -169,7 +166,7 @@ void GeneralHandler::load()
mNetwork->registerHandler(mLoginHandler.get());
mNetwork->registerHandler(mNpcHandler.get());
mNetwork->registerHandler(mPlayerHandler.get());
- mNetwork->registerHandler(mSpecialHandler.get());
+ mNetwork->registerHandler(mAbilityHandler.get());
mNetwork->registerHandler(mTradeHandler.get());
mNetwork->registerHandler(mPartyHandler.get());
}
@@ -209,11 +206,6 @@ void GeneralHandler::flushNetwork()
}
}
-void GeneralHandler::clearHandlers()
-{
- mNetwork->clearHandlers();
-}
-
void GeneralHandler::event(Event::Channel channel,
const Event &event)
{
@@ -221,7 +213,6 @@ void GeneralHandler::event(Event::Channel channel,
{
if (event.getType() == Event::GuiWindowsLoaded)
{
- inventoryWindow->setSplitAllowed(false);
skillDialog->loadSkills();
statusWindow->addAttribute(STRENGTH, _("Strength"), true, "");
diff --git a/src/net/tmwa/generalhandler.h b/src/net/tmwa/generalhandler.h
index f105da96..1da81ba8 100644
--- a/src/net/tmwa/generalhandler.h
+++ b/src/net/tmwa/generalhandler.h
@@ -19,8 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef NET_TMWA_GENERALHANDLER_H
-#define NET_TMWA_GENERALHANDLER_H
+#pragma once
#include "eventlistener.h"
@@ -49,8 +48,6 @@ class GeneralHandler final : public MessageHandler, public Net::GeneralHandler,
void flushNetwork() override;
- void clearHandlers() override;
-
void event(Event::Channel channel, const Event &event) override;
protected:
@@ -67,10 +64,8 @@ class GeneralHandler final : public MessageHandler, public Net::GeneralHandler,
MessageHandlerPtr mNpcHandler;
MessageHandlerPtr mPartyHandler;
MessageHandlerPtr mPlayerHandler;
- MessageHandlerPtr mSpecialHandler;
+ MessageHandlerPtr mAbilityHandler;
MessageHandlerPtr mTradeHandler;
};
} // namespace TmwAthena
-
-#endif // NET_TMWA_GENERALHANDLER_H
diff --git a/src/net/tmwa/gui/guildtab.h b/src/net/tmwa/gui/guildtab.h
index 3f864748..c51e63d0 100644
--- a/src/net/tmwa/gui/guildtab.h
+++ b/src/net/tmwa/gui/guildtab.h
@@ -19,8 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef TA_GUILDTAB_H
-#define TA_GUILDTAB_H
+#pragma once
#include "gui/widgets/chattab.h"
@@ -49,5 +48,3 @@ class GuildTab : public ChatTab
extern GuildTab *guildTab;
} // namespace TmwAthena
-
-#endif // TA_GUILDTAB_H
diff --git a/src/net/tmwa/gui/partytab.cpp b/src/net/tmwa/gui/partytab.cpp
index 418e0843..ee29757a 100644
--- a/src/net/tmwa/gui/partytab.cpp
+++ b/src/net/tmwa/gui/partytab.cpp
@@ -32,14 +32,13 @@
#include "resources/theme.h"
#include "utils/gettext.h"
-#include "utils/stringutils.h"
namespace TmwAthena {
PartyTab::PartyTab() :
ChatTab(_("Party"))
{
- setTabColor(&Theme::getThemeColor(Theme::PARTY_CHAT_TAB));
+ setTabColor(&Theme::getThemeColor(Theme::PARTY_TAB));
}
void PartyTab::handleInput(const std::string &msg)
diff --git a/src/net/tmwa/gui/partytab.h b/src/net/tmwa/gui/partytab.h
index a6c52f58..39a1f978 100644
--- a/src/net/tmwa/gui/partytab.h
+++ b/src/net/tmwa/gui/partytab.h
@@ -19,8 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef TA_PARTYTAB_H
-#define TA_PARTYTAB_H
+#pragma once
#include "gui/widgets/chattab.h"
@@ -49,5 +48,3 @@ class PartyTab : public ChatTab
extern PartyTab *partyTab;
} // namespace TmwAthena
-
-#endif // TA_PARTYTAB_H
diff --git a/src/net/tmwa/guildhandler.cpp b/src/net/tmwa/guildhandler.cpp
index 1877f0f1..e8ee4848 100644
--- a/src/net/tmwa/guildhandler.cpp
+++ b/src/net/tmwa/guildhandler.cpp
@@ -40,11 +40,6 @@ Guild *taGuild;
GuildHandler::GuildHandler()
{
- static const Uint16 _messages[] = {
- 0
- };
- handledMessages = _messages;
-
guildHandler = this;
}
diff --git a/src/net/tmwa/guildhandler.h b/src/net/tmwa/guildhandler.h
index 9bbe9b4a..6faca0cc 100644
--- a/src/net/tmwa/guildhandler.h
+++ b/src/net/tmwa/guildhandler.h
@@ -18,8 +18,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef NET_TA_GUILDHANDLER_H
-#define NET_TA_GUILDHANDLER_H
+#pragma once
#include "net/guildhandler.h"
@@ -67,5 +66,3 @@ class GuildHandler final : public Net::GuildHandler, public MessageHandler
};
}
-
-#endif // NET_TA_GUILDHANDLER_H
diff --git a/src/net/tmwa/inventoryhandler.cpp b/src/net/tmwa/inventoryhandler.cpp
index 496ce621..0d8e3005 100644
--- a/src/net/tmwa/inventoryhandler.cpp
+++ b/src/net/tmwa/inventoryhandler.cpp
@@ -521,11 +521,6 @@ void InventoryHandler::event(Event::Channel channel,
}
}
-bool InventoryHandler::canSplit(const Item *item)
-{
- return false;
-}
-
size_t InventoryHandler::getSize(int type) const
{
switch (type)
diff --git a/src/net/tmwa/inventoryhandler.h b/src/net/tmwa/inventoryhandler.h
index 51a0fe51..f5ef4492 100644
--- a/src/net/tmwa/inventoryhandler.h
+++ b/src/net/tmwa/inventoryhandler.h
@@ -19,11 +19,11 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef NET_TA_INVENTORYHANDLER_H
-#define NET_TA_INVENTORYHANDLER_H
+#pragma once
#include "eventlistener.h"
#include "inventory.h"
+#include "item.h"
#include "log.h"
#include "playerinfo.h"
@@ -38,7 +38,7 @@
#include "utils/gettext.h"
-#include <list>
+#include <vector>
namespace TmwAthena {
@@ -166,8 +166,6 @@ class InventoryHandler final : public MessageHandler, public Net::InventoryHandl
void event(Event::Channel channel, const Event &event) override;
- bool canSplit(const Item *item) override;
-
size_t getSize(int type) const override;
// Note the slot type id is equal to the slot Index for tA.
@@ -195,5 +193,3 @@ class InventoryHandler final : public MessageHandler, public Net::InventoryHandl
};
} // namespace TmwAthena
-
-#endif // NET_TA_INVENTORYHANDLER_H
diff --git a/src/net/tmwa/itemhandler.h b/src/net/tmwa/itemhandler.h
index 0c6175d8..5e42e0d8 100644
--- a/src/net/tmwa/itemhandler.h
+++ b/src/net/tmwa/itemhandler.h
@@ -19,8 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef NET_TA_ITEMHANDLER_H
-#define NET_TA_ITEMHANDLER_H
+#pragma once
#include "net/tmwa/messagehandler.h"
@@ -35,5 +34,3 @@ class ItemHandler final : public MessageHandler
};
} // namespace TmwAthena
-
-#endif // NET_TA_ITEMHANDLER_H
diff --git a/src/net/tmwa/loginhandler.cpp b/src/net/tmwa/loginhandler.cpp
index 24bc9ab2..a7162ee6 100644
--- a/src/net/tmwa/loginhandler.cpp
+++ b/src/net/tmwa/loginhandler.cpp
@@ -103,17 +103,15 @@ void LoginHandler::handleMessage(MessageIn &msg)
}
break;
- case SMSG_UPDATE_HOST:
- int len;
-
- len = msg.readInt16() - 4;
+ case SMSG_UPDATE_HOST: {
+ int len = msg.readInt16() - 4;
mUpdateHost = msg.readString(len);
loginData.updateHost = mUpdateHost;
logger->log("Received update host \"%s\" from login server.",
mUpdateHost.c_str());
break;
-
+ }
case SMSG_LOGIN_DATA:
// Skip the length word
msg.skip(2);
@@ -126,7 +124,7 @@ void LoginHandler::handleMessage(MessageIn &msg)
mToken.account_ID = msg.readInt32();
mToken.session_ID2 = msg.readInt32();
msg.skip(30); // unused
- mToken.sex = msg.readInt8() ? Gender::MALE : Gender::FEMALE;
+ mToken.sex = msg.readInt8() ? Gender::Male : Gender::Female;
for (int i = 0; i < worldCount; i++)
{
@@ -306,7 +304,7 @@ void LoginHandler::chooseServer(unsigned int server)
void LoginHandler::registerAccount(LoginData *loginData)
{
std::string username = loginData->username;
- username.append(loginData->gender == Gender::FEMALE ? "_F" : "_M");
+ username.append(loginData->gender == Gender::Female ? "_F" : "_M");
sendLoginRegister(username, loginData->password);
}
diff --git a/src/net/tmwa/loginhandler.h b/src/net/tmwa/loginhandler.h
index 25dd414d..f6b8a530 100644
--- a/src/net/tmwa/loginhandler.h
+++ b/src/net/tmwa/loginhandler.h
@@ -19,8 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef NET_TMWA_LOGINHANDLER_H
-#define NET_TMWA_LOGINHANDLER_H
+#pragma once
#include "net/loginhandler.h"
@@ -94,5 +93,3 @@ class LoginHandler final : public MessageHandler, public Net::LoginHandler
};
} // namespace TmwAthena
-
-#endif // NET_TA_LOGINHANDLER_H
diff --git a/src/net/tmwa/messagehandler.h b/src/net/tmwa/messagehandler.h
index 0d278c15..8e3c6a19 100644
--- a/src/net/tmwa/messagehandler.h
+++ b/src/net/tmwa/messagehandler.h
@@ -19,8 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef NET_TA_MESSAGEHANDLER_H
-#define NET_TA_MESSAGEHANDLER_H
+#pragma once
#include "net/messagehandler.h"
@@ -52,5 +51,3 @@ class MessageHandler : public Net::MessageHandler
using MessageHandlerPtr = const std::unique_ptr<MessageHandler>;
}
-
-#endif // NET_TA_MESSAGEHANDLER_H
diff --git a/src/net/tmwa/messagein.cpp b/src/net/tmwa/messagein.cpp
index 7c142619..c0db0fca 100644
--- a/src/net/tmwa/messagein.cpp
+++ b/src/net/tmwa/messagein.cpp
@@ -21,6 +21,9 @@
#include "net/tmwa/messagein.h"
+#include "being.h"
+#include "net/tmwa/protocol.h"
+
#include <SDL_endian.h>
#define MAKEWORD(low,high) \
@@ -88,38 +91,20 @@ void MessageIn::readCoordinates(uint16_t &x, uint16_t &y, uint8_t &direction)
direction = data[2] & 0x000f;
// Translate from tmwAthena format
- switch (direction)
+ switch (static_cast<DIR>(direction))
{
- case 0:
- direction = 1;
- break;
- case 1:
- direction = 3;
- break;
- case 2:
- direction = 2;
- break;
- case 3:
- direction = 6;
- break;
- case 4:
- direction = 4;
- break;
- case 5:
- direction = 12;
- break;
- case 6:
- direction = 8;
- break;
- case 7:
- direction = 9;
- break;
- case 8:
- direction = 8;
- break;
+ case DIR::S: direction = Being::DOWN; break;
+ case DIR::SW: direction = Being::DOWN | Being::LEFT; break;
+ case DIR::W: direction = Being::LEFT; break;
+ case DIR::NW: direction = Being::UP | Being::LEFT; break;
+ case DIR::N: direction = Being::UP; break;
+ case DIR::NE: direction = Being::UP | Being::RIGHT; break;
+ case DIR::E: direction = Being::RIGHT; break;
+ case DIR::SE: direction = Being::DOWN | Being::RIGHT; break;
default:
// OOPSIE! Impossible or unknown
direction = 0;
+ break;
}
}
mPos += 3;
@@ -162,7 +147,7 @@ std::string MessageIn::readString(int length)
if (length < 0 || mPos + length > mLength)
{
mPos = mLength + 1;
- return "";
+ return std::string();
}
// Read the string
diff --git a/src/net/tmwa/messagein.h b/src/net/tmwa/messagein.h
index 2f66ca28..b2fb6716 100644
--- a/src/net/tmwa/messagein.h
+++ b/src/net/tmwa/messagein.h
@@ -19,8 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef NET_TA_MESSAGEIN_H
-#define NET_TA_MESSAGEIN_H
+#pragma once
#include <cstdint>
#include <string>
@@ -109,5 +108,3 @@ class MessageIn
};
} // TmwAthena
-
-#endif // NET_TA_MESSAGEIN_H
diff --git a/src/net/tmwa/messageout.cpp b/src/net/tmwa/messageout.cpp
index 12c9419a..a886fb4d 100644
--- a/src/net/tmwa/messageout.cpp
+++ b/src/net/tmwa/messageout.cpp
@@ -31,6 +31,9 @@ namespace TmwAthena {
MessageOut::MessageOut(uint16_t id)
{
+#ifdef DEBUG
+ logger->log("Sending %s (0x%x)", Network::mInstance->messageName(id), id);
+#endif
writeInt16(id);
}
diff --git a/src/net/tmwa/messageout.h b/src/net/tmwa/messageout.h
index b60644de..ba2d3c75 100644
--- a/src/net/tmwa/messageout.h
+++ b/src/net/tmwa/messageout.h
@@ -19,8 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef NET_TA_MESSAGEOUT_H
-#define NET_TA_MESSAGEOUT_H
+#pragma once
#include <cstdint>
#include <string>
@@ -73,5 +72,3 @@ class MessageOut
};
} // namespace TmwAthena
-
-#endif // NET_TA_MESSAGEOUT_H
diff --git a/src/net/tmwa/network.cpp b/src/net/tmwa/network.cpp
index 5a2dd0d0..b448dc4f 100644
--- a/src/net/tmwa/network.cpp
+++ b/src/net/tmwa/network.cpp
@@ -45,9 +45,9 @@ struct PacketInfo
};
// indicator for a variable-length packet
-const uint16_t VAR = 1;
+constexpr uint16_t VAR = 1;
-static const PacketInfo packet_infos[] = {
+static constexpr PacketInfo packet_infos[] = {
// login server messages
{ SMSG_UPDATE_HOST, VAR, "SMSG_UPDATE_HOST" },
{ CMSG_LOGIN_REGISTER, 55, "CMSG_LOGIN_REGISTER" },
@@ -331,20 +331,16 @@ void Network::disconnect()
void Network::registerHandler(MessageHandler *handler)
{
- for (const Uint16 *i = handler->handledMessages; *i; ++i)
- {
+ for (const uint16_t *i = handler->handledMessages; *i; ++i)
mMessageHandlers[*i] = handler;
- }
handler->setNetwork(this);
}
void Network::unregisterHandler(MessageHandler *handler)
{
- for (const Uint16 *i = handler->handledMessages; *i; ++i)
- {
+ for (const uint16_t *i = handler->handledMessages; *i; ++i)
mMessageHandlers.erase(*i);
- }
handler->setNetwork(nullptr);
}
@@ -352,12 +348,20 @@ void Network::unregisterHandler(MessageHandler *handler)
void Network::clearHandlers()
{
for (auto& [_, messageHandler] : mMessageHandlers)
- {
messageHandler->setNetwork(nullptr);
- }
+
mMessageHandlers.clear();
}
+const char *Network::messageName(uint16_t id) const
+{
+ auto packetInfoIt = mPacketInfo.find(id);
+ if (packetInfoIt != mPacketInfo.end())
+ return packetInfoIt->second->name;
+
+ return "Unknown";
+}
+
void Network::dispatchMessages()
{
MutexLocker lock(&mMutex);
diff --git a/src/net/tmwa/network.h b/src/net/tmwa/network.h
index fa0237dd..b27d1eda 100644
--- a/src/net/tmwa/network.h
+++ b/src/net/tmwa/network.h
@@ -19,8 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef NET_TA_NETWORK_H
-#define NET_TA_NETWORK_H
+#pragma once
#include "utils/mutex.h"
@@ -67,6 +66,8 @@ class Network
void clearHandlers();
+ const char *messageName(uint16_t id) const;
+
int getState() const { return mState; }
const std::string &getError() const { return mError; }
@@ -125,5 +126,3 @@ class Network
};
} // namespace TmwAthena
-
-#endif // NET_TA_NETWORK_H
diff --git a/src/net/tmwa/npchandler.h b/src/net/tmwa/npchandler.h
index b55a8155..df23531f 100644
--- a/src/net/tmwa/npchandler.h
+++ b/src/net/tmwa/npchandler.h
@@ -19,8 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef NET_TA_NPCHANDLER_H
-#define NET_TA_NPCHANDLER_H
+#pragma once
#include "net/npchandler.h"
@@ -65,5 +64,3 @@ class NpcHandler final : public MessageHandler, public Net::NpcHandler
};
} // namespace TmwAthena
-
-#endif // NET_TA_NPCHANDLER_H
diff --git a/src/net/tmwa/partyhandler.h b/src/net/tmwa/partyhandler.h
index 14c6d9f3..3f99de20 100644
--- a/src/net/tmwa/partyhandler.h
+++ b/src/net/tmwa/partyhandler.h
@@ -19,8 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef NET_TA_PARTYHANDLER_H
-#define NET_TA_PARTYHANDLER_H
+#pragma once
#include "net/net.h"
#include "net/partyhandler.h"
@@ -71,5 +70,3 @@ class PartyHandler final : public MessageHandler, public Net::PartyHandler
};
} // namespace TmwAthena
-
-#endif // NET_TA_PARTYHANDLER_H
diff --git a/src/net/tmwa/playerhandler.h b/src/net/tmwa/playerhandler.h
index 1a90532e..f1a67e94 100644
--- a/src/net/tmwa/playerhandler.h
+++ b/src/net/tmwa/playerhandler.h
@@ -19,8 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef NET_TA_PLAYERHANDLER_H
-#define NET_TA_PLAYERHANDLER_H
+#pragma once
#include "net/net.h"
#include "net/playerhandler.h"
@@ -67,5 +66,3 @@ class PlayerHandler final : public MessageHandler, public Net::PlayerHandler
};
} // namespace TmwAthena
-
-#endif // NET_TA_PLAYERHANDLER_H
diff --git a/src/net/tmwa/protocol.h b/src/net/tmwa/protocol.h
index 609b18a5..532ac90e 100644
--- a/src/net/tmwa/protocol.h
+++ b/src/net/tmwa/protocol.h
@@ -19,8 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef TA_PROTOCOL_H
-#define TA_PROTOCOL_H
+#pragma once
#include <cstdint>
@@ -80,6 +79,20 @@ enum class LOOK : uint8_t
MISC2 = 13,
};
+enum class DIR : uint8_t
+{
+ S = 0,
+ SW = 1,
+ W = 2,
+ NW = 3,
+ N = 4,
+ NE = 5,
+ E = 6,
+ SE = 7,
+
+ COUNT,
+};
+
enum NpcCommand
{
NPC_REQUEST_LANG = 0,
@@ -283,5 +296,3 @@ enum {
};
}
-
-#endif
diff --git a/src/net/tmwa/token.h b/src/net/tmwa/token.h
index c0a2b3c8..b563bf65 100644
--- a/src/net/tmwa/token.h
+++ b/src/net/tmwa/token.h
@@ -21,8 +21,7 @@
#include "being.h"
-#ifndef NET_TA_TOKEN_H
-#define NET_TA_TOKEN_H
+#pragma once
struct Token
{
@@ -36,8 +35,6 @@ struct Token
account_ID = 0;
session_ID1 = 0;
session_ID2 = 0;
- sex = Gender::UNSPECIFIED;
+ sex = Gender::Unspecified;
}
};
-
-#endif // NET_TA_TOKEN_H
diff --git a/src/net/tmwa/tradehandler.cpp b/src/net/tmwa/tradehandler.cpp
index 60732eef..c129cfd4 100644
--- a/src/net/tmwa/tradehandler.cpp
+++ b/src/net/tmwa/tradehandler.cpp
@@ -131,7 +131,7 @@ void TradeHandler::handleMessage(MessageIn &msg)
"doesn't exist."));
break;
case 2: // Invite request check failed...
- serverNotice(_("Trade cancelled due to an unknown "
+ serverNotice(_("Trade canceled due to an unknown "
"reason."));
break;
case 3: // Trade accepted
@@ -140,11 +140,11 @@ void TradeHandler::handleMessage(MessageIn &msg)
tradePartnerName.c_str()));
tradeWindow->setVisible(true);
break;
- case 4: // Trade cancelled
+ case 4: // Trade canceled
if (player_relations.hasPermission(tradePartnerName,
PlayerPermissions::SPEECH_LOG))
{
- serverNotice(strprintf(_("Trade with %s cancelled."),
+ serverNotice(strprintf(_("Trade with %s canceled."),
tradePartnerName.c_str()));
}
// otherwise ignore silently
diff --git a/src/net/tmwa/tradehandler.h b/src/net/tmwa/tradehandler.h
index fa7ec034..1a2cfcef 100644
--- a/src/net/tmwa/tradehandler.h
+++ b/src/net/tmwa/tradehandler.h
@@ -19,8 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef NET_TA_TRADEHANDLER_H
-#define NET_TA_TRADEHANDLER_H
+#pragma once
#include "net/net.h"
#include "net/tradehandler.h"
@@ -57,5 +56,3 @@ class TradeHandler final : public MessageHandler, public Net::TradeHandler
};
} // namespace TmwAthena
-
-#endif // NET_TA_TRADEHANDLER_H
diff --git a/src/net/tradehandler.h b/src/net/tradehandler.h
index 609f8087..605d122b 100644
--- a/src/net/tradehandler.h
+++ b/src/net/tradehandler.h
@@ -19,8 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef TRADEHANDLER_H
-#define TRADEHANDLER_H
+#pragma once
#include "being.h"
@@ -49,5 +48,3 @@ class TradeHandler
virtual void cancel() {}
};
}
-
-#endif // TRADEHANDLER_H
diff --git a/src/net/worldinfo.h b/src/net/worldinfo.h
index d9596239..acc8a376 100644
--- a/src/net/worldinfo.h
+++ b/src/net/worldinfo.h
@@ -19,8 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef WORLD_INFO_H
-#define WORLD_INFO_H
+#pragma once
#include <string>
#include <vector>
@@ -34,5 +33,3 @@ struct WorldInfo {
};
using Worlds = std::vector<WorldInfo *>;
-
-#endif // WORLD_INFO_H