PlayCompute.psm1

function Get-PFQosServer
{
    [CmdletBinding( )]
    Param()
    
    Begin
    {}

    Process
    {

        $task = [PlayFab.PlayFabEntityAPI]::ListQosServersAsync($null)
        $task.Wait()
        $result = $task.Result.Result.QoSServers
        $result
     }

     <#
.SYNOPSIS
Gets a list of QoS servers.
 
.DESCRIPTION
Returns list of QoS servers to use for network performance measurements and region selection during allocation.
#>

}

function Get-PFTitleEntityToken
{
    [CmdletBinding( )]
    Param(
    [Parameter(Mandatory = $true)][string]$TitleID, 
    [Parameter(Mandatory = $true)][string]$SecretKey 
    )
    
    Begin
    {}

    Process
    {
 
        #Sets the public properties of the API's static class that configure which title target via entity tokens
        [PlayFab.PlayFabSettings]::TitleID = $TitleID
        [PlayFab.PlayFabSettings]::DeveloperSecretKey = $SecretKey

        $key = new-object PlayFab.EntityModels.EntityKey
        $key.ID = $TitleID
        
        $tokenRequest = new-object PlayFab.EntityModels.GetEntityTokenRequest
        $tokenRequest.Entity = $key

        $tokenTask = [PlayFab.PlayFabEntityAPI]::GetEntityTokenAsync($tokenRequest);
        $tokenTask.Wait()
        $result = $tokenTask.Result.Result.EntityToken
        $result
        
     }
     <#
.SYNOPSIS
Gets an entity token using the provided title and secret key. Required for other Entity API interactions.
 
.DESCRIPTION
Using a secret key generated in Game Manager, this cmdlet generates and entity token for the specified title id. The entity token will be used for authenticating other PlayCompute cmdlets for the length of the PowerShell session.
#>

}

function Get-PFGameAsset
{
    [CmdletBinding( )]
    Param()
    
    Begin
    {}

    Process
    {
        
            $task = [PlayFab.PlayFabEntityAPI]::ListAssetsAsync($null)
            $task.Wait()
            $result = $task.Result.Result.AssetSummaries
            $result
     }

     <#
.SYNOPSIS
 
Gets the game server assets that have been uploaded
 
.DESCRIPTION
 
Gets the game server assets that have been added through Add-PFGameAssets or GetAssetUploadURL API. Command is run in the context of the title specified using Get-PFTitleEntityToken
#>

}

function Add-PFGameAsset
{
    [CmdletBinding( )]
    Param(
    [Parameter(Mandatory = $true)][string]$FilePath 
    )
    
    Begin
    {}

    Process
    {
        $PathTest = Test-Path $FilePath
        if ($PathTest -eq $false)
        {
            write-error "Provided file path is not valid"
            return 
        }

        $FolderIndex = $FilePath.LastIndexOf("\")
        $FolderIndex++
        $Name = $FilePath.Substring($FolderIndex)

        $assetReq = NEW-OBJECT PlayFab.EntityModels.GetAssetUploadUrlRequest
        $assetReq.Name =  $Name
        
        $metadata = New-Object 'System.Collections.Generic.Dictionary[String,String]'
        $metadata.Add("OriginalFilePath",$FilePath)
        $assetReq.MetaData = $MetaData

        $assetTask = [PlayFab.PlayFabEntityAPI]::GetAssetUploadUrlAsync($assetReq);
        $assetTask.Wait()
        
        $sastoken = $assetTask.Result.Result.AssetUploadUrl
        
        $sastoken = $sastoken.Remove($sastoken.LastIndexOf("&api"))
        $storageaccountname = $sastoken.SubString(8,$sastoken.IndexOf("blob")-9)
        $sastoken = $sastoken.substring($sastoken.IndexOf("sv"))

        $accountContext = New-AzureStorageContext -SasToken $sasToken -StorageAccountName   $storageaccountname 
        ## $blob = Get-AzureStorageBlob -Container "gameassets" -Blob $ID -Context $accountContext
        Set-AzureStorageBlobContent -File $FilePath -Container "gameassets" -Context $accountContext -Blob $Name
                
     }

          <#
.SYNOPSIS
Uploads an asset to PlayFab.
 
.DESCRIPTION
Upload an asset (commonly a zip file) by providing a friendly name and file path. This cmdlet uses the GetAssetUploadURl API to get an Azure blob URL, and then uses Azure storage cmdlets to upload the asset.
#>


}

function Add-PFGameCertificate
{
    [CmdletBinding( )]
    Param(
    [Parameter(Mandatory = $true)][string]$Name, 
    [Parameter(Mandatory = $true)][string]$FilePath 
    )
    
    Begin
    {}

    Process
    {
    
        $PathTest = Test-Path $FilePath
        if ($PathTest -eq $false)
        {
            write-error "Provided file path is not valid"
            return 
        }

        $certificateBytes = [System.IO.File]::ReadAllBytes($FilePath)
        $base64 = [System.Convert]::ToBase64String($certificateBytes)

        $cert = NEW-OBJECT PlayFab.EntityModels.Certificate
        $cert.Base64EncodedValue = $base64 
        $cert.Name = $Name

        $certReq = NEW-OBJECT PlayFab.EntityModels.UploadCertificateRequest
        $certReq.GameCertificate = $cert

        $certTask = [PlayFab.PlayFabEntityAPI]::UploadCertificateAsync($certReq);
        $certTask.Wait();
        $certTask.Result;
     }

          <#
.SYNOPSIS
Uploads a certificate to PlayFab.
 
.DESCRIPTION
Uploads a certificate to PlayFab for game server usage. Cmdlet does not support certificates with passwords but coming soon.
#>


}

function Get-PFGameCertificate
{
    [CmdletBinding( )]
    Param()
    
    Begin
    {}

    Process
    {
        
            $task = [PlayFab.PlayFabEntityAPI]::ListCertificatesAsync($null)
            Write-Progress "Listing certificates"

            $task.Wait()
            $result = $task.Result.Result.CertificateSummaries
            $result
     }

     <#
.SYNOPSIS
 
Gets the game server certificates that have been uploaded
 
.DESCRIPTION
 
Gets the game server Certificate that have been added through Add-PFGameCertificate.
#>

}

function Get-PFGameBuild
{
    [CmdletBinding( )]
    Param( 
    [Parameter(ParameterSetName = "SpecificName", Mandatory = $true)][string]$BuildName),
    [Parameter(ParameterSetName = "All", Mandatory = $True)][Switch] $All
    
    Begin
    {}

    Process
    {
        
            $task = [PlayFab.PlayFabEntityAPI]::ListBuildsAsync($null)
            $task.Wait()
            $result = $task.Result.Result.BuildSummaries
            if ($All)
            {
                return $result
            }
            else {
                $newresult = $Result | where {$_.Buildname -contains $BuildName}
                return $newresult
            }
     }

     <#
.SYNOPSIS
 
Gets the game server builds that have been created
 
.DESCRIPTION
 
Gets the game server builds
 
#>

}


function New-PFGameBuild
{
    [CmdletBinding( )]
    Param(
    [Parameter(Mandatory = $true)][string]$BuildName, 
    [Parameter(Mandatory = $true)][string]$AssetName, 
    [Parameter(Mandatory = $true)][string]$AssetMountPath,
    [Parameter(Mandatory = $true)][string]$StartGameCommand,
    [Parameter(Mandatory = $true)]$MappedPorts,
    [Parameter(Mandatory = $true)]$VMSize,
    [Parameter(Mandatory = $true)]$BuildCerts
    )
    
    Begin
    {}

    Process
    {

        $BuildReq = NEW-OBJECT PlayFab.EntityModels.CreateBuildWithManagedContainerRequest
        $BuildReq.BuildName = $BuildName
        $BuildReq.ContainerFlavor = [PlayFab.EntityModels.ContainerFlavor]::WindowsServerCorePlayFab
 
        $BuildReq.StartGameCommand = $StartGameCommand
        $BuildReq.MappedPorts = $MappedPorts
        $BuildReq.VMSize = $VMSize
        $BuildReq.GameCertificateReferences =  $BuildCerts
 
        $BuildReq.SessionHostCountPerVm = 1 

        $Asset = NEW-OBJECT PlayFab.EntityModels.AssetReferenceParams
        $Asset.Name = $AssetName
        $Asset.MountPath = $AssetMountPath
        $BuildReq.GameAssetReferences = $Asset

        $Regions = NEW-OBJECT PlayFab.EntityModels.BuildRegionParams
        $Regions.MaxSessions = 50
        $Regions.Region = "EastUS"
        $Regions.StandbySessions = 2
        $BuildReq.RegionConfiguration = $Regions
    
        
        $metadata = New-Object 'System.Collections.Generic.Dictionary[String,String]'
        $metadata.Add("CreatedBy","PowerShell")
        $BuildReq.MetaData = $MetaData
        
        $buildTask = [PlayFab.PlayFabEntityAPI]::CreateBuildWithManagedContainerAsync($BuildReq)
        $buildTask.Wait()
        $buildTask.Result.Result.BuildSummary

     }

          <#
.SYNOPSIS
Creates a game server build.
 
.DESCRIPTION
Creates a game server build. Currently hard-coded to create a Windows Server Core build.
 
.EXAMPLE
        
$VMSelection = [PlayFab.EntityModels.AzureVMSize]::Standard_F4
 
$Ports = New-object PlayFab.EntityModels.Port
$Ports.Name = "Test Port"
$Ports.Num = 3055
$Ports.Protocol = [PlayFab.EntityModels.ProtocolType]::UDP
 
$BuildCert = New-Object 'System.Collections.Generic.List[String]'
$Buildcert.Add("WeirdErrorTest")
$Buildcert.Add("FakeCert")
 
New-PFGameBuild -BuildName "PowerShellTest" -AssetName "HaroRunner" -AssetMountPath "C:\Asset\" -StartGameCommand "C:\Assets\WinTestRunnerGame.exe" -MappedPorts $Ports -VMSize $VMSelection -BuildCerts $BuildCert
 
#>


}
function Remove-PFGameBuild
{
    [CmdletBinding( )]
    Param(
    [Parameter(Mandatory = $true)][string]$BuildId
    )

    Begin
    {}

    Process
    {
        $BuildReq = NEW-OBJECT PlayFab.EntityModels.DeleteBuildRequest
        $BuildReq.BuildId = $BuildId

        $buildTask = [PlayFab.PlayFabEntityAPI]::DeleteBuildAsync($BuildReq)
        $buildTask.Wait()
        $buildTask.Result.Result.BuildSummary
     }

          <#
.SYNOPSIS
Deletes a game server build.
 
.DESCRIPTION
Deletes a game server build.
 
.EXAMPLE
 
Remove-PFGameBuild -BuildId <build_id>
 
#>


}


function Get-PFGameSessionHost
{
    [CmdletBinding( )]
    Param(   
    [Parameter(Mandatory = $true)][string]$BuildName,
    [Parameter(ParameterSetName = "SpecificRegion", Mandatory = $True)][PlayFab.EntityModels.AzureRegion]$Region,
    [Parameter(ParameterSetName = "AllRegions", Mandatory = $True)][Switch] $AllRegions
    )
    
    Begin
    {}

    Process
    {
        $BuildID = Get-PFGameBuild -BuildName $BuildName
        $BuildID = $BuildID.BuildID

        $RegionList = New-Object 'System.Collections.Generic.List[PlayFab.EntityModels.AzureRegion]'
         

        if($AllRegion) {
            $East = [PlayFab.EntityModels.AzureRegion]::EastUs
            $West = [PlayFab.EntityModels.AzureRegion]::WestUs
            $Central = [PlayFab.EntityModels.AzureRegion]::CentralUs
            $NEurope = [PlayFab.EntityModels.AzureRegion]::NorthEurope
        
            $RegionList.Add($East)
            $RegionList.Add($West)
            $RegionList.Add($Central)
            $RegionList.Add($NEurope)

        }
        else {
            $RegionList.Add($Region)
        }

        foreach ($Region in $RegionList)
        {
            $SessionReq = NEW-OBJECT PlayFab.EntityModels.ListSessionHostsRequest
            $SessionReq.BuildID = $BuildID
            $SessionReq.Region =  $Region
    
            $task = [PlayFab.PLayFabEntityAPI]::ListSessionHostsAsync($SessionReq)
            $task.Wait()
            $Task.Result.Result.SessionHostSummaries
        }
     }

     <#
.SYNOPSIS
 
Gets the session hosts for a build
 
.DESCRIPTION
 
Gets the game session hosts for a build and specified region
 
.Example
 
Get sessions hosts from a specific build in East US
 
$Region = [PlayFab.EntityModels.AzureRegion]::EastUS
$Name = "ZIP_AllocationTest"
Get-PFGameSessionHost -BuildName $Name -Region $Region
 
.Example
Get sessions hosts from a specific build across all regions
 
 
$Name = "ZIP_AllocationTest"
Get-PFGameSessionHost -BuildName $Name -AllRegions
 
#>

}



function New-PFGameSessionHost
{
    [CmdletBinding( )]
    Param(   
    [Parameter(Mandatory = $true)][string]$BuildName
    )
    
    Begin
    {}

    Process
    {
         $BuildID = Get-PFGameBuild | where {$_.BuildName -eq $BuildName}
         $BuildID = $BuildID.BuildID

         $AllocateReq = NEW-OBJECT PlayFab.EntityModels.AllocateSessionHostRequest
         $AllocateReq.BuildID = $BuildID

         $East = [PlayFab.EntityModels.AzureRegion]::EastUs
         $West = [PlayFab.EntityModels.AzureRegion]::WestUs
         $RegionList = New-Object 'System.Collections.Generic.List[PlayFab.EntityModels.AzureRegion]'
         $RegionList.Add($East)
         $RegionList.Add($West)
         $AllocateReq.PreferredRegions = $RegionList

         $AllocateReq.SessionID = "784f4a2e-596e-451c-848c-9de2346b0000"
         $AllocateReq.SessionCookie = "test cookie"

         $task = [PlayFab.PLayFabEntityAPI]::AllocateSessionHostAsync($AllocateReq)
         $task.Wait()
         return $task.Result.Result
     }

     <#
.SYNOPSIS
 
Allocates a new session host
 
.DESCRIPTION
 
Allocates a new session host, uses a hard-coded set of regions
 
.Example
 
New-PFGameSessionHost -BuildName "MyBuild"
 
 
#>

}






##Export cmdlet and alias to module

New-Alias GPFQ Get-PFQosServer
Export-ModuleMember -Alias GPFQ -Function Get-PFQosServer

New-Alias GPFTET Get-PFTitleEntityToken
Export-ModuleMember -Alias GPFTET -Function Get-PFTitleEntityToken

New-Alias GPFGA Get-PFGameAsset
Export-ModuleMember -Alias GPFGA -Function Get-PFGameAsset

New-Alias APFGA Add-PFGameAsset
Export-ModuleMember -Alias APFGA -Function Add-PFGameAsset

New-Alias APFGC Add-PFGameCertificate
Export-ModuleMember -Alias APFGC -Function Add-PFGameCertificate

New-Alias GPFGC Get-PFGameCertificate
Export-ModuleMember -Alias GPFGC -Function Get-PFGameCertificate

New-Alias NPFGB New-PFGameBuild
Export-ModuleMember -Alias NPFGB -Function New-PFGameBuild


New-Alias RPFGB Remove-PFGameBuild
Export-ModuleMember -Alias RPFGB -Function Remove-PFGameBuild

New-Alias GPFGB Get-PFGameBuild
Export-ModuleMember -Alias GPFGB -Function Get-PFGameBuild

New-Alias GPFGSH Get-PFGameSessionHost
Export-ModuleMember -Alias GPFGSH -Function Get-PFGameSessionHost

New-Alias NPFGSH New-PFGameSessionHost
Export-ModuleMember -Alias NPFGSH -Function New-PFGameSessionHost