GameMode oparty o MySQL - Część 1     Wstęp
Na forum znajduje się wiele problemów dotyczących podstaw tworzenia map. Od czego zacząć, jak użyć systemu MySQL, jak prawidłowo skonfigurować połączenie z bazą danych. Postanowiłem pomóc wielu z tych osób i stworzyć poradnik dotyczący napisania prostego GameMode wykorzystującego system zapisu do bazy danych.
 
Cały poradnik będzie w kilku częściach, a po zakończeniu zostanie utworzona wersja OffLine, wersja HTML do pobrania. W poradniku nie będę opisywał szczegółowo funkcji, czy jej parametrów, tylko jej działanie, szczegóły znajdują się w polskiej wersji WIKI jak i angielskiej.     Wprowadzenie
Wykorzystamy system zapisu danych w bazie dlatego pierwszym etapem, będzie zdobycie takiej bazy. Mamy na to kilka sposobów. Utworzenie lokalnej bazy danych, wykorzystując XAMPP . Użycie bazy danych hostingu WWW (tutaj należy pamiętać, aby odblokowane było połączenie z zewnątrz) . Wykorzystanie bazy danych ze stron oferujących serwery SA-Mp (oczywiście jeśli zezwalają na zewnętrzne połączanie). Ostatnia opcja, użycie darmowej bazy danych, które oferuje Pawno.PL swoim użytkownikom. Nie ważne z jakiej opcji skorzystaliśmy, musimy posiadać kilka podstawowych danych, takich jak: Host bazy danych, Nazwa użytkownika, Hasło bazy Nazwa bazy danych Dodatkowo, bardzo przydatne może być narzędzie PHPMyAdmin. W mapie wykorzystamy kilka ciekawych pluginów, które pomogą nam w tworzeniu Naszego GameMode. MySQL by StrickenKid foreach by Y_Less sscanf by Y_Less XML by Zeex Przydatny również będzie nieco lepszy program do pisania, ponieważ standardowe Pawno, jest nieco kłopotliwe, jeśli chodzi o używanie kilku plików w jednym momencie. Ja posługiwał się będę Notepad++ Wraz z kilkoma dodatkami, które opisane są w tym temacie.   Dodatkowo cała mapa zostanie podzielona na moduły, przedstawiam jak będzie to wyglądać na samym początku:     Katalog source zawierał będzie wszystkie elementy dotyczące naszego GameMode. Includes zawiera wszystkie zewnętrzne include, jakie dołączymy do projektu, pozwoli nam to po dłuższym okresie czasu skompilować Nasz gamemode, bez potrzeby dopasowywania odpowiednich include. core.inc - plik zawierający wszystkie tablice, funkcje dotyczące walidacji serwera podczas uruchomienia, czy wyłączenia. header.inc - jedyny plik, który będziemy dołączać do Naszego głównego pliku z mapą, w nim znajdziemy ładowanie pozostałych include. mysql.inc - wszystkie funkcje dotyczące połączenia z bazą danych, rozłączenia jak i przydatne funkcje dla operacji na bazie. settings.inc - wszystko co dotyczy konfiguracji Naszego GameMode, czyli ładowanie danych z config, czy z pliku konfiguracyjnego. tutorial.pwn - główny plik mapy, w którym nie znajdziemy wiele config.xml - plik konfiguracji połączenia, autora itd.   Podstawy Utwórzmy teraz podstawowy szkielet naszej mapy, plik tutorial.pwn #include <a_samp> #include "source/header.inc" main() {} public OnGameModeInit() { return true; } public OnGameModeExit() { return true; } Znamy już wygląd naszego gamemode, więc następnym krokiem będzie edycja header.inc , jak pamiętamy w tym pliku znajdzie się ładowanie wszystkich include, więc tym się zajmijmy. #include "source/includes/foreach.inc" #include "source/includes/mysql.inc" #include "source/includes/sscanf2.inc" #include "source/includes/xml.inc" #include "source/core.inc" #include "source/settings.inc" #include "source/mysql.inc" W tym momencie, możemy pierwszy raz skompilować Naszą mapę z pozytywnym wynikiem Jednak, po co nam gamemode, który nie wykonuje żadnej akcji? Czas to zmienić.     Tworzenie config.xml Zawartość pliku konfiguracyjnego jest bardzo prosta, główna sekcja to settings, która dzieli się na kilka innych. <?xml version="1.0"?> <settings> <gm> <name>tutMap</name> <!-- Nazwa mapy --> <author>KoPcIu</author> <!-- Autor mapy --> <version>1.0 Beta</version> <!-- Wersja mapy --> </gm> <server> <name>Serwer tutMap!</name> <!-- Nazwa serwera w HostName --> <mode>tutMap 1.0 Beta</mode> <!-- Nazwa w kolumnie Mode --> <map>Las Venturas</map> <!-- Nazwa w kolumnie Map --> </server> <db> <host>46.4.177.235</host> <!-- Host bazy danych --> <user>KoPcIu</user> <!-- Nazwa użytkownika bazy --> <pass>NIE_PODAM_</pass> <!-- Hasło użytkownika bazy --> <name>KoPcIu</name> <!-- Nazwa bazy danych --> <prefix>Tut_</prefix> <!-- Prefix bazy danych --> </db> </settings> Ładowanie config.xml Jako pierwsze zdefiniujmy lokalizacje pliku config, u mnie będzie on się znajdować bezpośrednio w katalogu scriptfiles co oznacza, że ścieżka to po prostu nazwa pliku z rozszerzeniem.   Dodamy do naszego pliku core.inc definicje tej ścieżki: #define PATH_CONFIG "config.xml" Dodatkowo w tym samym pliku utwórzmy tablicę do przechowywania danych pobranych z pliku config. enum e_Setting { gmName[64], // Nazwa mapy, gmAuthor[32],         // Autor mapy, gmVersion[16],         // Wersja mapy servName[64],         // Nazwa serwera w HostName servMode[32],         // Nazwa w kolumnie Mode servMap[32],         // Nazwa w kolumnie Map dbHost[32], // Host bazy danych dbUser[32], // Nazwa użytkownika bazy dbPass[32], // Hasło użytkownika bazy dbName[32], // Nazwa bazy danych dbPrefix[8] // Prefix bazy danych } new Settings[e_Setting]; W pliku settings.inc utwórzmy funkcje ładującą podstawową konfigurację stock Settings_Load(file_name[]) { new XML:xml_file = xml_open(file_name); // Ładujemy plik konfiguracji, ścieżke pobieramy jako argument if(xml_file) { // Sprawdzamy czy plik został otwary /* Funkcje poniżej ładują poszczególne dane z pliku konfiguracyjnego, po więcej szczegółów zapraszam na stronę pluginu XML Dodatkowo, pamiętajmy o podaniu jako ostatni argument funkcji xml_get_string wielkości danej tablicy */ xml_get_string(xml_file, "settings/gm/name", Settings[gmName], sizeof(Settings[gmName])); xml_get_string(xml_file, "settings/gm/author", Settings[gmAuthor], sizeof(Settings[gmAuthor])); xml_get_string(xml_file, "settings/gm/version", Settings[gmVersion], sizeof(Settings[gmVersion])); xml_get_string(xml_file, "settings/server/name", Settings[servName], sizeof(Settings[servName])); xml_get_string(xml_file, "settings/server/mode", Settings[servMode], sizeof(Settings[servMode])); xml_get_string(xml_file, "settings/server/map", Settings[servMap], sizeof(Settings[servMap])); xml_get_string(xml_file, "settings/db/host", Settings[dbHost], sizeof(Settings[dbHost])); xml_get_string(xml_file, "settings/db/user", Settings[dbUser], sizeof(Settings[dbUser])); xml_get_string(xml_file, "settings/db/pass", Settings[dbPass], sizeof(Settings[dbPass])); xml_get_string(xml_file, "settings/db/name", Settings[dbName], sizeof(Settings[dbName])); xml_get_string(xml_file, "settings/db/prefix", Settings[dbPrefix], sizeof(Settings[dbPrefix])); xml_close(xml_file); // Zamykamy plik return true; // Zwracamy poprawne załadowanie pliku konfiguracyjnego } return false; // Zwracamy problem przy ładowaniu pliku } Następnie musimy wykonać kod wczytywania danych. Oczywiście najlepsze rozwiązanie to start gamemode, czyli otwieramy plik tutorial.pwn . Wkleimy tam kod zawierający nie tylko ładowanie, ale i odwołanie się do funkcji wyłączającej serwer gdy tylko konfiguracja nie zostanie wczytana.   W OnGameModeInit new check = 0; check = Settings_Load(PATH_CONFIG); // Oczywiście pamiętamy o podaniu ścieżki if(!check) return Core_Stop(REASON_CONFIGFILE); Jak widać kod wykonuje się przy problemie z odczytaniem pliku konfiguracyjnego i odwołuje się do funkcji Core_Stop z parametrem REASON_CONFIGFILE .     Funkcja Core_Stop Jak pamiętami funkcjami serwera zajmuje się plik core.inc dlatego funkcja wyłączająca serwer znajduje się w nim.   Na początku zdefiniujmy error REASON_CONFIGFILE . Przyjmijmy, że będzie to error o ID 1 . Oczywiście z czasem pojawi się więcej tego typu błędów, więc nie ma sensu tworzyć kilku funkcji do wyłączania serwera, a jedną i identyfikować błąd. #define REASON_CONFIGFILE 1 Sam kod funkcji: stock Core_Stop(reason) { switch(reason) { case REASON_CONFIGFILE: print("[ERROR] Problemy przy zaladowaniu pliku config. Plik: "PATH_CONFIG" ."); } SendRconCommand("exit"); return true; } Zakończenie Myślę że w tym momencie zakończymy pierwszą część poradnika o własnym gamemode. Mamy podstawy mapy jak i ładowanie pliku config. Już w następnej wersji dołączymy do tego połączenie z bazą danych jak i po raz pierwszy wejdziemy na swój serwer   W załączniku znajduje się projekt, który do tej pory utworzyliśmy    Pozdrawiam i czekam na opinie!   Druga część poradnika. Tutorial_#1.zip