Skip to content

Commit 516288b

Browse files
committed
Remove ConVar Check + Timeout Checks
- Removed checking for sv_allowupload on the client - Added a 90 second timeout period, where it would retry requesting a file (occurs when a player gets requested a file they don't have after a certain amount of times)
1 parent d1c0d51 commit 516288b

File tree

2 files changed

+151
-59
lines changed

2 files changed

+151
-59
lines changed

scripting/filenetwork.sp

Lines changed: 149 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77

88
#define PLUGIN_VERSION "manual"
99

10+
#define TIMEOUT_PERIOD 90 // How long until we consider a requested file to be timed out
11+
1012
enum struct FileEnum
1113
{
1214
int Client;
@@ -28,12 +30,14 @@ Address EngineAddress;
2830
// Sending
2931
int TransferID;
3032
ArrayList SendListing;
31-
bool InQuery[MAXPLAYERS+1];
3233
Handle SendingTimer[MAXPLAYERS+1];
3334
char CurrentlySending[MAXPLAYERS+1][PLATFORM_MAX_PATH];
3435

3536
// Requesting
3637
ArrayList RequestListing;
38+
Handle RequestingTimer[MAXPLAYERS+1];
39+
int CurrentlyRequesting[MAXPLAYERS+1] = {-1, ...};
40+
int StartedRequestingAt[MAXPLAYERS+1];
3741

3842
methodmap CNetChan
3943
{
@@ -48,7 +52,8 @@ methodmap CNetChan
4852
}
4953
public int RequestFile(const char[] filename)
5054
{
51-
return SDKCall(SDKRequestFile, this, filename);
55+
int id = SDKCall(SDKRequestFile, this, filename);
56+
return id;
5257
}
5358
public bool IsFileInWaitingList(const char[] filename)
5459
{
@@ -268,8 +273,30 @@ public void OnClientDisconnect_Post(int client)
268273

269274
delete SendingTimer[client];
270275
CurrentlySending[client][0] = 0;
276+
277+
delete RequestingTimer[client];
278+
CurrentlyRequesting[client] = -1;
279+
}
280+
281+
public void OnNotifyPluginUnloaded(Handle plugin)
282+
{
283+
int match = -1;
284+
while((match = SendListing.FindValue(plugin, FileEnum::Plugin)) != -1)
285+
{
286+
SendListing.Erase(match);
287+
}
288+
289+
match = -1;
290+
while((match = RequestListing.FindValue(plugin, FileEnum::Plugin)) != -1)
291+
{
292+
RequestListing.Erase(match);
293+
}
271294
}
272295

296+
/*
297+
Requesting Files
298+
*/
299+
273300
public MRESReturn OnFileReceived(Address address, DHookParam param)
274301
{
275302
int id = param.Get(2);
@@ -282,8 +309,15 @@ public MRESReturn OnFileReceived(Address address, DHookParam param)
282309
RequestListing.GetArray(i, info);
283310
if(info.Id == id && chan == CNetChan(info.Client))
284311
{
312+
if(CurrentlyRequesting[info.Client] == id)
313+
CurrentlyRequesting[info.Client] = -1;
314+
285315
RequestListing.Erase(i);
286316
CallRequestFileFinish(info, true);
317+
318+
if(RequestingTimer[info.Client])
319+
TriggerTimer(RequestingTimer[info.Client]);
320+
287321
break;
288322
}
289323
}
@@ -302,14 +336,106 @@ public MRESReturn OnFileDenied(Address address, DHookParam param)
302336
RequestListing.GetArray(i, info);
303337
if(info.Id == id && chan == CNetChan(info.Client))
304338
{
339+
if(CurrentlyRequesting[info.Client] == id)
340+
CurrentlyRequesting[info.Client] = -1;
341+
305342
RequestListing.Erase(i);
306343
CallRequestFileFinish(info, false);
344+
345+
if(RequestingTimer[info.Client])
346+
TriggerTimer(RequestingTimer[info.Client]);
347+
307348
break;
308349
}
309350
}
310351
return MRES_Ignored;
311352
}
312353

354+
void StartRequestingClient(int client)
355+
{
356+
if(!RequestingTimer[client])
357+
{
358+
RequestingTimer[client] = CreateTimer(1.0, Timer_RequestingClient, client, TIMER_REPEAT);
359+
TriggerTimer(RequestingTimer[client]);
360+
}
361+
}
362+
363+
public Action Timer_RequestingClient(Handle timer, int client)
364+
{
365+
CNetChan chan = CNetChan(client);
366+
if(!chan)
367+
return Plugin_Continue;
368+
369+
static FileEnum info;
370+
371+
if(CurrentlyRequesting[client] != -1)
372+
{
373+
// Client still giving this file
374+
if((StartedRequestingAt[client] + TIMEOUT_PERIOD) > GetTime())
375+
return Plugin_Continue;
376+
377+
// We timed out, this can be a case of the client getting stuck.
378+
// Request a different file to unstuck the client then try again.
379+
DeleteFile("download/scripts/cheatcodes.txt");
380+
381+
info.Client = client;
382+
strcopy(info.Filename, sizeof(info.Filename), "scripts/cheatcodes.txt");
383+
info.Func = INVALID_FUNCTION;
384+
info.Id = chan.RequestFile(info.Filename);
385+
RequestListing.PushArray(info);
386+
387+
CurrentlyRequesting[client] = info.Id;
388+
StartedRequestingAt[client] += 10;
389+
return Plugin_Continue;
390+
}
391+
392+
int length = RequestListing.Length;
393+
for(int i; i < length; i++)
394+
{
395+
RequestListing.GetArray(i, info);
396+
if(info.Client == client)
397+
{
398+
info.Id = chan.RequestFile(info.Filename);
399+
RequestListing.SetArray(i, info);
400+
401+
CurrentlyRequesting[client] = info.Id;
402+
StartedRequestingAt[client] = GetTime();
403+
return Plugin_Continue;
404+
}
405+
}
406+
407+
// No more files to send
408+
RequestingTimer[client] = null;
409+
return Plugin_Stop;
410+
}
411+
412+
static void CallRequestFileFinish(const FileEnum info, bool success)
413+
{
414+
if(info.Func && info.Func != INVALID_FUNCTION)
415+
{
416+
Call_StartFunction(info.Plugin, info.Func);
417+
Call_PushCell(info.Client);
418+
Call_PushString(info.Filename);
419+
Call_PushCell(info.Id);
420+
Call_PushCell(success);
421+
Call_PushCell(info.Data);
422+
Call_Finish();
423+
}
424+
}
425+
426+
/*
427+
Sending Files
428+
*/
429+
430+
void StartSendingClient(int client)
431+
{
432+
if(!SendingTimer[client])
433+
{
434+
SendingTimer[client] = CreateTimer(0.1, Timer_SendingClient, client, TIMER_REPEAT);
435+
TriggerTimer(SendingTimer[client]);
436+
}
437+
}
438+
313439
public Action Timer_SendingClient(Handle timer, int client)
314440
{
315441
CNetChan chan = CNetChan(client);
@@ -320,22 +446,26 @@ public Action Timer_SendingClient(Handle timer, int client)
320446
{
321447
// Client still downloading this file
322448
if(chan.IsFileInWaitingList(CurrentlySending[client]))
449+
{
323450
return Plugin_Continue;
324-
325-
// We finished this file
326-
int length = SendListing.Length;
327-
for(int i; i < length; i++)
451+
}
452+
else
328453
{
329-
static FileEnum info;
330-
SendListing.GetArray(i, info);
331-
if(info.Client == client && StrEqual(info.Filename, CurrentlySending[client], false))
454+
// We finished this file
455+
int length = SendListing.Length;
456+
for(int i; i < length; i++)
332457
{
333-
SendListing.Erase(i);
334-
CallSentFileFinish(info, true);
335-
break;
458+
static FileEnum info;
459+
SendListing.GetArray(i, info);
460+
if(info.Client == client && StrEqual(info.Filename, CurrentlySending[client], false))
461+
{
462+
SendListing.Erase(i);
463+
CallSentFileFinish(info, true);
464+
break;
465+
}
336466
}
337467
}
338-
468+
339469
CurrentlySending[client][0] = 0;
340470
}
341471

@@ -379,51 +509,16 @@ static void CallSentFileFinish(const FileEnum info, bool success)
379509
}
380510
}
381511

382-
static void CallRequestFileFinish(const FileEnum info, bool success)
383-
{
384-
if(info.Func && info.Func != INVALID_FUNCTION)
385-
{
386-
Call_StartFunction(info.Plugin, info.Func);
387-
Call_PushCell(info.Client);
388-
Call_PushString(info.Filename);
389-
Call_PushCell(info.Id);
390-
Call_PushCell(success);
391-
Call_PushCell(info.Data);
392-
Call_Finish();
393-
}
394-
}
512+
/*
513+
Natives
514+
*/
395515

396516
void StartNative()
397517
{
398518
if(!SendListing)
399519
ThrowNativeError(SP_ERROR_NATIVE, "Please wait until OnAllPluginsLoaded");
400520
}
401521

402-
void StartSendingClient(int client)
403-
{
404-
// Clients need sv_allowupload in order for this to work, sorry CSGO fans
405-
if(!InQuery[client] && QueryClientConVar(client, "sv_allowupload", QueryCallback) != QUERYCOOKIE_FAILED)
406-
InQuery[client] = true;
407-
}
408-
409-
public void QueryCallback(QueryCookie cookie, int client, ConVarQueryResult result, const char[] cvarName, const char[] cvarValue, any value)
410-
{
411-
if(!SendingTimer[client] && IsClientInGame(client))
412-
{
413-
if(result == ConVarQuery_Okay && StringToInt(cvarValue))
414-
{
415-
SendingTimer[client] = CreateTimer(0.5, Timer_SendingClient, client, TIMER_REPEAT);
416-
Timer_SendingClient(null, client);
417-
}
418-
else
419-
{
420-
PrintToChat(client, "[SM] The server is trying to send you a file, enable sv_allowupload to allow this process");
421-
}
422-
}
423-
424-
InQuery[client] = false;
425-
}
426-
427522
int GetNativeClient(int param)
428523
{
429524
int client = GetNativeCell(param);
@@ -486,13 +581,10 @@ public any Native_RequestFile(Handle plugin, int params)
486581
info.Func = GetNativeFunction(3);
487582
info.Data = GetNativeCell(4);
488583

489-
CNetChan chan = CNetChan(info.Client);
490-
if(!chan)
491-
ThrowError("Native_RequestFile: Client address is invalid");
492-
493-
info.Id = chan.RequestFile(info.Filename);
494584
RequestListing.PushArray(info);
495-
return info.Id;
585+
586+
StartRequestingClient(info.Client);
587+
return CurrentlyRequesting[info.Client];
496588
}
497589

498590
public any Native_IsFileInWaitingList(Handle plugin, int params)

scripting/include/filenetwork.inc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,9 +99,9 @@ native bool FileNet_SendFile(int client, const char[] file, FileNet_SendFileResu
9999
*
100100
* @error Invalid client index, client is not in game, or a fake client
101101
*
102-
* @return Unique request ID given by the engine per session
102+
* @noreturn
103103
*/
104-
native int FileNet_RequestFile(int client, const char[] file, FileNet_RequestFileResult callback = INVALID_FUNCTION, any data = 0);
104+
native void FileNet_RequestFile(int client, const char[] file, FileNet_RequestFileResult callback = INVALID_FUNCTION, any data = 0);
105105

106106
/**
107107
* Gets the CNetChan object of a specific client

0 commit comments

Comments
 (0)