src/network/network_data.cpp
author skidd13
Sun, 15 Jun 2008 22:10:22 +0000
changeset 10970 c0341ebaf88f
parent 10792 95b6eb9fcc9e
permissions -rw-r--r--
(svn r13524) -Codechange: use the typesafe QSort for vehicle sortings
-Prepare: vehicles sorting for convsersion to GUIList
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
10429
1b99254f9607 (svn r12971) -Documentation: add @file in files that missed them and add something more than whitespace as description of files that don't have a description.
rubidium
parents: 9190
diff changeset
     3
/** @file network_data.cpp Command handling over network connections. */
1b99254f9607 (svn r12971) -Documentation: add @file in files that missed them and add something more than whitespace as description of files that don't have a description.
rubidium
parents: 9190
diff changeset
     4
4826
63b1eb7c966b (svn r6750) -Codechange: Juggle around some header includes as they're only used when
Darkvater
parents: 4077
diff changeset
     5
#ifdef ENABLE_NETWORK
63b1eb7c966b (svn r6750) -Codechange: Juggle around some header includes as they're only used when
Darkvater
parents: 4077
diff changeset
     6
5720
cc0ceeafaa55 (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: 5568
diff changeset
     7
#include "../stdafx.h"
cc0ceeafaa55 (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: 5568
diff changeset
     8
#include "../debug.h"
10792
95b6eb9fcc9e (svn r13343) -Codechange: reorder/move variable/functions in the network headers so that nothing from the network directory needs to include basically all network headers.
rubidium
parents: 10429
diff changeset
     9
#include "network_internal.h"
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    10
#include "network_client.h"
8612
6414fc21c2f3 (svn r11677) -Codechange: move price and command related types/functions to their respective places.
rubidium
parents: 7718
diff changeset
    11
#include "../command_func.h"
5720
cc0ceeafaa55 (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: 5568
diff changeset
    12
#include "../callback_table.h"
8626
440dfcd14c4a (svn r11691) -Codechange: move+rename helpers.hpp and only include it when it is really needed.
rubidium
parents: 8612
diff changeset
    13
#include "../core/alloc_func.hpp"
8710
52015340050c (svn r11777) -Codechange: split the string header and make do not include it when it's not necessary.
rubidium
parents: 8695
diff changeset
    14
#include "../string_func.h"
8743
62a558995c35 (svn r11811) -Fix: make compilation without networking work again (and thus move the debugdumpcommand stuff out of the network 'area').
rubidium
parents: 8710
diff changeset
    15
#include "../date_func.h"
8750
fdd6054e7bae (svn r11818) -Codechange: split player.h into smaller pieces.
rubidium
parents: 8743
diff changeset
    16
#include "../player_func.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
// Add a command to the local command queue
5875
4a1391019791 (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: 5860
diff changeset
    19
void NetworkAddCommandQueue(NetworkTCPSocketHandler *cs, CommandPacket *cp)
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    20
{
5860
7fdc9b423ba1 (svn r8066) - Codechange: MallocT(), CallocT(), ReallocT() now return the pointer to allocated memory instead of modifying the pointer given as parameter
KUDr
parents: 5838
diff changeset
    21
	CommandPacket* new_cp = MallocT<CommandPacket>(1);
543
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
	*new_cp = *cp;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    24
4077
d3022f976946 (svn r5391) Miscellaneous, mostly bracing and whitespace, nothing spectacular
tron
parents: 3547
diff changeset
    25
	if (cs->command_queue == NULL) {
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    26
		cs->command_queue = new_cp;
4077
d3022f976946 (svn r5391) Miscellaneous, mostly bracing and whitespace, nothing spectacular
tron
parents: 3547
diff changeset
    27
	} else {
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    28
		CommandPacket *c = cs->command_queue;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    29
		while (c->next != NULL) c = c->next;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    30
		c->next = new_cp;
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
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    34
// 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
    35
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
    36
{
7339
661958642f62 (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5875
diff changeset
    37
	CommandPacket c;
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    38
7339
661958642f62 (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5875
diff changeset
    39
	c.player = _local_player;
661958642f62 (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5875
diff changeset
    40
	c.next   = NULL;
661958642f62 (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5875
diff changeset
    41
	c.tile   = tile;
661958642f62 (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5875
diff changeset
    42
	c.p1     = p1;
661958642f62 (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5875
diff changeset
    43
	c.p2     = p2;
661958642f62 (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5875
diff changeset
    44
	c.cmd    = cmd;
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    45
7339
661958642f62 (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5875
diff changeset
    46
	c.callback = 0;
661958642f62 (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5875
diff changeset
    47
	while (c.callback < _callback_table_count && _callback_table[c.callback] != callback) {
661958642f62 (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5875
diff changeset
    48
		c.callback++;
661958642f62 (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5875
diff changeset
    49
	}
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    50
7339
661958642f62 (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5875
diff changeset
    51
	if (c.callback == _callback_table_count) {
5568
75f13d7bfaed (svn r7565) -Codechange: Rework DEBUG functionality. Look for appropiate debugging levels to
Darkvater
parents: 4880
diff changeset
    52
		DEBUG(net, 0, "Unknown callback. (Pointer: %p) No callback sent", callback);
7339
661958642f62 (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5875
diff changeset
    53
		c.callback = 0; // _callback_table[0] == NULL
543
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
7339
661958642f62 (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5875
diff changeset
    56
	ttd_strlcpy(c.text, (_cmd_text != NULL) ? _cmd_text : "", lengthof(c.text));
661958642f62 (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5875
diff changeset
    57
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    58
	if (_network_server) {
7339
661958642f62 (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5875
diff changeset
    59
		/* If we are the server, we queue the command in our 'special' queue.
661958642f62 (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5875
diff changeset
    60
		 *   In theory, we could execute the command right away, but then the
661958642f62 (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5875
diff changeset
    61
		 *   client on the server can do everything 1 tick faster than others.
661958642f62 (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5875
diff changeset
    62
		 *   So to keep the game fair, we delay the command with 1 tick
661958642f62 (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5875
diff changeset
    63
		 *   which gives about the same speed as most clients.
661958642f62 (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5875
diff changeset
    64
		 */
661958642f62 (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5875
diff changeset
    65
		c.frame = _frame_counter_max + 1;
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    66
7339
661958642f62 (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5875
diff changeset
    67
		CommandPacket *new_cp = MallocT<CommandPacket>(1);
661958642f62 (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5875
diff changeset
    68
		*new_cp = c;
7718
220603f0122e (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: 7683
diff changeset
    69
		new_cp->my_cmd = true;
7339
661958642f62 (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5875
diff changeset
    70
		if (_local_command_queue == NULL) {
661958642f62 (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5875
diff changeset
    71
			_local_command_queue = new_cp;
661958642f62 (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5875
diff changeset
    72
		} else {
661958642f62 (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5875
diff changeset
    73
			/* Find last packet */
661958642f62 (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5875
diff changeset
    74
			CommandPacket *cp = _local_command_queue;
661958642f62 (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5875
diff changeset
    75
			while (cp->next != NULL) cp = cp->next;
661958642f62 (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5875
diff changeset
    76
			cp->next = new_cp;
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    77
		}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    78
7339
661958642f62 (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5875
diff changeset
    79
		/* Only the local client (in this case, the server) gets the callback */
661958642f62 (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5875
diff changeset
    80
		c.callback = 0;
661958642f62 (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5875
diff changeset
    81
		/* And we queue it for delivery to the clients */
661958642f62 (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5875
diff changeset
    82
		NetworkTCPSocketHandler *cs;
661958642f62 (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5875
diff changeset
    83
		FOR_ALL_CLIENTS(cs) {
9190
6aacd72e0d05 (svn r12367) -Fix [FS#1650](r707): commands were sent to clients waiting for map download causing 'executing command from the past' error
smatz
parents: 8750
diff changeset
    84
			if (cs->status > STATUS_MAP_WAIT) NetworkAddCommandQueue(cs, &c);
543
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
		return;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    87
	}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    88
7339
661958642f62 (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5875
diff changeset
    89
	c.frame = 0; // The client can't tell which frame, so just make it 0
661958642f62 (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5875
diff changeset
    90
661958642f62 (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5875
diff changeset
    91
	/* Clients send their command to the server and forget all about the packet */
661958642f62 (svn r10082) -Fix [FS#846]: another memory leak in the networking code (benc).
rubidium
parents: 5875
diff changeset
    92
	SEND_COMMAND(PACKET_CLIENT_COMMAND)(&c);
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    93
}
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
// Execute a DoCommand we received from the network
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
    96
void NetworkExecuteCommand(CommandPacket *cp)
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
	_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
    99
	_cmd_text = cp->text;
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   100
	/* 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
   101
	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
   102
		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
   103
		cp->callback = 0;
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   104
	}
7683
cd00f3932777 (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: 7339
diff changeset
   105
8743
62a558995c35 (svn r11811) -Fix: make compilation without networking work again (and thus move the debugdumpcommand stuff out of the network 'area').
rubidium
parents: 8710
diff changeset
   106
	DebugDumpCommands("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);
7683
cd00f3932777 (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: 7339
diff changeset
   107
7718
220603f0122e (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: 7683
diff changeset
   108
	DoCommandP(cp->tile, cp->p1, cp->p2, _callback_table[cp->callback], cp->cmd | CMD_NETWORK_COMMAND, cp->my_cmd);
543
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   109
}
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   110
e3b43338096b (svn r942) -Merged branch/network back into the trunk
truelight
parents:
diff changeset
   111
#endif /* ENABLE_NETWORK */