This document is about: PUN 2
SWITCH TO

PUN Classic (v1), PUN 2, Bolt는 휴업 모드입니다. Unity2022에 대해서는 PUN 2에서 서포트하지만, 신기능의 추가는 없습니다. 현재 이용중인 고객님의 PUN 및 Bolt 프로젝트는 중단되지 않고, 퍼포먼스나 성능이 떨어지는 일도 없습니다. 앞으로의 새로운 프로젝트에는 Photon Fusion 또는 Quantum을 사용해 주십시오.

Photon Steam 인증

애플리케이션 설정

인증 공급자로 Steam을 추가하는 것은 쉬우며Photon 애플리케이션의 관리 화면에서 몇 초만에 수행할 수 있습니다. 애플리케이션의 "관리" 페이지로 이동하여 "인증" 섹션까지 아래로 스크롤 합니다.

Steam에 대해 새로운 인증 공급자를 추가하거나 기존 것을 편집한다면, 다음을 필수적으로 설정해야 합니다:

  • apiKeySecret: Steam 퍼블리셔 Web API 키입니다. 키를 받는 방법에 대해서는 여기를 읽어보십시오.
  • appid: Steam의 ID입니다. 전에 Steam Greenlight로 알려져 있는 Steam Direct 프로세스를 통해 받을 수 있습니다.
  • verifyOwnership: true 또는 false 가 될 수 있습니다: 인증하는 동안 소유권 검증을 사용하거나 사용하지 않도록 합니다. 이를 통해 사용자가 게임에 대해 진짜 소유하고 있는지 여부에 대해 검증할 수 있습니다.(게임을 구매했고 라이브러리에 가지고 있는지) . 이 단계에서, 사용하도록 되어 있다면, 사용자 세션 티켓 확인 후 바로 수행됩니다. 이것을 사용하게 하면 인증 시 추가적인 지연이 발생할 수 있으므로 필요할 때만 사용하도록 합니다.
  • verifyVacBan: true 또는 false 가 될 수 있습니다: 인증할 때 Valve의 Anti-Cheat(VAC)을 사용하여 사용자가 추방되었는지 여부를 확인합니다. 여기에서 상세 내용을 확인하십시오. 이를 사용하는 것은 인증 시 추가적인 지연이 발생할 수 있으므로 필요할 때만 사용하도록 합니다.
  • verifyPubBan: true 또는 false 가 될 수 있습니다: 인증 시 퍼블리셔 밴을 사용하여 사용자가 추방되었는지 확인합니다. 여기에서 상세 내용을 확인하십시오. 이를 사용하는 것은 인증 시 추가적인 지연이 발생할 수 있으므로 필요할 때만 사용하도록 합니다.

클라이언트 코드(유니티)

클라이언트는 반드시 Valve의 Steamworks API를 사용하여 세션 티켓을 받아야 합니다. 이 티켓은 클라이언트가 유효한 Steam 사용자임을 증명해 줍니다.

Steamworks.NET

Steamworks.NET은 Steamworks API 래퍼의 인기 있는 무료, 오픈 소스입니다. Steamworks.NET의 유니티 버전의 임포트는 이 페이지에 있는 지침을 따라 해 보세요.

티켓 받기

다음 코드를 사용하여 Steamworks API를 사용하여 세션 티켓을 얻은 후 16진수 인코딩 UTF-8 문자열로 변환합니다:

C#

// hAuthTicket should be saved so you can use it to cancel the ticket as soon as you are done with it
public string GetSteamAuthTicket(out HAuthTicket hAuthTicket)
{
    byte[] ticketByteArray = new byte[1024];
    uint ticketSize;
    hAuthTicket = SteamUser.GetAuthSessionTicket(ticketByteArray, ticketByteArray.Length, out ticketSize);
    System.Array.Resize(ref ticketByteArray, (int)ticketSize);
    StringBuilder sb = new StringBuilder();
    for(int i=0; i < ticketSize; i++)
    {
        sb.AppendFormat("{0:x2}", ticketByteArray[i]);
    }
    return sb.ToString();
}

티켓 전송

클라이언트는 쿼리 문자열 키 "ticket"의 값으로 사용자의 세션 티켓(16진수 인코딩 UTF-8 문자열로 변환한 후)을 전송해야 합니다.

C#

PhotonNetwork.AuthValues = new AuthenticationValues();
PhotonNetwork.AuthValues.UserId = SteamUser.GetSteamID().ToString();
PhotonNetwork.AuthValues.AuthType = CustomAuthenticationType.Steam;
PhotonNetwork.AuthValues.AddAuthParameter("ticket", SteamAuthSessionTicket);
// connect

티켓 취소

인증이 완료되면 티켓을 취소하거나 원복하는 것이 좋습니다.

PUN 2에서 가장 먼저 트리거 되고 티켓을 취소할 수 있는 콜백은 IConnectionCallbacks.OnConnected입니다:

C#

private void OnConnected()
{
    SteamUser.CancelAuthTicket(hAuthTicket);
}

IConnectionCallbacks.OnConnectedToMaster, IConnectionCallbacks.OnCustomAuthenticationFail와 같은 콜백 또는 심지어 IConnectionCallbacks.OnDisconnected 콜백에서 티켓을 취소할 수도 있습니다.

전체 코드

이는 최소한의 자체 포함된 예제이며 전체를 복사/붙여 넣고 전체 그대로 사용할 수 없습니다.

C#

using Photon.Pun;
using Photon.Realtime;
using Steamworks;

public class MinimalSteamworksPunAuth : MonoBehaviourPunCallbacks
{
    private HAuthTicket hAuthTicket;

    private void Start()
    {
        if (SteamManager.Initialized)
        {
            Connect();
        }
    }

    public void Connect()
    {
        string SteamAuthSessionTicket = GetSteamAuthTicket(out hAuthTicket);
        PhotonNetwork.AuthValues = new AuthenticationValues();
        PhotonNetwork.AuthValues.UserId = SteamUser.GetSteamID().ToString();
        PhotonNetwork.AuthValues.AuthType = CustomAuthenticationType.Steam;
        PhotonNetwork.AuthValues.AddAuthParameter("ticket", SteamAuthSessionTicket);
        PhotonNetwork.ConnectUsingSettings();
    }
    
    public override void OnConnectedToMaster()
    {
        CancelAuthTicket(hAuthTicket);
    }
    
    public override void OnCustomAuthenticationFailed(string errorMessage)
    {
        CancelAuthTicket(hAuthTicket);
    }
    
    // ticket should be saved so you can use it to cancel the ticket as soon as you are done with it
    private string GetSteamAuthTicket(out HAuthTicket ticket)
    {
        byte[] ticketByteArray = new byte[1024];
        uint ticketSize;
        ticket = SteamUser.GetAuthSessionTicket(ticketByteArray, ticketByteArray.Length, out ticketSize);
        System.Array.Resize(ref ticketByteArray, (int)ticketSize);
        StringBuilder sb = new StringBuilder();
        for(int i=0; i < ticketSize; i++)
        {
            sb.AppendFormat("{0:x2}", ticketByteArray[i]);
        }
        return sb.ToString();
    }
    
  private void CancelAuthTicket(HAuthTicket ticket)
  {
      if (ticket != null)
      {
          SteamUser.CancelAuthTicket(ticket);
      }
  }
}

Facepunch.Steamworks

Facepunch.Steamworks은 Steamworks API를 구현할 수 있는 또 다른 무료인 오픈 소스입니다. Facepunch.Steamworks를 임포트 하시려면이 페이지에 있는 지침서를 따라 하세요.

티켓 얻기

다음 코드를 사용하여 세션 티켓을 얻고 16진수 인코딩된 UTF-8 문자열로 변환합니다:

C#

// authTicket should be saved so you can use it to cancel the ticket as soon as you are done with it
public string GetSteamAuthTicket(out AuthTicket authTicket)
{
    authTicket = SteamUser.GetAuthSessionTicket();
    StringBuilder ticketString = new StringBuilder();
    for (int i = 0; i < authTicket.Data.Length; i++)
    {
        ticketString.AppendFormat("{0:x2}", authTicket.Data[i]);
    }
    return ticketString.ToString();
}

티켓 전송

클라이언트는 사용자의 세션 티켓을 쿼리 문자열 키 "ticket"의 값으로(16진주 인코딩된 UTF-8 스트링으로 변환 후)로 전송해야 합니다.

C#

PhotonNetwork.AuthValues = new AuthenticationValues();
PhotonNetwork.AuthValues.UserId = SteamClient.SteamId.ToString();
PhotonNetwork.AuthValues.AuthType = CustomAuthenticationType.Steam;
PhotonNetwork.AuthValues.AddAuthParameter("ticket", steamAuthSessionTicket);
// connect

티켓 취소

인증이 완료된 이후 취소 또는 원복하는 것이 권장됩니다.

PUN 2에서는, 첫 번째 콜백이 트리거 되고 티켓을 취소할 수 있는 곳으IConnectionCallbacks.OnConnected 입니다:

C#

private void OnConnected()
{
    ticket.Cancel();
}

IConnectionCallbacks.OnConnectedToMaster, IConnectionCallbacks.OnCustomAuthenticationFail과 같은 다른 콜백 또는 심지어 IConnectionCallbacks.OnDisconnected 콜백에서 티켓을 취소할 수 있습니다.

전체 코드

이는 최소한의 자체 포함된 예제이며 전체를 복사/붙여 넣고 전체 그대로 사용할 수 없습니다.

C#

using Photon.Pun;
using Photon.Realtime;
using Steamworks;
using UnityEngine;

public class MinimalSteamworksPunAuth : MonoBehaviourPunCallbacks
{
    [SerializeField]
    private int steamAppId;
    private AuthTicket hAuthTicket;

    private void Awake()
    {
        try 
        {
            SteamClient.Init(steamAppId);
        }
        catch (System.Exception e)
        {
            // Couldn't init for some reason - it's one of these:
            //     Steam is closed?
            //     Can't find steam_api dll?
            //     Don't have permission to play app?
        }
    }

    private void Start()
    {
        Connect();
    }

    public void Connect()
    {
        string steamAuthSessionTicket = GetSteamAuthTicket(out hAuthTicket);
        PhotonNetwork.AuthValues = new AuthenticationValues();
        PhotonNetwork.AuthValues.UserId = SteamClient.SteamId.ToString();
        PhotonNetwork.AuthValues.AuthType = CustomAuthenticationType.Steam;
        PhotonNetwork.AuthValues.AddAuthParameter("ticket", steamAuthSessionTicket);
        PhotonNetwork.ConnectUsingSettings();
    }
    
    public override void OnConnectedToMaster()
    {
        CancelAuthTicket(hAuthTicket);
    }
    
    public override void OnCustomAuthenticationFailed(string errorMessage)
    {
        CancelAuthTicket(hAuthTicket);
    }
    
    // ticket should be saved so you can use it to cancel the ticket as soon as you are done with it
    private string GetSteamAuthTicket(out AuthTicket ticket)
    {
        ticket = SteamUser.GetAuthSessionTicket();
        StringBuilder ticketString = new StringBuilder();
        for (int i = 0; i < ticket.Data.Length; i++)
        {
            ticketString.AppendFormat("{0:x2}", ticket.Data[i]);
        }
        return ticketString.ToString();
    }
    
    private void CancelAuthTicket(AuthTicket ticket)
    {
        if (ticket != null)
        {
            ticket.Cancel();
        }
    }
    
    private void Update()
    {
        SteamClient.RunCallbacks();
    }
    
    private void OnApplicationQuit()
    {
        SteamClient.Shutdown();
    }
}
Back to top