1 /*
2 This file is part of Telegram Desktop,
3 the official desktop application for the Telegram messaging service.
4 
5 For license and copyright information please follow this link:
6 https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
7 */
8 #pragma once
9 
10 #include "base/timer.h"
11 #include "base/weak_ptr.h"
12 #include "base/bytes.h"
13 #include "mtproto/mtproto_response.h"
14 
15 namespace MTP {
16 
17 class Instance;
18 
19 namespace details {
20 
21 class SpecialConfigRequest;
22 
23 class ConfigLoader : public base::has_weak_ptr {
24 public:
25 	ConfigLoader(
26 		not_null<Instance*> instance,
27 		const QString &phone,
28 		Fn<void(const MTPConfig &result)> onDone,
29 		FailHandler onFail,
30 		bool proxyEnabled);
31 	~ConfigLoader();
32 
33 	void load();
34 	void setPhone(const QString &phone);
35 	void setProxyEnabled(bool value);
36 
37 private:
38 	mtpRequestId sendRequest(ShiftedDcId shiftedDcId);
39 	void addSpecialEndpoint(
40 		DcId dcId,
41 		const std::string &ip,
42 		int port,
43 		bytes::const_span secret);
44 	void sendSpecialRequest();
45 	void enumerate();
46 	void refreshSpecialLoader();
47 	void createSpecialLoader();
48 	DcId specialToRealDcId(DcId specialDcId);
49 	void specialConfigLoaded(const MTPConfig &result);
50 	void terminateRequest();
51 	void terminateSpecialRequest();
52 
53 	not_null<Instance*> _instance;
54 	base::Timer _enumDCTimer;
55 	DcId _enumCurrent = 0;
56 	mtpRequestId _enumRequest = 0;
57 
58 	struct SpecialEndpoint {
59 		DcId dcId;
60 		std::string ip;
61 		int port;
62 		bytes::vector secret;
63 	};
64 	friend bool operator==(const SpecialEndpoint &a, const SpecialEndpoint &b);
65 	std::unique_ptr<SpecialConfigRequest> _specialLoader;
66 	std::vector<SpecialEndpoint> _specialEndpoints;
67 	std::vector<SpecialEndpoint> _triedSpecialEndpoints;
68 	base::Timer _specialEnumTimer;
69 	DcId _specialEnumCurrent = 0;
70 	mtpRequestId _specialEnumRequest = 0;
71 	QString _phone;
72 	bool _proxyEnabled = false;
73 
74 	Fn<void(const MTPConfig &result)> _doneHandler;
75 	FailHandler _failHandler;
76 
77 };
78 
79 inline bool operator==(const ConfigLoader::SpecialEndpoint &a, const ConfigLoader::SpecialEndpoint &b) {
80 	return (a.dcId == b.dcId) && (a.ip == b.ip) && (a.port == b.port);
81 }
82 
83 } // namespace details
84 } // namespace MTP
85