TrinityCore
Loading...
Searching...
No Matches
UpdateData.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include "UpdateData.h"
19#include "Errors.h"
20#include "Log.h"
21#include "Opcodes.h"
22#include "World.h"
23#include "WorldPacket.h"
24#include <zlib.h>
25
26UpdateData::UpdateData() : m_blockCount(0) { }
27
29{
30 m_outOfRangeGUIDs.insert(guids.begin(), guids.end());
31}
32
37
38void UpdateData::Compress(void* dst, uint32 *dst_size, void* src, int src_size)
39{
40 z_stream c_stream;
41
42 c_stream.zalloc = (alloc_func)nullptr;
43 c_stream.zfree = (free_func)nullptr;
44 c_stream.opaque = (voidpf)nullptr;
45
46 // default Z_BEST_SPEED (1)
47 int z_res = deflateInit(&c_stream, sWorld->getIntConfig(CONFIG_COMPRESSION));
48 if (z_res != Z_OK)
49 {
50 TC_LOG_ERROR("misc", "Can't compress update packet (zlib: deflateInit) Error code: {} ({})", z_res, zError(z_res));
51 *dst_size = 0;
52 return;
53 }
54
55 c_stream.next_out = (Bytef*)dst;
56 c_stream.avail_out = *dst_size;
57 c_stream.next_in = (Bytef*)src;
58 c_stream.avail_in = (uInt)src_size;
59
60 z_res = deflate(&c_stream, Z_NO_FLUSH);
61 if (z_res != Z_OK)
62 {
63 TC_LOG_ERROR("misc", "Can't compress update packet (zlib: deflate) Error code: {} ({})", z_res, zError(z_res));
64 *dst_size = 0;
65 return;
66 }
67
68 if (c_stream.avail_in != 0)
69 {
70 TC_LOG_ERROR("misc", "Can't compress update packet (zlib: deflate not greedy)");
71 *dst_size = 0;
72 return;
73 }
74
75 z_res = deflate(&c_stream, Z_FINISH);
76 if (z_res != Z_STREAM_END)
77 {
78 TC_LOG_ERROR("misc", "Can't compress update packet (zlib: deflate should report Z_STREAM_END instead {} ({})", z_res, zError(z_res));
79 *dst_size = 0;
80 return;
81 }
82
83 z_res = deflateEnd(&c_stream);
84 if (z_res != Z_OK)
85 {
86 TC_LOG_ERROR("misc", "Can't compress update packet (zlib: deflateEnd) Error code: {} ({})", z_res, zError(z_res));
87 *dst_size = 0;
88 return;
89 }
90
91 *dst_size = c_stream.total_out;
92}
93
95{
96 ASSERT(packet->empty()); // shouldn't happen
97
98 ByteBuffer buf(4 + (m_outOfRangeGUIDs.empty() ? 0 : 1 + 4 + 9 * m_outOfRangeGUIDs.size()) + m_data.wpos());
99
100 buf << (uint32) (!m_outOfRangeGUIDs.empty() ? m_blockCount + 1 : m_blockCount);
101
102 if (!m_outOfRangeGUIDs.empty())
103 {
105 buf << uint32(m_outOfRangeGUIDs.size());
106
107 for (GuidSet::const_iterator i = m_outOfRangeGUIDs.begin(); i != m_outOfRangeGUIDs.end(); ++i)
108 buf << i->WriteAsPacked();
109 }
110
111 buf.append(m_data);
112
113 size_t pSize = buf.wpos(); // use real used data size
114
115 if (pSize > 100) // compress large packets
116 {
117 uint32 destsize = compressBound(pSize);
118 packet->resize(destsize + sizeof(uint32));
119
120 packet->put<uint32>(0, pSize);
121 Compress(const_cast<uint8*>(packet->contents()) + sizeof(uint32), &destsize, (void*)buf.contents(), pSize);
122 if (destsize == 0)
123 return false;
124
125 packet->resize(destsize + sizeof(uint32));
127 }
128 else // send small packets without compression
129 {
130 packet->append(buf);
132 }
133
134 return true;
135}
136
138{
139 m_data.clear();
140 m_outOfRangeGUIDs.clear();
141 m_blockCount = 0;
142}
uint8_t uint8
Definition Define.h:135
uint32_t uint32
Definition Define.h:133
#define ASSERT
Definition Errors.h:68
#define TC_LOG_ERROR(filterType__,...)
Definition Log.h:165
std::set< ObjectGuid > GuidSet
Definition ObjectGuid.h:260
@ UPDATETYPE_OUT_OF_RANGE_OBJECTS
Definition UpdateData.h:34
void resize(size_t newsize)
Definition ByteBuffer.h:412
void append(T value)
Definition ByteBuffer.h:129
size_t wpos() const
Definition ByteBuffer.h:321
void put(std::size_t pos, T value)
Definition ByteBuffer.h:137
void clear()
Definition ByteBuffer.h:123
bool empty() const
Definition ByteBuffer.h:410
uint8 * contents()
Definition ByteBuffer.h:395
uint32 m_blockCount
Definition UpdateData.h:75
void AddOutOfRangeGUID(GuidSet &guids)
bool BuildPacket(WorldPacket *packet)
ByteBuffer m_data
Definition UpdateData.h:77
GuidSet m_outOfRangeGUIDs
Definition UpdateData.h:76
void Compress(void *dst, uint32 *dst_size, void *src, int src_size)
void SetOpcode(uint16 opcode)
Definition WorldPacket.h:81
@ SMSG_COMPRESSED_UPDATE_OBJECT
Definition Opcodes.h:531
@ SMSG_UPDATE_OBJECT
Definition Opcodes.h:198
#define sWorld
Definition World.h:900
@ CONFIG_COMPRESSION
Definition World.h:211