/** * Tibia GIMUD Server - a free and open-source MMORPG server emulator * Copyright (C) 2019 Sabrehaven and Mark Samman * * 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(); } if (!canRead(stringLen)) { return std::string(); } char* v = reinterpret_cast(buffer) + info.position; //does not break strict aliasing info.position += stringLen; return std::string(v, stringLen); } Position NetworkMessage::getPosition() { Position pos; pos.x = get(); pos.y = get(); 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(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((value * std::pow(static_cast(10), precision)) + std::numeric_limits::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(pos.x); add(pos.y); addByte(pos.z); } void NetworkMessage::addItem(uint16_t id, uint8_t count) { const ItemType& it = Item::items[id]; if (it.disguise) { add(it.disguiseId); } else { add(it.id); } if (it.stackable) { addByte(count); } else if (it.isSplash() || it.isFluidContainer()) { addByte(getLiquidColor(count)); } } void NetworkMessage::addItem(const Item* item) { const ItemType& it = Item::items[item->getID()]; if (it.disguise) { add(it.disguiseId); } else { add(it.id); } if (it.stackable) { addByte(std::min(0xFF, item->getItemCount())); } else if (it.isSplash() || it.isFluidContainer()) { addByte(getLiquidColor(item->getFluidType())); } } void NetworkMessage::addItemId(uint16_t itemId) { add(itemId); }