outputmessage.cpp

main 165 lines · 4.5 KB Raw
Alex Alex Commit Client Upload Part 2 19/10/2026 00:06
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 <framework/net/outputmessage.h>
24#include <framework/util/crypt.h>
25
26OutputMessage::OutputMessage()
27{
28 reset();
29}
30
31void OutputMessage::reset()
32{
33 m_writePos = MAX_HEADER_SIZE;
34 m_headerPos = MAX_HEADER_SIZE;
35 m_messageSize = 0;
36}
37
38void OutputMessage::setBuffer(const std::string& buffer)
39{
40 int len = buffer.size();
41 reset();
42 checkWrite(len);
43 memcpy((char*)(m_buffer + m_writePos), buffer.c_str(), len);
44 m_writePos += len;
45 m_messageSize += len;
46}
47
48void OutputMessage::addU8(uint8 value)
49{
50 checkWrite(1);
51 m_buffer[m_writePos] = value;
52 m_writePos += 1;
53 m_messageSize += 1;
54}
55
56void OutputMessage::addU16(uint16 value)
57{
58 checkWrite(2);
59 stdext::writeULE16(m_buffer + m_writePos, value);
60 m_writePos += 2;
61 m_messageSize += 2;
62}
63
64void OutputMessage::addU32(uint32 value)
65{
66 checkWrite(4);
67 stdext::writeULE32(m_buffer + m_writePos, value);
68 m_writePos += 4;
69 m_messageSize += 4;
70}
71
72void OutputMessage::addU64(uint64 value)
73{
74 checkWrite(8);
75 stdext::writeULE64(m_buffer + m_writePos, value);
76 m_writePos += 8;
77 m_messageSize += 8;
78}
79
80void OutputMessage::addString(const std::string& buffer)
81{
82 int len = buffer.length();
83 if (len > MAX_STRING_LENGTH)
84 throw stdext::exception(stdext::format("string length > %d", MAX_STRING_LENGTH));
85 checkWrite(len + 2);
86 addU16(len);
87 memcpy((char*)(m_buffer + m_writePos), buffer.c_str(), len);
88 m_writePos += len;
89 m_messageSize += len;
90}
91
92void OutputMessage::addRawString(const std::string& buffer)
93{
94 int len = buffer.length();
95 if (len > MAX_STRING_LENGTH)
96 throw stdext::exception(stdext::format("string length > %d", MAX_STRING_LENGTH));
97 checkWrite(len);
98 memcpy((char*)(m_buffer + m_writePos), buffer.c_str(), len);
99 m_writePos += len;
100 m_messageSize += len;
101}
102
103void OutputMessage::addPaddingBytes(int bytes, uint8 byte)
104{
105 if(bytes <= 0)
106 return;
107 checkWrite(bytes);
108 memset((void*)&m_buffer[m_writePos], byte, bytes);
109 m_writePos += bytes;
110 m_messageSize += bytes;
111}
112
113void OutputMessage::encryptRsa()
114{
115 uint32_t size = g_crypt.rsaGetSize();
116 if(m_messageSize < size)
117 throw stdext::exception("insufficient bytes in buffer to encrypt");
118
119 if(!g_crypt.rsaEncrypt((unsigned char*)m_buffer + m_writePos - size, size))
120 throw stdext::exception("rsa encryption failed");
121}
122
123void OutputMessage::writeChecksum()
124{
125 uint32 checksum = stdext::adler32(m_buffer + m_headerPos, m_messageSize);
126 VALIDATE(m_headerPos >= 4);
127 m_headerPos -= 4;
128 stdext::writeULE32(m_buffer + m_headerPos, checksum);
129 m_messageSize += 4;
130}
131
132void OutputMessage::writeSequence(uint32_t sequence)
133{
134 VALIDATE(m_headerPos >= 4);
135 m_headerPos -= 4;
136 stdext::writeULE32(m_buffer + m_headerPos, sequence);
137 m_messageSize += 4;
138}
139
140
141void OutputMessage::writeMessageSize(bool bigSize)
142{
143 VALIDATE(m_headerPos >= (bigSize ? 4 : 2));
144 m_headerPos -= (bigSize ? 4 : 2);
145 if (bigSize) {
146 stdext::writeULE32(m_buffer + m_headerPos, m_messageSize);
147 } else {
148 stdext::writeULE16(m_buffer + m_headerPos, m_messageSize);
149 }
150 m_messageSize += (bigSize ? 4 : 2);
151}
152
153bool OutputMessage::canWrite(int bytes)
154{
155 if(m_writePos + bytes > BUFFER_MAXSIZE)
156 return false;
157 return true;
158}
159
160void OutputMessage::checkWrite(int bytes)
161{
162 if(!canWrite(bytes))
163 throw stdext::exception("OutputMessage max buffer size reached");
164}
165
Top