> For the complete documentation index, see [llms.txt](https://docs.ggwp.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.ggwp.com/kr/ggwp-sdk/handling-sanctions.md).

# 제재 처리

클라이언트 SDK는 모든 채널에서 경고 및 제재 처리를 제공합니다 - `채팅`, `게임` 및 `음성` . 이는 사용자에게 다음 방식으로 부여될 수 있습니다 [대시보드에서 수동으로](/kr/dashboard-user-guide/player-list.md#sanctioning-a-player) 또는 [자동모드(automod)에 의해](https://docs.ggwp.com/kr/ggwp-sdk/pages/8102de2e3efe45782d5015aedf0b40ae201edcfd#id-4.2-ggwp-automod).&#x20;

SDK 초기화 후 Sanctions를 사용할 수 있습니다:

```csharp
GGWPSDK.Instance?.InitializeSDK("user_id", "username");

if (GGWPSDK.Instance?.SanctionsAPI != null)
{
    // 제재 콜백을 사용할 준비가 되었습니다
}
```

#### Sanctions 구독하기

```csharp
using GGWP.Sanctions;
using GGWP.Utils.Async;

// 인증 전에 구독을 생성할 수 있습니다
var subscriber = new Subscriber<ChannelSanctionsState>(
    GGWPSDK.Instance?.SanctionsAPI.SubscribeSanctionsState()
);

// 하지만 실시간 업데이트는 코드 교환 인증 이후에만 시작됩니다
string authCode = GetAuthCodeFromYourBackend();
await GGWPSDK.Instance?.AuthManager.ExchangeAuthCode(authCode);

// 이제 연결이 설정되었고 실시간 업데이트를 수신합니다
await foreach (var state in subscriber.GetStream())
{
    Debug.Log($"채팅 상태: {state.chat.status}");
    Debug.Log($"게임 상태: {state.game.status}");
    Debug.Log($"음성 상태: {state.voice.status}");
}
```

#### 제재 상태 모니터링

모든 채널의 제재 상태 변경을 구독하세요. 실시간 업데이트는 인증을 완료한 후에만 흐르기 시작한다는 점을 기억하세요:

```csharp
using GGWP.Sanctions;
using GGWP.Utils.Async;

var subscriber = new Subscriber<ChannelSanctionsState>(
    GGWPSDK.Instance?.SanctionsAPI.SubscribeSanctionsState()
);

await foreach (var state in subscriber.GetStream())
{
    // 채팅 채널 확인
    Debug.Log($"채팅 상태: {state.chat.status}");
    
    // 게임 채널 확인
    Debug.Log($"게임 상태: {state.game.status}");
    
    // 음성 채널 확인
    Debug.Log($"음성 상태: {state.voice.status}");
}
```

#### 채널 상태 이해하기

각 채널은 다음 속성을 가집니다:

```csharp
// 특정 채널 상태 가져오기
SanctionState chatState = state.chat;

// 상태 (활성 또는 음소거)
GGWP.Sanctions.Impl.MuteStatus status = chatState.status;

// 만료 시간 (음소거된 경우)
DateTime? expiryAt = chatState.expiryAt;

// 경고 정보 (경고된 경우)
var warning = chatState.warning;

// 제재 세부정보 (제재된 경우)
var sanction = chatState.sanction;
```

#### 초기 상태

사용자에게 제재가 없을 때 모든 채널은 활성(Active) 상태에 있습니다. 인증 후 연결이 설정되면 이 초기 상태를 수신하게 됩니다:

```csharp
await foreach (var state in subscriber.GetStream())
{
    // 모든 채널은 Active로 시작합니다
    Assert.AreEqual(state.chat.status, GGWP.Sanctions.Impl.MuteStatus.Active);
    Assert.AreEqual(state.game.status, GGWP.Sanctions.Impl.MuteStatus.Active);
    Assert.AreEqual(state.voice.status, GGWP.Sanctions.Impl.MuteStatus.Active);
    
    // 만료, 경고 또는 제재 없음
    Assert.Null(state.chat.expiryAt);
    Assert.Null(state.chat.warning);
    Assert.Null(state.chat.sanction);
    
    break;
}
```

#### 적용된 제재 처리

제재가 적용되면 상태 변화를 모니터링하세요.

```csharp
using System.Threading;

var subscriber = new Subscriber<ChannelSanctionsState>(
    GGWPSDK.Instance?.SanctionsAPI.SubscribeSanctionsState()
);

using var cts = new CancellationTokenSource();

await foreach (var state in subscriber.GetStream(cts.Token))
{
    if (state.game.status == GGWP.Sanctions.Impl.MuteStatus.Muted)
    {
        Debug.Log("사용자가 게임 채널에서 음소거되었습니다");
        
        // 음소거가 해제될 시기를 확인하려면 만료 시간을 확인하세요
        if (state.game.expiryAt != null)
        {
            Debug.Log($"음소거 만료 시각: {state.game.expiryAt}");
        }
        
        // 상태 전환을 이해하려면 제재 세부정보를 가져오세요
        if (state.game.sanction != null)
        {
            var sanction = state.game.sanction.Value;
            Debug.Log($"이전 상태: {sanction.previousStatus}");
            Debug.Log($"현재 상태: {sanction.currentStatus}");
        }
        
        break;
    }
}
```

#### 권장 사용 패턴

권장 패턴은 먼저 인증한 다음 제재를 구독하는 것입니다. 이렇게 하면 연결이 즉시 설정되고 초기 상태 정보를 놓치지 않습니다:

```csharp
// 1단계: 사용자 인증
string authCode = GetAuthCodeFromYourBackend();
var authResult = await GGWPSDK.Instance?.AuthManager.ExchangeAuthCode(authCode);

if (authResult == GGWP.Impl.Result.Success)
{
    // 2단계: 이제 제재를 구독합니다
    var subscriber = new Subscriber<ChannelSanctionsState>(
        GGWPSDK.Instance?.SanctionsAPI.SubscribeSanctionsState()
    );

    // 3단계: 실시간으로 제재 상태 업데이트를 처리합니다
    await foreach (var state in subscriber.GetStream())
    {
        // 제재 상태 변경이 발생할 때 처리합니다
        Debug.Log($"채팅: {state.chat.status}");
    }
}
```

#### 취소 토큰 사용

취소 토큰을 사용하여 구독 수명을 제어하세요. 이는 사용자가 로그아웃하거나 특정 화면을 닫을 때처럼 제재 모니터링을 중지하려는 경우 유용합니다:

```csharp
using System.Threading;

var cts = new CancellationTokenSource();

try
{
    await foreach (var state in subscriber.GetStream(cts.Token))
    {
        // 상태 처리
        
        if (someCondition)
        {
            cts.Cancel(); // 수신 중지
            break;
        }
    }
}
catch (OperationCanceledException)
{
    Debug.Log("제재 모니터링이 취소되었습니다");
}
```
