Skip to content

Commit d786dea

Browse files
committed
Merge branch 'develop' into log-cleaner
2 parents 9c28ca8 + 7b20900 commit d786dea

26 files changed

Lines changed: 912 additions & 56 deletions

.github/workflows/build-windows.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,10 @@ jobs:
6868
name: Build win64
6969
runs-on: windows-2022
7070
steps:
71+
- name: Set up Python
72+
uses: actions/setup-python@v6
73+
with:
74+
python-version: '3.x'
7175
- name: Install build dependencies
7276
run: |
7377
choco install sccache

.pre-commit-config.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,11 @@ repos:
2020
args: ['--fix=lf']
2121
- id: trailing-whitespace
2222
- repo: https://github.com/python-jsonschema/check-jsonschema
23-
rev: 0.36.0
23+
rev: 0.36.1
2424
hooks:
2525
- id: check-github-workflows
2626
- repo: https://github.com/Lucas-C/pre-commit-hooks
27-
rev: v1.5.5
27+
rev: v1.5.6
2828
hooks:
2929
- id: forbid-tabs
3030
exclude_types:

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ cmake_policy(SET CMP0048 NEW)
66
cmake_policy(SET CMP0074 NEW)
77

88
# set up versioning.
9-
set(DF_VERSION "53.09")
9+
set(DF_VERSION "53.10")
1010
set(DFHACK_RELEASE "r1")
1111
set(DFHACK_PRERELEASE FALSE)
1212

docs/about/Authors.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ Omniclasm
163163
Ong Ying Gao ong-yinggao98
164164
oorzkws oorzkws
165165
OwnageIsMagic OwnageIsMagic
166+
pajawojciech pajawojciech
166167
palenerd dlmarquis
167168
PassionateAngler PassionateAngler
168169
Patrik Lundell PatrikLundell

docs/changelog.txt

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,16 +58,47 @@ Template for new versions:
5858
- ``logcleaner``: New plugin for time-triggered clearing of combat, sparring, and hunting reports with configurable filtering and overlay UI.
5959

6060
## New Features
61+
- `orders`: added search overlay to find and navigate to matching manager orders with arrow indicators
62+
- `sort`: Add death cause button to dead/missing tab in the creatures screen
6163

6264
## Fixes
6365

6466
## Misc Improvements
67+
- Core: DFHack now validates vtable pointers in objects read from memory and will throw an exception instead of crashing when an invalid vtable pointer is encountered. This makes it easier to identify which DF data structure contains corrupted data when this manifests in the form of a bad vtable pointer, and shifts blame for such crashes from DFHack to DF.
6568

6669
## Documentation
6770

6871
## API
72+
- Added ``Maps::addMaterialSpatter``: add a spatter of the specified material + state to the indicated tile, returning whatever amount wouldn't fit in the tile.
73+
- Added ``Maps::addItemSpatter``: add a spatter of the specified item + material + growth print to the indicated tile, returning whatever amount wouldn't fit in the tile.
74+
- Added ``Items::pickGrowthPrint``: given a plant material and a growth index, returns the print variant corresponding to the current in-game time.
75+
- Added ``Items::useStandardMaterial``: given an item type, returns true if the item is made of a specific material and false if it has a race and caste instead.
6976

7077
## Lua
78+
- Added ``Maps::addMaterialSpatter`` as ``dfhack.maps.addMaterialSpatter``.
79+
- Added ``Maps::addItemSpatter`` as ``dfhack.maps.addItemSpatter``.
80+
81+
## Removed
82+
83+
# 53.10-r1
84+
85+
## New Tools
86+
87+
## New Features
88+
89+
## Fixes
90+
- `autochop`: the report will no longer throw a C++ exception when burrows are defined.
91+
- `suspendmanager`: Fix the overlay appearing where it should not when following a unit
92+
93+
## Misc Improvements
94+
95+
## Documentation
96+
97+
## API
98+
- Added ``Burrows::getName``: obtains the name of a burrow, or the same placeholder name that DF would show if the burrow is unnamed.
99+
100+
## Lua
101+
- Added ``Burrows::getName`` as ``dfhack.burrows.getName``.
71102

72103
## Removed
73104

@@ -86,6 +117,7 @@ Template for new versions:
86117
## Documentation
87118

88119
## API
120+
- ``dfhack.job.getManagerOrderName``: New function to get the display name of a manager order
89121

90122
## Lua
91123

docs/dev/Lua API.rst

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1430,6 +1430,10 @@ Job module
14301430

14311431
Returns the job's description, as seen in the Units and Jobs screens.
14321432

1433+
* ``dfhack.job.getManagerOrderName(manager_order)``
1434+
1435+
Returns the manager order's description, as seen in the Work orders screen.
1436+
14331437
Hotkey module
14341438
-------------
14351439

@@ -2486,9 +2490,30 @@ Maps module
24862490
Removes an aquifer from the given tile position.
24872491
Returns *true* or *false* depending on success.
24882492

2493+
* ``dfhack.maps.addMaterialSpatter(pos, mat, matg, state, amount)``
2494+
2495+
Adds a material spatter to the specified map tile. If the tile is already
2496+
full of that spatter, returns the amount left over.
2497+
2498+
Specifying a state of -1 (None) will automatically choose either Solid,
2499+
Liquid, or Gas based on the material properties and the tile temperature.
2500+
2501+
* ``dfhack.maps.addItemSpatter(pos, i_type, i_subtype, subcat1, subcat2, print_variant, amount)``
2502+
2503+
Adds an item spatter to the specified map tile. If the tile is already
2504+
full of that spatter, returns the amount left over.
2505+
2506+
For plant growths, specifying a print_variant of -1 will automatically
2507+
choose an appropriate value. For other item types, this field is ignored.
2508+
24892509
Burrows module
24902510
--------------
24912511

2512+
* ``dfhack.burrows.getName(burrow)``
2513+
2514+
Returns the name of the burrow.
2515+
If the burrow has no set name, returns the same placeholder name that DF would show in the UI.
2516+
24922517
* ``dfhack.burrows.findByName(name[, ignore_final_plus])``
24932518

24942519
Returns the burrow pointer or *nil*. if ``ignore_final_plus`` is ``true``,

library/DataDefs.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,7 @@ const virtual_identity *virtual_identity::find(void *vtable)
370370

371371
// If using a reader/writer lock, re-grab as write here, and recheck
372372
Core &core = Core::getInstance();
373-
std::string name = core.p->doReadClassName(vtable);
373+
std::string name = core.p->readClassName(vtable);
374374

375375
auto name_it = (*name_lookup).find(name);
376376
if (name_it != (*name_lookup).end()) {

library/LuaApi.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ distribution.
9292
#include "df/job_item.h"
9393
#include "df/job_material_category.h"
9494
#include "df/language_word_table.h"
95+
#include "df/manager_order.h"
9596
#include "df/material.h"
9697
#include "df/map_block.h"
9798
#include "df/nemesis_record.h"
@@ -2018,6 +2019,7 @@ static const LuaWrapper::FunctionReg dfhack_job_module[] = {
20182019
WRAPM(Job,isSuitableItem),
20192020
WRAPM(Job,isSuitableMaterial),
20202021
WRAPM(Job,getName),
2022+
WRAPM(Job,getManagerOrderName),
20212023
WRAPM(Job,linkIntoWorld),
20222024
WRAPM(Job,removePostings),
20232025
WRAPM(Job,disconnectJobItem),
@@ -2781,6 +2783,40 @@ static int maps_removeTileAquifer(lua_State* L)
27812783
return 1;
27822784
}
27832785

2786+
static int maps_addMaterialSpatter(lua_State *L)
2787+
{
2788+
int32_t rv;
2789+
df::coord pos;
2790+
2791+
Lua::CheckDFAssign(L, &pos, 1);
2792+
int16_t mat = lua_tointeger(L, 2);
2793+
int32_t matg = lua_tointeger(L, 3);
2794+
df::matter_state state = (df::matter_state)lua_tointeger(L, 4);
2795+
int32_t amount = lua_tointeger(L, 5);
2796+
rv = Maps::addMaterialSpatter(pos, mat, matg, state, amount);
2797+
2798+
lua_pushinteger(L, rv);
2799+
return 1;
2800+
}
2801+
2802+
static int maps_addItemSpatter(lua_State *L)
2803+
{
2804+
int32_t rv;
2805+
df::coord pos;
2806+
2807+
Lua::CheckDFAssign(L, &pos, 1);
2808+
df::item_type i_type = (df::item_type)lua_tointeger(L, 2);
2809+
int16_t i_subtype = lua_tointeger(L, 3);
2810+
int16_t i_subcat1 = lua_tointeger(L, 4);
2811+
int32_t i_subcat2 = lua_tointeger(L, 5);
2812+
int32_t print_variant = lua_tointeger(L, 6);
2813+
int32_t amount = lua_tointeger(L, 7);
2814+
rv = Maps::addItemSpatter(pos, i_type, i_subtype, i_subcat1, i_subcat2, print_variant, amount);
2815+
2816+
lua_pushinteger(L, rv);
2817+
return 1;
2818+
}
2819+
27842820
static const luaL_Reg dfhack_maps_funcs[] = {
27852821
{ "isValidTilePos", maps_isValidTilePos },
27862822
{ "isTileVisible", maps_isTileVisible },
@@ -2796,6 +2832,8 @@ static const luaL_Reg dfhack_maps_funcs[] = {
27962832
{ "isTileHeavyAquifer", maps_isTileHeavyAquifer },
27972833
{ "setTileAquifer", maps_setTileAquifer },
27982834
{ "removeTileAquifer", maps_removeTileAquifer },
2835+
{ "addMaterialSpatter", maps_addMaterialSpatter },
2836+
{ "addItemSpatter", maps_addItemSpatter },
27992837
{ NULL, NULL }
28002838
};
28012839

library/Process.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,9 @@ Process::~Process()
236236

237237
string Process::doReadClassName (void * vptr)
238238
{
239+
if (!checkValidAddress(vptr))
240+
throw std::runtime_error(fmt::format("invalid vtable ptr {}", vptr));
241+
239242
char* rtti = Process::readPtr(((char*)vptr - sizeof(void*)));
240243
#ifndef WIN32
241244
char* typestring = Process::readPtr(rtti + sizeof(void*));
@@ -591,6 +594,20 @@ void Process::getMemRanges(vector<t_memrange>& ranges)
591594
}
592595
#endif
593596

597+
bool Process::checkValidAddress(void* ptr)
598+
{
599+
uintptr_t addr = reinterpret_cast<uintptr_t>(ptr);
600+
auto validate = [&] (t_memrange& r) {
601+
uintptr_t lo = reinterpret_cast<uintptr_t>(r.start);
602+
uintptr_t hi = reinterpret_cast<uintptr_t>(r.end);
603+
return addr >= lo && addr < hi;
604+
};
605+
std::vector<t_memrange> mr;
606+
getMemRanges(mr);
607+
bool valid = std::any_of(mr.begin(), mr.end(), validate);
608+
return valid;
609+
}
610+
594611
uintptr_t Process::getBase()
595612
{
596613
#if WIN32

library/include/MemAccess.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ namespace DFHack
221221

222222
std::string readClassName(void* vptr)
223223
{
224-
std::map<void*, std::string>::iterator it = classNameCache.find(vptr);
224+
auto it = classNameCache.find(vptr);
225225
if (it != classNameCache.end())
226226
return it->second;
227227
return classNameCache[vptr] = doReadClassName(vptr);
@@ -247,6 +247,9 @@ namespace DFHack
247247
/// get virtual memory ranges of the process (what is mapped where)
248248
static void getMemRanges(std::vector<t_memrange>& ranges);
249249

250+
/// check if an address has a mapping
251+
bool checkValidAddress(void* ptr);
252+
250253
/// get the symbol table extension of this process
251254
std::shared_ptr<DFHack::VersionInfo> getDescriptor()
252255
{

0 commit comments

Comments
 (0)