(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)
This commit is contained in:
rubidium 2007-06-22 20:04:18 +00:00
parent 141da0127f
commit aa6a621f0a
6 changed files with 66 additions and 55 deletions

View File

@ -31,6 +31,7 @@ CommandCallback CcPlaySound10;
CommandCallback CcPlaceSign;
CommandCallback CcTerraform;
CommandCallback CcBuildTown;
CommandCallback CcGiveMoney;
/* rail_gui.c */
CommandCallback CcPlaySound1E;
@ -85,7 +86,8 @@ CommandCallback *_callback_table[] = {
/* 0x17 */ CcCloneShip,
/* 0x18 */ CcCloneTrain,
/* 0x19 */ CcAI,
/* 0x1A */ CcCloneVehicle
/* 0x1A */ CcCloneVehicle,
/* 0x1B */ CcGiveMoney,
};
const int _callback_table_count = lengthof(_callback_table);

View File

@ -236,14 +236,16 @@ static void BuildDockStationWndProc(Window *w, WindowEvent *e)
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;

View File

@ -53,6 +53,18 @@ static int _scengen_town_size = 2; // depress medium-sized towns per default
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 @@ void HandleOnEditText(WindowEvent *e)
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 */

View File

@ -429,34 +429,24 @@ void NetworkAddCommandQueue(NetworkClientState *cs, CommandPacket *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 = 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 @@ void NetworkSend_Command(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, Comma
// 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;
// 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;
// We are the server, so set the command to be executed next possible frame
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

View File

@ -835,8 +835,7 @@ DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_COMMAND)
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 @@ DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_COMMAND)
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 @@ DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_COMMAND)
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 @@ DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_COMMAND)
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 @@ DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_COMMAND)
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 @@ DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_COMMAND)
if (cp->cmd == CMD_PLAYER_CTRL) {
if (cp->p1 != 0) {
SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_CHEATER);
free(cp);
return;
}

View File

@ -2924,7 +2924,7 @@ PalSpriteID GetVehiclePalette(const Vehicle *v)
{
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,