std::string str() const
	{
		return buffer.str();
	}
Beispiel #2
0
Exec::Variable Exec::eval(const String &value) {
	CharReaderBase r(value);
	if (r.is('$')) {
		++ r;
		return getVariable(r);
	} else if (r.is<Group<GroupId::Numbers>>()) {
		auto tmp = r;
		r.skipUntil<Chars<'e', 'E', '.'>>();
		if (!r.empty()) {
			return Variable{new data::Value(tmp.readFloat())};
		} else {
			return Variable{new data::Value(tmp.readInteger())};
		}
	} else if (r.is('\'')) {
		++ r;
		StringStream str;
		while (!r.empty() && !r.is('\'')) {
			str << r.readUntil<Chars<'\'', '\\'>>();
			if (r.is('\\')) {
				++ r;
				if (r.is('r')) {
					str << "\r";
				} else if (r.is('n')) {
					str << "\n";
				} else if (r.is('t')) {
					str << "\t";
				} else {
					str << r.front();
				}
				++ r;
			}
		}
		return Variable{new data::Value(str.str())};
	} else if (r.is('"')) {
		++ r;
		StringStream str;
		while (!r.empty() && !r.is('"')) {
			str << r.readUntil<Chars<'"', '\\'>>();
			if (r.is('\\')) {
				++ r;
				if (r.is('r')) {
					str << "\r";
				} else if (r.is('n')) {
					str << "\n";
				} else if (r.is('t')) {
					str << "\t";
				} else {
					str << r.front();
				}
				++ r;
			}
		}
		return Variable{new data::Value(str.str())};
	} else {
		if (r.is("true")) {
			return Variable{new data::Value(true)};
		} else if (r.is("false")) {
			return Variable{new data::Value(false)};
		} else if (r.is("null")) {
			return Variable{new data::Value()};
		} else if (r.is("inf")) {
			return Variable{new data::Value(std::numeric_limits<double>::infinity())};
		} else if (r.is("nan")) {
			return Variable{new data::Value(nan())};
		}
	}
	return Variable();
}
    void GLFrameBufferObject::initialise()
    {
		// Release depth and stencil, if they were bound
        mManager->releaseRenderBuffer(mDepth);
        mManager->releaseRenderBuffer(mStencil);
		mManager->releaseRenderBuffer(mMultisampleColourBuffer);
        /// First buffer must be bound
        if(!mColour[0].buffer)
        {
            OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, 
            "Attachment 0 must have surface attached",
		 	"GLFrameBufferObject::initialise");
        }

		// If we're doing multisampling, then we need another FBO which contains a
		// renderbuffer which is set up to multisample, and we'll blit it to the final 
		// FBO afterwards to perform the multisample resolve. In that case, the 
		// mMultisampleFB is bound during rendering and is the one with a depth/stencil

        /// Store basic stats
        size_t width = mColour[0].buffer->getWidth();
        size_t height = mColour[0].buffer->getHeight();
        GLuint format = mColour[0].buffer->getGLFormat();
        PixelFormat ogreFormat = mColour[0].buffer->getFormat();

		// Bind simple buffer to add colour attachments
		glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFB);

        /// Bind all attachment points to frame buffer
        for(size_t x=0; x<OGRE_MAX_MULTIPLE_RENDER_TARGETS; ++x)
        {
            if(mColour[x].buffer)
            {
                if(mColour[x].buffer->getWidth() != width || mColour[x].buffer->getHeight() != height)
                {
                    StringStream ss;
                    ss << "Attachment " << x << " has incompatible size ";
                    ss << mColour[x].buffer->getWidth() << "x" << mColour[x].buffer->getHeight();
                    ss << ". It must be of the same as the size of surface 0, ";
                    ss << width << "x" << height;
                    ss << ".";
                    OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, ss.str(), "GLFrameBufferObject::initialise");
                }
                if(mColour[x].buffer->getGLFormat() != format)
                {
                    StringStream ss;
                    ss << "Attachment " << x << " has incompatible format.";
                    OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, ss.str(), "GLFrameBufferObject::initialise");
                }
	            mColour[x].buffer->bindToFramebuffer(GL_COLOR_ATTACHMENT0_EXT+x, mColour[x].zoffset);
            }
            else
            {
                // Detach
                glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT+x,
                    GL_RENDERBUFFER_EXT, 0);
            }
        }

		// Now deal with depth / stencil
		if (mMultisampleFB)
		{
			// Bind multisample buffer
			glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mMultisampleFB);

			// Create AA render buffer (colour)
			// note, this can be shared too because we blit it to the final FBO
			// right after the render is finished
			mMultisampleColourBuffer = mManager->requestRenderBuffer(format, width, height, mNumSamples);

			// Attach it, because we won't be attaching below and non-multisample has
			// actually been attached to other FBO
			mMultisampleColourBuffer.buffer->bindToFramebuffer(GL_COLOR_ATTACHMENT0_EXT, 
				mMultisampleColourBuffer.zoffset);

			// depth & stencil will be dealt with below

		}

        /// Find suitable depth and stencil format that is compatible with colour format
        GLenum depthFormat, stencilFormat;
        mManager->getBestDepthStencil(ogreFormat, &depthFormat, &stencilFormat);
        
        /// Request surfaces
        mDepth = mManager->requestRenderBuffer(depthFormat, width, height, mNumSamples);
		if (depthFormat == GL_DEPTH24_STENCIL8_EXT)
		{
			// bind same buffer to depth and stencil attachments
            mManager->requestRenderBuffer(mDepth);
			mStencil = mDepth;
		}
		else
		{
			// separate stencil
			mStencil = mManager->requestRenderBuffer(stencilFormat, width, height, mNumSamples);
		}
        
        /// Attach/detach surfaces
        if(mDepth.buffer)
        {
            mDepth.buffer->bindToFramebuffer(GL_DEPTH_ATTACHMENT_EXT, mDepth.zoffset);
        }
        else
        {
            glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
                GL_RENDERBUFFER_EXT, 0);
        }
        if(mStencil.buffer)
        {
            mStencil.buffer->bindToFramebuffer(GL_STENCIL_ATTACHMENT_EXT, mStencil.zoffset);
        }
        else
        {
            glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT,
                GL_RENDERBUFFER_EXT, 0);
        }

		/// Do glDrawBuffer calls
		GLenum bufs[OGRE_MAX_MULTIPLE_RENDER_TARGETS];
		GLsizei n=0;
		for(size_t x=0; x<OGRE_MAX_MULTIPLE_RENDER_TARGETS; ++x)
		{
			// Fill attached colour buffers
			if(mColour[x].buffer)
			{
				bufs[x] = GL_COLOR_ATTACHMENT0_EXT + x;
				// Keep highest used buffer + 1
				n = x+1;
			}
			else
			{
				bufs[x] = GL_NONE;
			}
		}
		if(glDrawBuffers)
		{
			/// Drawbuffer extension supported, use it
			glDrawBuffers(n, bufs);
		}
		else
		{
			/// In this case, the capabilities will not show more than 1 simultaneaous render target.
			glDrawBuffer(bufs[0]);
		}
		if (mMultisampleFB)
		{
			// we need a read buffer because we'll be blitting to mFB
			glReadBuffer(bufs[0]);
		}
		else
		{
			/// No read buffer, by default, if we want to read anyway we must not forget to set this.
			glReadBuffer(GL_NONE);
		}
        
        /// Check status
        GLuint status;
        status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
        
        /// Bind main buffer
        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
        
        switch(status)
        {
        case GL_FRAMEBUFFER_COMPLETE_EXT:
            // All is good
            break;
        case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
            OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, 
            "All framebuffer formats with this texture internal format unsupported",
		 	"GLFrameBufferObject::initialise");
        default:
            OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, 
            "Framebuffer incomplete or other FBO status error",
		 	"GLFrameBufferObject::initialise");
        }
        
    }
//////////////////////////////////////////////////////////////////////////////
// 클라이언트에서 플레이어 등록 정보를 날릴 경우, 서버에서는 우선
// 현재 아이디가 "guest"인지 체크하고, 최초의 패킷인지 체크한 후,
// 사용자 정보를 DB에 등록하고나서, 연결을 차단한다.
//////////////////////////////////////////////////////////////////////////////
void CLRegisterPlayerHandler::execute (CLRegisterPlayer* pPacket , Player* pPlayer)
throw(ProtocolException , Error)
{
    __BEGIN_TRY __BEGIN_DEBUG_EX

#ifdef __LOGIN_SERVER__

    Assert(pPacket != NULL);
    Assert(pPlayer != NULL);

    __BEGIN_DEBUG

    LoginPlayer* pLoginPlayer = dynamic_cast<LoginPlayer*>(pPlayer);

    //cout << "Registering Player... " << endl;

    //----------------------------------------------------------------------
    // 로그인 플레이어의 아이디가 guest 인지 체크한다.
    //----------------------------------------------------------------------
//	if (pLoginPlayer->getID() != "guest")
//		throw InvalidProtocolException("must be guest user");

    //----------------------------------------------------------------------
    // 플레이어 정보 검증
    // 각 스트링의 길이 및 NULL 여부를 체크한다.
    //----------------------------------------------------------------------
    LCRegisterPlayerError lcRegisterPlayerError;

    try {

        //cout << "플레이어 정보 검증 : " << pPacket->toString() << endl;

        if (pPacket->getID() == "") {
            lcRegisterPlayerError.setErrorID(EMPTY_ID);
            throw string("ID field is empty");
        }

        if (pPacket->getID().size() < 4) {
            lcRegisterPlayerError.setErrorID(SMALL_ID_LENGTH);
            throw string("too small ID length");
        }

        if (pPacket->getPassword() == "")
        {
            lcRegisterPlayerError.setErrorID(EMPTY_PASSWORD);
            throw string("Password field is empty");
        }
        else
        {
            string password = pPacket->getPassword();
            if (password.find("\'") < password.size()) throw string("Invalid Password");
            if (password.find("'") < password.size()) throw string("Invalid Password");
            else if (password.find("\\") < password.size()) throw string("Invalid Password");
            else if (password.find("\"") < password.size()) throw string("Invalid Password");
            else if (password.find(";") < password.size()) throw string("Invalid Password");
        }

        if (pPacket->getPassword().size() < 6) {
            lcRegisterPlayerError.setErrorID(SMALL_PASSWORD_LENGTH);
            throw string("too small password length");
        }

        if (pPacket->getName() == "") {
            lcRegisterPlayerError.setErrorID(EMPTY_NAME);
            throw string("Name field is empty");
        }

        if (pPacket->getSSN() == "") {
            lcRegisterPlayerError.setErrorID(EMPTY_SSN);
            throw string("SSN field is empty");
        }

    } catch (string & errstr) {

        pLoginPlayer->sendPacket(&lcRegisterPlayerError);

        //cout << lcRegisterPlayerError.toString() << endl;

        // 일단 버퍼를 플러시하고, 연결을 차단한다.
        //
        // *TODO*
        // 실패 회수를 저장한 후, 그 회수보다 작은 경우에는 계속 연결을 유지하도록 한다.
        //
        throw DisconnectException(lcRegisterPlayerError.toString());
    }


    //----------------------------------------------------------------------
    // 이제 데이타베이스에 등록하도록 한다.
    //----------------------------------------------------------------------

    Statement* pStmt;
    Result* pResult;

    try {

        pStmt = g_pDatabaseManager->getConnection("DARKEDEN")->createStatement();

        //--------------------------------------------------------------------------------
        // 아이디 중복 여부를 체크한다.
        //--------------------------------------------------------------------------------
        pResult = pStmt->executeQuery("SELECT PlayerID FROM Player WHERE PlayerID = '%s'" , pPacket->getID().c_str());

        if (pResult->getRowCount() != 0) {
            lcRegisterPlayerError.setErrorID(ALREADY_REGISTER_ID);
            throw DuplicatedException("그런 아이디가 이미 존재합니다.");
        }


        //--------------------------------------------------------------------------------
        // 주민등록번호를 검증한다. 나중에.. -_-;
        //--------------------------------------------------------------------------------


        //--------------------------------------------------------------------------------
        // 주민등록번호 중복 여부를 체크한다.
        //--------------------------------------------------------------------------------
        pResult = pStmt->executeQuery("SELECT SSN FROM Player WHERE SSN = '%s'" , pPacket->getSSN().c_str());

        if (pResult->getRowCount() != 0) {
            lcRegisterPlayerError.setErrorID(ALREADY_REGISTER_SSN);
            throw DuplicatedException("이미 등록된 주민등록번호입니다.");
        }


        //--------------------------------------------------------------------------------
        // 플레이어를 등록한다.
        //--------------------------------------------------------------------------------
        pResult = pStmt->executeQuery(
                      "INSERT INTO Player (PlayerID , Password , Name , Sex , SSN , Telephone , Cellular , Zipcode , Address , Nation , Email , Homepage , Profile , Pub) VALUES ('%s' , PASSWORD('%s') , '%s' , '%s' , '%s' , '%s' , '%s' , '%s' , '%s' , %d , '%s' , '%s' , '%s' , '%s')" ,
                      pPacket->getID().c_str() ,
                      pPacket->getPassword().c_str() ,
                      pPacket->getName().c_str() ,
                      Sex2String[ pPacket->getSex() ].c_str() ,
                      pPacket->getSSN().c_str() ,
                      pPacket->getTelephone().c_str() ,
                      pPacket->getCellular().c_str() ,
                      pPacket->getZipCode().c_str() ,
                      pPacket->getAddress().c_str() ,
                      (int)pPacket->getNation() ,
                      pPacket->getEmail().c_str() ,
                      pPacket->getHomepage().c_str() ,
                      pPacket->getProfile().c_str() ,
                      (pPacket->getPublic() == true) ? "PUBLIC" : "PRIVATE"
                  );

        // 여기까지 왔다면, DB에 플레이어가 잘 추가되었다는 의미가 된다.
        // 플레이어에게 등록이 잘 되었다는 LCRegisterPlayerOK 패킷을 보내자.
        Assert(pResult == NULL);
        Assert(pStmt->getAffectedRowCount() == 1);

        // 등록한 후 디폴트 서버의 그룹 아이디를 받아온다.
        pResult = pStmt->executeQuery("SELECT CurrentWorldID, CurrentServerGroupID FROM Player WHERE PlayerID = '%s'" , pPacket->getID().c_str());

        if (pResult->getRowCount() == 0) {
            lcRegisterPlayerError.setErrorID(ETC_ERROR);
            throw SQLQueryException("정상적으로 데이터베이스가 입력, 출력 되지 않았습니다.");
        }

        WorldID_t 		 WorldID = 0;
        ServerGroupID_t  ServerGroupID = 0;

        if (pResult->next()) throw SQLQueryException("데이터베이스에 치명적인 문제가 있습니다.");

        WorldID = pResult->getInt(1);
        ServerGroupID = pResult->getInt(2);

        pLoginPlayer->setServerGroupID(ServerGroupID);

        LCRegisterPlayerOK lcRegisterPlayerOK;

        lcRegisterPlayerOK.setGroupName(g_pGameServerGroupInfoManager->getGameServerGroupInfo(ServerGroupID, WorldID)->getGroupName());

        string SSN = pPacket->getSSN();
        string preSSN;
        bool isChina = false;
        // 한국
        if (strstr(SSN.c_str(), "-") != NULL )
        {
            preSSN = SSN.substr(0, 6);
        }
        // 중국
        else
        {
            isChina = true;
            if (SSN.size() == 15)
            {
                preSSN = SSN.substr(6, 12);
            }
            else if (SSN.size() == 18)
            {
                preSSN = SSN.substr(8, 14);
            }
            else
            {
                // 이런 경우는 없다고 하지만 -_- 머 암튼
                preSSN = SSN.substr(0, 6);
            }
        }
//        string preSSN = pPacket->getSSN().substr(0, 6).c_str();

        StringStream AdultSSN;

        time_t daytime = time(0);
        tm Timec;
        localtime_r(&daytime, &Timec);
        AdultSSN << Timec.tm_year - 20 << Timec.tm_mon << Timec.tm_mday;

        // 성인인지 아닌지 주민등록 번호 체크
        if (atoi(preSSN.c_str()) <= atoi(AdultSSN.toString().c_str())) {
            lcRegisterPlayerOK.setAdult(true);
        } else {
            lcRegisterPlayerOK.setAdult(false);
        }

        // 중국이면 무조건 성인
        if (isChina )
        {
            lcRegisterPlayerOK.setAdult(true);
        }

        pLoginPlayer->sendPacket(&lcRegisterPlayerOK);

        // 이름을 변경해줘야 한다.
        pLoginPlayer->setID(pPacket->getID());

        // 등록에 성공했을 경우, CLGetPCList 패킷을 기다린다.
        pLoginPlayer->setPlayerStatus(LPS_WAITING_FOR_CL_GET_PC_LIST);

        SAFE_DELETE(pStmt);
    }
    catch (DuplicatedException & de)
    {
        SAFE_DELETE(pStmt);

        //cout << de.toString() << endl;

        //--------------------------------------------------------------------------------
        // 등록 실패 패킷을 전송한다.
        //--------------------------------------------------------------------------------
        pLoginPlayer->sendPacket(&lcRegisterPlayerError);

        //--------------------------------------------------------------------------------
        // 실패 회수를 증가시킨다. 너무 많이 실패했을 경우, 연결을 종료한다.
        //--------------------------------------------------------------------------------
        uint nFailed = pLoginPlayer->getFailureCount();

        //cout << pLoginPlayer->getID() << "'s Failure Count = " << ++nFailed << endl;

        if (nFailed > 3)
            throw DisconnectException("too many failure");

        pLoginPlayer->setFailureCount(nFailed);

        // 등록에 실패할 경우, 다시 CLRegisterPlayer 패킷을 기다린다.
        pLoginPlayer->setPlayerStatus(LPS_WAITING_FOR_CL_REGISTER_PLAYER);

    }
    catch (SQLQueryException & sqe)
    {
        SAFE_DELETE(pStmt);

        // 흠. SQL 에러이든지 등록이 잘 안되었다는 소리다.
        //cout << sqe.toString() << endl;

        //--------------------------------------------------------------------------------
        // 등록 실패 패킷을 전송한다.
        //--------------------------------------------------------------------------------
        lcRegisterPlayerError.setErrorID(ETC_ERROR);

        pLoginPlayer->sendPacket(&lcRegisterPlayerError);

        //--------------------------------------------------------------------------------
        // 실패 회수를 증가시킨다. 너무 많이 실패했을 경우, 연결을 종료한다.
        //--------------------------------------------------------------------------------
        uint nFailed = pLoginPlayer->getFailureCount();

        //cout << pLoginPlayer->getID() << "'s Failure Count = " << ++nFailed << endl;

        if (nFailed > 3)
            throw DisconnectException("too many failure");

        pLoginPlayer->setFailureCount(nFailed);

        // 등록에 실패할 경우, 다시 CLRegisterPlayer 패킷을 기다린다.
        pLoginPlayer->setPlayerStatus(LPS_WAITING_FOR_CL_REGISTER_PLAYER);

    }

    __END_DEBUG

#endif

    __END_DEBUG_EX __END_CATCH
}
Beispiel #5
0
void EventMorph::activate () 
	throw(Error)
{
	__BEGIN_TRY
	__BEGIN_DEBUG

	Assert(m_pGamePlayer != NULL);

	Creature* pFromCreature = m_pGamePlayer->getCreature();
	Assert(pFromCreature->isSlayer());

	if (m_pGamePlayer->getPlayerStatus() != GPS_NORMAL)
	{
		// 플레이어의 상태가 WAITING_FOR_CG_READY인데, morph가 
		// activate되어 밑의 존에서 크리쳐를 지우는 부분에서 에러가 throw되어
		// 서버가 죽는 버그가 있었다. 정확히 어떻게 해서 CG_READY상태에서
		// 이벤트가 activate되는지는 모르겠으나, GamePlayer의 
		// EventManager 자체를 GPS_NORMAL일 때만 돌아가게 하면,
		// Resurrect가 되지 않으니 주의하길 바란다. 결국 GamePlayer 내부에서
		// 체크를 하기가 곤란하기 때문에 이 부분에서, 처리한다.
		StringStream msg;
		msg << "EventMorph::activate() : GamePlayer의 상태가 GPS_NORMAL이 아닙니다."
			<< "PlayerID[" << m_pGamePlayer->getID() << "]"
			<< "CreatureName[" << pFromCreature->getName() << "]";

		filelog("EventMorphError.log", "%s", msg.toString().c_str());
		return;
	}

	pFromCreature->removeFlag(Effect::EFFECT_CLASS_BLOOD_DRAIN);
	Zone* pZone = pFromCreature->getZone();

	// 만일 Restore 이펙트가 걸려있다면 변신이 되지 않는다.
	if (pFromCreature->isFlag(Effect::EFFECT_CLASS_RESTORE))
	{
		return;
	}

	dropRelicToZone(pFromCreature);
	dropFlagToZone(pFromCreature);
	dropSweeperToZone(pFromCreature);

	//////////////////////////////////////////////////////////////////////
	// 각종 존 레벨 정보를 삭제해야 한다.
	//////////////////////////////////////////////////////////////////////
	
	// 파티 초대 중이라면 정보를 삭제해 준다.
	PartyInviteInfoManager* pPIIM = pZone->getPartyInviteInfoManager();
	Assert(pPIIM != NULL);
	pPIIM->cancelInvite(pFromCreature);

	// 파티 관련 정보를 삭제해 준다.
	uint PartyID = pFromCreature->getPartyID();
	if (PartyID != 0)
	{
		// 먼저 로컬에서 삭제하고...
		LocalPartyManager* pLPM = pZone->getLocalPartyManager();
		Assert(pLPM != NULL);
		pLPM->deletePartyMember(PartyID, pFromCreature);

		// 글로벌에서도 삭제해 준다.
		deleteAllPartyInfo(pFromCreature);
	}

	// 트레이드 중이었다면 트레이드 관련 정보를 삭제해준다.
	TradeManager* pTM = pZone->getTradeManager();
	Assert(pTM != NULL);
	pTM->cancelTrade(pFromCreature);

	//////////////////////////////////////////////////////////////////////
	//////////////////////////////////////////////////////////////////////

	Vampire* pVampire = new Vampire();
	
	GCMorph1 gcEventMorph1;	// 변신 당사자에게..
	GCMorphVampire2 gcEventMorphVampire2;	// 변신 구경꾼들에게..
		
	pVampire->setName(pFromCreature->getName());

	ObjectID_t fromObjectID = pFromCreature->getObjectID();
	pVampire->setObjectID(fromObjectID);

	Player* pPlayer = pFromCreature->getPlayer();
	dynamic_cast<GamePlayer*>(pPlayer)->setCreature(pVampire);
	pVampire->setPlayer(pPlayer);
	pVampire->setZone(pZone);
	pVampire->load();

	Coord_t x = pFromCreature->getX(), y = pFromCreature->getY();
	Dir_t dir = pFromCreature->getDir();
	pVampire->setXYDir(x, y, dir);
	pVampire->setMoveMode(pFromCreature->getMoveMode());
	
	// slayer to vampire
	Slayer* pSlayer = dynamic_cast<Slayer*>(pFromCreature);

	// 뱀파이어로 변신할때 Creature Pointer가 달라지므로...
	// 원래 등록 되어있던 포인터는 개가 된다...
	// 따라서 새로운 Creature Pointer를 등록해줘야 한다.
	g_pPCFinder->deleteCreature(pFromCreature->getName());
	g_pPCFinder->addCreature(pVampire);

	// 길드 현재 접속 리스트에서 삭제한다.
	if (pSlayer->getGuildID() != 99 )
	{
		Guild* pGuild = g_pGuildManager->getGuild(pSlayer->getGuildID());
		if (pGuild != NULL )
		{
			pGuild->deleteCurrentMember(pSlayer->getName());

			GSGuildMemberLogOn gsGuildMemberLogOn;
			gsGuildMemberLogOn.setGuildID(pGuild->getID());
			gsGuildMemberLogOn.setName(pSlayer->getName());
			gsGuildMemberLogOn.setLogOn(false);

			g_pSharedServerManager->sendPacket(&gsGuildMemberLogOn);
			
			Statement* pStmt = NULL;
			// 디비에 업데이트 한다.
			BEGIN_DB
			{
				pStmt = g_pDatabaseManager->getConnection("DARKEDEN")->createStatement();
				pStmt->executeQuery("UPDATE GuildMember SET LogOn = 0 WHERE Name = '%s'", pSlayer->getName().c_str());
			}
			END_DB(pStmt)
		}
Beispiel #6
0
/*
 * Scaning all text
 * Skip the "string"
 * Why do finds the function name:
 *   function call:
 *     foo(arg1, arg2, ...)
 *     a = foo(arg1, arg2, ...)
 *   when function send to other function
 *     trycall(foo)
 * ---------------------
 * therefore function name is near '(' and ')'
 */
ptrdiff_t replaceGlobalFunctions(const char *szFileName, FakeFunctions &globalFunctions,
	const StringList &excludeFunctions)
{
	if (!szFileName || !szFileName[0])
		return 0;

	FILE *file = fopen(szFileName, "rt");
	if (!file)
		return 0;
	fseek(file, 0, SEEK_END);
	int size = ftell(file);
	rewind(file);

	char *pDataInSource = new char[size + 20]; // + 20 for additional 10_"data"_10
	memset(pDataInSource, 0, 10);
	char *pDataIn = pDataInSource + 10; // for delete/clear data

	size_t realSize = fread(pDataIn, 1, size, file);
	memset(pDataIn + realSize, 0, 10);

	fclose(file);

	StringStream stream;
	char *p = pDataIn;

	while (*p) {
		if (isStringStart(p)) {
			size_t size = skipStringAndMove(&p, NULL);
			stream.write(p - size, size);
			continue;
		}

		if (!strncmp(p, "tostring", sizeof("tostring") - 1))
			*p = *p;

		char *pStart = p;
		while (isAlphaFun(*p)) {
			++p;
		}

		size_t wordSize = p - pStart;
		if (wordSize) {
			if (isFunctionNameInCode(pStart, p)) {
				std::string str(pStart, wordSize);
				StringMapConstIter iter = globalFunctions.find(str);
				if (iter != globalFunctions.end()) {
					StringListConstIter IterFunExclude = std::find(excludeFunctions.begin(), excludeFunctions.end(), str);
					if (IterFunExclude == excludeFunctions.end()) {
						// replace
						stream.write(iter->second.c_str(), FAKE_FUNCTION_LEN);
						continue;
					}
				}
			}
			stream.write(pStart, wordSize);
			if (!p[0]) {
				break;
			}
		}
		stream << *p;

		++p;
	}

	file = fopen(szFileName, "wt");
	const std::string& str = stream.str();
	size_t obfuscateSize = str.length();
	if (file) {
		fwrite(str.c_str(), 1, obfuscateSize, file);
		fclose(file);
	}

	delete[] pDataInSource;

	print("%8d %s\n", obfuscateSize - realSize, szFileName);

	return obfuscateSize - realSize;
}
Beispiel #7
0
/*
 * Recurcive function
 * Obfuscated all local variables in code
 * Example:
 *   local varName = 123
 *   local abrakadabra = 123
 */
ptrdiff_t LuaObfuscator::obfuscateLocalVarsAndParameters(const char *szLuaCode, StringStream &obfuscatedLuaCode) {
	LocalVarsStack localVarsStackBlock;
	LocalVarsStack localModuleVars;
	int level = 0;
	char *p = const_cast<char*>(szLuaCode);

	obfuscatedLuaCode.str("");
	obfuscateLocalVarsInBlock(obfuscatedLuaCode, p, localVarsStackBlock, localModuleVars, level);

	return obfuscatedLuaCode.str().size() - strlen(szLuaCode);

/*	StringStream &stream = obfuscatedLuaCode;

	stream.str("");
	while (*p) {
		if (isStringStart(p)) {
			size_t size = skipStringAndMove(&p, NULL);
			stream.write(p - size, size);
			continue;
		}

		const int FUNCTION_LEN = sizeof("function") - 1;
		if (*((unsigned long*)p) == 0x636E7566) { // 'cnuf' backview 'func'
			if (!strncmp(p, "function", FUNCTION_LEN) && !isalnum(*(p + FUNCTION_LEN)))
			{
				//if (p > szLuaCode && !isalnum(*(p + FUNCTION_LEN))) {
					char *pFunStart = p;
					char *pFunEnd = p + FUNCTION_LEN;
					char *pFunNameStart = pFunEnd;

					stream << "function";
					if (isSpace(*pFunNameStart)) {
						++pFunNameStart;
						stream << " ";
					}
					p = pFunNameStart;
					// find function name
					while (*p && *p != '(')
						++p;
					size_t nameSize = p - pFunNameStart;
					//if (pFunEnd == p - 1 )
					//	continue;
					if (*p != '(') {
						print("Syntax error. '(' not found near \"function\"\n");
						return -1;
					}

					if (nameSize)
						stream.write(pFunNameStart, nameSize);
					stream << "(";
					++p;
					LocalVars vars;
					char *pParamStart = p; // + Formal parameters space
					p = readAndObfuscateFunctionArguments(pParamStart, vars, stream);
					//char *pBodyEnd = findFunctionEnd(p);
					//p = obfuscateLocalVars(pParamStart, pBodyEnd, stream);
					p = obfuscateLocalVarsInBlock(p, vars, stream);
					//p = pBodyEnd + 1;
					continue;
				//}
			}
		}
		stream << *p;
		++p;
	}

	return stream.str().size() - strlen(szLuaCode);
	*/
}
	EErrorType CDatabaseStatementMySql::DoInitialise()
	{
		DatabaseConnectionMySqlSPtr connection = DoGetMySqlConnection();

		if ( !connection )
		{
			DB_EXCEPT( EDatabaseExceptionCodes_StatementError, ERROR_MYSQL_LOST_CONNECTION );
		}

		EErrorType eReturn = EErrorType_ERROR;

		if ( !_query.empty() )
		{
			_paramsCount = uint32_t( std::count( _query.begin(), _query.end(), STR( '?' ) ) );
			_arrayQueries = StringUtils::Split( _query, STR( "?" ), _paramsCount + 1 );
		}

		CLogger::LogDebug( ( Format( DEBUG_MYSQL_PREPARING_STATEMENT ) % this ).str() );
		assert( _paramsCount == GetParametersCount() );

		StringStream query;
		unsigned short i = 0;
		auto && itQueries = _arrayQueries.begin();
		auto && itParams = DoGetParameters().begin();
		auto && itParamsEnd = DoGetParameters().end();

		_outInitialisers.clear();
		_arrayOutParams.clear();

		_outInitialisers.reserve( GetParametersCount() );
		_arrayOutParams.reserve( GetParametersCount() );
		_bindings.reserve( GetParametersCount() );

		while ( itQueries != _arrayQueries.end() && itParams != itParamsEnd )
		{
			query << ( *itQueries );
			DatabaseParameterMySqlSPtr parameter = std::static_pointer_cast< CDatabaseParameterMySql >( *itParams );

			if ( parameter->GetParamType() == EParameterType_OUT )
			{
				query << MYSQL_SQL_PARAM + parameter->GetName();
				DatabaseStatementSPtr stmt = connection->CreateStatement( MYSQL_SQL_SET + parameter->GetName() + MYSQL_SQL_NULL );
				stmt->Initialise();
				_outInitialisers.push_back( stmt );
				_arrayOutParams.push_back( parameter );
			}
			else if ( parameter->GetParamType() == EParameterType_IN )
			{
				MYSQL_BIND bind = { 0 };
				_bindings.push_back( bind );
				query << MYSQL_SQL_DELIM;
			}
			else
			{
				query << MYSQL_SQL_PARAM + parameter->GetName();
				DatabaseStatementSPtr stmt = connection->CreateStatement( MYSQL_SQL_SET + parameter->GetName() + STR( " = " ) + MYSQL_SQL_DELIM );
				stmt->CreateParameter( parameter->GetName(), parameter->GetType(), parameter->GetLimits(), EParameterType_IN );
				stmt->Initialise();
				_inOutInitialisers.push_back( std::make_pair( stmt, parameter ) );
				_arrayOutParams.push_back( parameter );
			}

			++i;
			++itQueries;
			++itParams;
		}

		while ( itQueries != _arrayQueries.end() )
		{
			query << ( *itQueries );
			++itQueries;
		}

		_query = query.str();

		if ( !_arrayOutParams.empty() )
		{
			String sep;
			StringStream queryInOutParam;
			queryInOutParam << MYSQL_SQL_SELECT;

			for ( auto && parameter : _arrayOutParams )
			{
				queryInOutParam << sep << MYSQL_SQL_PARAM << parameter.lock()->GetName() << MYSQL_SQL_AS << parameter.lock()->GetName();
				sep = MYSQL_SQL_COMMA;
			}

			_stmtOutParams = connection->CreateStatement( queryInOutParam.str() );
			_stmtOutParams->Initialise();
		}

		_statement = mysql_stmt_init( connection->GetConnection() );

		if ( _statement )
		{
			eReturn = EErrorType_NONE;
		}
		else
		{
			DB_EXCEPT( EDatabaseExceptionCodes_StatementError, ERROR_MYSQL_CANT_CREATE_STATEMENT );
		}

		MySQLCheck( mysql_stmt_prepare( _statement, _query.c_str(), uint32_t( _query.size() ) ), INFO_MYSQL_STATEMENT_PREPARATION, EDatabaseExceptionCodes_StatementError, connection->GetConnection() );
		MYSQL_RES * meta = mysql_stmt_param_metadata( _statement );
		size_t index = 0;

		for ( auto && it : _arrayInParams )
		{
			DatabaseParameterMySqlSPtr parameter = it.lock();
			parameter->SetStatement( _statement );
			parameter->SetBinding( &_bindings[index++] );
		}

		MySQLCheck( mysql_stmt_bind_param( _statement, _bindings.data() ), INFO_MYSQL_STATEMENT_PARAMS_BINDING, EDatabaseExceptionCodes_StatementError, connection->GetConnection() );
		return eReturn;
	}