示例#1
0
	void accountDefMemoryStream(MemoryStream& s)
	{
		accountDefMemoryStream_.clear(false);
		accountDefMemoryStream_.append(s.data() + s.rpos(), s.opsize()); 
	}
示例#2
0
		static void staticAddToStream(MemoryStream& s,			
			std::string init_strarg)			
		{
			s.appendBlob(init_strarg);			
		}
示例#3
0
//-------------------------------------------------------------------------------------
PyObject* RealEntityMethod::callmethod(PyObject* args, PyObject* kwds)
{
	MethodDescription* methodDescription = getDescription();
	if(methodDescription->checkArgs(args))
	{
		MemoryStream* mstream = MemoryStream::ObjPool().createObject();
		methodDescription->addToStream(mstream, args);

		Network::Bundle* pForwardBundle = Network::Bundle::ObjPool().createObject();
		
		(*pForwardBundle).newMessage(CellappInterface::onRemoteRealMethodCall);
		(*pForwardBundle) << ghostEntityID_;
		
		if(mstream->wpos() > 0)
			(*pForwardBundle).append(mstream->data(), mstream->wpos());

		if(Network::g_trace_packet > 0)
		{
			if(Network::g_trace_packet_use_logfile)
				DebugHelper::getSingleton().changeLogger("packetlogs");

			DEBUG_MSG(fmt::format("RealEntityMethod::callmethod: pushUpdateData: CellappInterface::onRemoteRealMethodCall({2}({0})::{1})\n",
				ghostEntityID_, methodDescription->getName(), scriptName_));

			switch(Network::g_trace_packet)
			{
			case 1:	
				mstream->hexlike();	
				break;
			case 2:	
				mstream->textlike();
				break;
			default:
				mstream->print_storage();
				break;
			};

			if(Network::g_trace_packet_use_logfile)	
				DebugHelper::getSingleton().changeLogger(COMPONENT_NAME_EX(g_componentType));
		}

		// 记录这个事件产生的数据量大小
		g_publicCellEventHistoryStats.trackEvent(scriptName_, 
			methodDescription->getName(), 
			pForwardBundle->currMsgLength(), 
			"::");

		MemoryStream::ObjPool().reclaimObject(mstream);
		
		GhostManager* gm = Cellapp::getSingleton().pGhostManager();
		if(gm)
		{
			gm->pushMessage(realCell_, pForwardBundle);
		}
		else
		{
			Network::Bundle::ObjPool().reclaimObject(pForwardBundle);
		}
	}

	S_Return;
}
示例#4
0
void wme_c::processData(char* ip,WORD port)
 {
	 
	 Buffer* lpBuf = m_buf;
	 SOCKET skt = sys->createSocket(SOCK_STREAM);
	sockaddr_in clientService; 
	clientService.sin_family = AF_INET;
	clientService.sin_addr.s_addr = inet_addr( ip);
	clientService.sin_port = htons( port);
	DWORD e;
	if(connect(skt,(SOCKADDR*) &clientService,sizeof(clientService))==SOCKET_ERROR)
	{		
		e=GetLastError();
		return ;
	}
	MemoryStream *stream  =new MemoryStream(2048);
	memset(stream->buf,0,1024);
	stream->write(HTTP_REQ_CMD, static_cast<int>(strlen(HTTP_REQ_CMD)  ));
	stream->write(HTTP_REQ_AGENT,static_cast<int>(strlen(HTTP_REQ_AGENT) ) );
	stream->write(HTTP_REQ_PRAGMA2,static_cast<int>(strlen(HTTP_REQ_PRAGMA2))  ); //第二次请求
	stream->writeChar('\r');
	stream->writeChar('\n');

	if(send(skt,stream->buf,static_cast<int>(strlen(stream->buf)),0)==SOCKET_ERROR)
	{
		e = GetLastError();
		
		return ;
	}
	delete stream;
	
	//处理数据
 	const int BUF_SIZE = 64*1024 +12 ;// 8192; //64KB
	char buf[BUF_SIZE];
	int iGet = 0;
	Sleep(10);
	iGet = recv(skt,buf,17,0); //读取状态行
	if(0 == iGet)
	{
		e = GetLastError();
		return;
	}
	buf[18]='\0';

	if(strstr(buf,"OK")==NULL) // not got HTTP/1.x 200 OK
	{
		return;
	}
	iGet = recv(skt,buf,BUF_SIZE,0); //跳过头
	if(iGet == 0)
	{
		iGet = recv(skt,buf,BUF_SIZE,0); //跳过头
	}
	char* lpLoc = strstr(buf,"\r\n\r\n");
	if(lpLoc != NULL)
		lpLoc += 4;
	memcpy(buf,lpLoc,iGet - (lpLoc - buf )); //移动数据,覆盖http头部
	iGet -= (lpLoc - buf  ); 
	WORD len;
	memcpy(&len,buf+2,2); //get asf header len

	//跳过第二次传来的头数据
	while(len + 4 > iGet) //数据不够时,读取数据
	{
		int i = recv(skt,buf + iGet,BUF_SIZE - iGet,0);
		if(i == SOCKET_ERROR)
		{
			e = GetLastError();
			return;
		}
		if(0 == i)
		{
			e = GetLastError();
			return;//连接已断开
		}
		iGet +=i;
	}
	
	memcpy(buf,buf + len,iGet - (len +4)); //跳过asf 头 +4 = http streaming 's header
	iGet -= (len +4);

	len = 0;
	int iPos = 0;
	
	static int cSeqID = 0 ;//从第三秒开始 。用以缓冲。 //TODO:可以从BM中得到当前ID然后加一个缓冲时间
	byte cSeq = 0;	//live show packet 中的序号
	int iAsf = len; //当前asf chunk大小
	char buf_t [PACKET_DATA_SIZE];
	int iOffset_t = 0;
	int iNeedData = 0 ; //当前数据包需要的数据
		
	cSeq=0;
	assert(cSeq == 0);
	int iPadLen = 0;// Padding data length
	while(true)  //接收循环
	{
		while(iPos < iGet) //数据处理循环.iPos当前数据处理指针,iGet,当前可用数据长度
		{
			int iAvailable = iGet - iPos; //接收缓冲中可用数据

			if(iAvailable <= 12)
				break; //跳出,从wme中读取后续数据。
			if((char)0x24 == buf[iPos]  && (char)0x44 == buf[iPos + 1]) //a new asf chunk
			{
				if (memcmp(buf+iPos+2,buf+iPos+10,2)!=0)//len != confirm len
				{
					std::cout << endl << "ERROR!!Read Http Streaming chunk Error!len != confirm len.ERROR!!" << endl;
					closesocket(skt);
					return;
				}
				memcpy(&len,buf + iPos +2 ,2);//得到数据的报大小
				len -= 8;//http stream中的长度= 数据长度加上数据头长度(8字节)
				assert(len > 0);
				
				iAsf = len ; 

				//去除 http streaming 头 和数据头长度4+8
				iPos += 12;
				iAvailable -= 12;
				//fix asf parse info 's padding length

				
					//假设每个包以0x 82 00 00 开始,则接下来一个包就是asf parse info的第一个字节
					int iSkip =0;

					//assert((char)0x82==buf[iPos] && (char)0 == buf[iPos+1] && (char)0 == buf[iPos+2]);

					char c= (buf[iPos +3] & 0x60) ; //判断 Packet Length Type是否存在
					c = c>> 5 ;	
					
					switch(c)
					{
						case 0:
							iSkip =0;
							break;
						case 1:
							iSkip = 1;
							//TODO:最大256字节一个包?好像不会出现这种情况
#if _DEBUG
							log::WriteLine("Packet Length is 0x01(Byte)");
#endif
							memcpy(buf+iPos +5,&dwPacketSize,1);
							break;
						case 2: //340Kbps左右都0x5a4的大小
							iSkip = 2;
							memcpy(buf+iPos +5,&dwPacketSize,2);
							break;
						case 3:
							iSkip = 4;
							memcpy(buf+iPos +5,&dwPacketSize,4);
							break;
					}
					c= (buf[iPos +3] & 0x06) ; //判断 Sequence Length Type是否存在
					c = c>> 5 ;	
					switch(c)
					{
						case 0:
							iSkip += 0 ;
							break;
						case 1:
							iSkip += 1;
							break;
						case 2:
							iSkip += 2;
							break;
						case 3:
							iSkip += 4;
							break;
					}
				//这段程序假设Padding Type = 01 ,即Byte。如果出现非Byte,会有错误! 
				if(iAsf != dwPacketSize)	//计算padding 
				{
					buf[iPos + 5 + iSkip ] = (byte)(dwPacketSize - iAsf); //修改asf流中padding尺寸
					//在这里应该计算出iPadlen的大小???
					//iPadLen = dwPacketSize - iAsf;

				} //end of iAsf != dwPacketSize
				else
				{
					//assert(buf[iPos + 5 + iSkip] == 0);
				}


			}

			if( 0 == iNeedData) //当前数据包需要的数据为0,需要重新计算数据包所需数量
			{
				if(cSeq < Segment::getPacketsOfSegment() - 1)
				{
					//检查读到的数据是否足够push,如果不够,则启动一个读
					iNeedData = PACKET_DATA_SIZE;
				}
				else
				{
					iNeedData = Segment::getLastPacketSize();
				}
				//此时iOffset == 0
				assert(0 == iOffset_t);
				//如果有上一个包未容纳的padding数据,则将padding数据补到当前的cSeqment中
				while(iPadLen >0)
				{
					buf_t[iOffset_t] = 0;
					iOffset_t ++;
					iPadLen --;
				}
			}
			assert(iNeedData >= iOffset_t);
			if(iAvailable > (iNeedData - iOffset_t)) //主缓冲中的数据多余需求数据
			{
				if(iNeedData - iOffset_t >= iAsf) //需求的数据比一个asf chunk大或正好需要chunk
				{
					//将此asf复制到buf_t
					memcpy(buf_t + iOffset_t,buf + iPos,iAsf);
					iOffset_t += iAsf;
					iPos += iAsf;
					iAsf = len; //len 当前asf chunk长度。this is  necessary for next if sentence
					iPadLen = dwPacketSize - len; //padding data length

				}
				else //用不了一个asf chunk就可将当前but_t缓存区添满
				{
					memcpy(buf_t + iOffset_t,buf + iPos,iNeedData - iOffset_t);//复制一部分数据
					iPos += iNeedData - iOffset_t;
					iAsf -= iNeedData - iOffset_t;//iAsf chunk中剩余字节
					
					iOffset_t += iNeedData - iOffset_t;
				}
				
				if(len == iAsf && 0 != iPadLen && iOffset_t != iNeedData  ) //需要填充,且当前Segment有空间
				{
					while( iOffset_t != iNeedData && iPadLen >0 )
					{
						buf_t[iOffset_t] = 0;
						iOffset_t++;
						iPadLen --;
					}
					//执行完以上循环后,还可能剩余一部分padding数据,这个时候iPadLen>0,iOffset_t == iNeedData
				}

				//看数据是否已填满
				if(iOffset_t == iNeedData)
				{
					
#if _DEBUG
					if (0 == cSeq)
					{
						assert((char)0x82==buf_t[0] && (char)0 == buf_t[1] && (char)0 == buf_t[2]);
					}
#endif
					
					lpBuf->srv_PushData(cSeqID,cSeq,buf_t,iNeedData);

					if(cSeq == Segment::getPacketsOfSegment() -1) //最后一个包
					{
						//调整ID
						cSeq = 0;
						if(cSeqID == 0xFFFF)
							cSeqID = 0;
						else
							cSeqID++;
					}
					else
					{
						cSeq++;
					}
					iOffset_t = 0;
					iNeedData = 0; 
				}
				
			} 
			else //数据不足
			{
				break;
			}//end of 主缓冲
			
		} //end of 数据处理循环
		
		//调整缓冲区

		assert(iGet >= iPos);

		if(iGet - iPos >0)
			memcpy(buf,buf + iPos,iGet - iPos);
		iPos = iGet - iPos;
		
		assert(iPos <= BUF_SIZE);

		iGet = recv(skt,buf + iPos,BUF_SIZE - iPos,0); //启动接收		
		
		assert(iGet <= BUF_SIZE - iPos);

		if (0 == iGet)
			break; //无可用数据,连接已关闭
		iGet += iPos; //iGet表示读到的总数
		iPos = 0;
	}//end of 接收循环
 }
示例#5
0
//-------------------------------------------------------------------------------------
void Cellappmgr::reqCreateInNewSpace(Network::Channel* pChannel, MemoryStream& s) 
{
	std::string entityType;
	ENTITY_ID id;
	COMPONENT_ID componentID;
	bool hasClient;

	// 如果cellappIndex为0,则代表不强制指定cellapp
	// 非0的情况下,选择的cellapp可以用1,2,3,4来代替
	// 假如预期有4个cellapp, 假如不够4个, 只有3个, 那么4代表1
	uint32 cellappIndex = 0;

	s >> entityType;
	s >> id;
	s >> cellappIndex;
	s >> componentID;
	s >> hasClient;

	static SPACE_ID spaceID = 1;

	Network::Bundle* pBundle = Network::Bundle::createPoolObject();
	(*pBundle).newMessage(CellappInterface::onCreateInNewSpaceFromBaseapp);
	(*pBundle) << entityType;
	(*pBundle) << id;
	(*pBundle) << spaceID++;
	(*pBundle) << componentID;
	(*pBundle) << hasClient;

	(*pBundle).append(&s);
	s.done();

	uint32 cellappSize = cellapp_cids_.size();

	if (cellappSize > 0)
	{
		updateBestCellapp();

		// 选择特定的cellapp创建space
		if (cellappIndex > 0)
		{
			uint32 index = (cellappIndex - 1) % cellappSize;
			bestCellappID_ = cellapp_cids_[index];
		}
		else if (bestCellappID_ == 0 && numLoadBalancingApp() == 0)
		{
			ERROR_MSG(fmt::format("Cellappmgr::reqCreateInNewSpace: Unable to allocate cellapp for load balancing! entityType={}, entityID={}, componentID={}, cellappSize={}.\n",
				entityType, id, componentID, cellappSize));
		}
	}

	Components::ComponentInfos* cinfos = NULL;
	if (bestCellappID_ > 0)
		cinfos = Components::getSingleton().findComponent(CELLAPP_TYPE, bestCellappID_);

	if (cinfos == NULL || cinfos->pChannel == NULL || cinfos->state != COMPONENT_STATE_RUN)
	{
		WARNING_MSG("Cellappmgr::reqCreateInNewSpace: not found cellapp, message is buffered.\n");

		ForwardItem* pFI = new AppForwardItem();
		pFI->pHandler = NULL;
		pFI->pBundle = pBundle;

		if (cellappIndex == 0 || bestCellappID_ == 0)
			forward_anywhere_cellapp_messagebuffer_.push(pFI);
		else
			forward_cellapp_messagebuffer_.push(bestCellappID_, pFI);

		return;
	}
	else
	{
		cinfos->pChannel->send(pBundle);
	}

	std::map< COMPONENT_ID, Cellapp >::iterator cellapp_iter = cellapps_.find(bestCellappID_);
	DEBUG_MSG(fmt::format("Cellappmgr::reqCreateInNewSpace: entityType={}, entityID={}, componentID={}, cellapp(cid={}, load={}, numEntities={}).\n",
		entityType, id, componentID, bestCellappID_, cellapp_iter->second.load(), cellapp_iter->second.numEntities()));

	// 预先将实体数量增加
	if (cellapp_iter != cellapps_.end())
	{
		cellapp_iter->second.incNumEntities();
	}
}
//-------------------------------------------------------------------------------------
PyObject* EntityRemoteMethod::tp_call(PyObject* self, PyObject* args, 
	PyObject* kwds)	
{	
	EntityRemoteMethod* rmethod = static_cast<EntityRemoteMethod*>(self);
	MethodDescription* methodDescription = rmethod->getDescription();
	EntityMailboxAbstract* mailbox = rmethod->getMailbox();

	if(!mailbox->isClient())
	{
		return RemoteEntityMethod::tp_call(self, args, kwds);
	}

	Entity* pEntity = Cellapp::getSingleton().findEntity(mailbox->id());
	if(pEntity == NULL || pEntity->pWitness() == NULL)
	{
		//WARNING_MSG(fmt::format("EntityRemoteMethod::callClientMethod: not found entity({}).\n", 
		//	mailbox->id()));

		return RemoteEntityMethod::tp_call(self, args, kwds);
	}

	// 如果是调用客户端方法, 我们记录事件并且记录带宽
	if(methodDescription->checkArgs(args))
	{
		Mercury::Bundle* pBundle = Mercury::Bundle::ObjPool().createObject();
		mailbox->newMail((*pBundle));

		MemoryStream* mstream = MemoryStream::ObjPool().createObject();
		methodDescription->addToStream(mstream, args);

		if(mstream->wpos() > 0)
			(*pBundle).append(mstream->data(), mstream->wpos());

		if(Mercury::g_trace_packet > 0)
		{
			if(Mercury::g_trace_packet_use_logfile)
				DebugHelper::getSingleton().changeLogger("packetlogs");

			DEBUG_MSG(fmt::format("EntityRemoteMethod::tp_call: pushUpdateData: ClientInterface::onRemoteMethodCall({}::{})\n",
				pEntity->scriptName(), methodDescription->getName()));
																								
			switch(Mercury::g_trace_packet)																	
			{																								
			case 1:																							
				mstream->hexlike();																			
				break;																						
			case 2:																							
				mstream->textlike();																			
				break;																						
			default:																						
				mstream->print_storage();																	
				break;																						
			};																								

			if(Mercury::g_trace_packet_use_logfile)	
				DebugHelper::getSingleton().changeLogger(COMPONENT_NAME_EX(g_componentType));																				
		}

		//mailbox->postMail((*pBundle));
		pEntity->pWitness()->sendToClient(ClientInterface::onRemoteMethodCall, pBundle);

		//Mercury::Bundle::ObjPool().reclaimObject(pBundle);
		MemoryStream::ObjPool().reclaimObject(mstream);

		// 记录这个事件产生的数据量大小
		g_privateClientEventHistoryStats.trackEvent(pEntity->scriptName(), 
			methodDescription->getName(), 
			pBundle->currMsgLength(), 
			"::");
	}
	
	S_Return;
}	
示例#7
0
void wme_c::receive(char* ip,WORD port)
{
	Buffer* lpBuf = m_buf;
	SOCKET skt = sys->createSocket(SOCK_STREAM);
	sockaddr_in clientService; 
	clientService.sin_family = AF_INET;
	clientService.sin_addr.s_addr = inet_addr( ip);
	clientService.sin_port = htons( port);
	DWORD e;

	int iReqNum = 1;	//请求次数
	bool bCnnected = false;

	const int BUF_SIZE = 64*1024 +12 ;// 8192; //64KB
	char buf[BUF_SIZE];
	int iGet = 0;
	int iPos = 0;
	bool bInited = false;
	while (true)
	{
		
		if (!bCnnected) //not connected
		{
			if(connect(skt,(SOCKADDR*) &clientService,sizeof(clientService))==SOCKET_ERROR)
			{		
				e=GetLastError();
				throw StreamException("wme_c::getHeader.connect ",e);
				//return NULL;
			}	
			MemoryStream *stream  =new MemoryStream(2048);
			if (iReqNum % 2 != 0) //第一次请求
			{
				memset(stream->buf,0,stream->len);
				stream->write(HTTP_REQ_CMD, static_cast<int>( strlen(HTTP_REQ_CMD)  ));
				stream->write(HTTP_REQ_AGENT,static_cast<int>(strlen(HTTP_REQ_AGENT) ) );
				stream->write(HTTP_REQ_PRAGMA,static_cast<int>(strlen(HTTP_REQ_PRAGMA))  );
				stream->writeChar('\r');
				stream->writeChar('\n');
			} 
			else //第二次请求
			{
				
				memset(stream->buf,0,stream->len);
				stream->write(HTTP_REQ_CMD, static_cast<int>(strlen(HTTP_REQ_CMD)  ));
				stream->write(HTTP_REQ_AGENT,static_cast<int>(strlen(HTTP_REQ_AGENT) ) );
				stream->write(HTTP_REQ_PRAGMA2,static_cast<int>(strlen(HTTP_REQ_PRAGMA2))  ); //第二次请求
				stream->writeChar('\r');
				stream->writeChar('\n');
			}
			if(send(skt,stream->buf,static_cast<int>(strlen(stream->buf)),0)==SOCKET_ERROR)
			{
				e = GetLastError();

				return ;
			}
			delete stream;
		} 
		
		Sleep(10);
lblRecv:
		if (iPos > 0)
		{
			memcpy(buf,buf+iPos,iGet - iPos);
			iGet -= iPos;
			iPos = 0;
		}
		int iRecv = recv(skt,buf+iGet,BUF_SIZE - iGet,0);
		if (0 == iRecv)
		{
			//net workerror
		}
		iGet += iRecv;

		char* HTTP = "HTTP";
		
		char* RNRN = "\r\n\r\n";
		if (memfind(buf,iGet,HTTP,4) != NULL)
		{
			iPos = ( memfind(buf,iGet,RNRN,4)-buf) + 4;
		}
		AsfChunkHeader chkHeader;
		memcpy(&chkHeader,buf+iPos,sizeof(chkHeader));
		if (chkHeader.wConfirmLen != chkHeader.wLen)
		{
			//TODO:error
		}
		if (chkHeader.wLen + 4> iGet - iPos )
		{
			goto lblRecv;
		}

		switch(chkHeader.wCMD)
		{
		case 0x4824://"$H"
			{
				if (!bInited)
				{
					asfHeader *objHeader = new asfHeader(buf+iPos + 4 + 8,chkHeader.wLen);
					dwPacketSize = objHeader->getChunkSize();
					dwBitRate = objHeader->getBitRate();
					delete objHeader;
					int size = ( dwBitRate /8 /dwPacketSize)*dwPacketSize;//(349056 /8 /0x5a4) * 0x5a4;
					Segment::setSegmentSize( size);//试验用 1.06M

					lpBuf->m_Header.lpData = new char[chkHeader.wLen - 8];
					memcpy(lpBuf->m_Header.lpData,buf + iPos + 4 + 8 ,chkHeader.wLen -  8);
					lpBuf->m_Header.len = chkHeader.wLen - 8;
					lpBuf->Init(0);
					bInited = true;
				}
				bCnnected =true;
				iPos +=  chkHeader.wLen + 4;
			}
			break;
		case 0xa444://?D
		case 0x4424://$D
			{
				iPos = processData(lpBuf,buf,iPos,iGet);
				if(iPos<0)
				{
					bCnnected = false;
					closesocket(skt);
				}
			}
		    break;
		
		}
		
	}

}
示例#8
0
//-------------------------------------------------------------------------------------
void Loginapp::login(Mercury::Channel* pChannel, MemoryStream& s)
{
	COMPONENT_CLIENT_TYPE ctype;
	CLIENT_CTYPE tctype = UNKNOWN_CLIENT_COMPONENT_TYPE;
	std::string loginName;
	std::string password;
	std::string datas;

	// 前端类别
	s >> tctype;
	ctype = static_cast<COMPONENT_CLIENT_TYPE>(tctype);
	
	// 附带数据
	s.readBlob(datas);

	// 帐号登录名
	s >> loginName;

	// 密码
	s >> password;

	loginName = KBEngine::strutil::kbe_trim(loginName);
	if(loginName.size() == 0)
	{
		ERROR_MSG("Loginapp::login: loginName is NULL.\n");
		return;
	}

	if(loginName.size() > ACCOUNT_NAME_MAX_LENGTH)
	{
		ERROR_MSG(boost::format("Loginapp::login: loginName too big, size=%1%, limit=%2%.\n") %
			loginName.size() % ACCOUNT_NAME_MAX_LENGTH);

		return;
	}

	if(password.size() > ACCOUNT_PASSWD_MAX_LENGTH)
	{
		ERROR_MSG(boost::format("Loginapp::login: password too big, size=%1%, limit=%2%.\n") %
			password.size() % ACCOUNT_PASSWD_MAX_LENGTH);

		return;
	}
	
	if(datas.size() > ACCOUNT_DATA_MAX_LENGTH)
	{
		ERROR_MSG(boost::format("Loginapp::login: bindatas too big, size=%1%, limit=%2%.\n") %
			datas.size() % ACCOUNT_DATA_MAX_LENGTH);

		return;
	}

	if(!g_kbeSrvConfig.getDBMgr().allowEmptyDigest && ctype != CLIENT_TYPE_BROWSER)
	{
		std::string clientDigest;

		if(s.opsize() > 0)
			s >> clientDigest;

		if(clientDigest != digest_)
		{
			ERROR_MSG(boost::format("Loginapp::login: loginName(%1%), digest not match. curr(%2%) != dbmgr(%3%)\n") %
				loginName % clientDigest % digest_);

			datas = "";
			_loginFailed(pChannel, loginName, SERVER_ERR_DIGEST, datas, true);
			return;
		}
	}
示例#9
0
//-------------------------------------------------------------------------------------
bool CreateAccountTask::process()
{
	if(!enable)
	{
		return false;
	}

	// 如果没有设置第三方服务地址则我们默认为成功
	if(strlen(serviceAddr()) == 0)
	{
		success = true;
		getDatas = postDatas;
		return false;
	}

	Mercury::EndPoint endpoint;
	endpoint.socket(SOCK_STREAM);

	if (!endpoint.good())
	{
		ERROR_MSG("BillingTask::process: couldn't create a socket\n");
		return false;
	}

	if(postDatas.size() == 0)
	{
		ERROR_MSG(boost::format("BillingTask::process: %1% postData is NULL.\n") % commitName);
		return false;
	}

	u_int32_t addr;
	KBEngine::Mercury::EndPoint::convertAddress(serviceAddr(), addr);

	if(endpoint.connect(htons(servicePort()), addr) == -1)
	{
		ERROR_MSG(boost::format("BillingTask::process: connect billingserver(%1%:%2%) is error(%3%)!\n") % 
			serviceAddr() % servicePort() % kbe_strerror());

		endpoint.close();
		return false;
	}

	endpoint.setnonblocking(true);
	endpoint.setnodelay(true);

	Mercury::Bundle::SmartPoolObjectPtr bundle = Mercury::Bundle::createSmartPoolObj();
	(*(*bundle)).append(postDatas.data(), postDatas.size());
	(*(*bundle)).send(endpoint);

	Mercury::TCPPacket packet;
	packet.resize(1024);

	fd_set	frds;
	struct timeval tv = { 0, 5000000 }; // 5000ms

	FD_ZERO( &frds );
	FD_SET((int)endpoint, &frds);
	int selgot = select(endpoint+1, &frds, NULL, NULL, &tv);
	if(selgot <= 0)
	{
		ERROR_MSG(boost::format("BillingTask::process: %1% send(%2%).\n") % commitName % postDatas);
		ERROR_MSG(boost::format("BillingTask::process: %1% recv is error(%2%).\n") % commitName % KBEngine::kbe_strerror());
		endpoint.close();
		return false;
	}
	
	int len = endpoint.recv(packet.data(), 1024);

	if(len <= 0)
	{
		ERROR_MSG(boost::format("BillingTask::process: %1% recv is size<= 0.\n===>postdatas=%2%\n") % commitName % postDatas);
		endpoint.close();
		return false;
	}

	packet.wpos(len);

	getDatas.assign((const char *)(packet.data() + packet.rpos()), packet.opsize());

	try
	{
		std::string::size_type fi = getDatas.find("\r\n\r\n");
		if(fi != std::string::npos)
		{
			fi += 4;
			MemoryStream s;
			s.append(getDatas.data() + fi, getDatas.size() - fi);

			while(s.opsize() > 0)
			{
				int32 type, len;
				s >> type >> len;
				EndianConvertReverse<int32>(type);
				EndianConvertReverse<int32>(len);
				
				int32 error = 0;

				switch(type)
				{
				case 1:
					s >> error;
					EndianConvertReverse<int32>(error);

					if(error != 0)
					{
						success = false;
						endpoint.close();
						
						std::string err;
						if(s.opsize() >= (sizeof(int32) * 2))
						{
							s >> type >> len;
							
							if(len > 0 && len < 1024)
							{
								char* buf = new char[len + 1];
								memcpy(buf, s.data() + s.rpos(), len);
								buf[len] = 0;
								err = buf;
								delete[] buf;
							}

						}

						DEBUG_MSG(boost::format("BillingTask::process: (%1%)op is failed! err=%2%\n<==send(%3%)\n==>recv(%4%).\n") % commitName % err % postDatas % getDatas);
						return false;
					}
					else
					{
						success = true;
					}

					break;
				case 2:
					{
						s.read_skip(len);
					}
					break;
				case 3:
					{
						char* buf = new char[len + 1];
						memcpy(buf, s.data() + s.rpos(), len);
						buf[len] = 0;
						accountName = buf;
						delete[] buf;

						s.read_skip(len);
					}
					break;
				default:
					break;
				};
//-------------------------------------------------------------------------------------
PyObject* ClientsRemoteEntityMethod::callmethod(PyObject* args, PyObject* kwds)
{
	// 获取entityAOI范围内其他entity
	// 向这些entity的client推送这个方法的调用
	MethodDescription* methodDescription = getDescription();

	Entity* pEntity = Cellapp::getSingleton().findEntity(id_);
	if(pEntity == NULL || /*pEntity->pWitness() == NULL ||*/
		pEntity->isDestroyed() /*|| pEntity->clientMailbox() == NULL*/)
	{
		//WARNING_MSG(fmt::format("EntityRemoteMethod::callClientMethod: not found entity({}).\n", 
		//	mailbox->id()));

		S_Return;
	}
	
	const std::list<ENTITY_ID>& entities = pEntity->witnesses();

	if(otherClients_)
	{
		if(pEntity->witnessesSize() == 0)
			S_Return;
	}
	
	// 先发给自己
	if(methodDescription->checkArgs(args))
	{
		MemoryStream* mstream = MemoryStream::ObjPool().createObject();
		methodDescription->addToStream(mstream, args);

		if((!otherClients_ && (pEntity->pWitness() || (pEntity->clientMailbox()))))
		{
			Network::Bundle* pBundle = Network::Bundle::ObjPool().createObject();
			pEntity->clientMailbox()->newMail((*pBundle));

			if(mstream->wpos() > 0)
				(*pBundle).append(mstream->data(), mstream->wpos());

			if(Network::g_trace_packet > 0)
			{
				if(Network::g_trace_packet_use_logfile)
					DebugHelper::getSingleton().changeLogger("packetlogs");

				DEBUG_MSG(fmt::format("ClientsRemoteEntityMethod::callmethod: pushUpdateData: ClientInterface::onRemoteMethodCall({}::{})\n", 
					pEntity->scriptName(), methodDescription->getName()));
																									
				switch(Network::g_trace_packet)																	
				{																								
				case 1:																							
					mstream->hexlike();																			
					break;																						
				case 2:																							
					mstream->textlike();																			
					break;																						
				default:																						
					mstream->print_storage();																	
					break;																						
				};																								

				if(Network::g_trace_packet_use_logfile)	
					DebugHelper::getSingleton().changeLogger(COMPONENT_NAME_EX(g_componentType));																				
			}

			//mailbox->postMail((*pBundle));
			pEntity->pWitness()->sendToClient(ClientInterface::onRemoteMethodCall, pBundle);

			// 记录这个事件产生的数据量大小
			g_publicClientEventHistoryStats.trackEvent(pEntity->scriptName(), 
				methodDescription->getName(), 
				pBundle->currMsgLength(), 
				"::");
		}
		
		// 广播给其他人
		std::list<ENTITY_ID>::const_iterator iter = entities.begin();
		for(; iter != entities.end(); ++iter)
		{
			Entity* pAoiEntity = Cellapp::getSingleton().findEntity((*iter));
			if(pAoiEntity == NULL || pAoiEntity->pWitness() == NULL || pAoiEntity->isDestroyed())
				continue;
			
			EntityMailbox* mailbox = pAoiEntity->clientMailbox();
			if(mailbox == NULL)
				continue;

			Network::Channel* pChannel = mailbox->getChannel();
			if(pChannel == NULL)
				continue;

			if(!pAoiEntity->pWitness()->entityInAOI(pEntity->id()))
				continue;

			Network::Bundle* pSendBundle = Network::Bundle::ObjPool().createObject();
			Network::Bundle* pForwardBundle = Network::Bundle::ObjPool().createObject();
			
			pAoiEntity->pWitness()->addSmartAOIEntityMessageToBundle(pForwardBundle, ClientInterface::onRemoteMethodCall, 
					ClientInterface::onRemoteMethodCallOptimized, pEntity->id());

			if(mstream->wpos() > 0)
				(*pForwardBundle).append(mstream->data(), mstream->wpos());

			if(Network::g_trace_packet > 0)
			{
				if(Network::g_trace_packet_use_logfile)
					DebugHelper::getSingleton().changeLogger("packetlogs");

				DEBUG_MSG(fmt::format("ClientsRemoteEntityMethod::callmethod: pushUpdateData: ClientInterface::onRemoteOtherEntityMethodCall({}::{})\n", 
					pAoiEntity->scriptName(), methodDescription->getName()));
																									
				switch(Network::g_trace_packet)																	
				{																								
				case 1:																							
					mstream->hexlike();																			
					break;																						
				case 2:																							
					mstream->textlike();																			
					break;																						
				default:																						
					mstream->print_storage();																	
					break;																						
				};																								

				if(Network::g_trace_packet_use_logfile)	
					DebugHelper::getSingleton().changeLogger(COMPONENT_NAME_EX(g_componentType));																				
			}

			NETWORK_ENTITY_MESSAGE_FORWARD_CLIENT(pAoiEntity->id(), (*pSendBundle), (*pForwardBundle));

			//mailbox->postMail((*pBundle));
			pAoiEntity->pWitness()->sendToClient(ClientInterface::onRemoteMethodCallOptimized, pSendBundle);

			// 记录这个事件产生的数据量大小
			g_publicClientEventHistoryStats.trackEvent(pAoiEntity->scriptName(), 
				methodDescription->getName(), 
				pForwardBundle->currMsgLength(), 
				"::");

			Network::Bundle::ObjPool().reclaimObject(pForwardBundle);
		}

		MemoryStream::ObjPool().reclaimObject(mstream);
	}

	S_Return;
}
示例#11
0
文件: OggAudio.cpp 项目: fjz13/Medusa
long ogg_tell_func(void *datasource)
{
    MemoryStream* oggStream = (MemoryStream*)datasource;
    return (long)oggStream->Position();
}
示例#12
0
//-------------------------------------------------------------------------------------
void Bundle::debugCurrentMessages(MessageID currMsgID, const Network::MessageHandler* pCurrMsgHandler,
	Network::Packet* pCurrPacket, Network::Bundle::Packets& packets, Network::MessageLength1 currMsgLength,
	Network::Channel* pChannel)
{
	if (currMsgID == 0)
		return;

	if (!pCurrMsgHandler || currMsgID != pCurrMsgHandler->msgID || !pCurrMsgHandler->pMessageHandlers)
		return;

	if (pCurrMsgHandler->msgLen == NETWORK_VARIABLE_MESSAGE)
	{
		// 因为Bundle::finiMessage等地方遇到可变参数消息时将长度去掉了消息头部,这里要还原消息就要加回来
		currMsgLength += NETWORK_MESSAGE_ID_SIZE;
		currMsgLength += NETWORK_MESSAGE_LENGTH_SIZE;
		if (currMsgLength - NETWORK_MESSAGE_ID_SIZE - NETWORK_MESSAGE_LENGTH_SIZE >= NETWORK_MESSAGE_MAX_SIZE)
			currMsgLength += NETWORK_MESSAGE_LENGTH1_SIZE;
	}
	
	MemoryStream* pMemoryStream = MemoryStream::createPoolObject();
	
	// 通过消息长度找到消息头,然后将消息内容输出
	int msglen = currMsgLength;
	if(pCurrPacket)
	{
		// 如果当前消息所有内容都在当前包中,直接输出内容即可
		msglen -= pCurrPacket->length();
		if(msglen <= 0)
		{
			pMemoryStream->append(pCurrPacket->data() + pCurrPacket->wpos() - currMsgLength, currMsgLength);
		}
		else
		{
			int idx = 0;

			Network::Bundle::Packets::reverse_iterator packiter = packets.rbegin();
			for (; packiter != packets.rend(); ++packiter)
			{
				++idx;

				Network::Packet* pPacket = (*packiter);

				// 当前包可能已经计算过
				if (pCurrPacket == pPacket)
					continue;

				// 如果所有内容都在包中
				if((int)pPacket->length() >= msglen)
				{
					int wpos = pPacket->length() - msglen;
					pMemoryStream->append(pPacket->data() + wpos, msglen);
					
					for(size_t i = packets.size() - idx; i < packets.size(); ++i)
					{
						Network::Packet* pPacket1 = packets[i];
						
						// 这个包已经在上面处理过了
						if (pPacket1 == pPacket || pCurrPacket == pPacket1)
							continue;
						
						// 期间的包内容全部加入
						pMemoryStream->append(pPacket1->data() + pPacket1->rpos(), pPacket1->length());
					}
					
					// 把当前的包内容全部加进去
					pMemoryStream->append(pCurrPacket->data() + pCurrPacket->rpos(), pCurrPacket->length());
					break;
				}
				else
				{
					msglen -= pPacket->length();
				}
			}
		}
	}
	
	// 一些sendto操作的包导致, 这类包也不需要追踪
	if(pMemoryStream->length() < NETWORK_MESSAGE_ID_SIZE)
	{
		MemoryStream::reclaimPoolObject(pMemoryStream);
		return;
	}

	KBE_ASSERT(currMsgLength == pMemoryStream->length());
	
	TRACE_MESSAGE_PACKET(false, pMemoryStream, pCurrMsgHandler, pMemoryStream->length(),
		(pChannel != NULL ? pChannel->c_str() : "None"), false);
					
	MemoryStream::reclaimPoolObject(pMemoryStream);
}
示例#13
0
		virtual void createFromStream(MemoryStream& s)				
		{
			s.readBlob(strarg);	
		}
示例#14
0
		virtual void addToStream(MemoryStream& s)
		{
			s.appendBlob(strarg);	
		}
示例#15
0
//-------------------------------------------------------------------------------------
void Loginapp::onReqCreateMailAccountResult(Network::Channel* pChannel, MemoryStream& s)
{
	SERVER_ERROR_CODE failedcode;
	std::string accountName;
	std::string password;
	std::string retdatas = "";

	s >> failedcode >> accountName >> password;
	s.readBlob(retdatas);

	DEBUG_MSG(fmt::format("Loginapp::onReqCreateMailAccountResult: accountName={}, failedcode={}.\n",
		accountName.c_str(), failedcode));

	if(failedcode == SERVER_SUCCESS)
	{
		Components::COMPONENTS& loginapps = Components::getSingleton().getComponents(LOGINAPP_TYPE);

		std::string http_host = "localhost";
		if(startGroupOrder_ == 1)
		{
			if(strlen((const char*)&g_kbeSrvConfig.getLoginApp().externalAddress) > 0)
				http_host = g_kbeSrvConfig.getBaseApp().externalAddress;
			else
				http_host = inet_ntoa((struct in_addr&)Loginapp::getSingleton().networkInterface().extaddr().ip);
		}
		else
		{
			Components::COMPONENTS::iterator iter = loginapps.begin();
			for(; iter != loginapps.end(); ++iter)
			{
				if((*iter).groupOrderid == 1)
				{
					if(strlen((const char*)&(*iter).externalAddressEx) > 0)
						http_host = (*iter).externalAddressEx;
					else
						http_host = inet_ntoa((struct in_addr&)(*iter).pExtAddr->ip);
				}
			}
		}

		threadPool_.addTask(new SendActivateEMailTask(accountName, retdatas, 
			http_host, 
			g_kbeSrvConfig.getLoginApp().http_cbport));
	}

	PendingLoginMgr::PLInfos* ptinfos = pendingCreateMgr_.remove(accountName);
	if(ptinfos == NULL)
		return;

	Network::Channel* pClientChannel = this->networkInterface().findChannel(ptinfos->addr);
	if(pClientChannel == NULL)
		return;

	pClientChannel->extra("");
	retdatas = "";

	Network::Bundle* pBundle = Network::Bundle::createPoolObject();
	(*pBundle).newMessage(ClientInterface::onCreateAccountResult);
	(*pBundle) << failedcode;
	(*pBundle).appendBlob(retdatas);

	pClientChannel->send(pBundle);

	SAFE_RELEASE(ptinfos);
}
示例#16
0
/** 找开文件
@param   pszFileName:文件名
@param   
@return  
*/
bool CCsvReader::Open(const char* pszFileName, bool bEncrypt)
{
	if(pszFileName == NULL)
	{
		return false;
	}

	m_curStrName = pszFileName;

	// 取得文件系统
	FileSystem * pFileSystem = getFileSystem();
	if(pFileSystem == NULL)
	{
		return false;
	}

	// 读取文件
	Stream * pStream = pFileSystem->open(pszFileName);
	if(pStream == NULL)
	{
		return false;
	}

	// 解密文件
	char * pFileBuffer = NULL;
	MemoryStream memorystream;
	if(bEncrypt)
	{
		int nFileLength = pStream->getLength();
		pFileBuffer = new char [nFileLength + 1];
		if(!pStream->read(pFileBuffer, nFileLength))
		{
			return false;
		}
		pStream->close();
		pStream->release();

		if(!makeMap((uchar *)pFileBuffer, nFileLength, 'LAND'))
		{
			return false;
		}

		memorystream.attach((uchar *)pFileBuffer, nFileLength);
		pStream = &memorystream;
	}
	
	// 解析
	if(!_Open(pStream))
	{
		if(pFileBuffer != NULL)
		{
			delete [] pFileBuffer;
			pFileBuffer = NULL;
		}
		
		// 关闭文件
		pStream->close();
		pStream->release();
		return false;
	}
	// 关闭文件
	pStream->close();
	
	pStream->release();
	if(pFileBuffer != NULL)
	{
		delete [] pFileBuffer;
		pFileBuffer = NULL;
	}
	return true;
}
示例#17
0
//-------------------------------------------------------------------------------------
void Loginapp::login(Network::Channel* pChannel, MemoryStream& s)
{
	AUTO_SCOPED_PROFILE("login");

	COMPONENT_CLIENT_TYPE ctype;
	CLIENT_CTYPE tctype = UNKNOWN_CLIENT_COMPONENT_TYPE;
	std::string loginName;
	std::string password;
	std::string datas;

	// 前端类别
	s >> tctype;
	ctype = static_cast<COMPONENT_CLIENT_TYPE>(tctype);
	
	// 附带数据
	s.readBlob(datas);

	// 帐号登录名
	s >> loginName;

	// 密码
	s >> password;

	loginName = KBEngine::strutil::kbe_trim(loginName);
	if(loginName.size() == 0)
	{
		INFO_MSG("Loginapp::login: loginName is NULL.\n");
		_loginFailed(pChannel, loginName, SERVER_ERR_NAME, datas, true);
		s.done();
		return;
	}

	if(loginName.size() > ACCOUNT_NAME_MAX_LENGTH)
	{
		INFO_MSG(fmt::format("Loginapp::login: loginName is too long, size={}, limit={}.\n",
			loginName.size(), ACCOUNT_NAME_MAX_LENGTH));
		
		_loginFailed(pChannel, loginName, SERVER_ERR_NAME, datas, true);
		s.done();
		return;
	}

	if(password.size() > ACCOUNT_PASSWD_MAX_LENGTH)
	{
		INFO_MSG(fmt::format("Loginapp::login: password is too long, size={}, limit={}.\n",
			password.size(), ACCOUNT_PASSWD_MAX_LENGTH));
		
		_loginFailed(pChannel, loginName, SERVER_ERR_PASSWORD, datas, true);
		s.done();
		return;
	}
	
	if(datas.size() > ACCOUNT_DATA_MAX_LENGTH)
	{
		INFO_MSG(fmt::format("Loginapp::login: bindatas is too long, size={}, limit={}.\n",
			datas.size(), ACCOUNT_DATA_MAX_LENGTH));
		
		_loginFailed(pChannel, loginName, SERVER_ERR_OP_FAILED, datas, true);
		s.done();
		return;
	}

	// 首先必须baseappmgr和dbmgr都已经准备完毕了。
	Components::ComponentInfos* baseappmgrinfos = Components::getSingleton().getBaseappmgr();
	if(baseappmgrinfos == NULL || baseappmgrinfos->pChannel == NULL || baseappmgrinfos->cid == 0)
	{
		datas = "";
		_loginFailed(pChannel, loginName, SERVER_ERR_SRV_NO_READY, datas, true);
		s.done();
		return;
	}

	Components::ComponentInfos* dbmgrinfos = Components::getSingleton().getDbmgr();
	if(dbmgrinfos == NULL || dbmgrinfos->pChannel == NULL || dbmgrinfos->cid == 0)
	{
		datas = "";
		_loginFailed(pChannel, loginName, SERVER_ERR_SRV_NO_READY, datas, true);
		s.done();
		return;
	}

	if(!g_kbeSrvConfig.getDBMgr().allowEmptyDigest)
	{
		std::string clientDigest;

		if(s.length() > 0)
			s >> clientDigest;

		if(clientDigest.size() > 0)
		{
			if(clientDigest != digest_)
			{
				INFO_MSG(fmt::format("Loginapp::login: loginName({}), digest not match. curr({}) != dbmgr({})\n",
					loginName, clientDigest, digest_));

				datas = "";
				_loginFailed(pChannel, loginName, SERVER_ERR_ENTITYDEFS_NOT_MATCH, datas, true);
				return;
			}
		}
		else
		{
			//WARNING_MSG(fmt::format("Loginapp::login: loginName={} no check entitydefs!\n", loginName));
		}
	}
示例#18
0
int main(int argc, char* argv[])
#endif
{
	WString baseDirectory;
	{
#if defined VCZH_MSVC
		wchar_t currentDirectory[MAX_PATH]={0};
		GetCurrentDirectory(MAX_PATH, currentDirectory);
		baseDirectory=currentDirectory;
#elif defined VCZHGCC
		char currentDirectory[1024]={0};
		getcwd(currentDirectory, 1024);
		baseDirectory=atow(currentDirectory);
#endif
		if(baseDirectory[baseDirectory.Length()-1]!=PATH_DELIMITER)
		{
			baseDirectory+=PATH_DELIMITER;
		}
	}


	Regex regexPathSplitter(L"[///\\]");
	Ptr<ParsingGeneralParser> parser=CreateBootstrapStrictParser();

	Console::SetTitle(L"Vczh Parser Generator for C++");
	Console::SetColor(false, true, false, true);
	Console::WriteLine(L"parsing>Files : "+itow(argc-1));
	for(int i=1;i<argc;i++)
	{
		Console::WriteLine(L"------------------------------------------------------------");
#if defined VCZH_MSVC
		WString inputPath=argv[i];
#elif defined VCZH_GCC
		WString inputPath=atow(argv[i]);
#endif
		if(inputPath.Length()<2 || inputPath[1]!=L':')
		{
			inputPath=baseDirectory+inputPath;
		}
		Console::WriteLine(L"parsing>Making : "+inputPath);
		if(inputPath.Length()<11 || inputPath.Right(11)!=L".parser.txt")
		{
			Console::SetColor(true, false, false, true);
			Console::WriteLine(L"error> The extenion name of the input file path must be \".parser.txt\".");
			Console::SetColor(false, true, false, true);
		}
		else
		{
			WString name;
			{
				List<Ptr<RegexMatch>> matches;
				regexPathSplitter.Split(inputPath, true, matches);
				name=matches[matches.Count()-1]->Result().Value();
				name=name.Left(name.Length()-11);
			}
			WString outputMetaPath=inputPath.Left(inputPath.Length()-11);
			WString outputHeaderPath=outputMetaPath+L".h";
			WString outputCppPath=outputMetaPath+L".cpp";
			WString logPath=outputMetaPath+L".log";
			Console::WriteLine(L"parsing>Output header path : "+outputHeaderPath);
			Console::WriteLine(L"parsing>Output cpp path : "+outputCppPath);
			Console::WriteLine(L"parsing>Log path : "+logPath);

			CodegenConfig config;
			WString codeGrammar;
			{
				FileStream fileStream(inputPath, FileStream::ReadOnly);
				if(!fileStream.IsAvailable())
				{
					Console::SetColor(true, false, false, true);
					Console::WriteLine(L"error> Cannot open \""+inputPath+L" for read.");
					Console::SetColor(false, true, false, true);
					goto STOP_PARSING;
				}
				BomDecoder decoder;
				DecoderStream decoderStream(fileStream, decoder);
				StreamReader reader(decoderStream);

				if(!config.ReadConfig(reader))
				{
					goto STOP_PARSING;
				}
				codeGrammar=reader.ReadToEnd();
			}

			Ptr<ParsingDefinition> definition;
			Ptr<ParsingTable> table;
			{
				FileStream fileStream(logPath, FileStream::WriteOnly);
				if(!fileStream.IsAvailable())
				{
					Console::SetColor(true, false, false, true);
					Console::WriteLine(L"error> Cannot open \""+logPath+L" for write.");
					Console::SetColor(false, true, false, true);
					goto STOP_PARSING;
				}
				BomEncoder encoder(BomEncoder::Utf16);
				EncoderStream encoderStream(fileStream, encoder);
				StreamWriter writer(encoderStream);
				
				if(codeGrammar==L"<bootstrap-grammar>")
				{
					definition=CreateParserDefinition();
					MemoryStream bootstrapStream;
					{
						StreamWriter bootstrapWriter(bootstrapStream);
						Log(definition, bootstrapWriter);
					}
					bootstrapStream.SeekFromBegin(0);
					StreamReader bootstrapReader(bootstrapStream);
					codeGrammar=bootstrapReader.ReadToEnd();
				}
				else
				{
					definition=CreateDefinition(parser, codeGrammar, writer);
				}
				if(!definition)
				{
					Console::SetColor(true, false, false, true);
					Console::WriteLine(L"error> Error happened. Open \""+logPath+L" for details.");
					Console::SetColor(false, true, false, true);
					goto STOP_PARSING;
				}

				table=CreateTable(definition, writer, config.ambiguity);
				if(!table)
				{
					Console::SetColor(true, false, false, true);
					Console::WriteLine(L"error> Error happened. Open \""+logPath+L" for details.");
					Console::SetColor(false, true, false, true);
					goto STOP_PARSING;
				}
			}
			{
				FileStream fileStream(outputHeaderPath, FileStream::WriteOnly);
				if(!fileStream.IsAvailable())
				{
					Console::SetColor(true, false, false, true);
					Console::WriteLine(L"error> Cannot open \""+outputHeaderPath+L" for write.");
					Console::SetColor(false, true, false, true);
					goto STOP_PARSING;
				}
				BomEncoder encoder(BomEncoder::Mbcs);
				EncoderStream encoderStream(fileStream, encoder);
				StreamWriter writer(encoderStream);
				WriteHeaderFile(name, definition, table, config, writer);
			}
			{
				FileStream fileStream(outputCppPath, FileStream::WriteOnly);
				if(!fileStream.IsAvailable())
				{
					Console::SetColor(true, false, false, true);
					Console::WriteLine(L"error> Cannot open \""+outputCppPath+L" for write.");
					Console::SetColor(false, true, false, true);
					goto STOP_PARSING;
				}
				BomEncoder encoder(BomEncoder::Mbcs);
				EncoderStream encoderStream(fileStream, encoder);
				StreamWriter writer(encoderStream);
				
				config.includes.Clear();
				config.includes.Add(L"\""+name+L".h\"");
				WriteCppFile(name, codeGrammar, definition, table, config, writer);
			}
		}
	STOP_PARSING:;
	}
	Console::WriteLine(L"Finished!");
	return 0;
}
示例#19
0
int main()
{
    int result = -1;

    Object* root = NULL;

    esInit(&root);
    esReport("Check write().\n");

    MemoryStream* backingStore = new MemoryStream(0);
    if (!backingStore)
    {
        esReport("Bad alloc. (backingStore)\n");
        return 1;
    }

    long offset = 0;
    long size = PAGE_SIZE;

    // write one byte at a time.
    result = Verify(size, offset, backingStore, 1);
    if (result < 0)
    {
        goto ERROR;
    }
#ifdef VERBOSE
    esReport("done.\n");
#endif // VERBOSE

    // write 6KB at a time.
    size = 2 * PAGE_SIZE;
    result = Verify(size, offset, backingStore, PAGE_SIZE + PAGE_SIZE / 2);
    if (result < 0)
    {
        goto ERROR;
    }
#ifdef VERBOSE
    esReport("done.\n");
#endif // VERBOSE

    // write 8KB at a time from the offset.
    offset = 100;
    size = 4 * PAGE_SIZE;
    result = Verify(size, offset, backingStore, 2 * PAGE_SIZE);
    if (result < 0)
    {
        goto ERROR;
    }
#ifdef VERBOSE
    esReport("done.\n");
#endif // VERBOSE

    // write 64KB at a time.
    offset = 0;
    size = BUF_SIZE;
    result = Verify(size, offset, backingStore, PAGE_TABLE_SIZE);
    if (result < 0)
    {
        goto ERROR;
    }

    backingStore->release();
    esReport("done.\n");
    return 0;

ERROR:
    backingStore->release();
#ifdef VERBOSE
    esReport("*** error ***\n");
#endif // VERBOSE
    return 1;
}
示例#20
0
//-------------------------------------------------------------------------------------
void Baseappmgr::registerPendingAccountToBaseapp(Network::Channel* pChannel, MemoryStream& s)
{
    std::string loginName;
    std::string accountName;
    std::string password;
    std::string datas;
    DBID entityDBID;
    uint32 flags;
    uint64 deadline;
    COMPONENT_TYPE componentType;

    s >> loginName >> accountName >> password >> entityDBID >> flags >> deadline >> componentType;
    s.readBlob(datas);

    Components::ComponentInfos* cinfos = Components::getSingleton().findComponent(pChannel);
    if(cinfos == NULL || cinfos->pChannel == NULL)
    {
        ERROR_MSG("Baseappmgr::registerPendingAccountToBaseapp: not found loginapp!\n");
        return;
    }

    pending_logins_[loginName] = cinfos->cid;

    updateBestBaseapp();

    if (bestBaseappID_ == 0 && numLoadBalancingApp() == 0)
    {
        ERROR_MSG(fmt::format("Baseappmgr::registerPendingAccountToBaseapp: Unable to allocate baseapp for load balancing! baseappSize={}, accountName={}.\n",
                              baseapps_.size(), loginName));
    }

    ENTITY_ID eid = 0;
    cinfos = Components::getSingleton().findComponent(BASEAPP_TYPE, bestBaseappID_);

    if (cinfos == NULL || cinfos->pChannel == NULL || cinfos->state != COMPONENT_STATE_RUN)
    {
        Network::Bundle* pBundle = Network::Bundle::createPoolObject();
        ForwardItem* pFI = new AppForwardItem();

        pFI->pBundle = pBundle;
        (*pBundle).newMessage(BaseappInterface::registerPendingLogin);
        (*pBundle) << loginName << accountName << password << eid << entityDBID << flags << deadline << componentType;
        pBundle->appendBlob(datas);

        int runstate = -1;
        if (cinfos)
            runstate = (int)cinfos->state;

        WARNING_MSG(fmt::format("Baseappmgr::registerPendingAccountToBaseapp: not found baseapp({}, runstate={}, pChannel={}), message is buffered.\n",
                                bestBaseappID_, runstate, (cinfos && cinfos->pChannel ? cinfos->pChannel->c_str() : "NULL")));

        pFI->pHandler = NULL;
        forward_anywhere_baseapp_messagebuffer_.push(pFI);
        return;
    }

    std::map< COMPONENT_ID, Baseapp >::iterator baseapps_iter = baseapps_.find(bestBaseappID_);

    DEBUG_MSG(fmt::format("Baseappmgr::registerPendingAccountToBaseapp:{}. allocBaseapp={}, numEntities={}.\n",
                          accountName, bestBaseappID_, (bestBaseappID_ > 0 ? baseapps_iter->second.numEntities() : 0)));

    Network::Bundle* pBundle = Network::Bundle::createPoolObject();
    (*pBundle).newMessage(BaseappInterface::registerPendingLogin);
    (*pBundle) << loginName << accountName << password << eid << entityDBID << flags << deadline << componentType;
    pBundle->appendBlob(datas);
    cinfos->pChannel->send(pBundle);

    // 预先将实体数量增加
    if (baseapps_iter != baseapps_.end())
    {
        baseapps_iter->second.incNumProxices();
    }
}
示例#21
0
char* wme_c::getHeader(char* ip,WORD port)
{
	Buffer* lpBuf = m_buf;
	SOCKET skt = sys->createSocket(SOCK_STREAM);
	sockaddr_in clientService; 
	clientService.sin_family = AF_INET;
	clientService.sin_addr.s_addr = inet_addr( ip);
	clientService.sin_port = htons( port);
	DWORD e ;
	if(connect(skt,(SOCKADDR*) &clientService,sizeof(clientService))==SOCKET_ERROR && GetLastError() == WSAEWOULDBLOCK)
	{		
		e=GetLastError();
		throw StreamException("wme_c::getHeader.connect ",e);
		//return NULL;
	}
	MemoryStream *stream  =new MemoryStream(1024);
	memset(stream->buf,0,1024);
	stream->write(HTTP_REQ_CMD, static_cast<int>( strlen(HTTP_REQ_CMD)  ));
	stream->write(HTTP_REQ_AGENT,static_cast<int>(strlen(HTTP_REQ_AGENT) ) );
	stream->write(HTTP_REQ_PRAGMA,static_cast<int>(strlen(HTTP_REQ_PRAGMA))  );
	stream->writeChar('\r');
	stream->writeChar('\n');

	if(send(skt,stream->buf,static_cast<int>(strlen(stream->buf)),0)==SOCKET_ERROR)
	{
		e = GetLastError();
		throw StreamException("wme_c::getHeader.send ",e);
		//return NULL;
	}
	delete stream;
	 //处理接收
	char buf[8192];
	char *lpRet = NULL;//= new char;
	int iGet= 0,iPos = 0;
	WORD len = 0;
	while(true) //读取数据到尾
	{
		int l =0;
		if( (l = recv(skt,buf+iGet,sizeof(buf) - iGet,0)) == SOCKET_ERROR)
		{
			e = GetLastError();
			throw StreamException("wme_c::getHeader.recv ",e);
		}
		if( 0 == l)
		{
			//throw StreamException("wme_c::getHeader.socetclosed ");
			break;
		}
		iGet +=l ;
	}
		
	if(strstr(buf,"OK") !=NULL) // get ok
	{
		char* pLoc = strstr(buf,"\r\n\r\n");
		pLoc +=4;//移动到\r\n\r\n后边,进入实际的包体

		if( 0x24 == pLoc[0]  && 0x48 == pLoc[1]) //header
		{
			
			pLoc += 2;
			memcpy(&len,pLoc,2);
			len -= 8;
			//&len  pLoc[2] < 8 & pLoc[3]; //get length
			lpRet = new char[len];
			pLoc += 10 ;
			memcpy(lpRet,pLoc,len);

			

			//设置Segment::setSegmentSize;
			//memcpy(&dwPacketSize,pLoc + HDR_ASF_PACKET_SIZE,4);
			//memcpy(&dwBitRate,pLoc + HDR_ASF_BITRATE,4);
			asfHeader *objHeader = new asfHeader(pLoc,len);
			dwPacketSize = objHeader->getChunkSize();
			dwBitRate = objHeader->getBitRate();
			delete objHeader;
			int size = ( dwBitRate /8 /dwPacketSize)*dwPacketSize;//(349056 /8 /0x5a4) * 0x5a4;
			Segment::setSegmentSize( size);//试验用 1.06M
			
			lpBuf->m_Header.lpData = lpRet;
			lpBuf->m_Header.len = len;
			lpBuf->Init(0);
		}
		
		
	}
	else
	{
		//error
		return NULL;
	}
		
	
	closesocket(skt);

	return lpRet;
}
示例#22
0
//-------------------------------------------------------------------------------------
PyObject* ClientEntityMethod::callmethod(PyObject* args, PyObject* kwds)
{
	Entity* srcEntity = Cellapp::getSingleton().findEntity(srcEntityID_);

	if(srcEntity == NULL)
	{
		PyErr_Format(PyExc_AssertionError, "Entity::clientEntity(%s): srcEntityID(%d) not found!\n",		
			methodDescription_->getName(), srcEntityID_);		
		PyErr_PrintEx(0);
		return 0;
	}

	if(srcEntity->isDestroyed())
	{
		PyErr_Format(PyExc_AssertionError, "Entity::clientEntity(%s): srcEntityID(%d) is destroyed!\n",		
			methodDescription_->getName(), srcEntityID_);		
		PyErr_PrintEx(0);
		return 0;
	}

	if(srcEntity->pWitness() == NULL)
	{
		PyErr_Format(PyExc_AssertionError, "%s::clientEntity(%s): no client, srcEntityID(%d).\n",		
			srcEntity->getScriptName(), methodDescription_->getName(), srcEntity->getID());		
		PyErr_PrintEx(0);
		return 0;
	}

	EntityRef::AOI_ENTITIES::iterator iter = srcEntity->pWitness()->aoiEntities().begin();
	Entity* e = NULL;

	for(; iter != srcEntity->pWitness()->aoiEntities().end(); iter++)
	{
		if((*iter)->id() == clientEntityID_ && ((*iter)->flags() & ENTITYREF_FLAG_ENTER_CLIENT_PENDING) <= 0)
		{
			e = (*iter)->pEntity();
			break;
		}
	}

	if(e == NULL)
	{
		PyErr_Format(PyExc_AssertionError, "%s::clientEntity(%s): not found entity(%d), srcEntityID(%d).\n",		
			srcEntity->getScriptName(), methodDescription_->getName(), clientEntityID_, srcEntity->getID());		
		PyErr_PrintEx(0);
		return 0;
	}

	MethodDescription* methodDescription = getDescription();
	if(methodDescription->checkArgs(args))
	{
		MemoryStream* mstream = MemoryStream::ObjPool().createObject();
		methodDescription->addToStream(mstream, args);

		Mercury::Bundle* pForwardBundle = Mercury::Bundle::ObjPool().createObject();
		Mercury::Bundle* pSendBundle = Mercury::Bundle::ObjPool().createObject();

		srcEntity->pWitness()->addSmartAOIEntityMessageToBundle(pForwardBundle, ClientInterface::onRemoteMethodCall, 
				ClientInterface::onRemoteOtherEntityMethodCall, clientEntityID_);

		if(mstream->wpos() > 0)
			(*pForwardBundle).append(mstream->data(), mstream->wpos());

		if(Mercury::g_trace_packet > 0)
		{
			if(Mercury::g_trace_packet_use_logfile)
				DebugHelper::getSingleton().changeLogger("packetlogs");

			DEBUG_MSG(boost::format("ClientEntityMethod::callmethod: pushUpdateData: ClientInterface::onRemoteOtherEntityMethodCall(%1%::%2%)\n") % 
				srcEntity->getScriptName() % methodDescription->getName());
																								
			switch(Mercury::g_trace_packet)																	
			{																								
			case 1:																							
				mstream->hexlike();																			
				break;																						
			case 2:																							
				mstream->textlike();																			
				break;																						
			default:																						
				mstream->print_storage();																	
				break;																						
			};																								

			if(Mercury::g_trace_packet_use_logfile)	
				DebugHelper::getSingleton().changeLogger(COMPONENT_NAME_EX(g_componentType));																				
		}

		MERCURY_ENTITY_MESSAGE_FORWARD_CLIENT(srcEntity->getID(), (*pSendBundle), (*pForwardBundle));

		srcEntity->pWitness()->sendToClient(ClientInterface::onRemoteOtherEntityMethodCall, pSendBundle);

		// 记录这个事件产生的数据量大小
		g_publicClientEventHistoryStats.trackEvent(srcEntity->getScriptName(), 
			(std::string(e->getScriptName()) + "." + methodDescription->getName()), 
			pForwardBundle->currMsgLength(), 
			"::");

		MemoryStream::ObjPool().reclaimObject(mstream);
		Mercury::Bundle::ObjPool().reclaimObject(pForwardBundle);
	}

	S_Return;
}
示例#23
0
//-------------------------------------------------------------------------------------
void Baseapp::onCreateBaseAnywhere(Mercury::Channel* pChannel, MemoryStream& s)
{
	if(pChannel->isExternal())
		return;

	std::string strInitData = "";
	uint32 initDataLength = 0;
	PyObject* params = NULL;
	std::string entityType;
	COMPONENT_ID componentID;
	CALLBACK_ID callbackID;

	s >> entityType;
	s >> initDataLength;

	if(initDataLength > 0)
	{
		strInitData.assign((char*)(s.data() + s.rpos()), initDataLength);
		s.read_skip(initDataLength);
	}

	s >> componentID;
	s >> callbackID;

	if(strInitData.size() > 0)
		params = script::Pickler::unpickle(strInitData);

	Base* base = createEntityCommon(entityType.c_str(), params);
	Py_XDECREF(params);

	if(base == NULL)
		return;

	// 如果不是在发起创建entity的baseapp上创建则需要转发回调到发起方
	if(componentID != componentID_)
	{
		Components::ComponentInfos* cinfos = Components::getSingleton().findComponent(componentID);
		if(cinfos == NULL || cinfos->pChannel == NULL)
		{
			ForwardItem* pFI = new ForwardItem();
			pFI->pHandler = NULL;
			pFI->bundle.newMessage(BaseappInterface::onCreateBaseAnywhereCallback);
			pFI->bundle << callbackID;
			pFI->bundle << entityType;
			pFI->bundle << base->getID();
			pFI->bundle << componentID_;
			forward_messagebuffer_.push(componentID, pFI);
			WARNING_MSG("Baseapp::onCreateBaseAnywhere: not found baseapp, message is buffered.\n");
			return;
		}

		Mercury::Channel* lpChannel = cinfos->pChannel;

		// 需要baseappmgr转发给目的baseapp
		Mercury::Bundle forwardbundle;
		forwardbundle.newMessage(BaseappInterface::onCreateBaseAnywhereCallback);
		forwardbundle << callbackID;
		forwardbundle << entityType;
		forwardbundle << base->getID();
		forwardbundle << componentID_;
		forwardbundle.send(this->getNetworkInterface(), lpChannel);
	}
	else
	{
		ENTITY_ID eid = base->getID();
		_onCreateBaseAnywhereCallback(NULL, callbackID, entityType, eid, componentID_);
	}
}
示例#24
0
//-------------------------------------------------------------------------------------
PyObject* ClientEntityMethod::callmethod(PyObject* args, PyObject* kwds)
{
	Entity* srcEntity = Cellapp::getSingleton().findEntity(srcEntityID_);

	if(srcEntity == NULL)
	{
		PyErr_Format(PyExc_AssertionError, "Entity::clientEntity(%s): srcEntityID(%d) not found!\n",
			methodDescription_->getName(), srcEntityID_);		
		PyErr_PrintEx(0);
		return 0;
	}

	if(srcEntity->isDestroyed())
	{
		PyErr_Format(PyExc_AssertionError, "Entity::clientEntity(%s): srcEntityID(%d) is destroyed!\n",
			methodDescription_->getName(), srcEntityID_);
		PyErr_PrintEx(0);
		return 0;
	}

	if(!srcEntity->isReal())
	{
		PyErr_Format(PyExc_AssertionError, "%s::clientEntity(%s): not is real entity, srcEntityID(%d).\n",
			srcEntity->scriptName(), methodDescription_->getName(), srcEntity->id());		
		PyErr_PrintEx(0);
		return 0;
	}
	
	if(srcEntity->pWitness() == NULL)
	{
		PyErr_Format(PyExc_AssertionError, "%s::clientEntity(%s): no client, srcEntityID(%d).\n",
			srcEntity->scriptName(), methodDescription_->getName(), srcEntity->id());		
		PyErr_PrintEx(0);
		return 0;
	}

	Network::Channel* pChannel = srcEntity->pWitness()->pChannel();
	if(!pChannel)
	{
		PyErr_Format(PyExc_AssertionError, "%s::clientEntity(%s): no client, srcEntityID(%d).\n",
			srcEntity->scriptName(), methodDescription_->getName(), srcEntity->id());		
		PyErr_PrintEx(0);
		return 0;
	}
			
	EntityRef* pEntityRef = srcEntity->pWitness()->getAOIEntityRef(clientEntityID_);
	Entity* e = (pEntityRef && ((pEntityRef->flags() & (ENTITYREF_FLAG_ENTER_CLIENT_PENDING | ENTITYREF_FLAG_LEAVE_CLIENT_PENDING)) <= 0))
		? pEntityRef->pEntity() : NULL;

	if(e == NULL)
	{
		PyErr_Format(PyExc_AssertionError, "%s::clientEntity(%s): not found entity(%d), srcEntityID(%d).\n",
			srcEntity->scriptName(), methodDescription_->getName(), clientEntityID_, srcEntity->id());	

		PyErr_PrintEx(0);

		return 0;
	}

	MethodDescription* methodDescription = getDescription();
	if(methodDescription->checkArgs(args))
	{
		MemoryStream* mstream = MemoryStream::createPoolObject();
		methodDescription->addToStream(mstream, args);
		
		Network::Bundle* pSendBundle = pChannel->createSendBundle();
		NETWORK_ENTITY_MESSAGE_FORWARD_CLIENT_START(srcEntity->id(), (*pSendBundle));

		int ialiasID = -1;
		const Network::MessageHandler& msgHandler = 
				srcEntity->pWitness()->getAOIEntityMessageHandler(ClientInterface::onRemoteMethodCall, 
				ClientInterface::onRemoteMethodCallOptimized, clientEntityID_, ialiasID);

		ENTITY_MESSAGE_FORWARD_CLIENT_START(pSendBundle, msgHandler, aOIEntityMessage);

		if(ialiasID != -1)
		{
			KBE_ASSERT(msgHandler.msgID == ClientInterface::onRemoteMethodCallOptimized.msgID);
			(*pSendBundle)  << (uint8)ialiasID;
		}
		else
		{
			KBE_ASSERT(msgHandler.msgID == ClientInterface::onRemoteMethodCall.msgID);
			(*pSendBundle)  << clientEntityID_;
		}
			
		if(mstream->wpos() > 0)
			(*pSendBundle).append(mstream->data(), (int)mstream->wpos());

		if(Network::g_trace_packet > 0)
		{
			if(Network::g_trace_packet_use_logfile)
				DebugHelper::getSingleton().changeLogger("packetlogs");

			DEBUG_MSG(fmt::format("ClientEntityMethod::callmethod: pushUpdateData: ClientInterface::onRemoteOtherEntityMethodCall({}::{})\n",
				srcEntity->scriptName(), methodDescription->getName()));

			switch(Network::g_trace_packet)
			{
			case 1:
				mstream->hexlike();
				break;
			case 2:
				mstream->textlike();
				break;
			default:
				mstream->print_storage();
				break;
			};

			if(Network::g_trace_packet_use_logfile)
				DebugHelper::getSingleton().changeLogger(COMPONENT_NAME_EX(g_componentType));																				
		}

		ENTITY_MESSAGE_FORWARD_CLIENT_END(pSendBundle, msgHandler, aOIEntityMessage);

		// 记录这个事件产生的数据量大小
		g_publicClientEventHistoryStats.trackEvent(srcEntity->scriptName(), 
			(std::string(e->scriptName()) + "." + methodDescription->getName()), 
			pSendBundle->currMsgLength(), 
			"::");
		
		srcEntity->pWitness()->sendToClient(ClientInterface::onRemoteMethodCallOptimized, pSendBundle);

		MemoryStream::reclaimPoolObject(mstream);
	}

	S_Return;
}
示例#25
0
/*!
  Send a file to the client using the HTTP protocol.
  \param td The current HTTP thread context.
  \param filenamePath The path of the static file to send.
  \param exec Not used.
  \param execute Not used.
  \param onlyHeader Specify if send only the HTTP header.
  */
int HttpFile::send (HttpThreadContext* td, const char *filenamePath,
                    const char* exec, bool execute, bool onlyHeader)
{
  /*
    With this routine we send a file through the HTTP protocol.
    Open the file and save its handle.
   */
  off_t filesize = 0;
  File *file = NULL;
  size_t bytesToSend;
  off_t firstByte = td->request.rangeByteBegin;
  off_t lastByte = td->request.rangeByteEnd;
  bool keepalive = false;
  bool useChunks = false;
  bool useModifiers = false;
  MemoryStream memStream (td->auxiliaryBuffer);
  FiltersChain chain;
  size_t nbw;
  size_t nbr;
  time_t lastMT;
  string tmpTime;
  u_long dataSent = 0;

  try
    {

      if (! td->request.cmd.compare ("PUT"))
        return putFile (td, td->filenamePath);

      if (! td->request.cmd.compare ("DELETE"))
        return deleteFile (td, td->filenamePath);

      if (! (td->permissions & MYSERVER_PERMISSION_READ))
        return td->http->sendAuth ();

      if (! FilesUtility::nodeExists (filenamePath))
        return td->http->raiseHTTPError (404);

      lastMT = FilesUtility::getLastModTime (td->filenamePath.c_str ());

      if (lastMT == -1)
        return td->http->raiseHTTPError (500);

      getRFC822GMTTime (lastMT, tmpTime, 32);
      td->response.setValue ("last-modified", tmpTime.c_str ());

      HttpRequestHeader::Entry *ifModifiedSince =
        td->request.other.get ("last-modified");

      if (ifModifiedSince && ifModifiedSince->value.length () &&
          !ifModifiedSince->value.compare (tmpTime))
        return td->http->sendHTTPNonModified ();

      try
        {
          int symFlags = td->http->areSymlinksAllowed () ? 0
            : File::NO_FOLLOW_SYMLINK;
          file = Server::getInstance ()->getCachedFiles ()->open (filenamePath,
                                                                  symFlags);
          if (! file)
            return td->http->raiseHTTPError (500);
        }
      catch (exception & e)
        {
          td->connection->host->warningsLogWrite
            (_E ("HttpFile: error accessing file %s"),
             td->filenamePath.c_str (), &e);
          return td->http->raiseHTTPError (500);
        }

    /*
      Check how many bytes are ready to be send.
     */
    filesize = file->getFileSize ();

    string etag;
    generateEtag (etag, lastMT, filesize);

    HttpRequestHeader::Entry *etagHeader = td->request.other.get ("etag");
    if (etagHeader && !etagHeader->value.compare (etag))
      return td->http->sendHTTPNonModified ();
    else
      {
        HttpResponseHeader::Entry *e = td->response.other.get ("etag");
        if (e)
          e->value.assign (etag);
        else
          {
            e = new HttpResponseHeader::Entry ();
            e->name.assign ("etag");
            e->value.assign (etag);
            td->response.other.put (e->name, e);
          }
      }

    if (lastByte == 0)
      lastByte = filesize;
    else
      lastByte = std::min (lastByte + 1, filesize);

    bytesToSend = lastByte - firstByte;

    keepalive = td->request.isKeepAlive ();

    td->buffer->setLength (0);

    /* If a Range was requested send 206 and not 200 for success.  */
    if (td->request.rangeByteBegin || td->request.rangeByteEnd)
      {
        HttpResponseHeader::Entry *e;
        ostringstream buffer;
        td->response.httpStatus = 206;
        buffer << "bytes "<< (u_long) firstByte << "-"
               << (u_long) (lastByte - 1) << "/" << (u_long) filesize;

        e = td->response.other.get ("content-range");
        if (e)
          e->value.assign (buffer.str ());
        else
          {
            e = new HttpResponseHeader::Entry ();
            e->name.assign ("content-range");
            e->value.assign (buffer.str ());
            td->response.other.put (e->name, e);
          }
      }
    chain.setStream (&memStream);
    if (td->mime)
      {
        HttpRequestHeader::Entry* e = td->request.other.get ("accept-encoding");
        if (td->mime)
          Server::getInstance ()->getFiltersFactory ()->chain (&chain,
                                                               td->mime->filters,
                                                               &memStream,
                                                               &nbw, 0,
                                                               e ? &e->value : NULL);
        memStream.refresh ();
        dataSent += nbw;
      }

    useModifiers = chain.hasModifiersFilters ();
    if (!useModifiers)
      {
        ostringstream buffer;
        buffer << bytesToSend;
        td->response.contentLength.assign (buffer.str ());
      }

    if (keepalive)
      td->response.setValue ("connection", "keep-alive");
    else
      td->response.setValue ("connection", "close");

    if (useModifiers)
      {
        string s;
        HttpResponseHeader::Entry *e;
        chain.getName (s);
        e = td->response.other.get ("content-encoding");

        if (e)
          e->value.assign (s);
        else
          {
            e = new HttpResponseHeader::Entry ();
            e->name.assign ("content-encoding");
            e->value.assign (s);
            td->response.other.put (e->name, e);
          }
        /* Do not use chunked transfer with old HTTP/1.0 clients.  */
        if (keepalive)
          useChunks = true;
      }

    if (useChunks)
      {
        HttpResponseHeader::Entry *e;
        e = td->response.other.get ("transfer-encoding");
        if (e)
          e->value.assign ("chunked");
        else
          {
            e = new HttpResponseHeader::Entry ();
            e->name.assign ("transfer-encoding");
            e->value.assign ("chunked");
            td->response.other.put (e->name, e);
          }
      }
    else
      {	HttpResponseHeader::Entry *e;
        e = td->response.other.remove ("transfer-encoding");
        if (e)
          delete e;
      }

    HttpHeaders::sendHeader (td->response, *td->connection->socket,
                             *td->buffer, td);

    /*
      If is requested only the header exit from the function;
      used by the HEAD request.
    */
    if (onlyHeader)
      {
        file->close ();
        delete file;
        chain.clearAllFilters ();
        return HttpDataHandler::RET_OK;
      }

    /*
      Check if there are all the conditions to use a direct copy from the
      file to the socket.
    */
    if (!useChunks && chain.isEmpty () && !td->appendOutputs
        && !(td->http->getProtocolOptions () & Protocol::SSL))
      {
        size_t nbw = 0;
        file->fastCopyToSocket (td->connection->socket, firstByte,
                                td->buffer, &nbw);

        file->close ();
        delete file;

        chain.clearAllFilters ();

        td->sentData += nbw;

        return HttpDataHandler::RET_OK;
      }

    file->seek (firstByte);

    if (td->appendOutputs)
      chain.setStream (&(td->outputData));
    else
      chain.setStream (td->connection->socket);

    /*
      Flush initial data.  This is data that filters could have added
      and we have to send before the file itself, for example the gzip
      filter add a header to file.
    */
    if (memStream.availableToRead ())
      {
        memStream.read (td->buffer->getBuffer (),
                        td->buffer->getRealLength (), &nbr);

        memStream.refresh ();
        if (nbr)
          HttpDataHandler::appendDataToHTTPChannel (td,
                                                    td->buffer->getBuffer (),
                                                    nbr, &(td->outputData),
                                                    &chain, td->appendOutputs,
                                                    useChunks);
      } /* memStream.availableToRead ().  */

    /* Flush the rest of the file.  */
    for (;;)
      {
        size_t nbr;
        size_t nbw;

        /* Check if there are other bytes to send.  */
        if (bytesToSend)
          {
            /* Read from the file the bytes to send.  */
            size_t size = std::min (bytesToSend,
                                    td->buffer->getRealLength () / 2);

            file->read (td->buffer->getBuffer (), size, &nbr);
            if (nbr == 0)
              {
                bytesToSend = 0;
                continue;
              }

            bytesToSend -= nbr;

            appendDataToHTTPChannel (td, td->buffer->getBuffer (),
                           nbr, &(td->outputData), &chain, td->appendOutputs,
                               useChunks, td->buffer->getRealLength (), &memStream);
            dataSent += nbr;
          }
        else /* if (bytesToSend) */
          {
            /* If we don't use chunks we can flush directly.  */
            if (!useChunks)
              {
                chain.flush (&nbw);
                break;
              }
            else
              {
                /*
                  Replace the final stream before the flush and write to a
                  memory buffer, after all the data is flushed from the
                  chain we can replace the stream with the original one and
                  write there the HTTP data chunk.
                */
                Stream* tmpStream = chain.getStream ();
                chain.setStream (&memStream);
                memStream.refresh ();
                chain.flush (&nbw);

                chain.setStream (tmpStream);
                memStream.read (td->buffer->getBuffer (),
                                td->buffer->getRealLength (), &nbr);

                HttpDataHandler::appendDataToHTTPChannel (td,
                                                       td->buffer->getBuffer (),
                                                       nbr, &(td->outputData),
                                                       &chain, td->appendOutputs,
                                                          useChunks);
                break;
              }
          }
        memStream.refresh ();
      }/* End for loop.  */

    file->close ();
    delete file;
  }
  catch (exception & e)
    {
      if (file)
        {
          file->close ();
          delete file;
        }
      chain.clearAllFilters ();
      td->connection->host->warningsLogWrite (_E ("HttpFile: internal error"),
                                              &e);
      return td->http->raiseHTTPError (500);
    }

  /* For logging activity.  */
  td->sentData += dataSent;
  chain.clearAllFilters ();

  return HttpDataHandler::RET_OK;
}
示例#26
0
bool DmoPlayer::load(const std::string& filename)
{
    FileStream f(filename);
    if(!f || f.extension() != ".dmo")
        return false;

    unsigned char chkhdr[16];
    f.read(chkhdr, 16);

    DMOUnpacker unpacker;
    if(!unpacker.decrypt(chkhdr, 16))
    {
        return false;
    }

    f.seek(0);

    std::vector<uint8_t> packed_module(f.size());

    // load file
    f.read(packed_module.data(), f.size());

    // decrypt
    unpacker.decrypt(packed_module.data(), packed_module.size());

    const auto unpacked_length = 0x2000 * ARRAY_AS_WORD(packed_module.data(), 12);
    std::vector<uint8_t> module(unpacked_length);

    // unpack
    if(!unpacker.unpack(packed_module.data() + 12, module.data(), unpacked_length))
    {
        return false;
    }

    // "TwinTeam" - signed ?
    if(memcmp(module.data(), "TwinTeam Module File"
              "\x0D\x0A",
              22))
    {
        return false;
    }

    // load header
    MemoryStream uf;
    uf.write(module.data(), module.size());
    uf.seek(0);

    S3mHeader header;

    uf.seekrel(22); // ignore DMO header ID string
    uf.read(header.name, 28);

    uf.seekrel(2); // _unk_1
    uf >> header.orderCount >> header.instrumentCount >> header.patternCount;
    uf.seekrel(2); // _unk_2
    uf >> header.initialSpeed >> header.initialTempo;

    header.chanset.fill(0xff);

    for(int i = 0; i < 9; i++)
        header.chanset[i] = 0x10 + i;

    uf.seekrel(32); // ignore panning settings for all 32 channels

    // load orders
    for(int i = 0; i < header.orderCount; ++i)
    {
        uint8_t tmp;
        uf >> tmp;
        addOrder(tmp);
        std::cerr << "ORD=" << int(tmp) << "\n";
    }
    addOrder(0xff);
    uf.seekrel(256 - header.orderCount);

    // load pattern lengths
    uint16_t my_patlen[100];
    uf.read(my_patlen, 100);

    // load instruments
    for(int i = 0; i < header.instrumentCount; i++)
    {
        S3mInstrument instrument;

        uf.read(instrument.name, 28);

        uf >> instrument.volume;
        uf >> instrument.dsk;
        uf >> instrument.c2spd;
        uf >> instrument.type;
        uf >> instrument.d00;
        uf >> instrument.d01;
        uf >> instrument.d02;
        uf >> instrument.d03;
        uf >> instrument.d04;
        uf >> instrument.d05;
        uf >> instrument.d06;
        uf >> instrument.d07;
        uf >> instrument.d08;
        uf >> instrument.d09;
        uf >> instrument.d0a;
        /*
         * Originally, riven sets d0b = d0a and ignores 1 byte in the
         * stream, but i guess this was a typo, so i read it here.
         */
        uf >> instrument.d0b;

        setInstrument(i, instrument);
    }

    // load patterns
    for(int pattern = 0; pattern < header.patternCount; pattern++)
    {
        const auto cur_pos = uf.pos();

        for(int row = 0; row < 64; row++)
        {
            S3mCell* currentChannel = patternChannel(pattern, row);

            while(true)
            {
                uint8_t token;
                uf >> token;

                if(!token)
                    break;

                const auto chan = token & 31;

                // note + instrument ?
                if(token & 32)
                {
                    uint8_t bufbyte;
                    uf >> bufbyte;

                    currentChannel[chan].note = bufbyte & 15;
                    currentChannel[chan].octave = bufbyte >> 4;
                    uf >> currentChannel[chan].instrument;
                }

                // volume ?
                if(token & 64)
                    uf >> currentChannel[chan].volume;

                // command ?
                if(token & 128)
                {
                    uf >> currentChannel[chan].effect;
                    uf >> currentChannel[chan].effectValue;
                }
            }
        }