1
0
Fork 0

Add: precondition checks to functions that work with both valid company and deity

These are functions that either use ScriptObject::Command or ScriptObject::GetCompany.
This is a bit over-protective, but having the check everywhere makes it easier to
validate that no check is missing automatically instead of by review.

At this moment these checks will not do anything useful, as either IsValid or
IsDeity from ScriptCompanyMode returns true, but that will change later.
pull/10559/head
Rubidium 2023-03-02 21:22:37 +01:00 committed by rubidium42
parent 2fffde0891
commit 534f2419ad
27 changed files with 65 additions and 1 deletions

View File

@ -91,6 +91,7 @@
/* static */ SQInteger ScriptAirport::GetNumHangars(TileIndex tile)
{
EnforceDeityOrCompanyModeValid(-1);
if (!::IsValidTile(tile)) return -1;
if (!::IsTileType(tile, MP_STATION)) return -1;
@ -103,6 +104,7 @@
/* static */ TileIndex ScriptAirport::GetHangarOfAirport(TileIndex tile)
{
EnforceDeityOrCompanyModeValid(INVALID_TILE);
if (!::IsValidTile(tile)) return INVALID_TILE;
if (!::IsTileType(tile, MP_STATION)) return INVALID_TILE;
if (GetNumHangars(tile) < 1) return INVALID_TILE;

View File

@ -21,6 +21,7 @@
/* static */ bool ScriptBaseStation::IsValidBaseStation(StationID station_id)
{
EnforceDeityOrCompanyModeValid(false);
const BaseStation *st = ::BaseStation::GetIfValid(station_id);
return st != nullptr && (st->owner == ScriptObject::GetCompany() || ScriptCompanyMode::IsDeity() || st->owner == OWNER_NONE);
}

View File

@ -72,6 +72,7 @@ static void _DoCommandReturnBuildBridge1(class ScriptInstance *instance)
/* static */ bool ScriptBridge::BuildBridge(ScriptVehicle::VehicleType vehicle_type, BridgeID bridge_id, TileIndex start, TileIndex end)
{
EnforceDeityOrCompanyModeValid(false);
EnforcePrecondition(false, start != end);
EnforcePrecondition(false, ::IsValidTile(start) && ::IsValidTile(end));
EnforcePrecondition(false, TileX(start) == TileX(end) || TileY(start) == TileY(end));
@ -95,6 +96,8 @@ static void _DoCommandReturnBuildBridge1(class ScriptInstance *instance)
/* static */ bool ScriptBridge::_BuildBridgeRoad1()
{
EnforceDeityOrCompanyModeValid(false);
/* Build the piece of road on the 'start' side of the bridge */
TileIndex end = ScriptObject::GetCallbackVariable(0);
TileIndex start = ScriptObject::GetCallbackVariable(1);
@ -107,6 +110,8 @@ static void _DoCommandReturnBuildBridge1(class ScriptInstance *instance)
/* static */ bool ScriptBridge::_BuildBridgeRoad2()
{
EnforceDeityOrCompanyModeValid(false);
/* Build the piece of road on the 'end' side of the bridge */
TileIndex end = ScriptObject::GetCallbackVariable(0);
TileIndex start = ScriptObject::GetCallbackVariable(1);

View File

@ -16,6 +16,7 @@
ScriptDepotList::ScriptDepotList(ScriptTile::TransportType transport_type)
{
EnforceDeityOrCompanyModeValid_Void();
::TileType tile_type;
switch (transport_type) {
default: return;

View File

@ -24,6 +24,7 @@
/* static */ bool ScriptEngine::IsValidEngine(EngineID engine_id)
{
EnforceDeityOrCompanyModeValid(false);
const Engine *e = ::Engine::GetIfValid(engine_id);
if (e == nullptr || !e->IsEnabled()) return false;
@ -35,6 +36,7 @@
/* static */ bool ScriptEngine::IsBuildable(EngineID engine_id)
{
EnforceDeityOrCompanyModeValid(false);
const Engine *e = ::Engine::GetIfValid(engine_id);
return e != nullptr && ::IsEngineBuildable(engine_id, e->type, ScriptObject::GetCompany());
}

View File

@ -15,6 +15,7 @@
ScriptEngineList::ScriptEngineList(ScriptVehicle::VehicleType vehicle_type)
{
EnforceDeityOrCompanyModeValid_Void();
for (const Engine *e : Engine::IterateType((::VehicleType)vehicle_type)) {
if (ScriptCompanyMode::IsDeity() || HasBit(e->company_avail, ScriptObject::GetCompany())) this->AddItem(e->index);
}

View File

@ -62,6 +62,23 @@
#define EnforceDeityMode(returnval) \
EnforcePreconditionCustomError(returnval, ScriptCompanyMode::IsDeity(), ScriptError::ERR_PRECONDITION_INVALID_COMPANY)
/**
* Helper to enforce the precondition that the company mode is valid or that we are a deity.
* @param returnval The value to return on failure.
*/
#define EnforceDeityOrCompanyModeValid(returnval) \
EnforcePreconditionCustomError(returnval, ScriptCompanyMode::IsDeity() || ScriptCompanyMode::IsValid(), ScriptError::ERR_PRECONDITION_INVALID_COMPANY)
/**
* Helper to enforce the precondition that the company mode is valid or that we are a deity.
*/
#define EnforceDeityOrCompanyModeValid_Void() \
if (!(ScriptCompanyMode::IsDeity() || ScriptCompanyMode::IsValid())) { \
ScriptObject::SetLastError(ScriptError::ERR_PRECONDITION_INVALID_COMPANY); \
return; \
}
/**
* Class that handles all error related functions.
* @api ai game

View File

@ -9,6 +9,7 @@
#include "../../stdafx.h"
#include "script_game.hpp"
#include "script_error.hpp"
#include "../../command_type.h"
#include "../../settings_type.h"
#include "../../network/network.h"

View File

@ -33,6 +33,7 @@
/* static */ bool ScriptGameSettings::SetValue(const char *setting, SQInteger value)
{
EnforceDeityOrCompanyModeValid(false);
if (!IsValid(setting)) return false;
const SettingDesc *sd = GetSettingFromName(setting);

View File

@ -25,6 +25,7 @@
/* static */ bool ScriptGroup::IsValidGroup(GroupID group_id)
{
EnforceDeityOrCompanyModeValid(false);
const Group *g = ::Group::GetIfValid(group_id);
return g != nullptr && g->owner == ScriptObject::GetCompany();
}

View File

@ -9,12 +9,14 @@
#include "../../stdafx.h"
#include "script_grouplist.hpp"
#include "script_error.hpp"
#include "../../group.h"
#include "../../safeguards.h"
ScriptGroupList::ScriptGroupList()
{
EnforceDeityOrCompanyModeValid_Void();
for (const Group *g : Group::Iterate()) {
if (g->owner == ScriptObject::GetCompany()) this->AddItem(g->index);
}

View File

@ -119,6 +119,7 @@
/* static */ bool ScriptIndustryType::BuildIndustry(IndustryType industry_type, TileIndex tile)
{
EnforceDeityOrCompanyModeValid(false);
EnforcePrecondition(false, CanBuildIndustry(industry_type));
EnforcePrecondition(false, ScriptMap::IsValidTile(tile));
@ -129,6 +130,7 @@
/* static */ bool ScriptIndustryType::ProspectIndustry(IndustryType industry_type)
{
EnforceDeityOrCompanyModeValid(false);
EnforcePrecondition(false, CanProspectIndustry(industry_type));
uint32 seed = ScriptBase::Rand();

View File

@ -39,6 +39,7 @@
/* static */ bool ScriptObjectType::BuildObject(ObjectType object_type, SQInteger view, TileIndex tile)
{
EnforceDeityOrCompanyModeValid(false);
EnforcePrecondition(false, IsValidObjectType(object_type));
EnforcePrecondition(false, view >= 0 && view < GetViews(object_type));
EnforcePrecondition(false, ScriptMap::IsValidTile(tile));

View File

@ -69,6 +69,7 @@
/* static */ bool ScriptRail::IsRailTypeAvailable(RailType rail_type)
{
EnforceDeityOrCompanyModeValid(false);
if ((::RailType)rail_type >= RAILTYPE_END) return false;
return ScriptCompanyMode::IsDeity() || ::HasRailtypeAvail(ScriptObject::GetCompany(), (::RailType)rail_type);

View File

@ -9,13 +9,14 @@
#include "../../stdafx.h"
#include "script_railtypelist.hpp"
#include "script_companymode.hpp"
#include "script_error.hpp"
#include "../../rail.h"
#include "../../safeguards.h"
ScriptRailTypeList::ScriptRailTypeList()
{
EnforceDeityOrCompanyModeValid_Void();
for (RailType rt = RAILTYPE_BEGIN; rt != RAILTYPE_END; rt++) {
if (ScriptCompanyMode::IsDeity() || ::HasRailtypeAvail(ScriptObject::GetCompany(), rt)) this->AddItem(rt);
}

View File

@ -67,6 +67,7 @@
/* static */ bool ScriptRoad::IsRoadTypeAvailable(RoadType road_type)
{
EnforceDeityOrCompanyModeValid(false);
return (::RoadType)road_type < ROADTYPE_END && ::HasRoadTypeAvail(ScriptObject::GetCompany(), (::RoadType)road_type);
}
@ -489,6 +490,7 @@ static bool NeighbourHasReachableRoad(::RoadType rt, TileIndex start_tile, DiagD
/* static */ bool ScriptRoad::_BuildRoadInternal(TileIndex start, TileIndex end, bool one_way, bool full)
{
EnforceDeityOrCompanyModeValid(false);
EnforcePrecondition(false, start != end);
EnforcePrecondition(false, ::IsValidTile(start));
EnforcePrecondition(false, ::IsValidTile(end));

View File

@ -15,6 +15,7 @@
ScriptRoadTypeList::ScriptRoadTypeList(ScriptRoad::RoadTramTypes rtts)
{
EnforceDeityOrCompanyModeValid_Void();
for (RoadType rt = ROADTYPE_BEGIN; rt != ROADTYPE_END; rt++) {
if (!HasBit(rtts, GetRoadTramType(rt))) continue;
if (ScriptCompanyMode::IsDeity() || ::HasRoadTypeAvail(ScriptObject::GetCompany(), rt)) this->AddItem(rt);

View File

@ -21,6 +21,7 @@
/* static */ bool ScriptSign::IsValidSign(SignID sign_id)
{
EnforceDeityOrCompanyModeValid(false);
const Sign *si = ::Sign::GetIfValid(sign_id);
return si != nullptr && (si->owner == ScriptObject::GetCompany() || si->owner == OWNER_DEITY);
}
@ -36,6 +37,7 @@
{
CCountedPtr<Text> counter(name);
EnforceDeityOrCompanyModeValid(false);
EnforcePrecondition(false, IsValidSign(sign_id));
EnforcePrecondition(false, name != nullptr);
const std::string &text = name->GetDecodedText();
@ -63,6 +65,7 @@
/* static */ bool ScriptSign::RemoveSign(SignID sign_id)
{
EnforceDeityOrCompanyModeValid(false);
EnforcePrecondition(false, IsValidSign(sign_id));
return ScriptObject::Command<CMD_RENAME_SIGN>::Do(sign_id, "");
}
@ -71,6 +74,7 @@
{
CCountedPtr<Text> counter(name);
EnforceDeityOrCompanyModeValid(INVALID_SIGN);
EnforcePrecondition(INVALID_SIGN, ::IsValidTile(location));
EnforcePrecondition(INVALID_SIGN, name != nullptr);
const std::string &text = name->GetDecodedText();

View File

@ -21,6 +21,7 @@
/* static */ bool ScriptStation::IsValidStation(StationID station_id)
{
EnforceDeityOrCompanyModeValid(false);
const Station *st = ::Station::GetIfValid(station_id);
return st != nullptr && (st->owner == ScriptObject::GetCompany() || ScriptCompanyMode::IsDeity() || st->owner == OWNER_NONE);
}

View File

@ -18,6 +18,7 @@
ScriptStationList::ScriptStationList(ScriptStation::StationType station_type)
{
EnforceDeityOrCompanyModeValid_Void();
for (Station *st : Station::Iterate()) {
if ((st->owner == ScriptObject::GetCompany() || ScriptCompanyMode::IsDeity()) && (st->facilities & station_type) != 0) this->AddItem(st->index);
}

View File

@ -25,6 +25,7 @@
/* static */ bool ScriptTile::IsBuildable(TileIndex tile)
{
EnforceDeityOrCompanyModeValid(false);
if (!::IsValidTile(tile)) return false;
switch (::GetTileType(tile)) {
@ -277,6 +278,7 @@
/* static */ bool ScriptTile::DemolishTile(TileIndex tile)
{
EnforceDeityOrCompanyModeValid(false);
EnforcePrecondition(false, ::IsValidTile(tile));
return ScriptObject::Command<CMD_LANDSCAPE_CLEAR>::Do(tile);

View File

@ -281,6 +281,7 @@
{
CCountedPtr<Text> counter(name);
EnforceDeityOrCompanyModeValid(false);
EnforcePrecondition(false, ScriptCompanyMode::IsDeity() || _settings_game.economy.found_town != TF_FORBIDDEN);
EnforcePrecondition(false, ::IsValidTile(tile));
EnforcePrecondition(false, size == TOWN_SIZE_SMALL || size == TOWN_SIZE_MEDIUM || size == TOWN_SIZE_LARGE)

View File

@ -82,6 +82,7 @@ static void _DoCommandReturnBuildTunnel1(class ScriptInstance *instance)
/* static */ bool ScriptTunnel::BuildTunnel(ScriptVehicle::VehicleType vehicle_type, TileIndex start)
{
EnforceDeityOrCompanyModeValid(false);
EnforcePrecondition(false, ::IsValidTile(start));
EnforcePrecondition(false, vehicle_type == ScriptVehicle::VT_RAIL || vehicle_type == ScriptVehicle::VT_ROAD);
EnforcePrecondition(false, vehicle_type != ScriptVehicle::VT_RAIL || ScriptRail::IsRailTypeAvailable(ScriptRail::GetCurrentRailType()));
@ -99,6 +100,8 @@ static void _DoCommandReturnBuildTunnel1(class ScriptInstance *instance)
/* static */ bool ScriptTunnel::_BuildTunnelRoad1()
{
EnforceDeityOrCompanyModeValid(false);
/* Build the piece of road on the 'start' side of the tunnel */
TileIndex end = ScriptObject::GetCallbackVariable(0);
TileIndex start = ScriptTunnel::GetOtherTunnelEnd(end);
@ -111,6 +114,8 @@ static void _DoCommandReturnBuildTunnel1(class ScriptInstance *instance)
/* static */ bool ScriptTunnel::_BuildTunnelRoad2()
{
EnforceDeityOrCompanyModeValid(false);
/* Build the piece of road on the 'end' side of the tunnel */
TileIndex end = ScriptObject::GetCallbackVariable(0);
TileIndex start = ScriptTunnel::GetOtherTunnelEnd(end);

View File

@ -30,6 +30,7 @@
/* static */ bool ScriptVehicle::IsValidVehicle(VehicleID vehicle_id)
{
EnforceDeityOrCompanyModeValid(false);
const Vehicle *v = ::Vehicle::GetIfValid(vehicle_id);
return v != nullptr && (v->owner == ScriptObject::GetCompany() || ScriptCompanyMode::IsDeity()) && (v->IsPrimaryVehicle() || (v->type == VEH_TRAIN && ::Train::From(v)->IsFreeWagon()));
}

View File

@ -20,6 +20,7 @@
ScriptVehicleList::ScriptVehicleList()
{
EnforceDeityOrCompanyModeValid_Void();
for (const Vehicle *v : Vehicle::Iterate()) {
if ((v->owner == ScriptObject::GetCompany() || ScriptCompanyMode::IsDeity()) && (v->IsPrimaryVehicle() || (v->type == VEH_TRAIN && ::Train::From(v)->IsFreeWagon()))) this->AddItem(v->index);
}
@ -27,6 +28,7 @@ ScriptVehicleList::ScriptVehicleList()
ScriptVehicleList_Station::ScriptVehicleList_Station(StationID station_id)
{
EnforceDeityOrCompanyModeValid_Void();
if (!ScriptBaseStation::IsValidBaseStation(station_id)) return;
for (const Vehicle *v : Vehicle::Iterate()) {
@ -43,6 +45,7 @@ ScriptVehicleList_Station::ScriptVehicleList_Station(StationID station_id)
ScriptVehicleList_Depot::ScriptVehicleList_Depot(TileIndex tile)
{
EnforceDeityOrCompanyModeValid_Void();
if (!ScriptMap::IsValidTile(tile)) return;
DestinationID dest;
@ -100,6 +103,7 @@ ScriptVehicleList_SharedOrders::ScriptVehicleList_SharedOrders(VehicleID vehicle
ScriptVehicleList_Group::ScriptVehicleList_Group(GroupID group_id)
{
EnforceDeityOrCompanyModeValid_Void();
if (!ScriptGroup::IsValidGroup((ScriptGroup::GroupID)group_id)) return;
for (const Vehicle *v : Vehicle::Iterate()) {
@ -111,6 +115,7 @@ ScriptVehicleList_Group::ScriptVehicleList_Group(GroupID group_id)
ScriptVehicleList_DefaultGroup::ScriptVehicleList_DefaultGroup(ScriptVehicle::VehicleType vehicle_type)
{
EnforceDeityOrCompanyModeValid_Void();
if (vehicle_type < ScriptVehicle::VT_RAIL || vehicle_type > ScriptVehicle::VT_AIR) return;
for (const Vehicle *v : Vehicle::Iterate()) {

View File

@ -17,6 +17,7 @@
/* static */ bool ScriptWaypoint::IsValidWaypoint(StationID waypoint_id)
{
EnforceDeityOrCompanyModeValid(false);
const Waypoint *wp = ::Waypoint::GetIfValid(waypoint_id);
return wp != nullptr && (wp->owner == ScriptObject::GetCompany() || ScriptCompanyMode::IsDeity() || wp->owner == OWNER_NONE);
}

View File

@ -17,6 +17,7 @@
ScriptWaypointList::ScriptWaypointList(ScriptWaypoint::WaypointType waypoint_type)
{
EnforceDeityOrCompanyModeValid_Void();
for (const Waypoint *wp : Waypoint::Iterate()) {
if ((wp->facilities & waypoint_type) &&
(wp->owner == ScriptObject::GetCompany() || ScriptCompanyMode::IsDeity() || wp->owner == OWNER_NONE)) this->AddItem(wp->index);