mirror of
https://github.com/ErikasKontenis/SabrehavenServer.git
synced 2025-05-03 19:09:19 +02:00
145 lines
3.4 KiB
C++
145 lines
3.4 KiB
C++
/**
|
|
* Tibia GIMUD Server - a free and open-source MMORPG server emulator
|
|
* Copyright (C) 2019 Sabrehaven and Mark Samman <mark.samman@gmail.com>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
*/
|
|
|
|
#include "otpch.h"
|
|
|
|
#include "networkmessage.h"
|
|
|
|
#include "container.h"
|
|
#include "creature.h"
|
|
|
|
std::string NetworkMessage::getString(uint16_t stringLen/* = 0*/)
|
|
{
|
|
if (stringLen == 0) {
|
|
stringLen = get<uint16_t>();
|
|
}
|
|
|
|
if (!canRead(stringLen)) {
|
|
return std::string();
|
|
}
|
|
|
|
char* v = reinterpret_cast<char*>(buffer) + info.position; //does not break strict aliasing
|
|
info.position += stringLen;
|
|
return std::string(v, stringLen);
|
|
}
|
|
|
|
Position NetworkMessage::getPosition()
|
|
{
|
|
Position pos;
|
|
pos.x = get<uint16_t>();
|
|
pos.y = get<uint16_t>();
|
|
pos.z = getByte();
|
|
return pos;
|
|
}
|
|
|
|
void NetworkMessage::addString(const std::string& value)
|
|
{
|
|
size_t stringLen = value.length();
|
|
if (!canAdd(stringLen + 2) || stringLen > 8192) {
|
|
return;
|
|
}
|
|
|
|
add<uint16_t>(stringLen);
|
|
memcpy(buffer + info.position, value.c_str(), stringLen);
|
|
info.position += stringLen;
|
|
info.length += stringLen;
|
|
}
|
|
|
|
void NetworkMessage::addDouble(double value, uint8_t precision/* = 2*/)
|
|
{
|
|
addByte(precision);
|
|
add<uint32_t>((value * std::pow(static_cast<float>(10), precision)) + std::numeric_limits<int32_t>::max());
|
|
}
|
|
|
|
void NetworkMessage::addBytes(const char* bytes, size_t size)
|
|
{
|
|
if (!canAdd(size) || size > 8192) {
|
|
return;
|
|
}
|
|
|
|
memcpy(buffer + info.position, bytes, size);
|
|
info.position += size;
|
|
info.length += size;
|
|
}
|
|
|
|
void NetworkMessage::addPaddingBytes(size_t n)
|
|
{
|
|
if (!canAdd(n)) {
|
|
return;
|
|
}
|
|
|
|
memset(buffer + info.position, 0x33, n);
|
|
info.length += n;
|
|
}
|
|
|
|
void NetworkMessage::addPosition(const Position& pos)
|
|
{
|
|
add<uint16_t>(pos.x);
|
|
add<uint16_t>(pos.y);
|
|
addByte(pos.z);
|
|
}
|
|
|
|
void NetworkMessage::addItem(uint16_t id, uint8_t count, bool textWindow /* = false*/)
|
|
{
|
|
const ItemType& it = Item::items[id];
|
|
|
|
if (it.disguise) {
|
|
add<uint16_t>(it.disguiseId);
|
|
} else {
|
|
add<uint16_t>(it.id);
|
|
}
|
|
|
|
if (!textWindow) {
|
|
if (it.stackable || it.isRune()) {
|
|
addByte(count);
|
|
}
|
|
else if (it.isSplash() || it.isFluidContainer()) {
|
|
addByte(getLiquidColor(count));
|
|
}
|
|
}
|
|
}
|
|
|
|
void NetworkMessage::addItem(const Item* item, bool textWindow /* = false*/)
|
|
{
|
|
const ItemType& it = Item::items[item->getID()];
|
|
|
|
if (it.disguise) {
|
|
add<uint16_t>(it.disguiseId);
|
|
} else {
|
|
add<uint16_t>(it.id);
|
|
}
|
|
|
|
if (!textWindow) {
|
|
if (it.stackable) {
|
|
addByte(std::min<uint16_t>(0xFF, item->getItemCount()));
|
|
}
|
|
else if (it.isRune()) {
|
|
addByte(std::min<uint16_t>(0xFF, item->getCharges()));
|
|
}
|
|
else if (it.isSplash() || it.isFluidContainer()) {
|
|
addByte(getLiquidColor(item->getFluidType()));
|
|
}
|
|
}
|
|
}
|
|
|
|
void NetworkMessage::addItemId(uint16_t itemId)
|
|
{
|
|
add<uint16_t>(itemId);
|
|
}
|