PDA

View Full Version : Multiboxing on MAC



onivedlav
05-16-2013, 06:39 PM
Looking for help on this subject. With windows Multiboxing was easy, with so many tools available.
Now that i switched to Mac cant find a way to make it work.

Any mac user/computer genious got some tips?

ty in advance

Ryiah
05-16-2013, 08:36 PM
Now that i switched to Mac cant find a way to make it work.

My tactic on Windows is to create a second copy of DDO (I use mklink to reduce storage required but it isn't necessary). Then run both launchers initially before starting one of the clients. If I need the other I simply open the second launcher and start the second client from it. It might work on Mac OS X.

onivedlav
05-31-2013, 02:31 PM
Shameless /bump!

I keep searching, looking into lotr forums as well for ideas, cant make anything work.

How small is the Mac client comunnity!

Help please =)

Kaytis
06-01-2013, 02:29 AM
Hi onivedlav.

I cleaned up a script I have been using for several months. I put detailed instructions in the script itself about how to create it, set it up and use it. It was adapted from a script that has been available in the forums for a really long time now, so it should be ok to publish here.




#!/bin/bash

################################################## ###########################
# General Information

# Launch DDO client from CLI.
#
# (C) 2007-2011 SNy <SNy@bmx-chemnitz.de>
#
# Modded to take command line args and windoze use and by AtomicMew 6/3/12
# Modded to work on Mac OS X by Kaytis 5/31/13 v 1.1
# Modded to work on Mac OS X by Kaytis 2/18/15 v 1.2

################################################## ###########################
# How to install

# Open TextEdit, create a new document and paste the entire text of this
# document in, then select Format/Make Plain Text.
# Save the file to /Applications/DNDLauncherTemplate.sh
# Open /Applications/Utilities/Terminal and type:
#
# cp /Applications/DNDLauncherTemplate.sh /Applications/DNDLauncher.sh
# chmod 755 /Applications/DNDLauncher.sh
#
# Go back to TextEdit. Close DNDLauncherTemplate.sh and open /Applications/DNDLauncher.sh
#
# Once you have DNDLauncher.sh open follow the rest of the instructions.
# You will need to change everything that starts with "putYour".
# For every alt account you want to bring in, provide the account username
# and password. Provide the subscription index if you have more than one
# subscription for the account (this is usually not the case).
# Specify the server you play on by name.
# Wayfinder
# Ghallanda
# Argonnessen
# Thelanis
# Sarlona
# Khyber
# Cannith
# Orien
# Duplicate lines 73 through 80 to add another alt account.
# After making the mods save your file and quit TextEdit.
#
# To play a specific toon:
# Open /Applications/Utilities/Terminal and type:
# /Applications/DNDLauncher.sh putYourAltAccountToonnameHere
# Hit the return key, and you will be taken to a unique DND process running that toon.
# Use command-H to hide the DND process (or window it with the Options menu etc), and
# repeat these steps to multi-box another toon in another DND process on the same machine.
#
# To gp to the character selection screen of your main account:
# Open /Applications/Utilities/Terminal and type:
# /Applications/DNDLauncher.sh
#
# Handy tip: the up arrow will restore the last command you typed in the Terminal
# even if you quit it between sessions.
#
# This file will end up with your account usernames and passwords in it.
# DON'T SHARE YOUR CUSTOMIZED VERSION WITH OTHER PEOPLE.
# SHARE ONLY THE DNDLauncherTemplate.sh FILE.

################################################## ###########################
# User modifiable section

if [ "${1}" == "putYourAltAccountToonnameHere" ] ; then
# Alt account support
account=putYourAltAccountUsernameHere # Alt account username
pass=putYourAltAccountPasswordHere # Alt account password
selectedSub=0 # Alt account subscription. Delete this or use '0' if you only have one
selectedServer=putYourServerNameHere # Alt server name e.g. Orien
user="${1}"

elif [ "${1}" == "putYourAltAccountToonnameHere" ] ; then
# Alt account support
account=putYourAltAccountUsernameHere # Alt account username
pass=putYourAltAccountPasswordHere # Alt account password
selectedSub=0 # Alt account subscription. Delete this or use '0' if you only have one
selectedServer=putYourServerNameHere # Alt server name e.g. Orien
user="${1}"

else
# Main account support
account=putYourMainAccountUsernameHere # Main account username
pass=putYourMainAccountPasswordHere # Main account password
selectedServer=putYourServerIDHere # Server ID (e.g. 'selectedServer=7' for Orien)
user="${1}"
fi

################################################## ###########################
# Launcher script

echo "-----------------------------------------------------------------------"
echo -e "Welcome to the CLI launcher for DDO for Mac OS X version 1.2"
echo "-----------------------------------------------------------------------"

exe() { echo "> $@" ; "$@" ; }

# make this script be callable from elsewhere (desktop shortcuts etc)
oldDir=`pwd`
gameDir="/Applications/DNDLauncher.app/Contents/Resources/"

# change directory to where the launcher resources reside
cd "${gameDir}"

# cleanup temp directory for configuration files downloaded from the official servers
rm -rf .launcher
mkdir .launcher

echo "Reading game configuration..."

# Official launcher config file. The launcher config file starts it all.
# Get Game and DataCenter settings.
configFile="TurbineLauncher.exe.config"

if ! [ -r "${configFile}" ] ; then
echo -e "\nError: ${configFile} cannot be read.\n"
cd "${oldDir}"
exit
fi

game=`grep -h "DataCenter.GameName" "${configFile}" | grep -v '<!--.*-->' | sed -e "s/^.*value=\"\([^\"]*\)\".*$/\1/"`
glsDataCenter_URL=`grep -h "Launcher.DataCenterService.GLS" "${configFile}" | grep -v '<!--.*-->' | sed -e "s/^.*value=\"\([^\"]*\)\".*$/\1/"`

echo "Game Name: ${game}"
echo "Game Login Server: ${glsDataCenter_URL}"
echo "-----------------------------------------------------------------------"

# get configuration info (xml-file containing auth, patch and game servers with their corresponding settings)
# NOTE: while a normal HTTP GET to /GLS.DataCenterServer/Service.asmx/GetDatacenters?game=LOTROEU
# works fine for the european datacenter, it does not work for the US/AU/... LOTRO one
# instead, we need to send a SOAP request there, ending up with a SOAP answer (no whitespace whatsoever)
# now, to have at least some whitespace we can deal with, sed is used to insert a newline after each closing xml tag below

echo "Querying Game Login Server..."

# wget \
# --no-check-certificate -q \
# --header 'Content-Type: text/xml; charset=utf-8' \
# --header 'SOAPAction: "http://www.turbine.com/SE/GLS/GetDatacenters"' \
# --post-data "<?xml version=\"1.0\" encoding=\"utf-8\"?><soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"><soap:Body><GetDatacenters xmlns=\"http://www.turbine.com/SE/GLS\"><game>${game}</game></GetDatacenters></soap:Body></soap:Envelope>" \
# "${glsDataCenter_URL}" -O .launcher/GLSDataCenter.config

curl --silent \
--header 'Content-Type: text/xml; charset=utf-8' \
--header 'SOAPAction: "http://www.turbine.com/SE/GLS/GetDatacenters"' \
--data "<?xml version=\"1.0\" encoding=\"utf-8\"?><soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"><soap:Body><GetDatacenters xmlns=\"http://www.turbine.com/SE/GLS\"><game>${game}</game></GetDatacenters></soap:Body></soap:Envelope>" \
"${glsDataCenter_URL}" \
--output .launcher/GLSDataCenter.config

if ! [ -r .launcher/GLSDataCenter.config ] ; then
echo -e "\nError: Could not fetch GLS data center configuration.\n"
cd "${oldDir}"
exit
fi

# Format the response by adding new lines after the closing xml tags.
sed -e "s#\(</[^>]*>\)#\1_make_newline_#g" -i "" .launcher/GLSDataCenter.config
awk '{ gsub(/_make_newline_/,"\n",$0); print }' .launcher/GLSDataCenter.config >> .launcher/GLSDataCenter.config.tmp
rm -f .launcher/GLSDataCenter.config
mv .launcher/GLSDataCenter.config.tmp .launcher/GLSDataCenter.config

# Grab only the first DataCenter.
echo -e "<!--\n NOTE\n This file is NOT a valid XML file!\n-->" >> .launcher/GLSDataCenter.config."${game}"
cat .launcher/GLSDataCenter.config | sed -n -e "/^.*<Datacenter><Name>${game}<\/Name>/,/<\/Datacenter>.*$/ p" >> .launcher/GLSDataCenter.config."${game}"

# Extract global server URLs
patchServer_ADR=`grep -h "<PatchServer>" .launcher/GLSDataCenter.config.${game} | grep -v '<!--.*-->' | sed -e "s/^.*<PatchServer>//;s/<\/PatchServer>.*$//"`
launcherCfg_URL=`grep -h "<LauncherConfigurationServer>" .launcher/GLSDataCenter.config.${game} | grep -v '<!--.*-->' | sed -e "s/^.*<LauncherConfigurationServer>//;s/<\/LauncherConfigurationServer>.*$//"`
authServer_URL=`grep -h "<AuthServer>" .launcher/GLSDataCenter.config.${game} | grep -v '<!--.*-->' | sed -e "s/^.*<AuthServer>//;s/<\/AuthServer>.*$//"`

# Extract world specific server URLs
serverChat_URL=`grep -h -A 4 "<World>" .launcher/GLSDataCenter.config.${game} | grep -F -A 3 "${selectedServer}" | grep -h "<ChatServerUrl>" | grep -v '<!--.*-->' | sed -e "s/^.*<ChatServerUrl>//;s/<\/ChatServerUrl>.*$//"`
serverStatus_URL=`grep -h -A 4 "<World>" .launcher/GLSDataCenter.config.${game} | grep -F -A 3 "${selectedServer}" | grep -h "<StatusServerUrl>" | grep -v '<!--.*-->' | sed -e "s/^.*<StatusServerUrl>//;s/<\/StatusServerUrl>.*$//"`

# Look up the server info in the configuration file
# The chat server address is given directly, other stuff needs another file (cache_$REALMNAME.xml) from the server


if [ -z "${launcherCfg_URL}" ] || [ -z "${authServer_URL}" ] ; then
echo -e "\nError: Could not extract one or more server URLs from the Game Login Server response.\n"
cd "${oldDir}"
exit
fi

# Extract list of game servers into an array
worlds=`grep -h -A 4 "<World>" .launcher/GLSDataCenter.config.${game} | grep "<Name>" | grep -v '<!--.*-->' | sed -e "s/^.*<Name>//;s/<\/Name>.*$//"`
IFS=$'\n'
i=0
for name in ${worlds} ; do
serverNames[$i]=${name}
i=$(($i + 1))
done
serverNames[$i]="end-of-list"
unset IFS

echo "Launch Configuration Server: ${launcherCfg_URL}"
echo "Patch Server: ${patchServer_ADR}"
echo "Authorization Server: ${authServer_URL}"
if [[ "${serverNames[0]}" != "end-of-list" ]] ; then
echo "Available Worlds: ${serverNames[0]}"
i=1
while [[ "${serverNames[$i]}" != "end-of-list" ]] ; do
echo -e " ${serverNames[$i]}"
i=$(($i + 1))
done
else
echo "Available Worlds: None"
cd "${oldDir}"
exit
fi
echo "${selectedServer} Chat Server: ${serverChat_URL}"
echo "${selectedServer} Status Server: ${serverStatus_URL}"
echo "-----------------------------------------------------------------------"

echo "Querying Launch Configuration Server..."

# wget --no-check-certificate \
# -q "${launcherCfg_URL}" \
# -O .launcher/launcher.config

curl --silent \
"${launcherCfg_URL}" \
--output .launcher/launcher.config

if ! [ -r .launcher/launcher.config ] ; then
echo -e "\nError: Could not fetch dynamic launcher configuration.\n"
cd "${oldDir}"
exit
fi

# Extract game settings from launcher configuration.
worldQueue_URL=`grep -h "WorldQueue.LoginQueue.URL" .launcher/launcher.config | grep -v '<!--.*-->' | sed -e "s/^.*value=\"\([^\"]*\)\".*$/\1/"`
worldQueue_ARGTMPL=`grep -h "WorldQueue.TakeANumber.Parameters" .launcher/launcher.config | grep -v '<!--.*-->' | sed -e "s/^.*value=\"\([^\"]*\)\".*$/\1/"`
glsTicketLifetime=`grep -h "GameClient.Arg.glsticketlifetime" .launcher/launcher.config | grep -v '<!--.*-->' | sed -e "s/^.*value=\"\([^\"]*\)\".*$/\1/"`
support_URL=`grep -h "GameClient.Arg.supporturl" .launcher/launcher.config | grep -v '<!--.*-->' | sed -e "s/^.*value=\"\([^\"]*\)\".*$/\1/"`
bug_URL=`grep -h "GameClient.Arg.bugurl" .launcher/launcher.config | grep -v '<!--.*-->' | sed -e "s/^.*value=\"\([^\"]*\)\".*$/\1/"`
supportService_URL=`grep -h "GameClient.Arg.supportserviceurl" .launcher/launcher.config | grep -v '<!--.*-->' | sed -e "s/^.*value=\"\([^\"]*\)\".*$/\1/"`
gameClient_FILE=`grep -h "GameClient.OSX.Filename" .launcher/launcher.config | grep -v '<!--.*-->' | sed -e "s/^.*value=\"\([^\"]*\)\".*$/\1/"`
gameClient_ARGTMPL=`grep -h "GameClient.OSX.ArgTemplate" .launcher/launcher.config | grep -v '<!--.*-->' | sed -e "s/^.*value=\"\([^\"]*\)\".*$/\1/"`

echo "World Queue Server: ${worldQueue_URL}"
echo "World Queue Args: ${worldQueue_ARGTMPL}"
echo "GLS Ticket Lifetime: ${glsTicketLifetime}"
echo "Support URL: ${support_URL}"
echo "Bug URL: ${bug_URL}"
echo "Support Service URL: ${supportService_URL}"
echo "Game Client File: ${gameClient_FILE}"
echo "Game Client Args: ${gameClient_ARGTMPL}"
echo "-----------------------------------------------------------------------"

########### CHOOSE LANGUAGE
languages[0]=english
selectedLanguage=0

########### PATCHING
# Note: This script cannot patch the game. Use the Launcher to do that.

########### AUTHENTICATION

function GLSAuth() {

# "submit" the login form via POST, will download a file called "LoginAccount"
# NOTE: the same thing as with the DataCenterServer applies here
# the lotroeugls server even has a service description and test form online
# well, at least they provide the SOAP request body as well...

# wget \
# --no-check-certificate -q \
# --header 'Content-Type: text/xml; charset=utf-8' \
# --header 'SOAPAction: "http://www.turbine.com/SE/GLS/LoginAccount"' \
# --post-data "<?xml version=\"1.0\" encoding=\"utf-8\"?><soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"><soap:Body><LoginAccount xmlns=\"http://www.turbine.com/SE/GLS\"><username>${account}</username><password>${pass}</password><additionalInfo></additionalInfo></LoginAccount></soap:Body></soap:Envelope>" \
# "${authServer_URL}" -O .launcher/GLSAuthServer.config

curl --silent \
--header 'Content-Type: text/xml; charset=utf-8' \
--header 'SOAPAction: "http://www.turbine.com/SE/GLS/LoginAccount"' \
--data "<?xml version=\"1.0\" encoding=\"utf-8\"?><soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"><soap:Body><LoginAccount xmlns=\"http://www.turbine.com/SE/GLS\"><username>${account}</username><password>${pass}</password><additionalInfo></additionalInfo></LoginAccount></soap:Body></soap:Envelope>" \
"${authServer_URL}" \
--output .launcher/GLSAuthServer.config

if ! [ -s .launcher/GLSAuthServer.config ] ; then
echo -e "\nError: GLS auth server request failed. Wrong account/password?\n"
echo -e "\nRetry (Y/n)? "
read retry
if [[ $retry == "y" || $retry == "Y" || $retry == "" ]] ; then
GLSAuth
else
cd "${oldDir}"
exit
fi
fi
}

echo "Requesting account details and authentication token from the Authorization Server..."

GLSAuth

# Check for multiple game subscriptions for the authenticated account.

# Insert whitespace after </GameSubscription> tags here (to have linebreaks as separators for accounts)
sed -e "s#\(</GameSubscription>\)#\1_make_newline_#g" -i "" .launcher/GLSAuthServer.config
awk '{ gsub(/_make_newline_/,"\n",$0); print }' .launcher/GLSAuthServer.config >> .launcher/GLSAuthServer.config.tmp
rm -f .launcher/GLSAuthServer.config
mv .launcher/GLSAuthServer.config.tmp .launcher/GLSAuthServer.config

# Extract each of the ids as well as descriptions for subscriptions to the current game.
subNames=`grep -h "<Game>${game}<\/Game>" .launcher/GLSAuthServer.config | grep "<Name>" | grep -v '<!--.*-->' | sed -e "s/^.*<Name>//;s/<\/Name>.*$//"`
subDescs=`grep -h "<Game>${game}<\/Game>" .launcher/GLSAuthServer.config | grep "<Description>" | grep -v '<!--.*-->' | sed -e "s/^.*<Description>//;s/<\/Description>.*$//"`
IFS=$'\n'
i=0
for sub in ${subNames} ; do
subs[$i]="${sub}"
i=$(($i + 1))
done
subs[$i]="end-of-list"
i=0
for desc in ${subDescs} ; do
descs[$i]="${desc}"
i=$(($i + 1))
done
descs[$i]="end-of-list"
unset IFS

# Check for at least one active subscription.
if [[ $i == 0 ]] ; then
echo -e "\nError: There appears to be no subscription for ${game}.\n"
cd "${oldDir}"
exit
fi

# Extract the ticket from the GLS auth file, check for failure
# NOTE: only the id (not the ticket) is subscription-specific
glsTicket=`sed -n -e "s/^.*<Ticket>//;s/<\/Ticket>.*$// p" .launcher/GLSAuthServer.config`
if [[ -z "${glsTicket}" ]] ; then
echo -e "\nError: Could not extract authetication token from the Authorization Server response.\n"
cd "${oldDir}"
exit
fi

if [[ "${subs[0]}" != "end-of-list" ]] ; then
echo "Subscription Names: ${subs[0]}"
i=1
while [[ "${subs[$i]}" != "end-of-list" ]] ; do
echo -e " ${subs[$i]}"
i=$(($i + 1))
done
else
echo "Subscription Names: None"
cd "${oldDir}"
exit
fi
if [[ "${descs[0]}" != "end-of-list" ]] ; then
echo "Subscription Descriptions: ${descs[0]}"
i=1
while [[ "${descs[$i]}" != "end-of-list" ]] ; do
echo -e " ${descs[$i]}"
i=$(($i + 1))
done
else
echo "Subscription Descriptions: None"
cd "${oldDir}"
exit
fi
echo "Authentication Token: ${glsTicket}"
echo "-----------------------------------------------------------------------"

# If there are multiple subscriptions to the current game available for the account,
# and we haven't set the subscription choice, ask which one to use.
if [[ "${selectedSub}" == "" ]] ; then
if [[ $i > 1 && "${selectedSub}" == "" ]] ; then
i=0
echo "You have the following subscriptions for $game:"
while [[ "${subs[$i]}" != "end-of-list" ]] ; do
echo -e " $i: ${subs[$i]}\t'${descs[$i]}'"
i=$(($i + 1))
done
echo -n "Please select the one you wish to use (enter the number on the left): "
read selectedSub
else
selectedSub=0
fi
fi

echo "Requesting world information for ${selectedServer} from the Status Server..."

# Download the status file and get the server adress and login queue adress to
# establish the connection.
# TODO: this file also contains current availability information, use it

# wget --no-check-certificate \
# -q "$serverStatus_URL" \
# -O .launcher/server.config

curl --silent \
"$serverStatus_URL" \
--output .launcher/server.config

# Extract the list of loginServers and queue URLs (two at this time, it seems)
loginServers=`grep -h "<loginservers>" .launcher/server.config | grep -v '<!--.*-->' | sed -e "s/^.*<loginservers>//;s/<\/loginservers>.*$//"`

queueUrls=`grep -h "<queueurls>" .launcher/server.config | grep -v '<!--.*-->' | sed -e "s/^.*<queueurls>//;s/<\/queueurls>.*$//"`
if [ -z "${loginServers}" ] || [ -z "${queueUrls}" ] ; then
echo -e "\nError: Could not extract world information for ${selectedServer}.\n"
cd "${oldDir}"
exit
fi

# Create array of servers
IFS=";"
i=0
for adr in ${loginServers} ; do
serverAddresses[$i]="${adr}"
i=$(($i + 1))
done
serverAddresses[$i]="end-of-list"
i=0
for adr in ${queueUrls} ; do
serverQueues[$i]="${adr}"
i=$(($i + 1))
done
serverQueues[$i]="end-of-list"
unset IFS

# Create the world queue login request for the requested world.
# The ticket can contain special characters and needs to be URL encoded before
# POSTing it (same for queue_url). launcher.config included a parameter template
# for the world queue request, used the same way as the client args below
serverAddress="${serverAddresses[0]}"
serverQueue="${serverQueues[0]}"

rawurlencode() {
local string="${1}"
local strlen=${#string}
local encoded=""

for (( pos=0 ; pos<strlen ; pos++ )); do
c=${string:$pos:1}
case "$c" in
[-_.~a-zA-Z0-9] ) o="${c}" ;;
* ) printf -v o '%%%02x' "'$c"
esac
encoded+="${o}"
done
echo "${encoded}"
}

glsTicketURLencoded=$(rawurlencode "${glsTicket}")
loginQueueURLencoded=$(rawurlencode "${serverQueue}")

worldQueue_ARGS=`echo "${worldQueue_ARGTMPL}" | sed -e "s/[{]0[}]/${subs[$selectedSub]}/;s/[{]1[}]/${glsTicketURLencoded}/;s/[{]2[}]/${loginQueueURLencoded}/;s/\&amp\;/\&/g"`

if [[ "${serverAddresses[0]}" != "end-of-list" ]] ; then
echo "${selectedServer} Login Servers: ${serverAddresses[0]}"
i=1
while [[ "${serverAddresses[$i]}" != "end-of-list" ]] ; do
echo -e " ${serverAddresses[$i]}"
i=$(($i + 1))
done
else
echo "${selectedServer} Login Servers: None"
cd "${oldDir}"
exit
fi
if [[ "${serverQueues[0]}" != "end-of-list" ]] ; then
echo "${selectedServer} Login Servers: ${serverQueues[0]}"
i=1
while [[ "${serverQueues[$i]}" != "end-of-list" ]] ; do
echo -e " ${serverQueues[$i]}"
i=$(($i + 1))
done
else
echo "${selectedServer} Login Servers: None"
cd "${oldDir}"
exit
fi
echo "Selecting queue: ${serverQueue}"
echo "Queue Arguments: ${worldQueue_ARGS}"
echo "-----------------------------------------------------------------------"

########### LOGIN QUEUE / CLIENT START
function JoinQueue() {

# Now get a queue number from the world login queue so that the client can enqueue and authenticate
inQueue=1
while [ "${inQueue}" == "1" ]; do

# loop when necessary

# wget --no-check-certificate \
# -q --post-data="${worldQueue_ARGS}" \
# "${worldQueue_URL}" \
# -O .launcher/WorldQueue.config

curl --silent \
--data "${worldQueue_ARGS}" \
"${worldQueue_URL}" \
--output .launcher/WorldQueue.config
if ! [ -r .launcher/WorldQueue.config ] ; then
echo -e "\nError: World login queue request failed.\n"
cd "${oldDir}"
exit
fi

# check the result, should be HRESULT 0x00000000, indicating success (Windows API madness)
hresult=`grep -h "<HResult>" .launcher/WorldQueue.config | grep -v '<!--.*-->' | sed -e "s/^.*<HResult>//;s/<\/HResult>.*$//"`
if [ "${hresult}" != "0x00000000" ] ; then
echo -e "\nError: World login queue response indicates failure."
cd "${oldDir}"
exit
else
# lets see what position we are at
queuePos=`grep -h "<QueueNumber>" .launcher/WorldQueue.config | grep -v '<!--.*-->' | sed -e "s/^.*<QueueNumber>//;s/<\/QueueNumber>.*$//"`
queueSrvd=`grep -h "<NowServingNumber>" .launcher/WorldQueue.config | grep -v '<!--.*-->' | sed -e "s/^.*<NowServingNumber>//;s/<\/NowServingNumber>.*$//"`
queueAhead=$(( ${queuePos} - ${queueSrvd} ))
if [ ${queueAhead} -gt 0 ]; then
# d'oh, need to wait
echo -e "\n${queueAhead} ahead in queue, retrying in 5s..."
sleep 5
else
# hah, ready to go
inQueue=0
fi
fi
done
}

echo "Joining ${selectedServer} Login Server queue..."

# new: world queue is unused on (some?) EU servers, just like with DDO, skip if no queue URL
if [ -n "${serverQueue}" ] ; then
JoinQueue
else
echo -e "\nWorld login queue seems to be disabled, skipping..."
fi

echo "Login to ${selectedServer} successful."

# OK, so we have a template for the client arguments and we have the arguments
# Note that for replacing the glsTicket, I use s### instead of s/// due to the ticket containing slashes
# Hopefully, it doesn't contain any sharp characters :)

gameClient_ARGS=`echo "${gameClient_ARGTMPL}" | sed -e "
s/[{]SUBSCRIPTION[}]/${subs[$selectedSub]}/;
s/[{]LOGIN[}]/${serverAddress}/;
s#[{]GLS[}]#${glsTicket}#;
s/[{]CHAT[}]/${serverChat_URL}/;
s/[{]LANG[}]/${languages[$selectedLanguage]}/;
s#[{]AUTHSERVERURL[}]#${authServer_URL}#;
s/[{]GLSTICKETLIFETIME[}]/${glsTicketLifetime}/;
s#[{]SUPPORTURL[}]#${support_URL}#;
s#[{]BUGURL[}]#${bug_URL}#;
s#[{]SUPPORTSERVICEURL[}]#${supportService_URL}#;
"`

echo "Launching client with command line:"
if [ -n "${user}" ] ; then
echo "./${gameClient_FILE}/Contents/MacOS/dndclient ${gameClient_ARGS} -u ${user} &>/dev/null &"
./${gameClient_FILE}/Contents/MacOS/dndclient ${gameClient_ARGS} -u "${user}" &>/dev/null &
else
echo "./${gameClient_FILE}/Contents/MacOS/dndclient ${gameClient_ARGS} &>/dev/null &"
./${gameClient_FILE}/Contents/MacOS/dndclient ${gameClient_ARGS} &>/dev/null &
fi

echo "-----------------------------------------------------------------------"
echo "Done."
echo "-----------------------------------------------------------------------"

# Get back to where the caller was
cd "${oldDir}"

exit


If anything is unclear let me know and I will try to steer you in the right direction. Follow the instructions carefully and you should be able to multibox very easily once this is set up. If you are running on an SSD it's insane how quickly you can get into the game with this.

One thing though -on patch day you will need to run the app normally. The script will not be able to connect to the server if the client is out of date, and it does not know how to patch the game. Only the Launcher can do that.

Edit #1: the final script can be moved anywhere you like. It does not have to be in the Applications folder. You can put it in your Documents folder for example. Doing so will make access to the file a lot more secure in a shared environment. You will need to change the path to the script when launching it though. Something like:
~/Documents/DNDLauncher.sh
would work.

Edit #2: Replaced wget calls with curl calls so that there is no need to install wget on your machine.

onivedlav
06-01-2013, 09:22 PM
Mr. Seaglen,

I admire people like you, that spend your own time to help others and share your knowlegde.
And for that thank you!

It is working to perfection =)

Extremelly easy process, and well explained.

AtomicMew
06-02-2013, 06:20 AM
Very cool katie. Especially nice on Mac since you can run it natively I'm assuming :)

Kaytis
06-02-2013, 01:26 PM
Yes, the Mac is a native UNIX environment. There is no need to install cygwin or anything else to get the command-line interface.

And kudos to you and "SNy" for your work on the original script. It made my job easy.

Araslan
10-05-2013, 03:57 PM
Hi, thank you for this post. I am having trouble locating/saving to /Applications/DNDLauncherTemplate.sh

Running a mac mountain lion. Any help is welcome.

# How to use:
# Open TextEdit, create a new document and paste the entire text of this
# document in, then select Format/Make Plain Text.
# Save the file to /Applications/DNDLauncherTemplate.sh
# Open /Applications/Utilities/Terminal and type:
#
# cp /Applications/DNDLauncherTemplate.sh /Applications/DNDLauncher.sh
# chmod 755 /Applications/DNDLauncher.sh
#

Kaytis
10-06-2013, 09:29 AM
Hi, thank you for this post. I am having trouble locating/saving to /Applications/DNDLauncherTemplate.sh
#

Hello Araslan.
What are trying, what do you expect to happen, and what actually happens? Thanks.