에픽 친구 및 친구 상태 쿼리하기

Rajen Kishna, 테크니컬 어카운트 매니저, 에픽게임즈 |
2021년 10월 14일
에픽 계정 서비스에 대한 에픽 온라인 서비스 시작하기 연재글을 마무리하기 위해 이번에는 인증현재상태 인터페이스에 이어 친구 인터페이스로 에픽 친구 및 친구 상태를 쿼리하는 방법을 알아보겠습니다. 이번 연재글에서는 다음 내용을 살펴봅니다.
 

친구 API 스코프

쿼리 API를 다루기에 앞서 먼저 이 API들의 스코프를 어떻게 결정했는지 이해하는 것이 중요합니다. 이전 연재글에서 간단히 설명했듯이 친구 API는 플레이어가 에픽게임즈 런처에서 볼 수 있는 친구 목록의 전체를 기본적으로 반환하지 않습니다. 이미 보셨듯이 각 플레이어에게는 에픽의 EAS 애플리케이션이 기본 프로필, 현재상태, 친구 등 특정 정보에 액세스하는 데 동의하는지 묻는 메시지가 나타납니다. 플레이어의 친구가 이에 동의한 경우에만 친구 인터페이스가 해당 친구를 쿼리 시 반환합니다. 플레이어가 에픽게임즈 스토어에서 게임을 구매한 경우에는 구매 절차의 일부로서 암묵적으로 동의한 것이 됩니다. 다음과 같은 경우를 예로 들어봅시다.
 
  • 플레이어 A는 플레이어 B와 플레이어 C의 친구로, 에픽게임즈 스토어에서 게임을 구매했습니다.
  • 플레이어 B는 게임을 가지고 있지 않습니다.
  • 플레이어 C는 스팀(Steam)에서 게임을 구매했습니다.

이 시나리오에서 플레이어 C가 게임을 실행하고 인증 과정에서 동의하기 전까지는 쿼리 API를 호출하더라도 플레이어 A에게 친구가 보이지 않습니다. 플레이어 B는 게임을 가지고 있지 않으므로 쿼리 API를 실행해도 반환되지 않습니다.

문서에 따르면 현재는 친구 요청을 관리하거나 플레이어의 친구를 추가 및 삭제할 수 있는 API가 없습니다. 소셜 오버레이가 올해 말에 확장되면 이 기능이 지원될 것입니다.

애플리케이션에 친구 권한 추가하기

현재상태에서 했던 것과 비슷하게 EAS 애플리케이션에 친구 권한을 추가해야 플레이어로부터 적절한 동의를 구할 수 있습니다.
 
  1. https://dev.epicgames.com/portal/에서 개발자 포털에 로그인합니다.
  2. 왼쪽 메뉴에서 해당 제품으로 이동하여 에픽 계정 서비스(Epic Account Services)를 클릭합니다.
  3. 사용 중인 애플리케이션 옆의 구성(Configure) 버튼을 클릭합니다
  4. 우측 상단의 권한(Permission) 탭을 클릭합니다.
  5. 친구 (friends_list) 권한을 활성화합니다. 왼쪽의 프리뷰가 업데이트되어 이제 친구 동의 정보가 표시됩니다.
  6. 저장(Save)을 클릭하여 마칩니다.
Developer Portal Friends Permission
EAS 애플리케이션에 친구 권한 추가하기

마지막으로 Visual Studio 솔루션에서 ApplicationSettings.cs를 열고 현재상태 ScopeFlag를 추가합니다.

public AuthScopeFlags ScopeFlags
{
    get
    {
        return AuthScopeFlags.BasicProfile | AuthScopeFlags.Presence | AuthScopeFlags.FriendsList;
    }
}


앱을 실행하고 인증 로그인을 트리거하면 이제 브라우저에 업데이트된 동의 화면이 나타나며 여전히 인증을 완료할 수 있습니다.

친구 쿼리하기

친구 권한을 추가했다면 이제 쿼리 기능을 솔루션에 구현합니다.
 
  1. FriendsView라는 새로운 UserControl을 Views 폴더에 추가합니다.
  2. 빈 Grid 노드에 다음과 같은 XAML을 붙여넣습니다.
 

<Grid>

    <Grid.ColumnDefinitions>

        <ColumnDefinition Width="*" />

        <ColumnDefinition Width="Auto" />

    </Grid.ColumnDefinitions>


    <StackPanel Grid.Column="1">

        <Button Width="100" Height="23" Margin="2" Content="Query friends" Command="{Binding FriendsQuery}" />

        <Button Width="100" Height="23" Margin="2" Content="Subscribe" Command="{Binding FriendsSubscribeUpdates}" />

        <Button Width="100" Height="23" Margin="2" Content="Unsubscribe" Command="{Binding FriendsUnsubscribeUpdates}" />

        <Button Width="100" Height="23" Margin="2" Content="Query status" Command="{Binding PresenceQuery}" CommandParameter="{Binding SelectedFriend}" />

    </StackPanel>


    <ListView x:Name="FriendsListView" Grid.Column="0" Margin="2" ItemsSource="{Binding Friends}" SelectedItem="{Binding SelectedFriend}" SelectionChanged="FriendsListView_SelectionChanged">

        <ListView.View>

            <GridView>

                <GridViewColumn Header="Friend" Width="300" DisplayMemberBinding="{Binding EpicAccountId}">

                    <GridViewColumn.HeaderContainerStyle>

                        <Style TargetType="{x:Type GridViewColumnHeader}">

                            <Setter Property="HorizontalContentAlignment" Value="Left" />

                        </Style>

                    </GridViewColumn.HeaderContainerStyle>

                </GridViewColumn>

                <GridViewColumn Header="Friend Status" Width="150" DisplayMemberBinding="{Binding FriendsStatus}">

                    <GridViewColumn.HeaderContainerStyle>

                        <Style TargetType="{x:Type GridViewColumnHeader}">

                            <Setter Property="HorizontalContentAlignment" Value="Left" />

                        </Style>

                    </GridViewColumn.HeaderContainerStyle>

                </GridViewColumn>

                <GridViewColumn Header="Status" Width="150" DisplayMemberBinding="{Binding Status}">

                    <GridViewColumn.HeaderContainerStyle>

                        <Style TargetType="{x:Type GridViewColumnHeader}">

                            <Setter Property="HorizontalContentAlignment" Value="Left" />

                        </Style>

                    </GridViewColumn.HeaderContainerStyle>

                </GridViewColumn>

            </GridView>

        </ListView.View>

    </ListView>

</Grid>

 
  • ListView를 사용하여 API로부터 반환된 친구를 표시하고, 업데이트 구독 및 구독 해지 버튼, 친구 현재상태 쿼리 버튼 등을 만들겠습니다.
 
  1. FriendsView.xaml.cs를 열고 DataContext를 정의합니다.

public partial class FriendsView : UserControl
{
    public FriendsViewModel ViewModel { get { return ViewModelLocator.Friends; } }

    public FriendsView()
    {
        InitializeComponent();
        DataContext = ViewModel;
    }

    private void FriendsListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
    }
}

 
  • 빈 FriendsListView_SelectionChanged 이벤트 핸들러는 나중에 친구 현재상태 정보 쿼리를 구현할 때 사용하겠습니다.
 
  1. UI에 에픽 계정 ID, 친구 상태, 현재상태 정보 등 친구를 표시할 여러 기능을 결합할 것이므로 Models라는 새로운 폴더를 프로젝트 루트에 생성하고 Friend.cs 클래스를 추가합니다.

public class Friend : BindableBase
{
    private EpicAccountId _epicAccountId;
    public EpicAccountId EpicAccountId
    {
        get { return _epicAccountId; }
        set { SetProperty(ref _epicAccountId, value); }
    }

    private FriendsStatus _friendsStatus;
    public FriendsStatus FriendsStatus
    {
        get { return _friendsStatus; }
        set { SetProperty(ref _friendsStatus, value); }
    }

    private Status _status;
    public Status Status
    {
        get { return _status; }
        set { SetProperty(ref _status, value); }
    }
}

 
  1. ViewModels 폴더에 FriendsViewModel.cs 클래스를 추가합니다.

public class FriendsViewModel : BindableBase
{
    private ObservableCollection<Friend> _friends;
    public ObservableCollection<Friend> Friends
    {
        get { return _friends; }
        set { SetProperty(ref _friends, value); }
    }

    private Friend _selectedFriend;
    public Friend SelectedFriend
    {
        get { return _selectedFriend; }
        set { SetProperty(ref _selectedFriend, value); }
    }

    private ulong _notificationId;
    public ulong NotificationId
    {
        get { return _notificationId; }
        set { SetProperty(ref _notificationId, value); }
    }
}

 
  1. FriendsViewModel에 대한 스태틱 레퍼런스를 ViewModelLocator에 추가합니다.

private static FriendsViewModel _friends;
public static FriendsViewModel Friends
{
    get { return _friends ??= new FriendsViewModel(); }
}

 
  1. FriendsService.cs 클래스를 Services 폴더에 추가합니다.

public static class FriendsService
{
    public static void QueryFriends()
    {
        var queryFriendsOptions = new QueryFriendsOptions()
        {
            LocalUserId =​​​​​ EpicAccountId.FromString(ViewModelLocator.Main.AccountId)
        };

        ViewModelLocator.Main.StatusBarText = $"Querying friends...";

        App.Settings.PlatformInterface.GetFriendsInterface()
.QueryFriends(queryFriendsOptions, null, (QueryFriendsCallbackInfo queryFriendsCallbackInfo) =>
        {
            Debug.WriteLine($"QueryFriends {queryFriendsCallbackInfo.ResultCode}");

            if (queryFriendsCallbackInfo.ResultCode == Result.Success)
            {
                var getFriendsCountOptions = new GetFriendsCountOptions()
                {
                    LocalUserId = EpicAccountId.FromString(ViewModelLocator.Main.AccountId)
                };
                var friendsCount = App.Settings.PlatformInterface.GetFriendsInterface()
.GetFriendsCount(getFriendsCountOptions);

                for (int i = 0; i < friendsCount; i++)
                {
                    var getFriendAtIndexOptions = new GetFriendAtIndexOptions()
                    {
                        LocalUserId = EpicAccountId.FromString(ViewModelLocator.Main.AccountId),
                        Index = i
                    };
                    var friend = App.Settings.PlatformInterface.GetFriendsInterface()
.GetFriendAtIndex(getFriendAtIndexOptions);

                    if (friend != null)
                    {
                        var getStatusOptions = new GetStatusOptions()
                        {
                            LocalUserId = EpicAccountId.FromString(ViewModelLocator.Main.AccountId),
                            TargetUserId = friend
                        };
                        var friendStatus = App.Settings.PlatformInterface.GetFriendsInterface()
.GetStatus(getStatusOptions);

                        ViewModelLocator.Friends.Friends.Add(new Friend()
                        {
                            EpicAccountId = friend,
                            FriendsStatus = friendStatus
                        });
                    }
                }
            }

            ViewModelLocator.Main.StatusBarText = string.Empty;
        });
    }
}

 
  • 옵션 클래스를 인스턴스화하고 친구 인터페이스의 QueryFriends API에 전달하고 캐시에서 카운트를 가져온 후 반복작업하여 각 친구의 상태를 가져옵니다.
  • 그런 다음, 친구 상태를 포함한 친구를 ViewModel에 추가하여 UI에 표시합니다.
 
  1. FriendsQueryCommand.cs 클래스를 Commands 폴더에 추가합니다.

public class FriendsQueryCommand : CommandBase
{
    public override bool CanExecute(object parameter)
    {
        return !string.IsNullOrWhiteSpace(ViewModelLocator.Main.AccountId);
    }

    public override void Execute(object parameter)
    {
        ViewModelLocator.Friends.Friends = new ObservableCollection<Friend>();
        FriendsService.QueryFriends();
    }
}

 
  1. 이제 FriendsViewModel.cs를 다시 열고 FriendsQueryCommand를 인스턴스화합니다.

public FriendsQueryCommand FriendsQuery { get; set; }

public FriendsViewModel()
{
    FriendsQuery = new FriendsQueryCommand();
}

 
  1. 다음 라인을 ViewModelLocator RaiseAuthCanExecuteChanged() 메서드에 추가하여 사용자가 로그인한 경우에만 현재상태 쿼리 버튼이 활성화되게 합니다.

Friends.FriendsQuery.RaiseCanExecuteChanged();
 
  1. 마지막으로 PresenceView를 MainWindow TabControl에 추가합니다.

<TabItem x:Name="Friends" Header="Friends">
    <views:FriendsView />
</TabItem>



이제 앱을 실행하고 인증하고 브라우저에서 업데이트된 권한에 동의할 수 있으며, 그 후 친구 쿼리 버튼을 사용하여 플레이어의 친구 및 친구 상태를 가져올 수 있습니다. 그러나 예상대로 API로부터 친구를 가져올 수가 없습니다. 아무도 애플리케이션에 동의하지 않았기 때문입니다. 이 문제를 해결해 보겠습니다.

친구의 동의 받기

코드의 유효성을 검사하려면 친구를 애플리케이션에 동의하게 만들어야 합니다. 오직 친구 요청을 수락한 친구만이 우리가 구현한 QueryFriends API를 통해 반환됩니다. 이것이 실제 개발 중인 게임이었다면 애플리케이션의 브랜드 리뷰(Brand Review) 제출을 완료하고 게임을 친구에게 공유하여 동의를 받을 수 있었을 것입니다. 

그러나 지금은 샘플을 개발 중이므로 친구를 개발자 포털 조직에 추가해야 동의를 받을 수 있습니다. 추가하지 않으면 친구가 애플리케이션에 액세스할 수 없습니다. 이 조치는 에픽게임즈 생태계의 사용자인 여러분과 다른 게임 개발자 그리고 에픽게임즈를 브랜드 스푸핑, 피싱 등으로부터 보호하기 위해서입니다.
 
  1. https://dev.epicgames.com/portal/에서 개발자 포털에 로그인합니다.
  2. 왼쪽의 조직 탭을 클릭하고 적절한 역할을 선택한 후 파란색 초대 버튼으로 친구를 초대합니다.
 
Developer Portal Invite To Organization
조직에 멤버 추가하기

이제 친구가 제품, 클라이언트, 샌드박스, 디플로이에 연결하여 이 샘플 애플리케이션을 실행해야 합니다. 프로젝트의 /bin/ 디렉토리에 있는 다음 파일을 패키지로 만들고 공유합니다.
 
  • EOSCSharpSample.dll
  • EOSCSharpSample.exe
  • EOSCSharpSample.runtimeconfig.json
  • EOSSDK-Win32-Shipping.dll

처음 애플리케이션을 실행하면 동의 요청 창이 표시되고, 친구를 쿼리할 때 우리의 계정이 나타나는 것이 보일 것입니다. 그 후, 친구가 동의를 수락한 뒤 똑같은 절차를 실행하면 친구를 쿼리할 때 당 친구의 계정이 표시됩니다.
 
App Queried Friends
로그인한 사용자에 대해 친구 쿼리하기

오직 친구의 에픽 계정 ID만 볼 수 있으며 표시명은 볼 수 없다는 점에 유의하세요. 하지만 AuthService.Login()에서 사용한 것과 동일한 QueryUserInfo 호출을 사용하여 친구에 대한 추가 정보를 가져올 수 있습니다. 이 시점에서 상태 열은 항상 ‘오프라인(Offline)’으로 표시됩니다. Epic.OnlineServices.Presence.Status 열거형의 값이 0이기 때문입니다. 이 문제는 잠시 후에 다루겠습니다.

업데이트 구독하기

친구를 쿼리한 뒤에는 다시 쿼리하는 대신 친구 상태 변경 알림을 구독해야 합니다. 친구 인터페이스는 Epic.OnlineServices.Friends.FriendsStatus 열거형에 따라 다음의 네 가지 친구 상태 중 하나를 반환할 것입니다. NotFriends, InviteSent, InviteReceived, Friends. 앞서도 언급했듯 친구를 직접 관리할 API는 없지만 친구 요청이 수락되었다거나 누군가 친구 관계를 끊었는지를 알려면 업데이트를 구독해야 합니다. 친구 인터페이스는 이러한 업데이트를 구독 및 구독 해지하는 API를 제공합니다. 이 API를 구현해 보겠습니다.
 
  1. FriendsService.cs를 열고 다음 메서드를 추가합니다.

public static void SubscribeUpdates()
{
    var addNotifyFriendsUpdateOptions = new AddNotifyFriendsUpdateOptions();

    ViewModelLocator.Main.StatusBarText = $"Adding notification for friends updates...";

    ViewModelLocator.Friends.NotificationId = App.Settings.PlatformInterface.GetFriendsInterface()
.AddNotifyFriendsUpdate(addNotifyFriendsUpdateOptions, null, (OnFriendsUpdateInfo onFriendsUpdateInfo) =>
    {
        Debug.WriteLine($"OnFriendsUpdate: {onFriendsUpdateInfo.TargetUserId}");

        ViewModelLocator.Friends.Friends.SingleOrDefault(f => f.EpicAccountId == onFriendsUpdateInfo.TargetUserId).FriendsStatus = onFriendsUpdateInfo.CurrentStatus;
    });

    ViewModelLocator.Friends.FriendsSubscribeUpdates
.RaiseCanExecuteChanged();
    ViewModelLocator.Friends.FriendsUnsubscribeUpdates
.RaiseCanExecuteChanged();

    ViewModelLocator.Main.StatusBarText = string.Empty;
}

public static void UnsubscribeUpdates()
{
    ViewModelLocator.Main.StatusBarText = $"Removing notification for friends updates...";

    App.Settings.PlatformInterface.GetFriendsInterface()
.RemoveNotifyFriendsUpdate(ViewModelLocator.Friends.NotificationId);
    ViewModelLocator.Friends.NotificationId = 0;

    ViewModelLocator.Friends.FriendsSubscribeUpdates
.RaiseCanExecuteChanged();
    ViewModelLocator.Friends.FriendsUnsubscribeUpdates
.RaiseCanExecuteChanged();

    ViewModelLocator.Main.StatusBarText = string.Empty;
}

 
  • 빈 옵션을 전달하며 AddNotifyFriendsUpdate를 호출하여 알림 ID를 받습니다. 이는 알림이 구성되었으며 업데이트 구독 해지를 위해 사용해야 한다는 것을 확인합니다(UnsubscribeUpdates()와 같음).
  • 이제 알림이 전송될 때 실행하기를 원하는 함수 기능으로 콜백 메서드를 정의합니다. 여기서는 간단히 친구 목록에 새로운 상태를 알리는 다른 레코드를 추가해보겠습니다.
 
  1. 이 명령의 CanExecuteChanged 행동에 트리거도 추가하여 친구에 대한 첫 쿼리를 실시한 후에만 사용 가능하게 하겠습니다.

다음을 내용을,

ViewModelLocator.Friends.FriendsSubscribeUpdates
.RaiseCanExecuteChanged();
ViewModelLocator.Friends.FriendsUnsubscribeUpdates
.RaiseCanExecuteChanged();


FriendsService.QueryFriends()의 다음 라인 아래 추가합니다.

[...]
var friendStatus = App.Settings.PlatformInterface.GetFriendsInterface()
.GetStatus(getStatusOptions);

        ViewModelLocator.Friends.Friends.Add(new Friend()
        {
            EpicAccountId = friend,
            FriendsStatus = friendStatus
        });
    }
}


ViewModelLocator.Friends.FriendsSubscribeUpdates
.RaiseCanExecuteChanged();
ViewModelLocator.Friends.FriendsUnsubscribeUpdates
.RaiseCanExecuteChanged();

 
  1. FriendsSubscribeUpdatesCommand.cs 클래스를 Commands 폴더에 추가합니다.

public class FriendsSubscribeUpdatesCommand : CommandBase
{
    public override bool CanExecute(object parameter)
    {
        return !string.IsNullOrWhiteSpace(ViewModelLocator.Main.AccountId) && (ViewModelLocator.Friends.Friends.Count != 0) && (ViewModelLocator.Friends.NotificationId == 0);
    }

    public override void Execute(object parameter)
    {
        FriendsService.SubscribeUpdates();
    }
}

 
  1. Commands 폴더에 FriendsUnsubscribeUpdatesCommand.cs 클래스를 추가합니다.
public class FriendsUnsubscribeUpdatesCommand : CommandBase
{
    public override bool CanExecute(object parameter)
    {
        return !string.IsNullOrWhiteSpace(ViewModelLocator.Main.AccountId) && (ViewModelLocator.Friends.Friends.Count != 0) && (ViewModelLocator.Friends.NotificationId != 0);
    }

    public override void Execute(object parameter)
    {
        FriendsService.UnsubscribeUpdates();
    }
}

 
  1. FriendsViewModel.cs에서 새로운 명령을 선언하고 초기화합니다.

public FriendsQueryCommand FriendsQuery { get; set; }
public FriendsSubscribeUpdatesCommand FriendsSubscribeUpdates { get; set; }
public FriendsUnsubscribeUpdatesCommand FriendsUnsubscribeUpdates { get; set; }

public FriendsViewModel()
{
    FriendsQuery = new FriendsQueryCommand();
    FriendsSubscribeUpdates = new FriendsSubscribeUpdatesCommand();
    FriendsUnsubscribeUpdates = new FriendsUnsubscribeUpdatesCommand();
}


이제 앱을 실행할 때 친구를 쿼리하고 업데이트를 구독 및 구독 해지할 수 있습니다. 업데이트를 구독하면 목록에 등록된 친구를 에픽게임즈 런처에서 제거할 수 있으며, ListView에서 해당 친구가 NotFriends 상태의 새로운 엔트리로 나타나는 것을 볼 수 있습니다.

친구 현재상태 쿼리하기

이제 마지막으로 지난 연재글에서 구현한 것을 바탕으로 친구 현재상태 정보 쿼리에 함수 기능을 구현하는 일만 남았습니다. 이제 QueryPresence를 활용하여 각 친구의 현재상태를 가져올 수 있습니다. 
 
  1. Commands 폴더에서 PresenceQueryCommand를 열고 두 메서드를 다음 코드로 교체합니다.

public override bool CanExecute(object parameter)
{
    if (parameter == null)
        return !string.IsNullOrWhiteSpace(ViewModelLocator.Main.AccountId);
    else
        return ((Friend)parameter).EpicAccountId != null;
}

public override void Execute(object parameter)
{
    if (parameter == null)
        PresenceService.Copy(EpicAccountId
.FromString(ViewModelLocator.Main.AccountId), EpicAccountId
.FromString(ViewModelLocator.Main.AccountId));
    else
        PresenceService.Query(((Friend)parameter).EpicAccountId);
}

 
  • CanExecute 코드를 수정하여 파라미터도 체크하고(FriendsView ListView로부터 전달할 선택된 친구) ‘else’ 구문을 추가하여 친구가 전달됐을 때 PresenceService.Query() 호출을 실행하겠습니다.
 
  1. FriendsViewModel을 열고 PresenceQueryCommand를 인스턴스화합니다.

public FriendsQueryCommand FriendsQuery { get; set; }
public FriendsSubscribeUpdatesCommand FriendsSubscribeUpdates { get; set; }
public FriendsUnsubscribeUpdatesCommand FriendsUnsubscribeUpdates { get; set; }
public PresenceQueryCommand PresenceQuery { get; set; } 

public FriendsViewModel()
{
    FriendsQuery = new FriendsQueryCommand();
    FriendsSubscribeUpdates = new FriendsSubscribeUpdatesCommand();
    FriendsUnsubscribeUpdates = new FriendsUnsubscribeUpdatesCommand();
    PresenceQuery = new PresenceQueryCommand();
}

 
  1. 마지막으로 다음 라인을 FriendsView.xaml.cs 내의 FriendsListView_SelectionChanged 이벤트 핸들러에 추가하여 친구를 선택했을 때만 상태 쿼리 버튼이 활성화되게 합니다.

ViewModel.PresenceQuery.RaiseCanExecuteChanged();

이제 애플리케이션을 실행한 후 친구 쿼리 버튼을 누르고 온라인 상태인 친구를 선택하고 상태 쿼리 버튼을 누르면 UI에 해당 친구의 상태 업데이트가 표시됩니다.
 
App Queried Friends Status
쿼리된 친구 상태

이전 연재글에서 설명했듯이 친구의 현재상태 정보가 변경되었을 때 알림을 받으려면 프로덕션 게임에서 AddNotifyOnPresenceChanged를 구현해야 합니다.

코드 다운로드

이 연재글에서 보여준 코드를 아래에서 다운로드하세요. 솔루션에 SDK를 추가하려면 본 연재글의 5~10단계를 수행하고 SDK 크리덴셜을 ApplicationSettings.cs에 추가하세요.
 
다음 연재글에서는 에픽 온라인 서비스의 플랫폼과 무관한 백엔드 서비스인 게임 서비스를 사용해보겠습니다. 여러 ID 공급자 중 하나를 사용하여 이러한 서비스에 사용자를 인증하는 연결 인터페이스부터 설명하겠습니다.

전체 연재글은 연재글 자료에서 보실 수 있습니다. 이 연재글에 대한 질문이나 피드백이 있다면 아래 버튼을 눌러 커뮤니티 포럼으로 이동한 후 알려주세요.

    여러분의 성공이 곧 에픽의 성공입니다

    에픽은 개방되고 통합된 게이밍 커뮤니티를 지향합니다. 에픽 온라인 서비스를 누구에게나 무료로 제공함으로써 더 많은 개발자들이 플레이어 커뮤니티에 더 나은 서비스를 제공할 수 있도록 지원하고자 합니다.