Skocz do zawartości
  • Chmurka
  • Boróweczka
  • Jabłuszko
  • Limonka
  • Czekoladka
  • Węgielek

Znajdź zawartość

Wyświetlanie wyników dla tagów 'artykuł' .



Więcej opcji wyszukiwania

  • Wyszukaj za pomocą tagów

    Wpisz tagi, oddzielając je przecinkami.
  • Wyszukaj przy użyciu nazwy użytkownika

Typ zawartości


Forum

  • 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

Szukaj wyników w...

Znajdź wyniki, które zawierają...


Data utworzenia

  • Od tej daty

    Do tej daty


Ostatnia aktualizacja

  • Od tej daty

    Do tej daty


Filtruj po ilości...

Dołączył

  • Od tej daty

    Do tej daty


Grupa podstawowa


O mnie

Znaleziono 7 wyników

  1. Sourcemod oferuje nam bardzo wygodny system językowy, dzięki któremu jeden plugin może posiadać nieskończoną ilość wersji językowych, a wyświetlany język w danej chwili jest zależny od ustawienia serwera. Jednakże to, czy plugin będzie z tego korzystał, zależny tylko i wyłącznie od programisty. Ale niezależnie, czy umiesz programować czy nie, tłumaczenie pluginów jest proste i przyjemne. Jeśli plugin posiada wyżej wymienioną opcję to w paczce w której go pobrałeś powinien znajdować się folder /translations/ a w nim plik językowy z rozszerzeniem .phrases.txt. Jego zawartość jak w każdym pluginie wygląda podobnie: "Phrases" { "Bideo_Game_Dunky" { "en" "i will see you grandpa" "jp" "おじいちゃんに会いましょう" /* tutaj dalsze linie z kodem */ } "Im_Done_With_League_Of_Legends" { "en" "not even close baby" "jp" "赤ちゃんも閉じない" /* tutaj dalsze linie z kodem */ } } Nad pierwszymi klamrami znajduje się słowo kluczowe "Phrases", które mówi pluginowi "hej, to ja jestem ten plik od tłumaczeń". W dalszych blokach możemy zauważyć takie bloki { } jak "Bideo_Game_Dunky" oraz "Im_Done_With_League_Of_Legends". Dla tłumacza, czyli w naszym wypadku nie mają one absolutnie żadnego znaczenia i nie możemy ich zmieniać, ponieważ są one zastosowane jako zmienne w pluginie i ich zmiana tylko zepsułaby tłumaczenie. Dalej, między klamrami { } są już właściwe tłumaczenia, każdy język znajduje się w osobnej linii a format tłumaczenia frazy jest następujący: "kod_kraju" "tłumaczenie" Kod naszego kraju to oczywiście "pl". A więc wystarczy że dopiszemy następujące linie do pliku w ten sposób: "Phrases" { "Bideo_Game_Dunky" { "en" "i will see you grandpa" "jp" "おじいちゃんに会いましょう" "pl" "zobaczę cię dziadku" /* tutaj dalsze linie z kodem */ } "Im_Done_With_League_Of_Legends" { "en" "not even close baby" "jp" "赤ちゃんも閉じない" "pl" "nawet nie blisko dziecko" /* tutaj dalsze linie z kodem */ } } Zapisujemy plik, wgrywamy na miejsce jego oryginału, ustawiamy język serwera na polski i mamy przetłumaczony plugin! Aby zobaczyć jak wygląda normalny plik ze spolszczeniem możecie zajrzec do pluginu runda nożowa. Miłego tłumaczenia!
  2. DataPacki Przeważnie podczas tworzenia funkcji definiujemy pożądaną liczbę parametrów, którą chcemy użyć. Przykład: int Mnozenie(int a, int b) { return a * b; } /////////////// void JakasFunkcja() { PrintToChatAll("5x6 = %d", Mnozenie(5,6)); } Aby zrobić tutaj użytek z funkcji Mnozenie() konieczne było przekazanie dwóch argumentów. Niestety, w niektórych sytuacjach nie mamy komfortu przekazywania dowolnej ilości argumentów - jesteśmy ograniczeni tylko do...jednego! Dotyczy to chociażby asynchronicznych zapytać SQL lub timerów. Przykład: void JakasFunkcja(int client) { int a = 5; int b = 6; CreateTimer(10.0, PomnozCosPozniej, /*TUTAJ TYLKO JEDEN ARGUMENT!*/); } public Action PomnozCosPozniej(Handle timer, any data) { /// co tu zrobic ?! } Gdybyśmy chcieli wykonać operację mnożenia w tym przypadku, niezbędne jest przekazanie dwóch zmiennych. Co robić w takiej sytuacji? Z pomocą przychodzą nam DataPacki! Umożliwiają nam one "upakowanie" dowolnej liczby zmiennych o dowolnym typie do jednego ciągu danych. Cały proces zaczyna się od stworzenia uchwytu do DataPacka: DataPack data = new DataPack(); jesteśmy gotowi do załadowania go danymi. Do tego celu wykorzystuje się kolejno WriteCell, WriteFloat, WriteFunction, WriteString W naszym przykładzie poza dwiema zmiennymi przekażemy dodatkowo komunikat do wyświetlenia, aby pokazać jak posługiwać się ciągami znaków. Nasza funkcja będzie teraz wyglądać tak: void JakasFunkcja(int client) { char helloString[128]; Format(helloString, sizeof(helloString), "Siemanko %N!", client); DataPack data = new DataPack(); data.WriteCell(5); data.WriteString(helloString); data.WriteCell(6); CreateTimer(10.0, PomnozCosPozniej, data); } Celowo umieściłem stringa pomiędzy dwiema liczbami, aby pokazać, że odczyt jest odrobinę bardziej skomplikowany niż zapis. Po pierwsze, każdy DataPack posiada swój specjalny wskaźnik, który pokazuje w którym miejscu ma być przeprowadzany odczyt/zapis. Przeanalizujmy proces zapisu informacji w naszej funkcji JakasFunkcja(int client). Po stworzeniu DataPacka mamy pustą strukturę i wskaźnik znajdujący się na początku: [|] Znak '|' to właśnie nasz wskaźnik Po wywołaniu żądania umieszczenia piątki, proces zaczął się w miejscu gdzie stał nasz wskaźnik - czyli na samym początku: [5|] Po dodaniu inta, wskaźnik przesunął się (troche jak wskaźnik podczas pisania na klawiaturze) Kolejny w kolejce jest string: [5string|] I ostatnia już wartość - 6: [5string6|] W tym miejscu mamy już przygotowanego do wysyłki DataPacka. Zauważmy jednak, że nasz wskaźnik nie zmienił swojej pozycji - jest cały czas ustawiony na końcu struktury. Czy domyślacie się, jak wyglądałby odczyt tych danych? Bez przesunięcia wskaźnika na początek pliku ten proces jest niemożliwy... Na szczęście, istnieje operacja, która może tego dokonać. Nazywa się ona Reset: // zauważmy, że drugi argument funkcji zmienił się na nasz DataPack :) public Action PomnozCosPozniej(Handle timer, DataPack data) { data.Reset(); } Od tego momentu struktura DataPacka wygląda tak: [|5string6] Oznacza to, że jesteśmy gotowi do odczytu ? Istnieje jednak jeszcze jeden haczyk. Wspomniałem wcześniej, że dane w DataPacku przyjmują forme ciągu danych. Oznacza to, że SourceMod widzi je jako swoisty strumień. Właśnie do nas należy zadanie zapanowania nad tym haosem. Do odczytywania danych stosujemy kolejno ReadCell, ReadFloat, ReadFunction i ReadString. W naszym DataPacku nie możemy zacząć wyciągania od np. stringa - wszystko musimy wykonywać w takiej samej kolejności, w jakiej wkładaliśmy dane! Na pierwszy ogień pójdzie więc 5, następnie komunikat, a na samym końcu - 6. A więc pierwszą wartością jest int. Korzystamy z ReadCell: // zauważmy, że drugi argument funkcji zmienił się na nasz DataPack :) public Action PomnozCosPozniej(Handle timer, DataPack data) { data.Reset(); int a = data.ReadCell(); } // Aktualny stan DataPacka: [5|string6] Przyszła pora na stringa. W naszym przypadku nasz łańcuch składa się z 128 znaków i dokładnie tyle zapisaliśmy w DataPacku! Pamiętajmy więc o przygotowaniu odpowiednio dużej tablicy: char helloString[256]; // wielkość tablicy do której zapisujemy może się różnić - ważne, abyśmy pamiętali ile znaków zapisaliśmy WCZEŚNIEJ! data.ReadString(helloString, sizeof(helloString)); I na sam koniec ostatnia liczba: int b = data.ReadCell(); Gotowe! Wszystkie dane zostały pobrane prawidłowo. Nasz efekt końcowy: void JakasFunkcja(int client) { char helloString[128]; Format(helloString, sizeof(helloString), "Siemanko %N!", client); DataPack data = new DataPack(); data.WriteCell(5); data.WriteString(helloString); data.WriteCell(6); CreateTimer(10.0, PomnozCosPozniej, data); } public Action PomnozCosPozniej(Handle timer, DataPack data) { char helloString[256]; data.Reset(); int a = data.ReadCell(); data.ReadString(helloString, sizeof(helloString)); int b = data.ReadCell(); PrintToChatAll("Komunikat: %s", helloString); PrintToChatAll("%d x %d = %d", a, b, a*b); } // stan DataPacka: [5string6|] Oczywiście w razie pojawienia się pytań bądź wątpliwości zapraszam do dyskusji pod spodem ? PS: suplementem do tego materiału jest napisany przez @Vasto_Lorde poradnik o timerach:
  3. Jeżeli spędziłeś już trochę czasu na programowaniu w pawnie, na pewno natknąłeś się na funkcje, które pobierają dane z innych pluginów, np. cod_get_user_class, które zwróci ID postaci, na której aktualnie gramy. Warto zauważyć, że owe informacje wychodzą bezpośrednio z silnika cod moda - następuje więc tutaj bezpośrednia wymiana informacji pomiędzy pluginami. W tym poradniku zajmiemy się po krótce tym zagadnieniem. 1. Funkcje natywne Działanie "natywów" sprowadza się do zdalnego wywołania funkcji i ewentualnego zwrócenia rezultatu: 0 - Nasz plugin posiada funkcję natywną szarego pluginu I - zlecamy wykonanie funkcji II - szary plugin wykonuje polecenie III - szary plugin zwraca otrzymany rezultat IV - rezultat trafia do naszego pluginu Teraz pokażę jak takiego natywa z szarego pluginu stworzyć. Przede wszystkim natywy dodajemy w takiej funkcji: public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max) Daje nam to pewność, że załadują się one w odpowiedniej chwili. Warto wspomnieć, że natywy możemy wczytywać pojedynczo, bądź jako biblioteka - tworzyć nasze własne pliki #include. W tym poradniku skupię się tylko na tej drugiej metodzie. Musimy więc najpierw zarejestrować naszą bibliotekę: RegPluginLibrary("NaszaNazwa"); następnie dodajemy natywy w następujący sposób: CreateNative("nazwa_natywu", Funkcja_Ktora_Ma_Sie_Wywolac); na samym końcu zwracamy: return APLRes_Success; Teraz pora na Funkcja_Ktora_Ma_Sie_Wywolac. Natywy pozwalają nam również na bezproblemowe przekazywanie argumentów, jednak funkcja, o której przed chwilą wspomniałem, nie może po prostu tych argumentów przyjmować w nawiasach () - działa to w trochę inny sposób: public int Funkcja_Ktora_Ma_Sie_Wykonac(Handle plugin, int numParams) { int liczba = GetNativeCell(1); return liczba * 2; } po pierwsze, argumenty muszą być takie, jak wyżej - Handle plugin (uchwyt to NASZEGO pluginu), a także numParams (ilość parametrów, które przekazaliśmy) Pobieranie argumentów odbywa się poprzez specjalne funkcje GetNative___ (polecam po prostu wpisać sobie "getnative" a także "setnative" w dokumentacji). Każdorazowo pierwszy argument GetNative__ to numer argumentu z naszego wywołania (wyjątkowo numerujemy tutaj od 1!) W przykładzie powyżej założyłem, że przekazany zostanie jedynie int, który zostanie przemnożony przez 2 i zwrócony. Przykładowe zastosowanie: Pamiętajmy jednak, że ciągle nie stworzyliśmy biblioteki GoCode! Będzie ona wyglądać mniej więcej tak: Tak przygotowany plik możemy zapisać jako GoCode.inc i wrzucić do naszego folderu include w kompilatorze. Koniec ? 2. Forwardy (coming soon)
  4. Czasami zdarza się, że nie mamy pojęcia z jakimi ilościami elementów będziemy mieli do czynienia (np. ile klas w CodMod'ie musimy załadować do pamięci). I owszem, możemy wówczas sprowadzić to do prostego ograniczenia, np.: #define MAX_ILOSC_KLAS 100 int ClassID[MAX_ILOSC_KLAS]; //... Niestety, rodzi to dwa zasadnicze problemy: 1. Jeśli aktualnie nie wykorzystujemy całej zaalokowanej pamięci, marnujemy bez potrzeby miejsce 2. Zawsze jesteśmy ograniczeni przez limit, który sami na siebie nałożyliśmy Rozwiązaniem naszego problemu są tablice dynamiczne Mimo, że działają one nieco wolniej od zwykłych tablic, pozwalają na całkowicie dynamiczną alokację pamięci - oznacza to, że w trakcie trwania programu możemy dowolnie manipulować ilością zarezerwowanej pamięci - zarówno alokując, jak i zwalniając zasoby Korzystanie z nich jest naprawdę proste i wymaga jedynie odrobinę wprawy Na samym początku tworzymy uchwyt (najczęściej globalnie): ArrayList MojUchwyt Do poprawnego działania konieczne jest jeszcze jego zainicjowanie - bez tego niemożliwe jest jego działanie, a serwer będzie sypał errorami. Najczęściej piszemy w OnPluginStart: MojUchwyt = CreateArray(block_size, init_size) Teraz omówię parametry block_size oraz init_size, posługując się strukturą tablicy dynamicznej. Możemy sobie ją przyrównać do takiej oto szafeczki: block_size mówi nam ile komórek zarezerwowanych jest dla jednego poziomu. Wartość raz tam podana pozostanie niezmienna dla danej tablicy (chyba, że użyjemy ResizeArray). Na naszym przykładzie dla każdego poziomu zarezerwowane zostaną 3 komórki. init_size określa ile poziomów zostanie zaalokowane na samym początku. Jego wartość ulega zmianie na przestrzeni trwania programu. Nasza szafeczka ma na start zaalokowane 12 poziomów, jednak w praktyce tego parametru najczęścieć nie stosuje się wogóle - wówczas na starcie nie ma żadnego poziomu i zostaną one dodane dopiero później. Jaką wartość podawać w block_size? Jeżeli wiemy, że w danej tablicy umieszczone zostaną jakieś ciągi znaków, które de facto wymagają więcej niż jednej komórki, wówczas podajemy tam wartość, która pozwoli na zapewnienie odpowiedniej ilości miejsca. Przykładowa inicjalizacja tablicy na imiona graczy może wyglądać na przykład tak: MojUchwyt = CreateArray(MAX_NAME_LENGTH+1) Z wykorzystaniem methodmap: MojUchwyt = new ArrayList(MAX_NAME_LENGTH+1); Polecenie zainicjuje pustą tablicę, która będzie posiadała na każdym poziomie ilość komórek równą wartość stałej MAX_NAME_LENGTH + 1 Niedobrze jest ograniczać się do konkretnych ilości danych (np. klas), jednak już dobrą praktyką jest ograniczanie dopuszczalnej ilości znaków, jak w przypadku limitu w nazwie gracza, zdefiniowanego przez podaną wyżej stałą. Gdyby zdarzyło się, że przekroczymy te ograniczenie, nadmiarowe znaki zostają usuwane... Skoro znamy już podstawy, możemy zapoznać się z procedurą zarządzania tablicą dynamiczną: 1/4. Dodawanie Każdorazowe dodanie elementu powoduje utworzenie się na samej górze nowego poziomu (patrz: przykład z półką) z zaalokowanymi komórkami w ilości block_size. Możemy tam wrzucić pojedyńczą komórkę, ciąg znaków, bądź tablicę. Przykład: 2/4. Modyfikowanie Każdy poziom możemy dowolnie edytować. Musimy jedynie wiedzieć na jakiej wysokości się on znajduje. Ważne jest, że poziomy numerujemy od zera! (dół - zero). Przykład: 3/4. Pobieranie Jeżeli pobieramy komórkę ( GetArrayCell ), zostanie ona zwrócona przez return. W przypadku stringa i tablicy, wartości zostaną skopiowane do podanych przez nas lokalizacji. Przykład: 4/4. Usuwanie Nic prostszego - wystarczy index poziomu. Po usunięciu wszystkie wyższe poziomy spadają o jeden w dół (troche jak ściąganie obrusu z zastawionego stołu ?) 5/4. Reszta SourceMod posiada dużo więcej funkcji obsługujących tablicy dynamiczne. Zapraszam tutaj: https://go-code.pl/dokumentacja-sourcemod/adt_array/ Przykład Poniższy kod dodaje do tablic dynamicznych nazwę i UserId każdego gracza, który wejdzie na serwer. Ponadto, komenda !show pozwala na wyświetlenie zawartości owych tablic, a po wybraniu gracza z menu plugin wypisuje jego status - czy gracz jest połączony, czy też nie (lub wykonał reconnect): To by było na tyle ? Jeżeli pojawią się jakieś pytania z radością na nie odpowiem, a w razie potrzeby zaktualizuję poradnik Pozdrawiam!
  5. Ten temat zawiera spis wszystkich artykułów zamieszczonych w tym dziale 1. Ogólne Komendy admina SourceMod Spis broni CS:GO 2. Optymalizacja Jak pozbyć się lagów w CS:GO 3. Wygląd Jak włączyć panoramę w CS:GO? Jak WYŁĄCZYĆ panoramę w CS:GO? (-legacyscaleformui) Nóż w lewej ręce
  6. Ten temat zawiera spis wszystkich artykułów zamieszczonych w tym dziale 1. Wszystkie linki Opis flag SourceMod Wydanie sourcemoda w wersji 1.9 Jak wgrać ręcznie sourcemoda i metamoda
  7. Ten temat zawiera spis wszystkich artykułów zamieszczonych w tym dziale 1. Poradniki na temat wiedzy ogólnej Składnia nowa czy stara? (#pragma newdecls required) Jak skompilować plugin sourcemod? (linux) Spis errorlogów i co one oznaczają? Najczęściej popełniane błędy Co to backdoor? 2. Poradniki o strukturach danych Co to bity i jak ich używać? Jak działają tablice dynamiczne? Struktura enum i jak tego używać Co to datapack? 3. Poradniki dotyczące funkcji w dokumentacji Sourcemod Timer's - CreateTimer / TriggerTimer / KillTimer Pobieranie wielkości magazynka Wszystko co dotyczy Menu Kompendium wiedzy na temat Natywów i Forwardów 4. Inne Jak sprawdzić czy gracz używa panoramy? Dodatki do Danger Zone (weapon_axe weapon_hammer weapon_spanner) Jak działają wektory w przestrzeni 3D? Podświetlenie składni Sourcemod w Notepad++ Jak utworzyć licencję na plugin?

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

×
×
  • Dodaj nową pozycję...