· 7 years ago · Oct 17, 2018, 05:04 PM
1//pravimo sql strukturu sa ID igraca, name, steamid i naravno ono sto zelimo da mu pamti, u ovom primeru say /ljstats (stavimo mu ime kolone 'ljstats' )
2
3<include sqlx>
4
5new const napravi_tabelu[] = "CREATE TABLE IF NOT EXISTS player_connect_i (id INTEGER PRIMARY KEY, steamid VARCHAR(35) UNIQUE, name CHAR(32), ljstats INTEGER );" //nek stoji kao global, deluje preglednije a i lepse
6
7//uvodimo i globale koji su potrebni;
8new SteamID[ 33 ][ 35 ]//po ovome igrace ubacujemo u tabelu
9new bool:lj_p[ 33 ] //bool, vazan je kad igrac kuca /ljstats...da i ovaj plugin, pored ljstats plugina, upamti kad je promenio
10new lj[ 33 ] //ovo je napravljeno da transferuje query rezultat, jer ajde neka bude integer u tabeli
11new postoji_igrac[ id ] //ako igrac vec postoji u sql tabeli s kojom radimo
12
13new Handle:SQLTuple, query_cache[ 1024 ] //potrebne stvari za sam sql rad
14
15//plugin radi na svaki konekt igraca, ali pisacu hijerarhijski sta se poziva prvo, da bi bilo malo jasnije onima kojima nije jasno :D
16public plugin_init()
17{
18 //ok naravno na svaki start mape moramo da ocitamo taj nas divni sql
19 NapraviTabelu()
20}
21NapraviTabelu()
22{
23 SQL_SetAffinity( "sqlite" ) //uzimamo sqlite opciju za ovaj rad
24 g_SQLTuple = SQL_MakeDbTuple( "", "", "", "player_connect_info" ) //username, pass i ip su nebitni ovde, jer je sve na lokal masini, samo dajemo ime baze, gde sve cuvamo: player_connect_info
25
26 new Handle:SqlConnection , ErrorCode;
27 SqlConnection = SQL_Connect( SQLTuple , ErrorCode , query_cache , charsmax( query_cache ) )
28
29 if( SqlConnection == Empty_Handle )
30 set_fail_state( query_cache )
31
32 RunQuery( SqlConnection , napravi_tabelu ) //ovo smo vec definisali gore: ako ne postoji tabela - napravi je...
33}
34
35public RunQuery( Handle:SQLConnection , const szQuery[] )
36{
37 new Handle:Query = SQL_PrepareQuery( SQLConnection , szQuery )
38
39 if( !SQL_Execute( Query ) )
40 {
41 SQL_QueryError( Query , query_cache , 100 )
42 set_fail_state( query_cache )
43 }
44}//ovo sto ne komentujem je ili dosadan deo koda (a obavezan) ili je mnogo prosto da ne treba koment...u ovom slucaju je ovo prvo i moj predlog je da kopirate to :)
45
46//aj da vidimo sad, sta se desava kad se sam igrac konektuje na srv
47public client_putinserver( id )
48{
49 postoji_igrac[ id ] = false //odma ga pretpostavljamo da ga nema u tabeli, ubrzo ce da proverimo to
50
51 new Data[ 1 ]; Data[ 0 ] = id //podaci vazni za sql (by Bugsy)
52 get_user_authid( id , SteamID[ id ] , charsmax( SteamID[] ) )
53
54 formatex( query_cache, charsmax( query_cache ) , "SELECT id, name, steamid, ljstats FROM player_connect_i WHERE steamid='%s'" , SteamID[ id ] ) //kad saljemo komandu preko sql-a, selektovacemo tog igraca prema SteamID-u
55 SQL_ThreadQuery( SQLTuple , "SelectHandle" , query_cache , Data , sizeof( Data ) ) //saljemo upit aj da vidimo sta se dogadja:
56
57 set_task( 3.0, "ljstats_test", id ) //da ugasimo igracu stats ako treba
58}
59
60public SelectHandle( FailState , Handle:Query , Error[] , Errcode , Data[] , DataSize )
61{
62 if( FailState == TQUERY_CONNECT_FAILED )
63 {
64 return set_fail_state("Could not connect to SQL database." )
65 }
66 else if( FailState == TQUERY_QUERY_FAILED )
67 {
68 log_amx( "Query error: %s" , Error )
69 return set_fail_state( query_cache )
70 }
71
72 if( Errcode )
73 return log_amx( "Error on query: %s" , Error )
74
75 new id = Data[ 0 ]
76
77 //ovo iznad valjda vidite o cemu je rec...kao sto rekoh, to je dosadan deo ali nemojte bez njega...znaci kopirajte ga ili ga pamtite ako hocete, vas izbor...ajmo sad nesto interesantnije:
78
79 if ( SQL_NumResults( Query ) ) //ako su pronadjeni rezultati za tog igraca u tabeli:
80 {
81 pronadjen_igrac[ id ] = true //evo ga, cim je pronadjen, stavljamo mu tru, ovo ce koristiti kasnije za client_diskonnect
82 server_print( "RADI RADI SQLITE") //aj da ubacimo i rucni debug :D
83 lj[ id ] = SQL_ReadResult( Query, 3 ) //ovo je mozda i najvaznija stvar...nasu promenljivu stavljamo da je jednaka nekom rezultatu iz tabele...
84
85 //kako da znamo koji je koj rezultat? vrlo lako; SQL_ReadResult( Query, 3 ), ova linija cita kolonu-1 iz nase tabele; mi imamo tamo: id, name, steamid, ljstats (znaci trojka iz te komande je u STVARNOJ VREDNOSTI 4, znaci u nasoj tabeli je to ljstats..i idiot moze ovo da skapira :D)
86
87 }
88 if( lj[ id ] > 0 ) //pretvaramo broj u bool
89 lj_p[ id ] = true //ovo je mozda glupa forica za int->bool, ali trenutno ne znam pametnije, a i lepo radi :D
90 else
91 lj_p[ id ] = false //ako je tom igracu lj[ id ] = 0 onda mu je upamceno u tabeli da mu je lj stats iskljucen
92
93 return PLUGIN_CONTINUE
94} //sad moze da odahnemo jer smo najvazniji deo koda zavrsili...sta nam ostaje posle kratke pauze? pa ostaje da vidimo kako cemo da usnimimo igraca ili da mu apdejtujemo podatke, zavisno od pronadjen_igrac[id], pa ae i to:
95
96
97public client_disconnect( id )
98{
99 new Data[ 1 ]; Data[ 0 ] = id
100 new name_p[ 32 ]
101
102 if ( is_user_bot( id ) )
103 return PLUGIN_HANDLED
104
105 get_user_authid( id , SteamID[ id ] , charsmax( SteamID[] ) )
106 get_user_name( id, name_p, charsmax( name_p ) )
107
108 if( pronadjen_igrac[ id ] ) //ako je postojao, tj da smo ga pronasli u iznad funkciji, onda cemo da mu apdejtujemo samo ljstats kolonu, ne treba nista vise
109 {
110 server_print( "ovo je uradjeno bajo sqlite-pronadjen_igrac" ) //opet moj neki licni debilski debug heheh
111 formatex( query_cache, charsmax( query_cache ) , "UPDATE player_connect_i SET ljstats=%d WHERE steamid='%s'", lj[ id ], SteamID[ id ] ) //lj[ id ] mu ubacujemo, jer sa bool:lj_p[ id ] se nisam proslavio
112 }
113 else //ako ga ranije nismo pronasli u bazi, ajde onda ga na diskonekt sa servera ubacujemo u tabelu za svagda!
114 formatex( query_cache, charsmax( query_cache ) , "INSERT INTO player_connect_i (name, steamid, ljstats ) VALUES ('%s', '%s', '%d' )", name_p, zSteamID[ id ], lj[ id ] ) //provaljuje se valjda sta je uradjeno
115 }
116
117
118 new Handle:SqlConnection , ErrorCode;
119 SqlConnection = SQL_Connect( g_SQLTuple , ErrorCode , query_cache , charsmax( query_cache ) );
120
121 if( SqlConnection == Empty_Handle )
122 set_fail_state( query_cache )
123
124
125 //iznad smo formatirali sta saljemo za sql...ajde onda ga i stvarno posaljemo
126 RunQuery( SqlConnection , query_cache )
127}
128//pazi sad...sve je uradjeno kako treba sem jedne, isto vazne stvari..
129//moramo da provalimo kad je igrac odradio say /ljstats...aj to je ez:
130register_clcmd( "say /ljstats", "ljstats" )
131
132public ljstats( id )
133{
134 if( lj[ id ] == 0 ) //ako je ovo ocitano za igraca iz tabele, onda
135 lj[ id ] = 1 //mu se menja jer je pozvao ovu fuknciju
136 else
137 lj[ id ] = 0
138} //ako cemo bas sta je po redu pozvano, ovo je ipak pre client_diskonekt-a ali najbintije je da kapirate sustinu :)
139
140public ljstats_test( id )
141{
142 if( !is_user_connected( id ) )
143 return PLUGIN_HANDLED
144
145 if( lj[ id ] > 0 )
146 {
147 client_cmd( id, "say /ljstats" ) //da iskljuci igracu
148 lj[ id ] = 1 //ovo je stavljeno jer se radi na client_cmd...mozda je bolje callfunc_, ali me mrzi sad da trazim naziv funkcije
149 }
150}