Skip to content

Commit 9883704

Browse files
committed
Add http router functionality
1 parent 00995c5 commit 9883704

31 files changed

+830
-243
lines changed

Client/mods/deathmatch/logic/lua/CLuaArgument.cpp

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -320,11 +320,25 @@ void CLuaArgument::ReadNumber(double dNumber)
320320
m_Number = dNumber;
321321
}
322322

323-
void CLuaArgument::ReadString(const std::string& strString)
323+
void CLuaArgument::ReadString(const std::string& string)
324324
{
325325
m_iType = LUA_TSTRING;
326326
DeleteTableData();
327-
m_strString = strString;
327+
m_strString = string;
328+
}
329+
330+
void CLuaArgument::ReadString(const std::string_view& string)
331+
{
332+
m_iType = LUA_TSTRING;
333+
DeleteTableData();
334+
m_strString = std::string{string};
335+
}
336+
337+
void CLuaArgument::ReadString(const char* string)
338+
{
339+
m_iType = LUA_TSTRING;
340+
DeleteTableData();
341+
m_strString = string;
328342
}
329343

330344
void CLuaArgument::ReadScriptID(uint uiScriptID)
@@ -757,6 +771,11 @@ bool CLuaArgument::WriteToBitStream(NetBitStreamInterface& bitStream, CFastHashM
757771
return true;
758772
}
759773

774+
bool CLuaArgument::IsTable() const noexcept
775+
{
776+
return m_iType == LUA_TTABLE && m_pTableData && (m_pTableData->Count() % 2) == 0;
777+
}
778+
760779
void CLuaArgument::LogUnableToPacketize(const char* szMessage) const
761780
{
762781
#ifdef MTA_DEBUG

Client/mods/deathmatch/logic/lua/CLuaArgument.h

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,9 @@ class CLuaArgument
4040
void Read(lua_State* luaVM, int iArgument, CFastHashMap<const void*, CLuaArguments*>* pKnownTables = NULL);
4141
void ReadBool(bool bBool);
4242
void ReadNumber(double dNumber);
43-
void ReadString(const std::string& strString);
43+
void ReadString(const std::string& string);
44+
void ReadString(const std::string_view& string);
45+
void ReadString(const char* string);
4446
void ReadElement(CClientEntity* pElement);
4547
void ReadScriptID(uint uiScriptID);
4648
void ReadElementID(ElementID ID);
@@ -55,6 +57,7 @@ class CLuaArgument
5557
lua_Number GetNumber() const { return m_Number; };
5658
const SString& GetString() { return m_strString; };
5759
void* GetUserData() const { return m_pUserData; };
60+
CLuaArguments* GetTable() const { return m_pTableData; }
5861
CClientEntity* GetElement() const;
5962

6063
bool ReadFromBitStream(NetBitStreamInterface& bitStream, std::vector<CLuaArguments*>* pKnownTables = NULL);
@@ -63,6 +66,48 @@ class CLuaArgument
6366
bool ReadFromJSONObject(json_object* object, std::vector<CLuaArguments*>* pKnownTables = NULL);
6467
char* WriteToString(char* szBuffer, int length);
6568

69+
[[nodiscard]] bool IsString() const noexcept { return m_iType == LUA_TSTRING; }
70+
71+
[[nodiscard]] bool TryGetString(std::string_view& string) const noexcept
72+
{
73+
if (IsString())
74+
{
75+
string = m_strString;
76+
return true;
77+
}
78+
79+
string = {};
80+
return false;
81+
}
82+
83+
[[nodiscard]] bool IsNumber() const noexcept { return m_iType == LUA_TNUMBER; }
84+
85+
[[nodiscard]] bool TryGetNumber(lua_Number& number) const noexcept
86+
{
87+
if (IsNumber())
88+
{
89+
number = m_Number;
90+
return true;
91+
}
92+
93+
number = {};
94+
return false;
95+
}
96+
97+
[[nodiscard]] bool IsTable() const noexcept;
98+
99+
[[nodiscard]] bool TryGetTable(CLuaArguments*& table)
100+
{
101+
if (IsTable())
102+
{
103+
table = m_pTableData;
104+
return true;
105+
}
106+
107+
table = nullptr;
108+
return false;
109+
}
110+
66111
private:
67112
void LogUnableToPacketize(const char* szMessage) const;
68113

Client/mods/deathmatch/logic/lua/CLuaArguments.cpp

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -337,12 +337,28 @@ CLuaArgument* CLuaArguments::PushNumber(double dNumber)
337337
return pArgument;
338338
}
339339

340-
CLuaArgument* CLuaArguments::PushString(const std::string& strString)
340+
CLuaArgument* CLuaArguments::PushString(const std::string& string)
341341
{
342-
CLuaArgument* pArgument = new CLuaArgument();
343-
pArgument->ReadString(strString);
344-
m_Arguments.push_back(pArgument);
345-
return pArgument;
342+
CLuaArgument* arg = new CLuaArgument();
343+
arg->ReadString(string);
344+
m_Arguments.push_back(arg);
345+
return arg;
346+
}
347+
348+
CLuaArgument* CLuaArguments::PushString(const std::string_view& string)
349+
{
350+
CLuaArgument* arg = new CLuaArgument();
351+
arg->ReadString(string);
352+
m_Arguments.push_back(arg);
353+
return arg;
354+
}
355+
356+
CLuaArgument* CLuaArguments::PushString(const char* string)
357+
{
358+
CLuaArgument* arg = new CLuaArgument();
359+
arg->ReadString(string);
360+
m_Arguments.push_back(arg);
361+
return arg;
346362
}
347363

348364
CLuaArgument* CLuaArguments::PushResource(CResource* pResource)

Client/mods/deathmatch/logic/lua/CLuaArguments.h

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,9 @@ class CLuaArguments
5555
CLuaArgument* PushNil();
5656
CLuaArgument* PushBoolean(bool bBool);
5757
CLuaArgument* PushNumber(double dNumber);
58-
CLuaArgument* PushString(const std::string& strString);
58+
CLuaArgument* PushString(const std::string& string);
59+
CLuaArgument* PushString(const std::string_view& string);
60+
CLuaArgument* PushString(const char* string);
5961
CLuaArgument* PushElement(CClientEntity* pElement);
6062
CLuaArgument* PushArgument(const CLuaArgument& argument);
6163
CLuaArgument* PushResource(CResource* pResource);
@@ -74,9 +76,13 @@ class CLuaArguments
7476
bool ReadFromJSONObject(json_object* object, std::vector<CLuaArguments*>* pKnownTables = NULL);
7577
bool ReadFromJSONArray(json_object* object, std::vector<CLuaArguments*>* pKnownTables = NULL);
7678

77-
unsigned int Count() const { return static_cast<unsigned int>(m_Arguments.size()); };
78-
std::vector<CLuaArgument*>::const_iterator IterBegin() const { return m_Arguments.begin(); };
79-
std::vector<CLuaArgument*>::const_iterator IterEnd() const { return m_Arguments.end(); };
79+
[[nodiscard]] bool IsNotEmpty() const noexcept { return !m_Arguments.empty(); }
80+
[[nodiscard]] bool IsEmpty() const noexcept { return m_Arguments.empty(); }
81+
82+
[[nodiscard]] std::vector<CLuaArgument*>::size_type Count() const noexcept { return m_Arguments.size(); }
83+
84+
[[nodiscard]] std::vector<CLuaArgument*>::const_iterator begin() const noexcept { return m_Arguments.begin(); }
85+
[[nodiscard]] std::vector<CLuaArgument*>::const_iterator end() const noexcept { return m_Arguments.end(); }
8086

8187
private:
8288
std::vector<CLuaArgument*> m_Arguments;

Server/mods/deathmatch/logic/CHTTPD.cpp

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,8 @@ extern CGame* g_pGame;
2828

2929
CHTTPD::CHTTPD()
3030
: m_BruteForceProtect(4, 30000, 60000 * 5) // Max of 4 attempts per 30 seconds, then 5 minute ignore
31-
,
32-
m_HttpDosProtect(0, 0, 0)
31+
, m_HttpDosProtect(0, 0, 0)
3332
{
34-
m_resource = NULL;
35-
m_server = NULL;
36-
m_bStartedServer = false;
37-
3833
m_pGuestAccount = g_pGame->GetAccountManager()->AddGuestAccount(HTTP_GUEST_ACCOUNT_NAME);
3934

4035
m_HttpDosProtect = CConnectHistory(g_pGame->GetConfig()->GetHTTPDosThreshold(), 10000,
@@ -106,7 +101,7 @@ HttpResponse* CHTTPD::RouteRequest(HttpRequest* ipoHttpRequest)
106101
HttpResponse* poHttpResponse = new HttpResponse(ipoHttpRequest->m_nRequestId, ipoHttpRequest->m_poSourceEHSConnection);
107102
SStringX strWait("The server is not ready. Please try again in a minute.");
108103
poHttpResponse->SetBody(strWait.c_str(), strWait.size());
109-
poHttpResponse->m_nResponseCode = HTTPRESPONSECODE_200_OK;
104+
poHttpResponse->m_nResponseCode = HTTP_STATUS_CODE_200_OK;
110105
return poHttpResponse;
111106
}
112107

@@ -121,7 +116,7 @@ HttpResponse* CHTTPD::RouteRequest(HttpRequest* ipoHttpRequest)
121116
// Called from worker thread. g_pGame->Lock() has already been called.
122117
// creates a page based on user input -- either displays data from
123118
// form or presents a form for users to submit data.
124-
ResponseCode CHTTPD::HandleRequest(HttpRequest* ipoHttpRequest, HttpResponse* ipoHttpResponse)
119+
HttpStatusCode CHTTPD::HandleRequest(HttpRequest* ipoHttpRequest, HttpResponse* ipoHttpResponse)
125120
{
126121
// Check if server verification was requested
127122
auto challenge = ipoHttpRequest->oRequestHeaders["crypto_challenge"];
@@ -150,7 +145,7 @@ ResponseCode CHTTPD::HandleRequest(HttpRequest* ipoHttpRequest, HttpResponse* ip
150145
if (!cipherText.empty())
151146
{
152147
ipoHttpResponse->SetBody((const char*)cipherText.BytePtr(), cipherText.SizeInBytes());
153-
return HTTPRESPONSECODE_200_OK;
148+
return HTTP_STATUS_CODE_200_OK;
154149
}
155150
else
156151
CLogger::LogPrintf(LOGLEVEL_MEDIUM, "ERROR: Empty crypto challenge was passed during verification\n");
@@ -161,7 +156,7 @@ ResponseCode CHTTPD::HandleRequest(HttpRequest* ipoHttpRequest, HttpResponse* ip
161156
}
162157

163158
ipoHttpResponse->SetBody("", 0);
164-
return HTTPRESPONSECODE_401_UNAUTHORIZED;
159+
return HTTP_STATUS_CODE_401_UNAUTHORIZED;
165160
}
166161

167162
CAccount* account = CheckAuthentication(ipoHttpRequest);
@@ -174,7 +169,7 @@ ResponseCode CHTTPD::HandleRequest(HttpRequest* ipoHttpRequest, HttpResponse* ip
174169
ipoHttpResponse->SetBody(strWelcome.c_str(), strWelcome.size());
175170
SString strNewURL("http://%s/%s/", ipoHttpRequest->oRequestHeaders["host"].c_str(), m_strDefaultResourceName.c_str());
176171
ipoHttpResponse->oResponseHeaders["location"] = strNewURL.c_str();
177-
return HTTPRESPONSECODE_302_FOUND;
172+
return HTTP_STATUS_CODE_302_FOUND;
178173
}
179174
}
180175

@@ -183,10 +178,10 @@ ResponseCode CHTTPD::HandleRequest(HttpRequest* ipoHttpRequest, HttpResponse* ip
183178
"resource.<br/><br/>Alternatively, the server may be still starting up, if so, please try again in a minute.",
184179
ipoHttpRequest->oRequestHeaders["host"].c_str());
185180
ipoHttpResponse->SetBody(strWelcome.c_str(), strWelcome.size());
186-
return HTTPRESPONSECODE_200_OK;
181+
return HTTP_STATUS_CODE_200_OK;
187182
}
188183

189-
ResponseCode CHTTPD::RequestLogin(HttpRequest* ipoHttpRequest, HttpResponse* ipoHttpResponse)
184+
HttpStatusCode CHTTPD::RequestLogin(HttpRequest* ipoHttpRequest, HttpResponse* ipoHttpResponse)
190185
{
191186
if (m_WarnMessageTimer.Get() < 4000 && m_strWarnMessageForIp == ipoHttpRequest->GetAddress())
192187
{
@@ -196,14 +191,14 @@ ResponseCode CHTTPD::RequestLogin(HttpRequest* ipoHttpRequest, HttpResponse* ipo
196191
"https:"
197192
"//mtasa.com/authserialhttp");
198193
ipoHttpResponse->SetBody(strMessage, strMessage.length());
199-
return HTTPRESPONSECODE_401_UNAUTHORIZED;
194+
return HTTP_STATUS_CODE_401_UNAUTHORIZED;
200195
}
201196

202197
const char* szAuthenticateMessage = "Access denied, please login";
203198
ipoHttpResponse->SetBody(szAuthenticateMessage, strlen(szAuthenticateMessage));
204199
SString strName("Basic realm=\"%s\"", g_pGame->GetConfig()->GetServerName().c_str());
205200
ipoHttpResponse->oResponseHeaders["WWW-Authenticate"] = strName.c_str();
206-
return HTTPRESPONSECODE_401_UNAUTHORIZED;
201+
return HTTP_STATUS_CODE_401_UNAUTHORIZED;
207202
}
208203

209204
CAccount* CHTTPD::CheckAuthentication(HttpRequest* ipoHttpRequest)

Server/mods/deathmatch/logic/CHTTPD.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,10 @@ class CHTTPD : public EHS
2626
CHTTPD(); // start the initial server
2727
~CHTTPD();
2828
// EHS interface
29-
HttpResponse* RouteRequest(HttpRequest* ipoHttpRequest);
30-
ResponseCode HandleRequest(HttpRequest* ipoHttpRequest, HttpResponse* ipoHttpResponse);
31-
void HttpPulse();
32-
bool ShouldAllowConnection(const char* szAddress);
29+
HttpResponse* RouteRequest(HttpRequest* ipoHttpRequest);
30+
HttpStatusCode HandleRequest(HttpRequest* ipoHttpRequest, HttpResponse* ipoHttpResponse);
31+
void HttpPulse();
32+
bool ShouldAllowConnection(const char* szAddress);
3333

3434
// CHTTPD methods
3535
bool StartHTTPD(const char* szIP, unsigned int port);
@@ -38,16 +38,16 @@ class CHTTPD : public EHS
3838
CResource* GetResource() { return m_resource; }
3939
class CAccount* CheckAuthentication(HttpRequest* ipoHttpRequest);
4040
void SetDefaultResource(const char* szResourceName) { m_strDefaultResourceName = szResourceName ? szResourceName : ""; }
41-
ResponseCode RequestLogin(HttpRequest* ipoHttpRequest, HttpResponse* ipoHttpResponse);
41+
HttpStatusCode RequestLogin(HttpRequest* ipoHttpRequest, HttpResponse* ipoHttpResponse);
4242

4343
private:
44-
CResource* m_resource;
45-
CHTTPD* m_server;
44+
CResource* m_resource{};
45+
CHTTPD* m_server{};
4646
std::string m_strDefaultResourceName; // default resource name
4747

4848
EHSServerParameters m_Parameters;
4949

50-
bool m_bStartedServer;
50+
bool m_bStartedServer{};
5151

5252
class CAccount* m_pGuestAccount;
5353
std::map<string, long long> m_LoggedInMap;

Server/mods/deathmatch/logic/CMainConfig.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1103,15 +1103,15 @@ bool CMainConfig::GetSettingTable(const SString& strName, const char** szAttribN
11031103
resultLine.PushString(pAttribute->GetValue());
11041104
}
11051105

1106-
if (resultLine.Count() != 0)
1106+
if (resultLine.IsNotEmpty())
11071107
{
11081108
outTable->PushNumber(uiLuaIndex++);
11091109
outTable->PushTable(&resultLine);
11101110
}
11111111
}
11121112
} while (pNode);
11131113

1114-
return outTable->Count() != 0;
1114+
return outTable->IsNotEmpty();
11151115
}
11161116

11171117
//////////////////////////////////////////////////////////////////////

Server/mods/deathmatch/logic/CRemoteCalls.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -275,8 +275,10 @@ void CRemoteCall::DownloadFinishedCallback(const SHttpDownloadResult& result)
275275

276276
// Append stored arguments
277277
if (pCall->IsFetch())
278-
for (uint i = 0; i < pCall->GetFetchArguments().Count(); i++)
279-
arguments.PushArgument(*(pCall->GetFetchArguments()[i]));
278+
{
279+
for (CLuaArgument* argument : pCall->GetFetchArguments())
280+
arguments.PushArgument(*argument);
281+
}
280282

281283
if (pCall->m_VM)
282284
arguments.Call(pCall->m_VM, pCall->m_iFunction);

0 commit comments

Comments
 (0)