예제 #1
0
DTerr DeviceNetworkSockets::tcp_recv (NetworkPacket &packet, const NetworkSocket &socket)
{
	if (socket.is_empty())
		return DT3_ERR_NONE;

	DTint socket_raw = *reinterpret_cast<DTint*>(socket.network_socket_data());

    ssize_t size = ::recv(  socket_raw,
                            packet.data(),
                            (DTuint) packet.data_size(),
                            0
                        );
                            

    if (size < 0) {
        packet.set_data_size(0);

        switch (errno) {
            //case EAGAIN:  // Same as EWOULDBLOCK
			case EWOULDBLOCK:	
                return DT3_ERR_NET_WOULD_BLOCK;
			default:			
                LOG_MESSAGE << "TCPRecv: recv: " << strerror(errno) << " (" << (DTuint) errno << ")";
                return DT3_ERR_NET_UNKNOWN;
		};
	} else {
        packet.set_data_size(size);
    }

	return DT3_ERR_NONE;
}
예제 #2
0
DTerr DeviceNetworkSockets::udp_recv (NetworkPacket &packet, const NetworkSocket &socket)
{    
	if (socket.is_empty())
		return DT3_ERR_NONE;

	DTint socket_raw = *reinterpret_cast<DTint*>(socket.network_socket_data());

    struct sockaddr from;
    socklen_t       from_size = sizeof(from);

    DTsize size = ::recvfrom(   socket_raw,
                                packet.data(),
                                (DTuint) packet.data_size(),
                                0, 
                                &from,
                                &from_size
                            );
                            
    if (size > 0) {
        packet.set_network_address( address_to_string(&from) );
        packet.set_data_size(size);
    
	} else {	
		switch (errno) {
			case EWOULDBLOCK:	return DT3_ERR_NET_WOULD_BLOCK;
			default:			return DT3_ERR_NET_UNKNOWN;
		};
	}

	return DT3_ERR_NONE;

}
예제 #3
0
DTerr DeviceNetworkSockets::udp_send (const NetworkPacket &packet, const NetworkSocket &socket)
{
	if (socket.is_empty())
		return DT3_ERR_NONE;

	DTint socket_raw = *reinterpret_cast<DTint*>(socket.network_socket_data());
	
	struct sockaddr_storage sast = string_to_address(packet.network_address().network_address());
    struct sockaddr *sa = (struct sockaddr *) &sast;

#if DT3_OS == DT3_ANDROID
    ::sendto(   socket_raw, 
                packet.data(),
                packet.data_size(),
                0, 
                sa,
                sizeof(sockaddr));
#else
    ::sendto(   socket_raw, 
                packet.data(),
                (DTuint) packet.data_size(),
                0, 
                sa,
                sa->sa_len);
                
#endif

	return DT3_ERR_NONE;
}
예제 #4
0
void Controller::shutDown(void)
{
	NetworkPacket *grid = editor->writeToSerialization();
	
	setDataForUserInterfaceKey("environment", grid->getNetworkLength(), (void *) grid);
	
	free(grid);
}
예제 #5
0
void Network::SendServerPacket(NetworkPacket packet, const bool reliable)
{
	if(_isConnected && _isServer)
	{	
		ENetPacket* enetPacket = enet_packet_create(packet.GetBytes(), packet.GetSize(), reliable);

		enet_host_broadcast(_host, 0, enetPacket);
	}
}
예제 #6
0
s32 NetworkBaseUDP::sendPacketToAddress(
    SOCKET Socket, const NetworkPacket &Packet, const sockaddr_in &Address)
{
    /* Send network packet to raw address */
    return sendto(
        Socket,
        Packet.getRealBuffer(),
        Packet.getRealBufferSize(),
        0,
        (sockaddr*)&Address,
        sizeof(sockaddr_in)
    );
}
예제 #7
0
void MuxDemux :: remote_input_notify(Ticks_t when, void* data, int port)
{
    NetworkPacket* pkt = (NetworkPacket*)data;
    if(pkt->get_type() == CREDIT_MSG_TYPE) {
        //ignore
    }
    else {
        if(m_input_msg_ticks.size() > 0) {
            assert(m_input_msg_ticks.back() <= when);
        }
        m_input_msg_ticks.push_back(when);
    }
}
예제 #8
0
void Network::SendPacket(NetworkPacket packet, const bool reliable)
{
	if(_isConnected)
	{
		ENetPacket* enetPacket = enet_packet_create(packet.GetBytes(), packet.GetSize(), reliable);
		if(!_isServer)
			enet_peer_send(_peer, 0, enetPacket);
		else
		{
			_mutex.lock();
			_receivedPackets.push_back(NetworkPacket(enetPacket,0));
			_mutex.unlock();
		}
	}
}
예제 #9
0
DTerr DeviceNetworkSockets::tcp_send (const NetworkPacket &packet, const NetworkSocket &socket)
{
	if (socket.is_empty())
		return DT3_ERR_NONE;

	DTint socket_raw = *reinterpret_cast<DTint*>(socket.network_socket_data());
	
    ::send(   socket_raw, 
                packet.data(),
                (DTuint) packet.data_size(),
                0
            );

	return DT3_ERR_NONE;
}
예제 #10
0
void UdpMulticastChannel::notify_received(char* data, size_t sz,boost::asio::ip::udp::endpoint sender_endpoint)
{
    std::vector<unsigned>* lost;
    NetworkPacket* packet = new NetworkPacket;
    if (packet->ParseFromArray(data,sz))
    {
        lost = incoming->add_packet(packet);
        if (lost->size() > 0 )
        {
            send_nack(packet,sender_endpoint,lost);
        }
    }
    //std::cout << "Received: " << sz << " bytes " << std::endl;
    receive_from_network();
}
예제 #11
0
bool ReceivedPacketProcessor::process() {

    if (_packets.size() == 0) {
        _waitingOnPacketsMutex.lock();
        _hasPackets.wait(&_waitingOnPacketsMutex);
        _waitingOnPacketsMutex.unlock();
    }
    while (_packets.size() > 0) {
        lock(); // lock to make sure nothing changes on us
        NetworkPacket& packet = _packets.front(); // get the oldest packet
        NetworkPacket temporary = packet; // make a copy of the packet in case the vector is resized on us
        _packets.erase(_packets.begin()); // remove the oldest packet
        _nodePacketCounts[temporary.getNode()->getUUID()]--;
        unlock(); // let others add to the packets
        processPacket(temporary.getNode(), temporary.getByteArray()); // process our temporary copy
    }
    return isStillRunning();  // keep running till they terminate us
}
예제 #12
0
bool ReceivedPacketProcessor::process() {

    // If a derived class handles process sleeping, like the JurisdiciontListener, then it can set
    // this _dontSleep member and we will honor that request.
    if (_packets.size() == 0 && !_dontSleep) {
        const uint64_t RECEIVED_THREAD_SLEEP_INTERVAL = (1000 * 1000)/60; // check at 60fps
        usleep(RECEIVED_THREAD_SLEEP_INTERVAL);
    }
    while (_packets.size() > 0) {

        lock(); // lock to make sure nothing changes on us
        NetworkPacket& packet = _packets.front(); // get the oldest packet
        NetworkPacket temporary = packet; // make a copy of the packet in case the vector is resized on us
        _packets.erase(_packets.begin()); // remove the oldest packet
        unlock(); // let others add to the packets
        processPacket(temporary.getAddress(), temporary.getData(), temporary.getLength()); // process our temporary copy
    }
    return isStillRunning();  // keep running till they terminate us
}
예제 #13
0
void UdpMulticastChannel::read_from_network()
{
    boost::asio::ip::udp::endpoint sender_endpoint;
    unsigned int sz = MAX_PACKET_SIZE;
    std::vector<unsigned>* lost;
    char* data = new char[sz];
    receiver->sync_receive(data,sz,&sender_endpoint);
    NetworkPacket* packet = new NetworkPacket;
    if (packet->ParseFromArray(data,sz))
    {
        lost = incoming->add_packet(packet);
        if (lost->size() > 0 )
        {
            //send message to endpoint to resent data
            //sender->sync_send()
        }
    }

    delete data;
}
예제 #14
0
void Network::DistributePacket(NetworkPacket networkPacket)
{
	int type = networkPacket.GetType();
	if (type >= 0 && type < LAST_TYPE)
	{
		std::list<INetworkListener*>::const_iterator iterator;
		for (iterator = _listeners[type]->begin(); iterator != _listeners[type]->end(); ++iterator)
			(*iterator)->HandleNetworkMessage(networkPacket);
	}
	else
		printf("Unknown PacketType '%s' received", type);
}
예제 #15
0
// We may be called more frequently than we get packets or need to send packets, we may also get called less frequently.
//
// If we're called more often then out target PPS then we will space out our actual sends to be a single packet for multiple
// calls to process. Those calls to proces in which we do not need to send a packet to keep up with our target PPS we will
// just track our call rate (in order to predict our sends per call) but we won't actually send any packets.
//
// When we are called less frequently than we have packets to send, we will send enough packets per call to keep up with our
// target PPS.
//
// We also keep a running total of packets sent over multiple calls to process() so that we can adjust up or down for
// possible rounding error that would occur if we only considered whole integer packet counts per call to process
bool PacketSender::nonThreadedProcess() {
    quint64 now = usecTimestampNow();

    if (_lastProcessCallTime == 0) {
        _lastProcessCallTime = now - _usecsPerProcessCallHint;
    }

    const quint64 MINIMUM_POSSIBLE_CALL_TIME = 10; // in usecs
    const quint64 USECS_PER_SECOND = 1000 * 1000;
    const float ZERO_RESET_CALLS_PER_SECOND = 1; // used in guard against divide by zero

    // keep track of our process call times, so we have a reliable account of how often our caller calls us
    quint64 elapsedSinceLastCall = now - _lastProcessCallTime;
    _lastProcessCallTime = now;
    _averageProcessCallTime.updateAverage(elapsedSinceLastCall);

    float averageCallTime = 0;
    const int TRUST_AVERAGE_AFTER = AVERAGE_CALL_TIME_SAMPLES * 2;
    if (_usecsPerProcessCallHint == 0 || _averageProcessCallTime.getSampleCount() > TRUST_AVERAGE_AFTER) {
        averageCallTime = _averageProcessCallTime.getAverage();
    } else {
        averageCallTime = _usecsPerProcessCallHint;
    }

    if (_packets.size() == 0) {
        // in non-threaded mode, if there's nothing to do, just return, keep running till they terminate us
        return isStillRunning();
    }

    // This only happens once, the first time we get this far... so we can use it as an accurate initialization
    // point for these important timing variables
    if (_lastPPSCheck == 0) {
        _lastPPSCheck = now;
        // pretend like our lifetime began once call cycle for now, this makes our lifetime PPS start out most accurately
        _started = now - (quint64)averageCallTime;
    }


    float averagePacketsPerCall = 0;  // might be less than 1, if our caller calls us more frequently than the target PPS
    int packetsSentThisCall = 0;
    int packetsToSendThisCall = 0;

    // Since we're in non-threaded mode, we need to determine how many packets to send per call to process
    // based on how often we get called... We do this by keeping a running average of our call times, and we determine
    // how many packets to send per call

    // We assume you can't possibly call us less than MINIMUM_POSSIBLE_CALL_TIME apart
    if (averageCallTime <= 0) {
        averageCallTime = MINIMUM_POSSIBLE_CALL_TIME;
    }

    // we can determine how many packets we need to send per call to achieve our desired
    // packets per second send rate.
    float callsPerSecond = USECS_PER_SECOND / averageCallTime;

    // theoretically we could get called less than 1 time per second... but since we're using floats, it really shouldn't be
    // possible to get 0 calls per second, but we will guard agains that here, just in case.
    if (callsPerSecond == 0) {
        callsPerSecond = ZERO_RESET_CALLS_PER_SECOND;
    }

    // This is the average number of packets per call...
    averagePacketsPerCall = _packetsPerSecond / callsPerSecond;
    packetsToSendThisCall = averagePacketsPerCall;

    // if we get called more than 1 per second, we want to mostly divide the packets evenly across the calls...
    // but we want to track the remainder and make sure over the course of a second, we are sending the target PPS
    // e.g.
    //     200pps called 60 times per second...
    //     200/60 = 3.333... so really...
    //     each call we should send 3
    //     every 3rd call we should send 4...
    //     3,3,4,3,3,4...3,3,4 = 200...

    // if we get called less than 1 per second, then we want to send more than our PPS each time...
    // e.g.
    //     200pps called ever 1332.5ms
    //     200 / (1000/1332.5) = 200/(0.7505) = 266.5 packets per call
    //     so...
    //        every other call we should send 266 packets
    //        then on the next call we should send 267 packets

    // So no mater whether or not we're getting called more or less than once per second, we still need to do some bookkeeping
    // to make sure we send a few extra packets to even out our flow rate.
    quint64 elapsedSinceLastCheck = now - _lastPPSCheck;

    // we might want to tun this in the future and only check after a certain number of call intervals. for now we check
    // each time and adjust accordingly
    const float CALL_INTERVALS_TO_CHECK = 1;
    const float MIN_CALL_INTERVALS_PER_RESET = 5;

    // we will reset our check PPS and time each second (callsPerSecond) or at least 5 calls (if we get called less frequently
    // than 5 times per second) This gives us sufficient smoothing in our packet adjustments
    float callIntervalsPerReset = std::max(callsPerSecond, MIN_CALL_INTERVALS_PER_RESET);

    if  (elapsedSinceLastCheck > (averageCallTime * CALL_INTERVALS_TO_CHECK)) {
        float ppsOverCheckInterval = (float)_packetsOverCheckInterval;
        float ppsExpectedForCheckInterval = (float)_packetsPerSecond * ((float)elapsedSinceLastCheck / (float)USECS_PER_SECOND);

        if (ppsOverCheckInterval < ppsExpectedForCheckInterval) {
            int adjust = ppsExpectedForCheckInterval - ppsOverCheckInterval;
            packetsToSendThisCall += adjust;
        } else if (ppsOverCheckInterval > ppsExpectedForCheckInterval) {
            int adjust = ppsOverCheckInterval - ppsExpectedForCheckInterval;
            packetsToSendThisCall -= adjust;
        }

        // now, do we want to reset the check interval? don't want to completely reset, because we would still have
        // a rounding error. instead, we check to see that we've passed the reset interval (which is much larger than
        // the check interval), and on those reset intervals we take the second half average and keep that for the next
        // interval window...
        if (elapsedSinceLastCheck > (averageCallTime * callIntervalsPerReset)) {
            // Keep average packets and time for "second half" of check interval
            _lastPPSCheck += (elapsedSinceLastCheck / 2);
            _packetsOverCheckInterval = (_packetsOverCheckInterval / 2);

            elapsedSinceLastCheck = now - _lastPPSCheck;
        }
    }

    int packetsLeft = _packets.size();

    // Now that we know how many packets to send this call to process, just send them.
    while ((packetsSentThisCall < packetsToSendThisCall) && (packetsLeft > 0)) {
        lock();
        NetworkPacket& packet = _packets.front();
        NetworkPacket temporary = packet; // make a copy
        _packets.erase(_packets.begin());
        packetsLeft = _packets.size();
        unlock();

        // send the packet through the NodeList...
        NodeList::getInstance()->writeDatagram(temporary.getByteArray(), temporary.getDestinationNode());
        packetsSentThisCall++;
        _packetsOverCheckInterval++;
        _totalPacketsSent++;
        _totalBytesSent += temporary.getByteArray().size();
        
        emit packetSent(temporary.getByteArray().size());
        
        _lastSendTime = now;
    }
    return isStillRunning();
}
예제 #16
0
void QueryHandler::HandleMsg( NetworkPacket & recv_data, GameClient *pClient )
{
    NetworkPacket data;
    char f[256];
    sprintf(f, "WORLD: Query Opcode 0x%.4X", recv_data.opcode);
    LOG.outString( f );
    switch (recv_data.opcode)
    {
        case CMSG_NAME_QUERY:
        {
            uint32 guid;
            memcpy(&guid, recv_data.data, 4);

            uint32 race = 0, gender = 0, cl = 0;
            char name[32];

            std::map<uint32, Character*>::iterator itr = WORLDSERVER.mCharacters.find(guid);
            if (itr == WORLDSERVER.mCharacters.end())
            {

                DatabaseInterface *dbi = DATABASE.createDatabaseInterface( );

                if (!dbi->GetPlayerNameFromGUID(1, (uint8*)name))
                    LOG.outString( "No player name found for this guid" );

                DATABASE.removeDatabaseInterface( dbi );
            }
            else
            {
                Character *pChar = WORLDSERVER.mCharacters[guid];
                race = pChar->getRace();
                gender = pChar->getGender();
                cl = pChar->getClass();
                strcpy(name, pChar->getName());
            }

            data.Clear();
            data.length = 8 + strlen(name)+ 1 + 4*sizeof(uint32);
            data.data = new uint8[ data.length ];
            data.opcode = SMSG_NAME_QUERY_RESPONSE;

            LOG.outString( name );

            data << guid << uint32(0);
            data << (std::string)name << uint32(0);
            data << race << gender << cl;
            // FIXME, something wrong here, crashes client.
            pClient->SendMsg( &data );
        } break;

        case CMSG_QUERY_TIME:
        {
            data.Clear();
            data.Initialize(4, SMSG_QUERY_TIME_RESPONSE);

            data << (int32)time(NULL);
            pClient->SendMsg(&data);
        }break;

        case CMSG_CREATURE_QUERY:
        {
            uint32 entry=0;
            uint32 guid=0;

            recv_data.ReadData(entry);
            recv_data.ReadData(guid);

            uint8 *name = 0;

            /*std::map<uint32, uint8*>::iterator itr = WORLDSERVER.mCreatureNames.find(entry);
            if (itr == WORLDSERVER.mCreatureNames.end()){
                WPAssert(!"invalid creature entry");
            }*/

            name = WORLDSERVER.mCreatureNames[entry];
            if (!name)
                name = (uint8 *)"ERROR_NO_CREATURENAME_FOR_ENTRY";
            //    return;
            printf(" WORLD: CMSG_CREATURE_QUERY '%s'\n", name );

            uint16 namesize = strlen((char*)name)+1;

            data.Clear();
            data.Initialize(4+namesize+16, SMSG_CREATURE_QUERY_RESPONSE);
            data << (uint32)entry;
            strcpy((char*)data.data+4, (char*)name);

            uint8 somedata[] =
            {
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00
            };

            memcpy(data.data+namesize+4, somedata, 16);
            pClient->SendMsg(&data);
        }break;

        case CMSG_GAMEOBJECT_QUERY:
        {
            data.Initialize( 64, SMSG_GAMEOBJECT_QUERY_RESPONSE );
            //TODO: Check the database for the ENTRY (First long) and obtain all the details from there...
            data << uint32( 0x00000787 ) << uint32( 0x00000013 ) << uint32( 0x0000088e );
            data << uint32( 0x6c69614d ) << uint32( 0x00786f62 );
            data << uint32( 0x00000000 ) << uint32( 0x00000000 ) << uint32( 0x00000000 );
            data << uint32( 0x00000000 );
            data << uint32( 0 ) << uint32( 0 ) << uint32( 0 ) << uint32( 0 ) << uint32( 0 ) << uint32( 0 );
            data << uint16( 0 ) << uint8( 0 );

            /*
            00 00 07 87 00 00 00 08 00 00 00 C0 54 F9 EC 01
            04 00 00 00 0A 00 00 00 12 00 00 00 00 00 00 08
            00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
            00 00 00 00 00 00 00 00 00 00 00 4F 52 44 45 52
            */

            /* Mailbox
            22 33 02 00 // ENTRY
            13 00 00 00 // Unknown
            8e 08 00 00 // Display_id
            4d 61 69 6c | 62 6f 78 00 // Mailbox (Null terminated)
            00 00 00 00 // 1
            00 00 00 00 // 2
            00 00 00 00 // 3
            00 00 00 00 // 4
            00 00 00 00 // 5
            00 00 00 00 // 6
            00 00 00 00 // 7
            00 00 00 00 // 8
            00 00 00 00 // 9
            00 00 00 00 // 10
            00 00 00    // 11
            */

            pClient->SendMsg( &data );
            LOG.outString( "WORLD: Sent Object Query Response." );
        }break;
    }
}
예제 #17
0
void TestConnection::testConnectSendReceive()
{
	DSTACK("TestConnection::Run");

	/*
		Test some real connections

		NOTE: This mostly tests the legacy interface.
	*/

	u32 proto_id = 0xad26846a;

	Handler hand_server("server");
	Handler hand_client("client");

	Address address(0, 0, 0, 0, 30001);
	Address bind_addr(0, 0, 0, 0, 30001);
	/*
	 * Try to use the bind_address for servers with no localhost address
	 * For example: FreeBSD jails
	 */
	std::string bind_str = g_settings->get("bind_address");
	try {
		bind_addr.Resolve(bind_str.c_str());

		if (!bind_addr.isIPv6()) {
			address = bind_addr;
		}
	} catch (ResolveError &e) {
	}

	infostream << "** Creating server Connection" << std::endl;
	con::Connection server(proto_id, 512, 5.0, false, &hand_server);
	server.Serve(address);

	infostream << "** Creating client Connection" << std::endl;
	con::Connection client(proto_id, 512, 5.0, false, &hand_client);

	UASSERT(hand_server.count == 0);
	UASSERT(hand_client.count == 0);

	sleep_ms(50);

	Address server_address(127, 0, 0, 1, 30001);
	if (address != Address(0, 0, 0, 0, 30001)) {
		server_address = bind_addr;
	}

	infostream << "** running client.Connect()" << std::endl;
	client.Connect(server_address);

	sleep_ms(50);

	// Client should not have added client yet
	UASSERT(hand_client.count == 0);

	try {
		NetworkPacket pkt;
		infostream << "** running client.Receive()" << std::endl;
		client.Receive(&pkt);
		infostream << "** Client received: peer_id=" << pkt.getPeerId()
			<< ", size=" << pkt.getSize() << std::endl;
	} catch (con::NoIncomingDataException &e) {
	}

	// Client should have added server now
	UASSERT(hand_client.count == 1);
	UASSERT(hand_client.last_id == 1);
	// Server should not have added client yet
	UASSERT(hand_server.count == 0);

	sleep_ms(100);

	try {
		NetworkPacket pkt;
		infostream << "** running server.Receive()" << std::endl;
		server.Receive(&pkt);
		infostream << "** Server received: peer_id=" << pkt.getPeerId()
				<< ", size=" << pkt.getSize()
				<< std::endl;
	} catch (con::NoIncomingDataException &e) {
		// No actual data received, but the client has
		// probably been connected
	}

	// Client should be the same
	UASSERT(hand_client.count == 1);
	UASSERT(hand_client.last_id == 1);
	// Server should have the client
	UASSERT(hand_server.count == 1);
	UASSERT(hand_server.last_id == 2);

	//sleep_ms(50);

	while (client.Connected() == false) {
		try {
			NetworkPacket pkt;
			infostream << "** running client.Receive()" << std::endl;
			client.Receive(&pkt);
			infostream << "** Client received: peer_id=" << pkt.getPeerId()
				<< ", size=" << pkt.getSize() << std::endl;
		} catch (con::NoIncomingDataException &e) {
		}
		sleep_ms(50);
	}

	sleep_ms(50);

	try {
		NetworkPacket pkt;
		infostream << "** running server.Receive()" << std::endl;
		server.Receive(&pkt);
		infostream << "** Server received: peer_id=" << pkt.getPeerId()
				<< ", size=" << pkt.getSize()
				<< std::endl;
	} catch (con::NoIncomingDataException &e) {
	}

	/*
		Simple send-receive test
	*/
	{
		NetworkPacket pkt;
		pkt.putRawPacket((u8*) "Hello World !", 14, 0);

		Buffer<u8> sentdata = pkt.oldForgePacket();

		infostream<<"** running client.Send()"<<std::endl;
		client.Send(PEER_ID_SERVER, 0, &pkt, true);

		sleep_ms(50);

		NetworkPacket recvpacket;
		infostream << "** running server.Receive()" << std::endl;
		server.Receive(&recvpacket);
		infostream << "** Server received: peer_id=" << pkt.getPeerId()
				<< ", size=" << pkt.getSize()
				<< ", data=" << (const char*)pkt.getU8Ptr(0)
				<< std::endl;

		Buffer<u8> recvdata = pkt.oldForgePacket();

		UASSERT(memcmp(*sentdata, *recvdata, recvdata.getSize()) == 0);
	}

	u16 peer_id_client = 2;
	/*
		Send a large packet
	*/
	{
		const int datasize = 30000;
		NetworkPacket pkt(0, datasize);
		for (u16 i=0; i<datasize; i++) {
			pkt << (u8) i/4;
		}

		infostream << "Sending data (size=" << datasize << "):";
		for (int i = 0; i < datasize && i < 20; i++) {
			if (i % 2 == 0)
				infostream << " ";
			char buf[10];
			snprintf(buf, 10, "%.2X",
				((int)((const char *)pkt.getU8Ptr(0))[i]) & 0xff);
			infostream<<buf;
		}
		if (datasize > 20)
			infostream << "...";
		infostream << std::endl;

		Buffer<u8> sentdata = pkt.oldForgePacket();

		server.Send(peer_id_client, 0, &pkt, true);

		//sleep_ms(3000);

		Buffer<u8> recvdata;
		infostream << "** running client.Receive()" << std::endl;
		u16 peer_id = 132;
		u16 size = 0;
		bool received = false;
		u32 timems0 = porting::getTimeMs();
		for (;;) {
			if (porting::getTimeMs() - timems0 > 5000 || received)
				break;
			try {
				NetworkPacket pkt;
				client.Receive(&pkt);
				size = pkt.getSize();
				peer_id = pkt.getPeerId();
				recvdata = pkt.oldForgePacket();
				received = true;
			} catch (con::NoIncomingDataException &e) {
			}
			sleep_ms(10);
		}
		UASSERT(received);
		infostream << "** Client received: peer_id=" << peer_id
			<< ", size=" << size << std::endl;

		infostream << "Received data (size=" << size << "): ";
		for (int i = 0; i < size && i < 20; i++) {
			if (i % 2 == 0)
				infostream << " ";
			char buf[10];
			snprintf(buf, 10, "%.2X", ((int)(recvdata[i])) & 0xff);
			infostream << buf;
		}
		if (size > 20)
			infostream << "...";
		infostream << std::endl;

		UASSERT(memcmp(*sentdata, *recvdata, recvdata.getSize()) == 0);
		UASSERT(peer_id == PEER_ID_SERVER);
	}

	// Check peer handlers
	UASSERT(hand_client.count == 1);
	UASSERT(hand_client.last_id == 1);
	UASSERT(hand_server.count == 1);
	UASSERT(hand_server.last_id == 2);
}
예제 #18
0
void GossipHandler::HandleMsg( NetworkPacket & recv_data, GameClient *pClient )
{
    NetworkPacket data;
    char f[256];
    sprintf(f, "WORLD: Gossip Opcode 0x%.4X", recv_data.opcode);
    Log::getSingleton( ).outString( f );
    switch (recv_data.opcode)
    {
        case CMSG_GOSSIP_HELLO:
        {
            uint16 tSize,i;
            uint32 TextID;
            guid cguid;
            recv_data >> cguid.sno >> cguid.type;
            TextID = getTextID(cguid.sno);
            if(TextID == 0)
            {
                //text Id 0 don't exist so maybe they don't want to talk :P
                data.Initialize( 8 , SMSG_NPC_WONT_TALK );
                data << cguid.sno << cguid.type;
                pClient->SendMsg (&data);
                break;
            }
            //TextRelation * pRelation = getTextRelation(cguid.sno);
            NPCText * theText = getNPCText(TextID);
            //Calculate the size
            tSize = 20 + (8*theText->m_OptionCount);
            TextOption * theOption;
            for(i = 1; i <= theText->m_OptionCount;i++)
            {
                // add option textsize to the size
                theOption = getTextOption(theText->m_OptionID[i]);
                tSize += strlen((char *)theOption->m_OptionText.c_str())+1;
            }

            //Create the Packet
            data.Initialize( tSize, SMSG_GOSSIP_MESSAGE );
            data << cguid.sno << cguid.type;
            data << (uint32)TextID;                         //TextID
            data << (uint32)theText->m_OptionCount;         // Bullet Points Count
            for(i = 1; i <= theText->m_OptionCount;i++)
            {
                theOption = getTextOption(theText->m_OptionID[i]);
                data << (uint32)theOption->m_OptionID;      //Bullet Point Number
                data << (uint32)theOption->m_OptionIconID;  //Bullet Point IconID
                                                            //option text
                data.WriteData(theOption->m_OptionText.c_str() , strlen((char *)theOption->m_OptionText.c_str())+1 );
            }
            data << (uint32)0;
            pClient->SendMsg (&data);

            //pClient->getCurrentChar()->setUpdateValue(CORPSE_FIELD_ITEM3, 6947);
            //pClient->getCurrentChar()->setUpdateValue(CORPSE_FIELD_ITEM4, (uint32)0xf0001000 );
            //pClient->getCurrentChar()->UpdateObject();

        }break;

        case CMSG_GOSSIP_SELECT_OPTION:
        {
            uint32 option;
            guid cguid;
            recv_data >> cguid.sno >> cguid.type;
            recv_data >> option;
            TextOption * theOption;
            theOption = getTextOption(option);

            // Textid of 0 is Reserved for exiting and SH Comfirm
            if(theOption->m_TextID == 0)
            {
                Unit *pSelection = world.GetValidCreature(cguid.sno);
                if(pSelection != 0)
                {
                                                            //if the selection is a spirit healer
                    if(pSelection->getUpdateValue(UNIT_NPC_FLAGS) == 32)
                    {
                        // Sh Accept Dialog
                        data.Initialize(8,SMSG_SPIRIT_HEALER_CONFIRM);
                        data << cguid.sno << cguid.type;
                        pClient->SendMsg( &data );
                    }
                }

                //close the Gossip Window
                data.Initialize(0,SMSG_GOSSIP_COMPLETE);
                pClient->SendMsg( &data );
                break;
            }

            uint16 TextID,tSize,i;
            //get the Text ID
            TextID = theOption->m_TextID;
            //get the Related text info
            NPCText * theText = getNPCText(TextID);
            //calculate our size
            tSize = 20 + (8*theText->m_OptionCount);
            for(i = 1; i <= theText->m_OptionCount;i++)
            {
                //get each options text and add it to the size
                theOption = getTextOption(theText->m_OptionID[i]);
                tSize += strlen((char *)theOption->m_OptionText.c_str())+1;
            }

            //Create the Packet
            data.Initialize( tSize, SMSG_GOSSIP_MESSAGE );
            data << cguid.sno << cguid.type;
            data << (uint32)TextID;                         //TextID
            data << (uint32)theText->m_OptionCount;         // Bullet Points Count
            //Get each option
            for(i = 1; i <= theText->m_OptionCount;i++)
            {
                theOption = getTextOption(theText->m_OptionID[i]);
                data << (uint32)theOption->m_OptionID;      //Bullet Point Number
                data << (uint32)theOption->m_OptionIconID;  //Bullet Point IconID
                                                            //option text
                data.WriteData(theOption->m_OptionText.c_str() , strlen((char *)theOption->m_OptionText.c_str())+1 );
            }
            data << (uint32)0;                              //Null Terminator
            pClient->SendMsg (&data);
        }break;

        case CMSG_NPC_TEXT_QUERY:
        {
            uint32 textID, tSize;
            recv_data >> textID;

            /* i don't think this is used but if Spirit healers don't work try it :P
            //this is having to do with spirit healers
            uint32 uField0, uField1;
            recv_data >> uField0 >> uField1;

            Unit pSelection = world.GetValidCreature(uField0);
            if(pSelection != 0)
            {
            if(pSelection.getUpdateValue(UNIT_NPC_FLAGS) == 32) //if the selection is a spirit healer
            {
            pClient->getCurrentChar()->setUpdateValue(UNIT_FIELD_TARGET, uField0);
            pClient->getCurrentChar()->setUpdateValue(UNIT_FIELD_TARGET + 1, uField1);
            }
            }
            */

            //get the text from the text id
            NPCText * theText = getNPCText(textID);
            //calculate hte size
            tSize = strlen((char *)theText->m_Text.c_str())+9;

            //create the packet
            data.Initialize(tSize, SMSG_NPC_TEXT_UPDATE);
            data << textID << (uint32)0x42c80000;           //text id and text display fix ??
            data.WriteData((char *)theText->m_Text.c_str(), strlen((char *)theText->m_Text.c_str())+1);
            pClient->SendMsg( &data );
        }break;

        default:
            break;
    }
}
예제 #19
0
void ItemHandler::HandleMsg (NetworkPacket & recv_data, GameClient *pClient)
{
    NetworkPacket data;
    char f[ 256 ];
    sprintf (f, "WORLDSERVER: Item Opcode 0x%.4X", recv_data.opcode);
    LOG.outString (f);
    switch (recv_data.opcode)
    {
        case CMSG_SWAP_INV_ITEM:
        {
            //ok i'm gonna do that a looootttt cleaner :/
            uint8 srcslot, destslot;
            recv_data >> srcslot >> destslot;
            int slot = destslot;

            //START OF LINA LVL REQUIREMENT SWAP PATCH
            int8 CharLvl, ItemLvl;
            //printf("ITEM: LVL TEST\n");
            CharLvl=pClient->getCurrentChar()->getLevel();
            ItemLvl=WORLDSERVER.GetItem(pClient->getCurrentChar()->getItemIdBySlot(srcslot))->RequiredLevel;
            //printf("ITEM: CharLvl %d, ItemLvl %d\n", CharLvl, ItemLvl);
            if (CharLvl < ItemLvl)
            {
                ChatHandler * MsgLvlItem = new ChatHandler;
                if(MsgLvlItem  !=NULL)
                {
                    //NEED TO PUT SOME CODE TO UNGRAY ITEM
                    uint8 buf[256];
                    NetworkPacket data;
                    sprintf((char*)buf,"You need the Lvl %d to equip that item.", ItemLvl);
                    MsgLvlItem->FillMessageData(&data, 0x09, pClient, buf);
                    pClient->SendMsg (&data);
                    delete(MsgLvlItem);
                }
                else printf("ITEM: CMSG_SWAP_INV_ITEM can't send message\n");
                return;
            }
            //END OF LINA LVL REQUIREMENT SWAP PATCH

            //these are the bags slots...ignore it for now
            if ((slot <= 22) && (slot >=19))
                destslot = srcslot;

            //check to make sure items are not being put in wrong spots
            if (((srcslot > 23) && (destslot < 19)) || ((srcslot < 23) && (destslot > 19)))
            {
                if ((pClient->getCurrentChar()->getGuidBySlot(destslot) != 0) && (pClient->getCurrentChar()->getGuidBySlot(srcslot) != 0))
                {
                    Item * tmpitem1 = WORLDSERVER.GetItem(pClient->getCurrentChar()->getItemIdBySlot(destslot));
                    Item * tmpitem2 = WORLDSERVER.GetItem(pClient->getCurrentChar()->getItemIdBySlot(srcslot));
                    if ((tmpitem1 != NULL) && (tmpitem2 != NULL))
                    {
                        if (tmpitem1->Inventorytype != tmpitem2->Inventorytype)
                        {
                            data.Initialize (18, SMSG_INVENTORY_CHANGE_FAILURE);
                            data << uint8(0x0c) ;
                            data << uint32(pClient->getCurrentChar()->getGuidBySlot(destslot));
                            data << uint32(0x00000040);
                            data << uint32(pClient->getCurrentChar()->getGuidBySlot(srcslot));
                            data << uint32(0x00000040);
                            data << uint8(0);
                            pClient->SendMsg (&data);
                            return;
                        }
                    }
                }
            }

            //swap items
            pClient->getCurrentChar()->SwapItemInSlot((int)srcslot, (int)destslot);
            UpdateMask updateMask;
            updateMask.SetLength (PLAYER_FIELDS);

            //error
            if (srcslot == destslot)
            {
                data.Initialize (18, SMSG_INVENTORY_CHANGE_FAILURE);
                data << uint8(0x0c) ;
                data << uint32(pClient->getCurrentChar()->getGuidBySlot(destslot));
                data << uint32(0x00000040);
                data << uint32(pClient->getCurrentChar()->getGuidBySlot(srcslot));
                data << uint32(0x00000040);
                data << uint8(0);
                pClient->SendMsg (&data);
                return;
            }
            pClient->getCurrentChar()->updateItemStats();
            //send to zone players...they don't need to know about the item if the slot is over 19
            if (destslot < 19)
            {
                pClient->getCurrentChar ()->setUpdateValue (
                    PLAYER_FIELD_INV_SLOT_HEAD  + (destslot*2),
                    pClient->getCurrentChar()->getGuidBySlot(destslot),
                    updateMask.data);
                pClient->getCurrentChar ()->setUpdateValue (
                    PLAYER_FIELD_INV_SLOT_HEAD  + (destslot*2)+1,
                    pClient->getCurrentChar()->getGuidBySlot(destslot) == 0 ? 0 : 0x00000040,
                    updateMask.data);
            }
            if (srcslot < 19)
            {
                pClient->getCurrentChar ()->setUpdateValue (
                    PLAYER_FIELD_INV_SLOT_HEAD  + (srcslot*2),
                    pClient->getCurrentChar()->getGuidBySlot(srcslot),
                    updateMask.data);
                pClient->getCurrentChar ()->setUpdateValue (
                    PLAYER_FIELD_INV_SLOT_HEAD  + (srcslot*2)+1,
                    pClient->getCurrentChar()->getGuidBySlot(srcslot) == 0 ? 0 : 0x00000040,
                    updateMask.data);
            }

            pClient->getCurrentChar ()->UpdateObject (&updateMask, &data);
            //              WORLDSERVERSERVER.SendZoneMessage(&data, pClient, 0);
            pClient->getCurrentChar()->SendMessageToSet(&data, false);

            //send update to the player
            pClient->getCurrentChar ()->setUpdateValue (
                PLAYER_FIELD_INV_SLOT_HEAD  + (destslot*2),
                pClient->getCurrentChar()->getGuidBySlot(destslot),
                updateMask.data);
            pClient->getCurrentChar ()->setUpdateValue (
                PLAYER_FIELD_INV_SLOT_HEAD  + (destslot*2)+1,
                pClient->getCurrentChar()->getGuidBySlot(destslot) == 0 ? 0 : 0x00000040,
                updateMask.data);
            pClient->getCurrentChar ()->setUpdateValue (
                PLAYER_FIELD_INV_SLOT_HEAD  + (srcslot*2),
                pClient->getCurrentChar()->getGuidBySlot(srcslot),
                updateMask.data);
            pClient->getCurrentChar ()->setUpdateValue (
                PLAYER_FIELD_INV_SLOT_HEAD  + (srcslot*2)+1,
                pClient->getCurrentChar()->getGuidBySlot(srcslot) == 0 ? 0 : 0x00000040,
                updateMask.data);
            pClient->getCurrentChar ()->UpdateObject (&updateMask, &data);
            pClient->SendMsg (&data);

            if ((srcslot < 19) && (destslot < 19))
                return;

            int invcount = srcslot;
            if ((pClient->getCurrentChar()->getGuidBySlot(invcount) != 0) && (srcslot < 19))
            {
                createItemUpdate(&data, pClient, invcount);
                //                  WORLDSERVER.SendZoneMessage(&data, pClient, 0);
                pClient->getCurrentChar()->SendMessageToSet(&data, false);
            }

            invcount = destslot;

            if ((pClient->getCurrentChar()->getGuidBySlot(invcount) != 0) && (destslot < 19))
            {
                createItemUpdate(&data, pClient, invcount);
                //                  WORLDSERVER.SendZoneMessage(&data, pClient, 0);
                pClient->getCurrentChar()->SendMessageToSet(&data, false);
            }
            break;
        }
        case CMSG_DESTROYITEM:
        {
            uint8 srcslot, destslot;
            uint32 itemguid;
            recv_data >> srcslot >> destslot;
            if (WORLDSERVER.GetItem(pClient->getCurrentChar()->getItemIdBySlot(destslot)) != NULL)
                srcslot = WORLDSERVER.GetItem(pClient->getCurrentChar()->getItemIdBySlot(destslot))->Inventorytype && 0xff;
            else
                return;
            if (pClient->getCurrentChar()->getGuidBySlot(destslot) == 0)
                return;
            itemguid = pClient->getCurrentChar()->getGuidBySlot(destslot);
            pClient->getCurrentChar()->AddItemToSlot(destslot,0,0);

            UpdateMask updateMask;
            updateMask.SetLength (PLAYER_FIELDS);

            if (destslot < 19)
            {
                pClient->getCurrentChar ()->setUpdateValue (
                    PLAYER_FIELD_INV_SLOT_HEAD  + (destslot*2),
                    pClient->getCurrentChar()->getGuidBySlot (destslot),
                    updateMask.data);
                pClient->getCurrentChar ()->setUpdateValue (
                    PLAYER_FIELD_INV_SLOT_HEAD  + (destslot*2)+1,
                    pClient->getCurrentChar()->getGuidBySlot(destslot) == 0 ? 0 : 0x00000040,
                    updateMask.data);
            }
            pClient->getCurrentChar ()->UpdateObject (&updateMask, &data);
            //              WORLDSERVERSERVER.SendZoneMessage(&data, pClient, 0);
            pClient->getCurrentChar()->SendMessageToSet(&data, false);

            pClient->getCurrentChar ()->setUpdateValue (
                PLAYER_FIELD_INV_SLOT_HEAD  + (destslot*2),
                pClient->getCurrentChar()->getGuidBySlot(destslot),
                updateMask.data);
            pClient->getCurrentChar ()->setUpdateValue (
                PLAYER_FIELD_INV_SLOT_HEAD  + (destslot*2)+1,
                pClient->getCurrentChar()->getGuidBySlot(destslot) == 0 ? 0 : 0x00000040,
                updateMask.data);
            pClient->getCurrentChar ()->UpdateObject (&updateMask, &data);
            pClient->SendMsg (&data);

            data.Clear();
            data.Initialize(8, SMSG_DESTROY_OBJECT);
            data << itemguid << uint32(0x00000040);
            //              WORLDSERVER.SendZoneMessage(&data, pClient, 1);
            pClient->getCurrentChar()->SendMessageToSet(&data, true);
            break;
        }
        case CMSG_AUTOEQUIP_ITEM:
        {

            uint8 srcslot, destslot;
            recv_data >> srcslot >> destslot;

            int8 CharLvl, ItemLvl;
            //START OF LINA LVL REQUIREMENT AUTOEQUIP PATCH
            CharLvl=pClient->getCurrentChar()->getLevel();
            ItemLvl=WORLDSERVER.GetItem(pClient->getCurrentChar()->getItemIdBySlot(destslot))->RequiredLevel;
            //printf("ITEM: CharLvl %d, ItemLvl %d\n", CharLvl, ItemLvl);
            if (CharLvl < ItemLvl)
            {
                ChatHandler * MsgLvlItem = new ChatHandler;
                if (MsgLvlItem != NULL)
                {
                    //NEED TO PUT SOME CODE TO UNGRAY ITEM
                    uint8 buf[256];
                    NetworkPacket data;
                    sprintf((char*)buf,"You need the Lvl %d to equip that item.", ItemLvl);
                    MsgLvlItem->FillMessageData(&data, 0x09, pClient, buf);
                    pClient->SendMsg (&data);
                    delete(MsgLvlItem);
                }
                else printf("ITEM: CMSG_AUTOEQUIP_ITEM can't send message\n");
                return;
            }
            //END OF LINA LVL REQUIREMENT AUTOEQUIP PATCH

            if (WORLDSERVER.GetItem(pClient->getCurrentChar()->getItemIdBySlot(destslot)) != NULL)
                srcslot = uint8(WORLDSERVER.GetItem(pClient->getCurrentChar()->getItemIdBySlot(destslot))->Inventorytype);
            else
                return;

            if (WORLDSERVER.GetItem(pClient->getCurrentChar()->getItemIdBySlot(destslot))->Class == 4)
            {
                if (srcslot < 11)
                    srcslot--;
                else if (srcslot == 11)
                {
                    if (pClient->getCurrentChar()->getGuidBySlot(10) == 0)
                    {
                        srcslot = 10;
                    }
                    else if (pClient->getCurrentChar()->getGuidBySlot(11) == 0)
                    {

                        srcslot = 11;
                    }
                    else
                    {
                        srcslot = destslot;
                    }

                }
                else if (srcslot == 14)
                    srcslot += 2;
                else if (srcslot == 13)
                    srcslot += 2;
                else
                    srcslot = 4;
            }
            else if (WORLDSERVER.GetItem(pClient->getCurrentChar()->getItemIdBySlot(destslot))->Class == 2)
            {
                switch (WORLDSERVER.GetItem(pClient->getCurrentChar()->getItemIdBySlot(destslot))->SubClass)
                {
                    case 2: case 3: case 16: case 19:
                        srcslot = 17;
                        break;

                    default:
                        srcslot = 15;
                        break;
                }
            }
            else
            {
                srcslot = destslot;
            }

            if (srcslot == destslot)
            {
                data.Initialize (18, SMSG_INVENTORY_CHANGE_FAILURE);
                data << uint8(0x0c) ;
                data << uint32(pClient->getCurrentChar()->getGuidBySlot(destslot));
                data << uint32(0x00000040);
                data << uint32(0) << uint32(0) << uint8(0);
                pClient->SendMsg (&data);
                return;
            }

            pClient->getCurrentChar()->SwapItemInSlot((int)srcslot, (int)destslot);
            UpdateMask updateMask;
            updateMask.SetLength (PLAYER_FIELDS);
            if (destslot < 19)
            {
                pClient->getCurrentChar ()->setUpdateValue (
                    PLAYER_FIELD_INV_SLOT_HEAD  + (destslot*2),
                    pClient->getCurrentChar()->getGuidBySlot(destslot),
                    updateMask.data);
                pClient->getCurrentChar ()->setUpdateValue (
                    PLAYER_FIELD_INV_SLOT_HEAD  + (destslot*2)+1,
                    pClient->getCurrentChar()->getGuidBySlot(destslot) == 0 ? 0 : 0x00000040,
                    updateMask.data);
            }
            if (srcslot < 19)
            {
                pClient->getCurrentChar ()->setUpdateValue (
                    PLAYER_FIELD_INV_SLOT_HEAD  + (srcslot*2), pClient->getCurrentChar()->getGuidBySlot(srcslot),
                    updateMask.data);
                pClient->getCurrentChar ()->setUpdateValue (
                    PLAYER_FIELD_INV_SLOT_HEAD  + (srcslot*2)+1, pClient->getCurrentChar()->getGuidBySlot(srcslot) == 0 ? 0 : 0x00000040,
                    updateMask.data);
            }
            pClient->getCurrentChar ()->UpdateObject (&updateMask, &data);
            //              WORLDSERVERSERVER.SendZoneMessage(&data, pClient, 0);
            pClient->getCurrentChar()->SendMessageToSet(&data, false);

            pClient->getCurrentChar ()->setUpdateValue (
                PLAYER_FIELD_INV_SLOT_HEAD  + (destslot*2),
                pClient->getCurrentChar()->getGuidBySlot(destslot),
                updateMask.data);
            pClient->getCurrentChar ()->setUpdateValue (
                PLAYER_FIELD_INV_SLOT_HEAD  + (destslot*2)+1,
                pClient->getCurrentChar()->getGuidBySlot(destslot) == 0 ? 0 : 0x00000040,
                updateMask.data);
            pClient->getCurrentChar ()->setUpdateValue (
                PLAYER_FIELD_INV_SLOT_HEAD  + (srcslot*2),
                pClient->getCurrentChar()->getGuidBySlot(srcslot),
                updateMask.data);
            pClient->getCurrentChar ()->setUpdateValue (
                PLAYER_FIELD_INV_SLOT_HEAD  + (srcslot*2)+1,
                pClient->getCurrentChar()->getGuidBySlot(srcslot) == 0 ? 0 : 0x00000040,
                updateMask.data);
            pClient->getCurrentChar ()->UpdateObject (&updateMask, &data);
            pClient->SendMsg (&data);

            Item *tempitem;
            UpdateMask invUpdateMask;
            int invcount = srcslot;
            invUpdateMask.SetLength (64);
            tempitem = new Item;
            if ((pClient->getCurrentChar()->getGuidBySlot(invcount) != 0) && (srcslot < 19))
            {
                createItemUpdate(&data, pClient, invcount);
                //                  WORLDSERVER.SendZoneMessage(&data, pClient, 0);
                pClient->getCurrentChar()->SendMessageToSet(&data, false);
                delete tempitem;
            }
            else
                delete tempitem;
            invcount = destslot;
            invUpdateMask.SetLength (64);
            tempitem = new Item;
            if (srcslot == destslot)
                return;
            if ((pClient->getCurrentChar()->getGuidBySlot(invcount) != 0) && (destslot < 19))
            {
                createItemUpdate(&data, pClient, invcount);
                //                  WORLDSERVER.SendZoneMessage(&data, pClient, 0);
                pClient->getCurrentChar()->SendMessageToSet(&data, false);

            }
            LOG.outString ("WORLDSERVER: Sent Updated Item slot Masks");
            break;
        }

        case CMSG_ITEM_QUERY_SINGLE:
        {

            int i;
            uint32 itemid, guid1, guid2;
            recv_data >> itemid >> guid1 >> guid2;          // guid is the guid of the ITEM OWNER - NO ITS NOT
            if (WORLDSERVER.GetItem(itemid) == NULL)
                return;
            sprintf (curopcodebuf, "WORLDSERVER: Recvd CMSG_ITEM_QUERY_SINGLE for item id 0x%.8X, guid 0x%.8X 0x%.8X", itemid, guid1, guid2);
            LOG.outString (curopcodebuf);

            Item *tempItem = WORLDSERVER.GetItem(itemid);

            //data.Initialize (413 + tempItem->name1.length() + tempItem->name2.length()  + tempItem->name3.length()  + tempItem->name4.length()  + tempItem->Description.length(), SMSG_ITEM_QUERY_SINGLE_RESPONSE);
            data.Initialize (413 + 12 + tempItem->name1.length() + tempItem->name2.length()  + tempItem->name3.length()  + tempItem->name4.length()  + tempItem->Description.length(), SMSG_ITEM_QUERY_SINGLE_RESPONSE);
            //printf("%d\n", data.length);
            //printf("%s\n%s\n", tempItem->name1.c_str(), tempItem->Description.c_str());
            data << itemid;
            data << tempItem->Class;
            data << tempItem->SubClass;
            data << tempItem->name1.c_str();
            data << tempItem->name2.c_str();
            data << tempItem->name3.c_str();
            data << tempItem->name4.c_str();
            data << tempItem->DisplayInfoID;
            data << tempItem->OverallQualityID;
            data << tempItem->Flags;
            data << tempItem->Buyprice;
            data << tempItem->Sellprice;
            data << tempItem->Inventorytype;
            data << tempItem->AllowableClass;
            data << tempItem->AllowableRace;
            data << tempItem->ItemLevel;
            data << tempItem->RequiredLevel;
            data << tempItem->RequiredSkill;
            data << tempItem->RequiredSkillRank;
            data << uint32(0);                              // other requirements here? - 10 = "Requires Blizzard"
            data << uint32(0);                              // ??? 10 = "Requires Knight"
            data << uint32(0);                              // ??? 10 = "Requires "
            data << tempItem->MaxCount;
            data << tempItem->Stackable;
            data << tempItem->ContainerSlots;
            for(i = 0; i<10; i++)
            {
                data << tempItem->BonusStat[i];
                data << tempItem->BonusAmount[i];
            }
            for(i = 0; i<5; i++)
            {
                data << (float)(tempItem->MinimumDamage[i]);
                data << (float)(tempItem->MaximumDamage[i]);
                data << tempItem->DamageType[i];
            }
            data << tempItem->Resistances[0];               // armor
            data << uint32(0);                              // unknown extra resistance
            data << tempItem->Resistances[2];               // fire
            data << tempItem->Resistances[3];               // nature
            data << tempItem->Resistances[4];               // frost
            data << tempItem->Resistances[5];               // shadow
            data << tempItem->Resistances[1];               // arcane at the end now
            //for(i = 0; i<6; i++)
            //{
            //  data << tempItem->Resistances[i];
            //}

            data << tempItem->Delay;
            data << tempItem->AmmunitionType;
            //data << tempItem->MaxDurability;
            for(i = 0; i<5; i++)
            {
                data << tempItem->SpellID[i];
                data << tempItem->SpellTrigger[i];
                data << tempItem->SpellCharges[i];
                data << tempItem->SpellCooldown[i];
                data << tempItem->SpellCategory[i];
                data << tempItem->SpellCategoryCooldown[i];
            }
            data << tempItem->Bonding;
            if (tempItem->Description.c_str()[0] != 48)
                data << tempItem->Description.c_str();
            else
                data << uint32(0);
            data << tempItem->Pagetext;
            data << tempItem->LanguageID;
            data << tempItem->PageMaterial;
            data << tempItem->StartQuestID;
            data << tempItem->LockID;
            data << tempItem->Material;
            data << tempItem->Sheathetype;
            data << tempItem->Unknown1;
            data << tempItem->Unknown2;

            pClient->SendMsg (&data);
            break;
        }
        case CMSG_SELL_ITEM:
        {
            LOG.outString ("WORLDSERVER: Recieved CMSG_SELL_ITEM");
            uint32 srcguid1, srcguid2, itemguid1, itemguid2,newmoney;
            uint8 amount;
            recv_data >> srcguid1 >> srcguid2;
            recv_data >> itemguid1 >> itemguid2;
            recv_data >> amount;

            if (itemguid1 == 0)
            {
                data.Clear();
                data.Initialize(17, SMSG_SELL_ITEM);
                data << srcguid1 << srcguid2 << itemguid1 << itemguid2 << uint8(0x01);
                pClient->SendMsg (&data);
                return;
            }
            int itemindex = -1,i,check = 0;
            Unit *tempunit;
            tempunit = WORLDSERVER.GetCreature(srcguid1);
            if (tempunit == NULL)
                return;

            for(i = 0; i< 39;i++)
            {
                if (pClient->getCurrentChar()->getGuidBySlot(i) == itemguid1)
                {
                    itemindex = i;
                    break;
                }
            }
            if (itemindex == -1)
            {
                data.Clear();
                data.Initialize(17, SMSG_SELL_ITEM);
                data << srcguid1 << srcguid2 << itemguid1 << itemguid2 << uint8(0x01);
                pClient->SendMsg (&data);
                return;                                     //our player doesn't have this item
            }

            /*****************************************************
             *   i will need to put some stack count check here  *
             *****************************************************/
            if (amount == 0)
                amount = 1;

            //adding this item to the vendor's item list
            for(i=0; i<tempunit->getItemCount();i++)
            {
                if (tempunit->getItemId(i) == pClient->getCurrentChar()->getItemIdBySlot(itemindex))
                {
                    tempunit->setItemAmount(i, tempunit->getItemAmount(i) + amount);
                    check = 1;
                }
            }
            if (check == 0)
            {
                if (tempunit->getItemCount() > 100)
                {
                    data.Clear();
                    data.Initialize(17, SMSG_SELL_ITEM);
                    data << srcguid1 << srcguid2 << itemguid1 << itemguid2 << uint8(0x02);
                    pClient->SendMsg (&data);
                    return;
                }
                else
                    tempunit->addItem(pClient->getCurrentChar()->getItemIdBySlot(itemindex), amount);
            }
            newmoney = WORLDSERVER.GetItem(pClient->getCurrentChar()->getItemIdBySlot(itemindex))->Sellprice + pClient->getCurrentChar()->getUpdateValue(PLAYER_FIELD_COINAGE);

            //removing the item from the char's inventory
            pClient->getCurrentChar()->AddItemToSlot(itemindex,0,0);
            //sending a player update
            UpdateMask updateMask;
            updateMask.SetLength (PLAYER_FIELDS);

            if (itemindex < 19)
            {
                pClient->getCurrentChar ()->setUpdateValue (
                    PLAYER_FIELD_INV_SLOT_HEAD  + (itemindex*2),
                    pClient->getCurrentChar()->getGuidBySlot(itemindex),
                    updateMask.data);
                pClient->getCurrentChar ()->setUpdateValue (
                    PLAYER_FIELD_INV_SLOT_HEAD  + (itemindex*2)+1,
                    pClient->getCurrentChar()->getGuidBySlot(itemindex) == 0 ? 0 : 0x00000040,
                    updateMask.data);
            }
            pClient->getCurrentChar ()->UpdateObject (&updateMask, &data);
            //WORLDSERVER.SendZoneMessage(&data, pClient, 0);
            pClient->getCurrentChar()->SendMessageToSet(&data, false);

            pClient->getCurrentChar ()->setUpdateValue (
                PLAYER_FIELD_COINAGE, newmoney,
                updateMask.data);
            pClient->getCurrentChar ()->setUpdateValue (
                PLAYER_FIELD_INV_SLOT_HEAD  + (itemindex*2),
                pClient->getCurrentChar()->getGuidBySlot(itemindex),
                updateMask.data);
            pClient->getCurrentChar ()->setUpdateValue (
                PLAYER_FIELD_INV_SLOT_HEAD  + (itemindex*2)+1,
                pClient->getCurrentChar()->getGuidBySlot(itemindex) == 0 ? 0 : 0x00000040,
                updateMask.data);
            pClient->getCurrentChar ()->UpdateObject (&updateMask, &data);
            pClient->SendMsg (&data);

            //send an SMSG_SELL_ITEM
            data.Clear();
            data.Initialize(17, SMSG_SELL_ITEM);
            data << srcguid1 << srcguid2 << itemguid1 << itemguid2 << uint8(0x05);
            pClient->SendMsg (&data);

            //send an object destroy packet
            data.Clear();
            data.Initialize(8, SMSG_DESTROY_OBJECT);
            data << itemguid1 << uint32(0x00000040);
            //              WORLDSERVER.SendZoneMessage(&data, pClient, 1);
            pClient->getCurrentChar()->SendMessageToSet(&data, true);
            break;
        }

        case CMSG_BUY_ITEM_IN_SLOT:
        {
            LOG.outString ("WORLDSERVER: Recieved CMSG_BUY_ITEM_IN_SLOT");
            uint32 srcguid1, srcguid2, itemid, destguid1, destguid2;
            uint8 slot, amount;
            recv_data >> srcguid1 >> srcguid2 >> itemid;
            recv_data >> destguid1 >> destguid2;
            recv_data >> slot;
            recv_data >> amount;
            int itemindex,i,varify = 0;
            Unit *tempunit;
            tempunit = WORLDSERVER.GetCreature(srcguid1);
            if (tempunit == NULL)
                return;

            if (slot > 38)
                return;
            if (slot < 19)
                return;
            if ((slot <= 22) && (slot >=19))
                return;                                     //these are the bags slots...i'm not sure exactly how to use them
            if (pClient->getCurrentChar()->getGuidBySlot(slot) != 0)
                return;                                     //slot is not empty...i'll have to make code to check for other slots
            for(i = 0; i< tempunit->getItemCount();i++)
            {
                if (tempunit->getItemId(i) == itemid)
                {
                    varify = 1;
                    break;
                }
            }
            if (varify == 0)
                return;                                     //our vendor doesn't have this item
            itemindex = i;
            if (amount > tempunit->getItemAmount(i))
                return;                                     //our vendor doesn't have the required amount of that item
            tempunit->setItemAmountById(itemid,tempunit->getItemAmount(i) - amount);

            //START OF LINA BUY PATCH
                                                            //INFO
            printf("ARGENT: %d, COUT: %d\n", (pClient->getCurrentChar()->getUpdateValue(PLAYER_FIELD_COINAGE)), (WORLDSERVER.GetItem(tempunit->getItemId(itemindex))->Buyprice));
            int32 newmoney;
                                                            //LINA
            newmoney = ((pClient->getCurrentChar()->getUpdateValue(PLAYER_FIELD_COINAGE)) - (WORLDSERVER.GetItem(tempunit->getItemId(itemindex))->Buyprice));
            printf("DIF: %d\n",newmoney);                   //INFO
            if(newmoney < 0)
            {
                ChatHandler * MsgGold = new ChatHandler;
                if (MsgGold != NULL)
                {
                    uint8 buf[256];
                    NetworkPacket data;
                    sprintf((char*)buf,"You need %i to buy this item.", abs(newmoney));
                    MsgGold->FillMessageData(&data, 0x09, pClient, buf);
                    pClient->SendMsg (&data);
                    delete(MsgGold);
                }
                else printf("ITEM: CMSG_BUY_ITEM_IN_SLOT can't send message\n");
                return;
            }
            //END OF LINA BUY PATCH

            WORLDSERVER.m_hiItemGuid++;
            std::string templog;
            char tempiid[10];
            sprintf(tempiid,"%d",WORLDSERVER.m_hiItemGuid);
            templog = "Created Item. Guid: ";
            templog+= tempiid;

            LOG.outString (templog.c_str());

            pClient->getCurrentChar()->AddItemToSlot(slot,WORLDSERVER.m_hiItemGuid,itemid);

            data.Clear();
            data.Initialize(16, SMSG_BUY_ITEM);
            data << uint32(srcguid1) << uint32(srcguid2);
            data << uint32(itemid) << uint32(amount);
            pClient->SendMsg (&data);

            Item *tempitem;

            UpdateMask invUpdateMask;

            int invcount = slot;
            invUpdateMask.SetLength (64);
            tempitem = new Item;

            createItemUpdate(&data, pClient, invcount);

            if (slot > 23)
                pClient->SendMsg (&data);
            else
            {
                //                  WORLDSERVER.SendZoneMessage(&data, pClient, 0);
                pClient->getCurrentChar()->SendMessageToSet(&data, true);
                //                  pClient->SendMsg (&data);
            }
            delete tempitem;

            UpdateMask updateMask;
            updateMask.SetLength (PLAYER_FIELDS);
            pClient->getCurrentChar ()->setUpdateValue (
                PLAYER_FIELD_COINAGE, newmoney,
                updateMask.data);                           //LINA BUY PATCH NEXT
            pClient->getCurrentChar ()->setUpdateValue (
                PLAYER_FIELD_INV_SLOT_HEAD  + (slot*2),
                pClient->getCurrentChar()->getGuidBySlot(slot),
                updateMask.data);
            pClient->getCurrentChar ()->setUpdateValue (
                PLAYER_FIELD_INV_SLOT_HEAD  + (slot*2)+1,
                pClient->getCurrentChar()->getGuidBySlot(slot) == 0 ? 0 : 0x00000040,
                updateMask.data);
            pClient->getCurrentChar ()->UpdateObject (&updateMask, &data);
            if (slot > 23)
                pClient->SendMsg (&data);
            else
            {
                //                  WORLDSERVER.SendZoneMessage(&data, pClient, 0);
                pClient->getCurrentChar()->SendMessageToSet(&data, true);
                //                  pClient->SendMsg (&data);
            }
            break;
        }
        case CMSG_BUY_ITEM:                                 //right click
        {
            LOG.outString ("WORLDSERVER: Recieved CMSG_BUY_ITEM");
            uint32 srcguid1, srcguid2, itemid;
            uint8 slot, amount;
            recv_data >> srcguid1 >> srcguid2 >> itemid;
            recv_data >> amount >> slot;
            int itemindex,i,varify = 0;
            Unit *tempunit;
            tempunit = WORLDSERVER.GetCreature(srcguid1);
            if (tempunit == NULL)
                return;
            slot = 0;
            for(i = 23; i <= 38; i++)
            {
                if (pClient->getCurrentChar()->getGuidBySlot(i) == 0)
                {
                    slot = i;
                    break;
                }
            }
            if (slot == 0)
                return;
            for(i = 0; i< tempunit->getItemCount();i++)
            {
                if (tempunit->getItemId(i) == itemid)
                {
                    varify = 1;
                    break;
                }
            }
            if (varify == 0)
                return;                                     //our vendor doesn't have this item
            itemindex = i;
            if (amount > tempunit->getItemAmount(i))
                return;                                     //our vendor doesn't have the required amount of that item
            tempunit->setItemAmountById(itemid,tempunit->getItemAmount(i) - amount);

            //START OF LINA BUY PATCH
                                                            //INFO
            printf("ARGENT: %d, COUT: %d\n", (pClient->getCurrentChar()->getUpdateValue(PLAYER_FIELD_COINAGE)), (WORLDSERVER.GetItem(tempunit->getItemId(itemindex))->Buyprice));
            int32 newmoney;
                                                            //LINA
            newmoney = ((pClient->getCurrentChar()->getUpdateValue(PLAYER_FIELD_COINAGE)) - (WORLDSERVER.GetItem(tempunit->getItemId(itemindex))->Buyprice));
            printf("DIF: %d\n",newmoney);                   //INFO
            if(newmoney < 0)
            {
                //NEED TO PUT SOME CODE TO UNGRAY ITEM AND SEND A MESSAGE TO PLAYER
                ChatHandler * MsgGold = new ChatHandler;
                if (MsgGold != NULL)
                {
                    uint8 buf[256];
                    NetworkPacket data;
                    sprintf((char*)buf,"You need %i to buy this item.", abs(newmoney));
                    MsgGold->FillMessageData(&data, 0x09, pClient, buf);
                    pClient->SendMsg (&data);
                    delete(MsgGold);
                }
                else printf("ITEM: CMSG_BUY_ITEM can't send message\n");
                return;
            }
            //END OF LINA BUY PATCH

            WORLDSERVER.m_hiItemGuid++;
            std::string templog;
            char tempiid[10];
            sprintf(tempiid,"%d",WORLDSERVER.m_hiItemGuid);
            templog = "Created Item. Guid: ";
            templog+= tempiid;

            LOG.outString (templog.c_str());

            pClient->getCurrentChar()->AddItemToSlot(slot,WORLDSERVER.m_hiItemGuid,itemid);

            UpdateMask invUpdateMask;

            int invcount = slot;
            invUpdateMask.SetLength (64);

            createItemUpdate(&data, pClient, invcount);

            if (slot > 23)
                pClient->SendMsg (&data);
            else
            {
                //                  WORLDSERVER.SendZoneMessage(&data, pClient, 0);
                pClient->getCurrentChar()->SendMessageToSet(&data, true);
                //                  pClient->SendMsg (&data);
            }

            UpdateMask updateMask;
            updateMask.SetLength (PLAYER_FIELDS);
            pClient->getCurrentChar ()->setUpdateValue (
                PLAYER_FIELD_COINAGE, newmoney,
                updateMask.data);                           //LINA BUY PATCH NEXT
            pClient->getCurrentChar ()->setUpdateValue (
                PLAYER_FIELD_INV_SLOT_HEAD  + (slot*2),
                pClient->getCurrentChar()->getGuidBySlot(slot),
                updateMask.data);
            pClient->getCurrentChar ()->setUpdateValue (
                PLAYER_FIELD_INV_SLOT_HEAD  + (slot*2)+1,
                pClient->getCurrentChar()->getGuidBySlot(slot) == 0 ? 0 : 0x00000040,
                updateMask.data);
            pClient->getCurrentChar ()->UpdateObject (&updateMask, &data);
            if (slot > 23)
                pClient->SendMsg (&data);
            else
            {
                //                  WORLDSERVER.SendZoneMessage(&data, pClient, 0);
                pClient->getCurrentChar()->SendMessageToSet(&data, false);
                //                  pClient->SendMsg (&data);
            }
            break;
        }

        case CMSG_LIST_INVENTORY:
        {
            LOG.outString ("WORLDSERVER: Recvd CMSG_LIST_INVENTORY Message");
            uint32 guid1, guid2;
            //guid1+guid2 = npc's full uint64 guid

            recv_data >> guid1 >> guid2;
            Unit *tempunit;
            tempunit = WORLDSERVER.GetCreature(guid1);
            if (tempunit == NULL)
                return;
            uint8 numitems = (uint8)tempunit->getItemCount();

            if (numitems == 0)
                return;

            data.Initialize (8 + 1 + numitems * 7 * 4, SMSG_LIST_INVENTORY);
            data << guid1 << guid2;
            data << uint8 (numitems);                       // num items

            // each item has seven uint32's
            Item * curItem;
            for(uint8 itemcount = 0; itemcount < numitems; itemcount ++)
            {
                curItem = WORLDSERVER.GetItem(tempunit->getItemId(itemcount));
                if (!curItem)
                {
                    LOG.outError ("Unit %i has nonexistant item %i!", guid1, tempunit->getItemId(itemcount));
                    LOG.outString ("WORLDSERVER: DID NOT Send SMSG_LIST_INVENTORY Message");
                    for (int a = 0; a < 7; a ++) data << uint32 (0);
                }
                else
                {
                    data << uint32 (itemcount + 1);         // index ? doesn't seem to affect anything
                                                            // item id
                    data << uint32 (tempunit->getItemId(itemcount));
                    data << uint32 (curItem->DisplayInfoID);// item icon
                                                            // number of items available, -1 works for infinity, although maybe just 'cause it's really big
                    data << uint32 (tempunit->getItemAmount(itemcount));
                    data << uint32 (curItem->Buyprice);     // price
                    data << uint32 (0);                     // ?
                    data << uint32 (0);                     // ?
                }
            }

            //data.WriteData (tdata, sizeof (tdata));
            pClient->SendMsg (&data);
            LOG.outString ("WORLDSERVER: Sent SMSG_LIST_INVENTORY Message");
            break;
        }
    }
}
예제 #20
0
void AssetDownloader::downloader_task   (   const URL url,
                                            const FilePath save_path,
                                            DTfloat timeout)
{
    std::shared_ptr<DeviceNetwork> network = System::network_manager();

    //
    // Connecting Phase
    //
    
    // Update status
    update_status (STATUS_CONNECTING, 0,0);
    
    // Resolve the host
    NetworkSocket socket;
    NetworkAddress ip; 
    
    DTerr err = network->resolve_host( ip, url.hostname(), url.port() );
    if (err != DT3_ERR_NONE) {
        LOG_MESSAGE << "HTTPRequest: Unable to resolve host.";
        update_status (STATUS_ERROR, 0,0);
        return;
    }
        
    err = network->tcp_open(socket,ip);
    if (err != DT3_ERR_NONE) {
        LOG_MESSAGE << "HTTPRequest: Unable to resolve host.";
        update_status (STATUS_ERROR, 0,0);
        return;
    }
        
	// Send http request
    std::string server = url.hostname();
    std::string path = url.path();
    
    // Note:
    // HTTP/1.1 defines the "close" connection option for the sender to signal that the connection 
    // will be closed after completion of the response. For example,
    //      Connection: close
    // in either the request or the response header fields indicates that the connection SHOULD NOT
    // be considered `persistent' (section 8.1) after the current request/response is complete.
    // HTTP/1.1 applications that do not support persistent connections MUST include the "close" 
    // connection option in every message.

    std::string request =   "GET " + path + " HTTP/1.1\r\n" +
                            "Host: " + server + "\r\n" +
                            "User-Agent: DT3\r\n" +
                            "Accept: */*\r\n" +
                            "Cache-Control: max-age=0\r\n" +
                            "Connection: close\r\n" +
                            "\r\n";

    LOG_MESSAGE << "Sending...";
    LOG_MESSAGE << request;
    
    NetworkPacket packet_request;
    packet_request.set_data(request);
    
    err = network->tcp_send(packet_request, socket);
    if (err != DT3_ERR_NONE) {
        network->tcp_close(socket);
        
        LOG_MESSAGE << "HTTPRequest: Unable to send packet.";
        update_status (STATUS_ERROR, 0,0);
        return;
    }
    
    //
    // Downloading Phase
    //
    
    update_status (STATUS_DOWNLOADING, 0,0);

    // Hash the URL
    FilePath temp_file_path = FilePath(HAL::save_dir().full_path() + "/" + MoreStrings::cast_to_string(MoreStrings::hash(url.full_url())));
    
    // Create a temporary file
    BinaryFileStream temp_file;
    err = FileManager::open(temp_file, temp_file_path, false);
    
    if (err != DT3_ERR_NONE) {
        network->tcp_close(socket);
        
        LOG_MESSAGE << "HTTPRequest: Unable to open file for writing.";
        update_status (STATUS_ERROR, 0,0);
        return;
    }
    
    LOG_MESSAGE << "HTTPRequest: Opened temp file at " << temp_file_path.full_path();

    
    // Temporary storage for buffer
    std::string data;
        
    // Timer for timeout
    TimerHires timeout_timer;
    
    do {

        // Get the results
        NetworkPacket packet;
        packet.set_data_size(1024*16);

        err = network->tcp_recv(packet,socket);
        
        // If we recieved some data, append it to the buffer
        if (packet.data_size() > 0) {
            data += packet.data_as_string();
            append_data(data, temp_file);
            timeout_timer.reset_abs_time();
        }
        
        // Check complete
        if ( (_current_size == _total_size) && (_total_size > 0) ) {
            break;
        }
        
        // If we hit our timeout, then we abort
        if (timeout_timer.abs_time() > timeout) {
            network->tcp_close(socket);
            
            LOG_MESSAGE << "Http request timed out!";
            update_status (STATUS_ERROR, 0,0);
            
            // Remove the temporary file
            temp_file_path.del();
            return;
        }
        
        // Check for cancel
        if (_cancelled) {
            network->tcp_close(socket);
            
            LOG_MESSAGE << "Http request cancelled!";
            update_status (STATUS_CANCELLED, 0,0);
            
            // Remove the temporary file
            temp_file_path.del();
            return;
        }
        
    } while (err == DT3_ERR_NET_WOULD_BLOCK || err == DT3_ERR_NONE);
    
    // Close the connection, we're done
    network->tcp_close(socket);
    
    // Close off the stream
    finalize_data(data, temp_file);

    //
    // Finalizing phase
    //
    
    // Move the file
    save_path.del();
    temp_file_path.move(save_path);
    
    LOG_MESSAGE << "Saving file to " << save_path.full_path();


    // Final update of status
    update_status (STATUS_COMPLETE, _current_size, _total_size);
}
예제 #21
0
NetworkPacket::NetworkPacket(const NetworkPacket& packet) {
    copyContents(packet.getNode(), packet.getByteArray());
}
예제 #22
0
void SpellHandler::HandleMsg( NetworkPacket & recv_data, GameClient *pClient )
{
    NetworkPacket data;
    NetworkPacket data2;
    char f[256];
    sprintf(f, "WORLD: Spell 0x%.4X", recv_data.opcode);
    LOG.outString( f );
    switch (recv_data.opcode)
    {
        case CMSG_USE_ITEM:
        {
            //printf("ok got opcode here %u\n", recv_data.length);

            uint8 packslot,slot;
            uint16 targets;
            uint8 spell;

            int datalen = recv_data.length;
            recv_data >> packslot >> slot >> spell;
            recv_data >> targets;
            //if (targets == 0)
            //  return;
            uint32 spellid;
            //printf("recived data!\n");
            //printf("Item ID - %d\nItem GUID - %d\n",pClient->getCurrentChar()->getItemIdBySlot(slot),pClient->getCurrentChar()->getGuidBySlot(slot));
            Item *tmpItem = WORLDSERVER.GetItem( pClient->getCurrentChar()->getItemIdBySlot(slot) );
            spellid = tmpItem->SpellID[spell - 1];
            for(int i = 0;i < 5;i++)
            {
                //printf("spell number %d - %d\n",i,tmpItem->SpellID[i]);
            }

            data.Clear();
            data.Initialize (datalen - 3 + 32, SMSG_SPELL_GO);
            data << pClient->getCurrentChar()->GetGUID().sno << pClient->getCurrentChar()->GetGUID ().type;
            data << pClient->getCurrentChar()->GetGUID().sno << pClient->getCurrentChar()->GetGUID ().type;
            data << uint32(spellid);
            data << uint8(0x00) << uint8(0x01);

            if( targets & 0x2 || targets & 0x800 || targets & 0x8000 )
            {
                guid unitTarget;
                recv_data >> unitTarget.sno >> unitTarget.type;
                data << uint8(0x01);
                data << unitTarget.sno << unitTarget.type;
                data << uint8(0x00);
                data << uint16(targets);
                data << unitTarget.sno << unitTarget.type;
            }

            SpellInformation spellInfo;
                                                            //get a hook for the DB
            DatabaseInterface *dbi = DATABASE.createDatabaseInterface();
                                                            //returns a SpellInformation object/struct
            spellInfo = dbi->GetSpellInformation ( tmpItem->SpellID[0] );
            DATABASE.removeDatabaseInterface( dbi );        //clean up used resources

            if(spellInfo.spell_type == (uint32)POTIONS)
                usePotion(pClient, tmpItem->SpellID[0], spellInfo, targets);

        }break;

        case CMSG_CAST_SPELL:
        {
            uint32 spell, target1, target2;
            uint16 flags;
            uint8 hitCount ,missCount;
            recv_data >> spell >> flags;

            guid pguid = pClient->getCurrentChar()->GetGUID();

            SpellInformation spellInfo;
                                                            //get a hook for the DB
            DatabaseInterface *dbi = DATABASE.createDatabaseInterface();
            spellInfo = dbi->GetSpellInformation ( spell ); //returns a SpellInformation object/struct
            DATABASE.removeDatabaseInterface( dbi );        //clean up used resources

            //let's check spell type:
            if( spellInfo.spell_type == (uint32)SINGLE_TARGET)
            {
                recv_data >> target1 >> target2;
                printf("recv_data >> spell: %u\n", spell);
                printf("recv_data >> flags: %u\n", flags);

                Unit* pUnit_target = WORLDSERVER.GetCreature(target1);
                if(pUnit_target)
                {
                    if(spellInfo.race == 0 || pUnit_target->getRace() == spellInfo.race)
                    {
                        //if(  > spellInfo.Range ){
                        data.Clear();
                        data.Initialize( 36, SMSG_SPELL_START );
                        data << pguid.sno << pguid.type << pguid.sno << pguid.type << spell;
                        data << flags << uint32 (3500) << flags << target1 << target2;
                        pClient->SendMsg( &data );

                        hitCount = 1;
                        missCount = 0;

                        data2.Clear();
                        data2.Initialize( 42, SMSG_SPELL_GO );
                        data2 << pguid.sno << pguid.type << pguid.sno << pguid.type;
                        data2 << spell << uint16 (0x0100) << hitCount << target1 << target2;
                        data2 << missCount << flags << target1 << target2;

                        uint32 damage = spellInfo.DmgPlus1+rand()%spellInfo.RandomPercentDmg;
                        WORLDSERVER.mCombatHandler.AttackerStateUpdate(pClient->getCurrentChar( ), WORLDSERVER.getCreatureMap( )[ target1 ], damage);

                        if(spellInfo.addDuration > 0)
                        {
                            Unit* pCast_target = WORLDSERVER.GetCreature(target1);
                            if( pCast_target )
                            {
                                uint32 time = spellInfo.addDuration/1000;
                                uint32 addDmg = (uint32)((float)spellInfo.addDmg/(float)time);
                                if(addDmg == 0)
                                    addDmg = 1;

                                pCast_target->m_damageDuration = spellInfo.addDuration/1000;
                                pCast_target->m_damage = addDmg;
                                pCast_target->m_Attacker = pClient->getCurrentChar()->GetGUID();
                            }
                        }

                        uint32 mana = pClient->getCurrentChar()->getUpdateValue( UNIT_FIELD_POWER1 );
                        pClient->getCurrentChar( )->setUpdateValue( UNIT_FIELD_POWER1, mana-spellInfo.ManaCost );

                        data.Clear();
                        data.Initialize( 5, SMSG_CAST_RESULT );
                        data << spell << uint8( 0x01);
                        pClient->SendMsg( &data );

                        pClient->getCurrentChar()->SendMessageToSet(&data2, true);
                    }
                    else
                    {
                        data.Clear();
                        data.Initialize( 6, SMSG_CAST_RESULT );
                        data << spell << uint8( 0x02);
                        data << uint8(9);
                        pClient->SendMsg( &data );
                    }
                }

            }
            else if( spellInfo.spell_type == (uint32)MULTI_TARGET )
예제 #23
0
void NetworkServer::rawSend(const BitStream& bs,
	const NetworkPacket& packet, const User& user)
{
	assert(isConnected());
	sendBitStream(*_peer, bs, packet.params(), user.address());
}