mirror of https://github.com/OpenTTD/OpenTTD.git
(svn r2222) Check the parameters of Cmd{Insert,Delete,Modify,Skip}Order() and CmdRestoreOrderIndex():
- Check if the vehicle exists - Check if the vehicle belongs to the correct player - Check if the new order is valid (type, destination, flags) (CmdInsertOrder)
This commit is contained in:
parent
591217da4a
commit
6ceeedfd3c
7
depot.h
7
depot.h
|
@ -28,6 +28,11 @@ static inline uint16 GetDepotPoolSize(void)
|
|||
return _depot_pool.total_items;
|
||||
}
|
||||
|
||||
static inline bool IsDepotIndex(uint index)
|
||||
{
|
||||
return index < GetDepotPoolSize();
|
||||
}
|
||||
|
||||
#define FOR_ALL_DEPOTS_FROM(d, start) for (d = GetDepot(start); d != NULL; d = (d->index + 1 < GetDepotPoolSize()) ? GetDepot(d->index + 1) : NULL)
|
||||
#define FOR_ALL_DEPOTS(d) FOR_ALL_DEPOTS_FROM(d, 0)
|
||||
|
||||
|
@ -44,7 +49,7 @@ VARDEF TileIndex _last_built_ship_depot_tile;
|
|||
/**
|
||||
* Check if a depot really exists.
|
||||
*/
|
||||
static inline bool IsValidDepot(Depot* depot)
|
||||
static inline bool IsValidDepot(const Depot* depot)
|
||||
{
|
||||
return depot->xy != 0; /* XXX: Replace by INVALID_TILE someday */
|
||||
}
|
||||
|
|
172
order_cmd.c
172
order_cmd.c
|
@ -1,7 +1,10 @@
|
|||
#include "stdafx.h"
|
||||
#include "ttd.h"
|
||||
#include "airport.h"
|
||||
#include "depot.h"
|
||||
#include "table/strings.h"
|
||||
#include "vehicle.h"
|
||||
#include "waypoint.h"
|
||||
#include "command.h"
|
||||
#include "station.h"
|
||||
#include "player.h"
|
||||
|
@ -147,10 +150,146 @@ void AssignOrder(Order *order, Order data)
|
|||
*/
|
||||
int32 CmdInsertOrder(int x, int y, uint32 flags, uint32 veh_sel, uint32 packed_order)
|
||||
{
|
||||
Vehicle *v = GetVehicle(veh_sel & 0xFFFF);
|
||||
Vehicle *v;
|
||||
int sel = veh_sel >> 16;
|
||||
Order new_order = UnpackOrder(packed_order);
|
||||
|
||||
if (!IsVehicleIndex(veh_sel & 0xFFFF)) return CMD_ERROR;
|
||||
v = GetVehicle(veh_sel & 0xFFFF);
|
||||
if (v->type == 0 || !CheckOwnership(v->owner)) return CMD_ERROR;
|
||||
|
||||
switch (new_order.type) {
|
||||
case OT_GOTO_STATION: {
|
||||
const Station* st;
|
||||
|
||||
if (!IsStationIndex(new_order.station)) return CMD_ERROR;
|
||||
st = GetStation(new_order.station);
|
||||
|
||||
if (!IsValidStation(st) ||
|
||||
(st->airport_type != AT_OILRIG && !CheckOwnership(st->owner))) {
|
||||
return CMD_ERROR;
|
||||
}
|
||||
|
||||
switch (v->type) {
|
||||
case VEH_Train:
|
||||
if (!(st->facilities & FACIL_TRAIN)) return CMD_ERROR;
|
||||
break;
|
||||
|
||||
case VEH_Road:
|
||||
if (v->cargo_type == CT_PASSENGERS) {
|
||||
if (!(st->facilities & FACIL_BUS_STOP)) return CMD_ERROR;
|
||||
} else {
|
||||
if (!(st->facilities & FACIL_TRUCK_STOP)) return CMD_ERROR;
|
||||
}
|
||||
break;
|
||||
|
||||
case VEH_Ship:
|
||||
if (!(st->facilities & FACIL_DOCK)) return CMD_ERROR;
|
||||
break;
|
||||
|
||||
case VEH_Aircraft:
|
||||
if (!(st->facilities & FACIL_AIRPORT)) return CMD_ERROR;
|
||||
break;
|
||||
|
||||
default:
|
||||
return CMD_ERROR;
|
||||
}
|
||||
|
||||
switch (new_order.flags) {
|
||||
case 0:
|
||||
case OF_FULL_LOAD:
|
||||
case OF_UNLOAD:
|
||||
case OF_NON_STOP:
|
||||
case OF_NON_STOP | OF_FULL_LOAD:
|
||||
case OF_NON_STOP | OF_UNLOAD:
|
||||
break;
|
||||
|
||||
default:
|
||||
return CMD_ERROR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case OT_GOTO_DEPOT: {
|
||||
if (v->type == VEH_Aircraft) {
|
||||
const Station* st;
|
||||
|
||||
if (!IsStationIndex(new_order.station)) return CMD_ERROR;
|
||||
st = GetStation(new_order.station);
|
||||
|
||||
if (!IsValidStation(st) ||
|
||||
(st->airport_type != AT_OILRIG && !CheckOwnership(st->owner)) ||
|
||||
!(st->facilities & FACIL_AIRPORT) ||
|
||||
GetAirport(st->airport_type)->nof_depots == 0) {
|
||||
return CMD_ERROR;
|
||||
}
|
||||
} else {
|
||||
const Depot* dp;
|
||||
|
||||
if (!IsDepotIndex(new_order.station)) return CMD_ERROR;
|
||||
dp = GetDepot(new_order.station);
|
||||
|
||||
if (!IsValidDepot(dp) ||
|
||||
!CheckOwnership(GetTileOwner(dp->xy))) {
|
||||
return CMD_ERROR;
|
||||
}
|
||||
|
||||
switch (v->type) {
|
||||
case VEH_Train:
|
||||
if (!IsTileDepotType(dp->xy, TRANSPORT_RAIL)) return CMD_ERROR;
|
||||
break;
|
||||
|
||||
case VEH_Road:
|
||||
if (!IsTileDepotType(dp->xy, TRANSPORT_ROAD)) return CMD_ERROR;
|
||||
break;
|
||||
|
||||
case VEH_Ship:
|
||||
if (!IsTileDepotType(dp->xy, TRANSPORT_WATER)) return CMD_ERROR;
|
||||
break;
|
||||
|
||||
default:
|
||||
return CMD_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
switch (new_order.flags) {
|
||||
case OF_PART_OF_ORDERS:
|
||||
case OF_PART_OF_ORDERS | OF_HALT_IN_DEPOT:
|
||||
case OF_NON_STOP | OF_PART_OF_ORDERS:
|
||||
case OF_NON_STOP | OF_PART_OF_ORDERS | OF_HALT_IN_DEPOT:
|
||||
break;
|
||||
|
||||
default:
|
||||
return CMD_ERROR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case OT_GOTO_WAYPOINT: {
|
||||
const Waypoint* wp;
|
||||
|
||||
if (v->type != VEH_Train) return CMD_ERROR;
|
||||
|
||||
if (!IsWaypointIndex(new_order.station)) return CMD_ERROR;
|
||||
wp = GetWaypoint(new_order.station);
|
||||
|
||||
if (!CheckOwnership(GetTileOwner(wp->xy))) return CMD_ERROR;
|
||||
|
||||
switch (new_order.flags) {
|
||||
case 0:
|
||||
case OF_NON_STOP:
|
||||
break;
|
||||
|
||||
default:
|
||||
return CMD_ERROR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
return CMD_ERROR;
|
||||
}
|
||||
|
||||
if (sel > v->num_orders)
|
||||
return_cmd_error(STR_EMPTY);
|
||||
|
||||
|
@ -170,7 +309,7 @@ int32 CmdInsertOrder(int x, int y, uint32 flags, uint32 veh_sel, uint32 packed_o
|
|||
|
||||
int dist = DistanceManhattan(
|
||||
GetStation(GetVehicleOrder(v, sel - 1)->station)->xy,
|
||||
GetStation(new_order.station)->xy
|
||||
GetStation(new_order.station)->xy // XXX type != OT_GOTO_STATION?
|
||||
);
|
||||
if (dist >= 130)
|
||||
return_cmd_error(STR_0210_TOO_FAR_FROM_PREVIOUS_DESTINATIO);
|
||||
|
@ -269,10 +408,15 @@ static int32 DecloneOrder(Vehicle *dst, uint32 flags)
|
|||
*/
|
||||
int32 CmdDeleteOrder(int x, int y, uint32 flags, uint32 vehicle_id, uint32 selected)
|
||||
{
|
||||
Vehicle *v = GetVehicle(vehicle_id), *u;
|
||||
Vehicle *v;
|
||||
Vehicle *u;
|
||||
uint sel = selected;
|
||||
Order *order;
|
||||
|
||||
if (!IsVehicleIndex(vehicle_id)) return CMD_ERROR;
|
||||
v = GetVehicle(vehicle_id);
|
||||
if (v->type == 0 || !CheckOwnership(v->owner)) return CMD_ERROR;
|
||||
|
||||
/* XXX -- Why is this here? :s */
|
||||
_error_message = STR_EMPTY;
|
||||
|
||||
|
@ -347,7 +491,11 @@ int32 CmdDeleteOrder(int x, int y, uint32 flags, uint32 vehicle_id, uint32 selec
|
|||
*/
|
||||
int32 CmdSkipOrder(int x, int y, uint32 flags, uint32 vehicle_id, uint32 not_used)
|
||||
{
|
||||
Vehicle *v = GetVehicle(vehicle_id);
|
||||
Vehicle *v;
|
||||
|
||||
if (!IsVehicleIndex(vehicle_id)) return CMD_ERROR;
|
||||
v = GetVehicle(vehicle_id);
|
||||
if (v->type == 0 || !CheckOwnership(v->owner)) return CMD_ERROR;
|
||||
|
||||
if (flags & DC_EXEC) {
|
||||
/* Goto next order */
|
||||
|
@ -394,10 +542,14 @@ int32 CmdSkipOrder(int x, int y, uint32 flags, uint32 vehicle_id, uint32 not_use
|
|||
*/
|
||||
int32 CmdModifyOrder(int x, int y, uint32 flags, uint32 veh_sel, uint32 mode)
|
||||
{
|
||||
Vehicle *v = GetVehicle(veh_sel & 0xFFFF);
|
||||
Vehicle *v;
|
||||
byte sel = veh_sel >> 16;
|
||||
Order *order;
|
||||
|
||||
if (!IsVehicleIndex(veh_sel & 0xFFFF)) return CMD_ERROR;
|
||||
v = GetVehicle(veh_sel & 0xFFFF);
|
||||
if (v->type == 0 || !CheckOwnership(v->owner)) return CMD_ERROR;
|
||||
|
||||
/* Is it a valid order? */
|
||||
if (sel >= v->num_orders)
|
||||
return CMD_ERROR;
|
||||
|
@ -422,6 +574,9 @@ int32 CmdModifyOrder(int x, int y, uint32 flags, uint32 veh_sel, uint32 mode)
|
|||
case OFB_NON_STOP:
|
||||
TOGGLEBIT(order->flags, OFB_NON_STOP);
|
||||
break;
|
||||
|
||||
default:
|
||||
return CMD_ERROR;
|
||||
}
|
||||
|
||||
/* Update the windows, also for vehicles that share the same order list */
|
||||
|
@ -653,8 +808,13 @@ void RestoreVehicleOrders(Vehicle *v, BackuppedOrders *bak)
|
|||
*/
|
||||
int32 CmdRestoreOrderIndex(int x, int y, uint32 flags, uint32 vehicle_id, uint32 data)
|
||||
{
|
||||
Vehicle* v;
|
||||
|
||||
if (!IsVehicleIndex(vehicle_id)) return CMD_ERROR;
|
||||
v = GetVehicle(vehicle_id);
|
||||
if (v->type == 0 || !CheckOwnership(v->owner)) return CMD_ERROR;
|
||||
|
||||
if (flags & DC_EXEC) {
|
||||
Vehicle *v = GetVehicle(vehicle_id);
|
||||
v->service_interval = data >> 16;
|
||||
v->cur_order_index = data & 0xFFFF;
|
||||
}
|
||||
|
|
|
@ -146,6 +146,11 @@ static inline uint16 GetStationPoolSize(void)
|
|||
return _station_pool.total_items;
|
||||
}
|
||||
|
||||
static inline bool IsStationIndex(uint index)
|
||||
{
|
||||
return index < GetStationPoolSize();
|
||||
}
|
||||
|
||||
#define FOR_ALL_STATIONS_FROM(st, start) for (st = GetStation(start); st != NULL; st = (st->index + 1 < GetStationPoolSize()) ? GetStation(st->index + 1) : NULL)
|
||||
#define FOR_ALL_STATIONS(st) FOR_ALL_STATIONS_FROM(st, 0)
|
||||
|
||||
|
@ -292,7 +297,7 @@ static inline bool IsRoadStationTile(uint tile) {
|
|||
/**
|
||||
* Check if a station really exists.
|
||||
*/
|
||||
static inline bool IsValidStation(Station* station)
|
||||
static inline bool IsValidStation(const Station* station)
|
||||
{
|
||||
return station->xy != 0; /* XXX: Replace by INVALID_TILE someday */
|
||||
}
|
||||
|
|
|
@ -40,6 +40,11 @@ static inline uint16 GetWaypointPoolSize(void)
|
|||
return _waypoint_pool.total_items;
|
||||
}
|
||||
|
||||
static inline bool IsWaypointIndex(uint index)
|
||||
{
|
||||
return index < GetWaypointPoolSize();
|
||||
}
|
||||
|
||||
#define FOR_ALL_WAYPOINTS_FROM(wp, start) for (wp = GetWaypoint(start); wp != NULL; wp = (wp->index + 1 < GetWaypointPoolSize()) ? GetWaypoint(wp->index + 1) : NULL)
|
||||
#define FOR_ALL_WAYPOINTS(wp) FOR_ALL_WAYPOINTS_FROM(wp, 0)
|
||||
|
||||
|
|
Loading…
Reference in New Issue