(svn r10275) [0.5] -Backport from trunk (r10048, r10068, r10075, r10082, r10085, r10087):
- Fix: "Deactivate Electrified Railways" did not work [FS#836] (10083)
- Fix: Memory leaks in the networking code [FS#846, FS#844] (r10082, r10075)
- Fix: Coverage area highlight was still show when it was turned off for docks [FS#835] (r10068)
- Fix: Do not use override engine type for articulated wagon parts (r10048)
--- a/callback_table.c Fri Jun 22 20:01:02 2007 +0000
+++ b/callback_table.c Fri Jun 22 20:04:18 2007 +0000
@@ -31,6 +31,7 @@
CommandCallback CcPlaceSign;
CommandCallback CcTerraform;
CommandCallback CcBuildTown;
+CommandCallback CcGiveMoney;
/* rail_gui.c */
CommandCallback CcPlaySound1E;
@@ -85,7 +86,8 @@
/* 0x17 */ CcCloneShip,
/* 0x18 */ CcCloneTrain,
/* 0x19 */ CcAI,
- /* 0x1A */ CcCloneVehicle
+ /* 0x1A */ CcCloneVehicle,
+ /* 0x1B */ CcGiveMoney,
};
const int _callback_table_count = lengthof(_callback_table);
--- a/dock_gui.c Fri Jun 22 20:01:02 2007 +0000
+++ b/dock_gui.c Fri Jun 22 20:04:18 2007 +0000
@@ -236,14 +236,16 @@
case WE_CREATE: LowerWindowWidget(w, _station_show_coverage + 3); break;
case WE_PAINT: {
- int rad;
+ int rad = (_patches.modified_catchment) ? CA_DOCK : 4;
if (WP(w,def_d).close) return;
DrawWindowWidgets(w);
- rad = (_patches.modified_catchment) ? CA_DOCK : 4;
-
- if (_station_show_coverage) SetTileSelectBigSize(-rad, -rad, 2 * rad, 2 * rad);
+ if (_station_show_coverage) {
+ SetTileSelectBigSize(-rad, -rad, 2 * rad, 2 * rad);
+ } else {
+ SetTileSelectSize(1, 1);
+ }
DrawStationCoverageAreaText(4, 50, (uint)-1, rad);
break;
--- a/main_gui.c Fri Jun 22 20:01:02 2007 +0000
+++ b/main_gui.c Fri Jun 22 20:04:18 2007 +0000
@@ -53,6 +53,18 @@
extern void GenerateIndustries(void);
extern bool GenerateTowns(void);
+void CcGiveMoney(bool success, TileIndex tile, uint32 p1, uint32 p2)
+{
+ char msg[20];
+ if (!success) return;
+ /* Inform the player of this action */
+ snprintf(msg, sizeof(msg), "%d", p1);
+ if (!_network_server) {
+ SEND_COMMAND(PACKET_CLIENT_CHAT)(NETWORK_ACTION_GIVE_MONEY, DESTTYPE_TEAM, p2, msg);
+ } else {
+ NetworkServer_HandleChat(NETWORK_ACTION_GIVE_MONEY, DESTTYPE_TEAM, p2, msg, NETWORK_SERVER_INDEX);
+ }
+}
void HandleOnEditText(WindowEvent *e)
{
@@ -75,21 +87,11 @@
case 3: { /* Give money, you can only give money in excess of loan */
const Player *p = GetPlayer(_current_player);
int32 money = min(p->money64 - p->current_loan, atoi(e->we.edittext.str) / _currency->rate);
- char msg[20];
money = clamp(money, 0, 20000000); // Clamp between 20 million and 0
// Give 'id' the money, and substract it from ourself
- if (!DoCommandP(0, money, id, NULL, CMD_GIVE_MONEY | CMD_MSG(STR_INSUFFICIENT_FUNDS))) break;
-
- // Inform the player of this action
- snprintf(msg, sizeof(msg), "%d", money);
-
- if (!_network_server) {
- SEND_COMMAND(PACKET_CLIENT_CHAT)(NETWORK_ACTION_GIVE_MONEY, DESTTYPE_TEAM, id, msg);
- } else {
- NetworkServer_HandleChat(NETWORK_ACTION_GIVE_MONEY, DESTTYPE_TEAM, id, msg, NETWORK_SERVER_INDEX);
- }
+ DoCommandP(0, money, id, CcGiveMoney, CMD_GIVE_MONEY | CMD_MSG(STR_INSUFFICIENT_FUNDS));
break;
}
#endif /* ENABLE_NETWORK */
--- a/network_data.c Fri Jun 22 20:01:02 2007 +0000
+++ b/network_data.c Fri Jun 22 20:04:18 2007 +0000
@@ -429,34 +429,24 @@
// Prepare a DoCommand to be send over the network
void NetworkSend_Command(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback)
{
- CommandPacket *c = malloc(sizeof(CommandPacket));
- byte temp_callback;
+ CommandPacket c;
- c->player = _local_player;
- c->next = NULL;
- c->tile = tile;
- c->p1 = p1;
- c->p2 = p2;
- c->cmd = cmd;
- c->callback = 0;
+ 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) {
+ while (c.callback < _callback_table_count && _callback_table[c.callback] != callback)
+ c.callback++;
+ if (c.callback == _callback_table_count) {
DEBUG(net, 0) ("[NET] Unknown callback. (Pointer: %p) No callback sent.", callback);
- temp_callback = 0; /* _callback_table[0] == NULL */
+ c.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));
+ 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.
@@ -464,30 +454,38 @@
// 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.
- NetworkClientState *cs;
+ // Only the server gets the callback, because clients should not get them
- // And we queue it for delivery to the clients
- FOR_ALL_CLIENTS(cs) {
- if (cs->status > STATUS_AUTH) NetworkAddCommandQueue(cs, c);
- }
+ // We are the server, so set the command to be executed next possible frame
- // Only the server gets the callback, because clients should not get them
- c->callback = temp_callback;
+ NetworkClientState *cs;
+ CommandPacket *new_cp = malloc(sizeof(CommandPacket));
+
+ c.frame = _frame_counter_max + 1;
+ *new_cp = c;
+
if (_local_command_queue == NULL) {
- _local_command_queue = c;
+ _local_command_queue = new_cp;
} else {
// Find last packet
CommandPacket *cp = _local_command_queue;
while (cp->next != NULL) cp = cp->next;
- cp->next = c;
+ cp->next = new_cp;
+ }
+
+ c.callback = 0;
+
+ // And we queue it for delivery to the clients
+ FOR_ALL_CLIENTS(cs) {
+ if (cs->status > STATUS_AUTH) NetworkAddCommandQueue(cs, &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);
+ c.frame = 0;
+ SEND_COMMAND(PACKET_CLIENT_COMMAND)(&c);
}
// Execute a DoCommand we received from the network
--- a/network_server.c Fri Jun 22 20:01:02 2007 +0000
+++ b/network_server.c Fri Jun 22 20:04:18 2007 +0000
@@ -835,8 +835,7 @@
NetworkClientState *new_cs;
const NetworkClientInfo *ci;
byte callback;
-
- CommandPacket *cp = malloc(sizeof(CommandPacket));
+ CommandPacket *cp;
// The client was never joined.. so this is impossible, right?
// Ignore the packet, give the client a warning, and close his connection
@@ -845,6 +844,7 @@
return;
}
+ cp = malloc(sizeof(CommandPacket));
cp->player = NetworkRecv_uint8(cs, p);
cp->cmd = NetworkRecv_uint32(cs, p);
cp->p1 = NetworkRecv_uint32(cs, p);
@@ -854,7 +854,10 @@
callback = NetworkRecv_uint8(cs, p);
- if (cs->has_quit) return;
+ if (cs->has_quit) {
+ free(cp);
+ return;
+ }
ci = DEREF_CLIENT_INFO(cs);
@@ -862,11 +865,13 @@
if (!IsValidCommand(cp->cmd)) {
IConsolePrintF(_icolour_err, "WARNING: invalid command from client %d (IP: %s).", ci->client_index, GetPlayerIP(ci));
SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NOT_EXPECTED);
+ free(cp);
return;
}
if (!CheckCommandFlags(cp, ci)) {
SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_KICKED);
+ free(cp);
return;
}
@@ -878,6 +883,7 @@
IConsolePrintF(_icolour_err, "WARNING: player %d (IP: %s) tried to execute a command as player %d, kicking...",
ci->client_playas + 1, GetPlayerIP(ci), cp->player + 1);
SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_PLAYER_MISMATCH);
+ free(cp);
return;
}
@@ -889,6 +895,7 @@
if (cp->cmd == CMD_PLAYER_CTRL) {
if (cp->p1 != 0) {
SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_CHEATER);
+ free(cp);
return;
}
--- a/vehicle.c Fri Jun 22 20:01:02 2007 +0000
+++ b/vehicle.c Fri Jun 22 20:04:18 2007 +0000
@@ -2924,7 +2924,7 @@
{
if (v->type == VEH_Train) {
return GetEngineColourMap(
- (v->u.rail.first_engine != INVALID_ENGINE && (IsArticulatedPart(v) || UsesWagonOverride(v))) ?
+ (v->u.rail.first_engine != INVALID_ENGINE && (UsesWagonOverride(v) || (IsArticulatedPart(v) && (RailVehInfo(v->engine_type)->flags & RVI_WAGON) != 0))) ?
v->u.rail.first_engine : v->engine_type,
v->owner,
v->u.rail.first_engine,