-
Notifications
You must be signed in to change notification settings - Fork 16
/
NetworkConnectionActions.cs
130 lines (110 loc) · 5.48 KB
/
NetworkConnectionActions.cs
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
129
130
using System;
using System.Threading.Tasks;
using AutomaticTypeMapper;
using EOLib.Config;
using EOLib.Domain.Login;
using EOLib.Domain.Protocol;
using EOLib.Net.Communication;
using EOLib.Net.PacketProcessing;
using EOLib.Net.Translators;
namespace EOLib.Net.Connection
{
[AutoMappedType]
public class NetworkConnectionActions : INetworkConnectionActions
{
private readonly INetworkClientRepository _networkClientRepository;
private readonly IConnectionStateRepository _connectionStateRepository;
private readonly ISequenceRepository _sequenceRepository;
private readonly IConfigurationProvider _configurationProvider;
private readonly IHashService _hashService;
private readonly IHDSerialNumberService _hdSerialNumberService;
private readonly IPacketTranslator<IInitializationData> _initPacketTranslator;
private readonly INetworkClientFactory _networkClientFactory;
private readonly IPacketSendService _packetSendService;
private readonly IPlayerInfoRepository _playerInfoRepository;
public NetworkConnectionActions(INetworkClientRepository networkClientRepository,
IConnectionStateRepository connectionStateRepository,
ISequenceRepository sequenceRepository,
IConfigurationProvider configurationProvider,
IHashService hashService,
IHDSerialNumberService hdSerialNumberService,
IPacketTranslator<IInitializationData> initPacketTranslator,
INetworkClientFactory networkClientFactory,
IPacketSendService packetSendService,
IPlayerInfoRepository playerInfoRepository)
{
_networkClientRepository = networkClientRepository;
_connectionStateRepository = connectionStateRepository;
_sequenceRepository = sequenceRepository;
_configurationProvider = configurationProvider;
_hashService = hashService;
_hdSerialNumberService = hdSerialNumberService;
_initPacketTranslator = initPacketTranslator;
_networkClientFactory = networkClientFactory;
_packetSendService = packetSendService;
_playerInfoRepository = playerInfoRepository;
}
public async Task<ConnectResult> ConnectToServer()
{
if (Client.Connected)
return ConnectResult.AlreadyConnected;
var host = _configurationProvider.Host;
var port = _configurationProvider.Port;
var result = await Client.ConnectToServer(host, port);
if (result != ConnectResult.AlreadyConnected && result != ConnectResult.Success)
_connectionStateRepository.NeedsReconnect = true;
return result;
}
public async Task<ConnectResult> ReconnectToServer()
{
if (Client.Connected)
{
Client.CancelBackgroundReceiveLoop();
Client.Disconnect();
}
Client.Dispose();
_networkClientRepository.NetworkClient = _networkClientFactory.CreateNetworkClient();
return await ConnectToServer();
}
public void DisconnectFromServer()
{
Client.Disconnect();
_sequenceRepository.SequenceIncrement = 0;
_sequenceRepository.SequenceStart = 0;
_connectionStateRepository.NeedsReconnect = true;
}
public async Task<IInitializationData> BeginHandshake()
{
var stupidHash = _hashService.StupidHash(new Random().Next(6, 12));
var hdSerialNumber = _hdSerialNumberService.GetHDSerialNumber();
var packet = new PacketBuilder(PacketFamily.Init, PacketAction.Init)
.AddThree(stupidHash)
.AddChar(_configurationProvider.VersionMajor)
.AddChar(_configurationProvider.VersionMinor)
.AddChar(_configurationProvider.VersionBuild)
.AddChar(112)
.AddChar((byte)hdSerialNumber.Length)
.AddString(hdSerialNumber)
.Build();
var responsePacket = await _packetSendService.SendRawPacketAndWaitAsync(packet);
if (IsInvalidInitPacket(responsePacket))
throw new EmptyPacketReceivedException();
return _initPacketTranslator.TranslatePacket(responsePacket);
}
public void CompleteHandshake(IInitializationData initializationData)
{
_playerInfoRepository.PlayerID = (short)initializationData[InitializationDataKey.PlayerID];
var packet = new PacketBuilder(PacketFamily.Connection, PacketAction.Accept)
.AddShort((short)initializationData[InitializationDataKey.SendMultiple])
.AddShort((short)initializationData[InitializationDataKey.ReceiveMultiple])
.AddShort(_playerInfoRepository.PlayerID)
.Build();
_packetSendService.SendPacket(packet);
}
private static bool IsInvalidInitPacket(IPacket responsePacket)
{
return responsePacket.Family != PacketFamily.Init || responsePacket.Action != PacketAction.Init;
}
private INetworkClient Client => _networkClientRepository.NetworkClient;
}
}