From 6d0e6cf7d589dbaacfe7325e64ed8cd869a6e852 Mon Sep 17 00:00:00 2001 From: jj Date: Wed, 26 Feb 2014 12:44:10 +0100 Subject: [PATCH 1/3] remove old unused code from when dfhack was out of process --- library/Process-darwin.cpp | 22 ------ library/Process-linux.cpp | 22 ------ library/Process-windows.cpp | 104 +--------------------------- library/include/MemAccess.h | 25 ------- plugins/Dfusion/src/lua_Process.cpp | 18 +---- 5 files changed, 2 insertions(+), 189 deletions(-) diff --git a/library/Process-darwin.cpp b/library/Process-darwin.cpp index 8b4ae888c..30ed709b8 100644 --- a/library/Process-darwin.cpp +++ b/library/Process-darwin.cpp @@ -246,28 +246,6 @@ static int getdir (string dir, vector &files) return 0; } -bool Process::getThreadIDs(vector & threads ) -{ - stringstream ss; - vector subdirs; - if(getdir("/proc/self/task/",subdirs) != 0) - { - //FIXME: needs exceptions. this is a fatal error - cerr << "unable to enumerate threads. This is BAD!" << endl; - return false; - } - threads.clear(); - for(size_t i = 0; i < subdirs.size();i++) - { - uint32_t tid; - if(sscanf(subdirs[i].c_str(),"%d", &tid)) - { - threads.push_back(tid); - } - } - return true; -} - uint32_t Process::getTickCount() { struct timeval tp; diff --git a/library/Process-linux.cpp b/library/Process-linux.cpp index c3995a2aa..1b430e5a8 100644 --- a/library/Process-linux.cpp +++ b/library/Process-linux.cpp @@ -181,28 +181,6 @@ static int getdir (string dir, vector &files) return 0; } -bool Process::getThreadIDs(vector & threads ) -{ - stringstream ss; - vector subdirs; - if(getdir("/proc/self/task/",subdirs) != 0) - { - //FIXME: needs exceptions. this is a fatal error - cerr << "unable to enumerate threads. This is BAD!" << endl; - return false; - } - threads.clear(); - for(size_t i = 0; i < subdirs.size();i++) - { - uint32_t tid; - if(sscanf(subdirs[i].c_str(),"%d", &tid)) - { - threads.push_back(tid); - } - } - return true; -} - uint32_t Process::getTickCount() { struct timeval tp; diff --git a/library/Process-windows.cpp b/library/Process-windows.cpp index fdef9e225..a328a9e35 100644 --- a/library/Process-windows.cpp +++ b/library/Process-windows.cpp @@ -24,63 +24,8 @@ distribution. #include "Internal.h" -#define _WIN32_WINNT 0x0501 // needed for INPUT struct -#define WINVER 0x0501 // OpenThread(), PSAPI, Toolhelp32 #define WIN32_LEAN_AND_MEAN #include -#include -#include - -typedef LONG NTSTATUS; -#define STATUS_SUCCESS ((NTSTATUS)0x00000000L) - -// FIXME: it is uncertain how these map to 64bit -typedef struct _DEBUG_BUFFER -{ - HANDLE SectionHandle; - PVOID SectionBase; - PVOID RemoteSectionBase; - ULONG SectionBaseDelta; - HANDLE EventPairHandle; - ULONG Unknown[2]; - HANDLE RemoteThreadHandle; - ULONG InfoClassMask; - ULONG SizeOfInfo; - ULONG AllocatedSize; - ULONG SectionSize; - PVOID ModuleInformation; - PVOID BackTraceInformation; - PVOID HeapInformation; - PVOID LockInformation; - PVOID Reserved[8]; -} DEBUG_BUFFER, *PDEBUG_BUFFER; - -typedef struct _DEBUG_HEAP_INFORMATION -{ - ULONG Base; // 0×00 - ULONG Flags; // 0×04 - USHORT Granularity; // 0×08 - USHORT Unknown; // 0x0A - ULONG Allocated; // 0x0C - ULONG Committed; // 0×10 - ULONG TagCount; // 0×14 - ULONG BlockCount; // 0×18 - ULONG Reserved[7]; // 0x1C - PVOID Tags; // 0×38 - PVOID Blocks; // 0x3C -} DEBUG_HEAP_INFORMATION, *PDEBUG_HEAP_INFORMATION; - -// RtlQueryProcessDebugInformation.DebugInfoClassMask constants -#define PDI_MODULES 0x01 -#define PDI_BACKTRACE 0x02 -#define PDI_HEAPS 0x04 -#define PDI_HEAP_TAGS 0x08 -#define PDI_HEAP_BLOCKS 0x10 -#define PDI_LOCKS 0x20 - -extern "C" __declspec(dllimport) NTSTATUS __stdcall RtlQueryProcessDebugInformation( IN ULONG ProcessId, IN ULONG DebugInfoClassMask, IN OUT PDEBUG_BUFFER DebugBuffer); -extern "C" __declspec(dllimport) PDEBUG_BUFFER __stdcall RtlCreateQueryDebugBuffer( IN ULONG Size, IN BOOLEAN EventPair); -extern "C" __declspec(dllimport) NTSTATUS __stdcall RtlDestroyQueryDebugBuffer( IN PDEBUG_BUFFER DebugBuffer); #include #include @@ -106,8 +51,6 @@ namespace DFHack sections = 0; }; HANDLE my_handle; - vector threads; - vector stoppedthreads; uint32_t my_pid; IMAGE_NT_HEADERS pe_header; IMAGE_SECTION_HEADER * sections; @@ -138,7 +81,7 @@ Process::Process(VersionInfoFactory * factory) // read from this process try { - uint32_t pe_offset = Process::readDWord(d->base+0x3C); + uint32_t pe_offset = readDWord(d->base+0x3C); read(d->base + pe_offset, sizeof(d->pe_header), (uint8_t *)&(d->pe_header)); const size_t sectionsSize = sizeof(IMAGE_SECTION_HEADER) * d->pe_header.FileHeader.NumberOfSections; d->sections = (IMAGE_SECTION_HEADER *) malloc(sectionsSize); @@ -151,24 +94,10 @@ Process::Process(VersionInfoFactory * factory) VersionInfo* vinfo = factory->getVersionInfoByPETimestamp(d->pe_header.FileHeader.TimeDateStamp); if(vinfo) { - vector threads_ids; - if(!getThreadIDs( threads_ids )) - { - // thread enumeration failed. - return; - } identified = true; // give the process a data model and memory layout fixed for the base of first module my_descriptor = new VersionInfo(*vinfo); my_descriptor->rebaseTo(getBase()); - for(size_t i = 0; i < threads_ids.size();i++) - { - HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, (DWORD) threads_ids[i]); - if(hThread) - d->threads.push_back(hThread); - else - cerr << "Unable to open thread :" << hex << (DWORD) threads_ids[i] << endl; - } } } @@ -176,41 +105,10 @@ Process::~Process() { // destroy our rebased copy of the memory descriptor delete my_descriptor; - for(size_t i = 0; i < d->threads.size(); i++) - CloseHandle(d->threads[i]); if(d->sections != NULL) free(d->sections); } -bool Process::getThreadIDs(vector & threads ) -{ - HANDLE AllThreads = INVALID_HANDLE_VALUE; - THREADENTRY32 te32; - - AllThreads = CreateToolhelp32Snapshot( TH32CS_SNAPTHREAD, 0 ); - if( AllThreads == INVALID_HANDLE_VALUE ) - { - return false; - } - te32.dwSize = sizeof(THREADENTRY32 ); - - if( !Thread32First( AllThreads, &te32 ) ) - { - CloseHandle( AllThreads ); - return false; - } - - do - { - if( te32.th32OwnerProcessID == d->my_pid ) - { - threads.push_back(te32.th32ThreadID); - } - } while( Thread32Next(AllThreads, &te32 ) ); - - CloseHandle( AllThreads ); - return true; -} /* typedef struct _MEMORY_BASIC_INFORMATION { diff --git a/library/include/MemAccess.h b/library/include/MemAccess.h index 31647a25e..80844ae5f 100644 --- a/library/include/MemAccess.h +++ b/library/include/MemAccess.h @@ -43,29 +43,6 @@ namespace DFHack class VersionInfoFactory; class PlatformSpecific; - /** - * A type for storing an extended OS Process ID (combines PID and the time the process was started for unique identification) - * \ingroup grp_context - */ - struct ProcessID - { - ProcessID(const uint64_t _time, const uint64_t _pid): time(_time), pid(_pid){}; - bool operator==(const ProcessID &other) const - { - return (other.time == time && other.pid == pid); - } - bool operator< (const ProcessID& ms) const - { - if (time < ms.time) - return true; - else if(time == ms.time) - return pid < ms.pid ; - return false; - } - uint64_t time; - uint64_t pid; - }; - /** * Structure describing a section of virtual memory inside a process * \ingroup grp_context @@ -265,8 +242,6 @@ namespace DFHack { return identified; }; - /// find the thread IDs of the process - bool getThreadIDs(std::vector & threads ); /// get virtual memory ranges of the process (what is mapped where) void getMemRanges(std::vector & ranges ); diff --git a/plugins/Dfusion/src/lua_Process.cpp b/plugins/Dfusion/src/lua_Process.cpp index 19bf698d1..5d36c6246 100644 --- a/plugins/Dfusion/src/lua_Process.cpp +++ b/plugins/Dfusion/src/lua_Process.cpp @@ -144,21 +144,6 @@ static int lua_Process_isIdentified(lua_State *S) st.push(c->isIdentified()); return 1; } -static int lua_Process_getThreadIDs(lua_State *S) -{ - lua::state st(S); - DFHack::Process* c=GetProcessPtr(st); - std::vector threads; - c->getThreadIDs(threads); - st.newtable(); - for(size_t i=0;i Date: Wed, 26 Feb 2014 23:56:53 +0100 Subject: [PATCH 2/3] exterminate: add caste specifier --- NEWS | 1 + Readme.rst | 4 ++++ scripts/exterminate.rb | 18 +++++++++++++++++- 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 854c9353e..b43ced4f0 100644 --- a/NEWS +++ b/NEWS @@ -9,6 +9,7 @@ DFHack future Misc improvements: - digfort: improved csv parsing, add start() comment handling + - exterminate: allow specifying a caste (exterminate gob:male) DFHack v0.34.11-r4 diff --git a/Readme.rst b/Readme.rst index 0668fd6c9..29f0a71fa 100644 --- a/Readme.rst +++ b/Readme.rst @@ -2125,6 +2125,9 @@ With the special argument ``him``, targets only the selected creature. With the special argument ``undead``, targets all undeads on the map, regardless of their race. +When specifying a race, a caste can be specified to further restrict the +targeting. To do that, append and colon and the caste name after the race. + Any non-dead non-caged unit of the specified race gets its ``blood_count`` set to 0, which means immediate death at the next game tick. For creatures such as vampires, it also sets animal.vanish_countdown to 2. @@ -2140,6 +2143,7 @@ but ignore caged/chained creatures. Ex:: exterminate gob + exterminate gob:male To kill a single creature, select the unit with the 'v' cursor and:: diff --git a/scripts/exterminate.rb b/scripts/exterminate.rb index 9fedeb48b..5dfc36a96 100644 --- a/scripts/exterminate.rb +++ b/scripts/exterminate.rb @@ -84,6 +84,7 @@ The special final argument 'magma' will make magma rain on the targets instead. The special final argument 'butcher' will mark the targets for butchering instead. Ex: exterminate gob + exterminate gob:male exterminate elve magma exterminate him exterminate pig butcher @@ -115,6 +116,10 @@ when /^undead/i puts "#{slain} #{count} undeads" else + if race.index(':') + race, caste = race.split(':') + end + raw_race = df.match_rawname(race, all_races.keys) if not raw_race puts "Invalid race, use one of #{all_races.keys.sort.join(' ')}" @@ -123,13 +128,24 @@ else race_nr = df.world.raws.creatures.all.index { |cr| cr.creature_id == raw_race } + if caste + all_castes = df.world.raws.creatures.all[race_nr].caste.map { |c| c.caste_id } + raw_caste = df.match_rawname(caste, all_castes) + if not raw_caste + puts "Invalid caste, use one of #{all_castes.sort.join(' ')}" + throw :script_finished + end + caste_nr = all_castes.index(raw_caste) + end + count = 0 df.world.units.active.each { |u| if u.race == race_nr and checkunit[u] + next if caste_nr and u.caste != caste_nr slayit[u] count += 1 end } - puts "#{slain} #{count} #{raw_race}" + puts "#{slain} #{count} #{raw_caste} #{raw_race}" end From 2e680c4c2c2136ac7f0d4ecdf346f926280990ac Mon Sep 17 00:00:00 2001 From: jj Date: Thu, 27 Feb 2014 17:38:34 +0100 Subject: [PATCH 3/3] autounsuspend: check water level, make df recheck jobs on unsuspend --- scripts/autounsuspend.rb | 71 +++++++++++++++------------------------- 1 file changed, 26 insertions(+), 45 deletions(-) diff --git a/scripts/autounsuspend.rb b/scripts/autounsuspend.rb index aaa29ce9d..d2ee8bbd8 100644 --- a/scripts/autounsuspend.rb +++ b/scripts/autounsuspend.rb @@ -1,58 +1,39 @@ class AutoUnsuspend + attr_accessor :running - def initialize - end - - def process - return false unless @running - joblist = df.world.job_list.next - count = 0 + def process + count = 0 + df.world.job_list.each { |job| + if job.job_type == :ConstructBuilding and job.flags.suspend and df.map_tile_at(job).designation.flow_size <= 1 + job.flags.suspend = false + count += 1 + end + } + if count > 0 + puts "Unsuspended #{count} job(s)." + df.process_jobs = true + end + end - while joblist - job = joblist.item - joblist = joblist.next - - if job.job_type == :ConstructBuilding - if (job.flags.suspend) - item = job.items[0].item - job.flags.suspend = false - count += 1 - end - end - end + def start + @running = true + @onupdate = df.onupdate_register('autounsuspend', 5) { process if @running } + end - puts "Unsuspended #{count} job(s)." unless count == 0 - - end - - def start - @onupdate = df.onupdate_register('autounsuspend', 5) { process } - @running = true - end - - def stop - df.onupdate_unregister(@onupdate) - @running = false - end - - def status - @running ? 'Running.' : 'Stopped.' - end - -end + def stop + @running = false + df.onupdate_unregister(@onupdate) + end +end case $script_args[0] when 'start' - $AutoUnsuspend = AutoUnsuspend.new unless $AutoUnsuspend + $AutoUnsuspend ||= AutoUnsuspend.new $AutoUnsuspend.start when 'end', 'stop' $AutoUnsuspend.stop - + else - if $AutoUnsuspend - puts $AutoUnsuspend.status - else - puts 'Not loaded.' - end + puts $AutoUnsuspend && $AutoUnsuspend.running ? 'Running.' : 'Stopped.' end