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를 통해 여러 가지 유용한 스크립트를 만들 수 있게 되어 활용할 곳이 많아졌다.



Next Post
Keepalived VRRP를 사용한 소프트웨어 HA 환경 구성