root/trunk/src/game/UpdateData.cpp @ 9

Revision 2, 4.3 kB (checked in by yumileroy, 17 years ago)

[svn] * Proper SVN structure

Original author: Neo2003
Date: 2008-10-02 16:23:55-05:00

Line 
1/*
2 * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
3 *
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.
8 *
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.
13 *
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
17 */
18
19#include "Common.h"
20#include "ByteBuffer.h"
21#include "WorldPacket.h"
22#include "UpdateData.h"
23#include "Log.h"
24#include "Opcodes.h"
25#include "World.h"
26#include <zlib/zlib.h>
27
28UpdateData::UpdateData() : m_blockCount(0)
29{
30}
31
32void UpdateData::AddOutOfRangeGUID(std::set<uint64>& guids)
33{
34    m_outOfRangeGUIDs.insert(guids.begin(),guids.end());
35}
36
37void UpdateData::AddOutOfRangeGUID(const uint64 &guid)
38{
39    m_outOfRangeGUIDs.insert(guid);
40}
41
42void UpdateData::AddUpdateBlock(const ByteBuffer &block)
43{
44    m_data.append(block);
45    ++m_blockCount;
46}
47
48void UpdateData::Compress(void* dst, uint32 *dst_size, void* src, int src_size)
49{
50    z_stream c_stream;
51
52    c_stream.zalloc = (alloc_func)0;
53    c_stream.zfree = (free_func)0;
54    c_stream.opaque = (voidpf)0;
55
56    // default Z_BEST_SPEED (1)
57    int z_res = deflateInit(&c_stream, sWorld.getConfig(CONFIG_COMPRESSION));
58    if (z_res != Z_OK)
59    {
60        sLog.outError("Can't compress update packet (zlib: deflateInit) Error code: %i (%s)",z_res,zError(z_res));
61        *dst_size = 0;
62        return;
63    }
64
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;
69
70    z_res = deflate(&c_stream, Z_NO_FLUSH);
71    if (z_res != Z_OK)
72    {
73        sLog.outError("Can't compress update packet (zlib: deflate) Error code: %i (%s)",z_res,zError(z_res));
74        *dst_size = 0;
75        return;
76    }
77
78    if (c_stream.avail_in != 0)
79    {
80        sLog.outError("Can't compress update packet (zlib: deflate not greedy)");
81        *dst_size = 0;
82        return;
83    }
84
85    z_res = deflate(&c_stream, Z_FINISH);
86    if (z_res != Z_STREAM_END)
87    {
88        sLog.outError("Can't compress update packet (zlib: deflate should report Z_STREAM_END instead %i (%s)",z_res,zError(z_res));
89        *dst_size = 0;
90        return;
91    }
92
93    z_res = deflateEnd(&c_stream);
94    if (z_res != Z_OK)
95    {
96        sLog.outError("Can't compress update packet (zlib: deflateEnd) Error code: %i (%s)",z_res,zError(z_res));
97        *dst_size = 0;
98        return;
99    }
100
101    *dst_size = c_stream.total_out;
102}
103
104bool UpdateData::BuildPacket(WorldPacket *packet, bool hasTransport)
105{
106    ByteBuffer buf(m_data.size() + 10 + m_outOfRangeGUIDs.size()*8);
107
108    buf << (uint32) (!m_outOfRangeGUIDs.empty() ? m_blockCount + 1 : m_blockCount);
109    buf << (uint8) (hasTransport ? 1 : 0);
110
111    if(!m_outOfRangeGUIDs.empty())
112    {
113        buf << (uint8) UPDATETYPE_OUT_OF_RANGE_OBJECTS;
114        buf << (uint32) m_outOfRangeGUIDs.size();
115
116        for(std::set<uint64>::const_iterator i = m_outOfRangeGUIDs.begin();
117            i != m_outOfRangeGUIDs.end(); i++)
118        {
119            //buf.appendPackGUID(*i);
120            buf << (uint8)0xFF;
121            buf << (uint64) *i;
122        }
123    }
124
125    buf.append(m_data);
126
127    packet->clear();
128
129    if (m_data.size() > 50 )
130    {
131        uint32 destsize = buf.size() + buf.size()/10 + 16;
132        packet->resize( destsize );
133
134        packet->put(0, (uint32)buf.size());
135
136        Compress(const_cast<uint8*>(packet->contents()) + sizeof(uint32),
137            &destsize,
138            (void*)buf.contents(),
139            buf.size());
140        if (destsize == 0)
141            return false;
142
143        packet->resize( destsize + sizeof(uint32) );
144        packet->SetOpcode( SMSG_COMPRESSED_UPDATE_OBJECT );
145    }
146    else
147    {
148        packet->append( buf );
149        packet->SetOpcode( SMSG_UPDATE_OBJECT );
150    }
151
152    return true;
153}
154
155void UpdateData::Clear()
156{
157    m_data.clear();
158    m_outOfRangeGUIDs.clear();
159    m_blockCount = 0;
160}
Note: See TracBrowser for help on using the browser.