Beispiel #1
0
/** 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;
}
Beispiel #2
0
void LUA_Archive(void)
{
	INT32 i;
	thinker_t *th;

	if (gL)
		lua_newtable(gL); // tables to be archived.

	for (i = 0; i < MAXPLAYERS; i++)
	{
		if (!playeringame[i])
			continue;
		// all players in game will be archived, even if they just add a 0.
		ArchiveExtVars(&players[i], "player");
	}

	for (th = thinkercap.next; th != &thinkercap; th = th->next)
		if (th->function.acp1 == (actionf_p1)P_MobjThinker)
		{
			// archive function will determine when to skip mobjs,
			// and write mobjnum in otherwise.
			ArchiveExtVars(th, "mobj");
		}
	WRITEUINT32(save_p, UINT32_MAX); // end of mobjs marker, replaces mobjnum.

	NetArchiveHook(NetArchive); // call the NetArchive hook in archive mode
	ArchiveTables();

	if (gL)
		lua_pop(gL, 1); // pop tables
}
Beispiel #3
0
static void ArchiveExtVars(void *pointer, const char *ptype)
{
	int TABLESINDEX;
	UINT16 i;

	if (!gL) {
		if (fastcmp(ptype,"player")) // players must always be included, even if no vars
			WRITEUINT16(save_p, 0);
		return;
	}

	TABLESINDEX = lua_gettop(gL);

	lua_getfield(gL, LUA_REGISTRYINDEX, LREG_EXTVARS);
	I_Assert(lua_istable(gL, -1));
	lua_pushlightuserdata(gL, pointer);
	lua_rawget(gL, -2);
	lua_remove(gL, -2); // pop LREG_EXTVARS

	if (!lua_istable(gL, -1))
	{ // no extra values table
		lua_pop(gL, 1);
		if (fastcmp(ptype,"player")) // players must always be included, even if no vars
			WRITEUINT16(save_p, 0);
		return;
	}

	lua_pushnil(gL);
	for (i = 0; lua_next(gL, -2); i++)
		lua_pop(gL, 1);

	if (i == 0 && !fastcmp(ptype,"player")) // skip anything that has an empty table and isn't a player.
		return;
	if (fastcmp(ptype,"mobj")) // mobjs must write their mobjnum as a header
		WRITEUINT32(save_p, ((mobj_t *)pointer)->mobjnum);
	WRITEUINT16(save_p, i);
	lua_pushnil(gL);
	while (lua_next(gL, -2))
	{
		I_Assert(lua_type(gL, -2) == LUA_TSTRING);
		WRITESTRING(save_p, lua_tostring(gL, -2));
		if (ArchiveValue(TABLESINDEX, -1) == 2)
			CONS_Alert(CONS_ERROR, "Type of value for %s entry '%s' (%s) could not be archived!\n", ptype, lua_tostring(gL, -2), luaL_typename(gL, -1));
		lua_pop(gL, 1);
	}

	lua_pop(gL, 1);
}
Beispiel #4
0
/** 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;
}
Beispiel #5
0
static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
{
	if (myindex < 0)
		myindex = lua_gettop(gL)+1+myindex;
	switch (lua_type(gL, myindex))
	{
	case LUA_TNONE:
	case LUA_TNIL:
		WRITEUINT8(save_p, ARCH_NULL);
		break;
	// This might be a problem. D:
	case LUA_TLIGHTUSERDATA:
	case LUA_TTHREAD:
	case LUA_TFUNCTION:
		WRITEUINT8(save_p, ARCH_NULL);
		return 2;
	case LUA_TBOOLEAN:
		WRITEUINT8(save_p, ARCH_BOOLEAN);
		WRITEUINT8(save_p, lua_toboolean(gL, myindex));
		break;
	case LUA_TNUMBER:
	{
		lua_Integer number = lua_tointeger(gL, myindex);
		if (number < 0) {
			WRITEUINT8(save_p, ARCH_SIGNED);
			WRITEFIXED(save_p, number);
		} else {
			WRITEUINT8(save_p, ARCH_UNSIGNED);
			WRITEANGLE(save_p, number);
		}
		break;
	}
	case LUA_TSTRING:
		WRITEUINT8(save_p, ARCH_STRING);
		WRITESTRING(save_p, lua_tostring(gL, myindex));
		break;
	case LUA_TTABLE:
	{
		boolean found = false;
		INT32 i;
		UINT16 t = (UINT16)lua_objlen(gL, TABLESINDEX);

		for (i = 1; i <= t && !found; i++)
		{
			lua_rawgeti(gL, TABLESINDEX, i);
			if (lua_rawequal(gL, myindex, -1))
			{
				t = i;
				found = true;
			}
			lua_pop(gL, 1);
		}
		if (!found)
			t++;

		WRITEUINT8(save_p, ARCH_TABLE);
		WRITEUINT16(save_p, t);

		if (!found)
		{
			lua_pushvalue(gL, myindex);
			lua_rawseti(gL, TABLESINDEX, t);
			return 1;
		}
		break;
	}
	case LUA_TUSERDATA:
		switch (GetUserdataArchType())
		{
		case ARCH_MOBJINFO:
		{
			mobjinfo_t *info = *((mobjinfo_t **)lua_touserdata(gL, myindex));
			WRITEUINT8(save_p, ARCH_MOBJINFO);
			WRITEUINT8(save_p, info - mobjinfo);
			break;
		}
		case ARCH_STATE:
		{
			state_t *state = *((state_t **)lua_touserdata(gL, myindex));
			WRITEUINT8(save_p, ARCH_STATE);
			WRITEUINT8(save_p, state - states);
			break;
		}
		case ARCH_MOBJ:
		{
			mobj_t *mobj = *((mobj_t **)lua_touserdata(gL, myindex));
			if (!mobj)
				WRITEUINT8(save_p, ARCH_NULL);
			else {
				WRITEUINT8(save_p, ARCH_MOBJ);
				WRITEUINT32(save_p, mobj->mobjnum);
			}
			break;
		}
		case ARCH_PLAYER:
		{
			player_t *player = *((player_t **)lua_touserdata(gL, myindex));
			if (!player)
				WRITEUINT8(save_p, ARCH_NULL);
			else {
				WRITEUINT8(save_p, ARCH_PLAYER);
				WRITEUINT8(save_p, player - players);
			}
			break;
		}
		case ARCH_MAPTHING:
		{
			mapthing_t *mapthing = *((mapthing_t **)lua_touserdata(gL, myindex));
			if (!mapthing)
				WRITEUINT8(save_p, ARCH_NULL);
			else {
				WRITEUINT8(save_p, ARCH_MAPTHING);
				WRITEUINT16(save_p, mapthing - mapthings);
			}
			break;
		}
		case ARCH_VERTEX:
		{
			vertex_t *vertex = *((vertex_t **)lua_touserdata(gL, myindex));
			if (!vertex)
				WRITEUINT8(save_p, ARCH_NULL);
			else {
				WRITEUINT8(save_p, ARCH_VERTEX);
				WRITEUINT16(save_p, vertex - vertexes);
			}
			break;
		}
		case ARCH_LINE:
		{
			line_t *line = *((line_t **)lua_touserdata(gL, myindex));
			if (!line)
				WRITEUINT8(save_p, ARCH_NULL);
			else {
				WRITEUINT8(save_p, ARCH_LINE);
				WRITEUINT16(save_p, line - lines);
			}
			break;
		}
		case ARCH_SIDE:
		{
			side_t *side = *((side_t **)lua_touserdata(gL, myindex));
			if (!side)
				WRITEUINT8(save_p, ARCH_NULL);
			else {
				WRITEUINT8(save_p, ARCH_SIDE);
				WRITEUINT16(save_p, side - sides);
			}
			break;
		}
		case ARCH_SUBSECTOR:
		{
			subsector_t *subsector = *((subsector_t **)lua_touserdata(gL, myindex));
			if (!subsector)
				WRITEUINT8(save_p, ARCH_NULL);
			else {
				WRITEUINT8(save_p, ARCH_SUBSECTOR);
				WRITEUINT16(save_p, subsector - subsectors);
			}
			break;
		}
		case ARCH_SECTOR:
		{
			sector_t *sector = *((sector_t **)lua_touserdata(gL, myindex));
			if (!sector)
				WRITEUINT8(save_p, ARCH_NULL);
			else {
				WRITEUINT8(save_p, ARCH_SECTOR);
				WRITEUINT16(save_p, sector - sectors);
			}
			break;
		}
		case ARCH_MAPHEADER:
		{
			mapheader_t *header = *((mapheader_t **)lua_touserdata(gL, myindex));
			if (!header)
				WRITEUINT8(save_p, ARCH_NULL);
			else {
				WRITEUINT8(save_p, ARCH_MAPHEADER);
				WRITEUINT16(save_p, header - *mapheaderinfo);
			}
			break;
		}
		default:
			WRITEUINT8(save_p, ARCH_NULL);
			return 2;
		}
		break;
	}
	return 0;
}