PDA

View Full Version : Launcher Script For Mac OS X



Kaytis
02-19-2015, 12:15 AM
10/2/2020 Version 1.5
Added Lamannia and 64-bit Client support

This script can be run from the Terminal utility and allows you to enter the game directly on the toon you wish to play, bypassing the loading screen downloads, the launcher, and the character selection screen. You can alternatively go to the character selection screen first. You can multi-box by providing a toon name from a different account on the command line.

Instructions for installing and running the script are embedded in the text.

The script supports command line arguments for username, password, world, character, and 64-bits. This allows it to be used without modification.

Note that the script is not able to patch the game. The real "DDO" application must be run one time after every update to the game.

Enable the 64-bit client by adding -x64 to the command line. The 64-bit Client will only work seamlessly on a macOS 10.14 machine or earlier. MacOS 10.15 support is possible but requires an older machine to update the software whenever the game changes. This is because there is no 64-bit version of the Launcher. Until SSG gets around to that, the only way this will work in macOS 10.15 is to copy an up to date version of "/Applications/DDO" and ~"/Library/Application Support/com.standingstonegames.ddo" from an old machine to the macOS 10.15 machine. Additionally you will need to open System Preferences > Security & Privacy > Privacy" and allow Developer Tools > Terminal to run unverified software locally. This only needs to be done once.

Use Lamannia by adding "-w Lamannia" to the command line. Note that you will need the base Lamannia client installed in /Applications

Some observations about the Wine client:

It doesn't work in macOS 10.15 -don't upgrade to 10.15 if you want to keep playing DDO on the Mac. SSG needs to finish converting the Launcher to 64-bits before it will work well enough to use.

When installing wine, there are two confusing dialogs that come up asking if you want to install some extra pieces. It actually doesn't matter how you answer these two questions. The best answer is to say "No" -the DDO installer already comes with versions of the components needed. There is no need to load your machine down with software that won't be used.

There are some oddities with the command key. For some reason it registers as the alt key. Because I need the command key to tab between multiple clients, I had to clear "Rune Arm Use" from it. I did not remap it to the alt key, because the game would not recognize it. That is going to be a problem for people who care about the rune arm.

Saving and using ui layout files has become very complicated. The good news is that it can be done. If you have a layout file you like, copy it to:
"/[home]/Documents/Dungeons and Dragons Online/ui/layouts/myfavoritelayout.layout"
You will need to create the "ui" folder and the "layouts" folder. Make sure that the layout file has the ".layout" extension on it. To load it in the game go to the chat window and type:
/ui layout load myfavoritelayout
Easy!

If anyone runs into any trouble with the script, please let me know.



#!/bin/bash

################################################## ###########################
# General Information
#
# Command Line Interface launcher for Dungeons & Dragons online.
#
# To use this script, follow the instructions in the sections:
# 1) Create the script
# 2) Play the game
# 3) Optional: Personalize the script
#
# Note that this script cannot update the game. If it fails to work, run the
# original DDO Launcher to allow it to perform any pending updates first.
#
# (C) 2007-2011 SNy <SNy@bmx-chemnitz.de>
#
# AtomicMew 6/3/12
# -modded to take command line args and windoze use
#
# Kaytis 5/31/13 v 1.1
# -modded to work on Mac OS X
#
# Kaytis 2/18/15 v 1.2
# -updated to match new login protocols
#
# Kaytis 11/30/15 v 1.2.1
# -disabled peer verification to bypass invalid certificates
#
# Kaytis 4/4/19 v 1.3
# -simplified instructions
#
# Kaytis 10/19/19 v 1.4
# -added support for wine client
# -added support for command line arguments:
# -u username
# -p password
# -n subscription
# -w world
# -c character
#
# Kaytis 10/2/20 v 1.5
# -added support for Lamannia world
# -added support for 64-bit client
# -x64

################################################## ###########################
# Create the script
#
# 1) Open TextEdit, create a new document, and paste all of this text into it.
# 2) Select menu item "Format" > "Make Plain Text" (if you don't see this option, ignore this step).
# 3) Save the file as /Applications/DNDLauncher.sh
# 4) Open /Applications/Utilities/Terminal and type:
# chmod 755 /Applications/DNDLauncher.sh
# 5) Hit the return key to execute the command.

################################################## ###########################
# Play the game
#
# 1) Open /Applications/Utilities/Terminal
# 2) To start from the character selection screen, type:
# /Applications/DNDLauncher.sh -u username -p password -w world
# To start in world with a specific character type:
# /Applications/DNDLauncher.sh -u username -p password -w world -c character
# 3) Hit the return key to execute the command. The game will start.
#
# Handy tip: the up arrow will restore the last command you typed in the Terminal.
# Handy tip: you do not need to leave this file open after creating it.
#
# Note in certain circumstances, a subscription number is required. You can
# specify it using the -n parameter. If one is required, and it is not provided,
# the script will help you figure out what the number is so that it can be
# provided next time.

################################################## ###########################
# Parse the command line arguments.
#
# NOTE: If you don't personalize the script, you MUST provide at least the
# username, password and world on the command line.
# Version 1.4 and higher of this script can be customized in EXACTLY
# the same way as earlier versions, including personalizing it per character and
# invoking the script with just the character name (the "-c" is optional).
# If you want to personalize the script please skip to the
# "Personalize the script" section below.

while [[ $# -gt 0 ]]
do
key="$1"
case $key in
-u|--username)
ARG_USERNAME="$2"
shift # past argument
shift # past value
;;
-p|--password)
ARG_PASSWORD="$2"
shift # past argument
shift # past value
;;
-n|--subscription)
ARG_SUBSCRIPTION="$2"
shift # past argument
shift # past value
;;
-w|--world)
ARG_WORLD="$2"
shift # past argument
shift # past value
;;
-c|--character)
ARG_CHARACTER="$2"
shift # past argument
shift # past value
;;
-x64|--x64)
X64=YES
shift # past argument
;;
-h|--help)
HELP=YES
shift # past argument
;;
*) # unknown option -assume character name
ARG_CHARACTER="$1"
shift # past argument
;;
esac
done

################################################## ###########################
# Personalize the script
#
# Providing these values will allow you to go to the character select screen on
# a specific world without providing any arguments to the script. If you add a
# character name as an argument to the script, you will be taken straight to
# that character on the specified world.
#
# Optionally provide your username, password and primary world here. Note that
# if you choose to enter this information, you should NOT share this file with
# anyone. Note: arguments provided on the command line will override these
# values.
#
# 1) Fill in the following, by replacing,
# account_username_here,
# account_password_here, and
# world_name_here
# 2) When you are done typing the values, save the file. Don't share the
# file with anyone. Your password is in it.

username=account_username_here # Main account username. No spaces anywhere.
password=account_password_here # Main account password. No spaces anywhere.
subscription=0 # Main account subscription. Usually 0.
world=world_name_here # Main world name e.g. Orien. Capitalize the first letter!

################################################## ###########################
# Advanced instructions
#
# Providing values for:
# alt_account_character_name_here
# alt_account_username_here
# alt_account_password_here
# alt_world_name_here
# will allow you to go to a specific character on any account on any world by
# providing a character name as an argument to the script. The character name is
# used as a key to select the right account and world. You will typically just
# provide the character name and nothing else when multiboxing. Note: arguments
# provided on the command line will override these values.
#
# To play a character on an alternate account:
# 1) Open /Applications/Utilities/Terminal
# 2) Type:
# /Applications/DNDLauncher.sh alt_account_character_name
# 3) Hit the return key -a new copy of the game will start.
#
# Handy tip: you can have as many copies of the game open as you have alternate
# accounts. You can add more character names by duplicating an "elif" block.

if [ "${ARG_CHARACTER}" == "alt_account_character_name_here" ] ; then

username=alt_account_username_here # Alt account username
password=alt_account_password_here # Alt account password
subscription=0 # Alt account subscription. Usually 0
world=alt_world_name_here # Alt server name e.g. Orien

elif [ "${ARG_CHARACTER}" == "alt_account_character_name_here" ] ; then

username=alt_account_username_here # Alt account username
password=alt_account_password_here # Alt account password
subscription=0 # Alt account subscription. Usually 0
world=alt_world_name_here # Alt server name e.g. Orien

elif [ "${ARG_CHARACTER}" == "alt_account_character_name_here" ] ; then

username=alt_account_username_here # Alt account username
password=alt_account_password_here # Alt account password
subscription=0 # Alt account subscription. Usually 0
world=alt_world_name_here # Alt server name e.g. Orien

fi

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

if [ -n "${HELP}" ] ; then
echo ""
echo "A macOS command line launcher for DDO. Use this command for fast game launching"
echo "and multiboxing."
echo ""
echo "usage: DNDLauncher [-u username] [-p password] [-n subscription] [-w world] [-c character]"
echo ""
echo "-u username : account username"
echo "-p password : account password"
echo "-n subscription : account subscription. Usually 0. Omit if unknown."
echo "-w world : world e.g. Orien. Capitalize only the first letter"
echo "-c character : character to log in. '-c' is optional"
echo "-x64 : use 64-bit client"
echo ""
echo "Example:"
echo ""
echo " /Applications/DNDLauncher.sh -u my_account_name -p my_account_password -w Orien -c Kaytis"
echo ""
echo "or with appropriate script customization (see script for details):"
echo ""
echo " /Applications/DNDLauncher.sh -c Kaytis"
echo ""
exit 0
fi

# Snag the character name, if any, and stash it in the "character" variable.
character="${ARG_CHARACTER}"

# Apply overides
if [ -n "${ARG_USERNAME}" ] ; then
username="${ARG_USERNAME}"
fi
if [ -n "${ARG_PASSWORD}" ] ; then
password="${ARG_PASSWORD}"
fi
if [ -n "${ARG_SUBSCRIPTION}" ] ; then
subscription="${ARG_SUBSCRIPTION}"
fi
if [ -n "${ARG_WORLD}" ] ; then
world="${ARG_WORLD}"
fi

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

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

# Some common directories
gameCommon_DIR="$HOME/Library/Application Support/com.standingstonegames.ddo/common"
gameWineBin_DIR="$gameCommon_DIR/usr/bin"
gameWinePrefix_DIR="$gameCommon_DIR/wineprefix"
gameClient_DIR="$gameWinePrefix_DIR/drive_c/Program Files (x86)/StandingStoneGames/Dungeons & Dragons Online"
gameClient_EXE="C:/Program Files (x86)/StandingStoneGames/Dungeons & Dragons Online/dndclient.exe"
if [ -n "${X64}" ] ; then
gameClient_EXE="C:/Program Files (x86)/StandingStoneGames/Dungeons & Dragons Online/x64/dndclient64.exe"
fi

if [ "${world}" == "Lamannia" ] ; then
gameClient_DIR="$gameWinePrefix_DIR/drive_c/Program Files (x86)/StandingStoneGames/Dungeons & Dragons Online (Preview)"
gameClient_EXE="C:/Program Files (x86)/StandingStoneGames/Dungeons & Dragons Online (Preview)/dndclient.exe"
if [ -n "${X64}" ] ; then
gameClient_EXE="C:/Program Files (x86)/StandingStoneGames/Dungeons & Dragons Online (Preview)/x64/dndclient64.exe"
fi
fi

# make this script be callable from elsewhere (desktop shortcuts etc)
oldDir=`pwd`

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

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

echo "Reading game configuration..."

# Get Game and DataCenter settings from launcher config file.
configFile="ddo.launcherconfig"
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 \
--insecure \
--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 "${world}" | 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 "${world}" | 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 "${world} Chat Server: ${serverChat_URL}"
echo "${world} Status Server: ${serverStatus_URL}"
echo "-----------------------------------------------------------------------"

echo "Querying Launch Configuration Server..."

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

curl --silent \
--insecure \
"${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>${username}</username><password>${password}</password><additionalInfo></additionalInfo></LoginAccount></soap:Body></soap:Envelope>" \
# "${authServer_URL}" -O .launcher/GLSAuthServer.config

curl --silent \
--insecure \
--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>${username}</username><password>${password}</password><additionalInfo></additionalInfo></LoginAccount></soap:Body></soap:Envelope>" \
"${authServer_URL}" \
--output .launcher/GLSAuthServer.config

if ! [ -s .launcher/GLSAuthServer.config ] || grep -qs faultcode .launcher/GLSAuthServer.config ; then
echo -e "\nError: GLS auth server request failed. Wrong username / password?\n"
cd "${oldDir}"
exit
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 [[ "${subscription}" == "" ]] ; then
if [[ $i > 1 && "${subscription}" == "" ]] ; 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 subscription
else
subscription=0
fi
fi

echo "Requesting world information for ${world} 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 \
--insecure \
"$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 ${world}.\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[$subscription]}/;s/[{]1[}]/${glsTicketURLencoded}/;s/[{]2[}]/${loginQueueURLencoded}/;s/\&amp\;/\&/g"`

if [[ "${serverAddresses[0]}" != "end-of-list" ]] ; then
echo "${world} Login Servers: ${serverAddresses[0]}"
i=1
while [[ "${serverAddresses[$i]}" != "end-of-list" ]] ; do
echo -e " ${serverAddresses[$i]}"
i=$(($i + 1))
done
else
echo "${world} Login Servers: None"
cd "${oldDir}"
exit
fi
if [[ "${serverQueues[0]}" != "end-of-list" ]] ; then
echo "${world} Login Servers: ${serverQueues[0]}"
i=1
while [[ "${serverQueues[$i]}" != "end-of-list" ]] ; do
echo -e " ${serverQueues[$i]}"
i=$(($i + 1))
done
else
echo "${world} 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 \
--insecure \
--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 ${world} 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 ${world} 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[$subscription]}/;
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}#;
"`
if [ -n "${character}" ] ; then
gameClient_ARGS="$gameClient_ARGS -u $character"
fi

BP='\033[0;34m'
NC='\033[0m'
echo "Launching client:"
if [ -n "${X64}" ] ; then
echo -e "${BP}WINEPREFIX=$gameWinePrefix_DIR $gameWineBin_DIR/wine64 $gameClient_EXE ${gameClient_ARGS} &>/dev/null &${NC}"
WINEPREFIX="$gameWinePrefix_DIR" "$gameWineBin_DIR"/wine64 "$gameClient_EXE" ${gameClient_ARGS} &>/dev/null &
else
echo -e "${BP}WINEPREFIX=$gameWinePrefix_DIR $gameWineBin_DIR/wine $gameClient_EXE ${gameClient_ARGS} &>/dev/null &${NC}"
WINEPREFIX="$gameWinePrefix_DIR" "$gameWineBin_DIR"/wine "$gameClient_EXE" ${gameClient_ARGS} &>/dev/null &
fi
disown

echo "-----------------------------------------------------------------------"
echo "Done. Please allow the DDO client a few seconds to launch."
echo "-----------------------------------------------------------------------"

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

exit

onivedlav
07-21-2015, 02:04 AM
Kaytis is this version currently working?

I am getting the following error:
Error: Could not extract world information for thelanis.

Thank you once again for for sharing this newer version of the script. I hope i can get it to work and enjoy it!

Kaytis
07-22-2015, 02:46 PM
Kaytis is this version currently working?

I am getting the following error:
Error: Could not extract world information for thelanis.

Thank you once again for for sharing this newer version of the script. I hope i can get it to work and enjoy it!

You need to capitalize the 'T' in Thelanis. Modify your script and you should be all set.

onivedlav
07-31-2015, 05:21 PM
Working perfectly! Many thanks sr.

TheCanuck
11-11-2015, 02:11 PM
I've just tried to use this launcher and while the script runs fine, Launches the client properly. I see the game loading screen and then it crashes.

Does this version still work?

Thanks!!!

Kaytis
11-13-2015, 11:34 AM
I've just tried to use this launcher and while the script runs fine, Launches the client properly. I see the game loading screen and then it crashes.

Does this version still work?

Thanks!!!

Yes it still works. The script does not know how to apply game updates and when an un-patched client tries to launch it will crash. So when a new update is released you will need to run the official launcher "/Applications/Dungeons And Dragons Online" just one time so that it can patch the game. After that you can use the script again until the next game update.

Kaytis
11-30-2015, 11:02 PM
Bumping for version 1.2.1. Fixes a problem with invalid certificates.

Zweisteine
12-06-2015, 01:17 PM
I'm having the same problem as TheCanuck was, it seems. I get a loading screen without a loading bar, the loading bar appears for a moment, then the client crashes.

But I'm trying to use this because my launcher seems to be broken (it seems to stop after checking dat files, but before moving on). If I'm missing a patch,* I can't get it through the launcher.

*When was the last patch? Unless something has been added since 28.1, I should be up to date.


From the report that appears when the client crashes:

Crashed Thread: 0 Dispatch queue: com.apple.main-thread

Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x0000000000000000

I'm using OS X 10.10.3.


(Also, it would be nice to be able to put the server as an argument when running it, so you can connect to any server with one copy of the file.)

Kaytis
12-06-2015, 09:28 PM
I'm having the same problem as TheCanuck was, it seems. I get a loading screen without a loading bar, the loading bar appears for a moment, then the client crashes.

But I'm trying to use this because my launcher seems to be broken (it seems to stop after checking dat files, but before moving on). If I'm missing a patch,* I can't get it through the launcher.

*When was the last patch? Unless something has been added since 28.1, I should be up to date.


From the report that appears when the client crashes:

Crashed Thread: 0 Dispatch queue: com.apple.main-thread

Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x0000000000000000

I'm using OS X 10.10.3.


(Also, it would be nice to be able to put the server as an argument when running it, so you can connect to any server with one copy of the file.)

I would guess that the application or application data is corrupt. Update to 10.10.5 and see if that helps. If not, you should try reinstalling it.

Interesting idea about parameterizing the server. It wouldn't be that difficult to do. I will give it some thought.

Zweisteine
12-06-2015, 10:48 PM
I would guess that the application or application data is corrupt.

Well, I tried renaming/moving and redownloading all of the dat files, and nothing changed.

Looks like I'm stuck reinstalling. Oh well.

EDIT: Aaaaand it didn't help. Reinstalled the game completely, and it still hangs when patching dat files.

EDIT 2: Updating to 10.10.5 seems to have done the trick. After doing so, it stopped for only a moment at checking dat files, then prompted me to download an update. I did so, and the game works fine now. Gotta sleep though, so I won't be testing the script again today.

Myranna
01-03-2017, 07:07 PM
Awesome script, thank you so much! I was trying to find a way to dual box on macOS, this script is the answer :)

PwnHammer40K
08-13-2017, 04:05 PM
Thank you!

Daarsurra
03-03-2019, 03:30 PM
This script can be run from the Terminal utility and allows you to enter the game directly on the toon you wish to play, bypassing the loading screen downloads, the launcher, and the character selection screen. You can alternatively go to the character selection screen first. You can multi-box by providing a toon name from a different account on the command line.

Instructions for installing and running the script are embedded in the text.

You can update to the latest script by backing up your old script, following the installation instructions for the new script, and then copying the "User modifiable section" from your old script into the new script. Alternatively, you can re-enter the user information manually.

Note that the script is not able to patch the game when it has been updated. The real "Dungeons and Dragons Online" application must be run one time after every update to the game.

If anyone runs into any trouble, please let me know.



#!/bin/bash

################################################## ###########################
# General Information
#
# Launch DDO client from CLI.
#
# (C) 2007-2011 SNy <SNy@bmx-chemnitz.de>
#
# AtomicMew 6/3/12
# -modded to take command line args and windoze use
#
# Kaytis 5/31/13 v 1.1
# -modded to work on Mac OS X
#
# Kaytis 2/18/15 v 1.2
# -updated to match U24 login protocols
#
# Kaytis 11/30/15 v 1.2.1
# -disabled peer verification to bypass invalid certificates
#

################################################## ###########################
# 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 go 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=putYourServerNameHere # Alt server name e.g. Orien
user="${1}"
fi

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

echo "-----------------------------------------------------------------------"
echo -e "Welcome to the CLI launcher for DDO for Mac OS X version 1.2.1"
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 \
--insecure \
--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 \
--insecure \
"${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 \
--insecure \
--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 \
--insecure \
"$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 \
--insecure \
--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


yeah, just doesn't work, but as all things DDO, i'm guessing there are finer points here that aren't fully explained. thanks.

Kaytis
03-15-2019, 05:08 PM
yeah, just doesn't work, but as all things DDO, i'm guessing there are finer points here that aren't fully explained. thanks.

Hi Daarsurra. I still use the script all the time. What specifically do you see happening? Note that the script is not able to update the game. Every time SSG does an update, you will need to run the actual launcher one time to patch the game.

Kaytis
04-05-2019, 12:27 AM
I have tried to make the script easier to set up. I moved the three most important lines to the top of the script and made the overall steps a bit easier to follow. Multiboxing support has been moved down out of the way where it will be less of a distraction.

As always, if something isn't clear, let me know!

DeamonMaster
05-04-2019, 02:27 PM
I have tried to make the script easier to set up. I moved the three most important lines to the top of the script and made the overall steps a bit easier to follow. Multiboxing support has been moved down out of the way where it will be less of a distraction.

As always, if something isn't clear, let me know!

I've entered my username, password, and server the same as I enter in the client but I get the following error:

-----------------------------------------------------------------------
Welcome to the CLI launcher for DDO for Mac OS X version 1.3
-----------------------------------------------------------------------
Reading game configuration...
Game Name: DDO
Game Login Server: http://gls.ddo.com/GLS.DataCenterServer/Service.asmx
-----------------------------------------------------------------------
Querying Game Login Server...
Launch Configuration Server: http://gls.ddo.com/launcher/ddo/dndlauncher.server.config.xml
Patch Server: patch.ddo.com:5015
Authorization Server: https://gls-auth.ddo.com/GLS.AuthServer/Service.asmx
Available Worlds: Cannith
Argonnessen
Wayfinder
Thelanis
Sarlona
Khyber
Ghallanda
Orien
Argonnessen Chat Server: 198.252.160.40:2900
Argonnessen Status Server: http://gls.ddo.com/GLS.DataCenterServer/StatusServer.aspx?s=10.192.145.11
-----------------------------------------------------------------------
Querying Launch Configuration Server...
World Queue Server: https://gls.ddo.com/GLS.AuthServer/LoginQueue.aspx
World Queue Args: command=TakeANumber&amp;subscription={0}&amp;ticket={1}&amp;ti cket_type=GLS&amp;queue_url={2}
GLS Ticket Lifetime: 21600
Support URL: https://tss.turbine.com/TSSTrowser/trowser.aspx
Bug URL: http://ddobugs.turbine.com?task=ticket
Support Service URL: https://tss.turbine.com/TSSTrowser/SubmitTicket.asmx
Game Client File: dndclient.app
Game Client Args: -a {SUBSCRIPTION} -h {LOGIN} --glsticketdirect {GLS} --chatserver {CHAT} --rodat on --language {LANG} --gametype DDO --authserverurl {AUTHSERVERURL} --glsticketlifetime {GLSTICKETLIFETIME} --supporturl {SUPPORTURL} --bugurl {BUGURL} --supportserviceurl {SUPPORTSERVICEURL}
-----------------------------------------------------------------------
Requesting account details and authentication token from the Authorization Server...

Error: There appears to be no subscription for DDO.

Any suggestions?

Thanks!

Eric Sten

Kaytis
05-05-2019, 06:52 AM
Hi Eric. It looks like you have done everything right. Finding the subscription itself should be automatic unless you have more than one. Can you confirm this didn’t happen during the DNS outages around the 3rd/4th May?

Ayeye
08-13-2019, 04:40 PM
Dear Kaytis,
thank you for keeping this launcher alive. Actually it's the only way to play from mac (without installing windows) and I really like the "bash scripting art".
After 42.4 release the launcher fails, am I the one experiencing this issue (I don't know, due to local problems) or is it common to other users?

Last update had the following changes that does not seem to be a big deal but are launcher-related:

The launcher will now dynamically update your position in line if you are in a login queue.
The launcher will no longer bounce you between multiple login queues at random.
New splash screens are now checked and downloaded, if needed, in parallel instead of one at a time. Hopefully this will reduce the time spent on this stage.


However I get the following output before it fails:

Initializing display with title 'Dungeons and Dragons Online'...
/build/dnd/dnd_live/src/engine/client/device/osx/Device_OSX.cpp, 284: called.
Initializing the smartbox...
Initializing the user interface...
Client ready
Client::Connect() async logon begun.
Connection failed (0x00000004:0x00CD0B73) to server 0, addr 198.252.160.45:9004
./my_ddo_launch.sh: line 589: 1686 Segmentation fault: 11 ./${gameClient_FILE}/Contents/MacOS/dndclient ${gameClient_ARGS}

Seems to me that " gameClient_ARGS" could have been changed :rolleyes:
Kind regards,
Stefano

Daarsurra
08-13-2019, 05:00 PM
Hi Daarsurra. I still use the script all the time. What specifically do you see happening? Note that the script is not able to update the game. Every time SSG does an update, you will need to run the actual launcher one time to patch the game.

i whole-heartedly apologize for that sh*** response. i've forgotten i even explored this; i'll give it a try again.

EDIT: seems to work now, but unfortunately crashes just like the normal launcher ;[

Daarsurra
08-13-2019, 05:48 PM
I've entered my username, password, and server the same as I enter in the client but I get the following error:

-----------------------------------------------------------------------
Welcome to the CLI launcher for DDO for Mac OS X version 1.3
-----------------------------------------------------------------------
Reading game configuration...
Game Name: DDO
Game Login Server: http://gls.ddo.com/GLS.DataCenterServer/Service.asmx
-----------------------------------------------------------------------
Querying Game Login Server...
Launch Configuration Server: http://gls.ddo.com/launcher/ddo/dndlauncher.server.config.xml
Patch Server: patch.ddo.com:5015
Authorization Server: https://gls-auth.ddo.com/GLS.AuthServer/Service.asmx
Available Worlds: Cannith
Argonnessen
Wayfinder
Thelanis
Sarlona
Khyber
Ghallanda
Orien
Argonnessen Chat Server: 198.252.160.40:2900
Argonnessen Status Server: http://gls.ddo.com/GLS.DataCenterServer/StatusServer.aspx?s=10.192.145.11
-----------------------------------------------------------------------
Querying Launch Configuration Server...
World Queue Server: https://gls.ddo.com/GLS.AuthServer/LoginQueue.aspx
World Queue Args: command=TakeANumber&amp;subscription={0}&amp;ticket={1}&amp;ti cket_type=GLS&amp;queue_url={2}
GLS Ticket Lifetime: 21600
Support URL: https://tss.turbine.com/TSSTrowser/trowser.aspx
Bug URL: http://ddobugs.turbine.com?task=ticket
Support Service URL: https://tss.turbine.com/TSSTrowser/SubmitTicket.asmx
Game Client File: dndclient.app
Game Client Args: -a {SUBSCRIPTION} -h {LOGIN} --glsticketdirect {GLS} --chatserver {CHAT} --rodat on --language {LANG} --gametype DDO --authserverurl {AUTHSERVERURL} --glsticketlifetime {GLSTICKETLIFETIME} --supporturl {SUPPORTURL} --bugurl {BUGURL} --supportserviceurl {SUPPORTSERVICEURL}
-----------------------------------------------------------------------
Requesting account details and authentication token from the Authorization Server...

Error: There appears to be no subscription for DDO.

Any suggestions?

Thanks!

Eric Sten

i fixed that by making sure that i left the portion in bold:
"account=account_username_here, pass=account_password_here, selectedServer=server_name_here"

for me it was:

account=Daarsurra
pass=********
selectedServer=Orien

Kaytis
08-13-2019, 08:05 PM
i fixed that by making sure that i left the portion in bold:
"account=account_username_here, pass=account_password_here, selectedServer=server_name_here"

for me it was:

account=Daarsurra
pass=********
selectedServer=Orien

Hi Daarsurra. I am not sure if you still have a question. Bear in mind that the native Mac client is broken. It will crash on launch. It is scheduled to be fixed on August 14th (tomorrow). Neither the actual Launcher, nor my script will work until the client is patched.

Kaytis
08-13-2019, 08:08 PM
Dear Kaytis,
thank you for keeping this launcher alive. Actually it's the only way to play from mac (without installing windows) and I really like the "bash scripting art".
After 42.4 release the launcher fails, am I the one experiencing this issue (I don't know, due to local problems) or is it common to other users?

Last update had the following changes that does not seem to be a big deal but are launcher-related:

The launcher will now dynamically update your position in line if you are in a login queue.
The launcher will no longer bounce you between multiple login queues at random.
New splash screens are now checked and downloaded, if needed, in parallel instead of one at a time. Hopefully this will reduce the time spent on this stage.


However I get the following output before it fails:

Initializing display with title 'Dungeons and Dragons Online'...
/build/dnd/dnd_live/src/engine/client/device/osx/Device_OSX.cpp, 284: called.
Initializing the smartbox...
Initializing the user interface...
Client ready
Client::Connect() async logon begun.
Connection failed (0x00000004:0x00CD0B73) to server 0, addr 198.252.160.45:9004
./my_ddo_launch.sh: line 589: 1686 Segmentation fault: 11 ./${gameClient_FILE}/Contents/MacOS/dndclient ${gameClient_ARGS}

Seems to me that " gameClient_ARGS" could have been changed :rolleyes:
Kind regards,
Stefano

Hi Ayeye. It looks a little bit like you did not allow the real Launcher to update the client before trying the script. However, the native Mac client is broken. It will crash on launch even after you update it. It is scheduled to be fixed on August 14th (tomorrow). Neither the actual Launcher, nor my script will work until the client is patched.

EDIT: I was concerned about the logistical changes in the Launch process. However, the script still seemed to launch the client ok. Unfortunately the client itself broke with the update, so I can’t be completely sure.

Isys
08-13-2019, 10:17 PM
Gang...

Thanks for keeping this thread alive. Probably saved me an hour of futility!! So tomorrow a patch...
Does anyone know that the minimum OSX DDO will run on? I'm on 10.10.5 - Yosemite...

Ayeye
08-14-2019, 04:15 PM
Hi Ayeye. It looks a little bit like you did not allow the real Launcher to update the client before trying the script. However, the native Mac client is broken. It will crash on launch even after you update it. It is scheduled to be fixed on August 14th (tomorrow). Neither the actual Launcher, nor my script will work until the client is patched.

EDIT: I was concerned about the logistical changes in the Launch process. However, the script still seemed to launch the client ok. Unfortunately the client itself broke with the update, so I can’t be completely sure.


Ah nice!
I was quite puzzled but I did not notice the problem was wide and under fixing (btw... where I work there is a frozen zone in December and another in August where you cannot touch production without a green light from the CEO, planning an update in these days it's not a great idea).

Coming back to the main subject, is Daybreak Game Company LLC aware of launcher problem for mac users? I think that shouldn't be something hard to solve, also since there is a working launcher script in this thread. After this issue with the main client it could be nice to open a couple of tickets for the launcher.

@Isys
I'm playing from High Sierra 10.13.6


Stefano

JQP
08-14-2019, 06:37 PM
Devs--any update on when the Mac client will be fixed? The hot fix obviously did not happen and I see no indication of when one will occur.

Daarsurra
08-15-2019, 12:18 PM
as far as i can tell, the "hotfix" seems to have fixed things that most players care about and left the Mac client standing on coals. the Mac client now crashes at the character selection screen and not after hitting Play.

Ayeye
08-15-2019, 12:20 PM
as far as i can tell, the "hotfix" seems to have fixed things that most players care about and left the Mac client standing on coals. the Mac client now crashes at the character selection screen and not after hitting Play.

Fixed today.
You could have followed the discussion on the "service notice" page of the forum:

https://www.ddo.com/forums/showthread.php/507453-DDO-Downtime-Wednesday-August-14th-9-00-AM-12-00-PM-Eastern-(-4-GMT)
Checkout the post from MacnCheese guy.

*Edit: Well, mine works correctly, also "Play" mind the downtime times are close to this time*

Stefano

Daarsurra
08-15-2019, 02:49 PM
Fixed today.
You could have followed the discussion on the "service notice" page of the forum:
https://www.ddo.com/forums/showthread.php/507453-DDO-Downtime-Wednesday-August-14th-9-00-AM-12-00-PM-Eastern-(-4-GMT)
Checkout the post from MacnCheese guy.

*Edit: Well, mine works correctly, also "Play" mind the downtime times are close to this time*

Stefano

actually, the "legacy client" for Mac still doesn't work for me, and i think that you meant to post a different link; i've followed that thread (still explains nothing) and about 8 others related to Mac issues; while there's a more updated thread for August 15th downtime, i think this one might be more helpful to the Mac community:


While the legacy Mac client continues to work (after today's patch), we are moving away from that client to the WINE client that debuted earlier this year. So, make sure to download it here if you ever run into any issues with the legacy client: http://live.ddo.com/sites/clientdl/ddo/ddolive.dmg

We don't have a firm cutoff date (yet), but people who play on Mac should consider upgrading to the newer client regardless if they can.

Mc-Iver77
08-15-2019, 04:50 PM
I followed the instructions and saved the SH file in my user Application folder and realized that it should be in the Applications folder that holds the DDO client. Once I moved it there I ran the script `chmod 755 /Applications/DNDLauncher.sh` but nothing happened. If this is happening to you, run `sh /Applications/DNDLauncher.sh` Works for me now.

t.takli
08-15-2019, 05:51 PM
Works beautifully!! Thank you so much. Have been unable to login after one of the updates (and patch to fix problem). You are amazing!

t.takli
08-15-2019, 05:53 PM
I followed the instructions and saved the SH file in my user Application folder and realized that it should be in the Applications folder that holds the DDO client. Once I moved it there I ran the script `chmod 755 /Applications/DNDLauncher.sh` but nothing happened. If this is happening to you, run `sh /Applications/DNDLauncher.sh` Works for me now.

Obviously. You had to run the chmod line first BEFORE running the launcher.

Mc-Iver77
08-15-2019, 08:48 PM
Obviously. You had to run the chmod line first BEFORE running the launcher.

You're right, i only read half of the instructions.

Aredharr
08-28-2019, 02:12 PM
Hi Guys,

First thanks all for this super cool thread.

Knowing that DDO will move to the WINE client at some point, I decided to install it alongside the old DDO client, meaning I have 2 DDO installed currently (didn't want to delete the original/old one yet as I didn't want to be left without the game). One is the original, called DNDclient (default) and the new one, which I named DDOWINE when I installed it.

Every time I try to open the WINE client with the game launcher, I get the trigger to the resource folder and the whole thing goes to hell, which brought me to this thread.

I've setup the script as described and I was able to launch my original mac client quite easily (actually very cool). Then, I figured I could change the destination of the app and launch the WINE one. Sadly, I get the same code response from the terminal (log in, etc), but nothing launches after the scripts has ran...

Since I'm not super familiar with this stuff I figured I'd ask if this is something that can be done or if I'm just dreaming.

Thanks in advance!

Kaytis
08-29-2019, 03:51 PM
Hi Guys,

First thanks all for this super cool thread.

Knowing that DDO will move to the WINE client at some point, I decided to install it alongside the old DDO client, meaning I have 2 DDO installed currently (didn't want to delete the original/old one yet as I didn't want to be left without the game). One is the original, called DNDclient (default) and the new one, which I named DDOWINE when I installed it.

Every time I try to open the WINE client with the game launcher, I get the trigger to the resource folder and the whole thing goes to hell, which brought me to this thread.

I've setup the script as described and I was able to launch my original mac client quite easily (actually very cool). Then, I figured I could change the destination of the app and launch the WINE one. Sadly, I get the same code response from the terminal (log in, etc), but nothing launches after the scripts has ran...

Since I'm not super familiar with this stuff I figured I'd ask if this is something that can be done or if I'm just dreaming.

Thanks in advance!

Hi Aredharr.

Work has kept me busy lately. I have glanced at what it would take to get the script working with the Wine client. It shouldn't be too difficult, but don't hold me to that. I noticed that folks using Wine on Linux claim to be able to use the "pylotro" script as their game launcher. That is interesting. If it works on Linux, it can certainly work on Unix (Mac).

The biggest problem right now is that macOS 10.15, only a few weeks away, removes 32-bit support. The "legacy" client is 32-bits. So it won't work. Period. There is a beta version of a 64-bit Wine emulator available for the Mac. It can, in theory, run the 32-bit Windows client but I have not tried it. It is said to be very buggy at this point.

There's a bit of train wreck coming. If you want to keep playing DDO, don't upgrade to macOS 10.15 until a stable 64-bit solution becomes available. SSG will either need to rebuild the existing legacy app using the 64-bit version of Qt (the cross platform SDK they used), or try to ensure that the Windows client works ok in the 64-bit Wine emulator on Mac.

jkalten
09-02-2019, 09:20 PM
Kaytis,

Is your script needed for the new wine client beta, or is it only needed to launch the legacy native client?

I'm just curious as from a quick read of your script I should be able to create a UI for it pretty easily with swift if this is going to still be needed for the wine version.

Currently downloading the wine client currently on my MBP just to try to see what the condition of things is like.

Kaytis
09-03-2019, 11:09 AM
Kaytis,

Is your script needed for the new wine client beta, or is it only needed to launch the legacy native client?

I'm just curious as from a quick read of your script I should be able to create a UI for it pretty easily with swift if this is going to still be needed for the wine version.

Currently downloading the wine client currently on my MBP just to try to see what the condition of things is like.

Technically, the script was never needed. It is an alternative to the DDO Launcher. The only real advantage is that it can launch the DDO Client much faster than the DDO Launcher can. The only time it might have been "needed" was when the DDO Launcher stopped working in Mojave.

The script will only work with the legacy DDO Client at the moment. It is not set up to launch the Wine DDO Client. I have taken only the briefest of glances at what the running Wine DDO Client command line looks like, but it follows an identical pattern of parameterization. Launching the Wine client should be a matter of reforming the command itself. The hard part of determining the launch parameters is already done.

Putting a swift shell around it sounds like a fun project. The script is super naive about its own parameterization. It expects either one (a toon name) or none. The presence or absence of that one parameter drives everything else. It's actually a pretty lame way to do it. But it makes invoking it super easy. A better way to do it would be to do a full on flag driven kind of thing. Something like:



./DNDLauncher.sh -u _username_ -p _password_ -s Orien -c Kaytis


Doing that would make the script generic and require no end user modifications. At the cost of having to type all that every time (admittedly I just use the up arrow in the Terminal, so there wouldn't be any cost).

It would still be possible to allow handcrafting of the script to specify all the rest of the details when only the toon name is provided. I probably should have done it that way really. Hmm.

The biggest problem right now is the lack of Wine support. I would have to look at that first because that does seem to be the direction SSG is headed.

Eudoxus
09-03-2019, 08:16 PM
THANK YOU for this!

I just subscribed to VIP for a year, then the latest patch came out and BLAMMO I couldn't play any longer.
I contacted support and they said "we don't support MAC" and pointed me to the main community thread.
I shot them back an email that says "if you don't SUPPORT MAC, then please provide me the rationale for having a MAC DMG download on your website where you sell subscriptions and products"

I'll see what, if anything, they say in response to this.

piercia
10-11-2019, 02:35 AM
Kaytis, thank you for the script for the previous Mac client. Just wondering if you have had time to adapt the script for the new Wine client yet?

Kaytis
10-19-2019, 12:28 PM
Kaytis, thank you for the script for the previous Mac client. Just wondering if you have had time to adapt the script for the new Wine client yet?

I just got it working. I am going to clean it up, add a feature that people were asking for, and post it soon™

Edit: Posted. The OP has been updated.

Dassex
11-26-2019, 11:07 PM
So, right off the top - I am NOT tech savvy in the least.
My question is about the DDO Launcher.
While I can launch the game more times than not, the text in the small window for the launcher is complete gobble-gook (I believe that is the technical term.)
Can't make out which server I'm clicking on (though, I have done a bit of process of elimination calculations by deciphering some of the "gobble-gook."

Any thoughts about how to address or even possibly fix this would be appreciated.
Pretty exasperating on the whole.

Kaytis
10-02-2020, 11:48 PM
Bump for version 1.5