diff --git a/changelog.txt b/changelog.txt index a3c8fc3125..03938ee693 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,10 @@ 0.6.2 ?? (2008-??-??) ------------------------------------------------------------------------ +- Fix: Several minor memory leaks. They only happened once per game (r13809, 13810) +- Fix: Checking for train waiting at other side of two-way signal was broken [FS#2162] (r13806) +- Fix: Some revision checking code was unintentionally disabled (r13776) +- Fix: Enforce the validity of a NetworkAction (chat packet) issued by a client (r13775) +- Fix: Selecting non-full length vehicles in the depot gui would place the "mouse pointer" out of the center of the vehicle making it hard to "aim" [FS#2147] (r13759) - Fix: NewGRF rail continuation would always mark a tunnel on the same axis as connected, even when the tunnel faces the wrong direction (r13734) - Fix: Assumption that non-north tiles of a house do not have the 1x1 building bit set was flawed with some NewGRFs. This caused the amount of houses to differ, which causes the town radii to differ, which causes desyncs when towns are expanded (r13729) - Fix: Possible desync on the autorenew settings 20+ game years (i.e. 4.5+ hours) after a company was started (r13718) diff --git a/src/ai/ai.cpp b/src/ai/ai.cpp index 4849cf2735..c4e3e526d0 100644 --- a/src/ai/ai.cpp +++ b/src/ai/ai.cpp @@ -10,6 +10,7 @@ #include "../player_base.h" #include "ai.h" #include "default/default.h" +#include "trolly/trolly.h" #include "../signal_func.h" AIStruct _ai; @@ -223,6 +224,13 @@ void AI_PlayerDied(PlayerID player) { /* Called if this AI died */ _ai_player[player].active = false; + + if (_players_ainew[player].pathfinder == NULL) return; + + AyStarMain_Free(_players_ainew[player].pathfinder); + delete _players_ainew[player].pathfinder; + _players_ainew[player].pathfinder = NULL; + } /** @@ -244,9 +252,5 @@ void AI_Initialize() */ void AI_Uninitialize() { - const Player* p; - - FOR_ALL_PLAYERS(p) { - if (p->is_active && p->is_ai) AI_PlayerDied(p->index); - } + for (PlayerID p = PLAYER_FIRST; p < MAX_PLAYERS; p++) AI_PlayerDied(p); } diff --git a/src/depot_gui.cpp b/src/depot_gui.cpp index f9605dd65d..b0b41e85c0 100644 --- a/src/depot_gui.cpp +++ b/src/depot_gui.cpp @@ -440,6 +440,20 @@ static void DepotClick(Window *w, int x, int y) WP(w, depot_d).sel = v->index; SetWindowDirty(w); SetObjectToPlaceWnd(image, GetVehiclePalette(v), VHM_DRAG, w); + + switch (v->type) { + case VEH_TRAIN: + _cursor.short_vehicle_offset = 16 - v->u.rail.cached_veh_length * 2; + break; + + case VEH_ROAD: + _cursor.short_vehicle_offset = 16 - v->u.road.cached_veh_length * 2; + break; + + default: + _cursor.short_vehicle_offset = 0; + break; + } } } break; diff --git a/src/fileio.cpp b/src/fileio.cpp index 66a0bcc170..9dbef0da32 100644 --- a/src/fileio.cpp +++ b/src/fileio.cpp @@ -330,7 +330,7 @@ FILE *FioFOpenFileSp(const char *filename, const char *mode, Searchpath sp, Subd FILE *FioFOpenFileTar(TarFileListEntry *entry, size_t *filesize) { - FILE *f = fopen(entry->tar->filename, "rb"); + FILE *f = fopen(entry->tar_filename, "rb"); assert(f != NULL); fseek(f, entry->position, SEEK_SET); @@ -470,9 +470,8 @@ static bool TarListAddFile(const char *filename) FILE *f = fopen(filename, "rb"); assert(f != NULL); - TarListEntry *tar_entry = MallocT(1); - tar_entry->filename = strdup(filename); - _tar_list.insert(TarList::value_type(filename, tar_entry)); + const char *dupped_filename = strdup(filename); + _tar_list[filename].filename = dupped_filename; TarHeader th; char buf[sizeof(th.name) + 1], *end; @@ -523,9 +522,9 @@ static bool TarListAddFile(const char *filename) /* Store this entry in the list */ TarFileListEntry entry; - entry.tar = tar_entry; - entry.size = skip; - entry.position = pos; + entry.tar_filename = dupped_filename; + entry.size = skip; + entry.position = pos; /* Force lowercase */ strtolower(name); diff --git a/src/fileio.h b/src/fileio.h index 881c983f3c..81fcb9d4d1 100644 --- a/src/fileio.h +++ b/src/fileio.h @@ -67,13 +67,15 @@ extern const char *_searchpaths[NUM_SEARCHPATHS]; */ struct TarListEntry { const char *filename; + + ~TarListEntry() { free((void*)this->filename); } }; struct TarFileListEntry { - TarListEntry *tar; + const char *tar_filename; int size; int position; }; -typedef std::map TarList; +typedef std::map TarList; typedef std::map TarFileList; extern TarList _tar_list; extern TarFileList _tar_filelist; diff --git a/src/gfx.cpp b/src/gfx.cpp index f70f6f8d79..57f7fa4d45 100644 --- a/src/gfx.cpp +++ b/src/gfx.cpp @@ -965,7 +965,7 @@ void DrawMouseCursor() } w = _cursor.size.x; - x = _cursor.pos.x + _cursor.offs.x; + x = _cursor.pos.x + _cursor.offs.x + _cursor.short_vehicle_offset; if (x < 0) { w += x; x = 0; @@ -993,7 +993,7 @@ void DrawMouseCursor() /* Draw cursor on screen */ _cur_dpi = &_screen; - DrawSprite(_cursor.sprite, _cursor.pal, _cursor.pos.x, _cursor.pos.y); + DrawSprite(_cursor.sprite, _cursor.pal, _cursor.pos.x + _cursor.short_vehicle_offset, _cursor.pos.y); _video_driver->MakeDirty(_cursor.draw_pos.x, _cursor.draw_pos.y, _cursor.draw_size.x, _cursor.draw_size.y); @@ -1244,6 +1244,7 @@ static void SetCursorSprite(SpriteID cursor, SpriteID pal) cv->offs.y = p->y_offs; cv->dirty = true; + cv->short_vehicle_offset = 0; } static void SwitchAnimatedCursor() diff --git a/src/gfx_type.h b/src/gfx_type.h index 4e6cf28ff9..aa0748f597 100644 --- a/src/gfx_type.h +++ b/src/gfx_type.h @@ -112,6 +112,7 @@ struct AnimCursor { struct CursorVars { Point pos, size, offs, delta; ///< position, size, offset from top-left, and movement Point draw_pos, draw_size; ///< position and size bounding-box for drawing + int short_vehicle_offset; ///< offset of the X for short vehicles SpriteID sprite; ///< current image of cursor SpriteID pal; diff --git a/src/network/network_server.cpp b/src/network/network_server.cpp index 0b8e32cda7..fad5028d79 100644 --- a/src/network/network_server.cpp +++ b/src/network/network_server.cpp @@ -646,14 +646,12 @@ DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_JOIN) p->Recv_string(client_revision, sizeof(client_revision)); -#if defined(WITH_REV) || defined(WITH_REV_HACK) // Check if the client has revision control enabled if (!IsNetworkCompatibleVersion(client_revision)) { // Different revisions!! SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_WRONG_REVISION); return; } -#endif p->Recv_string(name, sizeof(name)); playas = (Owner)p->Recv_uint8(); @@ -1168,7 +1166,21 @@ DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_CHAT) p->Recv_string(msg, MAX_TEXT_MSG_LEN); - NetworkServer_HandleChat(action, desttype, dest, msg, cs->index); + const NetworkClientInfo *ci = DEREF_CLIENT_INFO(cs); + switch (action) { + case NETWORK_ACTION_GIVE_MONEY: + if (!IsValidPlayer(ci->client_playas)) break; + /* Fall-through */ + case NETWORK_ACTION_CHAT: + case NETWORK_ACTION_CHAT_CLIENT: + case NETWORK_ACTION_CHAT_COMPANY: + NetworkServer_HandleChat(action, desttype, dest, msg, cs->index); + break; + default: + IConsolePrintF(_icolour_err, "WARNING: invalid chat action from client %d (IP: %s).", ci->client_index, GetPlayerIP(ci)); + SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NOT_EXPECTED); + break; + } } DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_SET_PASSWORD) diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index 0f5c7bf6ba..de9a28195e 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -3041,13 +3041,13 @@ static void CheckTrainCollision(Vehicle *v) static void *CheckVehicleAtSignal(Vehicle *v, void *data) { - Direction dir = *(Direction*)data; + DiagDirection exitdir = *(DiagDirection *)data; - if (v->type == VEH_TRAIN && IsFrontEngine(v)) { - DirDiff diff = ChangeDirDiff(DirDifference(v->direction, dir), DIRDIFF_90RIGHT); - - if (diff == DIRDIFF_90RIGHT || (v->cur_speed <= 5 && diff <= DIRDIFF_REVERSE)) return v; + /* front engine of a train, not inside wormhole or depot */ + if (v->type == VEH_TRAIN && IsFrontEngine(v) && (v->u.rail.track & TRACK_BIT_MASK) != 0) { + if (v->cur_speed <= 5 && TrainExitDir(v->direction, v->u.rail.track) == exitdir) return v; } + return NULL; } @@ -3138,11 +3138,13 @@ static void TrainController(Vehicle *v, Vehicle *nomove, bool update_image) v->subspeed = 0; v->progress = 255 - 10; if (++v->load_unload_time_rem < _patches.wait_twoway_signal * 73) { - TileIndex o_tile = gp.new_tile + TileOffsByDiagDir(enterdir); - Direction rdir = ReverseDir(dir); + DiagDirection exitdir = TrackdirToExitdir(i); + TileIndex o_tile = TileAddByDiagDir(gp.new_tile, exitdir); + + exitdir = ReverseDiagDir(exitdir); /* check if a train is waiting on the other side */ - if (VehicleFromPos(o_tile, &rdir, &CheckVehicleAtSignal) == NULL) return; + if (VehicleFromPos(o_tile, &exitdir, &CheckVehicleAtSignal) == NULL) return; } } goto reverse_train_direction;