# 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分執行