삽질

팰월드에 RCON으로 인게임 메시지 및 어드민 명령어 사용하기

maengis 2024. 1. 31. 21:27

설정 파일 수정 후 팰월드 재시작 해서 RCON을 쓸 수 있게 함.

RCONEnabled=True,RCONPort=25575

 

 

서버에 ARRCON 설치

https://github.com/radj307/ARRCON/releases

 

Releases · radj307/ARRCON

Lightweight Source RCON client that works on Windows, macOS, & Linux. - radj307/ARRCON

github.com

 

sudo wget https://github.com/radj307/ARRCON/releases/download/3.3.7/ARRCON-3.3.7-Linux.zip
sudo unzip ARRCON-3.3.7-Linux.zip

 

테스트

 /home/app/ARRCON/ARRCON -P 25575 -p {어드민비밀번호} "broadcast test"

 

 


https://nodecraft.com/support/games/palworld/palworld-server-admin-commands

 

Palworld Server Admin Commands - Nodecraft

Manage your Palworld dedicated or community server with in-game or RCON commands.

nodecraft.com

 

https://nodecraft.com/support/games/palworld/palworld-server-moderation-guide

 

Palworld Moderator Guide

Find out who is playing on your Palworld server, and how to moderate it effectively.

nodecraft.com

 

명령어는 위에 링크 참조.

메모리 누수가 심해서 팰월드 재시작시 사용자들이 모인 텔레그램에 공지 후 재시작을 하고 있고, 메모리 한계치가 아니더라도 메모리 청소 겸 9시, 18시마다 재시작을 하고 있는데, RCON을 이용해서 기존에 텔레그램에 하던 공지를 인게임 메시지로 변경하고, 특정 시간에 하던 재시작을 사용자 접속 유무 판단해서 정해놓은 메모리 이상 쓰고 있으면 재시작.

 

import subprocess
import os
import time

COUNT_FILE = '/home/app/palworld_chk_cnt' # 분마다 메모리 초과 확인을 하면서 몇 번 체크 했는지 기록할 파일
RESTART_WAIT = 3 # 분 단위. 재시작 하기 전에 3분, 2분, 1분를 사용자에게 고지하기 위해 사용
MEMORY_LIMIT = 14.5 # 기가 단위. 한계치로 정할 메모리.
MEMORY_IDLE = 4 # 기가 단위. 사용자가 없을 때 해당 메모리보다 높게 사용 중이면 재시작 하기 위해 사용
ADMINPASSWORD = '' # ini 설정에 적은 관리자 비밀번호
RCON_PORT = '25575' # ini 설정에 적은 RCON 포트 (호스트는 같은 로컬이라 따로 지정 안 함)
RCON_CMD = '/home/app/ARRCON/ARRCON' # ARRCON 위치

def rcon_send(cmd):
    # 팰월드가 정상 응답 안 하는 경우에 ARRCON이 CPU를 너무 많이 써서 타임아웃 10초 사용
    return os.popen(f'timeout 10 {RCON_CMD} -P {RCON_PORT} -p {ADMINPASSWORD} "{cmd}"').read()

def send_msg(msg):
    cmd = f'broadcast {msg}'
    rcon_send(cmd)

def get_memory_usage():
    # free -b 명령어 실행
    result = subprocess.run(['free', '-b'], stdout=subprocess.PIPE)
    output = result.stdout.decode()

    # awk를 사용하여 used 메모리 양 추출
    memory_used = subprocess.run(['awk', '/^Mem:/ {print $3}'], input=output, stdout=subprocess.PIPE, text=True)
    return int(memory_used.stdout.strip())

def restart_service():
    send_msg('Restart.')
    rcon_send('save')
    time.sleep(2)
    subprocess.run(['sudo', 'service', 'palworld', 'restart'])

# 메모리 사용량 확인
used_memory = get_memory_usage()

cnt = int(os.popen(f'cat {COUNT_FILE}').read())

# 사용량을 초과하는 경우 서비스 재시작
if used_memory > (MEMORY_LIMIT * 1024 * 1024 * 1024):
    cnt_minute = (RESTART_WAIT + 1) - cnt - 1
    cnt_minute_str = str(cnt_minute)

    if cnt_minute > 0:
        send_msg(f'Memory_limit_exceeded._Restart_after_{cnt_minute_str}_minutes.')
        save_cnt = cnt + 1
        save_cnt = str(save_cnt)
        os.popen(f'echo {save_cnt} > {COUNT_FILE}')
    else:
        os.popen(f'echo 0 > {COUNT_FILE}')
        restart_service()
elif cnt > 0:
    send_msg('Dropped_below_memory_limit._But_it_may_happen_again_soon.')
    os.popen(f'echo 0 > {COUNT_FILE}')
elif used_memory > (MEMORY_IDLE * 1024 * 1024 * 1024):
    res = rcon_send('showplayers')

    players_cnt = -1
    for line in res.split('\n'):
        if ',' in line:
            players_cnt += 1

    if players_cnt == 0:
        send_msg('No_users._Restart_after_10_seconds.')
        time.sleep(10)
        restart_service()

 

반응형