/** ****************************************************************************** @file /net/comm.h @brief Spolecny predek k tridam klienta a serveru @author Vta @version 1.0 ******************************************************************************/ #ifndef _COMM_ #define _COMM_ #include #include #include "common/Msg.h" #include "common/mm.h" #include "common/exc.h" #include "common/Interface.h" #include "common/priority.h" #include "common/xml/package.h" #include "net/queue.h" #include "net/mysocket.h" /// Prostor sitove vrstvy namespace net { #define DEFAULT_PORT 5558 ///< Port na kterem se komunikuje se serverem #define DEFAULT_UDP_PORT 5587 ///< Port na kterem se oznamuje LAN hra #define COMPRESS_ACTIVE 0 ///< Zda se bude provadet komprese #define COMPRESS_LEVEL 9 ///< Uroven kompresse (0 nejmensi, 9 nejvetsi) #define MAX_SIZE_OF_MESSAGE 32768 ///< Nejvetsi zprava poslatelna pres sit najednou #define NICKNAME_LEN 25 ///< Maximalni delka oznaceni klienta serverem #define MAX_CLIENTS 16 ///< Maximalni pocet klientu na jeden server #define MAX_COMP_NAME_LEN 60 ///< Maximalni velikost jmena pocitace nebo IP adresy #define STATUS_ENDING 0 ///< Signalizace, ze server/klient ukoncuji svoji cinnost #define STATUS_RUNNING 1 ///< Signalizace, ze server/klient jsou v radnem stavu #define STATUS_THREAD_IS_RUNNING 2 ///< Signalizace, ze vlakno se jiz pustilo #define STATUS_GAME_STARTED 3 ///< Signalizace, ze hra zacala #define STATUS_PREPARE 4 ///< Signalizace, ze se zacina pripravovat k cinnosti #define STATUS_NOT_INICIALIZED 5 ///< Signalizace, ze jeste nebylo inicalizovano #define STATUS_GIVE_UP 6 ///< Vzdej pokus o pripojeni #define TO_NOBODY XML_NO_SUCH_A_PATH ///< Neexistujici adresat/odesilatel #define TO_EVERYBODY -2 ///< Zprava pro vsechny klienti i server #define TO_CLIENTS -3 ///< Zprava vsem klientum #define TO_SERVER -4 ///< Zprava serveru #define TO_NET_CLIENTS -5 ///< Zprava serveru #define COMM_WAIT_AFTER_SELECT 10 ///< Delka cekani po kazdem selectu (ms) #define COMM_WAIT_FOR_MESSAGE 1000 ///< Delka cekani pokud neni zprava k odeslani (ms) #define COMM_WAIT_AFTER_MESSAGE 100 ///< Delka cekani na odeslani dalsi zpravy #define COMM_WAIT_NO_CLIENTS 1000 ///< Delka cekani pokud nejsou zadni klienti pripojeni (ms) #define ANNOUNCE_TIME 4*60 /*(sec)*/ ///< Cas oznameni okoli o hre (s) #define ANNOUNCE_LAN_TIME 6 /*(sec)*/ ///< Cas oznameni okoli o LAN hre (s) #define PING_TIME 5 /* (*4sec)*/ ///< Perioda odesilani pingu (*4s) #define MAX_TIMEOUT 60 ///< Maximalni doba neozvani se (s) #define PING_ENABLED 0 ///< Zda povolit pingy #define MAX_LENGHT_UNAUTHORIZED_MESSAGE 300 ///< Nejvetsi delka zpravy od klienta, dokud nebyl jeste autorizovan /// Funkce spustena ve vlakne zajistujici odeslani zprav int sendInThread(void * data); /// Struktura udrzujici informace o ucastnicich ve hre pro potreby klienta struct TClientInfo { int clientid; ///< Jeho clientske id, identifikace na serveru char profileName[K8_MAX_NAME_LEN]; ///< Jmeno profilu int local; ///< Zda je tento klient ve stejnem procesu jako TClient, ktery tuto struktu vlastni }; /// Interface mezi GUI a klietem struct TClientsInfo { int num; ///< Pocet klientu pripojenych TClientInfo cinfo[MAX_CLIENTS]; ///< Informace o klientech }; /// Struktura udrzujici informace o jednom klientovi struct TNodeInfo { unsigned long IP; ///< IP adresa klienta int level; ///< Jeho prava unsigned int ping; ///< Cas obdrzeni minuleho pingu // int clientid; ///< Identifikace pripojeni char profileName[K8_MAX_NAME_LEN]; ///< Identifikace na serveru // struct sockaddr_in client; ///< Jeho socketaddr mysocket fd; ///< Na kterem portu je k serveru pripojen int localConnection; ///< Zda je o pripojeni na jednom PC (v ramci jednoho procesu) ==1 nebo ne ==0 DA * recvbuff; ///< Buffer na prijimani vetsich zprav DA * decompressbuff; ///< Buffer na robaleni prichozich zprav int size_of_next_message; ///< Velikost pristi zpravy }; class TMessageQueue; /// Spolecny predek klienta a serveru class TComm { public: /** Vytvori MySocket */ int createMySocket(); /** Virtualni funkce, kterou jak klient tak server pouziji pro pridani zpravy do fronty cekajicich zprav na odeslani */ virtual int sendMessage(TXMLdata * data) {return -1;}; /** Konstruktor */ TComm(); /** Destruktor */ ~TComm(); /** Zjisteni, zda byl objekt vytovren jako lokalni - vraci 1, nebo sitovy - vraci 0 */ int amILocal(); /** Vraci aktualni stav */ int getStatus(); protected: /** MySocket po kterem se bude komunikovat */ mysocket fd; /** Fronta zprav */ TMessageQueue * queue; /** Funkce odesilajici data na dany socket */ int sendTo(mysocket sock,const char * msg,size_t count); /** Funce ktera prijme z daneho socket data a posle KSendMessage s prijatymi daty. @param sock MySocket po kterem se komunikuje @param recvbuff buffer pro prijimane zpravy @param decompressbuff buffer pro dekomprimovani zpravy @param clientid je jen pro server (v pripade clienta==0) a pomoci toho se necha i otestovat, zda klient se nevydava za nekoho jineho @param sizeofmessage velikost prichozi zpravy (0 pokud se ocekava hlavicka) */ int recvFrom(mysocket sock,DA * recvbuff,DA *decompressbuff,int clientid,int &sizeofmessage); /** Socketaddr from server, ktery obsahuje jak klient, tak server (k accept()) */ struct sockaddr_in server; /** Port na kterem komunikujeme */ int port; /** Zamkne mutex */ void lock(void); /** Odemke mutex */ void unlock(void); /** Zamek pri pristupu k datum */ SDL_mutex *mutex; /** Id vlakna, ktere odesila zpravy */ SDL_Thread * sendThread; /** Promenna nabyvajici hodnot \ref STATUS_ENDING, \ref STATUS_RUNNING, \ref STATUS_THREAD_IS_RUNNING, \ref STATUS_GAME_STARTED, \ref STATUS_PREPARE, \ref STATUS_NOT_INICIALIZED pro synchonizaci s vlakny */ int status; /** Pomocny semafor pri cekani na vytvoreni vlakna */ SDL_sem *sem; /** Funkce odesilajici zpravy z fronty zprav */ friend int sendInThread(void * data); /** Pole na prijem zprav */ char *msg; /** Pomocna promenna na prevod XML do char */ DA * xml_in_da; /** Informace o tom, zda je to hra sitova nebo lokalni */ int localGame; /** Buffer na kompresi */ DA * compressbuff; /** Perioda odesilani pingu v sekundach */ int ping_time; /** Maximalni doba, po kterou se neprijal ping */ int max_timeout; }; } #endif