diff --git a/DefaultCloudScript.js b/DefaultCloudScript.js index 0c42aac..edc5875 100644 --- a/DefaultCloudScript.js +++ b/DefaultCloudScript.js @@ -211,54 +211,141 @@ var UnlockHighSkillContent = function (args, context) { return { profile: context.playerProfile }; }; handlers["unlockHighSkillContent"] = UnlockHighSkillContent; -// Photon Webhooks Integration -// -// The following functions are examples of Photon Cloud Webhook handlers. -// When you enable the Photon Add-on (https://playfab.com/marketplace/photon/) -// in the Game Manager, your Photon applications are automatically configured -// to authenticate players using their PlayFab accounts and to fire events that -// trigger your Cloud Script Webhook handlers, if defined. -// This makes it easier than ever to incorporate multiplayer server logic into your game. // Triggered automatically when a Photon room is first created var RoomCreated = function (args) { - log.debug("Room Created - Game: " + args.GameId + " MaxPlayers: " + args.CreateOptions.MaxPlayers); + server.WritePlayerEvent({ + EventName: "room_created", + PlayFabId: args.UserId, + Body: { + WebHook: { + AppVersion: args.AppVersion, + Region: args.Region, + GameId: args.GameId, + Type: args.Type, + ActorNr: args.ActorNr, + CreateOptions: args.CreateOptions + } + } + }); + return { ResultCode: 0 }; }; handlers["RoomCreated"] = RoomCreated; // Triggered automatically when a player joins a Photon room var RoomJoined = function (args) { - log.debug("Room Joined - Game: " + args.GameId + " PlayFabId: " + args.UserId); + server.WritePlayerEvent({ + EventName: "room_joined", + PlayFabId: args.UserId, + Body: { + WebHook: { + AppVersion: args.AppVersion, + Region: args.Region, + GameId: args.GameId, + ActorNr: args.ActorNr + } + } + }); + return { ResultCode: 0 }; }; handlers["RoomJoined"] = RoomJoined; // Triggered automatically when a player leaves a Photon room var RoomLeft = function (args) { - log.debug("Room Left - Game: " + args.GameId + " PlayFabId: " + args.UserId); + server.WritePlayerEvent({ + EventName: "room_left", + PlayFabId: args.UserId, + Body: { + WebHook: { + AppVersion: args.AppVersion, + Region: args.Region, + GameId: args.GameId, + Type: args.Type, + ActorNr: args.ActorNr, + IsInactive: args.IsInactive + } + } + }); + return { ResultCode: 0 }; }; handlers["RoomLeft"] = RoomLeft; // Triggered automatically when a Photon room closes // Note: currentPlayerId is undefined in this function var RoomClosed = function (args) { - log.debug("Room Closed - Game: " + args.GameId); + server.WriteTitleEvent({ + EventName: "room_closed", + Body: { + WebHook: { + AppVersion: args.AppVersion, + Region: args.Region, + GameId: args.GameId, + Type: args.Type, + ActorCount: args.ActorCount + } + } + }); + return { ResultCode: 0 }; }; handlers["RoomClosed"] = RoomClosed; // Triggered automatically when a Photon room game property is updated. -// Note: currentPlayerId is undefined in this function var RoomPropertyUpdated = function (args) { - log.debug("Room Property Updated - Game: " + args.GameId); + if (args.Type === "Game") { + server.WritePlayerEvent({ + EventName: "room_properties_updated", + PlayFabId: args.UserId, + Body: { + WebHook: { + AppVersion: args.AppVersion, + Region: args.Region, + GameId: args.GameId, + ActorNr: args.ActorNr, + Properties: args.Properties + } + } + }); + } + else { // "Actor" + server.WritePlayerEvent({ + EventName: "player_roperties_updated", + PlayFabId: args.UserId, + Body: { + WebHook: { + AppVersion: args.AppVersion, + Region: args.Region, + GameId: args.GameId, + ActorNr: args.ActorNr, + TargetActor: args.TargetActor, + Properties: args.Properties + } + } + }); + } + return { ResultCode: 0 }; }; handlers["RoomPropertyUpdated"] = RoomPropertyUpdated; // Triggered by calling "OpRaiseEvent" on the Photon client. The "args.Data" property is // set to the value of the "customEventContent" HashTable parameter, so you can use // it to pass in arbitrary data. var RoomEventRaised = function (args) { + server.WritePlayerEvent({ + EventName: "event_raised", + PlayFabId: args.UserId, + Body: { + WebHook: { + AppVersion: args.AppVersion, + Region: args.Region, + GameId: args.GameId, + ActorNr: args.ActorNr, + EvCode: args.EvCode + } + } + }); var eventData = args.Data; - log.debug("Event Raised - Game: " + args.GameId + " Event Type: " + eventData.eventType); - switch (eventData.eventType) { + switch (eventData.eventType) { // use args.EvCode instead of embedding eventType in payload case "playerMove": processPlayerMove(eventData); break; default: break; } + return { ResultCode: 0 }; }; handlers["RoomEventRaised"] = RoomEventRaised; //# sourceMappingURL=DefaultCloudScript.js.map \ No newline at end of file diff --git a/DefaultCloudScript.ts b/DefaultCloudScript.ts index bf3445b..710d183 100644 --- a/DefaultCloudScript.ts +++ b/DefaultCloudScript.ts @@ -55,7 +55,8 @@ var HelloWorldDefault = function (args: any, context: IPlayFabContext): IHelloWo // generated by the function execution. // (https://api.playfab.com/playstream/docs/PlayStreamEventModels/player/player_executed_cloudscript) return { messageValue: message }; -} +}; + interface IHelloWorldResponse { messageValue: string; } @@ -75,7 +76,7 @@ var MakeApiCall = function (args: any, context: IPlayFabContext): void { // authenticated as your title and handles all communication with // the PlayFab API, so you don't have to write extra code to issue HTTP requests. var playerStatResult = server.UpdatePlayerStatistics(request); -} +}; handlers["makeAPICall"] = MakeApiCall; // This is a simple example of making a web request to an external HTTP API. @@ -98,7 +99,8 @@ var MakeHttpRequest = function (args: any, context: IPlayFabContext): IMakeHttpR // The pre-defined http object makes synchronous HTTP requests var response = http.request(url, httpMethod, content, contentType, headers); return { responseContent: response }; -} +}; + interface IMakeHttpRequestResponse { responseContent: string; } @@ -121,7 +123,8 @@ var HandlePlayStreamEventAndProfile = function (args: any, context: IPlayFabCont var response = http.request('https://httpbin.org/status/200', 'post', content, 'application/json', null); return { externalAPIResponse: response }; -} +}; + interface IHandlePlayStreamEventAndProfileResponse { externalAPIResponse: string; } @@ -159,7 +162,7 @@ var CompletedLevel = function (args: any, context: IPlayFabContext): void { server.UpdatePlayerStatistics(request); log.debug("Updated level_monster_kills stat for player " + currentPlayerId + " to " + monstersKilled); -} +}; handlers["completedLevel"] = CompletedLevel; // In addition to the Cloud Script handlers, you can define your own functions and call them from your handlers. @@ -167,7 +170,8 @@ handlers["completedLevel"] = CompletedLevel; var UpdatePlayerMove = function (args): IUpdatePlayerMoveResponse { var validMove = processPlayerMove(args); return { validMove: validMove }; -} +}; + interface IUpdatePlayerMoveResponse { validMove: boolean; } @@ -203,7 +207,7 @@ function processPlayerMove(playerMove): boolean { log.debug("lastMoveTime: " + lastMoveTime + " now: " + now + " timeSinceLastMoveInSeconds: " + timeSinceLastMoveInSeconds); if (timeSinceLastMoveInSeconds < playerMoveCooldownInSeconds) { - log.error("Invalid move - time since last move: " + timeSinceLastMoveInSeconds + "s less than minimum of " + playerMoveCooldownInSeconds + "s.") + log.error("Invalid move - time since last move: " + timeSinceLastMoveInSeconds + "s less than minimum of " + playerMoveCooldownInSeconds + "s."); return false; } } @@ -256,7 +260,8 @@ var UnlockHighSkillContent = function (args: any, context: IPlayFabContext): IUn log.info('Unlocked HighSkillContent for ' + context.playerProfile.DisplayName); return { profile: context.playerProfile }; -} +}; + interface IUnlockHighSkillContentResponse { profile: IPlayFabPlayerProfile; } @@ -272,46 +277,148 @@ handlers["unlockHighSkillContent"] = UnlockHighSkillContent; // This makes it easier than ever to incorporate multiplayer server logic into your game. -// Triggered automatically when a Photon room is first created -var RoomCreated = function (args): void { - log.debug("Room Created - Game: " + args.GameId + " MaxPlayers: " + args.CreateOptions.MaxPlayers); +interface IPhotonRealtimeWebHookResponse { + ResultCode: number; + Message?: string; } + +interface IPhotonRealtimePathCreateWebHookResponse extends IPhotonRealtimeWebHookResponse { + State?: any; +} + +// Triggered automatically when a Photon room is first created +var RoomCreated = function(args) : IPhotonRealtimePathCreateWebHookResponse { + server.WritePlayerEvent({ + EventName : "room_created", + PlayFabId: args.UserId, + Body: { + WebHook: { + AppVersion: args.AppVersion, + Region: args.Region, + GameId: args.GameId, + Type: args.Type, + ActorNr: args.ActorNr, + CreateOptions: args.CreateOptions + } + } + }); + return { ResultCode: 0 }; +}; handlers["RoomCreated"] = RoomCreated; // Triggered automatically when a player joins a Photon room -var RoomJoined = function (args): void { - log.debug("Room Joined - Game: " + args.GameId + " PlayFabId: " + args.UserId); -} +var RoomJoined = function (args) : IPhotonRealtimeWebHookResponse { + server.WritePlayerEvent({ + EventName: "room_joined", + PlayFabId: args.UserId, + Body: { + WebHook: { + AppVersion: args.AppVersion, + Region: args.Region, + GameId: args.GameId, + ActorNr: args.ActorNr + } + } + }); + return { ResultCode: 0 }; +}; handlers["RoomJoined"] = RoomJoined; // Triggered automatically when a player leaves a Photon room -var RoomLeft = function (args): void { - log.debug("Room Left - Game: " + args.GameId + " PlayFabId: " + args.UserId); -} +var RoomLeft = function (args) : IPhotonRealtimeWebHookResponse { + server.WritePlayerEvent({ + EventName: "room_left", + PlayFabId: args.UserId, + Body: { + WebHook: { + AppVersion: args.AppVersion, + Region: args.Region, + GameId: args.GameId, + Type: args.Type, + ActorNr: args.ActorNr, + IsInactive: args.IsInactive + } + } + }); + return { ResultCode: 0 }; +}; handlers["RoomLeft"] = RoomLeft; // Triggered automatically when a Photon room closes // Note: currentPlayerId is undefined in this function -var RoomClosed = function (args): void { - log.debug("Room Closed - Game: " + args.GameId); -} +var RoomClosed = function (args) : IPhotonRealtimeWebHookResponse { + server.WriteTitleEvent({ + EventName: "room_closed", + Body: { + WebHook: { + AppVersion: args.AppVersion, + Region: args.Region, + GameId: args.GameId, + Type: args.Type, + ActorCount: args.ActorCount + } + } + }); + return { ResultCode: 0 }; +}; handlers["RoomClosed"] = RoomClosed; // Triggered automatically when a Photon room game property is updated. -// Note: currentPlayerId is undefined in this function -var RoomPropertyUpdated = function (args): void { - log.debug("Room Property Updated - Game: " + args.GameId); -} +var RoomPropertyUpdated = function (args) : IPhotonRealtimeWebHookResponse { + if (args.Type === "Game") { + server.WritePlayerEvent({ + EventName: "room_properties_updated", + PlayFabId: args.UserId, + Body: { + WebHook: { + AppVersion: args.AppVersion, + Region: args.Region, + GameId: args.GameId, + ActorNr: args.ActorNr, + Properties: args.Properties + } + } + }); + } else { // "Actor" + server.WritePlayerEvent({ + EventName: "player_roperties_updated", + PlayFabId: args.UserId, + Body: { + WebHook: { + AppVersion: args.AppVersion, + Region: args.Region, + GameId: args.GameId, + ActorNr: args.ActorNr, + TargetActor: args.TargetActor, + Properties: args.Properties + } + } + }); + } + return { ResultCode: 0 }; +}; handlers["RoomPropertyUpdated"] = RoomPropertyUpdated; // Triggered by calling "OpRaiseEvent" on the Photon client. The "args.Data" property is // set to the value of the "customEventContent" HashTable parameter, so you can use // it to pass in arbitrary data. -var RoomEventRaised = function (args): void { - var eventData = args.Data; - log.debug("Event Raised - Game: " + args.GameId + " Event Type: " + eventData.eventType); +var RoomEventRaised = function (args) : IPhotonRealtimeWebHookResponse { + server.WritePlayerEvent({ + EventName: "event_raised", + PlayFabId: args.UserId, + Body: { + WebHook: { + AppVersion: args.AppVersion, + Region: args.Region, + GameId: args.GameId, + ActorNr: args.ActorNr, + EvCode: args.EvCode + } + } + }); - switch (eventData.eventType) { + var eventData = args.Data; + switch (eventData.eventType) { // use args.EvCode instead of embedding eventType in payload case "playerMove": processPlayerMove(eventData); break; @@ -319,5 +426,6 @@ var RoomEventRaised = function (args): void { default: break; } -} + return { ResultCode: 0 }; +}; handlers["RoomEventRaised"] = RoomEventRaised; \ No newline at end of file