diff --git a/.gitignore b/.gitignore index 700671828..a70d22427 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ locale/ /gameshell* game shell* boxes-data.awk +*.img diff --git a/backup_disk.sh b/backup_disk.sh new file mode 100755 index 000000000..f96eb5a42 --- /dev/null +++ b/backup_disk.sh @@ -0,0 +1,22 @@ +#!/usr/bin/bash +ID_MISSION=$1 + +mkdir -p "/var/www/html/GameShell/missions/lvm/00_shared/data/$ID_MISSION/" + +umount /dev/esdea/ouskelcoule +umount /dev/esdea/douskelpar +umount /dev/esdebe/grandflac + +lvchange -an /dev/esdea/ouskelcoule +lvchange -an /dev/esdea/douskelpar +lvchange -an /dev/esdebe/grandflac + +vgchange -an esdea +vgchange -an esdebe +vgchange -an esdece + +vgexport esdea +vgexport esdebe +vgexport esdece + +zip -jr /var/www/html/GameShell/missions/lvm/00_shared/data/$ID_MISSION/disks.zip /var/www/html/GameShell/missions/lvm/00_shared/data/00/disk*.img diff --git a/missions/default.idx b/missions/default.idx index 5fe59affd..0df67bb06 100644 --- a/missions/default.idx +++ b/missions/default.idx @@ -1,5 +1,4 @@ # default Gameshell missions order - basic/default.idx misc/01_cal_nostradamus intermediate/01_alias_la @@ -21,4 +20,5 @@ finding_files_maze/05_find_xargs_grep pipes_merchant_stall/default.idx misc/03_tr_caesar_shift + lvm/default.idx FINAL_MISSION diff --git a/missions/lvm/00_shared/data/00/.tokeep b/missions/lvm/00_shared/data/00/.tokeep new file mode 100644 index 000000000..e69de29bb diff --git a/missions/lvm/00_shared/data/01/disks.zip b/missions/lvm/00_shared/data/01/disks.zip new file mode 100644 index 000000000..9e6816e94 Binary files /dev/null and b/missions/lvm/00_shared/data/01/disks.zip differ diff --git a/missions/lvm/00_shared/data/02/disks.zip b/missions/lvm/00_shared/data/02/disks.zip new file mode 100644 index 000000000..751f6ccbf Binary files /dev/null and b/missions/lvm/00_shared/data/02/disks.zip differ diff --git a/missions/lvm/00_shared/data/03/disks.zip b/missions/lvm/00_shared/data/03/disks.zip new file mode 100644 index 000000000..7a7a3529f Binary files /dev/null and b/missions/lvm/00_shared/data/03/disks.zip differ diff --git a/missions/lvm/00_shared/data/04/disks.zip b/missions/lvm/00_shared/data/04/disks.zip new file mode 100644 index 000000000..158e5c267 Binary files /dev/null and b/missions/lvm/00_shared/data/04/disks.zip differ diff --git a/missions/lvm/00_shared/data/05/disks.zip b/missions/lvm/00_shared/data/05/disks.zip new file mode 100644 index 000000000..5a50602f2 Binary files /dev/null and b/missions/lvm/00_shared/data/05/disks.zip differ diff --git a/missions/lvm/00_shared/data/06/disks.zip b/missions/lvm/00_shared/data/06/disks.zip new file mode 100644 index 000000000..0d84ce0e0 Binary files /dev/null and b/missions/lvm/00_shared/data/06/disks.zip differ diff --git a/missions/lvm/00_shared/data/07/disks.zip b/missions/lvm/00_shared/data/07/disks.zip new file mode 100644 index 000000000..797c72ab0 Binary files /dev/null and b/missions/lvm/00_shared/data/07/disks.zip differ diff --git a/missions/lvm/00_shared/data/08/disks.zip b/missions/lvm/00_shared/data/08/disks.zip new file mode 100644 index 000000000..8727431ed Binary files /dev/null and b/missions/lvm/00_shared/data/08/disks.zip differ diff --git a/missions/lvm/00_shared/data/09/disks.zip b/missions/lvm/00_shared/data/09/disks.zip new file mode 100644 index 000000000..f3b388af7 Binary files /dev/null and b/missions/lvm/00_shared/data/09/disks.zip differ diff --git a/missions/lvm/00_shared/data/10/disks.zip b/missions/lvm/00_shared/data/10/disks.zip new file mode 100644 index 000000000..dde56d9dd Binary files /dev/null and b/missions/lvm/00_shared/data/10/disks.zip differ diff --git a/missions/lvm/00_shared/data/11/disks.zip b/missions/lvm/00_shared/data/11/disks.zip new file mode 100644 index 000000000..2effe2a5c Binary files /dev/null and b/missions/lvm/00_shared/data/11/disks.zip differ diff --git a/missions/lvm/00_shared/data/12/disks.zip b/missions/lvm/00_shared/data/12/disks.zip new file mode 100644 index 000000000..786da8db6 Binary files /dev/null and b/missions/lvm/00_shared/data/12/disks.zip differ diff --git a/missions/lvm/00_shared/data/13/disks.zip b/missions/lvm/00_shared/data/13/disks.zip new file mode 100644 index 000000000..0b6e7d416 Binary files /dev/null and b/missions/lvm/00_shared/data/13/disks.zip differ diff --git a/missions/lvm/00_shared/data/14/disks.zip b/missions/lvm/00_shared/data/14/disks.zip new file mode 100644 index 000000000..295946633 Binary files /dev/null and b/missions/lvm/00_shared/data/14/disks.zip differ diff --git a/missions/lvm/00_shared/data/15/disks.zip b/missions/lvm/00_shared/data/15/disks.zip new file mode 100644 index 000000000..1753d25df Binary files /dev/null and b/missions/lvm/00_shared/data/15/disks.zip differ diff --git a/missions/lvm/00_shared/fish_generator.sh b/missions/lvm/00_shared/fish_generator.sh new file mode 100644 index 000000000..871cd4087 --- /dev/null +++ b/missions/lvm/00_shared/fish_generator.sh @@ -0,0 +1,66 @@ +#!/usr/bin/env bash + +gen_fishes() { + local count="${1:-}" + local dir="${2:-rivieres}" + + # Basic checks + if [[ -z "$count" || ! "$count" =~ ^[0-9]+$ || "$count" -le 0 ]]; then + echo "$(eval_gettext "Usage: gen_fishes [dir]")" + return 1 + fi + + mkdir -p "$dir" + + # Available species (just for choosing ASCII art) + local -a species=(spike catfish roach) + + # Generate exactly files total + local i sp file + for ((i=1; i<=count; i++)); do + sp="${species[RANDOM % ${#species[@]}]}" + file="$dir/poisson_$(printf '%03d' "$i").fish" + case "$sp" in + spike) cat > "$file" <<'EOF' + _______ + / / + /'''''\/ _ +/ @ \/ | +> _ | +\ <_) /\_| + \...../\ + \\____/ +EOF + ;; + catfish) cat > "$file" <<'EOF' + _.'.__ + _.' . +':'. .'' __ __ . + '.:._ ./ _ '' "-'.__ +.'''-: """-._ | . "-"._ + '. . "._.' " + '. "-.___ . .' . :o'. + | .---- . . .' ( + '| ----. ' ,.._ _-' + .' .--- |."" .-:;.. _____.----' + | .-"""" | ' + .' _' .' _' + |_.-' -cat- '-.' +EOF + ;; + roach) cat > "$file" <<'EOF' + /`·.¸ + /¸...¸`:· + ¸.·´ ¸ `·.¸.·´) +: © ):´; ¸ { + `·.¸ `· ¸.·´\`·¸) + `\\´´\¸.·´ +EOF + ;; + esac + done + + echo "$(eval_gettext "🐟 \$count fish created in '\$dir' (random ASCII per file).")" +} + +gen_fishes "$@" diff --git a/missions/lvm/00_shared/gshrc b/missions/lvm/00_shared/gshrc new file mode 100644 index 000000000..461872129 --- /dev/null +++ b/missions/lvm/00_shared/gshrc @@ -0,0 +1,24 @@ + +# Define a function "danger" allowing users to call sudo commandes +# this is necessary because gsh try to prevent usage of sudo by default +danger () { + if [ "$1" = "sudo" ]; then + shift + /usr/bin/sudo "$@" + else + command "$@" + fi +} + +# Img disks paths +export DISK_1_PATH="$MISSION_DIR/data/disk1.img" +export DISK_2_PATH="$MISSION_DIR/data/disk2.img" + +# Esdea and Esdebe physical volumes +export SDBA="/dev/gsh_sda" +export SDBB="/dev/gsh_sdb" + +# Loop devices created in the 00_shared mission +export LOOP1_PATH="/dev/gsh_lvm_loop1" +export LOOP2_PATH="/dev/gsh_lvm_loop2" + diff --git a/missions/lvm/00_shared/i18n/en.po b/missions/lvm/00_shared/i18n/en.po new file mode 100644 index 000000000..7daa1c6be --- /dev/null +++ b/missions/lvm/00_shared/i18n/en.po @@ -0,0 +1,992 @@ +# English translations for PACKAGE package. +# Copyright (C) 2025 THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-09-23 12:09+0200\n" +"PO-Revision-Date: 2025-09-23 12:09+0200\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: en_US\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#, sh-format +msgid "" +"Dummy mission '$DUMMY_MISSION' is required for mission $MISSION_NB " +"($MISSION_NAME)." +msgstr "" +"Dummy mission '$DUMMY_MISSION' is required for mission $MISSION_NB " +"($MISSION_NAME)." + +#, sh-format +msgid "" +"Loop devices $LOOP1_PATH and $LOOP2_PATH are required for mission " +"$MISSION_NB ($MISSION_NAME)." +msgstr "" +"Loop devices $LOOP1_PATH and $LOOP2_PATH are required for mission " +"$MISSION_NB ($MISSION_NAME)." + +#, sh-format +msgid "$GSH_HOME/Royaume" +msgstr "$GSH_HOME/Royaume" + +#, sh-format +msgid "Offices" +msgstr "Offices" + +#, sh-format +msgid "Unique Stamp Office" +msgstr "Unique Stamp Office" + +#, sh-format +msgid "Counter" +msgstr "Counter" + +#, sh-format +msgid "Orientation" +msgstr "Orientation" + +#, sh-format +msgid "Counter-counter" +msgstr "Counter-counter" + +#, sh-format +msgid "Return Form" +msgstr "Return Form" + +#, sh-format +msgid "Return Service" +msgstr "Return Service" + +#, sh-format +msgid "Return to beginning" +msgstr "Return to beginning" + +#, sh-format +msgid "Central Administration" +msgstr "Central Administration" + +#, sh-format +msgid "Unique counter" +msgstr "Unique counter" + +#, sh-format +msgid "King's Hotel" +msgstr "King's Hotel" + +#, sh-format +msgid "Antechamber" +msgstr "Antechamber" + +#, sh-format +msgid "Waiting Room" +msgstr "Waiting Room" + +#, sh-format +msgid "return to counter" +msgstr "return to counter" + +#, sh-format +msgid "" +"🖋️ Generating lore for the Kingdom of Bordereau VI the Stamped (edition " +"without villages)..." +msgstr "" +"🖋️ Generating lore for the Kingdom of Bordereau VI the Stamped (edition " +"without villages)..." + +#, sh-format +msgid "$GSH_HOME/Kingdom" +msgstr "$GSH_HOME/Kingdom" + +#, sh-format +msgid "Castle" +msgstr "Castle" + +#, sh-format +msgid "Main Tower" +msgstr "Main Tower" + +#, sh-format +msgid "First Floor" +msgstr "First Floor" + +#, sh-format +msgid "Second Floor" +msgstr "Second Floor" + +#, sh-format +msgid "Tower Summit" +msgstr "Tower Summit" + +#, sh-format +msgid "Objects" +msgstr "Objects" + +#, sh-format +msgid "Concierge's Journal.txt" +msgstr "Concierge's Journal.txt" + +#, sh-format +msgid "" +"Day 34: someone moved the audience hourglass. Time is now ahead of itself." +msgstr "" +"Day 34: someone moved the audience hourglass. Time is now ahead of itself." + +#, sh-format +msgid "Royal Stamp (unicorn wood).txt" +msgstr "Royal Stamp (unicorn wood).txt" + +#, sh-format +msgid "Usage: affix. Side effect: instant respect." +msgstr "Usage: affix. Side effect: instant respect." + +#, sh-format +msgid "Key to the key drawer.txt" +msgstr "Key to the key drawer.txt" + +#, sh-format +msgid "Only opens keys. For drawers, provide another form." +msgstr "Only opens keys. For drawers, provide another form." + +#, sh-format +msgid "Parade Paraph (too heavy to serve).txt" +msgstr "Parade Paraph (too heavy to serve).txt" + +#, sh-format +msgid "Ceremonial object. Appears more official than the law." +msgstr "Ceremonial object. Appears more official than the law." + +#, sh-format +msgid "Official Portraits" +msgstr "Official Portraits" + +#, sh-format +msgid "Bordereau VI the Stamped.txt" +msgstr "Bordereau VI the Stamped.txt" + +#, sh-format +msgid "" +"King, lover of clear procedures and opaque stamps. Motto: \"Who stamps " +"reigns.\"" +msgstr "" +"King, lover of clear procedures and opaque stamps. Motto: \"Who stamps " +"reigns.\"" + +#, sh-format +msgid "Great Chancellery" +msgstr "Great Chancellery" + +#, sh-format +msgid "Stamps Office" +msgstr "Stamps Office" + +#, sh-format +msgid "Ministry of Papers" +msgstr "Ministry of Papers" + +#, sh-format +msgid "Forms Directorate" +msgstr "Forms Directorate" + +#, sh-format +msgid "Duplicate Service" +msgstr "Duplicate Service" + +#, sh-format +msgid "Ministry of Bridges and Roads" +msgstr "Ministry of Bridges and Roads" + +#, sh-format +msgid "Mounting Office" +msgstr "Mounting Office" + +#, sh-format +msgid "Ministry of Rumors" +msgstr "Ministry of Rumors" + +#, sh-format +msgid "Whispers Cabinet" +msgstr "Whispers Cabinet" + +#, sh-format +msgid "Court of Accounts and Half Accounts" +msgstr "Court of Accounts and Half Accounts" + +#, sh-format +msgid "Registry" +msgstr "Registry" + +#, sh-format +msgid "Kingdom Prefecture" +msgstr "Kingdom Prefecture" + +#, sh-format +msgid "Counter A-M" +msgstr "Counter A-M" + +#, sh-format +msgid "Counter N-Z" +msgstr "Counter N-Z" + +#, sh-format +msgid "Archives" +msgstr "Archives" + +#, sh-format +msgid "Shelving" +msgstr "Shelving" + +#, sh-format +msgid "A to Z" +msgstr "A to Z" + +#, sh-format +msgid "Commissions" +msgstr "Commissions" + +#, sh-format +msgid "Commission 1" +msgstr "Commission 1" + +#, sh-format +msgid "Commission 2" +msgstr "Commission 2" + +#, sh-format +msgid "Commission 3" +msgstr "Commission 3" + +#, sh-format +msgid "Number 0001.txt" +msgstr "Number 0001.txt" + +#, sh-format +msgid "You will be called after number 0000 (when it exists)." +msgstr "You will be called after number 0000 (when it exists)." + +#, sh-format +msgid "Internal Regulations.md" +msgstr "Internal Regulations.md" + +#, sh-format +msgid "Any request must be stamped before being submitted to be stamped." +msgstr "Any request must be stamped before being submitted to be stamped." + +#, sh-format +msgid "" +"Stamps are not to be stamped, except in case of emergency (form \"URG-URG\")." +msgstr "" +"Stamps are not to be stamped, except in case of emergency (form \"URG-URG\")." + +#, sh-format +msgid "Employees must soothe the feathered stamp every morning." +msgstr "Employees must soothe the feathered stamp every morning." + +#, sh-format +msgid "Circular Procedure n° ∞.md" +msgstr "Circular Procedure n° ∞.md" + +#, sh-format +msgid "" +"Step 1: consult Step 2. Step 2: consult Step 1. (Stamp required at each " +"consultation.)" +msgstr "" +"Step 1: consult Step 2. Step 2: consult Step 1. (Stamp required at each " +"consultation.)" + +#, sh-format +msgid "Whisper of the day.txt" +msgstr "Whisper of the day.txt" + +#, sh-format +msgid "They say the pile of files is taller seen from below." +msgstr "They say the pile of files is taller seen from below." + +#, sh-format +msgid "Half-receipt (to complete).txt" +msgstr "Half-receipt (to complete).txt" + +#, sh-format +msgid "Please present the other half to prove the existence of this one." +msgstr "Please present the other half to prove the existence of this one." + +#, sh-format +msgid "Index (partial).txt" +msgstr "Index (partial).txt" + +#, sh-format +msgid "" +"Apricots (no); Certificates (yes); Warnings (maybe). See also: Zebras (filed " +"under A by mistake)." +msgstr "" +"Apricots (no); Certificates (yes); Warnings (maybe). See also: Zebras (filed " +"under A by mistake)." + +#, sh-format +msgid "Plastic plant (badge holder).txt" +msgstr "Plastic plant (badge holder).txt" + +#, sh-format +msgid "Seniority: 12 years. Acquired rights: priority at the counter." +msgstr "Seniority: 12 years. Acquired rights: priority at the counter." + +#, sh-format +msgid "Quantum stamp.txt" +msgstr "Quantum stamp.txt" + +#, sh-format +msgid "" +"Affixes and removes the seal simultaneously until observed by a superior." +msgstr "" +"Affixes and removes the seal simultaneously until observed by a superior." + +#, sh-format +msgid "Bottomless inkwell.txt" +msgstr "Bottomless inkwell.txt" + +#, sh-format +msgid "Structural deficit. Voted every year by acclamation." +msgstr "Structural deficit. Voted every year by acclamation." + +#, sh-format +msgid "Random forms dispenser.txt" +msgstr "Random forms dispenser.txt" + +#, sh-format +msgid "Spits out a different CERFA with each swear word. Doesn't take change." +msgstr "Spits out a different CERFA with each swear word. Doesn't take change." + +#, sh-format +msgid "Photocopy of an unfindable original copy.txt" +msgstr "Photocopy of an unfindable original copy.txt" + +#, sh-format +msgid "Authenticated by the absence of the original." +msgstr "Authenticated by the absence of the original." + +#, sh-format +msgid "Vertical bubble level.txt" +msgstr "Vertical bubble level.txt" + +#, sh-format +msgid "Indicates the moral inclination of the project." +msgstr "Indicates the moral inclination of the project." + +#, sh-format +msgid "Whispering microphone.txt" +msgstr "Whispering microphone.txt" + +#, sh-format +msgid "Repeats \"apparently\" with authority." +msgstr "Repeats \"apparently\" with authority." + +#, sh-format +msgid "Digital abacus (unplugged).txt" +msgstr "Digital abacus (unplugged).txt" + +#, sh-format +msgid "Optimizes invisible savings." +msgstr "Optimizes invisible savings." + +#, sh-format +msgid "Ticket regurgitator automaton.txt" +msgstr "Ticket regurgitator automaton.txt" + +#, sh-format +msgid "Returns a ticket older than yours." +msgstr "Returns a ticket older than yours." + +#, sh-format +msgid "Queue line snake rope.txt" +msgstr "Queue line snake rope.txt" + +#, sh-format +msgid "Lengthens as soon as you think you're reaching the goal." +msgstr "Lengthens as soon as you think you're reaching the goal." + +#, sh-format +msgid "Schrödinger's file (filed and lost).txt" +msgstr "Schrödinger's file (filed and lost).txt" + +#, sh-format +msgid "Exists as long as no one consults it." +msgstr "Exists as long as no one consults it." + +#, sh-format +msgid "Member list.txt" +msgstr "Member list.txt" + +#, sh-format +msgid "Dame Pénélope de la Punaise (president)" +msgstr "Dame Pénélope de la Punaise (president)" + +#, sh-format +msgid "Sire Fernand du Parapheur (vice-president)" +msgstr "Sire Fernand du Parapheur (vice-president)" + +#, sh-format +msgid "Master Loris des Liasses (rapporteur)" +msgstr "Master Loris des Liasses (rapporteur)" + +#, sh-format +msgid "Session bell (mute).txt" +msgstr "Session bell (mute).txt" + +#, sh-format +msgid "Signals the end of debate as soon as it begins." +msgstr "Signals the end of debate as soon as it begins." + +#, sh-format +msgid "Captain Clotaire du Cachet" +msgstr "Captain Clotaire du Cachet" + +#, sh-format +msgid "Demoiselle Agathe du Bordereau" +msgstr "Demoiselle Agathe du Bordereau" + +#, sh-format +msgid "Brother Nestor des Annexes" +msgstr "Brother Nestor des Annexes" + +#, sh-format +msgid "Folding chair (unfolded by decree).txt" +msgstr "Folding chair (unfolded by decree).txt" + +#, sh-format +msgid "Only folds to written injunctions." +msgstr "Only folds to written injunctions." + +#, sh-format +msgid "Stewardess Salomé de la Signature" +msgstr "Stewardess Salomé de la Signature" + +#, sh-format +msgid "Registrar Octave de l'Agrafe" +msgstr "Registrar Octave de l'Agrafe" + +#, sh-format +msgid "Sergeant Éline de la Reliure" +msgstr "Sergeant Éline de la Reliure" + +#, sh-format +msgid "Protocol stapler (without staples).txt" +msgstr "Protocol stapler (without staples).txt" + +#, sh-format +msgid "Brings together without attaching." +msgstr "Brings together without attaching." + +#, sh-format +msgid "Academy of Geo-mancy" +msgstr "Academy of Geo-mancy" + +#, sh-format +msgid "Study Secretariat" +msgstr "Study Secretariat" + +#, sh-format +msgid "Registration Office" +msgstr "Registration Office" + +#, sh-format +msgid "Retake Service" +msgstr "Retake Service" + +#, sh-format +msgid "Library of Impossible Maps" +msgstr "Library of Impossible Maps" + +#, sh-format +msgid "Contradictory Atlases Room" +msgstr "Contradictory Atlases Room" + +#, sh-format +msgid "Ground Floor" +msgstr "Ground Floor" + +#, sh-format +msgid "Moving Index" +msgstr "Moving Index" + +#, sh-format +msgid "Departments" +msgstr "Departments" + +#, sh-format +msgid "Etheric Cartography" +msgstr "Etheric Cartography" + +#, sh-format +msgid "Labs" +msgstr "Labs" + +#, sh-format +msgid "Stamp Topology" +msgstr "Stamp Topology" + +#, sh-format +msgid "Forms Geology" +msgstr "Forms Geology" + +#, sh-format +msgid "Institute of Flows and Counter-Flows" +msgstr "Institute of Flows and Counter-Flows" + +#, sh-format +msgid "Amphitheater ∮" +msgstr "Amphitheater ∮" + +#, sh-format +msgid "Observatory of Administrative Lines" +msgstr "Observatory of Administrative Lines" + +#, sh-format +msgid "Meridians Terrace" +msgstr "Meridians Terrace" + +#, sh-format +msgid "Competitions and Aggregations" +msgstr "Competitions and Aggregations" + +#, sh-format +msgid "Examination Room" +msgstr "Examination Room" + +#, sh-format +msgid "Tools Museum" +msgstr "Tools Museum" + +#, sh-format +msgid "Instruments" +msgstr "Instruments" + +#, sh-format +msgid "Student guide.md" +msgstr "Student guide.md" + +#, sh-format +msgid "Cardinal principle: every territory is a matter of paper." +msgstr "Cardinal principle: every territory is a matter of paper." + +#, sh-format +msgid "ECTS credits mean \"Echelons, Cachets, Tampons, Signatures\"." +msgstr "ECTS credits mean \"Echelons, Cachets, Tampons, Signatures\"." + +#, sh-format +msgid "Any valid map must include at least one administrative dead end." +msgstr "Any valid map must include at least one administrative dead end." + +#, sh-format +msgid "Opening hours.txt" +msgstr "Opening hours.txt" + +#, sh-format +msgid "Open on even working days, except when it's odd." +msgstr "Open on even working days, except when it's odd." + +#, sh-format +msgid "Flat atlas of the round Earth.txt" +msgstr "Flat atlas of the round Earth.txt" + +#, sh-format +msgid "Revised edition: now spheri-flat according to decree." +msgstr "Revised edition: now spheri-flat according to decree." + +#, sh-format +msgid "User manual.txt" +msgstr "User manual.txt" + +#, sh-format +msgid "To find A, look for Z, then return to A via Beta corridor." +msgstr "To find A, look for Z, then return to A via Beta corridor." + +#, sh-format +msgid "Program.md" +msgstr "Program.md" + +#, sh-format +msgid "Introduction to trace-therapy" +msgstr "Introduction to trace-therapy" + +#, sh-format +msgid "Variable geometry of moral borders" +msgstr "Variable geometry of moral borders" + +#, sh-format +msgid "Seminar: The hesitant compass" +msgstr "Seminar: The hesitant compass" + +#, sh-format +msgid "Indecisive compass.txt" +msgstr "Indecisive compass.txt" + +#, sh-format +msgid "Turns until the presence of a department head." +msgstr "Turns until the presence of a department head." + +#, sh-format +msgid "Non-commutative seal groups" +msgstr "Non-commutative seal groups" + +#, sh-format +msgid "Homotopy of validation circuits" +msgstr "Homotopy of validation circuits" + +#, sh-format +msgid "Seminar: Torus of waiting lines" +msgstr "Seminar: Torus of waiting lines" + +#, sh-format +msgid "Möbius stamp.txt" +msgstr "Möbius stamp.txt" + +#, sh-format +msgid "One side, two lines, no exit." +msgstr "One side, two lines, no exit." + +#, sh-format +msgid "Stratigraphy of annexes" +msgstr "Stratigraphy of annexes" + +#, sh-format +msgid "Metamorphism under paraph" +msgstr "Metamorphism under paraph" + +#, sh-format +msgid "Seminar: Version fossils" +msgstr "Seminar: Version fossils" + +#, sh-format +msgid "Stratified section of a file.txt" +msgstr "Stratified section of a file.txt" + +#, sh-format +msgid "Observe without disturbing the fragile \"missing pieces\" layer." +msgstr "Observe without disturbing the fragile \"missing pieces\" layer." + +#, sh-format +msgid "Self-erasing blackboard.txt" +msgstr "Self-erasing blackboard.txt" + +#, sh-format +msgid "Erases demonstrations just before the conclusion." +msgstr "Erases demonstrations just before the conclusion." + +#, sh-format +msgid "Paperwork telescope.txt" +msgstr "Paperwork telescope.txt" + +#, sh-format +msgid "Only magnifies illegible signatures." +msgstr "Only magnifies illegible signatures." + +#, sh-format +msgid "Deadline drawing board.txt" +msgstr "Deadline drawing board.txt" + +#, sh-format +msgid "Allows adding a calendar month to any natural delay." +msgstr "Allows adding a calendar month to any natural delay." + +#, sh-format +msgid "Sample subject.md" +msgstr "Sample subject.md" + +#, sh-format +msgid "Map a mobile border between two closed counters." +msgstr "Map a mobile border between two closed counters." + +#, sh-format +msgid "" +"Demonstrate the existence of a shortcut longer than the official detour." +msgstr "" +"Demonstrate the existence of a shortcut longer than the official detour." + +#, sh-format +msgid "Stamp the hypothesis, then remove it cleanly." +msgstr "Stamp the hypothesis, then remove it cleanly." + +#, sh-format +msgid "Approved cheat sheet (blank).txt" +msgstr "Approved cheat sheet (blank).txt" + +#, sh-format +msgid "To be filled only inadvertently." +msgstr "To be filled only inadvertently." + +#, sh-format +msgid "Cerfas Office" +msgstr "Cerfas Office" + +#, sh-format +msgid "CERFA 13B" +msgstr "CERFA 13B" + +#, sh-format +msgid "CERFA 13C" +msgstr "CERFA 13C" + +#, sh-format +msgid "Complaints and Complaint Requests Office" +msgstr "Complaints and Complaint Requests Office" + +#, sh-format +msgid "Example complaint (template).txt" +msgstr "Example complaint (template).txt" + +#, sh-format +msgid "Subject: complaint against the complaint form, too complaining." +msgstr "Subject: complaint against the complaint form, too complaining." + +#, sh-format +msgid "Orientation brochure.txt" +msgstr "Orientation brochure.txt" + +#, sh-format +msgid "" +"For any question, address the Counter-counter. To contest: Return Service." +msgstr "" +"For any question, address the Counter-counter. To contest: Return Service." + +#, sh-format +msgid "" +"Fill in blue. Except if you don't have blue, in which case: start over in " +"blue." +msgstr "" +"Fill in blue. Except if you don't have blue, in which case: start over in " +"blue." + +#, sh-format +msgid "Administrative hourglass set to \"in progress\".txt" +msgstr "Administrative hourglass set to \"in progress\".txt" + +#, sh-format +msgid "Never empties completely, in accordance with procedure." +msgstr "Never empties completely, in accordance with procedure." + +#, sh-format +msgid "Conditional ink pen.txt" +msgstr "Conditional ink pen.txt" + +#, sh-format +msgid "Writes only after the stamp, never before." +msgstr "Writes only after the stamp, never before." + +#, sh-format +msgid "Bottomless complaints box.txt" +msgstr "Bottomless complaints box.txt" + +#, sh-format +msgid "All claims find their downfall there." +msgstr "All claims find their downfall there." + +#, sh-format +msgid "Self-referenced form.txt" +msgstr "Self-referenced form.txt" + +#, sh-format +msgid "Please attach CERFA 13C to this CERFA 13C." +msgstr "Please attach CERFA 13C to this CERFA 13C." + +#, sh-format +msgid "Whispering megaphone.txt" +msgstr "Whispering megaphone.txt" + +#, sh-format +msgid "Amplifies indignant silences." +msgstr "Amplifies indignant silences." + +#, sh-format +msgid "Public Reception" +msgstr "Public Reception" + +#, sh-format +msgid "Ticket Distribution" +msgstr "Ticket Distribution" + +#, sh-format +msgid "Provisional Orientation" +msgstr "Provisional Orientation" + +#, sh-format +msgid "Preliminary Pre-validation" +msgstr "Preliminary Pre-validation" + +#, sh-format +msgid "Control Compliance Control" +msgstr "Control Compliance Control" + +#, sh-format +msgid "Internal Prefecture Visa" +msgstr "Internal Prefecture Visa" + +#, sh-format +msgid "Intent Stamping" +msgstr "Intent Stamping" + +#, sh-format +msgid "Verification Verification" +msgstr "Verification Verification" + +#, sh-format +msgid "Penultimate Step Counter-Validation" +msgstr "Penultimate Step Counter-Validation" + +#, sh-format +msgid "Counter No. 0" +msgstr "Counter No. 0" + +#, sh-format +msgid "Standard Administrative Path" +msgstr "Standard Administrative Path" + +#, sh-format +msgid "Instructions.txt" +msgstr "Instructions.txt" + +#, sh-format +msgid "Present the document obtained in the previous step." +msgstr "Present the document obtained in the previous step." + +#, sh-format +msgid "Motivating ceiling light.txt" +msgstr "Motivating ceiling light.txt" + +#, sh-format +msgid "Displays \"Almost done!\" upon arrival." +msgstr "Displays \"Almost done!\" upon arrival." + +#, sh-format +msgid "Imaginary number ticket.txt" +msgstr "Imaginary number ticket.txt" + +#, sh-format +msgid "Served after the real ones, before the priority ones." +msgstr "Served after the real ones, before the priority ones." + +#, sh-format +msgid "Administrative compass.txt" +msgstr "Administrative compass.txt" + +#, sh-format +msgid "Always points to the opposite counter." +msgstr "Always points to the opposite counter." + +#, sh-format +msgid "Shadow stamp.txt" +msgstr "Shadow stamp.txt" + +#, sh-format +msgid "Leaves an invisible but regulatory trace." +msgstr "Leaves an invisible but regulatory trace." + +#, sh-format +msgid "Checklist checklist.txt" +msgstr "Checklist checklist.txt" + +#, sh-format +msgid "Last item: check this checklist." +msgstr "Last item: check this checklist." + +#, sh-format +msgid "Swinging door (leads nowhere).txt" +msgstr "Swinging door (leads nowhere).txt" + +#, sh-format +msgid "Approved for back-and-forth." +msgstr "Approved for back-and-forth." + +#, sh-format +msgid "Tacit intentions form.txt" +msgstr "Tacit intentions form.txt" + +#, sh-format +msgid "To be filled without writing anything." +msgstr "To be filled without writing anything." + +#, sh-format +msgid "Protocol magnifying glass.txt" +msgstr "Protocol magnifying glass.txt" + +#, sh-format +msgid "Magnifies paperwork, reduces hope." +msgstr "Magnifies paperwork, reduces hope." + +#, sh-format +msgid "Contradictory seal.txt" +msgstr "Contradictory seal.txt" + +#, sh-format +msgid "Validates and invalidates simultaneously." +msgstr "Validates and invalidates simultaneously." + +#, sh-format +msgid "Impossible bell.txt" +msgstr "Impossible bell.txt" + +#, sh-format +msgid "Ring scheduled for next budget year." +msgstr "Ring scheduled for next budget year." + +#, sh-format +msgid "Next step" +msgstr "Next step" + +#, sh-format +msgid "Duplicate requests" +msgstr "Duplicate requests" + +#, sh-format +msgid "Final validation" +msgstr "Final validation" + +#, sh-format +msgid "next counter" +msgstr "next counter" + +#, sh-format +msgid "referral" +msgstr "referral" + +#, sh-format +msgid "transmission" +msgstr "transmission" + +#, sh-format +msgid "Stamp required" +msgstr "Stamp required" + +#, sh-format +msgid "Deposit" +msgstr "Deposit" + +#, sh-format +msgid "Prefecture validation" +msgstr "Prefecture validation" + +#, sh-format +msgid "Mandatory Academy internship" +msgstr "Mandatory Academy internship" + +#, sh-format +msgid "Bridge to the Library of Impossible Maps" +msgstr "Bridge to the Library of Impossible Maps" + +#, sh-format +msgid "Flow validation procedure" +msgstr "Flow validation procedure" + +#, sh-format +msgid "" +"✅ Kingdom of Bordereau VI the Stamped: bizarre objects, Academy of Geo-" +"mancy and administrative labyrinths created (without villages)." +msgstr "" +"✅ Kingdom of Bordereau VI the Stamped: bizarre objects, Academy of Geo-" +"mancy and administrative labyrinths created (without villages)." diff --git a/missions/lvm/00_shared/i18n/fr.po b/missions/lvm/00_shared/i18n/fr.po new file mode 100644 index 000000000..1200b4b32 --- /dev/null +++ b/missions/lvm/00_shared/i18n/fr.po @@ -0,0 +1,971 @@ +# French translations for PACKAGE package. +# Copyright (C) 2025 THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-09-23 12:09+0200\n" +"PO-Revision-Date: 2025-09-23 12:09+0200\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +#, sh-format +msgid "" +"Dummy mission '$DUMMY_MISSION' is required for mission $MISSION_NB " +"($MISSION_NAME)." +msgstr "" + +#, sh-format +msgid "" +"Loop devices $LOOP1_PATH and $LOOP2_PATH are required for mission " +"$MISSION_NB ($MISSION_NAME)." +msgstr "" + +#, sh-format +msgid "$GSH_HOME/Royaume" +msgstr "" + +#, sh-format +msgid "Offices" +msgstr "" + +#, sh-format +msgid "Unique Stamp Office" +msgstr "" + +#, sh-format +msgid "Counter" +msgstr "" + +#, sh-format +msgid "Orientation" +msgstr "" + +#, sh-format +msgid "Counter-counter" +msgstr "" + +#, sh-format +msgid "Return Form" +msgstr "" + +#, sh-format +msgid "Return Service" +msgstr "" + +#, sh-format +msgid "Return to beginning" +msgstr "" + +#, sh-format +msgid "Central Administration" +msgstr "" + +#, sh-format +msgid "Unique counter" +msgstr "" + +#, sh-format +msgid "King's Hotel" +msgstr "" + +#, sh-format +msgid "Antechamber" +msgstr "" + +#, sh-format +msgid "Waiting Room" +msgstr "" + +#, sh-format +msgid "return to counter" +msgstr "" + +#, sh-format +msgid "" +"🖋️ Generating lore for the Kingdom of Bordereau VI the Stamped (edition " +"without villages)..." +msgstr "" + +#, sh-format +msgid "$GSH_HOME/Kingdom" +msgstr "" + +#, sh-format +msgid "Castle" +msgstr "" + +#, sh-format +msgid "Main Tower" +msgstr "" + +#, sh-format +msgid "First Floor" +msgstr "" + +#, sh-format +msgid "Second Floor" +msgstr "" + +#, sh-format +msgid "Tower Summit" +msgstr "" + +#, sh-format +msgid "Objects" +msgstr "" + +#, sh-format +msgid "Concierge's Journal.txt" +msgstr "" + +#, sh-format +msgid "" +"Day 34: someone moved the audience hourglass. Time is now ahead of itself." +msgstr "" + +#, sh-format +msgid "Royal Stamp (unicorn wood).txt" +msgstr "" + +#, sh-format +msgid "Usage: affix. Side effect: instant respect." +msgstr "" + +#, sh-format +msgid "Key to the key drawer.txt" +msgstr "" + +#, sh-format +msgid "Only opens keys. For drawers, provide another form." +msgstr "" + +#, sh-format +msgid "Parade Paraph (too heavy to serve).txt" +msgstr "" + +#, sh-format +msgid "Ceremonial object. Appears more official than the law." +msgstr "" + +#, sh-format +msgid "Official Portraits" +msgstr "" + +#, sh-format +msgid "Bordereau VI the Stamped.txt" +msgstr "" + +#, sh-format +msgid "" +"King, lover of clear procedures and opaque stamps. Motto: \"Who stamps " +"reigns.\"" +msgstr "" + +#, sh-format +msgid "Great Chancellery" +msgstr "" + +#, sh-format +msgid "Stamps Office" +msgstr "" + +#, sh-format +msgid "Ministry of Papers" +msgstr "" + +#, sh-format +msgid "Forms Directorate" +msgstr "" + +#, sh-format +msgid "Duplicate Service" +msgstr "" + +#, sh-format +msgid "Ministry of Bridges and Roads" +msgstr "" + +#, sh-format +msgid "Mounting Office" +msgstr "" + +#, sh-format +msgid "Ministry of Rumors" +msgstr "" + +#, sh-format +msgid "Whispers Cabinet" +msgstr "" + +#, sh-format +msgid "Court of Accounts and Half Accounts" +msgstr "" + +#, sh-format +msgid "Registry" +msgstr "" + +#, sh-format +msgid "Kingdom Prefecture" +msgstr "" + +#, sh-format +msgid "Counter A-M" +msgstr "" + +#, sh-format +msgid "Counter N-Z" +msgstr "" + +#, sh-format +msgid "Archives" +msgstr "" + +#, sh-format +msgid "Shelving" +msgstr "" + +#, sh-format +msgid "A to Z" +msgstr "" + +#, sh-format +msgid "Commissions" +msgstr "" + +#, sh-format +msgid "Commission 1" +msgstr "" + +#, sh-format +msgid "Commission 2" +msgstr "" + +#, sh-format +msgid "Commission 3" +msgstr "" + +#, sh-format +msgid "Number 0001.txt" +msgstr "" + +#, sh-format +msgid "You will be called after number 0000 (when it exists)." +msgstr "" + +#, sh-format +msgid "Internal Regulations.md" +msgstr "" + +#, sh-format +msgid "Any request must be stamped before being submitted to be stamped." +msgstr "" + +#, sh-format +msgid "" +"Stamps are not to be stamped, except in case of emergency (form \"URG-URG\")." +msgstr "" + +#, sh-format +msgid "Employees must soothe the feathered stamp every morning." +msgstr "" + +#, sh-format +msgid "Circular Procedure n° ∞.md" +msgstr "" + +#, sh-format +msgid "" +"Step 1: consult Step 2. Step 2: consult Step 1. (Stamp required at each " +"consultation.)" +msgstr "" + +#, sh-format +msgid "Whisper of the day.txt" +msgstr "" + +#, sh-format +msgid "They say the pile of files is taller seen from below." +msgstr "" + +#, sh-format +msgid "Half-receipt (to complete).txt" +msgstr "" + +#, sh-format +msgid "Please present the other half to prove the existence of this one." +msgstr "" + +#, sh-format +msgid "Index (partial).txt" +msgstr "" + +#, sh-format +msgid "" +"Apricots (no); Certificates (yes); Warnings (maybe). See also: Zebras (filed " +"under A by mistake)." +msgstr "" + +#, sh-format +msgid "Plastic plant (badge holder).txt" +msgstr "" + +#, sh-format +msgid "Seniority: 12 years. Acquired rights: priority at the counter." +msgstr "" + +#, sh-format +msgid "Quantum stamp.txt" +msgstr "" + +#, sh-format +msgid "" +"Affixes and removes the seal simultaneously until observed by a superior." +msgstr "" + +#, sh-format +msgid "Bottomless inkwell.txt" +msgstr "" + +#, sh-format +msgid "Structural deficit. Voted every year by acclamation." +msgstr "" + +#, sh-format +msgid "Random forms dispenser.txt" +msgstr "" + +#, sh-format +msgid "Spits out a different CERFA with each swear word. Doesn't take change." +msgstr "" + +#, sh-format +msgid "Photocopy of an unfindable original copy.txt" +msgstr "" + +#, sh-format +msgid "Authenticated by the absence of the original." +msgstr "" + +#, sh-format +msgid "Vertical bubble level.txt" +msgstr "" + +#, sh-format +msgid "Indicates the moral inclination of the project." +msgstr "" + +#, sh-format +msgid "Whispering microphone.txt" +msgstr "" + +#, sh-format +msgid "Repeats \"apparently\" with authority." +msgstr "" + +#, sh-format +msgid "Digital abacus (unplugged).txt" +msgstr "" + +#, sh-format +msgid "Optimizes invisible savings." +msgstr "" + +#, sh-format +msgid "Ticket regurgitator automaton.txt" +msgstr "" + +#, sh-format +msgid "Returns a ticket older than yours." +msgstr "" + +#, sh-format +msgid "Queue line snake rope.txt" +msgstr "" + +#, sh-format +msgid "Lengthens as soon as you think you're reaching the goal." +msgstr "" + +#, sh-format +msgid "Schrödinger's file (filed and lost).txt" +msgstr "" + +#, sh-format +msgid "Exists as long as no one consults it." +msgstr "" + +#, sh-format +msgid "Member list.txt" +msgstr "" + +#, sh-format +msgid "Dame Pénélope de la Punaise (president)" +msgstr "" + +#, sh-format +msgid "Sire Fernand du Parapheur (vice-president)" +msgstr "" + +#, sh-format +msgid "Master Loris des Liasses (rapporteur)" +msgstr "" + +#, sh-format +msgid "Session bell (mute).txt" +msgstr "" + +#, sh-format +msgid "Signals the end of debate as soon as it begins." +msgstr "" + +#, sh-format +msgid "Captain Clotaire du Cachet" +msgstr "" + +#, sh-format +msgid "Demoiselle Agathe du Bordereau" +msgstr "" + +#, sh-format +msgid "Brother Nestor des Annexes" +msgstr "" + +#, sh-format +msgid "Folding chair (unfolded by decree).txt" +msgstr "" + +#, sh-format +msgid "Only folds to written injunctions." +msgstr "" + +#, sh-format +msgid "Stewardess Salomé de la Signature" +msgstr "" + +#, sh-format +msgid "Registrar Octave de l'Agrafe" +msgstr "" + +#, sh-format +msgid "Sergeant Éline de la Reliure" +msgstr "" + +#, sh-format +msgid "Protocol stapler (without staples).txt" +msgstr "" + +#, sh-format +msgid "Brings together without attaching." +msgstr "" + +#, sh-format +msgid "Academy of Geo-mancy" +msgstr "" + +#, sh-format +msgid "Study Secretariat" +msgstr "" + +#, sh-format +msgid "Registration Office" +msgstr "" + +#, sh-format +msgid "Retake Service" +msgstr "" + +#, sh-format +msgid "Library of Impossible Maps" +msgstr "" + +#, sh-format +msgid "Contradictory Atlases Room" +msgstr "" + +#, sh-format +msgid "Ground Floor" +msgstr "" + +#, sh-format +msgid "Moving Index" +msgstr "" + +#, sh-format +msgid "Departments" +msgstr "" + +#, sh-format +msgid "Etheric Cartography" +msgstr "" + +#, sh-format +msgid "Labs" +msgstr "" + +#, sh-format +msgid "Stamp Topology" +msgstr "" + +#, sh-format +msgid "Forms Geology" +msgstr "" + +#, sh-format +msgid "Institute of Flows and Counter-Flows" +msgstr "" + +#, sh-format +msgid "Amphitheater ∮" +msgstr "" + +#, sh-format +msgid "Observatory of Administrative Lines" +msgstr "" + +#, sh-format +msgid "Meridians Terrace" +msgstr "" + +#, sh-format +msgid "Competitions and Aggregations" +msgstr "" + +#, sh-format +msgid "Examination Room" +msgstr "" + +#, sh-format +msgid "Tools Museum" +msgstr "" + +#, sh-format +msgid "Instruments" +msgstr "" + +#, sh-format +msgid "Student guide.md" +msgstr "" + +#, sh-format +msgid "Cardinal principle: every territory is a matter of paper." +msgstr "" + +#, sh-format +msgid "ECTS credits mean \"Echelons, Cachets, Tampons, Signatures\"." +msgstr "" + +#, sh-format +msgid "Any valid map must include at least one administrative dead end." +msgstr "" + +#, sh-format +msgid "Opening hours.txt" +msgstr "" + +#, sh-format +msgid "Open on even working days, except when it's odd." +msgstr "" + +#, sh-format +msgid "Flat atlas of the round Earth.txt" +msgstr "" + +#, sh-format +msgid "Revised edition: now spheri-flat according to decree." +msgstr "" + +#, sh-format +msgid "User manual.txt" +msgstr "" + +#, sh-format +msgid "To find A, look for Z, then return to A via Beta corridor." +msgstr "" + +#, sh-format +msgid "Program.md" +msgstr "" + +#, sh-format +msgid "Introduction to trace-therapy" +msgstr "" + +#, sh-format +msgid "Variable geometry of moral borders" +msgstr "" + +#, sh-format +msgid "Seminar: The hesitant compass" +msgstr "" + +#, sh-format +msgid "Indecisive compass.txt" +msgstr "" + +#, sh-format +msgid "Turns until the presence of a department head." +msgstr "" + +#, sh-format +msgid "Non-commutative seal groups" +msgstr "" + +#, sh-format +msgid "Homotopy of validation circuits" +msgstr "" + +#, sh-format +msgid "Seminar: Torus of waiting lines" +msgstr "" + +#, sh-format +msgid "Möbius stamp.txt" +msgstr "" + +#, sh-format +msgid "One side, two lines, no exit." +msgstr "" + +#, sh-format +msgid "Stratigraphy of annexes" +msgstr "" + +#, sh-format +msgid "Metamorphism under paraph" +msgstr "" + +#, sh-format +msgid "Seminar: Version fossils" +msgstr "" + +#, sh-format +msgid "Stratified section of a file.txt" +msgstr "" + +#, sh-format +msgid "Observe without disturbing the fragile \"missing pieces\" layer." +msgstr "" + +#, sh-format +msgid "Self-erasing blackboard.txt" +msgstr "" + +#, sh-format +msgid "Erases demonstrations just before the conclusion." +msgstr "" + +#, sh-format +msgid "Paperwork telescope.txt" +msgstr "" + +#, sh-format +msgid "Only magnifies illegible signatures." +msgstr "" + +#, sh-format +msgid "Deadline drawing board.txt" +msgstr "" + +#, sh-format +msgid "Allows adding a calendar month to any natural delay." +msgstr "" + +#, sh-format +msgid "Sample subject.md" +msgstr "" + +#, sh-format +msgid "Map a mobile border between two closed counters." +msgstr "" + +#, sh-format +msgid "" +"Demonstrate the existence of a shortcut longer than the official detour." +msgstr "" + +#, sh-format +msgid "Stamp the hypothesis, then remove it cleanly." +msgstr "" + +#, sh-format +msgid "Approved cheat sheet (blank).txt" +msgstr "" + +#, sh-format +msgid "To be filled only inadvertently." +msgstr "" + +#, sh-format +msgid "Cerfas Office" +msgstr "" + +#, sh-format +msgid "CERFA 13B" +msgstr "" + +#, sh-format +msgid "CERFA 13C" +msgstr "" + +#, sh-format +msgid "Complaints and Complaint Requests Office" +msgstr "" + +#, sh-format +msgid "Example complaint (template).txt" +msgstr "" + +#, sh-format +msgid "Subject: complaint against the complaint form, too complaining." +msgstr "" + +#, sh-format +msgid "Orientation brochure.txt" +msgstr "" + +#, sh-format +msgid "" +"For any question, address the Counter-counter. To contest: Return Service." +msgstr "" + +#, sh-format +msgid "" +"Fill in blue. Except if you don't have blue, in which case: start over in " +"blue." +msgstr "" + +#, sh-format +msgid "Administrative hourglass set to \"in progress\".txt" +msgstr "" + +#, sh-format +msgid "Never empties completely, in accordance with procedure." +msgstr "" + +#, sh-format +msgid "Conditional ink pen.txt" +msgstr "" + +#, sh-format +msgid "Writes only after the stamp, never before." +msgstr "" + +#, sh-format +msgid "Bottomless complaints box.txt" +msgstr "" + +#, sh-format +msgid "All claims find their downfall there." +msgstr "" + +#, sh-format +msgid "Self-referenced form.txt" +msgstr "" + +#, sh-format +msgid "Please attach CERFA 13C to this CERFA 13C." +msgstr "" + +#, sh-format +msgid "Whispering megaphone.txt" +msgstr "" + +#, sh-format +msgid "Amplifies indignant silences." +msgstr "" + +#, sh-format +msgid "Public Reception" +msgstr "" + +#, sh-format +msgid "Ticket Distribution" +msgstr "" + +#, sh-format +msgid "Provisional Orientation" +msgstr "" + +#, sh-format +msgid "Preliminary Pre-validation" +msgstr "" + +#, sh-format +msgid "Control Compliance Control" +msgstr "" + +#, sh-format +msgid "Internal Prefecture Visa" +msgstr "" + +#, sh-format +msgid "Intent Stamping" +msgstr "" + +#, sh-format +msgid "Verification Verification" +msgstr "" + +#, sh-format +msgid "Penultimate Step Counter-Validation" +msgstr "" + +#, sh-format +msgid "Counter No. 0" +msgstr "" + +#, sh-format +msgid "Standard Administrative Path" +msgstr "" + +#, sh-format +msgid "Instructions.txt" +msgstr "" + +#, sh-format +msgid "Present the document obtained in the previous step." +msgstr "" + +#, sh-format +msgid "Motivating ceiling light.txt" +msgstr "" + +#, sh-format +msgid "Displays \"Almost done!\" upon arrival." +msgstr "" + +#, sh-format +msgid "Imaginary number ticket.txt" +msgstr "" + +#, sh-format +msgid "Served after the real ones, before the priority ones." +msgstr "" + +#, sh-format +msgid "Administrative compass.txt" +msgstr "" + +#, sh-format +msgid "Always points to the opposite counter." +msgstr "" + +#, sh-format +msgid "Shadow stamp.txt" +msgstr "" + +#, sh-format +msgid "Leaves an invisible but regulatory trace." +msgstr "" + +#, sh-format +msgid "Checklist checklist.txt" +msgstr "" + +#, sh-format +msgid "Last item: check this checklist." +msgstr "" + +#, sh-format +msgid "Swinging door (leads nowhere).txt" +msgstr "" + +#, sh-format +msgid "Approved for back-and-forth." +msgstr "" + +#, sh-format +msgid "Tacit intentions form.txt" +msgstr "" + +#, sh-format +msgid "To be filled without writing anything." +msgstr "" + +#, sh-format +msgid "Protocol magnifying glass.txt" +msgstr "" + +#, sh-format +msgid "Magnifies paperwork, reduces hope." +msgstr "" + +#, sh-format +msgid "Contradictory seal.txt" +msgstr "" + +#, sh-format +msgid "Validates and invalidates simultaneously." +msgstr "" + +#, sh-format +msgid "Impossible bell.txt" +msgstr "" + +#, sh-format +msgid "Ring scheduled for next budget year." +msgstr "" + +#, sh-format +msgid "Next step" +msgstr "" + +#, sh-format +msgid "Duplicate requests" +msgstr "" + +#, sh-format +msgid "Final validation" +msgstr "" + +#, sh-format +msgid "next counter" +msgstr "" + +#, sh-format +msgid "referral" +msgstr "" + +#, sh-format +msgid "transmission" +msgstr "" + +#, sh-format +msgid "Stamp required" +msgstr "" + +#, sh-format +msgid "Deposit" +msgstr "" + +#, sh-format +msgid "Prefecture validation" +msgstr "" + +#, sh-format +msgid "Mandatory Academy internship" +msgstr "" + +#, sh-format +msgid "Bridge to the Library of Impossible Maps" +msgstr "" + +#, sh-format +msgid "Flow validation procedure" +msgstr "" + +#, sh-format +msgid "" +"✅ Kingdom of Bordereau VI the Stamped: bizarre objects, Academy of Geo-" +"mancy and administrative labyrinths created (without villages)." +msgstr "" diff --git a/missions/lvm/00_shared/i18n/template.pot b/missions/lvm/00_shared/i18n/template.pot new file mode 100644 index 000000000..0441f01d1 --- /dev/null +++ b/missions/lvm/00_shared/i18n/template.pot @@ -0,0 +1,971 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-09-23 12:09+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#, sh-format +msgid "" +"Dummy mission '$DUMMY_MISSION' is required for mission $MISSION_NB " +"($MISSION_NAME)." +msgstr "" + +#, sh-format +msgid "" +"Loop devices $LOOP1_PATH and $LOOP2_PATH are required for mission " +"$MISSION_NB ($MISSION_NAME)." +msgstr "" + +#, sh-format +msgid "$GSH_HOME/Royaume" +msgstr "" + +#, sh-format +msgid "Offices" +msgstr "" + +#, sh-format +msgid "Unique Stamp Office" +msgstr "" + +#, sh-format +msgid "Counter" +msgstr "" + +#, sh-format +msgid "Orientation" +msgstr "" + +#, sh-format +msgid "Counter-counter" +msgstr "" + +#, sh-format +msgid "Return Form" +msgstr "" + +#, sh-format +msgid "Return Service" +msgstr "" + +#, sh-format +msgid "Return to beginning" +msgstr "" + +#, sh-format +msgid "Central Administration" +msgstr "" + +#, sh-format +msgid "Unique counter" +msgstr "" + +#, sh-format +msgid "King's Hotel" +msgstr "" + +#, sh-format +msgid "Antechamber" +msgstr "" + +#, sh-format +msgid "Waiting Room" +msgstr "" + +#, sh-format +msgid "return to counter" +msgstr "" + +#, sh-format +msgid "" +"🖋️ Generating lore for the Kingdom of Bordereau VI the Stamped (edition " +"without villages)..." +msgstr "" + +#, sh-format +msgid "$GSH_HOME/Kingdom" +msgstr "" + +#, sh-format +msgid "Castle" +msgstr "" + +#, sh-format +msgid "Main Tower" +msgstr "" + +#, sh-format +msgid "First Floor" +msgstr "" + +#, sh-format +msgid "Second Floor" +msgstr "" + +#, sh-format +msgid "Tower Summit" +msgstr "" + +#, sh-format +msgid "Objects" +msgstr "" + +#, sh-format +msgid "Concierge's Journal.txt" +msgstr "" + +#, sh-format +msgid "" +"Day 34: someone moved the audience hourglass. Time is now ahead of itself." +msgstr "" + +#, sh-format +msgid "Royal Stamp (unicorn wood).txt" +msgstr "" + +#, sh-format +msgid "Usage: affix. Side effect: instant respect." +msgstr "" + +#, sh-format +msgid "Key to the key drawer.txt" +msgstr "" + +#, sh-format +msgid "Only opens keys. For drawers, provide another form." +msgstr "" + +#, sh-format +msgid "Parade Paraph (too heavy to serve).txt" +msgstr "" + +#, sh-format +msgid "Ceremonial object. Appears more official than the law." +msgstr "" + +#, sh-format +msgid "Official Portraits" +msgstr "" + +#, sh-format +msgid "Bordereau VI the Stamped.txt" +msgstr "" + +#, sh-format +msgid "" +"King, lover of clear procedures and opaque stamps. Motto: \"Who stamps " +"reigns.\"" +msgstr "" + +#, sh-format +msgid "Great Chancellery" +msgstr "" + +#, sh-format +msgid "Stamps Office" +msgstr "" + +#, sh-format +msgid "Ministry of Papers" +msgstr "" + +#, sh-format +msgid "Forms Directorate" +msgstr "" + +#, sh-format +msgid "Duplicate Service" +msgstr "" + +#, sh-format +msgid "Ministry of Bridges and Roads" +msgstr "" + +#, sh-format +msgid "Mounting Office" +msgstr "" + +#, sh-format +msgid "Ministry of Rumors" +msgstr "" + +#, sh-format +msgid "Whispers Cabinet" +msgstr "" + +#, sh-format +msgid "Court of Accounts and Half Accounts" +msgstr "" + +#, sh-format +msgid "Registry" +msgstr "" + +#, sh-format +msgid "Kingdom Prefecture" +msgstr "" + +#, sh-format +msgid "Counter A-M" +msgstr "" + +#, sh-format +msgid "Counter N-Z" +msgstr "" + +#, sh-format +msgid "Archives" +msgstr "" + +#, sh-format +msgid "Shelving" +msgstr "" + +#, sh-format +msgid "A to Z" +msgstr "" + +#, sh-format +msgid "Commissions" +msgstr "" + +#, sh-format +msgid "Commission 1" +msgstr "" + +#, sh-format +msgid "Commission 2" +msgstr "" + +#, sh-format +msgid "Commission 3" +msgstr "" + +#, sh-format +msgid "Number 0001.txt" +msgstr "" + +#, sh-format +msgid "You will be called after number 0000 (when it exists)." +msgstr "" + +#, sh-format +msgid "Internal Regulations.md" +msgstr "" + +#, sh-format +msgid "Any request must be stamped before being submitted to be stamped." +msgstr "" + +#, sh-format +msgid "" +"Stamps are not to be stamped, except in case of emergency (form \"URG-URG\")." +msgstr "" + +#, sh-format +msgid "Employees must soothe the feathered stamp every morning." +msgstr "" + +#, sh-format +msgid "Circular Procedure n° ∞.md" +msgstr "" + +#, sh-format +msgid "" +"Step 1: consult Step 2. Step 2: consult Step 1. (Stamp required at each " +"consultation.)" +msgstr "" + +#, sh-format +msgid "Whisper of the day.txt" +msgstr "" + +#, sh-format +msgid "They say the pile of files is taller seen from below." +msgstr "" + +#, sh-format +msgid "Half-receipt (to complete).txt" +msgstr "" + +#, sh-format +msgid "Please present the other half to prove the existence of this one." +msgstr "" + +#, sh-format +msgid "Index (partial).txt" +msgstr "" + +#, sh-format +msgid "" +"Apricots (no); Certificates (yes); Warnings (maybe). See also: Zebras (filed " +"under A by mistake)." +msgstr "" + +#, sh-format +msgid "Plastic plant (badge holder).txt" +msgstr "" + +#, sh-format +msgid "Seniority: 12 years. Acquired rights: priority at the counter." +msgstr "" + +#, sh-format +msgid "Quantum stamp.txt" +msgstr "" + +#, sh-format +msgid "" +"Affixes and removes the seal simultaneously until observed by a superior." +msgstr "" + +#, sh-format +msgid "Bottomless inkwell.txt" +msgstr "" + +#, sh-format +msgid "Structural deficit. Voted every year by acclamation." +msgstr "" + +#, sh-format +msgid "Random forms dispenser.txt" +msgstr "" + +#, sh-format +msgid "Spits out a different CERFA with each swear word. Doesn't take change." +msgstr "" + +#, sh-format +msgid "Photocopy of an unfindable original copy.txt" +msgstr "" + +#, sh-format +msgid "Authenticated by the absence of the original." +msgstr "" + +#, sh-format +msgid "Vertical bubble level.txt" +msgstr "" + +#, sh-format +msgid "Indicates the moral inclination of the project." +msgstr "" + +#, sh-format +msgid "Whispering microphone.txt" +msgstr "" + +#, sh-format +msgid "Repeats \"apparently\" with authority." +msgstr "" + +#, sh-format +msgid "Digital abacus (unplugged).txt" +msgstr "" + +#, sh-format +msgid "Optimizes invisible savings." +msgstr "" + +#, sh-format +msgid "Ticket regurgitator automaton.txt" +msgstr "" + +#, sh-format +msgid "Returns a ticket older than yours." +msgstr "" + +#, sh-format +msgid "Queue line snake rope.txt" +msgstr "" + +#, sh-format +msgid "Lengthens as soon as you think you're reaching the goal." +msgstr "" + +#, sh-format +msgid "Schrödinger's file (filed and lost).txt" +msgstr "" + +#, sh-format +msgid "Exists as long as no one consults it." +msgstr "" + +#, sh-format +msgid "Member list.txt" +msgstr "" + +#, sh-format +msgid "Dame Pénélope de la Punaise (president)" +msgstr "" + +#, sh-format +msgid "Sire Fernand du Parapheur (vice-president)" +msgstr "" + +#, sh-format +msgid "Master Loris des Liasses (rapporteur)" +msgstr "" + +#, sh-format +msgid "Session bell (mute).txt" +msgstr "" + +#, sh-format +msgid "Signals the end of debate as soon as it begins." +msgstr "" + +#, sh-format +msgid "Captain Clotaire du Cachet" +msgstr "" + +#, sh-format +msgid "Demoiselle Agathe du Bordereau" +msgstr "" + +#, sh-format +msgid "Brother Nestor des Annexes" +msgstr "" + +#, sh-format +msgid "Folding chair (unfolded by decree).txt" +msgstr "" + +#, sh-format +msgid "Only folds to written injunctions." +msgstr "" + +#, sh-format +msgid "Stewardess Salomé de la Signature" +msgstr "" + +#, sh-format +msgid "Registrar Octave de l'Agrafe" +msgstr "" + +#, sh-format +msgid "Sergeant Éline de la Reliure" +msgstr "" + +#, sh-format +msgid "Protocol stapler (without staples).txt" +msgstr "" + +#, sh-format +msgid "Brings together without attaching." +msgstr "" + +#, sh-format +msgid "Academy of Geo-mancy" +msgstr "" + +#, sh-format +msgid "Study Secretariat" +msgstr "" + +#, sh-format +msgid "Registration Office" +msgstr "" + +#, sh-format +msgid "Retake Service" +msgstr "" + +#, sh-format +msgid "Library of Impossible Maps" +msgstr "" + +#, sh-format +msgid "Contradictory Atlases Room" +msgstr "" + +#, sh-format +msgid "Ground Floor" +msgstr "" + +#, sh-format +msgid "Moving Index" +msgstr "" + +#, sh-format +msgid "Departments" +msgstr "" + +#, sh-format +msgid "Etheric Cartography" +msgstr "" + +#, sh-format +msgid "Labs" +msgstr "" + +#, sh-format +msgid "Stamp Topology" +msgstr "" + +#, sh-format +msgid "Forms Geology" +msgstr "" + +#, sh-format +msgid "Institute of Flows and Counter-Flows" +msgstr "" + +#, sh-format +msgid "Amphitheater ∮" +msgstr "" + +#, sh-format +msgid "Observatory of Administrative Lines" +msgstr "" + +#, sh-format +msgid "Meridians Terrace" +msgstr "" + +#, sh-format +msgid "Competitions and Aggregations" +msgstr "" + +#, sh-format +msgid "Examination Room" +msgstr "" + +#, sh-format +msgid "Tools Museum" +msgstr "" + +#, sh-format +msgid "Instruments" +msgstr "" + +#, sh-format +msgid "Student guide.md" +msgstr "" + +#, sh-format +msgid "Cardinal principle: every territory is a matter of paper." +msgstr "" + +#, sh-format +msgid "ECTS credits mean \"Echelons, Cachets, Tampons, Signatures\"." +msgstr "" + +#, sh-format +msgid "Any valid map must include at least one administrative dead end." +msgstr "" + +#, sh-format +msgid "Opening hours.txt" +msgstr "" + +#, sh-format +msgid "Open on even working days, except when it's odd." +msgstr "" + +#, sh-format +msgid "Flat atlas of the round Earth.txt" +msgstr "" + +#, sh-format +msgid "Revised edition: now spheri-flat according to decree." +msgstr "" + +#, sh-format +msgid "User manual.txt" +msgstr "" + +#, sh-format +msgid "To find A, look for Z, then return to A via Beta corridor." +msgstr "" + +#, sh-format +msgid "Program.md" +msgstr "" + +#, sh-format +msgid "Introduction to trace-therapy" +msgstr "" + +#, sh-format +msgid "Variable geometry of moral borders" +msgstr "" + +#, sh-format +msgid "Seminar: The hesitant compass" +msgstr "" + +#, sh-format +msgid "Indecisive compass.txt" +msgstr "" + +#, sh-format +msgid "Turns until the presence of a department head." +msgstr "" + +#, sh-format +msgid "Non-commutative seal groups" +msgstr "" + +#, sh-format +msgid "Homotopy of validation circuits" +msgstr "" + +#, sh-format +msgid "Seminar: Torus of waiting lines" +msgstr "" + +#, sh-format +msgid "Möbius stamp.txt" +msgstr "" + +#, sh-format +msgid "One side, two lines, no exit." +msgstr "" + +#, sh-format +msgid "Stratigraphy of annexes" +msgstr "" + +#, sh-format +msgid "Metamorphism under paraph" +msgstr "" + +#, sh-format +msgid "Seminar: Version fossils" +msgstr "" + +#, sh-format +msgid "Stratified section of a file.txt" +msgstr "" + +#, sh-format +msgid "Observe without disturbing the fragile \"missing pieces\" layer." +msgstr "" + +#, sh-format +msgid "Self-erasing blackboard.txt" +msgstr "" + +#, sh-format +msgid "Erases demonstrations just before the conclusion." +msgstr "" + +#, sh-format +msgid "Paperwork telescope.txt" +msgstr "" + +#, sh-format +msgid "Only magnifies illegible signatures." +msgstr "" + +#, sh-format +msgid "Deadline drawing board.txt" +msgstr "" + +#, sh-format +msgid "Allows adding a calendar month to any natural delay." +msgstr "" + +#, sh-format +msgid "Sample subject.md" +msgstr "" + +#, sh-format +msgid "Map a mobile border between two closed counters." +msgstr "" + +#, sh-format +msgid "" +"Demonstrate the existence of a shortcut longer than the official detour." +msgstr "" + +#, sh-format +msgid "Stamp the hypothesis, then remove it cleanly." +msgstr "" + +#, sh-format +msgid "Approved cheat sheet (blank).txt" +msgstr "" + +#, sh-format +msgid "To be filled only inadvertently." +msgstr "" + +#, sh-format +msgid "Cerfas Office" +msgstr "" + +#, sh-format +msgid "CERFA 13B" +msgstr "" + +#, sh-format +msgid "CERFA 13C" +msgstr "" + +#, sh-format +msgid "Complaints and Complaint Requests Office" +msgstr "" + +#, sh-format +msgid "Example complaint (template).txt" +msgstr "" + +#, sh-format +msgid "Subject: complaint against the complaint form, too complaining." +msgstr "" + +#, sh-format +msgid "Orientation brochure.txt" +msgstr "" + +#, sh-format +msgid "" +"For any question, address the Counter-counter. To contest: Return Service." +msgstr "" + +#, sh-format +msgid "" +"Fill in blue. Except if you don't have blue, in which case: start over in " +"blue." +msgstr "" + +#, sh-format +msgid "Administrative hourglass set to \"in progress\".txt" +msgstr "" + +#, sh-format +msgid "Never empties completely, in accordance with procedure." +msgstr "" + +#, sh-format +msgid "Conditional ink pen.txt" +msgstr "" + +#, sh-format +msgid "Writes only after the stamp, never before." +msgstr "" + +#, sh-format +msgid "Bottomless complaints box.txt" +msgstr "" + +#, sh-format +msgid "All claims find their downfall there." +msgstr "" + +#, sh-format +msgid "Self-referenced form.txt" +msgstr "" + +#, sh-format +msgid "Please attach CERFA 13C to this CERFA 13C." +msgstr "" + +#, sh-format +msgid "Whispering megaphone.txt" +msgstr "" + +#, sh-format +msgid "Amplifies indignant silences." +msgstr "" + +#, sh-format +msgid "Public Reception" +msgstr "" + +#, sh-format +msgid "Ticket Distribution" +msgstr "" + +#, sh-format +msgid "Provisional Orientation" +msgstr "" + +#, sh-format +msgid "Preliminary Pre-validation" +msgstr "" + +#, sh-format +msgid "Control Compliance Control" +msgstr "" + +#, sh-format +msgid "Internal Prefecture Visa" +msgstr "" + +#, sh-format +msgid "Intent Stamping" +msgstr "" + +#, sh-format +msgid "Verification Verification" +msgstr "" + +#, sh-format +msgid "Penultimate Step Counter-Validation" +msgstr "" + +#, sh-format +msgid "Counter No. 0" +msgstr "" + +#, sh-format +msgid "Standard Administrative Path" +msgstr "" + +#, sh-format +msgid "Instructions.txt" +msgstr "" + +#, sh-format +msgid "Present the document obtained in the previous step." +msgstr "" + +#, sh-format +msgid "Motivating ceiling light.txt" +msgstr "" + +#, sh-format +msgid "Displays \"Almost done!\" upon arrival." +msgstr "" + +#, sh-format +msgid "Imaginary number ticket.txt" +msgstr "" + +#, sh-format +msgid "Served after the real ones, before the priority ones." +msgstr "" + +#, sh-format +msgid "Administrative compass.txt" +msgstr "" + +#, sh-format +msgid "Always points to the opposite counter." +msgstr "" + +#, sh-format +msgid "Shadow stamp.txt" +msgstr "" + +#, sh-format +msgid "Leaves an invisible but regulatory trace." +msgstr "" + +#, sh-format +msgid "Checklist checklist.txt" +msgstr "" + +#, sh-format +msgid "Last item: check this checklist." +msgstr "" + +#, sh-format +msgid "Swinging door (leads nowhere).txt" +msgstr "" + +#, sh-format +msgid "Approved for back-and-forth." +msgstr "" + +#, sh-format +msgid "Tacit intentions form.txt" +msgstr "" + +#, sh-format +msgid "To be filled without writing anything." +msgstr "" + +#, sh-format +msgid "Protocol magnifying glass.txt" +msgstr "" + +#, sh-format +msgid "Magnifies paperwork, reduces hope." +msgstr "" + +#, sh-format +msgid "Contradictory seal.txt" +msgstr "" + +#, sh-format +msgid "Validates and invalidates simultaneously." +msgstr "" + +#, sh-format +msgid "Impossible bell.txt" +msgstr "" + +#, sh-format +msgid "Ring scheduled for next budget year." +msgstr "" + +#, sh-format +msgid "Next step" +msgstr "" + +#, sh-format +msgid "Duplicate requests" +msgstr "" + +#, sh-format +msgid "Final validation" +msgstr "" + +#, sh-format +msgid "next counter" +msgstr "" + +#, sh-format +msgid "referral" +msgstr "" + +#, sh-format +msgid "transmission" +msgstr "" + +#, sh-format +msgid "Stamp required" +msgstr "" + +#, sh-format +msgid "Deposit" +msgstr "" + +#, sh-format +msgid "Prefecture validation" +msgstr "" + +#, sh-format +msgid "Mandatory Academy internship" +msgstr "" + +#, sh-format +msgid "Bridge to the Library of Impossible Maps" +msgstr "" + +#, sh-format +msgid "Flow validation procedure" +msgstr "" + +#, sh-format +msgid "" +"✅ Kingdom of Bordereau VI the Stamped: bizarre objects, Academy of Geo-" +"mancy and administrative labyrinths created (without villages)." +msgstr "" diff --git a/missions/lvm/00_shared/lore_generator.sh b/missions/lvm/00_shared/lore_generator.sh new file mode 100644 index 000000000..b5f44e029 --- /dev/null +++ b/missions/lvm/00_shared/lore_generator.sh @@ -0,0 +1,353 @@ +#!/usr/bin/env bash + +# Main lore generation function ————————————————————————————————————————————— +generate_lore() { + + # Helpers ———————————————————————————————————————————————————————————————— + mkd() { + mkdir -p "$1"; + } + + link() { + local dest="$1"; + local target="$2"; + mkd "$(dirname "$dest")"; + ln -sfn "$target" "$dest"; + } + + writ() { # writ "path" "content" + local path="$1"; mkd "$(dirname "$path")" + printf "%s\n" "$2" > "$path" + } + + heredoc() { # heredoc "path" <<'EOF' ... EOF + local path="$1"; mkd "$(dirname "$path")"; cat > "$path" + } + + echo "$(eval_gettext "🖋️ Generating lore for the Kingdom of Bordereau VI the Stamped (edition without villages)...")" + ROOT="$(eval_gettext "\$GSH_HOME/Royaume")" + + # Château ———————————————————————————————————————————————————————————————— + mkd "$ROOT/Château/Tour principale/Premier étage/Deuxième étage/Sommet de la tour" + mkd "$ROOT/Château/Objets" + writ "$ROOT/Château/Tour principale/Premier étage/Journal du Concierge.txt" \ + "Jour 34 : quelqu'un a déplacé le sablier des audiences. Le temps est désormais en avance sur lui-même." + writ "$ROOT/Château/Objets/Tampon royal (bois de licorne).txt" \ + "Usage : apposer. Effet secondaire : respect instantané." + writ "$ROOT/Château/Objets/Clé du tiroir des clés.txt" \ + "N'ouvre que les clés. Pour les tiroirs, prévoir un autre formulaire." + writ "$ROOT/Château/Objets/Parapheur de Parade (trop lourd pour servir).txt" \ + "Objet cérémoniel. Apparaît plus officiel que la loi." + + writ "$ROOT/Château/Portraits officiels/Bordereau VI le Tamponné.txt" \ + "Roi, amateur de procédures claires et de tampons opaques. Devise : « Qui tamponne règne. »" + + # Administration centrale —————————————————————————————————————————————— + mkd "$ROOT/Administration centrale/Hôtel du Roi/Grande Chancellerie/Bureau des Tampons" + mkd "$ROOT/Administration centrale/Hôtel du Roi/Antichambre/Salle d'attente" + mkd "$ROOT/Administration centrale/Ministère des Papiers/Direction des Formulaires" + mkd "$ROOT/Administration centrale/Ministère des Papiers/Service du Duplicata" + mkd "$ROOT/Administration centrale/Ministère des Ponts et Chemins/Bureau des Montages" + mkd "$ROOT/Administration centrale/Ministère des Rumeurs/Cabinet des Murmures" + mkd "$ROOT/Administration centrale/Cour des Comptes et Demi Comptes/Greffe" + mkd "$ROOT/Administration centrale/Préfecture du Royaume/Guichet A-M" + mkd "$ROOT/Administration centrale/Préfecture du Royaume/Guichet N-Z" + mkd "$ROOT/Administration centrale/Archives/Rayonnages/A à Z" + mkd "$ROOT/Administration centrale/Commissions/Commission 1" + mkd "$ROOT/Administration centrale/Commissions/Commission 2" + mkd "$ROOT/Administration centrale/Commissions/Commission 3" + + # Règlements, circulaires et murmures ———————————————————————————————————— + writ "$ROOT/Administration centrale/Hôtel du Roi/Antichambre/Salle d'attente/Numéro 0001.txt" \ + "Vous serez appelé après le numéro 0000 (quand il existera)." + + heredoc "$ROOT/Administration centrale/Hôtel du Roi/Grande Chancellerie/Bureau des Tampons/Règlement intérieur.md" <<'EOF' +# Règlement intérieur du Bureau des Tampons +1. Toute demande doit être tamponnée avant d'être déposée pour être tamponnée. +2. Les tampons ne sont pas à tamponner, sauf en cas d'urgence (formulaire « URG-URG »). +3. Les employés doivent apaiser le tampon à plumes chaque matin. +EOF + + writ "$ROOT/Administration centrale/Ministère des Papiers/Direction des Formulaires/Procédure circulaire n° ∞.md" \ + "Étape 1 : consulter l'Étape 2. Étape 2 : consulter l'Étape 1. (Tampon requis à chaque consultation.)" + + writ "$ROOT/Administration centrale/Ministère des Rumeurs/Cabinet des Murmures/Murmure du jour.txt" \ + "On dit que la pile de dossiers est plus haute vue d'en bas." + + writ "$ROOT/Administration centrale/Cour des Comptes et Demi Comptes/Greffe/Demi-reçu (à compléter).txt" \ + "Merci de présenter l'autre moitié pour prouver l'existence de celle-ci." + + writ "$ROOT/Administration centrale/Archives/Rayonnages/A à Z/Index (partiel).txt" \ + "Abricots (non) ; Attestations (oui) ; Avertissements (peut-être). Voir aussi : Zèbres (classés à A par erreur)." + + # Objets farfelus répartis dans les services ————————————————————————————————— + writ "$ROOT/Administration centrale/Hôtel du Roi/Antichambre/Salle d'attente/Plante en plastique (titulaire d'un badge).txt" \ + "Ancienneté : 12 ans. Droits acquis : priorité au guichet." + writ "$ROOT/Administration centrale/Hôtel du Roi/Grande Chancellerie/Bureau des Tampons/Tampon quantique.txt" \ + "Appose et retire le cachet simultanément jusqu'à observation par un supérieur." + writ "$ROOT/Administration centrale/Hôtel du Roi/Grande Chancellerie/Bureau des Tampons/Encrier sans fond.txt" \ + "Déficit structurel. Voté chaque année par acclamation." + writ "$ROOT/Administration centrale/Ministère des Papiers/Direction des Formulaires/Distributeur à formulaires aléatoires.txt" \ + "Crache un CERFA différent à chaque juron. Ne prend pas la monnaie." + writ "$ROOT/Administration centrale/Ministère des Papiers/Service du Duplicata/Photocopie d'une copie originale introuvable.txt" \ + "Authentifiée par l'absence de l'original." + writ "$ROOT/Administration centrale/Ministère des Ponts et Chemins/Bureau des Montages/Niveau à bulle vertical.txt" \ + "Indique l'inclinaison morale du projet." + writ "$ROOT/Administration centrale/Ministère des Rumeurs/Cabinet des Murmures/Micro murmurant.txt" \ + "Répète « il paraît » avec autorité." + writ "$ROOT/Administration centrale/Cour des Comptes et Demi Comptes/Greffe/Abacus numérique (débranché).txt" \ + "Optimise les économies invisibles." + writ "$ROOT/Administration centrale/Préfecture du Royaume/Guichet A-M/Automate à tickets régurgitateurs.txt" \ + "Rend un ticket plus ancien que le vôtre." + writ "$ROOT/Administration centrale/Préfecture du Royaume/Guichet N-Z/Corde serpent de file d'attente.txt" \ + "S'allonge dès qu'on croit toucher au but." + writ "$ROOT/Administration centrale/Archives/Rayonnages/A à Z/Dossier de Schrödinger (classé et perdu).txt" \ + "Existe tant que personne ne le consulte." + + # Commissions (avec membres + objets) —————————————————————————————————————— + heredoc "$ROOT/Administration centrale/Commissions/Commission 1/Liste des membres.txt" <<'EOF' +- Dame Pénélope de la Punaise (présidente) +- Sire Fernand du Parapheur (vice-président) +- Maître Loris des Liasses (rapporteur) +EOF + writ "$ROOT/Administration centrale/Commissions/Commission 1/Cloche de séance (muette).txt" \ + "Signale la fin du débat dès qu'il commence." + + heredoc "$ROOT/Administration centrale/Commissions/Commission 2/Liste des membres.txt" <<'EOF' +- Capitaine Clotaire du Cachet +- Demoiselle Agathe du Bordereau +- Frère Nestor des Annexes +EOF + writ "$ROOT/Administration centrale/Commissions/Commission 2/Chaise pliante (dépliée par arrêté).txt" \ + "Ne se plie qu'aux injonctions écrites." + + heredoc "$ROOT/Administration centrale/Commissions/Commission 3/Liste des membres.txt" <<'EOF' +- Intendante Salomé de la Signature +- Greffier Octave de l'Agrafe +- Sergente Éline de la Reliure +EOF + writ "$ROOT/Administration centrale/Commissions/Commission 3/Agrafeuse protocolaire (sans agrafes).txt" \ + "Réunit sans attacher." + + # ————————————————————————————————————————————————————————————————————————————— + # ACADÉMIE DE GÉO-MANCIE (nouvelle section) + # ————————————————————————————————————————————————————————————————————————————— + mkd "$ROOT/Académie de Géo-mancie/Secrétariat des Études/Bureau des Inscriptions" + mkd "$ROOT/Académie de Géo-mancie/Secrétariat des Études/Service des Rattrapages" + mkd "$ROOT/Académie de Géo-mancie/Bibliothèque des Cartes Impossibles/Salle des Atlas Contradictoires" + mkd "$ROOT/Académie de Géo-mancie/Bibliothèque des Cartes Impossibles/Rez-de-chaussée/Index mouvant" + mkd "$ROOT/Académie de Géo-mancie/Départements/Cartographie Éthérique/Labos" + mkd "$ROOT/Académie de Géo-mancie/Départements/Topologie des Tampons/Labos" + mkd "$ROOT/Académie de Géo-mancie/Départements/Géologie des Formulaires/Labos" + mkd "$ROOT/Académie de Géo-mancie/Institut des Flux et Contre-Flux/Amphithéâtre ∮" + mkd "$ROOT/Académie de Géo-mancie/Observatoire des Lignes Administratives/Terrasse des Méridiens" + mkd "$ROOT/Académie de Géo-mancie/Concours et Agrégations/Salle des Épreuves" + mkd "$ROOT/Académie de Géo-mancie/Musée des Outils/Instruments" + + # Règlements et présentation + heredoc "$ROOT/Académie de Géo-mancie/Secrétariat des Études/Guide de l'étudiant.md" <<'EOF' +# Guide de l'étudiant géo-mancien +- Principe cardinal : tout territoire est une question de papier. +- Les crédits ECTS signifient « Échelons, Cachets, Tampons, Signatures ». +- Toute carte valide doit comporter au moins un cul-de-sac administratif. +EOF + + writ "$ROOT/Académie de Géo-mancie/Secrétariat des Études/Bureau des Inscriptions/Heures d'ouverture.txt" \ + "Ouvert les jours ouvrés pairs, sauf quand c'est impair." + + # Bibliothèque et objets + writ "$ROOT/Académie de Géo-mancie/Bibliothèque des Cartes Impossibles/Salle des Atlas Contradictoires/Atlas plat de la Terre ronde.txt" \ + "Edition révisée : désormais sphéri-plate selon décret." + writ "$ROOT/Académie de Géo-mancie/Bibliothèque des Cartes Impossibles/Rez-de-chaussée/Index mouvant/Mode d'emploi.txt" \ + "Pour trouver A, chercher Z, puis revenir à A par le couloir Bêta." + + # Départements — enseignants, cours, objets + heredoc "$ROOT/Académie de Géo-mancie/Départements/Cartographie Éthérique/Programme.md" <<'EOF' +## Cartographie Éthérique — Programme +- Introduction à la calque-thérapie +- Géométrie variable des frontières morales +- Séminaire : Le compas qui hésite +EOF + writ "$ROOT/Académie de Géo-mancie/Départements/Cartographie Éthérique/Labos/Compas indécis.txt" \ + "Tourne jusqu'à la présence d'un chef de service." + + heredoc "$ROOT/Académie de Géo-mancie/Départements/Topologie des Tampons/Programme.md" <<'EOF' +## Topologie des Tampons — Programme +- Groupes de cachets non commutatifs +- Homotopie des circuits de validation +- Séminaire : Tore des files d'attente +EOF + writ "$ROOT/Académie de Géo-mancie/Départements/Topologie des Tampons/Labos/Tampon de Möbius.txt" \ + "Un seul côté, deux files, aucune issue." + + heredoc "$ROOT/Académie de Géo-mancie/Départements/Géologie des Formulaires/Programme.md" <<'EOF' +## Géologie des Formulaires — Programme +- Stratigraphie des annexes +- Métamorphisme sous parapheur +- Séminaire : Fossiles de versions +EOF + writ "$ROOT/Académie de Géo-mancie/Départements/Géologie des Formulaires/Labos/Coupe stratifiée d'un dossier.txt" \ + "Observer sans déranger la couche fragile « pièces manquantes »." + + # Institut des Flux + writ "$ROOT/Académie de Géo-mancie/Institut des Flux et Contre-Flux/Amphithéâtre ∮/Tableau noir auto-effaceur.txt" \ + "Efface les démonstrations juste avant la conclusion." + + # Observatoire + writ "$ROOT/Académie de Géo-mancie/Observatoire des Lignes Administratives/Terrasse des Méridiens/Lunette à paperasse.txt" \ + "Ne grossit que les signatures illisibles." + + # Musée des Outils + writ "$ROOT/Académie de Géo-mancie/Musée des Outils/Instruments/Planchette à tracer les délais.txt" \ + "Permet d'ajouter un mois calendaire à tout retard naturel." + + # Concours — épreuves, sujets, résultats + heredoc "$ROOT/Académie de Géo-mancie/Concours et Agrégations/Salle des Épreuves/Sujet type.md" <<'EOF' +# Agrégation de Géo-mancie administrative — Sujet type +1) Cartographier une frontière mobile entre deux guichets fermés. +2) Démontrer l'existence d'un raccourci plus long que le détour officiel. +3) Tamponner l'hypothèse, puis la retirer proprement. +EOF + writ "$ROOT/Académie de Géo-mancie/Concours et Agrégations/Salle des Épreuves/Copion homologué (vierge).txt" \ + "À remplir uniquement par inadvertance." + + # Offices spécialisés —————————————————————————————————————————————————————— + mkd "$ROOT/Offices/Office unique du Tampon/Guichet" + mkd "$ROOT/Offices/Office unique du Tampon/Contre-guichet" + mkd "$ROOT/Offices/Office unique du Tampon/Service du Retour" + mkd "$ROOT/Offices/Office des Cerfas/CERFA 13B" + mkd "$ROOT/Offices/Office des Cerfas/CERFA 13C" + mkd "$ROOT/Offices/Office des Plaintes et Demandes de Plaintes" + + writ "$ROOT/Offices/Office des Plaintes et Demandes de Plaintes/Exemple de plainte (modèle).txt" \ + "Objet : plainte contre le formulaire de plainte, trop plaintif." + writ "$ROOT/Offices/Office unique du Tampon/Guichet/Plaquette d'orientation.txt" \ + "Pour toute question, adressez-vous au Contre-guichet. Pour contester : Service du Retour." + writ "$ROOT/Offices/Office des Cerfas/CERFA 13B/Notice d'utilisation.txt" \ + "Remplir en bleu. Sauf si vous n'avez pas de bleu, dans ce cas : recommencer en bleu." + + # Objets des Offices + writ "$ROOT/Offices/Office unique du Tampon/Guichet/Sablier administratif réglé sur « en cours ».txt" \ + "Ne se vide jamais entièrement, conformément à la procédure." + writ "$ROOT/Offices/Office unique du Tampon/Contre-guichet/Stylo à encre conditionnelle.txt" \ + "Écrit uniquement après le tampon, jamais avant." + writ "$ROOT/Offices/Office unique du Tampon/Service du Retour/Boîte à contestations (sans fond).txt" \ + "Toutes les réclamations y trouvent une chute." + writ "$ROOT/Offices/Office des Cerfas/CERFA 13C/Formulaire auto-référencé.txt" \ + "Veuillez joindre le CERFA 13C à ce CERFA 13C." + writ "$ROOT/Offices/Office des Plaintes et Demandes de Plaintes/Mégaphone chuchoteur.txt" \ + "Amplifie les silences indignés." + + # Parcours kafkaïen en 10 étapes (boucle assurée) ———————————————————————————— + steps=( + "Accueil du Public" + "Distribution de Tickets" + "Orientation Provisoire" + "Pré-validation Préliminaire" + "Contrôle de Conformité aux Contrôles" + "Visa de Préfecture Interne" + "Tamponnage d'Intention" + "Vérification de la Vérification" + "Contre-Validation de l'Avant-Dernière Étape" + "Guichet n°0" + ) + base="$ROOT/Administration centrale/Parcours Administratif Standard" + prev="" + for s in "${steps[@]}"; do + mkd "$base/$s" + writ "$base/$s/Consignes.txt" "Présenter le document obtenu à l'étape précédente." + # Ajouter un objet absurde propre à l'étape + case "$s" in + "Accueil du Public") + writ "$base/$s/Plafonnier motivant.txt" "Affiche « Presque fini ! » dès l'arrivée." + ;; + "Distribution de Tickets") + writ "$base/$s/Ticket à numéro imaginaire.txt" "Servi après les réels, avant les prioritaires." + ;; + "Orientation Provisoire") + writ "$base/$s/Boussole administrative.txt" "Pointe toujours vers le guichet d'en face." + ;; + "Pré-validation Préliminaire") + writ "$base/$s/Tampon d'ombre.txt" "Laisse une trace invisible mais réglementaire." + ;; + "Contrôle de Conformité aux Contrôles") + writ "$base/$s/Checklist de la checklist.txt" "Dernier item : vérifier cette checklist." + ;; + "Visa de Préfecture Interne") + writ "$base/$s/Porte battante (ne mène nulle part).txt" "Homologuée pour le va-et-vient." + ;; + "Tamponnage d'Intention") + writ "$base/$s/Formulaire d'intentions tacites.txt" "À remplir sans rien écrire." + ;; + "Vérification de la Vérification") + writ "$base/$s/Loupe protocolaire.txt" "Grossit la paperasse, réduit l'espoir." + ;; + "Contre-Validation de l'Avant-Dernière Étape") + writ "$base/$s/Cachet contradictoire.txt" "Valide et invalide en même temps." + ;; + "Guichet n°0") + writ "$base/$s/Clochette impossible.txt" "Sonnerie prévue au prochain exercice budgétaire." + ;; + esac + + if [[ -n "${prev}" ]]; then + link "$base/$prev/Étape suivante" "$base/$s" + fi + prev="$s" + done + # boucle vers le début + link "$base/Guichet n°0/Retour au début" "$base/Accueil du Public" + + # Liens absurdes inter-services ———————————————————————————————————————————— + # 1) “Guichet unique” ↔ “Salle d'attente” + link "$ROOT/Administration centrale/Guichet unique" \ + "$ROOT/Administration centrale/Hôtel du Roi/Antichambre/Salle d'attente" + link "$ROOT/Administration centrale/Hôtel du Roi/Antichambre/Salle d'attente/retour au guichet" \ + "$ROOT/Administration centrale/Guichet unique" + + # 2) Bureau des Tampons ↔ Service du Duplicata + link "$ROOT/Administration centrale/Hôtel du Roi/Grande Chancellerie/Bureau des Tampons/Demandes de duplicata" \ + "$ROOT/Administration centrale/Ministère des Papiers/Service du Duplicata" + link "$ROOT/Administration centrale/Ministère des Papiers/Service du Duplicata/Validation finale" \ + "$ROOT/Administration centrale/Hôtel du Roi/Grande Chancellerie/Bureau des Tampons" + + # 3) Préfecture : A-M ↔ N-Z + link "$ROOT/Administration centrale/Préfecture du Royaume/Guichet A-M/prochain guichet" \ + "$ROOT/Administration centrale/Préfecture du Royaume/Guichet N-Z" + link "$ROOT/Administration centrale/Préfecture du Royaume/Guichet N-Z/renvoi" \ + "$ROOT/Administration centrale/Préfecture du Royaume/Guichet A-M" + + # 4) Commissions en cercle + link "$ROOT/Administration centrale/Commissions/Commission 1/transmission" \ + "$ROOT/Administration centrale/Commissions/Commission 2" + link "$ROOT/Administration centrale/Commissions/Commission 2/transmission" \ + "$ROOT/Administration centrale/Commissions/Commission 3" + link "$ROOT/Administration centrale/Commissions/Commission 3/transmission" \ + "$ROOT/Administration centrale/Commissions/Commission 1" + + # 5) Formulaires → Tampons → Cerfas → Formulaires + link "$ROOT/Administration centrale/Ministère des Papiers/Direction des Formulaires/Tampon nécessaire" \ + "$ROOT/Administration centrale/Hôtel du Roi/Grande Chancellerie/Bureau des Tampons" + link "$ROOT/Offices/Office des Cerfas/Dépôt" \ + "$ROOT/Administration centrale/Ministère des Papiers/Direction des Formulaires" + + # 6) Labyrinthe de l’Office unique du Tampon + link "$ROOT/Offices/Office unique du Tampon/Guichet/Orientation" \ + "$ROOT/Offices/Office unique du Tampon/Contre-guichet" + link "$ROOT/Offices/Office unique du Tampon/Contre-guichet/Formulaire de Retour" \ + "$ROOT/Offices/Office unique du Tampon/Service du Retour" + link "$ROOT/Offices/Office unique du Tampon/Service du Retour/Retour au début" \ + "$ROOT/Offices/Office unique du Tampon/Guichet" + + # 7) Ponts Académie ↔ Administration + link "$ROOT/Académie de Géo-mancie/Secrétariat des Études/Bureau des Inscriptions/Validation préfectorale" \ + "$ROOT/Administration centrale/Préfecture du Royaume" + link "$ROOT/Administration centrale/Ministère des Ponts et Chemins/Bureau des Montages/Stage obligatoire à l'Académie" \ + "$ROOT/Académie de Géo-mancie/Départements/Cartographie Éthérique/Labos" + link "$ROOT/Administration centrale/Archives/Passerelle vers la Bibliothèque des Cartes Impossibles" \ + "$ROOT/Académie de Géo-mancie/Bibliothèque des Cartes Impossibles/Rez-de-chaussée/Index mouvant" + link "$ROOT/Académie de Géo-mancie/Institut des Flux et Contre-Flux/Procédure de validation des flux" \ + "$ROOT/Administration centrale/Cour des Comptes et Demi Comptes/Greffe" + + echo "$(eval_gettext "✅ Kingdom of Bordereau VI the Stamped: quirky objects, Academy of Geo-mancy and administrative labyrinths created (without villages).")" +} diff --git a/missions/lvm/00_shared/lore_generator_en.sh b/missions/lvm/00_shared/lore_generator_en.sh new file mode 100644 index 000000000..6a441579d --- /dev/null +++ b/missions/lvm/00_shared/lore_generator_en.sh @@ -0,0 +1,362 @@ +#!/usr/bin/env bash + +# Main lore generation function ————————————————————————————————————————————— +generate_lore() { + + # Helpers ———————————————————————————————————————————————————————————————— + mkd() { + mkdir -p "$1"; + } + + link() { + local dest="$1"; + local target="$2 # 1) "Unique counter" ↔ "Waitin # 6) Unique Stamp Office labyrinth + link "$ROOT/$(eval_gettext "Offices")/$(eval_gettext "Unique Stamp Office")/$(eval_gettext "Counter")/$(eval_gettext "Orientation")" \ + "$ROOT/$(eval_gettext "Offices")/$(eval_gettext "Unique Stamp Office")/$(eval_gettext "Counter-counter")" + link "$ROOT/$(eval_gettext "Offices")/$(eval_gettext "Unique Stamp Office")/$(eval_gettext "Counter-counter")/$(eval_gettext "Return Form")" \ + "$ROOT/$(eval_gettext "Offices")/$(eval_gettext "Unique Stamp Office")/$(eval_gettext "Return Service")" + link "$ROOT/$(eval_gettext "Offices")/$(eval_gettext "Unique Stamp Office")/$(eval_gettext "Return Service")/$(eval_gettext "Return to beginning")" \ + "$ROOT/$(eval_gettext "Offices")/$(eval_gettext "Unique Stamp Office")/$(eval_gettext "Counter")" + link "$ROOT/$(eval_gettext "Central Administration")/$(eval_gettext "Unique counter")" \ + "$ROOT/$(eval_gettext "Central Administration")/$(eval_gettext "King's Hotel")/$(eval_gettext "Antechamber")/$(eval_gettext "Waiting Room")" + link "$ROOT/$(eval_gettext "Central Administration")/$(eval_gettext "King's Hotel")/$(eval_gettext "Antechamber")/$(eval_gettext "Waiting Room")/$(eval_gettext "return to counter")" \ + "$ROOT/$(eval_gettext "Central Administration")/$(eval_gettext "Unique counter")" mkd "$(dirname "$dest")"; + ln -sfn "$target" "$dest"; + } + + writ() { # writ "path" "content" + local path="$1"; mkd "$(dirname "$path")" + printf "%s\n" "$2" > "$path" + } + + heredoc() { # heredoc "path" <<'EOF' ... EOF + local path="$1"; mkd "$(dirname "$path")"; cat > "$path" + } + + echo "$(eval_gettext "🖋️ Generating lore for the Kingdom of Bordereau VI the Stamped (edition without villages)...")" + ROOT="$(eval_gettext "\$GSH_HOME/Kingdom")" + + # Castle ———————————————————————————————————————————————————————————————— + mkd "$ROOT/$(eval_gettext "Castle")/$(eval_gettext "Main Tower")/$(eval_gettext "First Floor")/$(eval_gettext "Second Floor")/$(eval_gettext "Tower Summit")" + mkd "$ROOT/$(eval_gettext "Castle")/$(eval_gettext "Objects")" + writ "$ROOT/$(eval_gettext "Castle")/$(eval_gettext "Main Tower")/$(eval_gettext "First Floor")/$(eval_gettext "Concierge's Journal.txt")" \ + "$(eval_gettext "Day 34: someone moved the audience hourglass. Time is now ahead of itself.")" + writ "$ROOT/$(eval_gettext "Castle")/$(eval_gettext "Objects")/$(eval_gettext "Royal Stamp (unicorn wood).txt")" \ + "$(eval_gettext "Usage: affix. Side effect: instant respect.")" + writ "$ROOT/$(eval_gettext "Castle")/$(eval_gettext "Objects")/$(eval_gettext "Key to the key drawer.txt")" \ + "$(eval_gettext "Only opens keys. For drawers, provide another form.")" + writ "$ROOT/$(eval_gettext "Castle")/$(eval_gettext "Objects")/$(eval_gettext "Parade Paraph (too heavy to serve).txt")" \ + "$(eval_gettext "Ceremonial object. Appears more official than the law.")" + + writ "$ROOT/$(eval_gettext "Castle")/$(eval_gettext "Official Portraits")/$(eval_gettext "Bordereau VI the Stamped.txt")" \ + "$(eval_gettext "King, lover of clear procedures and opaque stamps. Motto: \"Who stamps reigns.\"")" + + # Central Administration —————————————————————————————————————————————— + mkd "$ROOT/$(eval_gettext "Central Administration")/$(eval_gettext "King's Hotel")/$(eval_gettext "Great Chancellery")/$(eval_gettext "Stamps Office")" + mkd "$ROOT/$(eval_gettext "Central Administration")/$(eval_gettext "King's Hotel")/$(eval_gettext "Antechamber")/$(eval_gettext "Waiting Room")" + mkd "$ROOT/$(eval_gettext "Central Administration")/$(eval_gettext "Ministry of Papers")/$(eval_gettext "Forms Directorate")" + mkd "$ROOT/$(eval_gettext "Central Administration")/$(eval_gettext "Ministry of Papers")/$(eval_gettext "Duplicate Service")" + mkd "$ROOT/$(eval_gettext "Central Administration")/$(eval_gettext "Ministry of Bridges and Roads")/$(eval_gettext "Mounting Office")" + mkd "$ROOT/$(eval_gettext "Central Administration")/$(eval_gettext "Ministry of Rumors")/$(eval_gettext "Whispers Cabinet")" + mkd "$ROOT/$(eval_gettext "Central Administration")/$(eval_gettext "Court of Accounts and Half Accounts")/$(eval_gettext "Registry")" + mkd "$ROOT/$(eval_gettext "Central Administration")/$(eval_gettext "Kingdom Prefecture")/$(eval_gettext "Counter A-M")" + mkd "$ROOT/$(eval_gettext "Central Administration")/$(eval_gettext "Kingdom Prefecture")/$(eval_gettext "Counter N-Z")" + mkd "$ROOT/$(eval_gettext "Central Administration")/$(eval_gettext "Archives")/$(eval_gettext "Shelving")/$(eval_gettext "A to Z")" + mkd "$ROOT/$(eval_gettext "Central Administration")/$(eval_gettext "Commissions")/$(eval_gettext "Commission 1")" + mkd "$ROOT/$(eval_gettext "Central Administration")/$(eval_gettext "Commissions")/$(eval_gettext "Commission 2")" + mkd "$ROOT/$(eval_gettext "Central Administration")/$(eval_gettext "Commissions")/$(eval_gettext "Commission 3")" + + # Regulations, circulars and whispers ———————————————————————————————————— + writ "$ROOT/$(eval_gettext "Central Administration")/$(eval_gettext "King's Hotel")/$(eval_gettext "Antechamber")/$(eval_gettext "Waiting Room")/$(eval_gettext "Number 0001.txt")" \ + "$(eval_gettext "You will be called after number 0000 (when it exists).")" + + heredoc "$ROOT/$(eval_gettext "Central Administration")/$(eval_gettext "King's Hotel")/$(eval_gettext "Great Chancellery")/$(eval_gettext "Stamps Office")/$(eval_gettext "Internal Regulations.md")" <<'EOF' +# $(eval_gettext "Internal Regulations of the Stamps Office") +1. $(eval_gettext "Any request must be stamped before being submitted to be stamped.") +2. $(eval_gettext "Stamps are not to be stamped, except in case of emergency (form \"URG-URG\").") +3. $(eval_gettext "Employees must soothe the feathered stamp every morning.") +EOF + + writ "$ROOT/$(eval_gettext "Central Administration")/$(eval_gettext "Ministry of Papers")/$(eval_gettext "Forms Directorate")/$(eval_gettext "Circular Procedure n° ∞.md")" \ + "$(eval_gettext "Step 1: consult Step 2. Step 2: consult Step 1. (Stamp required at each consultation.)")" + + writ "$ROOT/$(eval_gettext "Central Administration")/$(eval_gettext "Ministry of Rumors")/$(eval_gettext "Whispers Cabinet")/$(eval_gettext "Whisper of the day.txt")" \ + "$(eval_gettext "They say the pile of files is taller seen from below.")" + + writ "$ROOT/$(eval_gettext "Central Administration")/$(eval_gettext "Court of Accounts and Half Accounts")/$(eval_gettext "Registry")/$(eval_gettext "Half-receipt (to complete).txt")" \ + "$(eval_gettext "Please present the other half to prove the existence of this one.")" + + writ "$ROOT/$(eval_gettext "Central Administration")/$(eval_gettext "Archives")/$(eval_gettext "Shelving")/$(eval_gettext "A to Z")/$(eval_gettext "Index (partial).txt")" \ + "$(eval_gettext "Apricots (no); Certificates (yes); Warnings (maybe). See also: Zebras (filed under A by mistake).")" + + # Bizarre objects distributed in services ————————————————————————————————— + writ "$ROOT/$(eval_gettext "Central Administration")/$(eval_gettext "King's Hotel")/$(eval_gettext "Antechamber")/$(eval_gettext "Waiting Room")/$(eval_gettext "Plastic plant (badge holder).txt")" \ + "$(eval_gettext "Seniority: 12 years. Acquired rights: priority at the counter.")" + writ "$ROOT/$(eval_gettext "Central Administration")/$(eval_gettext "King's Hotel")/$(eval_gettext "Great Chancellery")/$(eval_gettext "Stamps Office")/$(eval_gettext "Quantum stamp.txt")" \ + "$(eval_gettext "Affixes and removes the seal simultaneously until observed by a superior.")" + writ "$ROOT/$(eval_gettext "Central Administration")/$(eval_gettext "King's Hotel")/$(eval_gettext "Great Chancellery")/$(eval_gettext "Stamps Office")/$(eval_gettext "Bottomless inkwell.txt")" \ + "$(eval_gettext "Structural deficit. Voted every year by acclamation.")" + writ "$ROOT/$(eval_gettext "Central Administration")/$(eval_gettext "Ministry of Papers")/$(eval_gettext "Forms Directorate")/$(eval_gettext "Random forms dispenser.txt")" \ + "$(eval_gettext "Spits out a different CERFA with each swear word. Doesn't take change.")" + writ "$ROOT/$(eval_gettext "Central Administration")/$(eval_gettext "Ministry of Papers")/$(eval_gettext "Duplicate Service")/$(eval_gettext "Photocopy of an unfindable original copy.txt")" \ + "$(eval_gettext "Authenticated by the absence of the original.")" + writ "$ROOT/$(eval_gettext "Central Administration")/$(eval_gettext "Ministry of Bridges and Roads")/$(eval_gettext "Mounting Office")/$(eval_gettext "Vertical bubble level.txt")" \ + "$(eval_gettext "Indicates the moral inclination of the project.")" + writ "$ROOT/$(eval_gettext "Central Administration")/$(eval_gettext "Ministry of Rumors")/$(eval_gettext "Whispers Cabinet")/$(eval_gettext "Whispering microphone.txt")" \ + "$(eval_gettext "Repeats \"apparently\" with authority.")" + writ "$ROOT/$(eval_gettext "Central Administration")/$(eval_gettext "Court of Accounts and Half Accounts")/$(eval_gettext "Registry")/$(eval_gettext "Digital abacus (unplugged).txt")" \ + "$(eval_gettext "Optimizes invisible savings.")" + writ "$ROOT/$(eval_gettext "Central Administration")/$(eval_gettext "Kingdom Prefecture")/$(eval_gettext "Counter A-M")/$(eval_gettext "Ticket regurgitator automaton.txt")" \ + "$(eval_gettext "Returns a ticket older than yours.")" + writ "$ROOT/$(eval_gettext "Central Administration")/$(eval_gettext "Kingdom Prefecture")/$(eval_gettext "Counter N-Z")/$(eval_gettext "Queue line snake rope.txt")" \ + "$(eval_gettext "Lengthens as soon as you think you're reaching the goal.")" + writ "$ROOT/$(eval_gettext "Central Administration")/$(eval_gettext "Archives")/$(eval_gettext "Shelving")/$(eval_gettext "A to Z")/$(eval_gettext "Schrödinger's file (filed and lost).txt")" \ + "$(eval_gettext "Exists as long as no one consults it.")" + + # Commissions (with members + objects) —————————————————————————————————————— + heredoc "$ROOT/$(eval_gettext "Central Administration")/$(eval_gettext "Commissions")/$(eval_gettext "Commission 1")/$(eval_gettext "Member list.txt")" <<'EOF' +- $(eval_gettext "Dame Pénélope de la Punaise (president)") +- $(eval_gettext "Sire Fernand du Parapheur (vice-president)") +- $(eval_gettext "Master Loris des Liasses (rapporteur)") +EOF + writ "$ROOT/$(eval_gettext "Central Administration")/$(eval_gettext "Commissions")/$(eval_gettext "Commission 1")/$(eval_gettext "Session bell (mute).txt")" \ + "$(eval_gettext "Signals the end of debate as soon as it begins.")" + + heredoc "$ROOT/$(eval_gettext "Central Administration")/$(eval_gettext "Commissions")/$(eval_gettext "Commission 2")/$(eval_gettext "Member list.txt")" <<'EOF' +- $(eval_gettext "Captain Clotaire du Cachet") +- $(eval_gettext "Demoiselle Agathe du Bordereau") +- $(eval_gettext "Brother Nestor des Annexes") +EOF + writ "$ROOT/$(eval_gettext "Central Administration")/$(eval_gettext "Commissions")/$(eval_gettext "Commission 2")/$(eval_gettext "Folding chair (unfolded by decree).txt")" \ + "$(eval_gettext "Only folds to written injunctions.")" + + heredoc "$ROOT/$(eval_gettext "Central Administration")/$(eval_gettext "Commissions")/$(eval_gettext "Commission 3")/$(eval_gettext "Member list.txt")" <<'EOF' +- $(eval_gettext "Stewardess Salomé de la Signature") +- $(eval_gettext "Registrar Octave de l'Agrafe") +- $(eval_gettext "Sergeant Éline de la Reliure") +EOF + writ "$ROOT/$(eval_gettext "Central Administration")/$(eval_gettext "Commissions")/$(eval_gettext "Commission 3")/$(eval_gettext "Protocol stapler (without staples).txt")" \ + "$(eval_gettext "Brings together without attaching.")" + + # ————————————————————————————————————————————————————————————————————————————— + # ACADEMY OF GEO-MANCY (new section) + # ————————————————————————————————————————————————————————————————————————————— + mkd "$ROOT/$(eval_gettext "Academy of Geo-mancy")/$(eval_gettext "Study Secretariat")/$(eval_gettext "Registration Office")" + mkd "$ROOT/$(eval_gettext "Academy of Geo-mancy")/$(eval_gettext "Study Secretariat")/$(eval_gettext "Retake Service")" + mkd "$ROOT/$(eval_gettext "Academy of Geo-mancy")/$(eval_gettext "Library of Impossible Maps")/$(eval_gettext "Contradictory Atlases Room")" + mkd "$ROOT/$(eval_gettext "Academy of Geo-mancy")/$(eval_gettext "Library of Impossible Maps")/$(eval_gettext "Ground Floor")/$(eval_gettext "Moving Index")" + mkd "$ROOT/$(eval_gettext "Academy of Geo-mancy")/$(eval_gettext "Departments")/$(eval_gettext "Etheric Cartography")/$(eval_gettext "Labs")" + mkd "$ROOT/$(eval_gettext "Academy of Geo-mancy")/$(eval_gettext "Departments")/$(eval_gettext "Stamp Topology")/$(eval_gettext "Labs")" + mkd "$ROOT/$(eval_gettext "Academy of Geo-mancy")/$(eval_gettext "Departments")/$(eval_gettext "Forms Geology")/$(eval_gettext "Labs")" + mkd "$ROOT/$(eval_gettext "Academy of Geo-mancy")/$(eval_gettext "Institute of Flows and Counter-Flows")/$(eval_gettext "Amphitheater ∮")" + mkd "$ROOT/$(eval_gettext "Academy of Geo-mancy")/$(eval_gettext "Observatory of Administrative Lines")/$(eval_gettext "Meridians Terrace")" + mkd "$ROOT/$(eval_gettext "Academy of Geo-mancy")/$(eval_gettext "Competitions and Aggregations")/$(eval_gettext "Examination Room")" + mkd "$ROOT/$(eval_gettext "Academy of Geo-mancy")/$(eval_gettext "Tools Museum")/$(eval_gettext "Instruments")" + + # Regulations and presentation + heredoc "$ROOT/$(eval_gettext "Academy of Geo-mancy")/$(eval_gettext "Study Secretariat")/$(eval_gettext "Student guide.md")" <<'EOF' +# $(eval_gettext "Geo-mantic student guide") +- $(eval_gettext "Cardinal principle: every territory is a matter of paper.") +- $(eval_gettext "ECTS credits mean \"Echelons, Cachets, Tampons, Signatures\".") +- $(eval_gettext "Any valid map must include at least one administrative dead end.") +EOF + + writ "$ROOT/$(eval_gettext "Academy of Geo-mancy")/$(eval_gettext "Study Secretariat")/$(eval_gettext "Registration Office")/$(eval_gettext "Opening hours.txt")" \ + "$(eval_gettext "Open on even working days, except when it's odd.")" + + # Library and objects + writ "$ROOT/$(eval_gettext "Academy of Geo-mancy")/$(eval_gettext "Library of Impossible Maps")/$(eval_gettext "Contradictory Atlases Room")/$(eval_gettext "Flat atlas of the round Earth.txt")" \ + "$(eval_gettext "Revised edition: now spheri-flat according to decree.")" + writ "$ROOT/$(eval_gettext "Academy of Geo-mancy")/$(eval_gettext "Library of Impossible Maps")/$(eval_gettext "Ground Floor")/$(eval_gettext "Moving Index")/$(eval_gettext "User manual.txt")" \ + "$(eval_gettext "To find A, look for Z, then return to A via Beta corridor.")" + + # Departments — teachers, courses, objects + heredoc "$ROOT/$(eval_gettext "Academy of Geo-mancy")/$(eval_gettext "Departments")/$(eval_gettext "Etheric Cartography")/$(eval_gettext "Program.md")" <<'EOF' +## $(eval_gettext "Etheric Cartography — Program") +- $(eval_gettext "Introduction to trace-therapy") +- $(eval_gettext "Variable geometry of moral borders") +- $(eval_gettext "Seminar: The hesitant compass") +EOF + writ "$ROOT/$(eval_gettext "Academy of Geo-mancy")/$(eval_gettext "Departments")/$(eval_gettext "Etheric Cartography")/$(eval_gettext "Labs")/$(eval_gettext "Indecisive compass.txt")" \ + "$(eval_gettext "Turns until the presence of a department head.")" + + heredoc "$ROOT/$(eval_gettext "Academy of Geo-mancy")/$(eval_gettext "Departments")/$(eval_gettext "Stamp Topology")/$(eval_gettext "Program.md")" <<'EOF' +## $(eval_gettext "Stamp Topology — Program") +- $(eval_gettext "Non-commutative seal groups") +- $(eval_gettext "Homotopy of validation circuits") +- $(eval_gettext "Seminar: Torus of waiting lines") +EOF + writ "$ROOT/$(eval_gettext "Academy of Geo-mancy")/$(eval_gettext "Departments")/$(eval_gettext "Stamp Topology")/$(eval_gettext "Labs")/$(eval_gettext "Möbius stamp.txt")" \ + "$(eval_gettext "One side, two lines, no exit.")" + + heredoc "$ROOT/$(eval_gettext "Academy of Geo-mancy")/$(eval_gettext "Departments")/$(eval_gettext "Forms Geology")/$(eval_gettext "Program.md")" <<'EOF' +## $(eval_gettext "Forms Geology — Program") +- $(eval_gettext "Stratigraphy of annexes") +- $(eval_gettext "Metamorphism under paraph") +- $(eval_gettext "Seminar: Version fossils") +EOF + writ "$ROOT/$(eval_gettext "Academy of Geo-mancy")/$(eval_gettext "Departments")/$(eval_gettext "Forms Geology")/$(eval_gettext "Labs")/$(eval_gettext "Stratified section of a file.txt")" \ + "$(eval_gettext "Observe without disturbing the fragile \"missing pieces\" layer.")" + + # Institute of Flows + writ "$ROOT/$(eval_gettext "Academy of Geo-mancy")/$(eval_gettext "Institute of Flows and Counter-Flows")/$(eval_gettext "Amphitheater ∮")/$(eval_gettext "Self-erasing blackboard.txt")" \ + "$(eval_gettext "Erases demonstrations just before the conclusion.")" + + # Observatory + writ "$ROOT/$(eval_gettext "Academy of Geo-mancy")/$(eval_gettext "Observatory of Administrative Lines")/$(eval_gettext "Meridians Terrace")/$(eval_gettext "Paperwork telescope.txt")" \ + "$(eval_gettext "Only magnifies illegible signatures.")" + + # Tools Museum + writ "$ROOT/$(eval_gettext "Academy of Geo-mancy")/$(eval_gettext "Tools Museum")/$(eval_gettext "Instruments")/$(eval_gettext "Deadline drawing board.txt")" \ + "$(eval_gettext "Allows adding a calendar month to any natural delay.")" + + # Competitions — tests, subjects, results + heredoc "$ROOT/$(eval_gettext "Academy of Geo-mancy")/$(eval_gettext "Competitions and Aggregations")/$(eval_gettext "Examination Room")/$(eval_gettext "Sample subject.md")" <<'EOF' +# $(eval_gettext "Administrative Geo-mancy Aggregation — Sample subject") +1) $(eval_gettext "Map a mobile border between two closed counters.") +2) $(eval_gettext "Demonstrate the existence of a shortcut longer than the official detour.") +3) $(eval_gettext "Stamp the hypothesis, then remove it cleanly.") +EOF + writ "$ROOT/$(eval_gettext "Academy of Geo-mancy")/$(eval_gettext "Competitions and Aggregations")/$(eval_gettext "Examination Room")/$(eval_gettext "Approved cheat sheet (blank).txt")" \ + "$(eval_gettext "To be filled only inadvertently.")" + + # Specialized offices —————————————————————————————————————————————————————— + mkd "$ROOT/$(eval_gettext "Offices")/$(eval_gettext "Unique Stamp Office")/$(eval_gettext "Counter")" + mkd "$ROOT/$(eval_gettext "Offices")/$(eval_gettext "Unique Stamp Office")/$(eval_gettext "Counter-counter")" + mkd "$ROOT/$(eval_gettext "Offices")/$(eval_gettext "Unique Stamp Office")/$(eval_gettext "Return Service")" + mkd "$ROOT/$(eval_gettext "Offices")/$(eval_gettext "Cerfas Office")/$(eval_gettext "CERFA 13B")" + mkd "$ROOT/$(eval_gettext "Offices")/$(eval_gettext "Cerfas Office")/$(eval_gettext "CERFA 13C")" + mkd "$ROOT/$(eval_gettext "Offices")/$(eval_gettext "Complaints and Complaint Requests Office")" + + writ "$ROOT/$(eval_gettext "Offices")/$(eval_gettext "Complaints and Complaint Requests Office")/$(eval_gettext "Example complaint (template).txt")" \ + "$(eval_gettext "Subject: complaint against the complaint form, too complaining.")" + writ "$ROOT/$(eval_gettext "Offices")/$(eval_gettext "Unique Stamp Office")/$(eval_gettext "Counter")/$(eval_gettext "Orientation brochure.txt")" \ + "$(eval_gettext "For any question, address the Counter-counter. To contest: Return Service.")" + writ "$ROOT/$(eval_gettext "Offices")/$(eval_gettext "Cerfas Office")/$(eval_gettext "CERFA 13B")/$(eval_gettext "User manual.txt")" \ + "$(eval_gettext "Fill in blue. Except if you don't have blue, in which case: start over in blue.")" + + # Office objects + writ "$ROOT/$(eval_gettext "Offices")/$(eval_gettext "Unique Stamp Office")/$(eval_gettext "Counter")/$(eval_gettext "Administrative hourglass set to \"in progress\".txt")" \ + "$(eval_gettext "Never empties completely, in accordance with procedure.")" + writ "$ROOT/$(eval_gettext "Offices")/$(eval_gettext "Unique Stamp Office")/$(eval_gettext "Counter-counter")/$(eval_gettext "Conditional ink pen.txt")" \ + "$(eval_gettext "Writes only after the stamp, never before.")" + writ "$ROOT/$(eval_gettext "Offices")/$(eval_gettext "Unique Stamp Office")/$(eval_gettext "Return Service")/$(eval_gettext "Bottomless complaints box.txt")" \ + "$(eval_gettext "All claims find their downfall there.")" + writ "$ROOT/$(eval_gettext "Offices")/$(eval_gettext "Cerfas Office")/$(eval_gettext "CERFA 13C")/$(eval_gettext "Self-referenced form.txt")" \ + "$(eval_gettext "Please attach CERFA 13C to this CERFA 13C.")" + writ "$ROOT/$(eval_gettext "Offices")/$(eval_gettext "Complaints and Complaint Requests Office")/$(eval_gettext "Whispering megaphone.txt")" \ + "$(eval_gettext "Amplifies indignant silences.")" + + # Kafkaesque journey in 10 steps (loop assured) ———————————————————————————— + steps=( + "$(eval_gettext "Public Reception")" + "$(eval_gettext "Ticket Distribution")" + "$(eval_gettext "Provisional Orientation")" + "$(eval_gettext "Preliminary Pre-validation")" + "$(eval_gettext "Control Compliance Control")" + "$(eval_gettext "Internal Prefecture Visa")" + "$(eval_gettext "Intent Stamping")" + "$(eval_gettext "Verification Verification")" + "$(eval_gettext "Penultimate Step Counter-Validation")" + "$(eval_gettext "Counter No. 0")" + ) + base="$ROOT/$(eval_gettext "Central Administration")/$(eval_gettext "Standard Administrative Path")" + prev="" + for s in "${steps[@]}"; do + mkd "$base/$s" + writ "$base/$s/$(eval_gettext "Instructions.txt")" "$(eval_gettext "Present the document obtained in the previous step.")" + # Add an absurd object specific to the step + case "$s" in + "$(eval_gettext "Public Reception")") + writ "$base/$s/$(eval_gettext "Motivating ceiling light.txt")" "$(eval_gettext "Displays \"Almost done!\" upon arrival.")" + ;; + "$(eval_gettext "Ticket Distribution")") + writ "$base/$s/$(eval_gettext "Imaginary number ticket.txt")" "$(eval_gettext "Served after the real ones, before the priority ones.")" + ;; + "$(eval_gettext "Provisional Orientation")") + writ "$base/$s/$(eval_gettext "Administrative compass.txt")" "$(eval_gettext "Always points to the opposite counter.")" + ;; + "$(eval_gettext "Preliminary Pre-validation")") + writ "$base/$s/$(eval_gettext "Shadow stamp.txt")" "$(eval_gettext "Leaves an invisible but regulatory trace.")" + ;; + "$(eval_gettext "Control Compliance Control")") + writ "$base/$s/$(eval_gettext "Checklist checklist.txt")" "$(eval_gettext "Last item: check this checklist.")" + ;; + "$(eval_gettext "Internal Prefecture Visa")") + writ "$base/$s/$(eval_gettext "Swinging door (leads nowhere).txt")" "$(eval_gettext "Approved for back-and-forth.")" + ;; + "$(eval_gettext "Intent Stamping")") + writ "$base/$s/$(eval_gettext "Tacit intentions form.txt")" "$(eval_gettext "To be filled without writing anything.")" + ;; + "$(eval_gettext "Verification Verification")") + writ "$base/$s/$(eval_gettext "Protocol magnifying glass.txt")" "$(eval_gettext "Magnifies paperwork, reduces hope.")" + ;; + "$(eval_gettext "Penultimate Step Counter-Validation")") + writ "$base/$s/$(eval_gettext "Contradictory seal.txt")" "$(eval_gettext "Validates and invalidates simultaneously.")" + ;; + "$(eval_gettext "Counter No. 0")") + writ "$base/$s/$(eval_gettext "Impossible bell.txt")" "$(eval_gettext "Ring scheduled for next budget year.")" + ;; + esac + + if [[ -n "${prev}" ]]; then + link "$base/$prev/$(eval_gettext "Next step")" "$base/$s" + fi + prev="$s" + done + # loop to the beginning + link "$base/$(eval_gettext "Counter No. 0")/$(eval_gettext "Return to beginning")" "$base/$(eval_gettext "Public Reception")" + + # Absurd inter-service links ———————————————————————————————————————————— + # 1) “Guichet unique” ↔ “Salle d'attente” + link "$ROOT/Administration centrale/Guichet unique" \ + "$ROOT/Administration centrale/Hôtel du Roi/Antichambre/Salle d'attente" + link "$ROOT/Administration centrale/Hôtel du Roi/Antichambre/Salle d'attente/retour au guichet" \ + "$ROOT/Administration centrale/Guichet unique" + + # 2) Stamps Office ↔ Duplicate Service + link "$ROOT/$(eval_gettext "Central Administration")/$(eval_gettext "King's Hotel")/$(eval_gettext "Great Chancellery")/$(eval_gettext "Stamps Office")/$(eval_gettext "Duplicate requests")" \ + "$ROOT/$(eval_gettext "Central Administration")/$(eval_gettext "Ministry of Papers")/$(eval_gettext "Duplicate Service")" + link "$ROOT/$(eval_gettext "Central Administration")/$(eval_gettext "Ministry of Papers")/$(eval_gettext "Duplicate Service")/$(eval_gettext "Final validation")" \ + "$ROOT/$(eval_gettext "Central Administration")/$(eval_gettext "King's Hotel")/$(eval_gettext "Great Chancellery")/$(eval_gettext "Stamps Office")" + + # 3) Prefecture: A-M ↔ N-Z + link "$ROOT/$(eval_gettext "Central Administration")/$(eval_gettext "Kingdom Prefecture")/$(eval_gettext "Counter A-M")/$(eval_gettext "next counter")" \ + "$ROOT/$(eval_gettext "Central Administration")/$(eval_gettext "Kingdom Prefecture")/$(eval_gettext "Counter N-Z")" + link "$ROOT/$(eval_gettext "Central Administration")/$(eval_gettext "Kingdom Prefecture")/$(eval_gettext "Counter N-Z")/$(eval_gettext "referral")" \ + "$ROOT/$(eval_gettext "Central Administration")/$(eval_gettext "Kingdom Prefecture")/$(eval_gettext "Counter A-M")" + + # 4) Commissions in circle + link "$ROOT/$(eval_gettext "Central Administration")/$(eval_gettext "Commissions")/$(eval_gettext "Commission 1")/$(eval_gettext "transmission")" \ + "$ROOT/$(eval_gettext "Central Administration")/$(eval_gettext "Commissions")/$(eval_gettext "Commission 2")" + link "$ROOT/$(eval_gettext "Central Administration")/$(eval_gettext "Commissions")/$(eval_gettext "Commission 2")/$(eval_gettext "transmission")" \ + "$ROOT/$(eval_gettext "Central Administration")/$(eval_gettext "Commissions")/$(eval_gettext "Commission 3")" + link "$ROOT/$(eval_gettext "Central Administration")/$(eval_gettext "Commissions")/$(eval_gettext "Commission 3")/$(eval_gettext "transmission")" \ + "$ROOT/$(eval_gettext "Central Administration")/$(eval_gettext "Commissions")/$(eval_gettext "Commission 1")" + + # 5) Forms → Stamps → Cerfas → Forms + link "$ROOT/$(eval_gettext "Central Administration")/$(eval_gettext "Ministry of Papers")/$(eval_gettext "Forms Directorate")/$(eval_gettext "Stamp required")" \ + "$ROOT/$(eval_gettext "Central Administration")/$(eval_gettext "King's Hotel")/$(eval_gettext "Great Chancellery")/$(eval_gettext "Stamps Office")" + link "$ROOT/$(eval_gettext "Offices")/$(eval_gettext "Cerfas Office")/$(eval_gettext "Deposit")" \ + "$ROOT/$(eval_gettext "Central Administration")/$(eval_gettext "Ministry of Papers")/$(eval_gettext "Forms Directorate")" + + # 6) Labyrinthe de l’Office unique du Tampon + link "$ROOT/Offices/Office unique du Tampon/Guichet/Orientation" \ + "$ROOT/Offices/Office unique du Tampon/Contre-guichet" + link "$ROOT/Offices/Office unique du Tampon/Contre-guichet/Formulaire de Retour" \ + "$ROOT/Offices/Office unique du Tampon/Service du Retour" + link "$ROOT/Offices/Office unique du Tampon/Service du Retour/Retour au début" \ + "$ROOT/Offices/Office unique du Tampon/Guichet" + + # 7) Academy ↔ Administration bridges + link "$ROOT/$(eval_gettext "Academy of Geo-mancy")/$(eval_gettext "Study Secretariat")/$(eval_gettext "Registration Office")/$(eval_gettext "Prefecture validation")" \ + "$ROOT/$(eval_gettext "Central Administration")/$(eval_gettext "Kingdom Prefecture")" + link "$ROOT/$(eval_gettext "Central Administration")/$(eval_gettext "Ministry of Bridges and Roads")/$(eval_gettext "Mounting Office")/$(eval_gettext "Mandatory Academy internship")" \ + "$ROOT/$(eval_gettext "Academy of Geo-mancy")/$(eval_gettext "Departments")/$(eval_gettext "Etheric Cartography")/$(eval_gettext "Labs")" + link "$ROOT/$(eval_gettext "Central Administration")/$(eval_gettext "Archives")/$(eval_gettext "Bridge to the Library of Impossible Maps")" \ + "$ROOT/$(eval_gettext "Academy of Geo-mancy")/$(eval_gettext "Library of Impossible Maps")/$(eval_gettext "Ground Floor")/$(eval_gettext "Moving Index")" + link "$ROOT/$(eval_gettext "Academy of Geo-mancy")/$(eval_gettext "Institute of Flows and Counter-Flows")/$(eval_gettext "Flow validation procedure")" \ + "$ROOT/$(eval_gettext "Central Administration")/$(eval_gettext "Court of Accounts and Half Accounts")/$(eval_gettext "Registry")" + + echo "$(eval_gettext "✅ Kingdom of Bordereau VI the Stamped: bizarre objects, Academy of Geo-mancy and administrative labyrinths created (without villages).")" +} diff --git a/missions/lvm/00_shared/simple_translate.py b/missions/lvm/00_shared/simple_translate.py new file mode 100644 index 000000000..e69de29bb diff --git a/missions/lvm/00_shared/static.sh b/missions/lvm/00_shared/static.sh new file mode 100644 index 000000000..ebeb22846 --- /dev/null +++ b/missions/lvm/00_shared/static.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +source "$MISSION_DIR/lore_generator.sh" + +init_world() { + #!/usr/bin/env bash + + # Create lore + generate_lore + echo "$(eval_gettext "🖋️ (Lore generation skipped for now...)")" +} + +init_world \ No newline at end of file diff --git a/missions/lvm/00_shared/translate_po.py b/missions/lvm/00_shared/translate_po.py new file mode 100644 index 000000000..e69de29bb diff --git a/missions/lvm/00_shared/utils.sh b/missions/lvm/00_shared/utils.sh new file mode 100644 index 000000000..b4ba6c824 --- /dev/null +++ b/missions/lvm/00_shared/utils.sh @@ -0,0 +1,357 @@ + +lvm_init() { + + echo "$(eval_gettext "LAST ACTION : \$LAST_ACTION")" + + # Skip initialization if last action was "check_false" + if [ "$LAST_ACTION" == "check_false" ]; then + echo "$(eval_gettext "Skipping initialization due to last action being 'check_false'.")" + return 0 + fi + + MISSION_ID=$1 + DATA_PATH="$MISSION_DIR/../00_shared/data/00/" + MISSION_DATA_PATH="$MISSION_DIR/../00_shared/data/$MISSION_ID/" + + if ! [ -e "$DATA_PATH" ] + then + DUMMY_MISSION=$(missionname "$MISSION_DIR/../00_shared/") + echo "$(eval_gettext "Dummy mission '\$DUMMY_MISSION' is required for mission \$MISSION_NB (\$MISSION_NAME).")" >&2 + unset DUMMY_MISSION + return 1 + fi + + # 1. unzip the disk images + echo "$(eval_gettext "📦 Unzipping discs...")" + echo "$(eval_gettext " unzip -o \"\$MISSION_DATA_PATH/disks.zip\" -d \"\$DATA_PATH/\"")" + unzip -o "$MISSION_DATA_PATH/disks.zip" -d "$DATA_PATH" + + DISK_1_PATH="$DATA_PATH/disk1.img" + DISK_2_PATH="$DATA_PATH/disk2.img" + + # 2. Attach image files to loop devices if not already done + if ! danger sudo losetup -j "$DISK_1_PATH" | grep -q "$DISK_1_PATH"; then + echo "$(eval_gettext "⏳ Attaching \$DISK_1_PATH to a loop device...")" + LOOP1=$(danger sudo losetup --find -P --show "$DISK_1_PATH") + echo "$(eval_gettext "\$DISK_1_PATH attached to \$LOOP1")" + else + echo "$(eval_gettext "\$DISK_1_PATH is already attached to a loop device.")" + LOOP1=$(danger sudo losetup -j "$DISK_1_PATH" | cut -d: -f1) + fi + + if ! danger sudo losetup -j "$DISK_2_PATH" | grep -q "$DISK_2_PATH"; then + echo "$(eval_gettext "⏳ Attaching \$DISK_2_PATH to a loop device...")" + LOOP2=$(danger sudo losetup --find -P --show "$DISK_2_PATH") + echo "$(eval_gettext "\$DISK_2_PATH attached to \$LOOP2")" + else + echo "$(eval_gettext "\$DISK_2_PATH is already attached to a loop device.")" + LOOP2=$(danger sudo losetup -j "$DISK_2_PATH" | cut -d: -f1) + fi + + # 3. Create aliases in /dev + danger sudo ln -sf "$LOOP1" /dev/gsh_lvm_loop1 + danger sudo ln -sf "$LOOP2" /dev/gsh_lvm_loop2 + + + # 4. Prepare devices in /dev + LOOP1_PATH="/dev/gsh_lvm_loop1" + LOOP2_PATH="/dev/gsh_lvm_loop2" + + if ! [ -e "$LOOP1_PATH" ] || ! [ -e "$LOOP2_PATH" ] + then + echo "$(eval_gettext "Loop devices \$LOOP1_PATH and \$LOOP2_PATH are required for mission \$MISSION_NB (\$MISSION_NAME).")" >&2 + return 1 + fi + + # prepare world/dev + echo "$(eval_gettext "Preparing world/dev...")" + SDBA="/dev/gsh_sda" + SDBB="/dev/gsh_sdb" + danger sudo ln -sf "$LOOP1_PATH" "$SDBA" + danger sudo ln -sf "$LOOP2_PATH" "$SDBB" + + # For mission 08, we need a third disk + if [ "$MISSION_ID" -ge "08" ] && [ "$MISSION_ID" -lt "13" ]; then + echo "$(eval_gettext "Preparing third disk for world/dev...")" + + DISK_3_PATH="$DATA_PATH/disk3.img" + if ! danger sudo losetup -j "$DISK_3_PATH" | grep -q "$DISK_3_PATH"; then + echo "$(eval_gettext "⏳ Attaching \$DISK_3_PATH to a loop device...")" + LOOP3=$(danger sudo losetup --find -P --show "$DISK_3_PATH") + echo "$(eval_gettext "\$DISK_3_PATH attached to \$LOOP3")" + else + echo "$(eval_gettext "\$DISK_3_PATH is already attached to a loop device.")" + LOOP3=$(danger sudo losetup -j "$DISK_3_PATH" | cut -d: -f1) + fi + + SDBC="/dev/gsh_sdc" + LOOP3_PATH="/dev/gsh_lvm_loop3" + danger sudo ln -sf "$LOOP3" "$LOOP3_PATH" + + danger sudo ln -sf "$LOOP3_PATH" "$SDBC" + fi + + echo "$(eval_gettext "world/dev ready")" + + # if esdea VG exists activate it + # if danger sudo vgs --noheadings -o vg_name 2>/dev/null | awk '{print $1}' | grep -qx "esdea"; then + echo "$(eval_gettext "Activating esdea VG...")" + danger sudo vgimport -y esdea + danger sudo vgchange -ay esdea + # fi + + # if esdebe VG exists activate it + # if danger sudo vgs --noheadings -o vg_name 2>/dev/null | awk '{print $1}' | grep -qx "esdebe"; then + echo "$(eval_gettext "Activating esdebe VG...")" + danger sudo vgimport -y esdebe + danger sudo vgchange -ay esdebe + # fi + + # if esdece VG exists activate it + # if danger sudo vgs --noheadings -o vg_name 2>/dev/null | awk '{print $1}' | grep -qx "esdece"; then + echo "$(eval_gettext "Activating esdece VG...")" + danger sudo vgimport -y esdece + danger sudo vgchange -ay esdece + # fi + + # if usa VG exists activate it + # if danger sudo vgs --noheadings -o vg_name 2>/dev/null | awk '{print $1}' | grep -qx "usa"; then + if [ "$MISSION_ID" != "14" ]; then + echo "$(eval_gettext "Activating usa VG...")" + danger sudo vgimport -y usa + danger sudo vgchange -ay usa + fi + # fi + + # For missions after 05, Mount villages if possible + if [ "$MISSION_ID" -gt 05 ]; then + echo "$(eval_gettext "Mounting villages...")" + mounting_villages + fi + + return 0 +} + +# Purge a given VG (remove all LVs, then the VG, then wipe its PVs). +# Usage: purge_vg +purge_vg() { + local VG="$1" + + # check VG exists + if ! danger sudo vgs --noheadings -o vg_name 2>/dev/null | awk '{print $1}' | grep -qx "$VG"; then + echo "$(eval_gettext "VG '\$VG' not found.")" + return 0 + fi + + echo "$(eval_gettext "==> Purging VG: \$VG")" + + # capture PVs belonging to this VG (before removal) + local PVS=() + mapfile -t PVS < <( + danger sudo pvs --noheadings --separator '|' -o pv_name,vg_name 2>/dev/null \ + | sed 's/^ *//; s/ *$//' \ + | awk -F'|' -v vg="$VG" '$2==vg{gsub(/^ +| +$/,"",$1); print $1}' + ) + + # deactivate and remove all LVs in the VG (best effort) + danger sudo lvchange -an "$VG" || true + local LVS=() + mapfile -t LVS < <(danger sudo lvs --noheadings -o lv_path "$VG" 2>/dev/null | awk '{print $1}') + for LV in "${LVS[@]}"; do + echo "$(eval_gettext " - Removing LV: \$LV")" + danger sudo lvremove -fy "$LV" || true + done + + # drop missing PVs (if any) then remove VG + danger sudo vgreduce --removemissing -f "$VG" || true + echo "$(eval_gettext " - Removing VG: \$VG")" + danger sudo vgremove -ff "$VG" + + # wipe PV metadata + for PV in "${PVS[@]}"; do + echo "$(eval_gettext " - Wiping PV metadata: \$PV")" + danger sudo pvremove -ff -y "$PV" || true + done + + echo "$(eval_gettext "Done purging VG: \$VG")" +} + + +lvm_cleanup() { + MISSION_ID=$1 + + echo "$(eval_gettext "GSH LAST ACTION : \$GSH_LAST_ACTION")" + export LAST_ACTION="$GSH_LAST_ACTION" + + if [ "$LAST_ACTION" == "check_false" ]; then + echo "$(eval_gettext "Skipping cleanup due to last action being 'check_false'.")" + return 0 + fi + + DATA_PATH="$MISSION_DIR/../00_shared/data/00/" + MISSION_DATA_PATH="$MISSION_DIR/../00_shared/data/$MISSION_ID/" + + # Unmount villages if mounted + unmounting_villages + + # If vgs esdea exist, purge it + echo "$(eval_gettext "Cleaning up LVM configurations... esdea")" + if danger sudo vgs --noheadings -o vg_name 2>/dev/null | awk '{print $1}' | grep -qx "esdea"; then + purge_vg "esdea" + fi + + # If vgs esdebe exist, purge it + echo "$(eval_gettext "Cleaning up LVM configurations... esdebe")" + if danger sudo vgs --noheadings -o vg_name 2>/dev/null | awk '{print $1}' | grep -qx "esdebe"; then + purge_vg "esdebe" + fi + + # If vgs esdece exist, purge it + echo "$(eval_gettext "Cleaning up LVM configurations... esdece")" + if danger sudo vgs --noheadings -o vg_name 2>/dev/null | awk '{print $1}' | grep -qx "esdece"; then + purge_vg "esdece" + fi + + # If vgs usa exist, purge it + echo "$(eval_gettext "Cleaning up LVM configurations... usa")" + if danger sudo vgs --noheadings -o vg_name 2>/dev/null | awk '{print $1}' | grep -qx "usa"; then + purge_vg "usa" + fi + + # Cleanup loop devices and disk images if needed + echo "$(eval_gettext "Cleaning up loop devices and disk images...")" + + # Detach loop devices + # Get loop path from /dev/gsh_lvm_loop1 and /dev/gsh_lvm_loop2 + LOOP1=$(readlink -f /dev/gsh_lvm_loop1) + LOOP2=$(readlink -f /dev/gsh_lvm_loop2) + LOOP3=$(readlink -f /dev/gsh_lvm_loop3) + + if [ -e "$LOOP1" ]; then + danger sudo losetup -d "$LOOP1" + fi + + if [ -e "$LOOP2" ]; then + danger sudo losetup -d "$LOOP2" + fi + + if [ -e "$LOOP3" ]; then + danger sudo losetup -d "$LOOP3" + fi + + # Remove device links + danger sudo rm -f /dev/gsh_lvm_loop1 /dev/gsh_lvm_loop2 /dev/gsh_lvm_loop3 + + # Remove world/Esdea, world/Esdebe + danger rm -rf "$GSH_HOME/Esdea/" + danger rm -rf "$GSH_HOME/Esdebe/" + + # Remove disk images + rm -f "$DATA_PATH/disk*.img" + + # Detach all unused loop devices (if any) + danger sudo losetup -D + + return 0 +} + +mounting_villages() { + + local LVS=( + "esdea/ouskelcoule" + "esdea/douskelpar" + "esdebe/grandflac" + ) + + local MOUNT_POINTS=( + "$GSH_HOME/Esdea/Ouskelcoule" + "$GSH_HOME/Esdea/Douskelpar" + "$GSH_HOME/Esdebe/Grandflac" + ) + + local i=0 + for MOUNT_POINT in "${MOUNT_POINTS[@]}"; do + # if LV does not exist , pass + if [ ! -e "/dev/${LVS[$i]}" ]; then + echo "$(eval_gettext "Logical volume /dev/\${LVS[\$i]} not found, skipping mount.")" + i=$((i + 1)) + continue + fi + + # if mount point does not exist pass + if ! [ -d "$MOUNT_POINT" ]; then + echo "$(eval_gettext "Creating mount point \$MOUNT_POINT")" + mkdir -p "$MOUNT_POINT" + fi + + # mount if not already mounted + if ! mountpoint -q "$MOUNT_POINT"; then + danger sudo mount "/dev/${LVS[$i]}" "$MOUNT_POINT" + danger sudo chown -R "$USER:$USER" "$MOUNT_POINT" + fi + i=$((i + 1)) + done + + return 0 +} + +unmounting_villages() { + local MOUNT_POINTS=( + "$GSH_HOME/Esdea/Ouskelcoule" + "$GSH_HOME/Esdea/Douskelpar" + "$GSH_HOME/Esdebe/Grandflac" + "$GSH_HOME/USA/Ouskelcoule" + "$GSH_HOME/USA/Douskelpar" + "$GSH_HOME/USA/Grandflac" + ) + + for MOUNT_POINT in "${MOUNT_POINTS[@]}"; do + if mountpoint -q "$MOUNT_POINT"; then + echo "$(eval_gettext "Unmounting \$MOUNT_POINT")" + danger sudo umount "$MOUNT_POINT" + fi + done + + return 0 +} + + +## LV TOOLS + + +# Helper: check filesystem type of a logical volume +check_lv_fs_type() { + lv_path="$1" # e.g. esdea/ouskelcoule + expected="$2" # e.g. ext4 + dev="/dev/$lv_path" + + # Read filesystem TYPE via blkid (empty if unformatted) + fstype="$(danger sudo blkid -o value -s TYPE "$dev" 2>"/dev/null")" + if [ -z "$fstype" ]; then + return 3 # special code: no filesystem + fi + + # Match expected type + if [ "$fstype" = "$expected" ]; then + return 0 + else + return 1 + fi +} + +check_lv_size() { + VG_LV="$1" # e.g. esdea/ouskelcoule + TARGET="$2" # requested size in Mo (e.g. 50) + TOLERANCE="${3:-4}" # default = 4 Mo + + # Extract actual size (in Mo, without "m") + ACTUAL="$(danger sudo lvs "$VG_LV" --noheadings -o lv_size --units m \ + | awk '{gsub(/m/,""); gsub(/^ +| +$/,""); print $1}')" + + # Compute difference + DIFF=$(awk -v act="$ACTUAL" -v tgt="$TARGET" 'BEGIN{ d=act-tgt; if(d<0)d=-d; print d }') + + # Check within tolerance + RESULT=$(awk -v diff="$DIFF" -v tol="$TOLERANCE" 'BEGIN{ exit (diff <= tol ? 0 : 1) }') + return $RESULT +} \ No newline at end of file diff --git a/missions/lvm/00_shared/village_generator.sh b/missions/lvm/00_shared/village_generator.sh new file mode 100644 index 000000000..7f98c899f --- /dev/null +++ b/missions/lvm/00_shared/village_generator.sh @@ -0,0 +1,55 @@ +#!/usr/bin/env bash +set -e + +if [ "$GSH_HOME" != "" ]; then + BASE="$GSH_HOME" +else + BASE="/var/www/html/GameShell/World" +fi + +# Définition des industries par village +declare -A colonies +colonies["Ouskelcoule"]="Esdea" +colonies["Douskelpar"]="Esdea" +colonies["Grandflac"]="Esdebe" + +declare -A industries +industries["Ouskelcoule"]="Port De Peche" +industries["Douskelpar"]="Scierie" +industries["Grandflac"]="Moulin" + +for v in "${!industries[@]}"; do + VILLAGE="$BASE/${colonies[$v]}/$v" + INDUSTRY="${industries[$v]}" + + # Dossiers + mkdir -p "$VILLAGE/$INDUSTRY" + mkdir -p "$VILLAGE/Maison Commune" + + # Industrie spécifique + case "$v" in + Ouskelcoule) + echo "$(eval_gettext "Fishing boat")" > "$VILLAGE/$INDUSTRY/barque.txt" + echo "$(eval_gettext "Fish crates")" > "$VILLAGE/$INDUSTRY/caisses.txt" + echo "$(eval_gettext "Arsène the master fisherman")" > "$VILLAGE/$INDUSTRY/habitant_arsene.txt" + ;; + Douskelpar) + echo "$(eval_gettext "Stacked logs")" > "$VILLAGE/$INDUSTRY/troncs.txt" + echo "$(eval_gettext "Giant saw")" > "$VILLAGE/$INDUSTRY/scie.txt" + echo "$(eval_gettext "Milo the sawyer")" > "$VILLAGE/$INDUSTRY/habitant_milo.txt" + ;; + Grandflac) + echo "$(eval_gettext "Grain millstone")" > "$VILLAGE/$INDUSTRY/meule.txt" + echo "$(eval_gettext "Bag of flour")" > "$VILLAGE/$INDUSTRY/farine.txt" + echo "$(eval_gettext "Jeanne the miller")" > "$VILLAGE/$INDUSTRY/habitant_jeanne.txt" + ;; + esac + + # Maison Commune (population.txt déjà existant) + echo "$(eval_gettext "Bailiff of \$v")" > "$VILLAGE/Maison Commune/habitant_bailli.txt" + echo "$(eval_gettext "Property register: +- \$INDUSTRY : collective property")" > "$VILLAGE/Maison Commune/registre_proprietes.txt" + echo "$(eval_gettext "Decisions register: +- Friday = fish day +- Quota of 1000 Ko in the Common Granary")" > "$VILLAGE/Maison Commune/registre_decisions.txt" +done diff --git a/missions/lvm/00_shared/village_generator_2.sh b/missions/lvm/00_shared/village_generator_2.sh new file mode 100644 index 000000000..8ffa7773c --- /dev/null +++ b/missions/lvm/00_shared/village_generator_2.sh @@ -0,0 +1,119 @@ +#!/usr/bin/env bash +set -e + +# Base du monde (compatible avec GSH_HOME si défini) +if [[ -n "$GSH_HOME" ]]; then + BASE="$GSH_HOME" +else + BASE="/var/www/html/GameShell/World" +fi + +# Colonies par village +declare -A colonies=( + ["Ouskelcoule"]="Esdea" + ["Douskelpar"]="Esdea" + ["Grandflac"]="Esdebe" +) + +# --- Fonction utilitaire pour écrire (et créer le dossier parent si besoin) +w() { mkdir -p "$(dirname "$1")"; echo "$2" > "$1"; } + +for v in "Ouskelcoule" "Douskelpar" "Grandflac"; do + V="$BASE/${colonies[$v]}/$v" + + # Maison Commune (population.txt supposé déjà présent) + mkdir -p "$V/Maison Commune" + w "$V/Maison Commune/habitant_bailli.txt" "$(eval_gettext "Bailiff of \$v")" + w "$V/Maison Commune/habitant_scribe.txt" "$(eval_gettext "Communal scribe")" + w "$V/Maison Commune/habitant_garde.txt" "$(eval_gettext "Rural guard")" + w "$V/Maison Commune/registre_proprietes.txt" "$(eval_gettext "See buildings below")" + w "$V/Maison Commune/registre_decisions.txt" "$(eval_gettext "Friday = fish day; Quota 1000 Ko in the Common Granary")" + + case "$v" in + # ================= OUSKELCOULE ================= + Ouskelcoule) + # 1) Port de pêche + w "$V/Port De Peche/habitant_maitre_pecheur.txt" "$(eval_gettext "Arsène the master fisherman")" + w "$V/Port De Peche/barque.txt" "$(eval_gettext "Flat-bottomed boat")" + w "$V/Port De Peche/caisses.txt" "$(eval_gettext "Fish crates (strong smell)")" + # 2) Fumoir + w "$V/Fumoir/habitant_fumeuse.txt" "$(eval_gettext "Ysée the smoker")" + w "$V/Fumoir/bois_a_fumer.txt" "$(eval_gettext "Birch bundles")" + w "$V/Fumoir/poisson_fume.txt" "$(eval_gettext "Lots of smoked herring")" + # 3) Atelier de Filets + w "$V/Atelier De Filets/habitant_filetier.txt" "$(eval_gettext "Gaston the net maker")" + w "$V/Atelier De Filets/aiguille_a_filet.txt" "$(eval_gettext "Large bone needle")" + w "$V/Atelier De Filets/chutes_de_corde.txt" "$(eval_gettext "Hemp scraps")" + # 4) Chantier Naval + w "$V/Chantier Naval/habitant_calfat.txt" "$(eval_gettext "Basile the caulker")" + w "$V/Chantier Naval/rabot.txt" "$(eval_gettext "Well-sharpened plane")" + w "$V/Chantier Naval/coque_en_cours.txt" "$(eval_gettext "Hull #12 under construction")" + # 5) Marché aux Poissons + w "$V/Marche Aux Poissons/habitant_crieuse.txt" "$(eval_gettext "Marthe the crier")" + w "$V/Marche Aux Poissons/étals.txt" "$(eval_gettext "Damp wooden stalls")" + w "$V/Marche Aux Poissons/ardoises_prix.txt" "$(eval_gettext "Daily prices in Kroutons")" + # 6) Grenier Banal + w "$V/Grenier Banal/habitant_gardien.txt" "$(eval_gettext "Prudent the guardian")" + w "$V/Grenier Banal/stock_poissons.txt" "$(eval_gettext "0 Ko (quota 1000 Ko)")" + w "$V/Grenier Banal/cachets_officiels.txt" "$(eval_gettext "Seals of the Royal Canteen Administration")" + ;; + # ================= DOUSKELPAR ================= + Douskelpar) + # 1) Scierie + w "$V/Scierie/habitant_scieur.txt" "$(eval_gettext "Milo the sawyer")" + w "$V/Scierie/troncs.txt" "$(eval_gettext "Stacked logs")" + w "$V/Scierie/scie_ruban.txt" "$(eval_gettext "Large band saw")" + # 2) Dépôt de Bois + w "$V/Depot De Bois/habitant_garde_depot.txt" "$(eval_gettext "Radegonde the guard")" + w "$V/Depot De Bois/inventaire.txt" "$(eval_gettext "2m planks, rafters, beams")" + w "$V/Depot De Bois/chariots.txt" "$(eval_gettext "Two hand carts")" + # 3) Atelier Charpente + w "$V/Atelier Charpente/habitant_charpentier.txt" "$(eval_gettext "Hugo the carpenter")" + w "$V/Atelier Charpente/tenons_mortaises.txt" "$(eval_gettext "Set of templates")" + w "$V/Atelier Charpente/bois_selectionne.txt" "$(eval_gettext "Straight-grained oak")" + # 4) Bureau du Mesurage + w "$V/Bureau Du Mesurage/habitant_mesureur.txt" "$(eval_gettext "Isaac the measurer")" + w "$V/Bureau Du Mesurage/jauges.txt" "$(eval_gettext "Graduated rods")" + w "$V/Bureau Du Mesurage/registres_bois.txt" "$(eval_gettext "Register of cut volumes")" + # 5) Port Fluvial + w "$V/Port Fluvial/habitant_batelier.txt" "$(eval_gettext "Noé the boatman")" + w "$V/Port Fluvial/cornes_de_brouillard.txt" "$(eval_gettext "Two polished horns")" + w "$V/Port Fluvial/amarrages.txt" "$(eval_gettext "Tarred ropes")" + # 6) Cantine des Bûcherons + w "$V/Cantine Des Bucherons/habitant_cuisinier.txt" "$(eval_gettext "Thibaut the cook")" + w "$V/Cantine Des Bucherons/menu_du_jour.txt" "$(eval_gettext "Beef stew, barley soup")" + w "$V/Cantine Des Bucherons/banquettes.txt" "$(eval_gettext "Heavy wooden benches")" + ;; + # ================= GRANDFLAC ================= + Grandflac) + # 1) Moulin + w "$V/Moulin/habitant_meuniere.txt" "$(eval_gettext "Jeanne the miller")" + w "$V/Moulin/meule.txt" "$(eval_gettext "Large stone millstone")" + w "$V/Moulin/courroie.txt" "$(eval_gettext "Leather belt")" + # 2) Bief + w "$V/Bief/habitant_eclusier.txt" "$(eval_gettext "Arnaud the lock keeper")" + w "$V/Bief/vannes.txt" "$(eval_gettext "Oak sluice gates")" + w "$V/Bief/niveau_eau.txt" "$(eval_gettext "Stable water level")" + # 3) Grange à Grains + w "$V/Grange A Grains/habitant_magasinier.txt" "$(eval_gettext "Pélagie the storekeeper")" + w "$V/Grange A Grains/sacs_farine.txt" "$(eval_gettext "Bags of flour (sealed)")" + w "$V/Grange A Grains/palans.txt" "$(eval_gettext "Chain hoists")" + # 4) Pont à Péage + w "$V/Pont A Peage/habitant_ponctier.txt" "$(eval_gettext "Boniface le ponctier")" + # 4) Pont à Péage + w "$V/Pont A Peage/habitant_ponctier.txt" "$(eval_gettext "Boniface the toll keeper")" + w "$V/Pont A Peage/tarifs.txt" "$(eval_gettext "Rates per cart")" + w "$V/Pont A Peage/caisse_peage.txt" "$(eval_gettext "Sealed chest")" + # 5) Atelier de Meunerie + w "$V/Atelier De Meunerie/habitant_ajusteur.txt" "$(eval_gettext "Odon the adjuster")" + w "$V/Atelier De Meunerie/jeux_de_cales.txt" "$(eval_gettext "Wedges and fine wedges")" + w "$V/Atelier De Meunerie/graisse.txt" "$(eval_gettext "Pot of grease")" + # 6) Entrepôt de Farine + w "$V/Entrepot De Farine/habitant_gardienne.txt" "$(eval_gettext "Agnès the guardian")" + w "$V/Entrepot De Farine/livre_sorties.txt" "$(eval_gettext "Daily releases")" + w "$V/Entrepot De Farine/tamis.txt" "$(eval_gettext "Spare sieves")" + ;; + esac +done + +echo "$(eval_gettext "✅ Buildings, people and objects created for Ouskelcoule, Douskelpar and Grandflac.")" diff --git a/missions/lvm/01_physical_volumes/auto.sh b/missions/lvm/01_physical_volumes/auto.sh new file mode 100644 index 000000000..c9a214f1e --- /dev/null +++ b/missions/lvm/01_physical_volumes/auto.sh @@ -0,0 +1,2 @@ +#!/usr/bin/env sh +danger sudo pvcreate "/dev/gsh_sda" "/dev/gsh_sdb" \ No newline at end of file diff --git a/missions/lvm/01_physical_volumes/check.sh b/missions/lvm/01_physical_volumes/check.sh new file mode 100644 index 000000000..32114ea9b --- /dev/null +++ b/missions/lvm/01_physical_volumes/check.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env sh + +_mission_check() ( + SDBA="/dev/gsh_sda" + SDBB="/dev/gsh_sdb" + + # 1) Vérifier que les chemins existent + if [ ! -e "$SDBA" ]; then + echo "$(eval_gettext "Device \$SDBA does not exist.")" + return 1 + fi + if [ ! -e "$SDBB" ]; then + echo "$(eval_gettext "Device \$SDBB does not exist.")" + return 1 + fi + + # 2) Vérifier que ce sont des PV LVM + # pvs renvoie un code d'erreur si l'argument n'est pas un PV + if ! danger sudo pvs --noheadings "$SDBA" >/dev/null 2>&1; then + echo "$(eval_gettext "You must still incarnate the ethereal territory of Esdea into physical lands!")" + return 1 + fi + + if ! danger sudo pvs --noheadings "$SDBB" >/dev/null 2>&1; then + echo "$(eval_gettext "You must still incarnate the ethereal territory of Esdebe into physical lands!")" + return 1 + fi + + # 3) Optionnel : afficher un résumé pour le debug (non bloquant) + # Décommentez si utile : + # pvs -o pv_name,vg_name,pv_size,vg_uuid --noheadings "$SDBA" "$SDBB" 2>/dev/null | sed 's/^ *//' + + echo "$(eval_gettext "Bravo, the ethereal territories of Esdea and Esdebe have been incarnated into physical lands!")" + return 0 +) + +_mission_check diff --git a/missions/lvm/01_physical_volumes/clean.sh b/missions/lvm/01_physical_volumes/clean.sh new file mode 100644 index 000000000..a704c8676 --- /dev/null +++ b/missions/lvm/01_physical_volumes/clean.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env sh + +source "$MISSION_DIR/../00_shared/utils.sh" + +# Do nothing we need to keep the loop devices and the disk images +# for the next missions in the LVM series. + +lvm_cleanup "01" +return $? diff --git a/missions/lvm/01_physical_volumes/goal/en.txt b/missions/lvm/01_physical_volumes/goal/en.txt new file mode 100644 index 000000000..6cb44e586 --- /dev/null +++ b/missions/lvm/01_physical_volumes/goal/en.txt @@ -0,0 +1,52 @@ +Objective +========= +At the edges of the kingdom, the geo-mantic cartographers have identified two vast lands still shrouded in the mist of etheric dimensions: visible on their geo-magical maps, but not yet materialized in the tangible world. + +These phantom territories are located in a plane named by the mages as the +**Domain of Etheric Vastlands (dev)** and appear in ancient grimoires under the names **Esdea** and **Esdebe** (more prosaically referred to as **/dev/gsh_sda** and **/dev/gsh_sdb** in administrative records). + +King **Bordereau VI the Stamped** is determined to affix his seal to them before some nosy neighbor claims their annexation. + +To this end, he has established a new administration, the +**LVM (Lands & Villages Management)**, intended to bring together explorers, geo-mancers, and administrative scribes to materialize, conquer, and manage these new lands. + +But, as is fitting for any great bureaucracy, things are not going exactly as planned. + +The explorers are zealously mapping taverns, the geo-mancers are conspiring among themselves to exchange sinecures, and, worst of all, the administrative staff... administers: an activity that essentially consists of writing reports on the proceedings of the last meeting, which was intended to prepare for the next one... + +In short, all the actual work falls on your shoulders: +you, the intern on duty. + +Your first task is to give substance to these etheric lands, +transforming them into physical territories exploitable by the LVM. +The geo-mancers call this, in their obscure jargon, +the creation of **PV (Physical Volumes)**. + + +/!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ + + WARNING! + + These missions require you to wield administrator (root) powers. + To invoke such commands, you must always precede them with the magical seal: + + danger sudo + + Example, to list the files in a directory as admin: + $ danger sudo ls -alh + + Be cautious before any manipulation: working in "/dev" is dangerous, + always ensure you are working on the correct disk! + +/!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ + + +Useful Commands +=============== +pvcreate + Consult the `pvcreate` manual to learn how to give form + to a Physical Volume in the LVM universe. + +pvs + Allows you to obtain information about already created Physical Volumes. + diff --git a/missions/lvm/01_physical_volumes/goal/fr.txt b/missions/lvm/01_physical_volumes/goal/fr.txt new file mode 100644 index 000000000..0b60b83fa --- /dev/null +++ b/missions/lvm/01_physical_volumes/goal/fr.txt @@ -0,0 +1,62 @@ +Objectif +======== +Aux limites du royaume, les cartographes géo-mantiens ont repéré deux immenses +contrées encore suspendues dans la brume des dimensions éthériques : visibles sur leurs cartes +géo-magiques, mais point encore matérialisées dans le monde tangible. + +Ces territoires fantomatiques se trouvent dans un plan nommé par les mages +**Domain of Etheric Vastlands (dev)** et apparaissent dans d'anciens grimoires sous les nom +d’**Esdea** et **Esdebe** (plus prosaïquement nommés **/dev/gsh_sda** et **/dev/gsh_sdb** dans les registres administratifs). + +Le Roi **Bordereau VI le Tamponné** tient absolument à y apposer son sceau +avant que quelque voisin indiscret ne vienne réclamer leur annexion. + +Pour ce faire, il a institué une administration nouvelle, la +**LVM (Lands & Villages Management)**, censée réunir explorateurs, géo-mantiens +et scribes administratifs afin de matérialiser, conquérir et gérer ces terres +nouvelles. + +Mais, comme il sied à toute grande bureaucratie, les choses ne vont pas +exactement comme prévu. + +Les explorateurs se consacrent avec ardeur à la cartographie des tavernes, +les géo-mantiens complotent entre eux pour s’échanger des sinécures, +et, pire que tout, le personnel administratif… administre : +activité consistant essentiellement à rédiger des comptes rendus sur le déroulé de la dernière réunion, laquelle avait pour but de préparer la suivante... + +Bref, tout le travail concret retombe sur vos épaules : +vous, le stagiaire de service. + +Votre première tâche consiste à donner chair à ces contrées éthérées, +les transformer en territoires physiques exploitables par la LVM. +Les géo-mantiens appellent cela, dans leur jargon abscons, +la création de **PV (Physical Volumes)**. + + +/!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ + + ATTENTION ! + + Ces missions vous amènent à manier des pouvoirs d’administrateur (root). + Pour invoquer de telles commandes, vous devez impérativement les faire + précéder du sceau magique : + + danger sudo + + Exemple, pour recenser les fichiers d’un répertoire en tant qu’admin : + $ danger sudo ls -alh + + Prenez garde avant toute manipulation : travailler dans "/dev" est dangereux, + assurez-vous de toujours travailler sur le bon disque ! + +/!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ /!\ + + +Commandes utiles +================ +pvcreate + Consultez le manuel de `pvcreate` pour découvrir comment donner corps + à un Volume Physique dans l’univers de la LVM. + +pvs + Permet d’obtenir des informations sur les Volumes Physiques déjà créés. diff --git a/missions/lvm/01_physical_volumes/i18n/en.po b/missions/lvm/01_physical_volumes/i18n/en.po new file mode 100644 index 000000000..e0281cb80 --- /dev/null +++ b/missions/lvm/01_physical_volumes/i18n/en.po @@ -0,0 +1,69 @@ +# English translations for GameShell LVM Mission package. +# Copyright (C) 2025 THE GameShell LVM Mission'S COPYRIGHT HOLDER +# This file is distributed under the same license as the GameShell LVM Mission package. +# Automatically generated, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: GameShell LVM Mission 01_physical_volumes\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-12-04 20:10+0100\n" +"PO-Revision-Date: 2025-12-04 20:10+0100\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: en_US\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgid " \\$command_name is already installed." +msgstr " \\$command_name is already installed." + +msgid "" +"Bravo, the ethereal territories of Esdea and Esdebe have been incarnated " +"into physical lands!" +msgstr "" +"Bravo, the ethereal territories of Esdea and Esdebe have been incarnated " +"into physical lands!" + +msgid " Checking required software..." +msgstr " Checking required software..." + +msgid "" +" Could not detect a supported package manager. Please install \\" +"$package_name manually." +msgstr "" +" Could not detect a supported package manager. Please install \\" +"$package_name manually." + +msgid "Device \\$SDBA does not exist." +msgstr "Device \\$SDBA does not exist." + +msgid "Device \\$SDBB does not exist." +msgstr "Device \\$SDBB does not exist." + +msgid "Do you want to install \\$package_name? [y/N]: " +msgstr "Do you want to install \\$package_name? [y/N]: " + +msgid "" +"\n" +" \\$command_name (package: \\$package_name) is not installed." +msgstr "" +"\n" +" \\$command_name (package: \\$package_name) is not installed." + +msgid "Skipping \\$package_name." +msgstr "Skipping \\$package_name." + +msgid "" +"You must still incarnate the ethereal territory of Esdea into physical lands!" +msgstr "" +"You must still incarnate the ethereal territory of Esdea into physical lands!" + +msgid "" +"You must still incarnate the ethereal territory of Esdebe into physical " +"lands!" +msgstr "" +"You must still incarnate the ethereal territory of Esdebe into physical " +"lands!" diff --git a/missions/lvm/01_physical_volumes/i18n/fr.po b/missions/lvm/01_physical_volumes/i18n/fr.po new file mode 100644 index 000000000..a2ff8fb32 --- /dev/null +++ b/missions/lvm/01_physical_volumes/i18n/fr.po @@ -0,0 +1,60 @@ +# French translations for GameShell LVM Mission package. +# Copyright (C) 2025 THE GameShell LVM Mission'S COPYRIGHT HOLDER +# This file is distributed under the same license as the GameShell LVM Mission package. +# Automatically generated, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: GameShell LVM Mission 01_physical_volumes\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-12-04 20:10+0100\n" +"PO-Revision-Date: 2025-12-04 20:10+0100\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +msgid " \\$command_name is already installed." +msgstr "" + +msgid "" +"Bravo, the ethereal territories of Esdea and Esdebe have been incarnated " +"into physical lands!" +msgstr "" + +msgid " Checking required software..." +msgstr "" + +msgid "" +" Could not detect a supported package manager. Please install \\" +"$package_name manually." +msgstr "" + +msgid "Device \\$SDBA does not exist." +msgstr "" + +msgid "Device \\$SDBB does not exist." +msgstr "" + +msgid "Do you want to install \\$package_name? [y/N]: " +msgstr "" + +msgid "" +"\n" +" \\$command_name (package: \\$package_name) is not installed." +msgstr "" + +msgid "Skipping \\$package_name." +msgstr "" + +msgid "" +"You must still incarnate the ethereal territory of Esdea into physical lands!" +msgstr "" + +msgid "" +"You must still incarnate the ethereal territory of Esdebe into physical " +"lands!" +msgstr "" diff --git a/missions/lvm/01_physical_volumes/i18n/template.pot b/missions/lvm/01_physical_volumes/i18n/template.pot new file mode 100644 index 000000000..f499203e1 --- /dev/null +++ b/missions/lvm/01_physical_volumes/i18n/template.pot @@ -0,0 +1,52 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: GameShell LVM Mission 01_physical_volumes\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-12-04 20:10+0100\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + + +msgid " \\$command_name is already installed." +msgstr "" + +msgid "Bravo, the ethereal territories of Esdea and Esdebe have been incarnated into physical lands!" +msgstr "" + +msgid " Checking required software..." +msgstr "" + +msgid " Could not detect a supported package manager. Please install \\$package_name manually." +msgstr "" + +msgid "Device \\$SDBA does not exist." +msgstr "" + +msgid "Device \\$SDBB does not exist." +msgstr "" + +msgid "Do you want to install \\$package_name? [y/N]: " +msgstr "" + +msgid "\n \\$command_name (package: \\$package_name) is not installed." +msgstr "" + +msgid "Skipping \\$package_name." +msgstr "" + +msgid "You must still incarnate the ethereal territory of Esdea into physical lands!" +msgstr "" + +msgid "You must still incarnate the ethereal territory of Esdebe into physical lands!" +msgstr "" diff --git a/missions/lvm/01_physical_volumes/init.sh b/missions/lvm/01_physical_volumes/init.sh new file mode 100644 index 000000000..9799b3049 --- /dev/null +++ b/missions/lvm/01_physical_volumes/init.sh @@ -0,0 +1,73 @@ +#!/usr/bin/env sh + +source "$MISSION_DIR/../00_shared/utils.sh" + + +install_required_software() { + echo "$(eval_gettext "🔍 Checking required software...")" + + # List of required software (command:package) + # If command == package, you can just repeat the name + REQUIRED_SOFTWARE=( + "lvm: lvm2" + "quota: quota" + "mkfs.ext4: e2fsprogs" # mkfs.ext4 is in the e2fsprogs package + "lsattr: libext2fs2" # example: command in another package + ) + + # Function to check and install + check_and_install() { + local command_name="$1" + local package_name="$2" + + if ! danger sudo which $command_name >/dev/null 2>&1; then + echo -e "$(eval_gettext "\n❌ \$command_name (package: \$package_name) is not installed.")" + echo -n "$(eval_gettext "Do you want to install \$package_name? [y/N]: ")" + read choice < /dev/tty + + case "$choice" in + y|Y ) + if command -v apt-get >/dev/null 2>&1; then + danger sudo apt-get update && danger sudo apt-get install -y "$package_name" + elif command -v dnf >/dev/null 2>&1; then + danger sudo dnf install -y "$package_name" + elif command -v yum >/dev/null 2>&1; then + danger sudo yum install -y "$package_name" + elif command -v pacman >/dev/null 2>&1; then + danger sudo pacman -Sy --noconfirm "$package_name" + else + echo "$(eval_gettext "⚠️ Could not detect a supported package manager. Please install \$package_name manually.")" + fi + ;; + * ) + echo "$(eval_gettext "Skipping \$package_name.")" + return 1 + ;; + esac + else + echo "$(eval_gettext "✅ \$command_name is already installed.")" + fi + } + + # Loop through required software + for entry in "${REQUIRED_SOFTWARE[@]}"; do + command_name="${entry%%:*}" # text before the colon + package_name="${entry##*:}" # text after the colon + # Trim spaces if present + command_name="$(echo "$command_name" | xargs)" + package_name="$(echo "$package_name" | xargs)" + check_and_install "$command_name" "$package_name" + done +} + + +install_required_software + +_mission_init() ( + + lvm_init "01" + return $? + +) + +_mission_init diff --git a/missions/lvm/01_physical_volumes/static.sh b/missions/lvm/01_physical_volumes/static.sh new file mode 100644 index 000000000..a7e859dc8 --- /dev/null +++ b/missions/lvm/01_physical_volumes/static.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env sh + +# Do nothing, we will make symbolic links to the loop devices +# created in the 00_shared mission in the init script. +return 0 \ No newline at end of file diff --git a/missions/lvm/02_volumes_group/auto.sh b/missions/lvm/02_volumes_group/auto.sh new file mode 100644 index 000000000..812f00c02 --- /dev/null +++ b/missions/lvm/02_volumes_group/auto.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env sh +danger sudo vgcreate esdea "/dev/gsh_sda" +danger sudo vgcreate esdebe "/dev/gsh_sdb" \ No newline at end of file diff --git a/missions/lvm/02_volumes_group/check.sh b/missions/lvm/02_volumes_group/check.sh new file mode 100644 index 000000000..fcebc99aa --- /dev/null +++ b/missions/lvm/02_volumes_group/check.sh @@ -0,0 +1,48 @@ +#!/usr/bin/env sh + +_mission_check() ( + SDBA="/dev/gsh_sda" + SDBB="/dev/gsh_sdb" + + # 1) Vérifier que les chemins existent + if [ ! -e "$SDBA" ]; then + echo "$(eval_gettext "Device \$SDBA does not exist.")" + return 1 + fi + if [ ! -e "$SDBB" ]; then + echo "$(eval_gettext "Device \$SDBB does not exist.")" + return 1 + fi + + # 3) Vérifier que les VG 'esdea' et 'esdebe' existent + if ! danger sudo vgs --noheadings -o vg_name | grep -qw esdea; then + echo "$(eval_gettext "The Colony of Esdea has not yet been founded!")" + return 1 + fi + if ! danger sudo vgs --noheadings -o vg_name | grep -qw esdebe; then + echo "$(eval_gettext "The Colony of Esdebe has not yet been founded!")" + return 1 + fi + + # 4) Vérifier la correspondance PV↔VG + # - /dev/sda doit appartenir à VG 'esdea' + # - /dev/sdb doit appartenir à VG 'esdebe' + ESDEA_VG="$(danger sudo pvs --noheadings -o vg_name "$SDBA" 2>/dev/null | tr -d '[:space:]')" + ESDEBE_VG="$(danger sudo pvs --noheadings -o vg_name "$SDBB" 2>/dev/null | tr -d '[:space:]')" + + if [ "$ESDEA_VG" != "esdea" ]; then + [ -z "$ESDEA_VG" ] && ESDEA_VG="(aucun VG)" + echo "$(eval_gettext "Inconsistency: \$SDBA belongs to '\$ESDEA_VG' instead of 'esdea'.")" + return 1 + fi + if [ "$ESDEBE_VG" != "esdebe" ]; then + [ -z "$ESDEBE_VG" ] && ESDEBE_VG="(aucun VG)" + echo "$(eval_gettext "Inconsistency: \$SDBB belongs to '\$ESDEBE_VG' instead of 'esdebe'.")" + return 1 + fi + + echo "$(eval_gettext "Bravo, the colonies of Esdea and Esdebe are now founded!")" + return 0 +) + +_mission_check diff --git a/missions/lvm/02_volumes_group/clean.sh b/missions/lvm/02_volumes_group/clean.sh new file mode 100644 index 000000000..ed907fec5 --- /dev/null +++ b/missions/lvm/02_volumes_group/clean.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env sh + +source "$MISSION_DIR/../00_shared/utils.sh" + +# Do nothing we need to keep the loop devices and the disk images +# for the next missions in the LVM series. + +lvm_cleanup "02" +return $? diff --git a/missions/lvm/02_volumes_group/goal/en.txt b/missions/lvm/02_volumes_group/goal/en.txt new file mode 100644 index 000000000..900e3dc86 --- /dev/null +++ b/missions/lvm/02_volumes_group/goal/en.txt @@ -0,0 +1,31 @@ +Objective +========= +The ethereal territories of Esdea and Esdebe, which you have materialized into +tangible provinces (PV), are now ready to enter the administrative apparatus. + +At the palace, the **LVM (Lands & Villages Management)** officials have +held an endless cycle of consultations: pre-meetings for scoping, +plenary sessions, ad hoc committees, post-session debriefs and, of course, +drafting voluminous reports distributed in triplicate. + +From these works emerges a solemn decision: to preserve the balance of +ambitions and give an impression of efficiency, the new provinces will be +erected into two **independent colonies**. + +In administrative language, these colonies take the name of +**Volume Groups (VG)**. + +Your mission: officially establish these colonies under their official +designation (make sure to use lowercase names): +- The Colony of **Esdea** +- The Colony of **Esdebe** + + +Useful Commands +=============== +vgcreate + Consult the manual of `vgcreate` to discover how to establish a Volume + Group on a Physical Volume. + +vgs + Provides information on already established Volume Groups. diff --git a/missions/lvm/02_volumes_group/goal/fr.txt b/missions/lvm/02_volumes_group/goal/fr.txt new file mode 100644 index 000000000..aa1af46f7 --- /dev/null +++ b/missions/lvm/02_volumes_group/goal/fr.txt @@ -0,0 +1,32 @@ +Objectif +======== +Les territoires éthérés d’Esdea et d’Esdebe, que vous avez matérialisés en +provinces tangibles (PV), sont désormais prêts à entrer dans l’appareil +administratif. + +Au palais, les fonctionnaires de la **LVM (Lands & Villages Management)** ont +tenu un cycle de concertations interminables : pré-réunions de cadrage, +réunions plénières, comités ad hoc, débriefs post-séance et, bien sûr, +rédaction de volumineux comptes rendus distribués en triple exemplaire. + +De ces travaux sort une décision solennelle : pour préserver l’équilibre des +ambitions et donner une impression d’efficacité, les nouvelles provinces seront +érigées en deux **colonies indépendantes**. + +En langage administratif, ces colonies prennent le nom de +**Villages Groupés (VG)**. + +Votre mission : fonder officiellement ces colonies sous leur désignation +officielle (veillez à employer des noms en minuscules) : +- La Colonie d’**Esdea** +- La Colonie d’**Esdebe** + + +Commandes utiles +================ +vgcreate + Consultez le manuel de `vgcreate` pour découvrir comment ériger un Volume + Group sur un Volume Physique. + +vgs + Fournit des informations sur les Volume Groups déjà institués. diff --git a/missions/lvm/02_volumes_group/i18n/en.po b/missions/lvm/02_volumes_group/i18n/en.po new file mode 100644 index 000000000..62832adc8 --- /dev/null +++ b/missions/lvm/02_volumes_group/i18n/en.po @@ -0,0 +1,39 @@ +# English translations for GameShell LVM Mission package. +# Copyright (C) 2025 THE GameShell LVM Mission'S COPYRIGHT HOLDER +# This file is distributed under the same license as the GameShell LVM Mission package. +# Automatically generated, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: GameShell LVM Mission 02_volumes_group\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-12-04 20:10+0100\n" +"PO-Revision-Date: 2025-12-04 20:10+0100\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: en_US\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgid "Bravo, the colonies of Esdea and Esdebe are now founded!" +msgstr "Bravo, the colonies of Esdea and Esdebe are now founded!" + +msgid "Device \\$SDBA does not exist." +msgstr "Device \\$SDBA does not exist." + +msgid "Device \\$SDBB does not exist." +msgstr "Device \\$SDBB does not exist." + +msgid "Inconsistency: \\$SDBA belongs to '\\$ESDEA_VG' instead of 'esdea'." +msgstr "Inconsistency: \\$SDBA belongs to '\\$ESDEA_VG' instead of 'esdea'." + +msgid "Inconsistency: \\$SDBB belongs to '\\$ESDEBE_VG' instead of 'esdebe'." +msgstr "Inconsistency: \\$SDBB belongs to '\\$ESDEBE_VG' instead of 'esdebe'." + +msgid "The Colony of Esdea has not yet been founded!" +msgstr "The Colony of Esdea has not yet been founded!" + +msgid "The Colony of Esdebe has not yet been founded!" +msgstr "The Colony of Esdebe has not yet been founded!" diff --git a/missions/lvm/02_volumes_group/i18n/fr.po b/missions/lvm/02_volumes_group/i18n/fr.po new file mode 100644 index 000000000..2486bf84c --- /dev/null +++ b/missions/lvm/02_volumes_group/i18n/fr.po @@ -0,0 +1,39 @@ +# French translations for GameShell LVM Mission package. +# Copyright (C) 2025 THE GameShell LVM Mission'S COPYRIGHT HOLDER +# This file is distributed under the same license as the GameShell LVM Mission package. +# Automatically generated, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: GameShell LVM Mission 02_volumes_group\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-12-04 20:10+0100\n" +"PO-Revision-Date: 2025-12-04 20:10+0100\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +msgid "Bravo, the colonies of Esdea and Esdebe are now founded!" +msgstr "Bravo, les colonies d’Esdea et d’Esdebe sont désormais fondées !" + +msgid "Device $SDBA does not exist." +msgstr "Le périphérique $SDBA n'existe pas." + +msgid "Device $SDBB does not exist." +msgstr "Le périphérique $SDBB n'existe pas." + +msgid "Inconsistency: $SDBA belongs to '$ESDEA_VG' instead of 'esdea'." +msgstr "Incohérence : $SDBA appartient à '$ESDEA_VG' au lieu de 'esdea'." + +msgid "Inconsistency: $SDBB belongs to '$ESDEBE_VG' instead of 'esdebe'." +msgstr "Incohérence : $SDBB appartient à '$ESDEBE_VG' au lieu de 'esdebe'." + +msgid "The Colony of Esdea has not yet been founded!" +msgstr "La Colonie d’Esdea n’a pas encore été fondée !" + +msgid "The Colony of Esdebe has not yet been founded!" +msgstr "La Colonie d’Esdebe n’a pas encore été fondée !" diff --git a/missions/lvm/02_volumes_group/i18n/template.pot b/missions/lvm/02_volumes_group/i18n/template.pot new file mode 100644 index 000000000..79e08996f --- /dev/null +++ b/missions/lvm/02_volumes_group/i18n/template.pot @@ -0,0 +1,40 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: GameShell LVM Mission 02_volumes_group\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-12-04 20:10+0100\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + + +msgid "Bravo, the colonies of Esdea and Esdebe are now founded!" +msgstr "" + +msgid "Device \\$SDBA does not exist." +msgstr "" + +msgid "Device \\$SDBB does not exist." +msgstr "" + +msgid "Inconsistency: \\$SDBA belongs to '\\$ESDEA_VG' instead of 'esdea'." +msgstr "" + +msgid "Inconsistency: \\$SDBB belongs to '\\$ESDEBE_VG' instead of 'esdebe'." +msgstr "" + +msgid "The Colony of Esdea has not yet been founded!" +msgstr "" + +msgid "The Colony of Esdebe has not yet been founded!" +msgstr "" diff --git a/missions/lvm/02_volumes_group/init.sh b/missions/lvm/02_volumes_group/init.sh new file mode 100644 index 000000000..14267972d --- /dev/null +++ b/missions/lvm/02_volumes_group/init.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env sh + +source "$MISSION_DIR/../00_shared/utils.sh" + +_mission_init() ( + + lvm_init "02" + return $? + +) + +_mission_init diff --git a/missions/lvm/02_volumes_group/static.sh b/missions/lvm/02_volumes_group/static.sh new file mode 100644 index 000000000..a7e859dc8 --- /dev/null +++ b/missions/lvm/02_volumes_group/static.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env sh + +# Do nothing, we will make symbolic links to the loop devices +# created in the 00_shared mission in the init script. +return 0 \ No newline at end of file diff --git a/missions/lvm/03_logical_volumes/auto.sh b/missions/lvm/03_logical_volumes/auto.sh new file mode 100644 index 000000000..a6fc93648 --- /dev/null +++ b/missions/lvm/03_logical_volumes/auto.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env sh + +danger sudo lvcreate -L 30M -n ouskelcoule esdea +danger sudo lvcreate -L 20M -n douskelpar esdea +danger sudo lvcreate -L 25M -n grandflac esdebe \ No newline at end of file diff --git a/missions/lvm/03_logical_volumes/check.sh b/missions/lvm/03_logical_volumes/check.sh new file mode 100644 index 000000000..d0907a40a --- /dev/null +++ b/missions/lvm/03_logical_volumes/check.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env sh + +source "$MISSION_DIR/../00_shared/utils.sh" + +_mission_check() ( + + # Check that the logical volumes exist with the correct sizes + if ! check_lv_size esdea/ouskelcoule 30; then + echo "$(eval_gettext "The village of Ouskelcoule is not present or does not have the correct size (30 MB).")" + return 1 + fi + + if ! check_lv_size esdea/douskelpar 20; then + echo "$(eval_gettext "The village of Douskelpar is not present or does not have the correct size (20 MB).")" + return 1 + fi + + if ! check_lv_size esdebe/grandflac 25; then + echo "$(eval_gettext "The village of Grandflac is not present or does not have the correct size (25 MB).")" + return 1 + fi + + echo "$(eval_gettext "Bravo, the borders of the villages of Ouskelcoule, Douskelpar and Grandflac are now drawn!")" + return 0 +) + +_mission_check diff --git a/missions/lvm/03_logical_volumes/clean.sh b/missions/lvm/03_logical_volumes/clean.sh new file mode 100644 index 000000000..9ffd76c4c --- /dev/null +++ b/missions/lvm/03_logical_volumes/clean.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env sh + +source "$MISSION_DIR/../00_shared/utils.sh" + +# Do nothing we need to keep the loop devices and the disk images +# for the next missions in the LVM series. + +lvm_cleanup "03" +return $? diff --git a/missions/lvm/03_logical_volumes/goal/en.txt b/missions/lvm/03_logical_volumes/goal/en.txt new file mode 100644 index 000000000..0e1481998 --- /dev/null +++ b/missions/lvm/03_logical_volumes/goal/en.txt @@ -0,0 +1,48 @@ +Objectives +=========================================== +Now that the LVM officials have defined the organization of the provinces +(Esdea and Esdebebe), they have drafted countless forms and pieces of paper +granting exploitation rights to explorers in order to establish villages — +designated by the geo-mancers under the name of **Logical Volumes (LV)** — in these new colonies. + +Of course, said explorers can neither read administrative charters +nor interpret instructions. + +Aware of the problem and intrinsically convinced, like any self-respecting administrative staff, +that not only can nothing be organized without them, but also that +work is never better done than by others, the LVM officials +have therefore tasked you, humble intern, to accompany the explorers in their task +to ensure that the villages respect the guidelines established on high. + +The officials have planned the foundation of the following villages: + +- **Esdea**: + - *Ouskelcoule* → the village at the bottom of the main river, with an area of 30 Mo + - *Douskelpar* → the village perched high in the hills, with an area of 20 Mo + +- **Esdebebe**: + - *Grandflac* → the village established on the south shore of the great lake, with an area of 25 Mo + +--- + +Historical Note +=============== +The **Mornifle** (symbol *Mo*) is the official unit of measurement for areas +within the Kingdom since its establishment by **Moribond I**, great-great-grandfather +of King **Bordereau VI The Stamped**. + +This unit was born from a convoluted calculation: the surface of a royal hand multiplied +by the dimensions (in millimeters) of the chubby cheek of young prince +**Tédéhah the Restless**. +Step by step, the official surveyors decreed that one Mornifle corresponded +to about one of our modern hectares. + +--- + +Useful Commands +================ +lvcreate + Allows creating a Logical Volume on a Volume Group, specifying its size. + +lvs + Displays information about Logical Volumes. diff --git a/missions/lvm/03_logical_volumes/goal/fr.txt b/missions/lvm/03_logical_volumes/goal/fr.txt new file mode 100644 index 000000000..7b61447cd --- /dev/null +++ b/missions/lvm/03_logical_volumes/goal/fr.txt @@ -0,0 +1,51 @@ +Objectifs +=========================================== +Maintenant que les fonctionnaires de la LVM ont défini l’organisation des provinces +(Esdea et Esdebebe), ils ont rédigé d’innombrables formulaires et bouts de papier +accordant les droits d’exploitation aux explorateurs afin d’établir des villages — +désignés par les géo-mantiens sous le nom de **Logical Volumes (LV)** — dans ces nouvelles colonies. + +Bien entendu, lesdits explorateurs ne savent ni lire les chartes administratives +ni interpréter les consignes. + +Conscients du problème et intrinsèquement persuadés, comme tout personnel administratif +qui se respecte, que non seulement rien ne peut s’organiser sans eux, mais aussi que +le travail n’est jamais mieux fait que par les autres, les fonctionnaires de la LVM +vous ont donc chargé, vous humble stagiaire, d’accompagner les explorateurs dans leur tâche +afin de vous assurer que les villages respectent les consignes établies en haut lieu. + +Les fonctionnaires ont prévu la fondation des villages suivants : + +- **Esdea** : + + - *Ouskelcoule* → le village du bas de la rivière principale, d’une superficie de 30 Mo + + - *Douskelpar* → le village perché en haut des collines, d’une superficie de 20 Mo + +- **Esdebebe** : + + - *Grandflac* → le village établi sur la berge sud du grand lac, d’une superficie de 25 Mo + +--- + +Note historique +=============== +La **Mornifle** (symbole *Mo*) est l’unité de mesure officielle des superficies +au sein du Royaume depuis son instauration par **Moribond Ier**, arrière-arrière-grand-père +du roi **Bordereau VI Le Tamponné**. + +Cette unité est née d’un calcul alambiqué : la surface d’une main royale multipliée +par les dimensions (en millimètres) de la joue rebondie du jeune prince +**Tédéhah le Remuant**. +De fil en aiguille, les arpenteurs officiels décrétèrent qu’une Mornifle correspondait +à peu près à un de nos hectares modernes. + +--- + +Commandes utiles +================ +lvcreate + Permet de créer un Logical Volume sur un Volume Group, en précisant sa taille. + +lvs + Affiche les informations sur les Logical Volumes. diff --git a/missions/lvm/03_logical_volumes/i18n/en.po b/missions/lvm/03_logical_volumes/i18n/en.po new file mode 100644 index 000000000..3c583a0a9 --- /dev/null +++ b/missions/lvm/03_logical_volumes/i18n/en.po @@ -0,0 +1,46 @@ +# English translations for GameShell LVM Mission package. +# Copyright (C) 2025 THE GameShell LVM Mission'S COPYRIGHT HOLDER +# This file is distributed under the same license as the GameShell LVM Mission package. +# Automatically generated, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: GameShell LVM Mission 03_logical_volumes\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-12-04 20:10+0100\n" +"PO-Revision-Date: 2025-12-04 20:10+0100\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: en_US\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgid "" +"Bravo, the borders of the villages of Ouskelcoule, Douskelpar and Grandflac " +"are now drawn!" +msgstr "" +"Bravo, the borders of the villages of Ouskelcoule, Douskelpar and Grandflac " +"are now drawn!" + +msgid "" +"The village of Douskelpar is not present or does not have the correct size " +"(20 MB)." +msgstr "" +"The village of Douskelpar is not present or does not have the correct size " +"(20 MB)." + +msgid "" +"The village of Grandflac is not present or does not have the correct size " +"(25 MB)." +msgstr "" +"The village of Grandflac is not present or does not have the correct size " +"(25 MB)." + +msgid "" +"The village of Ouskelcoule is not present or does not have the correct size " +"(30 MB)." +msgstr "" +"The village of Ouskelcoule is not present or does not have the correct size " +"(30 MB)." diff --git a/missions/lvm/03_logical_volumes/i18n/fr.po b/missions/lvm/03_logical_volumes/i18n/fr.po new file mode 100644 index 000000000..6331e6a5e --- /dev/null +++ b/missions/lvm/03_logical_volumes/i18n/fr.po @@ -0,0 +1,38 @@ +# French translations for GameShell LVM Mission package. +# Copyright (C) 2025 THE GameShell LVM Mission'S COPYRIGHT HOLDER +# This file is distributed under the same license as the GameShell LVM Mission package. +# Automatically generated, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: GameShell LVM Mission 03_logical_volumes\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-12-04 20:10+0100\n" +"PO-Revision-Date: 2025-12-04 20:10+0100\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +msgid "" +"Bravo, the borders of the villages of Ouskelcoule, Douskelpar and Grandflac " +"are now drawn!" +msgstr "Bravo, les frontières des villages d'Ouskelcoule, de Douskelpar et de Grandflac sont désormais tracées !" + +msgid "" +"The village of Douskelpar is not present or does not have the correct size " +"(20 MB)." +msgstr "Le village de Douskelpar n'est pas présent ou n'a pas la bonne taille (20 Mo)." + +msgid "" +"The village of Grandflac is not present or does not have the correct size " +"(25 MB)." +msgstr "Le village de Grandflac n'est pas présent ou n'a pas la bonne taille (25 Mo)." + +msgid "" +"The village of Ouskelcoule is not present or does not have the correct size " +"(30 MB)." +msgstr "Le village d'Ouskelcoule n'est pas présent ou n'a pas la bonne taille (30 Mo)." diff --git a/missions/lvm/03_logical_volumes/i18n/template.pot b/missions/lvm/03_logical_volumes/i18n/template.pot new file mode 100644 index 000000000..e1a26e888 --- /dev/null +++ b/missions/lvm/03_logical_volumes/i18n/template.pot @@ -0,0 +1,31 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: GameShell LVM Mission 03_logical_volumes\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-12-04 20:10+0100\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + + +msgid "Bravo, the borders of the villages of Ouskelcoule, Douskelpar and Grandflac are now drawn!" +msgstr "" + +msgid "The village of Douskelpar is not present or does not have the correct size (20 MB)." +msgstr "" + +msgid "The village of Grandflac is not present or does not have the correct size (25 MB)." +msgstr "" + +msgid "The village of Ouskelcoule is not present or does not have the correct size (30 MB)." +msgstr "" diff --git a/missions/lvm/03_logical_volumes/init.sh b/missions/lvm/03_logical_volumes/init.sh new file mode 100644 index 000000000..2609c02a2 --- /dev/null +++ b/missions/lvm/03_logical_volumes/init.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env sh + +source "$MISSION_DIR/../00_shared/utils.sh" + +_mission_init() ( + + lvm_init "03" + return $? + +) + +_mission_init diff --git a/missions/lvm/03_logical_volumes/static.sh b/missions/lvm/03_logical_volumes/static.sh new file mode 100644 index 000000000..621502b6e --- /dev/null +++ b/missions/lvm/03_logical_volumes/static.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env sh + +# Do nothing +return 0 \ No newline at end of file diff --git a/missions/lvm/04_filesystem/auto.sh b/missions/lvm/04_filesystem/auto.sh new file mode 100644 index 000000000..c9c6e8ee5 --- /dev/null +++ b/missions/lvm/04_filesystem/auto.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env sh + +danger sudo mkfs.ext4 /dev/esdea/douskelpar +danger sudo mkfs.ext4 /dev/esdea/ouskelcoule +danger sudo mkfs.ext4 /dev/esdebe/grandflac \ No newline at end of file diff --git a/missions/lvm/04_filesystem/check.sh b/missions/lvm/04_filesystem/check.sh new file mode 100644 index 000000000..2fbc14ad8 --- /dev/null +++ b/missions/lvm/04_filesystem/check.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env sh + +source "$MISSION_DIR/../00_shared/utils.sh" + +_mission_check() ( + + # Ouskelcoule (esdea/ouskelcoule) must be EXT4 + if ! check_lv_fs_type esdea/ouskelcoule ext4; then + case $? in + 2) echo "$(eval_gettext "The village of Ouskelcoule does not exist (LV /dev/esdea/ouskelcoule not found).")";; + 3) echo "$(eval_gettext "The village of Ouskelcoule is not yet organized (no filesystem).")";; + *) echo "$(eval_gettext "The village of Ouskelcoule is not in EXT4 format.")";; + esac + return 1 + fi + + # Douskelpar (esdea/douskelpar) must be EXT4 + if ! check_lv_fs_type esdea/douskelpar ext4; then + case $? in + 2) echo "$(eval_gettext "The village of Douskelpar does not exist (LV /dev/esdea/douskelpar not found).")";; + 3) echo "$(eval_gettext "The village of Douskelpar is not yet organized (no filesystem).")";; + *) echo "$(eval_gettext "The village of Douskelpar is not in EXT4 format.")";; + esac + return 1 + fi + + # Grandflac (esdebe/grandflac) must be EXT4 + if ! check_lv_fs_type esdebe/grandflac ext4; then + case $? in + 2) echo "$(eval_gettext "The village of Grandflac does not exist (LV /dev/esdebe/grandflac not found).")";; + 3) echo "$(eval_gettext "The village of Grandflac is not yet organized (no filesystem).")";; + *) echo "$(eval_gettext "The village of Grandflac is not in EXT4 format.")";; + esac + return 1 + fi + + echo "$(eval_gettext "Bravo! Ouskelcoule, Douskelpar and Grandflac are duly organized and partitioned, almost ready to welcome their inhabitants!")" + return 0 +) + +_mission_check diff --git a/missions/lvm/04_filesystem/clean.sh b/missions/lvm/04_filesystem/clean.sh new file mode 100644 index 000000000..4763a5d0c --- /dev/null +++ b/missions/lvm/04_filesystem/clean.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env sh + +source "$MISSION_DIR/../00_shared/utils.sh" + +# Do nothing we need to keep the loop devices and the disk images +# for the next missions in the LVM series. + +lvm_cleanup "04" +return $? diff --git a/missions/lvm/04_filesystem/goal/en.txt b/missions/lvm/04_filesystem/goal/en.txt new file mode 100644 index 000000000..bd5fa5e2f --- /dev/null +++ b/missions/lvm/04_filesystem/goal/en.txt @@ -0,0 +1,43 @@ +Objectives +=========================================== +The explorers have pitched their tents in Ouskelcoule, Douskelpar and Grandflac, +but these "villages" remain for now vast wastelands without any +organization. + +The **LVM** officials, great lovers of registers and stamps, +have decreed that administrative rigor is necessary to avoid chaos. +According to them, before even erecting the slightest hut, it is appropriate to order the soil +through regular division, to draw up duly stamped inventories, and to +keep registers allowing to officially attribute each plot to +future inhabitants. + +In their technico-bureaucratic jargon, this division is called a +**file system**. + +It consists of dividing the land into **blocks** — identical surface units — +then cataloging in registers (tables) the use of each +block. Every house, every barn or every warehouse in the village will be assigned +its own file, called an **inode**, on which will appear all the essential +information: owner, dimensions, plot, allocation, etc. + +Without this initial classification step, the colonists would settle randomly, +and we would end up losing track of the granaries, markets, and even the +village wells. + +By royal decree, the chosen organization mode is +**EXT4: "Territorial eXploitation Edict, 4th version"**, +which sets the rules for construction, access and management of plots. + +Your mission is therefore to prepare the basic infrastructure: +- Divide the **Ouskelcoule** basin into regular blocks, +- Structure the verdant slopes of **Douskelpar**, +- Develop the lush banks of **Grandflac**. + + +Useful Commands +================ +mkfs.ext4 + Formats the Logical Volume with an ext4 file system. + +blkid + Displays file system metadata (UUID, type, label). diff --git a/missions/lvm/04_filesystem/goal/fr.txt b/missions/lvm/04_filesystem/goal/fr.txt new file mode 100644 index 000000000..bce9951d3 --- /dev/null +++ b/missions/lvm/04_filesystem/goal/fr.txt @@ -0,0 +1,43 @@ +Objectifs +=========================================== +Les explorateurs ont planté leurs tentes à Ouskelcoule, Douskelpar et Grandflac, +mais ces “villages” demeurent pour l’instant de vastes friches sans aucune +organisation. + +Les fonctionnaires de la **LVM**, grands amateurs de registres et de cachets, +ont décrété qu’une rigueur administrative s’impose afin d’éviter le chaos. +Selon eux, avant même d’ériger la moindre cabane, il convient d’ordonner le sol +par un découpage régulier, d’en dresser des inventaires dûment tamponnés, et de +tenir des registres permettant d’attribuer officiellement chaque parcelle aux +futurs habitants. + +Dans leur jargon technico-bureaucratique, ce découpage se nomme un +**système de fichiers**. + +Il consiste à fractionner la terre en **blocs** — des unités de surface +identiques — puis à répertorier dans des registres (tables) l’usage de chaque +bloc. Toute maison, toute grange ou tout entrepôt du village se verra attribuer +sa propre fiche, appelée **inode**, sur laquelle figureront toutes les mentions +indispensables : propriétaire, dimensions, parcelle, affectation, etc. + +Sans cette étape de classement initial, les colons s’installeraient au hasard, +et l’on finirait par perdre la trace des greniers, des marchés, voire même des +puits du village. + +Par décret royal, le mode d’organisation retenu est +**EXT4 : “Édit de eXploitation Territoriale, 4ᵉ version”**, +qui fixe les règles de construction, d’accès et de gestion des parcelles. + +Votre mission est donc de préparer les infrastructures de base : +- Diviser le bassin de **Ouskelcoule** en blocs réguliers, +- Structurer les pentes verdoyantes de **Douskelpar**, +- Aménager les berges luxuriantes de **Grandflac**. + + +Commandes utiles +================ +mkfs.ext4 + Formate le Logical Volume avec un système de fichiers ext4. + +blkid + Affiche les métadonnées du système de fichiers (UUID, type, label). diff --git a/missions/lvm/04_filesystem/i18n/en.po b/missions/lvm/04_filesystem/i18n/en.po new file mode 100644 index 000000000..e5741f57f --- /dev/null +++ b/missions/lvm/04_filesystem/i18n/en.po @@ -0,0 +1,62 @@ +# English translations for GameShell LVM Mission package. +# Copyright (C) 2025 THE GameShell LVM Mission'S COPYRIGHT HOLDER +# This file is distributed under the same license as the GameShell LVM Mission package. +# Automatically generated, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: GameShell LVM Mission 04_filesystem\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-12-04 20:10+0100\n" +"PO-Revision-Date: 2025-12-04 20:10+0100\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: en_US\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgid "" +"Bravo! Ouskelcoule, Douskelpar and Grandflac are duly organized and " +"partitioned, almost ready to welcome their inhabitants!" +msgstr "" +"Bravo! Ouskelcoule, Douskelpar and Grandflac are duly organized and " +"partitioned, almost ready to welcome their inhabitants!" + +msgid "" +"The village of Douskelpar does not exist (LV /dev/esdea/douskelpar not " +"found)." +msgstr "" +"The village of Douskelpar does not exist (LV /dev/esdea/douskelpar not " +"found)." + +msgid "The village of Douskelpar is not in EXT4 format." +msgstr "The village of Douskelpar is not in EXT4 format." + +msgid "The village of Douskelpar is not yet organized (no filesystem)." +msgstr "The village of Douskelpar is not yet organized (no filesystem)." + +msgid "" +"The village of Grandflac does not exist (LV /dev/esdebe/grandflac not found)." +msgstr "" +"The village of Grandflac does not exist (LV /dev/esdebe/grandflac not found)." + +msgid "The village of Grandflac is not in EXT4 format." +msgstr "The village of Grandflac is not in EXT4 format." + +msgid "The village of Grandflac is not yet organized (no filesystem)." +msgstr "The village of Grandflac is not yet organized (no filesystem)." + +msgid "" +"The village of Ouskelcoule does not exist (LV /dev/esdea/ouskelcoule not " +"found)." +msgstr "" +"The village of Ouskelcoule does not exist (LV /dev/esdea/ouskelcoule not " +"found)." + +msgid "The village of Ouskelcoule is not in EXT4 format." +msgstr "The village of Ouskelcoule is not in EXT4 format." + +msgid "The village of Ouskelcoule is not yet organized (no filesystem)." +msgstr "The village of Ouskelcoule is not yet organized (no filesystem)." diff --git a/missions/lvm/04_filesystem/i18n/fr.po b/missions/lvm/04_filesystem/i18n/fr.po new file mode 100644 index 000000000..a932d64b5 --- /dev/null +++ b/missions/lvm/04_filesystem/i18n/fr.po @@ -0,0 +1,55 @@ +# French translations for GameShell LVM Mission package. +# Copyright (C) 2025 THE GameShell LVM Mission'S COPYRIGHT HOLDER +# This file is distributed under the same license as the GameShell LVM Mission package. +# Automatically generated, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: GameShell LVM Mission 04_filesystem\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-12-04 20:10+0100\n" +"PO-Revision-Date: 2025-12-04 20:10+0100\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +msgid "" +"Bravo! Ouskelcoule, Douskelpar and Grandflac are duly organized and " +"partitioned, almost ready to welcome their inhabitants!" +msgstr "Bravo ! Ouskelcoule, Douskelpar et Grandflac sont dûment organisés et découpés, presque prêts à accueillir leurs habitants !" + +msgid "" +"The village of Douskelpar does not exist (LV /dev/esdea/douskelpar not " +"found)." +msgstr "Le village de Douskelpar n'existe pas (LV /dev/esdea/douskelpar introuvable)." + +msgid "The village of Douskelpar is not in EXT4 format." +msgstr "Le village de Douskelpar n'est pas au format EXT4." + +msgid "The village of Douskelpar is not yet organized (no filesystem)." +msgstr "Le village de Douskelpar n'est pas encore organisé (aucun système de fichiers)." + +msgid "" +"The village of Grandflac does not exist (LV /dev/esdebe/grandflac not found)." +msgstr "Le village de Grandflac n'existe pas (LV /dev/esdebe/grandflac introuvable)." + +msgid "The village of Grandflac is not in EXT4 format." +msgstr "Le village de Grandflac n'est pas au format EXT4." + +msgid "The village of Grandflac is not yet organized (no filesystem)." +msgstr "Le village de Grandflac n'est pas encore organisé (aucun système de fichiers)." + +msgid "" +"The village of Ouskelcoule does not exist (LV /dev/esdea/ouskelcoule not " +"found)." +msgstr "Le village d'Ouskelcoule n'existe pas (LV /dev/esdea/ouskelcoule introuvable)." + +msgid "The village of Ouskelcoule is not in EXT4 format." +msgstr "Le village d'Ouskelcoule n'est pas au format EXT4." + +msgid "The village of Ouskelcoule is not yet organized (no filesystem)." +msgstr "Le village d'Ouskelcoule n'est pas encore organisé (aucun système de fichiers)." diff --git a/missions/lvm/04_filesystem/i18n/template.pot b/missions/lvm/04_filesystem/i18n/template.pot new file mode 100644 index 000000000..4d1b56d62 --- /dev/null +++ b/missions/lvm/04_filesystem/i18n/template.pot @@ -0,0 +1,49 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: GameShell LVM Mission 04_filesystem\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-12-04 20:10+0100\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + + +msgid "Bravo! Ouskelcoule, Douskelpar and Grandflac are duly organized and partitioned, almost ready to welcome their inhabitants!" +msgstr "" + +msgid "The village of Douskelpar does not exist (LV /dev/esdea/douskelpar not found)." +msgstr "" + +msgid "The village of Douskelpar is not in EXT4 format." +msgstr "" + +msgid "The village of Douskelpar is not yet organized (no filesystem)." +msgstr "" + +msgid "The village of Grandflac does not exist (LV /dev/esdebe/grandflac not found)." +msgstr "" + +msgid "The village of Grandflac is not in EXT4 format." +msgstr "" + +msgid "The village of Grandflac is not yet organized (no filesystem)." +msgstr "" + +msgid "The village of Ouskelcoule does not exist (LV /dev/esdea/ouskelcoule not found)." +msgstr "" + +msgid "The village of Ouskelcoule is not in EXT4 format." +msgstr "" + +msgid "The village of Ouskelcoule is not yet organized (no filesystem)." +msgstr "" diff --git a/missions/lvm/04_filesystem/init.sh b/missions/lvm/04_filesystem/init.sh new file mode 100644 index 000000000..613defb63 --- /dev/null +++ b/missions/lvm/04_filesystem/init.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env sh + +source "$MISSION_DIR/../00_shared/utils.sh" + +_mission_init() ( + + lvm_init "04" + return $? + +) + +_mission_init diff --git a/missions/lvm/04_filesystem/static.sh b/missions/lvm/04_filesystem/static.sh new file mode 100644 index 000000000..621502b6e --- /dev/null +++ b/missions/lvm/04_filesystem/static.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env sh + +# Do nothing +return 0 \ No newline at end of file diff --git a/missions/lvm/05_mounting/auto.sh b/missions/lvm/05_mounting/auto.sh new file mode 100644 index 000000000..bfc7eac2d --- /dev/null +++ b/missions/lvm/05_mounting/auto.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env sh + +mkdir -p "$GSH_HOME/Esdea/Ouskelcoule" +mkdir -p "$GSH_HOME/Esdea/Douskelpar" +mkdir -p "$GSH_HOME/Esdebe/Grandflac" + +danger sudo mount /dev/esdea/ouskelcoule "$GSH_HOME/Esdea/Ouskelcoule" +danger sudo chown -R "$USER:$USER" "$GSH_HOME/Esdea/Ouskelcoule" + +danger sudo mount /dev/esdea/douskelpar "$GSH_HOME/Esdea/Douskelpar" +danger sudo chown -R "$USER:$USER" "$GSH_HOME/Esdea/Douskelpar" + +danger sudo mount /dev/esdebe/grandflac "$GSH_HOME/Esdebe/Grandflac" +danger sudo chown -R "$USER:$USER" "$GSH_HOME/Esdebe/Grandflac" + +mkdir -p "$GSH_HOME/Esdea/Ouskelcoule/Maison Commune" +mkdir -p "$GSH_HOME/Esdea/Douskelpar/Maison Commune" +mkdir -p "$GSH_HOME/Esdebe/Grandflac/Maison Commune" + +echo "40" > "$GSH_HOME/Esdea/Ouskelcoule/Maison Commune/population.txt" +echo "20" > "$GSH_HOME/Esdea/Douskelpar/Maison Commune/population.txt" +echo "50" > "$GSH_HOME/Esdebe/Grandflac/Maison Commune/population.txt" \ No newline at end of file diff --git a/missions/lvm/05_mounting/check.sh b/missions/lvm/05_mounting/check.sh new file mode 100644 index 000000000..406fe687e --- /dev/null +++ b/missions/lvm/05_mounting/check.sh @@ -0,0 +1,62 @@ +#!/usr/bin/env sh + +_mission_check() { + # Vérifier Ouskelcoule + if [ ! -d "$GSH_HOME/Esdea/Ouskelcoule" ]; then + echo "$(eval_gettext "Create the village Ouskelcoule in Esdea")" + return 1 + fi + + if ! mountpoint -q "$GSH_HOME/Esdea/Ouskelcoule" ; then + echo "$(eval_gettext "Connect the kingdom to the village of Ouskelcoule")" + return 1 + fi + + # Vérifier Douskelpar + if [ ! -d "$GSH_HOME/Esdea/Douskelpar" ]; then + echo "$(eval_gettext "Create the village Douskelpar in Esdea")" + return 1 + fi + + if ! mountpoint -q "$GSH_HOME/Esdea/Douskelpar" ; then + echo "$(eval_gettext "Connect the kingdom to the village of Douskelpar")" + return 1 + fi + + # Vérifier Grandflac + if [ ! -d "$GSH_HOME/Esdebe/Grandflac" ]; then + echo "$(eval_gettext "Create the village Grandflac in Esdebe")" + return 1 + fi + + if ! mountpoint -q "$GSH_HOME/Esdebe/Grandflac" ; then + echo "$(eval_gettext "Connect the kingdom to the village of Grandflac")" + return 1 + fi + + # Vérifications détaillées + if [ ! -d "$GSH_HOME/Esdea/Ouskelcoule/Maison Commune" ] || [ ! -d "$GSH_HOME/Esdea/Douskelpar/Maison Commune" ] || [ ! -d "$GSH_HOME/Esdebe/Grandflac/Maison Commune" ]; then + echo "$(eval_gettext "Create the 'Maison Commune' directory in each village")" + return 1 + fi + + if [ "$(cat "$GSH_HOME/Esdea/Ouskelcoule/Maison Commune/population.txt" 2>/dev/null)" != "40" ] ; then + echo "$(eval_gettext "Correctly fill in the Ouskelcoule register")" + return 1 + fi + + if [ "$(cat "$GSH_HOME/Esdea/Douskelpar/Maison Commune/population.txt" 2>/dev/null)" != "20" ]; then + echo "$(eval_gettext "Correctly fill in the Douskelpar register")" + return 1 + fi + + if [ "$(cat "$GSH_HOME/Esdebe/Grandflac/Maison Commune/population.txt" 2>/dev/null)" != "50" ]; then + echo "$(eval_gettext "Correctly fill in the Grandflac register")" + return 1 + fi + + echo "$(eval_gettext "Bravo! Ouskelcoule, Douskelpar and Grandflac are well connected to the Esdea kingdom and their registers are up to date!")" + return 0 +} + +_mission_check diff --git a/missions/lvm/05_mounting/clean.sh b/missions/lvm/05_mounting/clean.sh new file mode 100644 index 000000000..a67a0bbdf --- /dev/null +++ b/missions/lvm/05_mounting/clean.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env sh + +source "$MISSION_DIR/../00_shared/utils.sh" + +# Do nothing we need to keep the loop devices and the disk images +# for the next missions in the LVM series. + +lvm_cleanup "05" +return $? diff --git a/missions/lvm/05_mounting/goal/en.txt b/missions/lvm/05_mounting/goal/en.txt new file mode 100644 index 000000000..c3aeeb8c7 --- /dev/null +++ b/missions/lvm/05_mounting/goal/en.txt @@ -0,0 +1,49 @@ +Objectives +========= +The borders of Ouskelcoule, Douskelpar and Grandflac are now defined and their lands +parceled and organized thanks to the EXT4 edict. Yet, they remain isolated. +Without an official path to access them, these villages are still only makeshift camps: +scattered bivouacs and tents with the suspicious smell of feet from the first explorers, +whose hygiene leaves much to be desired. + +The LVM officials, wise people concerned with their daily +ablutions, have therefore decreed that it was time to establish a first road: +a direct link between the new villages and the rest of the kingdom. +This is the only way to bring in the workforce, supplies and tools +necessary for building real permanent villages. + +In the language of geo-mancers, this operation is called **mounting**. +It consists of officially registering a village on the kingdom's map +(by associating it with a mount point) and tracing a carriageway through +which colonists, stewards and goods can circulate. + +Your mission is therefore to create a new province in the kingdom +for each region, then establish a road to each village: +- Open the road to **Ouskelcoule** on `./Esdea/Ouskelcoule` +- Open the road to **Douskelpar** on `./Esdea/Douskelpar` +- Open the road to **Grandflac** on `./Esdebe/Grandflac` + +Then create in each village a first building "Maison Commune", and create a population.txt register with the number of village inhabitants: +- Ouskelcoule: 40 inhabitants +- Douskelpar: 20 inhabitants +- Grandflac: 50 inhabitants + +Note: Don't forget the space in "Maison Commune", and write only the number in population.txt + Also remember to make the mounted folder usable by your user with chown + +Useful Commands +================ +mkdir -p /path/to/dir + Creates a folder and all its parents if necessary. + +mount + Mounts the logical volume at the corresponding mount point. + +lsblk -f + Verifies that volumes are properly mounted and accessible. + +vim + Write to a file + +chown + Change the owner of a file diff --git a/missions/lvm/05_mounting/goal/fr.txt b/missions/lvm/05_mounting/goal/fr.txt new file mode 100644 index 000000000..9bcadb92b --- /dev/null +++ b/missions/lvm/05_mounting/goal/fr.txt @@ -0,0 +1,49 @@ +Objectifs +========= +Les frontières d’Ouskelcoule, Douskelpar et Grandflac sont désormais définies et leurs terres +parcellisées et organisées grâce à l’édit EXT4. Pourtant, elles demeurent isolées. +Sans chemin officiel pour y accéder, ces villages ne sont encore que des campements +de fortune : bivouacs épars et tentes aux relents de pieds suspects des premiers explorateurs, +dont l’hygiène laisse à désirer. + +Les fonctionnaires de la LVM, gens sages et soucieux de leurs ablutions +quotidiennes, ont donc décrété qu’il était temps d’établir une première route : +un lien direct entre les nouveaux villages et le reste du royaume. +C’est la seule manière de faire venir la main-d’œuvre, les vivres et les outils +nécessaires à l’édification de véritables villages en dur. + +Dans le langage des géo-mantiens, cette opération est appelée **montage**. +Elle consiste à inscrire officiellement un village sur la carte du royaume +(en l’associant à un point de montage) et à tracer une voie carrossable par +laquelle colons, intendants et marchandises pourront circuler. + +Votre mission est donc de créer dans le royaume une nouvelle province +pour chaque région, puis d’y établir une route vers chaque village : +- Ouvrir la route vers **Ouskelcoule** sur `./Esdea/Ouskelcoule` +- Ouvrir la route vers **Douskelpar** sur `./Esdea/Douskelpar` +- Ouvrir la route vers **Grandflac** sur `./Esdebe/Grandflac` + +Puis de créer dans chaque village un premier batiment "Maison Commune", et d'y créer un registre population.txt avec le nombre d'habitants du village : +- Ouskelcoule: 40 habitants +- Douskelpar: 20 habitants +- Grandflac: 50 habitants + +Note : N'oubliez pas l'espace dans "Maison Commune", et inscrivez uniquement le chiffre dans population.txt + Pensez aussi à rendre le dossier monté utilisable par votre utilisateur avec chown + +Commandes utiles +================ +mkdir -p /path/to/dir + Crée un dossier et tous ses parents si nécessaire. + +mount + Monte le volume logique au point de montage correspondant. + +lsblk -f + Vérifie que les volumes sont bien montés et accessibles. + +vim + Écrire dans un fichier + +chown + Changer le propriétaire d'un fichier \ No newline at end of file diff --git a/missions/lvm/05_mounting/i18n/en.po b/missions/lvm/05_mounting/i18n/en.po new file mode 100644 index 000000000..469459917 --- /dev/null +++ b/missions/lvm/05_mounting/i18n/en.po @@ -0,0 +1,58 @@ +# English translations for GameShell LVM Mission package. +# Copyright (C) 2025 THE GameShell LVM Mission'S COPYRIGHT HOLDER +# This file is distributed under the same license as the GameShell LVM Mission package. +# Automatically generated, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: GameShell LVM Mission 05_mounting\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-12-04 20:10+0100\n" +"PO-Revision-Date: 2025-12-04 20:10+0100\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: en_US\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgid "" +"Bravo! Ouskelcoule, Douskelpar and Grandflac are well connected to the Esdea " +"kingdom and their registers are up to date!" +msgstr "" +"Bravo! Ouskelcoule, Douskelpar and Grandflac are well connected to the Esdea " +"kingdom and their registers are up to date!" + +msgid "Connect the kingdom to the village of Douskelpar" +msgstr "Connect the kingdom to the village of Douskelpar" + +msgid "Connect the kingdom to the village of Grandflac" +msgstr "Connect the kingdom to the village of Grandflac" + +msgid "Connect the kingdom to the village of Ouskelcoule" +msgstr "Connect the kingdom to the village of Ouskelcoule" + +msgid "Correctly fill in the Douskelpar register" +msgstr "Correctly fill in the Douskelpar register" + +msgid "Correctly fill in the Grandflac register" +msgstr "Correctly fill in the Grandflac register" + +msgid "Correctly fill in the Ouskelcoule register" +msgstr "Correctly fill in the Ouskelcoule register" + +msgid "Create the 'Maison Commune' directory in each village" +msgstr "Create the 'Maison Commune' directory in each village" + +msgid "Create the village Douskelpar in Esdea" +msgstr "Create the village Douskelpar in Esdea" + +msgid "Create the village Grandflac in Esdebe" +msgstr "Create the village Grandflac in Esdebe" + +msgid "Create the village Ouskelcoule in Esdea" +msgstr "Create the village Ouskelcoule in Esdea" + +msgid "mission 5" +msgstr "mission 5" diff --git a/missions/lvm/05_mounting/i18n/fr.po b/missions/lvm/05_mounting/i18n/fr.po new file mode 100644 index 000000000..069e13ddc --- /dev/null +++ b/missions/lvm/05_mounting/i18n/fr.po @@ -0,0 +1,56 @@ +# French translations for GameShell LVM Mission package. +# Copyright (C) 2025 THE GameShell LVM Mission'S COPYRIGHT HOLDER +# This file is distributed under the same license as the GameShell LVM Mission package. +# Automatically generated, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: GameShell LVM Mission 05_mounting\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-12-04 20:10+0100\n" +"PO-Revision-Date: 2025-12-04 20:10+0100\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +msgid "" +"Bravo! Ouskelcoule, Douskelpar and Grandflac are well connected to the Esdea " +"kingdom and their registers are up to date!" +msgstr "Bravo ! Ouskelcoule, Douskelpar et Grandflac sont bien reliés au royaume Esdea et leurs registres sont à jour !" + +msgid "Connect the kingdom to the village of Douskelpar" +msgstr "Reliez le royaume au village de Douskelpar" + +msgid "Connect the kingdom to the village of Grandflac" +msgstr "Reliez le royaume au village de Grandflac" + +msgid "Connect the kingdom to the village of Ouskelcoule" +msgstr "Reliez le royaume au village d'Ouskelcoule" + +msgid "Correctly fill in the Douskelpar register" +msgstr "Remplissez correctement le registre de Douskelpar" + +msgid "Correctly fill in the Grandflac register" +msgstr "Remplissez correctement le registre de Grandflac" + +msgid "Correctly fill in the Ouskelcoule register" +msgstr "Remplissez correctement le registre d'Ouskelcoule" + +msgid "Create the 'Maison Commune' directory in each village" +msgstr "Créez le répertoire 'Maison Commune' dans chaque village" + +msgid "Create the village Douskelpar in Esdea" +msgstr "Créez le village Douskelpar dans Esdea" + +msgid "Create the village Grandflac in Esdebe" +msgstr "Créez le village Grandflac dans Esdebe" + +msgid "Create the village Ouskelcoule in Esdea" +msgstr "Créez le village Ouskelcoule dans Esdea" + +msgid "mission 5" +msgstr "mission 5" diff --git a/missions/lvm/05_mounting/i18n/template.pot b/missions/lvm/05_mounting/i18n/template.pot new file mode 100644 index 000000000..9f15cc374 --- /dev/null +++ b/missions/lvm/05_mounting/i18n/template.pot @@ -0,0 +1,55 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: GameShell LVM Mission 05_mounting\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-12-04 20:10+0100\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + + +msgid "Bravo! Ouskelcoule, Douskelpar and Grandflac are well connected to the Esdea kingdom and their registers are up to date!" +msgstr "" + +msgid "Connect the kingdom to the village of Douskelpar" +msgstr "" + +msgid "Connect the kingdom to the village of Grandflac" +msgstr "" + +msgid "Connect the kingdom to the village of Ouskelcoule" +msgstr "" + +msgid "Correctly fill in the Douskelpar register" +msgstr "" + +msgid "Correctly fill in the Grandflac register" +msgstr "" + +msgid "Correctly fill in the Ouskelcoule register" +msgstr "" + +msgid "Create the 'Maison Commune' directory in each village" +msgstr "" + +msgid "Create the village Douskelpar in Esdea" +msgstr "" + +msgid "Create the village Grandflac in Esdebe" +msgstr "" + +msgid "Create the village Ouskelcoule in Esdea" +msgstr "" + +msgid "mission 5" +msgstr "" diff --git a/missions/lvm/05_mounting/init.sh b/missions/lvm/05_mounting/init.sh new file mode 100644 index 000000000..74ff47963 --- /dev/null +++ b/missions/lvm/05_mounting/init.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env sh + +source "$MISSION_DIR/../00_shared/utils.sh" + +_mission_init() ( + echo "$(eval_gettext "mission 5")" + lvm_init "05" + return $? + +) + +_mission_init diff --git a/missions/lvm/05_mounting/static.sh b/missions/lvm/05_mounting/static.sh new file mode 100644 index 000000000..621502b6e --- /dev/null +++ b/missions/lvm/05_mounting/static.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env sh + +# Do nothing +return 0 \ No newline at end of file diff --git a/missions/lvm/06_resize/auto.sh b/missions/lvm/06_resize/auto.sh new file mode 100644 index 000000000..b4e179f88 --- /dev/null +++ b/missions/lvm/06_resize/auto.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env sh + +# Increase the size of ouskelcoule to 40M +danger sudo lvextend -L 40M /dev/esdea/ouskelcoule +danger sudo resize2fs /dev/esdea/ouskelcoule + +# Decrease the size of douskelpar to 10M +danger sudo umount /dev/esdea/douskelpar +danger sudo e2fsck -y -f /dev/esdea/douskelpar +danger sudo resize2fs -M /dev/esdea/douskelpar +danger sudo lvchange -an /dev/esdea/douskelpar +danger sudo lvreduce --yes -L 10M /dev/esdea/douskelpar +danger sudo lvchange -ay /dev/esdea/douskelpar +danger sudo resize2fs /dev/esdea/douskelpar +danger sudo mount /dev/esdea/douskelpar "$GSH_HOME/Esdea/Douskelpar" +danger sudo chown -R "$USER:$USER" "$GSH_HOME/Esdea/Douskelpar" + diff --git a/missions/lvm/06_resize/check.sh b/missions/lvm/06_resize/check.sh new file mode 100644 index 000000000..b5ac8e839 --- /dev/null +++ b/missions/lvm/06_resize/check.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env sh + +source "$MISSION_DIR/../00_shared/utils.sh" + +_mission_check() ( + + # Check that the logical volumes exist with the correct sizes + if ! check_lv_size esdea/ouskelcoule 40; then + echo "$(eval_gettext "The borders of the village of Ouskelcoule should be 40 Mornifles!")" + return 1 + fi + + if ! check_lv_size esdea/douskelpar 10; then + echo "$(eval_gettext "The borders of the village of Douskelpar should be 10 Mornifles!")" + return 1 + fi + + echo "$(eval_gettext "Bravo, the borders of the villages of Ouskelcoule and Douskelpar have been well adapted to the realities of the terrain!")" + return 0 +) + +_mission_check \ No newline at end of file diff --git a/missions/lvm/06_resize/clean.sh b/missions/lvm/06_resize/clean.sh new file mode 100644 index 000000000..b8d991ebf --- /dev/null +++ b/missions/lvm/06_resize/clean.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env sh + +source "$MISSION_DIR/../00_shared/utils.sh" + +# Do nothing we need to keep the loop devices and the disk images +# for the next missions in the LVM series. + +lvm_cleanup "06" +return $? diff --git a/missions/lvm/06_resize/goal/en.txt b/missions/lvm/06_resize/goal/en.txt new file mode 100644 index 000000000..ee0dafc7b --- /dev/null +++ b/missions/lvm/06_resize/goal/en.txt @@ -0,0 +1,48 @@ +Objectives +========= +It's been six months now since the colonists settled in, and the villages +are starting to take shape. + +In **Ouskelcoule**, development is spectacular: carried by strong fishing +activity and river exploitation thanks to the mill, the village prospers. +The original borders now seem too narrow to accommodate +all the newcomers. + +Conversely, **Douskelpar** has grown little. Its activity remains essential — +notably thanks to its sawmill, which provides the wood necessary for building +Ouskelcoule — but hostile climatic conditions push to maintain +a reduced village, faithful to traditional mountain architecture. +Here, the borders originally drawn are too large and must be tightened. + +The LVM administrators therefore send you on a mission to **Esdea** to +adapt the village boundaries. +They would have gone themselves, but you know how it is: a preparation +meeting to plan the meeting, followed by the meeting report to validate +in meeting, not forgetting the report summary — all this takes time... +And then it's Friday and on Friday, there are fries in the cafeteria. It was therefore +deemed preferable to delegate the mission to you since, I quote "you know the road well, the villages, the local populations." and "we trust you: you're going to do this very well!" + +After much debate and stamped and double-stamped reports, they have established the following new borders: +- **Ouskelcoule** → 40 Mornifles (Mo) +- **Douskelpar** → 10 Mornifles (Mo) + + +Useful Commands +================ +lvchange -ay/n + Activates/Deactivates an LVM volume + +lvextend + Enlarges a logical volume and adjusts the file system. + +lvreduce + Reduces a logical volume and adjusts the file system + (⚠️ warning, delicate and potentially destructive operation). + +e2fsck + Checks a Linux file system + +resize2fs -M + Resizes the file system to use the minimum possible space. + +umount diff --git a/missions/lvm/06_resize/goal/fr.txt b/missions/lvm/06_resize/goal/fr.txt new file mode 100644 index 000000000..16d968a32 --- /dev/null +++ b/missions/lvm/06_resize/goal/fr.txt @@ -0,0 +1,54 @@ +Objectifs +========= +Cela fait maintenant six mois que les colons se sont installés, et les villages +commencent à prendre forme. + +À **Ouskelcoule**, le développement est spectaculaire : porté par une forte activité +de pêche et l’exploitation de la rivière grâce au moulin, le village prospère. +Les frontières originales semblent désormais trop étroites pour accueillir +tous les nouveaux arrivants. + +À l’inverse, **Douskelpar** n’a que peu grandi. Son activité reste essentielle — +notamment grâce à sa scierie, qui fournit le bois nécessaire à l’édification +d’Ouskelcoule — mais les conditions climatiques hostiles poussent à maintenir +un village réduit, fidèle à l’architecture traditionnelle de montagne. +Ici, les frontières tracées à l’origine sont trop larges et doivent être resserrées. + +Les administrateurs de la LVM vous envoient donc en mission en **Esdea** pour +adapter les limites des villages. +Ils y seraient bien allés eux-mêmes, mais vous savez ce que c’est : une réunion +de préparation pour planifier la réunion, suivie du rapport de réunion à valider +en réunion, sans oublier le résumé du rapport — tout ça prend du temps… +Et puis c'est vendredi et le vendredi, il y a frites à la cantine. Il a donc été +jugé préférable de vous déléguer la mission puisque, je cite "vous connaissez bien la route, les villages, les populations locales." et que "on vous fait confiance : vous allez faire ça très bien !" + + +Après moult débats et rapports tamponnés et doubles tamponnés, ils ont établi les nouvelles frontières +suivantes : +- **Ouskelcoule** → 40 Mornifles (Mo) +- **Douskelpar** → 10 Mornifles (Mo) + + +Commandes utiles +================ +lvchange -ay/n + Active/Désactive un volume LVM + +lvextend + Agrandit un volume logique et ajuste le système de fichiers. + +lvreduce + Réduit un volume logique et ajuste le système de fichiers + (⚠️ attention, opération délicate et potentiellement destructive). + +e2fsck + Vérifie un système de fichier Linux + +resize2fs -M + Redimensionne le système de fichier pour utiliser le minimum de place possible. + +umount + Démonter disque du système de fichier. + +lsblk -f + Vérifie la taille et l’état actuels des volumes logiques. diff --git a/missions/lvm/06_resize/i18n/en.po b/missions/lvm/06_resize/i18n/en.po new file mode 100644 index 000000000..e2760b6c3 --- /dev/null +++ b/missions/lvm/06_resize/i18n/en.po @@ -0,0 +1,31 @@ +# English translations for GameShell LVM Mission package. +# Copyright (C) 2025 THE GameShell LVM Mission'S COPYRIGHT HOLDER +# This file is distributed under the same license as the GameShell LVM Mission package. +# Automatically generated, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: GameShell LVM Mission 06_resize\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-12-04 20:10+0100\n" +"PO-Revision-Date: 2025-12-04 20:10+0100\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: en_US\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgid "" +"Bravo, the borders of the villages of Ouskelcoule and Douskelpar have been " +"well adapted to the realities of the terrain!" +msgstr "" +"Bravo, the borders of the villages of Ouskelcoule and Douskelpar have been " +"well adapted to the realities of the terrain!" + +msgid "The borders of the village of Douskelpar should be 10 Mornifles!" +msgstr "The borders of the village of Douskelpar should be 10 Mornifles!" + +msgid "The borders of the village of Ouskelcoule should be 40 Mornifles!" +msgstr "The borders of the village of Ouskelcoule should be 40 Mornifles!" diff --git a/missions/lvm/06_resize/i18n/fr.po b/missions/lvm/06_resize/i18n/fr.po new file mode 100644 index 000000000..acbbc8f80 --- /dev/null +++ b/missions/lvm/06_resize/i18n/fr.po @@ -0,0 +1,29 @@ +# French translations for GameShell LVM Mission package. +# Copyright (C) 2025 THE GameShell LVM Mission'S COPYRIGHT HOLDER +# This file is distributed under the same license as the GameShell LVM Mission package. +# Automatically generated, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: GameShell LVM Mission 06_resize\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-12-04 20:10+0100\n" +"PO-Revision-Date: 2025-12-04 20:10+0100\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +msgid "" +"Bravo, the borders of the villages of Ouskelcoule and Douskelpar have been " +"well adapted to the realities of the terrain!" +msgstr "Bravo, les frontières des villages d'Ouskelcoule, de Douskelpar ont bien été adaptées aux réalités du terrain !" + +msgid "The borders of the village of Douskelpar should be 10 Mornifles!" +msgstr "Les frontières du village de Douskelpar devraient faire 10 Mornifles !" + +msgid "The borders of the village of Ouskelcoule should be 40 Mornifles!" +msgstr "Les frontières du village d'Ouskelcoule devraient faire 40 Mornifles !" diff --git a/missions/lvm/06_resize/i18n/template.pot b/missions/lvm/06_resize/i18n/template.pot new file mode 100644 index 000000000..0aa94859b --- /dev/null +++ b/missions/lvm/06_resize/i18n/template.pot @@ -0,0 +1,28 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: GameShell LVM Mission 06_resize\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-12-04 20:10+0100\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + + +msgid "Bravo, the borders of the villages of Ouskelcoule and Douskelpar have been well adapted to the realities of the terrain!" +msgstr "" + +msgid "The borders of the village of Douskelpar should be 10 Mornifles!" +msgstr "" + +msgid "The borders of the village of Ouskelcoule should be 40 Mornifles!" +msgstr "" diff --git a/missions/lvm/06_resize/init.sh b/missions/lvm/06_resize/init.sh new file mode 100644 index 000000000..c8416ed18 --- /dev/null +++ b/missions/lvm/06_resize/init.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env sh + +source "$MISSION_DIR/../00_shared/utils.sh" + +_mission_init() ( + + lvm_init "06" + return $? + +) + +_mission_init diff --git a/missions/lvm/06_resize/static.sh b/missions/lvm/06_resize/static.sh new file mode 100644 index 000000000..621502b6e --- /dev/null +++ b/missions/lvm/06_resize/static.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env sh + +# Do nothing +return 0 \ No newline at end of file diff --git a/missions/lvm/07_snapshot/auto.sh b/missions/lvm/07_snapshot/auto.sh new file mode 100644 index 000000000..63f51a8fc --- /dev/null +++ b/missions/lvm/07_snapshot/auto.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env sh + +danger sudo lvcreate -L 5M -s -n ouskelcoule_snap /dev/esdea/ouskelcoule +danger sudo lvcreate -L 5M -s -n douskelpar_snap /dev/esdea/douskelpar +danger sudo lvcreate -L 5M -s -n grandflac_snap /dev/esdebe/grandflac diff --git a/missions/lvm/07_snapshot/check.sh b/missions/lvm/07_snapshot/check.sh new file mode 100644 index 000000000..f5fd01712 --- /dev/null +++ b/missions/lvm/07_snapshot/check.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env sh + +_mission_check() ( + if ! [ -e "/dev/esdea/ouskelcoule_snap" ]; then + echo "$(eval_gettext "The backup of the village of Ouskelcoule is still missing.")" + return 1 + fi + + if ! [ -e "/dev/esdea/douskelpar_snap" ]; then + echo "$(eval_gettext "The backup of the village of Douskelpar is still missing.")" + return 1 + fi + + if ! [ -e "/dev/esdebe/grandflac_snap" ]; then + echo "$(eval_gettext "The backup of the village of Grandflac is still missing.")" + return 1 + fi + + echo "$(eval_gettext "Bravo! Ouskelcoule, Douskelpar and Grandflac are well archived, ready to be restored if necessary!")" + return 0 +) + +_mission_check diff --git a/missions/lvm/07_snapshot/clean.sh b/missions/lvm/07_snapshot/clean.sh new file mode 100644 index 000000000..16150dfbb --- /dev/null +++ b/missions/lvm/07_snapshot/clean.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env sh + +source "$MISSION_DIR/../00_shared/utils.sh" + +# Do nothing we need to keep the loop devices and the disk images +# for the next missions in the LVM series. + +lvm_cleanup "07" +return $? diff --git a/missions/lvm/07_snapshot/goal/en.txt b/missions/lvm/07_snapshot/goal/en.txt new file mode 100644 index 000000000..c7ea978f2 --- /dev/null +++ b/missions/lvm/07_snapshot/goal/en.txt @@ -0,0 +1,36 @@ +Objectives +========= +The LVM administrators, prudent people fond of paperwork, cannot stand +the idea that a change could take place without a **certified copy** being +archived beforehand. Lucky break, the geo-mancers have just developed a +new techno-magic allowing to store an etheric snapshot of a region. + +Thus, before enlarging Ouskelcoule or reducing Douskelpar, they require you +to produce a magical duplicate of the existing villages, in order to be able to +"go back" in case of problems... or simply to fill an additional file +at the Archives Office. + +In geo-mancer jargon, this is called a **snapshot**. +But the explorers, much less rigorous and more inclined towards +taverns, quickly distorted the word into **"schnapshot"**: a process that consists +of keeping a small security reserve... like a bottom of schnapps in the bottle, +just in case. + +Some confusion between **snapshot** (copy) and **schnaps-shot** (bottoms up) are still to be deplored +among illiterate adventurers, probably explaining why several land surveys +are illegible — stained with wine and annotated with bawdy songs. + +The LVM administrators are quite willing to manage snapshot archiving (think about it, sorting, storing, organizing papers that +will never be read by anyone, the whole office talks about nothing else), but they're counting on you to go do the operations on site. +Make a "snapshot" of the villages of Ouskelcoule, Ouskelpar and Grandflac +- ouskelcoule_snap +- douskelpar_snap +- grandflac_snap + +Note: The LVM administrators think that 5 Mornifles per snapshot are largely sufficient + + +Useful Commands +================ +lvcreate -s ... + Creates a snapshot (instant copy) of a logical volume. diff --git a/missions/lvm/07_snapshot/goal/fr.txt b/missions/lvm/07_snapshot/goal/fr.txt new file mode 100644 index 000000000..652c4382d --- /dev/null +++ b/missions/lvm/07_snapshot/goal/fr.txt @@ -0,0 +1,36 @@ +Objectifs +========= +Les administrateurs de la LVM, gens prudents et férus de paperasse, ne supportent +pas l’idée qu’un changement puisse avoir lieu sans qu’une **copie conforme** ne +soit archivée au préalable. Coup de chance, les géo-mantiens viennent justement de développé une +nouvelle techno-magie permettant de stocker un instantané éthérique d'une région. + +Ainsi, avant d’agrandir Ouskelcoule ou de réduire Douskelpar, ils exigent de vous +que vous produisiez un double magique des villages existants, afin de pouvoir +“revenir en arrière” en cas de problème… ou simplement pour remplir un dossier +supplémentaire au Bureau des Archives. + +Dans le jargon des géo-mantiens, on appelle cela un **snapshot**. +Mais les explorateurs, beaucoup moins rigoureux et d'avantage portés sur +les tavernes, ont vite déformé le mot en **“schnapshot”** : un procédé qui consiste +à garder une petite réserve de sécurité… comme un fond de schnaps dans la bouteille, +au cas où. + +Quelques confusions entre **snapshot** (copie) et **schnaps-shot** (cul sec) sont encore à déplorer +auprès des aventuriers peu lettrés, expliquant probablement pourquoi plusieurs relevés de +terrains sont illisibles — tachées de vin et annotées de chansons paillardes. + +Les administrateurs de la LVM sont tout disposés à gérer l'archivage des snapshots (pensez donc, trier, stocker, organiser des papiers qui +ne seront jamais lus par personne, tout le bureau ne parle que de ça), mais ils comptent sur vous pour aller faire les opérations sur place. +Faites une "snapshot" des villages d'Ouskelcoule, d'Ouskelpar et de Grandflac +- ouskelcoule_snap +- douskelpar_snap +- grandflac_snap + +Note : Les administrateurs de la LVM pense que 5 Mornifles par snapshot sont largement suffisants + + +Commandes utiles +================ +lvcreate -s ... + Crée un snapshot (copie instantanée) d'un logical volume. diff --git a/missions/lvm/07_snapshot/i18n/en.po b/missions/lvm/07_snapshot/i18n/en.po new file mode 100644 index 000000000..37f7c1334 --- /dev/null +++ b/missions/lvm/07_snapshot/i18n/en.po @@ -0,0 +1,34 @@ +# English translations for GameShell LVM Mission package. +# Copyright (C) 2025 THE GameShell LVM Mission'S COPYRIGHT HOLDER +# This file is distributed under the same license as the GameShell LVM Mission package. +# Automatically generated, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: GameShell LVM Mission 07_snapshot\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-12-04 20:10+0100\n" +"PO-Revision-Date: 2025-12-04 20:10+0100\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: en_US\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgid "" +"Bravo! Ouskelcoule, Douskelpar and Grandflac are well archived, ready to be " +"restored if necessary!" +msgstr "" +"Bravo! Ouskelcoule, Douskelpar and Grandflac are well archived, ready to be " +"restored if necessary!" + +msgid "The backup of the village of Douskelpar is still missing." +msgstr "The backup of the village of Douskelpar is still missing." + +msgid "The backup of the village of Grandflac is still missing." +msgstr "The backup of the village of Grandflac is still missing." + +msgid "The backup of the village of Ouskelcoule is still missing." +msgstr "The backup of the village of Ouskelcoule is still missing." diff --git a/missions/lvm/07_snapshot/i18n/fr.po b/missions/lvm/07_snapshot/i18n/fr.po new file mode 100644 index 000000000..81cf9b035 --- /dev/null +++ b/missions/lvm/07_snapshot/i18n/fr.po @@ -0,0 +1,32 @@ +# French translations for GameShell LVM Mission package. +# Copyright (C) 2025 THE GameShell LVM Mission'S COPYRIGHT HOLDER +# This file is distributed under the same license as the GameShell LVM Mission package. +# Automatically generated, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: GameShell LVM Mission 07_snapshot\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-12-04 20:10+0100\n" +"PO-Revision-Date: 2025-12-04 20:10+0100\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +msgid "" +"Bravo! Ouskelcoule, Douskelpar and Grandflac are well archived, ready to be " +"restored if necessary!" +msgstr "Bravo ! Ouskelcoule, Douskelpar et Grandflac sont bien archivés, prêts à être restaurés si nécessaire !" + +msgid "The backup of the village of Douskelpar is still missing." +msgstr "Il manque encore la sauvegarde du village de Douskelpar." + +msgid "The backup of the village of Grandflac is still missing." +msgstr "Il manque encore la sauvegarde du village de Grandflac." + +msgid "The backup of the village of Ouskelcoule is still missing." +msgstr "Il manque encore la sauvegarde du village d'Ouskelcoule." diff --git a/missions/lvm/07_snapshot/i18n/template.pot b/missions/lvm/07_snapshot/i18n/template.pot new file mode 100644 index 000000000..db15eb73f --- /dev/null +++ b/missions/lvm/07_snapshot/i18n/template.pot @@ -0,0 +1,31 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: GameShell LVM Mission 07_snapshot\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-12-04 20:10+0100\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + + +msgid "Bravo! Ouskelcoule, Douskelpar and Grandflac are well archived, ready to be restored if necessary!" +msgstr "" + +msgid "The backup of the village of Douskelpar is still missing." +msgstr "" + +msgid "The backup of the village of Grandflac is still missing." +msgstr "" + +msgid "The backup of the village of Ouskelcoule is still missing." +msgstr "" diff --git a/missions/lvm/07_snapshot/init.sh b/missions/lvm/07_snapshot/init.sh new file mode 100644 index 000000000..1e1611c3e --- /dev/null +++ b/missions/lvm/07_snapshot/init.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env sh + +source "$MISSION_DIR/../00_shared/utils.sh" + +_mission_init() ( + + lvm_init "07" + return $? + +) + +_mission_init diff --git a/missions/lvm/07_snapshot/static.sh b/missions/lvm/07_snapshot/static.sh new file mode 100644 index 000000000..621502b6e --- /dev/null +++ b/missions/lvm/07_snapshot/static.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env sh + +# Do nothing +return 0 \ No newline at end of file diff --git a/missions/lvm/08_extend_group/auto.sh b/missions/lvm/08_extend_group/auto.sh new file mode 100644 index 000000000..8d2f972f2 --- /dev/null +++ b/missions/lvm/08_extend_group/auto.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env sh + +danger sudo pvcreate "/dev/gsh_sdc" +danger sudo vgextend esdebe "/dev/gsh_sdc" +danger sudo lvcreate -L 10M -n oljoliptichaaah esdebe diff --git a/missions/lvm/08_extend_group/check.sh b/missions/lvm/08_extend_group/check.sh new file mode 100644 index 000000000..c39f5630e --- /dev/null +++ b/missions/lvm/08_extend_group/check.sh @@ -0,0 +1,34 @@ +#!/usr/bin/env sh + +source "$MISSION_DIR/../00_shared/utils.sh" + +_mission_check() ( + # Check /dev/gsh_sdc is a physical volume + danger sudo pvdisplay "/dev/gsh_sdc" > /dev/null 2>&1 + if [ $? -ne 0 ]; then + echo "$(eval_gettext "You must incarnate the province of Esdece as physical land.")" + return 1 + fi + + # Check /dev/gsh_sdc is part of esdebe VG + danger sudo pvdisplay "/dev/gsh_sdc" | grep "esdebe" > /dev/null 2>&1 + if [ $? -ne 0 ]; then + echo "$(eval_gettext "You must add the province of Esdece to Esdebe.")" + return 1 + fi + + # Check oljoliptichaaah LV exists + danger sudo lvdisplay /dev/esdebe/oljoliptichaaah > /dev/null 2>&1 + if [ $? -ne 0 ]; then + echo "$(eval_gettext "You must create the village of Oljoliptichaaah.")" + return 1 + fi + + # Check oljoliptichaaah LV size is 10M + if ! check_lv_size esdebe/oljoliptichaaah 10; then + echo "$(eval_gettext "The village of Oljoliptichaaah must be 10 Mornifles (MB).")" + return 1 + fi +) + +_mission_check diff --git a/missions/lvm/08_extend_group/clean.sh b/missions/lvm/08_extend_group/clean.sh new file mode 100644 index 000000000..e769d32f5 --- /dev/null +++ b/missions/lvm/08_extend_group/clean.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env sh + +source "$MISSION_DIR/../00_shared/utils.sh" + +# Do nothing we need to keep the loop devices and the disk images +# for the next missions in the LVM series. + +lvm_cleanup "08" +return $? diff --git a/missions/lvm/08_extend_group/goal/en.txt b/missions/lvm/08_extend_group/goal/en.txt new file mode 100644 index 000000000..54b9930d4 --- /dev/null +++ b/missions/lvm/08_extend_group/goal/en.txt @@ -0,0 +1,50 @@ +Objectives +=========================================== +The geo-mantic cartographers have spotted a new etheric land: +**Esdece** (code name **/dev/gsh_sdc**), floating in the DEV plane very close to the province of **Esdebe**. +The LVM has therefore decided, following several symposiums, that it should be attached +to the colony of **Esdebe** in order to promote its development. + +The administrators immediately entrust the explorers with founding +a new village there. After several commissions (and a quarrel over the +choice of name, requiring the intervention of the clerk to physically separate +the "Administrator of Cumbersome Registers" and the "Manager of Orthogonal +Lists"), the decree finally falls. + +The name chosen will be the one proposed by the explorers who carried out the reconnaissance mission, +as reported by the field staff in charge of colony/LVM liaison: **Oljoliptichaaah** + +The administrators have also decreed that the village's basic borders should be 10 Mornifles (Mo) + +Guess who is in charge of bringing the news to the explorers in the field? + +Extract from the minutes of R.A.P.P.O.R.T. (Administrative Meeting to Officially Present the Field Report): + STAKEHOLDERS: + Field Staff: Jean Courencor + Administrative Staff for Inspection and Registration of Reports: Louis de Pointe du Lac + + INTERVIEW MINUTES: + [...] + + PAPER: So there you got on your horse and left? + Jean Courencor: That's right, and leaving I said to him **"And for the name what do we say?"** + PAPER: And then? + Jean Courencor: He just yelled "Oljoliptichaaah!" + PAPER: "Oljolipticha"? + Jean Courencor: No, with more "a"s, "Oljoliptichaaah". + PAPER: Hmm... Does it take an "h" at the end? + +END OF MINUTES + + +--- + +Useful Commands +================ +pvcreate + Create a physical volume + +vgextend + Extends a volume group + +lvcreate diff --git a/missions/lvm/08_extend_group/goal/fr.txt b/missions/lvm/08_extend_group/goal/fr.txt new file mode 100644 index 000000000..186ac90b1 --- /dev/null +++ b/missions/lvm/08_extend_group/goal/fr.txt @@ -0,0 +1,51 @@ +Objectifs +=========================================== +Les cartographes géo-mantiens ont repéré une nouvelle terre éthérée : +**Esdece** (nom de code **/dev/gsh_sdc**), flottant dans le plan DEV tout proche de la province d’**Esdebe**. +La LVM a donc décidé, suite à plusieurs colloques, qu’elle devait être rattachée +à la colonie d’**Esdebe** afin de favoriser son développement. + +Les administrateurs confient aussitôt aux explorateurs le soin d’y fonder +un nouveau village. Après plusieurs commissions (et une querelle sur le +choix du nom, nécessitant l’intervention du greffier pour séparer physiquement +« l’Administrateur des Registres Encombrants » et le « Gestionnaire des Listes +Orthogoniques »), le décret finit par tomber. + +Le nom retenu sera celui proposé par les explorateurs ayant effectué la mission de reconnaissance, +tel que rapporté par le personnel de terrain en charge de la liaison colonie/LVM : **Oljoliptichaaah** + +Les administrateurs ont également décrété que les frontières de base du village devraient faire 10 Mornifles (Mo) + +Devinez qui est en charge d'apporter la nouvelle aux explorateurs sur le terrain ? + +Extrait du PV de R.A.P.P.O.R.T. (Réunion Administrative Pour Présenter Officiellement le Récit du Terrain) : + PARTIES PRENANTES : + Personnel De Terrain : Jean Courencor + Personnel Administratif Pour l’Inspection et l’Enregistrement des Récits : Louis de Pointe du Lac + + PV D'ENTRETIEN : + [...] + + PAPIER : Donc là vous êtes monté sur votre cheval et vous êtes parti ? + Jean Courencor : C’est ça, et en partant je lui ai dit **« Et pour le nom on dit quoi ? »** + PAPIER : Et alors ? + Jean Courencor : Il a juste crié « Oljoliptichaaah ! » + PAPIER : « Oljolipticha » ? + Jean Courencor : Non, avec plus de « a », « Oljoliptichaaah ». + PAPIER : Hum... Ça prend un « h » à la fin ? + +FIN DE PV + + +--- + +Commandes utiles +================ +pvcreate + Créer un volume physique + +vgextend + Étend un volume groupe + +lvcreate + Créer un volume logique \ No newline at end of file diff --git a/missions/lvm/08_extend_group/i18n/en.po b/missions/lvm/08_extend_group/i18n/en.po new file mode 100644 index 000000000..6c54027d5 --- /dev/null +++ b/missions/lvm/08_extend_group/i18n/en.po @@ -0,0 +1,30 @@ +# English translations for GameShell LVM Mission package. +# Copyright (C) 2025 THE GameShell LVM Mission'S COPYRIGHT HOLDER +# This file is distributed under the same license as the GameShell LVM Mission package. +# Automatically generated, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: GameShell LVM Mission 08_extend_group\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-12-04 20:10+0100\n" +"PO-Revision-Date: 2025-12-04 20:10+0100\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: en_US\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgid "The village of Oljoliptichaaah must be 10 Mornifles (MB)." +msgstr "The village of Oljoliptichaaah must be 10 Mornifles (MB)." + +msgid "You must add the province of Esdece to Esdebe." +msgstr "You must add the province of Esdece to Esdebe." + +msgid "You must create the village of Oljoliptichaaah." +msgstr "You must create the village of Oljoliptichaaah." + +msgid "You must incarnate the province of Esdece as physical land." +msgstr "You must incarnate the province of Esdece as physical land." diff --git a/missions/lvm/08_extend_group/i18n/fr.po b/missions/lvm/08_extend_group/i18n/fr.po new file mode 100644 index 000000000..b5daf5608 --- /dev/null +++ b/missions/lvm/08_extend_group/i18n/fr.po @@ -0,0 +1,30 @@ +# French translations for GameShell LVM Mission package. +# Copyright (C) 2025 THE GameShell LVM Mission'S COPYRIGHT HOLDER +# This file is distributed under the same license as the GameShell LVM Mission package. +# Automatically generated, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: GameShell LVM Mission 08_extend_group\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-12-04 20:10+0100\n" +"PO-Revision-Date: 2025-12-04 20:10+0100\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +msgid "The village of Oljoliptichaaah must be 10 Mornifles (MB)." +msgstr "Le village de Oljoliptichaaah doit faire 10 Mornifles (Mo)." + +msgid "You must add the province of Esdece to Esdebe." +msgstr "Vous devez ajouter la province d'Esdece à celle d'Esdebe." + +msgid "You must create the village of Oljoliptichaaah." +msgstr "Vous devez créer le village de Oljoliptichaaah." + +msgid "You must incarnate the province of Esdece as physical land." +msgstr "Vous devez incarner la province d'Esdece en tant que terre physique." diff --git a/missions/lvm/08_extend_group/i18n/template.pot b/missions/lvm/08_extend_group/i18n/template.pot new file mode 100644 index 000000000..ddf187565 --- /dev/null +++ b/missions/lvm/08_extend_group/i18n/template.pot @@ -0,0 +1,31 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: GameShell LVM Mission 08_extend_group\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-12-04 20:10+0100\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + + +msgid "The village of Oljoliptichaaah must be 10 Mornifles (MB)." +msgstr "" + +msgid "You must add the province of Esdece to Esdebe." +msgstr "" + +msgid "You must create the village of Oljoliptichaaah." +msgstr "" + +msgid "You must incarnate the province of Esdece as physical land." +msgstr "" diff --git a/missions/lvm/08_extend_group/init.sh b/missions/lvm/08_extend_group/init.sh new file mode 100644 index 000000000..d8465f2ef --- /dev/null +++ b/missions/lvm/08_extend_group/init.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env sh + +source "$MISSION_DIR/../00_shared/utils.sh" + +_mission_init() ( + + lvm_init "08" + return $? + +) + +_mission_init diff --git a/missions/lvm/08_extend_group/static.sh b/missions/lvm/08_extend_group/static.sh new file mode 100644 index 000000000..621502b6e --- /dev/null +++ b/missions/lvm/08_extend_group/static.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env sh + +# Do nothing +return 0 \ No newline at end of file diff --git a/missions/lvm/09_vgreduce/auto.sh b/missions/lvm/09_vgreduce/auto.sh new file mode 100644 index 000000000..9646a48cd --- /dev/null +++ b/missions/lvm/09_vgreduce/auto.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env sh + +danger sudo lvchange -an /dev/esdebe/oljoliptichaaah esdebe +danger sudo lvremove -f /dev/esdebe/oljoliptichaaah +danger sudo vgreduce esdebe "/dev/gsh_sdc" +danger sudo pvremove "/dev/gsh_sdc" diff --git a/missions/lvm/09_vgreduce/check.sh b/missions/lvm/09_vgreduce/check.sh new file mode 100644 index 000000000..77272322f --- /dev/null +++ b/missions/lvm/09_vgreduce/check.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env sh + +source "$MISSION_DIR/../00_shared/utils.sh" + +_mission_check() ( + # Check /dev/esdebe/oljoliptichaaah is removed + if danger sudo lvdisplay /dev/esdebe/oljoliptichaaah >/dev/null 2>&1; then + echo "$(eval_gettext "You must remove the village of Oljoliptichaaah from the province of Esdebe.")" + return 1 + fi + + # Check esdebe VG have been reduced + PV_COUNT=$(danger sudo vgdisplay esdebe | grep "PV Count" | awk '{print $3}') + if [ "$PV_COUNT" -ne 1 ]; then + echo "$(eval_gettext "You must separate the provinces of Esdebe and Esdece.")" + return 1 + fi + + # Check /dev/gsh_sdc is no longer a physical volume + if danger sudo pvdisplay "/dev/gsh_sdc" >/dev/null 2>&1; then + echo "$(eval_gettext "You must return the province of Esdece to the ethereal dimension.")" + return 1 + fi + + echo "$(eval_gettext "Bravo, Oljoliptichaaah has been erased from the map and the province of Esdece returned to the ethereal dimension! \ + This should prevent the king's subjects from being devoured by overly gluttonous felines, and more importantly, prevent LVM staff from having to fill out paperwork about these disappearances.")" + + return 0 +) + +_mission_check diff --git a/missions/lvm/09_vgreduce/clean.sh b/missions/lvm/09_vgreduce/clean.sh new file mode 100644 index 000000000..c9adf4922 --- /dev/null +++ b/missions/lvm/09_vgreduce/clean.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env sh + +source "$MISSION_DIR/../00_shared/utils.sh" + +# Do nothing we need to keep the loop devices and the disk images +# for the next missions in the LVM series. + +lvm_cleanup "09" +return $? diff --git a/missions/lvm/09_vgreduce/goal/en.txt b/missions/lvm/09_vgreduce/goal/en.txt new file mode 100644 index 000000000..1b97274a5 --- /dev/null +++ b/missions/lvm/09_vgreduce/goal/en.txt @@ -0,0 +1,46 @@ +Objectives +========= +Following the installation of the first colonists of **Oljoliptichaaah**, disturbing news +has reached the kingdom. +Upon their return to **Oljoliptichaaah**, the few colonists who left to look for supplies +at the village of **Grandflac** found a deserted place: meals still on the fire, +and a word clumsily carved on a tree **"TOACROCAN"**, the only vestige of village life. +Some speak of strange silhouettes prowling around the camps at night. + +After long discussions (and some reports filed in wrong folders, +found by chance while moving a closet), LVM scribes finally +noticed a detail that could have alerted from the start: the abnormal number of **"a"s** +in the village name. + +Indeed, after analysis, it would seem that the "pretty little cats" spotted +by the first travelers are actually **affectionate 250-kilogram balls of fur**, +equipped with **35-centimeter** fangs and whose sense of smell is not at all offended +by the foot odors of the average adventurer. + +The LVM administrators, considering it was better to prevent than to manage +even more posthumous paperwork, have therefore decided — at least for the moment — +to close the border and **separate Esdece from Esdebe**. +The geo-mancers have proposed to erase the village of **Oljoliptichaaah** from the maps, +to detach the province of **Esdece** from that of **Esdebe**, and to send it back, +temporarily, to the etheric sphere. + +Of course, the administrative staff felt quite enthusiastic about the idea +of going to discover the local fauna... but it turns out that an allergy to feline fur +disqualifies them all de facto. +It is therefore to you, valiant and intrepid intern, that the mission falls... + +--- + +Useful Commands +================ +lvchange -an + Deactivate a logical volume + +lvremove + Remove a logical volume + +vgreduce + Remove a physical volume from a volume group + +pvremove + Remove the LVM signature from a physical volume diff --git a/missions/lvm/09_vgreduce/goal/fr.txt b/missions/lvm/09_vgreduce/goal/fr.txt new file mode 100644 index 000000000..1db8d3393 --- /dev/null +++ b/missions/lvm/09_vgreduce/goal/fr.txt @@ -0,0 +1,47 @@ +Objectifs +========= +Suite à l’installation des premiers colons d’**Oljoliptichaaah**, des nouvelles inquiétantes +sont remontées jusqu’au royaume. +À leur retour à **Oljoliptichaaah**, les quelques colons partis chercher des vivres +au village de **Grandflac** ont trouvé un lieu désert : les repas encore sur le feu, +et un mot gravé maladroitement sur un arbre **"TOACROCAN"**, seul vestige de la vie du village. +Certains évoquent d’étranges silhouettes rôdant la nuit autour des campements. + +Après de longues discussions (et quelques rapports classés dans de mauvaises chemises, +retrouvés par hasard en déplaçant une armoire), des scribes de la LVM ont fini +par remarquer un détail qui aurait pu alerter dès le départ : le nombre anormal de **« a »** +dans le nom du village. + +En effet, après analyse, il semblerait que les « jolis petits chats » aperçus +par les premiers voyageurs soient en réalité d’**affectueuses boules de poils de 250 kilos**, +équipées de crocs de **35 centimètres** et dont l’odorat ne s’offusque nullement +des effluves de pieds de l’aventurier moyen. + +Les administrateurs de la LVM, estimant qu’il valait mieux prévenir que gérer +encore plus de paperasse posthume, ont donc décidé — au moins pour le moment — +de refermer la frontière et de **séparer Esdece d’Esdebe**. +Les géo-manciens ont proposé de rayer le village d’**Oljoliptichaaah** des cartes, +de détacher la province d’**Esdece** de celle d’**Esdebe**, et de la renvoyer, +provisoirement, dans la sphère éthérique. + +Bien sûr, le personnel administratif se sentait tout à fait enthousiaste à l’idée +d’aller découvrir la faune locale… mais il se trouve qu’une allergie aux poils de félins +les disqualifie tous de fait. +C’est donc à vous, stagiaire vaillant et intrépide, que revient la mission… + +--- + +Commandes utiles +================ +lvchange -an + Désactiver un volume logique + +lvremove + Supprimer un volume logique + +vgreduce + Retirer un volume physique d’un groupe de volumes + + +pvremove + Supprimer la signature LVM d’un volume physique diff --git a/missions/lvm/09_vgreduce/i18n/en.po b/missions/lvm/09_vgreduce/i18n/en.po new file mode 100644 index 000000000..67005ccc9 --- /dev/null +++ b/missions/lvm/09_vgreduce/i18n/en.po @@ -0,0 +1,29 @@ +# English translations for GameShell LVM Mission package. +# Copyright (C) 2025 THE GameShell LVM Mission'S COPYRIGHT HOLDER +# This file is distributed under the same license as the GameShell LVM Mission package. +# Automatically generated, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: GameShell LVM Mission 09_vgreduce\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-12-04 20:10+0100\n" +"PO-Revision-Date: 2025-12-04 20:10+0100\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: en_US\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgid "" +"You must remove the village of Oljoliptichaaah from the province of Esdebe." +msgstr "" +"You must remove the village of Oljoliptichaaah from the province of Esdebe." + +msgid "You must return the province of Esdece to the ethereal dimension." +msgstr "You must return the province of Esdece to the ethereal dimension." + +msgid "You must separate the provinces of Esdebe and Esdece." +msgstr "You must separate the provinces of Esdebe and Esdece." diff --git a/missions/lvm/09_vgreduce/i18n/fr.po b/missions/lvm/09_vgreduce/i18n/fr.po new file mode 100644 index 000000000..97e59be2e --- /dev/null +++ b/missions/lvm/09_vgreduce/i18n/fr.po @@ -0,0 +1,28 @@ +# French translations for GameShell LVM Mission package. +# Copyright (C) 2025 THE GameShell LVM Mission'S COPYRIGHT HOLDER +# This file is distributed under the same license as the GameShell LVM Mission package. +# Automatically generated, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: GameShell LVM Mission 09_vgreduce\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-12-04 20:10+0100\n" +"PO-Revision-Date: 2025-12-04 20:10+0100\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +msgid "" +"You must remove the village of Oljoliptichaaah from the province of Esdebe." +msgstr "Vous devez supprimer le village d'Oljoliptichaaah de la province d'Esdebe." + +msgid "You must return the province of Esdece to the ethereal dimension." +msgstr "Vous devez renvoyer la province d'Esdece dans la dimension éthérique." + +msgid "You must separate the provinces of Esdebe and Esdece." +msgstr "Vous devez séparer la province d'Esdebe et d'Esdece." diff --git a/missions/lvm/09_vgreduce/i18n/template.pot b/missions/lvm/09_vgreduce/i18n/template.pot new file mode 100644 index 000000000..0978ce64e --- /dev/null +++ b/missions/lvm/09_vgreduce/i18n/template.pot @@ -0,0 +1,28 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: GameShell LVM Mission 09_vgreduce\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-12-04 20:10+0100\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + + +msgid "You must remove the village of Oljoliptichaaah from the province of Esdebe." +msgstr "" + +msgid "You must return the province of Esdece to the ethereal dimension." +msgstr "" + +msgid "You must separate the provinces of Esdebe and Esdece." +msgstr "" diff --git a/missions/lvm/09_vgreduce/init.sh b/missions/lvm/09_vgreduce/init.sh new file mode 100644 index 000000000..37278fd16 --- /dev/null +++ b/missions/lvm/09_vgreduce/init.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env sh + +source "$MISSION_DIR/../00_shared/utils.sh" + +_mission_init() ( + + lvm_init "09" + return $? + +) + +_mission_init diff --git a/missions/lvm/09_vgreduce/static.sh b/missions/lvm/09_vgreduce/static.sh new file mode 100644 index 000000000..621502b6e --- /dev/null +++ b/missions/lvm/09_vgreduce/static.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env sh + +# Do nothing +return 0 \ No newline at end of file diff --git a/missions/lvm/09_vgreduce/treasure.txt b/missions/lvm/09_vgreduce/treasure.txt new file mode 100644 index 000000000..94f014268 --- /dev/null +++ b/missions/lvm/09_vgreduce/treasure.txt @@ -0,0 +1,29 @@ + ,---------------------------------------------------. + (_\ \ + | ╔════════════════════════════════════════╗ | + | ║ Classement C.V.Z.O.O ║ | + | ╚════════════════════════════════════════╝ | + | | + | La zone connue sous le nom de | + | "Province d'Esdece" est placée en | + | Classement en Zone à Vigilance | + | ZOOlogique Obligatoire. | + | | + | Par décret de la LVM, interdiction est faite | + | à tout citoyen du royaume de se rendre dans | + | le territoire susnommé, en raison de la | + | présence récurrente de félins de gabarit | + | anormal. | + | | + | Les agents sont priés de ne pas caresser la | + | faune locale, même si elle ronronne. | + | | + | ┌───────────────────────┐ | + | │ LVM │ | + | │ ✶ ✶ ✶ │ | + | └───────────────────────┘ | + _| | + (_/_____(*)__________________________________________/ + \\ + )) + ^ diff --git a/missions/lvm/10_quotas/auto.sh b/missions/lvm/10_quotas/auto.sh new file mode 100644 index 000000000..bf517c640 --- /dev/null +++ b/missions/lvm/10_quotas/auto.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash + +# --- CONFIG (edit these paths to match your system) --- +DEV="/dev/esdea/ouskelcoule" # device with the ext4 filesystem +MNT="$GSH_HOME/Esdea/Ouskelcoule" # mountpoint of the ext4 filesystem +TARGET_DIR="$MNT/Grenier Banal" # folder to limit +PROJID=4242 # arbitrary project ID number +LIMIT_KO=1000 # 1000 "Kroutons" (Ko) + + +# Add quota support to the filesystem +danger sudo umount "$MNT" 2>/dev/null +danger sudo tune2fs -O quota,project "$DEV" +danger sudo e2fsck -f "$DEV" + + +# Enable project quotas on the filesystem (temporary; add 'prjquota' to /etc/fstab to persist) +danger sudo mount -o prjquota "$DEV" "$MNT" + +# Assign a project ID to the folder and make it inherit for subfiles/subdirs +danger sudo chattr -p "$PROJID" "$TARGET_DIR" +danger sudo chattr +P "$TARGET_DIR" + +# Set the project quota (soft=hard=LIMIT_KO; in 1K blocks) +danger sudo setquota -P "$PROJID" "$LIMIT_KO" "$LIMIT_KO" 0 0 "$MNT" diff --git a/missions/lvm/10_quotas/check.sh b/missions/lvm/10_quotas/check.sh new file mode 100644 index 000000000..9406c0e8b --- /dev/null +++ b/missions/lvm/10_quotas/check.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env sh +source "$MISSION_DIR/../00_shared/utils.sh" + +_mission_check() ( + DIR="$GSH_HOME/Esdea/Ouskelcoule/Grenier Banal" + EXPECT_SIZE=1000 + + # Get project ID for the dir + PROJ=$(danger sudo lsattr -p -d "$DIR" 2>/dev/null | awk '{print $1}') + + if [[ -z "$PROJ" ]]; then + echo "$(eval_gettext "You must define a project ID for customs quotas.")" + exit 1 + fi + + # Get quota line for this project + LINE=$(danger sudo repquota -P "$(df --output=target "$DIR" | tail -1)" 2>/dev/null | awk -v id="$PROJ" '$1=="#"(id){print}') + + if [[ -z "$LINE" ]]; then + echo "$(eval_gettext "You must apply customs quotas to the granary.")" + exit 1 + fi + + # Extract soft/hard limits + USED=$(echo "$LINE" | awk '{print $3}') + SOFT=$(echo "$LINE" | awk '{print $4}') + HARD=$(echo "$LINE" | awk '{print $5}') + + if [[ "$SOFT" != "$EXPECT_SIZE" ]]; then + echo "$(eval_gettext "Customs quotas are not correctly applied to the granary, quotas must be 1000 Kroutons.")" + exit 1 + fi + + echo "$(eval_gettext "Bravo, customs quotas are correctly applied to the granary! The kingdom's economy and Friday fries are saved!")" + exit 0 +) + +_mission_check diff --git a/missions/lvm/10_quotas/clean.sh b/missions/lvm/10_quotas/clean.sh new file mode 100644 index 000000000..1cc9054a1 --- /dev/null +++ b/missions/lvm/10_quotas/clean.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env sh + +source "$MISSION_DIR/../00_shared/utils.sh" + +# Do nothing we need to keep the loop devices and the disk images +# for the next missions in the LVM series. + +lvm_cleanup "10" +return $? diff --git a/missions/lvm/10_quotas/goal/en.txt b/missions/lvm/10_quotas/goal/en.txt new file mode 100644 index 000000000..620832338 --- /dev/null +++ b/missions/lvm/10_quotas/goal/en.txt @@ -0,0 +1,50 @@ +Objectives +========= +In **Ouskelcoule**, prosperity rests on fishing: nets overflow, +the mill runs at full capacity and markets abound with fish. +But this abundance is beginning to worry LVM administrators, +who fear a collapse in fish prices in the kingdom if the colonies +start exporting their catches. + +For if the colonists see the river as a generous gift, the administrators +see it mainly as a new opportunity to draft decrees, reports and counter-reports. +After several sessions (including a preparation meeting for the validation meeting +of the preliminary report on halieutic impact), the conclusion falls: + +From now on, quotas will be in effect: the colony will be forbidden +to store more than **1,000 Kroutons (Ko)** of fish in the **Common Granary** +of the village of **Ouskelcoule**. + +Officially, it's about preserving the economy. +Unofficially, gossips claim that this decision is mainly due +to the new policy of the **Royal Canteen Administration**, +which has chosen to make Friday "fish day" rather than "fries day" +to support the economy of the young province of "Esdea". + +--- + +Historical Note +=============== +The **Krouton** (symbol Ko) is the official unit of measurement for small weights within the kingdom. +Since its implementation by **Kroûton I the Stale**, it is considered that one Krouton +corresponds to the average weight of a bread crust that fell into the king's soup. + +Learned calculations have then established that 1,000 Kroutons (Ko), placed end to end, +possess a surface of 1 Mornifle (Mo). + +Impeccable logic, according to the Royal Standards Commission, since *"a complete meal +always consists of a good crust for the meal and a good slap for +dessert"*. + +--- + +Useful Commands +================ +umount + Unmount a volume + +tune2fs -O quota,project + Enable quotas on a volume + +e2fsck + Check the filesystem diff --git a/missions/lvm/10_quotas/goal/fr.txt b/missions/lvm/10_quotas/goal/fr.txt new file mode 100644 index 000000000..56e931d45 --- /dev/null +++ b/missions/lvm/10_quotas/goal/fr.txt @@ -0,0 +1,59 @@ +Objectifs +========= +À **Ouskelcoule**, la prospérité repose sur la pêche : les filets débordent, +le moulin tourne à plein régime et les marchés regorgent de poissons. +Mais cette abondance commence à inquiéter les administrateurs de la LVM, +qui redoutent un effondrement des prix du poisson dans le royaume si les colonies +se mettent à exporter leurs prises. + +Car si les colons voient dans la rivière un don généreux, les administrateurs, eux, +y voient surtout une nouvelle occasion de rédiger décrets, rapports et contre-rapports. +Après plusieurs séances (dont une réunion de préparation à la réunion de validation +du rapport préliminaire sur l’impact halieutique), la conclusion tombe : + +Désormais, des quotas seront en vigueur : il sera interdit à la colonie +de stocker plus de **1 000 Kroutons (Ko)** de poisson dans le **Grenier Banal** +du village d’**Ouskelcoule**. + +Officiellement, il s’agit de préserver l’économie. +Officieusement, les mauvaises langues affirment que cette décision doit surtout +à la nouvelle politique de **l’Administration des Cantines Royales**, +qui a choisi de faire du vendredi le « jour du poisson » plutôt que le « jour des frites » +pour soutenir l'économie de la jeune province d'"Esdea". + +--- + +Note historique +=============== +Le **Krouton** (symbole Ko) est l’unité de mesure officielle des petits poids au sein du royaume. +Depuis sa mise en place par **Kroûton Ier le Rassis**, on considère qu’un Krouton +correspond au poids moyen d’un croûton de pain tombé dans la soupe du roi. + +De savants calculs ont ensuite établi que 1 000 Kroutons (Ko), mis bout à bout, +possèdent une surface de 1 Mornifle (Mo). + +Logique imparable, selon la Commission Royale des Étalons, puisque *« un repas +complet se compose toujours d’un bon croûton pour le repas et d’une bonne mornifle pour +le dessert »*. + +--- + +Commandes utiles +================ +umount + Démonter un volume + +tune2fs -O quota,project + Activer les quotas sur un volume + +e2fsck + Vérifier le filesystem + +mount -o prjquota + Monter un volume en activant les quotas de projet + +chattr -p + Définir un ID de projet pour un dossier + +setquota -P + Définir directement un quota pour un projet diff --git a/missions/lvm/10_quotas/i18n/en.po b/missions/lvm/10_quotas/i18n/en.po new file mode 100644 index 000000000..b1afcae3c --- /dev/null +++ b/missions/lvm/10_quotas/i18n/en.po @@ -0,0 +1,38 @@ +# English translations for GameShell LVM Mission package. +# Copyright (C) 2025 THE GameShell LVM Mission'S COPYRIGHT HOLDER +# This file is distributed under the same license as the GameShell LVM Mission package. +# Automatically generated, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: GameShell LVM Mission 10_quotas\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-12-04 20:10+0100\n" +"PO-Revision-Date: 2025-12-04 20:10+0100\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: en_US\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgid "" +"Bravo, customs quotas are correctly applied to the granary! The kingdom's " +"economy and Friday fries are saved!" +msgstr "" +"Bravo, customs quotas are correctly applied to the granary! The kingdom's " +"economy and Friday fries are saved!" + +msgid "" +"Customs quotas are not correctly applied to the granary, quotas must be 1000 " +"Kroutons." +msgstr "" +"Customs quotas are not correctly applied to the granary, quotas must be 1000 " +"Kroutons." + +msgid "You must apply customs quotas to the granary." +msgstr "You must apply customs quotas to the granary." + +msgid "You must define a project ID for customs quotas." +msgstr "You must define a project ID for customs quotas." diff --git a/missions/lvm/10_quotas/i18n/fr.po b/missions/lvm/10_quotas/i18n/fr.po new file mode 100644 index 000000000..692b88e67 --- /dev/null +++ b/missions/lvm/10_quotas/i18n/fr.po @@ -0,0 +1,34 @@ +# French translations for GameShell LVM Mission package. +# Copyright (C) 2025 THE GameShell LVM Mission'S COPYRIGHT HOLDER +# This file is distributed under the same license as the GameShell LVM Mission package. +# Automatically generated, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: GameShell LVM Mission 10_quotas\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-12-04 20:10+0100\n" +"PO-Revision-Date: 2025-12-04 20:10+0100\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +msgid "" +"Bravo, customs quotas are correctly applied to the granary! The kingdom's " +"economy and Friday fries are saved!" +msgstr "Bravo, les quotas douaniers sont correctement appliqués sur le grenier ! L'économie du royaume et les frites du vendredi sont sauvées !" + +msgid "" +"Customs quotas are not correctly applied to the granary, quotas must be 1000 " +"Kroutons." +msgstr "Les quotas douaniers ne sont pas correctement appliqués sur le grenier, les quotas doivent êtres de 1000 Kroutons." + +msgid "You must apply customs quotas to the granary." +msgstr "Vous devez appliquer les quotas douaniers sur le grenier." + +msgid "You must define a project ID for customs quotas." +msgstr "Vous devez définir un numéro de dossier (project ID) pour les quotas douaniers." diff --git a/missions/lvm/10_quotas/i18n/template.pot b/missions/lvm/10_quotas/i18n/template.pot new file mode 100644 index 000000000..e6202c235 --- /dev/null +++ b/missions/lvm/10_quotas/i18n/template.pot @@ -0,0 +1,31 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: GameShell LVM Mission 10_quotas\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-12-04 20:10+0100\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + + +msgid "Bravo, customs quotas are correctly applied to the granary! The kingdom's economy and Friday fries are saved!" +msgstr "" + +msgid "Customs quotas are not correctly applied to the granary, quotas must be 1000 Kroutons." +msgstr "" + +msgid "You must apply customs quotas to the granary." +msgstr "" + +msgid "You must define a project ID for customs quotas." +msgstr "" diff --git a/missions/lvm/10_quotas/init.sh b/missions/lvm/10_quotas/init.sh new file mode 100644 index 000000000..7682f6657 --- /dev/null +++ b/missions/lvm/10_quotas/init.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env sh + +source "$MISSION_DIR/../00_shared/utils.sh" + +_mission_init() ( + + lvm_init "10" + return $? + +) + +_mission_init diff --git a/missions/lvm/10_quotas/static.sh b/missions/lvm/10_quotas/static.sh new file mode 100644 index 000000000..621502b6e --- /dev/null +++ b/missions/lvm/10_quotas/static.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env sh + +# Do nothing +return 0 \ No newline at end of file diff --git a/missions/lvm/11_fsck/auto.sh b/missions/lvm/11_fsck/auto.sh new file mode 100644 index 000000000..199144c6b --- /dev/null +++ b/missions/lvm/11_fsck/auto.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env sh + +# Fix filesystem +danger sudo fsck -y /dev/esdea/douskelpar + +# Remount the filesystem +danger sudo mount /dev/esdea/douskelpar "$GSH_HOME/Esdea/Douskelpar" +danger sudo chown -R "$USER:$USER" "$GSH_HOME/Esdea/Douskelpar" diff --git a/missions/lvm/11_fsck/check.sh b/missions/lvm/11_fsck/check.sh new file mode 100644 index 000000000..25505f22d --- /dev/null +++ b/missions/lvm/11_fsck/check.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env sh + +source "$MISSION_DIR/../00_shared/utils.sh" + +_mission_check() ( + if ! danger sudo e2fsck -n /dev/esdea/douskelpar >/dev/null 2>&1; then + echo "$(eval_gettext "Help repair the village of Ouskelpar...")" + return 1 + fi + + if [ ! -e "$GSH_HOME/Esdea/Douskelpar/Maison Commune/population.txt" ] ||\ + [ ! -e "$GSH_HOME/Esdea/Douskelpar/Maison Commune/registre_decisions.txt" ] ||\ + [ ! -e "$GSH_HOME/Esdea/Douskelpar/Maison Commune/registre_proprietes.txt" ]; then + echo "$(eval_gettext "It seems that important administrative files for village management are missing...")" + echo "$(eval_gettext "You can probably find them by better restoring the village.")" + return 1 + fi + + return 0 +) + +_mission_check diff --git a/missions/lvm/11_fsck/clean.sh b/missions/lvm/11_fsck/clean.sh new file mode 100644 index 000000000..dac7880ae --- /dev/null +++ b/missions/lvm/11_fsck/clean.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env sh + +source "$MISSION_DIR/../00_shared/utils.sh" + +# Do nothing we need to keep the loop devices and the disk images +# for the next missions in the LVM series. + +lvm_cleanup "11" +return $? diff --git a/missions/lvm/11_fsck/goal/en.txt b/missions/lvm/11_fsck/goal/en.txt new file mode 100644 index 000000000..ddb1a921f --- /dev/null +++ b/missions/lvm/11_fsck/goal/en.txt @@ -0,0 +1,41 @@ +Objectives +========= +In **Douskelpar**, extreme weather conditions had already slowed +village development. But this time, it's much worse: a violent +rockslide has tumbled down the slopes, changing the local geography, scrambling +the organization of plots and, much worse still, carrying away part of the registers! + +Result: while the inhabitants organize among themselves to rebuild, +with help from neighboring colonies, they seem to ignore the real urgency +identified by LVM officials: +without registers, it is strictly impossible (except by resorting to archaic means +such as neighborhood inquiry) to know who uses which granary, who owns which plot, +and who gets the water from the communal well. + +The LVM officials, as always, don't lack brilliant ideas: +rather than going on site to assess the damage, help the survivors and take the opportunity +to ask them who owns the houses still standing or the plots covered with rubble, +they prefer to send you to do a **great land audit** in order to establish the **Seigneurial File for Correction of Katas (fsck)**... +this based on old maps (the fact that there is literally +a missing piece of mountain being, after all, only a minor annoyance). + +Of course, some grumblers still protest, under the pretext that *"gnagna, half of my neighbors +are under a pile of stones"* or *"patati, but of course it's my place, I built the house +myself with my uncle, there are even my initials carved right there"*. +But the LVM has decided: *"If it's not written in the registers, it never existed."* The question of whether the registers no longer exist having obviously nothing to do with it. + +Your mission: go down to Douskelpar, inspect the registers, correct the anomalies +and restore the cadastral order of the village. + +--- + +Useful Commands +================ +umount + Unmount a partition. + +fsck + Check and repair inconsistencies in a partition. + +mount + Remount a partition. diff --git a/missions/lvm/11_fsck/goal/fr.txt b/missions/lvm/11_fsck/goal/fr.txt new file mode 100644 index 000000000..c817d569b --- /dev/null +++ b/missions/lvm/11_fsck/goal/fr.txt @@ -0,0 +1,41 @@ +Objectifs +========= +À **Douskelpar**, les conditions climatiques extrêmes avaient déjà freiné +le développement du village. Mais cette fois, c’est bien pire : un violent +éboulis a dévalé les pentes, modifiant la géographie locale, brouillant +l’organisation des parcelles et, bien pire encore, emportant une partie des registres ! + +Résultat : tandis que les habitants s’organisent entre eux pour reconstruire, +avec l’aide des colonies voisines, ils semblent ignorer la véritable urgence +identifiée par les fonctionnaires de la LVM : +sans registres, il est strictement impossible (sauf à recourir à des moyens archaïques +tels que l'enquête de voisinage) de savoir qui utilise tel grenier, qui possède telle parcelle, +et à qui revient l’eau du puits communal. + +Les fonctionnaires de la LVM, comme toujours, ne manquent pas d’idées lumineuses : +plutôt que de monter sur place pour constater les dégâts, aider les survivants et en profiter +pour leur demander à qui appartiennent les maisons encore debout ou les parcelles recouvertes de gravats, +ils préfèrent vous envoyer faire un **grand audit foncier** afin d'établir le **Fichier Seigneurial de Correction des Katas (fsck)** … +ceci sur la base des anciennes cartes (le fait qu’il manque littéralement +un pan de montagne n’étant, après tout, qu’une menue contrariété). + +Bien sûr, quelques râleurs protestent encore, sous prétexte que *« gnagna, la moitié de mes voisins +sont sous un tas de cailloux »* ou *« patati, mais bien sûr que c’est chez moi, j’ai construit la maison +moi-même avec mon oncle, il y a même mes initiales gravées juste là »*. +Mais la LVM a tranché : *« Si ce n’est pas écrit dans les registres, cela n’a jamais existé. »*. La question de savoir si les registres n'existent plus n'ayant évidemment rien à voir là dedans. + +Votre mission : descendre à Douskelpar, inspecter les registres, corriger les anomalies +et restaurer l’ordre cadastral du village. + +--- + +Commandes utiles +================ +umount + Démonter une partition. + +fsck + Vérifier et réparer les incohérences d'une partition. + +mount + Remonter une partition. diff --git a/missions/lvm/11_fsck/i18n/en.po b/missions/lvm/11_fsck/i18n/en.po new file mode 100644 index 000000000..d1ba301f6 --- /dev/null +++ b/missions/lvm/11_fsck/i18n/en.po @@ -0,0 +1,31 @@ +# English translations for GameShell LVM Mission package. +# Copyright (C) 2025 THE GameShell LVM Mission'S COPYRIGHT HOLDER +# This file is distributed under the same license as the GameShell LVM Mission package. +# Automatically generated, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: GameShell LVM Mission 11_fsck\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-12-04 20:10+0100\n" +"PO-Revision-Date: 2025-12-04 20:10+0100\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: en_US\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgid "Help repair the village of Ouskelpar..." +msgstr "Help repair the village of Ouskelpar..." + +msgid "" +"It seems that important administrative files for village management are " +"missing..." +msgstr "" +"It seems that important administrative files for village management are " +"missing..." + +msgid "You can probably find them by better restoring the village." +msgstr "You can probably find them by better restoring the village." diff --git a/missions/lvm/11_fsck/i18n/fr.po b/missions/lvm/11_fsck/i18n/fr.po new file mode 100644 index 000000000..55881f7bf --- /dev/null +++ b/missions/lvm/11_fsck/i18n/fr.po @@ -0,0 +1,29 @@ +# French translations for GameShell LVM Mission package. +# Copyright (C) 2025 THE GameShell LVM Mission'S COPYRIGHT HOLDER +# This file is distributed under the same license as the GameShell LVM Mission package. +# Automatically generated, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: GameShell LVM Mission 11_fsck\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-12-04 20:10+0100\n" +"PO-Revision-Date: 2025-12-04 20:10+0100\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +msgid "Help repair the village of Ouskelpar..." +msgstr "Aidez à réparer le village d'Ouskelpar..." + +msgid "" +"It seems that important administrative files for village management are " +"missing..." +msgstr "Il semblerait que des fichiers administratifs importants pour la gestion du village soient manquants..." + +msgid "You can probably find them by better restoring the village." +msgstr "Vous pouvez probablement les retrouver en restaurant mieux le village." diff --git a/missions/lvm/11_fsck/i18n/template.pot b/missions/lvm/11_fsck/i18n/template.pot new file mode 100644 index 000000000..4e8d5b9c9 --- /dev/null +++ b/missions/lvm/11_fsck/i18n/template.pot @@ -0,0 +1,28 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: GameShell LVM Mission 11_fsck\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-12-04 20:10+0100\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + + +msgid "Help repair the village of Ouskelpar..." +msgstr "" + +msgid "It seems that important administrative files for village management are missing..." +msgstr "" + +msgid "You can probably find them by better restoring the village." +msgstr "" diff --git a/missions/lvm/11_fsck/init.sh b/missions/lvm/11_fsck/init.sh new file mode 100644 index 000000000..d7c26b9ba --- /dev/null +++ b/missions/lvm/11_fsck/init.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env sh + +source "$MISSION_DIR/../00_shared/utils.sh" + +_mission_init() ( + + lvm_init "11" + return $? + +) + +_mission_init diff --git a/missions/lvm/11_fsck/static.sh b/missions/lvm/11_fsck/static.sh new file mode 100644 index 000000000..621502b6e --- /dev/null +++ b/missions/lvm/11_fsck/static.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env sh + +# Do nothing +return 0 \ No newline at end of file diff --git a/missions/lvm/12_merging/auto.sh b/missions/lvm/12_merging/auto.sh new file mode 100644 index 000000000..7becbb979 --- /dev/null +++ b/missions/lvm/12_merging/auto.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env sh + +# Unmount filesystems to allow merging +danger sudo umount Esdea/Douskelpar/ +danger sudo umount Esdea/Ouskelcoule/ +danger sudo umount Esdebe/Grandflac/ + +# Rename the volume group Esdea to USA +danger sudo vgrename esdea usa + +# Merge the volume group Esdebe into USA +danger sudo lvchange -yf -an esdebe/grandflac_snap +danger sudo lvremove -yf esdebe/grandflac_snap + +danger sudo vgchange -an usa +danger sudo vgchange -an esdebe +danger sudo vgmerge -y usa esdebe + +# Activate the logical volumes in the merged volume group +danger sudo vgchange -ay usa + + diff --git a/missions/lvm/12_merging/check.sh b/missions/lvm/12_merging/check.sh new file mode 100644 index 000000000..c617d2758 --- /dev/null +++ b/missions/lvm/12_merging/check.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env sh + +source "$MISSION_DIR/../00_shared/utils.sh" + +_mission_check() ( + # Check that the volume group "usa" exists + if ! danger sudo vgdisplay usa >/dev/null 2>&1; then + echo "$(eval_gettext "You must rename the province of Esdea to USA.")" + return 1 + fi + + if danger sudo vgdisplay esdea >/dev/null 2>&1; then + echo "$(eval_gettext "You must delete the province of Esdea, only the province of USA must exist.")" + return 1 + fi + + if danger sudo vgdisplay esdebe >/dev/null 2>&1; then + echo "$(eval_gettext "You must attach the province of Esdebe to the province of USA.")" + return 1 + fi + + # Check that the volume group "usa" contains both logical volumes + if ! danger sudo lvs usa/douskelpar >/dev/null 2>&1; then + echo "$(eval_gettext "The village Douskelpar must be in the new province of USA.")" + return 1 + fi + if ! danger sudo lvs usa/ouskelcoule >/dev/null 2>&1; then + echo "$(eval_gettext "The village Ouskelcoule must be in the new province of USA.")" + return 1 + fi + if ! danger sudo lvs usa/grandflac >/dev/null 2>&1; then + echo "$(eval_gettext "The village Grandflac must be in the new province of USA.")" + return 1 + fi + + echo "$(eval_gettext "Bravo! You have successfully attached the colonies of Esdea and Esdebe into a new autonomous province, the USA!")" + + return 0 +) + +_mission_check diff --git a/missions/lvm/12_merging/clean.sh b/missions/lvm/12_merging/clean.sh new file mode 100644 index 000000000..bf5d7a269 --- /dev/null +++ b/missions/lvm/12_merging/clean.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env sh + +source "$MISSION_DIR/../00_shared/utils.sh" + +# Do nothing we need to keep the loop devices and the disk images +# for the next missions in the LVM series. + +lvm_cleanup "12" +return $? diff --git a/missions/lvm/12_merging/goal/en.txt b/missions/lvm/12_merging/goal/en.txt new file mode 100644 index 000000000..d9c7c3d7a --- /dev/null +++ b/missions/lvm/12_merging/goal/en.txt @@ -0,0 +1,49 @@ +Objectives +========= +Since their foundation, the colonies of **Esdea**, **Esdebe** and **Esdece** have patiently +endured the decrees, quotas, audits, censuses and extraordinary commissions +of the **LVM (Lands & Villages Management)**. + +But after the **Douskelpar** collapse, the cup runneth over: +- increasingly absurd administrative controls, +- customs rules changing every week, +- unfair decisions made solely based on incomplete registers, +- and, to crown it all, the new **Salted Fish Tax** — +imposed on each Krouton (Ko) of dried cod exported from Ouskelcoule. + +The triggering event was the sadly famous **Fish Party**, +which remained in the chronicles under the name of **Krouton Party**. +One night, the inhabitants of **Ouskelcoule**, exasperated by these iniquitous taxes, +went up to the docks, opened the granaries and threw a whole +shipment of salted fish into the river while shouting slogans that became famous: + +*"Down the stream with the fish, let's soak the Kroutons!"* +*"No taxation without ration!"* +*"The fish is ours, not the LVM's!"* + +From there, a question began to circulate in all the colonies: +*"But by the way... what exactly is the LVM for?"* + +Exhausted, the colonies gathered in assembly and decided it was time +to chart their own path. +They proclaimed their **independence** and founded a new kingdom: the **Union of Autonomous Settlements (USA)**, **Settlements** being the name given by the colonists to their first camps. + +The LVM did try to protest, and explain to the colonists that they first had to fill out form "B-12" to obtain receipt "A-127" necessary to file their case with the "Complaints and Claims Office", open every fourth Thursday of the month from 2:30 PM to 2:55 PM, but the colonists seemed little sensitive to the argument, too busy symbolically throwing stamps, feathers and registers marked with the LVM emblem into the river. + +Eager to organize their kingdom according to a new form of government, they have entrusted you, chief intern Trauma Jefassonne, a literate individual who has always been by their side in the field, to organize and implement the separation of the colonies from the kingdom and their fusion into a new entity. Sharing their annoyance against the administrative absurdity of the kingdom in general, and the LVM in particular, you have decided to accept and join the cause +of the rebels! + +Your first job as organizer of independence will therefore be: +- To cut the roads between the kingdom and the colony villages +- To rename the colony of Esdea to "USA" +- To attach the colony of Esdebe to that of Esdea. + +Note: Be careful, you may have to delete old snapshots that might be lying around in the bottom of LVM drawers + +--- + +Useful Commands +================ + +umount + Unmount a disk diff --git a/missions/lvm/12_merging/goal/fr.txt b/missions/lvm/12_merging/goal/fr.txt new file mode 100644 index 000000000..e63edc71f --- /dev/null +++ b/missions/lvm/12_merging/goal/fr.txt @@ -0,0 +1,59 @@ +Objectifs +========= +Depuis leur fondation, les colonies d’**Esdea**, **Esdebe** et **Esdece** ont supporté +patiemment les décrets, quotas, audits, recensements et commissions extraordinaires +de la **LVM (Lands & Villages Management)**. + +Mais après l’éboulement de **Douskelpar**, la coupe est pleine : +- contrôles administratifs toujours plus absurdes, +- règles douanières changeant chaque semaine, +- décisions injustes tranchées uniquement sur la base de registres incomplets, +- et, pour couronner le tout, la nouvelle **Taxe sur le Poisson Salé** — +imposée sur chaque Krouton (Ko) de morue séchée exportée hors d’Ouskelcoule. + +L’événement déclencheur a été le tristement célèbre **Poisson Party**, +resté dans les chroniques sous le nom de **Krouton Party**. +Une nuit, les habitants d’**Ouskelcoule**, excédés par ces taxes iniques, +sont montés sur les quais, ont ouvert les greniers et ont jeté tout un +chargement de poisson salé dans la rivière en criant des slogans restés célèbres : + +*« À la flotte les poissons, trempons les Kroutons ! »* +*« Pas de taxation sans ration ! »* +*« Le poisson est à nous, pas à la LVM ! »* + +À partir de là, une question a commencé à circuler dans toutes les colonies : +*« Mais au fait… la LVM, ça sert à quoi exactement ? »* + +Épuisées, les colonies se sont réunies en assemblée et ont décidé qu’il était temps +de tracer leur propre chemin. +Elles ont proclamé leur **indépendance** et ont fondé un nouveau royaume : l'**Union des Settlements Autonomes (USA)**, **Settlements** étant le nom donné par les colons à leurs premiers campements. + +La LVM a bien tenté de protester, et d'expliquer aux colons qu'ils devaient d'abord remplir le formulaire "B-12" pour obtenir le récépissé "A-127" nécessaire au dépôts de leur dossier auprès du "Bureau des plaintes et réclamations", ouvert tout les quatrièmes jeudi du mois de 14h30 à 14h55, les colons semblent avoir été peu sensibles à l'argument, trop occupés à jeter symboliquement à la rivière les tampons, plumes et registres marqués de l'emblème de la LVM. + +Désireux d'organiser leur royaume selon une forme nouvelle de gouvernement, ils vous ont chargé vous, stagiaire en chef Trauma Jefassonne, individu lettré mais qui a toujours été à leur coté sur le terrain, d'organiser et mettre en oeuvre la séparation des colonnies du royaume et leur fusions en une nouvelle entitée. Partageant leur agacement contre l'absurdité administrative du royaume en général, et de la LVM en particulier, vous avez décider d'accepter et de rejoindre la cause +des rebelles ! + +Votre premier travail en tant qu'organisateur de l'indépendance sera donc : +- De couper les routes entre le royaume et les villages colonnies +- De renommer la colonie d'Esdea en "USA" +- De rattacher la colonie d'Esdebe à celle d'Esdea. + +Note : Attention, vous risquez de devoir supprimer les vielles snapshots qui pourraient trainer au fond des tiroirs de la LVM + +--- + +Commandes utiles +================ + +umount + Démonter un disque + +vgrename + Renommer un groupe de volume + +vgmerge + Fussionner deux groupes de volume + +vgchange + Modifier l’état d’un groupe de volumes (par exemple, l’activer ou le désactiver). + diff --git a/missions/lvm/12_merging/i18n/en.po b/missions/lvm/12_merging/i18n/en.po new file mode 100644 index 000000000..78816be6a --- /dev/null +++ b/missions/lvm/12_merging/i18n/en.po @@ -0,0 +1,45 @@ +# English translations for GameShell LVM Mission package. +# Copyright (C) 2025 THE GameShell LVM Mission'S COPYRIGHT HOLDER +# This file is distributed under the same license as the GameShell LVM Mission package. +# Automatically generated, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: GameShell LVM Mission 12_merging\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-12-04 20:10+0100\n" +"PO-Revision-Date: 2025-12-04 20:10+0100\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: en_US\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgid "" +"Bravo! You have successfully attached the colonies of Esdea and Esdebe into " +"a new autonomous province, the USA!" +msgstr "" +"Bravo! You have successfully attached the colonies of Esdea and Esdebe into " +"a new autonomous province, the USA!" + +msgid "The village Douskelpar must be in the new province of USA." +msgstr "The village Douskelpar must be in the new province of USA." + +msgid "The village Grandflac must be in the new province of USA." +msgstr "The village Grandflac must be in the new province of USA." + +msgid "The village Ouskelcoule must be in the new province of USA." +msgstr "The village Ouskelcoule must be in the new province of USA." + +msgid "You must attach the province of Esdebe to the province of USA." +msgstr "You must attach the province of Esdebe to the province of USA." + +msgid "" +"You must delete the province of Esdea, only the province of USA must exist." +msgstr "" +"You must delete the province of Esdea, only the province of USA must exist." + +msgid "You must rename the province of Esdea to USA." +msgstr "You must rename the province of Esdea to USA." diff --git a/missions/lvm/12_merging/i18n/fr.po b/missions/lvm/12_merging/i18n/fr.po new file mode 100644 index 000000000..74a42e824 --- /dev/null +++ b/missions/lvm/12_merging/i18n/fr.po @@ -0,0 +1,41 @@ +# French translations for GameShell LVM Mission package. +# Copyright (C) 2025 THE GameShell LVM Mission'S COPYRIGHT HOLDER +# This file is distributed under the same license as the GameShell LVM Mission package. +# Automatically generated, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: GameShell LVM Mission 12_merging\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-12-04 20:10+0100\n" +"PO-Revision-Date: 2025-12-04 20:10+0100\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +msgid "" +"Bravo! You have successfully attached the colonies of Esdea and Esdebe into " +"a new autonomous province, the USA!" +msgstr "Bravo ! Vous avez réussi à rattacher les colonies d'Esdea et d'Esdebe en une nouvelle province autonome, les USA !" + +msgid "The village Douskelpar must be in the new province of USA." +msgstr "Le village Douskelpar doit être dans la nouvelle province d'USA." + +msgid "The village Grandflac must be in the new province of USA." +msgstr "Le village Grandflac doit être dans la nouvelle province d'USA." + +msgid "The village Ouskelcoule must be in the new province of USA." +msgstr "Le village Ouskelcoule doit être dans la nouvelle province d'USA." + +msgid "You must attach the province of Esdebe to the province of USA." +msgstr "Vous devez rattacher la province d'Esdebe à la province d'USA." + +msgid "You must delete the province of Esdea, only the province of USA must exist." +msgstr "Vous devez supprimer la province d'Esdea seule la province d'USA doit exister." + +msgid "You must rename the province of Esdea to USA." +msgstr "Vous devez renommer la province d'Esdea en USA." diff --git a/missions/lvm/12_merging/i18n/template.pot b/missions/lvm/12_merging/i18n/template.pot new file mode 100644 index 000000000..322b47e00 --- /dev/null +++ b/missions/lvm/12_merging/i18n/template.pot @@ -0,0 +1,40 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: GameShell LVM Mission 12_merging\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-12-04 20:10+0100\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + + +msgid "Bravo! You have successfully attached the colonies of Esdea and Esdebe into a new autonomous province, the USA!" +msgstr "" + +msgid "The village Douskelpar must be in the new province of USA." +msgstr "" + +msgid "The village Grandflac must be in the new province of USA." +msgstr "" + +msgid "The village Ouskelcoule must be in the new province of USA." +msgstr "" + +msgid "You must attach the province of Esdebe to the province of USA." +msgstr "" + +msgid "You must delete the province of Esdea, only the province of USA must exist." +msgstr "" + +msgid "You must rename the province of Esdea to USA." +msgstr "" diff --git a/missions/lvm/12_merging/init.sh b/missions/lvm/12_merging/init.sh new file mode 100644 index 000000000..e8dc8710e --- /dev/null +++ b/missions/lvm/12_merging/init.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env sh + +source "$MISSION_DIR/../00_shared/utils.sh" + +_mission_init() ( + + lvm_init "12" + return $? + +) + +_mission_init diff --git a/missions/lvm/12_merging/static.sh b/missions/lvm/12_merging/static.sh new file mode 100644 index 000000000..621502b6e --- /dev/null +++ b/missions/lvm/12_merging/static.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env sh + +# Do nothing +return 0 \ No newline at end of file diff --git a/missions/lvm/13_exporting/auto.sh b/missions/lvm/13_exporting/auto.sh new file mode 100644 index 000000000..ff875a398 --- /dev/null +++ b/missions/lvm/13_exporting/auto.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env sh + + +danger sudo vgchange -an usa +danger sudo vgexport -y usa diff --git a/missions/lvm/13_exporting/check.sh b/missions/lvm/13_exporting/check.sh new file mode 100644 index 000000000..9d20ada3a --- /dev/null +++ b/missions/lvm/13_exporting/check.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env sh + +source "$MISSION_DIR/../00_shared/utils.sh" + +_mission_check() ( + # Check that the volume group "usa" is exported + if danger sudo vgs -o vg_name,vgexported --noheadings | grep -q "^ *usa *exported"; then + echo "$(eval_gettext "Bravo, the federal republic of USA is ready for its ''disk change'' as the geo-mancers say!")" + return 0 + else + echo "$(eval_gettext "You must prepare the federal republic of USA to secure its astral teleportation!")" + return 1 + fi +) + +_mission_check diff --git a/missions/lvm/13_exporting/clean.sh b/missions/lvm/13_exporting/clean.sh new file mode 100644 index 000000000..dff7f089e --- /dev/null +++ b/missions/lvm/13_exporting/clean.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env sh + +source "$MISSION_DIR/../00_shared/utils.sh" + +# Do nothing we need to keep the loop devices and the disk images +# for the next missions in the LVM series. + +lvm_cleanup "13" +return $? diff --git a/missions/lvm/13_exporting/goal/en.txt b/missions/lvm/13_exporting/goal/en.txt new file mode 100644 index 000000000..ad1343deb --- /dev/null +++ b/missions/lvm/13_exporting/goal/en.txt @@ -0,0 +1,28 @@ +Objective +===================================================== +The situation has become critical. +The **United States of Autonomous Settlements (USA)**, recently proclaimed, +are in armed conflict with the Kingdom of **Bordereau VI The Stamped**. +The Federal Council of the new Republic is considering, on advice from the "Cabinet of geo-mantic experts of the federal republic", employing an unprecedented magical solution: **Astral Teleportation**, a technique +described by the geo-mancers as a "disk change", even though nobody really understands what they mean by that. + +In plain terms, the USA wants to tear their entire lands from this world to +reinstall them elsewhere, out of reach of the LVM and royal armies. + +You're not very reassured by this idea — after all, tearing pieces of world apart, it's nice on paper but it still seems a bit messy. You did manage to +convince the federal administrators that before such an extreme measure, +it was at least necessary to **freeze the villages** and **stabilize the Union**, in order +to prevent any unexpected access during the astral transfer. + +It is therefore to you, humble intern turned crisis management expert, that it falls to prepare the ground, by deactivating the different villages and preparing the new autonomous province for its plane change. + +--- + +Useful Commands +================ + +vgchange -an + Deactivate a volume group + +vgexport + Export a volume group diff --git a/missions/lvm/13_exporting/goal/fr.txt b/missions/lvm/13_exporting/goal/fr.txt new file mode 100644 index 000000000..b00f71fc3 --- /dev/null +++ b/missions/lvm/13_exporting/goal/fr.txt @@ -0,0 +1,29 @@ +Objectif +===================================================== +La situation est devenue critique. +Les **États Unis des Settlements Autonomes (USA)**, récemment proclamés, +sont en conflit armé avec le Royaume d’**Bordereau VI Le Tamponné**. +Le Conseil Fédéral de la nouvelle République songe, sur conseil du "Cabinet des experts géo-manciens de la république fédérale" à employer une solution magique inédite : la **Téléportation Astrale**, une technique +décrite par les géo-manciens comme un « changement de disque », même si personne ne comprend vraiment ce qu'ils veulent dire par là. + +En clair, les USA veulent arracher leurs terres entières de ce monde pour +les réinstaller ailleurs, hors de portée de la LVM et des armées royales. + +Vous n’êtes pas très rassuré par cette idée — après tout, arracher des bouts de monde, c'est bien joli sur le papier mais ça semble quand même un peu salissant. Vous avez tout de même réussi à +convaincre les administrateurs fédéraux qu’avant une mesure aussi extrême, +il fallait au moins **figer les villages** et **stabiliser l’Union**, afin +d’empêcher tout accès imprévu pendant le transfert astral. + +C’est donc à vous, humble stagiaire devenu expert en gestion de crise, qu’il revient de préparer le terrain, en désactivant les différents village et en préparant la nouvelle province autonome à son changement de plan. + +--- + +Commandes utiles +================ + +vgchange -an + Désactiver un groupe de volume + +vgexport + Exporter un groupe de volume + diff --git a/missions/lvm/13_exporting/i18n/en.po b/missions/lvm/13_exporting/i18n/en.po new file mode 100644 index 000000000..3a1b6822c --- /dev/null +++ b/missions/lvm/13_exporting/i18n/en.po @@ -0,0 +1,32 @@ +# English translations for GameShell LVM Mission package. +# Copyright (C) 2025 THE GameShell LVM Mission'S COPYRIGHT HOLDER +# This file is distributed under the same license as the GameShell LVM Mission package. +# Automatically generated, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: GameShell LVM Mission 13_exporting\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-12-04 20:10+0100\n" +"PO-Revision-Date: 2025-12-04 20:10+0100\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: en_US\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgid "" +"Bravo, the federal republic of USA is ready for its ''disk change'' as the " +"geo-mancers say!" +msgstr "" +"Bravo, the federal republic of USA is ready for its ''disk change'' as the " +"geo-mancers say!" + +msgid "" +"You must prepare the federal republic of USA to secure its astral " +"teleportation!" +msgstr "" +"You must prepare the federal republic of USA to secure its astral " +"teleportation!" diff --git a/missions/lvm/13_exporting/i18n/fr.po b/missions/lvm/13_exporting/i18n/fr.po new file mode 100644 index 000000000..3537d142b --- /dev/null +++ b/missions/lvm/13_exporting/i18n/fr.po @@ -0,0 +1,28 @@ +# French translations for GameShell LVM Mission package. +# Copyright (C) 2025 THE GameShell LVM Mission'S COPYRIGHT HOLDER +# This file is distributed under the same license as the GameShell LVM Mission package. +# Automatically generated, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: GameShell LVM Mission 13_exporting\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-12-04 20:10+0100\n" +"PO-Revision-Date: 2025-12-04 20:10+0100\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +msgid "" +"Bravo, the federal republic of USA is ready for its ''disk change'' as the " +"geo-mancers say!" +msgstr "Bravo, la république fédérale des USA est prête pour son \"changement de disque\" comme disent les géo-manciens !" + +msgid "" +"You must prepare the federal republic of USA to secure its astral " +"teleportation!" +msgstr "Vous devez préparer la république fédérale des USA pour sécuriser sa téléportation astrale !" diff --git a/missions/lvm/13_exporting/i18n/template.pot b/missions/lvm/13_exporting/i18n/template.pot new file mode 100644 index 000000000..341f2708b --- /dev/null +++ b/missions/lvm/13_exporting/i18n/template.pot @@ -0,0 +1,25 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: GameShell LVM Mission 13_exporting\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-12-04 20:10+0100\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + + +msgid "Bravo, the federal republic of USA is ready for its ''disk change'' as the geo-mancers say!" +msgstr "" + +msgid "You must prepare the federal republic of USA to secure its astral teleportation!" +msgstr "" diff --git a/missions/lvm/13_exporting/init.sh b/missions/lvm/13_exporting/init.sh new file mode 100644 index 000000000..9d8fe7ad3 --- /dev/null +++ b/missions/lvm/13_exporting/init.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env sh + +source "$MISSION_DIR/../00_shared/utils.sh" + +_mission_init() ( + + lvm_init "13" + return $? + +) + +_mission_init diff --git a/missions/lvm/13_exporting/static.sh b/missions/lvm/13_exporting/static.sh new file mode 100644 index 000000000..621502b6e --- /dev/null +++ b/missions/lvm/13_exporting/static.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env sh + +# Do nothing +return 0 \ No newline at end of file diff --git a/missions/lvm/14_importing/auto.sh b/missions/lvm/14_importing/auto.sh new file mode 100644 index 000000000..c428ba08f --- /dev/null +++ b/missions/lvm/14_importing/auto.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env sh + +# Make mount points +mkdir -p "$GSH_HOME/USA/Douskelpar" +mkdir -p "$GSH_HOME/USA/Ouskelcoule" +mkdir -p "$GSH_HOME/USA/Grandflac" + + +# Import USA VG +danger sudo vgimport -y usa +danger sudo vgchange -ay usa + +# Mount the filesystems +danger sudo mount /dev/usa/douskelpar "$GSH_HOME/USA/Douskelpar" +danger sudo chown -R "$USER:$USER" "$GSH_HOME/USA/Douskelpar" +danger sudo mount /dev/usa/ouskelcoule "$GSH_HOME/USA/Ouskelcoule" +danger sudo chown -R "$USER:$USER" "$GSH_HOME/USA/Ouskelcoule" +danger sudo mount /dev/usa/grandflac "$GSH_HOME/USA/Grandflac" +danger sudo chown -R "$USER:$USER" "$GSH_HOME/USA/Grandflac" + diff --git a/missions/lvm/14_importing/check.sh b/missions/lvm/14_importing/check.sh new file mode 100644 index 000000000..bd2399928 --- /dev/null +++ b/missions/lvm/14_importing/check.sh @@ -0,0 +1,36 @@ +#!/usr/bin/env sh + +source "$MISSION_DIR/../00_shared/utils.sh" + +_mission_check() ( + # Check if usa VG exists and is active + if ! danger sudo vgs --noheadings -o vg_name 2>/dev/null | awk '{print $1}' | grep -qx "usa"; then + echo "$(eval_gettext "You must unfreeze the federal republic of USA, astral teleportation is canceled!")" + return 1 + fi + + # Check that all mount points exists + VILLAGES=( + "Ouskelcoule" + "Douskelpar" + "Grandflac" + ) + for VILLAGE in "${VILLAGES[@]}"; do + MOUNT_POINT="$GSH_HOME/USA/$VILLAGE" + if ! [ -d "$MOUNT_POINT" ]; then + echo "$(eval_gettext "You must recreate the route between the kingdom and the village of \$VILLAGE, which does not exist!")" + return 1 + fi + + if ! mountpoint -q "$MOUNT_POINT"; then + echo "$(eval_gettext "You must reopen the route between the kingdom and the village of \$VILLAGE!")" + return 1 + fi + done + + echo "$(eval_gettext "Bravo, the federal republic of USA is again connected to the kingdom, no longer as a vassal, but as a federal and autonomous republic!")" + + return 0 +) + +_mission_check diff --git a/missions/lvm/14_importing/clean.sh b/missions/lvm/14_importing/clean.sh new file mode 100644 index 000000000..dcc9abd76 --- /dev/null +++ b/missions/lvm/14_importing/clean.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env sh + +source "$MISSION_DIR/../00_shared/utils.sh" + +# Do nothing we need to keep the loop devices and the disk images +# for the next missions in the LVM series. + +lvm_cleanup "14" +return $? diff --git a/missions/lvm/14_importing/goal/en.txt b/missions/lvm/14_importing/goal/en.txt new file mode 100644 index 000000000..2e44b72ff --- /dev/null +++ b/missions/lvm/14_importing/goal/en.txt @@ -0,0 +1,34 @@ +Objectives +========= +Aware that his kingdom's economy would be too severely impacted by +a total break in trade relations with the former colonies, and mired +in an inglorious war (the fact of having to individually stamp +each arrow by a **Grand Public Verifier of Points and Shafts** probably +not helping), King **Bordereau VI The Stamped** has consented to a meeting to sign peace. + +On the other side, after long parliamentary consultations, half a dozen +federal commissions and the creation of three new state agencies, +the republic of **USA (Union of Autonomous Settlements)** finally admitted +that the famous **astral teleportation** — this "disk change" proposed +by the geo-mancers — was probably not the most advantageous solution. + +For despite political independence, the USA also remains very dependent +on trade with the neighboring kingdom: salt, tools, and especially +Friday fries. + +It was therefore decided to bury the hatchet. +And it is once again to you, poor intern turned expert in thankless tasks, +that it falls to **unfreeze the state of the USA** and **reopen the roads between the kingdom** and the different cities of the independent republic of "USA". + +--- + +Useful Commands +================ +vgimport + Import a volume. + +vgchange -ay + Activate a volume. + +mount + Mount a partition diff --git a/missions/lvm/14_importing/goal/fr.txt b/missions/lvm/14_importing/goal/fr.txt new file mode 100644 index 000000000..8e01bed2e --- /dev/null +++ b/missions/lvm/14_importing/goal/fr.txt @@ -0,0 +1,34 @@ +Objectifs +========= +Conscient que l’économie de son royaume serait trop sévèrement impactée par +une rupture totale des liens commerciaux avec les anciennes colonies, et enlisé +dans une guerre peu glorieuse (le fait de devoir faire tamponner individuellement +chaque flèche par un **Grand Vérificateur Public des Pointes et Fûts** n’aidant +probablement pas), le roi ****Bordereau VI Le Tamponné**** a consenti à une rencontre en vue de signer la paix. + +De l’autre côté, après de longues consultations parlementaires, une demi-douzaine +de commissions fédérales et la création de trois nouvelles agences étatiques, +la république des **USA (Union des Settlements Autonomes)** a fini par admettre +que la fameuse **téléportation astrale** — ce “changement de disque” proposé +par les géo-manciens — n’était sans doute pas la solution la plus avantageuse. + +Car malgré l’indépendance politique, les USA restent, eux aussi, très dépendants +des échanges commerciaux avec le royaume voisin : le sel, les outils, et surtout +les frites du vendredi. + +Il a donc été décidé d’enterrer la hache de guerre. +Et c’est encore une fois à vous, pauvre stagiaire devenu expert en tâches ingrates, +qu’il revient de **dégeler l’état des USA** et de **rouvrir les routes entre le royaume** et les différentes ville de la république indépendante des "USA". + +--- + +Commandes utiles +================ +vgimport + Importer un volume. + +vgchange -ay + Activer un volume. + +mount + Monter une partition diff --git a/missions/lvm/14_importing/i18n/en.po b/missions/lvm/14_importing/i18n/en.po new file mode 100644 index 000000000..160c0541c --- /dev/null +++ b/missions/lvm/14_importing/i18n/en.po @@ -0,0 +1,44 @@ +# English translations for GameShell LVM Mission package. +# Copyright (C) 2025 THE GameShell LVM Mission'S COPYRIGHT HOLDER +# This file is distributed under the same license as the GameShell LVM Mission package. +# Automatically generated, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: GameShell LVM Mission 14_importing\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-12-04 20:10+0100\n" +"PO-Revision-Date: 2025-12-04 20:10+0100\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: en_US\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgid "" +"Bravo, the federal republic of USA is again connected to the kingdom, no " +"longer as a vassal, but as a federal and autonomous republic!" +msgstr "" +"Bravo, the federal republic of USA is again connected to the kingdom, no " +"longer as a vassal, but as a federal and autonomous republic!" + +msgid "" +"You must recreate the route between the kingdom and the village of \\" +"$VILLAGE, which does not exist!" +msgstr "" +"You must recreate the route between the kingdom and the village of \\" +"$VILLAGE, which does not exist!" + +msgid "" +"You must reopen the route between the kingdom and the village of \\$VILLAGE!" +msgstr "" +"You must reopen the route between the kingdom and the village of \\$VILLAGE!" + +msgid "" +"You must unfreeze the federal republic of USA, astral teleportation is " +"canceled!" +msgstr "" +"You must unfreeze the federal republic of USA, astral teleportation is " +"canceled!" diff --git a/missions/lvm/14_importing/i18n/fr.po b/missions/lvm/14_importing/i18n/fr.po new file mode 100644 index 000000000..65ad3ea4c --- /dev/null +++ b/missions/lvm/14_importing/i18n/fr.po @@ -0,0 +1,37 @@ +# French translations for GameShell LVM Mission package. +# Copyright (C) 2025 THE GameShell LVM Mission'S COPYRIGHT HOLDER +# This file is distributed under the same license as the GameShell LVM Mission package. +# Automatically generated, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: GameShell LVM Mission 14_importing\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-12-04 20:10+0100\n" +"PO-Revision-Date: 2025-12-04 20:10+0100\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +msgid "" +"Bravo, the federal republic of USA is again connected to the kingdom, no " +"longer as a vassal, but as a federal and autonomous republic!" +msgstr "Bravo, la république fédérale des USA est de nouveau connectée au royaume, non plus comme un vassale, mais une république fédérale et autonome !" + +msgid "" +"You must recreate the route between the kingdom and the village of \\" +"$VILLAGE, which does not exist!" +msgstr "Vous devez recréer la route entre le royaume et le village de $VILLAGE, qui n'existe pas !" + +msgid "" +"You must reopen the route between the kingdom and the village of \\$VILLAGE!" +msgstr "Vous devez rouvrir la route entre le royaume et le village de $VILLAGE !" + +msgid "" +"You must unfreeze the federal republic of USA, astral teleportation is " +"canceled!" +msgstr "Vous devez dégeler la république fédérale des USA, la téléportation astrale est annulée !" diff --git a/missions/lvm/14_importing/i18n/template.pot b/missions/lvm/14_importing/i18n/template.pot new file mode 100644 index 000000000..8874b259f --- /dev/null +++ b/missions/lvm/14_importing/i18n/template.pot @@ -0,0 +1,31 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: GameShell LVM Mission 14_importing\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-12-04 20:10+0100\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + + +msgid "Bravo, the federal republic of USA is again connected to the kingdom, no longer as a vassal, but as a federal and autonomous republic!" +msgstr "" + +msgid "You must recreate the route between the kingdom and the village of \\$VILLAGE, which does not exist!" +msgstr "" + +msgid "You must reopen the route between the kingdom and the village of \\$VILLAGE!" +msgstr "" + +msgid "You must unfreeze the federal republic of USA, astral teleportation is canceled!" +msgstr "" diff --git a/missions/lvm/14_importing/init.sh b/missions/lvm/14_importing/init.sh new file mode 100644 index 000000000..bcf147332 --- /dev/null +++ b/missions/lvm/14_importing/init.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env sh + +source "$MISSION_DIR/../00_shared/utils.sh" + +_mission_init() ( + + lvm_init "14" + return $? + +) + +_mission_init diff --git a/missions/lvm/14_importing/static.sh b/missions/lvm/14_importing/static.sh new file mode 100644 index 000000000..621502b6e --- /dev/null +++ b/missions/lvm/14_importing/static.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env sh + +# Do nothing +return 0 \ No newline at end of file diff --git a/missions/lvm/15_epilogue/auto.sh b/missions/lvm/15_epilogue/auto.sh new file mode 100644 index 000000000..0a6af5beb --- /dev/null +++ b/missions/lvm/15_epilogue/auto.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env sh + +danger sudo fsck -y /dev/esdea/douskelpar \ No newline at end of file diff --git a/missions/lvm/15_epilogue/check.sh b/missions/lvm/15_epilogue/check.sh new file mode 100644 index 000000000..7413b4fdf --- /dev/null +++ b/missions/lvm/15_epilogue/check.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env sh + +source "$MISSION_DIR/../00_shared/utils.sh" + +_mission_check() ( + return 0 +) + +_mission_check diff --git a/missions/lvm/15_epilogue/clean.sh b/missions/lvm/15_epilogue/clean.sh new file mode 100644 index 000000000..a26a9a588 --- /dev/null +++ b/missions/lvm/15_epilogue/clean.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env sh + +source "$MISSION_DIR/../00_shared/utils.sh" + +# Do nothing we need to keep the loop devices and the disk images +# for the next missions in the LVM series. + +lvm_cleanup "15" +return $? diff --git a/missions/lvm/15_epilogue/goal/en.txt b/missions/lvm/15_epilogue/goal/en.txt new file mode 100644 index 000000000..f4d58ec32 --- /dev/null +++ b/missions/lvm/15_epilogue/goal/en.txt @@ -0,0 +1,37 @@ +Thus ends the epic of the colonies of Esdea and Esdebe. +From the ethereal lands discovered by geo-mantic cartographers, +to villages transformed into administered provinces, to the proclamation +of independence and the founding of the **Union of Autonomous Settlements (USA)**, +you have accompanied each step, each decree and each bureaucratic absurdity. + +You have seen explorers settle, villages grow, quotas fall, +disasters strike and administrators get tangled in their own registers. +You have frozen entire kingdoms, repaired collapsed mountains, +and even prepared an astral teleportation before reason (and commerce) +brought everyone back to the negotiating table. + +The peace treaty is now signed. +The kingdom of **Bordereau VI The Stamped** and the USA again exchange their goods, their knowledge and their Friday fries. The colonists resume their lives, markets fill up, +and the royal officials, reassured, have already created three new royal offices: +one responsible for "supervising the application of the treaty", another for watching over "the balance of trade balance", and the third for "control of imports and exports of goods and services". +For their part, the USA has equipped itself with two permanent parliamentary commissions: +one dedicated to "maintaining attentive vigilance on the application of international commitments", +the other to "ensuring compliance with import rules", as well as a federal agency +specially mandated for "surveillance of extraterritorial issues", the "New Surveillance of Extraterritorial Affairs" (NSA). + +Suddenly, you feel a doubt rising in you: +the big mustachioed gentleman from the imports commission, there, +and the little hunched one from the NSA... their faces remind you of something. +Hadn't you already met them at the Christmas party +of the Royal Bureau of Arbitrary Stochastic Classifications? And there on the desk of the "First secretary for current affairs", wouldn't that be a stamp holder? +--- + +End of the Colonies Saga + +... +For now... + + + +You can stay and explore the kingdom and the new republic of USA a bit, +and do gsh when you're done! diff --git a/missions/lvm/15_epilogue/goal/fr.txt b/missions/lvm/15_epilogue/goal/fr.txt new file mode 100644 index 000000000..2600a2939 --- /dev/null +++ b/missions/lvm/15_epilogue/goal/fr.txt @@ -0,0 +1,38 @@ +Ainsi s’achève l’épopée des colonies d’Esdea et d’Esdebe. +Des terres éthérées découvertes par les cartographes géo-manciens, +aux villages transformés en provinces administrées, jusqu’à la proclamation +d’indépendance et la fondation de l’**Union des Settlements Autonomes (USA)**, +vous avez accompagné chaque étape, chaque décret et chaque absurdité bureaucratique. + +Vous avez vu les explorateurs s’installer, les villages grandir, les quotas tomber, +les catastrophes frapper et les administrateurs s’empêtrer dans leurs propres registres. +Vous avez figé des royaumes entiers, réparé des montagnes écroulées, +et même préparé une téléportation astrale avant que la raison (et le commerce) +ne ramènent tout le monde à la table des négociations. + +Le traité de paix est désormais signé. +Le royaume d’**Bordereau VI Le Tamponné** et les USA échangent de nouveau leurs biens, leurs savoirs et leurs frites du vendredi. Les colons reprennent leurs vies, les marchés se remplissent, +et les fonctionnaires royaux, rassurés, ont déjà créé trois nouveaux bureaux royaux : +l’un chargé de “superviser l’application du traité”, un autre de veiller à “l’équilibre de la balance commerciale”, et le troisième au “contrôle des importations et exportations de biens et services”. +De leur côté, les USA se sont dotés de deux commissions parlementaires permanentes : +l’une dédiée à “maintenir une vigilance attentive sur l’application des engagements internationaux”, +l’autre à “assurer la conformité des règles d’importations”, ainsi que d’une agence fédérale +spécialement mandatée pour la “surveillance des questions extraterritoriales”, la "Nouvelle Surveillance des Affaires extraterritoriales" (NSA). + +Soudain, vous sentez comme un doute monter en vous : +le gros monsieur à moustache de la commission des imports, là, +et le petit voûté de la NSA… leurs têtes vous disent quelque chose. +Vous ne les aviez pas déjà croisés au pot de Noël +du Bureau Royal des Classements Stochastiques Arbitraires ? Et là bas sur le bureau du "Premier secrétaire aux affaires courantes", ce ne serait pas un porte-tampons ? +--- + +Fin de la Saga des Colonies + +... +Pour le moment... + + + +Vous pouvez rester explorer un peu le royaume et la nouvelle république des USA, +et faire gsh quand vous avez fini ! + diff --git a/missions/lvm/15_epilogue/i18n/en.po b/missions/lvm/15_epilogue/i18n/en.po new file mode 100644 index 000000000..315af669c --- /dev/null +++ b/missions/lvm/15_epilogue/i18n/en.po @@ -0,0 +1,25 @@ +# English translations for GameShell LVM Mission package. +# Copyright (C) 2025 THE GameShell LVM Mission'S COPYRIGHT HOLDER +# This file is distributed under the same license as the GameShell LVM Mission package. +# Automatically generated, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: GameShell LVM Mission 15_epilogue\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-12-04 20:10+0100\n" +"PO-Revision-Date: 2025-12-04 20:10+0100\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: en_US\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgid "" +"You can stay and explore the kingdom and the new USA republic a bit, and " +"type gsh when you're done!" +msgstr "" +"You can stay and explore the kingdom and the new USA republic a bit, and " +"type gsh when you're done!" diff --git a/missions/lvm/15_epilogue/i18n/fr.po b/missions/lvm/15_epilogue/i18n/fr.po new file mode 100644 index 000000000..2db96dda6 --- /dev/null +++ b/missions/lvm/15_epilogue/i18n/fr.po @@ -0,0 +1,21 @@ +# French translations for GameShell LVM Mission package. +# Copyright (C) 2025 THE GameShell LVM Mission'S COPYRIGHT HOLDER +# This file is distributed under the same license as the GameShell LVM Mission package. +# Automatically generated, 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: GameShell LVM Mission 15_epilogue\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-12-04 20:10+0100\n" +"PO-Revision-Date: 2025-12-04 20:10+0100\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +msgid "You can stay and explore the kingdom and the new USA republic a bit, and type gsh when you're done!" +msgstr "Vous pouvez rester explorer un peu le royaume et la nouvelle république des USA, et faire gsh quand vous avez fini !" diff --git a/missions/lvm/15_epilogue/i18n/template.pot b/missions/lvm/15_epilogue/i18n/template.pot new file mode 100644 index 000000000..c1616d168 --- /dev/null +++ b/missions/lvm/15_epilogue/i18n/template.pot @@ -0,0 +1,22 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: GameShell LVM Mission 15_epilogue\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-12-04 20:10+0100\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + + +msgid "You can stay and explore the kingdom and the new USA republic a bit, and type gsh when you're done!" +msgstr "" diff --git a/missions/lvm/15_epilogue/init.sh b/missions/lvm/15_epilogue/init.sh new file mode 100644 index 000000000..96cfcbff4 --- /dev/null +++ b/missions/lvm/15_epilogue/init.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env sh + +source "$MISSION_DIR/../00_shared/utils.sh" + +_mission_init() ( + + lvm_init "15" + + # Display epilogue message + parchment -B Twinkle "$(eval_gettext '$MISSION_DIR/msg/en.txt')" + + + echo "$(eval_gettext "You can stay and explore the kingdom and the new USA republic a bit, and type gsh when you're done!")" + + cat $MISSION_DIR/msg/flag.txt > $GSH_HOME/USA/flag.txt + + return $? + +) + +_mission_init diff --git a/missions/lvm/15_epilogue/msg/flag.txt b/missions/lvm/15_epilogue/msg/flag.txt new file mode 100644 index 000000000..dd074fafa --- /dev/null +++ b/missions/lvm/15_epilogue/msg/flag.txt @@ -0,0 +1,61 @@ + + + + + + ███ +████ ███████████████████████████████████████████████ +██████████████████████████████████████████████████████████████████████████████████████████ █████████████████████████ +███████████████████████████████████████████████ ███████████████████████████████████████ ██ +███████████████████████████████████████████████ ██ +███ ███████████████████████████████████████████ ███ ██ +███ ████ ████████ ████████████████ ████████████ ██ +███ ████ ████ ███ █████████████ ████████████████ ███ ██ +███ █████ ███ ████████████ ██████ █████ ██ +███ █████ ████████████ ████ ████ ██ +███ █████ █████████████████ ████ ██ ███ ███ ██ ██ +███ █████ █ ██████ █ ████ ████ ███ ███ ███ ██████ ██ +███ █████ █████ █████ █ █ █████ ████ ███ █████ ██ ██ +███ ████ ██████████ █████ █ █████ █████ ███ ██ ███ ███ +███ ███████████████████████████████████████████ █████ ██ ██ ███ +███ ███████████████████████████████████████████ ███ ███ ██████ ██ ███ +███ ███████████████████████████████████████████ ███ ████ █████ ███ ██ ███ +███ ███████████████████████████████████████████ █████ ██████ ██████ █████ ███ +███ ██ ████ ██████ ██████████████ ████ ███ ███ +███ ██ █████ ██████ ██████████ ███ +███ ██ ███ █████ ██ ███ +███ ██ ███ ████ ████ ███ +███ ██ ███████ ██ ████ ██ ███ +███ ██ ██ ███ ██ ██████ ██ ███ +███ ██ █████ ██ ███ ██ ███ +███ ██ ████ ██ ███ ███ █ ██ ███ +███ ██ ██ ██████ ███ ███ ██ ██ +███ ██ ██ ██ ██ █████ ██ ██ +███ ██ ██ ████ ██████ ██ ██ +███ ██ ██ ██████ ███ ██ ██ ██ ██ ██ +███ ██ ██ ███ ███ ██ ███ ███ ██ ██ +███ ██ ██ ██ ███████ ██████ ██ +███ ██ ██ ███ ██ ███ ██████ ██ +███ ██ ██ ██ ██ ██ ███ ███ ███ +███ ██ ██ ██ ██ ███ ██ ███ +███ ██ ██ ██ ███ ████ ██ ███ ████ ███ +███ ██ ███ ████████ ████████ ████ ████ ███ ███ +███ ██ ██████ ██ ███ █████ █████ ███ +███ ██ ███ ███ ██████████ ███ +███ ██ ████████████████████████ ███ ███████ ██ +███ ██████████████ ███████████████████████ ███ ██████ ██ +███ ██ █████████████ █████ ███████████ +███ ██ ████████████████████████████████████████████████████████████████████ +███ ██ ██████████████████████████ +███ ██ ██ ███ ██████ ████ +███ ██ ████ ███ ██████████ ██████ +███ ██ ████ ███ ███ █ ███████ +███ ██ ████ ███ ██████ ███ ███ +███ ██ ████ ███ █████████ ████ ████ +███ ██ ████ ███ ████ ███████████ +██████ ███ ████ ██ ████ ████████████ +█████ ███████████ ██████████ ████ ████ +███ █████ ████ ██ ███ +███ +███ + diff --git a/missions/lvm/15_epilogue/msg/fr.txt b/missions/lvm/15_epilogue/msg/fr.txt new file mode 100644 index 000000000..f5ab6d77f --- /dev/null +++ b/missions/lvm/15_epilogue/msg/fr.txt @@ -0,0 +1,35 @@ +Ainsi s’achève l’épopée des colonies d’Esdea et d’Esdebe. +Des terres éthérées découvertes par les cartographes géo-manciens, +aux villages transformés en provinces administrées, jusqu’à la proclamation +d’indépendance et la fondation de l’**Union des Settlements Autonomes (USA)**, +vous avez accompagné chaque étape, chaque décret et chaque absurdité bureaucratique. + +Vous avez vu les explorateurs s’installer, les villages grandir, les quotas tomber, +les catastrophes frapper et les administrateurs s’empêtrer dans leurs propres registres. +Vous avez figé des royaumes entiers, réparé des montagnes écroulées, +et même préparé une téléportation astrale avant que la raison (et le commerce) +ne ramènent tout le monde à la table des négociations. + +Le traité de paix est désormais signé. +Le royaume d’**Bordereau VI Le Tamponné** et les USA échangent de nouveau leurs biens, leurs savoirs et leurs frites du vendredi. Les colons reprennent leurs vies, les marchés se remplissent, +et les fonctionnaires royaux, rassurés, ont déjà créé trois nouveaux bureaux royaux : +l’un chargé de “superviser l’application du traité”, un autre de veiller à “l’équilibre de la balance commerciale”, et le troisième au “contrôle des importations et exportations de biens et services”. +De leur côté, les USA se sont dotés de deux commissions parlementaires permanentes : +l’une dédiée à “maintenir une vigilance attentive sur l’application des engagements internationaux”, +l’autre à “assurer la conformité des règles d’importations”, ainsi que d’une agence fédérale +spécialement mandatée pour la “surveillance des questions extraterritoriales”, la "Nouvelle Surveillance des Affaires extraterritoriales" (NSA). + +Soudain, vous sentez comme un doute monter en vous : +le gros monsieur à moustache de la commission des imports, là, +et le petit voûté de la NSA… leurs têtes vous disent quelque chose. +Vous ne les aviez pas déjà croisés au pot de Noël +du Bureau Royal des Classements Stochastiques Arbitraires ? Et là bas sur le bureau du "Premier secrétaire aux affaires courantes", ce ne serait pas un porte-tampons ? +--- + +Fin de la Saga des Colonies + +... +Pour le moment... + + + diff --git a/missions/lvm/15_epilogue/static.sh b/missions/lvm/15_epilogue/static.sh new file mode 100644 index 000000000..621502b6e --- /dev/null +++ b/missions/lvm/15_epilogue/static.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env sh + +# Do nothing +return 0 \ No newline at end of file diff --git a/missions/lvm/default.idx b/missions/lvm/default.idx new file mode 100644 index 000000000..111a17c9a --- /dev/null +++ b/missions/lvm/default.idx @@ -0,0 +1,16 @@ +!00_shared +01_physical_volumes +02_volumes_group +03_logical_volumes +04_filesystem +05_mounting +06_resize +07_snapshot +08_extend_group +09_vgreduce +10_quotas +11_fsck +12_merging +13_exporting +14_importing +15_epilogue