---
# System prepended metadata

title: Web final

---

# Web final
- front-end
-- react 
-- motion dection
-- socket.io

- back-end
-- express
-- server (local and online <eg. heroku>)
-- login system (GraphQL?)
-- database (MySQL, or graphQL)
-- socket.io

- OpenCV
-- OpenCV.js tutorial
-- 

## Schedule
- 李昌
    - Webcam
    - OpenCV
- Leo
    - Session (done)
    - Home
    - Room

## API
- HomePage
    - `GET /rooms` 取得所有房間資訊(首頁)
        - dump all rooms in database
        - Input: NO
        - Output: an array of rooms
            ```
            [
                {
                    primary_k: primary key of the room in database (used for routing)
                    name:  name of room
                    player_num: number of waiting players in this room
                },
                ...
            ]
            ```
    - `GET /highScore` 取得最高分及玩家
        - get highScore player (10 player most)
        - Input:
            - none
        - Output:
            - player info (an array with objects) in ordered based on score, high to low
            ```
            [
                {
                    "id": 6,
                    "name": "ryanhu",
                    "score": 88
                },
            ]
            ```
    - `POST /rooms` 新增房間
        - create a new empty room
        -  Input:
            -  `req.body.roomName`
        -  Output:
            -  `{ roomid: primary_k }` of the new room (primary_k as "id" used in backend)
   - `post /record` 記錄玩家得分
       - record the score of certain player
       - Input:
           - `req.headers.id`
           - `req.body.score`
           - `req.body.roomid`
       - Output:
           - none

## Socket.io for Room
### server
- utilities
    - Response an error
        - Action: 'err'
        - Data: `string message`
- on `reqRoomInfo`
    - Data:
        ```
        {
            roomid: primary_k of the room
        }
        ```
    - return requesting info of the room
        - RESPONSE SINGLE
            - Action: `resRoomInfo`
            - Data:
                ```
                {
                    name: name of the room,
                    active: bool, if a room is activated (game starts)
                }
                ```
- On `enter`
    - Data:
        ```
        {
            userid: primary_k of the requester
            roomid: primary_k of the room
        }
        ```
    - If the room is inactive, **and the userid of requester not yet in that room**(might already in that due to another tab), add requester into the room and broadcast the update
        - BROADCAST ROOM
            - Action: `players`
            - Data:
                ```
                [
                    {
                        id: primary_k of the player
                        name: full name of the player
                    }
                ]
                ```
    - If the room is active or **requester's userid already in that room due to another tab**, notify the requester in this tab
        - RESPONSE SINGLE
            - Action: `kickout`
            - Data: `null`
            
- On `leave`
    - Data:
        ```
        {
            userid: primary_k of the requester
            roomid: primary_k of the room
        }
        ```
    - remove requester from the room
        - If there are some remaining players
            - BROADCAST ROOM
                - Action: `players`
                - Data:
                    ```
                    [
                        {
                            id: primary_k of the player
                            name: full name of the player
                        }
                    ]
                    ```
        - If no player is left, delete the room
            - No need to response
- On `step`
    - Data:
        ```
        {
            userid: primary_k of the requester
            roomid: primary_k of the room
            step: movement amount of the the requester 
        }
        ```
    - broadcast the step info of requester to all players in room
        - BROADCAST ROOM
            - Action: `update`
            - Data:
                ```
                {
                    id: primary_k of requester
                    step: movement amount of requester
                }
                ```
- On `start`
    - Data:
        ```
        {
            roomid: primary_k of the room
        }
        ```
    - broadcast to the whole room that the game starts, and force the room to become inactive
        - BROADCAST ROOM
            - Action: `start`
            - Data: `null`

## Toward Socket.io for `Home`
- Client will only listen on action `update_rooms`
- Action `update_rooms`
    - Data (server broadcast to room `home`):
        ```
        [
                {
                    primary_k: primary key of the room in database (used for routing)
                    name:  name of room
                    player_num: number of waiting players in this room
                },
                ...
        ]
        ```
    - This action will appear many times below
- On `enter_home`
    - add the requester socket into room `home`
- On `leave_home`
    - remove the requester socket from room `home`
- Modify socket.io `enter` action handling
    - When someone enter a room, the number of players in that room is changed, need to sync the update to all clients staying at Home
    - Send action `update_rooms` as specified above
- Modify socket.io `leave` action handling
    - Similar as `enter`, need to update the player num showing in Home
    - When the last user leave the room, the room is automatically deleted, also need to sync with all clients in Home
    - Send action `update_rooms` as specified above
- Modify API `POST /rooms`
    - New room is created
    - Send action `update_rooms` as specified above

## Database
- schema (columns)
    - User
        - id
        - first_name
        - last_name
        - email
        - password
        - created
    - Room
        - id (int)
        - name (string)
        - active (bool)
        - playerID (array)