void Room::RoomImpl::HandleJoinRequest(const ENetEvent* event) { Packet packet; packet.Append(event->packet->data, event->packet->dataLength); packet.IgnoreBytes(sizeof(u8)); // Ignore the message type std::string nickname; packet >> nickname; MacAddress preferred_mac; packet >> preferred_mac; u32 client_version; packet >> client_version; std::string pass; packet >> pass; if (pass != password) { SendWrongPassword(event->peer); return; } if (!IsValidNickname(nickname)) { SendNameCollision(event->peer); return; } if (preferred_mac != NoPreferredMac) { // Verify if the preferred mac is available if (!IsValidMacAddress(preferred_mac)) { SendMacCollision(event->peer); return; } } else { // Assign a MAC address of this client automatically preferred_mac = GenerateMacAddress(); } if (client_version != network_version) { SendVersionMismatch(event->peer); return; } // At this point the client is ready to be added to the room. Member member{}; member.mac_address = preferred_mac; member.nickname = nickname; member.peer = event->peer; { std::lock_guard<std::mutex> lock(member_mutex); members.push_back(std::move(member)); } // Notify everyone that the room information has changed. BroadcastRoomInformation(); SendJoinSuccess(event->peer, preferred_mac); }
void Room::RoomImpl::HandleModKickPacket(const ENetEvent* event) { if (!HasModPermission(event->peer)) { SendModPermissionDenied(event->peer); return; } Packet packet; packet.Append(event->packet->data, event->packet->dataLength); packet.IgnoreBytes(sizeof(u8)); // Ignore the message type std::string nickname; packet >> nickname; std::string username; { std::lock_guard lock(member_mutex); const auto target_member = std::find_if(members.begin(), members.end(), [&nickname](const auto& member) { return member.nickname == nickname; }); if (target_member == members.end()) { SendModNoSuchUser(event->peer); return; } // Notify the kicked member SendUserKicked(target_member->peer); username = target_member->user_data.username; enet_peer_disconnect(target_member->peer, 0); members.erase(target_member); } // Announce the change to all clients. SendStatusMessage(IdMemberKicked, nickname, username); BroadcastRoomInformation(); }
void Room::RoomImpl::HandleModUnbanPacket(const ENetEvent* event) { if (!HasModPermission(event->peer)) { SendModPermissionDenied(event->peer); return; } Packet packet; packet.Append(event->packet->data, event->packet->dataLength); packet.IgnoreBytes(sizeof(u8)); // Ignore the message type std::string address; packet >> address; bool unbanned = false; { std::lock_guard lock(ban_list_mutex); auto it = std::find(username_ban_list.begin(), username_ban_list.end(), address); if (it != username_ban_list.end()) { unbanned = true; username_ban_list.erase(it); } it = std::find(ip_ban_list.begin(), ip_ban_list.end(), address); if (it != ip_ban_list.end()) { unbanned = true; ip_ban_list.erase(it); } } if (unbanned) { SendStatusMessage(IdAddressUnbanned, address, ""); } else { SendModNoSuchUser(event->peer); } }
HRESULT CStreamParser::ParseH264AnnexB(Packet *pPacket) { if (!m_pPacketBuffer) { m_pPacketBuffer = InitPacket(pPacket); } m_pPacketBuffer->Append(pPacket); BYTE *start = m_pPacketBuffer->GetData(); BYTE *end = start + m_pPacketBuffer->GetDataSize(); MOVE_TO_H264_START_CODE(start, end); while(start <= end-4) { BYTE *next = start + 1; MOVE_TO_H264_START_CODE(next, end); // End of buffer reached if(next >= end-4) { break; } size_t size = next - start; CH264Nalu Nalu; Nalu.SetBuffer(start, (int)size, 0); Packet *p2 = NULL; while (Nalu.ReadNext()) { Packet *p3 = new Packet(); p3->SetDataSize(Nalu.GetDataLength() + 4); // Write size of the NALU (Big Endian) AV_WB32(p3->GetData(), (uint32_t)Nalu.GetDataLength()); memcpy(p3->GetData() + 4, Nalu.GetDataBuffer(), Nalu.GetDataLength()); if (!p2) { p2 = p3; } else { p2->Append(p3); SAFE_DELETE(p3); } } if (!p2) break; p2->StreamId = m_pPacketBuffer->StreamId; p2->bDiscontinuity = m_pPacketBuffer->bDiscontinuity; m_pPacketBuffer->bDiscontinuity = FALSE; p2->bSyncPoint = m_pPacketBuffer->bSyncPoint; m_pPacketBuffer->bSyncPoint = FALSE; p2->rtStart = m_pPacketBuffer->rtStart; m_pPacketBuffer->rtStart = Packet::INVALID_TIME; p2->rtStop = m_pPacketBuffer->rtStop; m_pPacketBuffer->rtStop = Packet::INVALID_TIME; p2->pmt = m_pPacketBuffer->pmt; m_pPacketBuffer->pmt = NULL; m_queue.Queue(p2); if(pPacket->rtStart != Packet::INVALID_TIME) { m_pPacketBuffer->rtStart = pPacket->rtStart; m_pPacketBuffer->rtStop = pPacket->rtStop; pPacket->rtStart = Packet::INVALID_TIME; } if(pPacket->bDiscontinuity) { m_pPacketBuffer->bDiscontinuity = pPacket->bDiscontinuity; pPacket->bDiscontinuity = FALSE; } if(pPacket->bSyncPoint) { m_pPacketBuffer->bSyncPoint = pPacket->bSyncPoint; pPacket->bSyncPoint = FALSE; } if(m_pPacketBuffer->pmt) { DeleteMediaType(m_pPacketBuffer->pmt); } m_pPacketBuffer->pmt = pPacket->pmt; pPacket->pmt = NULL; start = next; } if(start > m_pPacketBuffer->GetData()) { m_pPacketBuffer->RemoveHead(start - m_pPacketBuffer->GetData()); } SAFE_DELETE(pPacket); do { pPacket = NULL; REFERENCE_TIME rtStart = Packet::INVALID_TIME, rtStop = rtStart = Packet::INVALID_TIME; std::deque<Packet *>::iterator it; for (it = m_queue.GetQueue()->begin(); it != m_queue.GetQueue()->end(); ++it) { // Skip the first if (it == m_queue.GetQueue()->begin()) { continue; } Packet *p = *it; BYTE* pData = p->GetData(); if((pData[4]&0x1f) == 0x09) { m_bHasAccessUnitDelimiters = true; } if ((pData[4]&0x1f) == 0x09 || (!m_bHasAccessUnitDelimiters && p->rtStart != Packet::INVALID_TIME)) { pPacket = p; if (p->rtStart == Packet::INVALID_TIME && rtStart != Packet::INVALID_TIME) { p->rtStart = rtStart; p->rtStop = rtStop; } break; } if (rtStart == Packet::INVALID_TIME) { rtStart = p->rtStart; rtStop = p->rtStop; } } if (pPacket) { Packet *p = m_queue.Get(); Packet *p2 = NULL; while ((p2 = m_queue.Get()) != pPacket) { p->Append(p2); SAFE_DELETE(p2); } // Return m_queue.GetQueue()->push_front(pPacket); Queue(p); } } while (pPacket != NULL); return S_OK; }
void SceneryManager::SendPageRequest(const SceneryPageRequest& request, std::list<PacketManager::PACKET_PAIR>& outgoingPackets) { TimeObject to("SceneryManager::SendPageRequest"); STRINGLIST queryRows; Packet data; int wpos = 0; char idBuf[32]; GetThread("SceneryManager::HandlePageRequests[page]"); SceneryPage *page = GetOrCreatePage(request.zone, request.x, request.y); if(page == NULL) { g_Log.AddMessageFormat("[ERROR] SendPageRequest retrieved NULL page"); wpos = PrepExt_QueryResponseNull(prepBuf, request.queryID); data.Assign(prepBuf, wpos); outgoingPackets.push_back(PacketManager::PACKET_PAIR(request.socket, data)); ReleaseThread(); return; } SceneryPage::SCENERY_IT it; for(it = page->mSceneryList.begin(); it != page->mSceneryList.end(); ++it) { //Build the list of scenery ID strings to form the response to the scenery.list query. //No need to save row data unless the query is required. if(request.skipQuery == false) { sprintf(idBuf, "%d", it->second.ID); queryRows.push_back(idBuf); } wpos += PrepExt_UpdateScenery(&prepBuf[wpos], &it->second); if(wpos > Global::MAX_SEND_CHUNK_SIZE) { data.Assign(prepBuf, wpos); outgoingPackets.push_back(PacketManager::PACKET_PAIR(request.socket, data)); wpos = 0; } } if(wpos > 0) { data.Assign(prepBuf, wpos); outgoingPackets.push_back(PacketManager::PACKET_PAIR(request.socket, data)); } //Done accessing the scenery data itself, no need to hold the thread any longer. //All the remaining stuff is using a resident list of query IDs to form into a response //packet. ReleaseThread(); //Now build the query response if the client has requested it. if(request.skipQuery == true) return; //Reset the packet buffer and data. wpos = 0; data.Clear(); //Get the size of the response int sizeReq = 6; //Query ID (4 bytes) + row count (2 bytes) for(size_t s = 0; s < queryRows.size(); s++) { sizeReq++; //1 string per row sizeReq += PutStringReq(queryRows[s].c_str()); } wpos += PutByte(&prepBuf[wpos], 1); //_handleQueryResultMsg wpos += PutShort(&prepBuf[wpos], sizeReq); //Message size wpos += PutInteger(&prepBuf[wpos], request.queryID); wpos += PutShort(&prepBuf[wpos], queryRows.size()); for(size_t s = 0; s < queryRows.size(); s++) { wpos += PutByte(&prepBuf[wpos], 1); wpos += PutStringUTF(&prepBuf[wpos], queryRows[s].c_str()); if(wpos > Global::MAX_SEND_CHUNK_SIZE) { data.Append(prepBuf, wpos); wpos = 0; } } if(wpos > 0) data.Append(prepBuf, wpos); outgoingPackets.push_back(PacketManager::PACKET_PAIR(request.socket, data)); }
void Room::RoomImpl::HandleModBanPacket(const ENetEvent* event) { if (!HasModPermission(event->peer)) { SendModPermissionDenied(event->peer); return; } Packet packet; packet.Append(event->packet->data, event->packet->dataLength); packet.IgnoreBytes(sizeof(u8)); // Ignore the message type std::string nickname; packet >> nickname; std::string username; std::string ip; { std::lock_guard lock(member_mutex); const auto target_member = std::find_if(members.begin(), members.end(), [&nickname](const auto& member) { return member.nickname == nickname; }); if (target_member == members.end()) { SendModNoSuchUser(event->peer); return; } // Notify the banned member SendUserBanned(target_member->peer); nickname = target_member->nickname; username = target_member->user_data.username; char ip_raw[256]; enet_address_get_host_ip(&target_member->peer->address, ip_raw, sizeof(ip_raw) - 1); ip = ip_raw; enet_peer_disconnect(target_member->peer, 0); members.erase(target_member); } { std::lock_guard lock(ban_list_mutex); if (!username.empty()) { // Ban the forum username if (std::find(username_ban_list.begin(), username_ban_list.end(), username) == username_ban_list.end()) { username_ban_list.emplace_back(username); } } // Ban the member's IP as well if (std::find(ip_ban_list.begin(), ip_ban_list.end(), ip) == ip_ban_list.end()) { ip_ban_list.emplace_back(ip); } } // Announce the change to all clients. SendStatusMessage(IdMemberBanned, nickname, username); BroadcastRoomInformation(); }
void Room::RoomImpl::HandleJoinRequest(const ENetEvent* event) { { std::lock_guard lock(member_mutex); if (members.size() >= room_information.member_slots) { SendRoomIsFull(event->peer); return; } } Packet packet; packet.Append(event->packet->data, event->packet->dataLength); packet.IgnoreBytes(sizeof(u8)); // Ignore the message type std::string nickname; packet >> nickname; std::string console_id_hash; packet >> console_id_hash; MacAddress preferred_mac; packet >> preferred_mac; u32 client_version; packet >> client_version; std::string pass; packet >> pass; std::string token; packet >> token; if (pass != password) { SendWrongPassword(event->peer); return; } if (!IsValidNickname(nickname)) { SendNameCollision(event->peer); return; } if (preferred_mac != NoPreferredMac) { // Verify if the preferred mac is available if (!IsValidMacAddress(preferred_mac)) { SendMacCollision(event->peer); return; } } else { // Assign a MAC address of this client automatically preferred_mac = GenerateMacAddress(); } if (!IsValidConsoleId(console_id_hash)) { SendConsoleIdCollision(event->peer); return; } if (client_version != network_version) { SendVersionMismatch(event->peer); return; } // At this point the client is ready to be added to the room. Member member{}; member.mac_address = preferred_mac; member.console_id_hash = console_id_hash; member.nickname = nickname; member.peer = event->peer; std::string uid; { std::lock_guard lock(verify_UID_mutex); uid = verify_UID; } member.user_data = verify_backend->LoadUserData(uid, token); { std::lock_guard lock(ban_list_mutex); // Check username ban if (!member.user_data.username.empty() && std::find(username_ban_list.begin(), username_ban_list.end(), member.user_data.username) != username_ban_list.end()) { SendUserBanned(event->peer); return; } // Check IP ban char ip_raw[256]; enet_address_get_host_ip(&event->peer->address, ip_raw, sizeof(ip_raw) - 1); std::string ip = ip_raw; if (std::find(ip_ban_list.begin(), ip_ban_list.end(), ip) != ip_ban_list.end()) { SendUserBanned(event->peer); return; } } // Notify everyone that the user has joined. SendStatusMessage(IdMemberJoin, member.nickname, member.user_data.username); { std::lock_guard lock(member_mutex); members.push_back(std::move(member)); } // Notify everyone that the room information has changed. BroadcastRoomInformation(); if (HasModPermission(event->peer)) { SendJoinSuccessAsMod(event->peer, preferred_mac); } else { SendJoinSuccess(event->peer, preferred_mac); } }