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; }
void CCDemuxerThread::run_demuxer() { end = false; audio_stream = demuxer->audio_streams(); video_stream = demuxer->video_streams(); int index = 0; PacketData pkt; end = false; pause(false); packet_queue *aqueue = audio_thread->packet_queues(); packet_queue *vqueue = video_thread->packet_queues(); aqueue->set_blocking(true); vqueue->set_blocking(true); bool _has_audio = audio_thread->decoder()->is_available(); bool _has_video = video_thread->decoder()->is_available(); demuxer->started_ = true; while (!end) { if (try_pause()) continue; mutex_.lock(); if (!demuxer->read_frame()) { mutex_.unlock(); continue; } mutex_.unlock(); index = demuxer->stream(); pkt = *demuxer->packet(); if (index == audio_stream) { if (_has_video) aqueue->block_full(vqueue->size() >= vqueue->threshold()); aqueue->put(std::move(pkt)); //affect video_thread } else if (index == video_stream) { if (_has_audio) vqueue->block_full(aqueue->size() >= aqueue->threshold()); vqueue->put(std::move(pkt)); //affect audio_thread } else { //subtitle continue; } } aqueue->put(PacketData()); vqueue->put(PacketData()); qDebug("Demux thread stops running...."); }
RecordTSIG( const std::string &in_key_name = "", const std::string &in_algo = "HMAC-MD5.SIG-ALG.REG.INT", uint64_t in_signed_time = 0, uint16_t in_fudge = 0, uint16_t in_mac_size = 0, const PacketData & in_mac = PacketData(), uint16_t in_original_id = 0, uint16_t in_error = 0, uint16_t in_other_length = 0, const PacketData & in_other = PacketData() ) : key_name( in_key_name ), algorithm( in_algo ), signed_time( in_signed_time ), fudge( in_fudge ), mac_size( in_mac_size ), mac( in_mac ), original_id( in_original_id ), error( in_error ), other_length( in_other_length ), other( in_other ) { }
void CGameServerPlayer::PrepareInitialPackets() { QueuePacket(PacketData(std::begin(g_client0_login1), std::end(g_client0_login1))); QueuePacket(PacketData(std::begin(g_client0_login2), std::end(g_client0_login2))); QueuePacket(PacketData(std::begin(g_client0_login3), std::end(g_client0_login3))); QueuePacket(PacketData(std::begin(g_client0_login4), std::end(g_client0_login4))); QueuePacket(GetMotd()); QueuePacket(PacketData(std::begin(g_client0_login7), std::end(g_client0_login7))); QueuePacket(GetCharacterInfo()); QueuePacket(GetInventoryInfo()); QueuePacket(PacketData(std::begin(g_client0_login11), std::end(g_client0_login11))); QueuePacket(PacketData(std::begin(g_client0_login12), std::end(g_client0_login12))); QueuePacket(PacketData(std::begin(g_client0_login13), std::end(g_client0_login13))); QueuePacket(PacketData(std::begin(g_client0_login14), std::end(g_client0_login14))); ResetInstance(); #if 0 //Test mob in room SpawnNpc(1155006509, 10516, 3105901, 159.8f, 0, 156.4f, 0); #endif }
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; }
namespace dns { struct TSIGInfo { std::string name; PacketData key; std::string algorithm; PacketData mac; uint64_t signed_time; uint16_t fudge; uint16_t mac_size; uint16_t original_id; uint16_t error; PacketData other; TSIGInfo() : name(), key(), algorithm( "HMAC-MD5.SIG-ALG.REG.INT" ), mac(), signed_time( 0 ), fudge( 0 ), mac_size( 0 ), original_id( 0 ), error( 0 ), other() { } }; class RecordTSIG : public RData { public: Domainname key_name = ""; Domainname algorithm = "HMAC-MD5.SIG-ALG.REG.INT"; uint64_t signed_time = 0; uint16_t fudge = 0; uint16_t mac_size = 0; PacketData mac; uint16_t original_id = 0; uint16_t error = 0; uint16_t other_length = 0; PacketData other; public: RecordTSIG( const std::string &in_key_name = "", const std::string &in_algo = "HMAC-MD5.SIG-ALG.REG.INT", uint64_t in_signed_time = 0, uint16_t in_fudge = 0, uint16_t in_mac_size = 0, const PacketData & in_mac = PacketData(), uint16_t in_original_id = 0, uint16_t in_error = 0, uint16_t in_other_length = 0, const PacketData & in_other = PacketData() ) : key_name( in_key_name ), algorithm( in_algo ), signed_time( in_signed_time ), fudge( in_fudge ), mac_size( in_mac_size ), mac( in_mac ), original_id( in_original_id ), error( in_error ), other_length( in_other_length ), other( in_other ) { } virtual std::string toString() const; virtual void outputWireFormat( WireFormat & ) const; virtual uint16_t type() const { return TYPE_TSIG; } virtual uint16_t size() const; static RDataPtr parse( const uint8_t *packet, const uint8_t *begin, const uint8_t *end, const Domainname &key_name ); }; struct MessageInfo; void addTSIGResourceRecord( const TSIGInfo &tsig_info, WireFormat &message, const PacketData &query_mac = PacketData() ); bool verifyTSIGResourceRecord( const TSIGInfo &tsig_info, const MessageInfo &packet_info, const WireFormat &message ); }
void CGameServerPlayer::SendTeleportSequence(uint32 levelId, uint32 musicId, float x, float y, float z, float angle) { QueuePacket(PacketData(std::begin(g_client0_moor1), std::end(g_client0_moor1))); QueuePacket(PacketData(std::begin(g_client0_moor2), std::end(g_client0_moor2))); QueuePacket(PacketData(std::begin(g_client0_moor3), std::end(g_client0_moor3))); QueuePacket(PacketData(std::begin(g_client0_moor4), std::end(g_client0_moor4))); QueuePacket(PacketData(std::begin(g_client0_moor5), std::end(g_client0_moor5))); QueuePacket(PacketData(std::begin(g_client0_moor6), std::end(g_client0_moor6))); QueuePacket(PacketData(std::begin(g_client0_moor7), std::end(g_client0_moor7))); QueuePacket(PacketData(std::begin(g_client0_moor8), std::end(g_client0_moor8))); QueuePacket(PacketData(std::begin(g_client0_moor9), std::end(g_client0_moor9))); { CCompositePacket result; { CSetMusicPacket packet; packet.SetSourceId(PLAYER_ID); packet.SetTargetId(PLAYER_ID); packet.SetMusicId(musicId); result.AddPacket(packet.ToPacketData()); } { CSetWeatherPacket packet; packet.SetSourceId(PLAYER_ID); packet.SetTargetId(PLAYER_ID); packet.SetWeatherId(CSetWeatherPacket::WEATHER_CLEAR); result.AddPacket(packet.ToPacketData()); } { CSetMapPacket packet; packet.SetSourceId(PLAYER_ID); packet.SetTargetId(PLAYER_ID); packet.SetMapId(levelId); result.AddPacket(packet.ToPacketData()); } QueuePacket(result.ToPacketData()); } QueuePacket(PacketData(std::begin(g_client0_moor11), std::end(g_client0_moor11))); QueuePacket(PacketData(std::begin(g_client0_moor12), std::end(g_client0_moor12))); { PacketData outgoingPacket(std::begin(g_client0_moor13), std::end(g_client0_moor13)); { const uint32 setInitialPositionBase = 0x360; CSetInitialPositionPacket setInitialPosition; setInitialPosition.SetSourceId(PLAYER_ID); setInitialPosition.SetTargetId(PLAYER_ID); setInitialPosition.SetX(x); setInitialPosition.SetY(y); setInitialPosition.SetZ(z); setInitialPosition.SetAngle(angle); auto setInitialPositionPacket = setInitialPosition.ToPacketData(); memcpy(outgoingPacket.data() + setInitialPositionBase, setInitialPositionPacket.data(), setInitialPositionPacket.size()); } QueuePacket(outgoingPacket); } QueuePacket(GetInventoryInfo()); QueuePacket(PacketData(std::begin(g_client0_moor21), std::end(g_client0_moor21))); //QueuePacket(PacketData(std::begin(g_client0_moor22), std::end(g_client0_moor22))); if(!m_zoneMasterCreated) { //Zone Master QueuePacket(PacketData(std::begin(g_client0_moor23), std::end(g_client0_moor23))); /* QueuePacket(PacketData(std::begin(g_client0_moor24), std::end(g_client0_moor24))); QueuePacket(PacketData(std::begin(g_client0_moor25), std::end(g_client0_moor25))); QueuePacket(PacketData(std::begin(g_client0_moor26), std::end(g_client0_moor26))); QueuePacket(PacketData(std::begin(g_client0_moor27), std::end(g_client0_moor27))); QueuePacket(PacketData(std::begin(g_client0_moor28), std::end(g_client0_moor28))); QueuePacket(PacketData(std::begin(g_client0_moor29), std::end(g_client0_moor29))); QueuePacket(PacketData(std::begin(g_client0_moor30), std::end(g_client0_moor30))); QueuePacket(PacketData(std::begin(g_client0_moor31), std::end(g_client0_moor31))); QueuePacket(PacketData(std::begin(g_client0_moor32), std::end(g_client0_moor32))); QueuePacket(PacketData(std::begin(g_client0_moor33), std::end(g_client0_moor33))); QueuePacket(PacketData(std::begin(g_client0_moor34), std::end(g_client0_moor34))); QueuePacket(PacketData(std::begin(g_client0_moor35), std::end(g_client0_moor35))); QueuePacket(PacketData(std::begin(g_client0_moor36), std::end(g_client0_moor36))); QueuePacket(PacketData(std::begin(g_client0_moor37), std::end(g_client0_moor37))); */ //Enables chat? // QueuePacket(PacketData(std::begin(g_client0_moor38), std::end(g_client0_moor38))); { CCompositePacket packet; packet.AddPacket(PacketData(std::begin(g_client0_moor38), std::end(g_client0_moor38))); QueuePacket(packet.ToPacketData()); } // QueuePacket(PacketData(std::begin(g_client0_moor39), std::end(g_client0_moor39))); // QueuePacket(PacketData(std::begin(g_client0_moor40), std::end(g_client0_moor40))); ResetInstance(); //Only makes sense in Black Shroud for now if(levelId == CSetMapPacket::MAP_BLACKSHROUD) { const auto& actorDatabase = CGlobalData::GetInstance().GetActorDatabase(); for(const auto& actorInfo : actorDatabase.GetActors()) { SpawnNpc(actorInfo.id, actorInfo.baseModelId, actorInfo.nameStringId, std::get<0>(actorInfo.pos), std::get<1>(actorInfo.pos), std::get<2>(actorInfo.pos), 0); } } m_zoneMasterCreated = true; } }
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); }