malo pisalem w asm, ale nieskonczona petle uzyskasz przez skoki:
infinity: ;kod jmp infinity
co do opóźnienia, to jedyne co mi przychodzi to sprawdzanie czasu i wykonywanie odpowiedniego skoku
To równanie zostało stworzone przy pomocy kodu LaTeX:
Edytor LaTeX online: CodeCogs.com/latex/eqneditor.php
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.
|
Napisane przez plx211
w 03.01.2016 15:05
Napisane przez DarkGL
w 20.10.2015 08:04
Napisane przez plx211
w 19.10.2015 19:15
Napisane przez plx211
w 18.10.2015 22:05
Napisane przez Engi
w 30.03.2015 19:04
Nie możesz zamknąć funkcji ifem. Nie rozumiem sensu istnienia funkcji "Funkcja4()", przecież to jest bez sensu.
Funkcja4() powinna wyglądać tak:
Func Funkcja4() If $wykonano == 1 Then MsgBox(0, "Wiadomość", "Coś wykonałeś, funkcja przerwana") ElseIf $aktiv == 0 Then MsgBox(0, "Wiadomość", "Coś Ci nie pykło, bo $aktiv równa się zeru, funkcja przerwana") EndIf ;na jakiej zasadzie $wykonano ma się równać 1? Brakuje mi tu Ifa $wykonano = 1 Sleep(3000) If $aktiv == 0 Then MsgBox(0, "Wiadomość", "Coś Ci nie pykło, bo $aktiv równa się zeru, funkcja przerwana") EndIf $program = 1 Send("{3}") $wykonano = 0 EndFunc
Ale nie widzę sensu stosowania tego kodu. Może podaj całość co tam naskrobałeś to coś pomyślimy, albo napisz co chciałeś osiągnąć swoją "Funkcją czwartą" to napiszę Ci tą funkcję tak jak powinna być napisana.
Napisane przez DarkGL
w 28.03.2015 01:52
Napisane przez BlackPerfum
w 04.05.2014 01:09
SearchKey(value,keys) { return floatround(floatlog(float(value & keys),2.0)) }Taka mała niepozorna funkcja zastępuje całkiem dużo kodu.
new SB = 1<<CSW_ELITE | 1<<CSW_FIVESEVEN | 1<<CSW_USP | 1<<CSW_GLOCK18 | 1<<CSW_DEAGLE | 1<<CSW_P228 new weapons[32], numweapons,weapon; get_user_weapons(id, weapons, numweapons); for(new i=0; i<numweapons; i++) if((1<<weapons[i]) & SB) weapon = weapons[i]; //Jupii znaleźliśmy nasz pistolet :DOczywiście nie biorę pod uwagę gorszych przypadków szukania broni
new SB = 1<<CSW_ELITE | 1<<CSW_FIVESEVEN | 1<<CSW_USP | 1<<CSW_GLOCK18 | 1<<CSW_DEAGLE | 1<<CSW_P228 new weapons,weaponlist[32],num,weapon weapons = get_user_weapons(id,weaponlist,num) weapon = SearchKey(weapons,SB) //I tak oto znaleźliśmy pistoletZastrzegam prawa do gnębienia tego przykładu gdyż jest dosyć głupi (nie widać dużej różnicy kodu ani 100% poprawności) bo na połowie aktualnych serwerów można mieć wiele broni na raz (także tego samego typu(typ tzn. pierwszorzędne/drugorzędne/itd))
enum {Latam=1,Plywam,Biegam,Chodze,Stoje,NicSieZeMnaNieDzieje,PosiadamC4,Pisze,WidzeHud,WidzeMotd,WidzeSay} new Player[33]To gdy chcemy sprawdzić co się z ziomkiem (ale tylko rzeczy między Latam a NicSieZeMnaNieDzieje) dzieje to musimy zrobić tak:
new CoRobiGracz if(Player[id] & 1<<Latam) CoRobiGracz = Latam //Ja latam jeee else if(Player[id] & 1<<Plywam) CoRobiGracz = Plywam // Plywam :D else if(Player[id] & 1<<Biegam) CoRobiGracz = Biegam // A jednak biegam else if(Player[id] & 1<<Chodze) CoRobiGracz = Chodze // Spacerek else if(Player[id] & 1<<Stoje) CoRobiGracz = Stoje // Zmeczylem sie else if(Player[id] & 1<<NicSieZeMnaNieDzieje) CoRobiGracz = NicSieZeMnaNieDzieje // Totalny odpoczynekPamiętajmy iż może być więcej niż jeden bit aktywny!!!
new CoRobiGracz = SearchKey(Player[id],Player[id] & (1<<Latam|1<<Plywam|1<<Biegam|1<<Chodze|1<<Stoje|1<<NicSieZeMnaNieDzieje)) // I tak w oto sposob sie dowiedzielismy co sie dzieje z graczem (pewnie to ostatnie)Ten przykład tez nie pokazuje prawdziwego potencjału tej funkcji ale co zrobić jak brakuje nam weny.
public Wywolaj() { new R,X,text[6] formatex(text,5,"Zjem") X = CreateMultiForward("Tutorial",ET_IGNORE,FP_CELL,FP_STRING); ExecuteForward(X, R, X, text); } public Tutorial(id,text[]) { DestroyForward(id) server_print("%s noge tu byl",text) }A teraz drugi plugin:
public Tutorial(id,text[]) { new PolowaTekstu[10] formatex(PolowaTekstu,9,"%s ci",text) ExecuteForward(id, R, id, PolowaTekstu); }To wcale nie jakies wiekopomne odkrycie ale ciekawe. Wywołanie funkcji Wywolaj sprawi że plugin nr. 1 napisze w konsoli serwera Zjem ci noge tu byl. Prawda że ciekawe rzeczy robi ta funkcja, a najciekawsze jest to że przerzucam sobie po pluginach uchwyt do multi forwardu
public Menu(id) { new menu = menu_create( "Menu" , "Menu_Zwrot"); if(is_user_alive(id)) menu_additem(menu,"+ 50Hp") else menu_additem(menu,"Ozyw") menu_additem(menu,"Pusta opcja") menu_setprop(menu, MPROP_PERPAGE, 1) menu_display(id, menu); }Załóżmy że to menu samo się otwiera co 1 min. W pewnym przypadku graczu zostało otworzone te menu kiedy żył ale przez jego głupotę zginą i po śmierci widzi opcje +50Hp i nie kliknie jej (bo według niego ona nic mu nie da)
new const NameMenuItem[][] = {"+ 50Hp ","Ozyw"} public Menu2(id) { new menu = menu_create( "Menu" , "Menu_Zwrot"); new cb = menu_makecallback("Menu_Callback"); menu_additem(menu,"Taki tam tekst",_,_,cb) menu_additem(menu,"Pusta opcja",_,_,cb) menu_setprop(menu, MPROP_PERPAGE, 1) menu_display(id, menu); } public Menu_Callback(id,menu,item) { static acces,callback,name[100],tryb,data[2] menu_item_getinfo(menu,item,acces,data,1,name,99,callback) switch(item) { case 0: { if(is_user_alive(id)) tryb = 0 else tryb = 1 } case 1: return ITEM_DISABLED } if(contain(name, NameMenuItem[tryb]) == -1) { formatex(name,99,"%s^n^n Aby odswiezyc menu zmien strone",NameMenuItem[tryb]) menu_item_setname(menu,item,name) } return ITEM_ENABLED }Funkcja contain jest tu bardzo ale to bardzo ważna. Dlaczego? A bo zmieniając cały czas w menu nazwy przyciskow nasze cudne menu sie buguje i powoli zjada nam text (nie zawsze do gracza dochodzi opcja multipart ale czemu?? nie mam pojęcia) na szczęście ten bug występuje kiedy menu ma więcej znaków niż 1000 czy 1024 nie mam pojęcia bo nie sprawdzałem dokładnie. Ale grunt że po zmianie strony odświeża + nie trzeba używać jakichś rozległych funkcji
Napisane przez
Gość
w 20.05.2013 10:24
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:
indeksy od 0 (po prawej) do 31 (po lewej); 1 ∈ { B0 ; B10 ; B20 ; B30 }
następująco:
Przykład dla liczby D=13:
…
13 = 00000000000000000000000000001101
Przeliczanie liczby U2 na dziesiętną
Prostsza forma zapisu wzoru:
Dłuższa forma zapisu wzoru:
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+23 = 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 22 = 4.
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 ASCII: Lista 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:
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.
Napisane przez master522
w 02.01.2014 18:25
Napisane przez glutex
w 02.01.2014 11:11
Zrobilem tak i po wejsciu na serwer CS sie wyłącza
Napisane przez glutex
w 01.01.2014 13:04
Napisane przez DarkGL
w 17.01.2012 14:45
new laser; public plugin_precache(){ laser = precache_model("sprites/laserbeam.spr") } stock showGrenadeWay ( id , weapon ){ new Float:fGrenadeGrav = 1.0; switch( weapon) { case CSW_HEGRENADE: fGrenadeGrav = 0.55; case CSW_FLASHBANG: fGrenadeGrav = 0.5; case CSW_SMOKEGRENADE: fGrenadeGrav = 0.5; } static pGrav; if( !pGrav ) pGrav = get_cvar_pointer( "sv_gravity" ); new Float:fStartPos[ 3 ] , Float: fViewOfs[ 3 ] , Float: fVector[ 3 ] , Float: fVeloc [ 3 ] , Float: fAngles [ 3 ] , Float: fEndPos [ 3 ] , Float: fTmpVector [ 3 ] , pTr , Float: fFraction , Float: fNormal [ 3 ] , iCollision = 0 , Float: fVel; new Float:fGrav = get_pcvar_float( pGrav ) , pHit = 0; const maxCollsion = 30; const Float: fConstAliveTime = 2.0; const Float: fConstLoops = 20.0; new Float: fAliveTime = 0.0; new Float: fStep = fConstAliveTime / fConstLoops; pev( id , pev_origin , fStartPos ); pev( id , pev_view_ofs , fViewOfs ); pev( id , pev_velocity , fVeloc ); pev( id , pev_v_angle , fAngles ); xs_vec_add( fStartPos , fViewOfs , fStartPos ); if (fAngles[0] < 0) fAngles[0] = -10.0 + fAngles[0] * ((90.0 - 10.0) / 90.0); else fAngles[0] = -10.0 + fAngles[0] * ((90.0 + 10.0) / 90.0); fVel = (90.0 - fAngles[0]) * 6.0; if (fVel > 750.0) fVel = 750.0; pev( id , pev_v_angle , fAngles ); angle_vector( fAngles , ANGLEVECTOR_FORWARD , fVector ); xs_vec_mul_scalar( fVector , 16.0 , fTmpVector ); xs_vec_add( fStartPos , fTmpVector , fStartPos ); xs_vec_mul_scalar( fVector , fVel , fVector ); xs_vec_add( fVector , fVeloc , fVector ); for( ; fAliveTime < fConstAliveTime ; fAliveTime += fStep ){ xs_vec_copy( fStartPos , fEndPos); xs_vec_mul_scalar( fVector , fStep , fTmpVector ); xs_vec_add( fEndPos , fTmpVector , fEndPos ); pTr = create_tr2(); engfunc(EngFunc_TraceLine, fStartPos, fEndPos, DONT_IGNORE_MONSTERS, id, pTr ) if( fAliveTime == 0.0 ){ fStartPos [ 2 ] += 10.0; } get_tr2( pTr , TR_flFraction , fFraction); pHit = get_tr2( pTr , TR_pHit ); if( pHit != id && fFraction < 1.0 ){ get_tr2( pTr , TR_vecEndPos , fEndPos ); get_tr2( pTr , TR_vecPlaneNormal , fNormal ) if( fNormal [ 2 ] > 0.9 && fVector [ 2 ] <= 0.0 && fVector [ 2 ] >= -fGrav / 0.20 ){ return ; } new Float: fScalar = xs_vec_dot( fVector, fNormal ) * 1.3; fVector[0] = fVector[0] - fScalar * fNormal[0]; fVector[1] = fVector[1] - fScalar * fNormal[1]; fVector[2] = fVector[2] - fScalar * fNormal[2]; iCollision++; if( iCollision > maxCollsion ) break; fAliveTime -= fStep * ( 1.0 - fFraction ) ; } new iR , iG , iB; switch( weapon ) { case CSW_HEGRENADE:{ iR = 250; iG = 0; iB = 0; } case CSW_FLASHBANG:{ iR = 0; iG = 0; iB = 250; } case CSW_SMOKEGRENADE:{ iR = 0; iG = 250; iB = 0; } } message_begin( MSG_ONE_UNRELIABLE , SVC_TEMPENTITY , { 0 , 0 , 0 } , id ) write_byte(0) // TE_BEAMPOINTS engfunc( EngFunc_WriteCoord , fStartPos [ 0 ] ) engfunc( EngFunc_WriteCoord , fStartPos [ 1 ] ) engfunc( EngFunc_WriteCoord , fStartPos [ 2 ] ) engfunc( EngFunc_WriteCoord , fEndPos [ 0 ] ) engfunc( EngFunc_WriteCoord , fEndPos [ 1 ] ) engfunc( EngFunc_WriteCoord , fEndPos [ 2 ] ) write_short(laser) write_byte(1) write_byte(1) write_byte(1) write_byte(15) write_byte(0) write_byte( iR ) write_byte( iG ) write_byte( iB ) write_byte(210) write_byte(0) message_end() xs_vec_copy( fEndPos , fStartPos ); fVector[ 2 ] -= floatmul( floatmul( fGrenadeGrav , fGrav ) , floatmul( fFraction , fStep ) ); free_tr2( pTr ); } }
#include <xs> #include <fakemeta>
public client_PreThink( id ){ if( is_user_alive( id ) ){ new iWeapon = get_user_weapon( id ); if( iWeapon == CSW_HEGRENADE || iWeapon == CSW_SMOKEGRENADE || iWeapon == CSW_FLASHBANG ){ showGrenadeWay( id , iWeapon ); } } }
Napisane przez Amaroq
w 22.12.2013 19:28
Tu jest pierwszy problem. Dla nowej wersji silnika używasz dproto nowszego od tej wersji np. 0.9.364 (najnowsza).Mam wgrany dproto w wersji 0.9.187
2. problem to, że nawet nie widzi dproto.Currently running plugins: [ 1] AMX Mod X, v1.8.2, Feb 14 2013, by AMX Mod X Dev Team, see http://www.amxmodx.org [ 2] Fun, v1.8.2, Feb 14 2013, by AMX Mod X Dev Team, see http://www.amxmodx.org [ 3] Engine, v1.8.2, Feb 14 2013, by AMX Mod X Dev Team, see http://www.amxmodx.org [ 4] FakeMeta, v1.8.2, Feb 14 2013, by AMX Mod X Dev Team, see http://www.amxmodx.org [ 5] CStrike, v1.8.2, Feb 14 2013, by AMX Mod X Dev Team, see http://www.amxmodx.org [ 6] CSX, v1.8.2, Feb 14 2013, by AMX Mod X Dev Team, see http://www.amxmodx.org/ [ 7] Ham Sandwich, v1.8.2, Feb 14 2013, by AMX Mod X Dev Team, see http://www.amxmodx.org [ 8] MySQL, v1.8.2, Feb 14 2013, by AMX Mod X Dev Team, see http://www.amxmodx.org/
ServerInfoAnswerType = 0i zmień na
ServerInfoAnswerType = 2Pozwoli to dodać starszym NS serwer do favorites.
Napisane przez sebul
w 16.10.2011 11:54
"STEAM_0:0:123456" "" "abcde" "ce" "09-07-2011" "-1"Gracz będzie miał VIPa z flagami "abcde" na steam na czas nieokreślony.
"123.45.67.89" "" "abcde" "de" "26-10-2011" "15"Gracz będzie miał VIPa z flagami "abcde" na ip przez 15 dni licząc od 26 października br.
"My Name" "my_password" "abcde" "a" "20-10-2011" "30"Gracz będzie miał VIPa z flagami "abcde" na nick przez 30 dni licząc od 20 października br.
/* zwraca flagi gracza */
native get_user_vip_flags(id);
/* ustawia flagi graczowi */
native set_user_vip_flags(id, flags = -1);
/* dodaje flagi graczowi */
native add_user_vip_flags(id, flags = -1);
/* usuwa flagi graczowi */
native remove_user_vip_flags(id, flags = -1);
/* forward wysylany po sprawdzeniu pliku z flagami, nie wykonywany tylko wtedy gdy gracz zostaw wyrzucony
id - id gracza
flags - przypisane flagi
endtime - data zakonczenia vipa w sekundach (unix time)
-2: nie znaleziono gracza lub czas vipa juz sie skonczyl
-1: vip na czas nieokreslony
*/
forward vip_client_authorized(id, flags, endtime);
#include <vip>
get_user_flags(id)
set_user_flags(id, flags)
remove_user_flags(id, flags)
#define VIP_FLAG_ALL 0 /* kazdy */
#define VIP_FLAG_A (1<<0) /* flaga "a" */
#define VIP_FLAG_B (1<<1) /* flaga "b" */
#define VIP_FLAG_C (1<<2) /* flaga "c" */
#define VIP_FLAG_D (1<<3) /* flaga "d" */
#define VIP_FLAG_E (1<<4) /* flaga "e" */
#define VIP_FLAG_F (1<<5) /* flaga "f" */
#define VIP_FLAG_G (1<<6) /* flaga "g" */
#define VIP_FLAG_H (1<<7) /* flaga "h" */
#define VIP_FLAG_I (1<<8) /* flaga "i" */
#define VIP_FLAG_J (1<<9) /* flaga "j" */
#define VIP_FLAG_K (1<<10) /* flaga "k" */
#define VIP_FLAG_L (1<<11) /* flaga "l" */
#define VIP_FLAG_M (1<<12) /* flaga "m" */
#define VIP_FLAG_N (1<<13) /* flaga "n" */
#define VIP_FLAG_O (1<<14) /* flaga "o" */
#define VIP_FLAG_P (1<<15) /* flaga "p" */
#define VIP_FLAG_Q (1<<16) /* flaga "q" */
#define VIP_FLAG_R (1<<17) /* flaga "r" */
#define VIP_FLAG_S (1<<18) /* flaga "s" */
#define VIP_FLAG_T (1<<19) /* flaga "t" */
#define VIP_FLAG_U (1<<20) /* flaga "u" */
#define VIP_FLAG_V (1<<21) /* flaga "v" */
#define VIP_FLAG_W (1<<22) /* flaga "w" */
#define VIP_FLAG_X (1<<23) /* flaga "x" */
#define VIP_FLAG_Y (1<<24) /* flaga "y" */
#define VIP_FLAG_Z (1<<25) /* flaga "z" */
if(get_user_vip_flags(id) & VIP_FLAG_E) {
// gracz posiada flagę "e"
}
if(!(get_user_vip_flags(id) & VIP_FLAG_ B)) {
// gracz nie posiada flagi "b"
}
#include <amxmodx>
#include <vip>
#define PLUGIN "Nowy"
#define VERSION "0.1"
#define AUTHOR "Sebul"
public plugin_init() {
register_plugin(PLUGIN, VERSION, AUTHOR);
register_clcmd("say /test", "test");
}
public test(id) {
if(get_user_vip_flags(id) & VIP_FLAG_C) {
new name[48]; get_user_name(id, name, charsmax(name));
client_print(0, print_chat, "%s jest VIPem", name);
}
}
public vip_client_authorized(id, flags, endtime) {
if(flags & VIP_FLAG_C) {
new name[48]; get_user_name(id, name, charsmax(name));
client_print(0, print_chat, "%s jest VIPem", name);
}
}
vwg_wl "0" // czy plugin ma byc wlaczony vwg_od "21" // od ktorej godziny plugin ma dawac flagi vwg_do "24" // do ktorej godziny plugin ma dawac flagi vwg_flagi "abcdefghijklmnopqrstuvwxyz" // jakie flagi ma dawac plugin vwg_wiad "darmowego vipa" // co daja dawane flagi
say /endvip - na czacie wyświetli się graczowi data kiedy kończy się VIP
amx_addvip <name|ip|steamid> <password> <access flags> <account flags> <dd-mm-rrrr> <lenght in days> // dodaje VIPa