---
# System prepended metadata

title: W1遊戲接入

---

# W1遊戲接入
### 1. W1部分
:green_book: 參考 \Model\Game\RTG\
1. 將遊戲館加入OpenGame(appsettings.DEV.json)
```json
"OpenGame": "SABA,RCG,JDB,DS,PG,AE,STREAMER,RSG,RLG,TP,RTG,JILI,JOKER"
"RTG_URL": "https://api.rbgamerp2.com/",
"RTG_Client_ID": "Tp2fTILl2Q2RpIzC",
"RTG_Secret": "I%9FJ*O$vDDcEO1g24",
"RTG_Key": "G6scW9lq",
"RTG_IV": "qbZogH8s",
"RTG_SystemCode": "h1sys",
"RTG_WebID": "webdev"
```
2. 註冊Service (Startup.cs)
```csharp
services.AddScoped<IRTGApiService, RTGApiService>();
services.AddSingleton<RtgRecordSchedule>();
services.AddSingleton<RtgReportSchedule>();
services.AddSingleton<RtgAuditSchedule>();
```
3. 設定Schedule (Startup.cs)
```csharp
scheduler.Schedule<RtgRecordSchedule>().EverySeconds(20).Zoned(TimeZoneInfo.Local).PreventOverlapping("RtgRecordScheduleLock");
scheduler.Schedule<RtgReportSchedule>().Cron("10 01 * * *").Zoned(TimeZoneInfo.Local).PreventOverlapping("RtgReportScheduleLock");
scheduler.Schedule<RtgAuditSchedule>().Cron("20 01 * * *").Zoned(TimeZoneInfo.Local).PreventOverlapping("RtgAuditSchedule");
```  
### 2. 建立遊戲館API Request/Response Modle
:green_book: 參考 \Model\Game\RTG\
                                      
### 3. 遊戲API HTTP Service
:pencil2: 實作與遊戲館http requset 模型包含加解密與資料驗證

**reponse 需紀錄**
* GCP log request/response參數
```csharp!
var dics = new Dictionary<string, object>
{
    { "request", reqJson },
    { "response", responselog }
};
using (var scope = _logger.BeginScope(dics))
{
    _logger.LogInformation("Get RequestPath: {RequestPath} | ResponseHttpStatus:{Status} | exeTime:{exeTime} ms", url, response.StatusCode, sw.Elapsed.TotalMilliseconds);
}
``` 
* 遊戲館health參數
```csharp!
apiResInfo.ElapsedMilliseconds = sw.ElapsedMilliseconds;
_ = _apiHealthCheckService.SetResponseData(Platform.RTG, apiResInfo);
```

:green_book: 參考 \Service\Game\RTG\RTGApiService.cs (ApiHandle)

### 4. 建立遊戲館 API Service
:pencil2:實作必要與遊戲館溝通API

:green_book: 參考 \Service\Game\RTG\RTGApiService.cs

### 5. 實作遊戲IGameInterfaceService
:green_book: 參考 \Service\Game\RTG\RTG_InterfaceService.cs

#### 5.1 建立使用者 CreateGameUser
:::info
新接遊戲館請固定加上3個字元prefix key(定義在appsettings)
```json
    "WalletMode": "TransferWallet",
    "RCGMode": "H1",
    "Prefix_Key": "dev",
    "OpenGame": "SABA,RCG,JDB,DS,PG,AE,STREAMER,RSG,RLG,TP,RTG,JILI,JOKER"
```
:::
#### 5.2 登出使用者 KickUser
#### 5.3 登出所有使用者 KickAllUser
#### 5.4 轉入餘額 Deposit 
:::info
交易結果要回傳3個狀態
1. success : 遊戲回傳成功
2. fail : 遊戲回傳交易失敗(需要是遊戲定義error code 保證失敗無異動金額)
3. pending : 遊戲回傳狀態不明/延遲, 或是request time out
:::
#### 5.5 轉出餘額 WithDraw
 同5.4
#### 5.6 取得登入連結 Login
 幣別/語系等相關參數 資料轉換請定義在\Model\Game\遊戲館ID\遊戲館ID.cs
 
:green_book: 參考 \Model\Game\RTG\RTG.cs
 
 #### 5.7 查詢交易結果 CheckTransferRecord
 實作交易pending重新查詢
 :::warning
 遊戲館若回傳不明確不可變更狀態
 測試此功能可先將遊戲館轉帳timeout時間改成10-50ms
 :::
 
 #### 5.8 取得遊戲調閱URL GameDetailURL
 若遊戲舘不支援須提出討論
 
 #### 5.9 設定遊戲館線上清單　SetOnlineUser 
 :::info
 遊戲館若不支援改使用last_platform 判斷是否在線
 要回傳club_id 非遊戲中id (去除前/後綴)
 club_ename與frachiser_id 保持null即可
 :::

 #### 5.10 取得遊戲館線上清單 getOnlineUser
 
 #### 5.11 取得遊戲明細 getGameRecordList
 :::danger
 請等W1核心部分(BetRecordService)新增介面
 :::

### 6. 實作遊戲注單相關
 :::info
目前介面尚未統一, 分每個遊戲館自訂介面與實作
 :::
#### 6.1 寫入遊戲注單 PostRtgRecord
包含遊戲注單明細(t_rtg_bet_record), 5分鐘匯總帳(t_bet_record_summary)
注單明細player id 使用遊戲館內id
5分鐘匯總帳player 使用H1 club_id (注意要去除前/後綴)
:question: 匯總帳需確認是否要區分遊戲類型
#### 6.2 W1報表 SummaryW1Report
#### 6.3 遊戲館報表 SummaryGameProviderReport
若遊戲館沒提供報表API先忽略

### 7. 注單重拉
需要將輸入時間分段拉取(建議10分鐘1段)
```csharp
var RepairCount = 0;
while (RepairReq.EndTime.Subtract(startTime).TotalMinutes > 10)
{
    endTime = startTime.AddMinutes(10);
    _logger.LogDebug("Repair RTG record start Time : {startTime} end Time : {endTime}", startTime, endTime);
    RepairCount += await RepairRtg(startTime, endTime);
    startTime = endTime;
    await Task.Delay(1000);
}
_logger.LogDebug("Repair RTG record start Time : {startTime} end Time : {endTime}", startTime, RepairReq.EndTime);
RepairCount += await RepairRtg(startTime, RepairReq.EndTime);
```
* 要確認起始與結束時間的格式與遊戲館拉取是否包含該段時間
* 重補注單需要取得W1明細先排除重複的再寫入
* 注單重拉之後要重新產出報表
* 要回傳新增注單筆數

### 8. 建立排程
排程需要將執行參數自動建立並寫入DB
排程需要可重工具平台設定參數關閉
```csharp
    t_system_parameter parameter = null;
    // 取得當前時間，計算下一個帳務比對的時間
    var now = DateTime.Now.ToLocalTime();
    now = now.AddDays(-1);
    var nextTime = new DateTime(now.Year, now.Month, now.Day, 0, 0, 0);
    var key = "RtgAuditSchedule";

    // 取得帳務比對的時間基準
    parameter = await _commonService._serviceDB.GetSystemParameter(key);

    // 檢查有無資料，沒資料的話新增預設值
    if (parameter == null)
    {
        var model = new t_system_parameter()
        {
            key = key,
            value = nextTime.ToString("yyyy-MM-dd HH:mm:ss"),
            min_value = string.Format("{0}", 1),
            name = "RTG 每小時遊戲帳務比對排程",
            description = "RTG 紀錄帳務比對排程時間基準點"
        };

        var postSystemParameter = await _commonService._serviceDB.PostSystemParameter(model);
        if (postSystemParameter)
        {
            parameter = model;
        }
        else
        {
            return; // 新增失敗就結束排程
        }
    }
```
#### 8.1 注單排程 DsRecordSchedule
若是使用Max Id可參考 PgRecordSchedule
若是使用時間區間拉單可參考 DsRecordSchedule
排程執行時間請先參考DS遊戲
```csharp
scheduler.Schedule<DsRecordSchedule>().EverySeconds(20).Zoned(TimeZoneInfo.Local).PreventOverlapping("DsRecordScheduleLock").RunOnceAtStart();
scheduler.Schedule<DsReportSchedule>().Cron("0,20,40 * * * *").PreventOverlapping("DsReportScheduleLock").Zoned(TimeZoneInfo.Local);
scheduler.Schedule<DsAuditSchedule>().Cron("10,30,50 * * * *").PreventOverlapping("DsAuditScheduleLock").Zoned(TimeZoneInfo.Local);
```
:rotating_light:請注意遊戲商拉回是否會有重複資料
:rotating_light:請注意注單拉取時間是否有包含起始與結束時間
#### 8.2 遊戲注單報表排程 DsReportSchedule
每個遊戲商產生報表時間不盡相同, 目前預設2小時後執行
需確認時間後再決定執行排程時間
#### 8.3 遊戲注單檢查排程 DsAuditSchedule
遊戲注單報表產生後10分執行
