This was supposed to be an MVP backend and CLI frontend for extenible MTG game engine. It didn't work out. It became a chat server and client with command line argument parser. It can handle local and server commands though and has some interesting annotation-based command declaration system.
Projekt to głównie aplikacja klient-serwer będąca frameworkiem na przyszłe projekty silników do gier, wraz z przykładowym silnikiem gier który można postawić na takim serwerze.
- pakiet
clientzawiera definicja klas odpowiedzialnych za część klienta. - pakiet
serverto kod serwera, zarząjący połączeniami, przychodzącymi klientami, czatem i hubami. - pakiet
commonto most łączący pakietyclientiserver- zawiera klasy wykorzystywane przez obie strony m. in. Formatter, maszynę stanów i parser komend. W podkataloguprotoznajdują się wygenerowane klasy wiadomości przesyłanych między klientem i serwerem - pakier
MTGzawiera definicje klas odpowiedzialne za silnik do gry Magic The Gathering. Jest on zaimplementowany aktualnie tylko częściowo.
- Client-Server pattern: klasy
Server,User,Client.Clientłączy się doServera, serwer oczekuje na nadchodzace połączenia i tworzy osobne wątkiUsernasłuchujące na połączeniu klient-serwer. Klient i Serwer mają zaimplementowany protokół 4-way-handshake bez uwierzytelniania, gdzie wysyłają sobie na początku dane konfiguracyjne. Aplikacja potrafi wykryć zerwanie połączenia, zawieszonego klienta, nieodpowiadający serwer i inne problemy łącza. Dokładniejszy opis protokołu komunikacyjnego jest wewnątrz plikuMessages.proto - Factory pattern: wewnątrz
Deck.javaorazCard.java, Tworzone są i inicjalizowane obiekty talii i kart, na podstawie odpowiednio klasDeckModelorazCardModel. - Strategy pattern: wszystkie pliki
*.yml *.yamlsą wykorzystywane do parametryzacji serwera. w Plikuconfig.ymlznajdują się ogólne ustawienia silnika MTG, w plikach z katalaguresources/decks/*.ymlznajdują się modele talii kart a wresources/cards/*.ymldefinicje kart. Aktualnie została zaimplementowana tylko częściowa obsługa parametryzacji kart - Mixins: Dzięki domyślnych metodach w interfejsach w Javie 8 udało się zaimplementować wzorzec Mixin w klasach dziedziczących po
CommandorazState. - Finite State Machine: Klasa
FIniteStateMachinejest abstrakcyjną klasą reprezentującą automat skończony. Wewnętrzny interfejsStatereprezentuje pojedynczy stan maszyny stanów. Jest to interfejs, a nie klasa abstrakcyjna, aby można było wykorzystać ją jako mixin dla stanów implementowanych na enumach. Dlaczego tak? A ponieważ enumy javove są nierozszerzalne, tzn. nie można dziedziczyć po enumie. Mixiny pozwalają na dodawanie funkcjonalności do zmiennych enumów. Dodatkowo wykorzystuję kilka hacków języka aby tworzyć proste systemy kontroli przepływu dla maszyny stanów - klasaAbortTransitionjest lekkim obiektem dziedziczącym poThrowablei pozwala przerwać przejście między stanami w dowolnym momencie. - ResourceManager: Klasa
ResourceManagerjest lekko powiązana z klasamiDeckModeliCardModel. Zarządza ona ładowaniem i doładowywaniem modeli w trakcie działania programu. - Parser: klasa
CommandControllerprzyjmuje definicję klasy implementującejCommandi parsuje linię wejścia użytkownika do formatu interpretowalnego przez serwer.
Dużo klas zostało zrobionych jako klasy wewnętrzne. Taka decyzja została podięta po to, aby łatwiej było rozróżnić które elementy należą do jakiej mechaniki.
Odpalamy server (można podać port na którym będzie słuchał) oraz klientów (można podać IP i port, domyślnie localhost i port 62442). Następnie mamy pełną kontrolę nad serwerem za pomocy udostępnionego interfejsu do poleceń - ServerCommand definiuje wszystkie komendy. W dowolnym momencie mamy możliwość wywołania /help aby otrzymać pomoc odn. dostępnych komend.