quakeforge/libs/net/net_clc.c
Adam Olsen 7f10b0f237 - split net_clc.h into net_clc.h and net_clc_qw.h
- move clc_t into net_clc.h from net_protocol.h
- split packet processing stuff from net.h into net_packet.h
- add a is_server arg to Log_{Incoming,Outgoing}_Packet, so libs/net is
  oblivious to if we're running a server or not (except with the arg,
  obviously)
- remove the long obsolete (even in original quake) svc_spawnbinary
  stuff
- make nq use QF/net_svc.h
- make nq link to libQFnet too
- make qw's cl_parse.c use net_svc_qw_any_t instead of net_svc_any_t
2001-11-18 11:39:12 +00:00

257 lines
5.9 KiB
C

/*
net_clc.c
(description)
Copyright (C) 2001 Adam Olsen
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
static const char rcsid[] =
"$Id$";
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#ifndef _WIN32
# ifdef HAVE_UNISTD_H
# include <unistd.h>
# endif
#else
# include <windows.h>
#endif
#ifdef HAVE_STRING_H
# include <string.h>
#endif
#ifdef HAVE_STRINGS_H
# include <strings.h>
#endif
#include "QF/checksum.h"
#include "QF/msg.h"
#include "QF/net_clc.h"
#include "QF/net_ucmd.h"
#include "QF/sys.h"
//#include "compat.h"
//#include "msg_ucmd.h" // FIXME
//#include "net_clc.h"
static const char *net_clc_strings[] = {
[clc_bad] = "clc_bad",
[clc_nop] = "clc_nop",
// [clc_doublemove] = "clc_doublemove", // NQ only
[clc_move] = "clc_move",
[clc_stringcmd] = "clc_stringcmd",
[clc_delta] = "clc_delta",
[clc_tmove] = "clc_tmove",
[clc_upload] = "clc_upload",
};
const char *
NET_CLC_GetString (clc_t type)
{
if (type >= 0 && type < (sizeof (net_clc_strings) / sizeof (const char *)))
return net_clc_strings[type];
else
return "Invalid CLC";
}
// This is evil }:>
static net_clc_emit_t net_clc_emit_jumptable[] = {
[clc_nop] = (net_clc_emit_t) NET_CLC_NOP_Emit,
[clc_move] = (net_clc_emit_t) NET_CLC_Move_Emit,
[clc_stringcmd] = (net_clc_emit_t) NET_CLC_Stringcmd_Emit,
[clc_delta] = (net_clc_emit_t) NET_CLC_Delta_Emit,
[clc_tmove] = (net_clc_emit_t) NET_CLC_TMove_Emit,
[clc_upload] = (net_clc_emit_t) NET_CLC_Upload_Emit,
};
static net_clc_parse_t net_clc_parse_jumptable [] = {
[clc_nop] = (net_clc_parse_t) NET_CLC_NOP_Parse,
[clc_move] = (net_clc_parse_t) NET_CLC_Move_Parse,
[clc_stringcmd] = (net_clc_parse_t) NET_CLC_Stringcmd_Parse,
[clc_delta] = (net_clc_parse_t) NET_CLC_Delta_Parse,
[clc_tmove] = (net_clc_parse_t) NET_CLC_TMove_Parse,
[clc_upload] = (net_clc_parse_t) NET_CLC_Upload_Parse,
};
net_status_t
NET_CLC_Emit (clc_t type, void *block, sizebuf_t *buf)
{
int oldsize = buf->cursize;
net_status_t retval;
if (type < 0 ||
type >= sizeof (net_clc_emit_jumptable) / sizeof (net_clc_emit_t) ||
!net_clc_emit_jumptable[type])
return NET_ERROR;
MSG_WriteByte (buf, type);
retval = net_clc_emit_jumptable[type] (block, buf);
if (retval == NET_SHORT)
buf->cursize = oldsize; // revert the buffer
return retval;
}
net_status_t
NET_CLC_Parse (clc_t *type, net_clc_any_t *block, msg_t *msg)
{
*type = MSG_ReadByte (msg);
if (*type < 0 ||
*type >= sizeof (net_clc_parse_jumptable) / sizeof (net_clc_parse_t) ||
!net_clc_parse_jumptable[*type])
return NET_ERROR;
return net_clc_parse_jumptable[*type] (block, msg);
}
net_status_t
NET_CLC_NOP_Emit (net_clc_nop_t *block, sizebuf_t *buf)
{
return buf->overflowed;
}
net_status_t
NET_CLC_NOP_Parse (net_clc_nop_t *block, msg_t *msg)
{
return msg->badread;
}
net_status_t
NET_CLC_Move_Emit (net_clc_move_t *block, sizebuf_t *buf)
{
int checksumindex;
checksumindex = buf->cursize;
MSG_WriteByte (buf, 0); // space for checksum
MSG_WriteByte (buf, block->packetloss);
NET_WriteDeltaUsercmd (buf, &nullcmd, &block->usercmd[0]);
NET_WriteDeltaUsercmd (buf, &block->usercmd[0], &block->usercmd[1]);
NET_WriteDeltaUsercmd (buf, &block->usercmd[1], &block->usercmd[2]);
// write the checksum
if (!buf->overflowed)
buf->data[checksumindex] =
COM_BlockSequenceCRCByte (buf->data + checksumindex + 1,
buf->cursize - checksumindex - 1, block->seq_hash);
return buf->overflowed;
}
net_status_t
NET_CLC_Move_Parse (net_clc_move_t *block, msg_t *msg)
{
int checksumindex;
checksumindex = msg->readcount;
block->checksum = MSG_ReadByte (msg);
block->packetloss = MSG_ReadByte (msg);
NET_ReadDeltaUsercmd (msg, &nullcmd, &block->usercmd[0]);
NET_ReadDeltaUsercmd (msg, &block->usercmd[0], &block->usercmd[1]);
NET_ReadDeltaUsercmd (msg, &block->usercmd[1], &block->usercmd[2]);
if (!msg->badread)
block->calculatedchecksum = COM_BlockSequenceCRCByte (
msg->message->data + checksumindex + 1,
MSG_GetReadCount (msg) - checksumindex - 1, block->seq_hash);
return msg->badread;
}
net_status_t
NET_CLC_Stringcmd_Emit (net_clc_stringcmd_t *block, sizebuf_t *buf)
{
MSG_WriteString (buf, block->command);
return buf->overflowed;
}
net_status_t
NET_CLC_Stringcmd_Parse (net_clc_stringcmd_t *block, msg_t *msg)
{
block->command = MSG_ReadString (msg);
return msg->badread;
}
net_status_t
NET_CLC_Delta_Emit (net_clc_delta_t *block, sizebuf_t *buf)
{
MSG_WriteByte (buf, block->sequence);
return buf->overflowed;
}
net_status_t
NET_CLC_Delta_Parse (net_clc_delta_t *block, msg_t *msg)
{
block->sequence = MSG_ReadByte (msg);
return msg->badread;
}
net_status_t
NET_CLC_TMove_Emit (net_clc_tmove_t *block, sizebuf_t *buf)
{
int i;
for (i = 0; i < 3; i++)
MSG_WriteCoord (buf, block->origin[i]);
return buf->overflowed;
}
net_status_t
NET_CLC_TMove_Parse (net_clc_tmove_t *block, msg_t *msg)
{
int i;
for (i = 0; i < 3; i++)
block->origin[i] = MSG_ReadCoord (msg);
return msg->badread;
}
net_status_t
NET_CLC_Upload_Emit (net_clc_upload_t *block, sizebuf_t *buf)
{
MSG_WriteShort (buf, block->size);
MSG_WriteByte (buf, block->percent);
MSG_WriteBlock (buf, block->data, block->size);
return buf->overflowed;
}
net_status_t
NET_CLC_Upload_Parse (net_clc_upload_t *block, msg_t *msg)
{
block->size = MSG_ReadShort (msg);
block->percent = MSG_ReadByte (msg);
block->data = MSG_ReadBlock (msg, block->size);
return msg->badread;
}