This is a project created for the BYU CS 240 (Advanced Programming Concepts) course.
This project demonstrates mastery of proper software design, client/server architecture, networking using HTTP and WebSocket, database persistence, unit testing, serialization, concurrency, and security.
It would not be too difficult to create a front-end web app and deploy the server to enable a complete web-based multiplayer chess game.
The application implements a multiplayer chess server and a command line chess client.
- Install all dependencies as specified in the
pom.xml
files. - Run the server using the
client/src/main/java/Main
class. - Run multiple concurrent clients using the
server/src/main/java/server/Main
class.
Open the project directory in IntelliJ in order to develop, run, and debug your code using an IDE.
You can use the following commands to build, test, package, and run your code.
Command | Description |
---|---|
mvn compile |
Builds the code |
mvn package |
Run the tests and build an Uber jar file |
mvn package -DskipTests |
Build an Uber jar file |
mvn install |
Installs the packages into the local repository |
mvn test |
Run all the tests |
mvn -pl shared test |
Run all the shared tests |
mvn -pl client exec:java |
Build and run the client Main |
mvn -pl server exec:java |
Build and run the server Main |
These commands are configured by the pom.xml
(Project Object Model) files. There is a POM file in the root of the project, and one in each of the modules. The root POM defines any global dependencies and references the module POM files.
Endpoint | HTTP Method | Path | Header | Body | Returns |
---|---|---|---|---|---|
Register | POST | /user | {username, password, email} | authToken | |
Login | POST | /session | {username, password} | authToken | |
Logout | DELETE | /session | authToken | {} | |
List Games | GET | /game | authToken | {gameID, whiteUsername, blackUsername, gameName}[] | |
Create Game | POST | /game | authToken | {gameName} | gameID |
Join Game | PUT | /game | authToken | {ClientColor, gameID} | {} |
Clear Application | DELETE | /db | {} |
See the complete sequence diagram here. The code used is provided below:
actor Client
participant Server
participant Services
participant DataAccess
database db
group #navy Registration #white
Client -> Server: [POST] /user\n{username, password, email}
Server -> Services: register(username, password, email)
Services -> DataAccess: getUser(username)
DataAccess -> db: SELECT username from user
DataAccess --> Services: null
Services -> DataAccess: createUser(username, password)
DataAccess -> db: INSERT username, password, email INTO user
Services -> DataAccess: createAuth(username)
DataAccess -> db: INSERT username, authToken INTO auth
DataAccess --> Services: authData
Services --> Server: authToken
Server --> Client: 200\n{authToken}
end
group #orange Login #white
Client -> Server: [POST] /session\n{username, password}
Server -> Services: login(username, password)
Services -> DataAccess: getUser(username)
DataAccess -> db:SELECT password from user
DataAccess --> Services: UserData
Services -> DataAccess: createAuth(username)
DataAccess -> db:INSERT username, authToken INTO auth
DataAccess --> Services: AuthData
Services --> Server: authToken
Server --> Client: 200\n{username, authToken}
end
group #green Logout #white
Client -> Server: [DELETE] /session\nauthToken
Server -> Services: logout(authToken)
Services -> DataAccess: deleteAuth(authToken)
DataAccess -> db: DELETE username, authToken FROM auth
DataAccess --> Services:success
Services --> Server:success
Server --> Client: 200
end
group #red List Games #white
Client -> Server: [GET] /game\nauthToken
Server -> Services: listGames(authToken)
Services -> DataAccess:getAuth(authToken)
DataAccess -> db: SELECT username, authToken FROM auth
DataAccess --> Services: AuthData
Services -> DataAccess:listGames()
DataAccess -> db: SELECT * FROM game
DataAccess -> SELECT games FROM games
DataAccess --> Services: gameData[]
Services --> Server: [gameID, whiteUsername, blackUsername, gameName][]
Server --> Client: 200\n{games}
end
group #purple Create Game #white
Client -> Server: [POST] /game\nauthToken\n{gameName}
Server -> Services: createGame(gameName, authToken)
Services -> DataAccess:getAuth(authToken)
DataAccess -> db: SELECT AuthData FROM auth
DataAccess --> Services: AuthData
Services -> DataAccess:createGame(gameName)
DataAccess -> db:INSERT gameName INTO game
DataAccess --> Services: GameData
Services --> Server: gameID
Server --> Client:200\n{gameID}
end
group #yellow Join Game #black
Client -> Server: [PUT] /game\nauthToken\n{ClientColor, gameID}
Server -> Services: joinGame(ClientColor, gameID, authToken)
Services -> DataAccess:getAuth(authToken)
DataAccess -> db: SELECT AuthData FROM auth
DataAccess --> Services: AuthData
Services -> DataAccess:getGame(gameID)
DataAccess -> db:SELECT GameData FROM game
DataAccess --> Services: GameData
Services -> DataAccess:updateGame(GameData)
DataAccess -> db:UPDATE gameData IN game
DataAccess --> Services:success
Services --> Server:success
Server --> Client:200
end
group #gray Clear application #white
Client -> Server: [DELETE] /db
Server -> Services:clearApp()
Services -> DataAccess:deleteAllAuths()
DataAccess -> db:DELETE * FROM auth
Services -> DataAccess:deleteAllGames()
DataAccess -> db:DELETE * FROM game
Services -> DataAccess:deleteAllUsers()
DataAccess -> db:DELETE * FROM user
DataAccess --> Services:success
Services --> Server:success
Server --> Client:200
end