> ## Documentation Index
> Fetch the complete documentation index at: https://playwave.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# onVerified 콜백

> 검증 흐름 종료 시 플레이어당 1회 발화하는 콜백 (PC방 유저 여부 무관)

`onVerified`는 `PlayWaveServer.init`에 전달하는 선택 콜백으로, 검증 흐름이 종료될 때 **플레이어당 정확히 1회** 호출됩니다. PC방 유저인지 여부와 무관하게 항상 발화합니다.

이 콜백이 없을 때는 "검증은 끝났지만 카페 유저는 아님"을 알기 위해 `isPcCafeUser`를 폴링해야 했습니다 (`onPcCafe`는 카페 유저에게만 발화하므로). `onVerified`가 그 한계를 메웁니다.

## 시그니처

```lua theme={null}
onVerified = function(player, isPcCafe, reason)
    -- player:    Player 인스턴스
    -- isPcCafe:  boolean — 확정값 (실패 경로에서는 항상 false)
    -- reason:    string — PlayWaveServer.VerifyReason 값 중 하나
end
```

* `PlayWaveClientReady` 이벤트 1회당 정확히 1번 발화
* `isPcCafe`는 항상 boolean
* `reason`은 `PlayWaveServer.VerifyReason`에 정의된 값 중 하나 (아래 참조)
* 콜백 내부에서 발생하는 에러는 `pcall`로 잡혀 warn 로그만 남기고, verify 흐름 자체는 깨지지 않음

## 발화 시점

`onVerified`는 `PlayWaveClientReady` 핸들러 내부에서 호출됩니다. 즉, 클라이언트의 `PlayWaveClient` 스크립트가 로드 완료를 서버에 알린 후입니다. 어떤 분기를 타느냐에 따라 정확한 발화 지점이 다릅니다.

| 분기                          | 발화 시점                                        | reason                                                                                 | `isPcCafe`                      |
| --------------------------- | -------------------------------------------- | -------------------------------------------------------------------------------------- | ------------------------------- |
| 텔레포트 resume                 | `POST /game/session/check` 응답 후, 세션 등록 완료 시점 | `RESUMED` (성공) 또는 `RESUME_REJECTED` (4xx/5xx/네트워크 등 모든 실패)                             | 성공 → 출발지에서 상속된 값 / 실패 → `false` |
| 신규 OTT 검증                   | `POST /game/session/verify` 응답 후             | `VERIFIED` (성공) / `REQUEST_FAILED` (HTTP/네트워크/디코딩 에러) / `REJECTED` (`is_valid: false`) | 성공 → 서버 응답값 / 실패 → `false`      |
| `LaunchData`에 OTT 없음        | HTTP 호출 없이 즉시                                | `NO_OTT`                                                                               | `false`                         |
| OTT가 `playwave_` prefix가 아님 | HTTP 호출 없이 즉시                                | `INVALID_PREFIX`                                                                       | `false`                         |

### `onPcCafe`와의 발화 순서

둘 다 발화하는 카페 유저 성공 경로 기준:

* **신규 OTT 검증**: `onPcCafe` + 클라이언트 `PC_CAFE` 이벤트 → `onVerified`
* **텔레포트 resume**: `onVerified` → `onPcCafe` + 클라이언트 `PC_CAFE` 이벤트

<Warning>
  두 경로 사이의 순서가 다르므로 의존하지 마세요. `onVerified`는 순수하게 "검증 흐름 종료" 신호로만 사용하고, 카페 전용 부수효과는 `onPcCafe`에 두세요.
</Warning>

### 발화하지 않는 경우

* `TeleportInitFailed` 세션 복원 — 텔레포트 시도 전에 이미 검증된 플레이어이므로 재발화 시 동일 플레이어에게 중복 발화됨
* `PlayerRemoving` — 검증 이벤트가 아님

## 검증 reason 값

`onVerified`가 받는 `reason`은 `PlayWaveServer.VerifyReason`에 정의된 값입니다.

| Reason            | 의미                                                | `isPcCafe` |
| ----------------- | ------------------------------------------------- | ---------- |
| `VERIFIED`        | OTT 검증 성공                                         | 서버 응답값     |
| `RESUMED`         | 텔레포트 resume + `/game/session/check` 통과            | 출발지에서 상속   |
| `RESUME_REJECTED` | 텔레포트 resume이 서버 사이드 check에서 실패 (위변조, 만료 등)        | 항상 `false` |
| `NO_OTT`          | `LaunchData`에 OTT 없이 진입                           | 항상 `false` |
| `INVALID_PREFIX`  | OTT가 `playwave_` prefix로 시작하지 않음 (다른 시스템 토큰으로 간주) | 항상 `false` |
| `REQUEST_FAILED`  | verify HTTP/네트워크/디코딩 에러                           | 항상 `false` |
| `REJECTED`        | verify API가 `is_valid: false` 반환                  | 항상 `false` |

## 사용 예시

```lua theme={null}
local PlayWaveServer = require(script.PlayWaveServer)
local Reason = PlayWaveServer.VerifyReason

PlayWaveServer.init({
    apiKey = apiKey,
    apiUrl = apiUrl,

    onPcCafe = function(player)
        -- 카페 전용 혜택 (카페 유저일 때만 발화)
    end,

    onVerified = function(player, isPcCafe, reason)
        if reason == Reason.VERIFIED or reason == Reason.RESUMED then
            -- 정상 세션 — isPcCafe로 분기
        else
            -- 검증이 정상 세션을 만들지 못함
        end
    end,
})
```

## `onPcCafe`와의 관계

| 결과                               | `onPcCafe` | `onVerified`                             |
| -------------------------------- | ---------- | ---------------------------------------- |
| 카페 유저, 검증 성공                     | 발화         | 발화 (`VERIFIED`, `isPcCafe=true`)         |
| 비카페 유저, 검증 성공                    | 발화 안 함     | 발화 (`VERIFIED`, `isPcCafe=false`)        |
| Resume 성공, 카페                    | 발화         | 발화 (`RESUMED`, `isPcCafe=true`)          |
| Resume 거절                        | 발화 안 함     | 발화 (`RESUME_REJECTED`, `isPcCafe=false`) |
| OTT 없음 / prefix 불일치 / 요청 에러 / 거절 | 발화 안 함     | 해당 reason으로 발화, `isPcCafe=false`         |

`onVerified`는 순수 추가 기능입니다. 기존 `onPcCafe` 동작은 변경되지 않습니다.

## 비고

<Note>
  `RESUME_REJECTED`로 텔레포트 resume의 서버 check가 실패해도 로컬 세션은 그대로 둡니다. 다음 하트비트에서 서버가 404/410을 반환하면 자동으로 정리됩니다.
</Note>
