예제 #1
0
파일: net_ws.cpp 프로젝트: omertelli/rehlds
/* <d41a9> ../engine/net_ws.c:1454 */
void NET_AllocateQueues(void)
{
	net_messages_t *p;
	for (int i = 0; i < NUM_MSG_QUEUES; i++)
	{
		p = (net_messages_t *)Mem_ZeroMalloc(sizeof(net_messages_t));
		p->buffer = (unsigned char *)Mem_ZeroMalloc(MSG_QUEUE_SIZE);
		p->preallocated = 1;
		p->next = normalqueue;
		normalqueue = p;
	}

	NET_StartThread();
}
예제 #2
0
파일: net_chan.cpp 프로젝트: Chuvi-w/rehlds
fragbuf_t *Netchan_AllocFragbuf(void)
{
	fragbuf_t *buf;

	buf = (fragbuf_t *)Mem_ZeroMalloc(sizeof(fragbuf_t));
	buf->bufferid = 0;
	buf->frag_message.cursize = 0;
	buf->frag_message.data = buf->frag_message_buf;
	buf->frag_message.maxsize = sizeof(buf->frag_message_buf);
	buf->frag_message.buffername = "Frag Buffer Alloc'd";
	buf->next = nullptr;

	return buf;
}
예제 #3
0
NetChannel::fragbuf_t *NetChannel::FindBufferById(fragbuf_t **pplist, int id, bool allocate)
{
	fragbuf_t *list = *pplist;
	fragbuf_t *pnewbuf;

	while (list)
	{
		if (list->bufferId == id)
			return list;

		list = list->next;
	}

	if (!allocate)
		return nullptr;

	// Create new entry
	pnewbuf = (fragbuf_t *)Mem_ZeroMalloc(sizeof(fragbuf_t));
	pnewbuf->bufferId = id;
	AddBufferToList(pplist, pnewbuf);

	return pnewbuf;
}
예제 #4
0
파일: net_chan.cpp 프로젝트: Chuvi-w/rehlds
int Netchan_CreateFileFragments(qboolean server, netchan_t *chan, const char *filename)
#ifdef REHLDS_FIXES
{
	if (!server)
		return Netchan_CreateFileFragments_(server, chan, filename);

	if (!FS_FileExists(filename))
		return FALSE;
	if (FS_FileSize(filename) > sv_filetransfermaxsize.value)
		return FALSE;

	auto wait = (fragbufwaiting_t *)Mem_ZeroMalloc(sizeof(fragbufwaiting_t));

	auto buf = Netchan_AllocFragbuf();
	buf->bufferid = 1;
	buf->isbuffer = false;
	buf->isfile = true;
	Q_strncpy(buf->filename, filename, sizeof(buf->filename));
	buf->filename[sizeof(buf->filename) - 1] = '\0';

	Netchan_AddFragbufToTail(wait, buf);

	if (!chan->waitlist[FRAG_FILE_STREAM])
	{
		chan->waitlist[FRAG_FILE_STREAM] = wait;
	}
	else
	{
		auto p = chan->waitlist[FRAG_FILE_STREAM];
		while (p->next)
			p = p->next;

		p->next = wait;
	}

	return TRUE;
}
예제 #5
0
bool BitBuffer::Resize(unsigned int size)
{
	Free();

	m_Data = (unsigned char *)Mem_ZeroMalloc(size + 4);
	m_CurSize = 0;
	m_Overflowed = false;

	if (m_Data)
	{
		m_CurByte = m_Data;
		m_MaxSize = size;

		m_OwnData = true;
		m_LittleEndian = true;
		return true;
	}

	m_MaxSize = 0;
	m_OwnData = false;
	m_CurByte = nullptr;

	return false;
}
예제 #6
0
bool SystemWrapper::RegisterCommand(char *name, ISystemModule *module, int commandID)
{
	command_t *cmd = (command_t *)m_Commands.GetFirst();
	while (cmd)
	{
		if (Q_stricmp(cmd->name, name) == 0) {
			Printf("WARNING! System::RegisterCommand: command \"%s\" already exists.\n", name);
			return false;
		}

		cmd = (command_t *)m_Commands.GetNext();
	}

	cmd = (command_t *)Mem_ZeroMalloc(sizeof(command_t));

	Q_strlcpy(cmd->name, name);
	cmd->module = module;
	cmd->commandID = commandID;

	m_Commands.Add(cmd);
	Cmd_AddWrapperCommand(cmd->name, SystemWrapper_CommandForwarder);

	return true;
}
예제 #7
0
/* <2a7cb> ../engine/hashpak.c:65 */
qboolean HPAK_GetDataPointer(char *pakname, struct resource_s *pResource, unsigned char **pbuffer, int *bufsize)
{
	qboolean retval = FALSE;
	FileHandle_t fp;
	hash_pack_header_t header;
	hash_pack_directory_t directory;
	hash_pack_entry_t *entry;
	char name[MAX_PATH];
	byte *pbuf;

	if (pbuffer)
		*pbuffer = NULL;

	if (bufsize)
		*bufsize = 0;

	if (gp_hpak_queue)
	{
		for (hash_pack_queue_t *p = gp_hpak_queue; p != NULL; p = p->next)
		{
			if (Q_stricmp(p->pakname, pakname) != 0 || Q_memcmp(p->resource.rgucMD5_hash, pResource->rgucMD5_hash, 16) != 0)
				continue;

			if (pbuffer)
			{
				pbuf = (byte *)Mem_Malloc(p->datasize);
				if (!pbuf)
					Sys_Error("Error allocating %i bytes for hpak!", p->datasize);
				Q_memcpy((void *)pbuf, p->data, p->datasize);
				*pbuffer = pbuf;
			}
			if (bufsize)
				*bufsize = p->datasize;
			return TRUE;
		}
	}

	Q_snprintf(name, ARRAYSIZE(name), "%s", pakname);
#ifdef REHLDS_FIXES
	name[ARRAYSIZE(name) - 1] = 0;
#endif // REHLDS_FIXES

	COM_DefaultExtension(name, HASHPAK_EXTENSION);
	fp = FS_Open(name, "rb");
	if (!fp)
	{
		return FALSE;
	}
	FS_Read(&header, sizeof(hash_pack_header_t), 1, fp);
	if (Q_strncmp(header.szFileStamp, "HPAK", sizeof(header.szFileStamp)) != 0)
	{
		Con_Printf("%s is not an HPAK file\n", name);
		FS_Close(fp);
		return FALSE;
	}
	if (header.version != HASHPAK_VERSION)
	{
		Con_Printf("HPAK_List:  version mismatch\n");
		FS_Close(fp);
		return FALSE;
	}
	FS_Seek(fp, header.nDirectoryOffset, FILESYSTEM_SEEK_HEAD);
	FS_Read(&directory.nEntries, 4, 1, fp);
	if (directory.nEntries < 1 || (unsigned int)directory.nEntries > MAX_FILE_ENTRIES)
	{
		Con_Printf("ERROR: HPAK had bogus # of directory entries:  %i\n", directory.nEntries);
		FS_Close(fp);
		return FALSE;
	}
	directory.p_rgEntries = (hash_pack_entry_t *)Mem_ZeroMalloc(sizeof(hash_pack_entry_t) * directory.nEntries);
	FS_Read(directory.p_rgEntries, sizeof(hash_pack_entry_t) * directory.nEntries, 1, fp);

	for (int i = 0; i < directory.nEntries; i++)
	{
		entry = &directory.p_rgEntries[i];

		if (Q_memcmp(entry->resource.rgucMD5_hash, pResource->rgucMD5_hash, 16) != 0)
			continue;

		retval = TRUE;
		FS_Seek(fp, entry->nOffset, FILESYSTEM_SEEK_HEAD);

		if (pbuffer && entry->nFileLength > 0)
		{
			if (bufsize)
				*bufsize = entry->nFileLength;
			pbuf = (byte *)Mem_Malloc(entry->nFileLength);

			if (!pbuf)
			{
				Con_Printf("Couln't allocate %i bytes for HPAK entry\n", entry->nFileLength);

				if (bufsize)
					*bufsize = 0;
				retval = FALSE;
			}

			FS_Read(pbuf, entry->nFileLength, 1, fp);
			*pbuffer = pbuf;
		}
		break;
	}

	Mem_Free(directory.p_rgEntries);
	FS_Close(fp);

	return retval;
}
예제 #8
0
파일: net_chan.cpp 프로젝트: Chuvi-w/rehlds
qboolean Netchan_CopyFileFragments(netchan_t *chan)
{
	fragbuf_t *p;
	int nsize;
	unsigned char *buffer;
	int pos;
	signed int cursize;
	char filename[MAX_PATH];
	char compressor[32];
	fragbuf_s *n;
	qboolean bCompressed;
	unsigned int uncompressedSize;


	if (!chan->incomingready[FRAG_FILE_STREAM])
		return FALSE;

	p = chan->incomingbufs[FRAG_FILE_STREAM];
	if (!p)
	{
		Con_Printf("%s:  Called with no fragments readied\n", __func__);
		chan->incomingready[FRAG_FILE_STREAM] = FALSE;
		return FALSE;
	}

	bCompressed = FALSE;
	SZ_Clear(&net_message);
	MSG_BeginReading();
	SZ_Write(&net_message, p->frag_message.data, p->frag_message.cursize);
	Q_strncpy(filename, MSG_ReadString(), sizeof(filename) - 1);
	filename[sizeof(filename) - 1] = 0;

	Q_strncpy(compressor, MSG_ReadString(), sizeof(compressor) - 1);
	compressor[sizeof(compressor) - 1] = 0;
	if (!Q_stricmp(compressor, "bz2"))
		bCompressed = TRUE;

	uncompressedSize = (unsigned int)MSG_ReadLong();

#ifdef REHLDS_FIXES
	// TODO: this condition is invalid for server->client
	// TODO: add console message for client
	// TODO: add client name to message
	if (uncompressedSize > 1024 * 64) {
		Con_Printf("Received too large file (size=%u)\nFlushing input queue\n", uncompressedSize);
		Netchan_FlushIncoming(chan, 1);
		return FALSE;
	}
#endif

	if (Q_strlen(filename) <= 0)
	{
		Con_Printf("File fragment received with no filename\nFlushing input queue\n");
		Netchan_FlushIncoming(chan, 1);
		return FALSE;
	}

	if (Q_strstr(filename, ".."))
	{
		Con_Printf("File fragment received with relative path, ignoring\n");
		Netchan_FlushIncoming(chan, 1);
		return FALSE;
	}

	if (filename[0] != '!' && !IsSafeFileToDownload(filename))
	{
		Con_Printf("File fragment received with bad path, ignoring\n");
		Netchan_FlushIncoming(chan, 1);
		return FALSE;
	}
	// This prohibits to write files to FS on server
	if (g_pcls.state == ca_dedicated && filename[0] != '!')
	{
		Con_Printf("File fragment received with bad path, ignoring (2)\n");
		Netchan_FlushIncoming(chan, 1);
		return FALSE;
	}

	Q_strncpy(chan->incomingfilename, filename, MAX_PATH - 1);
	chan->incomingfilename[MAX_PATH - 1] = 0;

	if (filename[0] != '!' && FS_FileExists(filename))
	{
		Con_Printf("Can't download %s, already exists\n", filename);
		Netchan_FlushIncoming(chan, 1);
		return TRUE;
	}

	nsize = 0;
	while (p)
	{
		nsize += p->frag_message.cursize;
		if (p == chan->incomingbufs[FRAG_FILE_STREAM])
			nsize -= msg_readcount;
		p = p->next;
	}

	buffer = (unsigned char*)Mem_ZeroMalloc(nsize + 1);
	if (!buffer)
	{
		Con_Printf("Buffer allocation failed on %i bytes\n", nsize + 1);
		Netchan_FlushIncoming(chan, 1);
		return FALSE;
	}

	p = chan->incomingbufs[FRAG_FILE_STREAM];
	pos = 0;
	while (p)
	{
		n = p->next;

		cursize = p->frag_message.cursize;
		// First message has the file name, don't write that into the data stream, just write the rest of the actual data
		if (p == chan->incomingbufs[FRAG_FILE_STREAM])
		{
			// Copy it in
			cursize -= msg_readcount;
			Q_memcpy(&buffer[pos], &p->frag_message.data[msg_readcount], cursize);
			p->frag_message.cursize = cursize;
		}
		else
		{
			Q_memcpy(&buffer[pos], p->frag_message.data, cursize);
		}
		pos += p->frag_message.cursize;
		Mem_Free(p);
		p = n;

	}

	if (bCompressed)
	{
		unsigned char* uncompressedBuffer = (unsigned char*)Mem_Malloc(uncompressedSize);
		Con_DPrintf("Decompressing file %s (%d -> %d)\n", filename, nsize, uncompressedSize);
		BZ2_bzBuffToBuffDecompress((char*)uncompressedBuffer, &uncompressedSize, (char*)buffer, nsize, 1, 0);
		Mem_Free(buffer);
		pos = uncompressedSize;
		buffer = uncompressedBuffer;
	}

	if (filename[0] == '!')
	{
		if (chan->tempbuffer)
		{
			Con_DPrintf("Netchan_CopyFragments:  Freeing holdover tempbuffer\n");
			Mem_Free(chan->tempbuffer);
		}
		chan->tempbuffer = buffer;
		chan->tempbuffersize = pos;
	}
	else
	{
		char filedir[MAX_PATH];
		char *pszFileName;
		FileHandle_t handle;

#ifdef REHLDS_CHECKS
		Q_strncpy(filedir, filename, sizeof(filedir) - 1);
		filedir[sizeof(filedir) - 1] = 0;
#else
		Q_strncpy(filedir, filename, sizeof(filedir));
#endif // REHLDS_CHECKS
		COM_FixSlashes(filedir);
		pszFileName = Q_strrchr(filedir, '\\');
		if (pszFileName)
		{
			*pszFileName = 0;

#ifdef REHLDS_FIXES
			FS_CreateDirHierarchy(filedir, "GAMEDOWNLOAD");
#endif
		}

#ifndef REHLDS_FIXES
		FS_CreateDirHierarchy(filedir, "GAMEDOWNLOAD");
#endif
		handle = FS_OpenPathID(filename, "wb", "GAMEDOWNLOAD");
		if (!handle)
		{
			Con_Printf("File open failed %s\n", filename);
			Netchan_FlushIncoming(chan, 1);

#ifdef REHLDS_FIXES
			Mem_Free(buffer);
#endif
			return FALSE;
		}

		Sys_Printf("COM_WriteFile: %s\n", filename);
		FS_Write(buffer, pos, 1, handle);
		FS_Close(handle);

		Mem_Free(buffer);
	}
	SZ_Clear(&net_message);
	chan->incomingbufs[FRAG_FILE_STREAM] = nullptr;
	chan->incomingready[FRAG_FILE_STREAM] = FALSE;
	msg_readcount = 0;
	return TRUE;
}
예제 #9
0
파일: net_chan.cpp 프로젝트: Chuvi-w/rehlds
int Netchan_CreateFileFragments_(qboolean server, netchan_t *chan, const char *filename)
#endif // REHLDS_FIXES
{
	int chunksize;
	int compressedFileTime;
	FileHandle_t hfile;
	signed int filesize;
	int remaining;
	fragbufwaiting_t *p;
	int send;
	fragbuf_t *buf;
	char compressedfilename[MAX_PATH];
	qboolean firstfragment;
	int bufferid;
	qboolean bCompressed;
	int pos;
	fragbufwaiting_t *wait;
	int uncompressed_size;

	bufferid = 1;
	firstfragment = TRUE;
	bCompressed = FALSE;
	chunksize = chan->pfnNetchan_Blocksize(chan->connection_status);

	Q_snprintf(compressedfilename, sizeof compressedfilename, "%s.ztmp", filename);
	compressedFileTime = FS_GetFileTime(compressedfilename);
	if (compressedFileTime >= FS_GetFileTime(filename) && (hfile = FS_Open(compressedfilename, "rb")))
	{
		filesize = FS_Size(hfile);
		FS_Close(hfile);
		bCompressed = TRUE;
		hfile = FS_Open(filename, "rb");
		if (!hfile)
		{
			Con_Printf("Warning:  Unable to open %s for transfer\n", filename);
			return 0;
		}

		uncompressed_size = FS_Size(hfile);
		if (uncompressed_size > sv_filetransfermaxsize.value)
		{
			FS_Close(hfile);
			Con_Printf("Warning:  File %s is too big to transfer from host %s\n", filename, NET_AdrToString(chan->remote_address));
			return 0;
		}
	}
	else
	{
		hfile = FS_Open(filename, "rb");
		if (!hfile)
		{
			Con_Printf("Warning:  Unable to open %s for transfer\n", filename);
			return 0;
		}
		filesize = FS_Size(hfile);
		if (filesize > sv_filetransfermaxsize.value)
		{
			FS_Close(hfile);
			Con_Printf("Warning:  File %s is too big to transfer from host %s\n", filename, NET_AdrToString(chan->remote_address));
			return 0;
		}

		uncompressed_size = filesize;
		if (sv_filetransfercompression.value != 0.0)
		{
			unsigned char* uncompressed = (unsigned char*)Mem_Malloc(filesize);
			unsigned char* compressed = (unsigned char*)Mem_Malloc(filesize);
			unsigned int compressedSize = filesize;
			FS_Read(uncompressed, filesize, 1, hfile);
			if (BZ_OK == BZ2_bzBuffToBuffCompress((char*)compressed, &compressedSize, (char*)uncompressed, filesize, 9, 0, 30))
			{
				FileHandle_t destFile = FS_Open(compressedfilename, "wb");
				if (destFile)
				{
					Con_DPrintf("Creating compressed version of file %s (%d -> %d)\n", filename, filesize, compressedSize);
					FS_Write(compressed, compressedSize, 1, destFile);
					FS_Close(destFile);
					filesize = compressedSize;
					bCompressed = TRUE;
				}
			}
			Mem_Free(uncompressed);
			Mem_Free(compressed);
		}
	}
	FS_Close(hfile);

	wait = (fragbufwaiting_t *)Mem_ZeroMalloc(0xCu);
	remaining = filesize;
	pos = 0;

	while (remaining)
	{
		send = min(chunksize, remaining);
		buf = Netchan_AllocFragbuf();
		if (!buf)
		{
			Con_Printf("Couldn't allocate fragbuf_t\n");
			Mem_Free(wait);
			if (server)
			{
#ifdef REHLDS_FIXES
				SV_DropClient(&g_psvs.clients[chan->player_slot - 1], 0, "Malloc problem");
#else // REHLDS_FIXES
				SV_DropClient(host_client, 0, "Malloc problem");
#endif // REHLDS_FIXES
				return 0;
			}
			else
			{
				rehlds_syserror("%s: Reverse clientside code", __func__);
				//return 0;
			}
		}

		buf->bufferid = bufferid++;
		SZ_Clear(&buf->frag_message);
		if (firstfragment)
		{
			firstfragment = FALSE;
			MSG_WriteString(&buf->frag_message, filename);
			MSG_WriteString(&buf->frag_message, bCompressed ? "bz2" : "uncompressed");
			MSG_WriteLong(&buf->frag_message, uncompressed_size);
			send -= buf->frag_message.cursize;
		}
		buf->isfile = TRUE;
		buf->iscompressed = bCompressed;
		buf->size = send;
		buf->foffset = pos;

		Q_strncpy(buf->filename, filename, MAX_PATH - 1);
		buf->filename[MAX_PATH - 1] = 0;

		pos += send;
		remaining -= send;

		Netchan_AddFragbufToTail(wait, buf);
	}

	if (!chan->waitlist[FRAG_FILE_STREAM])
	{
		chan->waitlist[FRAG_FILE_STREAM] = wait;
	}
	else
	{
		p = chan->waitlist[FRAG_FILE_STREAM];
		while (p->next)
			p = p->next;

		p->next = wait;
	}

	return 1;
}
예제 #10
0
파일: net_chan.cpp 프로젝트: Chuvi-w/rehlds
void Netchan_CreateFileFragmentsFromBuffer(qboolean server, netchan_t *chan, const char *filename, unsigned char *uncompressed_pbuf, int uncompressed_size)
{
	int chunksize;
	int send;
	fragbufwaiting_t *p;
	fragbuf_t *buf;
	unsigned char *pbuf;
	qboolean bCompressed;
	qboolean firstfragment;
	signed int bufferid;
	int remaining;
	int pos;
	unsigned int size;
	fragbufwaiting_t *wait;

	if (!uncompressed_size)
		return;

	bufferid = 1;
	firstfragment = TRUE;
	size = uncompressed_size;

	pbuf = (unsigned char *)Mem_Malloc(uncompressed_size);
	if (BZ2_bzBuffToBuffCompress((char*)pbuf, &size, (char*)uncompressed_pbuf, uncompressed_size, 9, 0, 30))
	{
		bCompressed = FALSE;
		Mem_Free(pbuf);
		pbuf = uncompressed_pbuf;
		size = uncompressed_size;
	}
	else
	{
		bCompressed = TRUE;
		Con_DPrintf("Compressed %s for transmission (%d -> %d)\n", filename, uncompressed_size, size);
	}

	chunksize = chan->pfnNetchan_Blocksize(chan->connection_status);
	send = chunksize;
	wait = (fragbufwaiting_t *)Mem_ZeroMalloc(0xCu);
	remaining = size;
	pos = 0;

	while (remaining > 0)
	{
		send = min(remaining, chunksize);
		buf = (fragbuf_t *)Netchan_AllocFragbuf();
		if (!buf)
		{
			Con_Printf("Couldn't allocate fragbuf_t\n");
			Mem_Free(wait);
			if (server)
				SV_DropClient(host_client, 0, "Malloc problem");
			else
				rehlds_syserror("%s:Reverse me: client-side code", __func__);

#ifdef REHLDS_FIXES
			if (bCompressed) {
				Mem_Free(pbuf);
			}
#endif
			return;
		}

		buf->bufferid = bufferid++;
		SZ_Clear(&buf->frag_message);
		if (firstfragment)
		{
			firstfragment = FALSE;
			MSG_WriteString(&buf->frag_message, filename);
			MSG_WriteString(&buf->frag_message, bCompressed ? "bz2" : "uncompressed");
			MSG_WriteLong(&buf->frag_message, uncompressed_size);
			send -= buf->frag_message.cursize;
		}

		buf->isbuffer = TRUE;
		buf->isfile = TRUE;
		buf->size = send;
		buf->foffset = pos;

		MSG_WriteBuf(&buf->frag_message, send, &pbuf[pos]);
		pos += send;
		remaining -= send;

		Netchan_AddFragbufToTail(wait, buf);
	}

	if (!chan->waitlist[FRAG_FILE_STREAM]) {
		chan->waitlist[FRAG_FILE_STREAM] = wait;
	}
	else
	{
		p = chan->waitlist[FRAG_FILE_STREAM];
		while (p->next)
			p = p->next;

		p->next = wait;
	}

#ifdef REHLDS_FIXES
	if (bCompressed) {
		Mem_Free(pbuf);
	}
#endif
}
예제 #11
0
파일: net_chan.cpp 프로젝트: Chuvi-w/rehlds
void Netchan_CreateFragments_(qboolean server, netchan_t *chan, sizebuf_t *msg)
{
	fragbuf_t *buf;
	int chunksize;
	int send;
	int remaining;
	int pos;
	int bufferid = 1;
	fragbufwaiting_t *wait, *p;

	if (msg->cursize == 0)
	{
		return;
	}

	// Compress if not done already
	if (*(uint32 *)msg->data != MAKEID('B', 'Z', '2', '\0'))
	{
		unsigned char compressed[65536];
		char hdr[4] = "BZ2";
		unsigned int compressedSize = msg->cursize - sizeof(hdr);	// we should fit in same data buffer minus 4 bytes for a header
		if (!BZ2_bzBuffToBuffCompress((char *)compressed, &compressedSize, (char *)msg->data, msg->cursize, 9, 0, 30))
		{
			Con_DPrintf("Compressing split packet (%d -> %d bytes)\n", msg->cursize, compressedSize);
			Q_memcpy(msg->data, hdr, sizeof(hdr));
			Q_memcpy(msg->data + sizeof(hdr), compressed, compressedSize);
			msg->cursize = compressedSize + sizeof(hdr);
		}
	}

	chunksize = chan->pfnNetchan_Blocksize(chan->connection_status);

	wait = (fragbufwaiting_t *)Mem_ZeroMalloc(sizeof(fragbufwaiting_t));

	remaining = msg->cursize;
	pos = 0;
	while (remaining > 0)
	{
		send = min(remaining, chunksize);
		remaining -= send;

		buf = Netchan_AllocFragbuf();
		if (!buf)
		{
			return;
		}

		buf->bufferid = bufferid++;

		// Copy in data
		SZ_Clear(&buf->frag_message);
		SZ_Write(&buf->frag_message, &msg->data[pos], send);
		pos += send;

		Netchan_AddFragbufToTail(wait, buf);
	}

	// Now add waiting list item to the end of buffer queue
	if (!chan->waitlist[FRAG_NORMAL_STREAM])
	{
		chan->waitlist[FRAG_NORMAL_STREAM] = wait;
	}
	else
	{
		p = chan->waitlist[FRAG_NORMAL_STREAM];
		while (p->next)
		{
			p = p->next;
		}
		p->next = wait;
	}
}
예제 #12
0
bool NetChannel::CreateFragmentsFromBuffer(void *buffer, int size, int streamtype, char *filename)
{
	fragbuf_t *buf;
	int chunksize;
	int sendsize;
	int remaining;
	int pos;
	int bufferid = 1;
	bool firstfragment = true;
	fragbufwaiting_t *wait, *p;

	if (IsFakeChannel())
	{
		m_System->Printf("NetChannel::CreateFragmentsFromBuffer: IsFakeChannel()\n");
		return true;
	}

	if (size == 0) {
		return true;
	}

	unsigned char compressed[65536];
	char hdr[4] = "BZ2";

	unsigned int header_size = sizeof(hdr);
	unsigned int compressedSize = size - sizeof(hdr);	// we should fit in same data buffer minus 4 bytes for a header

	if (streamtype == FRAG_FILE_STREAM) {
		compressedSize -= 4;
	}

	if (!BZ2_bzBuffToBuffCompress((char *)compressed, &compressedSize, (char *)buffer, size, 9, 0, 30))
	{
		m_System->DPrintf("Compressing split packet (%d -> %d bytes)\n", size, compressedSize);
		memcpy(buffer, hdr, sizeof(hdr));

		if (streamtype == FRAG_FILE_STREAM) {
			memcpy((char *)buffer + 4, &size, sizeof(int));
			header_size = 8;
		}

		memcpy((char *)buffer + header_size, compressed, compressedSize);
		size = header_size + compressedSize;
	}

	chunksize = FRAGMENT_S2C_MIN_SIZE;
	wait = (fragbufwaiting_t *)Mem_ZeroMalloc(sizeof(fragbufwaiting_t));

	remaining = size;
	pos = 0;
	while (remaining > 0)
	{
		sendsize = min(remaining, chunksize);
		remaining -= sendsize;

		buf = (fragbuf_t *)Mem_ZeroMalloc(sizeof(fragbuf_t));
		if (!buf)
		{
			m_System->Printf("NetChannel::CreateFragmentsFromBuffer:Couldn't allocate fragbuf_t\n");
			Mem_Free(wait);
			return false;
		}

		if (firstfragment && filename)
		{
			firstfragment = false;

			unsigned int len = strlen(filename) + 1;
			memcpy(buf->data, filename, len);
			sendsize -= len;

			memcpy(&buf->data[len], (char *)buffer + pos, sendsize);
			buf->size = len + sendsize;
		}
		else
		{
			memcpy(buf->data, (char *)buffer + pos, sendsize);
			buf->size = sendsize;
		}

		buf->bufferId = bufferid++;
		buf->isfile = filename ? true : false;
		buf->isbuffer = true;

		// Copy in data
		pos += sendsize;

		AddFragbufToTail(wait, buf);
	}

	// Now add waiting list item to the end of buffer queue
	if (!m_waitlist[streamtype])
	{
		m_waitlist[streamtype] = wait;
	}
	else
	{
		p = m_waitlist[streamtype];
		while (p->next) {
			p = p->next;
		}

		p->next = wait;
	}

	return true;
}
예제 #13
0
파일: net_ws.cpp 프로젝트: omertelli/rehlds
/* <d38ba> ../engine/net_ws.c:784 */
qboolean NET_LagPacket(qboolean newdata, netsrc_t sock, netadr_t *from, sizebuf_t *data)
{
	packetlag_t *pNewPacketLag;
	packetlag_t *pPacket;
	float curtime;
	int ninterval;
	static int losscount[3];

	if (gFakeLag <= 0.0)
	{
		NET_ClearLagData(TRUE, TRUE);
		return newdata;
	}

	curtime = realtime;
	if (newdata)
	{
		if (fakeloss.value != 0.0)
		{
			if (allow_cheats)
			{
				++losscount[sock];
				if (fakeloss.value <= 0.0f)
				{
					ninterval = fabs(fakeloss.value);
					if (ninterval < 2)
						ninterval = 2;
					if ((losscount[sock] % ninterval) == 0)
						return FALSE;
				}
				else
				{
					if (RandomLong(0, 100) <= fakeloss.value)
						return FALSE;
				}
			}
			else
			{
				Cvar_SetValue("fakeloss", 0.0);
			}
		}
		pNewPacketLag = (packetlag_t *)Mem_ZeroMalloc(0x28u);
		NET_AddToLagged(sock, &g_pLagData[sock], pNewPacketLag, from, *data, curtime);
	}
	pPacket = g_pLagData[sock].pNext;

	while (pPacket != &g_pLagData[sock])
	{
		if (pPacket->receivedTime <= curtime - gFakeLag / 1000.0)
			break;

		pPacket = pPacket->pNext;
	}
	if (pPacket == &g_pLagData[sock])
		return FALSE;

	NET_RemoveFromPacketList(pPacket);
	NET_TransferRawData(&in_message, pPacket->pPacketData, pPacket->nSize);
	Q_memcpy(&in_from, &pPacket->net_from_, sizeof(in_from));
	if (pPacket->pPacketData)
		free(pPacket->pPacketData);

	Mem_Free(pPacket);
	return TRUE;
}
예제 #14
0
파일: net_ws.cpp 프로젝트: omertelli/rehlds
/* <d2c6f> ../engine/net_ws.c:1348 */
void *net_malloc(size_t size)
{
	return Mem_ZeroMalloc(size);
}
예제 #15
0
/* <ba1d0> ../engine/sv_upld.c:491 */
void SV_ParseResourceList(client_t *pSenderClient)
{
	int i, total;
	int totalsize;
	resource_t *resource;
	resourceinfo_t ri;

	total = MSG_ReadShort();

#ifdef REHLDS_FIXES
	SV_ClearResourceLists( host_client );
#else // REHLDS_FIXES
	SV_ClearResourceList( &host_client->resourcesneeded );
	SV_ClearResourceList( &host_client->resourcesonhand );
#endif // REHLDS_FIXES

#ifdef REHLDS_FIXES
	if (total > 1) // client uses only one custom resource (spray decal)
	{
		SV_DropClient(host_client, false, "Too many resources in client resource list");
		return;
	}
#endif // REHLDS_CHECKS

	for (i = 0; i < total; i++)
	{
		resource = (resource_t *)Mem_ZeroMalloc(sizeof(resource_t));
		Q_strncpy(resource->szFileName, MSG_ReadString(), sizeof(resource->szFileName) - 1);
		resource->szFileName[sizeof(resource->szFileName) - 1] = 0;
		resource->type = (resourcetype_t)MSG_ReadByte();
		resource->nIndex = MSG_ReadShort();
		resource->nDownloadSize = MSG_ReadLong();
		resource->ucFlags = MSG_ReadByte() & (~RES_WASMISSING);
		if (resource->ucFlags & RES_CUSTOM)
			MSG_ReadBuf(16, resource->rgucMD5_hash);
		resource->pNext = NULL;
		resource->pPrev = NULL;

#ifdef REHLDS_FIXES
		SV_AddToResourceList(resource, &host_client->resourcesneeded);	// FIXED: Mem leak. Add to list to free current resource in SV_ClearResourceList if something goes wrong.
#endif // REHLDS_FIXES

		if (msg_badread || resource->type > t_world ||
#ifdef REHLDS_FIXES
			resource->type != t_decal || !(resource->ucFlags & RES_CUSTOM) || Q_strcmp(resource->szFileName, "tempdecal.wad") != 0 || // client uses only tempdecal.wad for customization
			resource->nDownloadSize <= 0 ||		// FIXED: Check that download size is valid
#endif // REHLDS_FIXES
			resource->nDownloadSize > 1024 * 1024 * 1024)	// FIXME: Are they gone crazy??!
		{
#ifdef REHLDS_FIXES
			SV_ClearResourceLists( host_client );
#else // REHLDS_FIXES
			SV_ClearResourceList( &host_client->resourcesneeded );
			SV_ClearResourceList( &host_client->resourcesonhand );
#endif // REHLDS_FIXES		
			return;
		}

#ifndef REHLDS_FIXES
		SV_AddToResourceList(resource, &host_client->resourcesneeded);
#endif // REHLDS_FIXES
	}

	if (sv_allow_upload.value != 0.0f)
	{
		Con_DPrintf("Verifying and uploading resources...\n");
		totalsize = COM_SizeofResourceList(&host_client->resourcesneeded, &ri);
#ifdef REHLDS_FIXES
		if (totalsize > 0)
#else // REHLDS_FIXES
		if (totalsize != 0)
#endif // REHLDS_FIXES
		{
			Con_DPrintf("Custom resources total %.2fK\n", total / 1024.0f);
#ifndef REHLDS_FIXES // because client can send only decals, why there is need to check other types?
			if (ri.info[t_model].size)
			{
				total = ri.info[t_model].size;
				Con_DPrintf("  Models:  %.2fK\n", total / 1024.0f);
			}
			if (ri.info[t_sound].size)
			{
				total = ri.info[t_sound].size;
				Con_DPrintf("  Sounds:  %.2fK\n", total / 1024.0f);
			}
			if (ri.info[t_decal].size) 
			{
#endif // REHLDS_FIXES
			// this check is useless, because presence of decals was checked before.
				total = ri.info[t_decal].size;
				Con_DPrintf("  Decals:  %.2fK\n", total / 1024.0f);
#ifndef REHLDS_FIXES
			}
			if (ri.info[t_skin].size)
			{
				total = ri.info[t_skin].size;
				Con_DPrintf("  Skins :  %.2fK\n", total / 1024.0f);
			}
			if (ri.info[t_generic].size)
			{
				total = ri.info[t_generic].size;
				Con_DPrintf("  Generic :  %.2fK\n", total / 1024.0f);
			}
			if (ri.info[t_eventscript].size)
			{
				total = ri.info[t_eventscript].size;
				Con_DPrintf("  Events  :  %.2fK\n", total / 1024.0f);
			}
#endif // REHLDS_FIXES
			Con_DPrintf("----------------------\n");

			int bytestodownload = SV_EstimateNeededResources();

			if (bytestodownload > sv_max_upload.value * 1024 * 1024)
			{
#ifdef REHLDS_FIXES
				SV_ClearResourceLists( host_client );
#else // REHLDS_FIXES
				SV_ClearResourceList( &host_client->resourcesneeded );
				SV_ClearResourceList( &host_client->resourcesonhand );
#endif //REHLDS_FIXES
				return;
			}

			if (bytestodownload > 1024)
				Con_DPrintf("Resources to request: %.2fK\n", bytestodownload / 1024.0f);
			else
				Con_DPrintf("Resources to request: %i bytes\n", bytestodownload);
		}
	}

	host_client->uploading = TRUE;
	host_client->uploaddoneregistering = FALSE;

	SV_BatchUploadRequest(host_client);
}
예제 #16
0
/* <9a75> ../engine/com_custom.c:88 */
qboolean COM_CreateCustomization(customization_t *pListHead, resource_t *pResource, int playernumber, int flags, customization_t **pCustomization, int *nLumps)
{
	customization_t *pCust;                                      //    91
	qboolean bError;                                              //    92

	bError = FALSE;
	if (pCustomization)
		*pCustomization = NULL;
	pCust = (customization_t *)Mem_ZeroMalloc(sizeof(customization_t));

	Q_memcpy(&pCust->resource, pResource, sizeof(pCust->resource));
	if (pResource->nDownloadSize <= 0)
	{
		bError = TRUE;
		goto CustomizationError;
	}

	pCust->bInUse = TRUE;

	if (flags & FCUST_FROMHPAK)
	{
		if (!HPAK_GetDataPointer("custom.hpk", pResource, (uint8**)&pCust->pBuffer, NULL))
		{
			bError = TRUE;
			goto CustomizationError;
		}
	}
	else
	{
		pCust->pBuffer = COM_LoadFile(pResource->szFileName, 5, NULL);
	}

	if ((pCust->resource.ucFlags & RES_CUSTOM) && pCust->resource.type == t_decal)
	{
		pCust->resource.playernum = playernumber;
		if (!CustomDecal_Validate(pCust->pBuffer, pResource->nDownloadSize))
		{
			bError = TRUE;
			goto CustomizationError;
		}

		if (!(flags & RES_CUSTOM))
		{
			cachewad_t * pWad = (cachewad_t *)Mem_ZeroMalloc(sizeof(cachewad_t));
			pCust->pInfo = pWad;
			if (pResource->nDownloadSize >= 1024 && pResource->nDownloadSize <= 20480)
			{
				bError = (0 == CustomDecal_Init(pWad, pCust->pBuffer, pResource->nDownloadSize, playernumber));
				if (bError)
					goto CustomizationError;

				if (pWad->lumpCount > 0)
				{
					if (nLumps)
						*nLumps = pWad->lumpCount;

					pCust->bTranslated = TRUE;
					pCust->nUserData1 = 0;
					pCust->nUserData2 = pWad->lumpCount;
					if (flags & FCUST_WIPEDATA)
					{
						Mem_Free(pWad->name);
						Mem_Free(pWad->cache);
						Mem_Free(pWad->lumps);
						Mem_Free(pCust->pInfo);
						pCust->pInfo = NULL;
					}
				}
			}
		}
	}

CustomizationError:
	if (bError)
	{
		if (pCust->pBuffer)
			Mem_Free(pCust->pBuffer);
		if (pCust->pInfo)
			Mem_Free(pCust->pInfo);
		Mem_Free(pCust);
	}
	else
	{
		if (pCustomization)
			*pCustomization = pCust;
		pCust->pNext = pListHead->pNext;
		pListHead->pNext = pCust;
	}
	return bError == FALSE;
}