src/network/network_data.cpp
author glx
Sun, 30 Dec 2007 16:34:32 +0000
changeset 8160 2accc3a736ba
parent 8130 d2eb7d04f6e1
child 8199 3c13a496ca80
permissions -rw-r--r--
(svn r11722) -Fix (r11703): invalid plural form
2186
db48cf29b983 (svn r2701) Insert Id tags into all source files
tron
parents: 2163
diff changeset
     1
/* $Id$ */
db48cf29b983 (svn r2701) Insert Id tags into all source files
tron
parents: 2163
diff changeset
     2
4826
6a545d194528 (svn r6750) -Codechange: Juggle around some header includes as they're only used when
Darkvater
parents: 4077
diff changeset
     3
#ifdef ENABLE_NETWORK
6a545d194528 (svn r6750) -Codechange: Juggle around some header includes as they're only used when
Darkvater
parents: 4077
diff changeset
     4
5469
7edfc643abbc (svn r7751) -Codechange: move network_* to a new network map. Furthermore move the low level network functions to network/core, so they can be reused by the masterserver and website-serverlist-updater.
rubidium
parents: 5380
diff changeset
     5
#include "../stdafx.h"
7edfc643abbc (svn r7751) -Codechange: move network_* to a new network map. Furthermore move the low level network functions to network/core, so they can be reused by the masterserver and website-serverlist-updater.
rubidium
parents: 5380
diff changeset
     6
#include "../debug.h"
543
946badd71033 (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
     7
#include "network_data.h"
5469
7edfc643abbc (svn r7751) -Codechange: move network_* to a new network map. Furthermore move the low level network functions to network/core, so they can be reused by the masterserver and website-serverlist-updater.
rubidium
parents: 5380
diff changeset
     8
#include "../string.h"
543
946badd71033 (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
     9
#include "network_client.h"
8116
8da76dcb3287 (svn r11677) -Codechange: move price and command related types/functions to their respective places.
rubidium
parents: 7222
diff changeset
    10
#include "../command_func.h"
5469
7edfc643abbc (svn r7751) -Codechange: move network_* to a new network map. Furthermore move the low level network functions to network/core, so they can be reused by the masterserver and website-serverlist-updater.
rubidium
parents: 5380
diff changeset
    11
#include "../callback_table.h"
8130
d2eb7d04f6e1 (svn r11691) -Codechange: move+rename helpers.hpp and only include it when it is really needed.
rubidium
parents: 8116
diff changeset
    12
#include "../core/alloc_func.hpp"
543
946badd71033 (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    13
946badd71033 (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    14
// Add a command to the local command queue
5624
6afe9d27430a (svn r8083) -Codechange: make a NetworkSocketHandler as base for all sockets and move a little of NetworkClientState functionality to the NetworkSocketHandler. Move the rest of the NetworkClientState to the new NetworkTCPSocketHandler class/struct, which is not yet implemented in an object oriented manner. The UDP socket handler now extends the NetworkSocketHandler instead of having a reference to a NetworkClientState.
rubidium
parents: 5609
diff changeset
    15
void NetworkAddCommandQueue(NetworkTCPSocketHandler *cs, CommandPacket *cp)
543
946badd71033 (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    16
{
5609
dc6a58930ba4 (svn r8066) - Codechange: MallocT(), CallocT(), ReallocT() now return the pointer to allocated memory instead of modifying the pointer given as parameter
KUDr
parents: 5587
diff changeset
    17
	CommandPacket* new_cp = MallocT<CommandPacket>(1);
543
946badd71033 (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    18
946badd71033 (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    19
	*new_cp = *cp;
946badd71033 (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    20
4077
d4d440dd8925 (svn r5391) Miscellaneous, mostly bracing and whitespace, nothing spectacular
tron
parents: 3547
diff changeset
    21
	if (cs->command_queue == NULL) {
543
946badd71033 (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    22
		cs->command_queue = new_cp;
4077
d4d440dd8925 (svn r5391) Miscellaneous, mostly bracing and whitespace, nothing spectacular
tron
parents: 3547
diff changeset
    23
	} else {
543
946badd71033 (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    24
		CommandPacket *c = cs->command_queue;
946badd71033 (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    25
		while (c->next != NULL) c = c->next;
946badd71033 (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    26
		c->next = new_cp;
946badd71033 (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    27
	}
946badd71033 (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    28
}
946badd71033 (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    29
946badd71033 (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    30
// Prepare a DoCommand to be send over the network
1977
37bbebf94434 (svn r2483) Replace almost 500 "uint tile" (and variants) with "TileIndex tile"
tron
parents: 1820
diff changeset
    31
void NetworkSend_Command(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback)
543
946badd71033 (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    32
{
6843
691472811a8e (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5624
diff changeset
    33
	CommandPacket c;
543
946badd71033 (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    34
6843
691472811a8e (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5624
diff changeset
    35
	c.player = _local_player;
691472811a8e (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5624
diff changeset
    36
	c.next   = NULL;
691472811a8e (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5624
diff changeset
    37
	c.tile   = tile;
691472811a8e (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5624
diff changeset
    38
	c.p1     = p1;
691472811a8e (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5624
diff changeset
    39
	c.p2     = p2;
691472811a8e (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5624
diff changeset
    40
	c.cmd    = cmd;
543
946badd71033 (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    41
6843
691472811a8e (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5624
diff changeset
    42
	c.callback = 0;
691472811a8e (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5624
diff changeset
    43
	while (c.callback < _callback_table_count && _callback_table[c.callback] != callback) {
691472811a8e (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5624
diff changeset
    44
		c.callback++;
691472811a8e (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5624
diff changeset
    45
	}
543
946badd71033 (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    46
6843
691472811a8e (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5624
diff changeset
    47
	if (c.callback == _callback_table_count) {
5380
8ea58542b6e0 (svn r7565) -Codechange: Rework DEBUG functionality. Look for appropiate debugging levels to
Darkvater
parents: 4880
diff changeset
    48
		DEBUG(net, 0, "Unknown callback. (Pointer: %p) No callback sent", callback);
6843
691472811a8e (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5624
diff changeset
    49
		c.callback = 0; // _callback_table[0] == NULL
543
946badd71033 (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    50
	}
946badd71033 (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    51
6843
691472811a8e (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5624
diff changeset
    52
	ttd_strlcpy(c.text, (_cmd_text != NULL) ? _cmd_text : "", lengthof(c.text));
691472811a8e (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5624
diff changeset
    53
543
946badd71033 (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    54
	if (_network_server) {
6843
691472811a8e (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5624
diff changeset
    55
		/* If we are the server, we queue the command in our 'special' queue.
691472811a8e (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5624
diff changeset
    56
		 *   In theory, we could execute the command right away, but then the
691472811a8e (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5624
diff changeset
    57
		 *   client on the server can do everything 1 tick faster than others.
691472811a8e (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5624
diff changeset
    58
		 *   So to keep the game fair, we delay the command with 1 tick
691472811a8e (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5624
diff changeset
    59
		 *   which gives about the same speed as most clients.
691472811a8e (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5624
diff changeset
    60
		 */
691472811a8e (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5624
diff changeset
    61
		c.frame = _frame_counter_max + 1;
543
946badd71033 (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    62
6843
691472811a8e (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5624
diff changeset
    63
		CommandPacket *new_cp = MallocT<CommandPacket>(1);
691472811a8e (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5624
diff changeset
    64
		*new_cp = c;
7222
d46753675bf7 (svn r10501) -Fix [FS#1015]: error dialog was sometimes shown on all clients when a command failed instead of only the client that actually did the command.
rubidium
parents: 7187
diff changeset
    65
		new_cp->my_cmd = true;
6843
691472811a8e (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5624
diff changeset
    66
		if (_local_command_queue == NULL) {
691472811a8e (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5624
diff changeset
    67
			_local_command_queue = new_cp;
691472811a8e (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5624
diff changeset
    68
		} else {
691472811a8e (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5624
diff changeset
    69
			/* Find last packet */
691472811a8e (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5624
diff changeset
    70
			CommandPacket *cp = _local_command_queue;
691472811a8e (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5624
diff changeset
    71
			while (cp->next != NULL) cp = cp->next;
691472811a8e (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5624
diff changeset
    72
			cp->next = new_cp;
543
946badd71033 (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    73
		}
946badd71033 (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    74
6843
691472811a8e (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5624
diff changeset
    75
		/* Only the local client (in this case, the server) gets the callback */
691472811a8e (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5624
diff changeset
    76
		c.callback = 0;
691472811a8e (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5624
diff changeset
    77
		/* And we queue it for delivery to the clients */
691472811a8e (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5624
diff changeset
    78
		NetworkTCPSocketHandler *cs;
691472811a8e (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5624
diff changeset
    79
		FOR_ALL_CLIENTS(cs) {
691472811a8e (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5624
diff changeset
    80
			if (cs->status > STATUS_AUTH) NetworkAddCommandQueue(cs, &c);
543
946badd71033 (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    81
		}
946badd71033 (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    82
		return;
946badd71033 (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    83
	}
946badd71033 (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    84
6843
691472811a8e (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5624
diff changeset
    85
	c.frame = 0; // The client can't tell which frame, so just make it 0
691472811a8e (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5624
diff changeset
    86
691472811a8e (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5624
diff changeset
    87
	/* Clients send their command to the server and forget all about the packet */
691472811a8e (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5624
diff changeset
    88
	SEND_COMMAND(PACKET_CLIENT_COMMAND)(&c);
543
946badd71033 (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    89
}
946badd71033 (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    90
946badd71033 (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    91
// Execute a DoCommand we received from the network
946badd71033 (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    92
void NetworkExecuteCommand(CommandPacket *cp)
946badd71033 (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    93
{
946badd71033 (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    94
	_current_player = cp->player;
1820
d03c56850dc2 (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
    95
	_cmd_text = cp->text;
543
946badd71033 (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    96
	/* cp->callback is unsigned. so we don't need to do lower bounds checking. */
946badd71033 (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    97
	if (cp->callback > _callback_table_count) {
5380
8ea58542b6e0 (svn r7565) -Codechange: Rework DEBUG functionality. Look for appropiate debugging levels to
Darkvater
parents: 4880
diff changeset
    98
		DEBUG(net, 0, "Received out-of-bounds callback (%d)", cp->callback);
543
946badd71033 (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    99
		cp->callback = 0;
946badd71033 (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   100
	}
7187
7c9bf9e10d8b (svn r10462) -Add: a command dumper/loader that could be enabled compile-time and server side only to aid debugging some desyncs, i.e. dump the stream of commands so it could be replayed in exactly the same way later. This should primarily be used to make desyncs more easily reproducable, so it can be properly debugged.
rubidium
parents: 6843
diff changeset
   101
7c9bf9e10d8b (svn r10462) -Add: a command dumper/loader that could be enabled compile-time and server side only to aid debugging some desyncs, i.e. dump the stream of commands so it could be replayed in exactly the same way later. This should primarily be used to make desyncs more easily reproducable, so it can be properly debugged.
rubidium
parents: 6843
diff changeset
   102
#ifdef DEBUG_DUMP_COMMANDS
7c9bf9e10d8b (svn r10462) -Add: a command dumper/loader that could be enabled compile-time and server side only to aid debugging some desyncs, i.e. dump the stream of commands so it could be replayed in exactly the same way later. This should primarily be used to make desyncs more easily reproducable, so it can be properly debugged.
rubidium
parents: 6843
diff changeset
   103
	debug_dump_commands("ddc:cmd:%d;%d;%d;%d;%d;%d;%d;%s\n", _date, _date_fract, (int)cp->player, cp->tile, cp->p1, cp->p2, cp->cmd, cp->text);
7c9bf9e10d8b (svn r10462) -Add: a command dumper/loader that could be enabled compile-time and server side only to aid debugging some desyncs, i.e. dump the stream of commands so it could be replayed in exactly the same way later. This should primarily be used to make desyncs more easily reproducable, so it can be properly debugged.
rubidium
parents: 6843
diff changeset
   104
#endif /* DUMP_COMMANDS */
7c9bf9e10d8b (svn r10462) -Add: a command dumper/loader that could be enabled compile-time and server side only to aid debugging some desyncs, i.e. dump the stream of commands so it could be replayed in exactly the same way later. This should primarily be used to make desyncs more easily reproducable, so it can be properly debugged.
rubidium
parents: 6843
diff changeset
   105
7222
d46753675bf7 (svn r10501) -Fix [FS#1015]: error dialog was sometimes shown on all clients when a command failed instead of only the client that actually did the command.
rubidium
parents: 7187
diff changeset
   106
	DoCommandP(cp->tile, cp->p1, cp->p2, _callback_table[cp->callback], cp->cmd | CMD_NETWORK_COMMAND, cp->my_cmd);
543
946badd71033 (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   107
}
946badd71033 (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   108
946badd71033 (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   109
#endif /* ENABLE_NETWORK */