#!/usr/bin/env bash set -euo pipefail ROOT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) LOG_DIR=${HM_LOG_DIR:-"$ROOT_DIR/hm_log"} GAMESERVER_IP=${HM_GAMESERVER_IP:-"127.0.0.1"} GAMESERVER_PORT=${HM_GAMESERVER_PORT:-"3724"} GAMESERVER_BIN="$ROOT_DIR/hm_gameserver/hm_gameserver" LOBBYSERVER_BIN="$ROOT_DIR/hm_lobbyserver/hm_lobbyserver" GAMESERVER_PID="$LOG_DIR/hm_gameserver.pid" LOBBYSERVER_PID="$LOG_DIR/hm_lobbyserver.pid" usage() { cat < Commands: build Build gameserver and lobbyserver start Start gameserver and lobbyserver stop Stop running servers status Show server status logs Tail server logs docker-build Build docker images docker-start Start dockerized stack docker-stop Stop dockerized stack docker-status Show docker stack status docker-logs Tail dockerized logs Environment: HM_LOG_DIR Log directory (default: ./hm_log) HM_GAMESERVER_IP Lobby points to this IP (default: 127.0.0.1) HM_GAMESERVER_PORT Lobby points to this port (default: 3724) HM_SKIP_COUCHBASE_CHECK=1 Skip Couchbase availability check EOF } docker_compose() { if command -v docker >/dev/null 2>&1 && docker compose version >/dev/null 2>&1; then docker compose "$@" return fi if command -v docker-compose >/dev/null 2>&1; then docker-compose "$@" return fi echo "docker compose not found" >&2 exit 1 } require_bin() { if ! command -v "$1" >/dev/null 2>&1; then echo "Missing required binary: $1" >&2 exit 1 fi } check_couchbase() { if [ "${HM_SKIP_COUCHBASE_CHECK:-}" = "1" ]; then return 0 fi if command -v curl >/dev/null 2>&1; then if ! curl -s --max-time 2 http://localhost:8091/pools >/dev/null; then echo "Couchbase not reachable on localhost:8091." >&2 echo "Start Couchbase and restore bucket 'hbs' or set HM_SKIP_COUCHBASE_CHECK=1." >&2 exit 1 fi else echo "curl not found; cannot verify Couchbase availability." >&2 echo "Install curl or set HM_SKIP_COUCHBASE_CHECK=1." >&2 exit 1 fi } build() { require_bin make make -C "$ROOT_DIR/hm_gameserver" make -C "$ROOT_DIR/hm_lobbyserver" } start() { check_couchbase mkdir -p "$LOG_DIR" if [ ! -x "$GAMESERVER_BIN" ] || [ ! -x "$LOBBYSERVER_BIN" ]; then echo "Binaries missing; run ./dev build first." >&2 exit 1 fi if [ -f "$GAMESERVER_PID" ] || [ -f "$LOBBYSERVER_PID" ]; then echo "PID files exist; run ./dev stop first." >&2 exit 1 fi nohup "$GAMESERVER_BIN" > "$LOG_DIR/hm_gameserver.out" 2>&1 & echo $! > "$GAMESERVER_PID" nohup "$LOBBYSERVER_BIN" \ --gameserver="$GAMESERVER_IP" \ --gameserver_port="$GAMESERVER_PORT" \ > "$LOG_DIR/hm_lobbyserver.out" 2>&1 & echo $! > "$LOBBYSERVER_PID" echo "Servers started. Logs in $LOG_DIR" } stop() { if [ -f "$GAMESERVER_PID" ]; then kill "$(cat "$GAMESERVER_PID")" 2>/dev/null || true rm -f "$GAMESERVER_PID" fi if [ -f "$LOBBYSERVER_PID" ]; then kill "$(cat "$LOBBYSERVER_PID")" 2>/dev/null || true rm -f "$LOBBYSERVER_PID" fi } status() { if [ -f "$GAMESERVER_PID" ] && kill -0 "$(cat "$GAMESERVER_PID")" 2>/dev/null; then echo "hm_gameserver running (pid $(cat "$GAMESERVER_PID"))" else echo "hm_gameserver not running" fi if [ -f "$LOBBYSERVER_PID" ] && kill -0 "$(cat "$LOBBYSERVER_PID")" 2>/dev/null; then echo "hm_lobbyserver running (pid $(cat "$LOBBYSERVER_PID"))" else echo "hm_lobbyserver not running" fi } logs() { tail -f "$LOG_DIR/hm_gameserver.out" "$LOG_DIR/hm_lobbyserver.out" } case "${1:-}" in build) build ;; start) start ;; stop) stop ;; status) status ;; logs) logs ;; docker-build) docker_compose build ;; docker-start) docker_compose up -d ;; docker-stop) docker_compose down ;; docker-status) docker_compose ps ;; docker-logs) docker_compose logs -f --tail=200 gameserver lobbyserver ;; *) usage exit 1 ;; esac