SQLite не берёт данные из базы

Primo

типа серьёзный тип
Сообщения
1,532
Реакции
759
Есть запрос на подключение к бд, который работает.
PHP:
public ConnectBase()
{
	if (SQL_CheckConfig("dn_data"))
	{
		new String:Error[256];
		db = SQL_Connect("dn_data", true, Error, sizeof(Error));
		if (db == INVALID_HANDLE)
		{
			LogError("Fail connect: %s", Error);
		}
	}
	else
	{
        LogError("Database.cfg missing 'dn_data' entry!");
	}
	SQL_TQuery(db, SQL_DefCallback, "CREATE TABLE IF NOT EXISTS `users` (\ 
			Steam TEXT PRIMARY KEY, \
			Nick TEXT, \
			Level NUMERIC, \ 
			XP NUMERIC)", 0); 
}

Есть запрос на сохранение данных в бд, который тоже работает.

PHP:
public ClientDisconnect(Handle:event, const String:name[], bool:dontBroadcast)
{
	new client = GetClientOfUserId(GetEventInt(event, "userid"));
	new String:pName[256];
	GetClientAuthString(client, pSteamID, 256, true);
	GetClientName(client, pName, 256);
	decl String:query[256];
	Format(query, sizeof(query), "INSERT OR REPLACE INTO users('Steam', 'Nick', 'Level', 'XP') VALUES ('%s', '%s', %d, %d);", pSteamID, pName, Player[pLevel][client], Player[pXP][client]);
	SQL_TQuery(db, SQL_DefCallback, query, 0);
}

Но, не работает, собственно, запрос данных из бд...

PHP:
public OnClientAuthorized(client, const String:auth[])
{
	GetClientAuthString(client, pSteamID, 256, true);
	if(0 < client <= MaxClients && !IsFakeClient(client))
	{
		decl String:query[256];
		Format(query, sizeof(query), "SELECT * FROM users('Steam', 'Nick', 'Level', 'XP') WHERE 'Steam' = '%s'",pSteamID);
		pClient = client;
		SQL_TQuery(db, SQL_DefCallback, query, 0);
	}
}

PHP:
public SQL_DefCallback(Handle:owner, Handle:hndl, const String:error[], any:data) 
{ 
	if (hndl == INVALID_HANDLE) LogError(error);
	Player[pLevel][pClient] = SQL_FetchInt(hndl, 3);
	Player[pXP][pClient] = SQL_FetchInt(hndl, 4);
}
База имеет такой вид:

screen.png
 

wanted241

Real-Gamer.Ru
Сообщения
428
Реакции
161
Мб не
C-подобный:
    Format(query, sizeof(query), "INSERT OR REPLACE INTO users('Steam', 'Nick', 'Level', 'XP') VALUES ('%s', '%s', %d, %d);", pSteamID, pName, Player[pLevel][client], Player[pXP][client]);

А
C-подобный:
    Format(query, sizeof(query), "INSERT INTO users('Steam', 'Nick', 'Level', 'XP') VALUES ('%s', '%s', %d, %d);", pSteamID, pName, Player[pLevel][client], Player[pXP][client]);

Замечал, что если использовать 'OR REPLACE', то часто будет 'REPLACE'.

Добавлено через 2 минуты
На заметку: Не обязательно считывать *, можно отдельные параметры, пример:

C-подобный:
"SELECT lvl, race, gold, favraces FROM wcs WHERE steamid = '%s'"
 
Последнее редактирование:

Primo

типа серьёзный тип
Сообщения
1,532
Реакции
759
Проблема чуть изменилась.
Я понял так.
Когда игрок выходит его значения записываются в базу, но когда он вышел, сменилась карта, и он опять зашел, то все значения, которые в бд не берутся.
Весь код:

PHP:
#include <sourcemod>
#include <sdktools>
#include <sdktools_sound>
#include <cstrike>

static Handle:db;

enum PlayerInfo
{
	pLevel,
	pXP,
	pWeapon0,
	pWeapon1,
}
new String:pSteamID[256];
new Player[PlayerInfo][MAXPLAYERS];
new pClient;


public Plugin:myinfo = 
{ 
    name = "Day Night", 
    author = "Primo", 
    description = "Day Night - new mode to csgo", 
    version = "1.0", 
} 
  
public OnPluginStart() 
{
    ConnectBase();
    HookEvent("player_disconnect", ClientDisconnect);
    HookEvent("round_start", VErtoe_Round_Start); 
    HookEvent("player_spawn", VErtoe_PlayerSpawn);
    HookEvent("player_death", VErtoe_PlayerDeath);
} 

public VErtoe_Round_Start(Handle:event, const String:name[], bool:dontBroadcast) 
{
	new client = GetClientOfUserId(GetEventInt(event, "userid"));
	PrintToChat(client, "Your SteamID = %s", pSteamID);
} 

public OnClientConnected(client)
{
	GetClientAuthString(client, pSteamID, 256, true);
	if(0 < client <= MaxClients && !IsFakeClient(client))
	{
		decl String:query[256];
		Format(query, sizeof(query), "SELECT Steam, Nick, Level, XP FROM users WHERE 'Steam' = '%s';",pSteamID);
		pClient = client;
		SQL_TQuery(db, SQL_DefCallback, query, 0);
	}
}

public ClientDisconnect(Handle:event, const String:name[], bool:dontBroadcast)
{
	new client = GetClientOfUserId(GetEventInt(event, "userid"));
	if(0 < client <= MaxClients && !IsFakeClient(client))
	{

		new String:pName[256];
		GetClientAuthString(client, pSteamID, 256, true);
		GetClientName(client, pName, 256);
		decl String:query[256];
		Format(query, sizeof(query), "INSERT OR REPLACE INTO users('Steam', 'Nick', 'Level', 'XP') VALUES ('%s', '%s', %d, %d);", pSteamID, pName, Player[pLevel][client], Player[pXP][client]);
		SQL_TQuery(db, SQL_DefCallback, query, 0);
	}
}

public VErtoe_PlayerSpawn(Handle:event, const String:name[], bool:dontBroadcast) 
{ 
	new client = GetClientOfUserId(GetEventInt(event, "userid"));
	/*if(GetClientTeam(client) == 3)
	{
		SetEntProp(client, Prop_Send, "m_fEffects", GetEntProp(client, Prop_Send, "m_fEffects") ^ 4);
	}
	if(GetClientTeam(client) == 2)
	{
		SetEntProp(client, Prop_Send, "m_bNightVisionOn", 1)
	}*/
	PrintToChat(client, "В данный момент вы имеете %d уровеень", Player[pLevel][client]);
	if(Player[pLevel][client] == 0)
	{
		Player[pLevel][client]++;
	}
	CheckLvlUp(client);	
}

public VErtoe_PlayerDeath(Handle:event, const String:name[], bool:dontBroadcast)
{
	new attacker = GetClientOfUserId(GetEventInt(event, "attacker"));
	//new victim = GetClientOfUserId(GetEventInt(event, "victim"));
	new health = GetClientHealth(attacker);
	new nLvlXP = Player[pLevel][attacker]+2;
	nLvlXP = nLvlXP*150
	Player[pXP][attacker] = Player[pXP][attacker]+health/10
	PrintToChat(attacker, "Вы получили %d опыта", health/10);
	CheckLvlUp(attacker);
}

public CheckLvlUp(any:client)
{
	new nLvlXP = Player[pLevel][client]+2
	nLvlXP = nLvlXP*150
	PrintToChat(client, "Ваш опыт составляет %d из %d", Player[pXP][client], nLvlXP);
	if(Player[pXP][client] >= nLvlXP)
	{
		Player[pXP][client] = 0;
		Player[pLevel][client]++;
	}
	CheckLvlGun(client);
}

public ConnectBase()
{
	if (SQL_CheckConfig("dn_data"))
	{
		new String:Error[256];
		db = SQL_Connect("dn_data", true, Error, sizeof(Error));
		if (db == INVALID_HANDLE)
		{
			LogError("Fail connect: %s", Error);
		}
	}
	else
	{
        LogError("Database.cfg missing 'dn_data' entry!");
	}
	SQL_TQuery(db, SQL_DefCallback, "CREATE TABLE IF NOT EXISTS `users` (\ 
			Steam TEXT PRIMARY KEY, \
			Nick TEXT, \
			Level NUMERIC, \ 
			XP NUMERIC)", 0); 
}

public SQL_DefCallback(Handle:owner, Handle:hndl, const String:error[], any:data) 
{ 
	if (hndl == INVALID_HANDLE) LogError(error);
	Player[pLevel][pClient] = SQL_FetchInt(hndl, 3);
	Player[pXP][pClient] = SQL_FetchInt(hndl, 4);
}

public CheckLvlGun(any:client)
{
	if(GetClientTeam(client) == 3)
	{
		if(Player[pLevel][client] == 1)
		{
			GivePlayerItem(client, "weapon_glock", 0);
		}
		if(Player[pLevel][client] == 2)
		{
			GivePlayerItem(client, "weapon_p250", 0);
		}
		if(Player[pLevel][client] == 3)
		{
			GivePlayerItem(client, "weapon_fiveseven", 0);
		}
		if(Player[pLevel][client] == 4)
		{
			GivePlayerItem(client, "weapon_deagle", 0);
		}
		if(Player[pLevel][client] == 5)
		{
			GivePlayerItem(client, "weapon_elite", 0);
		}
		if(Player[pLevel][client] == 6)
		{
			GivePlayerItem(client, "weapon_hkp2000 CT-only", 0);
		}
		if(Player[pLevel][client] == 7)
		{
			GivePlayerItem(client, "weapon_nova", 0);
		}
		if(Player[pLevel][client] == 8)
		{
			GivePlayerItem(client, "weapon_xm1014", 0);
		}
		if(Player[pLevel][client] == 9)
		{
			GivePlayerItem(client, "weapon_mag7", 0);
		}
		if(Player[pLevel][client] == 10)
		{
			GivePlayerItem(client, "weapon_sawedoff", 0);
		}
		if(Player[pLevel][client] == 11)
		{
			GivePlayerItem(client, "weapon_m249", 0);
		}
	}
}
 

wanted241

Real-Gamer.Ru
Сообщения
428
Реакции
161
Лично у меня сохранения происходят таким образом:

C-подобный:
Format(query, sizeof(query), "UPDATE `wcs_bank` SET lvls = %d WHERE SteamId = '%s';", lvl, SteamId);
SQL_TQuery(g_hDb, SQL_SaveBank, query);
 

KorDen

Atra esterní ono thelduin!
Сообщения
2,142
Реакции
1,424
Primo, ошибка не в SQL. В OnClientConnected у клиента еще нет SteamID. Используй OnClientAuthorized
 

semjef

semjef.ru
Сообщения
993
Реакции
444
KorDen, также можно использовать OnClientPostAdminCheck:)


Primo, при окончании карты вызывается событие OnClientDisconnect, но при старте никаких событий коннекта не вызывается, если не хочешь при конце карты вызывать OnClientDisconnect, то хукай событие player_disconnect

И ещё: если делаешь глобальным new String:pSteamID[256];, то делай массив сток для каждого игрока, иначе бред получится, и размерности в 32 более чем хватит для записи стимида.
 

Primo

типа серьёзный тип
Сообщения
1,532
Реакции
759
KorDen, также можно использовать OnClientPostAdminCheck:)


Primo, при окончании карты вызывается событие OnClientDisconnect, но при старте никаких событий коннекта не вызывается, если не хочешь при конце карты вызывать OnClientDisconnect, то хукай событие player_disconnect

И ещё: если делаешь глобальным new String:pSteamID[256];, то делай массив сток для каждого игрока, иначе бред получится, и размерности в 32 более чем хватит для записи стимида.

Всё, что вы написали, либо не уместно, либо не внимательно смотрели код.

Бредом pSteamID глобальным не будет, т.к. изменяется она только тогда, когда игрок подключился и отключился.

Добавлено через 20 минут
В общем, проблема такова.
Есть глобальная переменная pClient;
Каждый раз, когда игрок авторизировался на сервер, его cliend индекс записывается в переменную pClient, и вызывается запрос
PHP:
SQL_TQuery(db, SQL_DefCallback, query, 0);
PHP:
public SQL_DefCallback(Handle:owner, Handle:hndl, const String:error[], any:data) 
{ 
	if (hndl == INVALID_HANDLE) LogError(error);
	Player[pLevel][pClient] = SQL_FetchInt(hndl, 3);
	Player[pXP][pClient] = SQL_FetchInt(hndl, 4);
}

Данные из ячеек записываются совершенно другому игроку. Или нужно как-то передать индекс игрока в SQL_DefCallback, либо другие варианты...
 
Последнее редактирование:

The End Is Near...

Russian Roulette
Сообщения
874
Реакции
691
Глобальной ее делать не стоит вовсе, а лучше, как сказал semjef, хранить SteamID индивидуально для игрока, а далее использовать ее, благодаря этому, не нужно будет повторно получать SteamID
 

Primo

типа серьёзный тип
Сообщения
1,532
Реакции
759
Глобальной ее делать не стоит вовсе, а лучше, как сказал semjef, хранить SteamID индивидуально для игрока, а далее использовать ее, благодаря этому, не нужно будет повторно получать SteamID

Как предложите реализовать индивидуальность?
 

R1KO

fuck society
Сообщения
9,457
Реакции
7,786
  • Команда форума
  • #11
Primo, передай клиента в запросе:
PHP:
public OnClientPostAdminCheck(iClient)
{
	if(!IsFakeClient(iClient))
	{
		decl String:sAuth[32];
		GetClientAuthString(iClient, sAuth, sizeof(sAuth) - 1);
		
		decl String:sQuery[256];
		Format(sQuery, sizeof(sQuery) - 1, "SELECT .... FROM .. WHERE ...;", sAuth);
		SQL_TQuery(g_hSQLdb, SQL_SelectPlayerCallback, sQuery, iClient);
	}
}

public SQL_SelectPlayerCallback(Handle:owner, Handle:hndl, const String:error[], any:iClient)
{
	if(hndl == INVALID_HANDLE) LogError("Ошибка подключения к базе данных (%s)", error);
	else
	{
		if(SQL_HasResultSet(hndl) && SQL_FetchRow(hndl) && IsClientInGame(iClient))
		{
			Player[pLevel][iClient] = SQL_FetchInt(hndl, 3);
			Player[pXP][iClient] = SQL_FetchInt(hndl, 4);

		}
	}
}

Primo, при окончании карты вызывается событие OnClientDisconnect, но при старте никаких событий коннекта не вызывается, если не хочешь при конце карты вызывать OnClientDisconnect, то хукай событие player_disconnect
+1
 

Primo

типа серьёзный тип
Сообщения
1,532
Реакции
759
Primo, передай клиента в запросе:
PHP:
public OnClientPostAdminCheck(iClient)
{
	if(!IsFakeClient(iClient))
	{
		decl String:sAuth[32];
		GetClientAuthString(iClient, sAuth, sizeof(sAuth) - 1);
		
		decl String:sQuery[256];
		Format(sQuery, sizeof(sQuery) - 1, "SELECT .... FROM .. WHERE ...;", sAuth);
		SQL_TQuery(g_hSQLdb, SQL_SelectPlayerCallback, sQuery, iClient);
	}
}

public SQL_SelectPlayerCallback(Handle:owner, Handle:hndl, const String:error[], any:iClient)
{
	if(hndl == INVALID_HANDLE) LogError("Ошибка подключения к базе данных (%s)", error);
	else
	{
		if(SQL_HasResultSet(hndl) && SQL_FetchRow(hndl) && IsClientInGame(iClient))
		{
			Player[pLevel][iClient] = SQL_FetchInt(hndl, 3);
			Player[pXP][iClient] = SQL_FetchInt(hndl, 4);

		}
	}
}


+1
player_disconnect хукается, не?
 

R1KO

fuck society
Сообщения
9,457
Реакции
7,786
  • Команда форума
  • #13
Primo, да, только тип Pre лучше поставь.
Причины его использования указал semjef.
 

R1KO

fuck society
Сообщения
9,457
Реакции
7,786
  • Команда форума
  • #15
Primo,
EventHookMode_Pre - вызываем функцию до того, как событие произошло
EventHookMode_Post - после того, как оно произошло (по умолчанию)
EventHookMode_PostNoCopy - после того, но без переменных
 

Primo

типа серьёзный тип
Сообщения
1,532
Реакции
759
Primo, передай клиента в запросе:
PHP:
public OnClientPostAdminCheck(iClient)
{
	if(!IsFakeClient(iClient))
	{
		decl String:sAuth[32];
		GetClientAuthString(iClient, sAuth, sizeof(sAuth) - 1);
		
		decl String:sQuery[256];
		Format(sQuery, sizeof(sQuery) - 1, "SELECT .... FROM .. WHERE ...;", sAuth);
		SQL_TQuery(g_hSQLdb, SQL_SelectPlayerCallback, sQuery, iClient);
	}
}

public SQL_SelectPlayerCallback(Handle:owner, Handle:hndl, const String:error[], any:iClient)
{
	if(hndl == INVALID_HANDLE) LogError("Ошибка подключения к базе данных (%s)", error);
	else
	{
		if(SQL_HasResultSet(hndl) && SQL_FetchRow(hndl) && IsClientInGame(iClient))
		{
			Player[pLevel][iClient] = SQL_FetchInt(hndl, 3);
			Player[pXP][iClient] = SQL_FetchInt(hndl, 4);

		}
	}
}


+1
Использовал ваш код.
Передал клиента в запросе, данные из таблицы всё-равно не берутся :this:

Добавлено через 19 часов 33 минуты
Может быть я не правильно пытаюсь получить уровень и опыт из бд?

Добавлено через 23 часа 5 минут
Проблема решена. Спасибо всем, кто помогал.
 
Последнее редактирование:
Сверху Снизу