Skocz do zawartości

Co nowego?

0

#1 Co to jest MVC?

Witajcie, dzisiaj opowiem Wam co nieco na temat architektury MVC, co to jest to MVC? Jest to architektura Model-View-Controller tzw. wzorzec projektowy, stosowany przy tworzeniu nowoczesnych aplikacji webowych.    Główną koncepcją MVC jest wymuszenie podziału aplikacji na 3 niezależne warstwy reprezentujące kolejno:              1. (Model) Model danych - logika aplikacji, czyli to czego nie widzi uzytkownik,              2. (View) Interfejs - widok, czyli to co przekazywane jest do użytkownika po przetworzeniu przez kontroler/model,              3. (Controller) Logika działania - przyjmuje i obsługuje dane od użytkownika, przekazuje je do modelu lub wyświetla widok.   Podział architektury systemu na warstwy jest potrzebny, aby utrzymać porządek. Dzięki temu, że każda logiczna część jest od siebie oddzielona, zmiana w jednym miejscu, nie powoduje konieczności wykonywania lawinowej ilości zmian w innych miejscach systemu.   Co to jest Model? Otóż nic innego jak jednostka (plik) odpowiedzialna za dane. Jest jedynie odpowiedzialna za ich przetwarzanie i dostarczanie. Zazwyczaj model jak już wspomniałem jest odpowiedzialny za komunikację z bazą danych.   Co to jest View? Po prostu szablon, plik który ma za zadanie odpowiednio przedstawić dane dostarczone z modelu, jednakże nie zawsze widok opiera się na danych z modelu, gdyż taką logikę może wykonać również kontroler. Reprezentacja tego co widzi użytkownik.   Co to jest Controller? Jest to jednostka odpowiedzialna za komunikację z modelem (danymi) i widokami (prezentacja/szablony). Ale pamiętaj - nic innego jak osobny, wyspecjalizowany do tego plik w którym dzieje się cała ta logika.     Jakie są wady i zalety korzystania z architektury MVC?   Zalety: Niezależność modelu - model nie jest zależny od widoku i aplikacja może posiadać wiele niezależnych widoków dla tego samego modelu, Duża elastyczność widoków - ze względu na na oddzielenie widoku od modelu, widoki mogą być modyfikowane częściej i niższym kosztem. Jest to szczególnie istotne, ponieważ w życiu systemu interfejs i warstwa prezentacji zmieniają się częściej niż logika biznesowa aplikacji. Brak chaotycznego kodu - cały kod mamy pogrupowany na 3 warstwy, dzięki czemu panuje porządek, a także umożliwia to łatwy rozwój aplikacji.   Wady: Złożoność - architektura MVC nanosi dodatkową warstwę abstrakcji i nowe sposoby interakcji, co prowadzi do wzrostu jej złożoności. Zależność widoków od modeli i dodatkowa logika widoków czyni je szczególnie skomplikowane w testowaniu, Mała elastyczność modelu - modyfikacja modelu może w konsekwencji wymagać modyfikacji wielu widoków operujących na tym modelu (ponieważ model jest niezależny od widoku, ale widok zawsze opiera się na modelu)     *Zobrazowanie architektury MVC*       Artykuł został stworzony na potrzeby forum GO-CODE.pl Zakaz kopiowania na inne fora. via vavatech.pl & devloger.pl

1

[Poradnik] Ręczna aktualizacja SM.

Witajcie! Wiele osób korzysta z hostingowych instalatorów/aktualizatorów SourceModa. Te samo grono osób często nie jest świadome, że ma przestarzałą wersję SM. W tym poradniku, krótko i szybko przedstawię jak zaktualizować SourceModa manualnie.   1. Sprawdzamy czy mamy najnowszą wersję SM. W tym celu wchodzimy w konsolę serwera i wpisujemy "sm version"   2. Wchodzimy na oficjalna stronę SM i sprawdzamy jaki jest ostatni build. >>KILK<<   3. Jeżeli jest nowszy build niż nasz aktualny to go pobieramy. (Wersja na linuxa *środkowa*) 4. Logujemy się na nasze FTP, przechodzimy do addons/sourcemod/ i przerzucamy 2 zaznaczone foldery. 5. Teraz pozostało nam już tylko zrestartować serwer i cieszyć się najnowszą wersją SourceModa.    

0

[Poradnik] Instalacja paczki na serwerze

Witam w dzisiejszym poradniku pokaże wam jak zainstalować paczkę na serwerze CSGO. 1. Wybranie/Znalezienie bądź kupienie paczki.   W moim przypadku wykorzystam paczkę RETAKE która jest dostępna na forum Klik. Na początek pobieramy naszą paczkę po otwarciu pliku .rar zobaczymy takie foldery (oczywiście w przypadku paczki której używam w poradniku) Następnie logujemy się do FTP naszego serwera.   2. Wrzucanie paczki na serwer    Na początek wrzucimy sobie zawartość folderu addons na nasz serwer. Aby wrzucić te pliki na serwer idziemy scieżką csgo/addons/sourcemod Następnie przeciągamy pliki z naszej paczki na nasz serwer  GOTOWE NASZE PLUGINY SĄ NA NASZYM SERWERZE   WRZUCANIE PLIKÓW KONFIGURACYJNYCH    Idziemy scieżką csgo/cfg/sourcemod  otwieramy folder z naszej paczki i przeciągamy pliki z paczki na serwer.   Jeśli już to zrobiliśmy to zresetujemy nasz serwer i sprawdźmy czy wszystko działa.   NIE ZEZWALAM NA KOPIOWANIE PORADNIKA NA INNE NIZ GO-CODE

1

[Poradnik] Instalacja SourceBans

WSTĘP   Cześć dziś postanowiłem,że strzelę szybki poradnik jak zainstalować sourcebans'a. A więc tak będziemy potrzebować Hostingu WWW [w moim przypadku będzie to hosting do serwera na pukawce], Bazę Danych i dostęp do internetu.   POBIERANIE/WRZUCANIE PLIKÓW   1. Pobierz pliki instalacyjne sourcebans'a z tej strony KLIK wybierz tę opcję .   Teraz zaloguj się do FTP swojego hostingu i usuń plik index.html, następnie otwórz plik który pobrałeś i wybierz  wszytko z tego folderu wrzuć na swój hosting.   USTAWIENIE ATRYBUTÓW   Jeśli wszystkie pliki z folderu web znajdują się na twoim hosting ustaw atrybut 777 następującym folderom /themes_c /images/maps /images/games /demos   PROCES INSTALACJI   Gdy już jesteśmy pewnie ,że wszystkie pliki są już na hosting i mają ustawiony atrybut 777 przechodzimy na adres naszej strony w moim przypadku poradniksourcebans.gameclan.pl po/ dopisujemy install  ma to wyglądać tak poradniksourcebans.gameclan.pl/install.    Jak wszystko zrobiliśmy poprawnie powinniśmy ujrzeć okno instalacji SourceBans.   Zaznaczamy i klikamy Ok.   BAZA DANYCH   Następnie widzimy takie okno uzupełnij je swoimi danymi  Server Hostname  localhost - adres bazy danych Server Port                   3306 - to zostawiamy  Username      Username poradnik_gocode - nazwa użytkownika bazy danych Password  fajnehaslojm- hasło użytkownika bazy danych Database   fajnabazadanych- nazwa bazy danych Table Prefix                  sb -  Prefix w bazie danych, zostaw to tak jak jest   Po kliknięciu Ok. ujrzymy następną kartę ,jeśli wszystko jest na zielono klikamy Ok ,jeśli jest na czerwono klikamy recheck.   TWORZENIE KONTA ADMINISTRATORA SOURCEBANS   Jeśli zrobiliśmy wszystko poprawnie powinniśmy ujrzeć takie okno    Admin Username --> Login Administratora Admin Password --> Hasło Administratora Confirm Password --> Wpisz hasło ponownie Steam ID --> Steam ID Administratora Email --> Mail Administratora    DATABASE   Jeśli instalacja przebiegła poprawnie zobaczymy okienko z danymi które warto zapisać ponieważ przyda się nam to gdy będziemy podpinać serwer pod SourceBans. Kiedy już sobie zapisaliśmy te dane przechodzimy do FTP i usuwamy z niego folder install.   INNE KROKI   Gdy już pozbyliśmy się folderu install wpisujemy adres naszej strony w moim przypadku poradniksourcebans.gameclan.pl i dopisujemy/updater Po zakończeniu usuwamy folder updater NO I GOTWE MOŻEMY SIĘ CIESZYĆ NASZYM SOURCEBASNEM   INSTALACJA SOURCEBANS NA SERWERZE CSGO   Nasz SourceBans jest gotowy teraz wystarczy wrzucić pliki z folderu na nasz serwer.   Jeśli wrzuciliśmy wszystkie pliki z folderu game na serwer CS przechodzimy do csgo/addons/sourcemod/configs i szukamy pliku sourcebans.cfg   Krok 1.    Zamieniamy www.yourwebsite.net/ na adres naszego bansa Krok 2. Przechodzimy do csgo/addons/sourcemod/configs i szukamy pliku databases.cfg    i wklejamy do niego to co wcześniej zapisaliśmy powinno to wyglądać tak :   DODAWANIE SERWERA NA STRONIE BANSA    Aby dodać serwer do sourcebansa aby wyświetlał się w tabeli w nim logujemy się na swoje konto administratora w SB Przechodzimy do zakładki  Następnie klikamy  Pojawi się nam takie okno  Wpisujemy w nim IP serwera,Port Serwera,Hasło Rcon i wybieramy mod naszego serwera.   To tyle już możecie się cieszyć swoim własnym SOURCEBANEM Jeśli poradnik ci się spodobał daj +     Nie pozwalam na kopiowanie poradnika na inne fora niż GO-CODE.Pl

0

[Python] Skrypt pobierający ścieżki do modeli

Korzystając ze strony CSGO Models i pobierając z niej skiny zauważyłem, że składają się one z wielu pomniejszych plików, których pobieranie muszę wymuszać graczom przez AddFilesToDownloadsTable. Z racji, iż jest to strasznie upierdliwe zadanie (szukanie wszystkich ścieżek), można na serwer wgrać plugin, który będzie pobierał całą zawartość folderu. Ja jednak stwierdziłem, że napiszę prosty skrypcik, który wszystkie ścieżki będzie rekurencyjnie pobierał i wypluwał ładny wynik, który po prostu kopiuj/wklejam do OnMapStart   Jest to skrypt pythonowy, który działa najzwyczajniej w świecie tak, że rekurencyjnie przeszukuje wszystkie foldery w lokalizacji w której obecnie się znajduje i wypisuje ich pełną ścieżkę, dodając potrzebne przedrostki 'AddFiles.......'   Step by step: 1. Utwórz sobie na pulpicie nowy folder o dowolnej nazwie i wrzuć do niego skrypt oraz foldery 'models' i 'materials' ze strony CSGO Models, lub dowolnej innej, której modele mają mnóstwo pomniejszych plików 2. Wejdź do folderu i odpal skrypt 3. Skopiuj wynik 4. elo   Przykładowo, przeprowadzając tę procedurę na tym modelu otrzymałem następujący wydruk z konsoli:     run.py

6

[Poradnik] KeyValues, czyli struktura o organizacji drzewkowej

Co to są KeyValues? KeyValues to prosta struktura bazująca na organizacji "drzewkowej" która zawiera zagnieżdżone w sobie sekcje które to zawierają klucze i wartości. Dla wzrokowców i objaśnienia sprawy, najprostsza struktura KeyValues wygląda w ten sposób: "sekcja" { "klucz" "wartosc" } Jak napisałem na samym początku, sekcje mogą być w sobie zagnieżdżone, czyli do sekcji możemy dopisać kolejną sekcję, do niej kolejną, itd. Przykład: "sekcja1" { "sekcja2" { "klucz" "wartosc" } } Przy budowaniu struktury KeyValues warto zaznaczyć, że nazwy sekcji i kluczy nie mogą się powtarzać w obrębie danej sekcji.  Trochę zagmatwane, ale mówiąc prościej tworząc sekcję "admin" nie możemy później wewnątrz tej sekcji stworzyć np. 2 razy sekcję "Kowalski", czy 2 razy klucza "Kowalski", nie powinniśmy też tworzyć klucza "Kowalski" a potem sekcji "Kowalski" czy też odwrotnie - myślę, że zrozumiałe. Dodatkowo do KeyValues możemy swobodnie dodawać komentarze. Komentarze pozwalają Nam dodawać tekst, który zostanie pominięty przy wczytywaniu KeyValues poprzez plugin. Dodajemy je poprzez użycie dwóch slashy (//) oraz wypisaniu za nimi jakiegoś tekstu. Komentarz jest jednolinijkowy, czyli od kolejnego wiersza będziemy mogli dalej budować naszą strukturę.   "sekcja" { "klucz1" "wartosc1" //To jest komentarz. Tekst ten zostanie pominiety przy wczytywaniu KeyValues przez plugin SourceMod "klucz2" "wartosc2" } Z KeyValues mogłeś(aś) się już spotkać wcześniej, np. przy konfigurowaniu połączenia z bazą danych w pliku addons/sourcemod/configs/databases.cfg. Dla przypomnienia taki plik wygląda mniej więcej tak: "Databases" { "driver_default" "mysql" // When specifying "host", you may use an IP address, a hostname, or a socket file path "default" { "driver" "mysql" "host" "localhost" "database" "db" "user" "root" "pass" "" //"timeout" "0" //"port" "0" } "storage-local" { "driver" "sqlite" "database" "sourcemod-local" } } Jak pracować z KeyValues w pluginie SourceMod? Na początku przyjmijmy pewne założenia. Mianowicie napiszemy sobie plugin, który będzie tworzył główne menu serwera. Plugin ten będzie wywoływał komendę w konsoli gracza po naciśnięciu konkretnej opcji w menu. Nasz plik KeyValues będzie w addons/sourcemod/configs, nazwiemy go main_server_menu.ini. Jego struktura będzie wyglądała w ten sposób (wiem, można by to zrobić lepiej): "MainServerMenu" { "sm_vip" { "name" "Sprawdź opis VIP'a" "command" "sm_vip" } "res" { "name" "Menu RoundSoundów" "command" "res" } "rs" { "name" "Resetuj statystyki" "command" "rs" } } Na początku zadeklarujmy zmienną globalną która będzie uchwytem dla naszego menu głównego oraz od razu dodajmy RegConsoleCmd do OnPluginStart: Menu g_mainServerMenu; public void OnPluginStart() { RegConsoleCmd("sm_menu", cmd_MainServerMenu); } public Action cmd_MainServerMenu(int client, int args) { g_mainServerMenu.Display(client, MENU_TIME_FOREVER); return Plugin_Handled; } Następnie zbudujmy funkcję, która będzie odpowiedzialna za stworzenie menu na podstawie naszych KeyValues. Niech to będzie funkcja BuildMenu void BuildMenu() { // kodzik... } Na samym jej początku stworzymy nasze menu: //tworzymy menu g_mainServerMenu = new Menu(MainServerMenu_Handler); g_mainServerMenu.SetTitle("Główne menu serwera", MENU_ACTIONS_ALL); Następnie stworzymy uchwyt do KeyValues oraz wczytamy jego strukturę z naszego pliku konfiguracyjnego: //budujemy sciezke do pliku addons/sourcemod/configs/main_server_menu.ini char path[256]; BuildPath(Path_SM, path, sizeof(path), "configs/main_server_menu.ini"); //tworzymy KeyValues oraz importujemy strukture z pliku KeyValues keyValues = new KeyValues("MainServerMenu"); keyValues.ImportFromFile(path);   Warto powiedzieć. że KeyValues wcale nie muszą wykorzystywać żadnego pliku. Można operować chociażby na strukturze podanej jako ciąg znaków wczytanej z zewnętrznego źródła (np. zawartość zewnętrznej strony WWW). Jednak najczęściej oczywiście struktura jest wczytywana z pliku, tak jak w przykładzie wyżej. Co jeszcze jest istotne, to przy deklaracji new KeyValues jako paramtetr podajemy nazwę pierwszej sekcji w naszym pliku, znaną również jako sekcja główna czy węzeł główny (więcej niżej). Mamy już wczytany pliczek do uchwytu, teraz trzeba by się odpowiednio po tej całej strukturze poruszać, a potem wczytać odpowiednie wartości do menu. Przy poruszaniu się po pliku należy wiedzieć, że: Sekcja to też w pewnym sensie klucz, o czym warto pamiętać przy poruszaniu się po strukturze. Sekcja to taka oddzielna nazwa dla kluczy, które posiadają w sobie jeszcze inne klucze. Poruszając się po pliku mamy do czynienia z pozycją. Pozycja określa nam na którym poziomie podsekcji jesteśmy (inaczej poziom zagnieżdżenia) oraz na którym kluczu w danej sekcji jesteśmy. Mówiąc o pozycji mamy zatem do czynienia z dwoma wartościami. Jak to wygląda praktyce? A no tak: "MainServerMenu" //sekcja główna (węzeł główny) { "sm_vip" //pierwszy klucz w pierwszym poziomie zagnieżdżenia { "name" "Sprawdź opis VIP'a" //pierwszy klucz w drugim poziomie zagnieżdżenia "command" "sm_vip" //drugi klucz w drugim poziomie zagnieżdżenia } "res" //drugi klucz w pierwszym poziomie zagnieżdżenia { "name" "Menu RoundSoundów" //pierwszy klucz w drugim poziomie zagnieżdżenia "command" "res" //drugi klucz w drugim poziomie zagnieżdżenia } "rs" //trzeci klucz w pierwszym poziomie zagnieżdżenia { "name" "Resetuj statystyki" //pierwszy klucz w drugim poziomie zagnieżdżenia "command" "rs" //drugi klucz w drugim poziomie zagnieżdżenia } } Podstawowe funkcje do poruszania się po KeyValues: GotoFirstSubKey(); // Przesuwa pozycje do pierwszej podsekcji (poziom zagniezdzenia nizej) // Zwraca false w przypadku nieznalezienia podsekcji GotoNextKey(); // Przesuwa pozycje do kolejnego klucza/sekcji w danej sekcji // Zwraca false w przypadku nieznalezienia kolejnego klucza GoBack(); // Przesuwa pozycje o poziom zagniezdzenia wyzej. // Zwraca false, kiedy nie da sie juz wyzej przesunac (np. jestesmy w wezle glownym) Rewind(); // Ustawia pozycje wezla glownego. Podobny cel mozna osiagnac poprzez // uzywanie GoBack dopoki nie zwroci false, jednak ta funkcja jest optymalniejsza. JumpToKey(const char[] key, bool create=false); // Przenosi nas do klucza w danej sekcji o podanej nazwie w parametrze "key" // W przypadku create=true oraz jezeli dany klucz nie zostanie znaleziony, funkcja ten klucz stworzy. // Zwraca true w przypadku znalezienia klucza, false jezeli klucza nie znaleziono Pominąłem parametry które mogły by być trudne do zrozumienia a mają one swoje domyślne wartości. Dla ciekawskich wszystkie i w pełni opisane funkcje można znaleźć w dokumentacji.   Okejj, więc co dalej po otwarciu pliku? Musimy przejść o jedno zagnieżdżenie niżej, a więc kolejny skrawek kodu będzie wyglądać tak: //nie znaleziono zadnej podsekcji? Plik jest nieprawidłowy, koniec :/ if (!keyValues.GotoFirstSubKey()) { PrintToServer("*** I had a problem while building a menu :/ Check main_server_menu.ini"); delete keyValues; return; } Po prawidłowym przejściu niżej, Nasza pozycja wygląda teraz tak: "MainServerMenu" //przed GotoFirstSubKey bylismy tutaj { "sm_vip" //po GotoFirstSubKey jestesmy tutaj { "name" "Sprawdź opis VIP'a" "command" "sm_vip" } "sm_res" { "name" "Menu RoundSoundów" "command" "sm_res" } "sm_rs" { "name" "Resetuj statystyki" "command" "sm_rs" } } Co teraz? Musimy wczytać dane z danej sekcji, dodać opcję do menu i przejść do kolejnego klucza (w Naszym wypadku kolejnej sekcji). Skorzystamy z pętli do while: char command[64], itemName[64]; do { //wczytujemy dane z danej sekcji keyValues.GetString("command", command, sizeof(command)); keyValues.GetString("name", itemName, sizeof(itemName)); //dodajemy opcje do menu g_mainServerMenu.AddItem(command, itemName); } while (keyValues.GotoNextKey()); //przechodzimy do kolejnej sekcji, dopoki te sekcje nie skoncza sie I to by było na tyle z wczytywanie, nasze menu jest już zbudowane ^^ Nie zapomnijmy o zamknięciu uchwytu no iii dajmy odpowiednie info serwerowi: //info dla serwera oraz oproznianie zmiennej kv delete keyValues; PrintToServer("*** Main server menu has been built"); Funkcję BuildMenu możemy zamknąć, a pod nią dodajmy funkcję Handler do naszego menu. Będziemy tam w momencie wybrania opcji wpisywać do konsoli gracza daną komendę zapisaną pod "info" tej właśnie opcji: //obsluga menu public int MainServerMenu_Handler(Menu menu, MenuAction action, int param1, int param2) { switch (action) { case MenuAction_Select: { int client = param1; //wczytujemy komende z pola "info" z danej opcji w menu oraz wywolujemy komende w konsoli char info[64]; menu.GetItem(param2, info, sizeof(info)); ClientCommand(client, info); } } } W OnPluginStart należy jeszcze wywołać funkcję od budowania menu: public void OnPluginStart() { RegConsoleCmd("sm_menu", cmd_MainServerMenu); BuildMenu(); } Nasz plugin jest gotowy 😄 Kod *.sp oraz plik *.ini podaję w załącznikach ->   main_server_menu.ini server_menu.sp Co jeszcze warto wiedzieć? Do wczytywania wartości z klucza mamy kilka funkcji, które odpowiadają danemu typowi wartości. Możemy np. wartość wczytać od razu w type int, słuzy do tego funkcja GetNum która zwraca wartość klucza. Jest wiele innych ciekawych funkcji jak GetFloat, GetColor, itd. - więcej w dokumentacji Strukturę można zmieniać, a zmiany potem zapisać poprzez funkcję ExportToFile. Są odpowiednie funkcje do usuwania kluczy, ustawiania ich wartości, itd. Jak wyżej - więcej info na ten temat można znaleźć w dokumentacji KeyValues nie powinny być zbyt wielkie. Niedopuszczalne jest skorzystanie z KeyValues w celu zapisywania ilości zabójstw graczy. Przy tak dużej ilości danych zdecydowanie lepszym rozwiązaniem jest baza danych. Wyjątkiem może być plik w którym tych graczy jest mniej, np. plik z graczami którzy dostają specjalny bonus. Plików KeyValues staraj się nie otwierać zbyt często, najlepiej zrobić to maks. raz na mapę bądź też poprzez komendę do której dostęp ma tylko opiekun serwera.   Zadanie domowe! Usuń klucz "command" i zamiast wczytywania go wykorzystaj funkcję GetSectionName dzięki której wczytasz nazwę sekcji, a co za tym idzie od teraz komendę będziesz podawać właśnie w nazwie sekcji. Rozwiązaniem możesz się pochwalić w tym temacie 😄 

1

[Poradnik] Cookies

W tym poradniku omówię tzw. ciasteczka, które zapisują nam np. Wybrany TAG w tabeli. Dla przykładu napiszemy plugin w którym będziemy ustawiać swój TAG w tabeli. Na początku musimy dodać odpowiednie include'y oraz zdefiniować nasz Handle(uchwyt) do którego będziemy się odwoływać.  *wymagane* #include <cstrike> #include <clientprefs> Handle g_hClientTag; Teraz musimy "zarejestrować" nasze ciasteczko w OnPluginStart używając funkcji RegClientCookie, który jako argumenty przyjmuje: - Nazwa naszego ciasteczka. - Opis naszego ciasteczka. - Dostęp naszego ciasteczka. CookieAccess_Public Jest ciasteczkiem publicznym i każdy gracz może je zmienić za pomocą komeny sm_cookies <nazwa ciasteczka> < wartość> CookieAccess_Protected Jest ciasteczkiem możliwym tylko do odczytania dla gracza. Gracz nie może go zmienić przy użyciu komendy. CookieAccess_Private Jest ciasteczkiem ukrytym. Gracz nie może go ani odczytać ani zmienić (nasz plugin oczywiście może :D).  g_hClientTAG = RegClientCookie("sm_selected_tag", "Zapisuje wybrany przez nas tag", CookieAccess_Protected);   W momencie kiedy zreloadujemy plugin, a nie mamy dodanego ponownego wczytania ciasteczek gracz, który wybrał dany TAG musi wybrać go ponownie. Dlatego zrobimy opcję gdzie w OnPluginStart załadujemy ciasteczka ponownie graczom, którzy są w grze oraz nie są botami for (int i = 1; i <= MaxClients; i++) {         if (IsClientInGame(i) && !IsFakeClient(i))         OnClientCookiesCached(i);     } *wymagane*   *nie wymagane* Ostatnią rzeczą, którą zrobimy w OnPluginStart to SetCookieMenuItem, ustawienie tego dodaje nam pod komendę !settings . Przyjmuje on 3 argumenty: - Callback do naszego handlera(uchwytu) - Info - Tekst pokazany w menu.  SetCookieMenuItem(TagChangeHandler, 0, "[TAG] Wybierz swój TAG w tabeli"); Po ustawieniu nazwy naszego callbacka oraz nazwy menu możemy robić callbacka Tego typu callback przyjmuje 5 argumentów: - Client ( slot gracza ) - CookieMenuAction czyli po prostu akcja jaka zostanie podjęta. CookieMenuAction_SelectOption po wybraniu opcji CookieMenuAction_DisplayOption po wyświetleniu opcji - Info - Buffer - maxlength public void TagChangeHandler(int client, CookieMenuAction action, any info, const char[] buffer, int maxlength) {     if (action == CookieMenuAction_SelectOption)ShowTagMenu(client); } Od teraz po wpisaniu !settings pojawi nam się również opcja zmienienia ciastekcza i w moim przypadku TAG'u. *nie wymagane*   *wymagane* Teraz musimy zrobić tak aby przy każdym połączeniu gracza ustawiać mu ciasteczko, które miał wybrane wcześniej czyli musimy użyć forwarda OnClientCookiesCached, przyjmuje on tylko 1 argument czyli slot gracza ( int client ). To teraz musimy pobrać ciasteczko, które miał ustawione gracz wcześniej. Użyjemy do tego funkcji GetClientCookie przyjmuje ona 4 argumenty: - Client ( slot gracza ) - Nasz handle(uchwyt) do którego "zapisywana" jest o tym informacja. - buffer do którego zapiszemy to co nam zwróci funkcja - maxlength ( maksymalna wielkość naszego buffer'a ) Po pobraniu ciasteczka ustawiamy graczowi na tą wartość. public void OnClientCookiesCached(int client) {     char value[16];     GetClientCookie(client, g_hClientTag, value, sizeof(value));     g_iClientTag[client] = StringToInt(value); } Mamy już nasze ciasteczko wiemy jak je "zarejestrować", pobrać i ustawić teraz czas na zapisywanie. Aby zapisać nasze ciasteczko użyjemy funkcji SetClientCookie, przyjmuje ona 3 argumenty: - Client ( slot gracza ) - Nasz handle(uchwyt) - Wartość Wartość ta nie jest INT'em tylko stringiem, dlatego zanim przekażemy INT'a musimy zamienić go na string używając funkcji IntToString, która przyjmuje 3 argument: - Liczbę, którą chcemy dać do stringa - Buffer w którym będzie się znajdować nasza liczba - Wielkość naszego buffer'u  char value[16]; IntToString(2,value,sizeof(value)); W moim przypadku nie będzie to nie potrzebne, ponieważ pobieram wartość z menu gdzie jest już jako string. SetClientCookie(client, g_hClientTag, info); *wymagane* Plugin, który powstał przy poradniku:    

0

Dlaczego mam usunąć niepotrzebny kod z mojego programu?

Usuwanie niepotrzebnego, zbędnego kodu z naszego projektu jest istotnym elementem dobrej opieki nad nim. Ale są ludzie, którzy powiedzą "Hej! Panie! Ja tu się namęczyłem z pisaniem tego kodu i NIE MA OPCJI żebym go teraz kasował nawet jeśli już go nie używam". Ten artykuł ma wszystkich upartych przekonać, dlaczego martwy kod trzeba zakopywać głęboko klawiszem backspace.       Nad projektem może pracować więcej niż jedna osoba. A jeśli produkujesz oprogramowanie open-source, to kod będzie przeglądać o wiele więcej ludzi niż Twój zespół programistyczny. Jak dobrze wiemy kod jest przede wszystkim komunikacją między programistami, a to, że działa i spełnia swoje zadania jest sprawą drugorzędną. Obca osoba czytając martwy kod musi poświęcić dwa razy więcej czasu niż w przypadku kodu który jest w użytku ponieważ a) Musi zrozumieć jak działa b) Musi zrozumieć dlaczego ten kod nie jest używany i czy na pewno nie jest nigdzie używany i może go usunąć;   Za każdym razem przeglądając kod po raz dziesiąty czy setny, ktoś spędzi dłuuugie sekundy myśląc sobie "ah, to tu jest martwy kod, moje oczy muszą go ominąć". Taki kod to po prostu hałas dla oczu. Niepotrzebny żwir na naszym asfalcie. Dlaczego na naszym płaskim, idealnym asfalcie jest wysypany żwir? To na pewno nie jest sposób w jaki chcemy produkować a tym bardziej przeglądać kod;   Martwy kod jest martwy. Nie jest rozwijany. Został pozostawiony sam sobie kilka, kilkadziesiąt, kilkaset iteracji temu. Programista może użyć go bez wiedzy, że jest martwy. "Jest tam, więc czemu miałby być źle napisany?" Otóż nierozwijany kod zostawiony sam sobie może już nie spełniać obecnych standardów projektu, lub nawet jego autor mógł go nie dokończyć. Wtedy przy jego użyciu mogą wystąpić konsekwencje - bugi   Jeśli używasz jakiegokolwiek systemu kontroli wersji kodu i to na Ciebie spada odpowiedzialność za utrzymanie i konserwację kodu (zachowując jednocześnie martwy kod w projekcie), to masz więcej linii kodu do przejrzenia, więcej odpowiedzialności na Twoich barkach oraz większe pole do popisu dla błędów w zarządzaniu kodem   Konsekwencją chomikowania martwego kodu jest to, że ten kod się kumuluje. Normalnie, zachowuje się tylko najpotrzebniejsze rzeczy, tylko rzeczy używane, tylko rzeczy które spełniają jakąś rolę w naszym programie. Dlatego opiekujemy się nim, optymalizujemy go, refaktorujemy. W przeciwieństwie do martwego kodu. Ten, kumuluje się i zbiera, rosnąc diametralnie, a swoim rozmiarem zniechęca maksymalnie kogokolwiek, żeby zrobił co trzeba - przejrzał jeszcze raz kod, zrozumiał go i wyrzucił do kosza   Nie martw się, że kod który napisałeś zostanie skasowany, bo nie jest już potrzebny. W dzisiejszych czasach praktycznie zawsze używa się systemu kontroli wersji (np. GIT). Twój kod, który kiedyś w swojej świetności działał idealnie, jest zakopany gdzieś w commitach. Nie ma powodu żeby za nim płakać. Z czasem, szansa na ponowne użycie nieużywanego kodu maleje. Nie musisz go trzymać w każdej iteracji. Odpuść, zrób przysługę sobie w przyszłości i skasuj go. Jeśli był naprawdę ważny i kiedyś zdarzy się sytuacja, gdzie będziesz potrzebował tego kodu, odkopiesz go z czeluści GITa.   Tutaj widzę dobrą okazję na przedstawienie jednej z reguły tworzenia oprogramowania w trybie extreme programming: YAGNI (ang. You aren't gonna need it). Mówi nam ona o tym, że mamy pisać tylko i wyłącznie funkcjonalności których potrzebujemy teraz. Nie mamy przewidywać jakich funkcjonalności będziemy potrzebować. Skupiamy się na chwili obecnej. Można to też interpretować w drugą stronę - jeśli czegoś już nie potrzebujesz to skasuj to natychmiast   Bibliografia https://stackoverflow.com/questions/15699995/why-unused-code-should-be-deleted https://en.wikipedia.org/wiki/You_aren't_gonna_need_it https://www.infoq.com/news/2017/02/dead-code/

4

[Poradnik] jak zrobić aby w menu admina pokazywały się tylko mapy które ma się w maplist.txt

Siemka postanowiłem, że napiszę mały "poradniczek" jak zrobić aby w menu admina pokazywały się tylko mapy które są podane w maplist.txt 1. Wchodzimy w csgo/addons/sourcemod/configs/ i szukamy pliku maplists.cfg 2. znajdujemy  30 linijke i w "file" zmieniamy jedynie końcówkę 3. ja zmieniam w taki sposób np. w pliku csgo.txt mam dodaną mapę de_mirage i wygląda to tak

1

[Poradnik] Korzystanie z "HUD" i "hint" tekstu - ShowHudText / SetHudTextParams

Na prośbę jednego z użytkowników poniżej umieszczam rozpiskę i przykłady zastosowania tekstu w hint i hud.     HudText   Tekst, który jest wyświetlany bezpośrednio na ekranie gracza. Tekst, który nie jest ani w menu, ani w żadnym z okienek dialogowych. To jest właśnie tzw HudText.  Istnieją co najmniej dwa sposoby wyświetlania takiego tekstu. Skupimy się na funkcji ShowHudText, która zawsze idzie w parze z funkcją SetHudTextParams, lub SetHudTextParamsEx. Różnica między tymi dwiema polega na tym, że w pierwszej z nich określamy jeden zestaw kolorów, a w drugiej dwa.  Nie będę się w to zagłębiał, bo przyznam szczerze że z drugiej funkcji nie korzystałem bodajże nigdy, więc nie czuję się w tym obszarze ekspertem.   W kodzie wygląda to tak, że najpierw należy określić parametry tekstu, a potem można go wyświetlić. Używając wcześniej wspomnianej funkcji SetHudTextParams możemy określić położenie na osiach X i Y, czas wyświetlania tekstu, kolor wraz z alfą i efekt (fade in/out z czasem zanikania).   Śmiało mogę powiedzieć, że odpowiednie ustawienie tekstu nierzadko wymaga nakładu pracy. Mamy do czynienia z różnymi rozdzielczościami ekranów graczy, i tylko środek pozostanie środkiem.   Dla przykładu - mnie interesuje tekst, który docelowo ma zostać wyświetlony w górnym lewym rogu ekranu. Nie ma mieć żadnego efektu, ma być zielony i w lekko przezroczysty. SetHudTextParams(0.01, 0.20, 0.2, 0, 255, 0, 140); ShowHudText(client, -1, "ŁADUNKI : %i", ilosc_min_gracza[client]); Po ustaleniu parametrów, funkcją ShowHudText wyświetlamy tekst klientowi, na kanale -1 = kanale poprzednio używanym, bądź najprawopodobniej randomowym przy pierwszym użyciu. Trzecim argumentem jest właśnie tekst - może to być wcześniej Formatowany string, może to być tekst w cudzysłowie. Argumenty wypisujemy po przecinku w odpowiedniej kolejności, dokładnie jak w przypadku np funkcji PrintToChat.   Przykład zastosowania kodu w timerze, którzy wyświetla tekst zawierający zabójstwa gracza w różnych kolorach, zależnie od ich ilości. Przy śmierci gracza resetujemy te wartości.       Hint text   Tekst, który jest wyświetlany w okienku z informacją np przy rozbrajaniu bomby. W tej sytuacji sprawa wygląda nieco inaczej, bo mimo używania tylko jednej funkcji możemy kolorować bądź zmieniać wielkość liter używając HTML.   Przykład użycia znajdziemy m.in w codmodzie.  Wygląda groźnie? To złudzenie. Pierwszym argumentem jest index klienta, któremu wyświetlamy tekst. Jeśli chcemy wyświetlić go wszystkim, użyjemy funkcji PrintHintTextToAll. W tym wypadku nie umieszczamy żadnego ID. Treść zostanie wyświetlona wszystkim. Wracając - po indexie klienta umieszczamy stringa - albo formatowanego tak jak w przypadku HudTextu, albo w cudzysłowie. Możemy również używać \n, czyli skoku linijkę w dół.  Co tu dużo mówić, zwyczajny tekst - z tym że formatowanie polega na używaniu HTML, a argumenty wciskane są tak jak w przypadku PrintToChat, i implementowane po cudzysłowie w odpowiedniej kolejności. Nic trudnego, spróbujcie sami 🙂     Co do HudText'u - bardzo pomocnym może okazać się plugin naszego kolegi z forum, @Master.  Dzięki temu pluginowi w dość prosty sposób jesteśmy w stanie określić położenie i kolor HUD tekstu, który chcemy wyświetlić. Bardzo polecam to rozwiązanie.   W razie pytań piszcie, bo trzasnąłem to dość na szybko i jestem delikatnie zmęczony, ale chciałem dotrzymać słowa i chyba mi się udało 😛

0

Zmiana mapy po czasie

Witam, poszukuje pluginu który by po np. 5 minutach po wyjściu ostatniego gracza z serwera zamieniał by mapę na de_mirage, mam nadzieje że coś znajdziecie 🙂

2

Sprzedam Mirage CS:GO

Witajcie, mam na sprzedaż serwer Only Mirage, staż serwera ponad rok (dla bardziej zainteresowanych mogę podać datę założenia). Serwer kręci się sam bez jakiejkolwiek reklamy. Ostatnio są lekkie spadki graczy z powodu mniejszej aktywności adminów, braku forum jak i mniejszego zainteresowania z mojej strony.  https://www.gametracker.com/server_info/137.74.7.15:30003 Hosting LiveServer, rabat 13 lub 14% na przedłużenie. Cena opłaty serwera to jakieś 46zł.  Jeśli chodzi o zarobki to nie posiadam udokumentowanych. Vipy raz są kupowane na dłuższe okresy czasu typu pół roku, czasem na miesiąc, a czasem wcale w skali miesiąca, różnie to bywa - wiadomo. Serwerowi nic nie dolega, żadnych błędów czy też lagów. Zachęcam do sprawdzenia. Cena jaka mnie interesuje to 450zł, pozdrawiam i proszę o kontakt tylko zdecydowane osoby. Nie mam czasu żeby tracić czas. Serwer zostanie przekazany kupujacemu wraz ze zmianą maila, hasła dopiero po zaksięgowaniu wpłaty na moim koncie bankowym lub PayPal, nie ma innej możliwości.  //Zapomniałem dopisać, że serwer jest opłacony na 31dni i do tego dochodzi ponad 20wPLN na hostingu

0

yAWPrestrict - Blokada zakupu AWP do 3 rundy

O pluginie : Plugin blokuje możliwość zakupu AWP do 3 rundy   Instalacja : Plik .smx : addons/sourcemod/plugins Aby plugin skompilować plugin potrzebny jest .inc multicolors     Download : yAWPRestrict.smxyAWPRestrict.sp   @Mesharsky Dzięki za pomoc   

1

szukam pluginu ENT_Hosties 4.2.2fix - [2020. 12. 02]

Witam, szukam pluginu jak w temacie: ENT_Hosties 4.2.2fix - [2020. 12. 02] na necie download nie działa, może ktoś to ma?    

3

Szukam pluginu lvl faceit.

Witam szukam pluginu lvl faceit. Sprawdzałem jeden plugin z internetu ale on nie do końca działa. Tamten plugin był podpięty do rankme i podczas resetowania rankme resetował się lvl faceit. Chciałbym aby ten plugin działał na zasadzie pluginu np. yRanks. Chciałbym aby po wpisaniu na czacie !lvl pojawiło się menu tak jak jest w yRanks oraz było wszystko jak tam w pluginie ale pod lvl faceit a nie pod rangi MM. Jeżeli jest potrzeba to zapłacę. 

5

Szukam pluginu z iconą vip

Cześc, szukam pluginu który dodaje vipowi ikonke która lata nad nim   Coś w tym stylu tylko ze fajne jak by sie to kręciło:    

1

Bug nie kończy rundy jak wywali gracza za afk

Witam,   Mam problem, że jak ktoś jest afk i plugin go wywali z serwa czy na spect to jeśli jest ostatnią osobą z drużyny to serwer się buguje i nie kończy tej rundy, jak to rozwiązać?

0

Brak funkcji zbanuj gracza w menu admina

Siema, po ostatniej aktualizacji serwery cs sie zepsuły i naprawiło je wgranie najnowszej wersji meta i sm, ale zniknęła funkcja zbanuj gracza z menu admina ktoś wie jak to naprawić? sm_ban działa, ale mi chodzi o to że w menu ta opcja zniknęła

2

round_end Wyłączenie informacji o wygranej drużynie

Cześć, Zrobiłem plugin dla ziomka, który wyświetla overlay, która drużyna wygrała. Jeden problem jest taki, że nie wiem jak wyłączyć informacje o tym, która drużyna wygrała. Nie zwracajcie uwagi na nazewnictwo xd. Jest w ogóle coś takiego możliwe? 

0

[JavaScript] System TSR - machine learning

Siemka, Sorki za post w dziale HTML, aczkolwiek nie dodano jeszcze sekcji JS. Przechodząc do tematu, chciałbym zaprojektować system rozpoznawania znaków drogowych. O ile z detektorem nie powinno być kłopotów, to gorzej z machine learning. W jaki sposób mógłbym zidentyfikować wczytany znak? Warto użyć tensorflow'a, czy jest jakieś łatwiejsze rozwiązanie?   Z góry dzięki za odpowiedź 🙂

2
2

Sprzedam Mirage CS:GO

Sprzedane dla @swierzak

11

pVip - Rozbudowany system VIP na serwery CS:GO

To jak i kilka innych rzeczy zostało już poprawione. Zapraszam wszystkich do pobrania aktualizacji https://github.com/Pawelx21/pVip--Advanced-Vip-System

3

Szukam pluginu lvl faceit.

Temat można zamknąć. Skorzystam  raczej z zakupu pRanks.

0

Zmiana mapy po czasie

Witam, poszukuje pluginu który by po np. 5 minutach po wyjściu ostatniego gracza z serwera zamieniał by mapę na de_mirage, mam nadzieje że coś znajdziecie 🙂

2

Sprzedam Mirage CS:GO

Witajcie, mam na sprzedaż serwer Only Mirage, staż serwera ponad rok (dla bardziej zainteresowanych mogę podać datę założenia). Serwer kręci się sam bez jakiejkolwiek reklamy. Ostatnio są lekkie spadki graczy z powodu mniejszej aktywności adminów, braku forum jak i mniejszego zainteresowania z mojej strony.  https://www.gametracker.com/server_info/137.74.7.15:30003 Hosting LiveServer, rabat 13 lub 14% na przedłużenie. Cena opłaty serwera to jakieś 46zł.  Jeśli chodzi o zarobki to nie posiadam udokumentowanych. Vipy raz są kupowane na dłuższe okresy czasu typu pół roku, czasem na miesiąc, a czasem wcale w skali miesiąca, różnie to bywa - wiadomo. Serwerowi nic nie dolega, żadnych błędów czy też lagów. Zachęcam do sprawdzenia. Cena jaka mnie interesuje to 450zł, pozdrawiam i proszę o kontakt tylko zdecydowane osoby. Nie mam czasu żeby tracić czas. Serwer zostanie przekazany kupujacemu wraz ze zmianą maila, hasła dopiero po zaksięgowaniu wpłaty na moim koncie bankowym lub PayPal, nie ma innej możliwości.  //Zapomniałem dopisać, że serwer jest opłacony na 31dni i do tego dochodzi ponad 20wPLN na hostingu

38

[CSGO] System Rang + 3 Moduły

Wczoraj wszystko śmigało dziś po update cs'a mam takie logi:   L 05/07/2021 - 07:59:28: [SM] Exception reported: Error on start. Reason: [1040]: Too many connections L 05/07/2021 - 07:59:28: [SM] Blaming: h2k_rangi.smx L 05/07/2021 - 07:59:28: [SM] Call stack trace: L 05/07/2021 - 07:59:28: [SM]   [0] SetFailState L 05/07/2021 - 07:59:28: [SM]   [1] Line 450, D:\Wszystko pouk�adane\WA�NE\sm compiler - stable\h2k_rangi.sp::DbConnect L 05/07/2021 - 07:59:28: [SM]   [2] Line 285, D:\Wszystko pouk�adane\WA�NE\sm compiler - stable\h2k_rangi.sp::OnPluginStart L 05/07/2021 - 07:59:28: [SM] Unable to load plugin "h2k_rangi.smx": Error detected in plugin startup (see error logs) L 05/07/2021 - 07:59:28: [SM] Unable to load plugin "h2k_rangi-Hazard.smx": Could not find required plugin "h2k_rangi"   Ktoś coś? Pluginy są na serwerze i wczoraj wszystko hulało

10

[CS:GO] Deathrun

nie mam dwóch menadzerow i nie wiem czy ktoś ma taki sam problem ale dziś naprzykład jak byłem na serwerze jeszcze nie było tego błędu moze to był tylko chwilowy przez jakis plugin który wyrzuciłem juz

10

[CS:GO] Deathrun

Hmm próbowałem powtórzyć ten błąd i ani razu mi się go nie udało wykonać. Może masz 2 menadżery wrzucone czy coś? Czy ktoś inny również ma takowy problem? 

  1. Go-Code.pl - Ogólne

    1. O serwisie 45 odpowiedzi

      Napisz swoją sugestię bądź przywitaj się z innymi użytkownikami forum. Zapraszamy do napisania propozycji bądź dyskutuj z nami na temat działania serwisu.

  2. SourcePawn

    1. Baza Wiedzy 279 odpowiedzi

      Ciekawe artykuły oraz poradniki związanie z programowaniem w SourcePawn'ie, dodatkowo dzielimy się w tym dziale naszymi gotowymi rozwiązaniami, znalazłeś/stworzyłeś ciekawą funkcję lub snippet? Podziel się nią z nami.

    2. Baza Danych 1,5tys. odpowiedzi

      Wszystkie możliwe do ściągnięcia przydatne rzeczy, plugin'y, silniki, kody źródłowe, extensions. Zajrzyj i ściągnij zebrane rzeczy związane z SourcePawn'em, albo podziel się własnym gotowym rozwiązaniem.

    3. Sekcja Dyskusji 3,9tys. odpowiedzi

      Dywagacje na temat programowania, rozwiązań algorytmicznych lub proste tematy z problemami jak coś językiem SourcePawn. Jeśli chcesz uzyskać pomoc w edycji kodu plugin'u albo wsparcie z jakimkolwiek aspektem wtyczek czy scripting'u, nasi mentorzy od plugin'ów postarają się odpowiedzieć na wszystkie pytania.

  3. PHP

    1. Baza Wiedzy 3 odpowiedzi

      Przydatne linki oraz artykuły związane z programowaniem w języki PHP. Tutoriale na temat obiektowego i funkcjonalnego pisania kodu, jak również zwykłe snippet'y.

    2. Baza Danych

      Linki do ściągnięcia popularnych frameworków razem z krótkimi opisami instalacji. Są tu zamieszczone również inne silniki napisane na PHP.

      • Brak odpowiedzi do wyświetlenia
    3. Sekcja Dyskusji

      Tutaj można otworzyć dyskusje na każdy temat związany z PHP, od problemów algorytmicznych i składniowych po zagwozdki związane z architekturą i tym, jak używa się danych narzędzi typu debbuger'y czy template engine'y.

      • Brak odpowiedzi do wyświetlenia
  4. Python

    1. Baza Wiedzy

      Tutaj będzie ładny opis stworzony przez Vasto Lorde

      • Brak odpowiedzi do wyświetlenia
    2. Baza Danych

      Siema Vasto, wiesz co robić.

      • Brak odpowiedzi do wyświetlenia
      • Brak odpowiedzi do wyświetlenia
  5. C++

    1. Baza Wiedzy

      Tutaj będzie ładny opis stworzony przez Vasto Lorde

      • Brak odpowiedzi do wyświetlenia
    2. Baza Danych

      Siema Vasto, wiesz co robić.

      • Brak odpowiedzi do wyświetlenia
      • Brak odpowiedzi do wyświetlenia
  6. C#

    1. Baza Wiedzy

      Tutaj będzie ładny opis stworzony przez Vasto Lorde

      • Brak odpowiedzi do wyświetlenia
    2. Baza Danych

      Siema Vasto, wiesz co robić.

      • Brak odpowiedzi do wyświetlenia
      • Brak odpowiedzi do wyświetlenia
  7. Front End

  8. Poza tematyką forum, OFF-TOPIC

    1. Życie społeczności 507 odpowiedzi

      Życie naszej kochanej społeczności. Chciałbyś pogadać o czymś z innymi? Może trafiłeś na ciekawy artykuł w internecie o którym chciałbyś się podzielić z innymi?
      Szukasz kogoś do swojej ekipy na forum lub ludzi do pogrania w jakieś gry? A może chciałbyś podzielić się swoją własną twórczością w internecie? np. Kanałem na YT, bądź piosenką? 
      Jeżeli tak to ten dział jest przeznaczony właśnie dla ciebie.

    2. Biznes 911 odpowiedzi

      Świat bizensu! Sprzedawaj/Kupuj na naszej giełdzie na forum, jeżeli miałeś styczność handlową pomiędzy jakimś użytkownikiem na forum wystaw mu opinię by podnieść jego zaufanie, jeżeli zostałeś oszukany warto ostrzec innych użytkowników przed transakcjami z ową osobą.

  9. Archiwum

    1. Przestarzałe tematy 647 odpowiedzi

      Tematy które są NAPRAWDĘ stare

    2. Kosz 132 odpowiedzi

      Tematy które łamią regulamin

    3. Wszystkie tematy ze starego gc 2,4tys. odpowiedzi

      Tutaj znajdują się wszystkie tematy które były przed re-brandingiem forum go-code w ogólne forum programistyczne.

×
×
  • Dodaj nową pozycję...