/** Fills a serverinfo packet with information about wad files loaded. * * \todo Give this function a better name since it is in global scope. * Used to have size limiting built in - now handed via W_LoadWadFile in w_wad.c * */ UINT8 *PutFileNeeded(void) { size_t i, count = 0; UINT8 *p = netbuffer->u.serverinfo.fileneeded; char wadfilename[MAX_WADPATH] = ""; UINT8 filestatus; for (i = 0; i < numwadfiles; i++) { // If it has only music/sound lumps, don't put it in the list if (!wadfiles[i]->important) continue; filestatus = 1; // Importance - not really used any more, holds 1 by default for backwards compat with MS // Store in the upper four bits if (!cv_downloading.value) filestatus += (2 << 4); // Won't send else if ((wadfiles[i]->filesize <= (UINT32)cv_maxsend.value * 1024)) filestatus += (1 << 4); // Will send if requested // else // filestatus += (0 << 4); -- Won't send, too big WRITEUINT8(p, filestatus); 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; return p; }
/** Fills a serverinfo packet with information about wad files loaded. * * \todo Give this function a better name since it is in global scope. * */ UINT8 *PutFileNeeded(void) { size_t i, count = 0; UINT8 *p = netbuffer->u.serverinfo.fileneeded; char wadfilename[MAX_WADPATH] = ""; UINT8 filestatus; size_t bytesused = 0; for (i = 0; i < numwadfiles; i++) { // If it has only music/sound lumps, mark it as unimportant if (W_VerifyNMUSlumps(wadfiles[i]->filename)) filestatus = 0; else filestatus = 1; // Important // Store in the upper four bits if (!cv_downloading.value) filestatus += (2 << 4); // Won't send else if ((wadfiles[i]->filesize > (UINT32)cv_maxsend.value * 1024)) filestatus += (0 << 4); // Won't send else filestatus += (1 << 4); // Will send if requested bytesused += (nameonlylength(wadfilename) + 22); // Don't write too far... if (bytesused > sizeof(netbuffer->u.serverinfo.fileneeded)) I_Error("Too many wad files added to host a game. (%s, stopped on %s)\n", sizeu1(bytesused), wadfilename); WRITEUINT8(p, filestatus); 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; return p; }
// Wrapper for COM_AddCommand commands void COM_Lua_f(void) { char *buf, *p; UINT8 i, flags; UINT16 len; INT32 playernum = consoleplayer; I_Assert(gL != NULL); lua_getfield(gL, LUA_REGISTRYINDEX, "COM_Command"); // push COM_Command I_Assert(lua_istable(gL, -1)); // use buf temporarily -- must use lowercased string buf = Z_StrDup(COM_Argv(0)); strlwr(buf); lua_getfield(gL, -1, buf); // push command info table I_Assert(lua_istable(gL, -1)); lua_remove(gL, -2); // pop COM_Command Z_Free(buf); lua_rawgeti(gL, -1, 2); // push flags from command info table if (lua_isboolean(gL, -1)) flags = (lua_toboolean(gL, -1) ? 1 : 0); else flags = (UINT8)lua_tointeger(gL, -1); lua_pop(gL, 1); // pop flags if (flags & 2) // flag 2: splitscreen player command. { if (!splitscreen) { lua_pop(gL, 1); // pop command info table return; // can't execute splitscreen command without player 2! } playernum = secondarydisplayplayer; } if (netgame) { // Send the command through the network UINT8 argc; lua_pop(gL, 1); // pop command info table if (flags & 1 && !server && !IsPlayerAdmin(playernum)) // flag 1: only server/admin can use this command. { CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n")); return; } if (COM_Argc() > UINT8_MAX) argc = UINT8_MAX; else argc = (UINT8)COM_Argc(); if (argc == UINT8_MAX) len = UINT16_MAX; else len = (argc+1)*256; buf = malloc(len); p = buf; WRITEUINT8(p, argc); for (i = 0; i < argc; i++) WRITESTRINGN(p, COM_Argv(i), 255); if (flags & 2) SendNetXCmd2(XD_LUACMD, buf, p-buf); else SendNetXCmd(XD_LUACMD, buf, p-buf); free(buf); return; } // Do the command locally, NetXCmds don't go through outside of GS_LEVEL || GS_INTERMISSION lua_rawgeti(gL, -1, 1); // push function from command info table I_Assert(lua_isfunction(gL, -1)); lua_remove(gL, -2); // pop command info table LUA_PushUserdata(gL, &players[playernum], META_PLAYER); for (i = 1; i < COM_Argc(); i++) lua_pushstring(gL, COM_Argv(i)); LUA_Call(gL, (int)COM_Argc()); // COM_Argc is 1-based, so this will cover the player we passed too. }