mirror of
https://github.com/NATroutter/egg-hytale.git
synced 2026-03-01 11:21:13 +03:00
Split up the code to multiple files for easier readability and maintainability
This commit is contained in:
@@ -42,6 +42,10 @@ COPY --chmod=755 ./entrypoint.sh /entrypoint.sh
|
||||
# Strip Windows line endings (\r) just in case the file was edited on Windows
|
||||
RUN sed -i 's/\r$//' /entrypoint.sh
|
||||
|
||||
# Copy lib directory
|
||||
COPY --chmod=755 ./lib /lib
|
||||
RUN sed -i 's/\r$//' /lib/*.sh
|
||||
|
||||
# Create the container user
|
||||
RUN useradd -m -d /home/container -s /bin/bash container
|
||||
|
||||
|
||||
532
entrypoint.sh
532
entrypoint.sh
@@ -14,6 +14,12 @@
|
||||
# Pelican or Pterodactyl panel instead.
|
||||
################################################################################
|
||||
|
||||
source "$(dirname "$0")/lib/utilities.sh"
|
||||
source "$(dirname "$0")/lib/authentication.sh"
|
||||
source "$(dirname "$0")/lib/system.sh"
|
||||
source "$(dirname "$0")/lib/downloader.sh"
|
||||
source "$(dirname "$0")/lib/plugins.sh"
|
||||
|
||||
DOWNLOAD_URL="https://downloader.hytale.com/hytale-downloader.zip"
|
||||
DOWNLOAD_FILE="hytale-downloader.zip"
|
||||
DOWNLOAD_CRED_FILE=".hytale-downloader-credentials.json"
|
||||
@@ -21,397 +27,22 @@ AUTH_CACHE_FILE=".hytale-auth-tokens.json"
|
||||
VERSION_FILE="version.txt"
|
||||
MODS_FOLDER="mods"
|
||||
|
||||
# Detect architecture and set appropriate downloader binary
|
||||
ARCH=$(uname -m)
|
||||
logger info "Platform: $ARCH"
|
||||
|
||||
case "$ARCH" in
|
||||
x86_64)
|
||||
DOWNLOADER="./hytale-downloader-linux-amd64"
|
||||
;;
|
||||
aarch64|arm64)
|
||||
DOWNLOADER="./hytale-downloader-linux-arm64"
|
||||
;;
|
||||
*)
|
||||
logger error "Unsupported architecture: $ARCH"
|
||||
logger info "Supported architectures: x86_64 (amd64), aarch64/arm64"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# Get and export timezone
|
||||
TZ=${TZ:-UTC}
|
||||
export TZ
|
||||
|
||||
# Get and export the internal docker ip
|
||||
INTERNAL_IP=$(ip route get 1 | awk '{print $(NF-2);exit}')
|
||||
export INTERNAL_IP
|
||||
|
||||
# Goto working directory
|
||||
cd /home/container || exit 1
|
||||
# Initialize system
|
||||
detect_architecture
|
||||
setup_environment
|
||||
|
||||
#Print java version
|
||||
echo " "
|
||||
java -version
|
||||
echo " "
|
||||
|
||||
# Setup colors
|
||||
RED="" GREEN="" YELLOW="" BLUE="" MAGENTA="" CYAN="" RESET=""
|
||||
if [ -t 1 ] || { [ -n "$TERM" ] && [ "$TERM" != "dumb" ]; }; then
|
||||
# Helper to get color code (tput or ANSI fallback)
|
||||
if command -v tput >/dev/null 2>&1 && tput setaf 1 >/dev/null 2>&1; then
|
||||
_c() { tput setaf "$1"; }
|
||||
_r() { tput sgr0; }
|
||||
else
|
||||
_c() { printf '\033[0;3%dm' "$1"; }
|
||||
_r() { printf '\033[0m'; }
|
||||
fi
|
||||
|
||||
RED=$(_c 1) GREEN=$(_c 2) YELLOW=$(_c 3)
|
||||
BLUE=$(_c 4) MAGENTA=$(_c 5) CYAN=$(_c 6)
|
||||
RESET=$(_r)
|
||||
unset -f _c _r
|
||||
fi
|
||||
|
||||
#Function to print colored text
|
||||
printc() {
|
||||
local text="$1"
|
||||
|
||||
# Replace tags with color codes (or empty string if not supported)
|
||||
text="${text//\{RED\}/$RED}"
|
||||
text="${text//\{GREEN\}/$GREEN}"
|
||||
text="${text//\{YELLOW\}/$YELLOW}"
|
||||
text="${text//\{BLUE\}/$BLUE}"
|
||||
text="${text//\{MAGENTA\}/$MAGENTA}"
|
||||
text="${text//\{CYAN\}/$CYAN}"
|
||||
text="${text//\{RESET\}/$RESET}"
|
||||
printf "%b\n" "$text"
|
||||
}
|
||||
|
||||
# Logger function to print messages with different colors based on level
|
||||
logger() {
|
||||
local level="$1"
|
||||
local message="$2"
|
||||
|
||||
case "${level^^}" in
|
||||
"INFO") printc "{BLUE}ℹ $message{RESET}" ;;
|
||||
"WARN") printc "{YELLOW}⚠ $message{RESET}" ;;
|
||||
"ERROR") printc "{RED}⨯ $message{RESET}" ;;
|
||||
"SUCCESS") printc "{GREEN}✓ $message{RESET}" ;;
|
||||
*) printc "$message" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Function to extract downloaded server files
|
||||
extract_server_files() {
|
||||
logger info "Extracting server files..."
|
||||
SERVER_ZIP="server.zip"
|
||||
|
||||
if [ -f "$SERVER_ZIP" ]; then
|
||||
logger success "Found server archive: $SERVER_ZIP"
|
||||
|
||||
# Extract to current directory
|
||||
unzip -o "$SERVER_ZIP"
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
logger error "Failed to extract $SERVER_ZIP"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
logger success "Extraction completed successfully."
|
||||
|
||||
# Move contents from Server folder to current directory
|
||||
if [ -d "Server" ]; then
|
||||
logger info "Moving server files from Server directory..."
|
||||
cp -rf Server/* .
|
||||
rm -rf ./Server
|
||||
logger success "Server files moved to root directory."
|
||||
fi
|
||||
|
||||
# Clean up the zip file
|
||||
logger info "Cleaning up archive file..."
|
||||
rm "$SERVER_ZIP"
|
||||
logger success "Archive removed."
|
||||
else
|
||||
logger error "Server archive not found at $SERVER_ZIP"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to check if cached tokens exist
|
||||
check_cached_tokens() {
|
||||
if [ -f "$AUTH_CACHE_FILE" ]; then
|
||||
# Check if jq is available
|
||||
if ! command -v jq &> /dev/null; then
|
||||
logger warn "jq not found, cannot use cached tokens"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Validate JSON format
|
||||
if ! jq empty "$AUTH_CACHE_FILE" 2>/dev/null; then
|
||||
logger warn "Invalid cached token file, removing..."
|
||||
rm "$AUTH_CACHE_FILE"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Check if required keys exist
|
||||
REFRESH_TOKEN_EXISTS=$(jq -r 'has("refresh_token")' "$AUTH_CACHE_FILE")
|
||||
PROFILE_UUID_EXISTS=$(jq -r 'has("profile_uuid")' "$AUTH_CACHE_FILE")
|
||||
|
||||
if [ "$REFRESH_TOKEN_EXISTS" != "true" ] || [ "$PROFILE_UUID_EXISTS" != "true" ]; then
|
||||
logger warn "Cached token file missing required keys, removing..."
|
||||
rm "$AUTH_CACHE_FILE"
|
||||
return 1
|
||||
fi
|
||||
|
||||
logger success "Found cached authentication tokens"
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
# Function to load cached tokens (refresh_token + profile_uuid only)
|
||||
load_cached_tokens() {
|
||||
REFRESH_TOKEN=$(jq -r '.refresh_token' "$AUTH_CACHE_FILE")
|
||||
PROFILE_UUID=$(jq -r '.profile_uuid' "$AUTH_CACHE_FILE")
|
||||
|
||||
# Validate required tokens are present
|
||||
if [ -z "$REFRESH_TOKEN" ] || [ "$REFRESH_TOKEN" = "null" ] || \
|
||||
[ -z "$PROFILE_UUID" ] || [ "$PROFILE_UUID" = "null" ]; then
|
||||
logger error "Incomplete cached tokens, re-authenticating..."
|
||||
rm "$AUTH_CACHE_FILE"
|
||||
return 1
|
||||
fi
|
||||
|
||||
logger success "Loaded cached refresh token + profile UUID"
|
||||
return 0
|
||||
}
|
||||
|
||||
# Function to refresh access token using cached refresh token
|
||||
refresh_access_token() {
|
||||
logger info "Refreshing access token..."
|
||||
|
||||
TOKEN_RESPONSE=$(curl -s -X POST "https://oauth.accounts.hytale.com/oauth2/token" \
|
||||
-H "Content-Type: application/x-www-form-urlencoded" \
|
||||
-d "client_id=hytale-server" \
|
||||
-d "grant_type=refresh_token" \
|
||||
-d "refresh_token=$REFRESH_TOKEN")
|
||||
|
||||
ERROR=$(echo "$TOKEN_RESPONSE" | jq -r '.error // empty')
|
||||
if [ -n "$ERROR" ]; then
|
||||
logger error "Failed to refresh access token: $ERROR"
|
||||
return 1
|
||||
fi
|
||||
|
||||
ACCESS_TOKEN=$(echo "$TOKEN_RESPONSE" | jq -r '.access_token')
|
||||
NEW_REFRESH_TOKEN=$(echo "$TOKEN_RESPONSE" | jq -r '.refresh_token // empty')
|
||||
|
||||
if [ -z "$ACCESS_TOKEN" ] || [ "$ACCESS_TOKEN" = "null" ]; then
|
||||
logger error "No access token in refresh response"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Update refresh token if a new one was provided
|
||||
if [ -n "$NEW_REFRESH_TOKEN" ] && [ "$NEW_REFRESH_TOKEN" != "null" ]; then
|
||||
REFRESH_TOKEN="$NEW_REFRESH_TOKEN"
|
||||
fi
|
||||
|
||||
logger success "Access token refreshed"
|
||||
return 0
|
||||
}
|
||||
|
||||
# Function to create a new game session
|
||||
create_game_session() {
|
||||
logger info "Creating game server session..."
|
||||
|
||||
SESSION_RESPONSE=$(curl -s -X POST "https://sessions.hytale.com/game-session/new" \
|
||||
-H "Authorization: Bearer $ACCESS_TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{\"uuid\": \"$PROFILE_UUID\"}")
|
||||
|
||||
# Validate JSON response
|
||||
if ! echo "$SESSION_RESPONSE" | jq empty 2>/dev/null; then
|
||||
logger error "Invalid JSON response from game session creation"
|
||||
logger info "Response: $SESSION_RESPONSE"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Extract session and identity tokens
|
||||
SESSION_TOKEN=$(echo "$SESSION_RESPONSE" | jq -r '.sessionToken')
|
||||
IDENTITY_TOKEN=$(echo "$SESSION_RESPONSE" | jq -r '.identityToken')
|
||||
|
||||
if [ -z "$SESSION_TOKEN" ] || [ "$SESSION_TOKEN" = "null" ]; then
|
||||
logger error "Failed to create game server session"
|
||||
logger info "Response: $SESSION_RESPONSE"
|
||||
return 1
|
||||
fi
|
||||
|
||||
logger success "Game server session created successfully!"
|
||||
return 0
|
||||
}
|
||||
|
||||
# Function to save authentication tokens (refresh_token + profile_uuid only)
|
||||
save_auth_tokens() {
|
||||
|
||||
# Create auth cache file (only in standard mode, not GSP mode)
|
||||
if [ ! -f "$AUTH_CACHE_FILE" ]; then
|
||||
logger info "Creating auth cache file..."
|
||||
touch $AUTH_CACHE_FILE
|
||||
fi
|
||||
|
||||
cat > "$AUTH_CACHE_FILE" << EOF
|
||||
{
|
||||
"refresh_token": "$REFRESH_TOKEN",
|
||||
"profile_uuid": "$PROFILE_UUID",
|
||||
"timestamp": $(date +%s)
|
||||
}
|
||||
EOF
|
||||
logger info "Refresh token cached for future use"
|
||||
}
|
||||
|
||||
# Function to perform full authentication
|
||||
perform_authentication() {
|
||||
logger info "Obtaining authentication tokens..."
|
||||
|
||||
# Step 1: Request device code
|
||||
AUTH_RESPONSE=$(curl -s -X POST "https://oauth.accounts.hytale.com/oauth2/device/auth" \
|
||||
-H "Content-Type: application/x-www-form-urlencoded" \
|
||||
-d "client_id=hytale-server" \
|
||||
-d "scope=openid offline auth:server")
|
||||
|
||||
# Extract device_code and verification_uri_complete using jq
|
||||
DEVICE_CODE=$(echo "$AUTH_RESPONSE" | jq -r '.device_code')
|
||||
VERIFICATION_URI=$(echo "$AUTH_RESPONSE" | jq -r '.verification_uri_complete')
|
||||
POLL_INTERVAL=$(echo "$AUTH_RESPONSE" | jq -r '.interval')
|
||||
|
||||
# Display authentication banner
|
||||
echo " "
|
||||
printc "{MAGENTA}╔═════════════════════════════════════════════════════════════════════════════╗"
|
||||
printc "{MAGENTA}║ {BLUE}HYTALE SERVER AUTHENTICATION REQUIRED {MAGENTA}║"
|
||||
printc "{MAGENTA}╠═════════════════════════════════════════════════════════════════════════════╣"
|
||||
printc "{MAGENTA}║ ║"
|
||||
printc "{MAGENTA}║ {CYAN}Please authenticate the server by visiting the following URL: {MAGENTA}║"
|
||||
printc "{MAGENTA}║ ║"
|
||||
printc "{MAGENTA}║ {YELLOW}$VERIFICATION_URI {MAGENTA}║"
|
||||
printc "{MAGENTA}║ ║"
|
||||
printc "{MAGENTA}║ {CYAN}1. Click the link above or copy it to your browser {MAGENTA}║"
|
||||
printc "{MAGENTA}║ {CYAN}2. Sign in with your Hytale account {MAGENTA}║"
|
||||
printc "{MAGENTA}║ {CYAN}3. Authorize the server {MAGENTA}║"
|
||||
printc "{MAGENTA}║ ║"
|
||||
printc "{MAGENTA}║ {CYAN}Waiting for authentication... {MAGENTA}║"
|
||||
printc "{MAGENTA}║ ║"
|
||||
printc "{MAGENTA}╚═════════════════════════════════════════════════════════════════════════════╝"
|
||||
printc " "
|
||||
|
||||
# Step 2: Poll for access token
|
||||
ACCESS_TOKEN=""
|
||||
while [ -z "$ACCESS_TOKEN" ]; do
|
||||
sleep $POLL_INTERVAL
|
||||
|
||||
TOKEN_RESPONSE=$(curl -s -X POST "https://oauth.accounts.hytale.com/oauth2/token" \
|
||||
-H "Content-Type: application/x-www-form-urlencoded" \
|
||||
-d "client_id=hytale-server" \
|
||||
-d "grant_type=urn:ietf:params:oauth:grant-type:device_code" \
|
||||
-d "device_code=$DEVICE_CODE")
|
||||
|
||||
# Check if we got an error
|
||||
ERROR=$(echo "$TOKEN_RESPONSE" | jq -r '.error // empty')
|
||||
|
||||
if [ "$ERROR" = "authorization_pending" ]; then
|
||||
logger info "Still waiting for authentication..."
|
||||
continue
|
||||
elif [ -n "$ERROR" ]; then
|
||||
logger error "Authentication error: $ERROR"
|
||||
exit 1
|
||||
else
|
||||
# Successfully authenticated
|
||||
ACCESS_TOKEN=$(echo "$TOKEN_RESPONSE" | jq -r '.access_token')
|
||||
REFRESH_TOKEN=$(echo "$TOKEN_RESPONSE" | jq -r '.refresh_token')
|
||||
echo ""
|
||||
logger success "Authentication successful!"
|
||||
echo ""
|
||||
fi
|
||||
done
|
||||
|
||||
# Fetch available game profiles
|
||||
logger info "Fetching game profiles..."
|
||||
|
||||
PROFILES_RESPONSE=$(curl -s -X GET "https://account-data.hytale.com/my-account/get-profiles" \
|
||||
-H "Authorization: Bearer $ACCESS_TOKEN")
|
||||
|
||||
# Check if profiles list is empty
|
||||
PROFILES_COUNT=$(echo "$PROFILES_RESPONSE" | jq '.profiles | length')
|
||||
|
||||
if [ "$PROFILES_COUNT" -eq 0 ]; then
|
||||
logger error "No game profiles found. You need to purchase Hytale to run a server."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Select profile based on GAME_PROFILE variable
|
||||
if [ -n "$GAME_PROFILE" ]; then
|
||||
# User specified a profile username, find matching UUID
|
||||
logger info "Looking for profile: $GAME_PROFILE"
|
||||
PROFILE_UUID=$(echo "$PROFILES_RESPONSE" | jq -r ".profiles[] | select(.username == \"$GAME_PROFILE\") | .uuid")
|
||||
|
||||
if [ -z "$PROFILE_UUID" ] || [ "$PROFILE_UUID" = "null" ]; then
|
||||
logger error "Profile '$GAME_PROFILE' not found."
|
||||
logger info "Available profiles:"
|
||||
logger success "$PROFILES_RESPONSE" | jq -r '.profiles[] | " - \(.username)"'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
logger success "Using profile: $GAME_PROFILE (UUID: $PROFILE_UUID)"
|
||||
else
|
||||
# Use first profile from the list
|
||||
PROFILE_UUID=$(echo "$PROFILES_RESPONSE" | jq -r '.profiles[0].uuid')
|
||||
PROFILE_USERNAME=$(echo "$PROFILES_RESPONSE" | jq -r '.profiles[0].username')
|
||||
|
||||
logger success "Using default profile: $PROFILE_USERNAME (UUID: $PROFILE_UUID)"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# Save refresh token + profile for future use
|
||||
save_auth_tokens
|
||||
|
||||
# Create game server session
|
||||
if ! create_game_session; then
|
||||
exit 1
|
||||
fi
|
||||
echo ""
|
||||
}
|
||||
|
||||
# Copy start.sh template to /home/container
|
||||
logger info "Copying start.sh template to /home/container..."
|
||||
cp -f /usr/local/bin/start.sh start.sh
|
||||
chmod 755 start.sh
|
||||
|
||||
# Check if the backup directory exists
|
||||
if [ ! -d "backup" ]; then
|
||||
logger info "Backup directory does not exist. Creating it..."
|
||||
mkdir -p backup
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
logger error "Failed to create backup directory: /backup"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
logger info "Backup directory already exists."
|
||||
fi
|
||||
chmod -R 755 backup
|
||||
|
||||
# Check if the downloader exists
|
||||
if [ ! -f "$DOWNLOADER" ]; then
|
||||
logger error "Hytale downloader not found!"
|
||||
logger error "Please run the installation script first."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if the downloader is executable
|
||||
if [ ! -x "$DOWNLOADER" ]; then
|
||||
logger info "Setting executable permissions..."
|
||||
chmod +x "$DOWNLOADER"
|
||||
fi
|
||||
setup_backup_directory
|
||||
ensure_downloader
|
||||
|
||||
# Create version file
|
||||
if [ ! -f "$VERSION_FILE" ]; then
|
||||
@@ -433,128 +64,9 @@ if [ -f "$AUTH_CACHE_FILE" ] && { [ ! -r "$AUTH_CACHE_FILE" ] || [ ! -w "$AUTH_C
|
||||
chmod 644 "$AUTH_CACHE_FILE"
|
||||
fi
|
||||
|
||||
INITIAL_SETUP=0
|
||||
|
||||
# Check if credentials file exists, if not run the updater
|
||||
if [ ! -f "$DOWNLOAD_CRED_FILE" ]; then
|
||||
INITIAL_SETUP=1
|
||||
logger warn "Credentials file not found, running initial setup..."
|
||||
logger info "Downloading server files..."
|
||||
|
||||
$DOWNLOADER -check-update
|
||||
|
||||
echo " "
|
||||
printc "{MAGENTA}╔══════════════════════════════════════════════════════════════════════════════════════╗"
|
||||
printc "{MAGENTA}║ {BLUE}NOTE: You must have purchased Hytale on the account you are using to authenticate. {MAGENTA}║"
|
||||
printc "{MAGENTA}╚══════════════════════════════════════════════════════════════════════════════════════╝"
|
||||
echo " "
|
||||
|
||||
if ! $DOWNLOADER -patchline $PATCHLINE -download-path server.zip; then
|
||||
|
||||
echo ""
|
||||
logger error "Failed to download Hytale server files."
|
||||
logger error "This may indicate:"
|
||||
logger error " - You haven't purchased Hytale"
|
||||
logger error " - Authentication credentials are invalid or expired"
|
||||
echo ""
|
||||
|
||||
logger warn "Removing invalid credential file..."
|
||||
rm -f $DOWNLOAD_CRED_FILE
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Save version info after initial setup
|
||||
DOWNLOADER_VERSION=$($DOWNLOADER -print-version 2>&1)
|
||||
|
||||
if [ $? -eq 0 ] && [ -n "$DOWNLOADER_VERSION" ]; then
|
||||
echo "$DOWNLOADER_VERSION" > $VERSION_FILE
|
||||
logger success "Saved version info!"
|
||||
fi
|
||||
|
||||
extract_server_files
|
||||
fi
|
||||
|
||||
# Run automatic update if enabled
|
||||
if [ "$AUTOMATIC_UPDATE" = "1" ] && [ "$INITIAL_SETUP" = "0" ]; then
|
||||
logger info "Checking for updates..."
|
||||
|
||||
# Read local version from file
|
||||
if [ -f "$VERSION_FILE" ]; then
|
||||
LOCAL_VERSION=$(cat $VERSION_FILE)
|
||||
else
|
||||
logger warn "version file not found, forcing update"
|
||||
LOCAL_VERSION=""
|
||||
fi
|
||||
|
||||
# Get remote/downloader version
|
||||
DOWNLOADER_VERSION=$($DOWNLOADER -print-version 2>&1)
|
||||
|
||||
# Check if version command failed
|
||||
if [ $? -ne 0 ] || [ -z "$DOWNLOADER_VERSION" ]; then
|
||||
logger error "Failed to get downloader version. This may indicate authentication issues."
|
||||
logger error "Output: $DOWNLOADER_VERSION"
|
||||
exit 1
|
||||
else
|
||||
if [ -n "$LOCAL_VERSION" ]; then
|
||||
logger info "Local version: $LOCAL_VERSION"
|
||||
fi
|
||||
logger info "Downloader version: $DOWNLOADER_VERSION"
|
||||
|
||||
# Compare versions
|
||||
if [ "$LOCAL_VERSION" != "$DOWNLOADER_VERSION" ]; then
|
||||
logger warn "Version mismatch, running update..."
|
||||
|
||||
$DOWNLOADER -check-update
|
||||
$DOWNLOADER -patchline $PATCHLINE -download-path server.zip
|
||||
|
||||
# Update version file after successful update
|
||||
echo "$DOWNLOADER_VERSION" > $VERSION_FILE
|
||||
logger success "Saved version info!"
|
||||
|
||||
extract_server_files
|
||||
else
|
||||
logger info "Versions match, skipping update"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check if server files were downloaded correctly
|
||||
if [ ! -f "HytaleServer.jar" ]; then
|
||||
logger error "HytaleServer.jar not found!"
|
||||
logger error "Server files were not downloaded correctly."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Download the latest hytale-sourcequery plugin if enabled
|
||||
if [ "$ENABLE_SOURCE_QUERY_SUPPORT" = "1" ]; then
|
||||
logger info "Source Query support enabled, checking for plugin..."
|
||||
|
||||
# Create mods directory if it doesn't exist
|
||||
if [ ! -d "$MODS_FOLDER" ]; then
|
||||
logger warn "Creating mods directory..."
|
||||
mkdir -p $MODS_FOLDER
|
||||
fi
|
||||
|
||||
if [ -d "$MODS_FOLDER" ] && { [ ! -r "$MODS_FOLDER" ] || [ ! -w "$MODS_FOLDER" ] || [ ! -x "$MODS_FOLDER" ]; }; then
|
||||
logger warn "Fixing permissions on directory $MODS_FOLDER..."
|
||||
chmod 755 "$MODS_FOLDER"
|
||||
fi
|
||||
|
||||
logger info "Downloading latest hytale-sourcequery plugin..."
|
||||
LATEST_URL=$(curl -sSL https://api.github.com/repos/physgun-com/hytale-sourcequery/releases/latest | jq -r '.assets[0].browser_download_url // empty')
|
||||
|
||||
if [ -n "$LATEST_URL" ]; then
|
||||
curl -sSL -o mods/hytale-sourcequery.jar "$LATEST_URL"
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
logger success "Successfully downloaded hytale-sourcequery plugin to mods folder"
|
||||
else
|
||||
logger error "Failed to download hytale-sourcequery plugin"
|
||||
fi
|
||||
else
|
||||
logger error "Could not find hytale-sourcequery plugin download URL"
|
||||
fi
|
||||
fi
|
||||
run_update_process
|
||||
validate_server_files
|
||||
install_sourcequery
|
||||
|
||||
# Check if GSP mode (tokens provided externally)
|
||||
if [ -n "$OVERRIDE_SESSION_TOKEN" ] && [ -n "$OVERRIDE_IDENTITY_TOKEN" ]; then
|
||||
@@ -589,19 +101,9 @@ export SESSION_TOKEN
|
||||
export IDENTITY_TOKEN
|
||||
|
||||
# Enforce file and folder permissions if enabled
|
||||
if [ "$ENFORCE_PERMISSIONS" = "1" ]; then
|
||||
logger warn "Enforcing permissions... This might take a while. Please be patient."
|
||||
# Set all directories to 755
|
||||
find . -type d -exec chmod 755 {} \;
|
||||
# Set all files to 644, excluding executables that need to remain executable
|
||||
find . -type f \
|
||||
! -name "hytale-downloader-linux-amd64" \
|
||||
! -name "hytale-downloader-linux-arm64" \
|
||||
! -name "qemu-x86_64-static" \
|
||||
! -name "start.sh" \
|
||||
-exec chmod 644 {} \;
|
||||
logger success "Permissions enforced (files: 644, folders: 755)"
|
||||
fi
|
||||
enforce_permissions
|
||||
|
||||
logger info "Starting Hytale server..."
|
||||
|
||||
# Convert startup variables to from {{VARIABLE}} to ${VARIABLE} for the evaluating
|
||||
PARSED=$(echo "$STARTUP" | sed -e 's/{{/${/g' -e 's/}}/}/g')
|
||||
|
||||
250
lib/authentication.sh
Normal file
250
lib/authentication.sh
Normal file
@@ -0,0 +1,250 @@
|
||||
# Function to check if cached tokens exist
|
||||
check_cached_tokens() {
|
||||
if [ -f "$AUTH_CACHE_FILE" ]; then
|
||||
# Check if jq is available
|
||||
if ! command -v jq &> /dev/null; then
|
||||
logger warn "jq not found, cannot use cached tokens"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Validate JSON format
|
||||
if ! jq empty "$AUTH_CACHE_FILE" 2>/dev/null; then
|
||||
logger warn "Invalid cached token file, removing..."
|
||||
rm "$AUTH_CACHE_FILE"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Check if required keys exist
|
||||
REFRESH_TOKEN_EXISTS=$(jq -r 'has("refresh_token")' "$AUTH_CACHE_FILE")
|
||||
PROFILE_UUID_EXISTS=$(jq -r 'has("profile_uuid")' "$AUTH_CACHE_FILE")
|
||||
|
||||
if [ "$REFRESH_TOKEN_EXISTS" != "true" ] || [ "$PROFILE_UUID_EXISTS" != "true" ]; then
|
||||
logger warn "Cached token file missing required keys, removing..."
|
||||
rm "$AUTH_CACHE_FILE"
|
||||
return 1
|
||||
fi
|
||||
|
||||
logger success "Found cached authentication tokens"
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
|
||||
|
||||
# Function to load cached tokens (refresh_token + profile_uuid only)
|
||||
load_cached_tokens() {
|
||||
REFRESH_TOKEN=$(jq -r '.refresh_token' "$AUTH_CACHE_FILE")
|
||||
PROFILE_UUID=$(jq -r '.profile_uuid' "$AUTH_CACHE_FILE")
|
||||
|
||||
# Validate required tokens are present
|
||||
if [ -z "$REFRESH_TOKEN" ] || [ "$REFRESH_TOKEN" = "null" ] || \
|
||||
[ -z "$PROFILE_UUID" ] || [ "$PROFILE_UUID" = "null" ]; then
|
||||
logger error "Incomplete cached tokens, re-authenticating..."
|
||||
rm "$AUTH_CACHE_FILE"
|
||||
return 1
|
||||
fi
|
||||
|
||||
logger success "Loaded cached refresh token + profile UUID"
|
||||
return 0
|
||||
}
|
||||
|
||||
|
||||
|
||||
# Function to refresh access token using cached refresh token
|
||||
refresh_access_token() {
|
||||
logger info "Refreshing access token..."
|
||||
|
||||
TOKEN_RESPONSE=$(curl -s -X POST "https://oauth.accounts.hytale.com/oauth2/token" \
|
||||
-H "Content-Type: application/x-www-form-urlencoded" \
|
||||
-d "client_id=hytale-server" \
|
||||
-d "grant_type=refresh_token" \
|
||||
-d "refresh_token=$REFRESH_TOKEN")
|
||||
|
||||
ERROR=$(echo "$TOKEN_RESPONSE" | jq -r '.error // empty')
|
||||
if [ -n "$ERROR" ]; then
|
||||
logger error "Failed to refresh access token: $ERROR"
|
||||
return 1
|
||||
fi
|
||||
|
||||
ACCESS_TOKEN=$(echo "$TOKEN_RESPONSE" | jq -r '.access_token')
|
||||
NEW_REFRESH_TOKEN=$(echo "$TOKEN_RESPONSE" | jq -r '.refresh_token // empty')
|
||||
|
||||
if [ -z "$ACCESS_TOKEN" ] || [ "$ACCESS_TOKEN" = "null" ]; then
|
||||
logger error "No access token in refresh response"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Update refresh token if a new one was provided
|
||||
if [ -n "$NEW_REFRESH_TOKEN" ] && [ "$NEW_REFRESH_TOKEN" != "null" ]; then
|
||||
REFRESH_TOKEN="$NEW_REFRESH_TOKEN"
|
||||
fi
|
||||
|
||||
logger success "Access token refreshed"
|
||||
return 0
|
||||
}
|
||||
|
||||
|
||||
|
||||
# Function to create a new game session
|
||||
create_game_session() {
|
||||
logger info "Creating game server session..."
|
||||
|
||||
SESSION_RESPONSE=$(curl -s -X POST "https://sessions.hytale.com/game-session/new" \
|
||||
-H "Authorization: Bearer $ACCESS_TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{\"uuid\": \"$PROFILE_UUID\"}")
|
||||
|
||||
# Validate JSON response
|
||||
if ! echo "$SESSION_RESPONSE" | jq empty 2>/dev/null; then
|
||||
logger error "Invalid JSON response from game session creation"
|
||||
logger info "Response: $SESSION_RESPONSE"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Extract session and identity tokens
|
||||
SESSION_TOKEN=$(echo "$SESSION_RESPONSE" | jq -r '.sessionToken')
|
||||
IDENTITY_TOKEN=$(echo "$SESSION_RESPONSE" | jq -r '.identityToken')
|
||||
|
||||
if [ -z "$SESSION_TOKEN" ] || [ "$SESSION_TOKEN" = "null" ]; then
|
||||
logger error "Failed to create game server session"
|
||||
logger info "Response: $SESSION_RESPONSE"
|
||||
return 1
|
||||
fi
|
||||
|
||||
logger success "Game server session created successfully!"
|
||||
return 0
|
||||
}
|
||||
|
||||
# Function to save authentication tokens (refresh_token + profile_uuid only)
|
||||
save_auth_tokens() {
|
||||
|
||||
# Create auth cache file (only in standard mode, not GSP mode)
|
||||
if [ ! -f "$AUTH_CACHE_FILE" ]; then
|
||||
logger info "Creating auth cache file..."
|
||||
touch $AUTH_CACHE_FILE
|
||||
fi
|
||||
|
||||
cat > "$AUTH_CACHE_FILE" << EOF
|
||||
{
|
||||
"refresh_token": "$REFRESH_TOKEN",
|
||||
"profile_uuid": "$PROFILE_UUID",
|
||||
"timestamp": $(date +%s)
|
||||
}
|
||||
EOF
|
||||
logger info "Refresh token cached for future use"
|
||||
}
|
||||
|
||||
|
||||
|
||||
# Function to perform full authentication
|
||||
perform_authentication() {
|
||||
logger info "Obtaining authentication tokens..."
|
||||
|
||||
# Step 1: Request device code
|
||||
AUTH_RESPONSE=$(curl -s -X POST "https://oauth.accounts.hytale.com/oauth2/device/auth" \
|
||||
-H "Content-Type: application/x-www-form-urlencoded" \
|
||||
-d "client_id=hytale-server" \
|
||||
-d "scope=openid offline auth:server")
|
||||
|
||||
# Extract device_code and verification_uri_complete using jq
|
||||
DEVICE_CODE=$(echo "$AUTH_RESPONSE" | jq -r '.device_code')
|
||||
VERIFICATION_URI=$(echo "$AUTH_RESPONSE" | jq -r '.verification_uri_complete')
|
||||
POLL_INTERVAL=$(echo "$AUTH_RESPONSE" | jq -r '.interval')
|
||||
|
||||
# Display authentication banner
|
||||
echo " "
|
||||
printc "{MAGENTA}╔═════════════════════════════════════════════════════════════════════════════╗"
|
||||
printc "{MAGENTA}║ {BLUE}HYTALE SERVER AUTHENTICATION REQUIRED {MAGENTA}║"
|
||||
printc "{MAGENTA}╠═════════════════════════════════════════════════════════════════════════════╣"
|
||||
printc "{MAGENTA}║ ║"
|
||||
printc "{MAGENTA}║ {CYAN}Please authenticate the server by visiting the following URL: {MAGENTA}║"
|
||||
printc "{MAGENTA}║ ║"
|
||||
printc "{MAGENTA}║ {YELLOW}$VERIFICATION_URI {MAGENTA}║"
|
||||
printc "{MAGENTA}║ ║"
|
||||
printc "{MAGENTA}║ {CYAN}1. Click the link above or copy it to your browser {MAGENTA}║"
|
||||
printc "{MAGENTA}║ {CYAN}2. Sign in with your Hytale account {MAGENTA}║"
|
||||
printc "{MAGENTA}║ {CYAN}3. Authorize the server {MAGENTA}║"
|
||||
printc "{MAGENTA}║ ║"
|
||||
printc "{MAGENTA}║ {CYAN}Waiting for authentication... {MAGENTA}║"
|
||||
printc "{MAGENTA}║ ║"
|
||||
printc "{MAGENTA}╚═════════════════════════════════════════════════════════════════════════════╝"
|
||||
printc " "
|
||||
|
||||
# Step 2: Poll for access token
|
||||
ACCESS_TOKEN=""
|
||||
while [ -z "$ACCESS_TOKEN" ]; do
|
||||
sleep $POLL_INTERVAL
|
||||
|
||||
TOKEN_RESPONSE=$(curl -s -X POST "https://oauth.accounts.hytale.com/oauth2/token" \
|
||||
-H "Content-Type: application/x-www-form-urlencoded" \
|
||||
-d "client_id=hytale-server" \
|
||||
-d "grant_type=urn:ietf:params:oauth:grant-type:device_code" \
|
||||
-d "device_code=$DEVICE_CODE")
|
||||
|
||||
# Check if we got an error
|
||||
ERROR=$(echo "$TOKEN_RESPONSE" | jq -r '.error // empty')
|
||||
|
||||
if [ "$ERROR" = "authorization_pending" ]; then
|
||||
logger info "Still waiting for authentication..."
|
||||
continue
|
||||
elif [ -n "$ERROR" ]; then
|
||||
logger error "Authentication error: $ERROR"
|
||||
exit 1
|
||||
else
|
||||
# Successfully authenticated
|
||||
ACCESS_TOKEN=$(echo "$TOKEN_RESPONSE" | jq -r '.access_token')
|
||||
REFRESH_TOKEN=$(echo "$TOKEN_RESPONSE" | jq -r '.refresh_token')
|
||||
echo ""
|
||||
logger success "Authentication successful!"
|
||||
echo ""
|
||||
fi
|
||||
done
|
||||
|
||||
# Fetch available game profiles
|
||||
logger info "Fetching game profiles..."
|
||||
|
||||
PROFILES_RESPONSE=$(curl -s -X GET "https://account-data.hytale.com/my-account/get-profiles" \
|
||||
-H "Authorization: Bearer $ACCESS_TOKEN")
|
||||
|
||||
# Check if profiles list is empty
|
||||
PROFILES_COUNT=$(echo "$PROFILES_RESPONSE" | jq '.profiles | length')
|
||||
|
||||
if [ "$PROFILES_COUNT" -eq 0 ]; then
|
||||
logger error "No game profiles found. You need to purchase Hytale to run a server."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Select profile based on GAME_PROFILE variable
|
||||
if [ -n "$GAME_PROFILE" ]; then
|
||||
# User specified a profile username, find matching UUID
|
||||
logger info "Looking for profile: $GAME_PROFILE"
|
||||
PROFILE_UUID=$(echo "$PROFILES_RESPONSE" | jq -r ".profiles[] | select(.username == \"$GAME_PROFILE\") | .uuid")
|
||||
|
||||
if [ -z "$PROFILE_UUID" ] || [ "$PROFILE_UUID" = "null" ]; then
|
||||
logger error "Profile '$GAME_PROFILE' not found."
|
||||
logger info "Available profiles:"
|
||||
logger success "$PROFILES_RESPONSE" | jq -r '.profiles[] | " - \(.username)"'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
logger success "Using profile: $GAME_PROFILE (UUID: $PROFILE_UUID)"
|
||||
else
|
||||
# Use first profile from the list
|
||||
PROFILE_UUID=$(echo "$PROFILES_RESPONSE" | jq -r '.profiles[0].uuid')
|
||||
PROFILE_USERNAME=$(echo "$PROFILES_RESPONSE" | jq -r '.profiles[0].username')
|
||||
|
||||
logger success "Using default profile: $PROFILE_USERNAME (UUID: $PROFILE_UUID)"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# Save refresh token + profile for future use
|
||||
save_auth_tokens
|
||||
|
||||
# Create game server session
|
||||
if ! create_game_session; then
|
||||
exit 1
|
||||
fi
|
||||
echo ""
|
||||
}
|
||||
93
lib/downloader.sh
Normal file
93
lib/downloader.sh
Normal file
@@ -0,0 +1,93 @@
|
||||
#!/bin/bash
|
||||
|
||||
ensure_downloader() {
|
||||
if [ ! -f "$DOWNLOADER" ]; then
|
||||
logger error "Hytale downloader not found!"
|
||||
logger error "Please run the installation script first."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -x "$DOWNLOADER" ]; then
|
||||
logger info "Setting executable permissions for downloader..."
|
||||
chmod +x "$DOWNLOADER"
|
||||
fi
|
||||
}
|
||||
|
||||
run_update_process() {
|
||||
local INITIAL_SETUP=0
|
||||
|
||||
# Check if credentials file exists, if not run the updater
|
||||
if [ ! -f "$DOWNLOAD_CRED_FILE" ]; then
|
||||
INITIAL_SETUP=1
|
||||
logger warn "Credentials file not found, running initial setup..."
|
||||
logger info "Downloading server files..."
|
||||
|
||||
$DOWNLOADER -check-update
|
||||
|
||||
echo " "
|
||||
printc "{MAGENTA}╔══════════════════════════════════════════════════════════════════════════════════════╗"
|
||||
printc "{MAGENTA}║ {BLUE}NOTE: You must have purchased Hytale on the account you are using to authenticate. {MAGENTA}║"
|
||||
printc "{MAGENTA}╚══════════════════════════════════════════════════════════════════════════════════════╝"
|
||||
echo " "
|
||||
|
||||
if ! $DOWNLOADER -patchline $PATCHLINE -download-path server.zip; then
|
||||
echo ""
|
||||
logger error "Failed to download Hytale server files."
|
||||
logger warn "Removing invalid credential file..."
|
||||
rm -f $DOWNLOAD_CRED_FILE
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Save version info after initial setup
|
||||
local DOWNLOADER_VERSION=$($DOWNLOADER -print-version 2>&1)
|
||||
if [ $? -eq 0 ] && [ -n "$DOWNLOADER_VERSION" ]; then
|
||||
echo "$DOWNLOADER_VERSION" > $VERSION_FILE
|
||||
logger success "Saved version info!"
|
||||
fi
|
||||
|
||||
extract_server_files
|
||||
fi
|
||||
|
||||
# Run automatic update if enabled
|
||||
if [ "$AUTOMATIC_UPDATE" = "1" ] && [ "$INITIAL_SETUP" = "0" ]; then
|
||||
logger info "Checking for updates..."
|
||||
|
||||
local LOCAL_VERSION=""
|
||||
if [ -f "$VERSION_FILE" ]; then
|
||||
LOCAL_VERSION=$(cat $VERSION_FILE)
|
||||
else
|
||||
logger warn "Version file not found, forcing update"
|
||||
fi
|
||||
|
||||
local DOWNLOADER_VERSION=$($DOWNLOADER -print-version 2>&1)
|
||||
|
||||
if [ $? -ne 0 ] || [ -z "$DOWNLOADER_VERSION" ]; then
|
||||
logger error "Failed to get downloader version."
|
||||
exit 1
|
||||
else
|
||||
if [ -n "$LOCAL_VERSION" ]; then
|
||||
logger info "Local version: $LOCAL_VERSION"
|
||||
fi
|
||||
logger info "Downloader version: $DOWNLOADER_VERSION"
|
||||
|
||||
if [ "$LOCAL_VERSION" != "$DOWNLOADER_VERSION" ]; then
|
||||
logger warn "Version mismatch, running update..."
|
||||
$DOWNLOADER -check-update
|
||||
$DOWNLOADER -patchline $PATCHLINE -download-path server.zip
|
||||
echo "$DOWNLOADER_VERSION" > $VERSION_FILE
|
||||
logger success "Saved version info!"
|
||||
extract_server_files
|
||||
else
|
||||
logger info "Versions match, skipping update"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
validate_server_files() {
|
||||
if [ ! -f "HytaleServer.jar" ]; then
|
||||
logger error "HytaleServer.jar not found!"
|
||||
logger error "Server files were not downloaded correctly."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
28
lib/plugins.sh
Normal file
28
lib/plugins.sh
Normal file
@@ -0,0 +1,28 @@
|
||||
#!/bin/bash
|
||||
|
||||
install_sourcequery() {
|
||||
if [ "$ENABLE_SOURCE_QUERY_SUPPORT" = "1" ]; then
|
||||
logger info "Source Query support enabled, checking for plugin..."
|
||||
|
||||
if [ ! -d "$MODS_FOLDER" ]; then
|
||||
logger warn "Creating mods directory..."
|
||||
mkdir -p $MODS_FOLDER
|
||||
fi
|
||||
|
||||
if [ -d "$MODS_FOLDER" ] && { [ ! -r "$MODS_FOLDER" ] || [ ! -w "$MODS_FOLDER" ] || [ ! -x "$MODS_FOLDER" ]; }; then
|
||||
logger warn "Fixing permissions on directory $MODS_FOLDER..."
|
||||
chmod 755 "$MODS_FOLDER"
|
||||
fi
|
||||
|
||||
logger info "Downloading latest hytale-sourcequery plugin..."
|
||||
local LATEST_URL=$(curl -sSL https://api.github.com/repos/physgun-com/hytale-sourcequery/releases/latest | jq -r '.assets[0].browser_download_url // empty')
|
||||
|
||||
if [ -n "$LATEST_URL" ]; then
|
||||
if curl -sSL -o "${MODS_FOLDER}/hytale-sourcequery.jar" "$LATEST_URL"; then
|
||||
logger success "Successfully downloaded hytale-sourcequery plugin"
|
||||
else
|
||||
logger error "Failed to download hytale-sourcequery plugin"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
}
|
||||
56
lib/system.sh
Normal file
56
lib/system.sh
Normal file
@@ -0,0 +1,56 @@
|
||||
#!/bin/bash
|
||||
|
||||
detect_architecture() {
|
||||
local ARCH=$(uname -m)
|
||||
logger info "Platform: $ARCH"
|
||||
|
||||
case "$ARCH" in
|
||||
x86_64)
|
||||
DOWNLOADER="./hytale-downloader-linux-amd64"
|
||||
;;
|
||||
aarch64|arm64)
|
||||
DOWNLOADER="./hytale-downloader-linux-arm64"
|
||||
;;
|
||||
*)
|
||||
logger error "Unsupported architecture: $ARCH"
|
||||
logger info "Supported architectures: x86_64 (amd64), aarch64/arm64"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
setup_environment() {
|
||||
# Get and export timezone
|
||||
export TZ=${TZ:-UTC}
|
||||
|
||||
# Get and export the internal docker ip
|
||||
export INTERNAL_IP=$(ip route get 1 | awk '{print $(NF-2);exit}')
|
||||
|
||||
# Goto working directory
|
||||
cd /home/container || exit 1
|
||||
}
|
||||
|
||||
setup_backup_directory() {
|
||||
if [ ! -d "backup" ]; then
|
||||
logger info "Backup directory does not exist. Creating it..."
|
||||
mkdir -p backup
|
||||
if [ $? -ne 0 ]; then
|
||||
logger error "Failed to create backup directory: /backup"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
chmod -R 755 backup
|
||||
}
|
||||
|
||||
enforce_permissions() {
|
||||
if [ "$ENFORCE_PERMISSIONS" = "1" ]; then
|
||||
logger warn "Enforcing permissions... This might take a while. Please be patient."
|
||||
find . -type d -exec chmod 755 {} \;
|
||||
find . -type f \
|
||||
! -name "hytale-downloader-linux-amd64" \
|
||||
! -name "hytale-downloader-linux-arm64" \
|
||||
! -name "start.sh" \
|
||||
-exec chmod 644 {} \;
|
||||
logger success "Permissions enforced (files: 644, folders: 755)"
|
||||
fi
|
||||
}
|
||||
82
lib/utilities.sh
Normal file
82
lib/utilities.sh
Normal file
@@ -0,0 +1,82 @@
|
||||
# Setup colors
|
||||
RED="" GREEN="" YELLOW="" BLUE="" MAGENTA="" CYAN="" RESET=""
|
||||
if [ -t 1 ] || { [ -n "$TERM" ] && [ "$TERM" != "dumb" ]; }; then
|
||||
# Helper to get color code (tput or ANSI fallback)
|
||||
if command -v tput >/dev/null 2>&1 && tput setaf 1 >/dev/null 2>&1; then
|
||||
_c() { tput setaf "$1"; }
|
||||
_r() { tput sgr0; }
|
||||
else
|
||||
_c() { printf '\033[0;3%dm' "$1"; }
|
||||
_r() { printf '\033[0m'; }
|
||||
fi
|
||||
|
||||
RED=$(_c 1) GREEN=$(_c 2) YELLOW=$(_c 3)
|
||||
BLUE=$(_c 4) MAGENTA=$(_c 5) CYAN=$(_c 6)
|
||||
RESET=$(_r)
|
||||
unset -f _c _r
|
||||
fi
|
||||
|
||||
#Function to print colored text
|
||||
printc() {
|
||||
local text="$1"
|
||||
|
||||
# Replace tags with color codes (or empty string if not supported)
|
||||
text="${text//\{RED\}/$RED}"
|
||||
text="${text//\{GREEN\}/$GREEN}"
|
||||
text="${text//\{YELLOW\}/$YELLOW}"
|
||||
text="${text//\{BLUE\}/$BLUE}"
|
||||
text="${text//\{MAGENTA\}/$MAGENTA}"
|
||||
text="${text//\{CYAN\}/$CYAN}"
|
||||
text="${text//\{RESET\}/$RESET}"
|
||||
printf "%b\n" "$text"
|
||||
}
|
||||
|
||||
# Logger function to print messages with different colors based on level
|
||||
logger() {
|
||||
local level="$1"
|
||||
local message="$2"
|
||||
|
||||
case "${level^^}" in
|
||||
"INFO") printc "{BLUE}ℹ $message{RESET}" ;;
|
||||
"WARN") printc "{YELLOW}⚠ $message{RESET}" ;;
|
||||
"ERROR") printc "{RED}⨯ $message{RESET}" ;;
|
||||
"SUCCESS") printc "{GREEN}✓ $message{RESET}" ;;
|
||||
*) printc "$message" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Function to extract downloaded server files
|
||||
extract_server_files() {
|
||||
logger info "Extracting server files..."
|
||||
SERVER_ZIP="server.zip"
|
||||
|
||||
if [ -f "$SERVER_ZIP" ]; then
|
||||
logger success "Found server archive: $SERVER_ZIP"
|
||||
|
||||
# Extract to current directory
|
||||
unzip -o "$SERVER_ZIP"
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
logger error "Failed to extract $SERVER_ZIP"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
logger success "Extraction completed successfully."
|
||||
|
||||
# Move contents from Server folder to current directory
|
||||
if [ -d "Server" ]; then
|
||||
logger info "Moving server files from Server directory..."
|
||||
cp -rf Server/* .
|
||||
rm -rf ./Server
|
||||
logger success "Server files moved to root directory."
|
||||
fi
|
||||
|
||||
# Clean up the zip file
|
||||
logger info "Cleaning up archive file..."
|
||||
rm "$SERVER_ZIP"
|
||||
logger success "Archive removed."
|
||||
else
|
||||
logger error "Server archive not found at $SERVER_ZIP"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
Reference in New Issue
Block a user