Active Member Draveniou1 716 Posted April 22, 2023 Active Member Share Posted April 22, 2023 This is the hidden content, please Sign In or Sign Up Alternative download links → This is the hidden content, please Sign In or Sign Up or This is the hidden content, please Sign In or Sign Up or This is the hidden content, please Sign In or Sign Up Changelogs Version 3. Fix quest pick in quest Fix delayed desc kick Now it works stable without problems in version 3 Version 2. Now, the players cannot delete messange other people's In 4 failures the server kick you @ TMP4 @ Abel(Tiger) Version 1. Normal fix guild comment 50 1 1 8 18 Link to comment Share on other sites More sharing options...
Active+ Member Abel(Tiger) 1196 Posted April 24, 2023 Active+ Member Share Posted April 24, 2023 1. The fix I posted is done because you can spam the database with queries. 2. With your "fix" you can delete all coments from the guild with no permissions :))) Link to comment Share on other sites More sharing options...
Active Member Draveniou1 716 Posted April 24, 2023 Author Active Member Share Posted April 24, 2023 15 minutes ago, Abel(Tiger) said: 1. The fix I posted is done because you can spam the database with queries. 2. With your "fix" you can delete all coments from the guild with no permissions :))) They are automatically deleted after 12 message you check Link to comment Share on other sites More sharing options...
Contributor TMP4 10998 Posted April 24, 2023 Contributor Share Posted April 24, 2023 (edited) 35 minutes ago, Draveniou1 said: They are automatically deleted after 12 message you check With your "fix" abusers got +1 query to spam, even if it's just a delete query. Fixing the possibility of the flood and delete old unnecessary comments is 2 seperate things to do. @ Abel(Tiger) did the first, you did the second. And yes, Abel is right because you're not checking any permission, if someone sends a packet on his own (cheat), he can delete other's messages without the required guild permission. Also you did hella lot uneceserry work. If you want to delete older comments, why don't you just do it after the insert? Why do you need a seperate packet? Edited April 24, 2023 by TMP4 Link to comment Share on other sites More sharing options...
Active Member Draveniou1 716 Posted April 24, 2023 Author Active Member Share Posted April 24, 2023 5 minutes ago, TMP4 said: With your "fix" abusers got +1 query to spam, even if it's just a delete query. Fixing the possibility of the flood and delete old unnecessary comments is 2 seperate things to do. @ Abel(Tiger) did the first, you did the second. And yes, Abel is right because you're not checking any permission, if someone sends a packet on his own (cheat), he can delete other's messages without the required guild permission. Also you did hella lot uneceserry work. If you want to delete older comments, why don't you just do it after the insert? Why do you need a seperate packet? -With your "fix" abusers got +1 query to spam, even if it's just a delete query. - We can easy add check query ------------- -Fixing the possibility of the flood and delete old unnecessary comments is 2 seperate things to do. @ Abel(Tiger) did the first, you did the second. - We can easily in the 2 failed attempts the player leaves the server --------------- -And yes, Abel is right because you're not checking any permission, if someone sends a packet on his own (cheat), he can delete other's messages without the required guild permission. you can easily check the player I will try to do them this 1 Link to comment Share on other sites More sharing options...
Active Member Draveniou1 716 Posted April 25, 2023 Author Active Member Share Posted April 25, 2023 I added to the post version2 thank you @ Abel(Tiger) @ TMP4 1 Link to comment Share on other sites More sharing options...
PetePeter 36 Posted April 25, 2023 Share Posted April 25, 2023 Or maybe something like that instead no ? void CGuild::AddComment(LPCHARACTER ch, const std::string& str) { if (str.length() > GUILD_COMMENT_MAX_LEN || str.length() == 0) // Added string null verification return; char text[GUILD_COMMENT_MAX_LEN * 2 + 1]; DBManager::instance().EscapeString(text, sizeof(text), str.c_str(), str.length()); // Fetch the number of existing comments and delete the oldest one if there are 12 comments. DBManager::instance().FuncQuery(std::bind(&CGuild::HandleCommentCount, this, ch, text, std::placeholders::_1), "SELECT COUNT(*), MIN(time) FROM guild_comment%s WHERE guild_id = %u", get_table_postfix(), m_data.guild_id); } void CGuild::HandleCommentCount(LPCHARACTER ch, const char* text, MYSQL_RES* result) { MYSQL_ROW row = mysql_fetch_row(result); if (!row) return; int commentCount = 0; sscanf(row[0], "%d", &commentCount); if (commentCount >= 12) { // Delete the oldest comment DBManager::instance().Query("DELETE FROM guild_comment%s WHERE guild_id = %u AND time = '%s'", get_table_postfix(), m_data.guild_id, row[1]); } // Insert the new comment DBManager::instance().FuncAfterQuery(void_bind(std::bind1st(std::mem_fun(&CGuild::RefreshCommentForce), this), ch->GetPlayerID()), "INSERT INTO guild_comment%s(guild_id, name, notice, content, time) VALUES(%u, '%s', %d, '%s', NOW())", get_table_postfix(), m_data.guild_id, ch->GetName(), (text[0] == '!') ? 1 : 0, text); } 1 1 Link to comment Share on other sites More sharing options...
Active Member Draveniou1 716 Posted April 25, 2023 Author Active Member Share Posted April 25, 2023 8 minutes ago, PetePeter said: Or maybe something like that instead no ? void CGuild::AddComment(LPCHARACTER ch, const std::string& str) { if (str.length() > GUILD_COMMENT_MAX_LEN || str.length() == 0) // Added string null verification return; char text[GUILD_COMMENT_MAX_LEN * 2 + 1]; DBManager::instance().EscapeString(text, sizeof(text), str.c_str(), str.length()); // Fetch the number of existing comments and delete the oldest one if there are 12 comments. DBManager::instance().FuncQuery(std::bind(&CGuild::HandleCommentCount, this, ch, text, std::placeholders::_1), "SELECT COUNT(*), MIN(time) FROM guild_comment%s WHERE guild_id = %u", get_table_postfix(), m_data.guild_id); } void CGuild::HandleCommentCount(LPCHARACTER ch, const char* text, MYSQL_RES* result) { MYSQL_ROW row = mysql_fetch_row(result); if (!row) return; int commentCount = 0; sscanf(row[0], "%d", &commentCount); if (commentCount >= 12) { // Delete the oldest comment DBManager::instance().Query("DELETE FROM guild_comment%s WHERE guild_id = %u AND time = '%s'", get_table_postfix(), m_data.guild_id, row[1]); } // Insert the new comment DBManager::instance().FuncAfterQuery(void_bind(std::bind1st(std::mem_fun(&CGuild::RefreshCommentForce), this), ch->GetPlayerID()), "INSERT INTO guild_comment%s(guild_id, name, notice, content, time) VALUES(%u, '%s', %d, '%s', NOW())", get_table_postfix(), m_data.guild_id, ch->GetName(), (text[0] == '!') ? 1 : 0, text); } I had thought about it too the problem is that mysql will always answer the player's queries and does not eat kick from the game it could be with mine version 1 better there should be a count as they mentioned @ Abel(Tiger) and @ TMP4 1 Link to comment Share on other sites More sharing options...
Active Member Draveniou1 716 Posted April 26, 2023 Author Active Member Share Posted April 26, 2023 My post updated i add version 3 full fix Changelog 1. Fix quest pick in quest 2. Fix delayed desc kick Now it works stable without problems in version 3 thanks a lot 1 Link to comment Share on other sites More sharing options...
PetePeter 36 Posted April 26, 2023 Share Posted April 26, 2023 2 hours ago, Draveniou1 said: My post updated i add version 3 full fix Changelog 1. Fix quest pick in quest 2. Fix delayed desc kick Now it works stable without problems in version 3 thanks a lot Did you recheck your code ? Here is a possible solution: void CGuild::DeleteComment(LPCHARACTER ch, DWORD comment_id) { const int maxAttempts = 3; const int resetIntervalMinutes = 10; // Change this to the desired interval in minutes time_t currentTime = time(0); int attempts = ch->GetQuestFlag("Newfixxed.Newguildcomment"); time_t lastAttemptTime = ch->GetQuestFlag("Newfixxed.LastAttemptTime"); // If the user's last attempt was longer than the reset interval ago, reset their attempts if (difftime(currentTime, lastAttemptTime) >= resetIntervalMinutes * 60) { attempts = 0; } // Check if the user has reached the maximum number of attempts if (attempts >= maxAttempts) { ch->GetDesc()->DelayedDisconnect(0); return; } std::unique_ptr<SQLMsg> pmsg; // Execute the appropriate query based on the user's guild grade if (GetMember(ch->GetPlayerID())->grade == GUILD_LEADER_GRADE) { pmsg.reset(DBManager::instance().DirectQuery("DELETE FROM guild_comment WHERE id = %u AND guild_id = %u", comment_id, m_data.guild_id)); } else { pmsg.reset(DBManager::instance().DirectQuery("DELETE FROM guild_comment WHERE id = %u AND guild_id = %u AND name = '%s'", comment_id, m_data.guild_id, ch->GetName())); } uint32_t affectedRows = pmsg->Get()->uiAffectedRows; // Check if the comment was successfully deleted if (affectedRows == 0 || affectedRows == (uint32_t)-1) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<길드> 삭제할 수 없는 글입니다.")); } else { RefreshCommentForce(ch->GetPlayerID()); } // Update the user's attempt count and last attempt time ch->SetQuestFlag("Newfixxed.Newguildcomment", attempts + 1); ch->SetQuestFlag("Newfixxed.LastAttemptTime", currentTime); } 1 Link to comment Share on other sites More sharing options...
Active Member Draveniou1 716 Posted April 26, 2023 Author Active Member Share Posted April 26, 2023 2 hours ago, PetePeter said: Did you recheck your code ? Here is a possible solution: void CGuild::DeleteComment(LPCHARACTER ch, DWORD comment_id) { const int maxAttempts = 3; const int resetIntervalMinutes = 10; // Change this to the desired interval in minutes time_t currentTime = time(0); int attempts = ch->GetQuestFlag("Newfixxed.Newguildcomment"); time_t lastAttemptTime = ch->GetQuestFlag("Newfixxed.LastAttemptTime"); // If the user's last attempt was longer than the reset interval ago, reset their attempts if (difftime(currentTime, lastAttemptTime) >= resetIntervalMinutes * 60) { attempts = 0; } // Check if the user has reached the maximum number of attempts if (attempts >= maxAttempts) { ch->GetDesc()->DelayedDisconnect(0); return; } std::unique_ptr<SQLMsg> pmsg; // Execute the appropriate query based on the user's guild grade if (GetMember(ch->GetPlayerID())->grade == GUILD_LEADER_GRADE) { pmsg.reset(DBManager::instance().DirectQuery("DELETE FROM guild_comment WHERE id = %u AND guild_id = %u", comment_id, m_data.guild_id)); } else { pmsg.reset(DBManager::instance().DirectQuery("DELETE FROM guild_comment WHERE id = %u AND guild_id = %u AND name = '%s'", comment_id, m_data.guild_id, ch->GetName())); } uint32_t affectedRows = pmsg->Get()->uiAffectedRows; // Check if the comment was successfully deleted if (affectedRows == 0 || affectedRows == (uint32_t)-1) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<길드> 삭제할 수 없는 글입니다.")); } else { RefreshCommentForce(ch->GetPlayerID()); } // Update the user's attempt count and last attempt time ch->SetQuestFlag("Newfixxed.Newguildcomment", attempts + 1); ch->SetQuestFlag("Newfixxed.LastAttemptTime", currentTime); } I don't want to use time_t I prefer the normal one because if I wanted time I have 5000 solutions with times i will use the normal way is better 1 Link to comment Share on other sites More sharing options...
PetePeter 36 Posted April 26, 2023 Share Posted April 26, 2023 (edited) It's not about "normal" ways. 1. You didn't add any return to the function after the player is kicked, so the rest of the function is executed normally 2. You never reset the counter, it's only reset after a kick as the script continue his path and reach the "if (NewFixGuildCommente >= 3)" again 3. (Optionnal) Consider using smart pointers (like std::unique_ptr) instead of raw pointers for better memory management and exception safety. I know the sql function is not made by you, but if we edit this function we can optimise everything also Edited April 26, 2023 by PetePeter 1 2 Link to comment Share on other sites More sharing options...
Active Member Draveniou1 716 Posted April 27, 2023 Author Active Member Share Posted April 27, 2023 23 hours ago, PetePeter said: It's not about "normal" ways. 1. You didn't add any return to the function after the player is kicked, so the rest of the function is executed normally 2. You never reset the counter, it's only reset after a kick as the script continue his path and reach the "if (NewFixGuildCommente >= 3)" again 3. (Optionnal) Consider using smart pointers (like std::unique_ptr) instead of raw pointers for better memory management and exception safety. I know the sql function is not made by you, but if we edit this function we can optimise everything also I don't want a timer if at the same time 90-160 players add the timer then the game that has low connection and you will send a message to the company to solve your problem I have 50 methods with a timer, do you think I'm stupid not to set a timer? one tip: Don't set timers to do something Timer = lag's problem's server He doesn't have a professional mind, man, we're dealing with you, speak for yourself -> 0% professionalism @PetePeter 3 Link to comment Share on other sites More sharing options...
Honorable Member martysama0134 7178 Posted April 30, 2023 Honorable Member Share Posted April 30, 2023 (edited) Without timers, or quest flags (persistent memory): This is the hidden content, please Sign In or Sign Up (enumtype branch) This is the hidden content, please Sign In or Sign Up It stores something like 10 bytes per player (when they use it) in an std::unordered_map (hash map with O(1) access time). It's only stored in memory, and not shared to other cores (it's irrelevant for this case). Edited April 30, 2023 by Metin2 Dev International Core X - External 2 Internal 37 4 1 12 Check out my GitHub Link to comment Share on other sites More sharing options...
Recommended Posts