A library that allows you to launch NosTale client without GF launcher, or create your own private server launcher that starts the game client in the server selection screen (you skip the login & pass window)
The launcher communicates with the game using named pipe and JSON-RPC protocol.
Before the game is started GF launcher creates two environment variables:
_TNT_CLIENT_APPLICATION_ID
- This is the UUID that is stored in windows registry, it is probably const for the GF launcher itself._TNT_SESSION_ID
- This var contains random UUID to identify game client in the launcher (in case you run multiple game clients)
_TNT_CLIENT_APPLICATION_ID
helps to locate the GF client installation folder, the game reads it from registry keyComputer\HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall{THE_UUID_FROM_VAR}_is1
in order to locate thegameforge_client_api.dll
. If the var doesn't exist the game tries to grab the dll from the game folder itself. So if you don't set the var you need to copy the dll manually from GF launcher to game folder._TNT_SESSION_ID
the var also isn't mandatory, you don't have to set it if you want to make things simpler.
Please note, as long as you don't set those vars you are fine, however if you for some reasons want to do that do NOT set those variables as global windows environments, instead set it as local vars for your process
The next step before launching the game is to create MS Windows pipe named \\.\pipe\GameforgeClientJSONRPC
using CreateNamedPipe
winapi func with duplex and byte modes. Then you need to launch the game client with gf
parameter, and wait for the informations sent over pipe using ConnectNamedPipe
If you see error messagebox like gf init failed
at this points, it means that the game client couldn't locate gameforge_client_api.dll
either in the location pointed via registry key, or inside the game folder itself.
You can read/write to the pipe using winapi calls like ReadFile
or WriteFile
. After the game client initialize, it will send...
Message from client:
{{\"id\":1,\"jsonrpc\":\"2.0\",\"method\":\"ClientLibrary.isClientRunning\",\"params\":{{\"sessionId\":\"SESSION_FROM_TNT_SESSION_ID\"}}}}
You need to answer:
{{\"id\":1,\"jsonrpc\":\"2.0\",\"result\":true}}
Message from client:
{{\"id\":2,\"jsonrpc\":\"2.0\",\"method\":\"ClientLibrary.initSession\",\"params\":{{\"sessionId\":\"SESSION_FROM_TNT_SESSION_ID\"}}}}
You need to answer:
{{\"id\":2,\"jsonrpc\":\"2.0\",\"result\":\"SESSION_FROM_TNT_SESSION_ID\"}}
It looks the same as first message, except the id: 1
now becomes id: 3
Message from client:
{{\"id\":4,\"jsonrpc\":\"2.0\",\"method\":\"ClientLibrary.queryAuthorizationCode\",\"params\":{{\"sessionId\":\"SESSION_FROM_TNT_SESSION_ID\"}}}}
You need to answer with the token obtained from GF API, you may use this library to obtain the token: Nostale-Auth. Remember, you need the raw token (the UUID), not the hexlified one. If you create private server launcher you need to suply your own auth token, that you can later validate inside your login/game server:
{{\"id\":4,\"jsonrpc\":\"2.0\",\"result\":\"AUTH_TOKEN_IN_UUID_FORM\"}}
Message from client:
{{\"id\":5,\"jsonrpc\":\"2.0\",\"method\":\"ClientLibrary.queryGameAccountName\",\"params\":{{\"sessionId\":\"SESSION_FROM_TNT_SESSION_ID\"}}}}
It looks like it really doesn't matter what display name you will send, you will login anyway, however if you want to stick what the GF launcher does, you can obtain the proper display name using library linked above.
{"id":5,"jsonrpc":"2.0","result":"DISPLAY_NAME"}
- All the communication is done in JSON format, it looks really strange here because it is in escaped format, however any proper json should be accepted.
- If you dont set the
_TNT_SESSION_ID
thenSESSION_FROM_TNT_SESSION_ID
will be empty in all the messages exchanged between launcher and game, however this doesn't really matter - After each packet send you may have to create the pipe again using
CreateNamedPipe
In order to run the example server you need to:
- Install python3 (remember, set the checkbox with "Add to PATH")
- Modify the very first line of server.py to set the correct game path
- Modify the second line of the server.py to set the correct code country
- Install the
requests
andpywin32
libraries, you can do it easily usingpip
- Run the shell with admin permissions and execute the
python server.py <email> <password>
NOTE: If you don't have the GF launcher installed you firstly need to put the gameforge_client_api.dll
into the game folder, and comment out the line with os.environ["_TNT_CLIENT_APPLICATION_ID"] = ....