Created
September 24, 2017 08:43
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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 |
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
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.