~ruther/NosTale-Gfless

ref: fc51a68e949a505ac95fe9b5e7363245d2b539d8 NosTale-Gfless/NosTaleGfless/NostalePipeServer.cs -rw-r--r-- 4.2 KiB
fc51a68e — František Boháček Initial commit 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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
using System;
using System.Collections.Generic;
using System.Diagnostics.SymbolStore;
using System.IO;
using System.IO.Pipes;
using System.Linq;
using System.Net.Http.Headers;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Newtonsoft.Json;
using NosTaleGfless.Pipes;

namespace NosTaleGfless
{
    public class NostalePipeServer
    {
        protected string _sessionToken;
        protected CancellationTokenSource _cancellationTokenSource;

        public NostalePipeServer(NostaleProcess process, string sessionToken)
        {
            _sessionToken = sessionToken;
            Process = process;
            _cancellationTokenSource = new CancellationTokenSource();

            Process.Process.Exited += OnNostaleExit;
        }

        public bool Successful { get; protected set; }

        public NostaleProcess Process { get; }

        public async Task Start()
        {
            byte[] buffer = new byte[1024];
            List<NamedPipeServerStream> servers = new List<NamedPipeServerStream>();
            servers.Add(CreateServer());
            
            while (!Successful)
            {
                NamedPipeServerStream serverStream = servers.Last();
                try
                {
                    await serverStream.WaitForConnectionAsync(_cancellationTokenSource.Token);
                }
                catch (OperationCanceledException)
                {
                    serverStream.Dispose();
                    break;
                }

                int read = await serverStream.ReadAsync(buffer, 0, 1024);
                ParamsMessage message = ParseMessage(buffer, read);

                string output = null;
                switch (message.Method)
                {
                    case "ClientLibrary.isClientRunning":
                        output = CreateResult<bool, ResultMessage<bool>>(message, true);
                        break;
                    case "ClientLibrary.initSession":
                        output = CreateResult<string, ResultMessage<string>>(message, message.Params.SessionId);
                        break;
                    case "ClientLibrary.queryAuthorizationCode":
                        output = CreateResult<string, ResultMessage<string>>(message, _sessionToken);
                        _sessionToken = null;
                        break;
                    case "ClientLibrary.queryGameAccountName":
                        output = CreateResult<string, ResultMessage<string>>(message, Process.Account.Name);
                        Process.Process.Exited -= OnNostaleExit;
                        Successful = true;
                        break;
                }

                if (!Successful)
                {
                    servers.Add(CreateServer());
                }

                if (output != null)
                {
                    byte[] data = Encoding.ASCII.GetBytes(output);
                    serverStream.Write(data, 0, data.Length);
                }
            }

            foreach (NamedPipeServerStream server in servers)
            {
                server.Dispose();
            }
        }

        protected NamedPipeServerStream CreateServer()
        {
            return new NamedPipeServerStream("GameforgeClientJSONRPC", PipeDirection.InOut, 254,
                PipeTransmissionMode.Byte, PipeOptions.Asynchronous);
        }

        protected ParamsMessage ParseMessage(byte[] data, int count)
        {
            return JsonConvert.DeserializeObject<ParamsMessage>(Encoding.ASCII.GetString(data, 0, count));
        }

        protected string SerializeResult<T>(ResultMessage<T> result)
        {
            return JsonConvert.SerializeObject(result);
            ;
        }

        protected string CreateResult<T, U>(ParamsMessage receivedMessage, T result)
            where U : ResultMessage<T>, new()
        {
            return SerializeResult(new U
            {
                Id = receivedMessage.Id,
                Jsonrpc = receivedMessage.Jsonrpc,
                Result = result
            });
        }

        protected void OnNostaleExit(object sender, EventArgs args)
        {
            Process.Process.Exited -= OnNostaleExit;
            _cancellationTokenSource.Cancel();
        }
    }
}
Do not follow this link