1/*
2 * Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 * THE SOFTWARE.
21 */
22
23#include "inputmessage.h"
24#include <framework/util/crypt.h>
25#include <client/map.h>
26
27InputMessage::InputMessage()
28{
29 reset();
30}
31
32void InputMessage::reset()
33{
34 m_messageSize = 0;
35 m_readPos = MAX_HEADER_SIZE;
36 m_headerPos = MAX_HEADER_SIZE;
37}
38
39void InputMessage::setBuffer(const std::string& buffer)
40{
41 int len = buffer.size();
42 checkWrite(MAX_HEADER_SIZE + len);
43 memcpy(m_buffer + MAX_HEADER_SIZE, buffer.c_str(), len);
44 m_readPos = MAX_HEADER_SIZE;
45 m_headerPos = MAX_HEADER_SIZE;
46 m_messageSize = len;
47}
48
49uint8 InputMessage::getU8()
50{
51 checkRead(1);
52 uint8 v = m_buffer[m_readPos];
53 m_readPos += 1;
54 return v;
55}
56
57uint16 InputMessage::getU16()
58{
59 checkRead(2);
60 uint16 v = stdext::readULE16(m_buffer + m_readPos);
61 m_readPos += 2;
62 return v;
63}
64
65uint32 InputMessage::getU32()
66{
67 checkRead(4);
68 uint32 v = stdext::readULE32(m_buffer + m_readPos);
69 m_readPos += 4;
70 return v;
71}
72
73uint64 InputMessage::getU64()
74{
75 checkRead(8);
76 uint64 v = stdext::readULE64(m_buffer + m_readPos);
77 m_readPos += 8;
78 return v;
79}
80
81std::string InputMessage::getString()
82{
83 uint16 stringLength = getU16();
84 checkRead(stringLength);
85 char* v = (char*)(m_buffer + m_readPos);
86 m_readPos += stringLength;
87 return std::string(v, stringLength);
88}
89
90double InputMessage::getDouble()
91{
92 uint8 precision = getU8();
93 int32 v = getU32() - INT_MAX;
94 return (v / std::pow((float)10, precision));
95}
96
97bool InputMessage::decryptRsa(int size)
98{
99 checkRead(size);
100 g_crypt.rsaDecrypt((unsigned char*)m_buffer + m_readPos, size);
101 return (getU8() == 0x00);
102}
103
104void InputMessage::fillBuffer(uint8 *buffer, uint32 size)
105{
106 checkWrite(m_readPos + size);
107 memcpy(m_buffer + m_readPos, buffer, size);
108 m_messageSize += size;
109}
110
111void InputMessage::setHeaderSize(uint32 size)
112{
113 VALIDATE(MAX_HEADER_SIZE >= size);
114 m_headerPos = MAX_HEADER_SIZE - size;
115 m_readPos = m_headerPos;
116}
117
118bool InputMessage::readChecksum()
119{
120 uint32 receivedCheck = getU32();
121 uint32 checksum = stdext::adler32(m_buffer + m_readPos, getUnreadSize());
122 return receivedCheck == checksum;
123}
124
125bool InputMessage::canRead(int bytes)
126{
127 if((m_readPos - m_headerPos + bytes > m_messageSize) || (m_readPos + bytes > BUFFER_MAXSIZE))
128 return false;
129 return true;
130}
131void InputMessage::checkRead(int bytes)
132{
133 if(!canRead(bytes))
134 throw stdext::exception("InputMessage eof reached");
135}
136
137void InputMessage::checkWrite(int bytes)
138{
139 if(bytes > BUFFER_MAXSIZE)
140 throw stdext::exception("InputMessage max buffer size reached");
141}
142
143void InputMessage::addZlibFooter()
144{
145 if (m_messageSize + 4 > BUFFER_MAXSIZE)
146 return;
147 m_buffer[m_messageSize + m_headerPos] = 0x00;
148 m_buffer[m_messageSize + m_headerPos + 1] = 0x00;
149 m_buffer[m_messageSize + m_headerPos + 2] = 0xFF;
150 m_buffer[m_messageSize + m_headerPos + 3] = 0xFF;
151 m_messageSize += 4;
152}
153