Premium masodikbela 1359 Posted January 17, 2016 Premium Share Posted January 17, 2016 (edited) M2 Download Center This is the hidden content, please Sign In or Sign Up ( Internal ) Hi there devs, I made some new reload commands about 2 weeks ago and published a tutorial about it on our Hungarian forum (you may saw them in the samurai core) and today I had some time to make the translation. What can I reload now? refine_proto (this is the only one which is not mine, its @xP3NG3Rx's, and already public here, but I added it, because I think this package has to contain it ) command: /reload p shop_item table (npc's shops) command: /reload p item_attr && item_attr_rare table; command: /reload p etc_drop_item.txt, mob_drop_item.txt, special_item_group.txt; command: /reload drop group.txt, group_group.txt; command: /reload group regen.txt, npc.txt, boss.txt, stone.txt (only on the current map) command: /reload regen because of the new "reload regen" command, I had to write a new purge command that destroys all mobs, npcs, stones (and so on...) on the current map, so I added a new /p map command to the "/p" commands that are already exists (no, the "/p all" only destroys the mobs on the current sectree (current block)) also I had to create a new command that stops all the regens (and ofc. deletes them from the memory) on the current map, so I added a new "/free_regens" command (because why not ) Its only deletes the loaded regens, and prevents the mobs from respawning (its not necessary to use this before the /reload regen) Known bug Well its not a serious problem, but for some unknown reason, when I'm debugging the core on windows server (no, not debug mode, but vs 13's debugger) and I try to do /reload regen, the core starts to consume ~40% cpu, and doesn't want to do anything (so stops working, but doesn't crash). It has no affect on FreeBSD and release or debug mode (without visual studio's debugger) on windows. Spoiler If you get fcked up codes like me, try to remove the pagestyle in your browser. game/src cmd.cpp Spoiler Add this to the top of the file (where you can find more ACMDs) ACMD(do_free_regen); Then above this: { "who", do_who, 0, POS_DEAD, GM_IMPLEMENTOR }, Add this: { "free_regens", do_free_regen, 0, POS_DEAD, GM_IMPLEMENTOR }, cmd_gm.cpp Spoiler Add this to the end of the file: ACMD(do_free_regen) { ch->ChatPacket(CHAT_TYPE_INFO, "freeing regens on mapindex %ld", ch->GetMapIndex()); regen_free_map(ch->GetMapIndex()); ch->ChatPacket(CHAT_TYPE_INFO, "the regens now FREEEE! :)"); } Replace the ACMD(do_purge) with this: ACMD(do_purge) { char arg1[256]; one_argument(argument, arg1, sizeof(arg1)); FuncPurge func(ch); if (*arg1 && !strcmp(arg1, "map")) { CHARACTER_MANAGER::instance().DestroyCharacterInMap(ch->GetMapIndex()); } else { if (*arg1 && !strcmp(arg1, "all")) func.m_bAll = true; LPSECTREE sectree = ch->GetSectree(); if (sectree) // #431 sectree->ForEachAround(func); else sys_err("PURGE_ERROR.NULL_SECTREE(mapIndex=%d, pos=(%d, %d)", ch->GetMapIndex(), ch->GetX(), ch->GetY()); } } In the ACMD(do_reload) function under this: case 'c': // cube // ·ÎÄĂ ÇÁ·ÎĽĽ˝ş¸¸ °»»ęÇŃ´Ů. Cube_init (); break; Insert this: default: const int FILE_NAME_LEN = 256; if (strstr(arg1, "drop")) { char szETCDropItemFileName[FILE_NAME_LEN]; char szMOBDropItemFileName[FILE_NAME_LEN]; char szSpecialItemGroupFileName[FILE_NAME_LEN]; snprintf(szETCDropItemFileName, sizeof(szETCDropItemFileName), "%s/etc_drop_item.txt", LocaleService_GetBasePath().c_str()); snprintf(szMOBDropItemFileName, sizeof(szMOBDropItemFileName), "%s/mob_drop_item.txt", LocaleService_GetBasePath().c_str()); snprintf(szSpecialItemGroupFileName, sizeof(szSpecialItemGroupFileName), "%s/special_item_group.txt", LocaleService_GetBasePath().c_str()); ch->ChatPacket(CHAT_TYPE_INFO, "Reloading: ETCDropItem: %s", szETCDropItemFileName); if (!ITEM_MANAGER::instance().ReadEtcDropItemFile(szETCDropItemFileName, true)) ch->ChatPacket(CHAT_TYPE_INFO, "failed to reload ETCDropItem: %s", szETCDropItemFileName); else ch->ChatPacket(CHAT_TYPE_INFO, "reload success: ETCDropItem: %s", szETCDropItemFileName); ch->ChatPacket(CHAT_TYPE_INFO, "Reloading: SpecialItemGroup: %s", szSpecialItemGroupFileName); if (!ITEM_MANAGER::instance().ReadSpecialDropItemFile(szSpecialItemGroupFileName, true)) ch->ChatPacket(CHAT_TYPE_INFO, "failed to reload SpecialItemGroup: %s", szSpecialItemGroupFileName); else ch->ChatPacket(CHAT_TYPE_INFO, "reload success: SpecialItemGroup: %s", szSpecialItemGroupFileName); ch->ChatPacket(CHAT_TYPE_INFO, "Reloading: MOBDropItemFile: %s", szMOBDropItemFileName); if (!ITEM_MANAGER::instance().ReadMonsterDropItemGroup(szMOBDropItemFileName, true)) ch->ChatPacket(CHAT_TYPE_INFO, "failed to reload MOBDropItemFile: %s", szMOBDropItemFileName); else ch->ChatPacket(CHAT_TYPE_INFO, "reload success: MOBDropItemFile: %s", szMOBDropItemFileName); } else if (strstr(arg1, "group")) { char szGroupFileName[FILE_NAME_LEN]; char szGroupGroupFileName[FILE_NAME_LEN]; snprintf(szGroupFileName, sizeof(szGroupGroupFileName), "%s/group.txt", LocaleService_GetBasePath().c_str()); snprintf(szGroupGroupFileName, sizeof(szGroupGroupFileName), "%s/group_group.txt", LocaleService_GetBasePath().c_str()); ch->ChatPacket(CHAT_TYPE_INFO, "Reloading: mob groups: %s", szGroupFileName); if (!CMobManager::instance().LoadGroup(szGroupFileName, true)) ch->ChatPacket(CHAT_TYPE_INFO, "failed to reload mob groups: %s", szGroupFileName); ch->ChatPacket(CHAT_TYPE_INFO, "Reloading: mob group group: %s", szGroupGroupFileName); if (!CMobManager::instance().LoadGroupGroup(szGroupGroupFileName, true)) ch->ChatPacket(CHAT_TYPE_INFO, "failed to reload mob group group: %s", szGroupGroupFileName); } else if (strstr(arg1, "regen")) { SendNoticeMap("Reloading regens!", ch->GetMapIndex(), false); regen_free_map(ch->GetMapIndex()); CHARACTER_MANAGER::instance().DestroyCharacterInMap(ch->GetMapIndex()); regen_reload(ch->GetMapIndex()); SendNoticeMap("Regens reloaded!", ch->GetMapIndex(), false); } break; input_db.cpp Spoiler void CInputDB::ReloadProto(const char * c_pData) Above this: CMotionManager::instance().Build(); Add this: /* * SHOP */ wSize = decode_2bytes(c_pData); c_pData += sizeof(WORD); sys_log(0, "RELOAD: SHOP: %d", wSize); if (wSize) { CShopManager::instance().Initialize((TShopTable *)c_pData, wSize); c_pData += wSize * sizeof(TShopTable); } /* * REFINE */ wSize = decode_2bytes(c_pData); c_pData += 2; sys_log(0, "RELOAD: REFINE: %d", wSize); if (wSize) { CRefineManager::instance().Initialize((TRefineTable *)c_pData, wSize); c_pData += wSize * sizeof(TRefineTable); } /* * ATTR */ wSize = decode_2bytes(c_pData); c_pData += 2; sys_log(0, "RELOAD: ItemAtt: %d", wSize); if (wSize) { TItemAttrTable * p = (TItemAttrTable *)c_pData; g_map_itemAttr.clear(); for (int i = 0; i < wSize; ++i, ++p) { if (p->dwApplyIndex >= MAX_APPLY_NUM) continue; g_map_itemAttr[p->dwApplyIndex] = *p; sys_log(0, "ITEM_ATTR[%d]: %s %u", p->dwApplyIndex, p->szApply, p->dwProb); } c_pData += wSize*sizeof(TItemAttrTable); } /* * ATTR_RARE */ wSize = decode_2bytes(c_pData); c_pData += 2; sys_log(0, "RELOAD: ItemRareAtt: %d", wSize); if (wSize) { TItemAttrTable * p = (TItemAttrTable *)c_pData; g_map_itemRare.clear(); for (int i = 0; i < wSize; ++i, ++p) { if (p->dwApplyIndex >= MAX_APPLY_NUM) continue; g_map_itemRare[p->dwApplyIndex] = *p; sys_log(0, "ITEM_RARE[%d]: %s %u", p->dwApplyIndex, p->szApply, p->dwProb); } c_pData += wSize*sizeof(TItemAttrTable); } shop_manager.cpp Spoiler bool CShopManager::Initialize(TShopTable * table, int size Replace this: if (!m_map_pkShop.empty()) return false; With this: if (!m_map_pkShop.empty()) { for (TShopMap::iterator it = m_map_pkShop.begin(); it != m_map_pkShop.end(); it++) { it->second->RemoveAllGuests(); } } m_map_pkShop.clear(); m_map_pkShopByNPCVnum.clear(); refine.cpp Spoiler Insert this to the top of this function:bool CRefineManager::Initialize(TRefineTable * table, int size) m_map_RefineRecipe.clear(); char_manager.cpp Spoiler Insert this to the end of the file: void CHARACTER_MANAGER::DestroyCharacterInMap(long lMapIndex) { std::vector<LPCHARACTER> tempVec; for (itertype(m_map_pkChrByVID) it = m_map_pkChrByVID.begin(); it != m_map_pkChrByVID.end(); it++) { LPCHARACTER pkChr = it->second; if (pkChr && pkChr->GetMapIndex() == lMapIndex && pkChr->IsNPC() && !pkChr->IsPet() && pkChr->GetRider() == NULL) { tempVec.push_back(pkChr); } } for (std::vector<LPCHARACTER>::iterator it = tempVec.begin(); it != tempVec.end(); it++) { DestroyCharacter(*it); } } char_manager.h Spoiler Above this: void Update(int iPulse); Insert this: void DestroyCharacterInMap(long lMapIndex); item_manager.h Spoiler Replace this: bool ReadEtcDropItemFile(const char * c_pszFileName); bool ReadMonsterDropItemGroup(const char * c_pszFileName); bool ReadSpecialDropItemFile(const char * c_pszFileName); With this: bool ReadEtcDropItemFile(const char * c_pszFileName, bool isReloading = false); bool ReadMonsterDropItemGroup(const char * c_pszFileName, bool isReloading = false); bool ReadSpecialDropItemFile(const char * c_pszFileName, bool isReloading = false); item_manager_read_tables.cpp Spoiler Firstly replace this: bool ITEM_MANAGER::ReadEtcDropItemFile(const char * c_pszFileName) With this: bool ITEM_MANAGER::ReadEtcDropItemFile(const char * c_pszFileName, bool isReloading) Now we will work in this function we just edited. Above this: char buf[512] Insert this: std::map<DWORD, DWORD> tempLoader; if (isReloading) { sys_log(0, "RELOADING EtcDrop"); } Then replace this: m_map_dwEtcItemDropProb[dwItemVnum] = (DWORD) (fProb * 10000.0f); With this: if (isReloading) tempLoader[dwItemVnum] = (DWORD)(fProb * 10000.0f); else m_map_dwEtcItemDropProb[dwItemVnum] = (DWORD) (fProb * 10000.0f); Add this above the return true; that we can find at the end of the function: if (isReloading) { m_map_dwEtcItemDropProb.clear(); for (std::map<DWORD, DWORD>::iterator it = tempLoader.begin(); it != tempLoader.end(); it++) { m_map_dwEtcItemDropProb[it->first] = it->second; } } Okay, now we finished this function. Lets search for this: bool ITEM_MANAGER::ReadSpecialDropItemFile(const char * c_pszFileName) Then replace with this: bool ITEM_MANAGER::ReadSpecialDropItemFile(const char * c_pszFileName, bool isReloading) Okay, we will work in this function. Before the first for loop add this: std::map<DWORD, CSpecialAttrGroup*> tempSpecAttr; std::map<DWORD, CSpecialItemGroup*> tempSpecItem; std::map<DWORD, CSpecialItemGroup*> tempSpecItemQuest; if (isReloading) sys_log(0, "RELOADING SpecialDrop"); Then replace this: m_map_pkSpecialAttrGroup.insert(std::make_pair(iVnum, pkGroup)); With this: if (isReloading) tempSpecAttr.insert(std::make_pair(iVnum, pkGroup)); else m_map_pkSpecialAttrGroup.insert(std::make_pair(iVnum, pkGroup)); Then replace this: if (CSpecialItemGroup::QUEST == type) { m_map_pkQuestItemGroup.insert(std::make_pair(iVnum, pkGroup)); } else { m_map_pkSpecialItemGroup.insert(std::make_pair(iVnum, pkGroup)); } With this: if (CSpecialItemGroup::QUEST == type) { if (isReloading) tempSpecItemQuest.insert(std::make_pair(iVnum, pkGroup)); else m_map_pkQuestItemGroup.insert(std::make_pair(iVnum, pkGroup)); } else { if (isReloading) tempSpecItem.insert(std::make_pair(iVnum, pkGroup)); else m_map_pkSpecialItemGroup.insert(std::make_pair(iVnum, pkGroup)); } Again, above the return true; (we can find this at the end of the function) add this: if (isReloading) { m_map_pkQuestItemGroup.clear(); m_map_pkSpecialItemGroup.clear(); m_map_pkSpecialAttrGroup.clear(); for (std::map<DWORD, CSpecialAttrGroup*>::iterator it = tempSpecAttr.begin(); it != tempSpecAttr.end(); it++) { m_map_pkSpecialAttrGroup[it->first] = it->second; } for (std::map<DWORD, CSpecialItemGroup*>::iterator it = tempSpecItem.begin(); it != tempSpecItem.end(); it++) { m_map_pkSpecialItemGroup[it->first] = it->second; } for (std::map<DWORD, CSpecialItemGroup*>::iterator it = tempSpecItemQuest.begin(); it != tempSpecItemQuest.end(); it++) { m_map_pkQuestItemGroup[it->first] = it->second; } } Lets search for a new function. Replace this: bool ITEM_MANAGER::ReadMonsterDropItemGroup(const char * c_pszFileName) With this: bool ITEM_MANAGER::ReadMonsterDropItemGroup(const char * c_pszFileName, bool isReloading) Okay, we will work again in the "just edited" function. Before the first for loop add this: std::map<DWORD, CMobItemGroup*> temMobItemGr; std::map<DWORD, CDropItemGroup*> tempDropItemGr; std::map<DWORD, CLevelItemGroup*> tempLevelItemGr; std::map<DWORD, CBuyerThiefGlovesItemGroup*> tempThiefGlovesGr; if (isReloading) { sys_log(0, "RELOADING MonsterDrop"); } Replace this: m_map_pkMobItemGroup.insert(std::map<DWORD, CMobItemGroup*>::value_type(iMobVnum, pkGroup)); With this: if (isReloading) temMobItemGr.insert(std::map<DWORD, CMobItemGroup*>::value_type(iMobVnum, pkGroup)); else m_map_pkMobItemGroup.insert(std::map<DWORD, CMobItemGroup*>::value_type(iMobVnum, pkGroup)); Then this: itertype(m_map_pkDropItemGroup) it = m_map_pkDropItemGroup.find(iMobVnum); if (it == m_map_pkDropItemGroup.end()) { pkGroup = M2_NEW CDropItemGroup(0, iMobVnum, stName); } else { bNew = false; CDropItemGroup* pkGroup = it->second; } With this: if (isReloading) { itertype(tempDropItemGr) it = tempDropItemGr.find(iMobVnum); if (it == tempDropItemGr.end()) { pkGroup = M2_NEW CDropItemGroup(0, iMobVnum, stName); } else { bNew = false; CDropItemGroup* pkGroup = it->second; } } else { itertype(m_map_pkDropItemGroup) it = m_map_pkDropItemGroup.find(iMobVnum); if (it == m_map_pkDropItemGroup.end()) { pkGroup = M2_NEW CDropItemGroup(0, iMobVnum, stName); } else { bNew = false; CDropItemGroup* pkGroup = it->second; } } Replace this: if (bNew) m_map_pkDropItemGroup.insert(std::map<DWORD, CDropItemGroup*>::value_type(iMobVnum, pkGroup)); With this: if (bNew) { if (isReloading) tempDropItemGr.insert(std::map<DWORD, CDropItemGroup*>::value_type(iMobVnum, pkGroup)); else m_map_pkDropItemGroup.insert(std::map<DWORD, CDropItemGroup*>::value_type(iMobVnum, pkGroup)); } This: m_map_pkLevelItemGroup.insert(std::map<DWORD, CLevelItemGroup*>::value_type(iMobVnum, pkLevelItemGroup)); With this: if (isReloading) tempLevelItemGr.insert(std::map<DWORD, CLevelItemGroup*>::value_type(iMobVnum, pkLevelItemGroup)); else m_map_pkLevelItemGroup.insert(std::map<DWORD, CLevelItemGroup*>::value_type(iMobVnum, pkLevelItemGroup)); This: m_map_pkGloveItemGroup.insert(std::map<DWORD, CBuyerThiefGlovesItemGroup*>::value_type(iMobVnum, pkGroup)); With this: if (isReloading) tempThiefGlovesGr.insert(std::map<DWORD, CBuyerThiefGlovesItemGroup*>::value_type(iMobVnum, pkGroup)); else m_map_pkGloveItemGroup.insert(std::map<DWORD, CBuyerThiefGlovesItemGroup*>::value_type(iMobVnum, pkGroup)); Then add this above the return true; at the end of the function: if (isReloading) { for (std::map<DWORD, CBuyerThiefGlovesItemGroup*>::iterator it = m_map_pkGloveItemGroup.begin(); it != m_map_pkGloveItemGroup.end(); it++) M2_DELETE(it->second); m_map_pkGloveItemGroup.clear(); for (std::map<DWORD, CLevelItemGroup*>::iterator it = m_map_pkLevelItemGroup.begin(); it != m_map_pkLevelItemGroup.end(); it++) M2_DELETE(it->second); m_map_pkLevelItemGroup.clear(); for (std::map<DWORD, CDropItemGroup*>::iterator it = m_map_pkDropItemGroup.begin(); it != m_map_pkDropItemGroup.end(); it++) M2_DELETE(it->second); m_map_pkDropItemGroup.clear(); for (std::map<DWORD, CMobItemGroup*>::iterator it = m_map_pkMobItemGroup.begin(); it != m_map_pkMobItemGroup.end(); it++) M2_DELETE(it->second); m_map_pkMobItemGroup.clear(); for (std::map<DWORD, CBuyerThiefGlovesItemGroup*>::iterator it = tempThiefGlovesGr.begin(); it != tempThiefGlovesGr.end(); it++) { m_map_pkGloveItemGroup[it->first] = it->second; } for (std::map<DWORD, CLevelItemGroup*>::iterator it = tempLevelItemGr.begin(); it != tempLevelItemGr.end(); it++) { m_map_pkLevelItemGroup[it->first] = it->second; } for (std::map<DWORD, CDropItemGroup*>::iterator it = tempDropItemGr.begin(); it != tempDropItemGr.end(); it++) { m_map_pkDropItemGroup[it->first] = it->second; } for (std::map<DWORD, CMobItemGroup*>::iterator it = temMobItemGr.begin(); it != temMobItemGr.end(); it++) { m_map_pkMobItemGroup[it->first] = it->second; } } mob_manager.h Spoiler Replace this: bool LoadGroup(const char * c_pszFileName); bool LoadGroupGroup(const char * c_pszFileName); With this: bool LoadGroup(const char * c_pszFileName, bool isReloading = false); bool LoadGroupGroup(const char * c_pszFileName, bool isReloading = false); mob_manager.cpp Spoiler Replace this: bool CMobManager::LoadGroupGroup(const char * c_pszFileName) With this: bool CMobManager::LoadGroupGroup(const char * c_pszFileName, bool isReloading) We will work in this function again. Add this above the first for loop: std::map<DWORD, CMobGroupGroup *> tempLoader; if (isReloading) sys_log(0, "RELOADING group group: %s", c_pszFileName); Then replace this: m_map_pkMobGroupGroup.insert(std::make_pair((DWORD)iVnum, pkGroup)); With this: if (isReloading) tempLoader.insert(std::make_pair((DWORD)iVnum, pkGroup)); else m_map_pkMobGroupGroup.insert(std::make_pair((DWORD)iVnum, pkGroup)); Then insert this above the return true; at the end of the function: if (isReloading) { for (std::map<DWORD, CMobGroupGroup *>::iterator it = m_map_pkMobGroupGroup.begin(); it != m_map_pkMobGroupGroup.end(); it++) M2_DELETE(it->second); m_map_pkMobGroupGroup.clear(); for (std::map<DWORD, CMobGroupGroup *>::iterator it = tempLoader.begin(); it != tempLoader.end(); it++) { m_map_pkMobGroupGroup[it->first] = it->second; } } Okay we done with the this function, lets search for this: bool CMobManager::LoadGroup(const char * c_pszFileName) And replace with this: bool CMobManager::LoadGroup(const char * c_pszFileName, bool isReloading) Obliviously we will work in this function. Lets add this again before the first for loop: std::map<DWORD, CMobGroup *> tempLoader; if (isReloading) sys_log(0, "RELOADING groups: %s", c_pszFileName); Then replace this: m_map_pkMobGroup.insert(std::map<DWORD, CMobGroup *>::value_type(iVnum, pkGroup)); With this: if (isReloading) tempLoader.insert(std::map<DWORD, CMobGroup *>::value_type(iVnum, pkGroup)); else m_map_pkMobGroup.insert(std::map<DWORD, CMobGroup *>::value_type(iVnum, pkGroup)); And last but not least lets add this before the return true; at the end of the function: if (isReloading) { for (std::map<DWORD, CMobGroup *>::iterator it = m_map_pkMobGroup.begin(); it != m_map_pkMobGroup.end(); it++) M2_DELETE(it->second); m_map_pkMobGroup.clear(); for (std::map<DWORD, CMobGroup *>::iterator it = tempLoader.begin(); it != tempLoader.end(); it++) { m_map_pkMobGroup[it->first] = it->second; } } char.cpp Spoiler void CHARACTER::Destroy() Replace this: if (m_pkRegen) { if (m_pkDungeon) { // Dungeon regen may not be valid at this point if (m_pkDungeon->IsValidRegen(m_pkRegen, regen_id_)) { --m_pkRegen->count; } } else { // Is this really safe? --m_pkRegen->count; } m_pkRegen = NULL; } With this: if (m_pkRegen) { if (m_pkDungeon) { // Dungeon regen may not be valid at this point if (m_pkDungeon->IsValidRegen(m_pkRegen, regen_id_)) { --m_pkRegen->count; } } else { // Is this really safe? NO IT ISNT! F*CK THAT SH!T! if (is_valid_regen(m_pkRegen)) --m_pkRegen->count; } m_pkRegen = NULL; } sectree_manager.cpp Spoiler int SECTREE_MANAGER::Build(const char * c_pszListFileName, const char* c_pszMapBasePath) Under this: snprintf(szFilename, sizeof(szFilename), "%s/%s/server_attr", c_pszMapBasePath, szMapName); LoadAttribute(pkMapSectree, szFilename, setting); Insert this: snprintf(szFilename, sizeof(szFilename), "%s/%s/", c_pszMapBasePath, szMapName); regen_register_map(szFilename, setting.iIndex, setting.iBaseX, setting.iBaseY); regen.h Spoiler Under this: extern bool regen_load(const char *filename, long lMapIndex, int base_x, int base_y); Insert this: extern void regen_free_map(long lMapIndex); extern void regen_reload(long lMapIndex); extern void regen_register_map(const char * szBaseName, long lMapIndex, int base_x, int base_y); extern bool is_valid_regen(LPREGEN currRegen); regen.cpp Spoiler Under this: LPREGEN_EXCEPTION regen_exception_list = NULL; Add this: typedef struct SMapDataContainer { char szBaseName[256]; int base_x; int base_y; }TMapDataContainer; #define mbMapDataCType std::map<DWORD, TMapDataContainer*> mbMapDataCType mbMapDataContainer; At the end of the file add these: bool is_valid_regen(LPREGEN currRegen) { LPREGEN regen; for (regen = regen_list; regen; regen = regen->next) { if (regen == currRegen) return true; } return false; } void regen_free_map(long lMapIndex) { LPREGEN regen, prev, next, next_regen; for (regen = regen_list; regen; regen = next_regen) { next_regen = regen->next; if (regen->lMapIndex != lMapIndex) continue; event_cancel(®en->event); REMOVE_FROM_TW_LIST(regen, regen_list, prev, next); M2_DELETE(regen); } } void regen_reload(long lMapIndex) { if (mbMapDataContainer.find(lMapIndex) == mbMapDataContainer.end()) return; char szFilename[256]; snprintf(szFilename, sizeof(szFilename), "%sregen.txt", mbMapDataContainer[lMapIndex]->szBaseName); regen_load(szFilename, lMapIndex, mbMapDataContainer[lMapIndex]->base_x, mbMapDataContainer[lMapIndex]->base_y); snprintf(szFilename, sizeof(szFilename), "%snpc.txt", mbMapDataContainer[lMapIndex]->szBaseName); regen_load(szFilename, lMapIndex, mbMapDataContainer[lMapIndex]->base_x, mbMapDataContainer[lMapIndex]->base_y); snprintf(szFilename, sizeof(szFilename), "%sboss.txt", mbMapDataContainer[lMapIndex]->szBaseName); regen_load(szFilename, lMapIndex, mbMapDataContainer[lMapIndex]->base_x, mbMapDataContainer[lMapIndex]->base_y); snprintf(szFilename, sizeof(szFilename), "%sstone.txt", mbMapDataContainer[lMapIndex]->szBaseName); regen_load(szFilename, lMapIndex, mbMapDataContainer[lMapIndex]->base_x, mbMapDataContainer[lMapIndex]->base_y); } void regen_register_map(const char * szBaseName, long lMapIndex, int base_x, int base_y) { TMapDataContainer* container = new TMapDataContainer; memset(container->szBaseName, 0, sizeof(container->szBaseName)); #ifdef __FreeBSD__ strlcpy(container->szBaseName, szBaseName, sizeof(container->szBaseName) - 1); #else strncpy(container->szBaseName, szBaseName, sizeof(container->szBaseName) - 1); #endif container->base_x = base_x; container->base_y = base_y; mbMapDataContainer[lMapIndex] = container; } EVENTFUNC(regen_event) Under this: LPREGEN regen = info->regen; Insert this: if (!is_valid_regen(regen)) return 0; shop.h Spoiler Under this: void RemoveGuest(LPCHARACTER ch); Insert this: void RemoveAllGuests(); shop.cpp Spoiler Add this at the end of the file: void CShop::RemoveAllGuests() { if (m_map_guest.empty()) return; for (GuestMapType::iterator it = m_map_guest.begin(); it != m_map_guest.end(); it++) { LPCHARACTER ch = it->first; if (ch) { if (ch->GetDesc() && ch->GetShop() == this) { ch->SetShop(NULL); TPacketGCShop pack; pack.header = HEADER_GC_SHOP; pack.subheader = SHOP_SUBHEADER_GC_END; pack.size = sizeof(TPacketGCShop); ch->GetDesc()->Packet(&pack, sizeof(pack)); } } } m_map_guest.clear(); } db/src ClientManager.cpp Spoiler void CClientManager::QUERY_RELOAD_PROTO() Replace this: tmp->EncodeHeader(HEADER_DG_RELOAD_PROTO, 0, sizeof(WORD) + sizeof(TSkillTable) * m_vec_skillTable.size() + sizeof(WORD) + sizeof(TBanwordTable) * m_vec_banwordTable.size() + sizeof(WORD) + sizeof(TItemTable) * m_vec_itemTable.size() + sizeof(WORD) + sizeof(TMobTable) * m_vec_mobTable.size()); With this: tmp->EncodeHeader(HEADER_DG_RELOAD_PROTO, 0, sizeof(WORD) + sizeof(TSkillTable) * m_vec_skillTable.size() + sizeof(WORD) + sizeof(TBanwordTable) * m_vec_banwordTable.size() + sizeof(WORD) + sizeof(TItemTable) * m_vec_itemTable.size() + sizeof(WORD) + sizeof(TMobTable) * m_vec_mobTable.size() + sizeof(WORD) + sizeof(TShopTable) * m_iShopTableSize + sizeof(WORD) + sizeof(TRefineTable)* m_iRefineTableSize + sizeof(WORD) + sizeof(TItemAttrTable)*m_vec_itemAttrTable.size() + sizeof(WORD) + sizeof(TItemAttrTable)*m_vec_itemRareTable.size()); Then under this: tmp->EncodeWORD(m_vec_mobTable.size()); tmp->Encode(&m_vec_mobTable[0], sizeof(TMobTable) * m_vec_mobTable.size()); Add this: tmp->EncodeWORD(m_iShopTableSize); tmp->Encode(m_pShopTable, sizeof(TShopTable) * m_iShopTableSize); tmp->EncodeWORD(m_iRefineTableSize); tmp->Encode(m_pRefineTable, sizeof(TRefineTable) * m_iRefineTableSize); tmp->EncodeWORD(m_vec_itemAttrTable.size()); tmp->Encode(&m_vec_itemAttrTable[0], sizeof(TItemAttrTable) * m_vec_itemAttrTable.size()); tmp->EncodeWORD(m_vec_itemRareTable.size()); tmp->Encode(&m_vec_itemRareTable[0], sizeof(TItemAttrTable) * m_vec_itemRareTable.size()); And finally let me wish you all good luck for the setup If you have further question(s), remark(s), or anything that you want to ask or suggest, feel free to post it here, or send it in PM. If you get error(s) please upload the affected (and edited) file to http://pastebin.com/ and link it in your post, to make my work easier and probably I will be able to help you only in one post, so please spare me from asking basic requests like "Could you upload...". Thank you Have a nice day, ~masodikbela Edited October 21, 2023 by masodikbela fix use after free in regen_free_map 69 1 1 1 16 4 83 The one and only UI programming guideline Link to comment Share on other sites More sharing options...
TheMt2 11 Posted January 17, 2016 Share Posted January 17, 2016 Good, thx ! Link to comment Share on other sites More sharing options...
Honorable Member xP3NG3Rx 19658 Posted January 17, 2016 Honorable Member Share Posted January 17, 2016 Nice, as always! Thank you . Link to comment Share on other sites More sharing options...
ManiacRobert 427 Posted January 17, 2016 Share Posted January 17, 2016 Error.. compile item_manager_read_tables.cpp item_manager_read_tables.cpp: In member function 'bool ITEM_MANAGER::ReadMonsterDropItemGroup(const char*, bool)': item_manager_read_tables.cpp:699: warning: unused variable 'pkGroup' item_manager_read_tables.cpp: In member function 'bool ITEM_MANAGER::ReadDropItemGroup(const char*)': item_manager_read_tables.cpp:945: error: 'isReloading' was not declared in this scope item_manager_read_tables.cpp:947: error: 'tempDropItemGr' was not declared in this scope item_manager_read_tables.cpp:947: error: invalid type in declaration before '=' token item_manager_read_tables.cpp:950: error: 'pkGroup' was not declared in this scope item_manager_read_tables.cpp:954: error: 'bNew' was not declared in this scope item_manager_read_tables.cpp:955: error: base operand of '->' is not a pointer item_manager_read_tables.cpp:955: warning: unused variable 'pkGroup' item_manager_read_tables.cpp:963: error: 'pkGroup' was not declared in this scope item_manager_read_tables.cpp:967: error: 'bNew' was not declared in this scope item_manager_read_tables.cpp:968: warning: unused variable 'pkGroup' item_manager_read_tables.cpp:989: error: 'it' was not declared in this scope item_manager_read_tables.cpp:990: error: 'pkGroup' was not declared in this scope item_manager_read_tables.cpp:1008: error: 'it' was not declared in this scope item_manager_read_tables.cpp:1009: error: 'pkGroup' was not declared in this scope item_manager_read_tables.cpp:1015: error: 'pkGroup' was not declared in this scope item_manager_read_tables.cpp:1022: error: 'it' was not declared in this scope item_manager_read_tables.cpp:1023: error: 'pkGroup' was not declared in this scope 1 Link to comment Share on other sites More sharing options...
Premium masodikbela 1359 Posted January 17, 2016 Author Premium Share Posted January 17, 2016 2 minutes ago, ManiacRobert said: Error.. compile item_manager_read_tables.cpp item_manager_read_tables.cpp: In member function 'bool ITEM_MANAGER::ReadMonsterDropItemGroup(const char*, bool)': item_manager_read_tables.cpp:699: warning: unused variable 'pkGroup' item_manager_read_tables.cpp: In member function 'bool ITEM_MANAGER::ReadDropItemGroup(const char*)': item_manager_read_tables.cpp:945: error: 'isReloading' was not declared in this scope item_manager_read_tables.cpp:947: error: 'tempDropItemGr' was not declared in this scope item_manager_read_tables.cpp:947: error: invalid type in declaration before '=' token item_manager_read_tables.cpp:950: error: 'pkGroup' was not declared in this scope item_manager_read_tables.cpp:954: error: 'bNew' was not declared in this scope item_manager_read_tables.cpp:955: error: base operand of '->' is not a pointer item_manager_read_tables.cpp:955: warning: unused variable 'pkGroup' item_manager_read_tables.cpp:963: error: 'pkGroup' was not declared in this scope item_manager_read_tables.cpp:967: error: 'bNew' was not declared in this scope item_manager_read_tables.cpp:968: warning: unused variable 'pkGroup' item_manager_read_tables.cpp:989: error: 'it' was not declared in this scope item_manager_read_tables.cpp:990: error: 'pkGroup' was not declared in this scope item_manager_read_tables.cpp:1008: error: 'it' was not declared in this scope item_manager_read_tables.cpp:1009: error: 'pkGroup' was not declared in this scope item_manager_read_tables.cpp:1015: error: 'pkGroup' was not declared in this scope item_manager_read_tables.cpp:1022: error: 'it' was not declared in this scope item_manager_read_tables.cpp:1023: error: 'pkGroup' was not declared in this scope Could you pastebin the edited item_manager_read_tables.cpp? 5 The one and only UI programming guideline Link to comment Share on other sites More sharing options...
ManiacRobert 427 Posted January 17, 2016 Share Posted January 17, 2016 Here http://pastebin.com/raw/PNwaex1L 2 2 Link to comment Share on other sites More sharing options...
Premium masodikbela 1359 Posted January 17, 2016 Author Premium Share Posted January 17, 2016 21 minutes ago, ManiacRobert said: Here http://pastebin.com/raw/PNwaex1L You edited the bool ITEM_MANAGER::ReadDropItemGroup(const char * c_pszFileName) function, but I don't know why because I didn't ever mentioned it. here is mine 1 2 1 5 The one and only UI programming guideline Link to comment Share on other sites More sharing options...
ManiacRobert 427 Posted January 17, 2016 Share Posted January 17, 2016 Thanks, Working. Link to comment Share on other sites More sharing options...
Mr.Oz J. 5 Posted January 17, 2016 Share Posted January 17, 2016 thanks dude! you r the best Link to comment Share on other sites More sharing options...
stein20 15 Posted January 22, 2016 Share Posted January 22, 2016 (edited) thx man On 17/1/2016 at 10:13 AM, masodikbela said: Hi there devs, I made some new reload commands about 2 weeks ago and published a tutorial about it on our Hungarian forum (you may saw them in the samurai core) and today I had some time to make the translation. What can I reload now? refine_proto (this is the only one which is not mine, its @xP3NG3Rx's, and already public here, but I added it, because I think this package has to contain it ) command: /reload p shop_item table (npc's shops) command: /reload p item_attr && item_attr_rare table; command: /reload p etc_drop_item.txt, mob_drop_item.txt, special_item_group.txt; command: /reload drop group.txt, group_group.txt; command: /reload group regen.txt, npc.txt, boss.txt, stone.txt (only on the current map) command: /reload regen because of the new "reload regen" command, I had to write a new purge command that destroys all mobs, npcs, stones (and so on...) on the current map, so I added a new /p map command to the "/p" commands that are already exists (no, the "/p all" only destroys the mobs on the current sectree (current block)) also I had to create a new command that stops all the regens (and ofc. deletes them from the memory) on the current map, so I added a new "/free_regens" command (because why not ) Its only deletes the loaded regens, and prevents the mobs from respawning (its not necessary to use this before the /reload regen) Known bug Well its not a serious problem, but for some unknown reason, when I'm debugging the core on windows server (no, not debug mode, but vs 13's debugger) and I try to do /reload regen, the core starts to consume ~40% cpu, and doesn't want to do anything (so stops working, but doesn't crash). It has no affect on FreeBSD and release or debug mode (without visual studio's debugger) on windows. Hide contents If you get fcked up codes like me, try to remove the pagestyle in your browser. game/src cmd.cpp Hide contents Add this to the top of the file (where you can find more ACMDs) ACMD(do_free_regen); Then above this: { "who", do_who, 0, POS_DEAD, GM_IMPLEMENTOR }, Add this: { "free_regens", do_free_regen, 0, POS_DEAD, GM_IMPLEMENTOR }, cmd_gm.cpp Hide contents Add this to the end of the file: ACMD(do_free_regen) { ch->ChatPacket(CHAT_TYPE_INFO, "freeing regens on mapindex %ld", ch->GetMapIndex()); regen_free_map(ch->GetMapIndex()); ch->ChatPacket(CHAT_TYPE_INFO, "the regens now FREEEE! :)"); } Replace the ACMD(do_purge) with this: ACMD(do_purge) { char arg1[256]; one_argument(argument, arg1, sizeof(arg1)); FuncPurge func(ch); if (*arg1 && !strcmp(arg1, "map")) { CHARACTER_MANAGER::instance().DestroyCharacterInMap(ch->GetMapIndex()); } else { if (*arg1 && !strcmp(arg1, "all")) func.m_bAll = true; LPSECTREE sectree = ch->GetSectree(); if (sectree) // #431 sectree->ForEachAround(func); else sys_err("PURGE_ERROR.NULL_SECTREE(mapIndex=%d, pos=(%d, %d)", ch->GetMapIndex(), ch->GetX(), ch->GetY()); } } In the ACMD(do_reload) function under this: case 'c': // cube // ·ÎÄĂ ÇÁ·ÎĽĽ˝ş¸¸ °»»ęÇŃ´Ů. Cube_init (); break; Insert this: default: const int FILE_NAME_LEN = 256; if (strstr(arg1, "drop")) { char szETCDropItemFileName[FILE_NAME_LEN]; char szMOBDropItemFileName[FILE_NAME_LEN]; char szSpecialItemGroupFileName[FILE_NAME_LEN]; snprintf(szETCDropItemFileName, sizeof(szETCDropItemFileName), "%s/etc_drop_item.txt", LocaleService_GetBasePath().c_str()); snprintf(szMOBDropItemFileName, sizeof(szMOBDropItemFileName), "%s/mob_drop_item.txt", LocaleService_GetBasePath().c_str()); snprintf(szSpecialItemGroupFileName, sizeof(szSpecialItemGroupFileName), "%s/special_item_group.txt", LocaleService_GetBasePath().c_str()); ch->ChatPacket(CHAT_TYPE_INFO, "Reloading: ETCDropItem: %s", szETCDropItemFileName); if (!ITEM_MANAGER::instance().ReadEtcDropItemFile(szETCDropItemFileName, true)) ch->ChatPacket(CHAT_TYPE_INFO, "failed to reload ETCDropItem: %s", szETCDropItemFileName); else ch->ChatPacket(CHAT_TYPE_INFO, "reload success: ETCDropItem: %s", szETCDropItemFileName); ch->ChatPacket(CHAT_TYPE_INFO, "Reloading: SpecialItemGroup: %s", szSpecialItemGroupFileName); if (!ITEM_MANAGER::instance().ReadSpecialDropItemFile(szSpecialItemGroupFileName, true)) ch->ChatPacket(CHAT_TYPE_INFO, "failed to reload SpecialItemGroup: %s", szSpecialItemGroupFileName); else ch->ChatPacket(CHAT_TYPE_INFO, "reload success: SpecialItemGroup: %s", szSpecialItemGroupFileName); ch->ChatPacket(CHAT_TYPE_INFO, "Reloading: MOBDropItemFile: %s", szMOBDropItemFileName); if (!ITEM_MANAGER::instance().ReadMonsterDropItemGroup(szMOBDropItemFileName, true)) ch->ChatPacket(CHAT_TYPE_INFO, "failed to reload MOBDropItemFile: %s", szMOBDropItemFileName); else ch->ChatPacket(CHAT_TYPE_INFO, "reload success: MOBDropItemFile: %s", szMOBDropItemFileName); } else if (strstr(arg1, "group")) { char szGroupFileName[FILE_NAME_LEN]; char szGroupGroupFileName[FILE_NAME_LEN]; snprintf(szGroupFileName, sizeof(szGroupGroupFileName), "%s/group.txt", LocaleService_GetBasePath().c_str()); snprintf(szGroupGroupFileName, sizeof(szGroupGroupFileName), "%s/group_group.txt", LocaleService_GetBasePath().c_str()); ch->ChatPacket(CHAT_TYPE_INFO, "Reloading: mob groups: %s", szGroupFileName); if (!CMobManager::instance().LoadGroup(szGroupFileName, true)) ch->ChatPacket(CHAT_TYPE_INFO, "failed to reload mob groups: %s", szGroupFileName); ch->ChatPacket(CHAT_TYPE_INFO, "Reloading: mob group group: %s", szGroupGroupFileName); if (!CMobManager::instance().LoadGroupGroup(szGroupGroupFileName, true)) ch->ChatPacket(CHAT_TYPE_INFO, "failed to reload mob group group: %s", szGroupGroupFileName); } else if (strstr(arg1, "regen")) { SendNoticeMap("Reloading regens!", ch->GetMapIndex(), false); regen_free_map(ch->GetMapIndex()); CHARACTER_MANAGER::instance().DestroyCharacterInMap(ch->GetMapIndex()); regen_reload(ch->GetMapIndex()); SendNoticeMap("Regens reloaded!", ch->GetMapIndex(), false); } break; input_db.cpp Hide contents void CInputDB::ReloadProto(const char * c_pData) Above this: CMotionManager::instance().Build(); Add this: /* * SHOP */ wSize = decode_2bytes(c_pData); c_pData += sizeof(WORD); sys_log(0, "RELOAD: SHOP: %d", wSize); if (wSize) { CShopManager::instance().Initialize((TShopTable *)c_pData, wSize); c_pData += wSize * sizeof(TShopTable); } /* * REFINE */ wSize = decode_2bytes(c_pData); c_pData += 2; sys_log(0, "RELOAD: REFINE: %d", wSize); if (wSize) { CRefineManager::instance().Initialize((TRefineTable *)c_pData, wSize); c_pData += wSize * sizeof(TRefineTable); } /* * ATTR */ wSize = decode_2bytes(c_pData); c_pData += 2; sys_log(0, "RELOAD: ItemAtt: %d", wSize); if (wSize) { TItemAttrTable * p = (TItemAttrTable *)c_pData; g_map_itemAttr.clear(); for (int i = 0; i < wSize; ++i, ++p) { if (p->dwApplyIndex >= MAX_APPLY_NUM) continue; g_map_itemAttr[p->dwApplyIndex] = *p; sys_log(0, "ITEM_ATTR[%d]: %s %u", p->dwApplyIndex, p->szApply, p->dwProb); } c_pData += wSize*sizeof(TItemAttrTable); } /* * ATTR_RARE */ wSize = decode_2bytes(c_pData); c_pData += 2; sys_log(0, "RELOAD: ItemRareAtt: %d", wSize); if (wSize) { TItemAttrTable * p = (TItemAttrTable *)c_pData; g_map_itemRare.clear(); for (int i = 0; i < wSize; ++i, ++p) { if (p->dwApplyIndex >= MAX_APPLY_NUM) continue; g_map_itemRare[p->dwApplyIndex] = *p; sys_log(0, "ITEM_RARE[%d]: %s %u", p->dwApplyIndex, p->szApply, p->dwProb); } c_pData += wSize*sizeof(TItemAttrTable); } shop_manager.cpp Reveal hidden contents bool CShopManager::Initialize(TShopTable * table, int size Replace this: if (!m_map_pkShop.empty()) return false; With this: if (!m_map_pkShop.empty()) { for (TShopMap::iterator it = m_map_pkShop.begin(); it != m_map_pkShop.end(); it++) { it->second->RemoveAllGuests(); } } m_map_pkShop.clear(); m_map_pkShopByNPCVnum.clear(); refine.cpp Hide contents Insert this to the top of this function:bool CRefineManager::Initialize(TRefineTable * table, int size) m_map_RefineRecipe.clear(); char_manager.cpp Hide contents Insert this to the end of the file: void CHARACTER_MANAGER::DestroyCharacterInMap(long lMapIndex) { std::vector<LPCHARACTER> tempVec; for (itertype(m_map_pkChrByVID) it = m_map_pkChrByVID.begin(); it != m_map_pkChrByVID.end(); it++) { LPCHARACTER pkChr = it->second; if (pkChr && pkChr->GetMapIndex() == lMapIndex && pkChr->IsNPC() && !pkChr->IsPet() && pkChr->GetRider() == NULL) { tempVec.push_back(pkChr); } } for (std::vector<LPCHARACTER>::iterator it = tempVec.begin(); it != tempVec.end(); it++) { DestroyCharacter(*it); } } char_manager.h Hide contents Above this: void Update(int iPulse); Insert this: void DestroyCharacterInMap(long lMapIndex); item_manager.h Reveal hidden contents Replace this: bool ReadEtcDropItemFile(const char * c_pszFileName); bool ReadMonsterDropItemGroup(const char * c_pszFileName); bool ReadSpecialDropItemFile(const char * c_pszFileName); With this: bool ReadEtcDropItemFile(const char * c_pszFileName, bool isReloading = false); bool ReadMonsterDropItemGroup(const char * c_pszFileName, bool isReloading = false); bool ReadSpecialDropItemFile(const char * c_pszFileName, bool isReloading = false); item_manager_read_tables.cpp Reveal hidden contents Firstly replace this: bool ITEM_MANAGER::ReadEtcDropItemFile(const char * c_pszFileName) With this: bool ITEM_MANAGER::ReadEtcDropItemFile(const char * c_pszFileName, bool isReloading) Now we will work in this function we just edited. Above this: char buf[512] Insert this: std::map<DWORD, DWORD> tempLoader; if (isReloading) { sys_log(0, "RELOADING EtcDrop"); } Then replace this: m_map_dwEtcItemDropProb[dwItemVnum] = (DWORD) (fProb * 10000.0f); With this: if (isReloading) tempLoader[dwItemVnum] = (DWORD)(fProb * 10000.0f); else m_map_dwEtcItemDropProb[dwItemVnum] = (DWORD) (fProb * 10000.0f); Add this above the return true; that we can find at the end of the function: if (isReloading) { m_map_dwEtcItemDropProb.clear(); for (std::map<DWORD, DWORD>::iterator it = tempLoader.begin(); it != tempLoader.end(); it++) { m_map_dwEtcItemDropProb[it->first] = it->second; } } Okay, now we finished this function. Lets search for this: bool ITEM_MANAGER::ReadSpecialDropItemFile(const char * c_pszFileName) Then replace with this: bool ITEM_MANAGER::ReadSpecialDropItemFile(const char * c_pszFileName, bool isReloading) Okay, we will work in this function. Before the first for loop add this: std::map<DWORD, CSpecialAttrGroup*> tempSpecAttr; std::map<DWORD, CSpecialItemGroup*> tempSpecItem; std::map<DWORD, CSpecialItemGroup*> tempSpecItemQuest; if (isReloading) sys_log(0, "RELOADING SpecialDrop"); Then replace this: m_map_pkSpecialAttrGroup.insert(std::make_pair(iVnum, pkGroup)); With this: if (isReloading) tempSpecAttr.insert(std::make_pair(iVnum, pkGroup)); else m_map_pkSpecialAttrGroup.insert(std::make_pair(iVnum, pkGroup)); Then replace this: if (CSpecialItemGroup::QUEST == type) { m_map_pkQuestItemGroup.insert(std::make_pair(iVnum, pkGroup)); } else { m_map_pkSpecialItemGroup.insert(std::make_pair(iVnum, pkGroup)); } With this: if (CSpecialItemGroup::QUEST == type) { if (isReloading) tempSpecItemQuest.insert(std::make_pair(iVnum, pkGroup)); else m_map_pkQuestItemGroup.insert(std::make_pair(iVnum, pkGroup)); } else { if (isReloading) tempSpecItem.insert(std::make_pair(iVnum, pkGroup)); else m_map_pkSpecialItemGroup.insert(std::make_pair(iVnum, pkGroup)); } Again, above the return true; (we can find this at the end of the function) add this: if (isReloading) { m_map_pkQuestItemGroup.clear(); m_map_pkSpecialItemGroup.clear(); m_map_pkSpecialAttrGroup.clear(); for (std::map<DWORD, CSpecialAttrGroup*>::iterator it = tempSpecAttr.begin(); it != tempSpecAttr.end(); it++) { m_map_pkSpecialAttrGroup[it->first] = it->second; } for (std::map<DWORD, CSpecialItemGroup*>::iterator it = tempSpecItem.begin(); it != tempSpecItem.end(); it++) { m_map_pkSpecialItemGroup[it->first] = it->second; } for (std::map<DWORD, CSpecialItemGroup*>::iterator it = tempSpecItemQuest.begin(); it != tempSpecItemQuest.end(); it++) { m_map_pkQuestItemGroup[it->first] = it->second; } } Lets search for a new function. Replace this: bool ITEM_MANAGER::ReadMonsterDropItemGroup(const char * c_pszFileName) With this: bool ITEM_MANAGER::ReadMonsterDropItemGroup(const char * c_pszFileName, bool isReloading) Okay, we will work again in the "just edited" function. Before the first for loop add this: std::map<DWORD, CMobItemGroup*> temMobItemGr; std::map<DWORD, CDropItemGroup*> tempDropItemGr; std::map<DWORD, CLevelItemGroup*> tempLevelItemGr; std::map<DWORD, CBuyerThiefGlovesItemGroup*> tempThiefGlovesGr; if (isReloading) { sys_log(0, "RELOADING MonsterDrop"); } Replace this: m_map_pkMobItemGroup.insert(std::map<DWORD, CMobItemGroup*>::value_type(iMobVnum, pkGroup)); With this: if (isReloading) temMobItemGr.insert(std::map<DWORD, CMobItemGroup*>::value_type(iMobVnum, pkGroup)); else m_map_pkMobItemGroup.insert(std::map<DWORD, CMobItemGroup*>::value_type(iMobVnum, pkGroup)); Then this: itertype(m_map_pkDropItemGroup) it = m_map_pkDropItemGroup.find(iMobVnum); if (it == m_map_pkDropItemGroup.end()) { pkGroup = M2_NEW CDropItemGroup(0, iMobVnum, stName); } else { bNew = false; CDropItemGroup* pkGroup = it->second; } With this: if (isReloading) { itertype(tempDropItemGr) it = tempDropItemGr.find(iMobVnum); if (it == tempDropItemGr.end()) { pkGroup = M2_NEW CDropItemGroup(0, iMobVnum, stName); } else { bNew = false; CDropItemGroup* pkGroup = it->second; } } else { itertype(m_map_pkDropItemGroup) it = m_map_pkDropItemGroup.find(iMobVnum); if (it == m_map_pkDropItemGroup.end()) { pkGroup = M2_NEW CDropItemGroup(0, iMobVnum, stName); } else { bNew = false; CDropItemGroup* pkGroup = it->second; } } Replace this: if (bNew) m_map_pkDropItemGroup.insert(std::map<DWORD, CDropItemGroup*>::value_type(iMobVnum, pkGroup)); With this: if (bNew) { if (isReloading) tempDropItemGr.insert(std::map<DWORD, CDropItemGroup*>::value_type(iMobVnum, pkGroup)); else m_map_pkDropItemGroup.insert(std::map<DWORD, CDropItemGroup*>::value_type(iMobVnum, pkGroup)); } This: m_map_pkLevelItemGroup.insert(std::map<DWORD, CLevelItemGroup*>::value_type(iMobVnum, pkLevelItemGroup)); With this: if (isReloading) tempLevelItemGr.insert(std::map<DWORD, CLevelItemGroup*>::value_type(iMobVnum, pkLevelItemGroup)); else m_map_pkLevelItemGroup.insert(std::map<DWORD, CLevelItemGroup*>::value_type(iMobVnum, pkLevelItemGroup)); This: m_map_pkGloveItemGroup.insert(std::map<DWORD, CBuyerThiefGlovesItemGroup*>::value_type(iMobVnum, pkGroup)); With this: if (isReloading) tempThiefGlovesGr.insert(std::map<DWORD, CBuyerThiefGlovesItemGroup*>::value_type(iMobVnum, pkGroup)); else m_map_pkGloveItemGroup.insert(std::map<DWORD, CBuyerThiefGlovesItemGroup*>::value_type(iMobVnum, pkGroup)); Then add this above the return true; at the end of the function: if (isReloading) { for (std::map<DWORD, CBuyerThiefGlovesItemGroup*>::iterator it = m_map_pkGloveItemGroup.begin(); it != m_map_pkGloveItemGroup.end(); it++) M2_DELETE(it->second); m_map_pkGloveItemGroup.clear(); for (std::map<DWORD, CLevelItemGroup*>::iterator it = m_map_pkLevelItemGroup.begin(); it != m_map_pkLevelItemGroup.end(); it++) M2_DELETE(it->second); m_map_pkLevelItemGroup.clear(); for (std::map<DWORD, CDropItemGroup*>::iterator it = m_map_pkDropItemGroup.begin(); it != m_map_pkDropItemGroup.end(); it++) M2_DELETE(it->second); m_map_pkDropItemGroup.clear(); for (std::map<DWORD, CMobItemGroup*>::iterator it = m_map_pkMobItemGroup.begin(); it != m_map_pkMobItemGroup.end(); it++) M2_DELETE(it->second); m_map_pkMobItemGroup.clear(); for (std::map<DWORD, CBuyerThiefGlovesItemGroup*>::iterator it = tempThiefGlovesGr.begin(); it != tempThiefGlovesGr.end(); it++) { m_map_pkGloveItemGroup[it->first] = it->second; } for (std::map<DWORD, CLevelItemGroup*>::iterator it = tempLevelItemGr.begin(); it != tempLevelItemGr.end(); it++) { m_map_pkLevelItemGroup[it->first] = it->second; } for (std::map<DWORD, CDropItemGroup*>::iterator it = tempDropItemGr.begin(); it != tempDropItemGr.end(); it++) { m_map_pkDropItemGroup[it->first] = it->second; } for (std::map<DWORD, CMobItemGroup*>::iterator it = temMobItemGr.begin(); it != temMobItemGr.end(); it++) { m_map_pkMobItemGroup[it->first] = it->second; } } mob_manager.h Reveal hidden contents Replace this: bool LoadGroup(const char * c_pszFileName); bool LoadGroupGroup(const char * c_pszFileName); With this: bool LoadGroup(const char * c_pszFileName, bool isReloading = false); bool LoadGroupGroup(const char * c_pszFileName, bool isReloading = false); mob_manager.cpp Reveal hidden contents Replace this: bool CMobManager::LoadGroupGroup(const char * c_pszFileName) With this: bool CMobManager::LoadGroupGroup(const char * c_pszFileName, bool isReloading) We will work in this function again. Add this above the first for loop: std::map<DWORD, CMobGroupGroup *> tempLoader; if (isReloading) sys_log(0, "RELOADING group group: %s", c_pszFileName); Then replace this: m_map_pkMobGroupGroup.insert(std::make_pair((DWORD)iVnum, pkGroup)); With this: if (isReloading) tempLoader.insert(std::make_pair((DWORD)iVnum, pkGroup)); else m_map_pkMobGroupGroup.insert(std::make_pair((DWORD)iVnum, pkGroup)); Then insert this above the return true; at the end of the function: if (isReloading) { for (std::map<DWORD, CMobGroupGroup *>::iterator it = m_map_pkMobGroupGroup.begin(); it != m_map_pkMobGroupGroup.end(); it++) M2_DELETE(it->second); m_map_pkMobGroupGroup.clear(); for (std::map<DWORD, CMobGroupGroup *>::iterator it = tempLoader.begin(); it != tempLoader.end(); it++) { m_map_pkMobGroupGroup[it->first] = it->second; } } Okay we done with the this function, lets search for this: bool CMobManager::LoadGroup(const char * c_pszFileName) And replace with this: bool CMobManager::LoadGroup(const char * c_pszFileName, bool isReloading) Obliviously we will work in this function. Lets add this again before the first for loop: std::map<DWORD, CMobGroup *> tempLoader; if (isReloading) sys_log(0, "RELOADING groups: %s", c_pszFileName); Then replace this: m_map_pkMobGroup.insert(std::map<DWORD, CMobGroup *>::value_type(iVnum, pkGroup)); With this: if (isReloading) tempLoader.insert(std::map<DWORD, CMobGroup *>::value_type(iVnum, pkGroup)); else m_map_pkMobGroup.insert(std::map<DWORD, CMobGroup *>::value_type(iVnum, pkGroup)); And last but not least lets add this before the return true; at the end of the function: if (isReloading) { for (std::map<DWORD, CMobGroup *>::iterator it = m_map_pkMobGroup.begin(); it != m_map_pkMobGroup.end(); it++) M2_DELETE(it->second); m_map_pkMobGroup.clear(); for (std::map<DWORD, CMobGroup *>::iterator it = tempLoader.begin(); it != tempLoader.end(); it++) { m_map_pkMobGroup[it->first] = it->second; } } char.cpp Reveal hidden contents void CHARACTER::Destroy() Replace this: if (m_pkRegen) { if (m_pkDungeon) { // Dungeon regen may not be valid at this point if (m_pkDungeon->IsValidRegen(m_pkRegen, regen_id_)) { --m_pkRegen->count; } } else { // Is this really safe? --m_pkRegen->count; } m_pkRegen = NULL; } With this: if (m_pkRegen) { if (m_pkDungeon) { // Dungeon regen may not be valid at this point if (m_pkDungeon->IsValidRegen(m_pkRegen, regen_id_)) { --m_pkRegen->count; } } else { // Is this really safe? NO IT ISNT! F*CK THAT SH!T! if (is_valid_regen(m_pkRegen)) --m_pkRegen->count; } m_pkRegen = NULL; } sectree_manager.cpp Reveal hidden contents int SECTREE_MANAGER::Build(const char * c_pszListFileName, const char* c_pszMapBasePath) Under this: snprintf(szFilename, sizeof(szFilename), "%s/%s/server_attr", c_pszMapBasePath, szMapName); LoadAttribute(pkMapSectree, szFilename, setting); Insert this: snprintf(szFilename, sizeof(szFilename), "%s/%s/", c_pszMapBasePath, szMapName); regen_register_map(szFilename, setting.iIndex, setting.iBaseX, setting.iBaseY); regen.h Reveal hidden contents Under this: extern bool regen_load(const char *filename, long lMapIndex, int base_x, int base_y); Insert this: extern void regen_free_map(long lMapIndex); extern void regen_reload(long lMapIndex); extern void regen_register_map(const char * szBaseName, long lMapIndex, int base_x, int base_y); extern bool is_valid_regen(LPREGEN currRegen); regen.cpp Reveal hidden contents Under this: LPREGEN_EXCEPTION regen_exception_list = NULL; Add this: typedef struct SMapDataContainer { char szBaseName[256]; int base_x; int base_y; }TMapDataContainer; #define mbMapDataCType std::map<DWORD, TMapDataContainer*> mbMapDataCType mbMapDataContainer; At the end of the file add this: bool is_valid_regen(LPREGEN currRegen) { LPREGEN regen; for (regen = regen_list; regen; regen = regen->next) { if (regen == currRegen) return true; } return false; } void regen_free_map(long lMapIndex) { LPREGEN regen, prev, next; for (regen = regen_list; regen; regen = regen->next) { if (regen->lMapIndex != lMapIndex) continue; event_cancel(®en->event); REMOVE_FROM_TW_LIST(regen, regen_list, prev, next); M2_DELETE(regen); } } void regen_reload(long lMapIndex) { if (mbMapDataContainer.find(lMapIndex) == mbMapDataContainer.end()) return; char szFilename[256]; snprintf(szFilename, sizeof(szFilename), "%sregen.txt", mbMapDataContainer[lMapIndex]->szBaseName); regen_load(szFilename, lMapIndex, mbMapDataContainer[lMapIndex]->base_x, mbMapDataContainer[lMapIndex]->base_y); snprintf(szFilename, sizeof(szFilename), "%snpc.txt", mbMapDataContainer[lMapIndex]->szBaseName); regen_load(szFilename, lMapIndex, mbMapDataContainer[lMapIndex]->base_x, mbMapDataContainer[lMapIndex]->base_y); snprintf(szFilename, sizeof(szFilename), "%sboss.txt", mbMapDataContainer[lMapIndex]->szBaseName); regen_load(szFilename, lMapIndex, mbMapDataContainer[lMapIndex]->base_x, mbMapDataContainer[lMapIndex]->base_y); snprintf(szFilename, sizeof(szFilename), "%sstone.txt", mbMapDataContainer[lMapIndex]->szBaseName); regen_load(szFilename, lMapIndex, mbMapDataContainer[lMapIndex]->base_x, mbMapDataContainer[lMapIndex]->base_y); } void regen_register_map(const char * szBaseName, long lMapIndex, int base_x, int base_y) { TMapDataContainer* container = new TMapDataContainer; memset(container->szBaseName, 0, sizeof(container->szBaseName)); #ifdef __FreeBSD__ strlcpy(container->szBaseName, szBaseName, sizeof(container->szBaseName) - 1); #else strncpy(container->szBaseName, szBaseName, sizeof(container->szBaseName) - 1); #endif container->base_x = base_x; container->base_y = base_y; mbMapDataContainer[lMapIndex] = container; } EVENTFUNC(regen_event) Under this: LPREGEN regen = info->regen; Insert this: if (!is_valid_regen(regen)) return 0; shop.h Reveal hidden contents Under this: void RemoveGuest(LPCHARACTER ch); Insert this: void RemoveAllGuests(); shop.cpp Reveal hidden contents Add this at the end of the file: void CShop::RemoveAllGuests() { if (m_map_guest.empty()) return; for (GuestMapType::iterator it = m_map_guest.begin(); it != m_map_guest.end(); it++) { LPCHARACTER ch = it->first; if (ch) { if (ch->GetDesc() && ch->GetShop() == this) { ch->SetShop(NULL); TPacketGCShop pack; pack.header = HEADER_GC_SHOP; pack.subheader = SHOP_SUBHEADER_GC_END; pack.size = sizeof(TPacketGCShop); ch->GetDesc()->Packet(&pack, sizeof(pack)); } } } m_map_guest.clear(); } db/src ClientManager.cpp Reveal hidden contents void CClientManager::QUERY_RELOAD_PROTO() Replace this: tmp->EncodeHeader(HEADER_DG_RELOAD_PROTO, 0, sizeof(WORD) + sizeof(TSkillTable) * m_vec_skillTable.size() + sizeof(WORD) + sizeof(TBanwordTable) * m_vec_banwordTable.size() + sizeof(WORD) + sizeof(TItemTable) * m_vec_itemTable.size() + sizeof(WORD) + sizeof(TMobTable) * m_vec_mobTable.size()); With this: tmp->EncodeHeader(HEADER_DG_RELOAD_PROTO, 0, sizeof(WORD) + sizeof(TSkillTable) * m_vec_skillTable.size() + sizeof(WORD) + sizeof(TBanwordTable) * m_vec_banwordTable.size() + sizeof(WORD) + sizeof(TItemTable) * m_vec_itemTable.size() + sizeof(WORD) + sizeof(TMobTable) * m_vec_mobTable.size() + sizeof(WORD) + sizeof(TShopTable) * m_iShopTableSize + sizeof(WORD) + sizeof(TRefineTable)* m_iRefineTableSize + sizeof(WORD) + sizeof(TItemAttrTable)*m_vec_itemAttrTable.size() + sizeof(WORD) + sizeof(TItemAttrTable)*m_vec_itemRareTable.size()); Then under this: tmp->EncodeWORD(m_vec_mobTable.size()); tmp->Encode(&m_vec_mobTable[0], sizeof(TMobTable) * m_vec_mobTable.size()); Add this: tmp->EncodeWORD(m_iShopTableSize); tmp->Encode(m_pShopTable, sizeof(TShopTable) * m_iShopTableSize); tmp->EncodeWORD(m_iRefineTableSize); tmp->Encode(m_pRefineTable, sizeof(TRefineTable) * m_iRefineTableSize); tmp->EncodeWORD(m_vec_itemAttrTable.size()); tmp->Encode(&m_vec_itemAttrTable[0], sizeof(TItemAttrTable) * m_vec_itemAttrTable.size()); tmp->EncodeWORD(m_vec_itemRareTable.size()); tmp->Encode(&m_vec_itemRareTable[0], sizeof(TItemAttrTable) * m_vec_itemRareTable.size()); And finally let me wish you all good luck for the setup If you have further question(s), remark(s), or anything that you want to ask or suggest, feel free to post it here, or send it in PM. If you get error(s) please upload the affected (and edited) file to http://pastebin.com/ and link it in your post, to make my work easier and probably I will be able to help you only in one post, so please spare me from asking basic requests like "Could you upload...". Thank you Have a nice day, ~masodikbela Edited August 20, 2022 by Metin2 Dev Core X - External 2 Internal 1 Link to comment Share on other sites More sharing options...
Premium phayara 424 Posted February 13, 2016 Premium Share Posted February 13, 2016 Thank you very much, it works. Link to comment Share on other sites More sharing options...
mdxyz 240 Posted February 13, 2016 Share Posted February 13, 2016 tx dude! 2 Link to comment Share on other sites More sharing options...
Dollar 104 Posted February 13, 2016 Share Posted February 13, 2016 thanks 2 Link to comment Share on other sites More sharing options...
Curinga 1 Posted February 16, 2016 Share Posted February 16, 2016 Thank You! Link to comment Share on other sites More sharing options...
alondark 59 Posted February 18, 2016 Share Posted February 18, 2016 thank Link to comment Share on other sites More sharing options...
Management Karbust 4881 Posted May 22, 2016 Management Share Posted May 22, 2016 Thank you I have a problem... When I reload the shops, I can't open any shop anymore until I restart the server... What I did wrong? Link to comment Share on other sites More sharing options...
alper40s 1 Posted June 28, 2016 Share Posted June 28, 2016 Dont read navicat > player table My banword table have 114 colums but after adding system reload p or reload reloading banword(0) ?* Link to comment Share on other sites More sharing options...
xRooT 24 Posted July 1, 2016 Share Posted July 1, 2016 Thank you Link to comment Share on other sites More sharing options...
RoyaLy 0 Posted November 7, 2016 Share Posted November 7, 2016 Thank you Link to comment Share on other sites More sharing options...
Hik 108 Posted February 13, 2017 Share Posted February 13, 2017 (edited) Someone have this problem? http://pastebin.com/HV4BQER7 FIX: source/teen/utils.h -- The identifier is here. Edited August 20, 2022 by Metin2 Dev Core X - External 2 Internal Link to comment Share on other sites More sharing options...
zeimpekis9 68 Posted September 10, 2017 Share Posted September 10, 2017 I have this prob: cmd_gm.cpp: In function 'void reload_regen(CHARACTER*, const char*, int, int)': cmd_gm.cpp:947: error: 'class SECTREE_MANAGER' has no member named 'BuildMap' gmake: *** [OBJDIR_GAME/cmd_gm.o] Error 1 Link to comment Share on other sites More sharing options...
Horinna 4 Posted December 25, 2017 Share Posted December 25, 2017 Thank you, @masodikbela. edit: everything works perfectly. Link to comment Share on other sites More sharing options...
Management Karbust 4881 Posted December 26, 2017 Management Share Posted December 26, 2017 Why is this topic on Metin2 Q&A? Moving it to "Programming / Scripts" would be easier to find... Link to comment Share on other sites More sharing options...
Forum Moderator Raylee 656 Posted February 17, 2018 Forum Moderator Share Posted February 17, 2018 #moved Best regards Raylee Link to comment Share on other sites More sharing options...
Atem 0 Posted July 26, 2018 Share Posted July 26, 2018 Thanks Link to comment Share on other sites More sharing options...
Recommended Posts