Jump to content
  • 0

pomoc Problém s OnRconCommand - sscanf


MichaelMik9

Dotaz

Ahoj :)

mám malý problém a potřeboval bych pomoct: Uvedu příkaz pro konzoli (OnRconCommand):

public OnRconCommand(cmd[])
{
	printf("[RCON COMMAND]: CONSOLE issued server command: | %s |", cmd);
	if(strcmp("addvip", cmd, true, 6) == 0)
	{
		printf("command %s executed!", cmd);
	    new playerVipName;
	    new days;
	    if(!sscanf(cmd, "s[65]i", playerVipName, days))
	    {        	
			new sqliteAddVip[120];
			format(sqliteAddVip, sizeof(sqliteAddVip), "UPDATE samp_players SET `Vip`='1' WHERE `Nick`='%s'", playerVipName);
			mysql_query(Database, sqliteAddVip, false);

		  	new registrydate;
		   	registrydate = GetTime(); // set second by NOW
			new expirationdate = SetExpirationTime(days, registrydate);

			//check if user is in samp_vip
			new checkVip[120];
			format(checkVip, sizeof(checkVip), "SELECT `Nick` FROM `samp_vip` WHERE `Nick`='%s'", playerVipName);
			mysql_query(Database, checkVip);
				
			if(cache_num_rows() != 0)
			{
				new updateQuery[256];
					format(updateQuery, sizeof(updateQuery), "UPDATE `samp_vip` SET `Registry`='%i', `Expiration`='%i' WHERE `Nick`='%s'", registrydate, expirationdate, playerVipName);
					mysql_query(Database, updateQuery, false);


					printf("[RCON] SERVER UPDATES Player |> %s <| to VIP for %i DAYS", playerVipName, days);
			}
				else
				{
					new insertQuery[256];
					format(insertQuery, sizeof(insertQuery), "INSERT INTO `samp_vip`(`Nick`, `Registry`, `Expiration`) VALUES ('%s','%i','%i')", playerVipName, registrydate, expirationdate);
					mysql_query(Database, insertQuery, false);

					new insert[135];
					format(insert, sizeof(insert), "INSERT INTO `samp_player_vip_car` (`Nick`) VALUES ('%s')", playerVipName);
					mysql_query(Database, insert, false);

					printf("[RCON] SERVER adds Player |> %s <| to VIP for %i DAYS", playerVipName, days);
				}

					//log event
					//new logText[200];
					//format(logText, sizeof(logText), "[*#46FF33*]%s[*///Color] si zakoupil [*#46FF33*]VIP[*/Color] ucet na [*#46FF33*]%i[*/Color] dnu!)", playerVipName, days);

					//samp_log(GetTime(), logText);
	        }
	        else
	        {
	        	print("USE SYNTAX: addvip [name] [days]");
	        	
			}
	}
	return 1;
}

Abych tedy věc vysvětlil.

Mám zde příkaz, který když zadám do konzole: addvip jmeno 30, tak se mi má hráč vložit do databáze do tabulky nebo upravit řádek a upravit čas registrace.

Jenomže, po zadání příkazu mi vyjede chyba:

[14:36:21] [RCON COMMAND]: CONSOLE issued server command: | addvip MichaelMik1 30 |
> [14:36:21] command addvip MichaelMik1 30 executed!
> [14:36:21] USE SYNTAX: addvip [name] [days]
> [14:36:21] [debug] Run time error 5: "Invalid memory access"
> [14:36:21] [debug] AMX backtrace:
> [14:36:21] [debug] #0 00000000 in public OnRconCommand ()

Hledal jsem na googlu, co konkrétně znamená chyba: Run time error 5 ale nějak jsem to nevygooglil.

Může mě prosím někdo nasměrovat a zkusit zjistit, kde by chyba mohla být?

Pro větší přehlednost přikládám nové funkce pro čas a datum expirace:

stock GetTime()
{
    new Hour, Minute, Second;
    return gettime(Hour, Minute, Second);
}

stock SetExpirationTime(days, registryTime)
{
	new expTime;
	new Days;
	Days = 60*60*24*days; //Expiration in seconds
	expTime = registryTime+Days;
	return expTime;
}

 

  • Líbí se mi to! (+1) 1
Link to comment
Share on other sites

14 odpovědí na tuto otázku

Recommended Posts

  • 0

Je rovnaký výstup aj s opraveným riadkom new playerVipName[65]?

 

Mimo témy: 
Vlastná funkcia GetTime nie je potrebná. Stačí úplne rovnakým spôsobom použiť existujúcu funkciu gettime.
Napríklad teda new timestampNow = gettime();

 

Edited by DuFF
Link to comment
Share on other sites

  • 0
  • Globální moderátor

Wow, zajímavý problém!

Jako první mě napadlo error 5 znamená, že nemáš práva, ta hláška tomu trochu nasvědčuje, ale na 99% to nebude problém, můžeš zkusit pouštět server jako správce. Databázi máš lokální nebo remote? Respektive není v cestě třeba firewall? Můžeš z ní číst, povedlo se na ní už napojit? (Tohle pode mě ale není hlavní příčina)

Víš jaký řádek tento runtime error způsobuje? Tipnul bych si že to je hned 

mysql_query(Database, sqliteAddVip, false);

ale nemohu určit, zkus zjistit, který řádek, od toho se můžeme všichni posunout dál. (Odmaž třeba zbytek kódu a vyzkoušej, zda to projde a dej vědět)

Link to comment
Share on other sites

  • 0
před 20 minutami, Hip said:

Víš jaký řádek tento runtime error způsobuje? Tipnul bych si že to je hned 


mysql_query(Database, sqliteAddVip, false);

V logu vidno hlášku "USE SYNTAX: addvip [name] [days]".
Keďže sa vykonala else vetva, nehľadal by som crashujúci riadok v druhej vetve.

Myslím si, že za crash môžu riadky:

new playerVipName;
new days;
if(!sscanf(cmd, "s[65]i", playerVipName, days))

Sscanf plugin sa pravdepodobne pokúšal natlačiť celý string "MichaelMik1" do premennej playerVipName, ktorá keď je definovaná týmto spôsobom, má iba 4 bajty.
Tento string tam nevošiel a plugin zapisoval do pamäte za touto premennou, čo mohlo spôsobiť invalid memory access. 

Preto by ma zaujímalo, či problém pretrváva, keď sa riadok new playerVipName; zmenil na new playerVipName[65];.

Link to comment
Share on other sites

  • 0

problém přetrvává ikdyž sem to právě opravil :)

jinak, jsem zkusil trošku jiný postup, který mi najednou začal fungovat (ale ten smysl, že následující kód jde a předchozí ne, mi to fakt nedává):

 

printf("[RCON COMMAND]: CONSOLE issued server command: | %s |", cmd);

		new command[6];
	    new playerVipName[65];
	    new days;

	    if(!sscanf(cmd, "s[6]s[65]i", command, playerVipName, days))
	    {        
	    	printf("command: %s %s %i", command, playerVipName, days);

	    	if(strcmp(command, "addvip", true, 6))
	    	{
		    	printf("command %s executed!", cmd);	
				new sqliteAddVip[120];
				format(sqliteAddVip, sizeof(sqliteAddVip), "UPDATE samp_players SET `Vip`='1' WHERE `Nick`='%s'", playerVipName);
				mysql_query(Database, sqliteAddVip, false);

			  	new registrydate;
			   	registrydate = GetTime(); // set second by NOW
				new expirationdate = SetExpirationTime(days, registrydate);

				//check if user is in samp_vip
				new checkVip[120];
				format(checkVip, sizeof(checkVip), "SELECT `Nick` FROM `samp_vip` WHERE `Nick`='%s'", playerVipName);
				mysql_query(Database, checkVip);
					
				if(cache_num_rows() != 0)
				{
					new updateQuery[256];
						format(updateQuery, sizeof(updateQuery), "UPDATE `samp_vip` SET `Registry`='%i', `Expiration`='%i' WHERE `Nick`='%s'", registrydate, expirationdate, playerVipName);
						mysql_query(Database, updateQuery, false);


						printf("[RCON] SERVER UPDATES Player |> %s <| to VIP for %i DAYS", playerVipName, days);
				}
					else
					{
						new insertQuery[256];
						format(insertQuery, sizeof(insertQuery), "INSERT INTO `samp_vip`(`Nick`, `Registry`, `Expiration`) VALUES ('%s','%i','%i')", playerVipName, registrydate, expirationdate);
						mysql_query(Database, insertQuery, false);

						new insert[135];
						format(insert, sizeof(insert), "INSERT INTO `samp_player_vip_car` (`Nick`) VALUES ('%s')", playerVipName);
						mysql_query(Database, insert, false);

						printf("[RCON] SERVER adds Player |> %s <| to VIP for %i DAYS", playerVipName, days);
					}

						//log event
						new logText[200];
						format(logText, sizeof(logText), "[*#46FF33*]%s[*///Color] si zakoupil [*#46FF33*]VIP[*/Color] ucet na [*#46FF33*]%i[*/Color] dnu!)", playerVipName, days);

						samp_log(GetTime(), logText);
		    }
		}
		else
		{
		   	print("USE SYNTAX: addvip [name] [days]");
		        	
		}
	return 1;

Jinak je to přes gamehosting, takže práva by v tom neměli hrát žádnou roly :)

Link to comment
Share on other sites

  • 0
před 1 hodinou, MichaelMik9 said:

ale ten smysl, že následující kód jde a předchozí ne, mi to fakt nedává

Pridáš sem aj výpis z logu s novým kódom? Nemyslím si, že ti to funguje tak, ako by si chcel.

před 1 hodinou, MichaelMik9 said:

if(strcmp(command, "addvip", true, 6))

je pravdivé iba ak sa command nezhoduje s "addvip", takže pochybujem, že ti to teraz niečo po rcon príkaze addvip vkladá do databázy.

Edited by DuFF
Link to comment
Share on other sites

  • 0

Prišiel som na to, kde bol problém.
String cmd okrem parametrov obsahuje na začiatku aj názov príkazu. 
Preto ti "s[65]i" nefungovalo a "s[6]s[65]i" už fungovalo.
 

Tento názov príkazu nemusíš ukladať do premennej, ale môžeš použiť feature sscanf2: "quiet" stringy. 
Dočítať sa o nich môžeš tu.
Napríklad takto to krásne funguje:
 

Spoiler

#define FILTERSCRIPT

#include <a_samp>
#include <sscanf2>

public OnRconCommand(cmd[])
{
    if (!strcmp(cmd, "addvip", true, 6))
    {
        printf("addvip executed");

        new playerName[65];
        new days;
        if (sscanf(cmd, "{s[128]}s[65]i", playerName, days))
        {
            printf("Usage: /rcon addvip [playerName] [days]");
            return 1;
        }

        printf("playerName='%s', days=%d", playerName, days);

        // mysql query, ...
        return 1;
    }

    if (!strcmp(cmd, "othercommand", true, 12))
    {
        printf("othercommand executed");
        return 1;
    }

    return 0;
}

 

 

Edited by DuFF
  • Líbí se mi to! (+1) 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...