~ruther/NosTale-Gfless

NosTale-Gfless/NosTaleGfless/NostaleLauncher.cs -rw-r--r-- 3.3 KiB
4f5eef52 — František Boháček chore: add license 4 years ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using NostaleAuth.Models;

namespace NosTaleGfless
{
    public class NostaleLauncher
    {
        private readonly object _lock;
        
        public NostaleLauncher()
        {
            _lock = new object();
        }
        
        public Task<NostaleProcess> Launch(GameforgeAccount account, string sessionToken, string nostalePath)
        {
            return Task.Run(() =>
            {
                lock (_lock)
                {
                    NostaleProcess process = RunProcess(account, nostalePath);
                    process.Initialized = ProcessPipeServer(process, sessionToken).GetAwaiter().GetResult();

                    if (process.Initialized)
                    {
                        while (true)
                        {
                            List<IntPtr> handles = new List<IntPtr>();

                            // wait for main window open
                            User32.EnumDesktopWindows(IntPtr.Zero, (hWnd, lParam) =>
                            {
                                User32.GetWindowThreadProcessId(hWnd, out uint processId);
                                if (processId == process.ProcessId)
                                {
                                    handles.Add(hWnd);
                                }

                                return true;
                            }, IntPtr.Zero);

                            if (handles.Count > 6 || process.HasExited)
                            {
                                break;
                            }

                            Task.Delay(50).GetAwaiter().GetResult();
                        }
                    }

                    return process;
                }
            });
        }
        
        public NostaleProcess RunProcess(GameforgeAccount account, string nostalePath)
        {
            Guid sessionId = Guid.NewGuid();
            
            Environment.SetEnvironmentVariable("_TNT_CLIENT_APPLICATION_ID", "d3b2a0c1-f0d0-4888-ae0b-1c5e1febdafb");
            Environment.SetEnvironmentVariable("_TNT_SESSION_ID", sessionId.ToString());
            
            string path = GetNostaleClientPath(nostalePath);
            Process process = Process.Start(path, $"gf {(int)account.GetRegionType()}");

            return new NostaleProcess(process, account)
            {
                SessionId = sessionId
            };
        }
        
        public async Task<bool> ProcessPipeServer(NostaleProcess process, string sessionToken)
        {
            var pipeServer = new NostalePipeServer(process, sessionToken);
            await pipeServer.Start();

            return pipeServer.Successful;
        }

        private string GetNostaleClientPath(string nostalePath)
        {
            if (Directory.Exists(nostalePath))
            {
                nostalePath = Path.Combine(nostalePath, "NostaleClientX.exe");
            }

            if (!File.Exists(nostalePath))
            {
                throw new InvalidOperationException("Nostale was not found.");
            }

            return nostalePath;
        }
    }
}
Do not follow this link