криво работает сохранение преференсов

Статус
В этой теме нельзя размещать новые ответы.
Сообщения
16
Реакции
2
Ошибка
L 03/28/2023 - 20:01:32: [player_prefs.amxx] [PP] Queue time: 0.0779
L 03/28/2023 - 20:01:32: [player_prefs.amxx] [PP] Error[1452]: Cannot add or update a child row: a foreign key constraint fails (`mysql`.`pp_preferences`, CONSTRAINT `pp_preferences_ibfk_2` FOREIGN KEY (`key_id`) REFERENCES `pp_keys` (`id`) ON DELETE CASCADE ON UPDATE CASCADE)
L 03/28/2023 - 20:01:32: [player_prefs.amxx] [PP] Query with error: INSERT INTO `pp_preferences` (`player_id`, `key_id`, `value`) VALUES (1, 0, '0.040000') ON DUPLICATE KEY UPDATE `value` = '0.040000';
L 03/28/2023 - 20:01:32: [player_prefs.amxx] [PP] Queue time: 0.0500
L 03/28/2023 - 20:01:32: [player_prefs.amxx] [PP] Error[1452]: Cannot add or update a child row: a foreign key constraint fails (`mysql`.`pp_preferences`, CONSTRAINT `pp_preferences_ibfk_2` FOREIGN KEY (`key_id`) REFERENCES `pp_keys` (`id`) ON DELETE CASCADE ON UPDATE CASCADE)
L 03/28/2023 - 20:01:32: [player_prefs.amxx] [PP] Query with error: INSERT INTO `pp_preferences` (`player_id`, `key_id`, `value`) VALUES (1, 0, '0.200000') ON DUPLICATE KEY UPDATE `value` = '0.200000';
ОС
Windows
Amx Mod X
1.9.0
Билд
Protocol version 48
Exe version 1.1.2.7/Stdio <cstirke>
ReHLDS version: 3.12.0.785-dev
Build date 17:12:40 Oct 08.2022 <3101>
ReGamedll
ReGameDLL version: 5.21.0.556-dev
Build date: 08:44:42 Jul 22 2022
Версия Metamod
Metamod-r v1.3.0.128, API <5:13>
Metamod-r build: 15:47:38 Aug 24 2018
Список метамодулей
Currently loaded plugins:
description stat pend file vers src load unlod
[ 1] Reunion RUN - reunion_mm_i386. v0.1.137d ini Start Never
[ 2] AMX Mod X RUN - amxmodx_mm_i386. v1.9.0.5 ini Start ANY
[ 3] Revoice RUN - revoice_mm_i386. v0.1.0.34 ini Start Never
[ 4] Rechecker RUN - rechecker_mm_i38 v2.5 ini Chlvl ANY
[5] FakeMeta RUN - fakemeta_amxx_i3 v1.9.0.5 pl3 ANY ANY
[6] Ham Sandwich RUN - hamsandwich_amxx v1.9.0.5 pl3 ANY ANY
[7] ReAimDetector RUN - reaimdetector_am v0.2.2 pl3 ANY Never
[8] MySQL RUN - mysql_amxx_i386. v1.9.0.5 pl3 ANY ANY
[9] ReAPI RUN - reapi_amxx_i386. v5.22.0.254-dev pl3 ANY Never
9 plugins, 9 running
Список плагинов
весь дефолт, кроме:

Currently loaded plugins:
name version author file status
[ 1] Playe preferences 1.0.0 ufame player_prefs.amxx running
[ 2] Playe preferences: test 1.0.0 ufame pp_test.amxx running
Автор плагина
ufame
Версия плагина
1.0.0
Исходный код
#include <amxmodx>
#include <sqlx>
#include <player_prefs>

#pragma semicolon 1

const MAX_QUERY_LENGTH = 4096;

enum {
State_LoadKeys,
State_LoadPlayer,
State_InsertPlayer,
State_LoadPreferences,
State_InsertKey,
State_InsertPreference,
State_SetDefaultValue
};

enum _: Forwards {
Forward_Initialized,
Forward_PlayerLoaded,
Forward_PlayerSaved
};

new g_iPlayerDatabaseId[MAX_PLAYERS + 1];
new Trie: g_tPlayerPreferences[MAX_PLAYERS + 1];

new Trie: g_tKeys;

new g_szSqlHost[32], g_szSqlUser[32], g_szSqlPassword[128], g_szSqlDatabase[32];
new g_iForwards[Forwards];

new g_szQuery[MAX_QUERY_LENGTH];
new Handle: g_hSqlTuple;

new bool: g_bDebugMode;

public plugin_init() {
register_plugin("Player preferences", "1.0.0", "ufame");

CreateForwards();
CreateCvars();

g_bDebugMode = bool: (plugin_flags() & AMX_FLAG_DEBUG);
}

public client_putinserver(iPlayer) {
if (is_user_hltv(iPlayer) || is_user_bot(iPlayer))
return;

g_iPlayerDatabaseId[iPlayer] = 0;
TrieDestroy(g_tPlayerPreferences[iPlayer]);

LoadPreferences(iPlayer);
}

public plugin_natives() {
register_native("pp_is_loaded", "native_is_loaded");
register_native("pp_get_preference", "native_get_preference");
register_native("pp_set_preference", "native_set_preference");

register_native("pp_set_key_default_value", "native_set_key_default_value");
}

public bool: native_is_loaded(iPlugin, iArgs) {
enum {
arg_player_id = 1
};

new iPlayer = get_param(arg_player_id);

if (!is_user_connected(iPlayer))
return false;

return bool: g_iPlayerDatabaseId[iPlayer];
}

public bool: native_get_preference(iPlugin, iArgs) {
enum {
arg_player_id = 1,
arg_key,
arg_dest,
arg_destlen
};

new iPlayer = get_param(arg_player_id);

if (!is_user_connected(iPlayer) || g_tPlayerPreferences[iPlayer] == Invalid_Trie)
return false;

new szKey[32], szValue[256];
new iLen = get_param(arg_destlen);

get_string(arg_key, szKey, charsmax(szKey));

if (!TrieGetString(g_tPlayerPreferences[iPlayer], szKey, szValue, charsmax(szValue)))
TrieGetString(g_tKeys, szKey, szValue, charsmax(szValue));

set_string(arg_dest, szValue, iLen);

return true;
}

public bool: native_set_preference(iPlugin, iArgs) {
enum {
arg_player_id = 1,
arg_key,
arg_value,
arg_default_value
};

new iPlayer = get_param(arg_player_id);

if (!is_user_connected(iPlayer))
return false;

new szKey[32], szValue[256], szDefaultValue[256];

get_string(arg_key, szKey, charsmax(szKey));
get_string(arg_value, szValue, charsmax(szValue));
get_string(arg_default_value, szDefaultValue, charsmax(szDefaultValue));

return bool: SetPreference(iPlayer, szKey, szValue, szDefaultValue);
}

public bool: native_set_key_default_value(iPlugin, iArgs) {
enum {
arg_key = 1,
arg_default_value
};

new szKey[32], szDefaultValue[256];

get_string(arg_key, szKey, charsmax(szKey));
get_string(arg_default_value, szDefaultValue, charsmax(szDefaultValue));

if (g_hSqlTuple != Empty_Handle) {
formatex(g_szQuery, charsmax(g_szQuery),
"INSERT INTO `pp_keys` (`key`, `default_value`) VALUES ('%s', '%s') \
ON DUPLICATE KEY UPDATE `default_value` = '%s';",
szKey, szDefaultValue, szDefaultValue
);

__debug("Insert key %s <%s>: %s", szKey, szDefaultValue, g_szQuery);

new iData[1];
iData[0] = State_SetDefaultValue;

SQL_ThreadQuery(g_hSqlTuple, "ThreadQuery_Handler", g_szQuery, iData, sizeof iData);
}

return bool: TrieSetString(g_tKeys, szKey, szDefaultValue);
}

stock LoadPreferences(iPlayer) {
if (g_hSqlTuple == Empty_Handle)
return;

new szAuth[MAX_AUTHID_LENGTH];
get_user_authid(iPlayer, szAuth, charsmax(szAuth));

formatex(g_szQuery, charsmax(g_szQuery),
"SELECT `id` FROM `pp_players` WHERE `authid` = '%s';",
szAuth
);

new iData[3];
iData[0] = State_LoadPlayer;
iData[1] = iPlayer;
iData[2] = get_user_userid(iPlayer);

SQL_ThreadQuery(g_hSqlTuple, "ThreadQuery_Handler", g_szQuery, iData, sizeof iData);
}

stock SetPreference(iPlayer, szKey[], szValue[], szDefaultValue[]) {
if (g_hSqlTuple != Empty_Handle) {
formatex(g_szQuery, charsmax(g_szQuery),
"INSERT INTO `pp_keys` (`key`, `default_value`) VALUES ('%s', '%s') \
ON DUPLICATE KEY UPDATE `default_value` = '%s';",
szKey, szDefaultValue, szDefaultValue
);

enum data {
query_state,
player_id,
player_userid,
value[256]
};

new szData[data];

szData[query_state] = State_InsertKey;
szData[player_id] = iPlayer;
szData[player_userid] = get_user_userid(iPlayer);
formatex(szData[value], charsmax(szData[value]), szValue);

__debug("Insert key %s: %d / %d - %s",
szKey, szData[player_id], szData[player_userid], szValue
);

SQL_ThreadQuery(g_hSqlTuple, "ThreadQuery_Handler", g_szQuery, szData, sizeof szData);
}

if (g_tPlayerPreferences[iPlayer] == Invalid_Trie)
g_tPlayerPreferences[iPlayer] = TrieCreate();

return bool: TrieSetString(g_tPlayerPreferences[iPlayer], szKey, szValue);
}

public ThreadQuery_Handler(iFailState, Handle: hQuery, szError[], iError, szData[], iDataSize, Float: flQueueTime) {
if (iFailState != TQUERY_SUCCESS) {
SQL_ThreadError(hQuery, szError, iError, flQueueTime);

return;
}

switch (szData[0]) {
case State_LoadKeys: {
new szKey[64], szDefaultValue[256];

while (SQL_MoreResults(hQuery)) {
SQL_ReadResult(hQuery, SQL_FieldNameToNum(hQuery, "key"), szKey, charsmax(szKey));
SQL_ReadResult(hQuery, SQL_FieldNameToNum(hQuery, "default_value"), szDefaultValue, charsmax(szDefaultValue));

TrieSetString(g_tKeys, szKey, szDefaultValue);

SQL_NextRow(hQuery);
}

log_amx("Successfully loaded %d keys", SQL_AffectedRows(hQuery));
}

case State_LoadPlayer: {
new iPlayer = szData[1];
new iUserid = szData[2];

__debug("State: Load Player #1 <%d><%d><%d>", iPlayer, iUserid, get_user_userid(iPlayer));

if (iUserid != get_user_userid(iPlayer))
return;

new szAuth[MAX_AUTHID_LENGTH];
get_user_authid(iPlayer, szAuth, charsmax(szAuth));

__debug("State: Load Player #2 <%d><%d><%d><%s>", iPlayer, iUserid, get_user_userid(iPlayer), szAuth);

if (!SQL_NumResults(hQuery)) {
formatex(g_szQuery, charsmax(g_szQuery),
"INSERT INTO `pp_players` (`authid`) VALUES ('%s');",
szAuth
);

szData[0] = State_InsertPlayer;

SQL_ThreadQuery(g_hSqlTuple, "ThreadQuery_Handler", g_szQuery, szData, iDataSize);

__debug("State: Insert Player #1 <%d><%d><%d><%s>: %s", iPlayer, iUserid, get_user_userid(iPlayer), szAuth, g_szQuery);

return;
}

g_iPlayerDatabaseId[iPlayer] = SQL_ReadResult(hQuery, SQL_FieldNameToNum(hQuery, "id"));

formatex(g_szQuery, charsmax(g_szQuery),
"SELECT `pp_keys`.`key`, `pp_preferences`.`value` \
FROM `pp_keys` \
JOIN `pp_preferences` \
ON `pp_keys`.`id` = `pp_preferences`.`key_id` \
WHERE `pp_preferences`.`player_id` = %d;",
g_iPlayerDatabaseId[iPlayer]
);

szData[0] = State_LoadPreferences;

SQL_ThreadQuery(g_hSqlTuple, "ThreadQuery_Handler", g_szQuery, szData, iDataSize);

__debug("State: Load Preferences #1 <%d><%d><%d><%s>: %s", iPlayer, iUserid, get_user_userid(iPlayer), szAuth, g_szQuery);
}

case State_InsertPlayer: {
new iPlayer = szData[1];
new iUserid = szData[2];

__debug("State: Insert Player #2 <%d><%d><%d>", iPlayer, iUserid, get_user_userid(iPlayer));

if (iUserid != get_user_userid(iPlayer))
return;

__debug("State: Insert Player #3 <%d><%d><%d>", iPlayer, iUserid, get_user_userid(iPlayer));

g_iPlayerDatabaseId[iPlayer] = SQL_GetInsertId(hQuery);

ExecuteForward(g_iForwards[Forward_PlayerLoaded], _, iPlayer);
}

case State_LoadPreferences: {
new iPlayer = szData[1];
new iUserid = szData[2];

__debug("State: Load Preferences #2 <%d><%d><%d>", iPlayer, iUserid, get_user_userid(iPlayer));

if (iUserid != get_user_userid(iPlayer))
return;

__debug("State: Load Preferences #3 <%d><%d><%d>", iPlayer, iUserid, get_user_userid(iPlayer));

new szKey[64], szValue[256];

if (g_tPlayerPreferences[iPlayer] == Invalid_Trie)
g_tPlayerPreferences[iPlayer] = TrieCreate();

while (SQL_MoreResults(hQuery)) {
SQL_ReadResult(hQuery, SQL_FieldNameToNum(hQuery, "key"), szKey, charsmax(szKey));
SQL_ReadResult(hQuery, SQL_FieldNameToNum(hQuery, "value"), szValue, charsmax(szValue));

TrieSetString(g_tPlayerPreferences[iPlayer], szKey, szValue);

SQL_NextRow(hQuery);
}

ExecuteForward(g_iForwards[Forward_PlayerLoaded], _, iPlayer);
}

case State_InsertKey: {
new iPlayer = szData[1];
new iUserid = szData[2];

__debug("State: Insert key #2 <%d><%d><%d>", iPlayer, iUserid, get_user_userid(iPlayer));

if (iUserid != get_user_userid(iPlayer))
return;

new szValue[256];
formatex(szValue, charsmax(szValue), szData[3], charsmax(szData[]));

formatex(g_szQuery, charsmax(g_szQuery),
"INSERT INTO `pp_preferences` (`player_id`, `key_id`, `value`) VALUES (%d, %d, '%s') \
ON DUPLICATE KEY UPDATE `value` = '%s';",
g_iPlayerDatabaseId[iPlayer], SQL_GetInsertId(hQuery), szValue, szValue
);

__debug("State: Insert key #3 <%d><%d><%d><%s>: %s", iPlayer, iUserid, get_user_userid(iPlayer), szValue, g_szQuery);

szData[0] = State_InsertPreference;

SQL_ThreadQuery(g_hSqlTuple, "ThreadQuery_Handler", g_szQuery, szData, iDataSize);
}

case State_InsertPreference: {
new iPlayer = szData[1];
new iUserid = szData[2];

__debug("State: Insert Preference #2 <%d><%d><%d>", iPlayer, iUserid, get_user_userid(iPlayer));

if (iUserid != get_user_userid(iPlayer))
return;

ExecuteForward(g_iForwards[Forward_PlayerSaved], _, iPlayer);
}

case State_SetDefaultValue: {

}
}
}

CreateCvars() {
bind_pcvar_string(create_cvar("pp_host", "Host", FCVAR_SPONLY | FCVAR_PROTECTED | FCVAR_UNLOGGED), g_szSqlHost, charsmax(g_szSqlHost));
bind_pcvar_string(create_cvar("pp_user", "User", FCVAR_SPONLY | FCVAR_PROTECTED | FCVAR_UNLOGGED), g_szSqlUser, charsmax(g_szSqlUser));
bind_pcvar_string(create_cvar("pp_pass", "Password", FCVAR_SPONLY | FCVAR_PROTECTED | FCVAR_UNLOGGED), g_szSqlPassword, charsmax(g_szSqlPassword));
bind_pcvar_string(create_cvar("pp_db", "Database", FCVAR_SPONLY | FCVAR_PROTECTED | FCVAR_UNLOGGED), g_szSqlDatabase, charsmax(g_szSqlDatabase));

AutoExecConfig();

ConnectionTest();
}

CreateForwards() {
g_iForwards[Forward_Initialized] = CreateMultiForward("pp_init", ET_IGNORE);
g_iForwards[Forward_PlayerLoaded] = CreateMultiForward("pp_player_loaded", ET_IGNORE, FP_CELL);
g_iForwards[Forward_PlayerSaved] = CreateMultiForward("pp_player_saved", ET_IGNORE, FP_CELL);
}

ConnectionTest() {
g_hSqlTuple = SQL_MakeDbTuple(g_szSqlHost, g_szSqlUser, g_szSqlPassword, g_szSqlDatabase);

new szError[512], iErrorCode, retVal;
new Handle: hConnection = SQL_Connect(g_hSqlTuple, iErrorCode, szError, charsmax(szError));

if (hConnection == Empty_Handle) {
SQL_FreeHandle(g_hSqlTuple);
g_hSqlTuple = Empty_Handle;

log_error(AMX_ERR_NATIVE, "[PP] Connection error[%d]: %s", iErrorCode, szError);

ExecuteForward(g_iForwards[Forward_Initialized], retVal);

return;
}

log_amx("[PP] Connection to database successfully estabilished");

g_tKeys = TrieCreate();

formatex(g_szQuery, charsmax(g_szQuery),
"SELECT * FROM `pp_keys`"
);

new iData[1];
iData[0] = State_LoadKeys;

SQL_ThreadQuery(g_hSqlTuple, "ThreadQuery_Handler", g_szQuery, iData, sizeof iData);

ExecuteForward(g_iForwards[Forward_Initialized], retVal);
}

SQL_ThreadError(Handle: hQuery, szError[], iError, Float: flQueueTime) {
SQL_GetQueryString(hQuery, g_szQuery, charsmax(g_szQuery));

log_amx("[PP] Queue time: %.4f", flQueueTime);
log_amx("[PP] Error[%d]: %s", iError, szError);
log_amx("[PP] Query with error: %s", g_szQuery);
}

__debug(const debug_message[], any: ...) {
if (!g_bDebugMode)
return;

new szMessage[1024];
vformat(szMessage, charsmax(szMessage), debug_message, 2);

log_to_file("pp_debug.log", szMessage);
}
действия:
-зашел на сервер
-ввел команду в чат /pp
-начал играться с менюшкой (менять координаты, и т.д)
-реконнект, данные криво сейвятся, в консоли ерроры с sql
 
В этой теме было размещено решение! Перейти к решению.
Сообщения
82
Реакции
49
Помог
4 раз(а)
pp_test.amxx отправьте исходник
 
Статус
В этой теме нельзя размещать новые ответы.

Пользователи, просматривающие эту тему

Сейчас на форуме нет ни одного пользователя.
Сверху Снизу