Last active
March 17, 2026 10:26
-
-
Save waggertron/410824540e55de7d77b3fda225379d8e to your computer and use it in GitHub Desktop.
Weyflix Connection Diagnostic - Mac/Linux (run in Terminal)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| # | |
| # Weyflix Connection Diagnostic (Mac / Linux) | |
| # | |
| # HOW TO RUN: | |
| # 1. Open Terminal: | |
| # - Mac: Press Command+Space, type "terminal", press Enter | |
| # - Linux: Press Ctrl+Alt+T | |
| # 2. Drag this file into the Terminal window (or type the path) | |
| # 3. Press Enter | |
| # 4. If you get "Permission denied", run: chmod +x weyflix-diagnose.sh | |
| # then try again | |
| # 5. Wait for it to finish | |
| # 6. The results will be saved to a file on your Desktop | |
| # 7. Send that file back so we can diagnose your issue | |
| # | |
| # ── CONFIG ── | |
| PLEX_PORT=32400 | |
| # Config file for saving IP across runs | |
| SAVED_IP_FILE="$HOME/.weyflix-server-ip" | |
| echo "" | |
| echo "========================================" | |
| echo " Weyflix Connection Diagnostic" | |
| echo "========================================" | |
| echo "" | |
| # Resolve server IP: argument > saved file > prompt | |
| if [ -n "$1" ]; then | |
| SERVER_PUBLIC_IP="$1" | |
| elif [ -f "$SAVED_IP_FILE" ]; then | |
| SAVED_IP=$(cat "$SAVED_IP_FILE" | tr -d '\r\n' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//') | |
| if [ -n "$SAVED_IP" ]; then | |
| echo " Found saved server IP: $SAVED_IP" | |
| echo "" | |
| printf " Is this correct? (y/n): " | |
| read CONFIRM | |
| CONFIRM=$(echo "$CONFIRM" | tr '[:upper:]' '[:lower:]' | tr -d '[:space:]') | |
| if [ "$CONFIRM" = "y" ] || [ "$CONFIRM" = "yes" ]; then | |
| SERVER_PUBLIC_IP="$SAVED_IP" | |
| else | |
| echo "" | |
| echo " OK, enter the correct IP below." | |
| echo " It looks something like: 73.162.45.100" | |
| echo "" | |
| printf " Enter the server IP (xxx.xxx.xxx.xxx): " | |
| read SERVER_PUBLIC_IP | |
| fi | |
| fi | |
| fi | |
| if [ -z "$SERVER_PUBLIC_IP" ]; then | |
| echo "The server admin should have given you an IP address." | |
| echo "It looks something like: 73.162.45.100" | |
| echo "" | |
| printf "Enter the server IP (xxx.xxx.xxx.xxx): " | |
| read SERVER_PUBLIC_IP | |
| fi | |
| # Sanitize: trim whitespace and strip newlines/carriage returns | |
| SERVER_PUBLIC_IP=$(echo "$SERVER_PUBLIC_IP" | tr -d '\r\n' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//') | |
| if [ -z "$SERVER_PUBLIC_IP" ]; then | |
| echo "" | |
| echo "[ERROR] No IP address entered." | |
| echo "" | |
| echo " Please re-run the script and enter the IP address" | |
| echo " that was provided to you (e.g. 73.162.45.100)" | |
| echo "" | |
| exit 1 | |
| fi | |
| # Validate IP format (IPv4: 1-3 digits separated by dots, 4 octets) | |
| if ! echo "$SERVER_PUBLIC_IP" | grep -qE '^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$'; then | |
| echo "" | |
| echo "[ERROR] '$SERVER_PUBLIC_IP' doesn't look like a valid IP address." | |
| echo "" | |
| echo " An IP address looks like: 73.162.45.100" | |
| echo " (four groups of numbers separated by dots)" | |
| echo "" | |
| echo " Make sure you're entering the IP address, not a website URL." | |
| echo " Don't include http:// or any slashes." | |
| echo "" | |
| exit 1 | |
| fi | |
| # Check if user entered a private/local IP range | |
| if echo "$SERVER_PUBLIC_IP" | grep -qE '^(10\.|172\.(1[6-9]|2[0-9]|3[01])\.|192\.168\.)'; then | |
| echo "" | |
| echo "[WARNING] '$SERVER_PUBLIC_IP' is a local/private IP address." | |
| echo "" | |
| echo " That's an internal network address (like a home Wi-Fi address)." | |
| echo " For remote access, you need the server's PUBLIC IP address." | |
| echo " Ask the server admin for the correct public IP and try again." | |
| echo "" | |
| exit 1 | |
| fi | |
| # Check if user entered their own IP by mistake (local or public) | |
| OWN_IP_MATCH=false | |
| if [ "$(uname)" = "Darwin" ]; then | |
| LOCAL_IPS=$(ifconfig 2>/dev/null | grep "inet " | awk '{print $2}' | grep -v "127\.") | |
| else | |
| LOCAL_IPS=$(hostname -I 2>/dev/null) | |
| fi | |
| MY_PUBLIC_CHECK=$(curl -s --connect-timeout 5 https://api.ipify.org 2>/dev/null) | |
| for ip in $LOCAL_IPS $MY_PUBLIC_CHECK; do | |
| if [ "$ip" = "$SERVER_PUBLIC_IP" ]; then | |
| OWN_IP_MATCH=true | |
| break | |
| fi | |
| done | |
| if [ "$OWN_IP_MATCH" = true ]; then | |
| echo "" | |
| echo "[WARNING] '$SERVER_PUBLIC_IP' is YOUR IP address, not the server's." | |
| echo "" | |
| echo " You entered your own IP address by mistake." | |
| echo " You need the Weyflix SERVER's IP address, not your own." | |
| echo " Ask the server admin for the correct IP and try again." | |
| echo "" | |
| exit 1 | |
| fi | |
| # Save IP for future runs | |
| echo "$SERVER_PUBLIC_IP" > "$SAVED_IP_FILE" | |
| echo "" | |
| echo " Target server: $SERVER_PUBLIC_IP" | |
| echo "" | |
| # ── OUTPUT SETUP ── | |
| OUTPUT_FILE="$HOME/Desktop/weyflix-diagnostic-$(date +%Y%m%d-%H%M%S).txt" | |
| log() { | |
| echo "$1" | |
| echo "$1" >> "$OUTPUT_FILE" | |
| } | |
| log_section() { | |
| log "" | |
| log "============================================" | |
| log " $1" | |
| log "============================================" | |
| } | |
| # Clear output file | |
| > "$OUTPUT_FILE" | |
| log "========================================================" | |
| log " WEYFLIX CONNECTION DIAGNOSTIC" | |
| log " $(date '+%Y-%m-%d %H:%M:%S')" | |
| log "========================================================" | |
| # ── 1. YOUR COMPUTER ── | |
| log_section "1. YOUR COMPUTER" | |
| log " Computer Name : $(hostname)" | |
| log " Username : $(whoami)" | |
| log " OS : $(uname -srm)" | |
| if [ "$(uname)" = "Darwin" ]; then | |
| log " macOS Version : $(sw_vers -productVersion 2>/dev/null || echo 'unknown')" | |
| IFACE=$(route -n get default 2>/dev/null | grep interface | awk '{print $2}') | |
| LOCAL_IP=$(ifconfig "$IFACE" 2>/dev/null | grep "inet " | awk '{print $2}') | |
| GATEWAY=$(route -n get default 2>/dev/null | grep gateway | awk '{print $2}') | |
| DNS=$(scutil --dns 2>/dev/null | grep "nameserver" | head -3 | awk '{print $3}' | tr '\n' ', ' | sed 's/,$//') | |
| else | |
| IFACE=$(ip route show default 2>/dev/null | awk '{print $5}' | head -1) | |
| LOCAL_IP=$(hostname -I 2>/dev/null | awk '{print $1}') | |
| GATEWAY=$(ip route show default 2>/dev/null | awk '{print $3}' | head -1) | |
| DNS=$(grep nameserver /etc/resolv.conf 2>/dev/null | awk '{print $2}' | tr '\n' ', ' | sed 's/,$//') | |
| fi | |
| log " Adapter : ${IFACE:-unknown}" | |
| log " Local IP : ${LOCAL_IP:-unknown}" | |
| log " Gateway : ${GATEWAY:-unknown}" | |
| log " DNS Servers : ${DNS:-unknown}" | |
| # ── 2. YOUR PUBLIC IP ── | |
| log_section "2. YOUR PUBLIC IP" | |
| log " Finding your public IP address..." | |
| MY_PUBLIC_IP=$(curl -s --connect-timeout 10 https://api.ipify.org 2>/dev/null) | |
| if [ -n "$MY_PUBLIC_IP" ]; then | |
| log " Your public IP: $MY_PUBLIC_IP" | |
| else | |
| log " [PROBLEM] Cannot determine your public IP" | |
| log " This usually means you have no internet connection" | |
| MY_PUBLIC_IP="UNKNOWN" | |
| fi | |
| # ── 3. INTERNET CONNECTION ── | |
| log_section "3. INTERNET CONNECTION" | |
| INTERNET_OK=false | |
| for site in "Google|https://www.google.com" "Plex.tv|https://plex.tv" "Apple|https://www.apple.com"; do | |
| name=$(echo "$site" | cut -d'|' -f1) | |
| url=$(echo "$site" | cut -d'|' -f2) | |
| code=$(curl -s -o /dev/null -w "%{http_code}" --connect-timeout 10 "$url" 2>/dev/null) | |
| if [ "$code" -ge 200 ] && [ "$code" -lt 400 ] 2>/dev/null; then | |
| log " [OK] $name - reachable (HTTP $code)" | |
| INTERNET_OK=true | |
| else | |
| log " [PROBLEM] $name - cannot reach (HTTP $code)" | |
| fi | |
| done | |
| if [ "$INTERNET_OK" = false ]; then | |
| log "" | |
| log " >>> DIAGNOSIS: You have no internet connection. <<<" | |
| log " >>> Fix your internet first, then try Weyflix again. <<<" | |
| log "" | |
| log "Results saved to: $OUTPUT_FILE" | |
| read -p "Press Enter to exit..." | |
| exit | |
| fi | |
| # ── 4. DNS RESOLUTION ── | |
| log_section "4. DNS RESOLUTION" | |
| DNS_OK=true | |
| for domain in plex.tv app.plex.tv google.com; do | |
| if command -v host >/dev/null 2>&1; then | |
| result=$(host "$domain" 2>/dev/null | grep "has address" | head -1 | awk '{print $NF}') | |
| elif command -v nslookup >/dev/null 2>&1; then | |
| result=$(nslookup "$domain" 2>/dev/null | grep "Address" | tail -1 | awk '{print $2}') | |
| elif command -v dig >/dev/null 2>&1; then | |
| result=$(dig +short "$domain" 2>/dev/null | head -1) | |
| fi | |
| if [ -n "$result" ]; then | |
| log " [OK] $domain -> $result" | |
| else | |
| log " [PROBLEM] $domain - DNS resolution FAILED" | |
| DNS_OK=false | |
| fi | |
| done | |
| if [ "$DNS_OK" = false ]; then | |
| log "" | |
| log " >>> DIAGNOSIS: DNS is not working properly. <<<" | |
| log " >>> Try changing your DNS servers to 1.1.1.1 and 8.8.8.8 <<<" | |
| if [ "$(uname)" = "Darwin" ]; then | |
| log " >>> Mac: System Settings > Network > your connection > Details > DNS <<<" | |
| log " >>> Remove existing entries, add 1.1.1.1 and 8.8.8.8 <<<" | |
| else | |
| log " >>> Linux: Edit /etc/resolv.conf or use your network manager <<<" | |
| log " >>> Set nameserver to 1.1.1.1 and 8.8.8.8 <<<" | |
| fi | |
| fi | |
| # ── 5. DIRECT SERVER CONNECTION ── | |
| log_section "5. DIRECT SERVER CONNECTION" | |
| log " Testing connection to Weyflix server at $SERVER_PUBLIC_IP:$PLEX_PORT..." | |
| log "" | |
| # Port test | |
| PORT_OPEN=false | |
| if command -v nc >/dev/null 2>&1; then | |
| if nc -z -w 5 "$SERVER_PUBLIC_IP" "$PLEX_PORT" 2>/dev/null; then | |
| log " [OK] Port $PLEX_PORT is OPEN and reachable" | |
| PORT_OPEN=true | |
| else | |
| log " [PROBLEM] Port $PLEX_PORT is BLOCKED or UNREACHABLE" | |
| fi | |
| else | |
| log " (nc not available, using curl for port test)" | |
| fi | |
| # Plex API test | |
| log "" | |
| log " Testing Plex API..." | |
| API_START=$(date +%s%N 2>/dev/null || date +%s) | |
| API_CODE=$(curl -s -o /dev/null -w "%{http_code}" --connect-timeout 15 "http://$SERVER_PUBLIC_IP:$PLEX_PORT/identity" 2>/dev/null) | |
| API_END=$(date +%s%N 2>/dev/null || date +%s) | |
| if [ "$API_CODE" = "200" ]; then | |
| log " [OK] Plex API responding (HTTP $API_CODE)" | |
| PORT_OPEN=true | |
| # Get server version | |
| VERSION=$(curl -s --connect-timeout 5 "http://$SERVER_PUBLIC_IP:$PLEX_PORT/identity" 2>/dev/null | grep -oP 'version="[^"]*"' | head -1) | |
| if [ -n "$VERSION" ]; then | |
| log " Server $VERSION" | |
| fi | |
| elif [ "$API_CODE" = "000" ]; then | |
| log " [PROBLEM] Plex API TIMED OUT" | |
| log " The port is likely blocked by a firewall or ISP" | |
| else | |
| log " [PROBLEM] Plex API returned HTTP $API_CODE" | |
| fi | |
| # ── 6. PING TEST ── | |
| log_section "6. PING TEST (latency & packet loss)" | |
| log " Sending 10 pings to $SERVER_PUBLIC_IP..." | |
| PING_OUTPUT=$(ping -c 10 -W 3 "$SERVER_PUBLIC_IP" 2>&1) | |
| log "$PING_OUTPUT" | |
| # Parse ping stats | |
| LOSS=$(echo "$PING_OUTPUT" | grep -oP '\d+(?=% packet loss)' || echo "$PING_OUTPUT" | grep -oP '\d+(?=\.?\d*% packet loss)') | |
| AVG_LATENCY=$(echo "$PING_OUTPUT" | grep -oP 'avg[^=]*= [^/]*/([^/]*)' | grep -oP '[\d.]+' || echo "$PING_OUTPUT" | tail -1 | awk -F'/' '{print $5}') | |
| if [ -n "$LOSS" ] && [ "$LOSS" != "100" ]; then | |
| if [ "$LOSS" -gt 0 ] 2>/dev/null; then | |
| log " [PROBLEM] Packet loss detected (${LOSS}%)" | |
| fi | |
| if [ -n "$AVG_LATENCY" ]; then | |
| AVG_INT=$(echo "$AVG_LATENCY" | cut -d. -f1) | |
| if [ "$AVG_INT" -gt 150 ] 2>/dev/null; then | |
| log " [PROBLEM] High latency (${AVG_LATENCY}ms) - streaming quality will be poor" | |
| elif [ "$AVG_INT" -gt 50 ] 2>/dev/null; then | |
| log " [OK] Latency is moderate (${AVG_LATENCY}ms) - should work" | |
| else | |
| log " [OK] Latency is good (${AVG_LATENCY}ms)" | |
| fi | |
| fi | |
| elif [ "$LOSS" = "100" ]; then | |
| log " [PROBLEM] All pings failed" | |
| log " Server may block ping or be offline" | |
| log " (This doesn't necessarily mean Plex won't work)" | |
| fi | |
| # ── 7. TRACEROUTE ── | |
| log_section "7. NETWORK PATH (traceroute)" | |
| log " Tracing route to $SERVER_PUBLIC_IP (this takes 30-60 seconds)..." | |
| if command -v traceroute >/dev/null 2>&1; then | |
| TRACE_OUTPUT=$(traceroute -m 15 "$SERVER_PUBLIC_IP" 2>&1) | |
| log "$TRACE_OUTPUT" | |
| # Check for CGNAT in your path | |
| CGNAT=$(echo "$TRACE_OUTPUT" | grep -E "100\.(6[4-9]|[7-9][0-9]|1[01][0-9]|12[0-7])\.") | |
| if [ -n "$CGNAT" ]; then | |
| log "" | |
| log " [INFO] CGNAT detected in YOUR network path" | |
| log " This means your ISP uses Carrier-Grade NAT" | |
| log " This is on YOUR side and should not affect connecting to Weyflix" | |
| fi | |
| elif command -v tracert >/dev/null 2>&1; then | |
| tracert -h 15 "$SERVER_PUBLIC_IP" 2>&1 | tee -a "$OUTPUT_FILE" | |
| else | |
| log " (traceroute not available on this system)" | |
| fi | |
| # ── 8. VPN CHECK ── | |
| log_section "8. VPN / PROXY CHECK" | |
| VPN_DETECTED=false | |
| # Check for common VPN interfaces | |
| if [ "$(uname)" = "Darwin" ]; then | |
| VPN_IFACES=$(ifconfig 2>/dev/null | grep -E "^(utun|tun|tap|ipsec|ppp)" | cut -d: -f1) | |
| else | |
| VPN_IFACES=$(ip link show 2>/dev/null | grep -E "(tun|tap|wg|nordlynx|proton|mullvad)" | awk -F: '{print $2}' | tr -d ' ') | |
| fi | |
| if [ -n "$VPN_IFACES" ]; then | |
| log " [INFO] VPN interface(s) detected: $VPN_IFACES" | |
| log " VPNs can sometimes block Plex connections" | |
| log " Try disconnecting your VPN and testing again" | |
| VPN_DETECTED=true | |
| else | |
| log " [OK] No VPN detected" | |
| fi | |
| # Check for proxy | |
| if [ -n "$http_proxy" ] || [ -n "$https_proxy" ] || [ -n "$HTTP_PROXY" ] || [ -n "$HTTPS_PROXY" ]; then | |
| log " [INFO] HTTP proxy detected in environment" | |
| log " http_proxy=$http_proxy" | |
| log " https_proxy=$https_proxy" | |
| else | |
| log " [OK] No system proxy" | |
| fi | |
| # ── 9. BANDWIDTH ESTIMATE ── | |
| log_section "9. BANDWIDTH ESTIMATE" | |
| log " Testing response speed..." | |
| if [ "$PORT_OPEN" = true ]; then | |
| SPEED_INFO=$(curl -s -o /dev/null -w "time_connect=%{time_connect} time_total=%{time_total} speed=%{speed_download}" --connect-timeout 10 "http://$SERVER_PUBLIC_IP:$PLEX_PORT/identity" 2>/dev/null) | |
| TOTAL_TIME=$(echo "$SPEED_INFO" | grep -oP 'time_total=[\d.]+' | cut -d= -f2) | |
| TOTAL_MS=$(echo "$TOTAL_TIME * 1000" | bc 2>/dev/null | cut -d. -f1 || echo "unknown") | |
| if [ "$TOTAL_MS" != "unknown" ] && [ "$TOTAL_MS" -lt 500 ] 2>/dev/null; then | |
| log " [OK] Fast response (${TOTAL_MS}ms) - streaming should work well" | |
| elif [ "$TOTAL_MS" != "unknown" ] && [ "$TOTAL_MS" -lt 2000 ] 2>/dev/null; then | |
| log " [OK] Moderate response (${TOTAL_MS}ms) - streaming should work" | |
| elif [ "$TOTAL_MS" != "unknown" ]; then | |
| log " [PROBLEM] Slow response (${TOTAL_MS}ms) - may have buffering issues" | |
| else | |
| log " Response info: $SPEED_INFO" | |
| fi | |
| else | |
| log " Cannot estimate (server unreachable)" | |
| fi | |
| # ── 10. SUMMARY ── | |
| log_section "SUMMARY" | |
| ISSUES=() | |
| if [ "$INTERNET_OK" = false ]; then ISSUES+=("No internet connection"); fi | |
| if [ "$DNS_OK" = false ]; then ISSUES+=("DNS resolution failing"); fi | |
| if [ "$PORT_OPEN" = false ]; then ISSUES+=("Server port $PLEX_PORT is blocked/unreachable"); fi | |
| if [ -n "$LOSS" ] && [ "$LOSS" -gt 20 ] 2>/dev/null; then ISSUES+=("Significant packet loss (${LOSS}%)"); fi | |
| if [ -n "$AVG_INT" ] && [ "$AVG_INT" -gt 150 ] 2>/dev/null; then ISSUES+=("High latency (${AVG_LATENCY}ms)"); fi | |
| if [ "$VPN_DETECTED" = true ]; then ISSUES+=("VPN active (may interfere)"); fi | |
| if [ ${#ISSUES[@]} -eq 0 ]; then | |
| log "" | |
| log " [OK] No issues detected from your end!" | |
| log "" | |
| log " If you still can't connect, try:" | |
| log " 1. Sign out of the Plex app and sign back in" | |
| log " 2. Clear the Plex app cache" | |
| log " 3. Make sure you're using the correct Plex account" | |
| log " 4. Try a different device or network" | |
| else | |
| log "" | |
| log " Issues found (${#ISSUES[@]}):" | |
| for issue in "${ISSUES[@]}"; do | |
| log " - $issue" | |
| done | |
| log "" | |
| log " Some issues above may have suggested fixes you can try." | |
| log " If you've fixed something, you can run this script again" | |
| log " to verify the fix worked and check for any remaining issues." | |
| log " (Your server IP is saved — just run the script again)" | |
| fi | |
| log "" | |
| log "========================================================" | |
| log " WHAT TO DO NOW" | |
| log "========================================================" | |
| log "" | |
| log " ** PLEASE SEND THESE RESULTS BACK, even if you see fixes **" | |
| log " ** you can try. This helps the admin see the full picture. **" | |
| log "" | |
| log " A file has been saved to your Desktop:" | |
| log " $OUTPUT_FILE" | |
| log "" | |
| log " Send it via email, text, or Discord." | |
| log "" | |
| log " If you tried a fix and want to verify it worked:" | |
| log " Just run this script again — your server IP is saved" | |
| log " so you won't need to re-enter it." | |
| log "" | |
| log "========================================================" | |
| log "" | |
| log " Weyflix is a free service provided with love to a" | |
| log " very fortunate group of people. That said, there are" | |
| log " real costs involved in keeping it running (hardware," | |
| log " electricity, storage, internet, and time)." | |
| log "" | |
| log " Donations are never necessary but always appreciated:" | |
| log " Venmo: @weylin" | |
| log "" | |
| log " Thanks for being part of the Weyflix family!" | |
| log "" | |
| echo "" | |
| echo "Results saved to: $OUTPUT_FILE" | |
| # Try to open the file | |
| if [ "$(uname)" = "Darwin" ]; then | |
| open "$OUTPUT_FILE" 2>/dev/null | |
| elif command -v xdg-open >/dev/null 2>&1; then | |
| xdg-open "$OUTPUT_FILE" 2>/dev/null | |
| fi | |
| echo "" | |
| read -p "Press Enter to exit..." |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment