game: prepare guild comment mutations

This commit is contained in:
server
2026-04-13 21:48:12 +02:00
parent cc8fa1e78a
commit a0ad693e13
3 changed files with 79 additions and 14 deletions

View File

@@ -18,6 +18,9 @@
#include "questmanager.h"
#include "MarkManager.h"
#include "MarkImage.h"
#include "libsql/Statement.h"
#include <string>
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<char*>(name))
|| !stmt.BindParam(MYSQL_TYPE_TINY, &notice)
|| !stmt.BindParam(MYSQL_TYPE_STRING, const_cast<char*>(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<char*>(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<SQLMsg> 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);
}
}

View File

@@ -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);
}

View File

@@ -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);