![]() |
|
Dynamically T_Magic - Printable Version +- LCKB (https://lckb.dev/forum) +-- Forum: ** OLD LCKB DATABASE ** (https://lckb.dev/forum/forumdisplay.php?fid=109) +--- Forum: Guides & Help Section (https://lckb.dev/forum/forumdisplay.php?fid=193) +---- Forum: Help & Support (https://lckb.dev/forum/forumdisplay.php?fid=157) +----- Forum: Ep4 Support (https://lckb.dev/forum/forumdisplay.php?fid=128) +----- Thread: Dynamically T_Magic (/showthread.php?tid=5091) |
- Scura - 05-30-2024 Hi guys! Since i seen the t_magic system doesn't use the lod file, i was thinking about dynamically load the data from the db when is needed by using a gm command. I've tested many stuff without any result ... the last thing i tried was to reload everything in a temp struct and then just overwrite the original one. Someone have a better idea about how to handle this ```C++ bool CMagicProtoList::ReloadFromDB() { CDBCmd cmd1; CDBCmd cmd2; cmd1.Init(&gserver->m_dbdata); cmd2.Init(&gserver->m_dbdata); cmd1.SetQuery("SELECT * FROM t_magic ORDER BY a_index"); if (!cmd1.Open()) return false; int new_count = cmd1.m_nrecords; if (new_count) { // Create a temporary array to hold the new CMagicProto objects CMagicProto** temp_list = new CMagicProto * [new_count]; int i = 0; while (cmd1.MoveNext()) { int index; char maxlevel; char type; char subtype; char damagetype; char hittype; char attribute; int psp; int ptp; int hsp; int htp; int bTogel; cmd1.GetRec("a_index", index); cmd1.GetRec("a_maxlevel", maxlevel); cmd1.GetRec("a_type", type); cmd1.GetRec("a_subtype", subtype); cmd1.GetRec("a_damagetype", damagetype); cmd1.GetRec("a_hittype", hittype); cmd1.GetRec("a_attribute", attribute); cmd1.GetRec("a_psp", psp); cmd1.GetRec("a_ptp", ptp); cmd1.GetRec("a_hsp", hsp); cmd1.GetRec("a_htp", htp); cmd1.GetRec("a_togle", bTogel); std: tring select_magiclevel_query = boost: tr(boost::format("SELECT * FROM t_magiclevel WHERE a_index=%d ORDER BY a_level") % index); cmd2.SetQuery(select_magiclevel_query); if (!cmd2.Open()) { for (int k = 0; k < i; ++k) { delete temp_list[k]; } delete[] temp_list; return false; } CMagicLevelProto** levelproto = new CMagicLevelProto * [maxlevel]; memset(levelproto, 0, sizeof(*levelproto) * maxlevel); int j = 0; while (cmd2.MoveNext()) { int power; int hitrate; cmd2.GetRec("a_power", power); cmd2.GetRec("a_hitrate", hitrate); levelproto[j] = new CMagicLevelProto(power, hitrate); j++; } // Create CMagicProto object with provided constructor temp_list[i] = new CMagicProto(index, maxlevel, type, subtype, damagetype, hittype, attribute, psp, ptp, hsp, htp, bTogel, levelproto); // Increment i i++; } // No need to delete old CMagicProto objects here // Just update m_list with the new data if (m_list) { m_list = temp_list; m_count = new_count; } } else LOG_ERROR("new_count is null"); return true; } ``` - Scura - 05-30-2024 Just wanna add more information since i am dig in to it: i've manage to make it works correctly but if you launch the command a few times, it sometimes report the error 3306 has been blocked. The system should still works as expected ? bool CMagicProtoList::ReloadFromDB() { CDBCmd cmd1; CDBCmd cmd2; cmd1.Init(&gserver->m_dbdata); cmd2.Init(&gserver->m_dbdata); cmd1.SetQuery("SELECT * FROM t_magic ORDER BY a_index"); if (!cmd1.Open()) return false; while (cmd1.MoveNext()) { int index; char maxlevel; char type; char subtype; char damagetype; char hittype; char attribute; int psp; int ptp; int hsp; int htp; int bTogel; cmd1.GetRec("a_index", index); cmd1.GetRec("a_maxlevel", maxlevel); cmd1.GetRec("a_type", type); cmd1.GetRec("a_subtype", subtype); cmd1.GetRec("a_damagetype", damagetype); cmd1.GetRec("a_hittype", hittype); cmd1.GetRec("a_attribute", attribute); cmd1.GetRec("a_psp", psp); cmd1.GetRec("a_ptp", ptp); cmd1.GetRec("a_hsp", hsp); cmd1.GetRec("a_htp", htp); cmd1.GetRec("a_togle", bTogel); std: tring select_magiclevel_query = boost: tr(boost::format("SELECT * FROM t_magiclevel WHERE a_index=%d ORDER BY a_level") % index); cmd2.SetQuery(select_magiclevel_query); if (!cmd2.Open()) return false; CMagicLevelProto** levelproto = new CMagicLevelProto * [maxlevel]; memset(levelproto, 0, sizeof(CMagicLevelProto*) * maxlevel); int j = 0; while (cmd2.MoveNext()) { int power; int hitrate; cmd2.GetRec("a_power", power); cmd2.GetRec("a_hitrate", hitrate); levelproto[j] = new CMagicLevelProto(power, hitrate); j++; } // Find the existing CMagicProto object in m_list by index for (int k = 0; k < m_count; ++k) { if (m_list[k]->m_index == index) { // Update the m_levelproto with the new levelproto //delete[] m_list[k]->m_levelproto; // Delete the old levelproto array (commented since may crash the reference, but may occure in memory leaks!) m_list[k]->m_levelproto = levelproto; // Assign the new levelproto array break; } } } return true; } - Scura - 05-30-2024 found that there was the spamblock system which cause this issues, i blocked it on client side. the system seems to works fine. You can also uncomment the delete[] m_list[k]->m_levelproto; part, since it works fine and fix the memory leaks issue ... i may convert this topic to a release ... but i am too lazy and not sure about it, so let me know ^^ - CyberClaus - 05-30-2024 Have a look at this, maybe it helps a bit: bool CMagicProtoList::ReloadFromDB() { CDBCmd cmd1; CDBCmd cmd2; cmd1.Init(&gserver->m_dbdata); cmd2.Init(&gserver->m_dbdata); cmd1.SetQuery("SELECT * FROM t_magic ORDER BY a_index"); if (!cmd1.Open()) return false; int new_count = cmd1.m_nrecords; if (new_count) { // Create a temporary array to hold the new CMagicProto objects CMagicProto** temp_list = new CMagicProto * [new_count]; memset(temp_list, 0, sizeof(CMagicProto*) * new_count); int i = 0; while (cmd1.MoveNext()) { int index; char maxlevel; char type; char subtype; char damagetype; char hittype; char attribute; int psp; int ptp; int hsp; int htp; int bTogel; cmd1.GetRec("a_index", index); cmd1.GetRec("a_maxlevel", maxlevel); cmd1.GetRec("a_type", type); cmd1.GetRec("a_subtype", subtype); cmd1.GetRec("a_damagetype", damagetype); cmd1.GetRec("a_hittype", hittype); cmd1.GetRec("a_attribute", attribute); cmd1.GetRec("a_psp", psp); cmd1.GetRec("a_ptp", ptp); cmd1.GetRec("a_hsp", hsp); cmd1.GetRec("a_htp", htp); cmd1.GetRec("a_togle", bTogel); std: tring select_magiclevel_query = boost: tr(boost::format("SELECT * FROM t_magiclevel WHERE a_index=%d ORDER BY a_level") % index); cmd2.SetQuery(select_magiclevel_query); if (!cmd2.Open()) { for (int k = 0; k < i; ++k) { delete temp_list[k]; } delete[] temp_list; return false; } CMagicLevelProto** levelproto = new CMagicLevelProto * [maxlevel]; memset(levelproto, 0, sizeof(CMagicLevelProto*) * maxlevel); int j = 0; while (cmd2.MoveNext()) { int power; int hitrate; cmd2.GetRec("a_power", power); cmd2.GetRec("a_hitrate", hitrate); levelproto[j] = new CMagicLevelProto(power, hitrate); j++; } // Create CMagicProto object with provided constructor temp_list[i] = new CMagicProto(index, maxlevel, type, subtype, damagetype, hittype, attribute, psp, ptp, hsp, htp, bTogel, levelproto); // Increment i i++; } // No need to delete old CMagicProto objects here // Just update m_list with the new data if (m_list) { for (int k = 0; k < m_count; ++k) { delete m_list[k]; } delete[] m_list; } m_list = temp_list; m_count = new_count; } else { LOG_ERROR("new_count is null"); return false; } return true; } - Scura - 05-30-2024 Yeah, that was the first thing I tried, but it also crashed the game server since you essentially delete the main reference of the address in memory. I got an access violation, and then I realized I needed to update all the address that refer to the struct in memory ... at least i thought .... open to discussion on it, have you tried by yourself ? When you perform tthis action, the orginal address of the list is destroyed delete[] m_list; and doing something like this is horrible CMagicProtoList::~CMagicProtoList() { } just end up reassigne the new value to the default structure was fine. - CyberClaus - 05-31-2024 I see, it is the main problem... the memory management. Not much to do there, you would need to do a specific memory management void. Good work there |