PalWorld Dedicated Server(Windows) 를 자동 시작 & 끄기 해주는 Python 스크립트
Posted 2024. 1. 28. 21:11, Filed under: 개발/PythonPalWorld-Dedicated-Server-Auto-Start-Stop
요즘 "팰월드"라는 이름의 포켓몬+아크 서바이벌+젤다 야생의 숨결+원신을 섞은 게임이 인기이다. 유행의 흐름을 따라 나도 플레이 하게 되었는데, 게임 불감증은 언제 있었는지 흔적도 없이 사라졌고 게임에 빠져 이번 주말 동안 한참을 플레이했다.
각설하고, 게임도 재밌고 다 좋은데 멀티를 위한 Dedicate Server 가 사람이 없을 때도 돌아가서 자원을 잡아먹는 것이 마음에 들지 않았다. 그래서 Python 을 이용해서 사람이 없으면 서버를 자동으로 끄고, 누군가 접속을 시도하면 서버를 자동으로 켜기 위한 간단한 스크립트를 작성했다. 이름은 PalWorld-Dedicated-Server-Auto-Start-Stop 이다.
이 스크립트는 다음과 같은 것을 해준다.
- PalWorld 서버가 구동 중이지 않을 때, 유저가 접속을 시도하면 자동으로 서버를 켬
- PalWorld 서버가 구동 중일 때, 온라인인 유저가 없으면 일정 시간 후 서버를 자동으로 끔
- Webserver 을 통해 서버를 On-Off 할 수 있는 Admin Page 를 제공
https://github.com/nomomo/PalWorld-Dedicated-Server-Auto-Start-Stop
https://github.com/nomomo/PalWorld-Dedicated-Server-Auto-Start-Stop/blob/main/README.ko.md (한국어 설명)
코드와 더욱 자세한 내용은 위 Github 링크에 올려두었으니 필요한 사람이 있으면 참고하길 바란다. 올려둔 스크립트를 그대로 사용할 수도 있지만 알 수 없는 문제가 많이 생길 수 있으니, 가능하다면 참고만 하고 자신만의 스크립트를 작성하는 것을 권장한다.
알려진 이슈
- 유저의 닉네임에 유니코드 문자가 포함되면 RCON Commands 에서 ShowPlayers 명령이 동작하지 않는 문제가 있다. 이 오류는 py-rcon 패키지의 _read 함수에서 수신된 읽어야 하는 문자 개수와 실제 수신된 문자의 개수가 달라 발생한다. ShowPlayers 명령을 보내면 몇 개의 문자를 읽어야 할지를 패킷의 가장 맨 앞에 보내오는데 이 값이 잘못되어있다. 대충 설명하자면 유니코드 문자 하나당 길이가 +2씩 되어있는데, 한글 네글자가 포함되어 있다면 실제 76이어야 하는 것이 84로 수신된다는 뜻이다. 여튼 무언가 미스매치가 되어있다.
- 해결 방법: 설치된 py-rcon 패키지와 함께 설치된 connection.py 파일을 열고 _read 함수의 내용을 다음과 같이 수정하여, 수신된 문자 길이와 읽어야 하는 문자 길이가 다르더라도 exception 이 발생하지 않도록 하면 일단 무식하고 간단하게 해결된다. 아마 여러 커맨드가 짧은 순간 연달아 실행되면 문제가 생길 것도 한데, 그런 상황을 만들지 않으면 된다.
def _read(self, length):
packet_data = self.sock.recv(length)
if len(packet_data) < length:
#raise Exception('Received few bytes!') # disable raise exception
return packet_data
return packet_data
동작 원리
서버 자동 시작
- PalWorld 서버가 구동 중이지 않으면 8211 포트를 열어 패킷을 수신.
- \x09\x08\x00
\x04\x40\x84\x92\x34\x01으로 시작하는 패킷을 대기. (버전마다 조금씩 바뀌는 것 같다.) - 패킷이 수신되면 8211 포트를 닫고, palworldExePath 경로에 위치한 파일을 실행하여 서버를 시작
서버 자동 정지
- RCON을 통해 현재 서버에 있는 플레이어 수를 체크 (ShowPlayers command)
- 플레이어 수가 0이면 RCON을 통해 Shutdown command 를 사용하여 서버를 정상 종료
동작 원리는 단순하다. 참고로 50% 이상의 코드를 ChatGPT 를 활용해서 작성했는데, 초기 컨셉 코드를 작성하는데 매우 유용했다.