2 * Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 #include "ByteBuffer.h"
21 #include "WorldPacket.h"
22 #include "UpdateData.h"
26 #include <zlib/zlib.h>
28 UpdateData::UpdateData() : m_blockCount(0)
32 void UpdateData::AddOutOfRangeGUID(std::set
<uint64
>& guids
)
34 m_outOfRangeGUIDs
.insert(guids
.begin(),guids
.end());
37 void UpdateData::AddOutOfRangeGUID(const uint64
&guid
)
39 m_outOfRangeGUIDs
.insert(guid
);
42 void UpdateData::AddUpdateBlock(const ByteBuffer
&block
)
48 void UpdateData::Compress(void* dst
, uint32
*dst_size
, void* src
, int src_size
)
52 c_stream
.zalloc
= (alloc_func
)0;
53 c_stream
.zfree
= (free_func
)0;
54 c_stream
.opaque
= (voidpf
)0;
56 // default Z_BEST_SPEED (1)
57 int z_res
= deflateInit(&c_stream
, sWorld
.getConfig(CONFIG_COMPRESSION
));
60 sLog
.outError("Can't compress update packet (zlib: deflateInit) Error code: %i (%s)",z_res
,zError(z_res
));
65 c_stream
.next_out
= (Bytef
*)dst
;
66 c_stream
.avail_out
= *dst_size
;
67 c_stream
.next_in
= (Bytef
*)src
;
68 c_stream
.avail_in
= (uInt
)src_size
;
70 z_res
= deflate(&c_stream
, Z_NO_FLUSH
);
73 sLog
.outError("Can't compress update packet (zlib: deflate) Error code: %i (%s)",z_res
,zError(z_res
));
78 if (c_stream
.avail_in
!= 0)
80 sLog
.outError("Can't compress update packet (zlib: deflate not greedy)");
85 z_res
= deflate(&c_stream
, Z_FINISH
);
86 if (z_res
!= Z_STREAM_END
)
88 sLog
.outError("Can't compress update packet (zlib: deflate should report Z_STREAM_END instead %i (%s)",z_res
,zError(z_res
));
93 z_res
= deflateEnd(&c_stream
);
96 sLog
.outError("Can't compress update packet (zlib: deflateEnd) Error code: %i (%s)",z_res
,zError(z_res
));
101 *dst_size
= c_stream
.total_out
;
104 bool UpdateData::BuildPacket(WorldPacket
*packet
, bool hasTransport
)
106 ByteBuffer
buf(m_data
.size() + 10 + m_outOfRangeGUIDs
.size()*8);
108 buf
<< (uint32
) (!m_outOfRangeGUIDs
.empty() ? m_blockCount
+ 1 : m_blockCount
);
109 //buf << (uint8) (hasTransport ? 1 : 0);
111 if(!m_outOfRangeGUIDs
.empty())
113 buf
<< (uint8
) UPDATETYPE_OUT_OF_RANGE_OBJECTS
;
114 buf
<< (uint32
) m_outOfRangeGUIDs
.size();
116 for(std::set
<uint64
>::const_iterator i
= m_outOfRangeGUIDs
.begin();
117 i
!= m_outOfRangeGUIDs
.end(); i
++)
119 //buf.appendPackGUID(*i);
129 if (m_data
.size() > 50 )
131 uint32 destsize
= buf
.size() + buf
.size()/10 + 16;
132 packet
->resize( destsize
);
134 packet
->put(0, (uint32
)buf
.size());
136 Compress(const_cast<uint8
*>(packet
->contents()) + sizeof(uint32
),
138 (void*)buf
.contents(),
143 packet
->resize( destsize
+ sizeof(uint32
) );
144 packet
->SetOpcode( SMSG_COMPRESSED_UPDATE_OBJECT
);
148 packet
->append( buf
);
149 packet
->SetOpcode( SMSG_UPDATE_OBJECT
);
155 void UpdateData::Clear()
158 m_outOfRangeGUIDs
.clear();