network_data.c
author Darkvater
Thu, 26 Jan 2006 16:19:24 +0000
changeset 2887 d5967e472eee
parent 2644 6f699b15c531
child 2989 99c95a3ebcaa
permissions -rw-r--r--
(svn r3439) - CodeChange: Remove a whole bunch of global variables and put them into the WP() macro. Also combine more than one WP-custom element. For this the maximum size of w->custom (WP) has been increased, and multiple types put inside one with possibly moved to the corresponding gui file if it is only used there.
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
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
     3
#include "stdafx.h"
1299
0a6510cc889b (svn r1803) Move debugging stuff into files of it's own
tron
parents: 1095
diff changeset
     4
#include "debug.h"
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
     5
#include "network_data.h"
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
     6
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
     7
// Is the network enabled?
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
     8
#ifdef ENABLE_NETWORK
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
     9
2163
637ec3c361f5 (svn r2673) Include functions.h directly, not globally via openttd.h
tron
parents: 2153
diff changeset
    10
#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
    11
#include "string.h"
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    12
#include "table/strings.h"
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    13
#include "network_client.h"
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    14
#include "command.h"
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    15
#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
    16
#include "variables.h"
543
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
// This files handles the send/receive of all packets
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    19
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    20
// Create a packet for sending
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    21
Packet *NetworkSend_Init(PacketType type)
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    22
{
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    23
	Packet *packet = malloc(sizeof(Packet));
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    24
	// 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
    25
	if (packet == NULL) error("Failed to allocate Packet");
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    26
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    27
	// 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
    28
	packet->size = sizeof(packet->size);
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    29
	packet->buffer[packet->size++] = type;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    30
	packet->pos = 0;
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
	return packet;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    33
}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    34
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    35
// The next couple of functions make sure we can send
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    36
//  uint8, uint16, uint32 and uint64 endian-safe
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    37
//  over the network. The order it uses is:
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
//  1 2 3 4
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    40
//
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
void NetworkSend_uint8(Packet *packet, uint8 data)
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    43
{
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    44
	assert(packet->size < sizeof(packet->buffer) - sizeof(data));
2644
6f699b15c531 (svn r3186) Unnecessary casts and truncation
tron
parents: 2186
diff changeset
    45
	packet->buffer[packet->size++] = data;
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    46
}
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
void NetworkSend_uint16(Packet *packet, uint16 data)
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    49
{
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    50
	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
    51
	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
    52
	packet->buffer[packet->size++] = GB(data, 8, 8);
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    53
}
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
void NetworkSend_uint32(Packet *packet, uint32 data)
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    56
{
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    57
	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
    58
	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
    59
	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
    60
	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
    61
	packet->buffer[packet->size++] = GB(data, 24, 8);
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    62
}
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
void NetworkSend_uint64(Packet *packet, uint64 data)
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    65
{
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    66
	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
    67
	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
    68
	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
    69
	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
    70
	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
    71
	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
    72
	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
    73
	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
    74
	packet->buffer[packet->size++] = GB(data, 56, 8);
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    75
}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    76
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    77
// Sends a string over the network. It sends out
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    78
//  the string + '\0'. No size-byte or something.
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    79
void NetworkSend_string(Packet *packet, const char* data)
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    80
{
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    81
	assert(data != NULL);
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    82
	assert(packet->size < sizeof(packet->buffer) - strlen(data) - 1);
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    83
	while ((packet->buffer[packet->size++] = *data++) != '\0') {}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    84
}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    85
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    86
// 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
    87
//   lines below matching the size of packet->size/PacketSize!
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    88
// (line 'packet->buffer[0] = packet->size & 0xFF;'  and below)
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    89
assert_compile(sizeof(PacketSize) == 2);
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    90
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    91
// 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
    92
//  as soon as possible
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    93
// (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
    94
//   OS-network-buffer is full)
716
40a349345f82 (svn r1168) -Cleanup: [Network] Cleaned the network code a bit. Added 'const'
truelight
parents: 543
diff changeset
    95
void NetworkSend_Packet(Packet *packet, NetworkClientState *cs)
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    96
{
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    97
	Packet *p;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    98
	assert(packet != NULL);
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    99
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   100
	packet->pos = 0;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   101
	packet->next = NULL;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   102
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   103
	packet->buffer[0] = packet->size & 0xFF;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   104
	packet->buffer[1] = packet->size >> 8;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   105
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   106
	// Locate last packet buffered for the client
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   107
	p = cs->packet_queue;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   108
	if (p == NULL) {
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   109
		// No packets yet
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   110
		cs->packet_queue = packet;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   111
	} else {
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   112
		// Skip to the last packet
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   113
		while (p->next != NULL) p = p->next;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   114
		p->next = packet;
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
}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   117
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   118
// Functions to help NetworkRecv_Packet/NetworkSend_Packet a bit
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   119
//  A socket can make errors. When that happens
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   120
//  this handles what to do.
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   121
// For clients: close connection and drop back to main-menu
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   122
// For servers: close connection and that is it
1095
90220990fd7c (svn r1596) Add some more statics
tron
parents: 903
diff changeset
   123
static NetworkRecvStatus CloseConnection(NetworkClientState *cs)
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   124
{
716
40a349345f82 (svn r1168) -Cleanup: [Network] Cleaned the network code a bit. Added 'const'
truelight
parents: 543
diff changeset
   125
	NetworkCloseClient(cs);
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   126
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   127
	// Clients drop back to the main menu
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   128
	if (!_network_server) {
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   129
		_switch_mode = SM_MENU;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   130
		_networking = false;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   131
		_switch_mode_errorstr = STR_NETWORK_ERR_LOSTCONNECTION;
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
		return NETWORK_RECV_STATUS_CONN_LOST;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   134
	}
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
	return NETWORK_RECV_STATUS_OKAY;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   137
}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   138
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   139
// Sends all the buffered packets out for this client
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   140
//  it stops when:
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   141
//   1) all packets are send (queue is empty)
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   142
//   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
   143
//        data right now (full network-buffer, it happens ;))
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   144
//   3) sending took too long
716
40a349345f82 (svn r1168) -Cleanup: [Network] Cleaned the network code a bit. Added 'const'
truelight
parents: 543
diff changeset
   145
bool NetworkSend_Packets(NetworkClientState *cs)
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   146
{
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   147
	ssize_t res;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   148
	Packet *p;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   149
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   150
	// We can not write to this socket!!
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   151
	if (!cs->writable) return false;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   152
	if (cs->socket == INVALID_SOCKET) return false;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   153
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   154
	p = cs->packet_queue;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   155
	while (p != NULL) {
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   156
		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
   157
		if (res == -1) {
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   158
			int err = GET_LAST_ERROR();
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   159
			if (err != EWOULDBLOCK) {
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   160
				// Something went wrong.. close client!
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   161
				DEBUG(net, 0) ("[NET] send() failed with error %d", err);
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   162
				CloseConnection(cs);
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   163
				return false;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   164
			}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   165
			return true;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   166
		}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   167
		if (res == 0) {
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   168
			// Client/server has left us :(
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   169
			CloseConnection(cs);
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   170
			return false;
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
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   173
		p->pos += res;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   174
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   175
		// Is this packet sent?
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   176
		if (p->pos == p->size) {
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   177
			// Go to the next packet
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   178
			cs->packet_queue = p->next;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   179
			free(p);
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   180
			p = cs->packet_queue;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   181
		} else
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   182
			return true;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   183
	}
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
	return true;
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
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   188
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   189
// Receiving commands
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   190
// Again, the next couple of functions are endian-safe
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   191
//  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
   192
uint8 NetworkRecv_uint8(NetworkClientState *cs, Packet *packet)
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   193
{
903
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   194
	/* Don't allow reading from a closed socket */
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   195
	if (cs->quited)
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   196
		return 0;
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   197
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   198
	/* 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
   199
	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
   200
		CloseConnection(cs);
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   201
		return 0;
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   202
	}
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   203
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   204
	return packet->buffer[packet->pos++];
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
903
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   207
uint16 NetworkRecv_uint16(NetworkClientState *cs, Packet *packet)
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   208
{
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   209
	uint16 n;
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
	/* Don't allow reading from a closed socket */
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   212
	if (cs->quited)
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   213
		return 0;
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   214
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   215
	/* 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
   216
	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
   217
		CloseConnection(cs);
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   218
		return 0;
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   219
	}
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   220
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   221
	n  = (uint16)packet->buffer[packet->pos++];
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   222
	n += (uint16)packet->buffer[packet->pos++] << 8;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   223
	return n;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   224
}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   225
903
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   226
uint32 NetworkRecv_uint32(NetworkClientState *cs, Packet *packet)
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   227
{
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   228
	uint32 n;
903
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   229
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   230
	/* Don't allow reading from a closed socket */
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   231
	if (cs->quited)
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
	/* 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
   235
	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
   236
		CloseConnection(cs);
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   237
		return 0;
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   238
	}
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   239
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   240
	n  = (uint32)packet->buffer[packet->pos++];
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   241
	n += (uint32)packet->buffer[packet->pos++] << 8;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   242
	n += (uint32)packet->buffer[packet->pos++] << 16;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   243
	n += (uint32)packet->buffer[packet->pos++] << 24;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   244
	return n;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   245
}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   246
903
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   247
uint64 NetworkRecv_uint64(NetworkClientState *cs, Packet *packet)
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   248
{
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   249
	uint64 n;
903
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   250
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   251
	/* Don't allow reading from a closed socket */
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   252
	if (cs->quited)
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   253
		return 0;
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   254
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   255
	/* 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
   256
	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
   257
		CloseConnection(cs);
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   258
		return 0;
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   259
	}
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   260
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   261
	n  = (uint64)packet->buffer[packet->pos++];
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   262
	n += (uint64)packet->buffer[packet->pos++] << 8;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   263
	n += (uint64)packet->buffer[packet->pos++] << 16;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   264
	n += (uint64)packet->buffer[packet->pos++] << 24;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   265
	n += (uint64)packet->buffer[packet->pos++] << 32;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   266
	n += (uint64)packet->buffer[packet->pos++] << 40;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   267
	n += (uint64)packet->buffer[packet->pos++] << 48;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   268
	n += (uint64)packet->buffer[packet->pos++] << 56;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   269
	return n;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   270
}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   271
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   272
// Reads a string till it finds a '\0' in the stream
903
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   273
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
   274
{
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   275
	int pos;
903
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   276
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   277
	/* Don't allow reading from a closed socket */
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   278
	if (cs->quited)
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   279
		return;
f860c7234167 (svn r1389) -Add: [Network] Added packet protection. No longer a client or server
truelight
parents: 826
diff changeset
   280
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   281
	pos = p->pos;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   282
	while (--size > 0 && pos < p->size && (*buffer++ = p->buffer[pos++]) != '\0') {}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   283
	if (size == 0 || pos == p->size)
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
		*buffer = '\0';
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   286
		// 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
   287
		//  skip till the \0, so the packet can be read out correctly for the rest
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   288
		while (pos < p->size && p->buffer[pos] != '\0') ++pos;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   289
		++pos;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   290
	}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   291
	p->pos = pos;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   292
}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   293
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   294
// 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
   295
//   lines below matching the size of packet->size/PacketSize!
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   296
// (the line: 'p->size = (uint16)p->buffer[0];' and below)
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   297
assert_compile(sizeof(PacketSize) == 2);
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   298
716
40a349345f82 (svn r1168) -Cleanup: [Network] Cleaned the network code a bit. Added 'const'
truelight
parents: 543
diff changeset
   299
Packet *NetworkRecv_Packet(NetworkClientState *cs, NetworkRecvStatus *status)
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   300
{
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   301
	ssize_t res;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   302
	Packet *p;
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
	*status = NETWORK_RECV_STATUS_OKAY;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   305
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   306
	if (cs->socket == INVALID_SOCKET) return NULL;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   307
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   308
	if (cs->packet_recv == NULL) {
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   309
		cs->packet_recv = malloc(sizeof(Packet));
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   310
		if (cs->packet_recv == NULL) error("Failed to allocate packet");
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   311
		// Set pos to zero!
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   312
		cs->packet_recv->pos = 0;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   313
		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
   314
	}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   315
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   316
	p = cs->packet_recv;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   317
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   318
	// Read packet size
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   319
	if (p->pos < sizeof(PacketSize)) {
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   320
		while (p->pos < sizeof(PacketSize)) {
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   321
			// Read the size of the packet
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   322
			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
   323
			if (res == -1) {
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   324
				int err = GET_LAST_ERROR();
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   325
				if (err != EWOULDBLOCK) {
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   326
					// Something went wrong..
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   327
					if (err != 104) // 104 is Connection Reset by Peer
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   328
						DEBUG(net, 0) ("[NET] recv() failed with error %d", err);
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   329
					*status = CloseConnection(cs);
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   330
					return NULL;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   331
				}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   332
				// Connection would block, so stop for now
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
			if (res == 0) {
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   336
				// Client/server has left us :(
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   337
				*status = CloseConnection(cs);
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   338
				return NULL;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   339
			}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   340
			p->pos += res;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   341
		}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   342
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   343
		p->size = (uint16)p->buffer[0];
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   344
		p->size += (uint16)p->buffer[1] << 8;
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
		if (p->size > SEND_MTU) {
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   347
			*status = CloseConnection(cs);
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   348
			return NULL;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   349
		}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   350
	}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   351
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   352
	// Read rest of packet
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   353
	while (p->pos < p->size) {
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   354
		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
   355
		if (res == -1) {
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   356
			int err = GET_LAST_ERROR();
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   357
			if (err != EWOULDBLOCK) {
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   358
				// Something went wrong..
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   359
				if (err != 104) // 104 is Connection Reset by Peer
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   360
					DEBUG(net, 0) ("[NET] recv() failed with error %d", err);
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   361
				*status = CloseConnection(cs);
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   362
				return NULL;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   363
			}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   364
			// Connection would block
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   365
			return NULL;
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
		if (res == 0) {
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   368
			// Client/server has left us :(
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   369
			*status = CloseConnection(cs);
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   370
			return NULL;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   371
		}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   372
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   373
		p->pos += res;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   374
	}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   375
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   376
	// We have a complete packet, return it!
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   377
	p->pos = 2;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   378
	p->next = NULL; // Should not be needed, but who knows...
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
	// Prepare for receiving a new packet
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   381
	cs->packet_recv = NULL;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   382
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   383
	return p;
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
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   386
// 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
   387
void NetworkAddCommandQueue(NetworkClientState *cs, CommandPacket *cp)
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   388
{
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   389
	CommandPacket *new_cp = malloc(sizeof(CommandPacket));
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   390
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   391
	*new_cp = *cp;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   392
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   393
	if (cs->command_queue == NULL)
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   394
		cs->command_queue = new_cp;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   395
	else {
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   396
		CommandPacket *c = cs->command_queue;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   397
		while (c->next != NULL) c = c->next;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   398
		c->next = new_cp;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   399
	}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   400
}
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
// 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
   403
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
   404
{
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   405
	CommandPacket *c = malloc(sizeof(CommandPacket));
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   406
	byte temp_callback;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   407
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   408
	c->player = _local_player;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   409
	c->next = NULL;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   410
	c->tile = tile;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   411
	c->p1 = p1;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   412
	c->p2 = p2;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   413
	c->cmd = cmd;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   414
	c->callback = 0;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   415
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   416
	temp_callback = 0;
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
	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
   419
		temp_callback++;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   420
	if (temp_callback == _callback_table_count) {
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   421
		DEBUG(net, 0) ("[NET] Unknown callback. (Pointer: %p) No callback sent.", callback);
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   422
		temp_callback = 0; /* _callback_table[0] == NULL */
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   423
	}
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
	if (_network_server) {
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   426
		// 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
   427
		c->frame = _frame_counter_max + 1;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   428
	} else {
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   429
		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
   430
	}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   431
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
   432
	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
   433
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   434
	if (_network_server) {
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   435
		// 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
   436
		//   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
   437
		//   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
   438
		//   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
   439
		//   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
   440
		NetworkClientState *cs;
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   441
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   442
		// And we queue it for delivery to the clients
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   443
		FOR_ALL_CLIENTS(cs) {
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   444
			if (cs->status > STATUS_AUTH) {
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   445
				NetworkAddCommandQueue(cs, c);
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   446
			}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   447
		}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   448
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   449
		// 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
   450
		c->callback = temp_callback;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   451
		if (_local_command_queue == NULL) {
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   452
			_local_command_queue = c;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   453
		} else {
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   454
			// Find last packet
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   455
			CommandPacket *cp = _local_command_queue;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   456
			while (cp->next != NULL) cp = cp->next;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   457
			cp->next = 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
		return;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   461
	}
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
	// 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
   464
	c->callback = temp_callback;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   465
	SEND_COMMAND(PACKET_CLIENT_COMMAND)(c);
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   466
}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   467
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   468
// Execute a DoCommand we received from the network
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   469
void NetworkExecuteCommand(CommandPacket *cp)
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   470
{
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   471
	_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
   472
	_cmd_text = cp->text;
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   473
	/* 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
   474
	if (cp->callback > _callback_table_count) {
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   475
		DEBUG(net,0) ("[NET] Received out-of-bounds callback! (%d)", cp->callback);
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   476
		cp->callback = 0;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   477
	}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   478
	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
   479
}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   480
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   481
#endif /* ENABLE_NETWORK */