mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-11-28 23:21:58 +00:00
[Engine] Dynamically allocate wadfiles, raise limit to 2048
[Netcode port] SRB2Kart server addon list code 1425ed936cd38c5ac4887b35a6551c46c6248f1b
This commit is contained in:
parent
bcd3245b76
commit
0391b6b9f7
13 changed files with 660 additions and 292 deletions
531
src/d_clisrv.c
531
src/d_clisrv.c
|
@ -127,10 +127,14 @@ static UINT8 localtextcmd[MAXTEXTCMD];
|
|||
static UINT8 localtextcmd2[MAXTEXTCMD]; // splitscreen
|
||||
static tic_t neededtic;
|
||||
SINT8 servernode = 0; // the number of the server node
|
||||
|
||||
/// \brief do we accept new players?
|
||||
/// \todo WORK!
|
||||
boolean acceptnewnode = true;
|
||||
|
||||
static boolean serverisfull = false; //lets us be aware if the server was full after we check files, but before downloading, so we can ask if the user still wants to download or not
|
||||
static tic_t firstconnectattempttime = 0;
|
||||
|
||||
// engine
|
||||
|
||||
// Must be a power of two
|
||||
|
@ -510,18 +514,24 @@ static INT16 Consistancy(void);
|
|||
typedef enum
|
||||
{
|
||||
CL_SEARCHING,
|
||||
CL_CHECKFILES,
|
||||
CL_DOWNLOADFILES,
|
||||
CL_ASKJOIN,
|
||||
CL_LOADFILES,
|
||||
CL_WAITJOINRESPONSE,
|
||||
CL_DOWNLOADSAVEGAME,
|
||||
CL_CONNECTED,
|
||||
CL_ABORTED
|
||||
CL_ABORTED,
|
||||
CL_ASKFULLFILELIST,
|
||||
CL_CONFIRMCONNECT
|
||||
} cl_mode_t;
|
||||
|
||||
static void GetPackets(void);
|
||||
|
||||
static cl_mode_t cl_mode = CL_SEARCHING;
|
||||
|
||||
static UINT16 cl_lastcheckedfilecount = 0; // used for full file list
|
||||
|
||||
#ifndef NONET
|
||||
#define SNAKE_SPEED 5
|
||||
|
||||
|
@ -919,6 +929,8 @@ static void Snake_Draw(void)
|
|||
INT16 i;
|
||||
|
||||
// Background
|
||||
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
|
||||
|
||||
V_DrawFlatFill(
|
||||
SNAKE_LEFT_X + SNAKE_BORDER_SIZE,
|
||||
SNAKE_TOP_Y + SNAKE_BORDER_SIZE,
|
||||
|
@ -1020,6 +1032,13 @@ static void Snake_Draw(void)
|
|||
);
|
||||
}
|
||||
|
||||
static void CL_DrawConnectionStatusBox(void)
|
||||
{
|
||||
M_DrawTextBox(BASEVIDWIDTH/2-128-8, BASEVIDHEIGHT-16-8, 32, 1);
|
||||
if (cl_mode != CL_CONFIRMCONNECT)
|
||||
V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-16-16, V_YELLOWMAP, "Press ESC to abort");
|
||||
}
|
||||
|
||||
//
|
||||
// CL_DrawConnectionStatus
|
||||
//
|
||||
|
@ -1030,28 +1049,32 @@ static inline void CL_DrawConnectionStatus(void)
|
|||
INT32 ccstime = I_GetTime();
|
||||
|
||||
// Draw background fade
|
||||
if (!menuactive) // menu already draws its own fade
|
||||
V_DrawFadeScreen(0xFF00, 16); // force default
|
||||
V_DrawFadeScreen(0xFF00, 16); // force default
|
||||
|
||||
// Draw the bottom box.
|
||||
M_DrawTextBox(BASEVIDWIDTH/2-128-8, BASEVIDHEIGHT-16-8, 32, 1);
|
||||
V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-16-16, V_YELLOWMAP, "Press ESC to abort");
|
||||
|
||||
if (cl_mode != CL_DOWNLOADFILES)
|
||||
if (cl_mode != CL_DOWNLOADFILES && cl_mode != CL_LOADFILES)
|
||||
{
|
||||
INT32 i, animtime = ((ccstime / 4) & 15) + 16;
|
||||
UINT8 palstart = (cl_mode == CL_SEARCHING) ? 32 : 96;
|
||||
// 15 pal entries total.
|
||||
UINT8 palstart;
|
||||
const char *cltext;
|
||||
|
||||
// Draw the bottom box.
|
||||
CL_DrawConnectionStatusBox();
|
||||
|
||||
if (cl_mode == CL_SEARCHING)
|
||||
palstart = 32; // Red
|
||||
else if (cl_mode == CL_CONFIRMCONNECT)
|
||||
palstart = 48; // Orange
|
||||
else
|
||||
palstart = 96; // Green
|
||||
|
||||
if (!(cl_mode == CL_DOWNLOADSAVEGAME && lastfilenum != -1))
|
||||
for (i = 0; i < 16; ++i)
|
||||
for (i = 0; i < 16; ++i) // 15 pal entries total.
|
||||
V_DrawFill((BASEVIDWIDTH/2-128) + (i * 16), BASEVIDHEIGHT-16, 16, 8, palstart + ((animtime - i) & 15));
|
||||
|
||||
switch (cl_mode)
|
||||
{
|
||||
case CL_DOWNLOADSAVEGAME:
|
||||
if (lastfilenum != -1)
|
||||
if (fileneeded && lastfilenum != -1)
|
||||
{
|
||||
UINT32 currentsize = fileneeded[lastfilenum].currentsize;
|
||||
UINT32 totalsize = fileneeded[lastfilenum].totalsize;
|
||||
|
@ -1075,9 +1098,22 @@ static inline void CL_DrawConnectionStatus(void)
|
|||
else
|
||||
cltext = M_GetText("Waiting to download game state...");
|
||||
break;
|
||||
case CL_ASKFULLFILELIST:
|
||||
case CL_CHECKFILES:
|
||||
cltext = M_GetText("Checking server addon list ...");
|
||||
break;
|
||||
case CL_CONFIRMCONNECT:
|
||||
cltext = "";
|
||||
break;
|
||||
case CL_LOADFILES:
|
||||
cltext = M_GetText("Loading server addons...");
|
||||
break;
|
||||
case CL_ASKJOIN:
|
||||
case CL_WAITJOINRESPONSE:
|
||||
cltext = M_GetText("Requesting to join...");
|
||||
if (serverisfull)
|
||||
cltext = M_GetText("Server full, waiting for a slot...");
|
||||
else
|
||||
cltext = M_GetText("Requesting to join...");
|
||||
break;
|
||||
default:
|
||||
cltext = M_GetText("Connecting to server...");
|
||||
|
@ -1087,14 +1123,51 @@ static inline void CL_DrawConnectionStatus(void)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (lastfilenum != -1)
|
||||
if (cl_mode == CL_LOADFILES)
|
||||
{
|
||||
INT32 totalfileslength;
|
||||
INT32 loadcompletednum = 0;
|
||||
INT32 i;
|
||||
|
||||
V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-16-16, V_YELLOWMAP, "Press ESC to abort");
|
||||
|
||||
//ima just count files here
|
||||
if (fileneeded)
|
||||
{
|
||||
for (i = 0; i < fileneedednum; i++)
|
||||
if (fileneeded[i].status == FS_OPEN)
|
||||
loadcompletednum++;
|
||||
}
|
||||
|
||||
// Loading progress
|
||||
V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-16-24, V_YELLOWMAP, "Loading server addons...");
|
||||
totalfileslength = (INT32)((loadcompletednum/(double)(fileneedednum)) * 256);
|
||||
M_DrawTextBox(BASEVIDWIDTH/2-128-8, BASEVIDHEIGHT-16-8, 32, 1);
|
||||
V_DrawFill(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-16, 256, 8, 111);
|
||||
V_DrawFill(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-16, totalfileslength, 8, 96);
|
||||
V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-16, V_20TRANS|V_MONOSPACE,
|
||||
va(" %2u/%2u Files",loadcompletednum,fileneedednum));
|
||||
}
|
||||
else if (lastfilenum != -1)
|
||||
{
|
||||
INT32 dldlength;
|
||||
static char tempname[28];
|
||||
fileneeded_t *file = &fileneeded[lastfilenum];
|
||||
char *filename = file->filename;
|
||||
fileneeded_t *file;
|
||||
char *filename;
|
||||
|
||||
Snake_Draw();
|
||||
if (snake)
|
||||
Snake_Draw();
|
||||
|
||||
// Draw the bottom box.
|
||||
CL_DrawConnectionStatusBox();
|
||||
|
||||
if (fileneeded)
|
||||
{
|
||||
file = &fileneeded[lastfilenum];
|
||||
filename = file->filename;
|
||||
}
|
||||
else
|
||||
return;
|
||||
|
||||
Net_GetNetStat();
|
||||
dldlength = (INT32)((file->currentsize/(double)file->totalsize) * 256);
|
||||
|
@ -1127,20 +1200,32 @@ static inline void CL_DrawConnectionStatus(void)
|
|||
va("%3.1fK/s ", ((double)getbps)/1024));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (snake)
|
||||
Snake_Draw();
|
||||
|
||||
CL_DrawConnectionStatusBox();
|
||||
V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-16-24, V_YELLOWMAP,
|
||||
M_GetText("Waiting to download files..."));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static boolean CL_AskFileList(INT32 firstfile)
|
||||
{
|
||||
netbuffer->packettype = PT_TELLFILESNEEDED;
|
||||
netbuffer->u.filesneedednum = firstfile;
|
||||
|
||||
return HSendPacket(servernode, false, 0, sizeof (INT32));
|
||||
}
|
||||
|
||||
/** Sends a special packet to declare how many players in local
|
||||
* Used only in arbitratrenetstart()
|
||||
* Sends a PT_CLIENTJOIN packet to the server
|
||||
*
|
||||
* \return True if the packet was successfully sent
|
||||
* \todo Improve the description...
|
||||
* Because to be honest, I have no idea what arbitratrenetstart is...
|
||||
* Is it even used...?
|
||||
*
|
||||
*/
|
||||
static boolean CL_SendJoin(void)
|
||||
|
@ -1232,7 +1317,7 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime)
|
|||
sizeof netbuffer->u.serverinfo.gametypename);
|
||||
netbuffer->u.serverinfo.modifiedgame = (UINT8)modifiedgame;
|
||||
netbuffer->u.serverinfo.cheatsenabled = CV_CheatsEnabled();
|
||||
netbuffer->u.serverinfo.isdedicated = (UINT8)dedicated;
|
||||
netbuffer->u.serverinfo.flags = (dedicated ? SV_DEDICATED : 0);
|
||||
strncpy(netbuffer->u.serverinfo.servername, cv_servername.string,
|
||||
MAXSERVERNAME);
|
||||
strncpy(netbuffer->u.serverinfo.mapname, G_BuildMapName(gamemap), 7);
|
||||
|
@ -1267,7 +1352,7 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime)
|
|||
if (mapheaderinfo[gamemap-1])
|
||||
netbuffer->u.serverinfo.actnum = mapheaderinfo[gamemap-1]->actnum;
|
||||
|
||||
p = PutFileNeeded();
|
||||
p = PutFileNeeded(0);
|
||||
|
||||
HSendPacket(node, false, 0, p - ((UINT8 *)&netbuffer->u));
|
||||
}
|
||||
|
@ -1521,6 +1606,8 @@ static void CL_LoadReceivedSavegame(boolean reloading)
|
|||
size_t length, decompressedlen;
|
||||
char tmpsave[256];
|
||||
|
||||
FreeFileNeeded();
|
||||
|
||||
sprintf(tmpsave, "%s" PATHSEP TMPSAVENAME, srb2home);
|
||||
|
||||
length = FIL_ReadFile(tmpsave, &savebuffer);
|
||||
|
@ -1838,6 +1925,162 @@ void CL_UpdateServerList(boolean internetsearch, INT32 room)
|
|||
|
||||
#endif // ifndef NONET
|
||||
|
||||
static void M_ConfirmConnect(event_t *ev)
|
||||
{
|
||||
#ifndef NONET
|
||||
if (ev->type == ev_keydown)
|
||||
{
|
||||
if (ev->data1 == ' ' || ev->data1 == 'y' || ev->data1 == KEY_ENTER)
|
||||
{
|
||||
if (totalfilesrequestednum > 0)
|
||||
{
|
||||
if (CL_SendFileRequest())
|
||||
{
|
||||
cl_mode = CL_DOWNLOADFILES;
|
||||
Snake_Initialise();
|
||||
}
|
||||
}
|
||||
else
|
||||
cl_mode = CL_LOADFILES;
|
||||
|
||||
M_ClearMenus(true);
|
||||
}
|
||||
else if (ev->data1 == 'n' || ev->data1 == KEY_ESCAPE)
|
||||
{
|
||||
cl_mode = CL_ABORTED;
|
||||
M_ClearMenus(true);
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void)ev;
|
||||
#endif
|
||||
}
|
||||
|
||||
static boolean CL_FinishedFileList(void)
|
||||
{
|
||||
INT32 i;
|
||||
char *downloadsize = NULL;
|
||||
//CONS_Printf(M_GetText("Checking files...\n"));
|
||||
i = CL_CheckFiles();
|
||||
if (i == 4) // still checking ...
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (i == 3) // too many files
|
||||
{
|
||||
D_QuitNetGame();
|
||||
CL_Reset();
|
||||
D_StartTitle();
|
||||
M_StartMessage(M_GetText(
|
||||
"You have too many WAD files loaded\n"
|
||||
"to add ones the server is using.\n"
|
||||
"Please restart SRB2 before connecting.\n\n"
|
||||
"Press ESC\n"
|
||||
), NULL, MM_NOTHING);
|
||||
return false;
|
||||
}
|
||||
else if (i == 2) // cannot join for some reason
|
||||
{
|
||||
D_QuitNetGame();
|
||||
CL_Reset();
|
||||
D_StartTitle();
|
||||
M_StartMessage(M_GetText(
|
||||
"You have the wrong addons loaded.\n\n"
|
||||
"To play on this server, restart\n"
|
||||
"the game and don't load any addons.\n"
|
||||
"SRB2 will automatically add\n"
|
||||
"everything you need when you join.\n\n"
|
||||
"Press ESC\n"
|
||||
), NULL, MM_NOTHING);
|
||||
return false;
|
||||
}
|
||||
else if (i == 1)
|
||||
{
|
||||
if (serverisfull)
|
||||
{
|
||||
M_StartMessage(M_GetText(
|
||||
"This server is full!\n"
|
||||
"\n"
|
||||
"You may load server addons (if any), and wait for a slot.\n"
|
||||
"\n"
|
||||
"Press ENTER to continue\nor ESC to cancel.\n\n"
|
||||
), M_ConfirmConnect, MM_EVENTHANDLER);
|
||||
cl_mode = CL_CONFIRMCONNECT;
|
||||
curfadevalue = 0;
|
||||
}
|
||||
else
|
||||
cl_mode = CL_LOADFILES;
|
||||
}
|
||||
else
|
||||
{
|
||||
// must download something
|
||||
// can we, though?
|
||||
if (!CL_CheckDownloadable()) // nope!
|
||||
{
|
||||
D_QuitNetGame();
|
||||
CL_Reset();
|
||||
D_StartTitle();
|
||||
M_StartMessage(M_GetText(
|
||||
"An error occured when trying to\n"
|
||||
"download missing addons.\n"
|
||||
"(This is almost always a problem\n"
|
||||
"with the server, not your game.)\n\n"
|
||||
"See the console or log file\n"
|
||||
"for additional details.\n\n"
|
||||
"Press ESC\n"
|
||||
), NULL, MM_NOTHING);
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifndef NONET
|
||||
downloadcompletednum = 0;
|
||||
downloadcompletedsize = 0;
|
||||
totalfilesrequestednum = 0;
|
||||
totalfilesrequestedsize = 0;
|
||||
|
||||
if (fileneeded == NULL)
|
||||
I_Error("CL_FinishedFileList: fileneeded == NULL");
|
||||
#endif
|
||||
|
||||
for (i = 0; i < fileneedednum; i++)
|
||||
if (fileneeded[i].status == FS_NOTFOUND || fileneeded[i].status == FS_MD5SUMBAD)
|
||||
{
|
||||
#ifndef NONET
|
||||
totalfilesrequestednum++;
|
||||
totalfilesrequestedsize += fileneeded[i].totalsize;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef NONET
|
||||
if (totalfilesrequestedsize>>20 >= 100)
|
||||
downloadsize = Z_StrDup(va("%uM",totalfilesrequestedsize>>20));
|
||||
else
|
||||
downloadsize = Z_StrDup(va("%uK",totalfilesrequestedsize>>10));
|
||||
#endif
|
||||
|
||||
if (serverisfull)
|
||||
M_StartMessage(va(M_GetText(
|
||||
"This server is full!\n"
|
||||
"Download of %s additional content\nis required to join.\n"
|
||||
"\n"
|
||||
"You may download, load server addons,\nand wait for a slot.\n"
|
||||
"\n"
|
||||
"Press ENTER to continue\nor ESC to cancel.\n"
|
||||
), downloadsize), M_ConfirmConnect, MM_EVENTHANDLER);
|
||||
else
|
||||
M_StartMessage(va(M_GetText(
|
||||
"Download of %s additional content\nis required to join.\n"
|
||||
"\n"
|
||||
"Press ENTER to continue\nor ESC to cancel.\n"
|
||||
), downloadsize), M_ConfirmConnect, MM_EVENTHANDLER);
|
||||
|
||||
Z_Free(downloadsize);
|
||||
cl_mode = CL_CONFIRMCONNECT;
|
||||
curfadevalue = 0;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Called by CL_ServerConnectionTicker
|
||||
*
|
||||
* \param asksent The last time we asked the server to join. We re-ask every second in case our request got lost in transmit.
|
||||
|
@ -1869,15 +2112,15 @@ static boolean CL_ServerConnectionSearchTicker(tic_t *asksent)
|
|||
}
|
||||
|
||||
// Quit here rather than downloading files and being refused later.
|
||||
if (serverlist[i].info.refusereason)
|
||||
if (serverlist[i].info.refusereason == 2)
|
||||
serverisfull = true;
|
||||
else if (serverlist[i].info.refusereason)
|
||||
{
|
||||
D_QuitNetGame();
|
||||
CL_Reset();
|
||||
D_StartTitle();
|
||||
if (serverlist[i].info.refusereason == 1)
|
||||
M_StartMessage(M_GetText("The server is not accepting\njoins for the moment.\n\nPress ESC\n"), NULL, MM_NOTHING);
|
||||
else if (serverlist[i].info.refusereason == 2)
|
||||
M_StartMessage(va(M_GetText("Maximum players reached: %d\n\nPress ESC\n"), serverlist[i].info.maxplayer), NULL, MM_NOTHING);
|
||||
else
|
||||
M_StartMessage(M_GetText("You can't join.\nI don't know why,\nbut you can't join.\n\nPress ESC\n"), NULL, MM_NOTHING);
|
||||
return false;
|
||||
|
@ -1885,71 +2128,22 @@ static boolean CL_ServerConnectionSearchTicker(tic_t *asksent)
|
|||
|
||||
if (client)
|
||||
{
|
||||
D_ParseFileneeded(serverlist[i].info.fileneedednum,
|
||||
serverlist[i].info.fileneeded);
|
||||
CONS_Printf(M_GetText("Checking files...\n"));
|
||||
i = CL_CheckFiles();
|
||||
if (i == 3) // too many files
|
||||
D_ParseFileneeded(serverlist[i].info.fileneedednum, serverlist[i].info.fileneeded, 0);
|
||||
|
||||
if (serverlist[i].info.flags & SV_LOTSOFADDONS)
|
||||
{
|
||||
D_QuitNetGame();
|
||||
CL_Reset();
|
||||
D_StartTitle();
|
||||
M_StartMessage(M_GetText(
|
||||
"You have too many WAD files loaded\n"
|
||||
"to add ones the server is using.\n"
|
||||
"Please restart SRB2 before connecting.\n\n"
|
||||
"Press ESC\n"
|
||||
), NULL, MM_NOTHING);
|
||||
return false;
|
||||
}
|
||||
else if (i == 2) // cannot join for some reason
|
||||
{
|
||||
D_QuitNetGame();
|
||||
CL_Reset();
|
||||
D_StartTitle();
|
||||
M_StartMessage(M_GetText(
|
||||
"You have the wrong addons loaded.\n\n"
|
||||
"To play on this server, restart\n"
|
||||
"the game and don't load any addons.\n"
|
||||
"SRB2 will automatically add\n"
|
||||
"everything you need when you join.\n\n"
|
||||
"Press ESC\n"
|
||||
), NULL, MM_NOTHING);
|
||||
return false;
|
||||
}
|
||||
else if (i == 1)
|
||||
cl_mode = CL_ASKJOIN;
|
||||
else
|
||||
{
|
||||
// must download something
|
||||
// can we, though?
|
||||
if (!CL_CheckDownloadable()) // nope!
|
||||
{
|
||||
D_QuitNetGame();
|
||||
CL_Reset();
|
||||
D_StartTitle();
|
||||
M_StartMessage(M_GetText(
|
||||
"You cannot connect to this server\n"
|
||||
"because you cannot download the files\n"
|
||||
"that you are missing from the server.\n\n"
|
||||
"See the console or log file for\n"
|
||||
"more details.\n\n"
|
||||
"Press ESC\n"
|
||||
), NULL, MM_NOTHING);
|
||||
return false;
|
||||
}
|
||||
// no problem if can't send packet, we will retry later
|
||||
if (CL_SendFileRequest())
|
||||
{
|
||||
cl_mode = CL_DOWNLOADFILES;
|
||||
#ifndef NONET
|
||||
Snake_Initialise();
|
||||
#endif
|
||||
}
|
||||
cl_mode = CL_ASKFULLFILELIST;
|
||||
cl_lastcheckedfilecount = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
cl_mode = CL_CHECKFILES;
|
||||
}
|
||||
else
|
||||
{
|
||||
cl_mode = CL_ASKJOIN; // files need not be checked for the server.
|
||||
*asksent = 0;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -1995,6 +2189,22 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic
|
|||
return false;
|
||||
break;
|
||||
|
||||
case CL_ASKFULLFILELIST:
|
||||
if (cl_lastcheckedfilecount == UINT16_MAX) // All files retrieved
|
||||
cl_mode = CL_CHECKFILES;
|
||||
else if (fileneedednum != cl_lastcheckedfilecount || I_GetTime() >= *asksent)
|
||||
{
|
||||
if (CL_AskFileList(fileneedednum))
|
||||
{
|
||||
cl_lastcheckedfilecount = fileneedednum;
|
||||
*asksent = I_GetTime() + NEWTICRATE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CL_CHECKFILES:
|
||||
if (!CL_FinishedFileList())
|
||||
return false;
|
||||
break;
|
||||
case CL_DOWNLOADFILES:
|
||||
waitmore = false;
|
||||
for (i = 0; i < fileneedednum; i++)
|
||||
|
@ -2015,21 +2225,50 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic
|
|||
}
|
||||
#endif
|
||||
|
||||
cl_mode = CL_ASKJOIN; // don't break case continue to cljoin request now
|
||||
/* FALLTHRU */
|
||||
|
||||
cl_mode = CL_LOADFILES;
|
||||
break;
|
||||
case CL_LOADFILES:
|
||||
if (CL_LoadServerFiles())
|
||||
{
|
||||
*asksent = 0; //This ensure the first join ask is right away
|
||||
firstconnectattempttime = I_GetTime();
|
||||
cl_mode = CL_ASKJOIN;
|
||||
}
|
||||
break;
|
||||
case CL_ASKJOIN:
|
||||
CL_LoadServerFiles();
|
||||
if (firstconnectattempttime + NEWTICRATE*300 < I_GetTime() && !server)
|
||||
{
|
||||
CONS_Printf(M_GetText("5 minute wait time exceeded.\n"));
|
||||
CONS_Printf(M_GetText("Network game synchronization aborted.\n"));
|
||||
D_QuitNetGame();
|
||||
CL_Reset();
|
||||
D_StartTitle();
|
||||
M_StartMessage(M_GetText(
|
||||
"5 minute wait time exceeded.\n"
|
||||
"You may retry connection.\n"
|
||||
"\n"
|
||||
"Press ESC\n"
|
||||
), NULL, MM_NOTHING);
|
||||
return false;
|
||||
}
|
||||
#ifndef NONET
|
||||
// prepare structures to save the file
|
||||
// WARNING: this can be useless in case of server not in GS_LEVEL
|
||||
// but since the network layer doesn't provide ordered packets...
|
||||
CL_PrepareDownloadSaveGame(tmpsave);
|
||||
#endif
|
||||
if (CL_SendJoin())
|
||||
if (I_GetTime() >= *asksent && CL_SendJoin())
|
||||
{
|
||||
*asksent = I_GetTime() + NEWTICRATE*3;
|
||||
cl_mode = CL_WAITJOINRESPONSE;
|
||||
}
|
||||
break;
|
||||
case CL_WAITJOINRESPONSE:
|
||||
if (I_GetTime() >= *asksent)
|
||||
{
|
||||
cl_mode = CL_ASKJOIN;
|
||||
}
|
||||
break;
|
||||
|
||||
#ifndef NONET
|
||||
case CL_DOWNLOADSAVEGAME:
|
||||
// At this state, the first (and only) needed file is the gamestate
|
||||
|
@ -2043,8 +2282,8 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic
|
|||
break;
|
||||
#endif
|
||||
|
||||
case CL_WAITJOINRESPONSE:
|
||||
case CL_CONNECTED:
|
||||
case CL_CONFIRMCONNECT: //logic is handled by M_ConfirmConnect
|
||||
default:
|
||||
break;
|
||||
|
||||
|
@ -2052,7 +2291,6 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic
|
|||
case CL_ABORTED:
|
||||
cl_mode = CL_SEARCHING;
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
GetPackets();
|
||||
|
@ -2062,13 +2300,19 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic
|
|||
if (*oldtic != I_GetTime())
|
||||
{
|
||||
I_OsPolling();
|
||||
for (; eventtail != eventhead; eventtail = (eventtail+1) & (MAXEVENTS-1))
|
||||
G_MapEventsToControls(&events[eventtail]);
|
||||
|
||||
if (gamekeydown[KEY_ESCAPE] || gamekeydown[KEY_JOY1+1])
|
||||
if (cl_mode == CL_CONFIRMCONNECT)
|
||||
D_ProcessEvents(); //needed for menu system to receive inputs
|
||||
else
|
||||
{
|
||||
for (; eventtail != eventhead; eventtail = (eventtail+1) & (MAXEVENTS-1))
|
||||
G_MapEventsToControls(&events[eventtail]);
|
||||
}
|
||||
|
||||
if (gamekeydown[KEY_ESCAPE] || gamekeydown[KEY_JOY1+1] || cl_mode == CL_ABORTED)
|
||||
{
|
||||
CONS_Printf(M_GetText("Network game synchronization aborted.\n"));
|
||||
// M_StartMessage(M_GetText("Network game synchronization aborted.\n\nPress ESC\n"), NULL, MM_NOTHING);
|
||||
M_StartMessage(M_GetText("Network game synchronization aborted.\n\nPress ESC\n"), NULL, MM_NOTHING);
|
||||
|
||||
#ifndef NONET
|
||||
if (snake)
|
||||
|
@ -2101,13 +2345,20 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic
|
|||
#ifndef NONET
|
||||
if (client && cl_mode != CL_CONNECTED && cl_mode != CL_ABORTED)
|
||||
{
|
||||
if (cl_mode != CL_DOWNLOADFILES && cl_mode != CL_DOWNLOADSAVEGAME)
|
||||
if (!snake)
|
||||
{
|
||||
F_MenuPresTicker(true); // title sky
|
||||
F_TitleScreenTicker(true);
|
||||
F_TitleScreenDrawer();
|
||||
}
|
||||
CL_DrawConnectionStatus();
|
||||
#ifdef HAVE_THREADS
|
||||
I_lock_mutex(&m_menu_mutex);
|
||||
#endif
|
||||
M_Drawer(); //Needed for drawing messageboxes on the connection screen
|
||||
#ifdef HAVE_THREADS
|
||||
I_unlock_mutex(m_menu_mutex);
|
||||
#endif
|
||||
I_UpdateNoVsync(); // page flip or blit buffer
|
||||
if (moviemode)
|
||||
M_SaveFrame();
|
||||
|
@ -2169,8 +2420,10 @@ static void CL_ConnectToServer(void)
|
|||
ClearAdminPlayers();
|
||||
pnumnodes = 1;
|
||||
oldtic = I_GetTime() - 1;
|
||||
|
||||
#ifndef NONET
|
||||
asksent = (tic_t) - TICRATE;
|
||||
firstconnectattempttime = I_GetTime();
|
||||
|
||||
i = SL_SearchServer(servernode);
|
||||
|
||||
|
@ -2611,8 +2864,16 @@ void CL_Reset(void)
|
|||
CV_RevertNetVars();
|
||||
|
||||
// make sure we don't leave any fileneeded gunk over from a failed join
|
||||
FreeFileNeeded();
|
||||
fileneedednum = 0;
|
||||
memset(fileneeded, 0, sizeof(fileneeded));
|
||||
|
||||
#ifndef NONET
|
||||
totalfilesrequestednum = 0;
|
||||
totalfilesrequestedsize = 0;
|
||||
#endif
|
||||
firstconnectattempttime = 0;
|
||||
serverisfull = false;
|
||||
connectiontimeout = (tic_t)cv_nettimeout.value; //reset this temporary hack
|
||||
|
||||
// D_StartTitle should get done now, but the calling function will handle it
|
||||
}
|
||||
|
@ -3839,31 +4100,40 @@ static void HandlePacketFromAwayNode(SINT8 node)
|
|||
switch (netbuffer->packettype)
|
||||
{
|
||||
case PT_ASKINFOVIAMS:
|
||||
#if 0
|
||||
Net_CloseConnection(node);
|
||||
break;
|
||||
|
||||
case PT_TELLFILESNEEDED:
|
||||
if (server && serverrunning)
|
||||
{
|
||||
INT32 clientnode;
|
||||
if (ms_RoomId < 0) // ignore if we're not actually on the MS right now
|
||||
{
|
||||
Net_CloseConnection(node); // and yes, close connection
|
||||
return;
|
||||
}
|
||||
clientnode = I_NetMakeNode(netbuffer->u.msaskinfo.clientaddr);
|
||||
if (clientnode != -1)
|
||||
{
|
||||
SV_SendServerInfo(clientnode, (tic_t)LONG(netbuffer->u.msaskinfo.time));
|
||||
SV_SendPlayerInfo(clientnode); // Send extra info
|
||||
Net_CloseConnection(clientnode);
|
||||
// Don't close connection to MS...
|
||||
}
|
||||
else
|
||||
Net_CloseConnection(node); // ...unless the IP address is not valid
|
||||
UINT8 *p;
|
||||
INT32 firstfile = netbuffer->u.filesneedednum;
|
||||
|
||||
netbuffer->packettype = PT_MOREFILESNEEDED;
|
||||
netbuffer->u.filesneededcfg.first = firstfile;
|
||||
netbuffer->u.filesneededcfg.more = 0;
|
||||
|
||||
p = PutFileNeeded(firstfile);
|
||||
|
||||
HSendPacket(node, false, 0, p - ((UINT8 *)&netbuffer->u));
|
||||
}
|
||||
else // Shouldn't get this if you aren't the server...?
|
||||
Net_CloseConnection(node);
|
||||
break;
|
||||
|
||||
case PT_MOREFILESNEEDED:
|
||||
if (server && serverrunning)
|
||||
{ // But wait I thought I'm the server?
|
||||
Net_CloseConnection(node);
|
||||
break;
|
||||
}
|
||||
SERVERONLY
|
||||
if (cl_mode == CL_ASKFULLFILELIST && netbuffer->u.filesneededcfg.first == fileneedednum)
|
||||
{
|
||||
D_ParseFileneeded(netbuffer->u.filesneededcfg.num, netbuffer->u.filesneededcfg.files, netbuffer->u.filesneededcfg.first);
|
||||
if (!netbuffer->u.filesneededcfg.more)
|
||||
cl_lastcheckedfilecount = UINT16_MAX; // Got the whole file list
|
||||
}
|
||||
else
|
||||
Net_CloseConnection(node); // you're not supposed to get it, so ignore it
|
||||
#else
|
||||
Net_CloseConnection(node);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case PT_ASKINFO:
|
||||
|
@ -3889,13 +4159,24 @@ static void HandlePacketFromAwayNode(SINT8 node)
|
|||
if (!reason)
|
||||
I_Error("Out of memory!\n");
|
||||
|
||||
D_QuitNetGame();
|
||||
CL_Reset();
|
||||
D_StartTitle();
|
||||
if (strstr(reason, "Maximum players reached"))
|
||||
{
|
||||
serverisfull = true;
|
||||
//Special timeout for when refusing due to player cap. The client will wait 3 seconds between join requests when waiting for a slot, so we need this to be much longer
|
||||
//We set it back to the value of cv_nettimeout.value in CL_Reset
|
||||
connectiontimeout = NEWTICRATE*7;
|
||||
cl_mode = CL_ASKJOIN;
|
||||
free(reason);
|
||||
break;
|
||||
}
|
||||
|
||||
M_StartMessage(va(M_GetText("Server refuses connection\n\nReason:\n%s"),
|
||||
reason), NULL, MM_NOTHING);
|
||||
|
||||
D_QuitNetGame();
|
||||
CL_Reset();
|
||||
D_StartTitle();
|
||||
|
||||
free(reason);
|
||||
|
||||
// Will be reset by caller. Signals refusal.
|
||||
|
@ -4486,9 +4767,9 @@ static INT16 Consistancy(void)
|
|||
{
|
||||
if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
|
||||
continue;
|
||||
|
||||
|
||||
mo = (mobj_t *)th;
|
||||
|
||||
|
||||
if (mo->flags & (MF_SPECIAL | MF_SOLID | MF_PUSHABLE | MF_BOSS | MF_MISSILE | MF_SPRING | MF_MONITOR | MF_FIRE | MF_ENEMY | MF_PAIN | MF_STICKY))
|
||||
{
|
||||
ret -= mo->type;
|
||||
|
|
|
@ -90,6 +90,9 @@ typedef enum
|
|||
|
||||
PT_LOGIN, // Login attempt from the client.
|
||||
|
||||
PT_TELLFILESNEEDED, // Client, to server: "what other files do I need starting from this number?"
|
||||
PT_MOREFILESNEEDED, // Server, to client: "you need these (+ more on top of those)"
|
||||
|
||||
PT_PING, // Packet sent to tell clients the other client's latency to server.
|
||||
NUMPACKETTYPE
|
||||
} packettype_t;
|
||||
|
@ -200,6 +203,9 @@ typedef struct
|
|||
char names[MAXSPLITSCREENPLAYERS][MAXPLAYERNAME];
|
||||
} ATTRPACK clientconfig_pak;
|
||||
|
||||
#define SV_DEDICATED 0x40 // server is dedicated
|
||||
#define SV_LOTSOFADDONS 0x20 // flag used to ask for full file list in d_netfil
|
||||
|
||||
#define MAXSERVERNAME 32
|
||||
#define MAXFILENEEDED 915
|
||||
// This packet is too large
|
||||
|
@ -221,7 +227,7 @@ typedef struct
|
|||
char gametypename[24];
|
||||
UINT8 modifiedgame;
|
||||
UINT8 cheatsenabled;
|
||||
UINT8 isdedicated;
|
||||
UINT8 flags;
|
||||
UINT8 fileneedednum;
|
||||
tic_t time;
|
||||
tic_t leveltime;
|
||||
|
@ -275,6 +281,14 @@ typedef struct
|
|||
UINT8 ctfteam;
|
||||
} ATTRPACK plrconfig;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
INT32 first;
|
||||
UINT8 num;
|
||||
UINT8 more;
|
||||
UINT8 files[MAXFILENEEDED]; // is filled with writexxx (byteptr.h)
|
||||
} ATTRPACK filesneededconfig_pak;
|
||||
|
||||
//
|
||||
// Network packet data
|
||||
//
|
||||
|
@ -304,6 +318,8 @@ typedef struct
|
|||
msaskinfo_pak msaskinfo; // 22 bytes
|
||||
plrinfo playerinfo[MAXPLAYERS]; // 576 bytes(?)
|
||||
plrconfig playerconfig[MAXPLAYERS]; // (up to) 528 bytes(?)
|
||||
INT32 filesneedednum; // 4 bytes
|
||||
filesneededconfig_pak filesneededcfg; // ??? bytes
|
||||
UINT32 pingtable[MAXPLAYERS+1]; // 68 bytes
|
||||
} u; // This is needed to pack diff packet types data together
|
||||
} ATTRPACK doomdata_t;
|
||||
|
|
83
src/d_main.c
83
src/d_main.c
|
@ -65,7 +65,7 @@
|
|||
#include "m_cond.h" // condition initialization
|
||||
#include "fastcmp.h"
|
||||
#include "keys.h"
|
||||
#include "filesrch.h" // refreshdirmenu, mainwadstally
|
||||
#include "filesrch.h" // refreshdirmenu
|
||||
#include "g_input.h" // tutorial mode control scheming
|
||||
#include "m_perfstats.h"
|
||||
|
||||
|
@ -96,11 +96,8 @@ int SUBVERSION;
|
|||
// platform independant focus loss
|
||||
UINT8 window_notinfocus = false;
|
||||
|
||||
//
|
||||
// DEMO LOOP
|
||||
//
|
||||
static char *startupwadfiles[MAX_WADFILES];
|
||||
static char *startuppwads[MAX_WADFILES];
|
||||
static addfilelist_t startupwadfiles;
|
||||
static addfilelist_t startuppwads;
|
||||
|
||||
boolean devparm = false; // started game with -devparm
|
||||
|
||||
|
@ -119,6 +116,9 @@ boolean midi_disabled = false;
|
|||
boolean sound_disabled = false;
|
||||
boolean digital_disabled = false;
|
||||
|
||||
//
|
||||
// DEMO LOOP
|
||||
//
|
||||
boolean advancedemo;
|
||||
#ifdef DEBUGFILE
|
||||
INT32 debugload = 0;
|
||||
|
@ -860,35 +860,47 @@ void D_StartTitle(void)
|
|||
tutorialmode = false;
|
||||
}
|
||||
|
||||
//
|
||||
// D_AddFile
|
||||
//
|
||||
static void D_AddFile(char **list, const char *file)
|
||||
static void D_AddFile(addfilelist_t *list, const char *file)
|
||||
{
|
||||
size_t pnumwadfiles;
|
||||
char *newfile;
|
||||
size_t index = 0;
|
||||
|
||||
for (pnumwadfiles = 0; list[pnumwadfiles]; pnumwadfiles++)
|
||||
;
|
||||
if (list->files == NULL)
|
||||
{
|
||||
list->files = calloc(sizeof(list->files), 2);
|
||||
list->numfiles = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
index = list->numfiles;
|
||||
list->files = realloc(list->files, sizeof(list->files) * ((++list->numfiles) + 1));
|
||||
if (list->files == NULL)
|
||||
I_Error("D_AddFile: No more free memory to add file %s (list reallocation)", file);
|
||||
}
|
||||
|
||||
newfile = malloc(strlen(file) + 1);
|
||||
if (!newfile)
|
||||
{
|
||||
I_Error("No more free memory to AddFile %s",file);
|
||||
}
|
||||
I_Error("D_AddFile: No more free memory to add file %s (filename allocation)", file);
|
||||
strcpy(newfile, file);
|
||||
|
||||
list[pnumwadfiles] = newfile;
|
||||
list->files[index] = newfile;
|
||||
list->files[index + 1] = NULL;
|
||||
}
|
||||
|
||||
static inline void D_CleanFile(char **list)
|
||||
static inline void D_CleanFile(addfilelist_t *list)
|
||||
{
|
||||
size_t pnumwadfiles;
|
||||
for (pnumwadfiles = 0; list[pnumwadfiles]; pnumwadfiles++)
|
||||
if (list->files)
|
||||
{
|
||||
free(list[pnumwadfiles]);
|
||||
list[pnumwadfiles] = NULL;
|
||||
size_t pnumwadfiles = 0;
|
||||
|
||||
for (; pnumwadfiles < list->numfiles; pnumwadfiles++)
|
||||
free(list->files[pnumwadfiles]);
|
||||
|
||||
free(list->files);
|
||||
list->files = NULL;
|
||||
}
|
||||
|
||||
list->numfiles = 0;
|
||||
}
|
||||
|
||||
///\brief Checks if a netgame URL is being handled, and changes working directory to the EXE's if so.
|
||||
|
@ -972,7 +984,7 @@ static void IdentifyVersion(void)
|
|||
|
||||
// Load the IWAD
|
||||
if (srb2wad != NULL && FIL_ReadFileOK(srb2wad))
|
||||
D_AddFile(startupwadfiles, srb2wad);
|
||||
D_AddFile(&startupwadfiles, srb2wad);
|
||||
else
|
||||
I_Error("srb2.pk3 not found! Expected in %s, ss file: %s\n", srb2waddir, srb2wad);
|
||||
|
||||
|
@ -983,14 +995,14 @@ static void IdentifyVersion(void)
|
|||
// checking in D_SRB2Main
|
||||
|
||||
// Add the maps
|
||||
D_AddFile(startupwadfiles, va(pandf,srb2waddir,"zones.pk3"));
|
||||
D_AddFile(&startupwadfiles, va(pandf,srb2waddir, "zones.pk3"));
|
||||
|
||||
// Add the players
|
||||
D_AddFile(startupwadfiles, va(pandf,srb2waddir, "player.dta"));
|
||||
D_AddFile(&startupwadfiles, va(pandf,srb2waddir, "player.dta"));
|
||||
|
||||
#ifdef USE_PATCH_DTA
|
||||
// Add our crappy patches to fix our bugs
|
||||
D_AddFile(startupwadfiles, va(pandf,srb2waddir,"patch.pk3"));
|
||||
D_AddFile(&startupwadfiles, va(pandf,srb2waddir, "patch.pk3"));
|
||||
#endif
|
||||
|
||||
#if !defined (HAVE_SDL) || defined (HAVE_MIXER)
|
||||
|
@ -1000,7 +1012,7 @@ static void IdentifyVersion(void)
|
|||
const char *musicpath = va(pandf,srb2waddir,str);\
|
||||
int ms = W_VerifyNMUSlumps(musicpath, false); \
|
||||
if (ms == 1) \
|
||||
D_AddFile(startupwadfiles, musicpath); \
|
||||
D_AddFile(&startupwadfiles, musicpath); \
|
||||
else if (ms == 0) \
|
||||
I_Error("File "str" has been modified with non-music/sound lumps"); \
|
||||
}
|
||||
|
@ -1187,7 +1199,7 @@ void D_SRB2Main(void)
|
|||
const char *s = M_GetNextParm();
|
||||
|
||||
if (s) // Check for NULL?
|
||||
D_AddFile(startuppwads, s);
|
||||
D_AddFile(&startuppwads, s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1227,8 +1239,8 @@ void D_SRB2Main(void)
|
|||
|
||||
// load wad, including the main wad file
|
||||
CONS_Printf("W_InitMultipleFiles(): Adding IWAD and main PWADs.\n");
|
||||
W_InitMultipleFiles(startupwadfiles);
|
||||
D_CleanFile(startupwadfiles);
|
||||
W_InitMultipleFiles(&startupwadfiles);
|
||||
D_CleanFile(&startupwadfiles);
|
||||
|
||||
#ifndef DEVELOP // md5s last updated 22/02/20 (ddmmyy)
|
||||
|
||||
|
@ -1243,8 +1255,6 @@ void D_SRB2Main(void)
|
|||
// ...except it does if they slip maps in there, and that's what W_VerifyNMUSlumps is for.
|
||||
#endif //ifndef DEVELOP
|
||||
|
||||
mainwadstally = packetsizetally; // technically not accurate atm, remember to port the two-stage -file process from kart in 2.2.x
|
||||
|
||||
cht_Init();
|
||||
|
||||
//---------------------------------------------------- READY SCREEN
|
||||
|
@ -1275,9 +1285,12 @@ void D_SRB2Main(void)
|
|||
|
||||
I_RegisterSysCommands();
|
||||
|
||||
CONS_Printf("W_InitMultipleFiles(): Adding extra PWADs.\n");
|
||||
W_InitMultipleFiles(startuppwads);
|
||||
D_CleanFile(startuppwads);
|
||||
if (startuppwads.numfiles)
|
||||
{
|
||||
CONS_Printf("W_InitMultipleFiles(): Adding extra PWADs.\n");
|
||||
W_InitMultipleFiles(&startuppwads);
|
||||
D_CleanFile(&startuppwads);
|
||||
}
|
||||
|
||||
CONS_Printf("HU_LoadGraphics()...\n");
|
||||
HU_LoadGraphics();
|
||||
|
|
|
@ -815,6 +815,8 @@ static const char *packettypename[NUMPACKETTYPE] =
|
|||
"CLIENTJOIN",
|
||||
"NODETIMEOUT",
|
||||
"LOGIN",
|
||||
"TELLFILESNEEDED",
|
||||
"MOREFILESNEEDED",
|
||||
"PING"
|
||||
};
|
||||
|
||||
|
|
|
@ -3324,8 +3324,7 @@ static void Command_Addfile(void)
|
|||
|
||||
// check total packet size and no of files currently loaded
|
||||
// See W_LoadWadFile in w_wad.c
|
||||
if ((numwadfiles >= MAX_WADFILES)
|
||||
|| ((packetsizetally + nameonlylength(fn) + 22) > MAXFILENEEDED*sizeof(UINT8)))
|
||||
if (numwadfiles >= MAX_WADFILES)
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, M_GetText("Too many files loaded to add %s\n"), fn);
|
||||
return;
|
||||
|
@ -3402,8 +3401,7 @@ static void Got_RequestAddfilecmd(UINT8 **cp, INT32 playernum)
|
|||
}
|
||||
|
||||
// See W_LoadWadFile in w_wad.c
|
||||
if ((numwadfiles >= MAX_WADFILES)
|
||||
|| ((packetsizetally + nameonlylength(filename) + 22) > MAXFILENEEDED*sizeof(UINT8)))
|
||||
if (numwadfiles >= MAX_WADFILES)
|
||||
toomany = true;
|
||||
else
|
||||
ncs = findfile(filename,md5sum,true);
|
||||
|
@ -3485,7 +3483,7 @@ static void Command_ListWADS_f(void)
|
|||
{
|
||||
INT32 i = numwadfiles;
|
||||
char *tempname;
|
||||
CONS_Printf(M_GetText("There are %d wads loaded:\n"),numwadfiles);
|
||||
CONS_Printf(M_GetText("There are %d/%d wads loaded:\n"),numwadfiles,MAX_WADFILES);
|
||||
for (i--; i >= 0; i--)
|
||||
{
|
||||
nameonly(tempname = va("%s", wadfiles[i]->filename));
|
||||
|
|
|
@ -73,6 +73,7 @@ extern consvar_t cv_teamscramble;
|
|||
extern consvar_t cv_scrambleonchange;
|
||||
|
||||
extern consvar_t cv_netstat;
|
||||
extern consvar_t cv_nettimeout;
|
||||
|
||||
extern consvar_t cv_countdowntime;
|
||||
extern consvar_t cv_runscripts;
|
||||
|
|
193
src/d_netfil.c
193
src/d_netfil.c
|
@ -91,7 +91,7 @@ static filetran_t transfer[MAXNETNODES];
|
|||
|
||||
// Receiver structure
|
||||
INT32 fileneedednum; // Number of files needed to join the server
|
||||
fileneeded_t fileneeded[MAX_WADFILES]; // List of needed files
|
||||
fileneeded_t *fileneeded; // List of needed files
|
||||
static tic_t lasttimeackpacketsent = 0;
|
||||
char downloaddir[512] = "DOWNLOAD";
|
||||
|
||||
|
@ -109,6 +109,10 @@ static pauseddownload_t *pauseddownload = NULL;
|
|||
#ifndef NONET
|
||||
// for cl loading screen
|
||||
INT32 lastfilenum = -1;
|
||||
INT32 downloadcompletednum = 0;
|
||||
UINT32 downloadcompletedsize = 0;
|
||||
INT32 totalfilesrequestednum = 0;
|
||||
UINT32 totalfilesrequestedsize = 0;
|
||||
#endif
|
||||
|
||||
luafiletransfer_t *luafiletransfers = NULL;
|
||||
|
@ -123,19 +127,40 @@ char luafiledir[256 + 16] = "luafiles";
|
|||
* Used to have size limiting built in - now handled via W_LoadWadFile in w_wad.c
|
||||
*
|
||||
*/
|
||||
UINT8 *PutFileNeeded(void)
|
||||
UINT8 *PutFileNeeded(UINT16 firstfile)
|
||||
{
|
||||
size_t i, count = 0;
|
||||
UINT8 *p = netbuffer->u.serverinfo.fileneeded;
|
||||
size_t i;
|
||||
UINT8 count = 0;
|
||||
UINT8 *p_start = netbuffer->packettype == PT_MOREFILESNEEDED ? netbuffer->u.filesneededcfg.files : netbuffer->u.serverinfo.fileneeded;
|
||||
UINT8 *p = p_start;
|
||||
char wadfilename[MAX_WADPATH] = "";
|
||||
UINT8 filestatus;
|
||||
|
||||
for (i = 0; i < numwadfiles; i++)
|
||||
for (i = mainwads+1; i < numwadfiles; i++) //mainwads+1, otherwise we start on the first mainwad
|
||||
{
|
||||
// If it has only music/sound lumps, don't put it in the list
|
||||
if (!wadfiles[i]->important)
|
||||
continue;
|
||||
|
||||
if (firstfile)
|
||||
{ // Skip files until we reach the first file.
|
||||
firstfile--;
|
||||
continue;
|
||||
}
|
||||
|
||||
nameonly(strcpy(wadfilename, wadfiles[i]->filename));
|
||||
|
||||
// Look below at the WRITE macros to understand what these numbers mean.
|
||||
if (p + 1 + 4 + min(strlen(wadfilename) + 1, MAX_WADPATH) + 16 > p_start + MAXFILENEEDED)
|
||||
{
|
||||
// Too many files to send all at once
|
||||
if (netbuffer->packettype == PT_MOREFILESNEEDED)
|
||||
netbuffer->u.filesneededcfg.more = 1;
|
||||
else
|
||||
netbuffer->u.serverinfo.flags |= SV_LOTSOFADDONS;
|
||||
break;
|
||||
}
|
||||
|
||||
filestatus = 1; // Importance - not really used any more, holds 1 by default for backwards compat with MS
|
||||
|
||||
// Store in the upper four bits
|
||||
|
@ -150,32 +175,52 @@ UINT8 *PutFileNeeded(void)
|
|||
|
||||
count++;
|
||||
WRITEUINT32(p, wadfiles[i]->filesize);
|
||||
nameonly(strcpy(wadfilename, wadfiles[i]->filename));
|
||||
WRITESTRINGN(p, wadfilename, MAX_WADPATH);
|
||||
WRITEMEM(p, wadfiles[i]->md5sum, 16);
|
||||
}
|
||||
netbuffer->u.serverinfo.fileneedednum = (UINT8)count;
|
||||
|
||||
if (netbuffer->packettype == PT_MOREFILESNEEDED)
|
||||
netbuffer->u.filesneededcfg.num = count;
|
||||
else
|
||||
netbuffer->u.serverinfo.fileneedednum = count;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
void AllocFileNeeded(INT32 size)
|
||||
{
|
||||
if (fileneeded == NULL)
|
||||
fileneeded = Z_Calloc(sizeof(fileneeded_t) * size, PU_STATIC, NULL);
|
||||
}
|
||||
|
||||
void FreeFileNeeded(void)
|
||||
{
|
||||
if (fileneeded == NULL)
|
||||
Z_Free(fileneeded);
|
||||
fileneeded = NULL;
|
||||
}
|
||||
|
||||
/** Parses the serverinfo packet and fills the fileneeded table on client
|
||||
*
|
||||
* \param fileneedednum_parm The number of files needed to join the server
|
||||
* \param fileneededstr The memory block containing the list of needed files
|
||||
*
|
||||
*/
|
||||
void D_ParseFileneeded(INT32 fileneedednum_parm, UINT8 *fileneededstr)
|
||||
void D_ParseFileneeded(INT32 fileneedednum_parm, UINT8 *fileneededstr, UINT16 firstfile)
|
||||
{
|
||||
INT32 i;
|
||||
UINT8 *p;
|
||||
UINT8 filestatus;
|
||||
|
||||
fileneedednum = fileneedednum_parm;
|
||||
fileneedednum = firstfile + fileneedednum_parm;
|
||||
p = (UINT8 *)fileneededstr;
|
||||
for (i = 0; i < fileneedednum; i++)
|
||||
|
||||
AllocFileNeeded(fileneedednum);
|
||||
|
||||
for (i = firstfile; i < fileneedednum; i++)
|
||||
{
|
||||
fileneeded[i].status = FS_NOTFOUND; // We haven't even started looking for the file yet
|
||||
fileneeded[i].type = FILENEEDED_WAD;
|
||||
fileneeded[i].status = FS_NOTCHECKED; // We haven't even started looking for the file yet
|
||||
fileneeded[i].justdownloaded = false;
|
||||
filestatus = READUINT8(p); // The first byte is the file status
|
||||
fileneeded[i].willsend = (UINT8)(filestatus >> 4);
|
||||
|
@ -192,7 +237,10 @@ void CL_PrepareDownloadSaveGame(const char *tmpsave)
|
|||
lastfilenum = -1;
|
||||
#endif
|
||||
|
||||
AllocFileNeeded(1);
|
||||
|
||||
fileneedednum = 1;
|
||||
fileneeded[0].type = FILENEEDED_SAVEGAME;
|
||||
fileneeded[0].status = FS_REQUESTED;
|
||||
fileneeded[0].justdownloaded = false;
|
||||
fileneeded[0].totalsize = UINT32_MAX;
|
||||
|
@ -375,17 +423,8 @@ INT32 CL_CheckFiles(void)
|
|||
{
|
||||
INT32 i, j;
|
||||
char wadfilename[MAX_WADPATH];
|
||||
INT32 ret = 1;
|
||||
size_t packetsize = 0;
|
||||
size_t filestoget = 0;
|
||||
|
||||
// if (M_CheckParm("-nofiles"))
|
||||
// return 1;
|
||||
|
||||
// the first is the iwad (the main wad file)
|
||||
// we don't care if it's called srb2.pk3 or not.
|
||||
// Never download the IWAD, just assume it's there and identical
|
||||
fileneeded[0].status = FS_OPEN;
|
||||
size_t filestoload = 0;
|
||||
boolean downloadrequired = false;
|
||||
|
||||
// Modified game handling -- check for an identical file list
|
||||
// must be identical in files loaded AND in order
|
||||
|
@ -393,7 +432,7 @@ INT32 CL_CheckFiles(void)
|
|||
if (modifiedgame)
|
||||
{
|
||||
CONS_Debug(DBG_NETPLAY, "game is modified; only doing basic checks\n");
|
||||
for (i = 1, j = 1; i < fileneedednum || j < numwadfiles;)
|
||||
for (i = 0, j = mainwads+1; i < fileneedednum || j < numwadfiles;)
|
||||
{
|
||||
if (j < numwadfiles && !wadfiles[j]->important)
|
||||
{
|
||||
|
@ -420,15 +459,21 @@ INT32 CL_CheckFiles(void)
|
|||
return 1;
|
||||
}
|
||||
|
||||
// See W_LoadWadFile in w_wad.c
|
||||
packetsize = packetsizetally;
|
||||
|
||||
for (i = 1; i < fileneedednum; i++)
|
||||
for (i = 0; i < fileneedednum; i++)
|
||||
{
|
||||
if (fileneeded[i].status == FS_NOTFOUND || fileneeded[i].status == FS_MD5SUMBAD)
|
||||
downloadrequired = true;
|
||||
|
||||
if (fileneeded[i].status != FS_OPEN)
|
||||
filestoload++;
|
||||
|
||||
if (fileneeded[i].status != FS_NOTCHECKED) //since we're running this over multiple tics now, its possible for us to come across files checked in previous tics
|
||||
continue;
|
||||
|
||||
CONS_Debug(DBG_NETPLAY, "searching for '%s' ", fileneeded[i].filename);
|
||||
|
||||
// Check in already loaded files
|
||||
for (j = 1; wadfiles[j]; j++)
|
||||
for (j = mainwads+1; wadfiles[j]; j++)
|
||||
{
|
||||
nameonly(strcpy(wadfilename, wadfiles[j]->filename));
|
||||
if (!stricmp(wadfilename, fileneeded[i].filename) &&
|
||||
|
@ -436,37 +481,30 @@ INT32 CL_CheckFiles(void)
|
|||
{
|
||||
CONS_Debug(DBG_NETPLAY, "already loaded\n");
|
||||
fileneeded[i].status = FS_OPEN;
|
||||
break;
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
if (fileneeded[i].status != FS_NOTFOUND)
|
||||
continue;
|
||||
|
||||
packetsize += nameonlylength(fileneeded[i].filename) + 22;
|
||||
|
||||
if ((numwadfiles+filestoget >= MAX_WADFILES)
|
||||
|| (packetsize > MAXFILENEEDED*sizeof(UINT8)))
|
||||
return 3;
|
||||
|
||||
filestoget++;
|
||||
|
||||
fileneeded[i].status = findfile(fileneeded[i].filename, fileneeded[i].md5sum, true);
|
||||
fileneeded[i].status = FS_NOTFOUND; //findfile(fileneeded[i].filename, fileneeded[i].md5sum, true);
|
||||
CONS_Debug(DBG_NETPLAY, "found %d\n", fileneeded[i].status);
|
||||
if (fileneeded[i].status != FS_FOUND)
|
||||
ret = 0;
|
||||
return 4;
|
||||
}
|
||||
return ret;
|
||||
|
||||
//now making it here means we've checked the entire list and no FS_NOTCHECKED files remain
|
||||
if (numwadfiles+filestoload > MAX_WADFILES)
|
||||
return 3;
|
||||
else if (downloadrequired)
|
||||
return 0; //some stuff is FS_NOTFOUND, needs download
|
||||
else
|
||||
return 1; //everything is FS_OPEN or FS_FOUND, proceed to loading
|
||||
}
|
||||
|
||||
// Load it now
|
||||
void CL_LoadServerFiles(void)
|
||||
boolean CL_LoadServerFiles(void)
|
||||
{
|
||||
INT32 i;
|
||||
|
||||
// if (M_CheckParm("-nofiles"))
|
||||
// return;
|
||||
|
||||
for (i = 1; i < fileneedednum; i++)
|
||||
for (i = 0; i < fileneedednum; i++)
|
||||
{
|
||||
if (fileneeded[i].status == FS_OPEN)
|
||||
continue; // Already loaded
|
||||
|
@ -475,6 +513,7 @@ void CL_LoadServerFiles(void)
|
|||
P_AddWadFile(fileneeded[i].filename);
|
||||
G_SetGameModified(true);
|
||||
fileneeded[i].status = FS_OPEN;
|
||||
return false;
|
||||
}
|
||||
else if (fileneeded[i].status == FS_MD5SUMBAD)
|
||||
I_Error("Wrong version of file %s", fileneeded[i].filename);
|
||||
|
@ -500,6 +539,7 @@ void CL_LoadServerFiles(void)
|
|||
fileneeded[i].status, s);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void AddLuaFileTransfer(const char *filename, const char *mode)
|
||||
|
@ -681,7 +721,10 @@ void CL_PrepareDownloadLuaFile(void)
|
|||
netbuffer->packettype = PT_ASKLUAFILE;
|
||||
HSendPacket(servernode, true, 0, 0);
|
||||
|
||||
AllocFileNeeded(1);
|
||||
|
||||
fileneedednum = 1;
|
||||
fileneeded[0].type = FILENEEDED_LUAFILE;
|
||||
fileneeded[0].status = FS_REQUESTED;
|
||||
fileneeded[0].justdownloaded = false;
|
||||
fileneeded[0].totalsize = UINT32_MAX;
|
||||
|
@ -760,7 +803,7 @@ static boolean AddFileToSendQueue(INT32 node, const char *filename, UINT8 fileid
|
|||
// This formerly checked if (!findfile(p->id.filename, NULL, true))
|
||||
|
||||
// Not found
|
||||
// Don't inform client (probably someone who thought they could leak 2.2 ACZ)
|
||||
// Don't inform client
|
||||
DEBFILE(va("Client %d request %s: not found\n", node, filename));
|
||||
free(p->id.filename);
|
||||
free(p);
|
||||
|
@ -1345,6 +1388,7 @@ void PT_FileFragment(void)
|
|||
// Tell the server we have received the file
|
||||
netbuffer->packettype = PT_HASLUAFILE;
|
||||
HSendPacket(servernode, true, 0, 0);
|
||||
FreeFileNeeded();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1415,32 +1459,37 @@ void CloseNetFile(void)
|
|||
SV_AbortSendFiles(i);
|
||||
|
||||
// Receiving a file?
|
||||
for (i = 0; i < MAX_WADFILES; i++)
|
||||
if (fileneeded[i].status == FS_DOWNLOADING && fileneeded[i].file)
|
||||
{
|
||||
fclose(fileneeded[i].file);
|
||||
free(fileneeded[i].ackpacket);
|
||||
|
||||
if (!pauseddownload && i != 0) // 0 is either srb2.srb or the gamestate...
|
||||
if (fileneeded)
|
||||
{
|
||||
for (i = 0; i < fileneedednum; i++)
|
||||
if (fileneeded[i].status == FS_DOWNLOADING && fileneeded[i].file)
|
||||
{
|
||||
// Don't remove the file, save it for later in case we resume the download
|
||||
pauseddownload = malloc(sizeof(*pauseddownload));
|
||||
if (!pauseddownload)
|
||||
I_Error("CloseNetFile: No more memory\n");
|
||||
fclose(fileneeded[i].file);
|
||||
free(fileneeded[i].ackpacket);
|
||||
|
||||
strcpy(pauseddownload->filename, fileneeded[i].filename);
|
||||
memcpy(pauseddownload->md5sum, fileneeded[i].md5sum, 16);
|
||||
pauseddownload->currentsize = fileneeded[i].currentsize;
|
||||
pauseddownload->receivedfragments = fileneeded[i].receivedfragments;
|
||||
pauseddownload->fragmentsize = fileneeded[i].fragmentsize;
|
||||
if (!pauseddownload && (fileneeded[i].type == FILENEEDED_WAD || i != 0)) // 0 is the gamestate...
|
||||
{
|
||||
// Don't remove the file, save it for later in case we resume the download
|
||||
pauseddownload = malloc(sizeof(*pauseddownload));
|
||||
if (!pauseddownload)
|
||||
I_Error("CloseNetFile: No more memory\n");
|
||||
|
||||
strcpy(pauseddownload->filename, fileneeded[i].filename);
|
||||
memcpy(pauseddownload->md5sum, fileneeded[i].md5sum, 16);
|
||||
pauseddownload->currentsize = fileneeded[i].currentsize;
|
||||
pauseddownload->receivedfragments = fileneeded[i].receivedfragments;
|
||||
pauseddownload->fragmentsize = fileneeded[i].fragmentsize;
|
||||
}
|
||||
else
|
||||
{
|
||||
// File is not complete, delete it.
|
||||
free(fileneeded[i].receivedfragments);
|
||||
remove(fileneeded[i].filename);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
free(fileneeded[i].receivedfragments);
|
||||
// File is not complete delete it
|
||||
remove(fileneeded[i].filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FreeFileNeeded();
|
||||
}
|
||||
|
||||
void Command_Downloads_f(void)
|
||||
|
|
|
@ -27,6 +27,7 @@ typedef enum
|
|||
|
||||
typedef enum
|
||||
{
|
||||
FS_NOTCHECKED,
|
||||
FS_NOTFOUND,
|
||||
FS_FOUND,
|
||||
FS_REQUESTED,
|
||||
|
@ -35,12 +36,20 @@ typedef enum
|
|||
FS_MD5SUMBAD
|
||||
} filestatus_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
FILENEEDED_WAD,
|
||||
FILENEEDED_SAVEGAME,
|
||||
FILENEEDED_LUAFILE
|
||||
} fileneededtype_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UINT8 willsend; // Is the server willing to send it?
|
||||
char filename[MAX_WADPATH];
|
||||
UINT8 md5sum[16];
|
||||
filestatus_t status; // The value returned by recsearch
|
||||
UINT8 willsend; // Is the server willing to send it?
|
||||
fileneededtype_t type;
|
||||
boolean justdownloaded; // To prevent late fragments from causing an I_Error
|
||||
|
||||
// Used only for download
|
||||
|
@ -55,19 +64,25 @@ typedef struct
|
|||
} fileneeded_t;
|
||||
|
||||
extern INT32 fileneedednum;
|
||||
extern fileneeded_t fileneeded[MAX_WADFILES];
|
||||
extern fileneeded_t *fileneeded;
|
||||
extern char downloaddir[512];
|
||||
|
||||
#ifndef NONET
|
||||
extern INT32 lastfilenum;
|
||||
extern INT32 downloadcompletednum;
|
||||
extern UINT32 downloadcompletedsize;
|
||||
extern INT32 totalfilesrequestednum;
|
||||
extern UINT32 totalfilesrequestedsize;
|
||||
#endif
|
||||
|
||||
UINT8 *PutFileNeeded(void);
|
||||
void D_ParseFileneeded(INT32 fileneedednum_parm, UINT8 *fileneededstr);
|
||||
void AllocFileNeeded(INT32 size);
|
||||
void FreeFileNeeded(void);
|
||||
UINT8 *PutFileNeeded(UINT16 firstfile);
|
||||
void D_ParseFileneeded(INT32 fileneedednum_parm, UINT8 *fileneededstr, UINT16 firstfile);
|
||||
void CL_PrepareDownloadSaveGame(const char *tmpsave);
|
||||
|
||||
INT32 CL_CheckFiles(void);
|
||||
void CL_LoadServerFiles(void);
|
||||
boolean CL_LoadServerFiles(void);
|
||||
void AddRamToSendQueue(INT32 node, void *data, size_t size, freemethod_t freemethod,
|
||||
UINT8 fileid);
|
||||
|
||||
|
|
|
@ -337,9 +337,6 @@ size_t dir_on[menudepth];
|
|||
UINT8 refreshdirmenu = 0;
|
||||
char *refreshdirname = NULL;
|
||||
|
||||
size_t packetsizetally = 0;
|
||||
size_t mainwadstally = 0;
|
||||
|
||||
filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *wantedmd5sum, boolean completepath, int maxsearchdepth)
|
||||
{
|
||||
filestatus_t retval = FS_NOTFOUND;
|
||||
|
@ -453,8 +450,7 @@ char exttable[NUM_EXT_TABLE][7] = { // maximum extension length (currently 4) pl
|
|||
#endif
|
||||
"\5.pk3", "\5.soc", "\5.lua"}; // addfile
|
||||
|
||||
char filenamebuf[MAX_WADFILES][MAX_WADPATH];
|
||||
|
||||
static char (*filenamebuf)[MAX_WADPATH];
|
||||
|
||||
static boolean filemenucmp(char *haystack, char *needle)
|
||||
{
|
||||
|
@ -732,6 +728,10 @@ boolean preparefilemenu(boolean samedepth)
|
|||
if (ext >= EXT_LOADSTART)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (filenamebuf == NULL)
|
||||
filenamebuf = calloc(sizeof(char) * MAX_WADPATH, numwadfiles);
|
||||
|
||||
for (i = 0; i < numwadfiles; i++)
|
||||
{
|
||||
if (!filenamebuf[i][0])
|
||||
|
@ -781,6 +781,12 @@ boolean preparefilemenu(boolean samedepth)
|
|||
}
|
||||
}
|
||||
|
||||
if (filenamebuf)
|
||||
{
|
||||
free(filenamebuf);
|
||||
filenamebuf = NULL;
|
||||
}
|
||||
|
||||
closedir(dirhandle);
|
||||
|
||||
if ((menudepthleft != menudepth-1) // now for UP... entry
|
||||
|
|
|
@ -42,9 +42,6 @@ extern size_t dir_on[menudepth];
|
|||
extern UINT8 refreshdirmenu;
|
||||
extern char *refreshdirname;
|
||||
|
||||
extern size_t packetsizetally;
|
||||
extern size_t mainwadstally;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
EXT_FOLDER = 0,
|
||||
|
|
|
@ -3213,7 +3213,7 @@ boolean M_Responder(event_t *ev)
|
|||
if (gamestate == GS_TITLESCREEN && finalecount < TICRATE)
|
||||
return false;
|
||||
|
||||
if (CON_Ready())
|
||||
if (CON_Ready() && gamestate != GS_WAITINGPLAYERS)
|
||||
return false;
|
||||
|
||||
if (noFurtherInput)
|
||||
|
@ -6453,10 +6453,7 @@ static void M_DrawAddons(void)
|
|||
y = FRACUNIT;
|
||||
else
|
||||
{
|
||||
x = FixedDiv(((ssize_t)(numwadfiles) - (ssize_t)(mainwads+1))<<FRACBITS, ((ssize_t)MAX_WADFILES - (ssize_t)(mainwads+1))<<FRACBITS);
|
||||
y = FixedDiv((((ssize_t)packetsizetally-(ssize_t)mainwadstally)<<FRACBITS), ((((ssize_t)MAXFILENEEDED*sizeof(UINT8)-(ssize_t)mainwadstally)-(5+22))<<FRACBITS)); // 5+22 = (a.ext + checksum length) is minimum addition to packet size tally
|
||||
if (x > y)
|
||||
y = x;
|
||||
y = FixedDiv(((ssize_t)(numwadfiles) - (ssize_t)(mainwads+1))<<FRACBITS, ((ssize_t)MAX_WADFILES - (ssize_t)(mainwads+1))<<FRACBITS);
|
||||
if (y > FRACUNIT) // happens because of how we're shrinkin' it a little
|
||||
y = FRACUNIT;
|
||||
}
|
||||
|
|
53
src/w_wad.c
53
src/w_wad.c
|
@ -104,7 +104,7 @@ static UINT16 lumpnumcacheindex = 0;
|
|||
// GLOBALS
|
||||
//===========================================================================
|
||||
UINT16 numwadfiles; // number of active wadfiles
|
||||
wadfile_t *wadfiles[MAX_WADFILES]; // 0 to numwadfiles-1 are valid
|
||||
wadfile_t **wadfiles; // 0 to numwadfiles-1 are valid
|
||||
|
||||
// W_Shutdown
|
||||
// Closes all of the WAD files before quitting
|
||||
|
@ -128,6 +128,8 @@ void W_Shutdown(void)
|
|||
Z_Free(wad->lumpinfo);
|
||||
Z_Free(wad);
|
||||
}
|
||||
|
||||
Z_Free(wadfiles);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
@ -715,7 +717,6 @@ UINT16 W_InitFile(const char *filename, boolean mainfile, boolean startup)
|
|||
#ifndef NOMD5
|
||||
size_t i;
|
||||
#endif
|
||||
size_t packetsize;
|
||||
UINT8 md5sum[16];
|
||||
int important;
|
||||
|
||||
|
@ -755,24 +756,7 @@ UINT16 W_InitFile(const char *filename, boolean mainfile, boolean startup)
|
|||
return INT16_MAX;
|
||||
}
|
||||
|
||||
// Check if wad files will overflow fileneededbuffer. Only the filename part
|
||||
// is send in the packet; cf.
|
||||
// see PutFileNeeded in d_netfil.c
|
||||
if ((important = !important))
|
||||
{
|
||||
packetsize = packetsizetally + nameonlylength(filename) + 22;
|
||||
|
||||
if (packetsize > MAXFILENEEDED*sizeof(UINT8))
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, M_GetText("Maximum wad files reached\n"));
|
||||
refreshdirmenu |= REFRESHDIR_MAX;
|
||||
if (handle)
|
||||
fclose(handle);
|
||||
return W_InitFileError(filename, startup);
|
||||
}
|
||||
|
||||
packetsizetally = packetsize;
|
||||
}
|
||||
important = !important;
|
||||
|
||||
#ifndef NOMD5
|
||||
//
|
||||
|
@ -782,16 +766,17 @@ UINT16 W_InitFile(const char *filename, boolean mainfile, boolean startup)
|
|||
//
|
||||
W_MakeFileMD5(filename, md5sum);
|
||||
|
||||
for (i = 0; i < numwadfiles; i++)
|
||||
if (wadfiles)
|
||||
{
|
||||
if (!memcmp(wadfiles[i]->md5sum, md5sum, 16))
|
||||
for (i = 0; i < numwadfiles; i++)
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, M_GetText("%s is already loaded\n"), filename);
|
||||
if (important)
|
||||
packetsizetally -= nameonlylength(filename) + 22;
|
||||
if (handle)
|
||||
fclose(handle);
|
||||
return W_InitFileError(filename, false);
|
||||
if (!memcmp(wadfiles[i]->md5sum, md5sum, 16))
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, M_GetText("%s is already loaded\n"), filename);
|
||||
if (handle)
|
||||
fclose(handle);
|
||||
return W_InitFileError(filename, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -853,6 +838,7 @@ UINT16 W_InitFile(const char *filename, boolean mainfile, boolean startup)
|
|||
// add the wadfile
|
||||
//
|
||||
CONS_Printf(M_GetText("Added file %s (%u lumps)\n"), filename, numlumps);
|
||||
wadfiles = Z_Realloc(wadfiles, sizeof(wadfile_t) * (numwadfiles + 1), PU_STATIC, NULL);
|
||||
wadfiles[numwadfiles] = wadfile;
|
||||
numwadfiles++; // must come BEFORE W_LoadDehackedLumps, so any addfile called by COM_BufInsertText called by Lua doesn't overwrite what we just loaded
|
||||
|
||||
|
@ -898,13 +884,14 @@ UINT16 W_InitFile(const char *filename, boolean mainfile, boolean startup)
|
|||
*
|
||||
* \param filenames A null-terminated list of files to use.
|
||||
*/
|
||||
void W_InitMultipleFiles(char **filenames)
|
||||
void W_InitMultipleFiles(addfilelist_t *list)
|
||||
{
|
||||
// will be realloced as lumps are added
|
||||
for (; *filenames; filenames++)
|
||||
size_t i = 0;
|
||||
|
||||
for (; i < list->numfiles; i++)
|
||||
{
|
||||
//CONS_Debug(DBG_SETUP, "Loading %s\n", *filenames);
|
||||
W_InitFile(*filenames, numwadfiles < mainwads, true);
|
||||
W_InitFile(list->files[i], numwadfiles < mainwads, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1838,7 +1825,7 @@ void W_VerifyFileMD5(UINT16 wadfilenum, const char *matchmd5)
|
|||
#else
|
||||
I_Error
|
||||
#endif
|
||||
(M_GetText("File is old, is corrupt or has been modified: %s (found md5: %s, wanted: %s)\n"), wadfiles[wadfilenum]->filename, actualmd5text, matchmd5);
|
||||
(M_GetText("File is old, is corrupt or has been modified:\n%s\nFound MD5: %s\nWanted MD5: %s\n"), wadfiles[wadfilenum]->filename, actualmd5text, matchmd5);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
12
src/w_wad.h
12
src/w_wad.h
|
@ -97,7 +97,7 @@ virtlump_t* vres_Find(const virtres_t*, const char*);
|
|||
// =========================================================================
|
||||
|
||||
#define MAX_WADPATH 512
|
||||
#define MAX_WADFILES 48 // maximum of wad files used at the same time
|
||||
#define MAX_WADFILES 2048 // Maximum of files that can be loaded
|
||||
// (there is a max of simultaneous open files anyway, and this should be plenty)
|
||||
|
||||
#define lumpcache_t void *
|
||||
|
@ -131,7 +131,13 @@ typedef struct wadfile_s
|
|||
#define LUMPNUM(lumpnum) (UINT16)((lumpnum)&0xFFFF) // lump number for this pwad
|
||||
|
||||
extern UINT16 numwadfiles;
|
||||
extern wadfile_t *wadfiles[MAX_WADFILES];
|
||||
extern wadfile_t **wadfiles;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char **files;
|
||||
size_t numfiles;
|
||||
} addfilelist_t;
|
||||
|
||||
// =========================================================================
|
||||
|
||||
|
@ -143,7 +149,7 @@ FILE *W_OpenWadFile(const char **filename, boolean useerrors);
|
|||
UINT16 W_InitFile(const char *filename, boolean mainfile, boolean startup);
|
||||
|
||||
// W_InitMultipleFiles exits if a file was not found, but not if all is okay.
|
||||
void W_InitMultipleFiles(char **filenames);
|
||||
void W_InitMultipleFiles(addfilelist_t *list);
|
||||
|
||||
const char *W_CheckNameForNumPwad(UINT16 wad, UINT16 lump);
|
||||
const char *W_CheckNameForNum(lumpnum_t lumpnum);
|
||||
|
|
Loading…
Reference in a new issue