diff --git a/src/game/guild.cpp b/src/game/guild.cpp index b8c7a4d..0e5339b 100644 --- a/src/game/guild.cpp +++ b/src/game/guild.cpp @@ -18,6 +18,9 @@ #include "questmanager.h" #include "MarkManager.h" #include "MarkImage.h" +#include "libsql/Statement.h" + +#include SGuildMember::SGuildMember(LPCHARACTER ch, BYTE grade, DWORD offer_exp) : pid(ch->GetPlayerID()), grade(grade), is_general(0), job(ch->GetJob()), level(ch->GetLevel()), offer_exp(offer_exp), name(ch->GetName()) @@ -28,6 +31,67 @@ namespace { + bool PrepareGameStmt(CStmt& stmt, const std::string& query) + { + CAsyncSQL* sql = DBManager::instance().GetDirectSQL(); + + if (!sql) + { + sys_err("game direct SQL handle is not initialized"); + return false; + } + + return stmt.Prepare(sql, query.c_str()); + } + + bool InsertGuildComment(uint32_t guildId, const char* name, uint8_t notice, const char* content) + { + CStmt stmt; + const std::string query = std::string("INSERT INTO guild_comment") + get_table_postfix() + + "(guild_id, name, notice, content, time) VALUES(?, ?, ?, ?, NOW())"; + + if (!PrepareGameStmt(stmt, query)) + return false; + + if (!stmt.BindParam(MYSQL_TYPE_LONG, &guildId) + || !stmt.BindParam(MYSQL_TYPE_STRING, const_cast(name)) + || !stmt.BindParam(MYSQL_TYPE_TINY, ¬ice) + || !stmt.BindParam(MYSQL_TYPE_STRING, const_cast(content))) + { + return false; + } + + return stmt.Execute(); + } + + bool DeleteGuildComment(uint32_t guildId, uint32_t commentId, const char* nameFilter, unsigned long long& affectedRows) + { + CStmt stmt; + const std::string query = nameFilter + ? std::string("DELETE FROM guild_comment") + get_table_postfix() + " WHERE id=? AND guild_id=? AND name=?" + : std::string("DELETE FROM guild_comment") + get_table_postfix() + " WHERE id=? AND guild_id=?"; + + affectedRows = 0; + + if (!PrepareGameStmt(stmt, query)) + return false; + + if (!stmt.BindParam(MYSQL_TYPE_LONG, &commentId) + || !stmt.BindParam(MYSQL_TYPE_LONG, &guildId)) + { + return false; + } + + if (nameFilter && !stmt.BindParam(MYSQL_TYPE_STRING, const_cast(nameFilter))) + return false; + + if (!stmt.Execute()) + return false; + + affectedRows = stmt.GetAffectedRows(); + return true; + } + struct FGuildNameSender { FGuildNameSender(uint32_t id, const char* guild_name) : id(id), name(guild_name) @@ -1042,25 +1106,18 @@ void CGuild::AddComment(LPCHARACTER ch, const std::string& str) return; } - char text[GUILD_COMMENT_MAX_LEN * 2 + 1]; - DBManager::instance().EscapeString(text, sizeof(text), str.c_str(), str.length()); + const uint8_t notice = (str[0] == '!') ? 1 : 0; - DBManager::instance().FuncAfterQuery(std::bind(&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(), (str[0] == '!') ? 1 : 0, text); + if (InsertGuildComment(m_data.guild_id, ch->GetName(), notice, str.c_str())) + RefreshCommentForce(ch->GetPlayerID()); } void CGuild::DeleteComment(LPCHARACTER ch, DWORD comment_id) { - std::unique_ptr pmsg{}; + unsigned long long affectedRows = 0; + const char* nameFilter = GetMember(ch->GetPlayerID())->grade == GUILD_LEADER_GRADE ? NULL : ch->GetName(); - if (GetMember(ch->GetPlayerID())->grade == GUILD_LEADER_GRADE) - pmsg = DBManager::instance().DirectQuery("DELETE FROM guild_comment%s WHERE id = %u AND guild_id = %u",get_table_postfix(), comment_id, m_data.guild_id); - else - pmsg = DBManager::instance().DirectQuery("DELETE FROM guild_comment%s WHERE id = %u AND guild_id = %u AND name = '%s'",get_table_postfix(), comment_id, m_data.guild_id, ch->GetName()); - - auto* res = pmsg ? pmsg->Get() : nullptr; - if (!res || res->uiAffectedRows == 0 || res->uiAffectedRows == (uint32_t)-1) + if (!DeleteGuildComment(m_data.guild_id, comment_id, nameFilter, affectedRows) || affectedRows == 0) ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<길드> 삭제할 수 없는 글입니다.")); else RefreshCommentForce(ch->GetPlayerID()); @@ -2171,4 +2228,3 @@ void CGuild::SendGuildDataUpdateToAllMember(SQLMsg* pmsg) SendAllGradePacket(*iter); } } - diff --git a/src/libsql/Statement.cpp b/src/libsql/Statement.cpp index a1776b1..a34e7a8 100644 --- a/src/libsql/Statement.cpp +++ b/src/libsql/Statement.cpp @@ -180,3 +180,11 @@ unsigned long CStmt::GetResultLength(unsigned int index) const return m_vec_result_len[index]; } + +unsigned long long CStmt::GetAffectedRows() const +{ + if (!m_pkStmt) + return 0; + + return mysql_stmt_affected_rows(m_pkStmt); +} diff --git a/src/libsql/Statement.h b/src/libsql/Statement.h index 1871512..3a52e1f 100644 --- a/src/libsql/Statement.h +++ b/src/libsql/Statement.h @@ -18,6 +18,7 @@ class CStmt int Execute(); bool Fetch(); unsigned long GetResultLength(unsigned int index) const; + unsigned long long GetAffectedRows() const; void Error(const char * c_pszMsg);