Skip to content

Instantly share code, notes, and snippets.

@depressed-pho
Last active April 9, 2017 12:35
Show Gist options
  • Save depressed-pho/0c35009bad6a0b96ee6a4182cd4ee22f to your computer and use it in GitHub Desktop.
Save depressed-pho/0c35009bad6a0b96ee6a4182cd4ee22f to your computer and use it in GitHub Desktop.
A bash script to manage MCPE data directory mounted on PC
% mcpe-managa-data
You have 31 worlds, 1 world templates, 20 resource packs, and 2 behavior packs.
What do you want to do?
[w]: Manage worlds [t]: Manage templates [r]: Manage resource packs
[b]: Manage behavior packs [B]: Manage backups [q]: Quit
> w
Searching for worlds...
You have 31 worlds. What do you want to do?
[l]: List worlds [e]: Export a world [q]: Return to the main menu
> l
1. Vanilla Survival Challenge
2. Sandbox
3. Water and Lava
4. 7seg
5. Invis. Stuck Piston Glitch
6. Flying Machines
7. Villagers Ignoring Y
8. the end
9. Minecart Experiments
10. Item Farms
11. Slippery Vines
12. clone
13. MCPE-12422 (Vert. distance)
14. breed/food-share
15. MCPE-13983
16. MCPE-10839
17. MCPE-18496
18. Mob farm experiment
19. Fence Gate Translocation
20. Slabbed Roof Glitch
21. ZRST3.1
22. Nether Farm
23. Winter
You have 31 worlds. What do you want to do?
[l]: List worlds [e]: Export a world [q]: Return to the main menu
> e
Which world do you want to export?
world number> 4
Exporting world `7seg' as `/home/pho/var/MCPE/exports/worlds/7seg.mcworld'...
updating: behavior_packs/ (stored 0%)
updating: db/ (stored 0%)
updating: db/000005.ldb (deflated 10%)
updating: db/000006.log (deflated 97%)
updating: db/CURRENT (deflated 6%)
updating: db/LOCK (stored 0%)
updating: db/MANIFEST-000004 (deflated 10%)
updating: level.dat (deflated 37%)
updating: level.dat_old (deflated 37%)
updating: levelname.txt (stored 0%)
updating: resource_packs/ (stored 0%)
updating: world_behavior_packs.json (stored 0%)
updating: world_resource_packs.json (stored 0%)
You have 31 worlds. What do you want to do?
[l]: List worlds [e]: Export a world [q]: Return to the main menu
> q
You have 31 worlds, 1 world templates, 20 resource packs, and 2 behavior packs.
What do you want to do?
[w]: Manage worlds [t]: Manage templates [r]: Manage resource packs
[b]: Manage behavior packs [B]: Manage backups [q]: Quit
> B
What do you want to do?
[t]: Take a complete backup [q]: Return to the main menu
> t
Reinitialized existing Git repository in /home/pho/var/MCPE/backups/
Updating local copy of MCPE data directory...
sending incremental file list
Number of files: 8,503 (reg: 8,026, dir: 477)
Number of created files: 0
Number of deleted files: 0
Number of regular files transferred: 0
Total file size: 903,479,330 bytes
Total transferred file size: 0 bytes
Literal data: 0 bytes
Matched data: 0 bytes
File list size: 0
File list generation time: 0.064 seconds
File list transfer time: 0.000 seconds
Total bytes sent: 149,987
Total bytes received: 623
sent 149,987 bytes received 623 bytes 786.48 bytes/sec
total size is 903,479,330 speedup is 5,998.80
Updating a bup index...
Indexing: 8503, done (12521 paths/s).
bup: merging indexes (17013/17013), done.
Saving changed files since the last backup...
Reading index: 8503, done.
Saving: 100.00% (882711/882712k, 8503/8503 files), done.
bloom: creating from 1 file (124734 objects).
What do you want to do?
[t]: Take a complete backup [q]: Return to the main menu
> q
You have 31 worlds, 1 world templates, 20 resource packs, and 2 behavior packs.
What do you want to do?
[w]: Manage worlds [t]: Manage templates [r]: Manage resource packs
[b]: Manage behavior packs [B]: Manage backups [q]: Quit
> q
%
#!/usr/bin/env bash
set -o errexit -o nounset
shopt -s nullglob
readonly cmd_name=$(basename "$0")
readonly default_root_dir="/mnt/iPad Pro _Documents"
readonly default_var_dir="$HOME/var/MCPE"
declare root_dir="$default_root_dir"
declare var_dir="$default_var_dir"
declare worlds_dir
declare world_templates_dir
declare resource_packs_dir
declare behavior_packs_dir
declare -r -i bup_supports_non_mmap_access=0
function usage() {
echo "Usage: $0 [OPTS...]"
echo
echo "Options:"
echo " -h show this message"
echo " -r DIR set the MCPE root directory to DIR [default: $default_root_dir]"
echo " -d DIR set the local state directory to DIR [default: $default_var_dir]"
}
function parse_args() {
local opt
while getopts hr:d: opt; do
case "$opt" in
h)
usage
exit 0
;;
r)
root_dir="$OPTARG"
;;
d)
var_dir="$OPTARG"
;;
\?)
exit 1
;;
esac
done
shift $((OPTIND - 1))
if [[ ! -d "$root_dir" ]]; then
echo >&2 "$0: $root_dir: directory not found"
return 1
fi
worlds_dir="${root_dir}/games/com.mojang/minecraftWorlds"
world_templates_dir="${root_dir}/games/com.mojang/world_templates"
resource_packs_dir="${root_dir}/games/com.mojang/resource_packs"
behavior_packs_dir="${root_dir}/games/com.mojang/behavior_packs"
}
function num_items() {
local -i n=0
local d
for d in "$1"/*; do
(( n++ ))
done
echo $n
}
function show_stats() {
echo -n "You have "$(num_items "$worlds_dir")" worlds, "
echo -n $(num_items "$world_templates_dir")" world templates, "
echo -n $(num_items "$resource_packs_dir")" resource packs, "
echo "and "$(num_items "$behavior_packs_dir")" behavior packs."
}
function dump_world_map() {
ls -t "$worlds_dir" | {
while read dir; do
local name=$(< "${worlds_dir}/${dir}/levelname.txt")
printf '%s\t%s\n' "$dir" "$name"
done
}
}
function manage_worlds() {
echo "Searching for worlds..."
local -r worlds=$(dump_world_map)
local key
while true; do
echo -n "You have "$(num_items "$worlds_dir")" worlds. "
echo "What do you want to do?"
echo " [l]: List worlds [e]: Export a world [q]: Return to the main menu"
read -N 1 -p "> " key
echo
case "$key" in
"l")
echo "$worlds" | cut -f2 | nl -s '. ' -w 3 | ${PAGER:-more}
;;
"e")
while true; do
echo "Which world do you want to export?"
local world
read -p "world number> " world
if [[ ! "$world" =~ [0-9]+ ]]; then
continue
fi
local name=$(echo "$worlds" | head -n "$world" | tail -n 1 | cut -f2)
local dirname=$(echo "$worlds" | head -n "$world" | tail -n 1 | cut -f1)
local mcworld="${var_dir}/exports/worlds/${name}.mcworld"
echo "Exporting world \`${name}' as \`${mcworld}'..."
mkdir -p "$(dirname "$mcworld")"
(cd "${worlds_dir}/${dirname}" && zip -r "${mcworld}" .)
break
done
;;
"q")
break;;
*)
continue;;
esac
done
}
function manage_backups() {
local key
while true; do
echo "What do you want to do?"
echo " [t]: Take a complete backup [q]: Return to the main menu"
read -N 1 -p "> " key
echo
case "$key" in
"t")
local bup_dir="${var_dir}/backups"
BUP_DIR="${bup_dir}" bup init
if (( $bup_supports_non_mmap_access )); then
echo "Updating a bup index..."
BUP_DIR="${bup_dir}" bup index --update "$root_dir"
echo "Saving changed files since the last backup..."
BUP_DIR="${bup_dir}" bup save --strip --compress=9 -n "master" "$root_dir"
else
local local_dir="${var_dir}/backups.local"
echo "Updating local copy of MCPE data directory..."
mkdir -p "${local_dir}"
rsync --archive --fuzzy --delete --stats --progress "${root_dir}/" "$local_dir"
echo "Updating a bup index..."
BUP_DIR="${bup_dir}" bup index --update "$local_dir"
echo "Saving changed files since the last backup..."
BUP_DIR="${bup_dir}" bup save --strip --compress=9 -n "master" "$local_dir"
fi
;;
"q")
break;;
*)
continue;;
esac
done
}
function main_menu() {
show_stats
echo "What do you want to do?"
echo " [w]: Manage worlds [t]: Manage templates [r]: Manage resource packs"
echo " [b]: Manage behavior packs [B]: Manage backups [q]: Quit"
local key
while true; do
read -N 1 -p "> " key
echo
case "$key" in
"w") manage_worlds; break;;
"t") manage_templates; break;;
"r") manage_resource_packs; break;;
"b") manage_behavior_packs; break;;
"B") manage_backups; break;;
"q") return;;
*) continue;;
esac
done
main_menu
}
parse_args "$@"
main_menu
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment