Skip to content

Commit 97ab9f7

Browse files
committed
Add async overloads to passwordHash and passwordVerify
Async is the recommended way to call both functions
1 parent 04d117c commit 97ab9f7

File tree

3 files changed

+91
-9
lines changed

3 files changed

+91
-9
lines changed

Shared/mods/deathmatch/logic/lua/CLuaShared.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,3 +81,13 @@ void CLuaShared::AddClasses(lua_State* luaVM)
8181
CLuaFileDefs::AddClass ( luaVM );
8282
CLuaXMLDefs::AddClass ( luaVM );
8383
}
84+
85+
86+
SharedUtil::CAsyncTaskScheduler* CLuaShared::GetAsyncTaskScheduler()
87+
{
88+
#ifdef MTA_CLIENT
89+
return g_pClientGame->GetAsyncTaskScheduler();
90+
#else
91+
return g_pGame->GetAsyncTaskScheduler();
92+
#endif
93+
}

Shared/mods/deathmatch/logic/lua/CLuaShared.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,8 @@ class CLuaShared
2828
static bool CheckUTF8BOMAndUpdate ( const char** pcpOutBuffer, uint* puiOutSize );
2929
static void LoadFunctions ( void );
3030
static void AddClasses ( lua_State* luaVM );
31+
32+
// Shared scripting is the only place where we need the async task scheduler
33+
// so just go with a hack here
34+
static SharedUtil::CAsyncTaskScheduler* GetAsyncTaskScheduler();
3135
};

Shared/mods/deathmatch/logic/luadefs/CLuaCryptDefs.cpp

Lines changed: 77 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -178,16 +178,23 @@ int CLuaCryptDefs::Base64decode ( lua_State* luaVM )
178178

179179
int CLuaCryptDefs::PasswordHash(lua_State* luaVM)
180180
{
181-
// string password_hash(string password, string algorithm, table options = {})
181+
// string password_hash(string password, string algorithm, table options = {} [, function callback])
182182
SString password;
183183
PasswordHashFunction algorithm;
184184
std::unordered_map<SString, SString> options;
185+
CLuaFunctionRef luaFunctionRef;
185186

186187
CScriptArgReader argStream(luaVM);
187188
argStream.ReadString(password);
188189
argStream.ReadEnumString(algorithm);
189190
argStream.ReadStringMap(options, true);
190191

192+
if (argStream.NextIsFunction())
193+
{
194+
argStream.ReadFunction(luaFunctionRef);
195+
argStream.ReadFunctionComplete();
196+
}
197+
191198
if (!argStream.HasErrors())
192199
{
193200
if (algorithm == PasswordHashFunction::Bcrypt)
@@ -202,14 +209,45 @@ int CLuaCryptDefs::PasswordHash(lua_State* luaVM)
202209

203210
if (!ss.fail())
204211
{
205-
SString hash = SharedUtil::BcryptHash(password, options["salt"], cost);
206-
if (!hash.empty())
212+
// Sync
213+
if (luaFunctionRef == CLuaFunctionRef{})
214+
{
215+
SString hash = SharedUtil::BcryptHash(password, options["salt"], cost);
216+
if (!hash.empty())
217+
{
218+
lua_pushstring(luaVM, hash);
219+
return 1;
220+
}
221+
else
222+
m_pScriptDebugging->LogCustom(luaVM, "Invalid value for field 'salt'");
223+
}
224+
else // Async
207225
{
208-
lua_pushstring(luaVM, hash);
209-
return 1;
226+
CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM);
227+
if (pLuaMain)
228+
{
229+
CLuaShared::GetAsyncTaskScheduler()->PushTask<SString>([password, salt = options["salt"], cost] {
230+
// Execute time-consuming task
231+
return SharedUtil::BcryptHash(password, salt, cost);
232+
233+
}, [luaFunctionRef, pLuaMain](const SString& hash) {
234+
CLuaArguments arguments;
235+
236+
if (hash.empty())
237+
{
238+
m_pScriptDebugging->LogCustom(pLuaMain->GetVM(), "Invalid value for field 'salt'");
239+
arguments.PushBoolean(false);
240+
}
241+
else
242+
arguments.PushString(hash);
243+
244+
arguments.Call(pLuaMain, luaFunctionRef);
245+
});
246+
247+
lua_pushboolean(luaVM, true);
248+
return 1;
249+
}
210250
}
211-
else
212-
m_pScriptDebugging->LogCustom(luaVM, "Invalid value for field 'salt'");
213251
}
214252
else
215253
m_pScriptDebugging->LogWarning(luaVM, "Invalid value for field 'cost'");
@@ -224,19 +262,49 @@ int CLuaCryptDefs::PasswordHash(lua_State* luaVM)
224262

225263
int CLuaCryptDefs::PasswordVerify(lua_State* luaVM)
226264
{
227-
// bool passwordVerify(string password, string hash)
265+
// bool passwordVerify(string password, string hash [, function callback])
228266
SString password;
229267
SString hash;
268+
CLuaFunctionRef luaFunctionRef;
230269

231270
CScriptArgReader argStream(luaVM);
232271
argStream.ReadString(password);
233272
argStream.ReadString(hash);
234273

274+
if (argStream.NextIsFunction())
275+
{
276+
argStream.ReadFunction(luaFunctionRef);
277+
argStream.ReadFunctionComplete();
278+
}
279+
235280
if (!argStream.HasErrors())
236281
{
237282
if (hash.BeginsWith("$2y$"))
238283
{
239-
lua_pushboolean(luaVM, SharedUtil::BcryptVerify(password, hash));
284+
// Sync
285+
if (luaFunctionRef == CLuaFunctionRef())
286+
{
287+
lua_pushboolean(luaVM, SharedUtil::BcryptVerify(password, hash));
288+
}
289+
else // Async
290+
{
291+
CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM);
292+
if (pLuaMain)
293+
{
294+
CLuaShared::GetAsyncTaskScheduler()->PushTask<bool>([password, hash]{
295+
// Execute time-consuming task
296+
return SharedUtil::BcryptVerify(password, hash);
297+
298+
}, [luaFunctionRef, pLuaMain](const bool& correct) {
299+
CLuaArguments arguments;
300+
arguments.PushBoolean(correct);
301+
302+
arguments.Call(pLuaMain, luaFunctionRef);
303+
});
304+
305+
lua_pushboolean(luaVM, true);
306+
}
307+
}
240308
return 1;
241309
}
242310
else

0 commit comments

Comments
 (0)