Skip to content

Instantly share code, notes, and snippets.

@codingthat
Created September 24, 2017 08:43
Show Gist options
  • Save codingthat/ad37fdbb16fe6afe9ae1ff9d1876df12 to your computer and use it in GitHub Desktop.
Save codingthat/ad37fdbb16fe6afe9ae1ff9d1876df12 to your computer and use it in GitHub Desktop.
Update to word_realms_mods.sh that helps it find your swf on Linux Mint
#!/bin/bash
echo "Welcome to word-realms-mods version 0.995"
checkfile () {
if [ ! -f "$1" ]; then
echo "$1 not found! We need that."
return 1
fi
return 0
}
p () {
# Windows programs, aside from cygwin utils, will expect backslash paths
if [[ $OSTYPE == cygwin* ]]; then
slashless=$(cygpath --windows $1)
slashless=${slashless//\\/\\\\}
if [[ $2 -eq 1 ]]; then
slashless=${slashless//\\/\\\\}
fi
echo $slashless
else
echo $1
fi
return 0
}
# where are we
MY_DIR="$( cd -P "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
# try to get config
MY_CONFIG="$MY_DIR/word-realms-mods.conf"
checkfile "$MY_CONFIG" && source "$MY_CONFIG"
# any luck? check ffdec first
FFDEC_SH_CONFIG_HELP="edit $MY_CONFIG and put the full path there, e.g. FFDEC_SH_PATH=\"/path to/ffdec_x.y.z/ffdec.sh\" or with .bat under Windows"
if [ -z ${FFDEC_SH_PATH+x} ]; then
# Cygwin on Windows may not have $HOME defined where we want; use its import of %USERPROFILE%
if [ ! -z ${USERPROFILE+x} ]; then
HOME=$(cygpath "$USERPROFILE/Downloads")
fi
echo "Looking for ffdec under $HOME..."
shopt -s extglob
FFDEC_SH_PATH=$(find "$HOME" -name 'ffdec.sh')
if [ $(echo -e "$FFDEC_SH_PATH" | wc -l) -gt 1 ]; then
echo "Found more than one copy of ffdec under $HOME:"
echo
echo -e "$FFDEC_SH_PATH"
echo
echo "Please $FFDEC_SH_CONFIG_HELP"
checkfile "$MY_CONFIG" || echo "FFDEC_SH_PATH=\"\"" > $MY_CONFIG
exit
elif [ ! -n "${FFDEC_SH_PATH##+([[:space:]])}" ]; then
echo "Cannot find ffdec under $HOME . Either download it and unzip it there, or $FFDEC_SH_CONFIG_HELP"
checkfile "$MY_CONFIG" || echo "FFDEC_SH_PATH=\"\"" > $MY_CONFIG
exit
fi
fi
if [[ $(checkfile "$FFDEC_SH_PATH") ]]; then
echo "Config file $MY_CONFIG has ffdec at $FFDEC_SH_PATH , but it doesn't appear to be there"
echo "If it's the correct path, check permissions; if that doesn't work, file a bug report"
echo "If it's not the correct path, please $FFDEC_SH_CONFIG_HELP"
exit
fi
if [[ "$OS" =~ Windows ]]; then
FFDEC_SH_PATH=${FFDEC_SH_PATH//ffdec\.sh/ffdec\.bat}
fi
# at this point we have ffdec. now for WR
WR_SWF_CONFIG_HELP="edit $MY_CONFIG and put the full path there, e.g. WR_SWF_PATH=\"/path to/wordgamerelease.swf\""
if [ -z ${WR_SWF_PATH+x} ]; then
echo "Looking for Word Realms under common install directories...please report if yours is elsewhere"
# Look for Word Realms in these directories
if [[ "$OS" =~ Windows ]]; then
LOOKUP_WR_DIRS=("$(cygpath "$PROGRAMFILES/Word Realms")" "$(cygpath "$PROGRAMFILES (x86)/Word Realms")")
else
LOOKUP_WR_DIRS=("/opt/Word Realms/share" "$HOME/Downloads/Word Realms")
fi
LOOKUP_WR_NAMES=("wordgamerelease.swf" "WordRealms.swf")
for ((i = 0; i < ${#LOOKUP_WR_DIRS[@]}; i++)); do
LOOKUP_WR_DIR="${LOOKUP_WR_DIRS[$i]}"
echo "Looking in $LOOKUP_WR_DIR"
for ((j = 0; j < ${#LOOKUP_WR_NAMES[@]}; j++)); do
LOOKUP_WR_PATH="$LOOKUP_WR_DIR/${LOOKUP_WR_NAMES[$j]}"
echo $LOOKUP_WR_PATH
if [ -f "$LOOKUP_WR_PATH" ]; then
WR_SWF_PATH="$LOOKUP_WR_PATH"
echo "Found it!"
break 2
fi
done
done
# at this point we have an ffdec path and possibly a WR path. save it/them.
echo "Saving config to $MY_CONFIG"
echo "FFDEC_SH_PATH=\"$FFDEC_SH_PATH\"" > $MY_CONFIG
if [ -z ${WR_SWF_PATH+x} ]; then
echo "Cannot find the main SWF file. If Word Realms is installed, please find it, file a bug report with its location, and $WR_SWF_CONFIG_HELP"
exit
else
echo "WR_SWF_PATH=\"$WR_SWF_PATH\"" >> $MY_CONFIG
fi
fi
if [ $(checkfile "$WR_SWF_PATH") ]; then
echo "Config file $MY_CONFIG has Word Realms at $WR_SWF_PATH , but it doesn't appear to be there"
echo "If it's the correct path, check permissions; if that doesn't work, file a bug report"
echo "If it's not the correct path, please $WR_SWF_CONFIG_HELP"
exit
fi
# OK, we have the prerequisites
# now, have we previously backed up and extracted the game data?
ORIGINAL_DIR="$MY_DIR/original"
if [ ! -d "$ORIGINAL_DIR" ]; then
mkdir "$ORIGINAL_DIR"
fi
ORIGINAL_EXTRACTED_DIR="$ORIGINAL_DIR/extracted"
if [ ! -d "$ORIGINAL_EXTRACTED_DIR" ]; then
mkdir "$ORIGINAL_EXTRACTED_DIR"
fi
ORIGINAL_SWF="$ORIGINAL_DIR/wordgamerelease.swf"
if [ ! -f "$ORIGINAL_SWF" ]; then
chmod +w "$ORIGINAL_DIR"
echo "Backing up original SWF"
cp "$WR_SWF_PATH" "$ORIGINAL_SWF"
echo "Making it read-only, just in case"
chmod -w "$ORIGINAL_SWF"
fi
# mapping of numbered bin files to named xml/txt files
declare -A BINMAP=(
[2]=player.xml
[3]=parts.xml
[4]=buckets.xml
[5]=subs.xml
[6]=recipes.xml
[7]=maps.xml
[8]=monsters.xml
[9]=thwacks.xml
[10]=generate.xml
[11]=dreams.xml
[12]=taunts.xml
[13]=beeps.xml
[15]=achievements.xml
[16]=alias.xml
[17]=sfx.xml
[18]=credits.xml
[19]=skills.xml
[20]=affects.xml
[21]=anims.xml
[22]=manual.xml
[23]=scripts.txt
[24]=enchantments.xml
[25]=items.xml
[26]=dictionary_wordlist.xml
[28]=fightclub.xml
[33]=music.xml
[34]=tutorials.xml
[35]=gauntlet.xml
[39]=scenes.xml
)
TEMP_DIR="$MY_DIR/temp"
rm -rf "$TEMP_DIR"
mkdir "$TEMP_DIR"
# check for extracted data
if [ ! -f "$ORIGINAL_EXTRACTED_DIR/Word.PFR.pcode" ]; then
chmod +w "$ORIGINAL_DIR"
chmod +w "$ORIGINAL_EXTRACTED_DIR"
rm -f "$ORIGINAL_EXTRACTED_DIR/*"
echo "Extracting game data using ffdec from $FFDEC_SH_PATH"
$FFDEC_SH_PATH -format script:pcode -selectclass Word.++ -export binaryData,script "$(p "$TEMP_DIR")" "$(p "$ORIGINAL_SWF")"
if [ ! $? -eq 0 ]; then
echo "FFDec failed, bailing..."
exit 1
fi
echo "Renaming numbered files"
for i in "${!BINMAP[@]}"; do
mv "$TEMP_DIR/binaryData/$i.bin" "$ORIGINAL_EXTRACTED_DIR/${BINMAP[$i]}"
done
echo "Moving and renaming P-code files"
pcodefiles="$(find -L "$TEMP_DIR/scripts/Word" -type f -name '*.pcode')"
echo "$pcodefiles" | while read origfile; do
pcodefile="${origfile#$TEMP_DIR/scripts/Word/}"
mv "$origfile" "$ORIGINAL_EXTRACTED_DIR/Word.$pcodefile"
done
echo "Cleaning up temp files"
rm -rf "$TEMP_DIR/*"
echo "Making extracted data read-only, just in case"
chmod a-w "$ORIGINAL_EXTRACTED_DIR"/*.*
fi
MODS_DIR="$MY_DIR/mods"
if [ ! -d "$MODS_DIR" ]; then
mkdir "$MODS_DIR"
fi
# search for .tar.gz files that don't have a corresponding mod dir and unpack them automatically
shopt -s nullglob
for TARGZ in "$MODS_DIR"/*.tar.gz; do
[ "$TARGZ" == "$MODS_DIR/*.tar.gz" ] && break
mod_name=$(basename "$TARGZ" .tar.gz)
MOD_DIR="$MODS_DIR/${mod_name}"
if [ ! -d "$MOD_DIR" ]; then
echo "Found new mod $mod_name, unpacking..."
mkdir "$MOD_DIR"
tar -C "$MOD_DIR" -zxf "$TARGZ"
for DIFF in "$MOD_DIR"/*.diff; do
TO_PATCH="$(basename "$DIFF" .diff)"
patch -s -n --read-only=ignore -o "$MOD_DIR/$TO_PATCH" "$ORIGINAL_EXTRACTED_DIR/$TO_PATCH" "$DIFF"
done
rm -f "$MOD_DIR"/*.diff
fi
done
mods=("Quit")
for path in "$MODS_DIR/"*; do
[ -d "${path}" ] || continue # if not a directory, skip
dirname="$(basename "${path}")"
mods=("$dirname" "${mods[@]}")
done
options=("Install a Mod" "Restore the Original" "Create a New Mod" "Package a Mod for Distribution" "Quit")
PS3='Please enter your choice: '
select opt in "${options[@]}"
do
case $opt in
"Install a Mod")
select mod_name in "${mods[@]}"
do
if [ "$mod_name" == "Quit" ]; then
exit
fi
MOD_DIR="$MODS_DIR/$mod_name"
MOD_README="$MOD_DIR/readme.txt"
if [ -f "$MOD_README" ]; then
echo
cat "$MOD_README"
echo
fi
read -p "Are you sure you want to install $mod_name [y/N]? " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]
then
exit
fi
echo "Installing \"$mod_name\"..."
MOD_SWF="$MOD_DIR/wordgamerelease.swf"
NEEDS_REMOD=0
for f in "$MOD_DIR"/*; do
if [ "$f" -nt "$MOD_SWF" ]; then
NEEDS_REMOD=1
fi
done
if [ $NEEDS_REMOD -eq 0 ]; then
read -p "Mod files seem to already have been made into a finished SWF. [U]se it or [r]emod? " -n 1 -r
echo
if [[ $REPLY =~ ^[Rr]$ ]]
then
NEEDS_REMOD=1
fi
fi
if [ $NEEDS_REMOD -gt 0 ]; then
MOD_TEMP="$MOD_DIR/wordgamerelease-temp.swf"
echo "Making sure directory is writable"
chmod a+w "${MOD_DIR}"
echo "Making temporary copy of game to modify"
cp "$ORIGINAL_SWF" "$MOD_SWF"
echo "Replacing game data. This may take a minute or two..."
FFDEC_COMMAND_ARGS=()
for i in "${!BINMAP[@]}"; do
if [ ! -f "$MOD_DIR/${BINMAP[$i]}" ]; then
continue
fi
DIFFERENT=`diff -q "$ORIGINAL_EXTRACTED_DIR/${BINMAP[$i]}" "$MOD_DIR/${BINMAP[$i]}"`
if [ -n "$DIFFERENT" ]; then
echo "Will replace ${BINMAP[$i]}"
FFDEC_COMMAND_ARGS+=($i "$(p "${MOD_DIR}/${BINMAP[$i]}")")
if [ "${BINMAP[$i]}" == "dictionary_wordlist.xml" ]; then
echo "Will disable played-word reporting, since dictionary is modified"
cp "$MY_DIR"/mandatory/*.pcode "$MOD_DIR/"
fi
fi
done
# update the path in the easy-reload patch, unless it's been customized in some other way
MOD_FILE="$MOD_DIR/Word.GObject.691.pcode"
if [ -e "${MOD_FILE}" ]; then
MOD_FILE_BASE="$(basename "${MOD_FILE}")"
# this patch makes it so you can easily reload your changes in-game using the console, but it's computer-specific, so we need to temporarily re-create it
NATIVE_MOD_DIR=$(p "$MOD_DIR/" 1)
awk -v "MOD_DIR=$NATIVE_MOD_DIR" '{sub(/MODPATHPLACEHOLDER/,MOD_DIR)}; 1' "$MY_DIR/optional/Word.GObject.691.pcode" > "$MOD_FILE.temp"
# then see if it's significantly different from our auto-generated one or not (if it is, we don't want to scrap the modder's changes)
REASONABLE_LINES=4
DIFFERENT=`diff "$MOD_FILE.temp" "$MOD_FILE" | wc -l`
if [ "$DIFFERENT" -eq 0 ] || [ "$DIFFERENT" -gt "$REASONABLE_LINES" ]; then
rm -f "$MOD_FILE.temp"
else
rm -f "$MOD_FILE"
mv "$MOD_FILE.temp" "$MOD_FILE"
fi
fi
for pcodefile in "$MOD_DIR"/*.pcode ; do
pcodefile="$(basename "$pcodefile")"
if [[ "$pcodefile" =~ \.[0-9]+\.pcode$ ]]; then
classname="${pcodefile%.*.pcode}"
methodid="${pcodefile%.pcode}"
methodid="${methodid#$classname.}"
echo "Will replace $classname method with id $methodid"
FFDEC_COMMAND_ARGS+=($classname "$(p "${MOD_DIR}/$pcodefile")" $methodid)
fi
done
# this feature is experimental in ffdec right now and I have not had success with it yet; the game always hangs on the loading screen
for asfile in "$MOD_DIR"/*.as ; do
asfile="$(basename "$asfile")"
if [[ "$asfile" =~ \.as$ ]]; then
classname="${asfile%.as}"
echo "Will replace $classname"
FFDEC_COMMAND_ARGS+=($classname "$(p "${MOD_DIR}/$asfile")")
fi
done
echo "Doing replacements..."
"$FFDEC_SH_PATH" -replace "$(p "$MOD_SWF")" "$(p "$MOD_TEMP")" "${FFDEC_COMMAND_ARGS[@]}"
if [ ! $? -eq 0 ]; then
echo "Modification failed, apparently"
exit
fi
rm -f "$MOD_SWF"
mv "$MOD_TEMP" "$MOD_SWF"
fi
echo "Copying overtop installed game"
cp "$MOD_SWF" "$WR_SWF_PATH"
exit
echo "\"$mod_name\" installed, attempting to launch Word Realms so you can play it"
if [[ $OSTYPE == cygwin* ]]; then
"$(dirname "$WR_SWF_PATH")/Word Realms.exe" &
else
"$(dirname "$WR_SWF_PATH")/../bin/Word Realms" &
fi
break
done
exit
;;
"Restore the Original")
read -p "Are you sure you want to restore the original [y/N]? " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]
then
echo "Restoring the original game, without any mods"
cp "$ORIGINAL_SWF" "$WR_SWF_PATH"
echo "Game restored"
fi
exit
;;
"Create a New Mod")
read -p "What should the mod be called? " -e mod_name
MOD_DIR="$MODS_DIR/$mod_name"
if [ -d "$MOD_DIR" ]; then
echo "Can't call it that, $MOD_DIR already exists"
exit
fi
mkdir "$MOD_DIR"
chmod +w "$MOD_DIR"
cp "$ORIGINAL_EXTRACTED_DIR"/*.xml "$ORIGINAL_EXTRACTED_DIR"/*.txt "$MOD_DIR"/
# this patch auto-enables the in-game console so you don't need the SWORDFISH trick:
cp "$MY_DIR/optional/Word.Game.49.pcode" "$MOD_DIR/"
# this patch makes it so you can easily reload your changes in-game using the console:
NATIVE_MOD_DIR=$(p "$MOD_DIR/" 1)
awk -v "MOD_DIR=$NATIVE_MOD_DIR" '{sub(/MODPATHPLACEHOLDER/,MOD_DIR)}; 1' "$MY_DIR/optional/Word.GObject.691.pcode" > "$MOD_DIR/Word.GObject.691.pcode"
# this patch puts your mod name on the title screen:
PCODE_MOD_NAME=${mod_name//\"/\\\"}
awk -v "MOD_NAME=$PCODE_MOD_NAME" '{sub(/MODNAMEPLACEHOLDER/,MOD_NAME)}; 1' "$MY_DIR/optional/Word.MenuWindow.183.pcode" > "$MOD_DIR/Word.MenuWindow.183.pcode"
touch "$MOD_DIR"/readme.txt
chmod +w "$MOD_DIR"/*
echo "$(p "$MOD_DIR") is ready to go. Modify the files there, then rerun word-realms-mods and install your mod to test it."
exit
;;
"Package a Mod for Distribution")
select mod_name in "${mods[@]}"
do
if [ "$mod_name" == "Quit" ]; then
exit
fi
if [ -f "$MODS_DIR/$mod_name.tar.gz" ]; then
read -p "This will clobber $MODS_DIR/$mod_name.tar.gz, are you sure [y/N]? " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
exit
fi
fi
echo "Packaging $mod_name"
MOD_DIR="$MODS_DIR/$mod_name"
shopt -s nullglob
for MOD_FILE in "$MOD_DIR"/*.*; do
MOD_FILE_BASE="$(basename "${MOD_FILE}")"
# don't diff the ready-made SWF
[[ "$MOD_FILE_BASE" =~ .(swf|diff|md)$ ]] && continue
DIFFERENT=
# add any files that aren't part of original extractions
[ ! -f "$ORIGINAL_EXTRACTED_DIR/$MOD_FILE_BASE" ] && DIFFERENT=1
# however, we don't want these 'debugging' files unless the user remodded them
if [[ "$MOD_FILE_BASE" =~ 'Word.Game.49.pcode' ]]; then
# this one, compare with the optional dir
DIFFERENT=`diff -q "$MY_DIR/optional/$MOD_FILE_BASE" "$MOD_FILE"`
elif [[ "$MOD_FILE_BASE" =~ 'Word.GObject.691.pcode' ]]; then
# this patch makes it so you can easily reload your changes in-game using the console, but it's computer-specific, so we need to temporarily re-create it
NATIVE_MOD_DIR=$(p "$MOD_DIR/" 1)
awk -v "MOD_DIR=$NATIVE_MOD_DIR" '{sub(/MODPATHPLACEHOLDER/,MOD_DIR)}; 1' "$MY_DIR/optional/Word.GObject.691.pcode" > "$MOD_FILE.temp"
# then see if it's different from our auto-generated one or not (if it is, we don't want to scrap the modder's changes)
DIFFERENT=`diff -q "$MOD_FILE.temp" "$MOD_FILE"`
rm -f "$MOD_FILE.temp"
if [ -n "$DIFFERENT" ]; then
diff --normal -N -d "$ORIGINAL_EXTRACTED_DIR/$MOD_FILE_BASE" "$MOD_FILE" > "$TEMP_DIR/$MOD_FILE_BASE.diff"
else
continue
fi
elif [ -z "$DIFFERENT" ]; then
DIFFERENT=`diff -q "$ORIGINAL_EXTRACTED_DIR/$MOD_FILE_BASE" "$MOD_FILE"`
fi
if [ -n "$DIFFERENT" ]; then
echo "Preparing to package $MOD_FILE"
diff --normal -N "$ORIGINAL_EXTRACTED_DIR/$MOD_FILE_BASE" "$MOD_FILE" > "$TEMP_DIR/$MOD_FILE_BASE.diff"
fi
done
echo "Zipping diffs"
tar --strip-components=1 -czvf "$MODS_DIR/$mod_name.tar.gz" -C "$TEMP_DIR" .
if [ -d "$MOD_DIR/.hg" ]; then
echo "Mercurial repo detected. Adding diffs and asking for commit message, will push if message given..."
cp "$TEMP_DIR"/*.diff "$MOD_DIR"/
hg -R "$MOD_DIR" add "$MOD_DIR"/*.diff
hg -R "$MOD_DIR" stat -m -a
hg -R "$MOD_DIR" com && hg -R "$MOD_DIR" push
rm -f "$MOD_DIR"/*.diff
fi
rm -f "$TEMP_DIR"/*.diff
echo "Okay, you should be able to distribute $MODS_DIR/$mod_name.tar.gz for others to enjoy"
break
done
exit
;;
"Quit")
break
;;
*) echo invalid option;;
esac
done
@codingthat
Copy link
Author

If I could log in to my bitbucket account, I would do it there, but they've decided to force you to link to an Atlassin account but don't seem to be able to successfully send me a reset link, probably because I never made an Atlassin account with that address, only a plain old BitBucket one.

@codingthat
Copy link
Author

Also it should be noted that newer versions of ffdec break this script, so stick with 6.1.1 from the archives.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment