TBTR: Delete orphaned virtual trains on client disconnection
This commit is contained in:
@@ -429,11 +429,11 @@ static const Command _command_proc_table[] = {
|
||||
DEF_CMD(CmdToggleRefitAsTemplate, CMD_ALL_TILES, CMDT_VEHICLE_MANAGEMENT ), // CMD_TOGGLE_REFIT_AS_TEMPLATE
|
||||
DEF_CMD(CmdToggleTemplateReplaceOldOnly, CMD_ALL_TILES, CMDT_VEHICLE_MANAGEMENT ), // CMD_TOGGLE_TMPL_REPLACE_OLD_ONLY
|
||||
|
||||
DEF_CMD(CmdVirtualTrainFromTemplateVehicle, CMD_NO_TEST | CMD_ALL_TILES, CMDT_VEHICLE_MANAGEMENT), // CMD_VIRTUAL_TRAIN_FROM_TEMPLATE_VEHICLE
|
||||
DEF_CMD(CmdVirtualTrainFromTrain, CMD_NO_TEST | CMD_ALL_TILES, CMDT_VEHICLE_MANAGEMENT), // CMD_VIRTUAL_TRAIN_FROM_TRAIN
|
||||
DEF_CMD(CmdDeleteVirtualTrain, CMD_ALL_TILES, CMDT_VEHICLE_MANAGEMENT ), // CMD_DELETE_VIRTUAL_TRAIN
|
||||
DEF_CMD(CmdBuildVirtualRailVehicle, CMD_NO_TEST | CMD_ALL_TILES, CMDT_VEHICLE_MANAGEMENT), // CMD_BUILD_VIRTUAL_RAIL_VEHICLE
|
||||
DEF_CMD(CmdReplaceTemplateVehicle, CMD_ALL_TILES, CMDT_VEHICLE_MANAGEMENT ), // CMD_REPLACE_TEMPLATE_VEHICLE
|
||||
DEF_CMD(CmdVirtualTrainFromTemplateVehicle, CMD_CLIENT_ID | CMD_NO_TEST | CMD_ALL_TILES, CMDT_VEHICLE_MANAGEMENT), // CMD_VIRTUAL_TRAIN_FROM_TEMPLATE_VEHICLE
|
||||
DEF_CMD(CmdVirtualTrainFromTrain, CMD_CLIENT_ID | CMD_NO_TEST | CMD_ALL_TILES, CMDT_VEHICLE_MANAGEMENT), // CMD_VIRTUAL_TRAIN_FROM_TRAIN
|
||||
DEF_CMD(CmdDeleteVirtualTrain, CMD_ALL_TILES, CMDT_VEHICLE_MANAGEMENT), // CMD_DELETE_VIRTUAL_TRAIN
|
||||
DEF_CMD(CmdBuildVirtualRailVehicle, CMD_CLIENT_ID | CMD_NO_TEST | CMD_ALL_TILES, CMDT_VEHICLE_MANAGEMENT), // CMD_BUILD_VIRTUAL_RAIL_VEHICLE
|
||||
DEF_CMD(CmdReplaceTemplateVehicle, CMD_ALL_TILES, CMDT_VEHICLE_MANAGEMENT), // CMD_REPLACE_TEMPLATE_VEHICLE
|
||||
|
||||
DEF_CMD(CmdTemplateVehicleFromTrain, CMD_ALL_TILES, CMDT_VEHICLE_MANAGEMENT ), // CMD_CLONE_TEMPLATE_VEHICLE_FROM_TRAIN
|
||||
DEF_CMD(CmdDeleteTemplateVehicle, CMD_ALL_TILES, CMDT_VEHICLE_MANAGEMENT ), // CMD_DELETE_TEMPLATE_VEHICLE
|
||||
|
@@ -230,6 +230,9 @@ ServerNetworkGameSocketHandler::~ServerNetworkGameSocketHandler()
|
||||
if (_redirect_console_to_client == this->client_id) _redirect_console_to_client = INVALID_CLIENT_ID;
|
||||
OrderBackup::ResetUser(this->client_id);
|
||||
|
||||
extern void RemoveVirtualTrainsOfUser(uint32 user);
|
||||
RemoveVirtualTrainsOfUser(this->client_id);
|
||||
|
||||
if (this->savegame != nullptr) {
|
||||
this->savegame->Destroy();
|
||||
this->savegame = nullptr;
|
||||
|
@@ -117,7 +117,7 @@ void AfterLoadTemplateVehiclesUpdateImage()
|
||||
if (tv->Prev() == nullptr) {
|
||||
Backup<CompanyID> cur_company(_current_company, tv->owner, FILE_LINE);
|
||||
StringID err;
|
||||
Train* t = VirtualTrainFromTemplateVehicle(tv, err);
|
||||
Train* t = VirtualTrainFromTemplateVehicle(tv, err, 0);
|
||||
if (t != nullptr) {
|
||||
int tv_len = 0;
|
||||
for (TemplateVehicle *u = tv; u != nullptr; u = u->Next()) {
|
||||
@@ -154,7 +154,7 @@ void AfterLoadTemplateVehiclesUpdateProperties()
|
||||
if (tv->Prev() == nullptr) {
|
||||
Backup<CompanyID> cur_company(_current_company, tv->owner, FILE_LINE);
|
||||
StringID err;
|
||||
Train* t = VirtualTrainFromTemplateVehicle(tv, err);
|
||||
Train* t = VirtualTrainFromTemplateVehicle(tv, err, 0);
|
||||
if (t != nullptr) {
|
||||
uint32 full_cargo_weight = 0;
|
||||
for (Train *u = t; u != nullptr; u = u->Next()) {
|
||||
|
@@ -15,7 +15,7 @@
|
||||
|
||||
#include "tbtr_template_vehicle.h"
|
||||
|
||||
Train* VirtualTrainFromTemplateVehicle(TemplateVehicle* tv, StringID &err);
|
||||
Train* VirtualTrainFromTemplateVehicle(TemplateVehicle* tv, StringID &err, uint32 user);
|
||||
|
||||
void BuildTemplateGuiList(GUITemplateList*, Scrollbar*, Owner, RailType);
|
||||
|
||||
|
@@ -417,8 +417,7 @@ protected: // These functions should not be called outside acceleration code.
|
||||
CommandCost CmdMoveRailVehicle(TileIndex, DoCommandFlag , uint32, uint32, const char *);
|
||||
CommandCost CmdMoveVirtualRailVehicle(TileIndex, DoCommandFlag, uint32, uint32, const char*);
|
||||
|
||||
Train* CmdBuildVirtualRailWagon(const Engine*);
|
||||
Train* CmdBuildVirtualRailVehicle(EngineID, StringID &error);
|
||||
Train* CmdBuildVirtualRailVehicle(EngineID, StringID &error, uint32 user);
|
||||
|
||||
int GetTileMarginInFrontOfTrain(const Train *v, int x_pos, int y_pos);
|
||||
|
||||
|
@@ -5350,7 +5350,7 @@ int GetDisplayImageWidth(Train *t, Point *offset)
|
||||
return t->gcache.cached_veh_length * reference_width / VEHICLE_LENGTH;
|
||||
}
|
||||
|
||||
Train* CmdBuildVirtualRailWagon(const Engine *e)
|
||||
Train* CmdBuildVirtualRailWagon(const Engine *e, uint32 user)
|
||||
{
|
||||
const RailVehicleInfo *rvi = &e->u.rail;
|
||||
|
||||
@@ -5371,6 +5371,7 @@ Train* CmdBuildVirtualRailWagon(const Engine *e)
|
||||
v->track = TRACK_BIT_DEPOT;
|
||||
SetBit(v->flags, VRF_CONSIST_SPEED_REDUCTION);
|
||||
v->vehstatus = VS_HIDDEN | VS_DEFPAL;
|
||||
v->motion_counter = user;
|
||||
|
||||
v->SetWagon();
|
||||
v->SetFreeWagon();
|
||||
@@ -5407,7 +5408,7 @@ Train* CmdBuildVirtualRailWagon(const Engine *e)
|
||||
return v;
|
||||
}
|
||||
|
||||
Train* CmdBuildVirtualRailVehicle(EngineID eid, StringID &error)
|
||||
Train* CmdBuildVirtualRailVehicle(EngineID eid, StringID &error, uint32 user)
|
||||
{
|
||||
const Engine *e = Engine::GetIfValid(eid);
|
||||
if (e == nullptr || e->type != VEH_TRAIN) {
|
||||
@@ -5426,7 +5427,7 @@ Train* CmdBuildVirtualRailVehicle(EngineID eid, StringID &error)
|
||||
RegisterGameEvents(GEF_VIRT_TRAIN);
|
||||
|
||||
if (rvi->railveh_type == RAILVEH_WAGON) {
|
||||
return CmdBuildVirtualRailWagon(e);
|
||||
return CmdBuildVirtualRailWagon(e, user);
|
||||
}
|
||||
|
||||
Train *v = new Train();
|
||||
@@ -5444,6 +5445,7 @@ Train* CmdBuildVirtualRailVehicle(EngineID eid, StringID &error)
|
||||
v->cargo_type = e->GetDefaultCargoType();
|
||||
v->cargo_cap = rvi->capacity;
|
||||
v->last_station_visited = INVALID_STATION;
|
||||
v->motion_counter = user;
|
||||
|
||||
v->engine_type = e->index;
|
||||
v->gcache.first_engine = INVALID_ENGINE; // needs to be set before first callback
|
||||
@@ -5492,7 +5494,7 @@ Train* CmdBuildVirtualRailVehicle(EngineID eid, StringID &error)
|
||||
* @param p1 various bitstuffed data
|
||||
* bits 0-15: vehicle type being built.
|
||||
* bits 24-31: refit cargo type.
|
||||
* @param p2 unused
|
||||
* @param p2 user
|
||||
* @param text unused
|
||||
* @return the cost of this operation or an error
|
||||
*/
|
||||
@@ -5512,7 +5514,7 @@ CommandCost CmdBuildVirtualRailVehicle(TileIndex tile, DoCommandFlag flags, uint
|
||||
|
||||
if (should_execute) {
|
||||
StringID err = INVALID_STRING_ID;
|
||||
Train* train = CmdBuildVirtualRailVehicle(eid, err);
|
||||
Train* train = CmdBuildVirtualRailVehicle(eid, err, p2);
|
||||
|
||||
if (train == nullptr) {
|
||||
return_cmd_error(err);
|
||||
|
@@ -1508,6 +1508,20 @@ void CallVehicleTicks()
|
||||
_vehicles_to_pay_repair.clear();
|
||||
}
|
||||
|
||||
void RemoveVirtualTrainsOfUser(uint32 user)
|
||||
{
|
||||
if (!_tick_caches_valid || HasChickenBit(DCBF_VEH_TICK_CACHE)) RebuildVehicleTickCaches();
|
||||
|
||||
Backup<CompanyID> cur_company(_current_company, FILE_LINE);
|
||||
for (const Train *front : _tick_train_front_cache) {
|
||||
if (front->IsVirtual() && front->motion_counter == user) {
|
||||
cur_company.Change(front->owner);
|
||||
DoCommandP(0, front->index, 0, CMD_DELETE_VIRTUAL_TRAIN);
|
||||
}
|
||||
}
|
||||
cur_company.Restore();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add vehicle sprite for drawing to the screen.
|
||||
* @param v Vehicle to draw.
|
||||
|
@@ -328,7 +328,7 @@ public:
|
||||
uint16 cur_speed; ///< current speed
|
||||
byte subspeed; ///< fractional speed
|
||||
byte acceleration; ///< used by train & aircraft
|
||||
uint32 motion_counter; ///< counter to occasionally play a vehicle sound.
|
||||
uint32 motion_counter; ///< counter to occasionally play a vehicle sound. (Also used as virtual train client ID).
|
||||
byte progress; ///< The percentage (if divided by 256) this vehicle already crossed the tile unit.
|
||||
|
||||
byte random_bits; ///< Bits used for determining which randomized variational spritegroups to use when drawing.
|
||||
|
@@ -993,7 +993,7 @@ CommandCost CmdVirtualTrainFromTemplateVehicle(TileIndex tile, DoCommandFlag fla
|
||||
|
||||
if (should_execute) {
|
||||
StringID err = INVALID_STRING_ID;
|
||||
Train* train = VirtualTrainFromTemplateVehicle(tv, err);
|
||||
Train* train = VirtualTrainFromTemplateVehicle(tv, err, p2);
|
||||
|
||||
if (train == nullptr) {
|
||||
return_cmd_error(err);
|
||||
@@ -1005,20 +1005,20 @@ CommandCost CmdVirtualTrainFromTemplateVehicle(TileIndex tile, DoCommandFlag fla
|
||||
|
||||
CommandCost CmdDeleteVirtualTrain(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text);
|
||||
|
||||
Train* VirtualTrainFromTemplateVehicle(TemplateVehicle* tv, StringID &err)
|
||||
Train* VirtualTrainFromTemplateVehicle(TemplateVehicle* tv, StringID &err, uint32 user)
|
||||
{
|
||||
CommandCost c;
|
||||
Train *tmp, *head, *tail;
|
||||
|
||||
assert(tv->owner == _current_company);
|
||||
|
||||
head = CmdBuildVirtualRailVehicle(tv->engine_type, err);
|
||||
head = CmdBuildVirtualRailVehicle(tv->engine_type, err, user);
|
||||
if (!head) return nullptr;
|
||||
|
||||
tail = head;
|
||||
tv = tv->GetNextUnit();
|
||||
while (tv) {
|
||||
tmp = CmdBuildVirtualRailVehicle(tv->engine_type, err);
|
||||
tmp = CmdBuildVirtualRailVehicle(tv->engine_type, err, user);
|
||||
if (!tmp) {
|
||||
CmdDeleteVirtualTrain(INVALID_TILE, DC_EXEC, head->index, 0, nullptr);
|
||||
return nullptr;
|
||||
@@ -1042,7 +1042,7 @@ Train* VirtualTrainFromTemplateVehicle(TemplateVehicle* tv, StringID &err)
|
||||
* @param tile unused
|
||||
* @param flags type of operation
|
||||
* @param p1 the train index
|
||||
* @param p2 unused
|
||||
* @param p2 user
|
||||
* @param text unused
|
||||
* @return the cost of this operation or an error
|
||||
*/
|
||||
@@ -1064,13 +1064,13 @@ CommandCost CmdVirtualTrainFromTrain(TileIndex tile, DoCommandFlag flags, uint32
|
||||
Train *tmp, *head, *tail;
|
||||
StringID err = INVALID_STRING_ID;
|
||||
|
||||
head = CmdBuildVirtualRailVehicle(train->engine_type, err);
|
||||
head = CmdBuildVirtualRailVehicle(train->engine_type, err, p2);
|
||||
if (!head) return_cmd_error(err);
|
||||
|
||||
tail = head;
|
||||
train = train->GetNextUnit();
|
||||
while (train) {
|
||||
tmp = CmdBuildVirtualRailVehicle(train->engine_type, err);
|
||||
tmp = CmdBuildVirtualRailVehicle(train->engine_type, err, p2);
|
||||
if (!tmp) {
|
||||
CmdDeleteVirtualTrain(tile, flags, head->index, 0, nullptr);
|
||||
return_cmd_error(err);
|
||||
|
Reference in New Issue
Block a user