Difference between revisions of "Server:MacSupport"

From The Al`Kabor Project Wiki
Jump to navigation Jump to search
 
(26 intermediate revisions by 2 users not shown)
Line 1: Line 1:
=== Client-based Constraints ===
The Everquest: Macintosh edition with which the TAKP client is based is a 32-bit application.  The last version of MacOS to support 32-bit applications was MacOS Mojave 10.14 on either Intel or PPC architectures.  Thus, the only way currently to play TAKP on a MAC is using a machine with one of these architectures and MacOS 10.14 or earlier.


== Opcodes ==
Mac support requires special care to provide a server name to the client application since it lacks a server select screen UI.  This is typically handled by the server, but it is possible to also manipulate it at client level using Apple IPC mechanisms (as Solar did for the [https://github.com/EQArchives/EQMacEmu/blob/09da8370ff01ea671fbc772511579b8d4876741e/utils/EQPPCLaunch/main.c PPC launcher]).
All opcodes are found at [https://github.com/EQMacEmu/Server/blob/fc08674c9bf0d02aa1b408b2d9c7e5cb578a0c75/loginserver/login_util/login_opcodes_oldver.conf login_opcodes_oldver.conf] and listed below for convenience:
 
== Login Protocol ==
The original Everquest: Macintosh Edition used the launcher to authenticate with an SOE session server which would then provide a ticket back to the client.  The client would then pass the ticket to the world server.  EQ has a basic crypt mechanism for the password and this is similar in concept to how Kerberos is/was used by Active Directory in Windows operating systems.
 
To get MAC support working, the client simply passes username/password directly to the loginserver as if it was a ticket (skipping the session server step).  The loginserver parses the username/password part of the ticket string.
 
'''''Editor's Note: The password is being passed over the wire in the clear (no encryption/hashing).  This is a potential area for future improvement.'''''
 
=== Opcodes ===
All opcodes are found at [https://github.com/EQMacEmu/Server/blob/fc08674c9bf0d02aa1b408b2d9c7e5cb578a0c75/loginserver/login_util/login_opcodes_oldver.conf login_opcodes_oldver.conf] but the following are relevant to this discussion:


* OP_SessionReady=0x5900
* OP_SessionReady=0x5900
* OP_LoginOSX=0x8e00
* OP_LoginOSX=0x8e00
* OP_LoginPC=0x0100
* OP_ClientError=0x0200
* OP_ServerListRequest=0x4600
* OP_PlayEverquestRequest=0x4700
* OP_LoginUnknown1=0x4800
* OP_LoginUnknown2=0x4A00
* <s>OP_PlayEverquestResponse=0x0021</s>
* <s>OP_ChatMessage=0x0016</s>
* OP_LoginAccepted=0x0400
* OP_LoginAccepted=0x0400
* OP_LoginComplete=0x8800
* OP_LoginComplete=0x8800
* OP_ServerName=0x4900
* OP_ServerName=0x4900
* OP_LoginBanner=0x5200
* OP_LoginBanner=0x5200
* <s>OP_ServerListResponse=0x004a</s>
* <s>OP_Poll=0x0029</s>
* <s>OP_EnterChat=0x000f</s>
* <s>OP_PollResponse=0x0011</s>


== Login ==
When a client first authenticates to the loginserver, it sends the <span style="font-weight:bold">OP_SessionReady</span> opcode to the server, and the server responds back with <span style="font-weight:bold">OP_SessionReady</span>.
When a client first authenticates to the loginserver, it sends the **OP_LoginOSX** opcode followed by the username/password and eqworld-52.989studios.com.  This url is no longer used but rather parsed server-side to validate mac clients (see [https://github.com/EQArchives/EQMacEmu/blob/09da8370ff01ea671fbc772511579b8d4876741e/loginserver/client.cpp#L62 OP_LoginOSX] and [https://github.com/EQArchives/EQMacEmu/blob/09da8370ff01ea671fbc772511579b8d4876741e/loginserver/client.cpp#L245 handle_login] behavior).
 
The client then replies with the <span style="font-weight:bold">OP_LoginOSX</span> opcode followed by the username/password and eqworld-52.989studios.com as a UDP datagramThe url is no longer used but rather parsed server-side to validate mac clients (see [https://github.com/EQArchives/EQMacEmu/blob/09da8370ff01ea671fbc772511579b8d4876741e/loginserver/client.cpp#L62 OP_LoginOSX] and [https://github.com/EQArchives/EQMacEmu/blob/09da8370ff01ea671fbc772511579b8d4876741e/loginserver/client.cpp#L245 handle_login] behavior).
 
If the username was found in the accounts table, the server pulls the sha1 hash of the user's password and compares it against what the user sent to the server.  If it checks out, the server sends a packet back to the client with the <span style="font-weight:bold">OP_LoginAccepted</span> opcode and the account ID prepended with "LS#" which is used as the session id, a field with the string "unused", and the number 4 (possibly macclientversion where pc=2, intel=4, ppc=8).  The second and third fields would appear on the wire as <span style="font-weight:bold">75 6e 75 73 65 64 00 04</span>.


The key difference between a Windows Client and OSX client successfully authenticating is the following [https://github.com/EQArchives/EQMacEmu/blob/09da8370ff01ea671fbc772511579b8d4876741e/loginserver/client.cpp#L337|block of code] that sends an extra packet:
Finally, the client responds to the server with <span style="font-weight:bold">OP_LoginComplete</span>.
 
The key difference for TAKP loginserver source between a Windows Client and OSX client successfully authenticating is the following [https://github.com/EQArchives/EQMacEmu/blob/09da8370ff01ea671fbc772511579b8d4876741e/loginserver/client.cpp#L337 block of code] in the loginserver source that sends an extra UDP packet to the client telling it which world server to connect to:
<pre>
<pre>
string buf = server.options.GetNetworkIP();
string buf = server.options.GetNetworkIP();
Line 35: Line 39:
</pre>
</pre>


_GetNetworkIP()_ pulls the world server's URL from you login.ini file and/or the database as mentioned previously.  This leaves you with a packet containing "0x4900" and your server's URL which the client will then use to reach server select.
This second packet shown above being sent is technically unnecessary - it just overwrites the server selected by the client.
 
<span style="font-weight:bold">GetNetworkIP()</span> pulls the world server's URL from your login.ini file and/or the database as mentioned previously.  This leaves you with a packet containing "0x4900" and your server's URL which the client will then use to reach server select.


== Server Selection ==
== Server Selection ==
Mac Clients do not have a server select option.  As a result, server selection is passed to them after successful login.  While there is a way to have the client select a server based on an Apple IPC mechanism, the server is currently hardcoded as a configuration setting in `login.ini` as well as the `loginserversettings` table.
Mac Clients do not have a server select option.  As a result, server selection is passed to them after successful login.  While there is a way to have the client select a server based on an Apple IPC mechanism, the server is currently hardcoded as a configuration setting in [https://github.com/EQArchives/EQMacEmu/blob/09da8370ff01ea671fbc772511579b8d4876741e/loginserver/login_util/login.ini login.ini] as well as the <span style="font-weight:bold">loginserversettings</span> table.
 
The loginserversettings table is where you set your world server's URL in the "network_ip" setting.
<pre>
UPDATE loginserversettings (`type`, `value`, `category`, `description`, `defaults`) VALUES ("network_ip", "takp.example.com", "options", "World Server URL", "takp.example.com");
</pre>
 
Your login.ini also has this setting:
<pre>
network_ip = takp.example.com
</pre>
 
<div style="font-style:italic">Note: You should use your server's <span style="font-weight:bold">short name for the subdomain</span> in this use case.  What you place here will determine what your client uses as part of your character's UI file names.</div>
 
Finally, make sure the <span style="font-weight:bold">world->address</span> field in your <span style="font-weight:bold">eqemu_config.json</span> file is also set to this value:
<pre>
"address": "takp.example.com"
</pre>
 
The loginserver will use this value to match with its network_ip setting.
 
== Client Configuration ==
Since there is currently no mechanism in place to allow multiple servers to be selected by Mac clients, the loginserver you use will determine the world server the client jumps to after logging in.  Thus, you should set your <span style="font-weight:bold">Everquest.app/Content/Resources/eqhost.txt</span> file to point to the loginserver matching the world server you want to connect to.

Latest revision as of 16:12, 31 December 2023

Client-based Constraints[edit]

The Everquest: Macintosh edition with which the TAKP client is based is a 32-bit application. The last version of MacOS to support 32-bit applications was MacOS Mojave 10.14 on either Intel or PPC architectures. Thus, the only way currently to play TAKP on a MAC is using a machine with one of these architectures and MacOS 10.14 or earlier.

Mac support requires special care to provide a server name to the client application since it lacks a server select screen UI. This is typically handled by the server, but it is possible to also manipulate it at client level using Apple IPC mechanisms (as Solar did for the PPC launcher).

Login Protocol[edit]

The original Everquest: Macintosh Edition used the launcher to authenticate with an SOE session server which would then provide a ticket back to the client. The client would then pass the ticket to the world server. EQ has a basic crypt mechanism for the password and this is similar in concept to how Kerberos is/was used by Active Directory in Windows operating systems.

To get MAC support working, the client simply passes username/password directly to the loginserver as if it was a ticket (skipping the session server step). The loginserver parses the username/password part of the ticket string.

Editor's Note: The password is being passed over the wire in the clear (no encryption/hashing). This is a potential area for future improvement.

Opcodes[edit]

All opcodes are found at login_opcodes_oldver.conf but the following are relevant to this discussion:

  • OP_SessionReady=0x5900
  • OP_LoginOSX=0x8e00
  • OP_LoginAccepted=0x0400
  • OP_LoginComplete=0x8800
  • OP_ServerName=0x4900
  • OP_LoginBanner=0x5200

When a client first authenticates to the loginserver, it sends the OP_SessionReady opcode to the server, and the server responds back with OP_SessionReady.

The client then replies with the OP_LoginOSX opcode followed by the username/password and eqworld-52.989studios.com as a UDP datagram. The url is no longer used but rather parsed server-side to validate mac clients (see OP_LoginOSX and handle_login behavior).

If the username was found in the accounts table, the server pulls the sha1 hash of the user's password and compares it against what the user sent to the server. If it checks out, the server sends a packet back to the client with the OP_LoginAccepted opcode and the account ID prepended with "LS#" which is used as the session id, a field with the string "unused", and the number 4 (possibly macclientversion where pc=2, intel=4, ppc=8). The second and third fields would appear on the wire as 75 6e 75 73 65 64 00 04.

Finally, the client responds to the server with OP_LoginComplete.

The key difference for TAKP loginserver source between a Windows Client and OSX client successfully authenticating is the following block of code in the loginserver source that sends an extra UDP packet to the client telling it which world server to connect to:

string buf = server.options.GetNetworkIP();
auto outapp2 = new EQApplicationPacket(OP_ServerName, (uint32)buf.length() + 1);
strncpy((char*)outapp2->pBuffer, buf.c_str(), buf.length() + 1);
connection->QueuePacket(outapp2);
delete outapp2;
sentsessioninfo = true;

This second packet shown above being sent is technically unnecessary - it just overwrites the server selected by the client.

GetNetworkIP() pulls the world server's URL from your login.ini file and/or the database as mentioned previously. This leaves you with a packet containing "0x4900" and your server's URL which the client will then use to reach server select.

Server Selection[edit]

Mac Clients do not have a server select option. As a result, server selection is passed to them after successful login. While there is a way to have the client select a server based on an Apple IPC mechanism, the server is currently hardcoded as a configuration setting in login.ini as well as the loginserversettings table.

The loginserversettings table is where you set your world server's URL in the "network_ip" setting.

UPDATE loginserversettings (`type`, `value`, `category`, `description`, `defaults`) VALUES ("network_ip", "takp.example.com", "options", "World Server URL", "takp.example.com");

Your login.ini also has this setting:

network_ip = takp.example.com
Note: You should use your server's short name for the subdomain in this use case. What you place here will determine what your client uses as part of your character's UI file names.

Finally, make sure the world->address field in your eqemu_config.json file is also set to this value:

"address": "takp.example.com"

The loginserver will use this value to match with its network_ip setting.

Client Configuration[edit]

Since there is currently no mechanism in place to allow multiple servers to be selected by Mac clients, the loginserver you use will determine the world server the client jumps to after logging in. Thus, you should set your Everquest.app/Content/Resources/eqhost.txt file to point to the loginserver matching the world server you want to connect to.