mirror of https://github.com/OpenTTD/OpenTTD.git
(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:
parent
141da0127f
commit
aa6a621f0a
|
@ -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);
|
||||
|
|
10
dock_gui.c
10
dock_gui.c
|
@ -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;
|
||||
|
|
24
main_gui.c
24
main_gui.c
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue