initial dotfiles

This commit is contained in:
srtk 2026-04-25 16:39:11 +05:30
commit 45e5fe53d2
370 changed files with 25449 additions and 0 deletions

View file

@ -0,0 +1,341 @@
#!/usr/bin/env bash
set -euo pipefail
# Get the directory where the script is located
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
BASE="$SCRIPT_DIR/providers"
ROFI="rofi -dmenu -i"
NOTIFY="notify-send"
VPN_CMD="sudo openvpn"
# Helpers
die() {
$NOTIFY "MultiVPN" "$1"
exit 1
}
pick_random() { printf "%s\n" "$@" | shuf -n1; }
# Provider menu
providers=()
while IFS= read -r d; do
[[ -d "$BASE/$d" ]] && providers+=("$d")
done < <(ls "$BASE")
[[ ${#providers[@]} -eq 0 ]] && die "No providers found in $BASE"
provider_menu="[Disconnect]\n[Random Provider]\n$(printf "%s\n" "${providers[@]}" | sort)"
provider=$(echo -e "$provider_menu" | $ROFI -p "Select Provider")
[[ -z "$provider" ]] && exit 0
if [[ "$provider" == "[Disconnect]" ]]; then
sudo pkill openvpn 2>/dev/null && $NOTIFY "MultiVPN" "Disconnected ✓" || $NOTIFY "MultiVPN" "No active VPN connection"
exit 0
elif [[ "$provider" == "[Random Provider]" ]]; then
provider=$(pick_random "${providers[@]}")
random_provider=true
else
random_provider=false
fi
AUTH="$BASE/$provider/auth"
SERVER_DIR="$BASE/$provider/servers"
# Dynamic city map
declare -A countries
declare -A city_country_map
# Scan all .ovpn files and extract city-country info
while IFS= read -r f; do
filename=$(basename "$f" .ovpn)
# Parse filename format: city-country-###-scramble or city-country-###
if [[ "$filename" =~ ^([a-z0-9-]+)-([a-z]{2})-([0-9]{3})(-scramble)?$ ]]; then
city="${BASH_REMATCH[1]}"
country="${BASH_REMATCH[2]}"
# Server number is in BASH_REMATCH[3]
# Scramble flag is in BASH_REMATCH[4]
# Capitalize city name (replace hyphens with spaces)
city_display=$(echo "$city" | sed 's/-/ /g' | sed 's/\b\(.\)/\u\1/g')
# Get full country name from country code
case "$country" in
# North America
us) country_full="United States" ;;
ca) country_full="Canada" ;;
mx) country_full="Mexico" ;;
# Europe - Western
uk | gb) country_full="United Kingdom" ;;
de) country_full="Germany" ;;
fr) country_full="France" ;;
nl) country_full="Netherlands" ;;
ch) country_full="Switzerland" ;;
es) country_full="Spain" ;;
it) country_full="Italy" ;;
be) country_full="Belgium" ;;
at) country_full="Austria" ;;
ie) country_full="Ireland" ;;
pt) country_full="Portugal" ;;
lu) country_full="Luxembourg" ;;
# Europe - Northern
se) country_full="Sweden" ;;
no) country_full="Norway" ;;
dk) country_full="Denmark" ;;
fi) country_full="Finland" ;;
is) country_full="Iceland" ;;
# Europe - Eastern
pl) country_full="Poland" ;;
cz) country_full="Czech Republic" ;;
hu) country_full="Hungary" ;;
ro) country_full="Romania" ;;
bg) country_full="Bulgaria" ;;
sk) country_full="Slovakia" ;;
si) country_full="Slovenia" ;;
hr) country_full="Croatia" ;;
rs) country_full="Serbia" ;;
ua) country_full="Ukraine" ;;
# Europe - Southern
gr) country_full="Greece" ;;
tr) country_full="Turkey" ;;
cy) country_full="Cyprus" ;;
mt) country_full="Malta" ;;
# Asia - East
jp) country_full="Japan" ;;
kr) country_full="South Korea" ;;
cn) country_full="China" ;;
tw) country_full="Taiwan" ;;
hk) country_full="Hong Kong" ;;
mo) country_full="Macau" ;;
# Asia - Southeast
sg) country_full="Singapore" ;;
my) country_full="Malaysia" ;;
th) country_full="Thailand" ;;
id) country_full="Indonesia" ;;
ph) country_full="Philippines" ;;
vn) country_full="Vietnam" ;;
# Asia - South
in) country_full="India" ;;
pk) country_full="Pakistan" ;;
bd) country_full="Bangladesh" ;;
lk) country_full="Sri Lanka" ;;
# Middle East
ae) country_full="United Arab Emirates" ;;
sa) country_full="Saudi Arabia" ;;
il) country_full="Israel" ;;
qa) country_full="Qatar" ;;
kw) country_full="Kuwait" ;;
bh) country_full="Bahrain" ;;
om) country_full="Oman" ;;
jo) country_full="Jordan" ;;
# Oceania
au) country_full="Australia" ;;
nz) country_full="New Zealand" ;;
# South America
br) country_full="Brazil" ;;
ar) country_full="Argentina" ;;
cl) country_full="Chile" ;;
co) country_full="Colombia" ;;
pe) country_full="Peru" ;;
uy) country_full="Uruguay" ;;
py) country_full="Paraguay" ;;
ve) country_full="Venezuela" ;;
ec) country_full="Ecuador" ;;
# Central America & Caribbean
cr) country_full="Costa Rica" ;;
pa) country_full="Panama" ;;
gt) country_full="Guatemala" ;;
jm) country_full="Jamaica" ;;
tt) country_full="Trinidad and Tobago" ;;
# Africa
za) country_full="South Africa" ;;
eg) country_full="Egypt" ;;
ng) country_full="Nigeria" ;;
ke) country_full="Kenya" ;;
ma) country_full="Morocco" ;;
gh) country_full="Ghana" ;;
# Baltic States
ee) country_full="Estonia" ;;
lv) country_full="Latvia" ;;
lt) country_full="Lithuania" ;;
# Other European
md) country_full="Moldova" ;;
al) country_full="Albania" ;;
mk) country_full="North Macedonia" ;;
ba) country_full="Bosnia and Herzegovina" ;;
me) country_full="Montenegro" ;;
# Fallback
*) country_full=$(echo "$country" | tr '[:lower:]' '[:upper:]') ;;
esac
# Add to country map
if [[ -z "${countries[$country_full]:-}" ]]; then
countries[$country_full]="$city"
else
# Only add if city not already in list
if [[ ! " ${countries[$country_full]} " =~ " $city " ]]; then
countries[$country_full]+=" $city"
fi
fi
# Map city -> country for later lookup
city_country_map[$city]="$country_full"
fi
done < <(find "$SERVER_DIR" -name "*.ovpn")
[[ ${#countries[@]} -eq 0 ]] && die "No valid .ovpn files found in $SERVER_DIR"
# Country menu
country_menu="[Random Country]\n"
country_menu+="$(printf "%s\n" "${!countries[@]}" | sort)"
country=$(echo -e "$country_menu" | $ROFI -p "Select Country")
[[ -z "$country" ]] && exit 0
if [[ "$country" == "[Random Country]" ]]; then
country=$(pick_random "${!countries[@]}")
random_country=true
else
random_country=false
fi
# City menu
cities=(${countries[$country]})
if [[ "$random_country" == true ]]; then
city=$(pick_random "${cities[@]}")
city_display=$(echo "$city" | sed 's/-/ /g' | sed 's/\b\(.\)/\u\1/g')
else
city_menu="[Random City]\n"
for c in "${cities[@]}"; do
city_display=$(echo "$c" | sed 's/-/ /g' | sed 's/\b\(.\)/\u\1/g')
city_menu+="$city_display\n"
done
city_display=$(echo -e "$city_menu" | $ROFI -p "$country")
[[ -z "$city_display" ]] && exit 0
if [[ "$city_display" == "[Random City]" ]]; then
city=$(pick_random "${cities[@]}")
city_display=$(echo "$city" | sed 's/-/ /g' | sed 's/\b\(.\)/\u\1/g')
else
# Convert display name back to filename format
city=$(echo "$city_display" | tr '[:upper:]' '[:lower:]' | sed 's/ /-/g')
fi
fi
# Check if scrambled servers exist for this city
mapfile -t scrambled_servers < <(ls "$SERVER_DIR" | grep "^$city-[a-z]\{2\}-[0-9]\{3\}-scramble\.ovpn$" || true)
mapfile -t regular_servers < <(ls "$SERVER_DIR" | grep "^$city-[a-z]\{2\}-[0-9]\{3\}\.ovpn$" || true)
has_scrambled=$([[ ${#scrambled_servers[@]} -gt 0 ]] && echo true || echo false)
has_regular=$([[ ${#regular_servers[@]} -gt 0 ]] && echo true || echo false)
if [[ "$has_scrambled" == true && "$has_regular" == true ]]; then
# Both types available, ask user
scramble_menu="Regular\nScrambled\n[Random]"
scramble_choice=$(echo -e "$scramble_menu" | $ROFI -p "Connection Type")
[[ -z "$scramble_choice" ]] && exit 0
case "$scramble_choice" in
"Regular")
use_scramble=false
;;
"Scrambled")
use_scramble=true
;;
"[Random]")
use_scramble=$([[ $((RANDOM % 2)) -eq 0 ]] && echo true || echo false)
;;
esac
elif [[ "$has_scrambled" == true ]]; then
# Only scrambled available
use_scramble=true
elif [[ "$has_regular" == true ]]; then
# Only regular available
use_scramble=false
else
die "No servers found for $city_display"
fi
# Server menu
if [[ "$use_scramble" == true ]]; then
server_files=("${scrambled_servers[@]}")
connection_type="🔒 Scrambled"
else
server_files=("${regular_servers[@]}")
connection_type="Regular"
fi
[[ "${#server_files[@]}" -eq 0 ]] && die "No $connection_type servers for $city_display"
if [[ "$random_provider" == true || "$random_country" == true ]]; then
server_file=$(pick_random "${server_files[@]}")
else
server_menu="[Random Server]\n"
for s in "${server_files[@]}"; do
# Extract server number (it's always before -scramble or .ovpn)
if [[ "$s" =~ -([0-9]{3})(-scramble)?\.ovpn$ ]]; then
server_menu+="Server ${BASH_REMATCH[1]}\n"
else
server_menu+="$s\n"
fi
done
server_menu+="[Disconnect]"
choice=$(echo -e "$server_menu" | $ROFI -p "$city_display ($connection_type)")
[[ -z "$choice" ]] && exit 0
if [[ "$choice" == "[Disconnect]" ]]; then
sudo killall openvpn && exit 0
elif [[ "$choice" == "[Random Server]" ]]; then
server_file=$(pick_random "${server_files[@]}")
else
num=$(echo "$choice" | grep -o '[0-9]\{3\}')
if [[ "$use_scramble" == true ]]; then
server_file=$(printf "%s\n" "${server_files[@]}" | grep -- "-$num-scramble\.ovpn$")
else
server_file=$(printf "%s\n" "${server_files[@]}" | grep -- "-$num\.ovpn$")
fi
fi
fi
# Ask for sudo
SUDO_PASS=$(rofi -dmenu -password -p "Enter sudo password")
[[ -z "$SUDO_PASS" ]] && exit 0
# Kill old VPN if existing
echo "$SUDO_PASS" | sudo -S pkill openvpn 2>/dev/null || true
# Notify
$NOTIFY "MultiVPN" "Connecting…\n$provider$country$city_display\nType: $connection_type"
# Launch openvpn
echo "$SUDO_PASS" | sudo -S openvpn --config "$SERVER_DIR/$server_file" --auth-user-pass "$AUTH" &
# Wait for VPN to establish and routing to settle
sleep 8
# Get public IP
# Retry a few times to ensure we get the VPN IP
for i in {1..3}; do
ip=$(curl -s --max-time 5 ifconfig.me 2>/dev/null || echo "")
[[ -n "$ip" ]] && break
sleep 2
done
[[ -z "$ip" ]] && ip="Unknown"
$NOTIFY "MultiVPN" "Connected ✓\n$provider$country$city_display\nType: $connection_type\nIP: $ip"