net_ser.c
来自「quake1 dos源代码最新版本」· C语言 代码 · 共 952 行 · 第 1/2 页
C
952 行
sock->sendMessageLength = message->cursize;
sock->lastSendTime = net_time;
return 1;
}
static void ReSendMessage (qsocket_t *sock)
{
sizebuf_t temp;
Con_DPrintf("Serial: re-sending reliable\n");
temp.data = sock->sendMessage;
temp.maxsize = sock->sendMessageLength;
temp.cursize = sock->sendMessageLength;
Serial_SendMessage (sock, &temp);
}
int Serial_SendUnreliableMessage (qsocket_t *sock, sizebuf_t *message)
{
SerialLine *p;
int n;
unsigned short crc;
byte b;
p = (SerialLine *)sock->driverdata;
if (!TTY_OutputQueueIsEmpty(p->tty))
{
TTY_Flush(p->tty);
return 1;
}
CRC_Init (&crc);
// message type
b = MTYPE_UNRELIABLE;
if (p->client)
b |= MTYPE_CLIENT;
TTY_WriteByte(p->tty, b);
CRC_ProcessByte (&crc, b);
// sequence
b = p->sock->unreliableSendSequence;
p->sock->unreliableSendSequence = (b + 1) & 0xff;
TTY_WriteByte(p->tty, b);
if (b == ESCAPE_COMMAND)
TTY_WriteByte(p->tty, b);
CRC_ProcessByte (&crc, b);
// data length
b = message->cursize >> 8;
TTY_WriteByte(p->tty, b);
if (b == ESCAPE_COMMAND)
TTY_WriteByte(p->tty, b);
CRC_ProcessByte (&crc, b);
b = message->cursize & 0xff;
TTY_WriteByte(p->tty, b);
if (b == ESCAPE_COMMAND)
TTY_WriteByte(p->tty, b);
CRC_ProcessByte (&crc, b);
// data
for (n = 0; n < message->cursize; n++)
{
b = message->data[n];
TTY_WriteByte(p->tty, b);
if (b == ESCAPE_COMMAND)
TTY_WriteByte(p->tty, b);
CRC_ProcessByte (&crc, b);
}
// checksum
b = CRC_Value (crc) >> 8;
TTY_WriteByte(p->tty, b);
if (b == ESCAPE_COMMAND)
TTY_WriteByte(p->tty, b);
b = CRC_Value (crc) & 0xff;
TTY_WriteByte(p->tty, b);
if (b == ESCAPE_COMMAND)
TTY_WriteByte(p->tty, b);
// end of message
TTY_WriteByte(p->tty, ESCAPE_COMMAND);
TTY_WriteByte(p->tty, ESCAPE_EOM);
TTY_Flush(p->tty);
return 1;
}
static void Serial_SendACK (SerialLine *p, byte sequence)
{
unsigned short crc;
byte b;
CRC_Init (&crc);
// message type
b = MTYPE_ACK;
if (p->client)
b |= MTYPE_CLIENT;
TTY_WriteByte(p->tty, b);
CRC_ProcessByte (&crc, b);
// sequence
b = sequence;
TTY_WriteByte(p->tty, b);
if (b == ESCAPE_COMMAND)
TTY_WriteByte(p->tty, b);
CRC_ProcessByte (&crc, b);
// checksum
b = CRC_Value (crc) >> 8;
TTY_WriteByte(p->tty, b);
if (b == ESCAPE_COMMAND)
TTY_WriteByte(p->tty, b);
b = CRC_Value (crc) & 0xff;
TTY_WriteByte(p->tty, b);
if (b == ESCAPE_COMMAND)
TTY_WriteByte(p->tty, b);
// end of message
TTY_WriteByte(p->tty, ESCAPE_COMMAND);
TTY_WriteByte(p->tty, ESCAPE_EOM);
TTY_Flush(p->tty);
}
static void Serial_SendControlMessage (SerialLine *p, sizebuf_t *message)
{
unsigned short crc;
int n;
byte b;
CRC_Init (&crc);
// message type
b = MTYPE_CONTROL;
if (p->client)
b |= MTYPE_CLIENT;
TTY_WriteByte(p->tty, b);
CRC_ProcessByte (&crc, b);
// data length
b = message->cursize >> 8;
TTY_WriteByte(p->tty, b);
if (b == ESCAPE_COMMAND)
TTY_WriteByte(p->tty, b);
CRC_ProcessByte (&crc, b);
b = message->cursize & 0xff;
TTY_WriteByte(p->tty, b);
if (b == ESCAPE_COMMAND)
TTY_WriteByte(p->tty, b);
CRC_ProcessByte (&crc, b);
// data
for (n = 0; n < message->cursize; n++)
{
b = message->data[n];
TTY_WriteByte(p->tty, b);
if (b == ESCAPE_COMMAND)
TTY_WriteByte(p->tty, b);
CRC_ProcessByte (&crc, b);
}
// checksum
b = CRC_Value (crc) >> 8;
TTY_WriteByte(p->tty, b);
if (b == ESCAPE_COMMAND)
TTY_WriteByte(p->tty, b);
b = CRC_Value (crc) & 0xff;
TTY_WriteByte(p->tty, b);
if (b == ESCAPE_COMMAND)
TTY_WriteByte(p->tty, b);
// end of message
TTY_WriteByte(p->tty, ESCAPE_COMMAND);
TTY_WriteByte(p->tty, ESCAPE_EOM);
TTY_Flush(p->tty);
}
static int _Serial_GetMessage (SerialLine *p)
{
byte ret;
short length;
if (ProcessInQueue(p))
return -1;
if (p->sock->receiveMessageLength == 0)
return 0;
ret = p->sock->receiveMessage[0];
length = *(short *)&p->sock->receiveMessage[1];
if (ret == MTYPE_CONTROL)
ret = 1;
SZ_Clear (&net_message);
SZ_Write (&net_message, &p->sock->receiveMessage[3], length);
length += 3;
p->sock->receiveMessageLength -= length;
if (p->sock->receiveMessageLength + p->lengthFound)
Q_memcpy(p->sock->receiveMessage, &p->sock->receiveMessage[length], p->sock->receiveMessageLength + p->lengthFound);
return ret;
}
int Serial_GetMessage (qsocket_t *sock)
{
SerialLine *p;
int ret;
p = (SerialLine *)sock->driverdata;
ret = _Serial_GetMessage (p);
if (ret == 1)
messagesReceived++;
if (!sock->canSend)
if ((net_time - sock->lastSendTime) > 1.0)
{
ReSendMessage (sock);
sock->lastSendTime = net_time;
}
return ret;
}
void Serial_Close (qsocket_t *sock)
{
SerialLine *p = (SerialLine *)sock->driverdata;
TTY_Close(p->tty);
ResetSerialLineProtocol (p);
}
char *com_types[] = {"direct", "modem"};
unsigned com_bauds[] = {9600, 14400, 19200, 28800, 57600};
void Serial_SearchForHosts (qboolean xmit)
{
int n;
SerialLine *p;
if (sv.active)
return;
if (hostCacheCount == HOSTCACHESIZE)
return;
// see if we've already answered
for (n = 0; n < hostCacheCount; n++)
if (strcmp (hostcache[n].cname, "#") == 0)
return;
for (n = 0; n < NUM_COM_PORTS; n++)
if (TTY_IsEnabled(n))
break;
if (n == NUM_COM_PORTS)
return;
p = &serialLine[n];
if (TTY_IsModem(p->tty))
return;
sprintf(hostcache[hostCacheCount].name, "COM%u", n+1);
strcpy(hostcache[hostCacheCount].map, "");
hostcache[hostCacheCount].users = 0;
hostcache[hostCacheCount].maxusers = 0;
hostcache[hostCacheCount].driver = net_driverlevel;
strcpy(hostcache[hostCacheCount].cname, "#");
hostCacheCount++;
return;
}
static qsocket_t *_Serial_Connect (char *host, SerialLine *p)
{
int ret;
double start_time;
double last_time;
p->client = true;
if (TTY_Connect(p->tty, host))
return NULL;
p->sock = NET_NewQSocket ();
p->sock->driver = myDriverLevel;
if (p->sock == NULL)
{
Con_Printf("No sockets available\n");
return NULL;
}
p->sock->driverdata = p;
// send the connection request
start_time = SetNetTime();
last_time = 0.0;
SZ_Clear(&net_message);
MSG_WriteByte(&net_message, CCREQ_CONNECT);
MSG_WriteString(&net_message, "QUAKE");
do
{
SetNetTime();
if ((net_time - last_time) >= 1.0)
{
Serial_SendControlMessage (p, &net_message);
last_time = net_time;
Con_Printf("trying...\n"); SCR_UpdateScreen ();
}
ret = _Serial_GetMessage (p);
}
while (ret == 0 && (net_time - start_time) < 5.0);
if (ret == 0)
{
Con_Printf("Unable to connect, no response\n");
goto ErrorReturn;
}
if (ret == -1)
{
Con_Printf("Connection request error\n");
goto ErrorReturn;
}
MSG_BeginReading ();
ret = MSG_ReadByte();
if (ret == CCREP_REJECT)
{
Con_Printf(MSG_ReadString());
goto ErrorReturn;
}
if (ret != CCREP_ACCEPT)
{
Con_Printf("Unknown connection response\n");
goto ErrorReturn;
}
p->connected = true;
p->sock->lastMessageTime = net_time;
Con_Printf ("Connection accepted\n");
return p->sock;
ErrorReturn:
TTY_Disconnect(p->tty);
return NULL;
}
qsocket_t *Serial_Connect (char *host)
{
int n;
qsocket_t *ret = NULL;
// see if this looks like a phone number
if (*host == '#')
host++;
for (n = 0; n < strlen(host); n++)
if (host[n] == '.' || host[n] == ':')
return NULL;
for (n = 0; n < NUM_COM_PORTS; n++)
if (TTY_IsEnabled(n) && !serialLine[n].connected)
if ((ret = _Serial_Connect (host, &serialLine[n])))
break;
return ret;
}
static qsocket_t *_Serial_CheckNewConnections (SerialLine *p)
{
int command;
p->client = false;
if (!TTY_CheckForConnection(p->tty))
return NULL;
if (TTY_IsModem(p->tty))
{
if (!p->connecting)
{
p->connecting = true;
p->connect_time = net_time;
}
else if ((net_time - p->connect_time) > 15.0)
{
p->connecting = false;
TTY_Disconnect(p->tty);
return NULL;
}
}
p->sock = NET_NewQSocket ();
p->sock->driver = myDriverLevel;
if (p->sock == NULL)
{
Con_Printf("No sockets available\n");
return NULL;
}
p->sock->driverdata = p;
SZ_Clear(&net_message);
if (_Serial_GetMessage(p) != 1)
{
NET_FreeQSocket(p->sock);
return NULL;
}
MSG_BeginReading ();
command = MSG_ReadByte();
if (command == CCREQ_SERVER_INFO)
{
if (strcmp(MSG_ReadString(), "QUAKE") != 0)
return NULL;
if (MSG_ReadByte() != SERIAL_PROTOCOL_VERSION)
return NULL;
SZ_Clear(&net_message);
MSG_WriteByte(&net_message, CCREP_SERVER_INFO);
MSG_WriteString(&net_message, hostname->string);
MSG_WriteString(&net_message, sv.name);
MSG_WriteByte(&net_message, net_activeconnections);
MSG_WriteByte(&net_message, svs.maxclients);
Serial_SendControlMessage (p, &net_message);
SZ_Clear(&net_message);
return NULL;
}
if (command != CCREQ_CONNECT)
return NULL;
if (strcmp(MSG_ReadString(), "QUAKE") != 0)
return NULL;
// send him back the info about the server connection he has been allocated
SZ_Clear(&net_message);
MSG_WriteByte(&net_message, CCREP_ACCEPT);
Serial_SendControlMessage (p, &net_message);
SZ_Clear(&net_message);
p->connected = true;
p->connecting = false;
p->sock->lastMessageTime = net_time;
sprintf(p->sock->address, "COM%u", (int)((p - serialLine) + 1));
return p->sock;
}
qsocket_t *Serial_CheckNewConnections (void)
{
int n;
qsocket_t *ret = NULL;
for (n = 0; n < NUM_COM_PORTS; n++)
if (TTY_IsEnabled(n) && !serialLine[n].connected)
if ((ret = _Serial_CheckNewConnections (&serialLine[n])))
break;
return ret;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?