void Gate::OnRecvDeleteRoleReq(IKernel * kernel, const s64 id, const OBuffer& buf) { s64 actorId = 0; if (!buf.Read(actorId)) return; OASSERT(_players.find(id) != _players.end(), "where is agent???"); Player& player = _players[id]; if (player.state == ST_ROLELOADED) { auto itr = std::find_if(player.roles.begin(), player.roles.end(), [actorId](const Role& role) { return role.actorId == actorId; }); if (itr != player.roles.end()) { if (_roleMgr->DeleteRole(itr->actorId, itr->role)) { player.roles.erase(itr); olib::Buffer<128> buf; buf << _noError << actorId; SendToClient(kernel, id, _deleteRoleAckId, buf.Out()); } else { olib::Buffer<128> buf; buf << _errorDeleteRoleFailed; SendToClient(kernel, id, _deleteRoleAckId, buf.Out()); } } } }
/** * Timer to periodically check for join/quit signals from client, and call * appropriate input handler. * * @param DeltaTime Time taken by method */ bool CloudyWebAPIImpl::CheckConnection(float DeltaTime) { bool Success = false; if (HasInputStrChanged) { if (GEngine->GameViewport != nullptr && GIsRunning && IsInGameThread()) { UE_LOG(CloudyWebAPILog, Warning, TEXT("Success! input str: %s"), *InputStr); GetCloudyWebData(InputStr); UE_LOG(CloudyWebAPILog, Warning, TEXT("Success! Controllerid: %d command: %s"), ControllerId, *Command); Success = CCloudyPanelPluginModule::Get().ExecuteCommand(Command, ControllerId, StreamingPort, StreamingIP, GameSessionId); InputStr = ""; HasInputStrChanged = false; } // Send response to client if (Success) { SendToClient(TCPConnection, SUCCESS_MSG); } else { SendToClient(TCPConnection, FAILURE_MSG); } } return true; // continue timer to check for requests }
void Gate::OnRecvCreateRoleReq(IKernel * kernel, const s64 id, const OBuffer& buf) { OASSERT(_players.find(id) != _players.end(), "where is agent???"); Player& player = _players[id]; if (player.state == ST_ROLELOADED) { if (player.roles.size() >= _maxRole) { olib::Buffer<128> buf; buf << _errorTooMuchRole; SendToClient(kernel, id, _createRoleAckId, buf.Out()); return; } s64 actorId = _idMgr->AllocId(); IRole * role = _roleMgr->CreateRole(actorId, buf); if (role) { player.roles.push_back({ actorId, role }); olib::Buffer<128> buf; buf << _noError; role->Pack(buf); SendToClient(kernel, id, _createRoleAckId, buf.Out()); } else { olib::Buffer<128> buf; buf << _errorCreateRoleFailed; SendToClient(kernel, id, _createRoleAckId, buf.Out()); } } }
void Gate::OnRecvLoginReq(IKernel * kernel, const s64 id, const OBuffer& buf) { const char * token = nullptr; if (!buf.Read(token)) return; OASSERT(_players.find(id) != _players.end(), "where is agent???"); Player& player = _players[id]; if (player.state == ST_NONE) { TokenData data; if (strlen(token) > MAX_TOKEN_SIZE || !CheckToken(token, data, true)) { olib::Buffer<128> buf; buf << _errorInvalidToken; SendToClient(kernel, player.agentId, _loginAckId, buf.Out()); return; } s64 lastActorId = 0; s64 bantime = 0; bool writeOk = true; bool readOk = _cacheDB->Read("account", data.accountID, [&data, &lastActorId, &bantime, &writeOk, this](IKernel * kernel, ICacheDBReadResult * result) { if (result->Count() > 0) { lastActorId = result->GetDataInt64(0, 1); bantime = result->GetDataInt64(0, 2); } else { ICacheDBContext * writer = _cacheDB->PrepareWrite("account", data.accountID); writer->WriteInt64("id", data.accountID); writer->WriteInt64("platform", data.platform); writer->WriteInt64("lastActor", 0); writer->WriteInt64("bantime", 0); writeOk = writer->Update(); } }, "lastActor", "bantime"); if (readOk && writeOk) { player.accountId = data.accountID; player.lastActorId = lastActorId; player.state = ST_AUTHENING; IArgs<3, 128> args; args << player.agentId << player.accountId << 0; args.Fix(); _harbor->Send(user_node_type::ACCOUNT, 1, framework_proto::BIND_ACCOUNT_REQ, args.Out()); } else { olib::Buffer<128> buf; buf << _errorReadAccountFailed; SendToClient(kernel, player.agentId, _loginAckId, buf.Out()); } } }
void CCmdProcess::OnGetAllClient(unsigned int flow, Commpack *pPack) { unsigned int nCmd = pPack->GetCmd(); unsigned short nSeq = pPack->GetSeq(); Commpack pack; pack.SetCmd(nCmd); pack.SetSeq(nSeq); pack.AddUInt(0); unsigned int ulLen = 0; vector<string> vecSession; GetAllSession(vecSession); pack.AddUInt(vecSession.size()); for (unsigned int i = 0; i < vecSession.size(); i++) { string strIP = vecSession[i]; ulLen = strIP.length() + 1; pack.AddUInt(ulLen); pack.AddData((const void*) strIP.c_str(), ulLen); } SendToClient(flow, &pack); }
void Gate::OnBindLogicAck(IKernel * kernel, s32 nodeType, s32 nodeId, const OArgs & args) { s64 actorId = args.GetDataInt64(0); s64 accountId = args.GetDataInt64(1); s32 errorCode = args.GetDataInt32(2); if (_actors.find(actorId) != _actors.end()) { OASSERT(_players.find(_actors[actorId]) != _players.end(), "wtf"); Player& player = _players[_actors[actorId]]; OASSERT(player.state == ST_BINDING && actorId == player.selectActorId, "wtf"); if (errorCode) { player.state = ST_ONLINE; player.lastActorId = actorId; ICacheDBContext * writer = _cacheDB->PrepareWrite("account", player.accountId); writer->WriteInt64("id", player.accountId); writer->WriteInt64("lastActor", actorId); writer->Update(); const s32 tokenCount = args.GetDataInt32(3); } else { Reset(kernel, _actors[actorId], ST_ROLELOADED, node_type::USER); olib::Buffer<128> buf; buf << _errorBindLogicFailed; SendToClient(kernel, _actors[actorId], _selectRoleAckId, buf.Out()); } } }
void Gate::OnRecvDistributeAck(IKernel * kernel, s32 nodeType, s32 nodeId, const OArgs & args) { s64 agentId = args.GetDataInt64(0); s64 actorId = args.GetDataInt64(1); s32 logic = args.GetDataInt32(2); if (_players.find(agentId) != _players.end()) { if (logic > 0) { Player& player = _players[agentId]; OASSERT(player.state == ST_DISTRIBUTE, "wtf"); player.selectActorId = actorId; player.logic = logic; player.state = ST_BINDING; _actors[actorId] = agentId; _logicPlayers[logic].insert(agentId); IArgs<2, 32> args; args << actorId << player.accountId; args.Fix(); _harbor->Send(user_node_type::LOGIC, logic, framework_proto::BIND_PLAYER, args.Out()); } else { Reset(kernel, agentId, ST_ROLELOADED, node_type::USER); olib::Buffer<128> buf; buf << _errorDistributeLogicFailed; SendToClient(kernel, agentId, _selectRoleAckId, buf.Out()); } } }
void NetworkManager::SendToAllExcept(const std::string& message, long long clientID) { typedef ClientList::const_iterator it; for (it iter = clients.begin(), iend = clients.end(); iter != iend; iter++){ if (iter->left != clientID) SendToClient(message, iter->left); } }
void CCmdProcess::OnTask1(unsigned int flow, Commpack *pPack) { unsigned int nCmd = pPack->GetCmd(); unsigned short nSeq = pPack->GetSeq(); Commpack pack; pack.SetCmd(nCmd); pack.SetSeq(nSeq); Commpack packForward; packForward.SetCmd(CMD_TASK1); packForward.SetSeq(nSeq); string strClientIP; unsigned int ulLen; void * pData; if (!pPack->GetUInt(ulLen) || !pPack->GetData(pData, ulLen)) { pack.AddUInt(1000); SendToClient(flow, &pack); return; } strClientIP = (char *) pData; unsigned int ulTestData; if (!pPack->GetUInt(ulTestData)) { pack.AddUInt(1000); SendToClient(flow, &pack); return; } packForward.AddUInt(ulTestData); unsigned int ulForwardFlow; if (!GetFlowByIP(strClientIP, ulForwardFlow)) { pack.AddUInt(1000); SendToClient(flow, &pack); return; } SendToClient(ulForwardFlow, &packForward); pack.AddUInt(0); SendToClient(flow, &pack); }
void Gate::OnRecvBindAccountAck(IKernel * kernel, s32 nodeType, s32 nodeId, const OArgs & args) { s64 agentId = args.GetDataInt64(0); s64 accountId = args.GetDataInt64(1); s32 errorCode = args.GetDataInt32(2); s32 tokenCount = args.GetDataInt32(3); if (_players.find(agentId) != _players.end()) { Player& player = _players[agentId]; OASSERT(player.state == ST_AUTHENING && player.accountId == accountId, "wtf"); if (player.accountId != accountId) return; if (errorCode == 0) { bool ret = _roleMgr->GetRoleList(accountId, [&player](IKernel * kernel, s64 actorId, IRole * role) { player.roles.push_back({ actorId, role }); }); if (ret) { TokenData data = { player.accountId, 0, (s32)(tools::GetTimeMillisecond() / 1000), tokenCount }; char token[MAX_TOKEN_SIZE + 1]; BuildToken(token, sizeof(token) - 1, data); olib::Buffer<4096> buf; buf << _noError << token << (s32)player.roles.size(); for (const auto& role : player.roles) { buf << role.actorId; role.role->Pack(buf); } SendToClient(kernel, player.agentId, _loginAckId, buf.Out()); } else { Reset(kernel, agentId, ST_NONE, node_type::USER); olib::Buffer<128> buf; buf << _errorLoadRoleListFailed; SendToClient(kernel, player.agentId, _loginAckId, buf.Out()); } } else { olib::Buffer<128> buf; buf << errorCode; SendToClient(kernel, player.agentId, _loginAckId, buf.Out()); } } }
int HookClient_WalkRequest(unsigned char *Packet, int Len) { if(SmoothWalk) { unsigned char MoveAck[3]= { 0x22, 0x00, 0x00 }; MoveAck[1] = Packet[2]; SendToClient(MoveAck, 3); } return SEND_PACKET; }
void CCmdProcess::OnTest(unsigned int flow, Commpack *pPack) { unsigned int nCmd = pPack->GetCmd(); unsigned short nSeq = pPack->GetSeq(); Commpack pack; pack.SetCmd(nCmd); pack.SetSeq(nSeq); unsigned int ulTestData; if (pPack->GetUInt(ulTestData)) { pack.AddUInt(0); pack.AddUInt(ulTestData * 2); SendToClient(flow, &pack); } else { pack.AddUInt(1000); SendToClient(flow, &pack); } }
void CCmdProcess::OnLogin(unsigned int flow, Commpack *pPack) { unsigned int nCmd = pPack->GetCmd(); unsigned short nSeq = pPack->GetSeq(); Commpack pack; pack.SetCmd(nCmd); pack.SetSeq(nSeq); unsigned int ulLen; void * pData; if (!pPack->GetUInt(ulLen) || !pPack->GetData(pData, ulLen)) { pack.AddUInt(1000); SendToClient(flow, &pack); } else { pack.AddUInt(0); SendToClient(flow, &pack); } //Associate IP of user to flow once user logon MapIP2Flow(flow); }
void CCmdProcess::OnLogin(unsigned int flow, Commpack *pPack) { unsigned int nCmd = pPack->GetCmd(); unsigned short nSeq = pPack->GetSeq(); Commpack pack; pack.SetCmd(nCmd); pack.SetSeq(nSeq); unsigned int ulLen; void * pData; if (!pPack->GetUInt(ulLen) || !pPack->GetData(pData, ulLen)) { pack.AddUInt(1000); SendToClient(flow, &pack); } else { pack.AddUInt(0); SendToClient(flow, &pack); } //一旦用户登陆后,将用户登录IP关联到flow上 MapIP2Flow(flow); }
void Gate::OnRecvReselectRole(IKernel * kernel, const s64 id, const OBuffer& buf) { OASSERT(_players.find(id) != _players.end(), "where is agent???"); Player& player = _players[id]; if (player.state == ST_ONLINE) { Reset(kernel, id, ST_ROLELOADED, node_type::USER); olib::Buffer<4096> buf; buf << _noError << (s32)player.roles.size(); for (const auto& role : player.roles) { buf << role.actorId; role.role->Pack(buf); } SendToClient(kernel, player.agentId, _reselectRoleAckId, buf.Out()); } }
void *ForwardUDP(void *v) { fd_set inputs; char buff[BUFFLENGTH]; while (1) { FD_ZERO(&inputs); FD_SET(Socket[1], &inputs); int result = select(FD_SETSIZE, &inputs, NULL, NULL, NULL); //wait until some messages arrive if (result <= 0)continue; if (FD_ISSET(Socket[1], &inputs)) { int msglen = Recvfrom(1, &buff[1]); printf("!>>Get UDP from local port<<!\n"); buff[0] = '0' + totalLinkNum; //printf("%s\n", buff); int LinkNow_t = currLinkNow; SendToClient(LinkNow_t, buff, msglen + 1); } } }
int main(int argc, char **argv) { ServerConfig config; if (argc != 2) { //printf("Usage: %s {ConfigFileName}", argv[0]); //exit(1); printf("Read config file from default path...\n"); config = loadServer("/etc/multiswitch/server.ini"); } else config = loadServer(argv[1]); printf("This is a UDP server, I will received message from client and reply with same message\n"); totalLinkNum = config.linkCount; initMemory(); init_sock_s(0, config.receivePort);//init the Socket and addr init_sock_local("127.0.0.1", config.localForwardPort); //printf("Socket init....finish\n"); //srand(time(NULL)); currLinkNow = 0; Maxtot = 0; pthread_t pt_f; pthread_create(&pt_f, NULL, ForwardUDP, NULL); fd_set inputs; char buff[BUFFLENGTH]; while (true) { FD_ZERO(&inputs); FD_SET(Socket[0], &inputs); int result = select(FD_SETSIZE, &inputs, NULL, NULL, NULL); //wait until some messages arrive if (result <= 0)continue; if (FD_ISSET(Socket[0], &inputs)) { int msglen = Recvfrom(0, buff); printf("%s %u says: %s\n", inet_ntoa(RecvAddr[0].sin_addr), ntohs(RecvAddr[0].sin_port), buff); int pi, LinkNow_c; pi = buff[0] - '0'; LinkNow_c = buff[1] - '0'; if (pi < 0 || pi > totalLinkNum - 1 || LinkNow_c < 0 || LinkNow_c > totalLinkNum) { printf("Invalid package.\n"); continue; } UpdateAddr(&SendAddr[pi], &RecvAddr[0]);//update destination address of this link if (buff[1] == '0' + totalLinkNum)// if the packet is a data packet, not a test packet. { printf("!!receive UDP data packet from client!: \n"); SendToLocal(&buff[2], msglen - 2); continue; } //for debug, sleep to simulate net delay //int WaitTime = rand()%400; //usleep(WaitTime * 1000); SendToClient(pi, buff, msglen);//send msg printf("sent: %s\n", buff); long long tot; sscanf(&buff[2], "%lld", &tot); if (tot > Maxtot || (Maxtot - tot) > MAXMINUS) { Maxtot = tot; if (LinkNow_c != currLinkNow) { ChangeNet(LinkNow_c); } } } } }
void CCmdProcess::OnReptTask(unsigned int flow, Commpack *pPack) { unsigned int nCmd = pPack->GetCmd(); unsigned short nSeq = pPack->GetSeq(); Commpack pack; pack.SetCmd(nCmd); pack.SetSeq(nSeq); //1. get data from client unsigned uClientTS = 0; unsigned uSize = 0; if (!pPack->GetUInt(uClientTS) || !pPack->GetUInt(uSize)) { pack.AddUInt(1000); SendToClient(flow, &pack); return; } string sIP; if (!GetIPByFlow(sIP, flow)) { pack.AddUInt(1000); SendToClient(flow, &pack); Warn("[CCmdProcess::OnReptTask] GetIPByFlow error, return 1000."); return; } string sDay(""); unsigned uDayPoint = 0; GetDayMin(sDay, uDayPoint, uClientTS); vector<SReptTask> vecRT; for(size_t i = 0; i < uSize; i++) { SReptTask rt; if (!pPack->GetUInt(rt.uCountry) || !pPack->GetUInt(rt.uISP) || !pPack->GetUInt(rt.uProv) || !pPack->GetUInt(rt.uIPNum) || !pPack->GetUInt(rt.uDelay)) { pack.AddUInt(1000); SendToClient(flow, &pack); return; } rt.sDay = sDay; rt.uDayPoint = uDayPoint; rt.sIP = sIP; vecRT.push_back(rt); } //2. set data to db for(size_t j = 0; j < vecRT.size(); j++) { if (!m_pDBProcessor->InsUpdReptTask(vecRT[j])) { Err("[CCmdProcess::OnReptTask] InsUpdReptTask error!" " Err[%s]", m_pDBProcessor->GetErrMsg().c_str()); } } pack.AddUInt(0); SendToClient(flow, &pack); Info("[CCmdProcess::OnReptTask] ip:[%s], day[%s], point[%u], size[%u]", sIP.c_str(), sDay.c_str(), uDayPoint, vecRT.size()); }
void CCmdProcess::GetIPByTS(unsigned int flow, Commpack *pPack) { unsigned int nCmd = pPack->GetCmd(); unsigned short nSeq = pPack->GetSeq(); Commpack pack; pack.SetCmd(nCmd); pack.SetSeq(nSeq); unsigned uTSOld; if (!pPack->GetUInt(uTSOld)) { pack.AddUInt(1000); SendToClient(flow, &pack); Warn("[GetIPByTS] error protocal, return 1000."); return; } time_t t1 = time(0); //1. get incremental change from memory by timestamp vector<SIPAttr> vecMod; vector < string > vecDel; unsigned uTSNew = uTSOld; pthread_rwlock_rdlock(&this->m_lock); map<string, SIPAttr>::iterator it; for(it = this->m_mapIPAttr.begin(); it != this->m_mapIPAttr.end(); it++) { SIPAttr &ia = it->second; if (ia.uModTS >= uTSOld) { if (0 == ia.uOptFlag) { vecMod.push_back(ia); } else { vecDel.push_back(ia.szIP); } } uTSNew = max(uTSNew, ia.uModTS); } pthread_rwlock_unlock(&this->m_lock); time_t t2 = time(0); Debug("select:%lus", t2-t1); //2. new a package, for enought size. compress data. Commpack pack_new(vecMod.size() * 8 + vecDel.size() * 4 + 512); pack_new.SetCmd(nCmd); pack_new.SetSeq(nSeq); pack_new.AddUInt(0); pack_new.AddUInt(uTSNew); pack_new.AddUInt(vecMod.size()); for(size_t i = 0; i < vecMod.size(); i++) { SIPAttr &ia = vecMod[i]; pack_new.AddUInt(inet_addr(ia.szIP)); pack_new.AddUShort(ia.uCountry); pack_new.AddByte(ia.uIsp); pack_new.AddByte(ia.uProvince); } pack_new.AddUInt(vecDel.size()); for(size_t j = 0; j < vecDel.size(); j++) { pack_new.AddUInt(inet_addr(vecDel[j].c_str())); } time_t t3 = time(0); Debug("add :%lus", t3-t2); SendToClient(flow, &pack_new); time_t t4 = time(0); Debug("send:%lus", t4-t3); }
void NetworkManager::SendToAll(const std::string& message){ typedef ClientList::const_iterator it; for(it iter = clients.begin(), iend = clients.end(); iter != iend; ++iter ) { SendToClient(message,iter->left); } }
bool PlayerManager::Entry( DNID dnidClient, LINKSTATUS enumStatus, void *data, size_t size ) { //这里收到玩家启动客户端的消息,发送服务器状态 SMessage *pMsg = (SMessage *)data; if ( pMsg == NULL ) { return true; } //给客户端发送服务器状态数据 if ( pMsg->_protocol == pMsg->EPRO_Center_MESSAGE ) { SCenterBaseMsg* _pMsg = static_cast< SCenterBaseMsg* >( pMsg ); switch (_pMsg->_protocol) { case SCenterBaseMsg::EPRO_RequestClientVersionInfo: //返回当前游戏资源更新信息 { SARequestAssetUpdateInfo _msg; CDAppMain& appMain = GetApp(); _msg.streamLength = appMain.m_iAssetBundleInfoLength; memcpy(_msg.streamData, appMain.m_AssetbundleVersionInfo, appMain.m_iAssetBundleInfoLength); SendToClient(dnidClient, &_msg, sizeof(SARequestAssetUpdateInfo) - (MAX_ASSET_SIZE - appMain.m_iAssetBundleInfoLength)); //rfalse(2, 1, ""); } break; case SCenterBaseMsg::EPRO_RequestServerState: { //接受请求数据 SARequestServerState _msg; bool b = GetApp().m_ServerManager[GAMESERVER_FLAG].GetGameServerList(&_msg); if (b) { SendToClient(dnidClient, &_msg, _msg.MySize()); m_dPlayerConnectNum++; char string[100] = {}; sprintf_s(string, "\nPlayeConnectCenterServer: %d ", m_dPlayerConnectNum); GetApp().SaveConnectNumString(string); } } break; case SCenterBaseMsg::EPRO_RequestServerDetailInfo: { SQRequestServeDetailInfoMsg *psrcMsg = static_cast<SQRequestServeDetailInfoMsg*>(pMsg); if (NULL == psrcMsg) break; ServerData *pServerData = NULL; GameServer *pGameServer = NULL; if (GetApp().m_ServerManager[GAMESERVER_FLAG].FindGameServerByIndex(psrcMsg->dwIndex, &pGameServer)) { if (NULL != pGameServer) { pServerData = pGameServer->GetServerData(); } } if (NULL != pServerData) { SARequestServeDetailInfoMsg msg; msg.dwIndex = pServerData->m_dwIndex; lite::Serializer sl(msg.streamData, sizeof(msg.streamData)); sl(pServerData->m_dwIP)(pServerData->m_dwPort); SendToClient(dnidClient, &msg, sizeof(msg) - sl.EndEdition()); } } break; default: break; } } else if (pMsg->_protocol == SMessage::EPRO_SYSTEM_MESSAGE) { SQLoginMsg* _pMsg = static_cast<SQLoginMsg*>(pMsg); } return true; }
HRESULT MkvMediaClient::SetPlayableRangeAfterSended(UINT HeaderIndex, DWORD MinIndex, DWORD MaxIndex) { LIVE_ASSERT( true == m_IsSending ); for ( MediaDataPiecePtr dataPiece = m_NetWriter->GetFirst(m_WillPlayIndex); dataPiece && dataPiece->GetPieceIndex() <= MaxIndex; dataPiece = m_NetWriter->GetNext(dataPiece->GetPieceIndex())) { MonoMediaDataPiecePtr lpDataPacket = dataPiece->ToMonoPiece(); if ( ! lpDataPacket ) continue; NETWRITER_DEBUG( "CMkvNetWriter::MkvMediaClient SetPlayableRangeAfterSended Piece index:" << lpDataPacket->GetPieceIndex() <<" Piece length:"<<lpDataPacket->GetMediaDataLength()); if( lpDataPacket->GetHeaderPiece() > HeaderIndex ) { // 说明这个文件已经非常平滑的就播放完毕了啊,于是自然就要断开连接了 NETWRITER_DEBUG( "MkvMediaClient::SetPlayableRangeAfterSended Send Media Data Gracefully End "<<*m_Socket ); m_NetWriter->SavePlaytoIndex(lpDataPacket->GetPieceIndex() - 1); return E_SEND_ERROR; } if( lpDataPacket->GetHeaderPiece() != HeaderIndex ) continue; if(lpDataPacket->GetPieceIndex()!= m_WillPlayIndex) { if(IsInDataUnit()) { NETWRITER_ERROR("MkvMediaClient::SetPlayableRangeAfterSended - InDataUnit Missed: "<< m_WillPlayIndex <<"Actual:"<<lpDataPacket->GetPieceIndex()<<"SubDataIndex:"<< m_PiecesIndexWanted); PrepareForNextDataUnit(); } else { NETWRITER_ERROR("MkvMediaClient::SetPlayableRangeAfterSended - NotInDataUnit Missed: "<< m_WillPlayIndex <<"Actual:"<<lpDataPacket->GetPieceIndex()); } } //piece is OK, let's check data units const BYTE* data = lpDataPacket->GetMediaData(); const UINT32 length = (UINT32)lpDataPacket->GetMediaDataLength(); UINT32 off = 0; while(off < length) { UINT8 piecesIndex = *((UINT8 *)(data + off)); UINT8 piecesNumber = *((UINT8 *)(data + off + 1)); UINT16 pieceSize = *((UINT16 *)(data + off + 2)); UINT32 packetSize = 0; if( piecesNumber == 1 && piecesIndex == 0) // a single data unit { packetSize = pieceSize; m_PacketSize = packetSize; m_PiecesIndexWanted = 0; m_piecesNumber = piecesNumber; off += 4; m_DataUnitBuffer.append(data+off, packetSize); off += packetSize; } else if( piecesNumber > 1 ) //sliced data unit { packetSize = *((UINT32 *)(data + off + 4)); off += 8; if(IsInDataUnit()) { if( m_PacketSize == packetSize && m_PiecesIndexWanted == piecesIndex && m_piecesNumber == piecesNumber) { m_DataUnitBuffer.append(data + off, pieceSize); m_PiecesIndexWanted++; off += pieceSize; if(m_PiecesIndexWanted == m_piecesNumber) { if(!SendToClient(lpDataPacket->GetPieceIndex())) { return E_SEND_ERROR; } } } else // Data pieces is error, skip this data unit { off += pieceSize; PrepareForNextDataUnit(); continue; } } else // Not in a data unit { if(piecesIndex != 0) { //corrupted data unit, skip this piece NETWRITER_ERROR("MkvMediaClient::SetPlayableRangeAfterSended - Corrupted data unit : PieceIndex:"<<lpDataPacket->GetPieceIndex()<< "Off:"<<off << "SubDataUnitIndex: "<< piecesIndex); off += pieceSize; continue; } else // go into a data unit { //send complete data to client first if(!SendToClient(lpDataPacket->GetPieceIndex())) { return E_SEND_ERROR; } m_PacketSize = packetSize; m_piecesNumber = piecesNumber; m_DataUnitBuffer.append(data + off, pieceSize); m_PiecesIndexWanted++; off += pieceSize; continue; } } } else if( piecesNumber == 0) // This is a format error! { NETWRITER_ERROR("MkvMediaClient::SetPlayableRangeAfterSended - Error: PieceNumber is 0 : PieceIndex:"<<lpDataPacket->GetPieceIndex()<< "Off:"<<off); m_NetWriter->SavePlaytoIndex(lpDataPacket->GetPieceIndex() - 1); return E_SEND_ERROR; } } LIVE_ASSERT(off == length); //send complete data units to client if(!IsInDataUnit()) { if(!SendToClient(lpDataPacket->GetPieceIndex())) { return E_SEND_ERROR; } } m_LastPlayIndex = lpDataPacket->GetPieceIndex(); m_NetWriter->m_dwLastIndex = m_LastPlayIndex + 1; m_WillPlayIndex = m_LastPlayIndex + 1; } m_WillPlayIndex = m_LastPlayIndex + 1; m_NetWriter->SavePlaytoIndex(m_LastPlayIndex); LIVE_ASSERT( m_WillPlayIndex > m_LastPlayIndex ); return S_OK; }