Jump to content
  • Chmurka
  • Boróweczka
  • Jabłuszko
  • Limonka
  • Czekoladka
  • Węgielek

Search the Community

Showing results for tags 'flagi'.



More search options

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


Forums

  • Nasze Sprawy
    • Nowości
    • Dyskusje
    • Propozycje
    • Przywitaj się!
  • Sourcemod Scripting
    • Artykuły, poradniki, tutoriale
    • Pytania na temat kodowania
    • Problem z kodem pluginu
    • Prośby o przerobienie pluginu
    • Gotowe funkcje
    • Koduj z Magnetem
  • Konfiguracja pluginów
    • Artykuły, poradniki i tutoriale
    • Szukam pluginu
    • Duże modyfikacje
    • Zbiór pluginów
    • Extensions
    • Gotowe paczki serwerowe
  • Konfiguracja serwera
    • Artykuły, poradniki, tutoriale
    • Pytania
    • Problemy
    • Ochrona
    • Metamod
  • Counter-Strike: Global Offensive
    • Nowości
    • Artykuły, poradniki, tutoriale
    • Pytania
    • Problemy
    • Pliki
    • Wasza twórczość
    • Publikacje serwerów
  • Hostingi serwerów
    • Oferty firm
    • Opinie o hostingach
    • Pytania
  • Plac zabaw
    • Luźne rozmowy
    • Szukam ekipy
    • Rynek
    • Opinie o ludziach
    • RoundSoundy
  • Archiwum
    • Przestarzałe tematy
    • Kosz

Find results in...

Find results that contain...


Date Created

  • Start

    End


Last Updated

  • Start

    End


Filter by number of...

Joined

  • Start

    End


Group


O mnie

Found 3 results

  1. Cześc mam pytanie czy można w jakiś sposób zignorować flagę? w sensie jeśli mam np stock bool IsPlayerVIP(int client) { return CheckCommandAccess(client, "", ADMFLAG_RESERVATION) } i nie chce żeby czytało flagi "z" to co musiałbym zrobić? Cały kod:
  2. Cześć! Dzisiaj pokażę wam jakie są flagi (czyli uprawnienia) w SourceModzie. Legenda: Nazwa: // Flaga: // Opis: ADMFLAG_RESERVATION // a // Rezerwacja slota ADMFLAG_GENERIC // b // Admin ogólny (wymagane dla Adminów) ADMFLAG_KICK // c // Pozwala na Kickowanie (wykopanie) gracza ADMFLAG_BAN // d // Pozwala na zbanowanie gracza ADMFLAG_UNBAN // e // Pozwala na odbanowanie gracza ADMFLAG_SLAY // f // Pozwala na slayowanie (zabicie) gracza ADMFLAG_CHANGEMAP // g // Pozwala na zmianę mapy ADMFLAG_CONVARS // h // Pozwala na zmianę cvarów ADMFLAG_CONFIG // i // Pozwala na ładowanie cfg. na serwerze ADMFLAG_CHAT // j // Pozwala na pisanie na środku i z boku ekranu ADMFLAG_VOTE // k // Pozwala na tworzenie głosowań ADMFLAG_PASSWORD // l // Pozwala na ustawienie hasła na serwerze ADMFLAG_RCON // m // Pozwala na używanie komend RCON. ADMFLAG_CHEATS // n // Pozwala na zmianę wartości sv_cheats ADMFLAG_ROOT // z // Posiada wszystkie flagi ADMFLAG_CUSTOM1 // o // Flaga niestandardowa 1 ADMFLAG_CUSTOM2 // p // Flaga niestandardowa 2 ADMFLAG_CUSTOM3 // q // Flaga niestandardowa 3 ADMFLAG_CUSTOM4 // r // Flaga niestandardowa 4 ADMFLAG_CUSTOM5 // s // Flaga niestandardowa 5 ADMFLAG_CUSTOM6 // t // Flaga niestandardowa 6 Co to znaczy, że flaga jest "niestandardowa"? - To znaczy, że flaga nie posiada funkcji. Do czego są potrzebne flagi "niestandardowe"? - Dzięki temu możemy stworzyć nową własną funkcję dla danej flagi (np. stworzyć pod flagę "o" Klasę Premium a pod flagę "p" VIP'a)
  3. KOMPEDIUM WIEDZY O BITACH, OPERACJACH BITOWYCH I ZASTOSOWANIU W PRAKTYCE Jeśli masz już jakieś doświadczenie z programowaniem, niezależnie czy jest to pawn, C czy inny język, na pewno na trafiłeś na takie pojęcie, jak "flaga" w pluginie/skrypcie etc. Masz też zapewne świadomość do czego taka flaga służy Przykładowo, w poradniku Vasto o timerach mamy do czynienia z flagami timera, np. UchwytNaszegoTimeru = CreateTimer(99999.9, FunkcjaKtoraSieWywola, INVALID_HANDLE, TIMER_REPEAT); czwarty argument funkcji CreateTimer mówi nam, że timer będzie cyklicznie wywoływał podaną funkcję dopóki go nie 'zabijemy' (KillTimer). Idea wydaje się być prosta - funkcja działa tak, jak jej rozkażemy. Nieco wyżej pojawia się jednak takie wywołanie: CreateTimer(1.0, FunkcjaKtoraSieWywola, GetClientUserId(client), TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE|TIMER_DATA_HNDL_CLOSE); Czy potrafisz wyjaśnić, co tutaj się dzieje? Na pewno domyślasz się, że timer wykona się wraz ze wszystkimi trzema flagami, jednak rozłożenie tego na czynniki pierwsze wydaje się być dosyć enigmatyczne. Okazuje się jednak, że nie jest to wcale takie straszne. Wymaga to dobrego zrozumienia, jednak na pewno zapunktuje w przyszłości. Postaram się wyjaśnić to tak dobrze, na ile tylko będę w stanie. Przygotuj sobie jakieś jedzenie i do roboty! Część I - jak zapisujemy liczby? Podstawą tutaj jest dwubitowa architektura komputerów. Oznacza to, że dane w pamięci reprezentowane są w postaci logicznej prawdy (1 - jedynka logiczna), lub fałszu (0 - zero logiczne). Kiedyś nieodzownym było operowanie właśnie na pamięci w takiej formie, jednak z czasem zaczęły powstawać języki programowania, które pozwalały na bardziej abstrakcyjne podejście do tematu kodowania. Jednak pomimo tego, programowanie cały czas sprowadza się do tych samych operacji, co wiele lat temu, jednak w ładniejszym wydaniu (co niekonieczne oznacza, że lepszym). Pod tym, co widzi współczesny programista kodując w C++, w dalszym ciągu kryją się skomplikowane operacje bitowe. I tutaj mamy całe clue sprawy - flagi są reprezentowane bitowo! Od razu nasuwa się pytanie - dlaczego? Po co ktoś miałby używać takiego podejścia? Odpowiedź nasunie się sama w dalszej części poradnika W komputerach najmniejszą adresowalną jednostką jest bajt, który składa się z ośmiu bitów, gdzie każdy bit może zawierać 1 lub 0 (jak wspominałem wyżej). My nie posługujemy się "bajtami" - my działamy ma zmiennych, jak int, float, czy char. Otóż każda zmienna składa się ze stałej ilości bajtów (char 1 bajt, int i float 4 bajty w pawnie). Współczesne języki są jednak na tyle elastyczne, że możemy bez problemu posługiwać się znanymi nam dobrze operacjami dodawania, odejmowania, mnożenia, potęgowania itd bez potrzeby działania na bitach Nie oznacza to jednak, że jesteśmy od tych operacji odcięci ? programiści bardzo dobrze wykorzystują je do optymalizacji działania programów, w tym znanych nam już flag. Dzisiaj również nauczymy się, jak pisać takie flagi samemu. Skoro wiemy już, że pod takim "prostym" integerem(int) kryje się zlepek bitów, zajrzyjmy sobie do niego: Jak widzimy w powyższej jakże profesjonalnie wykonanej, tabeli pokazana jest tylko połowa integera - 2 bajty. Tyle jednak w zupełności wystarczy, żeby pokazać o co tutaj chodzi... Dowolną liczbę zapisaną w jednym systemie można zapisać w innym (np. z dziesiętnego na szesnastkowy). W tym przypadku interesuje nas zamiana liczby dziesiętnej na binarną(ciąg zer i jedynek). Ktoś kiedyś słusznie zauważył, że: i tak 1 to 2^0, 2 to 2^1 i tak dalej.... można zauważyć tutaj jeszcze jedną ciekawą zależność - wartość dziesiętna każdego bitu jest równa wartości wszystkich poprzednich bitów plus jeden, np. 2^6 = 64 = 32+16+8+4+2+1+1 Płynący z tego wniosek jest taki, że każda liczba dziesiętna ma swoją unikalną reprezentację w systemie dwójkowym. Jak zapisujemy liczby dwójkowo? Oto przykłady: 15 = 1111 (2^0 + 2^1 + 2^2 + 2^3) | 20 = 10100 (2^4 + 2^2) | 1024 = 10000000000 (2^10) Działanie odwrotne (liczba binarna na dziesiętną) prezentuje się następująco: 101 = 2^0*1 + 2^1*0 + 2^2*1 = 5 | 1000 = 2^0*0 + 2^1*0 + 2^2*0 + 2^3*1 = 8 Po więcej informacji odnośnie przeliczeń zapraszam tutaj. Skoro więc wiemy, że pod każdą zmienną kryją się bity, oraz że jest ich skończona ilość dla danej zmiennej, możemy również znaleźć największą wartość, jaką dany typ zmiennej może przechowywać. Dla uproszczenia nie będę się zagłębiał w liczby zmiennoprzecinkowe - dziś skupimy się tylko na liczbach całkowitym i na integerze. Przydatnym narzędziem systemowym jest kalkulator, który oferuje tryb programisty. Po wprowadzeniu do niego 32 jedynek binarnie (bo tyle bitów posiada integer), otrzymałem nastepujący wynik: Sporo, ale...nie jest to faktyczna wartość maksymalna integera. Musimy także pamiętać o tym, że liczba może być także ujemna! Jak określić tutaj ujemność liczby? W tej sytuacji poświęca się ostatni bit, którego wartośc określa, czy liczba jest dodatnia, czy ujemna. Skoro straciliśmy jeden bit, nasza liczba "skurczyła się" do 31 miejsc, a więc teraz jest to... 2 147 483 647, a konkretniej przedział < -2 147 483 647 ; 2 147 483 647 > Na tym etapie rozumiemy jak zapisywane są liczby w komputerze, co to bit, bajt i jak przechodzimy z systemu dziesiętnego do binarnego i odwrotnie. Teraz możemy zająć się operacjami bitowymi. Część II - operacje bitowe W systemie dziesiętnym wykonujemy operacje dodawania, odejmowania, mnożenia, dzielenia, potęgowania, pierwiastkowania i tak dalej. System binarny charakteryzuje się swoim własnym zestawem operacji. Każdą operację wykonujemy parami - pierwszy bit liczby numer 1 z pierwszym bitem numer 2 - czynność powtarzamy na wszystkich bitach. Omówię teraz po kolei wszystkie operacje. 1. AND (mnożenie - koniunkcja) -> Znak & Wynik operacji AND daje 1, jeśli obydwie liczby są jedynką Przykład: 1010 & 1001 = 1000 | 1100 & 0101 = 0100 2. OR (dodawanie - alternatywa) -> Znak | Wynik operacji daje 1, jeśli przynajmniej jedna z liczb jest jedynką Przykład: 1010 | 1001 = 1011 | 1100 | 0101 = 1101 3. XOR (alternatywa wykluczająca) | Znak ^ Wynik operacji daje 1, jeśli dwie liczby różnią się, a 0, jeśli są takie same Przykład: 1010 ^ 1001 = 0011 | 1100 ^ 0101 = 1001 4. NOT (negacja) | Znak ~ (tylda) Operacja odwraca wartość bitu Przykład: ~1010 = 0101 | ~1100 = 0011 Są to cztery podstawowe operacje logiczne. Do omówienia pozostały jeszcze przesunięcia bitowe: 5. Przesunięcie bitowe w lewo | Znak << Operacja powoduje, że wszystkie bity w liczbie zostają przesunięte w lewo. Wszystkie bity, które na skutek przesunięcia 'wypadły' poza liczbę zostają utracone. Bity, które 'pojawiają się z prawej strony są zapisywane zawsze jako zera. Po lewej stronie operandu zapisujemy liczbę, natomiast po prawej o ile miejsc przesuwamy. Przykład: 1010 << 1 = 0100 | 1100 << 1 = 1000 5. Przesunięcie bitowe w prawo | Znak >> Operacja powoduje, że wszystkie bity w liczbie zostają przesunięte w prawo. Wszystkie bity, które na skutek przesunięcia 'wypadły' poza liczbę zostają utracone. Bity, które 'pojawiają się z lewej strony są zapisywane zawsze jako zera. Po lewej stronie operandu zapisujemy liczbę, natomiast po prawej o ile miejsc przesuwamy. Przykład: 1010 >> 1 = 0101 | 1100 >> 1 = 0110 Wszystko wydaje się być dziwne i bezsensowne, jednak o tym jak potężne jest to narzędzie przekonasz się w części trzeciej ? Omówiliśmy już wszystkie operacje. Teraz, kiedy jesteśmy już gruntowo przygotowani pod względem teoretycznym, możemy wreszcie przejść do praktyki. Część III - flagi Rozpatrzmy teoretyczną sytuację, w której chcemy monitorować, czy gracz (dla uproszczenia jeden) posiada w nicku frazę "[GO-Code]", aby nagradzać go dodatkową ilością złota co rundę. Aby tego dokonać, musimy wykonać szereg operacji: znaleźć id gracza, na jego podstawie pobrać nick i umieścić w tablicy, sprawdzić, czy nazwa posiada szukaną frazę za pomocą StrContains, a następnie zwrócić rezultat. Mimo, że wszystkie te operacje trwają dość szybko (dla człowieka), to komputer nie ma świadomości tego, że już raz sprawdziliśmy nick gracza - dlatego w każdej kolejnej rundzie musi mieć jasną informację, czy ma przydzielać złoto z tytułu posiadanej frazy... Co byś w tej sytuacji zrobił? Najsensowniejszym rozwiązaniem wydaje się być zastosowanie zwykłej zmiennej, która domyślnie przyjmuje wartość 0 i zmienia się na 1, jeśli powyższe warunki zostaną spełnione. Teraz wystarczy, że serwer będzie na początku rundy sprawdzał zawartość zmiennej, zamiast każdorazowo wykonywać szereg kosztownych operacji - a nie zapominajmy, że przeważnie jest dużo więcej graczy do sprawdzenia ? Załóżmy teraz, że poza sprawdzeniem frazy [GO-Code] chcielibyśmy, by serwer dodatkowo sprawdzał, czy SteamID gracza to STEAM_0:1:1234567, gdyż jest to streamer, które gra na naszym serwerze i chcemy zapewnić mu dodatkowe przywileje. Aby to sprawdzać zapewne ponownie zastosujemy dodatkową zmienną, jednak musimy być świadomi, że teraz mamy już dwie zmienne, zamiast jednej. A co, jeżeli nasze dwie zmienne są lokalne i chcielibyśmy je przekazać do innej funkcji? Sprawa wygląda w miarę prosto, gdy mamy dwie zmienne, ale co w sytuacji, gdzie potrzebujemy takich zmiennych np. dziesięć? PrzekazStatystyki(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10) Pomyślmy, jak wyglądałaby deklaracja flag regexa? Co w sytuacji, gdybyśmy chcieli skorzystać tylko z jednej opcji? Mimo wszystko musielibyśmy wysyłać wszystkie zmienne (bez wyraźnej potrzeby) Dopiero teraz na wierzch wychodzi to, jak użyteczne są operacje bitowe Pamiętamy, że każdy int to zestaw 32 bitów. Każdy bit przyjmuje wartość 1 lub 0.... czyli właśnie to, czego potrzebujemy! 1 i 0 to właśnie nasza prawda i fałsz! daje nam to niesamowicie szeroki wachlarz odogodnień. Zamiast tworzyć dziesięć zmiennych: int x1, x2, x3, x4, x5, x6, x7, x8, x9; tworzymy jedną: int flags; Zamiast przekazywać do funkcji dziesięć zmiennych: PrzekazStatystyki(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10) przekazujemy jedną: PrzekazStatystyki(flags) Teraz pozostaje nam nauczenie się, jak z tego korzystać, gdyż wszystkie operacje będą przeprowadzane na bitach. Powróćmy do naszego przykładu dwóch flag gracza. Gdybyśmy realizowali to standardową metodą, robilibyśmy to w taki sposób: Oraz funkcja przydzielająca atrybuty graczowi: Teraz napiszmy to samo z wykorzystaniem bitów  W naszym przykładzie posiadanie frazy w nicku będzie równoznaczne z ustawieniem pierwszego bitu (od prawej) w zmiennej na 1, natomiast streamer - drugiego bitu. Zauważmy tutaj ciekawą rzecz - pierwszy bit oznacza jedynkę (2^0), natomiast drugi bit dwójkę (2^1). Jeśli więc streamer będzie miał w nicku frazę "GO-Code" (obydwa przypadki spełnione), nasza flaga przyjmie wartość...3! Dlaczego? Oto wyjaśnienie (przypominam, że int ma 32 bity): int flags = 0000 0000 0000 0000 0000 0000 0000 0011 + 2^0 + 2^1 = 3 Prawda, że intuicyjne? Podobnie, gdybyśmy mieli dziesięć flag i chcielibyśmy sprawdzić, czy WSZYSTKIE są ustawione na true(1) wystarczyłoby porównanie wartości zmiennej flags do 1023 (ponieważ każdy bit to suma poprzedników plus jeden, a pod jedenastym bitem siedzi 2^10, czyli 1024. Oznacza to, że wartość 1024 to 00...100 0000 0000, a 1023 to 00...011 1111 1111) Dodatkowo, jeśli wykonujemy operacje arytmetyczne na liczbie dziesiętnej, i tak można ją przedstawić w postaci binarnej. Jeśli więc do zmiennej, która ma wartość 0, dodamy 2 (zmienna += 2) drugi bit tej zmiennej stanie się jedynką, a pozostałe będą zerami. My jednak nie będziemy wykonywać operacji arytmetycznych, gdyż operacja na np. dziesięciu zmiennych mogłaby przyprawić o zawrót głowy nawet największego wymiatacza  Aby dodać flagę do zmiennej (zmienić wartość bitu), będziemy posługiwać się logiczną operacją OR. Wiemy z części drugiej, że OR zwraca 1, jeśli przynajmniej jedna ze zmiennych jest prawdziwa. Jeśli więc wykonamy taką operację: flags |= 1 ( to samo, co flags = flags|1 ) spowodujemy, że pierwszy bit naszej zmiennej stanie się jedynką, natomiast pozostałe pozostaną bez zmian: ...101010 | ...000001(jedynka binarnie) = ...101011 prawda, że fajne? jedynym problemem jest dobre zrozumienie co tutaj się dzieje  podobnie, ustawienie drugiej flagi wiąże się z operacją OR, jednak tutaj posłużymy się już dwójką: ...010101 | ...000010(dwójka binarnie) = ...010111 Ale to jeszcze nie wszystko! Aby nie musieć poruszać się cały czas po potęgach dwójki, możemy również użyć przesunięć bitowych. Jak to działa? Zauważmy, że przesunięcie bitowe w lewo jest równoznaczne z pomnożeniem naszej liczby przez 2. Tak więc 2<<1 = 4. Widzimy też, że działa to dokładnie tak, jak nasza identyfikacja numeru bitu. Jeśli więc zrobimy coś takiego: flags |= (1<<1) efekt będzie taki sam, jak: flags |= 2 Sytuacja robi się jeszcze przyjemniejsza, gdy zdefiniujemy sobie takie makra: #define FRAZA (1<<0) #define STREAMER (1<<1) a później już tylko sama bajka: flags |= STREAMER; flags |= FRAZA; lub flags |= (STREAMER|FRAZA); I WŁAŚNIE TAKICH MAKR UŻYWA SIĘ WSZĘDZIE! Nie ważne, czy będzie to ADMIN_IMMUNITY z flag admina, czy PCRE_UTF8 z regexa - wszędzie odbywa się to w dokładnie ten sam sposób! Ostatnią rzeczą jest sprawdzenie, czy dana flaga jest aktywna, Tutaj posługujemy się logiczną operacją AND. Daje ona jedynkę tylko w sytuacji, gdy obydwie zmienne są prawdziwe. Możemy to obrócić na naszą korzyść. Aby sprawdzić, czy dany bit (tj nasza flaga) jest "włączona", robimy coś takiego: if(flags & FRAZA) jak wiemy, if "przepuszcza dalej", jeśli wartość wyrażenia jest różna od zera. A więc jeśli if otrzymał przykładowo: ...010101 & ...000001 = ...000001 = 1 (binarnie) ...musiał on przepuścić warunek sprawdzenia możemy łączyć: if(flags & FRAZA && flags & STREAMER) { // uprawnienia i kasiora prosze } pamiętajmy też o kolejności wykonywania działań! Z tego właśnie powodu stosuję nawiasy zarówno w warunku jak i przy deklaracji makr #define Tak oto przerobiliśmy cały materiał. Po zastosowaniu zdobytej wiedzy w praktyce, nasz poprzedni kod możemy napisać w następujący sposób: Oczywiście nie należy popadać w paranoję i stosować tych flag wszędzie, gdzie się tylko da xD. W małych pluginach możemy spokojnie korzystać ze zwykłych zmiennych, gdyż narzut pamięciowy jest i tak znikomy. Wierzę, że będziesz w stanie znaleźć do tego wiele zastosowań. Wooah.. ale poleciałem. Poradnik wyszedł strasznie długi, ale chciałem to zrobić w sposób rzetelny i w takiej formie, jaką sam bym chciał otrzymać lata temu, ponieważ nikt nie wytłumaczył tego w należyty sposób. Niech Wam dobrze służy Jeśli macie jeszcze jakieś pytania, czy wątpliwości, śmiało zadawajcie pytania, a jeśli okaże się to potrzebne, zaktualizuję poradnik. Oczywiście zachęcam do przeglądania innych poradników i ciągłego samodoskonalenia. Dzięki za uwagę i powodzenia w lekturze

Nasza historia

Na początku byliśmy małą grupą internetowych znajomych, którzy stwierdzili, że potrzebne jest solidne forum, na którym znajdą się ludzie z dużą wiedzą programistyczną ukierunkowaną na CS:GO. Pomysł powstał na początku 2018 roku, a parę miesięcy później, 19 kwietnia, powstała ta strona internetowa. Jako alternatywna odpowiedź na inne tego typu miejsca, poważnie podeszliśmy do tematu, najpierw tłumacząc angielską dokumentację SourceMod'a na język polski, a potem pisząc rozległe poradniki i wypełniając forum najpotrzebniejszymi rzeczami dla właścicieli serwerów i programistów. Cała nasza Ekipa jest dumna z pracy jaką w to włożyliśmy i cieszymy się że zbierają się wokół nas zarówno ludzie znający tematy sourcepawn'a i konfiguracji, jak i również nowe twarze w tym "biznesie", którym z chęcią niesiemy wiedzę oraz pomoc w rozwiązywaniu problemów.

Największe modyfikacje serwerowe

×
×
  • Create New...