network_data.c
author celestar
Mon, 01 Jan 2007 16:07:21 +0000
branchcustombridgeheads
changeset 5621 6ce400c0a2f4
parent 5568 75f13d7bfaed
permissions -rw-r--r--
(svn r7719) [cbh] - Codechange: KUDr and I have decided that our developemnt efforts went in the wrong direction, so revert all changes from 7686 onwards
2186
461a2aff3486 (svn r2701) Insert Id tags into all source files
tron
parents: 2163
diff changeset
     1
/* $Id$ */
461a2aff3486 (svn r2701) Insert Id tags into all source files
tron
parents: 2163
diff changeset
     2
4826
63b1eb7c966b (svn r6750) -Codechange: Juggle around some header includes as they're only used when
Darkvater
parents: 4077
diff changeset
     3
#ifdef ENABLE_NETWORK
63b1eb7c966b (svn r6750) -Codechange: Juggle around some header includes as they're only used when
Darkvater
parents: 4077
diff changeset
     4
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
     5
#include "stdafx.h"
1299
0a6510cc889b (svn r1803) Move debugging stuff into files of it's own
tron
parents: 1095
diff changeset
     6
#include "debug.h"
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
     7
#include "network_data.h"
2163
637ec3c361f5 (svn r2673) Include functions.h directly, not globally via openttd.h
tron
parents: 2153
diff changeset
     8
#include "functions.h"
1820
9b6458526480 (svn r2324) Introduce _cmd_text for passing strings with a command instead of abusing _decode_parameters as text buffer. This should prevent several possible buffer overruns and is a bit cleaner to use. As bonus it reduces the size of most command packets by 79 bytes.
tron
parents: 1299
diff changeset
     9
#include "string.h"
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    10
#include "table/strings.h"
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    11
#include "network_client.h"
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    12
#include "command.h"
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    13
#include "callback_table.h"
2153
91e89aa8c299 (svn r2663) Include variables.h only in these files which need it, not globally via openttd.h
tron
parents: 2140
diff changeset
    14
#include "variables.h"
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    15
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    16
// This files handles the send/receive of all packets
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    17
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    18
// Create a packet for sending
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    19
Packet *NetworkSend_Init(PacketType type)
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    20
{
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    21
	Packet *packet = malloc(sizeof(Packet));
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    22
	// An error is inplace here, because it simply means we ran out of memory.
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    23
	if (packet == NULL) error("Failed to allocate Packet");
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    24
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    25
	// Skip the size so we can write that in before sending the packet
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    26
	packet->size = sizeof(packet->size);
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    27
	packet->buffer[packet->size++] = type;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    28
	packet->pos = 0;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    29
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    30
	return packet;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    31
}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    32
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    33
// The next couple of functions make sure we can send
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    34
//  uint8, uint16, uint32 and uint64 endian-safe
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    35
//  over the network. The order it uses is:
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    36
//
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    37
//  1 2 3 4
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    38
//
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    39
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    40
void NetworkSend_uint8(Packet *packet, uint8 data)
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    41
{
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    42
	assert(packet->size < sizeof(packet->buffer) - sizeof(data));
2644
6f699b15c531 (svn r3186) Unnecessary casts and truncation
tron
parents: 2186
diff changeset
    43
	packet->buffer[packet->size++] = data;
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    44
}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    45
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    46
void NetworkSend_uint16(Packet *packet, uint16 data)
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    47
{
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    48
	assert(packet->size < sizeof(packet->buffer) - sizeof(data));
2140
d708eb80ab8b (svn r2650) Convert many explicit shifts+ands to extract bits to invocations of GB - should be a bit nicer to read
tron
parents: 1977
diff changeset
    49
	packet->buffer[packet->size++] = GB(data, 0, 8);
d708eb80ab8b (svn r2650) Convert many explicit shifts+ands to extract bits to invocations of GB - should be a bit nicer to read
tron
parents: 1977
diff changeset
    50
	packet->buffer[packet->size++] = GB(data, 8, 8);
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    51
}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    52
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    53
void NetworkSend_uint32(Packet *packet, uint32 data)
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    54
{
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    55
	assert(packet->size < sizeof(packet->buffer) - sizeof(data));
2140
d708eb80ab8b (svn r2650) Convert many explicit shifts+ands to extract bits to invocations of GB - should be a bit nicer to read
tron
parents: 1977
diff changeset
    56
	packet->buffer[packet->size++] = GB(data,  0, 8);
d708eb80ab8b (svn r2650) Convert many explicit shifts+ands to extract bits to invocations of GB - should be a bit nicer to read
tron
parents: 1977
diff changeset
    57
	packet->buffer[packet->size++] = GB(data,  8, 8);
d708eb80ab8b (svn r2650) Convert many explicit shifts+ands to extract bits to invocations of GB - should be a bit nicer to read
tron
parents: 1977
diff changeset
    58
	packet->buffer[packet->size++] = GB(data, 16, 8);
d708eb80ab8b (svn r2650) Convert many explicit shifts+ands to extract bits to invocations of GB - should be a bit nicer to read
tron
parents: 1977
diff changeset
    59
	packet->buffer[packet->size++] = GB(data, 24, 8);
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    60
}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    61
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    62
void NetworkSend_uint64(Packet *packet, uint64 data)
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    63
{
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    64
	assert(packet->size < sizeof(packet->buffer) - sizeof(data));
2140
d708eb80ab8b (svn r2650) Convert many explicit shifts+ands to extract bits to invocations of GB - should be a bit nicer to read
tron
parents: 1977
diff changeset
    65
	packet->buffer[packet->size++] = GB(data,  0, 8);
d708eb80ab8b (svn r2650) Convert many explicit shifts+ands to extract bits to invocations of GB - should be a bit nicer to read
tron
parents: 1977
diff changeset
    66
	packet->buffer[packet->size++] = GB(data,  8, 8);
d708eb80ab8b (svn r2650) Convert many explicit shifts+ands to extract bits to invocations of GB - should be a bit nicer to read
tron
parents: 1977
diff changeset
    67
	packet->buffer[packet->size++] = GB(data, 16, 8);
d708eb80ab8b (svn r2650) Convert many explicit shifts+ands to extract bits to invocations of GB - should be a bit nicer to read
tron
parents: 1977
diff changeset
    68
	packet->buffer[packet->size++] = GB(data, 24, 8);
d708eb80ab8b (svn r2650) Convert many explicit shifts+ands to extract bits to invocations of GB - should be a bit nicer to read
tron
parents: 1977
diff changeset
    69
	packet->buffer[packet->size++] = GB(data, 32, 8);
d708eb80ab8b (svn r2650) Convert many explicit shifts+ands to extract bits to invocations of GB - should be a bit nicer to read
tron
parents: 1977
diff changeset
    70
	packet->buffer[packet->size++] = GB(data, 40, 8);
d708eb80ab8b (svn r2650) Convert many explicit shifts+ands to extract bits to invocations of GB - should be a bit nicer to read
tron
parents: 1977
diff changeset
    71
	packet->buffer[packet->size++] = GB(data, 48, 8);
d708eb80ab8b (svn r2650) Convert many explicit shifts+ands to extract bits to invocations of GB - should be a bit nicer to read
tron
parents: 1977
diff changeset
    72
	packet->buffer[packet->size++] = GB(data, 56, 8);
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    73
}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    74
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    75
// Sends a string over the network. It sends out
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    76
//  the string + '\0'. No size-byte or something.
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    77
void NetworkSend_string(Packet *packet, const char* data)
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    78
{
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    79
	assert(data != NULL);
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    80
	assert(packet->size < sizeof(packet->buffer) - strlen(data) - 1);
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    81
	while ((packet->buffer[packet->size++] = *data++) != '\0') {}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    82
}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    83
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    84
// If PacketSize changes of size, you have to change the 2 packet->size
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    85
//   lines below matching the size of packet->size/PacketSize!
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    86
// (line 'packet->buffer[0] = packet->size & 0xFF;'  and below)
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    87
assert_compile(sizeof(PacketSize) == 2);
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    88
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    89
// This function puts the packet in the send-queue and it is send
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    90
//  as soon as possible
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    91
// (that is: the next tick, or maybe one tick later if the
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    92
//   OS-network-buffer is full)
716
40a349345f82 (svn r1168) -Cleanup: [Network] Cleaned the network code a bit. Added 'const'
truelight
parents: 543
diff changeset
    93
void NetworkSend_Packet(Packet *packet, NetworkClientState *cs)
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    94
{
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    95
	Packet *p;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    96
	assert(packet != NULL);
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    97
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    98
	packet->pos = 0;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    99
	packet->next = NULL;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   100
2989
99c95a3ebcaa (svn r3564) Several smaller changes:
tron
parents: 2644
diff changeset
   101
	packet->buffer[0] = GB(packet->size, 0, 8);
99c95a3ebcaa (svn r3564) Several smaller changes:
tron
parents: 2644
diff changeset
   102
	packet->buffer[1] = GB(packet->size, 8, 8);
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   103
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   104
	// Locate last packet buffered for the client
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   105
	p = cs->packet_queue;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   106
	if (p == NULL) {
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   107
		// No packets yet
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   108
		cs->packet_queue = packet;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   109
	} else {
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   110
		// Skip to the last packet
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   111
		while (p->next != NULL) p = p->next;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   112
		p->next = packet;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   113
	}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   114
}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   115
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   116
// Functions to help NetworkRecv_Packet/NetworkSend_Packet a bit
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   117
//  A socket can make errors. When that happens
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   118
//  this handles what to do.
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   119
// For clients: close connection and drop back to main-menu
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   120
// For servers: close connection and that is it
1095
90220990fd7c (svn r1596) Add some more statics
tron
parents: 903
diff changeset
   121
static NetworkRecvStatus CloseConnection(NetworkClientState *cs)
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   122
{
716
40a349345f82 (svn r1168) -Cleanup: [Network] Cleaned the network code a bit. Added 'const'
truelight
parents: 543
diff changeset
   123
	NetworkCloseClient(cs);
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   124
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   125
	// Clients drop back to the main menu
3547
a4584d709460 (svn r4413) -Fix: fixed a bug which pushed the client back to the main menu when a
truelight
parents: 3457
diff changeset
   126
	if (!_network_server && _networking) {
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   127
		_switch_mode = SM_MENU;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   128
		_networking = false;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   129
		_switch_mode_errorstr = STR_NETWORK_ERR_LOSTCONNECTION;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   130
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   131
		return NETWORK_RECV_STATUS_CONN_LOST;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   132
	}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   133
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   134
	return NETWORK_RECV_STATUS_OKAY;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   135
}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   136
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   137
// Sends all the buffered packets out for this client
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   138
//  it stops when:
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   139
//   1) all packets are send (queue is empty)
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   140
//   2) the OS reports back that it can not send any more
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   141
//        data right now (full network-buffer, it happens ;))
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   142
//   3) sending took too long
716
40a349345f82 (svn r1168) -Cleanup: [Network] Cleaned the network code a bit. Added 'const'
truelight
parents: 543
diff changeset
   143
bool NetworkSend_Packets(NetworkClientState *cs)
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   144
{
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   145
	ssize_t res;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   146
	Packet *p;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   147
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   148
	// We can not write to this socket!!
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   149
	if (!cs->writable) return false;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   150
	if (cs->socket == INVALID_SOCKET) return false;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   151
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   152
	p = cs->packet_queue;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   153
	while (p != NULL) {
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   154
		res = send(cs->socket, p->buffer + p->pos, p->size - p->pos, 0);
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   155
		if (res == -1) {
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   156
			int err = GET_LAST_ERROR();
5568
75f13d7bfaed (svn r7565) -Codechange: Rework DEBUG functionality. Look for appropiate debugging levels to
Darkvater
parents: 4880
diff changeset
   157
			if (err != EWOULDBLOCK) { // Something went wrong.. close client!
75f13d7bfaed (svn r7565) -Codechange: Rework DEBUG functionality. Look for appropiate debugging levels to
Darkvater
parents: 4880
diff changeset
   158
				DEBUG(net, 0, "send failed with error %d", err);
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   159
				CloseConnection(cs);
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   160
				return false;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   161
			}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   162
			return true;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   163
		}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   164
		if (res == 0) {
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   165
			// Client/server has left us :(
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   166
			CloseConnection(cs);
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   167
			return false;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   168
		}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   169
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   170
		p->pos += res;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   171
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   172
		// Is this packet sent?
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   173
		if (p->pos == p->size) {
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   174
			// Go to the next packet
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   175
			cs->packet_queue = p->next;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   176
			free(p);
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   177
			p = cs->packet_queue;
4077
d3022f976946 (svn r5391) Miscellaneous, mostly bracing and whitespace, nothing spectacular
tron
parents: 3547
diff changeset
   178
		} else {
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   179
			return true;
4077
d3022f976946 (svn r5391) Miscellaneous, mostly bracing and whitespace, nothing spectacular
tron
parents: 3547
diff changeset
   180
		}
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   181
	}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   182
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   183
	return true;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   184
}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   185
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   186
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   187
// Receiving commands
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   188
// Again, the next couple of functions are endian-safe
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   189
//  see the comment around NetworkSend_uint8 for more info.
903
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   190
uint8 NetworkRecv_uint8(NetworkClientState *cs, Packet *packet)
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   191
{
903
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   192
	/* Don't allow reading from a closed socket */
4880
0708f34e3586 (svn r6816) -Codechange: Some coding style, variable localization, const correctness.
Darkvater
parents: 4826
diff changeset
   193
	if (cs->has_quit) return 0;
903
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   194
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   195
	/* Check if variable is within packet-size */
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   196
	if (packet->pos + 1 > packet->size) {
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   197
		CloseConnection(cs);
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   198
		return 0;
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   199
	}
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   200
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   201
	return packet->buffer[packet->pos++];
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   202
}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   203
903
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   204
uint16 NetworkRecv_uint16(NetworkClientState *cs, Packet *packet)
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   205
{
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   206
	uint16 n;
903
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   207
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   208
	/* Don't allow reading from a closed socket */
4880
0708f34e3586 (svn r6816) -Codechange: Some coding style, variable localization, const correctness.
Darkvater
parents: 4826
diff changeset
   209
	if (cs->has_quit) return 0;
903
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   210
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   211
	/* Check if variable is within packet-size */
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   212
	if (packet->pos + 2 > packet->size) {
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   213
		CloseConnection(cs);
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   214
		return 0;
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   215
	}
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   216
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   217
	n  = (uint16)packet->buffer[packet->pos++];
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   218
	n += (uint16)packet->buffer[packet->pos++] << 8;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   219
	return n;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   220
}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   221
903
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   222
uint32 NetworkRecv_uint32(NetworkClientState *cs, Packet *packet)
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   223
{
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   224
	uint32 n;
903
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   225
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   226
	/* Don't allow reading from a closed socket */
4880
0708f34e3586 (svn r6816) -Codechange: Some coding style, variable localization, const correctness.
Darkvater
parents: 4826
diff changeset
   227
	if (cs->has_quit) return 0;
903
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   228
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   229
	/* Check if variable is within packet-size */
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   230
	if (packet->pos + 4 > packet->size) {
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   231
		CloseConnection(cs);
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   232
		return 0;
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   233
	}
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   234
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   235
	n  = (uint32)packet->buffer[packet->pos++];
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   236
	n += (uint32)packet->buffer[packet->pos++] << 8;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   237
	n += (uint32)packet->buffer[packet->pos++] << 16;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   238
	n += (uint32)packet->buffer[packet->pos++] << 24;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   239
	return n;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   240
}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   241
903
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   242
uint64 NetworkRecv_uint64(NetworkClientState *cs, Packet *packet)
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   243
{
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   244
	uint64 n;
903
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   245
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   246
	/* Don't allow reading from a closed socket */
4880
0708f34e3586 (svn r6816) -Codechange: Some coding style, variable localization, const correctness.
Darkvater
parents: 4826
diff changeset
   247
	if (cs->has_quit) return 0;
903
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   248
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   249
	/* Check if variable is within packet-size */
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   250
	if (packet->pos + 8 > packet->size) {
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   251
		CloseConnection(cs);
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   252
		return 0;
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   253
	}
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   254
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   255
	n  = (uint64)packet->buffer[packet->pos++];
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   256
	n += (uint64)packet->buffer[packet->pos++] << 8;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   257
	n += (uint64)packet->buffer[packet->pos++] << 16;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   258
	n += (uint64)packet->buffer[packet->pos++] << 24;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   259
	n += (uint64)packet->buffer[packet->pos++] << 32;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   260
	n += (uint64)packet->buffer[packet->pos++] << 40;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   261
	n += (uint64)packet->buffer[packet->pos++] << 48;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   262
	n += (uint64)packet->buffer[packet->pos++] << 56;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   263
	return n;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   264
}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   265
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   266
// Reads a string till it finds a '\0' in the stream
3457
c581652f3e83 (svn r4292) - CodeChange: sprinkle some holy water on l'ugly code (braces, and pos is PacketSize not int)
Darkvater
parents: 3456
diff changeset
   267
void NetworkRecv_string(NetworkClientState *cs, Packet *p, char *buffer, size_t size)
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   268
{
3457
c581652f3e83 (svn r4292) - CodeChange: sprinkle some holy water on l'ugly code (braces, and pos is PacketSize not int)
Darkvater
parents: 3456
diff changeset
   269
	PacketSize pos;
3456
133bad819a94 (svn r4291) - Fix: validate all received strings for correctness. This fixes potential crashes on invalid clients/servers (thanks test for bringing this to our attention)
Darkvater
parents: 2989
diff changeset
   270
	char *bufp = buffer;
903
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   271
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   272
	/* Don't allow reading from a closed socket */
4880
0708f34e3586 (svn r6816) -Codechange: Some coding style, variable localization, const correctness.
Darkvater
parents: 4826
diff changeset
   273
	if (cs->has_quit) return;
903
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   274
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   275
	pos = p->pos;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   276
	while (--size > 0 && pos < p->size && (*buffer++ = p->buffer[pos++]) != '\0') {}
3457
c581652f3e83 (svn r4292) - CodeChange: sprinkle some holy water on l'ugly code (braces, and pos is PacketSize not int)
Darkvater
parents: 3456
diff changeset
   277
c581652f3e83 (svn r4292) - CodeChange: sprinkle some holy water on l'ugly code (braces, and pos is PacketSize not int)
Darkvater
parents: 3456
diff changeset
   278
	if (size == 0 || pos == p->size) {
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   279
		*buffer = '\0';
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   280
		// If size was sooner to zero then the string in the stream
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   281
		//  skip till the \0, so the packet can be read out correctly for the rest
3457
c581652f3e83 (svn r4292) - CodeChange: sprinkle some holy water on l'ugly code (braces, and pos is PacketSize not int)
Darkvater
parents: 3456
diff changeset
   282
		while (pos < p->size && p->buffer[pos] != '\0') pos++;
c581652f3e83 (svn r4292) - CodeChange: sprinkle some holy water on l'ugly code (braces, and pos is PacketSize not int)
Darkvater
parents: 3456
diff changeset
   283
		pos++;
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   284
	}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   285
	p->pos = pos;
3456
133bad819a94 (svn r4291) - Fix: validate all received strings for correctness. This fixes potential crashes on invalid clients/servers (thanks test for bringing this to our attention)
Darkvater
parents: 2989
diff changeset
   286
133bad819a94 (svn r4291) - Fix: validate all received strings for correctness. This fixes potential crashes on invalid clients/servers (thanks test for bringing this to our attention)
Darkvater
parents: 2989
diff changeset
   287
	str_validate(bufp);
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   288
}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   289
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   290
// If PacketSize changes of size, you have to change the 2 packet->size
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   291
//   lines below matching the size of packet->size/PacketSize!
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   292
// (the line: 'p->size = (uint16)p->buffer[0];' and below)
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   293
assert_compile(sizeof(PacketSize) == 2);
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   294
716
40a349345f82 (svn r1168) -Cleanup: [Network] Cleaned the network code a bit. Added 'const'
truelight
parents: 543
diff changeset
   295
Packet *NetworkRecv_Packet(NetworkClientState *cs, NetworkRecvStatus *status)
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   296
{
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   297
	ssize_t res;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   298
	Packet *p;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   299
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   300
	*status = NETWORK_RECV_STATUS_OKAY;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   301
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   302
	if (cs->socket == INVALID_SOCKET) return NULL;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   303
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   304
	if (cs->packet_recv == NULL) {
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   305
		cs->packet_recv = malloc(sizeof(Packet));
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   306
		if (cs->packet_recv == NULL) error("Failed to allocate packet");
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   307
		// Set pos to zero!
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   308
		cs->packet_recv->pos = 0;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   309
		cs->packet_recv->size = 0; // Can be ommited, just for safety reasons
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   310
	}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   311
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   312
	p = cs->packet_recv;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   313
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   314
	// Read packet size
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   315
	if (p->pos < sizeof(PacketSize)) {
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   316
		while (p->pos < sizeof(PacketSize)) {
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   317
			// Read the size of the packet
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   318
			res = recv(cs->socket, p->buffer + p->pos, sizeof(PacketSize) - p->pos, 0);
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   319
			if (res == -1) {
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   320
				int err = GET_LAST_ERROR();
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   321
				if (err != EWOULDBLOCK) {
5568
75f13d7bfaed (svn r7565) -Codechange: Rework DEBUG functionality. Look for appropiate debugging levels to
Darkvater
parents: 4880
diff changeset
   322
					/* Something went wrong... (104 is connection reset by peer) */
75f13d7bfaed (svn r7565) -Codechange: Rework DEBUG functionality. Look for appropiate debugging levels to
Darkvater
parents: 4880
diff changeset
   323
					if (err != 104) DEBUG(net, 0, "recv failed with error %d", err);
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   324
					*status = CloseConnection(cs);
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   325
					return NULL;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   326
				}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   327
				// Connection would block, so stop for now
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   328
				return NULL;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   329
			}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   330
			if (res == 0) {
5568
75f13d7bfaed (svn r7565) -Codechange: Rework DEBUG functionality. Look for appropiate debugging levels to
Darkvater
parents: 4880
diff changeset
   331
				// Client/server has left
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   332
				*status = CloseConnection(cs);
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   333
				return NULL;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   334
			}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   335
			p->pos += res;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   336
		}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   337
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   338
		p->size = (uint16)p->buffer[0];
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   339
		p->size += (uint16)p->buffer[1] << 8;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   340
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   341
		if (p->size > SEND_MTU) {
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   342
			*status = CloseConnection(cs);
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   343
			return NULL;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   344
		}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   345
	}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   346
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   347
	// Read rest of packet
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   348
	while (p->pos < p->size) {
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   349
		res = recv(cs->socket, p->buffer + p->pos, p->size - p->pos, 0);
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   350
		if (res == -1) {
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   351
			int err = GET_LAST_ERROR();
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   352
			if (err != EWOULDBLOCK) {
5568
75f13d7bfaed (svn r7565) -Codechange: Rework DEBUG functionality. Look for appropiate debugging levels to
Darkvater
parents: 4880
diff changeset
   353
				/* Something went wrong... (104 is connection reset by peer) */
75f13d7bfaed (svn r7565) -Codechange: Rework DEBUG functionality. Look for appropiate debugging levels to
Darkvater
parents: 4880
diff changeset
   354
				if (err != 104) DEBUG(net, 0, "recv failed with error %d", err);
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   355
				*status = CloseConnection(cs);
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   356
				return NULL;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   357
			}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   358
			// Connection would block
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   359
			return NULL;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   360
		}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   361
		if (res == 0) {
5568
75f13d7bfaed (svn r7565) -Codechange: Rework DEBUG functionality. Look for appropiate debugging levels to
Darkvater
parents: 4880
diff changeset
   362
			// Client/server has left
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   363
			*status = CloseConnection(cs);
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   364
			return NULL;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   365
		}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   366
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   367
		p->pos += res;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   368
	}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   369
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   370
	// We have a complete packet, return it!
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   371
	p->pos = 2;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   372
	p->next = NULL; // Should not be needed, but who knows...
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   373
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   374
	// Prepare for receiving a new packet
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   375
	cs->packet_recv = NULL;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   376
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   377
	return p;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   378
}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   379
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   380
// Add a command to the local command queue
716
40a349345f82 (svn r1168) -Cleanup: [Network] Cleaned the network code a bit. Added 'const'
truelight
parents: 543
diff changeset
   381
void NetworkAddCommandQueue(NetworkClientState *cs, CommandPacket *cp)
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   382
{
4077
d3022f976946 (svn r5391) Miscellaneous, mostly bracing and whitespace, nothing spectacular
tron
parents: 3547
diff changeset
   383
	CommandPacket* new_cp = malloc(sizeof(*new_cp));
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   384
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   385
	*new_cp = *cp;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   386
4077
d3022f976946 (svn r5391) Miscellaneous, mostly bracing and whitespace, nothing spectacular
tron
parents: 3547
diff changeset
   387
	if (cs->command_queue == NULL) {
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   388
		cs->command_queue = new_cp;
4077
d3022f976946 (svn r5391) Miscellaneous, mostly bracing and whitespace, nothing spectacular
tron
parents: 3547
diff changeset
   389
	} else {
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   390
		CommandPacket *c = cs->command_queue;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   391
		while (c->next != NULL) c = c->next;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   392
		c->next = new_cp;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   393
	}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   394
}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   395
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   396
// Prepare a DoCommand to be send over the network
1977
4392ae3d8e31 (svn r2483) Replace almost 500 "uint tile" (and variants) with "TileIndex tile"
tron
parents: 1820
diff changeset
   397
void NetworkSend_Command(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback)
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   398
{
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   399
	CommandPacket *c = malloc(sizeof(CommandPacket));
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   400
	byte temp_callback;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   401
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   402
	c->player = _local_player;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   403
	c->next = NULL;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   404
	c->tile = tile;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   405
	c->p1 = p1;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   406
	c->p2 = p2;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   407
	c->cmd = cmd;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   408
	c->callback = 0;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   409
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   410
	temp_callback = 0;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   411
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   412
	while (temp_callback < _callback_table_count && _callback_table[temp_callback] != callback)
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   413
		temp_callback++;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   414
	if (temp_callback == _callback_table_count) {
5568
75f13d7bfaed (svn r7565) -Codechange: Rework DEBUG functionality. Look for appropiate debugging levels to
Darkvater
parents: 4880
diff changeset
   415
		DEBUG(net, 0, "Unknown callback. (Pointer: %p) No callback sent", callback);
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   416
		temp_callback = 0; /* _callback_table[0] == NULL */
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   417
	}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   418
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   419
	if (_network_server) {
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   420
		// We are the server, so set the command to be executed next possible frame
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   421
		c->frame = _frame_counter_max + 1;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   422
	} else {
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   423
		c->frame = 0; // The client can't tell which frame, so just make it 0
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   424
	}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   425
1820
9b6458526480 (svn r2324) Introduce _cmd_text for passing strings with a command instead of abusing _decode_parameters as text buffer. This should prevent several possible buffer overruns and is a bit cleaner to use. As bonus it reduces the size of most command packets by 79 bytes.
tron
parents: 1299
diff changeset
   426
	ttd_strlcpy(c->text, (_cmd_text != NULL) ? _cmd_text : "", lengthof(c->text));
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   427
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   428
	if (_network_server) {
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   429
		// If we are the server, we queue the command in our 'special' queue.
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   430
		//   In theory, we could execute the command right away, but then the
826
0e2b569b737b (svn r1297) Language fixes in the source.. (ln-)
miham
parents: 716
diff changeset
   431
		//   client on the server can do everything 1 tick faster than others.
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   432
		//   So to keep the game fair, we delay the command with 1 tick
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   433
		//   which gives about the same speed as most clients.
716
40a349345f82 (svn r1168) -Cleanup: [Network] Cleaned the network code a bit. Added 'const'
truelight
parents: 543
diff changeset
   434
		NetworkClientState *cs;
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   435
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   436
		// And we queue it for delivery to the clients
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   437
		FOR_ALL_CLIENTS(cs) {
4077
d3022f976946 (svn r5391) Miscellaneous, mostly bracing and whitespace, nothing spectacular
tron
parents: 3547
diff changeset
   438
			if (cs->status > STATUS_AUTH) NetworkAddCommandQueue(cs, c);
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   439
		}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   440
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   441
		// Only the server gets the callback, because clients should not get them
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   442
		c->callback = temp_callback;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   443
		if (_local_command_queue == NULL) {
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   444
			_local_command_queue = c;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   445
		} else {
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   446
			// Find last packet
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   447
			CommandPacket *cp = _local_command_queue;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   448
			while (cp->next != NULL) cp = cp->next;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   449
			cp->next = c;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   450
		}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   451
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   452
		return;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   453
	}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   454
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   455
	// Clients send their command to the server and forget all about the packet
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   456
	c->callback = temp_callback;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   457
	SEND_COMMAND(PACKET_CLIENT_COMMAND)(c);
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   458
}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   459
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   460
// Execute a DoCommand we received from the network
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   461
void NetworkExecuteCommand(CommandPacket *cp)
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   462
{
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   463
	_current_player = cp->player;
1820
9b6458526480 (svn r2324) Introduce _cmd_text for passing strings with a command instead of abusing _decode_parameters as text buffer. This should prevent several possible buffer overruns and is a bit cleaner to use. As bonus it reduces the size of most command packets by 79 bytes.
tron
parents: 1299
diff changeset
   464
	_cmd_text = cp->text;
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   465
	/* cp->callback is unsigned. so we don't need to do lower bounds checking. */
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   466
	if (cp->callback > _callback_table_count) {
5568
75f13d7bfaed (svn r7565) -Codechange: Rework DEBUG functionality. Look for appropiate debugging levels to
Darkvater
parents: 4880
diff changeset
   467
		DEBUG(net, 0, "Received out-of-bounds callback (%d)", cp->callback);
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   468
		cp->callback = 0;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   469
	}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   470
	DoCommandP(cp->tile, cp->p1, cp->p2, _callback_table[cp->callback], cp->cmd | CMD_NETWORK_COMMAND);
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   471
}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   472
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   473
#endif /* ENABLE_NETWORK */