This document is about: QUANTUM 3
SWITCH TO

Webhooks

概述

Webhooks主要用於擁有受信任的遊戲配置和房間組成來源,並可大幅提升線上應用程式的安全性。

預設的雲端外掛程式支援透過AppID儀表板定義的不同鉤子。
一旦設定並啟用後,Photon Cloud會向自訂後端發送WebRequests(HTTP POST),並會使用回應資料(Json)對Photon房間和遊戲階段進行各種配置。

安裝

在Photon儀錶板上,每個AppId都啟用了Webhooks。

  1. 導航到Photon儀錶板並登入。
  2. 找到AppId並按一下Manage
  3. 向下滾動到挿件,然後按一下Edit
  4. 按一下Add New Pair並添加keysvalues(每個設定值允許的最大長度為1024個字元)。
  5. Save,等待更改生效最多一分鐘。
Photon Dashboard Properties

儀錶板配置

類型 示例 描述
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操作上傳遊戲設定RuntimeConfigSessionConfig時,將觸發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將根據ReplayStartReplayChunk web 請求啟用重播串流。

Webhook API

Webhooks傳送Json內容且只接受Json內容作為回應。Json使用UTF-8字元集是強制性的。

Webhooks期望HTTP回應代碼為200400

  • 200: 請求成功。
  • 400: 錯誤或操作已被拒絕(例如,客戶端不能建立房間/遊戲會話)。

Photon伺服器在傳輸錯誤後會重試三次網鉤(webhook),同樣在收到狀態碼 503(服務不可用)後,也會分別延遲400毫秒、1600毫秒和6400毫秒進行重試。請求失敗且不再重試前的超時時間為10秒。

填寫WebhookError定義,以將錯誤性質的資訊回傳至Photon外掛程式。其可用於:

  • 日誌記錄;
  • 將資訊回傳給客戶;
  • 一個自訂外掛程式,用以新增進一步的自訂錯誤處理;

Http請求重試

Photon Server會對來自後端的可重試錯誤回應作出反應,額外重新發送請求三次。

後續的請求有不同的標頭以識別它們。

EGRepeatId - 重複的數字,例如 0123 (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儀錶板上設定WebHookBaseUrlWebHookEnableCreateGame

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儀錶板上設定WebHookBaseUrlWebHookEnableOnJoin

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儀錶板上設定WebHookBaseUrlWebHookEnableOnLeave

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儀錶板上設定WebHookBaseUrlWebHookEnableOnClose

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

當玩家傳送附加遊戲設定RuntimeConfigSessionConfigStartRequest操作時,將傳送GameConfigs webhook。

此 webhook 僅在任何用戶端的啟動操作首次到達時,每個房間傳送一次。

需要在 Photon 儀表板上設定WebHookBaseUrlWebHookEnableGameConfigs

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 儀表板上設定WebHookBaseUrlWebHookEnableAddPlayer

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 用於覆寫用戶端傳送的RuntimePlayerRuntimePlayer物件。若為null,將接受用戶端的RuntimePlayer

Json範例:

JSON

{
  "RuntimePlayer": {
    "Name": "player1"
  }
}

PlayerAdded

在用戶端成功將玩家加入線上遊戲後,將傳送PlayerAdded webhook。

需要在 Photon 儀表板上設定WebHookBaseUrlWebHookEnablePlayerAdded

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 儀表板上設定WebHookBaseUrlWebHookEnablePlayerRemoved

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 = Requested
1 = ClientDisconnected
2 = 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 儀表板上設定WebHookBaseUrlWebHookEnableGameResult

Note:

  • The GameResult webhook supports both standard JSON format and binary payloads using base64 encoding.
  • 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 儀表板上設定WebHookBaseUrlWebHookEnableGameResult

如果伺服器正在執行模擬,則 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 儀表板上設定WebHookBaseUrlWebHookEnableReplay

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 儀表板上設定WebHookBaseUrlWebHookEnableReplay

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 執行時間設定檔RuntimeConfigRuntimePlayer由用戶端使用 Json 序列化上傳。這樣可以將設定傳送到 Quantum 公用雲端遊戲伺服器,而無需知道其實作和序列化詳細資訊。

當在 webhook 回應中使用RuntimeConfigRuntimePlayer時,它們需要是完整的,因為用戶端傳送的設定會被完全取代。

自訂後端傳送的 Json 數據必須能在每個用戶端上確定性地反序列化。

Quantum 內部類別通常使用欄位,請確保 Json 序列化和反序列化程式碼需要 IncludeFields = trueIgnoreReadOnlyProperties = 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

SessionConfigDeterministicSessionConfig類別的縮寫。

當 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 Dictionary <string, object> 在創建過程中設定房間的自訂屬性。
CustomRoomPropertiesForLobby string[] 定義哪些自定義房間内容將在大廳中列出。

内容的值類型必須是bool, byte, short, int, longstring

内容的最大數量為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: 30000
  • LimitHttpResponseMaxSize: 200000
  • MaxQueuedRequests: 5000
Back to top