From d39a7aaa2902f20fde834c463851d845a20b084d Mon Sep 17 00:00:00 2001 From: caley <195605706+cqley@users.noreply.github.com> Date: Wed, 22 Jul 2026 01:56:55 +0200 Subject: changing folder name to from mdls to modules --- nixos/modules/gms/dayz.nix | 1808 ++++++++++++++++++++++++++++++++++++++++++++ nixos/modules/gms/mc.nix | 80 ++ 2 files changed, 1888 insertions(+) create mode 100644 nixos/modules/gms/dayz.nix create mode 100644 nixos/modules/gms/mc.nix (limited to 'nixos/modules/gms') diff --git a/nixos/modules/gms/dayz.nix b/nixos/modules/gms/dayz.nix new file mode 100644 index 0000000..128a10c --- /dev/null +++ b/nixos/modules/gms/dayz.nix @@ -0,0 +1,1808 @@ +{ config, pkgs, ... }: + +let + dayzDir = "${config.home.homeDirectory}/.local/share/Steam/steamapps/compatdata/221100/pfx/drive_c/users/steamuser/Documents/DayZ"; +in +{ + home.packages = [ (pkgs.writeShellApplication { + name = "meowz"; + runtimeInputs = with pkgs; [ curl jq fzf steamcmd ]; + excludeShellChecks = [ "SC2155" "SC2162" "SC2207" "SC2086" "SC2178" "SC2128" ]; + text = '' + +config="$HOME/.config/dayz" +favfile="$config/favorites" +logfile="$config/last_launch.log" +steamapps="$HOME/.local/share/Steam/steamapps" +workshop="$steamapps/workshop/content/221100" +d=$'\x1f' + +mkdir -p "$config" +touch "$favfile" +sed -i '/^[[:space:]]*$/d' "$favfile" +awk -F"$d" 'NF==4' "$favfile" > "$favfile.tmp" && mv "$favfile.tmp" "$favfile" + +log() { printf '%s\n' "$*"; } +err() { printf '%s\n' "$*" >&2; } + +api() { + curl -sg -A "mozilla" "https://api.battlemetrics.com$1" +} + +fetch_servers() { + local path="/servers?filter[game]=dayz&page[size]=100$1" + local pages=0 + while [ -n "$path" ] && [ "$pages" -lt 4 ]; do + local resp=$(api "$path") + echo "$resp" | jq -e . >/dev/null 2>&1 || break + echo "$resp" | jq -r '.data[]? | "\(.id)|\(.attributes.ip):\(.attributes.port)|\(.attributes.name) [\(.attributes.players)/\(.attributes.maxPlayers)]"' + path=$(echo "$resp" | jq -r '.links.next // empty' | sed 's|.*battlemetrics.com||') + pages=$((pages + 1)) + done +} + +if [ "''${1:-}" = "--fetch" ]; then + fetch_servers "''${2:+&filter[search]=$2}" + exit 0 +fi + +steamuser="" +[ -f "$config/steamuser" ] && steamuser=$(cat "$config/steamuser") +if [ -z "$steamuser" ]; then + read -p "steam username: " steamuser + echo "$steamuser" > "$config/steamuser" +fi + +steampass="" +[ -f "$config/steampass" ] && steampass=$(cat "$config/steampass") +if [ -z "$steampass" ]; then + read -rsp "steam password (stored in plaintext, blank to skip caching): " steampass + echo + if [ -n "$steampass" ]; then + (umask 177; echo "$steampass" > "$config/steampass") + fi +fi + +loginmarker="$config/steam_authenticated" + +get_mods_by_id() { + api "/servers/$1" | jq -r '.data?.attributes?.details?.modIds[]? // empty' | paste -sd, - +} + +get_mods() { + local ip="$1" port="$2" + local m=$(curl -s "https://dayzsalauncher.com/api/v1/server/$ip:$port" | jq -r '.result?.mods[]?.steamWorkshopId // empty' | paste -sd, -) + if [ -z "$m" ]; then + local id=$(api "/servers?filter[game]=dayz&filter[search]=$ip:$port" | jq -r '.data[0]?.id // empty') + [ -n "$id" ] && m=$(get_mods_by_id "$id") + fi + echo "$m" +} + +download_mods() { + local mods=($(echo "$1" | tr ',' '\n')) + [ "''${#mods[@]}" -eq 0 ] && return 0 + + touch "$config/blacklist" + local missing=() + for mod in "''${mods[@]}"; do + grep -qx "$mod" "$config/blacklist" && continue + find "$workshop/$mod" -mindepth 1 2>/dev/null | grep -q . || missing+=("$mod") + done + [ "''${#missing[@]}" -eq 0 ] && { log "mods already present"; return 0; } + + local runner="steamcmd" + command -v steamcmd >/dev/null 2>&1 || { err "steamcmd not found"; return 1; } + + mods=("''${missing[@]}") + local cmds="" + for mod in "''${mods[@]}"; do + cmds="$cmds +workshop_download_item 221100 $mod" + done + + if pgrep -x steam >/dev/null; then + log "closing steam..." + steam -shutdown + while pgrep -x steam >/dev/null; do sleep 1; done + fi + + log "downloading mods..." + local attempt=1 + while [ "$attempt" -le 4 ]; do + [ "$attempt" -gt 1 ] && log "retry $attempt/4, ''${#mods[@]} mods" + local out + local login_args=("$steamuser") + if [ ! -f "$loginmarker" ] && [ -n "$steampass" ]; then + login_args=("$steamuser" "$steampass") + fi + out=$($runner +@sSteamCmdForcePlatformType linux -forceipv4 +login "''${login_args[@]}" $cmds +quit | tee /dev/tty) || true + + if echo "$out" | grep -q "Waiting for user info"; then + touch "$loginmarker" + fi + if echo "$out" | grep -q "FAILED"; then + rm -f "$loginmarker" + fi + + if echo "$out" | grep -q "Invalid Password"; then + err "wrong password, clearing cache" + rm -f "$config/steampass" + steampass="" + fi + + local failed=() + for mod in "''${mods[@]}"; do + if echo "$out" | grep -q "Success. Downloaded item $mod "; then + continue + fi + if echo "$out" | grep -qE "Download item $mod failed \((Access Denied|No match|File Not Found)\)"; then + err "mod $mod unavailable, blacklisting" + grep -qx "$mod" "$config/blacklist" || echo "$mod" >> "$config/blacklist" + continue + fi + failed+=("$mod") + done + + [ "''${#failed[@]}" -eq 0 ] && { log "mods downloaded"; return 0; } + + mods=("''${failed[@]}") + cmds="" + for mod in "''${mods[@]}"; do + cmds="$cmds +workshop_download_item 221100 $mod" + done + attempt=$((attempt + 1)) + sleep 3 + done + + err "failed to download: ''${mods[*]}" + return 1 +} + +launch() { + local ip="$1" port="$2" mods="$3" mod_arg="" + + if [ -z "$ip" ] || [ -z "$port" ]; then + err "invalid ip/port" + return 1 + fi + + log "verifying server..." + local verify + verify=$(api "/servers?filter[game]=dayz&filter[search]=$ip:$port" | jq -r --arg ip "$ip" --arg port "$port" '.data[]? | select(.attributes.ip == $ip and (.attributes.port | tostring) == $port) | "\(.attributes.name) [\(.attributes.players)/\(.attributes.maxPlayers)]"' | head -n 1) + if [ -n "$verify" ]; then + log "found: $verify" + else + err "server not found on battlemetrics, connecting anyway" + fi + + if [ -z "$mods" ]; then + log "no mod list found, may still require mods" + else + log "downloading mods..." + download_mods "$mods" || err "some mods failed, launching anyway" + for m in $(echo "$mods" | tr ',' '\n'); do + [ -z "$m" ] && continue + local folder=$(find "$workshop/$m" -maxdepth 1 -type d -name "@*" 2>/dev/null | head -n 1) + [ -z "$folder" ] && folder="$workshop/$m" + find "$folder" -iname "*.pbo" 2>/dev/null | grep -q . || { err "missing pbo for $m, skipping"; continue; } + mod_arg="$mod_arg;z:''${folder//\//\\}" + done + mod_arg="''${mod_arg#;}" + [ -n "$mod_arg" ] && mod_arg="-mod=$mod_arg" + sleep 3 + fi + + echo "$(date '+%F %T') connect=$ip:$port $mod_arg" >> "$logfile" + + if ! pgrep -x steam >/dev/null; then + log "starting steam..." + if [ ! -f "$loginmarker" ]; then + if [ -n "$steampass" ]; then + steam -login "$steamuser" "$steampass" >>"$config/steam.log" 2>&1 & disown + else + steam -login "$steamuser" >>"$config/steam.log" 2>&1 & disown + fi + else + steam >>"$config/steam.log" 2>&1 & disown + fi + while ! pgrep -x steam >/dev/null; do sleep 1; done + sleep 5 + fi + + log "connecting to $ip:$port..." + if [ -n "$mod_arg" ]; then + steam -applaunch 221100 -noLauncher "-connect=$ip" "-port=$port" "$mod_arg" >>"$config/steam.log" 2>&1 + else + steam -applaunch 221100 -noLauncher "-connect=$ip" "-port=$port" >>"$config/steam.log" 2>&1 + fi +} + +pick_server() { + fzf --prompt="server> " --delimiter="|" --with-nth=3.. --layout=reverse \ + --disabled --ansi \ + --bind "start:reload:$0 --fetch" \ + --bind "change:reload:sleep 0.4; $0 --fetch {q}" +} + +save_favorite() { + local ip="$1" port="$2" name="$3" + if grep -qF "$ip$d$port$d" "$favfile"; then + err "already saved" + return + fi + local mods=$(get_mods "$ip" "$port") + printf "%s%s%s%s%s%s%s\n" "$ip" "$d" "$port" "$d" "$mods" "$d" "$name" >> "$favfile" + log "saved $name" +} + +show_favorites() { + grep -vE '^[[:space:]]*$' "$favfile" | fzf --prompt="fav> " --delimiter="$d" --with-nth=4 --layout=reverse +} + +while true; do + action=$(printf "favorites\nbrowse\nadd manual\nremove\nrefresh mods\nquit\n" | fzf --prompt="dayz> " --layout=reverse) + + case "$action" in + browse) + selection=$(pick_server) + [ -z "$selection" ] && continue + id=$(echo "$selection" | cut -d'|' -f1) + ip_port=$(echo "$selection" | cut -d'|' -f2) + name=$(echo "$selection" | cut -d'|' -f3- | sed 's/ \[[0-9]*\/[0-9]*\]$//') + ip=''${ip_port%%:*} + port=''${ip_port##*:} + confirm=$(printf "play\nsave to favorites\n" | fzf --prompt="$name> " --layout=reverse) + case "$confirm" in + play) mods=$(get_mods_by_id "$id"); launch "$ip" "$port" "$mods"; exit 0 ;; + "save to favorites") save_favorite "$ip" "$port" "$name"; show_favorites ;; + esac + ;; + favorites) + selection=$(show_favorites) + [ -z "$selection" ] && continue + ip=$(echo "$selection" | cut -d"$d" -f1) + port=$(echo "$selection" | cut -d"$d" -f2) + mods=$(echo "$selection" | cut -d"$d" -f3) + launch "$ip" "$port" "$mods" + exit 0 + ;; + "add manual") + read -p "ip: " ip + read -p "port: " port + read -p "name: " name + save_favorite "$ip" "$port" "$name" + show_favorites + ;; + remove) + selection=$(show_favorites) + [ -z "$selection" ] && continue + grep -vF "$selection" "$favfile" | grep -vE '^[[:space:]]*$' > "$favfile.tmp" && mv "$favfile.tmp" "$favfile" + show_favorites + ;; + "refresh mods") + selection=$(show_favorites) + [ -z "$selection" ] && continue + ip=$(echo "$selection" | cut -d"$d" -f1) + port=$(echo "$selection" | cut -d"$d" -f2) + name=$(echo "$selection" | cut -d"$d" -f4) + mods=$(get_mods "$ip" "$port") + grep -vF "$selection" "$favfile" | grep -vE '^[[:space:]]*$' > "$favfile.tmp" && mv "$favfile.tmp" "$favfile" + printf "%s%s%s%s%s%s%s\n" "$ip" "$d" "$port" "$d" "$mods" "$d" "$name" >> "$favfile" + show_favorites + ;; + quit|"") break ;; + esac +done + ''; + }) ]; + + xdg.desktopEntries.meowz = { + name = "MeowZ"; + comment = "dayz server launcher"; + exec = "kitty --hold -e meowz"; + icon = "applications-games"; + terminal = false; + categories = [ "Game" ]; + }; + + home.file."${dayzDir}/DayZ.cfg".text = '' + language="English"; + adapter=-1; + 3D_Performance=57692; + Resolution_Bpp=32; + WinX=0; + WinY=0; + WindowWidth=1920; + WindowHeight=1080; + MSAA=0; + PostFX=0; + VSync=1; + FXAO=0; + AToC=0; + AnisoFilter=4; + TerrainDetail=2; + FXAA=0; + refreshMode=200; + maxGPUToRenderFrames=1; + ''; + + home.file."${dayzDir}/steamuser_settings.DayZProfile".text = '' + version=1; + blood=1; + singleVoice=0; + gamma=1; + lastMPServer=""; + lastMPServerName=""; + lastMPMission=""; + inputVersion=1; + perspective=1; + trackIR=1; + freeTrack=1; + mouseSmoothing=0; + maxSamplesPlayed=96; + vonInputMode=0; + TexQuality=1; + WaterQuality=1; + tripleHead=0; + showTitles=1; + vehicleFreelook=0; + pauseMode=0; + shadowQuality=1; + headBob=0; + fov=0.95993; + sceneComplexity=150000; + shadowZDistance=80; + viewDistance=1200; + preferredObjectViewDistance=1200; + terrainGrid=12.5; + volumeMaster=5; + volumeCD=0.5; + volumeFX=4; + volumeSpeech=5; + volumeVoN=10; + vonRecThreshold=0.029999999; + brightness=1; + uiTopLeftX=0.12500001; + uiTopLeftY=0; + uiBottomRightX=0.875; + uiBottomRightY=1; + IGUIScale=0.55000001; + showHUD=1; + hudBrightness=1.0; + showCrosshair=0; + showQuickbar=1; + showVehicleHUD=1; + showServerInfo=0; + ''; + + home.file."${dayzDir}/steamuser.dayz_preset_User.xml".text = '' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ''; +} diff --git a/nixos/modules/gms/mc.nix b/nixos/modules/gms/mc.nix new file mode 100644 index 0000000..d8c6734 --- /dev/null +++ b/nixos/modules/gms/mc.nix @@ -0,0 +1,80 @@ +{ config, pkgs, ... }: + +{ + home.packages = [ pkgs.prismlauncher ]; + + home.file.".local/share/PrismLauncher/prismlauncher.cfg" = { + text = pkgs.lib.generators.toINI {} { + General = { + ApplicationTheme = "dark"; + AutoCloseConsole = false; + AutomaticJavaDownload = false; + AutomaticJavaSwitch = true; + CatFit = "fit"; + CatOpacity = 100; + CentralModsDir = "mods"; + CloseAfterLaunch = false; + ConfigVersion = "1.3"; + ConsoleFont = "DejaVu Sans Mono"; + ConsoleFontSize = 11; + ConsoleMaxLines = 100000; + ConsoleOverflowStop = true; + DownloadsDir = "/home/cat/Downloads"; + DownloadsDirWatchRecursive = false; + EnableFeralGamemode = false; + EnableMangoHud = false; + Env = "{}"; + FallbackMRBlockedMods = 2; + IconTheme = "OSX"; + IconsDir = "icons"; + IgnoreJavaCompatibility = false; + IgnoreJavaWizard = false; + InstRenamingMode = "AskEverytime"; + InstSortMode = "Name"; + InstanceDir = "instances"; + JavaArchitecture = "64"; + JavaDir = "java"; + JavaPath = "/nix/store/55mw2ly3dxh5008li72rx6ilc75hgvr0-openjdk-8u502-b01/bin/java"; + Language = "en_US"; + LaunchMaximized = false; + LowMemWarning = true; + MaxMemAlloc = 6016; + MinMemAlloc = 2048; + MinecraftWinHeight = 480; + MinecraftWinWidth = 854; + ModDependenciesDisabled = false; + ModMetadataDisabled = false; + MoveModsFromDownloadsDir = true; + NumberOfConcurrentDownloads = 6; + NumberOfConcurrentTasks = 10; + NumberOfManualRetries = 1; + OnlineFixes = false; + PastebinType = 3; + PermGen = 128; + ProxyAddr = "127.0.0.1"; + ProxyPort = 8080; + ProxyType = "None"; + QuitAfterGameStop = false; + RecordGameTime = true; + RequestTimeout = 60; + ShowConsole = false; + ShowConsoleOnError = true; + ShowGameTime = true; + ShowGameTimeWithoutDays = false; + ShowGlobalGameTime = true; + ShowModIncompat = false; + SkinsDir = "skins"; + SkipModpackUpdatePrompt = false; + StatusBarVisible = false; + TheCat = false; + ToolbarsLocked = true; + UseDiscreteGpu = false; + UseNativeGLFW = false; + UseNativeOpenAL = false; + UseZink = false; + UserAskedAboutAutomaticJavaDownload = true; + }; + }; + force = true; + }; +} -- cgit v1.3.1