1/*
2 * LegacyClonk
3 *
4 * Copyright (c) RedWolf Design
5 * Copyright (c) 2013-2016, The OpenClonk Team and contributors
6 * Copyright (c) 2017-2020, The LegacyClonk Team and contributors
7 *
8 * Distributed under the terms of the ISC license; see accompanying file
9 * "COPYING" for details.
10 *
11 * "Clonk" is a registered trademark of Matthes Bender, used with permission.
12 * See accompanying file "TRADEMARK" for details.
13 *
14 * To redistribute this file separately, substitute the full license texts
15 * for the above references.
16 */
17
18#pragma once
19
20#include "C4Coroutine.h"
21#include "C4ForwardDeclarations.h"
22#include "C4HTTPClient.h"
23#include "C4Log.h"
24#include "C4Network2.h"
25#include "C4Network2Client.h"
26
27#include "C4GameParameters.h"
28#include "C4Version.h"
29#include "C4GameVersion.h"
30#include "C4InputValidation.h"
31
32#include <atomic>
33#include <chrono>
34#include <memory>
35#include <mutex>
36#include <optional>
37#include <string>
38#include <vector>
39
40// Session data
41class C4Network2Reference
42{
43public:
44 C4Network2Reference();
45 ~C4Network2Reference();
46
47 // Game parameters
48 C4GameParameters Parameters;
49
50private:
51 // General information
52 int32_t Icon;
53 C4Network2Status GameStatus;
54 int32_t Time;
55 int32_t Frame;
56 int32_t StartTime;
57 int32_t LeaguePerformance; // custom settlement league performance if scenario doesn't use elapsed frames
58 ValidatedStdStrBuf<C4InVal::VAL_Comment> Comment;
59 bool JoinAllowed;
60 bool PasswordNeeded;
61 bool OfficialServer;
62 C4NetpuncherID NetpuncherGameID;
63 StdStrBuf NetpuncherAddr;
64
65 // Engine information
66 C4GameVersion Game;
67
68 // Network addresses
69 std::vector<C4Network2Address> Addrs;
70 C4Network2EndpointAddress source;
71
72public:
73 const std::vector<C4Network2Address> &getAddresses() const { return Addrs; }
74 const char *getTitle() const { return Parameters.ScenarioTitle.getData(); }
75 int32_t getIcon() const { return Icon; }
76 C4Network2Status getGameStatus() const { return GameStatus; }
77 const char *getComment() const { return Comment.getData(); }
78 const C4GameVersion &getGameVersion() const { return Game; }
79 bool isPasswordNeeded() const { return PasswordNeeded; }
80 bool isJoinAllowed() const { return JoinAllowed; }
81 bool isOfficialServer() const { return OfficialServer; }
82 int32_t getSortOrder() const;
83 int32_t getTime() const { return Time; }
84 int32_t getStartTime() const { return StartTime; }
85 C4NetpuncherID getNetpuncherGameID() const { return NetpuncherGameID; }
86 StdStrBuf getNetpuncherAddr() const { return NetpuncherAddr; }
87
88 void SetSourceAddress(const C4Network2EndpointAddress &ip);
89 const C4Network2EndpointAddress &GetSourceAddress() const { return source; }
90
91 void InitLocal(C4Game *pGame);
92
93 void CompileFunc(StdCompiler *pComp);
94};
95
96// Serves references (mini-HTTP-server)
97class C4Network2RefServer : public C4NetIOTCP
98{
99public:
100 C4Network2RefServer();
101 virtual ~C4Network2RefServer();
102
103private:
104 CStdCSec RefCSec;
105 C4Network2Reference *pReference;
106
107public:
108 void Clear();
109 void SetReference(C4Network2Reference *pReference);
110
111protected:
112 // Overridden
113 virtual void PackPacket(const C4NetIOPacket &rPacket, StdBuf &rOutBuf) override;
114 virtual size_t UnpackPacket(const StdBuf &rInBuf, const C4NetIO::addr_t &addr) override;
115
116private:
117 // Responses
118 void RespondMethodNotAllowed(const C4NetIO::addr_t &addr);
119 void RespondReference(const C4NetIO::addr_t &addr);
120};
121
122class C4Network2HTTPClient : public StdSchedulerProc
123{
124public:
125 class Impl;
126
127public:
128 C4Network2HTTPClient();
129 ~C4Network2HTTPClient() override;
130
131public:
132 bool Init();
133 bool Query(const StdBuf &Data, bool binary, C4HTTPClient::Headers headers = {});
134 bool Query(const std::string_view data, bool binary, C4HTTPClient::Headers headers = {}) { return Query(Data: StdBuf::MakeRef(pData: data.data(), iSize: data.size()), binary, headers: std::move(headers)); }
135
136 bool isBusy() const;
137 bool isSuccess() const;
138 bool isConnected() const;
139 std::size_t getTotalSize() const;
140 std::size_t getDownloadedSize() const;
141 const StdBuf &getResultBin() const;
142 const StdStrBuf &getResultString() const;
143 const char *getURL() const;
144 const char *getServerName() const;
145 const C4NetIO::addr_t &getServerAddress() const;
146 virtual const char *GetError() const;
147 void ResetError();
148 bool Cancel(std::string_view reason);
149 void Clear();
150
151 bool SetServer(std::string_view serverAddress, std::uint16_t defaultPort = 0);
152 void SetNotify(class C4InteractiveThread *thread);
153
154 bool Execute(int iMaxTime = StdSync::Infinite) override;
155 int GetTimeout() override;
156
157#ifdef _WIN32
158 HANDLE GetEvent() override;
159#else
160 void GetFDs(std::vector<pollfd> &fds) override;
161#endif
162
163protected:
164 void SetError(const char *error);
165
166private:
167 std::unique_ptr<Impl> impl;
168};
169
170C4LOGGERCONFIG_NAME_TYPE(C4Network2HTTPClient);
171
172// Loads references (mini-HTTP-client)
173class C4Network2RefClient : public C4Network2HTTPClient
174{
175 C4GameVersion MasterVersion;
176 StdStrBuf MessageOfTheDay, MessageOfTheDayHyperlink;
177 StdStrBuf LeagueServerRedirect;
178 bool fVerSet;
179
180public:
181 C4Network2RefClient() : fVerSet(false), C4Network2HTTPClient() {}
182
183 bool QueryReferences();
184 bool GetReferences(C4Network2Reference ** &rpReferences, int32_t &rRefCount);
185 const char *GetMessageOfTheDay() const { return MessageOfTheDay.getData(); }
186 const char *GetMessageOfTheDayHyperlink() const { return MessageOfTheDayHyperlink.getData(); }
187 const char *GetLeagueServerRedirect() const { return LeagueServerRedirect.getLength() ? LeagueServerRedirect.getData() : nullptr; }
188};
189