marein / php-gaming-website Goto Github PK
View Code? Open in Web Editor NEWA gaming website where people can play against each other.
License: MIT License
A gaming website where people can play against each other.
License: MIT License
Problem description
Jane and John are playing. After a few moves, it looks like Jane will definitely win. John can now decide if he wants to resign the game. Resigning is only possible after the second move is done. Before that, the game can be aborted.
The documentation should be improved regarding to the following steps.
Almost all PHP containers currently look the same. Have a look at extension fields to improve this.
Since the functionality in the user interface is fixed, we can finally adjust the code for microsoft edge. Following actions needs to be done.
custom elements
https://github.com/webcomponents/custom-elementsSSE
https://github.com/Yaffle/EventSource<!DOCTYPE html>
The JavaScript
is already written with components in mind. Each class could be replaced sequentially with each component.
Following components needs to be updated.
Chat/Widget.js
Common/Notification.js
ConnectFour/AbortGameButton.js
ConnectFour/Game.js
ConnectFour/GameList.js
ConnectFour/JoinGameButton.js
ConnectFour/OpenGameButton.js
ConnectFour/ResignGameButton.js
ConnectFour/RunningGames.js
Then we have to clean up the following files (see todo with link to this issue).
Common/EventSource.js
The following files can be deleted after everything has been replaced.
Common/EventPublisher.js
bootstrap.js
The next game to come will be memory. Following things needs to be done.
Developers should be able to access data or general information without having to install external dependencies.
Following interfaces should be provided.
Application | Port |
---|---|
The application. | 80 |
MySQL management interface. | 8081 |
Redis management interface. | 8082 |
RabbitMq management interface. | 8083 |
Traefik management interface. | 8084 |
The documentation should reflect that.
Problem description
The classes PredisGameProjection
and PredisGameFinder
have both knowledge about how the query model for a game is stored. PredisGameProjection
knows how to retrieve and save it. PredisGameFinder
knows how to retrieve it. It's a given that this code changes together. They're sharing a constant for the storage key prefix already. Furthermore, the class PredisGameProjection
implements an in memory cache
for games.
Possible solution
We should move the responsibility to store a game to the GameFinder
. This leads to higher cohesion. While we're doing that, we should extract the in memory cache
part from PredisGameProjection
to a dedicated implementation of GameFinder
. This implementation should have a cache size limit to prevent memory leaks.
The game should be rendered within canvas in web/assets/js/ConnectFour/Game.js
. With that we should animate the fall of the stone.
There's a new major version. The migration path can be viewed at https://docs.traefik.io/migration/v1-to-v2/.
Problem description
The classes PredisGamesByPlayerProjection
and PredisGamesByPlayerFinder
have both knowledge about how the query model for a game by player relation is stored. It's a given that this code changes together. They're sharing a constant for the storage key prefix already.
Possible solution
We should move the responsibility to store a running game to the PredisGamesByPlayerFinder
. This leads to higher cohesion.
Problem description
Since we use cookie based authentication, this application is vulnerable to CSRF.
Problem description
After playing for a while, Jane decides to sign up to the page. She must provide an username and a password. Additionally she'll be asked if she would like to add her already played games to the account.
Possible implementation
Assigning the played games to the account should be easy. If she says yes, then she gets the UUID of her anonymous account. If she says no, she gets a new UUID.
Codeception
has the ability to run unit tests of PHPUnit
files. In addition, the output is nicely formatted.
Problem description
John is considered online while he's interacting with the page. John is considered offline if he hasn't performed a request within the next five minutes.
This could also be used to show which users are watching a particular game.
Possible implementation
We can leverage Redis and its Sorted Set for this feature.
./code/
to ./
./container/
to ./docker/
Problem description
Jane wants to know what the last move was.
A game is considered inactive after 5 days. The player whose turn it was last automatically loses.
Seems like the package predis/predis
is not maintained anymore. We can switch to the php
extension phpredis/phpredis
.
Symfony\Component\Dotenv\Dotenv
is deprecated, use Dotenv::usePutenv()
.controller::action
instead.docker-compose build
takes a long time because each PHP container specifies the build
directive (even if we have docker's caching mechanism). The time increases with the number of containers and should be worked on before new features are added. This build time should be minimized.
Problem description
Currently exceptions are bubbling up to the event dispatcher from symfony. The registered listener Gaming\Common\ExceptionHandling\GamingExceptionListener
is catching those exceptions and try to guess a error message for the user (currently via the name of the exception). Furthermore it has some logic to test if the name contains NotFound
. In that case it sets the status code to 404
. This might not always be valid and also enforces certain exception names.
Possible solution
Catching domain exceptions at the application level and re-throw an ApplicationException
with violations. A violation contains a property path, an identifier and a context (that combined makes them translatable and mappable to the UI if needed). These violations are part of the contract of the application itself. Furthermore, these application exception can be thrown by a bus implementation which is validating the incoming message with a validation library before it's delegating the message to the next bus implementation. As soon as every exception which is actually a violation is handled properly, the Gaming\Common\ExceptionHandling\GamingExceptionListener
can be deleted.
Tasks
ApplicationException
ApplicationException
to a http messageGaming\Common\ExceptionHandling\GamingExceptionListener
Problem description
Jane wants to know when John has written the message.
[PHPUnit\Framework\Exception] Undefined index: ELEMENT
Probably because we always use the latest
tag when fetching the selenium
image.
Problem description
Currently the username "Anonymous" is hard coded everywhere. When Jane signs up, her chosen username should be displayed instead. An anonymous user should still be called "Anonymous".
Possible solutions
With the first solution, the contexts are independent. Any context interested in usernames must subscribe to the events from the Identity context. These events (UserSignedUp and UsernameChanged) are applied to the local copies of the respective context. The WebInterface context has nothing todo but to forward the request to the respective context and return the response back to the user. I like the independence of this approach, but its a lot of common duplication. The second approach pushes these responsibilities to the WebInterface context (see below). Following is a diagram of how this process looks like with a closer look to the Chat context.
With the second solution, the contexts can't answer the username question themselves. It's the responsibility of the WebInterface context to assign usernames to the responses. The WebInterface is anyway the intermediate in every conversation. While the contexts are not independent, I think it's okay to couple the username question to the WebInterface context to gain a little less code. Of course, the first solution is more explicit and explicitness wins over "Don't repeat yourself". Following is a diagram of how this process looks like with a closer look to the Chat context.
Problem description
Jane and John are both explicitly assigned to their private chat. Eve shouldn't be able to read those messages.
This is because links
has been deprecated for some time, see here.
Problem description
The classes PredisOpenGamesProjection
and PredisOpenGamesFinder
have both knowledge about how the query model for an open game is stored. It's a given that this code changes together. They're sharing a constant for the storage key already.
Possible solution
We should move the responsibility to store an open game to the OpenGamesFinder
. This leads to higher cohesion.
What to do is described at OWASP. This replaces our dependency dunglas/angular-csrf-bundle
and removes its double submit cookie from the request. As described in OWASP, there are some edge cases in which the required headers are not available. But we're not live and never will be (side project).
Problem description
It occurs because of a change in MySQL version 8.0.4. It's documented here.
Libraries should be moved to the organization. They should be registered and loaded within this composer repository. This enables us to use them in other services and break the domains out of this project.
marein
account.marein
account.marein
account.The parameter was added because, for example, doctrine/doctrine-migrations-bundle
still depends on it.
This issue is currently not resolvable and should be checked again from time to time.
The workaround was introduced in #51.
We can use the Lax
setting because we adhere to the HTTP protocol and don't use secure methods to change data. It looks like this will protect against CSRF
attacks, but it doesn't. Normal forms, let's call them pre-auth
, like a login or a contact form, still need to be protected.
The migrations were created just to make them work and make the application deployable with single-commands like docker-compose up
or docker stack deploy
. However, there're known issues with the current approach, some of them are:
--allow-no-migration
with the doctrine:migrations:migrate
command that could be used. >/dev/null 2>/dev/null
which hides all the problems with the current solution.entrypoint: docker-php-entrypoint
in stack files obsolet. The feature can also be disabled if the deployment strategy wants to manually apply migrations.The goal of this issue is to use a clean solution while considering all the points above. Executing the migrations manually is not an option because we want to make the application deployable with one-click applications like Play with Docker
(at least the file docker-compose.production.yml
) and docker-compose up
should be enough for setting up the development environment.
Possible solutions:
Problem description
Although the volume is mapped to the host, the queues are empty after restarting the container. The queues themselves still exist.
Problem description
Jane and John want to know how they perform.
Possible solution
Create a new class named Player
inside the context ConnectFour
. Below there's an example structure of this class. The username
is there as an example of how this issue supplements issue #14.
final class Player
{
/**
* @var string
*/
private $id;
/**
* @var string
*/
private $username;
/**
* @var int
*/
private $eloRating;
}
Problem description
The classes PredisRunningGamesProjection
and PredisRunningGamesFinder
have both knowledge about how the query model for a running game is stored. It's a given that this code changes together. They're sharing a constant for the storage key already.
Possible solution
We should move the responsibility to store a running game to the RunningGamesFinder
. This leads to higher cohesion.
Problem description
Jane wants to analyze a game by looking at the previous moves.
Problem description
Jane wants to study her own won, drawn and lost games.
Possible solution
Split the current view in 4 categories: running, won, drawn, lost.
Additional ideas
Problem description
Currently the invariants are only captured on the server. Following needs to be done in the web interface.
This repository should be moved to https://github.com/gaming-platform and the main application Docker image should be made accessible via ghcr.io
.
Reason
Everything else about the project is already or will end up in the organization. There is no reason to leave this repository in my personal account.
Naming
The name php-gaming-website
will change. Since this is a modular monolith, this will not match with the current repository naming conventions like gaming-platform/service-js-polyfill
, gaming-platform/service-mailer
, gaming-platform/docker-php-fpm
or gaming-platform/php-mailer-client
. It could be named to gaming-platform/application
.
Symfony provides a file from the generated container, see here. However, files in src
should also be loaded.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.