Skocz do zawartości

  • Zaloguj korzystając z Facebooka Zaloguj korzystając z Twittera Zaloguj przez Steam Zaloguj poprzez Google      Logowanie »   
  • Rejestracja

Witamy w Nieoficjalnym polskim support'cie AMX Mod X

Witamy w Nieoficjalnym polskim support'cie AMX Mod X, jak w większości społeczności internetowych musisz się zarejestrować aby móc odpowiadać lub zakładać nowe tematy, ale nie bój się to jest prosty proces w którym wymagamy minimalnych informacji.

  • Rozpoczynaj nowe tematy i odpowiedaj na inne
  • Zapisz się do tematów i for, aby otrzymywać automatyczne uaktualnienia
  • Dodawaj wydarzenia do kalendarza społecznościowego
  • Stwórz swój własny profil i zdobywaj nowych znajomych
  • Zdobywaj nowe doświadczenia

Dołączona grafika Dołączona grafika

Guest Message by DevFuse
 

Uprawnienia w AMXXczyli wszystko o flagach

flagi uprawnienia u2

  • Nie możesz napisać tematu
  • Zaloguj się, aby dodać odpowiedź
3 odpowiedzi w tym temacie

#1 Gość_21977_*

  • Gość

Reputacja: 0

Offline

Napisano 20.05.2013 10:24

*
Popularny

Uprawnienia w AMXX
AMX Mod X, jako modyfikacja mająca ułatwić Administratorom pracę na serwerze, posiada system uprawnień.
Użytkownikom nadawane są pewne uprawnienia, które zezwalają na wykonywanie określonych operacji.
Do dyspozycji mamy 1024 uprawnienia dla każdego z graczy, a każde z nich to jeden bit, czyli 0 lub 1.
Uprawnienia podzielone są na 32 zestawy po 32 bity. Każdy taki bit nazywany jest zwyczajowo flagą.
 
Każdy z 32 zestawów uprawnień jest liczbą całkowitą typu U2 i przyjmuje wartości od -231 -2147483648 do 231 - 1 2147483647.

Przeliczanie liczby dziesiętnej na U2
Liczbę dziesiętną D (na co dzień korzystamy z dziesiętnego systemu liczbowego) przeliczamy na U2 B,
gdzie Bn oznacza n-tą cyfrę od prawej (licząc od zera) trzydziestodwucyfrowej liczby binarnej B, np. dla:

B = 01000000000100000000010000000001

indeksy dla każdej z 32 cyfer to:

 

binIndex.png

 

indeksy od 0 (po prawej) do 31 (po lewej); ∈ { B; B10 ; B20 B30 }

 

następująco:

  • Jeśli D jest ujemne:
    • B31 (pierwsza cyfra B od lewej) przyjmuje wartość 1.
    • D przyjmuje wartość o jeden mniejszą od swojej przeciwności (- D - 1).
  • Jeśli D jest nieujemne:
    • B31 (pierwsza cyfra B od lewej) przyjmuje wartość 0.
  • Dla każdej kolejnej (od lewej) cyfry Bn:
    • jeśli aktualne D ≥ 2n:
      • przypisujemy wartość 1.
      • zmniejszamy D o 2n.
    • jeśli aktualne D < 2n:
      • przypisujemy wartość 0.

Przykład dla liczby D=13:

  • B31 = 0 (D=13 jest nieujemna)
  • B30 = 0 (D=13 < 2n=30=1073741824)
  • B29 = 0 (D=13 < 2n=29=536870912)

  • B4 = 0 (D=13 < 2n=4=16)
  • B3 = 1 (D=13 ≥ 2n=3=8)
    • D=D-2n=13-23=13-8=5
  • B2 = 1 (D=5 ≥ 2n=2=4)
    • D=D-2n=5-22=5-4=1
  • B1 = 0 (D=1 < 2n=1=2)
  • B0 = 1 (D=1 ≥ 2n=1=1)
    • D=D-2n=1-20=1-1=0
13 = 00000000000000000000000000001101

Przeliczanie liczby U2 na dziesiętną
D=\sum_{n=0}^{31}B_{n}\cdot 2^{n}\cdot (-1)^{\lfloor n/31\rfloor }
 
Prostsza forma zapisu wzoru:
D=\sum_{n=0}^{30}B_{n}\cdot 2^{n}-B_{31}\cdot 2^{31}

Dłuższa forma zapisu wzoru:
D=B_{0}\cdot 2^{0}+B_{1}\cdot 2^{1}+\cdots +B_{28}\cdot 2^{28}+B_{29}\cdot 2^{29}+B_{30}\cdot 2^{30}-B_{31}\cdot 2^{31}
 
Liczbę U2 uzyskuje się poprzez zsumowanie iloczynów wartości każdego z 32 bitów i kolejnych, od prawej strony, potęg liczby 2, począwszy od potęgi zerowej.
Wyjątkiem jest tutaj iloczyn liczby pierwszej od lewej (o najwyższej potędze mnożnika dwójki, tj. 31), którego to odejmujemy od sumy, zamiast go do niej dodać.
 
Przykładowo, liczba 13 zapisywana jest binarnie w postaci:

00000000000000000000000000001101

Jedynki stoją na pozycjach: 0, 2 i 3 od prawej strony (licząc od zera), co daje nam wartość 20+22+2= 1+4+8 = 13.
Liczba 13 daje zatem nam 3 uprawnienia, mianowicie i roboczo "uprawnienie 0", "uprawnienie 2" i 'uprawnienie 3".
Każde uprawnienie oznacza jedynkę w kodzie binarnym naszej liczby, a zero oznacza brak tego uprawnienia.
 

Sprawdzanie uprawnień
Niech "uprawnienie N" będzie N-tym od prawej strony bitem zapisu zestawu uprawnień gracza w postaci U2.
Wiedząc, że przyjmuje ono wartość N-tej potęgi liczby 2 (bądź przeciwność tej potęgi w przypadku "uprawnienia 31"),
w łatwy sposób możemy sprawdzić, czy gracz posiada daną flagę, czy też nie. W tym celu najpierw pobierzemy flagi
uprawnień gracza, korzystając z funkcji get_user_flags, która zwróci nam liczbę całkowitą jako uprawnienia gracza.

new flags=get_user_flags(id);

Za pomocą iloczynu binarnego, w łatwy sposób sprawdzimy, czy gracz posiada daną flagę.

Iiloczyn binarny
Iloczyn binarny przyjmuje wartość 1, jeśli każda z mnożonych liczb wynosi 1, w przeciwnym przypadku przyjmuje wartość 0.
Dla każdej pary bitów o tym samym indeksie, liczymy ich iloczyn binarny i wynik zapisujemy jako bit o tymże właśnie indeksie.

Przykład:

13 = 00000000000000000000000000001101
 4 = 00000000000000000000000000000100
   & 00000000000000000000000000000100

Iloczyn binarny liczb 13 i 4 wyniesie 4, co oznacza, że posiadając uprawnienia równe 13, posiada się "uprawnienie 2" równe 24.
W pawnie, iloczyn binarny otrzymamy, używając znaku etki: &. Przyda nam się także przesunięcie bitowe, które przesuwa wszystkie bity.
Mamy do dyspozycji przesunięcie bitowe w lewo, w prawo arytmetyczie oraz prawo logicznie, nas będzie interesować przesunięcie bitowe w lewo.

Przesunięcie bitowe
Przesuwamy bity w lewo za pomocą operatora a << b podwajając wartość liczby a dokładnie b-krotnie. Przykład dla 13 << 3:

13      = 00000000000000000000000000001101
13 << 1 = 00000000000000000000000000011010
13 << 2 = 00000000000000000000000000110100
13 << 3 = 00000000000000000000000001101000

W ten sam sposób możemy uzyskać wartość flagi "uprawnienia N", przesuwając liczbę 1 N razy w lewo, co jest równe dokładnie 2N. przykładowo "uprawnienie 3":

1 << 3 = 00000000000000000000000000001000

Chcąc się dowiedzieć, czy użytkownik posiada "uprawnienie N", wystarczy zsumować binarnie uprawnienia gracza z N-tą potęgą liczby 2:

get_user_flags(id) & (1 << N)

Przykład:

if(get_user_flags(id) & (1 << 3)){
	client_print(id, print_chat, "Posiadasz ^"uprawnienie 3^".");
}

Suma binarna
Suma binarna przyjmuje wartość 1, jeśli przynajmniej jedna z mnożonych liczb wynosi 1, w przeciwnym przypadku przyjmuje wartość 0.
Dla każdej pary bitów o tym samym indeksie, liczymy ich sumę binarną i wynik zapisujemy jako bit o tymże właśnie indeksie. Przykład:

12 = 00000000000000000000000000001100
 5 = 00000000000000000000000000000101
   | 00000000000000000000000000001101

Suma binarna liczb 12 i 5 wyniesie 13. W pawnie, sumę binarny otrzymamy, używając znaku barierki (tzw. pałki)|.
Za pomocą sumy binarnej, możemy sprawdzić, czy gracz posiada którąkolwiek z wielu flag, poprzez ich zsumowanie.

Przykład:

if(get_user_flags(id) & ((1 << 2) | (1 << 3) | (1 << 4))){
	client_print(id, print_chat, "Posiadasz ^"uprawnienie 2, 3 lub 4^".");
}

Chcąc  sprawdzić, czy użytkownik posiada wszystkie z wymaganych flag uprawnień, wykonujemy identyczne działanie,
porównując uzyskany wynik z sumą binarną flag, które poddaliśmy sprawdzeniu. Jeśli gracz nie będzie posiadał choć
jednej ze sprawdzanych flag, wynik iloczynu będzie mniejszy niż suma binarna sprawdzanych flag uprawnień.

Przykład:

if(
		get_user_flags(id)
	&	((1 << 2) | (1 << 3) | (1 << 4))
	== 	((1 << 2) | (1 << 3) | (1 << 4))
){
	client_print(id, print_chat, "Posiadasz wszystkie ^"uprawnienia 2, 3 oraz 4^".");
} 

Definicje preprocesora
Używanie postaci liczb jest jednak niepraktyczne i trudno jest spamiętać, za co dane uprawnienie odpowiada.
W tym celu, niektóre z flag uprawnień zostały zdefiniowane za pomocą komendy preprocesora: #define.

#define ADMIN_ALL		0	/* everyone */
#define ADMIN_IMMUNITY		(1<<0)	/* flag "a" */
#define ADMIN_RESERVATION	(1<<1)	/* flag "b" */
#define ADMIN_KICK		(1<<2)	/* flag "c" */
#define ADMIN_BAN		(1<<3)	/* flag "d" */
#define ADMIN_SLAY		(1<<4)	/* flag "e" */
#define ADMIN_MAP		(1<<5)	/* flag "f" */
#define ADMIN_CVAR		(1<<6)	/* flag "g" */
#define ADMIN_CFG		(1<<7)	/* flag "h" */
#define ADMIN_CHAT		(1<<8)	/* flag "i" */
#define ADMIN_VOTE		(1<<9)	/* flag "j" */
#define ADMIN_PASSWORD		(1<<10)	/* flag "k" */
#define ADMIN_RCON		(1<<11)	/* flag "l" */
#define ADMIN_LEVEL_A		(1<<12)	/* flag "m" */
#define ADMIN_LEVEL_B		(1<<13)	/* flag "n" */
#define ADMIN_LEVEL_C		(1<<14)	/* flag "o" */
#define ADMIN_LEVEL_D		(1<<15)	/* flag "p" */
#define ADMIN_LEVEL_E		(1<<16)	/* flag "q" */
#define ADMIN_LEVEL_F		(1<<17)	/* flag "r" */
#define ADMIN_LEVEL_G		(1<<18)	/* flag "s" */
#define ADMIN_LEVEL_H		(1<<19)	/* flag "t" */
#define ADMIN_MENU		(1<<20)	/* flag "u" */
#define ADMIN_ADMIN		(1<<24)	/* flag "y" */
#define ADMIN_USER		(1<<25)	/* flag "z" */

amxconst.inc

Dzięki tym definicjom, zamiast potęg dwójki, możemy, używać zdefiniowanej nazwy.
W przykładzie użyjemy naszego "uprawnienia 3", zapisanego jako ADMIN_BAN:

if(get_user_flags(id) & ADMIN_BAN){
	client_print(id, print_chat, "Posiadasz ^"uprawnienie 3^".");
}

Pomimo pokaźnych i użytecznych definicji, 9 flag uprawnień wciąż nie zostało zdefiniowanych.
Możemy to zrobić sami, np. poprzez zdefiniowanie następujących definicji (nazwy mogą być inne):

#define ADMIN_FLAG_V		(1<<21)	/* flag "v" */
#define ADMIN_FLAG_W		(1<<22)	/* flag "w" */
#define ADMIN_FLAG_X		(1<<23)	/* flag "x" */
#define ADMIN_FLAG_COMMA	(1<<26)	/* flag ";" */
#define ADMIN_FLAG_BAR		(1<<27)	/* flag "|" */
#define ADMIN_FLAG_EQUAL	(1<<28)	/* flag "=" */
#define ADMIN_FLAG_TILDE	(1<<29)	/* flag "~" */
#define ADMIN_FLAG_QUESTION	(1<<30)	/* flag "?" */
#define ADMIN_FLAG_SPACE	(1<<31)	/* flag " " */

Flagi jako znaki ASCII
Alternatywną metodą zapisu flag uprawnień do potęg liczby 2, są znaki ASCII.
Aby określić wartość liczbową, jakiej odpowiada dany znak, najpierw musimy
pobrać jego identyfikator z listy ASCIILista 128 znaków ASCII na wiki.
Po poznaniu identyfikatora, możemy określić jego wartość, która
wynosi 2 do potęgi reszty z dzielenia identyfikatora przez 32.
 
Innymi słowy, wartość liczbowa D dowolnego znaku ASCII o identyfikatorze C wynosi:
D=2^{C-32\lfloor \frac{C}{32}\rfloor}
 
Przykład dla pawna:

// returns flag value by given ASCII code
stock ASCII2DEC(ASCII_ID){
	ASCII_ID = ASCII_ID % 32;	// identyfikator dzielimy modulo 32, bo mamy 32 flagi uprawnień
	return power(2, ASCII_ID);	// podnosimy 2 do potęgi tego identyfiaktora, uzyskując wartośc flagi
}

W pawnie mamy też funkcję, która zwraca wartość flagi na podstawie samego znaku, nie jego wartości, co jest
jeszcze bardziej przydatne. Funkcją tą jest read_flags, która potrafi także zwrócić sumę binarną wielu flag naraz.
 
Przykład:

log_amx("%d", read_flags(""));		// zwróci 0
log_amx("%d", read_flags("a"));         // zwróci 1             // =  2!0
log_amx("%d", read_flags("b"));		// zwróci 2		// =  2!1
log_amx("%d", read_flags("ab"));	// zwróci 3		// =  2!0+2!1
log_amx("%d", read_flags("acd"));	// zwróci 13		// =  2!0+2!2+2!3
log_amx("%d", read_flags("z"));		// zwróci 33554432	// =  2!25
log_amx("%d", read_flags(";"));		// zwróci 67108864	// =  2!26
log_amx("%d", read_flags(" "));		// zwróci -2147483648	// = -2!31

Skoro wartość znaku ASCII jest dzielona modulo przez 32, to wszelkie znaki o indeksach różnicy wielokrotności 32 oznaczają tę samą wartość.
W szczególności, nie ma znaczenia wielkość liter, gdyż oddalone są one od siebie o 32 znaki ASCII. Pomimo obsługiwania wszystkich 32 znaków
ASCII z pliku users.ini oraz odpowiedniego konwertowania w funkcji read_flags, komenda amx_who jest w stanie odczytać jedynie
wartości liczb do 26. potęgi dwójki włącznie, przez co nie można tą komendą zobaczyć posiadanych flag o wyższych wartościach, tj.
flag "średnik", "pałka", "znak równości", "tylda", "znak zapytania" oraz "spacja" pomimo, że są one nadane i możliwe do odczytania.

Flagi w pluginach standardowych AMXX
Aby używać systemu flag, muszą one zostać nadane użytkownikowi, a następnie w jakiś sposób wykorzystane.
Standardowe pluginy AMXX odczytują uprawnienia określonych graczy z pliku amxmodx/configs/users.ini.
To, w jaki sposób należy przyznawać tam uprawnienia, jest kwestią dla end userów i wyjaśnioną w tym pliku.
Jeśli użytkownik nie otrzyma żadnych uprawnień z pliku users.ini, zostaną mu przypisane flagi z cvaru amx_default_access.
Domyślnie, jest to flaga "z". Flagi, same w sobie nie oznaczają i nie robią absolutnie nic, dopiero pluginy mogą te flagi wykorzystać.
 
Standardowe pluginy AMXX, flagę "a" uznają jako immunitet i nie pozwalają na wykonanie niektórych akcji na użytkownikach z tą flagą.
Flaga "b" zapewnia tzw. slot, "c" pozwala na wyrzucanie graczy z serwera, "d" na ich banowanie, itd. przy czym flaga "z" przypisana jakiemukolwiek
użytkownikowi, pomimo posiadania innej, wymaganej flagi, np. nie pozwala na wykonanie danej operacji, Jest to takie profilaktyczne zabezpieczenie.
Przykładowo, Administrator, posiadający flagi "cz", nie może wyrzucać graczy z serwera pomimo posiadania flagi "c".
Spełnia on wymów konieczny, tzn. posiada flagę "c", ale nie spełnia wymogu wystarczającego, tzn. ma też flagę "z".
 
Wchodząc na serwer z plikiem users.ini, którego zawartość wynosi:

"STEAM_0:1:57046937" "" "abcdefghijklmnopqrstuvwxy;|=~? " "ce"

zostaną mi przypisane wszystkie flagi uprawnień i uprzedzając pytania: jest to ustawienie dające najwięcej flag, nie zabierając możliwości
korzystania z pozostałych (czyt. brak flagi "z"). Uprawnienie to w postaci liczby dziesiętnej wynosi dokładnie -33554433. W postaci U2:

11111111111111111111111110111111

Ten sam efekt osiągniemy za pomocą wywołania funkcji:

set_user_flags(id, -1);
remove_user_flags(id, ADMIN_USER);

Jak sprawdzić, czy dany gracz posiada flagę, której nie wyświetla nawet komenda amx_who?
Tak samo, jak robimy to dla każdej innej flag. Poniżej 5 najczęściej stosowanych metod:
 
Przykład dla flagi "?" w postaci liczby wprost:

if(get_user_flags(id) & 1073741824){
	client_print(id, print_chat, "Posiadasz flagę ^"znak zapytania^".");
}

Przykład dla flagi "?" w postaci liczby jako potęgi dwójki:

if(get_user_flags(id) & (1 << 30)){
	client_print(id, print_chat, "Posiadasz flagę ^"znak zapytania^".");
}

Przykład dla własnej definicji preprocesora:

#define ADMIN_FLAG_QUESTION	(1<<30)	/* flag "?" */

if(get_user_flags(id) & ADMIN_FLAG_QUESTION){
    client_print(id, print_chat, "Posiadasz flagę ^"znak zapytania^".");
}

Przykład z funkcją read_flags:

if(get_user_flags(id) & read_flags("?")){
    client_print(id, print_chat, "Posiadasz flagę ^"znak zapytania^".");
}

Przykład z funkcją biblioteki amxmisc: has_flag:

if(has_flags("?")){
    client_print(id, print_chat, "Posiadasz flagę ^"znak zapytania^".");
}

Flagi w pluginach autorskich AMXX
Role flag ze standardowych pluginów AMXX stały się na tyle popularne, że niektórzy Administratorzy utożsamiają flagi z uprawnieniami.
Wiele autorskich pluginów także korzysta z domyślnych ról standardowych pluginów AMXX, szczególnie ustalając immunitet na flagę "a".
Niewielu administratorów korzysta z jakiejkolwiek z 9 flag, których nazwa nie została zdefiniowana w preprocesorze komendą #define ,
Niemal żaden z pluginów nie korzysta natomiast z żadnego z pozostałych 31 zestawów uprawnień o identyfikatorach od 1 do 31.
 
Przykład praktyczny wykorzystania niedomyślnego zestawu uprawnień: ustawienia blokowania chatu innym graczom:
 
Wykorzystamy w przykładzie zestaw uprawnień nr 1.
Po dołączeniu nowego gracza do gry, wyzerowane zostaną jego uprawnienia, co nam odpowiada.
Niechaj każda flaga w zestawie uprawnień 1 oznacza, czy gracz o identyfikatorze równym tej fladze został zablokowany przez właściciela tych flag.
Sama flaga równa identyfikatorowi gracza niech oznacza zaś, czy sam gracz został uciszony globalnie przez Administrację, czy też nie.
 
Pozwólmy graczom na indywidualne blokowanie chatu innych graczy komendą /block name, gdzie name to nick gracza uciszanego.
Odblokować gracza komendą /unblock name, a będąc Administratorem, zablokować całkowicie chat gracza, którego właśnie
obserwujemy, komendą /ucisz i odblokować jego czat komendą /ub. Przykładowy kod, który działa na zestawie uprawnień nr 1:

#include <amxmodx>
#include <ColorChat>
#include <fakemeta>

new maxPlayers;

public plugin_init(){
	register_plugin("system uciszania", "1.0", "Benio");
	register_clcmd("say", "say");
}

public plugin_cfg(){
	maxPlayers=get_maxplayers(); // pobieramy maksymalną liczbę graczy na serwerze
}

public say(id){
	if(id>0 && id<=maxPlayers){ // sprawdzamy tylko, jeśli piszący na czacie jest graczem
		new txt[192];
		read_args(txt,192); // czyta tekst
		remove_quotes(txt); // usuwa cudzysłowia
		
		if(equal(txt, "/block ", 7)){ // filtrujemy komendę jedynie do blokującej
			copy(txt, 185, txt[7]);
			
			new player2block = find_player("b", txt); // szukamy gracza do zablokowania
			if(player2block){ // jeśli znaleźliśmy gracza do zablokowania,
				set_user_flags(id, 1<<(player2block%32), 1); // to blokujemy, ustawiając flagę jego identyfikatora na 1
			}
		}
		
		if(equal(txt, "/unblock ", 9)){ // filtrujemy komendę jedynie do odblokującej
			copy(txt, 185, txt[9]);
			
			new player2unblock = find_player("b", txt); // szukamy gracza do zablokowania
			if(player2unblock){ // jeśli znaleźliśmy gracza do odblokowania,
				remove_user_flags(id, 1<<(player2unblock%32), 1); // to odblokowania, ustawiając flagę jego identyfikatora na 0
			}
		}
		
		if(equal(txt, "/ucisz ", 7)){ // filtrujemy komendę jedynie do uciszającej
			new player2shutup = pev(id, pev_iuser2); // pobieramy gracza do uciszenia na czacie
			if(player2shutup){ // jeśli znaleźliśmy gracza do uciszenia,
				set_user_flags(id, 1<<(player2shutup%32), 1); // to uciszamy, ustawiając flagę wlasnego jego identyfikatora na 1
			}
		}
		
		if(equal(txt, "/ub ", 4)){ // filtrujemy komendę jedynie do odbanowującej
			new player2ub = pev(id, pev_iuser2); // pobieramy gracza do odbanowania na czacie
			if(player2ub){ // jeśli znaleźliśmy gracza do odbanowania,
				remove_user_flags(id, 1<<(player2ub%32), 1); // to odbanowujemy, ustawiając flagę wlasnego jego identyfikatora na 0
			}
		}
		
		if(get_user_flags(id, 1) & (1<<(id%32))){ // sprawdzamy, czy gracz nie został uciszony przez Administrację
			client_print(id, print_chat, "Zostałeś uciszony. Nie możesz używać chatu");
			
			return PLUGIN_HANDLED_MAIN;
		}
		
		new name[32];
		get_user_name(id, name, 31); // pobranie nicku gracza
		
		for(new i=1; i<=32; ++i){ // wysyłamy wiadomośc do wszystkich graczy, którzy nie zablokowali gracza piszącego na czacie
			if(is_user_connected(i) && !(get_user_flags(i, 1) & (1<<(id%32)))){
				ColorChat(i, TEAM_COLOR, "%s^x01 :  %s", name, txt);
			}
		}
		
		return PLUGIN_HANDLED_MAIN; // blokujemy domyślne wywołanie saya przez silnik gry (już obsłużyliśmy saya)
	}

	return PLUGIN_CONTINUE;
}

 
Dodatkowe zestawy uprawnień można także wykorzystać jako oznaczenie posiadanych / użytych przedmiotów dodatkowych.
Flagi uprawnień są na tyle korzystne, że bez problemu można odczytywać i modyfikować ich ustawienia z dowolnego pluginu, bez konieczności
korzystania z natywów, forwardów, ustawiania cvarów serwera, wywoływania komendy u klienta, czy wywoływania funkcji publicznych innego pluginu.
 
Dodawanie i zabieranie flag uprawnień
Do dodania graczowi flag uprawnień służy funkcja set_user_flags, która wbrew pozorom dodaje flagi, a nie ustala.
Użycie domyślnej wartości -1 w drugim parametrze funkcji set_user_flags da graczowi wszystkie możliwe flagi uprawnień (łącznie z "z").
Funkcja ustala graczowi uprawnienia, będące sumą binarną jego obecnie posiadanych uprawnień i dodawanych przez drugi argument funkcji.
 
Przykład:

set_user_flags(id, ADMIN_BAN); // dodaje graczowi flagę ADMIN_BAN = 1<<3, czyli "uprawnienie 3"
set_user_flags(id, read_flags("d")); // dodaje graczowi tę samą flagę, której wartość zwraca funkcja read_flags.

 
Do odebrania graczowi flag uprawnień służy funkcja remove_user_flags.
Użycie domyślnej wartości -1 w drugim parametrze funkcji remove_user_flags odbierze graczowi wszystkie możliwe flagi uprawnień (łącznie z "z").
Funkcja ustala graczowi uprawnienia, będące iloczynem binarnym jego obecnie posiadanych uprawnień i negacji bitów dodawanych przez drugi argument funkcji.

Przykład:

remove_user_flags(id, ADMIN_BAN); // odbiera graczowi flagę ADMIN_BAN = 1<<3, czyli "uprawnienie 3"
remove_user_flags(id, read_flags("d")); // odbiera graczowi tę samą flagę, której wartość zwraca funkcja read_flags.

amxmisc
Funkcje z biblioteki amxmisc z reguły są niepotrzebne i mogą być łatwo zastąpione, aczkolwiek jest to alternatywna metoda do odczytywania uprawnień:
 
Funkcja has_flag pozwala na sprawdzenie, czy gracz posiada którąkolwiek z podanych flag w postaci znaków ASCII.
Funkcja has_all_flags pozwala na sprawdzenie, czy gracz posiada wszystkie z podanych flag w postaci znaków ASCII.
Funkcja access pozwala na sprawdzenie, czy gracz posiada podaną flagę podaną w postaci liczby dziesiętnej.
Funkcja cmd_access pozwala na sprawdzenie wewnątrz komendy, czy gracz posiada flagę podaną w postaci liczby dziesiętnej przy rejestrowaniu tej komendy.


Użytkownik Benio101 edytował ten post 09.06.2013 16:57
lit.


#2 Gość_Joachim_*

  • Autor tematu
  • Gość

Reputacja: 0

Offline

Napisano 20.05.2013 11:36

to się napracowałeś, brawa dla tego Pana  :like_it:



#3 Pan Marian

    Banned

  • Zbanowany

Reputacja: 89
Zaawansowany

  • Postów:283
  • Imię:Marian
  • Lokalizacja:इंटरनेट
Offline

Napisano 20.05.2013 13:12

Co jest bardziej optymalne,

get_userflags(id) & ADMIN_LEVEL_H
czy
get_user_flags(id) & (1<<19)

 



:facepalm:  A jeżeli byłoby tak?

 

Co jest bardziej optymalne,

get_user_flags(id) & ADMIN_LEVEL_H
czy
get_user_flags(id) & (1<<19)

 


sharkowy (20.05.2013 12:39):
to drugie, bo to pierwsze nawet Ci nie zadziała :D
sharkowy (20.05.2013 13:37):
bez różnicy ^.^


#4 GwynBleidD

    Godlike

  • Administrator

Reputacja: 1849
Godlike

  • Postów:3066
  • Steam:steam
  • Lokalizacja:Przemyśl
Offline

Napisano 20.05.2013 13:51

Bez różnicy są następujące zapisy:

get_user_flags(id) & ADMIN_LEVEL_H // ADMIN_LEVEL_H jest na etapie kompilaci przekształcane na (1<<19) (#define odpowiednie)
get_user_flags(id) & (1<<19) // to jest przekształcane po prostu na liczbę, gdyż nie użyta jest w wyrażeniu żadna zmienna.
get_user_flags(id) & 524288 // to jest właśnie ta liczba, w formacie dziesiętnym
get_user_flags(id) & 0x80000 // ta sama liczba w szesnastkowym
get_user_flags(id) & 02000000 // ta sama w ósemkowym
get_user_flags(id) & 0b10000000000000000000 // ta sama w binarnym...

Można jeszcze to zapisać na milion innych sposobów, jednak tylko 2 pierwsze mają jakiś sens... 3ci nie ma kompletnie żadnego, gdyż nie wiemy zupełnie co ta liczba oznacza, więc kod się staje nieczytelny. Czwarty sposób jeszcze coś wnosi, ale też trzeba przeliczać. Piąty i szósty zostawię bez komentarza.

 

Jeśli potrzeba sprawdzić kilka flag na raz, można użyć sumy bitowej (znak |) w ten sposób:

 

get_user_flags(id) & (ADMIN_LEVEL_A|ADMIN_LEVEL_H) == (ADMIN_LEVEL_A|ADMIN_LEVEL_H)
get_user_flags(id) & ((1<<12)|(1<<19)) == (1<<12)|(1<<19)

Co sprawdzi nam, czy gracz ma obie z tych flag. Bez == i tego po == sprawdzi, czy ma którąkolwiek z nich.

 

Więc na boga, kto w generatorze VIPa wymyślił get_user_flags(id) & 524288 ???

 


(20.05.2013 18:41):
ja wymyśliłem, dawno dawno temu i jakoś od tego czasu nigdy nie było to modyfikowane.
Nie mniej jednak, zmienię to na bardziej czytelną wersję w kolejnej wersji :)

  • +
  • -
  • 2
NIE pomagam na PW. Nie trudź się, na zlecenia nie odpiszę... Od pomagania jest forum.
NIE zaglądam w tematy wysłane na PW. Jeśli są na forum to prędzej czy później je przeczytam. Jeśli mam co w nich odpisać, to odpiszę.
 
1988650.png?theme=dark





Również z jednym lub większą ilością słów kluczowych: flagi, uprawnienia, u2

Użytkownicy przeglądający ten temat: 0

0 użytkowników, 0 gości, 0 anonimowych