From aaac451c1b9e69624840d4aaff5397c064e981ab Mon Sep 17 00:00:00 2001 From: NATroutter Date: Tue, 13 Jan 2026 14:47:56 +0200 Subject: [PATCH] Updated the starting script to automaticly authenticate and creating game session Added "Game Profile" argument to both eggs --- egg-hytale.pelican.json | 41 +++++++---- egg-hytale.pterodactyl.json | 12 +++- start.sh | 133 ++++++++++++++++++++++++++++++++++++ 3 files changed, 171 insertions(+), 15 deletions(-) diff --git a/egg-hytale.pelican.json b/egg-hytale.pelican.json index a0b3f29..8405944 100644 --- a/egg-hytale.pelican.json +++ b/egg-hytale.pelican.json @@ -2,9 +2,9 @@ "_comment": "DO NOT EDIT: FILE GENERATED AUTOMATICALLY BY PANEL", "meta": { "version": "PLCN_v3", - "update_url": "https://raw.githubusercontent.com/NATroutter/egg-hytale/refs/heads/main/egg-hytale.json" + "update_url": "https://raw.githubusercontent.com/NATroutter/egg-hytale/refs/heads/main/egg-hytale.pelican.json" }, - "exported_at": "2026-01-12T17:49:33+00:00", + "exported_at": "2026-01-13T12:29:34+00:00", "name": "Hytale", "author": "contact@natroutter.fi", "uuid": "6594b287-2d7b-4249-bc93-4d40283c57e3", @@ -31,7 +31,7 @@ }, "scripts": { "installation": { - "script": "#!/bin/bash\nDOWNLOAD_URL=\"https://downloader.hytale.com/hytale-downloader.zip\"\nDOWNLOAD_FILE=\"hytale-downloader.zip\"\n\napt update\napt install -y curl unzip\n\ncd /mnt/server\n\n# Downloads and extracts the Hytale downloader\necho \"Starting Hytale downloader installation...\"\n\n# Download the file\necho \"Downloading hytale-downloader.zip...\"\ncurl -L -o \"${DOWNLOAD_FILE}\" \"${DOWNLOAD_URL}\"\n\nif [ $? -ne 0 ]; then\n echo \"Error: Failed to download ${DOWNLOAD_URL}\"\n exit 1\nfi\n\necho \"Download completed successfully.\"\n\n# Extract the zip file\necho \"Extracting ${DOWNLOAD_FILE}...\"\nunzip -o \"${DOWNLOAD_FILE}\"\n\nif [ $? -ne 0 ]; then\n echo \"Error: Failed to extract ${DOWNLOAD_FILE}\"\n exit 1\nfi\n\necho \"Extraction completed successfully.\"\n\n# Remove the unnessasery file\necho \"Cleaning up...\"\nrm \"${DOWNLOAD_FILE}\"\nrm QUICKSTART.md\nrm hytale-downloader-windows-amd64.exe\n\necho \"Downloading start.sh script...\"\ncurl -L -o start.sh \"https://raw.githubusercontent.com/NATroutter/egg-hytale/main/start.sh\"\n\nif [ $? -ne 0 ]; then\n echo \"Error: Failed to download start.sh\"\n exit 1\nfi\n\necho \"Setting executable permissions...\"\nchmod +x ./hytale-downloader-linux-amd64\nchmod +x ./start.sh\n\necho \"Installation complete!\"", + "script": "#!/bin/bash\nDOWNLOAD_URL=\"https://downloader.hytale.com/hytale-downloader.zip\"\nDOWNLOAD_FILE=\"hytale-downloader.zip\"\n\napt update\napt install -y curl unzip jq\n\ncd /mnt/server\n\n# Downloads and extracts the Hytale downloader\necho \"Starting Hytale downloader installation...\"\n\n# Download the file\necho \"Downloading hytale-downloader.zip...\"\ncurl -L -o \"${DOWNLOAD_FILE}\" \"${DOWNLOAD_URL}\"\n\nif [ $? -ne 0 ]; then\n echo \"Error: Failed to download ${DOWNLOAD_URL}\"\n exit 1\nfi\n\necho \"Download completed successfully.\"\n\n# Extract the zip file\necho \"Extracting ${DOWNLOAD_FILE}...\"\nunzip -o \"${DOWNLOAD_FILE}\"\n\nif [ $? -ne 0 ]; then\n echo \"Error: Failed to extract ${DOWNLOAD_FILE}\"\n exit 1\nfi\n\necho \"Extraction completed successfully.\"\n\n# Remove the unnessasery file\necho \"Cleaning up...\"\nrm \"${DOWNLOAD_FILE}\"\nrm QUICKSTART.md\nrm hytale-downloader-windows-amd64.exe\n\necho \"Downloading start.sh script...\"\ncurl -L -o start.sh \"https://raw.githubusercontent.com/NATroutter/egg-hytale/main/start.sh\"\n\nif [ $? -ne 0 ]; then\n echo \"Error: Failed to download start.sh\"\n exit 1\nfi\n\necho \"Setting executable permissions...\"\nchmod +x ./hytale-downloader-linux-amd64\nchmod +x ./start.sh\n\necho \"Installation complete!\"", "container": "ghcr.io/pelican-eggs/installers:debian", "entrypoint": "bash" } @@ -48,7 +48,7 @@ "boolean", "required" ], - "sort": 3 + "sort": 4 }, { "name": "Allow OP", @@ -61,7 +61,7 @@ "boolean", "required" ], - "sort": 1 + "sort": 2 }, { "name": "Asset Pack", @@ -75,7 +75,7 @@ "regex:/^([\\w\\d._-]+)(\\.zip)$/", "nullable" ], - "sort": 2 + "sort": 3 }, { "name": "Auth Mode", @@ -89,7 +89,7 @@ "string", "in:authenticated,offline" ], - "sort": 4 + "sort": 5 }, { "name": "Automatic Update", @@ -102,7 +102,7 @@ "required", "boolean" ], - "sort": 10 + "sort": 11 }, { "name": "Backup Directory", @@ -115,7 +115,7 @@ "required", "string" ], - "sort": 6 + "sort": 7 }, { "name": "Backup Frequency", @@ -129,7 +129,7 @@ "required", "min:1" ], - "sort": 7 + "sort": 8 }, { "name": "Disable Sentry Crash Reporting", @@ -142,7 +142,7 @@ "boolean", "required" ], - "sort": 9 + "sort": 10 }, { "name": "Enable Backups", @@ -155,7 +155,20 @@ "boolean", "required" ], - "sort": 5 + "sort": 6 + }, + { + "name": "Game Profile (username)", + "description": "Specify which Hytale profile should be used for server authentication.\n\nHow to find your profile username:\n1. Visit https://accounts.hytale.com/\n2. Click \"Game Profiles\" in the left side menu\n3. Copy the username of the profile you want to use\n4. Paste it into this field\n\nLeave empty to use your default/first profile automatically.", + "env_variable": "GAME_PROFILE", + "default_value": "", + "user_viewable": true, + "user_editable": true, + "rules": [ + "nullable", + "string" + ], + "sort": 1 }, { "name": "JVM Arguments", @@ -168,7 +181,7 @@ "string", "nullable" ], - "sort": 11 + "sort": 12 }, { "name": "Leverage Ahead-Of-Time Cache", @@ -181,7 +194,7 @@ "required", "boolean" ], - "sort": 8 + "sort": 9 } ] } \ No newline at end of file diff --git a/egg-hytale.pterodactyl.json b/egg-hytale.pterodactyl.json index 6c898fb..1ac2b67 100644 --- a/egg-hytale.pterodactyl.json +++ b/egg-hytale.pterodactyl.json @@ -4,7 +4,7 @@ "version": "PTDL_v2", "update_url": "https:\/\/raw.githubusercontent.com\/NATroutter\/egg-hytale\/refs\/heads\/main\/egg-hytale.pterodactyl.json" }, - "exported_at": "2026-01-12T19:49:12+02:00", + "exported_at": "2026-01-13T14:30:56+02:00", "name": "Hytale", "author": "contact@natroutter.fi", "description": "Hytale is a block-based sandbox game that blends creative building with RPG adventure. Explore procedurally generated worlds filled with unique biomes, dungeons, and creatures. Build anything from simple homes to grand castles, craft items, and battle monsters. Create custom content with built-in modding tools, host your own servers, and shape the experience with plugins and mods. Play solo or with friends in a world designed for both creation and exploration.\r\n\r\nCredits:\r\n- Made by NATroutter\r\n- https:\/\/natroutter.fi\r\n- https:\/\/github.com\/NATroutter", @@ -30,6 +30,16 @@ } }, "variables": [ + { + "name": "Game Profile (username)", + "description": "Specify which Hytale profile should be used for server authentication.\r\n\r\nHow to find your profile username:\r\n1. Visit https:\/\/accounts.hytale.com\/\r\n2. Click \"Game Profiles\" in the left side menu\r\n3. Copy the username of the profile you want to use\r\n4. Paste it into this field\r\n\r\nLeave empty to use your default\/first profile automatically.", + "env_variable": "GAME_PROFILE", + "default_value": "", + "user_viewable": true, + "user_editable": true, + "rules": "nullable|string", + "field_type": "text" + }, { "name": "Accept Early Plugins", "description": "Acknowledge that loading early plugins is unsupported and may cause stability issues", diff --git a/start.sh b/start.sh index aadad8d..ea7d6ca 100644 --- a/start.sh +++ b/start.sh @@ -40,6 +40,134 @@ if [ "${AUTOMATIC_UPDATE}" = "1" ]; then $DOWNLOADER fi +# Obtain authentication tokens +echo "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 "" +echo "╔═════════════════════════════════════════════════════════════════════════════╗" +echo "║ HYTALE SERVER AUTHENTICATION REQUIRED ║" +echo "╠═════════════════════════════════════════════════════════════════════════════╣" +echo "║ ║" +echo "║ Please authenticate the server by visiting the following URL: ║" +echo "║ ║" +echo "║ $VERIFICATION_URI ║" +echo "║ ║" +echo "║ 1. Click the link above or copy it to your browser ║" +echo "║ 2. Sign in with your Hytale account ║" +echo "║ 3. Authorize the server ║" +echo "║ ║" +echo "║ Waiting for authentication... ║" +echo "║ ║" +echo "╚═════════════════════════════════════════════════════════════════════════════╝" +echo "" + +# 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 + echo "Still waiting for authentication..." + continue + elif [ -n "$ERROR" ]; then + echo "Authentication error: $ERROR" + exit 1 + else + # Successfully authenticated + ACCESS_TOKEN=$(echo "$TOKEN_RESPONSE" | jq -r '.access_token') + echo "" + echo "✓ Authentication successful!" + echo "" + fi +done + +# Fetch available game profiles +echo "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 + echo "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 + echo "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 + echo "Error: Profile '$GAME_PROFILE' not found." + echo "Available profiles:" + echo "$PROFILES_RESPONSE" | jq -r '.profiles[] | " - \(.username)"' + exit 1 + fi + + echo "✓ 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') + + echo "✓ Using default profile: $PROFILE_USERNAME (UUID: $PROFILE_UUID)" +fi + +echo "" + +# Create game server session +echo "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 + echo "Error: Invalid JSON response from game session creation" + echo "Response: $SESSION_RESPONSE" + exit 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 + echo "Error: Failed to create game server session" + echo "Response: $SESSION_RESPONSE" + exit 1 +fi + +echo "✓ Game server session created successfully!" +echo "" + echo "Starting Hytale server..." # Build the Java command @@ -89,6 +217,11 @@ if [ "${ENABLE_BACKUPS}" = "1" ]; then JAVA_CMD="${JAVA_CMD} --backup --backup-dir ${BACKUP_DIRECTORY} --backup-frequency ${BACKUP_FREQUENCY}" fi +# Add session tokens and owner UUID +JAVA_CMD="${JAVA_CMD} --session-token ${SESSION_TOKEN}" +JAVA_CMD="${JAVA_CMD} --identity-token ${IDENTITY_TOKEN}" +JAVA_CMD="${JAVA_CMD} --owner-uuid ${PROFILE_UUID}" + # Add bind address JAVA_CMD="${JAVA_CMD} --bind 0.0.0.0:${SERVER_PORT}"