std::string str() const { return buffer.str(); }
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 }
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) }
/* * 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; }
/* * 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; }