diff --git a/src/game/questlua_pc.cpp b/src/game/questlua_pc.cpp index e183e5f..8346948 100644 --- a/src/game/questlua_pc.cpp +++ b/src/game/questlua_pc.cpp @@ -48,6 +48,58 @@ namespace return stmt.Prepare(sql, query.c_str()); } + bool InsertItemAward(const char* login, uint32_t vnum, int count, const char* why) + { + CStmt stmt; + const std::string query = + "INSERT INTO item_award (login, vnum, count, given_time, why, mall) " + "SELECT ?, ?, ?, NOW(), ?, 1 FROM DUAL " + "WHERE NOT EXISTS (SELECT 1 FROM item_award WHERE login=? AND why=?)"; + + if (!PrepareGameStmt(stmt, query)) + return false; + + if (!stmt.BindParam(MYSQL_TYPE_STRING, const_cast(login)) + || !stmt.BindParam(MYSQL_TYPE_LONG, &vnum) + || !stmt.BindParam(MYSQL_TYPE_LONG, &count) + || !stmt.BindParam(MYSQL_TYPE_STRING, const_cast(why)) + || !stmt.BindParam(MYSQL_TYPE_STRING, const_cast(login)) + || !stmt.BindParam(MYSQL_TYPE_STRING, const_cast(why))) + { + return false; + } + + return stmt.Execute(); + } + + bool InsertItemAwardWithSockets(const char* login, uint32_t vnum, int count, const char* why, + long long socket0, long long socket1, long long socket2) + { + CStmt stmt; + const std::string query = + "INSERT INTO item_award (login, vnum, count, given_time, why, mall, socket0, socket1, socket2) " + "SELECT ?, ?, ?, NOW(), ?, 1, ?, ?, ? FROM DUAL " + "WHERE NOT EXISTS (SELECT 1 FROM item_award WHERE login=? AND why=?)"; + + if (!PrepareGameStmt(stmt, query)) + return false; + + if (!stmt.BindParam(MYSQL_TYPE_STRING, const_cast(login)) + || !stmt.BindParam(MYSQL_TYPE_LONG, &vnum) + || !stmt.BindParam(MYSQL_TYPE_LONG, &count) + || !stmt.BindParam(MYSQL_TYPE_STRING, const_cast(why)) + || !stmt.BindParam(MYSQL_TYPE_LONGLONG, &socket0) + || !stmt.BindParam(MYSQL_TYPE_LONGLONG, &socket1) + || !stmt.BindParam(MYSQL_TYPE_LONGLONG, &socket2) + || !stmt.BindParam(MYSQL_TYPE_STRING, const_cast(login)) + || !stmt.BindParam(MYSQL_TYPE_STRING, const_cast(why))) + { + return false; + } + + return stmt.Execute(); + } + bool CharacterNameExists(const char* name, bool& exists) { CStmt stmt; @@ -2781,26 +2833,21 @@ teleport_area: return 1; } - DWORD dwVnum = (int) lua_tonumber(L, 1); + DWORD dwVnum = (int) lua_tonumber(L, 1); - int icount = (int) lua_tonumber(L, 2); - const char* login = ch->GetDesc()->GetAccountTable().login; - const char* why = lua_tostring(L, 3); - const std::string escapedLogin = DBManager::instance().EscapeStringCopy(login ? login : "", login ? strlen(login) : 0); - const std::string escapedWhy = DBManager::instance().EscapeStringCopy(why ? why : "", why ? strlen(why) : 0); + int icount = (int) lua_tonumber(L, 2); + const char* login = ch->GetDesc()->GetAccountTable().login; + const char* why = lua_tostring(L, 3); + const char* safeLogin = login ? login : ""; + const char* safeWhy = why ? why : ""; - sys_log(0, "QUEST [award] item %d to login %s", dwVnum, ch->GetDesc()->GetAccountTable().login); + sys_log(0, "QUEST [award] item %d to login %s", dwVnum, ch->GetDesc()->GetAccountTable().login); - DBManager::instance().Query("INSERT INTO item_award (login, vnum, count, given_time, why, mall)select '%s', %d, %d, now(), '%s', 1 from DUAL where not exists (select login, why from item_award where login = '%s' and why = '%s') ;", - escapedLogin.c_str(), - dwVnum, - icount, - escapedWhy.c_str(), - escapedLogin.c_str(), - escapedWhy.c_str()); + if (!InsertItemAward(safeLogin, dwVnum, icount, safeWhy)) + sys_err("failed to insert item award for login %s", safeLogin); - lua_pushnumber (L, 0); - return 1; + lua_pushnumber (L, 0); + return 1; } int pc_give_award_socket(lua_State* L) { @@ -2813,32 +2860,24 @@ teleport_area: return 1; } - DWORD dwVnum = (int) lua_tonumber(L, 1); + DWORD dwVnum = (int) lua_tonumber(L, 1); - int icount = (int) lua_tonumber(L, 2); - const char* login = ch->GetDesc()->GetAccountTable().login; - const char* why = lua_tostring(L, 3); - long socket0 = strtol(lua_tostring(L, 4), nullptr, 10); - long socket1 = strtol(lua_tostring(L, 5), nullptr, 10); - long socket2 = strtol(lua_tostring(L, 6), nullptr, 10); - const std::string escapedLogin = DBManager::instance().EscapeStringCopy(login ? login : "", login ? strlen(login) : 0); - const std::string escapedWhy = DBManager::instance().EscapeStringCopy(why ? why : "", why ? strlen(why) : 0); + int icount = (int) lua_tonumber(L, 2); + const char* login = ch->GetDesc()->GetAccountTable().login; + const char* why = lua_tostring(L, 3); + long long socket0 = strtoll(lua_tostring(L, 4), nullptr, 10); + long long socket1 = strtoll(lua_tostring(L, 5), nullptr, 10); + long long socket2 = strtoll(lua_tostring(L, 6), nullptr, 10); + const char* safeLogin = login ? login : ""; + const char* safeWhy = why ? why : ""; - sys_log(0, "QUEST [award] item %d to login %s", dwVnum, ch->GetDesc()->GetAccountTable().login); + sys_log(0, "QUEST [award] item %d to login %s", dwVnum, ch->GetDesc()->GetAccountTable().login); - DBManager::instance().Query("INSERT INTO item_award (login, vnum, count, given_time, why, mall, socket0, socket1, socket2)select '%s', %d, %d, now(), '%s', 1, %ld, %ld, %ld from DUAL where not exists (select login, why from item_award where login = '%s' and why = '%s') ;", - escapedLogin.c_str(), - dwVnum, - icount, - escapedWhy.c_str(), - socket0, - socket1, - socket2, - escapedLogin.c_str(), - escapedWhy.c_str()); + if (!InsertItemAwardWithSockets(safeLogin, dwVnum, icount, safeWhy, socket0, socket1, socket2)) + sys_err("failed to insert socket item award for login %s", safeLogin); - lua_pushnumber (L, 0); - return 1; + lua_pushnumber (L, 0); + return 1; } int pc_get_informer_type(lua_State* L) //독일 선물 기능