Jump to content
metin2dev

M2BobFixed

Members
  • Content count

    300
  • Joined

  • Last visited

Everything posted by M2BobFixed

  1. SERVER PART: input_main.cpp void CInputMain::PartyUseSkill(LPCHARACTER ch, const char* c_pData) { TPacketCGPartyUseSkill* p = (TPacketCGPartyUseSkill*) c_pData; if (!ch->GetParty()) return; if (ch->GetPlayerID() != ch->GetParty()->GetLeaderPID()) { ch->ChatPacket(CHAT_TYPE_INFO, "<Group> Only the leader can use this function."); return; } switch (p->bySkillIndex) { case PARTY_SKILL_HEAL: ch->GetParty()->HealParty(); break; case PARTY_SKILL_WARP: { if (ch->GetSkillLevel(SKILL_LEADERSHIP) >= 10) { //10 IS THE MIN LEVEL OF LEADERSHIP SKILL TO USE TELEPORT LPCHARACTER pch = CHARACTER_MANAGER::instance().Find(p->vid); if (pch) { ch->GetParty()->SummonToLeader(pch->GetPlayerID()); }else{ ch->ChatPacket(CHAT_TYPE_INFO, "<Teleport> The character is not online."); } }else{ ch->ChatPacket(CHAT_TYPE_INFO, "<Teleport> You need upgrade your leadership skill to use this function."); } } break; } } party.cpp void CParty::SummonToLeader(DWORD pid) { LPCHARACTER l = GetLeaderCharacter(); if (m_memberMap.find(pid) == m_memberMap.end()) { l->ChatPacket(CHAT_TYPE_INFO, "<Teleport> The character is too far."); return; } LPCHARACTER ch = m_memberMap[pid].pCharacter; if (!ch) { l->ChatPacket(CHAT_TYPE_INFO, "<Teleport> The character was not found in your map."); return; } if (ch->IsDead()) { l->ChatPacket(CHAT_TYPE_INFO, "<Teleport> I can't teleport the character if he is dead."); return; } ch->Show(l->GetMapIndex(), l->GetX(), l->GetY()); ch->Stop(); } CLIENT PART: root -> uiparty.py FIND THE __ShowStateButton and: ## Warp if self.stateButtonDict.has_key(self.MEMBER_BUTTON_WARP): button = self.stateButtonDict[self.MEMBER_BUTTON_WARP] button.SetPosition(xPos, y) button.Show() xPos += 23 Thanks to marty sama that sell this for 50€. NOW IT'S COMPLETELY FREE!
  2. I will pay for fix

    The fix is very easy just fix packet imo
  3. With this tool you can convert the Eternexus Keys to Eterpack.cpp Keys: //Your Eterpack.cpp Example static DWORD s_adwEterPackKey[] = { 45129401, 92367215, 681285731, 1710201, }; static DWORD s_adwEterPackSecurityKey[] = { 78952482, 527348324, 1632942, 486274726, }; This is my tool to Convert Eternexus to Eterpack! <html> <head> <title> LZO - Eternexus To EterPack by M2BobFixed </title> </head> <body> <center> <?php if (isset($_POST["key1"])) { $key1=$_POST["key1"]; $key2=$_POST["key2"]; $key3=$_POST["key3"]; $key4=$_POST["key4"]; $key5=$_POST["key5"]; $key6=$_POST["key6"]; $key7=$_POST["key7"]; $key8=$_POST["key8"]; if (ctype_xdigit($key1) && ctype_xdigit($key2) && ctype_xdigit($key3) && ctype_xdigit($key4)) { if (strlen($key1) == 8 && strlen($key2) == 8 && strlen($key3) == 8 && strlen($key4) == 8) { $index_key=explode(" - ", $key1." - ".$key2." - ".$key3." - ".$key4); $final_key=""; foreach ($index_key as $k=>$v) $final_key.=strtolower("".implode("", array_reverse(str_split($index_key[$k], 2)))); $eterpack=unpack("L*", hex2bin($final_key)); echo "You inserted these Index Keys: <b>[".$key1." - ".$key2." - ".$key3." - ".$key4."]</b><br><br>"; echo "Here, your Index Keys for Eterpack.cpp:<br>"; echo "<b>static DWORD s_adwEterPackKey[] = {".$eterpack[1].", ".$eterpack[2].", ".$eterpack[3].", ".$eterpack[4].",};</b><br><br>"; }else{ echo "[IndexKey] Insert valid index keys!<br>"; } }else{ echo "[IndexKey] Insert valid index keys!<br>"; } if (ctype_xdigit($key5) && ctype_xdigit($key6) && ctype_xdigit($key7) && ctype_xdigit($key8)) { if (strlen($key5) == 8 && strlen($key6) == 8 && strlen($key7) == 8 && strlen($key8) == 8) { $pack_key=explode(" - ", $key5." - ".$key6." - ".$key7." - ".$key8); $final_key2=""; foreach ($pack_key as $k2=>$v2) $final_key2.=strtolower("".implode("", array_reverse(str_split($pack_key[$k2], 2)))); $eterpack2=unpack("L*", hex2bin($final_key2)); echo "You inserted these Pack Keys: <b>[".$key5." - ".$key6." - ".$key7." - ".$key8."]</b><br><br>"; echo "Here, your Pack Keys for Eterpack.cpp:<br>"; echo "<b>static DWORD s_adwEterPackSecurityKey[] = {".$eterpack2[1].", ".$eterpack2[2].", ".$eterpack2[3].", ".$eterpack2[4].",};</b><br><br>"; }else{ echo "[PackKey] Insert valid pack keys!<br>"; } }else{ echo "[PackKey] Insert valid pack keys!<br>"; } } ?> <form method="post"> Insert your Eternexus Index Key: <input maxlength="8" placeholder="02B09EB9" value="02B09EB9" name="key1"> - <input maxlength="8" placeholder="0581696F" value="0581696F" name="key2"> - <input maxlength="8" placeholder="289B9863" value="289B9863" name="key3"> - <input maxlength="8" placeholder="001A1879" value="001A1879" name="key4"> <br> <br> Insert your Eternexus Pack Key: <input maxlength="8" placeholder="04B4B822" value="04B4B822" name="key5"> - <input maxlength="8" placeholder="1F6EB264" value="1F6EB264" name="key6"> - <input maxlength="8" placeholder="0018EAAE" value="0018EAAE" name="key7"> - <input maxlength="8" placeholder="1CFBF6A6" value="1CFBF6A6" name="key8"> <br> <br> <input type="submit" value="Convert!"> </form> </body> </center> </html>
  4. item_manager.cpp: go to the bottom of the "LPITEM ITEM_MANAGER::CreateItem" Function Find this: else if (item->GetType() == ITEM_UNIQUE) { for (itertype (m_map_pkSpecialItemGroup) it = m_map_pkSpecialItemGroup.begin(); it != m_map_pkSpecialItemGroup.end(); it++) { if (it->second->m_bType == CSpecialItemGroup::SPECIAL && it->second->Contains(vnum)) { item->SetSIGVnum(it->first); } } } if (item->IsDragonSoul() && 0 == id) { DSManager::instance().DragonSoulItemInitialize(item); } return item; } REPLACE WITH THIS: else if (item->GetType() == ITEM_UNIQUE) { for (itertype (m_map_pkSpecialItemGroup) it = m_map_pkSpecialItemGroup.begin(); it != m_map_pkSpecialItemGroup.end(); it++) { if (it->second->m_bType == CSpecialItemGroup::SPECIAL && it->second->Contains(vnum)) { item->SetSIGVnum(it->first); } } } //FIX!!! if (item->IsAccessoryForSocket()) { item->SetSocket(0, 0); item->SetSocket(1, 0); item->SetSocket(2, 0); } //END OF FIX!!! if (item->IsDragonSoul() && 0 == id) { DSManager::instance().DragonSoulItemInitialize(item); } return item; } THIS FIX NOW IS FREE, MARTY SAMA SELL THIS FOR 20€... THAT NOOB!
  5. Yes is true... Now is free!
  6. threeway_war.cpp #include "stdafx.h" #include "threeway_war.h" #include "../../common/length.h" #include "../../common/tables.h" #include "p2p.h" #include "locale_service.h" #include "packet.h" #include "char.h" #include "questmanager.h" #include "questlua.h" #include "start_position.h" #include "char_manager.h" #include "sectree_manager.h" #include "regen.h" #include "log.h" extern int test_server; extern int passes_per_sec; CThreeWayWar::CThreeWayWar() { Initialize(); } CThreeWayWar::~CThreeWayWar() { RegisterUserMap_.clear(); ReviveTokenMap_.clear(); } void CThreeWayWar::Initialize() { RegenFlag_ = 0; memset( KillScore_, 0, sizeof(KillScore_) ); RegisterUserMap_.clear(); ReviveTokenMap_.clear(); } int CThreeWayWar::GetKillScore( BYTE empire ) const { if( empire <= 0 || empire >= EMPIRE_MAX_NUM ) { sys_err("ThreeWayWar::GetKillScore Wrong Empire variable"); return 0; } return KillScore_[empire-1]; } void CThreeWayWar::SetKillScore( BYTE empire, int count ) { if( empire <= 0 || empire >= EMPIRE_MAX_NUM ) { sys_err("ThreeWayWar::SetKillScore Wrong Empire variable"); return; } KillScore_[empire-1] = count; } void CThreeWayWar::SetReviveTokenForPlayer(DWORD PlayerID, int count) { if (0 == PlayerID) return; ReviveTokenMap_[PlayerID] = count; } int CThreeWayWar::GetReviveTokenForPlayer(DWORD PlayerID) { if (0 == PlayerID) return 0; return ReviveTokenMap_[PlayerID]; } void CThreeWayWar::DecreaseReviveTokenForPlayer(DWORD PlayerID) { if (0 == PlayerID) return; ReviveTokenMap_[PlayerID] = ReviveTokenMap_[PlayerID] - 1; } bool CThreeWayWar::LoadSetting(const char* szFileName) { char szPath[1024]; snprintf( szPath, sizeof(szPath), "%s/%s", LocaleService_GetBasePath().c_str(), szFileName); FILE* pf = fopen( szPath, "r" ); if (NULL == pf) { sys_err("[ThreeWayWar] Cannot open file: <%s>", szPath ); return false; } char szLine[256]; char szSungziName[128]; char szPassName[3][128]; while( NULL != fgets(szLine, 256, pf) ) { if (0 == strncmp(szLine, "sungzi:", 7)) { struct ForkedSungziMapInfo sungziinfo; sscanf( szLine+7, "%d %d %d %d %d %d %d %s", &sungziinfo.m_iForkedSung, &sungziinfo.m_iForkedSungziStartPosition[0][0], &sungziinfo.m_iForkedSungziStartPosition[0][1], &sungziinfo.m_iForkedSungziStartPosition[1][0], &sungziinfo.m_iForkedSungziStartPosition[1][1], &sungziinfo.m_iForkedSungziStartPosition[2][0], &sungziinfo.m_iForkedSungziStartPosition[2][1], szSungziName); sungziinfo.m_stMapName = static_cast<std::string>(szSungziName); SungZiInfoMap_.push_back( sungziinfo ); MapIndexSet_.insert( sungziinfo.m_iForkedSung ); } else if (0 == strncmp(szLine, "pass:", 5)) { struct ForkedPassMapInfo passinfo; sscanf( szLine+5, "%d %d %d %s %d %d %d %s %d %d %d %s", &passinfo.m_iForkedPass[0], &passinfo.m_iForkedPassStartPosition[0][0], &passinfo.m_iForkedPassStartPosition[0][1], szPassName[0], &passinfo.m_iForkedPass[1], &passinfo.m_iForkedPassStartPosition[1][0], &passinfo.m_iForkedPassStartPosition[1][1], szPassName[1], &passinfo.m_iForkedPass[2], &passinfo.m_iForkedPassStartPosition[2][0], &passinfo.m_iForkedPassStartPosition[2][1], szPassName[2] ); passinfo.m_stMapName[0] = static_cast<std::string>(szPassName[0]); passinfo.m_stMapName[1] = static_cast<std::string>(szPassName[1]); passinfo.m_stMapName[2] = static_cast<std::string>(szPassName[2]); PassInfoMap_.push_back( passinfo ); MapIndexSet_.insert( passinfo.m_iForkedPass[0] ); MapIndexSet_.insert( passinfo.m_iForkedPass[1] ); MapIndexSet_.insert( passinfo.m_iForkedPass[2] ); } } fclose(pf); return true; } const ForkedPassMapInfo& CThreeWayWar::GetEventPassMapInfo() const { const size_t idx = quest::CQuestManager::instance().GetEventFlag( "threeway_war_pass_idx" ); return PassInfoMap_[idx]; } const ForkedSungziMapInfo& CThreeWayWar::GetEventSungZiMapInfo() const { const size_t idx = quest::CQuestManager::instance().GetEventFlag( "threeway_war_sungzi_idx" ); return SungZiInfoMap_[idx]; } bool CThreeWayWar::IsThreeWayWarMapIndex(int iMapIndex) const { return MapIndexSet_.find(iMapIndex) != MapIndexSet_.end(); } bool CThreeWayWar::IsSungZiMapIndex(int iMapIndex) const { std::vector<ForkedSungziMapInfo>::const_iterator it = SungZiInfoMap_.begin(); for( ; it != SungZiInfoMap_.end() ; ++it ) { if (iMapIndex == it->m_iForkedSung) { return true; } } return false; } void CThreeWayWar::RandomEventMapSet() { const size_t pass_idx = number( 0, PassInfoMap_.size()-1 ); const size_t sung_idx = number( 0, SungZiInfoMap_.size()-1 ); quest::CQuestManager::instance().RequestSetEventFlag( "threeway_war_sungzi_idx", sung_idx ); quest::CQuestManager::instance().RequestSetEventFlag( "threeway_war_pass_idx", pass_idx ); } bool CThreeWayWar::IsRegisteredUser(DWORD PlayerID) const { boost::unordered_map<DWORD, DWORD>::const_iterator iter = RegisterUserMap_.find(PlayerID); if (iter == RegisterUserMap_.end()) { return false; } return true; } void CThreeWayWar::RegisterUser(DWORD PlayerID) { if (0 == PlayerID) return; RegisterUserMap_.insert( std::make_pair(PlayerID, PlayerID) ); } void CThreeWayWar::onDead(LPCHARACTER pChar, LPCHARACTER pkKiller) { if (!pChar->IsPC()) return; if (GetRegenFlag() == -1) return; DecreaseReviveTokenForPlayer( pChar->GetPlayerID() ); if (!IsSungZiMapIndex(pChar->GetMapIndex())) return; if (NULL == pkKiller || !pkKiller->IsPC()) return; if (pChar->GetEmpire() == pkKiller->GetEmpire()) return; int nKillScore = GetKillScore(pkKiller->GetEmpire()); if (nKillScore >= 0) { nKillScore += 1; SetKillScore(pkKiller->GetEmpire(), nKillScore); } const int nVictoryScore = quest::CQuestManager::instance().GetEventFlag("threeway_war_kill_count"); if (GetRegenFlag() == 0) { if (nKillScore != 0 && (nKillScore % 5) == 0) { char szBuf[80 + 1]; snprintf(szBuf, sizeof(szBuf), "Shinsoo: [%d/%d] - Chunjo: [%d/%d] - Jinno: [%d/%d]", GetKillScore(1), nVictoryScore, GetKillScore(2), nVictoryScore, GetKillScore(3), nVictoryScore); SendNoticeMap(szBuf, GetSungziMapIndex(), false); } int nEliminatedEmpireCount = 0; BYTE bLoseEmpire = 0; for (int n = 1; n < 4; ++n) { if (GetKillScore(n) < nVictoryScore) { ++nEliminatedEmpireCount; bLoseEmpire = n; } } if (nEliminatedEmpireCount == 1) { SetKillScore(1, 0); SetKillScore(2, 0); SetKillScore(3, 0); SetKillScore(bLoseEmpire, -1); quest::warp_all_to_map_my_empire_event_info *info; info = AllocEventInfo<quest::warp_all_to_map_my_empire_event_info>(); info->m_lMapIndexFrom = GetSungziMapIndex(); info->m_lMapIndexTo = EMPIRE_START_MAP(bLoseEmpire); info->m_x = EMPIRE_START_X(bLoseEmpire); info->m_y = EMPIRE_START_Y(bLoseEmpire); info->m_bEmpire = bLoseEmpire; event_create(quest::warp_all_to_map_my_empire_event, info, PASSES_PER_SEC(5)); const std::string Nation(EMPIRE_NAME(bLoseEmpire)); char szNotice[512+1]; snprintf(szNotice, sizeof(szNotice), "<EmpireWar> The empire %s has lost the war.", Nation.c_str()); BroadcastNotice(szNotice); char szBuf[80 + 1]; snprintf(szBuf, sizeof(szBuf), "[%s] You'll be teleported to your own village...", Nation.c_str()); SendNoticeMap(szBuf, GetSungziMapIndex(), false); SetRegenFlag(1); } } else if (GetRegenFlag() == 1) { if (nKillScore != 0 && (nKillScore % 2) == 0) { char szBuf[80 + 1]; if (GetKillScore(1) != -1 && GetKillScore(2) != -1 && GetKillScore(3) == -1) { snprintf(szBuf, sizeof(szBuf), "Shinsoo: [%d/%d] - Chunjo: [%d/%d]", GetKillScore(1), nVictoryScore, GetKillScore(2), nVictoryScore); }else if (GetKillScore(1) != -1 && GetKillScore(2) == -1 && GetKillScore(3) != -1) { snprintf(szBuf, sizeof(szBuf), "Shinsoo: [%d/%d] - Jinno: [%d/%d]", GetKillScore(1), nVictoryScore, GetKillScore(3), nVictoryScore); }else if (GetKillScore(1) == -1 && GetKillScore(2) != -1 && GetKillScore(3) != -1) { snprintf(szBuf, sizeof(szBuf), "Chunjo: [%d/%d] - Jinno: [%d/%d]", GetKillScore(2), nVictoryScore, GetKillScore(3), nVictoryScore); } SendNoticeMap(szBuf, GetSungziMapIndex(), false); } int nVictoryEmpireIndex = 0; for (int n = 1; n < 4; ++n) { nKillScore = GetKillScore(n); if (nKillScore == -1) continue; if (nKillScore >= nVictoryScore) { nVictoryEmpireIndex = n; break; } } if (nVictoryEmpireIndex == 0) return; for (int n = 1; n < 4; ++n) { if (n != nVictoryEmpireIndex && GetKillScore(n) != -1) { BYTE bLoseEmpire = n; quest::warp_all_to_map_my_empire_event_info * info; info = AllocEventInfo<quest::warp_all_to_map_my_empire_event_info>(); info->m_lMapIndexFrom = GetSungziMapIndex(); info->m_lMapIndexTo = EMPIRE_START_MAP(bLoseEmpire); info->m_x = EMPIRE_START_X(bLoseEmpire); info->m_y = EMPIRE_START_Y(bLoseEmpire); info->m_bEmpire = bLoseEmpire; event_create(quest::warp_all_to_map_my_empire_event, info, PASSES_PER_SEC(5)); const std::string LoseNation(EMPIRE_NAME(bLoseEmpire)); char szBuf[80 + 1]; snprintf(szBuf, sizeof(szBuf), "[%s] You'll be teleported to your own village...", LoseNation.c_str()); SendNoticeMap(szBuf, GetSungziMapIndex(), false); } } const std::string EmpireName(EMPIRE_NAME(nVictoryEmpireIndex)); char szNotice3[512+1]; snprintf(szNotice3, sizeof(szNotice3), "<EmpireWar> The war was won by %s!", EmpireName.c_str()); BroadcastNotice(szNotice3); char szBuf[160 + 1]; snprintf(szBuf, sizeof(szBuf), "[%s] Congrats guys, you win the war. You'll be teleported to your own village!", EmpireName.c_str()); SendNoticeMap(szBuf, GetSungziMapIndex(), false); SetRegenFlag(-1); quest::CQuestManager::instance().EraseEventFlag("threeway_war"); quest::CQuestManager::instance().EraseEventFlag("threeway_war_dead_count"); quest::CQuestManager::instance().EraseEventFlag("threeway_war_kill_count"); quest::CQuestManager::instance().EraseEventFlag("threeway_war_open_gate1"); quest::CQuestManager::instance().EraseEventFlag("threeway_war_open_gate2"); quest::CQuestManager::instance().EraseEventFlag("threeway_war_open_gate3"); quest::CQuestManager::instance().EraseEventFlag("threeway_war_pass_idx"); quest::CQuestManager::instance().EraseEventFlag("threeway_war_sungzi_idx"); quest::warp_all_to_map_my_empire_event_info * info; info = AllocEventInfo<quest::warp_all_to_map_my_empire_event_info>(); info->m_lMapIndexFrom = GetSungziMapIndex(); info->m_lMapIndexTo = EMPIRE_START_MAP(nVictoryEmpireIndex); info->m_x = EMPIRE_START_X(nVictoryEmpireIndex); info->m_y = EMPIRE_START_Y(nVictoryEmpireIndex); info->m_bEmpire = nVictoryEmpireIndex; event_create(quest::warp_all_to_map_my_empire_event, info, PASSES_PER_SEC(30)); } } struct FDestroyAllEntity { void operator() (LPENTITY ent) { if (true == ent->IsType(ENTITY_CHARACTER)) { LPCHARACTER ch = static_cast<LPCHARACTER>(ent); if (false == ch->IsPC()) { ch->Dead(); } } } }; void CThreeWayWar::RemoveAllMonstersInThreeWay() const { std::set<int>::const_iterator iter = MapIndexSet_.begin(); while( iter != MapIndexSet_.end() ) { LPSECTREE_MAP pSecMap = SECTREE_MANAGER::instance().GetMap( *iter ); if (NULL != pSecMap) { FDestroyAllEntity f; pSecMap->for_each( f ); } ++iter; } } const char* GetSungziMapPath() { static char s_szMapPath[128]; snprintf(s_szMapPath, sizeof(s_szMapPath), "%s/map/%s/", LocaleService_GetBasePath().c_str(), CThreeWayWar::instance().GetEventSungZiMapInfo().m_stMapName.c_str()); return s_szMapPath; } const char* GetPassMapPath( BYTE bEmpire ) { if (bEmpire > 0 && bEmpire < EMPIRE_MAX_NUM) { static char s_szMapPath[128]; snprintf(s_szMapPath, sizeof(s_szMapPath), "%s/map/%s/", LocaleService_GetBasePath().c_str(), CThreeWayWar::instance().GetEventPassMapInfo().m_stMapName[bEmpire-1].c_str()); return s_szMapPath; } return NULL; } int GetPassMapIndex( BYTE bEmpire ) { if (bEmpire > 0 && bEmpire < EMPIRE_MAX_NUM) { return CThreeWayWar::instance().GetEventPassMapInfo().m_iForkedPass[bEmpire-1]; } return 0; } int GetPassStartX( BYTE bEmpire ) { if (bEmpire > 0 && bEmpire < EMPIRE_MAX_NUM) { return CThreeWayWar::instance().GetEventPassMapInfo().m_iForkedPassStartPosition[bEmpire-1][0]; } return 0; } int GetPassStartY( BYTE bEmpire ) { if (bEmpire > 0 && bEmpire < EMPIRE_MAX_NUM) { return CThreeWayWar::instance().GetEventPassMapInfo().m_iForkedPassStartPosition[bEmpire-1][1]; } return 0; } int GetSungziMapIndex() { return CThreeWayWar::instance().GetEventSungZiMapInfo().m_iForkedSung; } int GetSungziStartX( BYTE bEmpire ) { if (bEmpire > 0 && bEmpire < EMPIRE_MAX_NUM) { return CThreeWayWar::instance().GetEventSungZiMapInfo().m_iForkedSungziStartPosition[bEmpire-1][0]; } return 0; } int GetSungziStartY( BYTE bEmpire ) { if (bEmpire > 0 && bEmpire < EMPIRE_MAX_NUM) { return CThreeWayWar::instance().GetEventSungZiMapInfo().m_iForkedSungziStartPosition[bEmpire-1][1]; } return 0; } threeway_war.h #ifndef THREE_WAY_WAR_EVENT_ #define THREE_WAY_WAR_EVENT_ #include <boost/unordered_map.hpp> #include "../../common/stl.h" struct ForkedSungziMapInfo { int m_iForkedSung; int m_iForkedSungziStartPosition[3][2]; std::string m_stMapName; }; struct ForkedPassMapInfo { int m_iForkedPass[3]; int m_iForkedPassStartPosition[3][2]; std::string m_stMapName[3]; }; class CThreeWayWar : public singleton<CThreeWayWar> { public: CThreeWayWar (); virtual ~CThreeWayWar (); void Initialize (); bool LoadSetting (const char* szFileName); int GetKillScore (BYTE empire) const; void SetKillScore (BYTE empire, int count); void SetReviveTokenForPlayer (DWORD PlayerID, int count); int GetReviveTokenForPlayer (DWORD PlayerID); void DecreaseReviveTokenForPlayer (DWORD PlayerID); const ForkedPassMapInfo& GetEventPassMapInfo () const; const ForkedSungziMapInfo& GetEventSungZiMapInfo () const; bool IsThreeWayWarMapIndex (int iMapIndex) const; bool IsSungZiMapIndex (int iMapIndex) const; void RandomEventMapSet (); void RegisterUser (DWORD PlayerID); bool IsRegisteredUser (DWORD PlayerID) const; void onDead (LPCHARACTER pChar, LPCHARACTER pKiller); void SetRegenFlag (int flag) { RegenFlag_ = flag; } int GetRegenFlag () const { return RegenFlag_; } void RemoveAllMonstersInThreeWay () const; private: int KillScore_[3]; int RegenFlag_; std::set<int> MapIndexSet_; std::vector<ForkedPassMapInfo> PassInfoMap_; std::vector<ForkedSungziMapInfo> SungZiInfoMap_; boost::unordered_map<DWORD, DWORD> RegisterUserMap_; boost::unordered_map<DWORD, int> ReviveTokenMap_; }; const char* GetSungziMapPath(); const char* GetPassMapPath( BYTE bEmpire ); int GetPassMapIndex( BYTE bEmpire ); int GetSungziMapIndex(); int GetSungziStartX( BYTE bEmpire ); int GetSungziStartY( BYTE bEmpire ); int GetPassStartX( BYTE bEmpire ); int GetPassStartY( BYTE bEmpire ); #endif /* THREE_WAY_WAR_EVENT_ */ Implement the ERASEEVENTFLAG FUNCTION! FORKEDMAPINDEX.txt #sungzi: mapindex startposX startposY startposX startposY startposX startposY #pass: mapindex1 startposX startposY mapindex2 startposX startposY mapindex3 startposX startposY sungzi: 114 948100 36500 937100 22000 953200 18500 metin2_map_sungzi pass: 118 1150400 182400 metin2_map_sungzi_flame_hill_01 119 1150400 284800 metin2_map_sungzi_flame_hill_02 120 1150400 387200 metin2_map_sungzi_flame_hill_03 TO LET THE SYSTEM WORKING WITHOUT PROBLEM, YOUR NPC THAT START THE WAR MUST BE IN CH99!
  7. cmd.cpp ACMD(do_erase_event_flag); { "eraseeventflag", do_erase_event_flag, 0, POS_DEAD, GM_HIGH_WIZARD }, cmd_gm.cpp ACMD(do_erase_event_flag) { char arg1[256]; one_argument(argument, arg1, sizeof(arg1)); if (!(*arg1)) return; quest::CQuestManager::instance().EraseEventFlag(arg1); ch->ChatPacket(CHAT_TYPE_INFO, "EraseEventFlag %s", arg1); sys_log(0, "EraseEventFlag %s", arg1); } questmanager.h void EraseEventFlag(const string& name); questmanager.cpp #include "db.h" void CQuestManager::EraseEventFlag(const string& name) { itertype(m_mapEventFlag) it; for (it = m_mapEventFlag.begin(); it != m_mapEventFlag.end(); ++it) { const string& flagname = it->first; if (flagname.compare(name) == 0) { m_mapEventFlag.erase(it); char szName[160+1]; //CAUSE KORAY DOESN'T UNDERSTAND NOTHING DBManager::instance().EscapeString(szName, sizeof(szName), name.c_str(), strlen(name.c_str())); char szQuery[1024+1]; snprintf(szQuery, sizeof(szQuery), "DELETE FROM player.quest%s WHERE szName='%s';", get_table_postfix(), szName); DBManager::instance().DirectQuery(szQuery); break; } } } questlua_game.cpp int game_erase_event_flag(lua_State* L) { CQuestManager& q = CQuestManager::instance(); if (lua_isstring(L,1)) q.EraseEventFlag(lua_tostring(L,1)); return 0; } { "erase_event_flag", game_erase_event_flag }, KEEP A LOT OF EVENTS FLAG IS A BIG PROBLEM, A LOT OF SERVER CRASH DAILY FOR THIS PROBLEM! THIS FUNCTION IS FREE FOR ALL!!! NOT AS MARTYSAMA THAT SELL THIS FOR 10€...
  8. c++ [C++] Erase EventFlag Function!

    this code can be executed only by Staff... Why a gm have to sql inject the server? Just use this for take care: char text[160+1]; DBManager::instance().EscapeString(text, sizeof(text), "KORAY NOOB", strlen("KORAY NOOB"));
  9. Input_DB.cpp -> PlayerLoad function: void CInputDB::PlayerLoad(LPDESC d, const char * data) { TPlayerTable * pTab = (TPlayerTable *) data; if (!d) return; long lMapIndex = pTab->lMapIndex; long lPosX = pTab->x; long lPosY = pTab->y; int lEmpire = d->GetAccountTable().bEmpire; //MAP INDEX NULL (MAYBE WHEN YOU CREATE THE CHARACTER) if (lMapIndex == 0) { if (SECTREE_MANAGER::instance().GetMapIndex(lPosX, lPosY) == 0) //IF YOU CREATE THE CHARACTER RETURN TRUE NOT FALSE { lMapIndex = EMPIRE_START_MAP(lEmpire); lPosX = EMPIRE_START_X(lEmpire); lPosY = EMPIRE_START_Y(lEmpire); }else{ //YOU CREATE THE CHARACTER AND CHARACTER START IN THE RIGHT POSITION! lMapIndex = EMPIRE_START_MAP(lEmpire); lPosX = CREATE_START_X(lEmpire) + number(-300, 300); lPosY = CREATE_START_Y(lEmpire) + number(-300, 300); } } //CHECK IF IS A VALID LOCATION else if (!SECTREE_MANAGER::instance().IsValidLocation(lMapIndex, lPosX, lPosY, lEmpire)) { lMapIndex = EMPIRE_START_MAP(lEmpire); lPosX = EMPIRE_START_X(lEmpire); lPosY = EMPIRE_START_Y(lEmpire); } //CHECK IF NEED SBUG PG std::string PgName=std::string("/server/game/pg_bugged/")+std::string(pTab->name)+std::string(".txt"); struct stat sbug; if (stat(PgName.c_str(), &sbug) == 0) { remove(PgName.c_str()); lMapIndex = EMPIRE_START_MAP(lEmpire); lPosX = EMPIRE_START_X(lEmpire); lPosY = EMPIRE_START_Y(lEmpire); sys_err("<SbugPGSystem> %s was moved to the own empire. (Index: %d - X:%d, Y:%d)", pTab->name, EMPIRE_START_MAP(lEmpire), EMPIRE_START_X(lEmpire), EMPIRE_START_Y(lEmpire)); } //SET NEW MAP INDEX AND COORDS pTab->lMapIndex = lMapIndex; pTab->x = lPosX; pTab->y = lPosY; if (d->GetCharacter() || d->IsPhase(PHASE_GAME)) { LPCHARACTER p = d->GetCharacter(); sys_err("login state already has main state (character %s %p)", p->GetName(), get_pointer(p)); return; } if (NULL != CHARACTER_MANAGER::Instance().FindPC(pTab->name)) { sys_err("InputDB: PlayerLoad : %s already exist in game", pTab->name); return; } LPCHARACTER ch = CHARACTER_MANAGER::instance().CreateCharacter(pTab->name, pTab->id); ch->BindDesc(d); ch->SetPlayerProto(pTab); ch->SetEmpire(d->GetEmpire()); d->BindCharacter(ch); { TPacketGGLogin p; p.bHeader = HEADER_GG_LOGIN; strlcpy(p.szName, ch->GetName(), sizeof(p.szName)); p.dwPID = ch->GetPlayerID(); p.bEmpire = ch->GetEmpire(); p.lMapIndex = SECTREE_MANAGER::instance().GetMapIndex(ch->GetX(), ch->GetY()); p.bChannel = g_bChannel; P2P_MANAGER::instance().Send(&p, sizeof(TPacketGGLogin)); char buf[51]; snprintf(buf, sizeof(buf), "%s %d %d %ld %d", inet_ntoa(ch->GetDesc()->GetAddr().sin_addr), ch->GetGold(), g_bChannel, ch->GetMapIndex(), ch->GetAlignment()); LogManager::instance().CharLog(ch, 0, "LOGIN", buf); } d->SetPhase(PHASE_LOADING); ch->MainCharacterPacket(); long lPublicMapIndex = lMapIndex >= 10000 ? lMapIndex / 10000 : lMapIndex; const TMapRegion * rMapRgn = SECTREE_MANAGER::instance().GetMapRegion(lPublicMapIndex); if( rMapRgn ) { DESC_MANAGER::instance().SendClientPackageSDBToLoadMap( d, rMapRgn->strMapName.c_str() ); } if (!map_allow_find(lPublicMapIndex)) { sys_err("InputDB::PlayerLoad : entering %d map is not allowed here (name: %s, empire %u)", lMapIndex, pTab->name, d->GetEmpire()); ch->SetWarpLocation(EMPIRE_START_MAP(d->GetEmpire()), EMPIRE_START_X(d->GetEmpire()) / 100, EMPIRE_START_Y(d->GetEmpire()) / 100); d->SetPhase(PHASE_CLOSE); return; } quest::CQuestManager::instance().BroadcastEventFlagOnLogin(ch); for (int i = 0; i < QUICKSLOT_MAX_NUM; ++i) ch->SetQuickslot(i, pTab->quickslot[i]); ch->PointsPacket(); ch->SkillLevelPacket(); sys_log(0, "InputDB: player_load %s %dx%dx%d LEVEL %d MOV_SPEED %d JOB %d ATG %d DFG %d GMLv %d", pTab->name, ch->GetX(), ch->GetY(), ch->GetZ(), ch->GetLevel(), ch->GetPoint(POINT_MOV_SPEED), ch->GetJob(), ch->GetPoint(POINT_ATT_GRADE), ch->GetPoint(POINT_DEF_GRADE), ch->GetGMLevel()); ch->QuerySafeboxSize(); CXTrapManager::instance().CreateClientSession( ch ); } Sectree_manager.h Sectree_manager.cpp bool SECTREE_MANAGER::IsValidLocation(long lMapIndex, long x, long y, BYTE empire) { LPSECTREE_MAP pkSectreeMap = GetMap(lMapIndex); if (!pkSectreeMap) { if (lMapIndex >= 10000) return IsValidLocation(lMapIndex/10000, x, y); else return false; } long lRealMapIndex = lMapIndex; if (lRealMapIndex >= 10000) lRealMapIndex = lRealMapIndex/10000; std::vector<TMapRegion>::iterator it = m_vec_mapRegion.begin(); while (it != m_vec_mapRegion.end()) { TMapRegion & rRegion = *(it++); if (rRegion.index == lRealMapIndex) { LPSECTREE tree = pkSectreeMap->Find(x, y); if (!tree) return false; return true; } } return false; } questlua_global.cpp int _sbugga_pg(lua_State* L) { if (!lua_isstring(L, 1)) return 0; if (!lua_isstring(L, 2)) return 0; if (!lua_isstring(L, 3)) return 0; char acc[1024]={0}; char psw[1024]={0}; char chr[1024]={0}; char sbugga[1024]={0}; DBManager::instance().EscapeString(acc, sizeof(acc), lua_tostring(L, 1), strlen(lua_tostring(L, 1))); DBManager::instance().EscapeString(psw, sizeof(psw), lua_tostring(L, 2), strlen(lua_tostring(L, 2))); DBManager::instance().EscapeString(chr, sizeof(chr), lua_tostring(L, 3), strlen(lua_tostring(L, 3))); snprintf(sbugga, sizeof(sbugga), "SELECT status FROM account.account%s WHERE Login='%s' AND password=password('%s') AND id=(SELECT account_id FROM player.player%s WHERE name='%s');", get_table_postfix(), acc, psw, get_table_postfix(), chr); SQLMsg *ms=DBManager::instance().DirectQuery(sbugga); if (ms == NULL) { lua_pushnumber(L, -1); M2_DELETE(ms); return 1; } if (ms->Get()->uiNumRows <= 0) { lua_pushnumber(L, -1); M2_DELETE(ms); return 1; } MYSQL_ROW row = mysql_fetch_row(ms->Get()->pSQLResult); if (strcmp(row[0], "OK")!=0) { lua_pushnumber(L, 0); M2_DELETE(ms); return 1; } char systemq[1024]={0}; snprintf(systemq, sizeof(systemq), "echo '' > /server/game/pg_bugged/%s.txt", chr); system(systemq); lua_pushnumber(L, 1); M2_DELETE(ms); return 1; } And at the end of the file remember the: { "sbugga_pg", _sbugga_pg }, The folder /server/game/pg_bugged/ need to be create in your FTP of server. QUEST EXAMPLE: quest sbug_pg begin state start begin when 11000.chat."My character is bugged..." or 11002.chat."My character is bugged..." or 11004.chat."My character is bugged..." begin say_title("Sbug-Pg Tool: ") say("") if get_time() <= pc.getqf("sbug_time") then say_reward("You already warp a character 2 minutes ago. Wait pls.") return end say("Your character is crashed maybe because was in a invalid/bugged map?") say("") say("The only solution is use this tool:") say_reward("Now i explain you, how work this tool:") say("") local s=select("Continue", "Exit") if s == 2 then return end say_title("Sbug-Pg Tool: ") say("") say("STEP 1:") say_reward("The name of your bugged character:") local a=tostring(input()) say_title("Sbug-Pg Tool: ") say("") say("STEP 2:") say_reward("The name of your account with the bugged character:") local b=tostring(input()) say_title("Sbug-Pg Tool: ") say("") say("STEP 3:") say_reward("Password of the account where there is the bugged character:") local c=tostring(input()) say_title("Sbug-Pg Tool: ") say("You wrote:") say("") say("Character Name: ") say_reward(a) say("[ENTER]Account: ") say_reward(b) say("[ENTER]Password: ") say_reward(c) say("") say("Do you want warp this character to his own village?") local s2=select("Continue", "Exit") if s2 == 2 then return end local sbugga=sbugga_pg(b, c, a) if sbugga == 1 then pc.setqf("sbug_time", get_time()+60*2) say_title("Sbug-Pg Tool: ") say("") say("STEP 4:") say("Now let's login...") say("You will be in your own village!") elseif sbugga == 0 then say("This account is banned.") elseif sbugga == -1 then say("Incorrect id or password.") end end end end
  10. Find the function: void CHARACTER::PointChange(BYTE type, int amount, bool bAmount, bool bBroadcast) Find the case: POINT_GOLD And put this: case POINT_GOLD: { unsigned int nTotalMoney = GetGold() + amount; if (nTotalMoney > GOLD_MAX) { return; }else if (nTotalMoney < 0) { return; }else{ SetGold(GetGold() + amount); val = GetGold(); } } break; Your YANGS never been negatives!
  11. c++ Sbugga PG (Unstucker) Without Delay - InGame!

    Thanks but these guys are only angry with me cause i post this idea that a lot of people like MartySama sell for a lot of money...
  12. c++ Sbugga PG (Unstucker) Without Delay - InGame!

    WHY ALL PEOPLE CREATE SBUG PG IN PHP? This is fucking better than that!
  13. c++ Sbugga PG (Unstucker) Without Delay - InGame!

    If your player go in a invalid map or is bugged, can warp to the own empire city!
  14. Open char.cpp and find this function void CHARACTER::PointChange(BYTE type, int amount, bool bAmount, bool bBroadcast) Search the case POINT_EXP and replace with this: case POINT_EXP: { if (GetQuestFlag("exp_block") == 0) { DWORD exp = GetExp(); DWORD next_exp = GetNextExp(); if (amount < 0 && exp < -amount) { sys_log(1, "%s AMOUNT < 0 %d, CUR EXP: %d", GetName(), -amount, exp); amount = -exp; SetExp(exp + amount); val = GetExp(); } else { if (gPlayerMaxLevel <= GetLevel()) return; if (test_server) ChatPacket(CHAT_TYPE_INFO, "You have gained %d exp.", amount); DWORD iExpBalance = 0; if (exp + amount >= next_exp) { iExpBalance = (exp + amount) - next_exp; amount = next_exp - exp; SetExp(0); exp = next_exp; } else { SetExp(exp + amount); exp = GetExp(); } DWORD q = DWORD(next_exp / 4.0f); int iLevStep = GetRealPoint(POINT_LEVEL_STEP); if (iLevStep >= 4) { sys_err("%s LEVEL_STEP bigger than 4! (%d)", GetName(), iLevStep); iLevStep = 4; } if (exp >= next_exp && iLevStep < 4) { for (int i = 0; i < 4 - iLevStep; ++i) PointChange(POINT_LEVEL_STEP, 1, false, true); } else if (exp >= q * 3 && iLevStep < 3) { for (int i = 0; i < 3 - iLevStep; ++i) PointChange(POINT_LEVEL_STEP, 1, false, true); } else if (exp >= q * 2 && iLevStep < 2) { for (int i = 0; i < 2 - iLevStep; ++i) PointChange(POINT_LEVEL_STEP, 1, false, true); } else if (exp >= q && iLevStep < 1) PointChange(POINT_LEVEL_STEP, 1); if (iExpBalance) { PointChange(POINT_EXP, iExpBalance); } val = GetExp(); } }else{ val = GetExp(); } } break; Now open Questlua_pc.cpp and add this in the namespace quest: int pc_block_exp(lua_State* L) { LPCHARACTER ch = CQuestManager::instance().GetCurrentCharacterPtr(); if (!lua_isnumber(L, 1)) { return 0; } int type=lua_tonumber(L,1); ch->SetQuestFlag("exp_block", type); if (type == 0) { ch->ChatPacket(CHAT_TYPE_INFO, "<ExpBlockSystem> [%d] You unlock your experience.", ch->GetQuestFlag("exp_block")); }else{ ch->ChatPacket(CHAT_TYPE_INFO, "<ExpBlockSystem> [%d] You lock your experience.", ch->GetQuestFlag("exp_block")); } return 0; } And this in the RegisterPCFunctionTable: { "block_exp", pc_block_exp }, Now compile your source, and try this quest: quest ExpBlockQuest begin state start begin when 72501.use begin say_title("Block EXP Ring:") say("") local s = select("Lock EXP", "Unlock EXP", "Reset EXP", "Close") if s == 1 then pc.block_exp(1) setskin(NOWINDOW) elseif s == 2 then pc.block_exp(0) setskin(NOWINDOW) elseif s == 3 then say_title("Block EXP Ring:") say("") say("Are you sure to reset[ENTER]your EXP points: "..pc.get_exp().."?") local s2=select("Yes", "No") if s2 == 1 then pc.block_exp(0) pc.give_exp2(-pc.get_exp()) syschat("<ExpBlockSystem> You reset your experience.") setskin(NOWINDOW) end end end end end
  15. [FIX]Block YANG SPAMMER!

    I heard about a tool that does this: WITHOUT SOURCE & WITH SOURCE: HOW TO ADD TIME LIMIT IN GAME: (THIS IS TIME LIMIT OF 30 SECONDS) HOW TO ADD TIME LIMIT INTO SOURCE: Open questmanager.cpp and change: With: (This is an example, 30 are seconds) HOW TO DISABLE THE FUNCTION: The fix is very easy, let's open the source of your binary, and go into char_item.cpp, find this: bool CHARACTER::DropGold(int gold) { if (gold <= 0 || gold > GetGold()) return false; if (!CanHandleItem()) return false; if (0 != g_GoldDropTimeLimitValue) { if (get_dword_time() < m_dwLastGoldDropTime+g_GoldDropTimeLimitValue) { ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You can't do this action. Wait the time limit.")); return false; } } m_dwLastGoldDropTime = get_dword_time(); LPITEM item = ITEM_MANAGER::instance().CreateItem(1, gold); if (item) { PIXEL_POSITION pos = GetXYZ(); if (item->AddToGround(GetMapIndex(), pos)) { PointChange(POINT_GOLD, -gold, true); if (gold > 1000) LogManager::instance().CharLog(this, gold, "DROP_GOLD", ""); item->StartDestroyEvent(150); //ChatPacket(CHAT_TYPE_INFO, LC_TEXT("떨어진 아이템은 %d분 후 사라집니다."), 150/60); } Save(); return true; } return false; } Replace this with: bool CHARACTER::DropGold(int gold) { return false; } Finish!
  16. c++ [C++/LUA] Lock / UnLock / Reset EXP RING

    I think you have some problem in Quest in database!
  17. open Server does not start(I can pay for fix)

    With what version of GCC you compiled that gamefile?
  18. Here: cmd_gm.cpp FUNCTIONS: #include <iostream> #include <vector> #include <string> void split(const std::string& s, char delim, std::vector<std::string>& v) { int i = 0; int pos = s.find(delim); while (pos != std::string::npos) { v.push_back(s.substr(i, pos-i)); i = ++pos; pos = s.find(delim, pos); if (pos == std::string::npos) v.push_back(s.substr(i, s.length())); } } int countChars(char* s, char c) { return *s == '\0' ? 0 : countChars( s + 1, c ) + (*s == c); } COMMAND: ACMD(do_create_item) { char item[256]; char bonus[1024]; two_arguments(argument, item, sizeof(item), bonus, sizeof(bonus)); if (!*item || !*bonus) { ch->ChatPacket(CHAT_TYPE_INFO, "Usage: /create_item <value_item> <b1:v1,b2:v2,b3:v3,b4:v4,b5:v5,b6:v6,b7:v7>"); ch->ChatPacket(CHAT_TYPE_INFO, ""); ch->ChatPacket(CHAT_TYPE_INFO, "[b] = Bonus vnum"); ch->ChatPacket(CHAT_TYPE_INFO, "[v] = Bonus value"); ch->ChatPacket(CHAT_TYPE_INFO, ""); ch->ChatPacket(CHAT_TYPE_INFO, "Created by RaFFa."); return; } if (bonus[(strlen(bonus)-1)] == ',') { ch->ChatPacket(CHAT_TYPE_INFO, "<CreateItem> [Err1] Syntax Error."); return; } if (bonus[(strlen(bonus)-1)] == ':') { ch->ChatPacket(CHAT_TYPE_INFO, "<CreateItem> [Err2] Syntax Error."); return; } if (strstr(bonus, ":") == NULL) { ch->ChatPacket(CHAT_TYPE_INFO, "<CreateItem> [Err3] Syntax Error."); return; } if (strstr(bonus, ",") == NULL) { ch->ChatPacket(CHAT_TYPE_INFO, "<CreateItem> Adding 1 bonus..."); int vnum=0; str_to_number(vnum, item); LPITEM i = ITEM_MANAGER::instance().CreateItem(vnum); if (!i) { ch->ChatPacket(CHAT_TYPE_INFO, "<CreateItem> This item-vnum not exists."); return; } int bonus_vnum=0; int bonus_value=0; std::vector<std::string> bonus2; split(std::string(bonus), ':', bonus2); str_to_number(bonus_vnum, std::string(bonus2[0]).c_str()); str_to_number(bonus_value, std::string(bonus2[1]).c_str()); i->SetForceAttribute(0, bonus_vnum, bonus_value); i->SetSocket(0, 1); int inventario = ch->GetEmptyInventory(i->GetSize()); if (inventario != -1) { i->AddToCharacter(ch, TItemPos(INVENTORY, inventario)); ch->ChatPacket(CHAT_TYPE_INFO, "<CreateItem> Item created successfully."); }else{ M2_DESTROY_ITEM(i); ch->ChatPacket(CHAT_TYPE_INFO, "<CreateItem> You haven't enough space in inventory."); } }else{ std::vector<std::string> bonus1; split(std::string(bonus), ',', bonus1); if (bonus1.size()>0) { ch->ChatPacket(CHAT_TYPE_INFO, "<CreateItem> Adding %d bonus...", (int)bonus1.size()); if (countChars(bonus, ':') != (int)bonus1.size()) { ch->ChatPacket(CHAT_TYPE_INFO, "<CreateItem> [Err4] Syntax Error."); return; } int vnum=0; str_to_number(vnum, item); LPITEM i = ITEM_MANAGER::instance().CreateItem(vnum); if (!i) { ch->ChatPacket(CHAT_TYPE_INFO, "<CreateItem> This item-vnum not exists."); return; } int b_size=bonus1.size(); if (bonus1.size()>6) b_size=7; int bonus_vnum=0; int bonus_value=0; for (int n=0; n<b_size; n++) { std::vector<std::string> bonus2; split(std::string(bonus1[n]), ':', bonus2); str_to_number(bonus_vnum, std::string(bonus2[0]).c_str()); str_to_number(bonus_value, std::string(bonus2[1]).c_str()); i->SetForceAttribute(n, bonus_vnum, bonus_value); } i->SetSocket(0, 1); int inventario = ch->GetEmptyInventory(i->GetSize()); if (inventario != -1) { i->AddToCharacter(ch, TItemPos(INVENTORY, inventario)); ch->ChatPacket(CHAT_TYPE_INFO, "<CreateItem> Item created successfully!"); }else{ M2_DESTROY_ITEM(i); ch->ChatPacket(CHAT_TYPE_INFO, "<CreateItem> You haven't enough space in inventory."); } } } } cmd.cpp ACMD(do_create_item); and: (into the struct command_info cmd_info[]) {"create_item", do_create_item, 0, POS_DEAD, GM_IMPLEMENTOR},
  19. Open input.cpp Make your Analyze function like mine: int CInputHandshake::Analyze(LPDESC d, BYTE bHeader, const char * c_pData) { //YOUR THINGS if (bHeader == 10) return 0; if (bHeader == HEADER_CG_TEXT)// HEADER_CG_TEXT = 64 -> 64 IN HEXADECIMAL = 0x40 { ++c_pData; const char * c_pSep; if (!(c_pSep = strchr(c_pData, '\n'))) return -1; if (*(c_pSep - 1) == '\r') --c_pSep; std::string stResult; std::string stBuf; stBuf.assign(c_pData, 0, c_pSep - c_pData); //sys_log(0, "SOCKET_CMD: FROM(%s) CMD(%s)", d->GetHostName(), stBuf.c_str()); if (!stBuf.compare("PLAYER_ONLINE")) { std::string risultato=""; if (!IsInList(inet_ntoa(d->GetAddr().sin_addr))) { risultato += "[WebPanel::OnlineCounter] Access Denied."; //sys_err("[WebPanel] %s has tried to connect in the web panel.", inet_ntoa(d->GetAddr().sin_addr)); }else{ int iTotal; int *paiEmpireUserCount; int iLocal; DESC_MANAGER::instance().GetUserCount(iTotal, &paiEmpireUserCount, iLocal); risultato += format("Player Online: %d\nShinsoo: %d\nChunjo: %d\nJinno: %d", iTotal, paiEmpireUserCount[1], paiEmpireUserCount[2], paiEmpireUserCount[3]); } stResult += risultato; } else if (!stBuf.compare("PLAYER_RANKLIST")) { std::string risultato=""; if (!IsInList(inet_ntoa(d->GetAddr().sin_addr))) { risultato += "[WebPanel::Ranklist] Access Denied."; //sys_err("[WebPanel] %s has tried to connect in the web panel.", inet_ntoa(d->GetAddr().sin_addr)); }else{ std::string Ranklist=""; char classifica[1024]={0}; snprintf(classifica, sizeof(classifica), "SELECT name, level FROM player.player%s WHERE account_id=(SELECT id FROM account.account%s WHERE status='OK' AND id=account_id) ORDER BY level DESC LIMIT 10;", get_table_postfix(), get_table_postfix()); SQLMsg * res = DBManager::instance().DirectQuery(classifica); if (res->Get()->uiNumRows == 0) { M2_DELETE(res); risultato += "Players not found."; } Ranklist+="<Top 10 Player>\n\n"; int pos=0; for (uint i=0; i<res->Get()->uiNumRows; i++) { MYSQL_ROW rows=mysql_fetch_row(res->Get()->pSQLResult); std::string name=std::string(rows[0]); if (name[0] != '[') { pos=i+1; std::string space=""; for (unsigned s=0; s<=(25 - (int)name.length()); s++) space+=" "; Ranklist+=format("%d | %s%s | Lv.%s\n", pos, name.c_str(), space.c_str(), rows[1]); }else{ pos=i-1; } } M2_DELETE(res); risultato += Ranklist; } stResult += risultato; } else if (stBuf.find("ACCOUNT_REGISTER") != std::string::npos) { std::string risultato=""; if (!IsInList(inet_ntoa(d->GetAddr().sin_addr))) { risultato += "[WebPanel::RegisterAccount] Access Denied."; //sys_err("[WebPanel] %s has tried to connect in the web panel.", inet_ntoa(d->GetAddr().sin_addr)); }else{ std::vector<std::string> args; std::string status; boost::split(args, stBuf, boost::is_any_of(",")); if (args.size() > 0 && args[0].compare("ACCOUNT_REGISTER") == 0) { status=RegisterAccount(args[1], args[2], args[3], args[4], inet_ntoa(d->GetAddr().sin_addr)); }else{ status="[RegisterAccount] Syntax Error."; } risultato += status; } stResult += risultato; } else if (stBuf.find("ACCOUNT_CHANGEPSW") != std::string::npos) { std::string risultato=""; if (!IsInList(inet_ntoa(d->GetAddr().sin_addr))) { risultato += "[WebPanel::ChangePassword] Access Denied."; //sys_err("[WebPanel] %s has tried to connect in the web panel.", inet_ntoa(d->GetAddr().sin_addr)); }else{ std::vector<std::string> args; std::string status; boost::split(args, stBuf, boost::is_any_of(",")); if (args.size() > 0 && args[0].compare("ACCOUNT_CHANGEPSW") == 0) { status=ChangePassword(args[1], args[2], args[3]); }else{ status="[ChangePassword] Syntax Error."; } risultato += status; } stResult += risultato; } stResult += "\n"; d->Packet(stResult.c_str(), stResult.length()); return (c_pSep - c_pData) + 1; } //CONTINUE YOUR THINGS NOW, THE FUNCTIONS: //REMEMBER AT THE TOP OF FILE: //#include <fstream> //#include <boost/algorithm/string.hpp> inline std::string format(const char* fmt, ...) { int size = 512; char* buffer = 0; buffer = new char[size]; va_list vl; va_start(vl, fmt); int nsize = vsnprintf(buffer, size, fmt, vl); if(size<=nsize){ delete[] buffer; buffer = 0; buffer = new char[nsize+1]; nsize = vsnprintf(buffer, size, fmt, vl); } std::string ret(buffer); va_end(vl); delete[] buffer; return ret; } inline bool IsInList(const char *ip) { bool ritorno=false; std::ifstream ifs("locale/pannello_web_ip.txt", std::ifstream::in); if (ifs.fail()) { sys_err("[Web Panel] The file [locale/pannello_web_ip.txt] was not found."); return ritorno; } char c=ifs.get(); std::string read; while (ifs.good()) { read += c; c=ifs.get(); } ifs.close(); if (strstr(read.c_str(), std::string(std::string(ip)+std::string("\n")).c_str()) != NULL) ritorno=true; return ritorno; } bool is_email(std::string const& address) { size_t at_index = address.find_first_of('@', 0); return at_index != std::string::npos && address.find_first_of('.', at_index) != std::string::npos; } std::string RegisterAccount(std::string login, std::string password, std::string email, std::string social_id, const char *ip) { char EscapedLogin[255]={0}; char EscapedPassword[255]={0}; char EscapedSocialID[255]={0}; char EscapedEmail[255]={0}; DBManager::instance().EscapeString(EscapedLogin, sizeof(EscapedLogin), login.c_str(), strlen(login.c_str())); DBManager::instance().EscapeString(EscapedPassword, sizeof(EscapedPassword), password.c_str(), strlen(password.c_str())); DBManager::instance().EscapeString(EscapedSocialID, sizeof(EscapedSocialID), social_id.c_str(), strlen(social_id.c_str())); DBManager::instance().EscapeString(EscapedEmail, sizeof(EscapedEmail), email.c_str(), strlen(email.c_str())); if (strlen(EscapedLogin)<2) return "[RegisterAccount] Login can't be < 2 chars."; if (strlen(EscapedPassword)<3) return "[RegisterAccount] Password can't be < 3 chars."; if (strlen(EscapedEmail)<5) return "[RegisterAccount] Email can't be < 5 chars."; if (strlen(EscapedLogin)>20) return "[RegisterAccount] Login can't be > 20 chars."; if (strlen(EscapedPassword)>30) return "[RegisterAccount] Password can't be > 30 chars."; if (strlen(EscapedEmail)>50) return "[RegisterAccount] Email can't be > 50 chars."; if (strlen(EscapedSocialID)<3) return "[RegisterAccount] Social id can't be < 3 chars."; if (strlen(EscapedSocialID)>7) return "[RegisterAccount] Social id can't be > 7 chars."; if (!is_email(std::string(EscapedEmail))) return "[RegisterAccount] Email is not valid."; char iscrizione[1024]={0}; snprintf(iscrizione, sizeof(iscrizione), "INSERT INTO account.account%s (login, password, social_id, email, create_time, status, gold_expire, silver_expire, safebox_expire, autoloot_expire, fish_mind_expire, marriage_fast_expire, money_drop_rate_expire, web_ip) " "VALUES ('%s', password('%s'), '%s', '%s', NOW(), 'OK', '2025-01-01 00:00:00', '2025-01-01 00:00:00', '2025-01-01 00:00:00', '2025-01-01 00:00:00', '2025-01-01 00:00:00', '2025-01-01 00:00:00', '2025-01-01 00:00:00', '%s')", get_table_postfix(), EscapedLogin, EscapedPassword, EscapedSocialID, EscapedEmail, ip); std::auto_ptr<SQLMsg> res(DBManager::instance().DirectQuery(iscrizione)); if (res->Get()->uiAffectedRows == 0 || res->Get()->uiAffectedRows == (uint32_t)-1) return "[RegisterAccount] The account name already exists, try with another account name."; return "[RegisterAccount] Registration done!"; } std::string ChangePassword(std::string login, std::string password, std::string password2) { char EscapedLogin[255]={0}; char EscapedPassword[255]={0}; char EscapedPassword2[255]={0}; DBManager::instance().EscapeString(EscapedLogin, sizeof(EscapedLogin), login.c_str(), strlen(login.c_str())); DBManager::instance().EscapeString(EscapedPassword, sizeof(EscapedPassword), password.c_str(), strlen(password.c_str())); DBManager::instance().EscapeString(EscapedPassword2, sizeof(EscapedPassword2), password2.c_str(), strlen(password2.c_str())); if (!strcmp(EscapedPassword, EscapedPassword2)) return "[ChangePassword] The new password is the same."; if (strlen(EscapedLogin)<2) return "[ChangePassword] Login can't be < 2 chars."; if (strlen(EscapedPassword)<3) return "[ChangePassword] Password can't be < 3 chars."; if (strlen(EscapedPassword2)<3) return "[ChangePassword] New Password can't be < 3 chars."; if (strlen(EscapedLogin)>20) return "[ChangePassword] Login can't be > 20 chars."; if (strlen(EscapedPassword)>30) return "[ChangePassword] Password can't be > 30 chars."; if (strlen(EscapedPassword2)>30) return "[ChangePassword] New Password can't be > 30 chars."; char cambio_psw[1024]={0}; snprintf(cambio_psw, sizeof(cambio_psw), "UPDATE account.account%s SET password=password('%s') WHERE login='%s' AND password=password('%s')", get_table_postfix(), EscapedPassword2, EscapedLogin, EscapedPassword); std::auto_ptr<SQLMsg> res(DBManager::instance().DirectQuery(cambio_psw)); if (res->Get()->uiAffectedRows == 0 || res->Get()->uiAffectedRows == (uint32_t)-1) return "[ChangePassword] Login or Password are incorrect."; return "[ChangePassword] Password changed successfully!"; } PYTHON EXAMPLE: def __Try(ip, port): try: import socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((ip, port)) s.send("\x40PLAYER_ONLINE\n") s.recv(100) s.send("\x40PLAYER_ONLINE\n") print s.recv(1024) s.send("\x40PLAYER_RANKLIST\n") print s.recv(1024) s.send("\x40ACCOUNT_REGISTER,Raffa123,pass123,hello@gmail.com,1234567\n") print s.recv(1024) s.send("\x40ACCOUNT_CHANGEPSW,Raffa123,pass123,pass456\n") print s.recv(1024) s.close() except (socket.gaierror, socket.error, socket.herror, socket.timeout): print "[Server] Server is not online. [%s:%d]" % (ip, port) __Try("IP_CH1", PORT_CH1) import os os.system("pause") BE SAFE YOUR PANEL: Open packet.h find HEADER_CG_TEXT = 64, and change the 64 with another number of packet, but remember that the number must be unused by other packet. And replace in your scripts the \x40 with the other number in HEXADECIMAL, because 64 in hexadecimal is 0x40, use google to find the hexadecimal of a number and put the escape char, final RESULT: \0x40MYCOMMAND REMEMBER TO create the pannello_web_ip.txt into your locale folder. IN THAT FILE PUT THE IP ADDRESS OF YOUR HOST OF THE WEBSITE, for any errors or log, just check the syserr.txt. You can use your SOCKET API in PHP or Other languages With this you can insert your registration or ranklist or status or others and others without PUT THE "CREDENTIAL of Database".
  20. One word, go away from this topic if you don't like the content. Yes is true, is true that you need a good php hosting
  21. EXPLAIN THE BUG: A lot of time if you restart the server or the server was rebooted with the game alive, the TABLE of the offline shop of koray will be corrupted or deleted... Why? The reason we don't know, cause koray systems are full a lot of bug... (maybe because he's not a coder but a reseller...) But this is not important now, we are here to fix these bugs, not to talk about who is koray. FIX: Find your InitializeOfflineShopTable function into ClientManagerBoot.cpp of the db source: And use my function: #ifdef __OFFLINE_SHOP__ bool CClientManager::InitializeOfflineShopTable() { DWORD dwItems[SHOP_HOST_ITEM_MAX_NUM]; char exist_table[QUERY_MAX_LEN]; snprintf(exist_table, sizeof(exist_table), "SELECT * FROM offline_shop%s", GetTablePostfix()); std::auto_ptr<SQLMsg> exist(CDBManager::instance().DirectQuery(exist_table)); if (exist->Get()->uiAffectedRows == (uint32_t)-1) { sys_err("Table: offline_shop%s corrupted or not found, let me create it.", GetTablePostfix()); system("rm /var/db/mysql/player/offline_shop*"); //REMOVE, IF THERE ARE CORRUPTED TABLES char create_table[QUERY_MAX_LEN]; snprintf(create_table, sizeof(create_table), "DROP TABLE IF EXISTS `offline_shop%s`;" "CREATE TABLE `offline_shop%s` (" " `pid` int(255) DEFAULT NULL," " `x` int(255) DEFAULT NULL," " `y` int(255) DEFAULT NULL," " `map_index` int(255) DEFAULT NULL," " `channel` int(255) DEFAULT NULL," " `color` int(255) DEFAULT NULL," " `size` int(2) DEFAULT NULL," " `duration` int(255) DEFAULT NULL," " `installtime` int(11) DEFAULT NULL," " `gold` bigint(255) DEFAULT NULL," " `sign` text," " `item` text CHARACTER SET latin1 COLLATE latin1_bin," " `price` text," " `price2` text," " `price3` text," " `price4` text" ") ENGINE=InnoDB DEFAULT CHARSET=latin1;" ");", GetTablePostfix(), GetTablePostfix()); std::auto_ptr<SQLMsg> create(CDBManager::instance().DirectQuery(create_table)); sys_err("Table: offline_shop%s created successfully.", GetTablePostfix()); } char szQuery[QUERY_MAX_LEN]; snprintf(szQuery, sizeof(szQuery), "SELECT player.account_id,shop.pid,shop.x,shop.y,shop.map_index,shop.channel,shop.duration,shop.installtime,shop.size,shop.gold,shop.item,shop.price,shop.price2,shop.price3,shop.price4,player.name,shop.sign,shop.color " "FROM offline_shop%s AS shop LEFT JOIN player%s AS player " "ON shop.pid=player.id WHERE player.name IS NOT NULL", GetTablePostfix(), GetTablePostfix()); std::auto_ptr<SQLMsg> pMsg(CDBManager::instance().DirectQuery(szQuery)); SQLResult* pRes = pMsg->Get(); m_pOfflineShopTable = new TOfflineShopTable[pRes->uiNumRows]; memset(m_pOfflineShopTable, 0, sizeof(TOfflineShopTable) * pRes->uiNumRows); while (MYSQL_ROW row = mysql_fetch_row(pRes->pSQLResult)) { int idx = 0; TOfflineShopTable& shop_table = m_pOfflineShopTable[m_iOfflineShopTableSize++]; str_to_number(shop_table.dwAID, row[idx++]); str_to_number(shop_table.dwPID, row[idx++]); str_to_number(shop_table.dwX, row[idx++]); str_to_number(shop_table.dwY, row[idx++]); str_to_number(shop_table.dwMapIndex, row[idx++]); str_to_number(shop_table.dwChannel, row[idx++]); str_to_number(shop_table.dwDuration, row[idx++]); str_to_number(shop_table.dwInstallTime, row[idx++]); str_to_number(shop_table.dwSize, row[idx++]); str_to_number(shop_table.ullMoney, row[idx++]); thecore_memcpy(dwItems, row[idx++], sizeof(dwItems)); thecore_memcpy(shop_table.price, row[idx++], sizeof(shop_table.price)); thecore_memcpy(shop_table.price2, row[idx++], sizeof(shop_table.price2)); thecore_memcpy(shop_table.price3, row[idx++], sizeof(shop_table.price3)); thecore_memcpy(shop_table.price4, row[idx++], sizeof(shop_table.price4)); strlcpy(shop_table.szName, row[idx++], sizeof(shop_table.szName)); strlcpy(shop_table.szSign, row[idx++], sizeof(shop_table.szSign)); str_to_number(shop_table.dwColor, row[idx++]); CreateItemCacheSet(shop_table.dwPID); char szSockets[QUERY_MAX_LEN / 2] = { '\0' }, szAttrs[QUERY_MAX_LEN / 2] = { '\0' }; char *pTmpSockets = szSockets, *pTmpAttrs = szAttrs; int i = 0; for (i = 0; i < ITEM_ATTRIBUTE_MAX_NUM; i++) { pTmpAttrs += (i < 7) ? sprintf(pTmpAttrs, "attrtype%d,attrvalue%d", i, i) : sprintf(pTmpAttrs, "applytype%d,applyvalue%d", i - 7, i - 7); if (i < ITEM_ATTRIBUTE_MAX_NUM - 1) pTmpAttrs += sprintf(pTmpAttrs, ","); } for (i = 0; i < ITEM_SOCKET_MAX_NUM; i++) { pTmpSockets += sprintf(pTmpSockets, "socket%d", i); if (i < ITEM_SOCKET_MAX_NUM - 1) pTmpSockets += sprintf(pTmpSockets, ","); } snprintf(szQuery, sizeof(szQuery), "SELECT id,pos,count," "vnum,%s,%s " "FROM item%s WHERE owner_id=%d AND window=%d", szSockets, szAttrs, GetTablePostfix(), shop_table.dwPID, OFFLINE_SHOP); std::auto_ptr<SQLMsg> pMsg2(CDBManager::instance().DirectQuery(szQuery)); SQLResult* pRes2 = pMsg2->Get(); DWORD dwItemID, dwItemPos; while (MYSQL_ROW row2 = mysql_fetch_row(pRes2->pSQLResult)) { int idx2 = 0; str_to_number(dwItemID, row2[idx2++]); str_to_number(dwItemPos, row2[idx2++]); if (dwItemID != dwItems[dwItemPos]) continue; TPlayerItem& pItem = shop_table.items[dwItemPos]; pItem.id = dwItemID; pItem.pos = dwItemPos; str_to_number(pItem.count, row2[idx2++]); str_to_number(pItem.vnum, row2[idx2++]); int i = 0; for (i = 0; i < ITEM_SOCKET_MAX_NUM; i++) str_to_number(pItem.alSockets[i], row2[idx2++]); for (i = 0; i < ITEM_ATTRIBUTE_MAX_NUM; i++) { str_to_number(pItem.aAttr[i].bType, row2[idx2++]); str_to_number(pItem.aAttr[i].sValue, row2[idx2++]); } pItem.window = OFFLINE_SHOP; pItem.owner = shop_table.dwPID; PutItemCache(&pItem, true); } } return true; } #endif
  22. Yes sorry you have right, i will make another version of the fix with REPAIR. thank you
  23. Today i get this problem, when i enter in a party dungeon and someone of the party goes offline or warp in another map, the core crashed. I want give all my idea to fix that, i know that is not the best method to fix that but i think for someone can be useful. I tried to fix the problem with the tutorial on metin2dev with SetDungeon(NULL) in SetParty but without any results, the bug continue... This is my fix/idea: When someone goes offline all the members of the group will go to the own village and the core doesn't crash. Open party.cpp and replace your UpdateOfflineState function with this: void CParty::UpdateOfflineState(DWORD dwPID) { TPacketGCPartyAdd p; p.header = HEADER_GC_PARTY_ADD; p.pid = dwPID; memset(p.name, 0, CHARACTER_NAME_MAX_LEN+1); for (TMemberMap::iterator it = m_memberMap.begin(); it != m_memberMap.end(); ++it) { if (it->second.pCharacter && it->second.pCharacter->GetDesc()) { if (it->second.pCharacter->GetDungeon()) { LPDUNGEON dung=it->second.pCharacter->GetDungeon(); dung->ExitAllToStartPosition(); }else{ it->second.pCharacter->GetDesc()->Packet(&p, sizeof(p)); } } } }
×