Cześć, dziś chciałem podzielić się tym, co udało mi się zrobić do tej pory. Zauważyłem ostatnio, że robię wszystko żeby nie ukończyć tego projektu na czas… Rzeczy które powinienem zostawić na koniec, lub inne mniej ważne elementy programu zostały po części zrobione, a o samej rozgrywce ani widu, ani słychu. Skoro już zdałem sobie z tego sprawę, może teraz uda się pójść w dobrym kierunku. No, ale do rzeczy.
Model bazy danych
Zaczynam od rzeczy która jest akurat bardzo ważna. Dane oczywiście muszą być gdzieś przechowywane. Tutaj nie wymyślałem niczego interesującego, używam Microsoft SQL Server. Użytkownicy przechowywani są w tabelach, które generowane są automatycznie gdy używamy ASP.NET Core Identity. Wszystko byłoby pięknie, ale gdy projektowałem własne tabele, jako identyfikatora użyłem typu danych bigint, czyli long w C#. Domyślnym identyfikatorem użytkownika generowanym przez system był string, a w bazie danych nvarchar(450). Nie podobało mi się to, że w systemie będę miał dwa typy identyfikatora. Musiałem więc to zmienić. Zadanie to nie jest specjalnie trudne, ale zajęło mi trochę więcej czasu niż się spodziewałem. Myślę że napiszę o tym osobny post, dlatego nie będę się rozpisywał na ten temat tutaj. Tabele zostały zmienione, wszystko gra. Możemy przejść dalej. W systemie naturalnie muszą się znaleźć także moje tabele, nie tylko te domyślne. Tak więc usiadłem i zacząłem je rozpisywać. Zmieniałem je kilkukrotnie, ale mniej więcej udało mi się ustalić jak będą wyglądały, przynajmniej te podstawowe dotyczące rozgrywki.
Jak widać, wszystko sprowadza się do powiązania z tabelą Games, gdzie będą przechowane ustawienia gry. GameStatuses odpowiadać będzie za aktualny stan rozgrywki, czyja tura aktualnie trwa, czy została już zakończona etc. GameTeams, jak nazwa wskazuje, przechowuje dane drużyn które biorą udział w grze. W przypadku, gdy grą steruje tylko jedna osoba, nie jest ona powiązana z użytkownikiem. GameFields to pola na których znajdują się słowa, ich rodzaj, czy są przypisane do któregoś zespołu i czy zostało one odkryte. GameMoves to historia wszystkich ruchów, a GameClients to urządzenia które są połączone z rozgrywką. Jestem pewny że tabel przybędzie, ale na razie tyle powinno wystarczyć, wyjdzie w praniu.
Kolejne tabele to takie przechowujące słowa. W grze chce mieć możliwość wyboru języka, więc dodałem tabelę z językami, oraz kategorie żeby łatwiej było nimi zarządzać. Tabele te są dosyć proste, nic szczególnego.
WebAPI do zarządzania słowami
Tak, bardzo ważna rzecz w grze która jeszcze nie działa. Dodałem możliwość zarządzania językami, kategoriami i słowami. Jest ono zabezpieczone w taki sposób, że jedynie użytkownicy będący administratorami mają do nich dostęp. Tabele ze słowami są pomocne od początku, ale zarządzanie nimi mogło poczekać… Już się zabierałem za robienie interfejsu użytkownika do tego, ale na szczęście się powstrzymałem. Dalszy rozwój tej części aplikacji odkładam na później.
Routing aplikacji webowej
W poprzednich postach opisywałem routing w Angularze. Na tej samej zasadzie zrobiłem go w mojej aplikacji. Na stronę główną mają dostęp wszyscy, ale żeby zobaczyć coś więcej trzeba się zalogować. Do panelu administracyjnego dostęp mają tylko administratorzy. Wykorzystałem tutaj mechanizm o którym nie wspomniałem w tamtym poście, RouteGuards. Na pewno opiszę go w drugiej części posta dotyczącej routingu. A poniżej przykład:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
// Auth Guard import { Injectable } from '@angular/core'; import { Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router'; import { UserService } from '../user.service'; @Injectable() export class AuthGuard implements CanActivate { constructor(private router: Router, private userService: UserService) { } canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot) { return this.userService .validateLoginState() .map(result => { if (this.userService.isLoggedIn()) { return true; } this.router.navigate(['/login'], { queryParams: { redirectTo: state.url } }); return false; }); } } |
Podsumowanie
Rozwój aplikacji nie przebiegał ostatnio w najlepszym tempie. Wydaje mi się jednak że zrobiłem dużo nudnych rzeczy, które i tak trzeba by było prędzej czy później dodać (może nawet bardzo później…). Dzięki temu teraz będę mógł przejść do konkretów i development przyśpieszy. Kolejne krotki to dodanie możliwości uruchomienia gry, czyli strona z wyborem ustawień, następnie zapisanie ich do bazy danych. Później przyjdzie czas na system rozgłaszania wykonanego ruchu przez użytkownika do innych klientów. Ale o tym w kolejnych postach.