Пример #1
0
/*
 * @brief
 */
void WriteAASFile(void) {
	char path[MAX_QPATH];
	file_t *f;

	StripExtension(bsp_name, path);
	g_strlcat(path, ".aas", sizeof(path));

	if (!(f = Fs_OpenWrite(path))) {
		Com_Error(ERR_FATAL, "Couldn't open %s for writing\n", path);
	}

	Com_Print("Writing %d AAS nodes..\n", d_aas.num_nodes);

	SwapAASFile();

	d_bsp_header_t header;
	memset(&header, 0, sizeof(header));

	header.ident = LittleLong(AAS_IDENT);
	header.version = LittleLong(AAS_VERSION);

	Fs_Write(f, &header, 1, sizeof(header));

	d_bsp_lump_t *lump = &header.lumps[AAS_LUMP_NODES];
	WriteLump(f, lump, d_aas.nodes, sizeof(d_aas_node_t) * d_aas.num_nodes);

	// rewrite the header with the populated lumps

	Fs_Seek(f, 0);
	Fs_Write(f, &header, 1, sizeof(header));

	Fs_Close(f);
}
Пример #2
0
/*
 * @brief Writes the specified lump to the AAS file.
 */
static void WriteLump(file_t *f, d_bsp_lump_t *lump, void *data, size_t len) {

	lump->file_ofs = LittleLong((int32_t) Fs_Tell(f));
	lump->file_len = LittleLong((int32_t) len);

	Fs_Write(f, data, 1, (len + 3) & ~3);
}
Пример #3
0
/*
 * @brief Dumps the current net message, prefixed by the length.
 */
void Cl_WriteDemoMessage(void) {
	int32_t len;

	if (!cls.demo_file)
		return;

	// if we received an uncompressed frame, write the demo header
	if (cl.frame.delta_frame < 1 && !Fs_Tell(cls.demo_file)) {
		Cl_WriteDemoHeader();
	}

	// the first eight bytes are just packet sequencing stuff
	len = LittleLong(net_message.size - 8);
	Fs_Write(cls.demo_file, &len, sizeof(len), 1);
	Fs_Write(cls.demo_file, net_message.data + 8, len, 1);
}
Пример #4
0
/*
 * Pak_CreatePakstream
 *
 * Allocate a new Pakfile for creating a new archive from arbitrary resources.
 */
pak_t *Pak_CreatePakstream(char *pakfile) {
	FILE *f;
	pak_t *pak;
	pak_header_t header;

	if (!(f = fopen(pakfile, "wb"))) {
		fprintf(stderr, "Couldn't open %s.\n", pakfile);
		err = ERR_DIR;
		return NULL;
	}

	// allocate a new pak
	pak = (pak_t *) Z_Malloc(sizeof(*pak));
	pak->entries = (pak_entry_t *) Z_Malloc(
			sizeof(pak_entry_t) * MAX_PAK_ENTRIES);

	pak->num_entries = 0;

	pak->handle = f;
	strcpy(pak->file_name, pakfile);

	// stuff a bogus header for now
	memset(&header, 0, sizeof(header));
	Fs_Write(&header, sizeof(header), 1, pak->handle);

	return pak;
}
Пример #5
0
END_TEST

START_TEST(check_Ms_BlacklistServer) {
	file_t *f = Fs_OpenAppend("servers-blacklist");
	ck_assert_msg(f != NULL, "Failed to open servers-blacklist");

	const char *test = "192.168.0.*\n";
	int64_t len = Fs_Write(f, (void *) test, 1, strlen(test));

	ck_assert_msg((size_t) len == strlen(test), "Failed to write servers-blacklist");
	ck_assert_msg(Fs_Close(f), "Failed to close servers-blacklist");

	struct sockaddr_in addr;
	memset(&addr, 0, sizeof(addr));

	*(in_addr_t *) &addr.sin_addr = inet_addr("192.168.0.1");
	addr.sin_family = AF_INET;
	addr.sin_port = htons(PORT_SERVER);

	ck_assert_msg(Ms_BlacklistServer(&addr), "Missed %s", inet_ntoa(addr.sin_addr));

	*(in_addr_t *) &addr.sin_addr = inet_addr("127.0.0.1");

	ck_assert_msg(!Ms_BlacklistServer(&addr), "False positive for %s", inet_ntoa(addr.sin_addr));

}
Пример #6
0
/*
 * Pak_ClosePakstream
 *
 * Finalizes and frees a newly created Pakfile archive.
 */
void Pak_ClosePakstream(pak_t *pak) {
	pak_header_t header;
	int i;

	header.ident = PAK_HEADER;
	header.dir_len = pak->num_entries * sizeof(pak_entry_t);
	header.dir_ofs = ftell(pak->handle);

	// write the directory (table of contents) of entries
	for (i = 0; i < pak->num_entries; i++)
		Fs_Write(&pak->entries[i], sizeof(pak_entry_t), 1, pak->handle);

	// go back to the beginning to finalize header
	fseek(pak->handle, 0, SEEK_SET);
	Fs_Write(&header, sizeof(pak_header_t), 1, pak->handle);

	Pak_FreePakfile(pak);
}
Пример #7
0
/*
 * Cl_WriteDemoMessage
 *
 * Dumps the current net message, prefixed by the length.
 */
void Cl_WriteDemoMessage(void) {
	int size;

	if (!cls.demo_file)
		return;

	if (cls.demo_waiting) // we have not yet received a non-delta frame
		return;

	if (!ftell(cls.demo_file)) // write header
		Cl_WriteDemoHeader();

	// the first eight bytes are just packet sequencing stuff
	size = LittleLong(net_message.size - 8);
	Fs_Write(&size, 4, 1, cls.demo_file);

	// write the message payload
	Fs_Write(net_message.data + 8, size, 1, cls.demo_file);
}
Пример #8
0
/**
 * @brief Dumps the current net message, prefixed by the length.
 */
void Cl_WriteDemoMessage(void) {

	if (!cls.demo_file) {
		return;
	}

	if (!Fs_Tell(cls.demo_file)) {
		if (cl.frame.delta_frame_num < 0) {
			Com_Debug(DEBUG_CLIENT, "Received uncompressed frame, writing demo header..\n");
			Cl_WriteDemoHeader();
		} else {
			return; // wait for an uncompressed packet
		}
	}

	// the first eight bytes are just packet sequencing stuff
	const int32_t len = LittleLong((int32_t) (net_message.size - 8));

	Fs_Write(cls.demo_file, &len, sizeof(len), 1);
	Fs_Write(cls.demo_file, net_message.data + 8, len, 1);
}
Пример #9
0
/*
 * @brief A download message has been received from the server.
 */
static void Cl_ParseDownload(void) {
	int32_t size, percent;

	// read the data
	size = Net_ReadShort(&net_message);
	percent = Net_ReadByte(&net_message);
	if (size < 0) {
		Com_Debug("Server does not have this file\n");
		if (cls.download.file) {
			// if here, we tried to resume a file but the server said no
			Fs_Close(cls.download.file);
			cls.download.file = NULL;
		}
		Cl_RequestNextDownload();
		return;
	}

	// open the file if not opened yet
	if (!cls.download.file) {

		if (!(cls.download.file = Fs_OpenWrite(cls.download.tempname))) {
			net_message.read += size;
			Com_Warn("Failed to open %s\n", cls.download.tempname);
			Cl_RequestNextDownload();
			return;
		}
	}

	Fs_Write(cls.download.file, net_message.data + net_message.read, 1, size);

	net_message.read += size;

	if (percent != 100) {
		Net_WriteByte(&cls.net_chan.message, CL_CMD_STRING);
		Net_WriteString(&cls.net_chan.message, "nextdl");
	} else {
		Fs_Close(cls.download.file);
		cls.download.file = NULL;

		// add new archives to the search path
		if (Fs_Rename(cls.download.tempname, cls.download.name)) {
			if (strstr(cls.download.name, ".zip")) {
				Fs_AddToSearchPath(cls.download.name);
			}
		} else {
			Com_Error(ERR_DROP, "Failed to rename %s\n", cls.download.name);
		}

		// get another file if needed
		Cl_RequestNextDownload();
	}
}
Пример #10
0
/*
 * Pak_ExtractPakfile
 *
 * A convenience function for deserializing a Pakfile to the filesystem.
 */
void Pak_ExtractPakfile(const char *pakfile, char *dir, boolean_t test) {
	pak_t *pak;
	FILE *f;
	void *p;
	int i;

	if (dir && chdir(dir) == -1) {
		fprintf(stderr, "Couldn't unpak to %s.\n", dir);
		err = ERR_DIR;
		return;
	}

	if (!(pak = Pak_ReadPakfile(pakfile))) {
		err = ERR_PAK;
		return;
	}

	for (i = 0; i < pak->num_entries; i++) {

		if (test) { // print contents and continue
			printf("Contents %s (%d bytes).\n", pak->entries[i].name,
					pak->entries[i].file_len);
			continue;
		}

		Pak_MakePath(pak->entries[i].name);

		if (!(f = fopen(pak->entries[i].name, "wb"))) {
			fprintf(stderr, "Couldn't write %s.\n", pak->entries[i].name);
			err = ERR_PAK;
			continue;
		}

		fseek(pak->handle, pak->entries[i].file_ofs, SEEK_SET);

		p = (void *) Z_Malloc(pak->entries[i].file_len);

		Fs_Read(p, 1, pak->entries[i].file_len, pak->handle);

		Fs_Write(p, 1, pak->entries[i].file_len, f);

		Fs_CloseFile(f);
		Z_Free(p);

		printf("Extracted %s (%d bytes).\n", pak->entries[i].name,
				pak->entries[i].file_len);
	}

	Pak_FreePakfile(pak);
}
Пример #11
0
/**
 * @brief Stop recording a demo
 */
void Cl_Stop_f(void) {
	int32_t len = -1;

	if (!cls.demo_file) {
		Com_Print("Not recording a demo\n");
		return;
	}

	// finish up
	Fs_Write(cls.demo_file, &len, sizeof(len), 1);
	Fs_Close(cls.demo_file);

	cls.demo_file = NULL;
	Com_Print("Stopped demo\n");
}
Пример #12
0
	}END_TEST

START_TEST(check_Fs_OpenWrite)
	{
		file_t *f = Fs_OpenWrite(__func__);

		ck_assert_msg(f != NULL, "Failed to open %s", __func__);

		const char *testing = "testing";
		int64_t len = Fs_Write(f, (void *) testing, 1, strlen(testing));

		ck_assert_msg((size_t) len == strlen(testing), "Failed to write %s", __func__);
		ck_assert_msg(Fs_Close(f), "Failed to close %s", __func__);

	}END_TEST
Пример #13
0
/*
 * Cl_Stop_f
 *
 * Stop recording a demo
 */
void Cl_Stop_f(void) {
	int size;

	if (!cls.demo_file) {
		Com_Print("Not recording a demo.\n");
		return;
	}

	// finish up
	size = -1;
	Fs_Write(&size, 4, 1, cls.demo_file);
	Fs_CloseFile(cls.demo_file);

	cls.demo_file = NULL;
	Com_Print("Stopped demo.\n");

	// inform server we're done recording
	Cvar_ForceSet("recording", "0");
}
Пример #14
0
/*
 * Pak_AddEntry
 *
 * Add an entry to the specified Pakfile stream.
 */
void Pak_AddEntry(pak_t *pak, char *name, int len, void *p) {
	char *c;

	if (pak->num_entries == MAX_PAK_ENTRIES) {
		fprintf(stderr, "Maximum pak entries (4096) reached.\n");
		return;
	}

	c = name; // strip './' from names
	if (!strncmp(c, "./", 2))
		c += 2;

	memset(pak->entries[pak->num_entries].name, 0, 56);
	strncpy(pak->entries[pak->num_entries].name, c, 55);

	pak->entries[pak->num_entries].file_len = len;
	pak->entries[pak->num_entries].file_ofs = ftell(pak->handle);

	Fs_Write(p, len, 1, pak->handle);

	printf("Added %s (%d bytes).\n", c, len);

	pak->num_entries++;
}
Пример #15
0
/**
 * @brief Writes server_data, config_strings, and baselines once a non-delta
 * compressed frame arrives from the server.
 */
static void Cl_WriteDemoHeader(void) {
	static entity_state_t null_state;
	mem_buf_t msg;
	byte buffer[MAX_MSG_SIZE];

	// write out messages to hold the startup information
	Mem_InitBuffer(&msg, buffer, sizeof(buffer));

	// write the server data
	Net_WriteByte(&msg, SV_CMD_SERVER_DATA);
	Net_WriteShort(&msg, PROTOCOL_MAJOR);
	Net_WriteShort(&msg, cls.cgame->protocol);
	Net_WriteByte(&msg, 1); // demo_server byte
	Net_WriteString(&msg, Cvar_GetString("game"));
	Net_WriteShort(&msg, cl.client_num);
	Net_WriteString(&msg, cl.config_strings[CS_NAME]);

	// and config_strings
	for (int32_t i = 0; i < MAX_CONFIG_STRINGS; i++) {
		if (*cl.config_strings[i] != '\0') {
			if (msg.size + strlen(cl.config_strings[i]) + 32 > msg.max_size) { // write it out
				const int32_t len = LittleLong((int32_t) msg.size);
				Fs_Write(cls.demo_file, &len, sizeof(len), 1);
				Fs_Write(cls.demo_file, msg.data, msg.size, 1);
				msg.size = 0;
			}

			Net_WriteByte(&msg, SV_CMD_CONFIG_STRING);
			Net_WriteShort(&msg, i);
			Net_WriteString(&msg, cl.config_strings[i]);
		}
	}

	// and baselines
	for (size_t i = 0; i < lengthof(cl.entities); i++) {
		entity_state_t *ent = &cl.entities[i].baseline;
		if (!ent->number) {
			continue;
		}

		if (msg.size + 64 > msg.max_size) { // write it out
			const int32_t len = LittleLong((int32_t) msg.size);
			Fs_Write(cls.demo_file, &len, sizeof(len), 1);
			Fs_Write(cls.demo_file, msg.data, msg.size, 1);
			msg.size = 0;
		}

		Net_WriteByte(&msg, SV_CMD_BASELINE);
		Net_WriteDeltaEntity(&msg, &null_state, &cl.entities[i].baseline, true);
	}

	Net_WriteByte(&msg, SV_CMD_CBUF_TEXT);
	Net_WriteString(&msg, "precache 0\n");

	// write it to the demo file

	const int32_t len = LittleLong((int32_t) msg.size);

	Fs_Write(cls.demo_file, &len, sizeof(len), 1);
	Fs_Write(cls.demo_file, msg.data, msg.size, 1);

	Com_Debug(DEBUG_CLIENT, "Demo started\n");
	// the rest of the demo file will be individual frames
}
Пример #16
0
/*
 * Cl_WriteDemoHeader
 *
 * Writes server_data, config_strings, and baselines once a non-delta
 * compressed frame arrives from the server.
 */
static void Cl_WriteDemoHeader(void) {
	byte buffer[MAX_MSG_SIZE];
	size_buf_t msg;
	int i;
	int len;
	entity_state_t null_state;

	// write out messages to hold the startup information
	Sb_Init(&msg, buffer, sizeof(buffer));

	// write the server data
	Msg_WriteByte(&msg, SV_CMD_SERVER_DATA);
	Msg_WriteLong(&msg, PROTOCOL);
	Msg_WriteLong(&msg, cl.server_count);
	Msg_WriteLong(&msg, cl.server_frame_rate);
	Msg_WriteByte(&msg, 1); // demo_server byte
	Msg_WriteString(&msg, Cvar_GetString("game"));
	Msg_WriteShort(&msg, cl.player_num);
	Msg_WriteString(&msg, cl.config_strings[CS_NAME]);

	// and config_strings
	for (i = 0; i < MAX_CONFIG_STRINGS; i++) {
		if (*cl.config_strings[i] != '\0') {
			if (msg.size + strlen(cl.config_strings[i]) + 32 > msg.max_size) { // write it out
				len = LittleLong(msg.size);
				Fs_Write(&len, 4, 1, cls.demo_file);
				Fs_Write(msg.data, msg.size, 1, cls.demo_file);
				msg.size = 0;
			}

			Msg_WriteByte(&msg, SV_CMD_CONFIG_STRING);
			Msg_WriteShort(&msg, i);
			Msg_WriteString(&msg, cl.config_strings[i]);
		}
	}

	// and baselines
	for (i = 0; i < MAX_EDICTS; i++) {
		entity_state_t *ent = &cl.entities[i].baseline;
		if (!ent->number)
			continue;

		if (msg.size + 64 > msg.max_size) { // write it out
			len = LittleLong(msg.size);
			Fs_Write(&len, 4, 1, cls.demo_file);
			Fs_Write(msg.data, msg.size, 1, cls.demo_file);
			msg.size = 0;
		}

		memset(&null_state, 0, sizeof(null_state));

		Msg_WriteByte(&msg, SV_CMD_ENTITY_BASELINE);
		Msg_WriteDeltaEntity(&null_state, &cl.entities[i].baseline, &msg, true,
				true);
	}

	Msg_WriteByte(&msg, SV_CMD_CBUF_TEXT);
	Msg_WriteString(&msg, "precache 0\n");

	// write it to the demo file

	len = LittleLong(msg.size);
	Fs_Write(&len, 4, 1, cls.demo_file);
	Fs_Write(msg.data, msg.size, 1, cls.demo_file);

	Com_Print("Recording to %s.\n", cls.demo_path);
	// the rest of the demo file will be individual frames
}
Пример #17
0
	long status;

	_Bool ready;
	_Bool success;

	char error_buffer[MAX_STRING_CHARS];
} cl_http_state_t;

static cl_http_state_t cl_http_state;

/*
 * @brief cURL HTTP receive handler.
 */
static size_t Cl_HttpDownload_Receive(void *buffer, size_t size, size_t count, void *p __attribute__((unused))) {
	const int64_t i = Fs_Write(cls.download.file, buffer, size, count);
	return i > 0 ? (size_t) i : 0;
}

/*
 * @brief If a download is currently taking place, clean it up. This is called
 * both to finalize completed downloads as well as abort incomplete ones.
 */
void Cl_HttpDownload_Complete() {

	if (!cls.download.file || !cls.download.http)
		return;

	curl_multi_remove_handle(cl_http_state.curlm, cl_http_state.curl); // cleanup curl

	Fs_Close(cls.download.file); // always close the file