PacketData CGameServerPlayer::GetInventoryInfo() { auto playerActor = m_instance.GetActor<CPlayerActor>(PLAYER_ID); const auto& inventory = playerActor->GetInventory(); PacketData outgoingPacket; unsigned int itemCount = inventory.size(); //Item count can be less than 200, but we have to make sure no equipped items are using item indices over the itemCount assert(itemCount <= 200); while(itemCount != 0) { CCompositePacket compositePacket; { unsigned int itemsToCopy = std::min<unsigned int>(itemCount, 32); unsigned int itemBase = itemCount - itemsToCopy; CSetInventoryPacket setInventoryPacket; setInventoryPacket.SetSourceId(PLAYER_ID); setInventoryPacket.SetTargetId(PLAYER_ID); setInventoryPacket.SetItemCount(itemsToCopy); for(unsigned int i = 0; i < itemsToCopy; i++) { const auto& inventoryItem = inventory[i + itemBase]; setInventoryPacket.SetItemIndex(i, i + itemBase + 1); setInventoryPacket.SetItemId(i, inventoryItem.itemId); setInventoryPacket.SetItemDefinitionId(i, inventoryItem.itemDefId); } compositePacket.AddPacket(setInventoryPacket.ToPacketData()); itemCount -= itemsToCopy; } auto compositePacketData = compositePacket.ToPacketData(); outgoingPacket.insert(std::end(outgoingPacket), std::begin(compositePacketData), std::end(compositePacketData)); } return outgoingPacket; }
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; }
void CPacketUtils::EncryptPacket(PacketData& packet) { if(packet.size() <= sizeof(PACKETHEADER)) { assert(0); return; } uint8* data = &packet[0]; uint32 size = packet.size(); data += 0x10; size -= 0x10; while(1) { uint32 subPacketSize = *reinterpret_cast<uint16*>(data); size -= subPacketSize; subPacketSize -= 0x10; data += 0x10; for(unsigned int i = 0; i < subPacketSize; i += 8) { Blowfish_encipher( reinterpret_cast<uint32*>(data + i), reinterpret_cast<uint32*>(data + i + 4)); } data += subPacketSize; if(size == 0) break; } }
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; }
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; }
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; }
bool Host::dispatchEvent(TargetID sourceID, PacketData& data) { const ObjectID recipientID = data.read16(); const EventID eventID = data.read8(); Object* object = findObject(recipientID); if (!object) { if (isClient() || m_objectIDs.bucketOf(recipientID) == ID_BUCKET_UNUSED) logError("Failed to find recipient object %u", recipientID); return false; } object->receiveEvent(sourceID, data, eventID); return true; }
std::string CPacketUtils::DumpPacket(const PacketData& packet) { std::string result; static const unsigned int lineWidth = 0x10; for(unsigned int i = 0; i < (packet.size() + lineWidth - 1) / lineWidth; i++) { for(unsigned int j = 0; j < lineWidth; j++) { unsigned int offset = i * lineWidth + j; if(offset >= packet.size()) { result += " "; } else { char byteString[4]; sprintf(byteString, "%0.2X ", packet[offset]); result += byteString; } } result += " "; for(unsigned int j = 0; j < lineWidth; j++) { unsigned int offset = i * lineWidth + j; if(offset >= packet.size()) continue; char character = packet[offset]; if((character >= 0) && (isdigit(character) || isalpha(character))) { result += character; } else { result += "."; } } result += "\r\n"; } return result; }
void CPacketUtils::EncryptPacket(PacketData& packet) { if (packet.size() <= sizeof(PACKETHEADER)) { assert(0); return; } uint8_t* data = &packet[0]; uint32_t size = (uint32_t)packet.size(); data += sizeof(PACKETHEADER); size -= sizeof(PACKETHEADER); if (size % 8 != 0) { return; } while (1) { SUBPACKETHEADER subPacket = *reinterpret_cast<SUBPACKETHEADER*>(data); uint32_t subPacketSize = subPacket.subPacketSize; size -= subPacketSize; subPacketSize -= sizeof(SUBPACKETHEADER); data += sizeof(SUBPACKETHEADER); for (unsigned int i = 0; i < subPacketSize; i += 8) { Blowfish_encipher( reinterpret_cast<uint32_t*>(data + i), reinterpret_cast<uint32_t*>(data + i + 4)); } data += subPacketSize; if (size == 0) break; } }
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; }
uint16_t send( const PacketData &packet ) { return send( packet.data(), packet.size() ); }
void CCVideoThread::run_video() { DPTR_D(CCVideoThread); if (!d.dec || !d.dec->is_available() || !d.writer) return; reset_state(); Q_ASSERT(d.clock != 0); CCDecodeVideo *dec = static_cast<CCDecodeVideo*>(d.dec); CCVideoRenderer* vo = static_cast<CCVideoRenderer*>(d.writer); while (!d.stop) { if (try_pause()) { if (d.stop) break; } std::unique_lock<std::mutex> lock(d.mutex_); if (d.packets.is_empty() && !d.stop) { d.stop = d.demux_end; if (d.stop) { break; } } PacketData pkt; d.packets.pop(pkt); if (!pkt.is_valid()) { qDebug("Invalid pts or empty packet!"); dec->flush_codec(); continue; } d.delay = pkt.pts - d.clock->value(); if (qAbs(d.delay) < 2.718) { if (d.delay > kSyncThreshold) { av_usleep(d.delay * 1000000); } else if (d.delay < -kSyncThreshold) { //continue; } } else { qDebug("delay %f/%f", d.delay, d.clock->value()); if (d.delay > 0) { av_usleep(0.064 * 1000000); } else { continue; } } d.clock->update_video_pts(pkt.pts); bool vo_ok = vo && vo->is_available(); if (vo_ok) { if (vo->last_width() > 0 && vo->last_height() > 0 && !vo->scale_in()) dec->resize_video(vo->last_size()); else vo->set_source_size(dec->width(), dec->height()); //setLastSize() } ByteArray da(pkt.date); if (d.dec->decode(da)) { d.pts = pkt.pts; d.decoded_datas = d.dec->data_video(); if (vo_ok) { vo->write_data(d.decoded_datas); } /*d.width = dec->width(); d.height = dec->height(); d.decoded_datas = d.dec->data_video(); if (vo && vo->is_available()) { vo->set_source_size(dec->width(), dec->height()); vo->write_data(d.decoded_datas); }*/ } if (vo_ok && !vo->scale_in()) vo->set_source_size(vo->video_sizes()); } qDebug("Video thread stops running..."); }
int MediaThread::publishPacket(PacketData &packetData, const Name& packetPrefix, PacketNumber packetNo, PrefixMetaInfo prefixMeta, double captureTimestamp) { if (!faceProcessor_->getTransport()->getIsConnected()) return notifyError(-1, "transport is not connected"); Name prefix = packetPrefix; Segmentizer::SegmentList segments; if (RESULT_FAIL(Segmentizer::segmentize(packetData, segments, segSizeNoHeader_))) return notifyError(-1, "packet segmentation failed"); #ifdef DROP_FRAMES static int count = 0; count++; bool drop = (count%100 == 0); #endif #ifdef DELAY_FRAMES static int count2 = 0; count2++; bool delay = (count2 > 200 && count2 % 200 < 10); if (delay) { LogWarnC << "drop frame " << packetPrefix << std::endl; return segments.size(); } #endif try { // update metadata for the packet PacketData::PacketMetadata metadata = { NdnRtcUtils::currentFrequencyMeterValue(packetRateMeter_), NdnRtcUtils::millisecondTimestamp(), captureTimestamp}; packetData.setMetadata(metadata); prefixMeta.crcValue_ = packetData.getCrcValue(); Name metaSuffix = PrefixMetaInfo::toName(prefixMeta); for (Segmentizer::SegmentList::iterator it = segments.begin(); it != segments.end(); ++it) { // add segment # Name segmentName = prefix; segmentName.appendSegment(it-segments.begin()); // lookup for pending interests and construct metaifno accordingly SegmentData::SegmentMetaInfo meta = {0,0,0}; bool pitHit = (lookupPrefixInPit(segmentName, meta) != 0); // add name suffix meta info segmentName.append(metaSuffix); // pack into network data SegmentData segmentData(it->getDataPtr(), it->getPayloadSize(), meta); Data ndnData(segmentName); ndnData.getMetaInfo().setFreshnessPeriod(settings_->dataFreshnessMs_); ndnData.setContent(segmentData.getData(), segmentData.getLength()); settings_->keyChain_->sign(ndnData, settings_->certificateName_); if (memCache_.get() && !pitHit) { // according to http://named-data.net/doc/ndn-ccl-api/memory-content-cache.html#memorycontentcache-registerprefix-method // adding content should be synchronized with the processEvents // call; this must be done in calling routines memCache_->add(ndnData); LogTraceC << "added to cache " << segmentName << " " << ndnData.getContent().size() << " bytes" << std::endl; } else { SignedBlob encodedData = ndnData.wireEncode(); faceProcessor_->getTransport()->send(*encodedData); LogTraceC << "sent " << segmentName << " " << ndnData.getContent().size() << " bytes" << std::endl; } #if 0 // enable this if you want measuring outgoing bitrate w/o ndn overhead NdnRtcUtils::dataRateMeterMoreData(dataRateMeter_, ndnData.getContent().size()); #else // enable this if you want measuring outgoing bitrate with ndn overhead NdnRtcUtils::dataRateMeterMoreData(dataRateMeter_, ndnData.getDefaultWireEncoding().size()); #endif #ifdef DROP_FRAMES if (drop) { LogWarnC << "drop frame " << packetPrefix << std::endl; break; } #endif } // for cleanPitForFrame(prefix); } catch (std::exception &e) { return notifyError(RESULT_ERR, "got error from ndn library while sending data: %s", e.what()); } int64_t timestamp = NdnRtcUtils::millisecondTimestamp(); if (publishingTimestampMs_) { int64_t delay = timestamp-publishingTimestampMs_; ((delay > FRAME_DELAY_DEADLINE) ? LogWarnC : LogTraceC) << "frame publishing delay " << delay << " (" << packetPrefix << ")" << std::endl; } publishingTimestampMs_ = timestamp; return segments.size(); }
uint16 CPacketUtils::GetSubPacketCommand(const PacketData& subPacket) { return *reinterpret_cast<const uint16*>(subPacket.data() + 0x12); }
int main(){ int port = 11111; const char * addr = "127.0.0.1"; // Some non-trivial test data to pass around PacketData data; // ------------------------------------------------------------------------- // Constructing packets { osc::Packet p; // Create a message-only packet p.beginMessage("/test"); p << "a string" << data.i << data.f << data.d << data.c; p << osc::Blob(&data, sizeof(data)); p.endMessage(); assert(!p.isBundle()); assert(p.isMessage()); printf("\nOSC Message\n"); p.printRaw(); // Create a more complicated packet containing bundles p.clear(); // clear any previous contents p.beginBundle(12345); p.addMessage("/message11", (int)0x12345678, 1.f, 1., "hello world!"); p.addMessage("/message12", (int)0x23456789); p.beginBundle(12346); p.addMessage("/message21", (int)0x3456789a); p.beginBundle(12347); p.addMessage("/message31", (int)0x456789ab); p.endBundle(); p.endBundle(); p.addMessage("/message13", (int)0x56789abc); p.endBundle(); assert(p.isBundle()); assert(!p.isMessage()); printf("\nOSC Bundle\n"); p.printRaw(); } // ------------------------------------------------------------------------- // Sending packets { osc::Send s(port, addr); // A simple way to send a message s.send("/foo", 1, 2.3, "four"); // Sending a fairly complex time-tagged bundle osc::TimeTag timeNow = 0; osc::TimeTag dt = 1; s.beginBundle(timeNow); s.addMessage("/message11", 12345678, 1.f, 1., "hello world!"); s.addMessage("/message12", 23456789); s.beginBundle(timeNow + dt); s.addMessage("/message21", 3456789); s.beginBundle(timeNow + dt*2); s.addMessage("/message31", 456789); s.endBundle(); s.endBundle(); s.addMessage("/message13", 56789); s.endBundle(); s.send(); // If sending data infrequently, we can just use a temporary object osc::Send(port, addr).send("/foo", 1, 2.3, "four"); } // ------------------------------------------------------------------------- // Receiving packets { struct OSCHandler : public osc::PacketHandler{ void onMessage(osc::Message& m){ m.print(); assert(m.typeTags() == "sifdcb"); assert(m.addressPattern() == "/test"); std::string s; PacketData d; osc::Blob b; d.clear(); m >> s >> d.i >> d.f >> d.d >> d.c >> b; assert(s == "a string"); assert(d.valid()); assert(((const PacketData *)b.data)->valid()); } } handler; int numTrials = 40; osc::Send s(port, addr); osc::Recv r(port); // Assign a handler to the receiver r.handler(handler); // Here we launch a background thread that automatically checks the // socket for incoming OSC packets. r.timeout(0.1); // set receiver to block with timeout r.start(); for(int i=0; i<numTrials; ++i){ s.clear(); s.beginBundle(i); s.beginMessage("/test"); s << "a string" << data.i << data.f << data.d << data.c; s << osc::Blob(&data, sizeof(data)); s.endMessage(); s.endBundle(); s.send(); al_sleep(0.02); } r.stop(); // If we want more control over when to check for packets, we can poll // the receiver manually. // r.timeout(0); // do not block // // for(int i=0; i<numTrials; ++i){ // s.clear(); // s.beginBundle(i); // s.beginMessage("/test"); // s << "a string" << data.i << data.f << data.d << data.c; // s << osc::Blob(&data, sizeof(data)); // s.endMessage(); // s.endBundle(); // s.send(); // // while(r.recv()){} // } }
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); }