---
# System prepended metadata

title: 設計書(在這裡改動)
tags: [開發中, document]

---

:::info
有改動就紀錄在這裡，不要動規格書
:::

:::danger
### 開發環境
前端：unity (2022.3.9f1)
後端：flask (3.0)
資料庫：MySQL (8.1.0)
虛擬機：
* OS：ubuntu server 22.04
* IP：140.122.185.169
* 儲存空間：160G
* 登入方法：https://hackmd.io/5Ks0Cy2sRayWeaq4JZaN3w

開發用Docker **(10/30修改過)**：https://github.com/ToshaETang/SWEgroup3/tree/dev/docker/nginx-flask-mysql

github空間：https://github.com/NTNU-SWE-GROUP3/SWEgroup3
會議記錄總表：https://hackmd.io/X4tS1BY0RKCvELo291u0gw
函式變數紀錄：https://hackmd.io/vplKQYbARmqOX-gS5sZ_Tg
問題和筆記： https://hackmd.io/oV8HkRxVTXWSSk2R5OSMKg

測試書：https://hackmd.io/NASmIXV-S_aTA09MN6Mfew
:::


:::warning
### 命名方式
變數：小駝峰
函式(不論pubic/private)：大駝峰
物件(object)：大駝峰
Manerger：大駝峰
:::

----

:::success
:notebook: **Syllabus**
[ToC]
:::

# 遊戲介紹

**遊戲基本資訊** 
遊戲名稱：Fate of thrones: Kingdoms Collide
官方平台：https://instagram.com/ntnu.swe3?igshid=MzMyNGUyNmU2YQ==
遊戲平台：Android手機(5.0以上版本)
遊戲類型：卡牌遊戲(PVP、PVE)
遊戲收益：10抽30元
遊戲概要：取材自《謊言遊戲》第五集-不等邊三角關係
遊戲包裝：軟工宇宙中，各世界平衡突然被L紀打亂，所有世界的角色、故事及時代都混亂不堪，請你號召屬於你的世界隊伍，擊敗所有對手，取得軟工宇宙的故事主導權！
遊戲主視覺：黑白分裂多重宇宙，透過取得更稀有的遊戲角色增加遊戲色彩
遊戲開發環境：前端-Unity (2022.3.9f1)、後端-flask (3.0)、資料庫-MySQL (8.1.0)、虛擬機：(預設值)

# 前端畫面

**前端介面關係圖**
![](https://hackmd.io/_uploads/SJ_pErVZ6.png)

**遊戲UI**
![](https://hackmd.io/_uploads/HkAWHHEbp.png)

# 遊戲流程

### 遊戲總類

1. 排位
    - 關於排位計算
        > 實際會以經驗值判斷，不過這裡以勝場估計
        
        | 排位 | 到達該排位所需勝場 |
        | :--: | :--: |
        | 1 | 0 |
        | 2 | 2 |
        | 3 | 4 |
        | 4 | 7 |
        | 5 | 10 |
        | 6 | 12 |
        | 7 | 15 |
        - 排位升級獎勵
            - 卡池解鎖：技能或服裝
            - 技能升級突破極限 ( +1 )
    - 關於排位結果計算
        - 經驗值增加 ( 底下以比例表示 )
        - 勝利：+1
            > Bonus
            - 連勝 n 場：+0.3 * n
            - 敵人分數與自己分數差值：+-0.3
        - 失敗：-0.5
2. 一般場
    - 關於一般場結果計算
        - 經驗值增加 ( 底下以比例表示 )
        - 勝利：+1
        - 失敗：+0.8
        - 連勝 n 場：+0.3 * n
    - 關於一般場升級獎勵
        - 每升一級：金幣
        - 特定等級：送特殊服裝、技能、金幣、課金用抽獎券
3. 友誼賽
    - 友誼賽不發放任何獎勵

### 玩家配對

```mermaid
    sequenceDiagram
    participant A as 玩家
    participant B as 前端
    participant C as server

    alt 勝率入口
        A ->> B: 玩家選擇勝率入口
        B ->> C: 將玩家 nickname 帶入對應排位房間、計算配對分數
        alt 在配對時間內
            alt 玩家屬於新手玩家
                C ->> C: 配對新手玩家
            else 其他
                C ->> C: 配對分數較為接近的玩家
            end
        else 超過配對時間
            alt 玩家屬於新手玩家
                C ->> C: 配對簡單版電腦玩家
            else 其他
                C ->> C: 配對一般電腦玩家
            end
        end
        C ->> B: 回傳配對結果
        B ->> A: 顯示配對結果
    else 排位入口
        A ->> B: 玩家選擇排位入口
        B ->> C: 將玩家 nickname 帶入對應排位房間、計算配對分數
        alt 玩家段位=1、2
            alt 該房間有現場玩家
                C ->> C: 選擇與玩家配對分數最接近之現場玩家
                C ->> B: 回傳配對結果
            else 無現場玩家
                C ->> B: 回傳電腦玩家
            end
        else 玩家段位=3、4、5、6、7
            alt 該房間有現場玩家
                C ->> C: 選擇與玩家配對分數最接近之現場玩家
                C ->> B: 回傳配對結果
            else 無現場玩家
                C ->> B: 停留在配對頁面
            end
        B ->> A: 顯示配對結果
    else 友誼賽
        A ->> B: 玩家選擇友誼賽入口
        B ->> C: 將玩家 nickname 帶入友誼賽房間
        C ->> C: 產生房間代碼，回傳房間代碼
        C ->> B: 顯示房間代碼
        C ->> B: 回傳配對結果
        B ->> A: 顯示配對結果
    end
    end
```
    
本遊戲分成三個遊戲入口：勝率入口、排位入口及友誼賽
- 勝率入口
    > 當玩家進入勝率入口會進行特殊判斷：若玩家為新手玩家 ( 遊戲總場數 <= 2 )，則保證配對新手玩家或簡易版電腦玩家
    > 否則，玩家進入房間前會計算一個配對分數，並攜帶該分數進去，分數由玩家等級、勝率進行計算，最終配對分數較為接近的玩家，若指定時間配對不到玩家，房間會自行配對電腦玩家
- 排位入口
    > 排位共分成 1 - 7 段位，預期是讓玩家配對到程度接近的玩家。我們把配對房間分成段位12、段位34、段位5、段位6、段位7等五個房間，不同房間不會互相配對，以此保證不會讓玩家配對到太弱或太強的玩家。
    > 配對方式如下：玩家進入房間前會計算一個配對分數，並攜帶該分數進去，分數由段位、玩家等級、連勝場數進行計算，最終配對分數較為接近的玩家，若指定時間內配對不到玩家，段位12會直接配對電腦玩家，而其他段位會繼續等待，除非玩家自行離開。
- 友誼賽
    > 當玩家進入友誼賽，玩家可以選擇創建房間或進入房間，若為創建房間，則配對系統會回傳一個房間代碼，待好友輸入房間代碼並進入房間，遊戲就開始。若為進入房間，則系統會判斷玩家輸入之房間代碼是否存在，若存在則進入遊戲，否則顯示該房間不存在。
- 關於配對機制開發
    ```
        matched_pair match( player->nickname )
        {
            count_match_score( player->nickname );
            enter_room();
            pair = match();
            return pair;
        }
    ```

### PVE機制

* 電腦玩家根據強度分為不同等級，強度越強所攜帶的技能強度越強
* 每張牌出牌機率相同
* ![](https://hackmd.io/_uploads/S1pzP-ygp.png)

### 遊戲進行流程

```mermaid
sequenceDiagram
participant A as UI
participant B as 前端
participant C as 後端

critical 遊戲開場 15秒
    A ->> B: 進入遊戲
    B ->> C: 呼叫玩家配對函式
    alt 成功
        C ->> B: 回傳玩家配對結果
        B ->> A: 顯示玩家配對結果
    else 失敗
        C ->> B: 回傳玩家配對失敗
        B ->> A: 顯示玩家配對失敗
    end
    B ->> C: 呼叫遊戲開場動畫
    C ->> B: 回傳遊戲開場動畫
    B ->> A: 顯示遊戲開場動畫
end

loop 遊戲進行 13 回合

    critical 選牌階段 10秒
        alt 玩家於時間內選牌
            A ->> C: 傳送選牌結果
        else 玩家位於時間內選牌
            A ->> B: 隨機挑選最右側卡牌送出
        end
    end

    critical 揭牌階段 5秒
        C ->> C: 呼叫卡牌強弱判斷函式
        C ->> B: 回傳卡牌強弱判斷結果
        B ->> A: 顯示卡牌強弱判斷結果
    end

end

critical 遊戲結束 15秒
    C ->> C: 呼叫遊戲勝負判斷函式
    C ->> B: 回傳遊戲勝負判斷函式
    B ->> A: 顯示遊戲勝負結果、獎勵
end
```

> 共計一局遊戲約 5 分鐘
1. 開場動畫：約15秒
    > 開場動畫包括玩家配對及進入遊戲之開場動畫，玩家配對至多10秒，若在10秒內仍未找到對應之適合玩家，則會由電腦創建角色與玩家進行對戰
2. **選牌階段**：最多10秒，最少3秒
    > 一般情況下，玩家有10秒選牌時間，若玩家未於10秒內出牌，則由電腦直接選擇玩家手中最右方一張牌丟出，若雙方皆提早出牌，則提早結束選牌階段
    > 技能會縮短對方玩家出牌時間，進而影響此處10秒之設定
3. 揭牌階段：約5秒
    > 揭牌階段會顯示卡牌強弱判斷之結果
4. 結束動畫：約15秒
    > 結束動畫包括顯示遊戲勝負及顯示經驗值、金幣獲取量，若超過15秒玩家仍未畫面則會自動跳至主畫面

### 卡牌強弱判斷

```mermaid
sequenceDiagram
    participant UI
    participant 前端
    critical 成功
        UI->>前端: 點選卡牌
    option 失敗
        UI-->>UI: 回傳錯誤訊息    
    end
    critical 成功
        前端->>後端: 呼叫判斷卡牌強弱函式
    option 失敗
        前端-->>前端: 回傳錯誤訊息
    end
    後端->>後端: 判斷勝負
    critical 成功
        critical 有勝負
            後端->>後端: 揭牌區卡牌轉移至勝者贏牌區
        option 平手
            後端-->>後端: 揭牌區卡牌繼續累積、觸發平民卡效果（若有）
        end
        後端->>前端:  回傳結果
    option 失敗
        後端-->>前端: 回傳錯誤訊息
    end
  
    critical 成功
        前端->>UI: 顯示勝負資訊、揭牌區卡牌轉移或累積、平民卡效果
    option 失敗
        前端-->>UI: 回傳錯誤訊息
    end
```
![](https://hackmd.io/_uploads/H1Z4HTbmT.png)

![](https://hackmd.io/_uploads/HJwQ6AjfT.png)

| Player 1 | Player 2 | 勝者 |
| -------- | -------- | ---- |
| 國王     | 國王     | 平手     |
| 國王     | 王子     |Player 1      |
| 國王     | 皇后     |Player 2      |
| 國王     | 騎士     |Player 1      |
| 國王     | 殺手     |Player 2      |
| 國王     | 平民     |Player 1      |
| 王子     | 國王     |Player 2      |
| 王子     | 王子     |平手      |
| 王子     | 皇后     |Player 1      |
| 王子     | 騎士     |Player 1      |
| 王子     | 殺手     |Player 2    |
| 王子     | 平民     |Player 1    |
| 皇后     | 國王     |Player 1    |
| 皇后     | 王子     |Player 2    |
| 皇后     | 皇后     |平手   |
| 皇后     | 騎士     |Player 1    |
| 皇后     | 殺手     |Player 2    |
| 皇后     | 平民     |Player 1    |
| 騎士     | 國王     |Player 2    |
| 騎士     | 王子     |Player 2    |
| 騎士     | 皇后     |Player 2    |
| 騎士     | 騎士     |平手   |
| 騎士     | 殺手     |Player 1   |
| 騎士     | 平民    |Player 1    |
| 殺手    | 國王    |Player 1    |
| 殺手    | 王子    |Player 1    |
| 殺手    | 皇后    |Player 1    |
| 殺手    | 騎士    |Player 2    |
| 殺手    | 殺手    |平手    |
| 殺手    | 平民    |平手   |
| 平民    | 國王    |Player 2    |
| 平民    | 王子    |Player 2    |
| 平民    | 皇后    |Player 2    |
| 平民    | 騎士    |Player 2    |
| 平民    | 殺手    |平手    |
| 平民    | 平民    |平手    |

### 平民卡效果執行

- 當玩家該回合丟出平民卡時，根據該回合結果觸發平民卡效果

| 陣營 | 名稱 | 觸發條件 | 技能 |
| -------- | -------- | -------- | -------- |
| Ａ    | 簡易剔除     | 平手     | 從對手手排中選出一張卡牌移出遊戲 |
|Ａ     | 全部重置     | 平手     | 將對手贏到的牌全部放到平手區 | 
|Ａ     | 不敗的勇者   | 不限輸贏平手| 可以贏過任何一張牌 |
| Ｂ    | 爆發式成長    | 平手     | 增加Ｘ張自身的贏取卡（Ｘ為回合數） | 
|Ｂ     | 大革命     | 平手     | 從此以後，所有卡牌優劣反轉 |
|Ｂ     | 特洛伊木馬 | 當遇上王家或騎士時|把對手玩家的一半贏取卡牌（半張自動進位為一張）加到自身贏取卡牌當中|

``` mermaid
sequenceDiagram
participant Frontend as 前端
participant Backend as 後端

Frontend ->>Backend: 玩家丟出平民卡
Frontend->>Backend: 發送平民卡資訊與該回合結果
Backend ->> Backend: 檢查平民卡效果觸發條件
Backend->>Frontend: 回傳平民卡效果觸發條件

alt 符合觸發條件
    Frontend->>Backend: 請求觸發平民卡效果
    Backend->>Backend: 根據平民卡效果計算並執行結果
    Backend->>Frontend: 回傳並顯示平民卡效果執行結果
else 不符合觸發條件
    Backend-->>Frontend: 無法觸發平民卡效果
end
```

### 玩家技能執行
   
1. UI互動
    - 遊戲中顯示技能狀態
    - 可使用 : 達成技能使用條件
    - 已使用 : 技能已使用過
    - 無法使用 : 未達成技能使用條件、被敵方玩家干擾
    - 點擊 : 第一次點擊該技能圖案放大(或其他特效)，表示被選取，再次點擊技能會發動
    - 長按 : 顯示技能詳細敘述

2. 技能發動

    點選發動後，呼叫該玩家技能的函式，由後端計算完後將結果回傳至前端，前端將結果轉換成對應的技能效果、特效，顯示至螢幕上

    ![](https://hackmd.io/_uploads/ByfhJEbg6.png)

3. 玩家技能內容
    * **時間限縮(timeWarp)** :縮短對手選牌時間5秒  (1回合)  (可升級)
    * **階級流動(peasantAscension)** :一張平民變騎士  (整場)
    * **暗影轉職(civillianDagger)** :一張平民變殺手  (整場)
    * **技能封印(skillNullifier)** :禁止對方使用玩家技能  (1回合)  (可升級)
    * **力量剝奪(peasantImmunity)** :平民卡效果無效  (1回合)  (可升級)~~~~
    * **黃金風暴(goldRush)** :獲勝金幣總數*1.5 (整場)  (可升級)
    * **知己知彼(deckRecon)** :看對手剩下的手牌  (1回合)  (可升級)
    * **抉擇束縛(dilemmaDictator)** :限制對手二選一出牌  (1回合)  (可升級)
    * **強制徵收(triumphManipulation)** :對手贏牌區張數-1 (整場)
    * **勝者之堆(victoryBoost)** :己方贏牌區張數+1 (整場)


### 回合紀錄

* 紀錄現在是第幾回合
* 玩家應該在遊戲進行中不會看得到每個回合的紀錄，但遊戲結束的畫面中可以顯示每個回合的紀錄。

### 遊戲結束判斷

1. 當其中一方玩家手牌耗盡，遊戲就會進入結算階段。
2. 如果另一方玩家手牌尚有剩餘，則將手牌全部放入該玩家贏牌區。

### 遊戲結果判斷

1. 贏牌區卡牌數量較多的玩家勝出，如果兩位玩家贏牌區卡牌張數相同則平手。
2. 獲勝的玩家可以得到較多獎勵與積分，落敗的玩家則會扣除積分並獲得少許獎勵。
3. 結算完獎勵後將退出遊戲並回到主畫面。
![](https://hackmd.io/_uploads/rJ7xpUJxa.png)


# 其他功能

### 玩家註冊
用email當帳號
1. 玩家註冊
```mermaid
sequenceDiagram

    participant UI
    participant signUp manager
    participant Server
    UI->>UI: 輸入 username,email,password
    UI->>signUp manager: 點擊註冊按鈕

    signUp manager->>Server: send username,email,password
    
    Server->>Server: check account eligibity
    Note right of Server: go through database<br/>to check duplicates
    Note over Server: check username & email
    
    opt if not eligible
        Server-->>UI: send sign Up failed notification
        Note over signUp manager,Server: case 1: Username is already used<br/>case 2: email is already registered<br/>case 3: password too short
    end

    Server->>Server: generate & send verification code to user email
    Note over UI: user receive verification<br/>code from email
   
    UI->>UI: 輸入 verification code
    UI->>signUp manager: confirm verification code
    signUp manager->>Server: send verification code
    Server->>Server: check verification code
    
    alt if verCode wrong
        Server-->>UI: code doesnt match notification
    else if verCode right
        Server->>Server: username & password hashing
        Server->>Server: add account to the database
        Server->>Server: generate user identification token
    end

    Server->>signUp manager: (sign up succesfull) notification
    Server->>signUp manager: send user identification token
    signUp manager->>signUp manager: record player token
    signUp manager-->>UI: sign up status : success
```

**UI (前端)**
Input :

- user email
- username
- password
(user will receive a verification code through email)

Output :

- registration status (username has been used, email is already registered, password too short)
- sign up status : success -> logged in (with token)
- Status：
        - 400001 -- Signup Success
        - 403003 -- username has been used
        - 403004 -- email is already registered
        - 403005 -- password too short

**Server**
Input :

- user email
- username
- password
(server will sent a verification code to verify email)

Output :

- account verification code
- account identification token
- status : sign up successfull
  
### 玩家登入

```mermaid
sequenceDiagram
    participant UI
    participant LoginManerger
    participant Server
    UI->>UI    : 輸入帳號、密碼
    UI->>LoginManerger    : 點擊登入按鈕
    LoginManerger->>LoginManerger    : 檢查連線狀況
    note left of LoginManerger: 沒有連線到網路
    LoginManerger-->>UI: Status:Poor Network
    note right of LoginManerger: 有連線到網路
    LoginManerger->>LoginManerger: 檢查帳號密碼輸入是否合法
    note left of LoginManerger: 帳號密碼不合法
    LoginManerger-->>UI: Status: Invalid Password or Account
    LoginManerger-->>UI: Status: Invalid Account
    note right of LoginManerger: 帳號密碼合法
    LoginManerger->>Server: 傳送帳號、密碼
    Server->>Server: 檢查帳號、密碼格式與內容
    note left of Server: 格式不合法
    Server-->>LoginManerger: Status: Invalid Input
    note right of Server: 格式合法
    Server->>Server: 帳號、密碼 hash 處理
    Server->>Server: 資料庫驗證帳號密碼
    note left of Server: 登入失敗
    Server-->>LoginManerger: Status: Wrong Password or Account
    note right of Server: 登入成功
 
    
    Server->>Server: 產生用戶識別 Token
    Server->>Server: 紀錄 Tokne 於 Database
    Server->>LoginManerger: Status: Success / Token = ...
    LoginManerger->>LoginManerger: 紀錄玩家取得的 Token
    LoginManerger-->>UI: Status: Success
```
- 用戶登入 - UI Input

    - account：用戶帳號
        - public TMP_InputField accountInput;
    - password：用戶密碼
        - public TMP_InputField passwordInput;
    - ~~HandleLoginResult：回調函數~~
    
- 用戶登入 - UI Output
    - Status：登入結果
        - 400000 -- Success
        - 403001 -- No such account
        - 403002 -- Wrong password
    - Token：(登入成功) 用戶識別token
        - jsonify({"status":"400000","token":token})


- 用戶登入 - Server Input
    - account：用戶帳號
    - password：用戶密碼
    - SendPostRequest(account, password)

- 用戶登入 - Server Output
    - Status：登入結果
    - Token：(登入成功) 用戶識別token

### 忘記密碼

```mermaid
sequenceDiagram
    participant 前端
    participant APP
    participant Server
    前端->>前端: 輸入username和email
    前端->>APP: 按忘記密碼按鈕，送出username和email
    APP->>APP: 檢查username和email輸入是否合法
    alt 輸入不合法
        APP-->>前端: 輸入不合法，改密碼失敗！
    else 輸入合法
        APP->>Server: 輸入合法，送出username和email
        Server->>Server: 搜尋username
        alt 找不到username
            Server-->>前端: 忘記密碼失敗
        else 找得到username
            Server->>Server: 檢查user輸入的email與資料庫裏記錄的userEmail是否相等
            alt 不相等
                Server-->>Server: 改密碼失敗
            else 相等  
                Server->>Server: 發驗證碼到user的email
                alt 驗證失敗
                    APP-->>前端: 驗證失敗，忘記密碼失敗
                else 驗證成功
                    APP->>前端: 驗證成功
                    前端->>前端: 輸入新的密碼
                    前端->>前端: 輸入確認新密碼
                    前端->>APP: 送出新密碼和確認新密碼
                    APP->>APP: 檢查新密碼是否跟確認新密碼相等
                    alt 新密碼和確認密碼不相等
                        APP-->>前端: 新密碼!=確認新密碼，改密碼失敗
                    else 新密碼和確認密碼相等
                        APP->>APP: 檢查密碼輸入是否合法
                        alt 新密碼輸入不合法
                            APP-->>前端: 密碼不合法，改密碼失敗
                        else 新密碼輸入合法
                            APP->>Server: 送出新密碼
                            Server->>Server: 新密碼hash處理，存新密碼
                            Server->>前端: 改密碼成功
                        end
                    end
                end
            end
        end
    end
```
**Status：**
- 400002 = Email & Username match
- 400003 = Password changed successfully
- 403001 = No such account
- 403006 = Email & account NOT match
- 403007 = Password too short
- 403008 = Password too long


**前端使用方法：**
Input: username, 新密碼，確認新密碼
Output: 是否成功改密碼
**Server需要的功能:**
Input: username, 新密碼
Output: username是否存在，email, 是否成功改密碼


### 抽卡系統
```mermaid
sequenceDiagram
    participant UI
    participant APP
    participant Server
    participant DB
    UI->>APP    : 按抽卡
    APP->>Server: 傳送帳號，等級，抽卡分類
    Server->>Server: 檢查玩家是否有足夠的錢或金幣進行抽卡
    alt 錢或金幣不足
        Server -->> APP :回傳錯誤訊息<br>(錢/金幣不足，無法抽卡)
        APP -->> UI: 顯示錯誤訊息
    else
        note right of Server: 課金與免費抽卡<br>抽到skill, card_style, coins機率不同
        loop 抽卡次數
        critical 開始抽卡
            Server->>Server: 執行抽卡
        option 抽到 coins
            Server->>DB: 更新 account_data 玩家金幣數 
        option 抽到 skill
            Server->>DB: 更新 account_skill
        option 抽到 card_style
            Server->>DB: 更新 account_card_style
        
        end
            Server ->> Server: 儲存抽卡結果 
        end
            Server ->> APP: 回傳抽卡結果
            APP ->> UI: 顯示抽卡結果
    end
```

輸入
- **APP** 按抽卡
- **Server** 帳號，等級，抽卡分類(AccountId, Class, LotteryType)

輸出
- **Server** 抽到的事物，數量
- **APP** 抽到的事物，數量，特效

抽卡機率（未定）
- 無課金
    - coins: 70%
    - skill: 15%
    - card_style: 15%
- 課金
    - coins: 55.5%
    - skill: 22.5%
    - card_style: 22.5%

**抽卡若是抽到已擁有的東西，則自動轉為金幣 (11/30會議)**

課金時有付款資訊視窗

### 背包~~賣出~~系統

**取消賣出功能，改成顯示整個遊戲的所有造型和技能，該玩家擁有的顯示彩色，沒有的顯示灰色 (11/30)**

~~該功能提供可將背包裡的物品兌換成虛擬金幣的功能。
兌換的金幣數量取決於物品的類型和數量。
系統管理員可根據情況更改金幣兌換率。
背包賣出系統的流程如下所示。~~

```mermaid
sequenceDiagram
    participant UI
    participant APP
    participant Server
    UI->>UI    : 按背包賣出
    UI->>APP    : 選擇物品和數量
    APP->>APP: 計算每個物品的價值
    APP->>UI: 顯示總價值
    UI->>APP: 確定
    APP->>Server: 傳送帳號，物品，數量
    Server->>Server: 計算&兌換
    Server->>Server: 更改該帳號的物品數量和金幣資訊
    Server->>APP: 通知成功
    Server-->>APP: 通知失敗
    APP->>UI    : 顯示兌換的金幣
    APP-->>UI    : 顯示錯誤訊息
```



### 換卡牌造型

```mermaid
sequenceDiagram
    participant UI
    participant EquipmentManerger
    participant Server
    UI->>UI: 選擇想要更換的造型
    UI->>EquipmentManerger: 按下更換造型按鈕
    EquipmentManerger->>EquipmentManerger: 檢查內部變數是否符合條件
    note left of EquipmentManerger: 使用者沒有此造型，無法裝備
    EquipmentManerger-->>UI: Fail: User do NOT have this Item.
    note right of EquipmentManerger: 使用者有此造型
    EquipmentManerger->>Server: 檢查使用者是否擁有造型
    Server->>Server: 資料庫數據比對
    note left of Server: 使用者沒有此造型，無法裝備
    Server-->>UI: Fail: User do NOT have this Item.
    note right of Server: 使用者有此造型
    Server->>Server: 資料庫儲存使用者目前使用的造型
    Server->>EquipmentManerger: Success: User do have this Item
    EquipmentManerger->>EquipmentManerger: 更改裝備造型變數
    EquipmentManerger->>UI: Success 
    
```

```EquipmentManerger.change_card_style``` --- 用來換造型

- **UI Input**
    - Style_Id：造型辨識碼
    - Result：回調函數

- **UI Output**
    - Status：是否成功更換造型 (Success / Fail)

- **Server Input**
    - Token：用戶識別token
    - Style_Id：造型辨識碼

- **Server Output**
    - Result：玩家是否成功更換造型

- **內部**
    - 修改”玩家目前使用造型“ 的變數


### 換玩家技能

``EquipmentManerger.change_skills``--- 用來換攜帶技能

```mermaid
sequenceDiagram
    participant UI
    participant EquipmentManerger
    participant Server
    UI->>UI: 選擇想要更換的技能
    UI->>EquipmentManerger: 按下更換技能按鈕
    EquipmentManerger->>EquipmentManerger: 檢查內部變數是否符合條件
    note left of EquipmentManerger: 使用者沒有此技能，無法裝備
    EquipmentManerger-->>UI: Fail: User do NOT have this Item.
    note right of EquipmentManerger: 使用者有此技能
    EquipmentManerger->>Server: 檢查使用者是否擁有技能
    Server->>Server: 資料庫數據比對
    note left of Server: 使用者沒有此技能，無法裝備
    Server-->>UI: Fail: User do NOT have this Item.
    note right of Server: 使用者有此技能
    Server->>Server: 資料庫儲存使用者目前使用的技能
    Server->>EquipmentManerger: Success: User do have this Item
    EquipmentManerger->>EquipmentManerger: 更改裝備技能變數
    EquipmentManerger->>UI: Success 
    
```

```EquipmentManerger.change_card_style``` --- 用來換技能

- **UI Input**
    - Style_Id：技能辨識碼
    - Result：回調函數

- **UI Output**
    - Status：是否成功更換技能 (Success / Fail)

- **Server Input**
    - Token：用戶識別token
    - Style_Id：技能辨識碼

- **Server Output**
    - Result：玩家是否成功更換技能

- **內部**
    - 修改”玩家目前使用技能“ 的變數
    

### ~~玩家技能升級系統~~

**刪除此功能 (11/30)**

想法：在資料庫中，用低等級的 skill 換高等級的 skill
(e.g., Skill_1_Lv1 numbers:3->1; Skill1_Lv2 numbers:0->1)

```mermaid
sequenceDiagram
    participant UI
    participant Upgrade System
    participant Server
    UI->>UI: 選擇想要升級的卡牌
    UI->>Upgrade System: 發出升級請求
    Upgrade System->>Upgrade System: 檢查內部變數是否符合條件
    note left of Upgrade System: 特定 Skills 數目不足，無法升級
    Upgrade System-->>UI: Fail: Not enough skills for upgrade
    note left of Upgrade System: 特定 Skills 不可以升級
    Upgrade System-->>UI: Fail: This skills can NOT upgrade
    note right of Upgrade System: 符合升級條件
    Upgrade System->>Server: 傳送要用戶升級的資訊
    Server->>Server: 檢查資料庫中玩家特定技能數量
    note left of Server: 特定技能數量不足
    Server-->>UI: Fail: NOT enough numbers of certain skills
    note right of Server: 特定技能數量正確
    Server->>Server: 將資料庫中舊技能的數目扣除 
    Server->>Server: 將資料庫中新技能的數目增加
    Server->>Upgrade System: 傳送用戶目前擁有的道具變數
    Upgrade System->>Upgrade System: 更新遊戲內道具變數
    Upgrade System->>UI: Success / new skill = skill_id
```

- 升級系統 - UI Input

    - skill_id：想要升級的技能id
    - HandleLoginResult：回調函數
    
- 升級系統 - UI Output
    - Status：動作結果 (Fail/Success)
    - new_skill： 新獲得skill的skill_id (If status = Success) 


- 升級系統 - Server Input
    - Token：用戶Token
    - Upgrade_Skill_ID：用戶想要升級的卡片ID

- 升級系統 - Server Output
    - Status：Success / Fail , Reasons
    - Skill_Data：更新過後的Player skill data
    

### 玩家統計數據

**可修改暱稱、修改email(要傳送驗證信) (11/30)**

可以將玩家的統計數據顯示出來給玩家看。
```mermaid
sequenceDiagram
    participant 前端
    participant APP
    participant Server
    APP->>APP: 檢查token是否還有效
    alt token已過期
        APP-->>前端: 請從新登入
    else token還有效
        APP->>Server: 送出user's token
        Server->>Server: 搜尋token
        Server->>APP: 送出等級，排名，total match played, total match won
        APP->>APP: 計算勝率
        APP->>前端: 送出等級，排名，total match played, total match won, 勝率
    end
    
```
**前端使用方法：**
Output: user的數據

**Server需要的功能:**
Input: user's token
Output: user是否存在，user的數據


### 玩家成就系統

可以將玩家所得到的成就按照他的分類顯示出來。
```mermaid
sequenceDiagram
    participant 前端
    participant APP
    participant Server
    前端->>APP: 請求查看玩家成就
    APP->>APP: 檢查token是否還有效
    alt token已過期
        APP-->>前端: 請重新登入
    else token還有效
        APP->>Server: 送出user's token
        Server->>Server: 搜尋user's token
        Server->>APP: 送出user所得的成就名單
        APP->>APP: 成就分類
        note over APP: (on db achievement_type)<br/> 1. 有功能:協助遊戲進行<br/>ex: 新手玩家 ( 配對機制友善 )<br/>2. 無功能:增加遊戲趣味姓<br/>ex: 革命家 ( 連續三場以平民打敗王 )<br/>3. 顯示於玩家資料
        APP->>前端: 送出結果
    end
```
**前端使用方法**：
Output: user的數據

**Server需要的功能**:
Input: user’s token
Output: user是否存在，user的數據


### 用戶設定儲存系統

該功能提供以下功能。
a. 更改名字
b. 更改背景音樂
c. 調整音量
d. 更改背景主題

---

**a. ~~更改名字(nickname)~~**

**合併進玩家資料顯示 (11/30)**

輸入
- **UI** 新的名字
- **APP** 帳號，新的名字
輸出
- **Server** 通知儲存成功

```mermaid
sequenceDiagram
    participant UI
    participant APP
    participant Server
    UI->>UI    : 按更改名字
    UI->>UI    : 輸入新的名字
    note right of UI: 檢查不可以使用的字
    UI->>APP   : 檢證過的新的名字
    APP->>Server: 傳送帳號，新的名字
    Server->>Server: 儲存新的名字
    Server->>APP: 通知儲存成功
    Server-->>APP: 通知儲存失敗
    APP->>UI    : 顯示新的名字
    APP-->>UI    : 顯示錯誤訊息
```

---

**b. 更改背景音樂(background music)**

該功能可以更改遊戲過程中播放的 BGM。
BGM 更改流程如下所示。

```mermaid
sequenceDiagram
    participant UI
    participant APP
    UI->>UI    : 按背景音樂
    UI->>APP   : 音量分類ID
    APP->>APP: 更改播放背景音樂ID
    APP->>UI    : 播放
```

---

**c. 調整音量(system volume, Voice volume, etc)**

該功能可調節背景音樂和音效的音量。
音量控制流程如下所示。

```mermaid
sequenceDiagram
    participant UI
    participant APP
    UI->>UI    : 按調整音量
    UI->>APP   : 音量分類ID，數值
    APP->>APP: 更改音量變數的數值
    APP->>UI    : 播放
```

---

**d. 更改背景主題(background theme)**

該功能可以更改背景主題。
更改背景主題的流程如下所示。

```mermaid
sequenceDiagram
    participant UI
    participant APP
    UI->>UI    : 按背景主題
    UI->>APP   : 背景主題ID
    APP->>APP: 更改背景主題ID
    APP->>UI    : 換背景主題
```

### 新手教學系統

•	獨立進行
•	使用影片教學
•	首次完成獲得抽卡機會
•	於遊戲主頁面UI進入

# 資料庫設計
使用方法:https://hackmd.io/E-PElFT2SK2UcInpVP0Wfw

decimal都是(4,3)
```mermaid
erDiagram
    account ||--o{ account_card_styles : ""
    account ||--o{ account_skills : ""
    account ||--o{ account_achievement : ""
    account ||--o{ account_data: ""
    account_card_styles }o--|| card_style : ""
    account_skills }o--|| skill : ""
    account_achievement }o--|| achievement : ""
    account{
        int id PK "Player ID"
        varchar name "Account name"
        varchar email
        varchar password
        varchar token_id "UniqueKey"
        timestamp token_validity
        varchar verify_code
        timestamp expiration_time
        varchar salt
    }
    account_card_styles{
        int id PK
        int account_id FK
        int card_style_id FK
    }
    card_style{
        int card_style_id PK
        int card_style_name
        varchar card_style_description
        decimal card_probability
    }
    account_skills{
        int id PK
        int account_id FK
        int skill_id FK
    }
    skill {
        int skill_id PK
        varchar skill_name
        varchar skill_description
        decimal skill_probability
    }
    
    account_achievement{
        int id PK
        int account_id FK
        int achievement_id FK
    }
    achievement{
        int achievement_id PK
        varchar achievement_name
        varchar achievement_type
        varchar achievement_description
    }
    account_data{
        int account_id FK
        varchar nickname "Player name"
        int level
        int experience
        varchar rank
        int total_match
        int total_win
        int ranked_winning_streak
        int ranked_XP
        int coin
    }
```    

# 資安要求
1.	行動應用程式應於發布時說明欲存取之敏感性資料、行動裝置資源及宣告之權限用途
2.	行動應用程式開發者應提供回報安全性問題之管道
3.	行動應用程式應於蒐集敏感性資料前，取得使用者同意
4.	行動應用程式應提供使用者拒絕蒐集敏感性資料之權利
5.	行動應用程式應於儲存敏感性資料前，取得使用者同意
6.	行動應用程式應提供使用者拒絕儲存敏感性資料之權利
7.	行動應用程式應避免在關閉及登出後將敏感性資料儲存於冗餘檔案或日誌檔案中
8.	行動應用程式應避免將敏感性資料儲存於冗餘檔案或日誌檔案中
9.	敏感性資料應採用適當且有效之金鑰長度與加密演算法，進行加密處理再儲存
10.	敏感性資料應儲存於受作業系統保護之區域，以防止其他應用程式未經授權之存取
11.	敏感性資料應避免出現於行動應用程式之程式碼
12.	行動應用程式於非使用者主動進行的畫面擷取時應主動警示使用者
13.	行動應用程式應將個人可識別資訊、使用者憑證及加密金鑰等敏感性資料儲存於系統憑證儲存設施
14.	行動應用程式應於使用者輸入敏感性資料時將鍵盤的快取機制關閉
15.	行動應用程式應避免在 IPC 機制中洩漏敏感性資料
16.	行動應用程式中的使用者介面應避免洩漏敏感性資料
17.	行動作業系統的備份資料中不應存有行動應用程式的敏感性資料
18.	行動應用程式透過網路傳輸敏感性資料，應使用適當且有效之金鑰長度與加密演算法進行安全加密
19.	行動裝置內之不同行動應用程式間，應於分享敏感性資料前，取得使用者同意
20.	行動應用程式應提供使用者拒絕分享敏感性資料之權利
21.	行動應用程式分享敏感性資料時，應避免未授權之行動應用程式存取
22.	行動應用程式應於使用交易資源時主動通知使用者
23.	行動應用程式應提供使用者拒絕使用交易資源之權利
24.	行動應用程式應於使用交易資源時進行使用者身分鑑別
25.	行動應用程式應記錄使用之交易資源與時間
26.	行動應用程式應有適當之身分鑑別機制，確認使用者身分
27.	行動應用程式應依使用者身分授權
28.	行動應用程式應避免使用具有規則性之交談識別碼
29.	行動應用程式應確認伺服器憑證之有效性
30.	行動應用程式應確認伺服器憑證為可信任之憑
31.	行動應用程式應避免含有惡意程式碼
32.	行動應用程式應避免資訊安全漏洞
33.	行動應用程式於引用之函式庫有更新時，應備妥對應之更新版本
34.	行動應用程式應針對使用者於輸入階段之字串，進行安全檢查
35.	行動應用程式應提供相關注入攻擊防護機制
36.	行動應用程式於 Webview 呈現功能時，所連線之網域應為安全網域

# 伺服器規劃
**放上面的東西**
* 遊戲判定
* 抽卡
* 玩家資料
* 玩家連線
* 金流系統
* 資料庫

**虛擬機規格：**
* OS: ubuntu server 22.04
* IP: 140.122.185.169
* 儲存空間: 160G
**直接把程式碼拉到伺服器，不要在上面跑docker**

**使用docker讓後端開發**
docker：https://github.com/ToshaETang/SWEgroup3/tree/main/docker/nginx-flask-mysql

# git
專案位置: https://github.com/NTNU-SWE-GROUP3/SWEgroup3

**branches名稱&所屬**
main：主要的(基本上不動)
dev：總開發支線
body：遊戲本體組
gaming：遊戲本體B組
~~UI：設計組~~ 合併進dev (11/30)
other-function：其他功能組
other-function-player-setting：其他功能組-玩家資料顯示修改
other-function-bp：其他功能組-背包
backend 
document：文件在這裡改
gacha：遊戲本體組-抽卡
gacha_errorPage：遊戲本體組-抽卡