Skip to content
신선한 자몽 농장
Go back

[Game] 마인크래프트 서버 내 아이템 사용 제한하기

효율적인 모드 서버 운영을 위해

친구들과 함께 게임을 하면서 종종 마인크래프트 모드 서버를 운영하고는 한다. 이럴 때 가장 큰 문제는 다수의 모드를 사용하면서 생기는 서버 성능 문제다. 대부분의 모드 호환성이나 맵 로딩 문제는 설정을 제한하거나 맵을 사전 로딩 시켜놓는 방식으로 해결할 수 있다. 아니면 물리적으로 서버 사양을 빵빵하게 주면 해결된다.

가장 큰 문제는 겉날개에 있다.

겉날개와 폭죽을 사용한 부스트로 인해 맵 로딩보다 더 빠른 이동으로 서버에 굉장히 많은 부하를 주고 있다.

이를 해결하기 위해 근본이 되는 겉날개 자체를 사용하지 못하도록 하는 방안을 찾아보던 중 KubeJS라는 모드를 알게 되어서 이를 활용하고자 한다.


KubeJS란 무엇인가?

모드 다운로드 페이지 : KubeJS - Modrinth

KubeJS는 JavaScript를 사용해서 마인크래프트를 커스터마이징할 수 있게 해주는 모드다.

보통 마인크래프트 모드를 만들려면 Java 코드를 작성하고 컴파일하고 패키징하는 복잡한 과정을 거쳐야 하는데, KubeJS를 사용하면 JavaScript 스크립트만으로 다양한 기능을 구현할 수 있다.

주요 기능

KubeJS로 할 수 있는 것들은 굉장히 많다

스크립트 실행 시점

KubeJS는 세 가지 시점에 스크립트를 실행한다:

  1. Startup: 게임이 시작될 때 한 번 실행 (아이템/블록 등록용)
  2. Server: 월드에 접속할 때 실행 (레시피, 이벤트 처리용)
  3. Client: 클라이언트 측에서 실행 (UI 커스터마이징용)

우리가 겉날개 사용을 막으려면 Server 스크립트에서 아이템 사용 이벤트를 가로채면 된다.


적용방법

우선 KubeJS와 의존성 모드인 Rhino를 설치했다는 가정하에 진행한다.

스크립트는 마인크래프트 서버 내 kubejs/server_scripts 경로에 JavaScript 파일로 작성하면 된다.

겉날개 사용을 차단하려는 것이지만, 엔드에서 힘들게 얻은 겉날개를 강제로 빼앗으면 서버 내 플레이어들의 분노를 살 수 있으니 적당한 보상으로 교환하게 할 예정이다.

겉날개의 가치를 생각해보면 네더라이트 주괴 1개 정도가 적당하다고 생각하여 다음과 같은 동작을 제공할 것이다.

동작 흐름도

1. 플레이어의 인벤토리를 주기적으로 체크 (5초마다)
   ↓
2. 겉날개 아이템이 감지되는가?
   ├─ 예 → 3단계로 진행
   └─ 아니오 → 1단계로 돌아감
   ↓
3. 감지된 겉날개 아이템 제거
   ↓
4. 네더라이트 주괴 1개를 플레이어에게 지급
   ↓
5. 플레이어에게 경고 메시지 출력
   ("겉날개는 서버 성능을 위해 네더라이트 주괴로 교환되었습니다!")
   ↓
6. 1단계로 돌아가서 계속 감시

이런 방식으로 동작하면 플레이어가 겉날개를 획득하는 즉시 자동으로 네더라이트 주괴로 교환되어 서버 성능 저하를 방지할 수 있다.

이제 이 동작 흐름에 맞게 스크립트를 작성해보자.

스크립트 작성

스크립트 작성은 Claude Code의 도움을 받았다.

// kubejs/server_scripts/elytra_block.js

var ELYTRA_ID = "minecraft:elytra";
var REPLACE_ITEM = "minecraft:netherite_ingot";
var CHECK_INTERVAL = 20;

PlayerEvents.tick(function(event) {
    var player = event.player;

    if (player.tickCount % CHECK_INTERVAL !== 0) return;

    // 1. 장비 슬롯 검사 (흉갑 슬롯 위주)
    var armorSlotNames = ["chest", "head", "legs", "feet"];

    for (var s = 0; s < armorSlotNames.length; s++) {
        var slotName = armorSlotNames[s];
        var armorItem = player.getItemBySlot(slotName);
        if (armorItem && armorItem.id === ELYTRA_ID) {
            player.setItemInSlot(slotName, Item.of(REPLACE_ITEM));
            player.tell("§c[서버] 겉날개는 이 서버에서 사용이 금지되어 있습니다.");
            console.info("[ElytraBan] " + player.username + " 장비 슬롯(" + slotName + ")에서 겉날개 제거");
        }
    }

    // 2. 인벤토리 전체 검사
    var inv = player.inventory;
    var invSize = inv.containerSize;

    for (var i = 0; i < invSize; i++) {
        var invItem = inv.getItem(i);
        if (invItem && invItem.id === ELYTRA_ID) {
            inv.setItem(i, Item.of(REPLACE_ITEM));
            player.tell("§c[서버] 겉날개는 이 서버에서 사용이 금지되어 있습니다.");
            console.info("[ElytraBan] " + player.username + " 인벤토리 슬롯 " + i + "에서 겉날개 제거");
        }
    }
});

이제 적용을 위해 서버 내에서 /reload 명령어로 새로고침하거나 서버를 재시작하면 된다.


마무리

위 과정을 통해 서버 내 겉날개 사용을 효과적으로 제한했다.

대신 플레이어들의 불만을 잠재우기 위해 이동속도는 느리지만 공중 체공이 가능한 제트팩 모드를 추가함으로써 이동에 대한 영향은 줄였다.

추후 KubeJS를 통해 여러 가지 유용한 스크립트를 만들 수 있게 되어 활용할 곳이 많아졌다.



Previous Post
Synology 대용량 파일 업로드 실패 해결하기
Next Post
Keepalived VRRP를 사용한 소프트웨어 HA 환경 구성