Files
@ r5686:efbdee22bd39
Branch filter:
Location: cpp/openttd-patchpack/source/src/network/network_data.cpp
r5686:efbdee22bd39
3.0 KiB
text/x-c
(svn r8147) -Fix: [autoreplace] v->leave_depot_instantly was not always reset correctly
While it's not certain if this would have any serious sideeffects (or any at all), it's reset when intended now
While it's not certain if this would have any serious sideeffects (or any at all), it's reset when intended now
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | /* $Id$ */
#ifdef ENABLE_NETWORK
#include "../stdafx.h"
#include "../debug.h"
#include "network_data.h"
#include "../string.h"
#include "network_client.h"
#include "../command.h"
#include "../callback_table.h"
#include "../helpers.hpp"
// Add a command to the local command queue
void NetworkAddCommandQueue(NetworkTCPSocketHandler *cs, CommandPacket *cp)
{
CommandPacket* new_cp = MallocT<CommandPacket>(1);
*new_cp = *cp;
if (cs->command_queue == NULL) {
cs->command_queue = new_cp;
} else {
CommandPacket *c = cs->command_queue;
while (c->next != NULL) c = c->next;
c->next = new_cp;
}
}
// Prepare a DoCommand to be send over the network
void NetworkSend_Command(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback)
{
CommandPacket *c = MallocT<CommandPacket>(1);
byte temp_callback;
c->player = _local_player;
c->next = NULL;
c->tile = tile;
c->p1 = p1;
c->p2 = p2;
c->cmd = cmd;
c->callback = 0;
temp_callback = 0;
while (temp_callback < _callback_table_count && _callback_table[temp_callback] != callback)
temp_callback++;
if (temp_callback == _callback_table_count) {
DEBUG(net, 0, "Unknown callback. (Pointer: %p) No callback sent", callback);
temp_callback = 0; /* _callback_table[0] == NULL */
}
if (_network_server) {
// We are the server, so set the command to be executed next possible frame
c->frame = _frame_counter_max + 1;
} else {
c->frame = 0; // The client can't tell which frame, so just make it 0
}
ttd_strlcpy(c->text, (_cmd_text != NULL) ? _cmd_text : "", lengthof(c->text));
if (_network_server) {
// If we are the server, we queue the command in our 'special' queue.
// In theory, we could execute the command right away, but then the
// client on the server can do everything 1 tick faster than others.
// So to keep the game fair, we delay the command with 1 tick
// which gives about the same speed as most clients.
NetworkTCPSocketHandler *cs;
// And we queue it for delivery to the clients
FOR_ALL_CLIENTS(cs) {
if (cs->status > STATUS_AUTH) NetworkAddCommandQueue(cs, c);
}
// Only the server gets the callback, because clients should not get them
c->callback = temp_callback;
if (_local_command_queue == NULL) {
_local_command_queue = c;
} else {
// Find last packet
CommandPacket *cp = _local_command_queue;
while (cp->next != NULL) cp = cp->next;
cp->next = c;
}
return;
}
// Clients send their command to the server and forget all about the packet
c->callback = temp_callback;
SEND_COMMAND(PACKET_CLIENT_COMMAND)(c);
}
// Execute a DoCommand we received from the network
void NetworkExecuteCommand(CommandPacket *cp)
{
_current_player = cp->player;
_cmd_text = cp->text;
/* cp->callback is unsigned. so we don't need to do lower bounds checking. */
if (cp->callback > _callback_table_count) {
DEBUG(net, 0, "Received out-of-bounds callback (%d)", cp->callback);
cp->callback = 0;
}
DoCommandP(cp->tile, cp->p1, cp->p2, _callback_table[cp->callback], cp->cmd | CMD_NETWORK_COMMAND);
}
#endif /* ENABLE_NETWORK */
|