void CGameServerPlayer::ProcessInitialHandshake(unsigned int clientId, const PacketData& subPacket)
{
	if(m_sentInitialHandshake) return;

	const char* characterIdString = reinterpret_cast<const char*>(subPacket.data() + 0x14);
	uint32 characterId = atoi(characterIdString);

	CLog::GetInstance().LogDebug(LOG_NAME, "Initial handshake for clientId = %d and characterId = 0x%0.8X", clientId, characterId);

	if(clientId == 1)
	{
		//Put player in instance
		{
			auto playerActor = std::make_unique<CPlayerActor>(characterId);
			playerActor->SetId(PLAYER_ID);
			playerActor->RawPacketReady.connect([&] (const PacketData& packet) { m_currentComposite.AddPacket(packet); });
			playerActor->LocalPacketReady.connect([&] (CActor* actor, const PacketPtr& packet) { QueueToCurrentComposite(actor, packet); });
			playerActor->GlobalPacketReady.connect([&] (CActor* actor, const PacketPtr& packet) { QueueToCurrentComposite(actor, packet); });
			m_instance.AddActor(std::move(playerActor));
		}

		PrepareInitialPackets();
	}
	else if(clientId == 2)
	{
		QueuePacket(PacketData(std::begin(g_client1_login1), std::end(g_client1_login1)));
		QueuePacket(PacketData(std::begin(g_client1_login2), std::end(g_client1_login2)));
	}

	m_sentInitialHandshake = true;
}
Exemple #2
0
bool Host::broadcast(ChannelID channel, PacketType type, const PacketData& data)
{
  if (!isServer())
  {
    logError("Only the server is allowed to broadcast");
    return false;
  }

  uint32 flags = 0;

  if (type == RELIABLE)
    flags |= ENET_PACKET_FLAG_RELIABLE;
  else
  {
    if (type == UNSEQUENCED)
      flags |= ENET_PACKET_FLAG_UNSEQUENCED;

    flags |= ENET_PACKET_FLAG_NO_ALLOCATE;
  }

  ENetPacket* packet = enet_packet_create(data.data(), data.size(), flags);
  if (!packet)
  {
    logError("Failed to create ENet packet");
    return false;
  }

  enet_host_broadcast((ENetHost*) m_object, channel, packet);
  return true;
}
Exemple #3
0
bool Peer::sendPacket(ChannelID channel,
                      PacketType type,
                      const PacketData& data)
{
  uint32 flags = 0;

  if (type == RELIABLE)
    flags |= ENET_PACKET_FLAG_RELIABLE;
  else
  {
    if (type == UNSEQUENCED)
      flags |= ENET_PACKET_FLAG_UNSEQUENCED;

    flags |= ENET_PACKET_FLAG_NO_ALLOCATE;
  }

  ENetPacket* packet = enet_packet_create(data.data(), data.size(), flags);
  if (!packet)
  {
    logError("Failed to create ENet packet");
    return false;
  }

  if (enet_peer_send((ENetPeer*) m_peer, channel, packet) < 0)
  {
    logError("Failed to send ENet packet to peer %s", m_name.c_str());
    return false;
  }

  return true;
}
Exemple #4
0
PacketData CBasePacket::ToPacketData() const
{
	assert(m_packetSize >= PACKET_HEADER_SIZE);
	assert(m_sourceId != 0);
	assert(m_targetId != 0);

	PacketData result;
	result.resize(m_packetSize);

	//Write subpacket header
	*reinterpret_cast<uint16*>(result.data() + 0x00) = m_packetSize;
	*reinterpret_cast<uint16*>(result.data() + 0x02) = 3;			//Unknown
	*reinterpret_cast<uint32*>(result.data() + 0x04) = m_sourceId;
	*reinterpret_cast<uint32*>(result.data() + 0x08) = m_targetId;
	*reinterpret_cast<uint32*>(result.data() + 0x0C) = 0xFED2E000;	//Unknown

	//Write command header
	*reinterpret_cast<uint16*>(result.data() + 0x10) = 0x14;		//Unknown
	*reinterpret_cast<uint16*>(result.data() + 0x12) = m_commandId;
	*reinterpret_cast<uint32*>(result.data() + 0x14) = 0;
	*reinterpret_cast<uint32*>(result.data() + 0x18) = time(nullptr);
	*reinterpret_cast<uint32*>(result.data() + 0x1C) = 0;

	return result;
}
	SubPacketArray CPacketUtils::SplitPacketSubPacket(const PacketData& packet)
	{
		printf("%s", CPacketUtils::DumpPacket(packet).c_str());

		SubPacketArray subPackets;
		if (packet.size() < sizeof(PACKETHEADER))
		{
			CLog::GetInstance().LogError(LOG_NAME, "Packet to split is smaller than PACKETHEADER.\r\n");
			return subPackets;
		}
		const uint8_t* packetData = packet.data();
		PACKETHEADER header = *reinterpret_cast<const PACKETHEADER*>(packetData);
		assert(packet.size() == header.packetSize);
		uint32_t currentSize = header.packetSize - sizeof(PACKETHEADER);
		packetData += sizeof(PACKETHEADER);

		while (currentSize != 0)
		{
			SUBPACKETHEADER subHeader = *reinterpret_cast<const SUBPACKETHEADER*>(packetData);
			if (subHeader.subPacketSize == 0)
			{
				CLog::GetInstance().LogError(LOG_NAME, "Got zero sized subpacket. Stopping packet processing.\r\n");
				break;
			}

			if (subHeader.subPacketSize > currentSize)
			{
				CLog::GetInstance().LogError(LOG_NAME, "Subpacket doesn't fit in packet. Stopping packet processing.\r\n");
				break;
			}

			auto subPacket = PacketData(packetData, packetData + subHeader.subPacketSize);
			subPackets.push_back(subPacket);

			currentSize -= subHeader.subPacketSize;
			packetData += subHeader.subPacketSize;
		}
		return subPackets;
	}
	uint16_t CPacketUtils::GetSubPacketCommand(const PacketData& subPacket)
	{
		SUBPACKETHEADER header = *reinterpret_cast<const SUBPACKETHEADER*>(subPacket.data());
		return  header.subCommandId;
	}
Exemple #7
0
 uint16_t send( const PacketData &packet )
 {
     return send( packet.data(), packet.size() );
 }
uint16 CPacketUtils::GetSubPacketCommand(const PacketData& subPacket)
{
	return *reinterpret_cast<const uint16*>(subPacket.data() + 0x12);
}
void CGameServerPlayer::ProcessScriptCommand(const PacketData& subPacket)
{
	uint32 clientTime = *reinterpret_cast<const uint32*>(&subPacket[0x18]);
	uint32 sourceId = *reinterpret_cast<const uint32*>(&subPacket[0x20]);
	uint32 targetId = *reinterpret_cast<const uint32*>(&subPacket[0x24]);
	const char* commandName = reinterpret_cast<const char*>(subPacket.data()) + 0x31;

	CLog::GetInstance().LogDebug(LOG_NAME, "ProcessScriptCommand: %s Source Id = 0x%0.8X, Target Id = 0x%0.8X.", commandName, sourceId, targetId);

	auto playerActor = m_instance.GetActor<CPlayerActor>(PLAYER_ID);
	if(playerActor == nullptr)
	{
		CLog::GetInstance().LogError(LOG_NAME, "Failed to get player actor.");
		return;
	}

	if(!strcmp(commandName, "commandRequest"))
	{
		//commandRequest (emote, changing equipment, ...)
		playerActor->ProcessCommandRequest(targetId, subPacket);
	}
	else if(!strcmp(commandName, "commandContent"))
	{
		switch(targetId)
		{
		case 0xA0F05E9B:
			//Quit
			CLog::GetInstance().LogDebug(LOG_NAME, "Quit.");
			m_disconnect = true;
			break;
		case 0xA0F05E9C:
			//Teleport
			CLog::GetInstance().LogDebug(LOG_NAME, "Teleport.");
			m_disconnect = true;
			break;
		}
	}
	else if(!strcmp(commandName, "commandForced"))
	{
		playerActor->ProcessCommandForced(targetId);
	}
	else if(!strcmp(commandName, "commandDefault"))
	{
		playerActor->ProcessCommandDefault(targetId);
	}
	else if(!strcmp(commandName, "talkDefault"))
	{
		switch(targetId)
		{
		case 0x47A00007:
			//Talking to the door inside the room
			{
				static const uint8 commandRequestPacket[] =
				{
					0x01, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x01, 0x00, 0x52, 0xE2, 0xA4, 0xEE, 0x3B, 0x01, 0x00, 0x00,
					0xb0, 0x00, 0x03, 0x00, 0x41, 0x29, 0x9b, 0x02, 0x41, 0x29, 0x9b, 0x02, 0x00, 0xe0, 0xd2, 0xfe,
					0x14, 0x00, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0xe9, 0xe0, 0x50, 0x00, 0x00, 0x00, 0x00,
					0x41, 0x29, 0x9b, 0x02, 0x07, 0x00, 0xa0, 0x47, 0x01, 0x74, 0x61, 0x6c, 0x6b, 0x44, 0x65, 0x66,
					0x61, 0x75, 0x6c, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74,
					0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x02, 0x9b, 0x29, 0x41, 0x06, 0xa0,
					0xf1, 0xaf, 0xcd, 0x02, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x54, 0x61, 0x6c, 0x6b, 0x57,
					0x69, 0x74, 0x68, 0x49, 0x6e, 0x6e, 0x5f, 0x45, 0x78, 0x69, 0x74, 0x44, 0x6f, 0x6f, 0x72, 0x00,
					0x05, 0x05, 0x05, 0x05, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0xe8, 0x4e, 0x40, 0x00, 0x00, 0x00,
				};

				QueuePacket(PacketData(std::begin(commandRequestPacket), std::end(commandRequestPacket)));
			}
			break;
		default:
#if 0
			//Talking Test (doesn't work)
			{
				static const uint8 commandRequestPacket[] =
				{
					0x01, 0x01, 0x00, 0x00, 0xC0, 0x00, 0x01, 0x00, 0xD2, 0x16, 0x9E, 0xEE, 0x3B, 0x01, 0x00, 0x00, 
					0xB0, 0x00, 0x03, 0x00, 0x41, 0x29, 0x9B, 0x02, 0x41, 0x29, 0x9B, 0x02, 0x00, 0xE0, 0xD2, 0xFE, 
					0x14, 0x00, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x14, 0xED, 0xE0, 0x50, 0x00, 0x00, 0x00, 0x00, 
					0x41, 0x29, 0x9B, 0x02, 0x82, 0x00, 0x70, 0x46, 0x01, 0x74, 0x61, 0x6C, 0x6B, 0x44, 0x65, 0x66, 
					0x61, 0x75, 0x6C, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x45, 
					0x76, 0x65, 0x6E, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xA0, 0xF1, 0xAF, 0xCD, 0x06, 0xA0, 
					0xF1, 0xB4, 0x00, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 
					0x00, 0x00, 0x03, 0xF1, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6C, 0xB8, 0x45, 0x40, 0x00, 0x00, 0x00, 
				};

				QueuePacket(PacketData(std::begin(commandRequestPacket), std::end(commandRequestPacket)));
			}
#endif
			m_disconnect = true;
			break;
		}
	}
	else
	{
		//Anything else will probably crash, so just bail
		m_disconnect = true;
	}
}
void CGameServerPlayer::ProcessChat(const PacketData& subPacket)
{
	const char* chatText = reinterpret_cast<const char*>(subPacket.data() + 0x3C);

	static std::map<std::string, uint32> weatherCommands;
	if(weatherCommands.empty())
	{
		weatherCommands["weather_clear"]		= CSetWeatherPacket::WEATHER_CLEAR;
		weatherCommands["weather_fine"]			= CSetWeatherPacket::WEATHER_FINE;
		weatherCommands["weather_cloudy"]		= CSetWeatherPacket::WEATHER_CLOUDY;
		weatherCommands["weather_foggy"]		= CSetWeatherPacket::WEATHER_FOGGY;
		weatherCommands["weather_blustery"]		= CSetWeatherPacket::WEATHER_BLUSTERY;
		weatherCommands["weather_rainy"]		= CSetWeatherPacket::WEATHER_RAINY;
		weatherCommands["weather_stormy"]		= CSetWeatherPacket::WEATHER_STORMY;
		weatherCommands["weather_sandy"]		= CSetWeatherPacket::WEATHER_SANDY;
		weatherCommands["weather_gloomy"]		= CSetWeatherPacket::WEATHER_GLOOMY;
		weatherCommands["weather_dalamud"]		= CSetWeatherPacket::WEATHER_DALAMUD;
	}

	auto weatherCommandIterator = weatherCommands.find(chatText);
	if(weatherCommandIterator != std::end(weatherCommands))
	{
		CCompositePacket result;
		
		{
			CSetWeatherPacket packet;
			packet.SetSourceId(PLAYER_ID);
			packet.SetTargetId(PLAYER_ID);
			packet.SetWeatherId(weatherCommandIterator->second);
			result.AddPacket(packet.ToPacketData());
		}

		QueuePacket(result.ToPacketData());
	}
	else if(!strcmp(chatText, "teleport_mordhona"))
	{
		SendTeleportSequence(CSetMapPacket::MAP_MORDHONA, CSetMusicPacket::MUSIC_MORDHONA, INITIAL_POSITION_MOR_DHONA);
	}
	else if(!strcmp(chatText, "teleport_coerthas"))
	{
		SendTeleportSequence(CSetMapPacket::MAP_COERTHAS, CSetMusicPacket::MUSIC_COERTHAS, INITIAL_POSITION_COERTHAS);
	}
	else if(!strcmp(chatText, "teleport_thanalan"))
	{
		SendTeleportSequence(CSetMapPacket::MAP_THANALAN, CSetMusicPacket::MUSIC_THANALAN, INITIAL_POSITION_THANALAN);
	}
	else if(!strcmp(chatText, "teleport_lanoscea"))
	{
		SendTeleportSequence(CSetMapPacket::MAP_NOSCEA, CSetMusicPacket::MUSIC_NOSCEA, INITIAL_POSITION_NOSCEA);
	}
	else if(!strcmp(chatText, "teleport_gridania"))
	{
		SendTeleportSequence(CSetMapPacket::MAP_BLACKSHROUD, CSetMusicPacket::MUSIC_GRIDANIA, INITIAL_POSITION_GRIDANIA_INN);
	}
	else if(!strcmp(chatText, "teleport_rivenroad"))
	{
		SendTeleportSequence(CSetMapPacket::MAP_RIVENROAD, CSetMusicPacket::MUSIC_MORDHONA, INITIAL_POSITION_RIVENROAD);
	}
	else if(!strcmp(chatText, "teleport_largeboat"))
	{
		SendTeleportSequence(CSetMapPacket::MAP_LARGEBOAT, CSetMusicPacket::MUSIC_NOSCEA, INITIAL_POSITION_LARGEBOAT);
	}
	else if(!strcmp(chatText, "teleport_smallboat"))
	{
		SendTeleportSequence(CSetMapPacket::MAP_SMALLBOAT, CSetMusicPacket::MUSIC_NOSCEA, INITIAL_POSITION_SMALLBOAT);
	}
	else if(!strcmp(chatText, "ride_chocobo"))
	{
		QueuePacket(PacketData(std::begin(g_chocoboRider1), std::end(g_chocoboRider1)));
		QueuePacket(PacketData(std::begin(g_chocoboRider2), std::end(g_chocoboRider2)));
	}
//	printf("%s\r\n", chatText);
}