Webhooks
概述
Webhooks主要用於擁有受信任的遊戲配置和房間組成來源,並可大幅提升線上應用程式的安全性。
預設的雲端外掛程式支援透過AppID儀表板定義的不同鉤子。
一旦設定並啟用後,Photon Cloud會向自訂後端發送WebRequests(HTTP POST),並會使用回應資料(Json)對Photon房間和遊戲階段進行各種配置。
安裝
在Photon儀錶板上,每個AppId都啟用了Webhooks。
- 導航到Photon儀錶板並登入。
- 找到AppId並按一下
Manage。 - 向下滾動到挿件,然後按一下
Edit。 - 按一下
Add New Pair並添加keys和values(每個設定值允許的最大長度為1024個字元)。 - 按
Save,等待更改生效最多一分鐘。
儀錶板配置
| 鍵 | 類型 | 示例 | 描述 |
|---|---|---|---|
| WebHookBaseUrl | string |
https://localhost:3581 |
自定義後端的基本url。將附加Webhook路徑,導致路徑格式為:{WebHookBaseUrl}/game/create必須始終設定。 |
| WebHookIntegration | string |
Default |
所選的webhook集成(預設值為Default)。Default, PlayFab |
| WebHookSecret | string |
********** |
這將與每個web請求一起發送,可用於對請求進行身份驗證。 將設定名為X-SecretKey的標頭。 |
| WebHookCustomHttpHeaders | Dictionary <string, string> |
{"A": "Foo", "B": "100" } |
JSON字典。所有條目都將添加到自定義web請求標頭中。確保使用雙引號。 |
| WebHookEnableOnCreate | bool |
true |
如果設定為true,則當用戶端創建遊戲會話時,將觸發CreateGame webhook。 |
| WebHookEnableOnClose | bool |
false |
如果設定為true,則當遊戲會話關閉時,將觸發CloseGame webhook。 |
| WebHookEnableOnJoin | bool |
true |
如果設定為true,則當任何用戶端嘗試加入遊戲會話時,將觸發JoinGame webhook。 |
| WebHookEnableOnLeave | bool |
false |
如果設定為true,則當任何用戶端離開遊戲會話時,將觸發LeaveGame webhook |
| WebHookUrl{KEY} | string |
https://foo.net/path |
此模式是可選的,可用於覆蓋基於單個Webhook的WebHookBaseUrl的默認路徑。{KEY}的有效替代品是OnCreate, OnJoin, OnLeave等。 |
| WebHookBaseUrlAllowList | Dictionary<string, string> |
{ "one": "https://foo-one", "two": "https://foo-two" } |
基本url允許清單,用戶端可以通過將金鑰添加為房間内容“QuantumWebHookBaseUrl”來選擇金鑰。
MatchmakingArguments.CustomProperties = new PhotonHashtable() { { RoomProperties.WebHookBaseUrl, "two" } }
如果用戶端發送的金鑰與允許清單中的條目匹配,它將替換會話中所有Webhook的 WebHookBaseUrl。 如果找不到金鑰,則會記錄一條警告,並使用WebHookBaseUrl。
|
| WebHookDefaultTimeout | int |
60 |
覆蓋Photon Server應用於webhooks的默認超時(以秒為組織)(30秒)。 |
Quantum儀表板設定
| 鍵值 | 類型 | 示例 | 描述 |
|---|---|---|---|
| WebHookEnableGameConfigs | bool |
false |
若設為true,當用戶端使用StartRequest操作上傳遊戲設定RuntimeConfig和SessionConfig時,將觸發GameConfigs webhook。 |
| WebHookEnableGameResult | bool |
false |
若設為true,將呼叫GameResult webhook。 |
| WebHookEnableAddPlayer | bool |
false |
若設為true,用戶端操作AddPlayer將呼叫AddPlayer web 請求。 |
| WebHookEnablePlayerAdded | bool |
false |
若設為true,在玩家成功加入 Quantum 線上遊戲後,將呼叫PlayerAdded web 請求。 |
| WebHookEnablePlayerRemoved | bool |
false |
若設為true,在玩家被從 Quantum 遊戲中移除後,將呼叫PlayerRemoved web 請求。 |
| WebHookEnableReplay | bool |
false |
設為true將根據ReplayStart和ReplayChunk web 請求啟用重播串流。 |
Webhook API
Webhooks傳送Json內容且只接受Json內容作為回應。Json使用UTF-8字元集是強制性的。
Webhooks期望HTTP回應代碼為200或400:
200: 請求成功。400: 錯誤或操作已被拒絕(例如,客戶端不能建立房間/遊戲會話)。
Photon伺服器在傳輸錯誤後會重試三次網鉤(webhook),同樣在收到狀態碼 503(服務不可用)後,也會分別延遲400毫秒、1600毫秒和6400毫秒進行重試。請求失敗且不再重試前的超時時間為10秒。
填寫WebhookError定義,以將錯誤性質的資訊回傳至Photon外掛程式。其可用於:
- 日誌記錄;
- 將資訊回傳給客戶;
- 一個自訂外掛程式,用以新增進一步的自訂錯誤處理;
Http請求重試
Photon Server會對來自後端的可重試錯誤回應作出反應,額外重新發送請求三次。
後續的請求有不同的標頭以識別它們。
EGRepeatId - 重複的數字,例如 0、1、2 或 3 (int)
EGInvokeId - 請求識別碼 (int)
常見的請求頭
這些常見的請求頭被添加到每個web請求中。
| 名稱 | 類型 | 內容 | 描述 |
|---|---|---|---|
| 接受 | string |
application/json |
Webhooks只接受JSON作為響應體 |
| 接受字元集 | string |
utf-8 |
Webhooks只接受utf-8作為響應體字元集 |
| 內容類型 | string |
application/json |
Webhooks都發送JSON正文數據 |
| X-SecretKey | string |
********** |
此金鑰只應為自定義後端所知,並應用於對傳入的web請求進行身份驗證。這在Photon儀錶板上設定為WebHookSecret。 |
| X-Origin | string |
Photon |
將始終設定為“Photon” |
CreateGame
在Photon服務器上創建房間/遊戲會話之前,會調用此webhook。在webhook收到響應之前,創建將被封鎖,這將影響用戶端創建連接所需的時間。
CreateGame webhook始終是發起房間/遊戲會話創建的用戶的JoinGame請求。此用戶將沒有後續的JoinGame webhook。此webhook共享來自JoinGame webhook的數據。
需要在Photon儀錶板上設定WebHookBaseUrl及WebHookEnableCreateGame。
JavaScript
POST https://{WebHookBaseUrl}/game/create
CreateGame請求
| 名稱 | 類型 | 示例 | 描述 |
|---|---|---|---|
| AppId | string |
d1f67eec-51fb-45c1 |
Photon AppId。 |
| AppVersion | string |
1.0-live |
創建房間/遊戲會話時使用的AppVersion。 |
| 地區 | string |
eu |
創建房間/遊戲會話的遊戲服務器的地區碼。 |
| Cloud | string |
1 |
運行遊戲服務器的Cloud Id。 |
| UserId | string |
db757806-8570-45aa |
創建房間/遊戲會話的用戶端的UserId。 |
| AuthCookie | Dictionary<string, object> |
db757806-8570-45aa |
後端設定的Photon自定義身份驗證cookie。 |
| RoomName | string |
e472a861-a1e2-49f7 |
房間/遊戲會話名稱。 |
| GameId | string |
0:eu:e472a861-a1e2-49f7 |
一個唯一的GameId,由{Cloud:}{Region:}RoomName組成。可以在響應中覆蓋。 |
| EnterRoomParams | EnterRoomParams |
JSON:請參閱EnterRoomParam部分 |
用戶端發送的Photon房間/遊戲會話選項。 |
Json範例:
JSON
{
"AppId": "d1f67eec-51fb-45c1",
"AppVersion": "1.0-live",
"Region": "eu",
"Cloud": "1",
"UserId": "db757806-8570-45aa",
"AuthCookie": {
"Secret": "**********"
}
"RoomName": "e472a861-a1e2-49f7",
"GameId": "0:eu:e472a861-a1e2-49f7",
"EnterRoomParams": {
"RoomOptions": {
"IsVisible": true,
"IsOpen": true
}
}
}
HTTP回應碼
| 名稱 | 類型 | 描述 |
|---|---|---|
| 200 OK | CreateGame Response |
房間/遊戲會話創建可以開始,響應中的配置數據將覆蓋用戶端發送的數據。 |
| 400 Bad Request | WebhookError |
不允許創建房間/遊戲會話,將被取消。 用戶端將收到一個錯誤。 |
CreateGame回應
| 名稱 | 類型 | 描述 |
|---|---|---|
| GameId | string |
覆蓋後續web請求中使用的GameId。可以是null或省略。 |
| EnterRoomParams | EnterRoomParams |
在創建時強制執行選定的“房間選項”。JSON對象不必包含所有成員,只需包含應被覆蓋的成員。發送 EnterRoomParams僅保護初始選項。其中大多數可以通過用戶端發送Photon Room内容進行更改。 要封鎖此操作,請啟用Photon儀錶板内容BlockRoomProperties。 可以是null或省略。 |
| 名稱 | 類型 | 描述 |
|---|---|---|
SessionConfig |
SessionConfig |
傳回遊戲使用的SessionConfig物件。用戶端傳送的遊戲設定將被忽略。 |
RuntimeConfig |
RuntimeConfig |
傳回遊戲使用的RuntimeConfig物件。用戶端傳送的遊戲設定將被忽略。 |
RuntimePlayer |
RuntimePlayer |
傳回用於建立此房間 / 工作階段的用戶端的RuntimePlayer物件。這僅會覆寫為玩家位置 0傳送的第一個AddPlayer資料。MaxPlayerSlots應設為1。 |
MaxPlayerSlots |
int |
此用戶端可以取得的最大玩家位置數:0 = 僅觀戰1..255 = 特定數量-1 = 無限制若傳送此回應但未設定此值, MaxPlayerSlots將預設為 1。請求無效玩家位置編號或超過允許數量的玩家將被中斷連線。 |
SnapshotsBlocked |
bool |
若有其他用戶端可用,此玩家將不會被選取用於向其他玩家傳送遊戲快照。 |
StartPropertyBlockedTimeSec |
int |
建立房間後啟動 Quantum 之前的最小延遲(以秒為單位),確保玩家有足夠時間加入。大於零的值會啟用此功能。 |
StartPropertyForcedTimeSec |
int |
建立房間後啟動 Quantum 之前的最大延遲(以秒為單位)。超過此時間將自動啟用 "StartQuantum"(若尚未設定)。大於零的值會啟用此功能。 |
HideRoomAfterStartSec |
int |
房間內 Quantum 啟動後,房間將從公開清單中隱藏的秒數。大於零的值會啟用此功能。 |
CloseRoomAfterStartSec |
int |
房間內 Quantum 啟動後,房間將關閉以防止新玩家加入的秒數。大於零的值會啟用此功能。 |
Json範例:
JSON
{
"AppId": "d1f67eec-51fb-45c1",
"GameId": "0:eu:db757806-8570-45aa",
"EnterRoomParams": {
"RoomOptions": {
"IsVisible": true,
"IsOpen": true
}
},
"SessionConfig": {
"PlayerCount": 8,
"ChecksumCrossPlatformDeterminism": false,
"UpdateFPS": 30
},
"RuntimeConfig": {
"Map": {
"Id": {
"Value": 94358348534
}
}
},
"RuntimePlayer": {
"Name": "player1"
},
"MaxPlayerSlots": 2,
"SnapshotsBlocked": true
}
JoinGame
在用戶端加入現有的房間/遊戲會話之前,會發送JoinGame webhook。 返回200表示允許加入,返回400表示取消加入。
需要在Photon AppId儀錶板上設定WebHookBaseUrl和WebHookEnableOnJoin。
JavaScript
POST https://{WebHookBaseUrl}/game/join
JoinGame請求
| 名稱 | 類型 | 示例 | 描述 |
|---|---|---|---|
| AppId | string |
d1f67eec-51fb-45c1 |
Photon AppId |
| GameId | string |
0:eu:db757806-8570-45aa |
唯一GameId |
| UserId | string |
db757806-8570-45aa |
Photon UserId |
| AuthCookie | Dictionary<string, object> |
db757806-8570-45aa |
後端設定的Photon自定義身份驗證cookie。 |
Json範例:
JSON
{
"AppId": "*******************",
"GameId": "0:eu:db757806-8570-45aa",
"UserId": "db757806-8570-45aa",
"AuthCookie": {
"Secret": "**********"
}
}
HTTP回應碼
| 名稱 | 類型 | 描述 |
|---|---|---|
| 200 OK | JoinGame回應 |
客戶將加入房間。 |
| 400 Bad Request | WebhookError |
加入房間將失敗。 |
JoinGame回應
| 名稱 | 類型 | 描述 |
|---|---|---|
| RuntimePlayer | RuntimePlayer |
傳回用於建立此房間 / 工作階段的用戶端的RuntimePlayer物件。這僅會覆寫為玩家位置 0傳送的第一個AddPlayer資料。MaxPlayerSlots應設為1。 |
| MaxPlayerSlots | int |
此用戶端可以取得的最大玩家位置數:0 = 僅觀戰1..255 = 特定數量-1 = 無限制若傳送此回應但未設定此值, MaxPlayerSlots將預設為 1。請求無效玩家位置編號或超過允許數量的玩家將被中斷連線。 |
Json範例:
JSON
{
"RuntimePlayer": {
"Name": "player1"
},
"MaxPlayerSlots": 1
}
提示
較好的做法是使用AddPlayer傳回RuntimePlayer資料,因為其請求將包含用戶端傳送的RuntimePlayer用戶端物件。
另請考慮使用CreateGame回應為使用者保留玩家位置(若當時已知道使用者)。
LeaveGame
LeaveGame webhook是在用戶端離開現有的房間/遊戲會話後發送的。
需要在Photon AppId儀錶板上設定WebHookBaseUrl及WebHookEnableOnLeave。
JavaScript
POST https://{WebHookBaseUrl}/game/leave
LeaveGame請求
| 名稱 | 類型 | 示例 | 描述 |
|---|---|---|---|
| AppId | string |
d1f67eec-51fb-45c1 |
Photon AppId |
| GameId | string |
0:eu:db757806-8570-45aa |
唯一GameId |
| UserId | string |
db757806-8570-45aa |
Photon UserId |
| ActorNr | int |
db757806-8570-45aa |
Photon角色編號,用戶端的遞增運行階段id。 |
| AuthCookie | Dictionary<string, object> |
db757806-8570-45aa |
Photon UserId |
| IsInactive | bool |
false |
當離開房間的玩家仍被標記為非活動狀態時,例如當設定了PlayerTTL時,true。 在這種情況下,可以提出其他LeaveGame請求。 |
| FailedOnCreate | bool |
false |
此標誌表示此離開遊戲webhook是為創建房間失敗的用戶端調用的。 |
Json範例:
JSON
{
"AppId": "*******************",
"GameId": "0:eu:db757806-8570-45aa",
"UserId": "db757806-8570-45aa",
"ActorNr": 1,
"AuthCookie": {
"Secret": "**********"
},
"IsInactive": false,
"FailedOnCreate": false
}
HTTP回應碼
| 名稱 | 類型 | 描述 |
|---|---|---|
| 200 OK | LeaveGame Response |
只是確認收到。 |
| 400 Bad Request | WebhookError |
錯誤被忽略,它將被記錄在Photon Cloud上。 |
LeaveGame回應
Json範例:
JSON
{
}
CloseGame
當所有用戶端離開後,房間/遊戲會話關閉時,會發送CloseGame webhook。
需要在Photon儀錶板上設定WebHookBaseUrl及WebHookEnableOnClose。
JavaScript
POST https://{WebHookBaseUrl}/game/close
CloseGame請求
| 名稱 | 類型 | 示例 | 描述 |
|---|---|---|---|
| AppId | string |
d1f67eec-51fb-45c1 |
Photon AppId |
| GameId | string |
0:eu:db757806-8570-45aa |
唯一遊戲id |
| CloseReason | int (CloseReason) |
0 |
本會議室/環節關閉的原因。 |
Json範例:
JSON
{
"GameId": "0:eu:db757806-8570-45aa",
"CloseReason": 0
}
HTTP回應碼
| 名稱 | 類型 | 描述 |
|---|---|---|
| 200 OK | 確認收到。 |
CloseReason
| 名稱 | 值 | 描述 |
|---|---|---|
| Ok | 0 |
會話已關閉,沒有錯誤。 |
| FailedOnCreate | 1 |
會話已關閉,因為創建失敗。 |
GameConfigs
當玩家傳送附加遊戲設定RuntimeConfig和SessionConfig的StartRequest操作時,將傳送GameConfigs webhook。
此 webhook 僅在任何用戶端的啟動操作首次到達時,每個房間傳送一次。
需要在 Photon 儀表板上設定WebHookBaseUrl和WebHookEnableGameConfigs。
JavaScript
POST https://{WebHookBaseUrl}/game/configs
GameConfigs請求
| 名稱 | 類型 | 示例 | 描述 |
|---|---|---|---|
| AppId | string |
d1f67eec-51fb-45c1 |
Photon AppId |
| GameId | string |
0:eu:db757806-8570-45aa |
唯一遊戲 ID。 |
| UserId | string |
db757806-8570-45aa |
Photon UserId |
| ActorNr | int |
db757806-8570-45aa |
Photon 參與者編號,用戶端的遞增執行時間 ID。 |
| RuntimeConfig | RuntimeConfig |
{ "Level": 1 } |
用戶端傳送到外掛程式的RuntimeConfig物件。可為 null。 |
| SessionConfig | SessionConfig |
{ "PlayerCount": 8, .. } |
用戶端傳送到外掛程式的SessionConfig物件。可為 null。 |
| AuthCookie | Dictionary<string, object> |
db757806-8570-45aa |
後端設定的 Photon 自訂驗證 Cookie。 |
Json範例:
JSON
{
"AppId": "d1f67eec-51fb-45c1",
"GameId": "0:eu:db757806-8570-45aa",
"UserId": "db757806-8570-45aa",
"ActorNr": 1,
"RuntimeConfig": {
"Map": {
"Id": {
"Value": 94358348534
}
}
},
"SessionConfig": {
"PlayerCount": 8,
"ChecksumCrossPlatformDeterminism": false,
"LockstepSimulation": false,
//..
},
"AuthCookie": {
"Secret": "**********"
}
}
HTTP回應碼
| 名稱 | 類型 | 描述 |
|---|---|---|
| 200 OK | GameConfigs Response |
遊戲啟動序列可以繼續。附加到回應的遊戲設定應被覆寫。 |
| 400 Bad Request | WebhookError |
遊戲將終止,所有用戶端都會被中斷連線。 |
GameConfigs回應
回應中的兩個物件都可以是null,以接受用戶端傳送的設定。否則它們將被覆寫。
| 名稱 | 類型e | 描述 |
|---|---|---|
| RuntimeConfig | RuntimeConfig |
用於覆寫用戶端傳送的RuntimeConfig物件。 |
| SessionConfig | SessionConfig |
用於覆寫用戶端傳送的SessionConfig物件。 |
Json範例:
JSON
{
"RuntimeConfig": {
"Map": {
"Id": {
"Value": 94358348534
}
}
},
"SessionConfig": {
"PlayerCount": 8,
"ChecksumCrossPlatformDeterminism": false,
"LockstepSimulation": false,
//..
}
}
AddPlayer
當用戶端嘗試使用AddPlayer操作將玩家加入 Quantum 線上遊戲時,將傳送AddPlayer webhook。
即使此 webhook 傳回,若沒有免費的玩家位置,將玩家加入線上遊戲仍可能失敗。使用PlayerAdded webhook 追蹤玩家的線上狀態。
需要在 Photon 儀表板上設定WebHookBaseUrl和WebHookEnableAddPlayer。
JavaScript
POST https://{WebHookBaseUrl}/player/add
AddPlayer請求
| 名稱 | 類型 | 示例 | 描述 |
|---|---|---|---|
| AppId | string |
d1f67eec-51fb-45c1 |
Photon AppId |
| GameId | string |
0:eu:db757806-8570-45aa |
唯一遊戲 ID。 |
| UserId | string |
db757806-8570-45aa |
Photon UserId 或 ClientId。 |
| ActorNr | int |
db757806-8570-45aa |
Photon 參與者編號,用戶端的遞增執行時間 ID。 |
| PlayerSlot | int |
0 |
請求的玩家位置。通常是 0。 |
| RuntimePlayer | RuntimePlayer |
{ "Foo": 222 } |
用戶端傳送到外掛程式的RuntimePlayer物件。可為 null。 |
| AuthCookie | Dictionary<string, object> |
db757806-8570-45aa |
後端設定的 Photon 自訂驗證 Cookie。 |
Json範例:
JSON
{
"AppId": "d1f67eec-51fb-45c1",
"GameId": "0:eu:db757806-8570-45aa",
"UserId": "db757806-8570-45aa",
"ActorNr": 1,
"PlayerSlot": 0,
"RuntimePlayer": {
"Name": "player1"
},
"AuthCookie": {
"Secret": "**********"
}
}
HTTP回應碼
| 名稱 | 類型 | 描述 |
|---|---|---|
| 200 OK | AddPlayer Response |
用戶端可以將玩家加入選定的玩家位置,並可選擇從後端接收RuntimePlayer物件。 |
| 400 Bad Request | WebhookError |
用戶端無法加入玩家,並將收到錯誤協定訊息和回呼:OnLocalPlayerAddFailed。 |
AddPlayer回應
| 名稱 | 類型 | 描述 |
|---|---|---|
| RuntimePlayer | object |
用於覆寫用戶端傳送的RuntimePlayer的RuntimePlayer物件。若為null,將接受用戶端的RuntimePlayer。
|
Json範例:
JSON
{
"RuntimePlayer": {
"Name": "player1"
}
}
PlayerAdded
在用戶端成功將玩家加入線上遊戲後,將傳送PlayerAdded webhook。
需要在 Photon 儀表板上設定WebHookBaseUrl和WebHookEnablePlayerAdded。
JavaScript
POST https://{WebHookBaseUrl}/player/added
PlayerAdded請求
| 名稱 | 類型 | 示例 | 描述 |
|---|---|---|---|
| AppId | string |
d1f67eec-51fb-45c1 |
Photon AppId |
| GameId | string |
0:eu:db757806-8570-45aa |
唯一遊戲 ID。 |
| UserId | string |
db757806-8570-45aa |
Photon UserId 或 ClientId。 |
| ActorNr | int |
db757806-8570-45aa |
Photon 參與者編號,用戶端的遞增執行時間 ID。 |
| PlayerSlot | int |
0 | 用戶端保留的(本機)玩家位置。 |
| Player | int |
21 | 用戶端收到的(全域)玩家 ID。 |
| AuthCookie | Dictionary<string, object> |
db757806-8570-45aa |
後端設定的 Photon 自訂驗證 Cookie。 |
Json範例:
JSON
{
"AppId": "d1f67eec-51fb-45c1",
"GameId": "0:eu:db757806-8570-45aa",
"UserId": "db757806-8570-45aa",
"ActorNr": 1,
"PlayerSlot": 0,
"Player": 21,
"AuthCookie": {
"Secret": "**********"
}
}
HTTP回應碼
| 名稱 | 類型 | 描述 |
|---|---|---|
| 200 OK | 確認已接收。 |
PlayerRemoved
當用戶端被從線上遊戲中移除時,將傳送PlayerRemoved webhook。
需要在 Photon 儀表板上設定WebHookBaseUrl和WebHookEnablePlayerRemoved。
JavaScript
POST https://{WebHookBaseUrl}/player/removed
PlayerRemoved請求
| 名稱 | 類型 | 示例 | 描述 |
|---|---|---|---|
| AppId | string |
d1f67eec-51fb-45c1 |
Photon AppId |
| GameId | string |
0:eu:db757806-8570-45aa |
唯一遊戲 ID。 |
| UserId | string |
db757806-8570-45aa |
Photon UserId 或 ClientId。 |
| ActorNr | int |
db757806-8570-45aa |
Photon 參與者編號,用戶端的遞增執行時間 ID。 |
| PlayerSlot | int |
0 | (本機)玩家位置。 |
| Player | int |
21 | (全域)玩家 ID。 |
| Reason | int |
0 | 玩家被從遊戲中移除的原因。 0 = Requested1 = ClientDisconnected2 = Error |
| AuthCookie | Dictionary<string, object> |
db757806-8570-45aa |
後端設定的 Photon 自訂驗證 Cookie。 |
Json範例:
JSON
{
"AppId": "d1f67eec-51fb-45c1",
"GameId": "0:eu:db757806-8570-45aa",
"UserId": "db757806-8570-45aa",
"ActorNr": 1,
"PlayerSlot": 0,
"Player": 21,
"Reason": 0,
"AuthCookie": {
"Secret": "**********"
}
}
HTTP回應碼
| 名稱 | 類型 | 描述 |
|---|---|---|
| 200 OK | 確認已接收。 |
GameResult
在模擬中使用GameResult Quantum 事件將觸發用戶端向 Quantum 伺服器上傳GameResult執行個體,每個遊戲 一次。
結果會被彙總,並在遊戲 / 房間 關閉 時作為GameResult webhook 轉送給自訂後端伺服器。由於逗留的用戶端和RoomTTL可能會延長房間關閉時間,因此遊戲結束與結果 webhook 之間可能會有延遲。
結果會按每個不同的提交結果進行合併。理想情況下只有一個,因為每個用戶端都會傳送相同的數據。結果清單會根據提交它的玩家數量進行排序,可用於執行簡單的多數投票,以略微提高結果的正確性。
需要在 Photon 儀表板上設定WebHookBaseUrl及WebHookEnableGameResult。
Note:
- The
GameResultwebhook supports both standard JSON format and binary payloads usingbase64encoding.- Dictionaries are not supported, due to Unity serialization limitations. Quantum relies on Unity's built-in serialization system, which does not support
Dictionary<,>types. These fields will be ignored or cause deserialization failures if present.
需要在 Photon 儀表板上設定WebHookBaseUrl及WebHookEnableGameResult。
如果伺服器正在執行模擬,則 webhook 會立即從伺服器模擬執行,將IsServerResult設定為true,並可用作可靠且可信的遊戲結果來源。
JavaScript
POST https://{WebHookBaseUrl}/game/result
重播
也可以在重播中使用遊戲結果,方法是註冊到EventGameResult 。
C#
var eventDispatcher = new EventDispatcher();
eventDispatcher.SubscribeManual((EventGameResult e) => {
if (e.Game?.Session != null) {
// Handle result and stop replay
}
});
GameResult請求
| 名稱 | 類型 | 示例 | 描述 |
|---|---|---|---|
| AppId | string |
d1f67eec-51fb-45c1 |
Photon AppId |
| GameId | string |
0:eu:db757806-8570-45aa |
唯一遊戲 ID。 |
| Results | GameResultInfo[] |
見下文 | 彙總的遊戲結果。 |
Json範例:
JSON
{
"AppId": "d1f67eec-51fb-45c1",
"GameId": "0:eu:db757806-8570-45aa",
"Results": [
{
"Clients": [
{
"UserId": "FJEH43FL56FSDR",
"Players": [ 0 ],
"GameTime": 63.3636703
},
{
"UserId": "8FMEINF3845BSD",
"Players": [ 1 ],
"GameTime": 62.9345634
}
],
"Result": {
"$type": "Quantum.GameResult, Quantum.Simulation",
"Frame": 12010,
"Winner": 0
},
"IsServerResult": false
},
{
"Clients": [
{
"UserId": "LUDHBS7Z3F55",
"Players": [ 2 ],
"GameTime": 63.1234567
}
],
"Result": {
"$type": "Quantum.GameResult, Quantum.Simulation",
"Frame": 12010,
"Winner": 2
},
"IsServerResult": false
}
]
}
HTTP回應碼
| 名稱 | 描述 |
|---|---|
| 200 OK | 確認已接收。 |
GameResultInfo
| 名稱 | 類型 | 描述 |
|---|---|---|
| Result | GameResult |
列出的用戶端傳送的特定於遊戲的遊戲結果 Json 物件。 |
| Clients | GameResultClientInfo[] |
產生此結果的用戶端清單。 |
| IsServerResult | bool |
此結果是否由伺服器模擬產生。 |
GameResultClientInfo
| 名稱 | 類型 | 描述 |
|---|---|---|
| UserId | string |
Photon 使用者 ID。 |
| Players | int[] |
此使用者控制的玩家清單。 |
| GameTime | float |
結果到達伺服器的時間戳記。 |
ReplayStart
當伺服器上的模擬和輸入記錄開始時,將傳送ReplayStart webhook。它是一個可信來源,用於直接從伺服器擷取遊戲重播,而不是依賴用戶端將其傳送到開發人員的後端。
此 webhook 必須以ReplayStartResponse回應,該回應可以表示為跳過此特定遊戲工作階段的重播串流。
Quantum 伺服器在傳送其第一個重播片段之前必須收到回應,否則重播記錄將被取消。
需要在 Photon 儀表板上設定WebHookBaseUrl和WebHookEnableReplay。
JavaScript
POST https://{WebHookBaseUrl}/replay/start
ReplayStart請求
| 名稱 | 類型 | 描述 |
|---|---|---|
| AppId | string |
Photon AppId。 |
| AppVersion | string |
建立房間 / 遊戲工作階段時使用的 AppVersion。 |
| Region | string |
建立房間 / 遊戲工作階段的 Game Server 所在的區域代碼。 |
| Cloud | string |
Game Server 執行所在的Cloud Id。 |
| RoomName | string |
房間 / 遊戲工作階段名稱。 |
| GameId | string |
由{Cloud:}{Region:}RoomName組成的唯一GameId。 |
| SessionConfig | SessionConfig |
模擬開始時使用的SessionConfig。 |
| RuntimeConfig | byte[] |
RuntimeConfig的 GZipped Json,模擬開始時使用。 |
Json範例:
JSON
{
"AppId": "d1f67eec-51fb-45c1",
"AppVersion": "1.0-live",
"Region": "eu",
"Cloud": "0:",
"RoomName": "1.2-party-2349535735",
"GameId": "0:eu:e472a861-a1e2-49f7",
"SessionConfig": { },
"RuntimeConfig": "H4sIAAAAAAAACnWNPQvCMBCG/4ocjkWuye
X6sXZycNCCe8AogSYtNBlK6X/3UHQR4Zb35X2eW2GflslBC+ds
Y8rhcMkx+eC6Md79o9h96t6HPNjkxwgF9M7doMUCTnaCdoWjpB
WudshiUkxYsVHacE11KWe2TZiv4K3+4YjQkECKNJcVMuoXtszJ
hfkPI1tUVc1sqFGN1g3Kr+0J+3ktedUAAAA="
}
HTTP回應碼
| 名稱 | 類型 | 描述 |
|---|---|---|
| 200 OK | ReplayStart Response |
當設定Skip屬性時,重播串流可以開始或被停用。 |
| 400 Bad Request | WebhookError |
在這種情況下,錯誤會記錄在伺服器上,並停止重播串流。 |
ReplayStart回應
| 名稱 | 類型 | 描述 |
|---|---|---|
| Skip | bool |
為此遊戲工作階段停用重播串流。 |
Json範例:
JSON
{
"Skip": true
}
ReplayChunk
ReplayChunk webhook 會定期傳送,其中包含模擬部分的差異壓縮輸入歷程記錄。
需要在 Photon 儀表板上設定WebHookBaseUrl及WebHookEnableReplay。
JavaScript
POST https://{WebHookBaseUrl}/replay/chunk
有其他儀表板變數可設定重播輸入串流。
| 儀表板變數 | 類型 | 描述 | 預設 |
|---|---|---|---|
| WebHookReplayUseBinaryRequests | bool |
Web 請求不會以 JSON 內容傳送,而是以二進制數據傳送。 | false |
| WebHookReplayUseCompression | bool |
區塊上的輸入數據是 GZip 壓縮的。 | false |
| WebHookReplaySendIntervalInSec | int |
區塊傳送間隔(以秒為單位)(最小值 = 2,最大值 = 40)。 | 20 |
ReplayChunk請求
如果選取WebHookReplayUseBinaryRequests,則以下屬性是 web 請求Headers的一部分,而不是 JSON 主體。然後主體將包含二進制Input。
| 名稱 | 類型 | 描述 |
|---|---|---|
| AppId | string |
Photon AppId。 |
| GameId | string |
用於識別重播區塊的遊戲 ID。 |
| ChunkNumber | int |
遞增的區塊編號。 |
| IsLast | bool |
表示已傳送最後一個區塊的旗標。通常在房間關閉時。 |
| LastTick | int |
此區塊上輸入的最舊刻度。 |
| TickCount | int |
此區塊上輸入的刻度數。 |
| TickCountTotal | int |
整個重播中總的遞增刻度數。 |
| IsCompressed | bool |
表示輸入是否經過 GZip 壓縮的旗標。 |
| Input | byte[] |
需要附加到此重播的完整輸入串流的二進制差異壓縮輸入。
每個刻度的輸入都有一個開頭的 int 描述數據長度。它可以儲存在ReplayFile.InputHistoryRaw欄位中,以便在 Unity 中使用QuantumRunnerLocalReplay指令碼讀取。 |
Json範例:
JSON
{
"AppId": "d1f67eec-51fb-45c1",
"GameId": ":eu:e472a861-a1e2-49f7",
"ChunkNumber": 0,
"IsLast": false,
"LastTick": 302,
"TickCount": 243,
"TickCountTotal": 243,
"IsCompressed": false,
"Input": "JQAAADwAAAAIAAMKFsCUwYDggOB/UCAAAPgfDMhgEoAHA////4PRBwATAAAAPQAAAAgAA2PaSK"
}
HTTP回應碼
| 名稱 | 類型 | 描述 |
|---|---|---|
| 200 OK | 確認已接收。 | |
| 400 Bad Request | WebhookError |
在這種情況下,錯誤會記錄在伺服器上,並停止重播串流。 |
WebhookError
| 名稱 | 類型 | 描述 |
|---|---|---|
| Status | int |
HTTP狀態碼 |
| Error | string |
錯誤名稱 |
| Message | string |
錯誤訊息 |
Json範例:
JSON
{
"Status": 400,
"Error": "PlayerNotAllowed",
"Message": "LoremIpsum"
}
Quantum類別
RuntimeConfig
Quantum 3 執行時間設定檔RuntimeConfig和RuntimePlayer由用戶端使用 Json 序列化上傳。這樣可以將設定傳送到 Quantum 公用雲端遊戲伺服器,而無需知道其實作和序列化詳細資訊。
當在 webhook 回應中使用RuntimeConfig或RuntimePlayer時,它們需要是完整的,因為用戶端傳送的設定會被完全取代。
自訂後端傳送的 Json 數據必須能在每個用戶端上確定性地反序列化。
Quantum 內部類別通常使用欄位,請確保 Json 序列化和反序列化程式碼需要 IncludeFields = true及IgnoreReadOnlyProperties = true。
RuntimeConfig類別的簡單範例。除了部分宣告外,基底類別還會新增幾個屬性(Seed、Map、SimulationConfig、SystemsConfig)。
$type屬性是獨立程式或自訂外掛程式反序列化所必需的。
C#
namespace Quantum {
public partial class RuntimeConfig {
public int GameMode;
}
}
Json範例:
JSON
{
"$type": "Quantum.RuntimeConfig, Quantum.Simulation",
"GameMode": 1,
"Seed": 0,
"Map": {
"Id": {
"Value":2640765235684814815
}
},
"SimulationConfig": {
"Id": {
"Value":440543562436170603
}
},
"SystemsConfig": {
"Id": {
"Value":2430278665492933905
}
}
}
RuntimePlayer
C#
namespace Quantum {
public partial class RuntimePlayer {
public AssetRef<GearConfig> Loadout;
}
}
Json範例:
JSON
{
"$type":"Quantum.RuntimePlayer, Quantum.Simulation",
"Loadout": {
"Id": {
"Value": 440543562436170603
}
},
"PlayerAvatar": {
"Id": {
"Value": 2430278665492933905
}
},
"PlayerNickname": "foo"
}
SessionConfig
SessionConfig是 DeterministicSessionConfig類別的縮寫。
當 webhook 傳回SessionConfig時,它需要是完整的,因為單個值不會被取代。
目前的SessionConfig資產可以在 Unity 中使用以下功能表項目匯出:
Unity Editor > Quantum > Export > SessionConfig (Json)
在netcoreapp3.1上序列化類別時,請使用Newtonsoft或對Text.Json使用DeterministicSessionConfigJsonConverter。因為 "including fields" 是net5的功能。
Json範例:
JSON
{
"PlayerCount": 8,
"ChecksumCrossPlatformDeterminism": false,
"LockstepSimulation": false,
"InputDeltaCompression": true,
"UpdateFPS": 60,
"ChecksumInterval": 60,
"RollbackWindow": 60,
"InputHardTolerance": 8,
"InputRedundancy": 3,
"InputRepeatMaxDistance": 10,
"SessionStartTimeout": 1,
"TimeCorrectionRate": 4,
"MinTimeCorrectionFrames": 1,
"MinOffsetCorrectionDiff": 1,
"TimeScaleMin": 100,
"TimeScalePingMin": 100,
"TimeScalePingMax": 300,
"InputDelayMin": 0,
"InputDelayMax": 60,
"InputDelayPingStart": 100,
"InputFixedSizeEnabled": true,
"InputFixedSize": 24
}
GameResult事件
可以透過在GameResult.User.cs指令碼中使用部分類別宣告新增欄位來擴充GameResult類別。它將在客戶端上進行 Json 序列化並傳送到 Quantum 伺服器。
C#
namespace Quantum {
public partial class GameResult {
public int Winner;
}
}
Json範例:
JSON
{
"$type":"Quantum.GameResult, Quantum.Simulation",
"Frame": 200,
"Winner": 2
}
遊戲結果事件可以由每個用戶端在遊戲中呼叫 一次,這是透過在模擬內部呼叫 GameResult Quantum 事件來觸發的。實際的 webhook 會在房間解散並關閉時啟動。
C#
f.Events.GameResult(new GameResult { Winner = 3 });
當執行具有伺服器模擬的企業版 Photon Quantum 雲時,伺服器將以可信的遊戲結果來源透明地傳送此事件。
Photon Realtime類別
EnterRoomParams
此定義旨在類似於Photon Realtime中的EnterRoomParams類。 它包括所有可以通過CreateGame webhook設定的選項。 在編寫JsonResponse時,每個成員都是可選的,可以為null或不設定。
| 名稱 | 類型 | 描述 |
|---|---|---|
| RoomOptions | RoomOptions |
RoomOptions物件 |
| ExpectedUsers | string[] |
允許進入房間/會話的UserIds清單(除創建房間的用戶外)。 如果MaxPlayers大於列出的 ExpectedUsers數量,則任何玩家都可以加入並填補未保留的插槽。僅適用於 RoomJoin(),不適用於JoinRandom()。 |
Json範例:
JSON
{
"RoomOptions": {
"IsVisible": true,
"IsOpen": true,
"MaxPlayers": 8,
"PlayerTtl": null,
"EmptyRoomTtl": 10000,
"CustomRoomProperties": {
"Foo": "bar",
"PlayerClass": 1
},
"CustomRoomPropertiesForLobby": [
"Foo"
],
"SuppressRoomEvents": null,
"SuppressPlayerInfo": null,
"PublishUserId": null,
"DeleteNullProperties": null,
"BroadcastPropsChangeToAll": null,
"CleanupCacheOnLeave": null,
"CheckUserOnJoin": null
},
"ExpectedUsers": [
"A",
"B",
"C"
]
}
RoomOptions
所有值都是可以為null的類型,可以設定為null,也可以在發送回Quantum服務器時省略,在這種情況下,此響應不會改變為null或省略的房間内容,並將保持預設值或用戶端在創建房間時發送的值。
| 名稱 | 類型 | 描述 |
|---|---|---|
| IsVisible | bool |
定義此房間是否列在Photon匹配中。 |
| IsOpen | bool |
定義此房間是否可以由其他用戶端加入。 |
| MaxPlayers | byte |
任何時候可以在房間裏的最大玩家數量。 0表示“無限制”。 |
| PlayerTtl | int |
房間裏“演員”的生存時間(TTL)。如果用戶端斷開連接,此參與者將首先處於非活動狀態,並在此超時後被删除。 以毫秒為單位。 |
| EmptyRoomTtl | int |
最後一名玩家離開時房間的生存時間(TTL)。 在記憶體中保留空間,以防玩家很快重新加入。 以毫秒為單位。 |
| CustomRoomProperties | |
在創建過程中設定房間的自訂屬性。 |
| CustomRoomPropertiesForLobby | string[] |
定義哪些自定義房間内容將在大廳中列出。 内容的值類型必須是 bool, byte, short, int, long或string。内容的最大數量為3。 字串值的最大長度為64。 鍵限制也可以通過Photon儀錶板内容強制執行: AllowedLobbyProperties。 |
| SuppressRoomEvents | bool |
告訴服務器跳過加入和離開玩家的房間事件。 預設值為 false。 |
| SuppressPlayerInfo | bool |
禁用事件加入和離開服務器以及房間中的内容廣播(以儘量減少流量)。 預設值為 false。 |
| PublishUserId | bool |
定義玩家的用戶ID是否在房間中“發佈”。 如果玩家想一起玩另一個遊戲,對FindFriends很有用。 預設值為 false。 |
| DeleteNullProperties | bool |
可選地,當null被賦值時,内容會被删除。 預設值為 false。 |
PlayFab
要啟用PlayFab整合,請新增WebHookIntegration儀表板變數並將其設定為PlayFab。
- 所有路徑中的斜線都將被替換為下劃線:
game/create=>game_create - 所有webhook請求將自動新增
AppId屬性(若缺失),由WebHooksConfig.AppId控制 - 所有 webhook 請求皆會自動新增
UserId屬性(若缺失)為"0" - Webhook回應將處理以下Json結果主體,並導致webhooks失敗於
ResultCode != 0。發生錯誤時,Message會被複製到WebHookError.Message。
JSON
{
"ResultCode": 0,
"Message": "success"
}
Photon Cloud Web請求限制
默認情況下,Photon Server按順序管理HTTP請求,並且在當前請求完成之前不會啟動新請求。 新請求已排隊。 此限制為每間房都有。
這可能會導致用戶端在使用OnJoin或AddPlayer webhooks時出現意外的等待時間,同時玩家湧入率很高,從Photon雲到自定義後端的往返時間也很長。
可以為企業雲啟用並行請求。 我們正在研究一種解決方案,讓他們也選擇使用公共應用程式。
其他限制包括:
HttpRequestTimeout: 30000LimitHttpResponseMaxSize: 200000MaxQueuedRequests: 5000