Exemple #1
0
void Client::sendDeletedBlocks(std::vector<v3s16> &blocks)
{
	NetworkPacket pkt(TOSERVER_DELETEDBLOCKS, 1 + sizeof(v3s16) * blocks.size());

	pkt << (u8) blocks.size();

	u32 k = 0;
	for(std::vector<v3s16>::iterator
			j = blocks.begin();
			j != blocks.end(); ++j) {
		pkt << *j;
		k++;
	}

	Send(&pkt);
}
Exemple #2
0
void WardenMac::RequestHash()
{
    sLog.outDebug("Request hash");

    // Create packet structure
    WardenHashRequest Request;
    Request.Command = WARDEN_SMSG_HASH_REQUEST;
    memcpy(Request.Seed, Seed, 16);

    // Encrypt with warden RC4 key.
    EncryptData((uint8*)&Request, sizeof(WardenHashRequest));

    WorldPacket pkt(SMSG_WARDEN_DATA, sizeof(WardenHashRequest));
    pkt.append((uint8*)&Request, sizeof(WardenHashRequest));
    Client->SendPacket(&pkt);
}
Exemple #3
0
void WardenWin::RequestHash()
{
    sLog->outDebug(LOG_FILTER_WARDEN, "Request hash");

    // Create packet structure
    WardenHashRequest Request;
    Request.Command = WARDEN_SMSG_HASH_REQUEST;
    memcpy(Request.Seed, _seed, 16);

    // Encrypt with warden RC4 key.
    EncryptData((uint8*)&Request, sizeof(WardenHashRequest));

    WorldPacket pkt(SMSG_WARDEN_DATA, sizeof(WardenHashRequest));
    pkt.append((uint8*)&Request, sizeof(WardenHashRequest));
    _session->SendPacket(&pkt);
}
void PacketHandlers::HandleDialogueDecision(Session* sess, SmartPacket& packet)
{
    uint64_t guid = packet.ReadUInt64();
    uint32_t decision = packet.ReadUInt32();

    WorldObject* obj = sObjectAccessor->FindWorldObject(guid);
    // if the object is not found, or is not creature, send dialogue close packet
    if (!obj || obj->GetType() != OTYPE_CREATURE)
    {
        SmartPacket pkt(SP_DIALOGUE_CLOSE);
        sess->SendPacket(pkt);
        return;
    }

    obj->ToCreature()->DialogueDecision(sess->GetPlayer(), decision);
}
Exemple #5
0
void Client::sendInit(const std::string &playerName)
{
	NetworkPacket pkt(TOSERVER_INIT, 1 + 2 + 2 + (1 + playerName.size()));

	// we don't support network compression yet
	u16 supp_comp_modes = NETPROTO_COMPRESSION_NONE;

	u16 proto_version_min = g_settings->getFlag("send_pre_v25_init") ?
		CLIENT_PROTOCOL_VERSION_MIN_LEGACY : CLIENT_PROTOCOL_VERSION_MIN;

	pkt << (u8) SER_FMT_VER_HIGHEST_READ << (u16) supp_comp_modes;
	pkt << (u16) proto_version_min << (u16) CLIENT_PROTOCOL_VERSION_MAX;
	pkt << playerName;

	Send(&pkt);
}
void PacketHandlers::HandleNameQuery(Session* sess, SmartPacket& packet)
{
    uint64_t guid = packet.ReadUInt64();

    SmartPacket pkt(SP_NAME_QUERY_RESPONSE);
    pkt.WriteUInt64(guid);

    // object has to exist and be in world
    WorldObject* obj = sObjectAccessor->FindWorldObject(guid);
    if (!obj)
        pkt.WriteUInt8(0); // empty string if not found
    else
        pkt.WriteString(obj->GetName());

    sess->SendPacket(pkt);
}
int StateLobby::OnValidateCharacterName (IPacket &packet)
{
    std::string name = packet.Read();

    if (!packet.EndOfStream())
        return MSG_ERROR_SIZE;

    if (IsNameValid(name))
    {
        boost::shared_ptr<OPacket> pkt(new OPacket);
        srv_pkt::Lobby(pkt,srv_pkt::LOBBY_ACTION_VALIDATE_NAME);
        m_connection->Send(pkt);
    }

    return MSG_SUCCESS;
}
void WardenMac::RequestHash()
{
    TC_LOG_DEBUG("warden", "Request hash");

    // Create packet structure
    WardenHashRequest Request;
    Request.Command = WARDEN_SMSG_HASH_REQUEST;
    memcpy(Request.Seed, _seed, 16);

    // Encrypt with warden RC4 key.
    EncryptData((uint8*)&Request, sizeof(WardenHashRequest));

    WorldPacket pkt(SMSG_WARDEN_DATA, sizeof(WardenHashRequest)+4);
    pkt << uint32(sizeof(WardenHashRequest));
    pkt.append((uint8*)&Request, sizeof(WardenHashRequest));
    _session->SendPacket(&pkt);
}
Exemple #9
0
void Client::sendLegacyInit(const std::string &playerName, const std::string &playerPassword)
{
	NetworkPacket pkt(TOSERVER_INIT_LEGACY,
			1 + PLAYERNAME_SIZE + PASSWORD_SIZE + 2 + 2);

	pkt << (u8) SER_FMT_VER_HIGHEST_READ;
	
	std::string tmp = playerName;
	tmp.resize(tmp.size()+PLAYERNAME_SIZE);
	pkt.putRawString(tmp.c_str(),PLAYERNAME_SIZE);
	tmp = playerPassword;
	tmp.resize(tmp.size()+PASSWORD_SIZE);
	pkt.putRawString(tmp.c_str(), PASSWORD_SIZE);
	pkt << (u16) CLIENT_PROTOCOL_VERSION_MIN << (u16) CLIENT_PROTOCOL_VERSION_MAX;

	Send(&pkt);
}
Exemple #10
0
void Unit::StartMoving(MoveDirectionElement dir)
{
    if ((m_moveMask & dir) != 0)
        return;

    SmartPacket pkt(SP_MOVE_START_DIRECTION);
    pkt.WriteUInt64(GetGUID());
    pkt.WriteUInt8(dir);
    SendPacketToSorroundings(pkt);

    // if started movement, set timers for movement update
    if (m_moveMask == 0)
        m_lastMovementUpdate = getMSTime();

    m_moveMask |= dir;
    UpdateMovementVector();
}
int StateLobby::OnListCharacter (IPacket &packet)
{
    if (!packet.EndOfStream())
        return MSG_ERROR_SIZE;

    if (!m_loaded)
    {
        LoadCharacters();
        m_loaded = true;
    }

    boost::shared_ptr<OPacket> pkt(new OPacket);
    srv_pkt::Lobby(pkt,m_player_list);
    m_connection->Send(pkt);

    return MSG_SUCCESS;
}
void WardenWin::InitializeModule()
{
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
    sLog->outDebug(LOG_FILTER_WARDEN, "Initialize module");
#endif

    // Create packet structure
    WardenInitModuleRequest Request;
    Request.Command1 = WARDEN_SMSG_MODULE_INITIALIZE;
    Request.Size1 = 20;
    Request.Unk1 = 1;
    Request.Unk2 = 0;
    Request.Type = 1;
    Request.String_library1 = 0;
    Request.Function1[0] = 0x00024F80;                      // 0x00400000 + 0x00024F80 SFileOpenFile
    Request.Function1[1] = 0x000218C0;                      // 0x00400000 + 0x000218C0 SFileGetFileSize
    Request.Function1[2] = 0x00022530;                      // 0x00400000 + 0x00022530 SFileReadFile
    Request.Function1[3] = 0x00022910;                      // 0x00400000 + 0x00022910 SFileCloseFile
    Request.CheckSumm1 = BuildChecksum(&Request.Unk1, 20);

    Request.Command2 = WARDEN_SMSG_MODULE_INITIALIZE;
    Request.Size2 = 8;
    Request.Unk3 = 4;
    Request.Unk4 = 0;
    Request.String_library2 = 0;
    Request.Function2 = 0x00419D40;                         // 0x00400000 + 0x00419D40 FrameScript::GetText
    Request.Function2_set = 1;
    Request.CheckSumm2 = BuildChecksum(&Request.Unk2, 8);

    Request.Command3 = WARDEN_SMSG_MODULE_INITIALIZE;
    Request.Size3 = 8;
    Request.Unk5 = 1;
    Request.Unk6 = 1;
    Request.String_library3 = 0;
    Request.Function3 = 0x0046AE20;                         // 0x00400000 + 0x0046AE20 PerformanceCounter
    Request.Function3_set = 1;
    Request.CheckSumm3 = BuildChecksum(&Request.Unk5, 8);

    // Encrypt with warden RC4 key.
    EncryptData((uint8*)&Request, sizeof(WardenInitModuleRequest));

    WorldPacket pkt(SMSG_WARDEN_DATA, sizeof(WardenInitModuleRequest));
    pkt.append((uint8*)&Request, sizeof(WardenInitModuleRequest));
    _session->SendPacket(&pkt);
}
Exemple #13
0
bool Client::sendModChannelMessage(const std::string &channel, const std::string &message)
{
	if (!m_modchannel_mgr->canWriteOnChannel(channel))
		return false;

	if (message.size() > STRING_MAX_LEN) {
		warningstream << "ModChannel message too long, dropping before sending "
				<< " (" << message.size() << " > " << STRING_MAX_LEN << ", channel: "
				<< channel << ")" << std::endl;
		return false;
	}

	// @TODO: do some client rate limiting
	NetworkPacket pkt(TOSERVER_MODCHANNEL_MSG, 2 + channel.size() + 2 + message.size());
	pkt << channel << message;
	Send(&pkt);
	return true;
}
void PacketHandlers::HandleCharacterListRequest(Session* sess, SmartPacket& packet)
{
    std::list<CharacterBaseRecord> charList;
    // retrieve character list
    sCharacterStorage->GetCharacterListForAccount(sess->GetAccountId(), charList);

    SmartPacket pkt(SP_CHARACTER_LIST);

    pkt.WriteUInt8((uint8_t)charList.size());   // count
    for (CharacterBaseRecord &rec : charList)
    {
        pkt.WriteUInt32(rec.guid);              // guid
        pkt.WriteString(rec.name.c_str());      // name
        pkt.WriteUInt16(rec.level);             // level
    }

    sess->SendPacket(pkt);
}
Exemple #15
0
	void encode_audio_frame(core::read_frame& frame)
	{			
		auto c = audio_st_->codec;

		boost::range::push_back(audio_buf_, convert_audio(frame, c));
		
		std::size_t frame_size = c->frame_size;
		auto input_audio_size = frame_size * av_get_bytes_per_sample(c->sample_fmt) * c->channels;
		
		while(audio_buf_.size() >= input_audio_size)
		{
			safe_ptr<AVPacket> pkt(new AVPacket, [](AVPacket* p)
			{
				av_free_packet(p);
				delete p;
			});
			av_init_packet(pkt.get());

			if(frame_size > 1)
			{								
				pkt->size = avcodec_encode_audio(c, audio_outbuf_.data(), audio_outbuf_.size(), reinterpret_cast<short*>(audio_buf_.data()));
				audio_buf_.erase(audio_buf_.begin(), audio_buf_.begin() + input_audio_size);
			}
			else
			{
				audio_outbuf_ = std::move(audio_buf_);		
				audio_buf_.clear();
				pkt->size = audio_outbuf_.size();
				pkt->data = audio_outbuf_.data();
			}
		
			if(pkt->size == 0)
				return;

			if (c->coded_frame && c->coded_frame->pts != AV_NOPTS_VALUE)
				pkt->pts = av_rescale_q(c->coded_frame->pts, c->time_base, audio_st_->time_base);

			pkt->flags		 |= AV_PKT_FLAG_KEY;
			pkt->stream_index = audio_st_->index;
			pkt->data		  = reinterpret_cast<uint8_t*>(audio_outbuf_.data());
		
			av_interleaved_write_frame(oc_.get(), pkt.get());
		}
	}
Exemple #16
0
void WardenBase::RequestModule()
{
    sLog->outStaticDebug("Request module");

    // Create packet structure
    WardenModuleUse Request;
    Request.Command = WARDEN_SMSG_MODULE_USE;

    memcpy(Request.Module_Id, Module->ID, 16);
    memcpy(Request.Module_Key, Module->Key, 16);
    Request.Size = Module->CompressedSize;

    // Encrypt with warden RC4 key.
    EncryptData((uint8*)&Request, sizeof(WardenModuleUse));

    WorldPacket pkt(SMSG_WARDEN_DATA, sizeof(WardenModuleUse));
    pkt.append((uint8*)&Request, sizeof(WardenModuleUse));
    Client->SendPacket(&pkt);
}
Exemple #17
0
void Warden::RequestModule()
{
    sLog->outDebug(LOG_FILTER_WARDEN, "Request module");

    // Create packet structure
    WardenModuleUse request;
    request.Command = WARDEN_SMSG_MODULE_USE;

    memcpy(request.ModuleId, _module->Id, 16);
    memcpy(request.ModuleKey, _module->Key, 16);
    request.Size = _module->CompressedSize;

    // Encrypt with warden RC4 key.
    EncryptData((uint8*)&request, sizeof(WardenModuleUse));

    WorldPacket pkt(SMSG_WARDEN_DATA, sizeof(WardenModuleUse));
    pkt.append((uint8*)&request, sizeof(WardenModuleUse));
    _session->SendPacket(&pkt);
}
Exemple #18
0
void Client::sendPlayerItem(u16 item)
{
	Player *myplayer = m_env.getLocalPlayer();
	if(myplayer == NULL)
		return;

	u16 our_peer_id = m_con.GetPeerID();

	// Set peer id if not set already
	if(myplayer->peer_id == PEER_ID_INEXISTENT)
		myplayer->peer_id = our_peer_id;
	assert(myplayer->peer_id == our_peer_id);

	NetworkPacket pkt(TOSERVER_PLAYERITEM, 2);

	pkt << item;

	Send(&pkt);
}
Exemple #19
0
void Client::interact(u8 action, const PointedThing& pointed)
{
	if(m_state != LC_Ready) {
		errorstream << "Client::interact() "
				"Canceled (not connected)"
				<< std::endl;
		return;
	}

	LocalPlayer *myplayer = m_env.getLocalPlayer();
	if (myplayer == NULL)
		return;

	/*
		[0] u16 command
		[2] u8 action
		[3] u16 item
		[5] u32 length of the next item (plen)
		[9] serialized PointedThing
		[9 + plen] player position information
		actions:
		0: start digging (from undersurface) or use
		1: stop digging (all parameters ignored)
		2: digging completed
		3: place block or item (to abovesurface)
		4: use item
		5: perform secondary action of item
	*/

	NetworkPacket pkt(TOSERVER_INTERACT, 1 + 2 + 0);

	pkt << action;
	pkt << (u16)getPlayerItem();

	std::ostringstream tmp_os(std::ios::binary);
	pointed.serialize(tmp_os);

	pkt.putLongString(tmp_os.str());

	writePlayerPos(myplayer, &m_env.getClientMap(), &pkt);

	Send(&pkt);
}
Exemple #20
0
void Client::sendInventoryFields(const std::string &formname,
		const StringMap &fields)
{
	size_t fields_size = fields.size();
	FATAL_ERROR_IF(fields_size > 0xFFFF, "Unsupported number of inventory fields");

	NetworkPacket pkt(TOSERVER_INVENTORY_FIELDS, 0);
	pkt << formname << (u16) (fields_size & 0xFFFF);

	StringMap::const_iterator it;
	for (it = fields.begin(); it != fields.end(); ++it) {
		const std::string &name  = it->first;
		const std::string &value = it->second;
		pkt << name;
		pkt.putLongString(value);
	}

	Send(&pkt);
}
Exemple #21
0
void PlayerSubtitle::tryReload(int flag)
{
    if (!m_player)
        return;
    if (!m_player->isPlaying())
        return;
    const int kReloadInternal = 1;
    const int kReloadExternal = 1<<1;
    if (flag & kReloadExternal) {
        if (!m_file.isEmpty() && m_enabled) { //engine changed
            m_sub->processHeader(QByteArray(), QByteArray()); // reset
            m_sub->loadAsync();
            return;
        }
    }
    if (!(flag & kReloadInternal)) { // if internal flag is set, try internal first, then fallback to external if internal is failed
        if (!m_enabled)
            return;
        if (flag & kReloadExternal) {
            m_sub->processHeader(QByteArray(), QByteArray()); // reset
            m_sub->loadAsync();
        }
        return;
    }

    const int n = m_player->currentSubtitleStream();
    if (n < 0 || m_tracks.isEmpty() || m_tracks.size() <= n) {
        m_sub->processHeader(QByteArray(), QByteArray()); // reset, null processor
        //try to fallback to external sub if an invalid internal sub track is set
        if ((flag & kReloadExternal) && m_enabled)
            m_sub->loadAsync();
        return;
    }
    QVariantMap track = m_tracks[n].toMap();
    QByteArray codec(track.value("codec").toByteArray());
    QByteArray data(track.value("extra").toByteArray());
    m_sub->processHeader(codec, data);
    Packet pkt(m_current_pkt[n]);
    if (pkt.isValid()) {
        processInternalSubtitlePacket(n, pkt);
    }
}
void PacketHandlers::HandleMoveHeartbeat(Session* sess, SmartPacket& packet)
{
    float x = packet.ReadFloat();
    float y = packet.ReadFloat();

    // TODO: verify if this is possible, anticheat, etc.

    Player* plr = sess->GetPlayer();

    plr->RelocateWithinMap(x, y);

    // TODO: timer, limit maximum count of heartbeats per second

    SmartPacket pkt(SP_MOVE_HEARTBEAT);
    pkt.WriteUInt64(plr->GetGUID());
    pkt.WriteUInt8(plr->GetMoveMask());
    pkt.WriteFloat(x);
    pkt.WriteFloat(y);
    plr->SendPacketToSorroundings(pkt);
}
Exemple #23
0
void Client::sendNodemetaFields(v3s16 p, const std::string &formname,
		const std::map<std::string, std::string> &fields)
{
	size_t fields_size = fields.size();

	FATAL_ERROR_IF(fields_size > 0xFFFF, "Unsupported number of nodemeta fields");

	NetworkPacket pkt(TOSERVER_NODEMETA_FIELDS, 0);

	pkt << p << formname << (u16) (fields_size & 0xFFFF);

	for(std::map<std::string, std::string>::const_iterator
			i = fields.begin(); i != fields.end(); i++) {
		const std::string &name = i->first;
		const std::string &value = i->second;
		pkt << name;
		pkt.putLongString(value);
	}

	Send(&pkt);
}
Exemple #24
0
	void encode_video_frame(core::read_frame& frame)
	{ 
		auto c = video_st_->codec;
		
		auto in_time  = static_cast<double>(in_frame_number_) / format_desc_.fps;
		auto out_time = static_cast<double>(out_frame_number_) / (static_cast<double>(c->time_base.den) / static_cast<double>(c->time_base.num));
		
		in_frame_number_++;

		if(out_time - in_time > 0.01)
			return;
 
		auto av_frame = convert_video(frame, c);
		av_frame->interlaced_frame	= format_desc_.field_mode != core::field_mode::progressive;
		av_frame->top_field_first	= format_desc_.field_mode == core::field_mode::upper;
		av_frame->pts				= out_frame_number_++;

		int out_size = THROW_ON_ERROR2(avcodec_encode_video(c, video_outbuf_.data(), video_outbuf_.size(), av_frame.get()), "[ffmpeg_consumer]");
		if(out_size == 0)
			return;
				
		safe_ptr<AVPacket> pkt(new AVPacket, [](AVPacket* p)
		{
			av_free_packet(p);
			delete p;
		});
		av_init_packet(pkt.get());
 
		if (c->coded_frame->pts != AV_NOPTS_VALUE)
			pkt->pts = av_rescale_q(c->coded_frame->pts, c->time_base, video_st_->time_base);

		if(c->coded_frame->key_frame)
			pkt->flags |= AV_PKT_FLAG_KEY;

		pkt->stream_index	= video_st_->index;
		pkt->data			= video_outbuf_.data();
		pkt->size			= out_size;
 			
		av_interleaved_write_frame(oc_.get(), pkt.get());		
	}
int StateGame::OnExchangeClose (IPacket &packet)
{
    if (!packet.EndOfStream())
        return MSG_ERROR_SIZE;

    bool closed = false;

    boost::shared_ptr<Player> player = static_cast<srv::Connection*>(m_connection)->GetPlayer();

    if (!player)
        return MSG_ERROR;

    if (closed)
    {
        player->set_invitation_player(0);

        player->close_exchange();
    }

    boost::shared_ptr<OPacket> pkt(new OPacket);

    srv_pkt::ExchangeClose(pkt,closed);
    m_connection->Send(pkt);

    boost::shared_ptr<Player> target = get_invitation_player(player);

    if (target)
    {
        target->set_invitation_player(0);

        target->close_exchange();

        pkt.reset(new OPacket);

        srv_pkt::ExchangeClose(pkt,closed);
        m_server->Send(pkt,target->ConnectionID());
    }

    return MSG_SUCCESS;
}
/** \brief write data on the \ref socket_full_udp_t
 */
size_t	socket_full_udp_t::send(const void *data_ptr, size_t data_len)	throw()
{
	nlay_err_t	nlay_err;
	size_t		sent_len;
	// build the packet
	pkt_t		pkt(data_ptr, data_len);
	// go thru nlay_full_t
	nlay_err	= nlay_full->pkt_from_upper( pkt );
	if( !nlay_err.succeed() ){
		KLOG_ERR("NLAAAAAAAAAAAAYYYYYYYYYYYYYYYY RETURNNNNNNNN in PKT_FROM_UPPER=" << nlay_err);
		return 0;
	}
	// send it thru udp_full_t
	sent_len	= udp_full->send(pkt.get_data(), pkt.get_len());
#if 0 // TMP:
	if( sent_len != pkt.get_len() ){
		DBG_ASSERT(0);	// TODO dunno what error to return
	}
#endif
	// return no error
	return sent_len;
}
Exemple #27
0
/*
	u16 command
	u16 number of files requested
	for each file {
		u16 length of name
		string name
	}
*/
void Client::request_media(const std::vector<std::string> &file_requests)
{
	std::ostringstream os(std::ios_base::binary);
	writeU16(os, TOSERVER_REQUEST_MEDIA);
	size_t file_requests_size = file_requests.size();

	FATAL_ERROR_IF(file_requests_size > 0xFFFF, "Unsupported number of file requests");

	// Packet dynamicly resized
	NetworkPacket pkt(TOSERVER_REQUEST_MEDIA, 2 + 0);

	pkt << (u16) (file_requests_size & 0xFFFF);

	for (const std::string &file_request : file_requests) {
		pkt << file_request;
	}

	Send(&pkt);

	infostream << "Client: Sending media request list to server ("
			<< file_requests.size() << " files. packet size)" << std::endl;
}
bool StateLobby::IsNameValid (const std::string &name)
{
    ///CHECK THE NAME LENGTH DONT EXCEEDS THE MAX
    if (name.length() > MAX_PLAYER_NAME_LENTH)
        return false;

    boost::shared_ptr<OPacket> pkt(new OPacket);

    ///CHECK FOR INVALID CHARACTER
    if (name.find_first_of(m_ch_filter) != std::string::npos)
    {
        srv_pkt::Lobby(pkt,srv_pkt::LOBBY_ACTION_VALIDATE_NAME,srv_pkt::LOBBY_ERROR_NAME_EXIST);
        m_connection->Send(pkt);
        return false;
    }

    std::vector<std::string>::const_iterator i;
    for ( i = m_substr_filter_list.begin(); i != m_substr_filter_list.end(); ++i)
    {
        if (name.find(*i) != std::string::npos)
        {
            srv_pkt::Lobby(pkt,srv_pkt::LOBBY_ACTION_VALIDATE_NAME,srv_pkt::LOBBY_ERROR_NAME_EXIST);
            m_connection->Send(pkt);
            return false;
        }
    }

    ///CHECK THAT THE NAME ISNT ALREDY IN USE
    DB::PLAYER::Check check;

    if (!check(m_server->DBConnection(),name))
    {
        srv_pkt::Lobby(pkt,srv_pkt::LOBBY_ACTION_VALIDATE_NAME,srv_pkt::LOBBY_ERROR_NAME_EXIST);
        m_connection->Send(pkt);
        return false;
    }

    return true;
}
Exemple #29
0
void WardenMac::RequestData()
{
    sLog.outDebug("Request data");

    ByteBuffer buff;
    buff << uint8(WARDEN_SMSG_CHEAT_CHECKS_REQUEST);

    std::string str = "Test string!";

    buff << uint8(str.size());
    buff.append(str.c_str(), str.size());

    buff.hexlike();

    // Encrypt with warden RC4 key.
    EncryptData(const_cast<uint8*>(buff.contents()), buff.size());

    WorldPacket pkt(SMSG_WARDEN_DATA, buff.size());
    pkt.append(buff);
    Client->SendPacket(&pkt);

    m_WardenDataSent = true;
}
bool ResourceStreamService::SendNextResourceStreamData(ResourceStreamRecord* rec)
{
    uint8_t* data = new uint8_t[DEFAULT_STREAM_DATA_SIZE];

    size_t res = fread(data, 1, DEFAULT_STREAM_DATA_SIZE, rec->src);
    if (res == 0)
    {
        FinishStream(rec);
        return false;
    }

    SmartPacket pkt(SP_RESOURCE_DATA);
    pkt.WriteUInt8(rec->type);
    pkt.WriteUInt32(rec->id);
    pkt.WriteUInt16((uint16_t)res);
    for (size_t i = 0; i < res; i++)
        pkt.WriteUInt8(data[i]);
    sNetwork->SendPacketToSession(pkt, rec->sessionId);

    delete data;

    return true;
}