월드 유저 제재 관리

월드가 인기가 많아지고, 많은 이들이 플레이를 하다 보면 월드의 규칙을 위반하는 유저가 나타날 수 있습니다. 많은 유저가 즐겁게 월드를 즐길 수 있도록 크리에이터는 그 유저를 적절하게 제재해야 합니다. 메이플스토리 월드에서는 월드 인사이트의 PlayerBan과 UserService의 메소드를 활용해 유저를 특정 기간 혹은 영구 제재할 수 있습니다. 를 통해 유저 제재 시, 월드에서 제재된 상태의 유저가 메이플스토리 월드를 탈퇴 후 새롭게 가입했을 때 플랫폼에서 유저의 이전 제재 이력을 식별하고, 제재 유무를 자동으로 승계합니다.

유저를 제재하고, 월드 입장을 제한하기 위해서는 2가지 작업이 모두 완료되어야 합니다.

  1. 월드 인사이트에서 제재할 유저 등록
  2. 해당 월드에서 제재 여부를 확인하는 스크립트 작성



## 월드 인사이트 제재 등록

유저를 제재하기 위해서는 유저의 User Id 혹은 프로필 코드가 필요합니다.

### 제재 권한

그룹 월드인 경우 그룹장, 매니저만이 제재 등록 및 해제, 제재 목록 조회가 가능합니다. 제재 현황의 Period는 아래 3가지 중 하나로 표시됩니다.

  * Banned: 현재 제재 중입니다.
  * Scheduled: 제재 예정입니다.
  * Expired : 제재가 종료되었습니다.



### 단건 등록

  1. 월드 인사이트 - Player Ban - [\+ Register] 버튼을 누릅니다.
  2. 팝업창에서 각 항목에 맞는 값을 입력합니다. [png](1779429047356782417c586b44a2ea88030b98828a4b6)
     * Profile Code/User Id: 제재할 플레이어의 식별자
     * Reason Key: 제재 유저가 월드에 진입했을 때 나타날 제재 사유 키입니다. 스크립트에서 이 값을 Key로 사용합니다.
     * Start At : 제재 시작일 입니다. 기본값은 현재 시각입니다.
     * End At : 제재 종료일 입니다. 종료일을 설정하지 않으면 영구 제재됩니다.
  3. [Register] 버튼을 눌러 제재 유저를 등록합니다.



### 대량 등록

제재 유저가 많을 경우 CSV 파일을 활용해 일괄로 제재 유저를 등록할 수 있습니다. 등록/해제용 CSV는 특정 형식을 따라야 합니다. 대량 등록을 하고 나면 Linked Profiles가 일단 Verifying 상태로 변합니다. 이는 기존에 제재를 등록했던 UserId나 profile code 중 연결되는 것이 있는지 탐색하는 과정입니다. Verifying은 최대 10분 정도 소요됩니다. Verifying 이후 연결된 UserId나 profile code가 있다면 Linked Profiles에 표시됩니다. 이때 연결된 User Id나 Profile code가 이미 서비스 탈퇴를 한 상태라면 Deactivated로 표시됩니다. 만약 방금 등록한 UserId나 Profile code가 유효하지 않다면 Invalid로 표시됩니다.

  1. [Bulk] 버튼을 누르고, CSV 파일을 다운로드 합니다. [png](17793428771993464cd1479804b05870b0c1d69628e0a)
  2. CSV 파일 형식에 맞춰 제재 등록할 유저의 값을 입력합니다.
  3. CSV 파일을 추가하고, [Upload] 버튼을 누릅니다.
  4. 등록이 완료되면, Linked Profiles가 Verifying 상태가 됩니다. 10분 이내에 상태가 갱신됩니다. [png](17793328909721ee2bad0f73e4abc92bfb78fa70f7895)
     * Verifying : 제재 등록된 유저의 연결 프로필 및 기존 제재 여부를 확인 중인 상태
     * Deactivated : 제재 등록된 유저가 서비스 탈퇴를 한 상태
     * Invalid : 제재 등록된 유저의 UserId, ProfileCode가 유효하지 않은 상태



#### CSV 예시

[{"Action":"REGISTER","PlayerIdentifyType":"ProfileCode","PlayerIdentifier":"AAAAA","ReasonKey":"Default","StartTime":"2026-04-30T07:00:00Z","EndTime":"2026-05-30T07:00:00Z"},{"Action":"REGISTER","PlayerIdentifyType":"UserId","PlayerIdentifier":"BBBBB","ReasonKey":"Scam","StartTime":"2026-04-30T07:00:00Z","EndTime":"nan"}]

  * Action: 현재 제재 상태를 의미합니다. 
    * REGISTER: 제재합니다.
    * UNREGISTER: 제재를 해지합니다.
  * PlayerIdentifyType: 제재할 유저의 식별자 타입입니다. 2가지 중 하나를 선택해 입력합니다. 
    * UserId: 계정 고유의 UserId입니다.
    * ProfileCode: 유저의 프로필 코드입니다.
  * PlayerIdentifier: 타입에 맞는 실제 유저 식별자 값입니다.
  * ReasonKey: 제재 사유입니다. 크리에이터가 직접 사유를 입력해야 합니다. 스크립트에서 이 값을 Key로 사용합니다.
  * StartTime: 제재 시작일입니다. 필수 입력 항목입니다.
  * EndTime: 제재 종료일 입니다. 종료일을 설정하지 않으면 영구 제재됩니다.



## 월드 인사이트 제재 해제

크리에이터의 월드 정책에 따라 특정 기간 동안만 유저를 제재할 경우 제재 해지 작업이 필요합니다.

### 단건 해제

  1. 해제할 항목의 휴지통 버튼을 누릅니다. [png](1779342803306c58635df832d416f8eadbf69b27a750c)
  2. 확인 버튼을 누르면 즉시 해당 유저의 제재가 해제됩니다.



### 대량 해제

제재 해제 유저가 많을 경우 CSV 파일을 활용해 일괄로 제재를 해제할 수 있습니다. 등록/해제용 CSV는 특정 형식을 따라야 합니다. 대량으로 제재를 해제할 경우 전체 해제까지 약 10분 정도 소요될 수 있습니다.

  1. Bulk 버튼 클릭 후 Unregister 선택
  2. CSV 파일에서 Action 항목을 UNREGISTER로 입력합니다. 

[{"index":"Action","0":"UNREGISTER"},{"index":"PlayerIdentifyType","0":"UserId"},{"index":"PlayerIdentifier","0":"BBBBB"},{"index":"ReasonKey","0":"Scam"},{"index":"StartTime","0":"2026-04-30T07:00:00Z"},{"index":"EndTime","0":"nan"}]

  3. 작성한 CSV 파일을 업로드하고, [Register]를 눌러 등록합니다.



> Tip Linked Profiles가 Verifying 상태인 경우에는 제재를 해제할 수 없습니다. 상태 변경이 완료된 후에 제재를 해제해야 합니다.

## 월드에서 제재 처리

월드 인사이트에서 제재를 등록한 후 크리에이터는 `[UserService](/apiReference/Services/UserService{"target":"_blank"})`의 메소드를 활용해 유저 입장 시점에 제재 여부를 확인하고 처리하는 스크립트를 작성해야 합니다. 월드 인사이트 등록만으로는 유저의 입장이 자동으로 차단되지 않기 때문입니다.

  * `_UserService:IsUserBanned(string profileCode)`: 유저가 제재 대상인지 여부를 반환합니다.
  * `_UserService:GetUserBanReason(string profileCode)`: 유저의 제재 사유 키를 반환합니다.



### 제재 처리 예제

유저가 월드에 입장할 때 제재 여부를 확인하고, 제재 대상이라면 사유 메시지를 팝업으로 표시한 뒤 10초 후 월드에서 추방하는 예제입니다.

  1. 새로운 Logic을 생성합니다.
  2. 이름을 `BanGateLogic`으로 변경하고, 아래와 같이 작성합니다. 
         
         @Component
         script EntryBanKicker extends Component
         property number kickDelaySeconds = 10
         
         @ExecSpace("ClientOnly")
         method void ShowBanPopup(string message)
         -- 제재 사유 메시지를 팝업 메시지로 표시합니다.
         _UIPopup:Open(message, nil, nil)    
         end
         
         @EventSender("Self")
         handler HandleUserEnterEvent(UserEnterEvent event)
         local profileCode = event.ProfileCode
         local userId = event.UserId
         
         local isBanned = _UserService:IsUserBanned(profileCode)
         if not isBanned then
             return
         end
         
         local key = _UserService:GetUserBanReason(profileCode)
         local message = _BanReasonTable:GetMessage(key)
         
         -- 해당 유저 클라이언트에만 팝업을 전달합니다.
         self:ShowBanPopup(message, userId)
         
         local delay = self.kickDelaySeconds
         _TimerService:SetTimerOnce(function()
             -- 팝업 메시지 표시 후 유저를 추방합니다.
             _UserService:KickUser(userId, KickReason.WorldContent)   
         end, delay)
         end
         end
         



    
    
    3. 새로운 `BanReasonTable` Logic을 생성하고, 월드 인사이트의 Reason Key에 입력한 값에 맞는 메시지가 나올 수 있도록 아래와 같이 작성합니다.
    예제의 경우 Reason Key에 DEFAULT, CHEAT, ABUSE, PROFANITY를 사용했습니다.
        
        ```lua
    @Component
    script RestrictionMessageProvider extends Component
        method string GetMessage(string key)
        local reasons = {
            ["DEFAULT"]   = "운영 정책 위반으로 인해 월드 입장이 제한되었습니다.",
            ["CHEAT"]     = "어뷰징/치트 사용이 확인되어 월드 입장이 제한되었습니다.",
            ["ABUSE"]     = "다른 유저에게 피해를 준 행위가 확인되어 월드 입장이 제한되었습니다.",
            ["PROFANITY"] = "비속어/욕설 사용이 확인되어 월드 입장이 제한되었습니다.",
        }
    
        if key == nil or key == "" then
            return reasons["DEFAULT"]
        end
    
        local msg = reasons[key]
        if msg == nil or msg == "" then
            return reasons["DEFAULT"]
        end
        return msg
        end
    end