#include "Core.h" #include "Console.h" #include "PluginManager.h" #include "MemAccess.h" #include "MiscUtils.h" #include <../depends/tthread/tinythread.h> //not sure if correct #include #include #include using std::vector; using std::string; using namespace DFHack; uint64_t timeLast=0; static tthread::mutex* mymutex=0; struct memory_data { size_t addr; size_t len; size_t refresh; int state; uint8_t *buf,*lbuf; vector ranges; }memdata; enum HEXVIEW_STATES { STATE_OFF,STATE_ON }; DFhackCExport command_result memview (Core * c, vector & parameters); DFhackCExport const char * plugin_name ( void ) { return "memview"; } DFhackCExport command_result plugin_init ( Core * c, std::vector &commands) { commands.clear(); commands.push_back(PluginCommand("memview","Shows memory in real time. Params: adrr length refresh_rate. If addr==0 then stop viewing",memview)); memdata.state=STATE_OFF; mymutex=new tthread::mutex; return CR_OK; } size_t convert(const std::string& p,bool ishex=false) { size_t ret; std::stringstream conv; if(ishex) conv<>ret; return ret; } bool isAddr(uint32_t *trg,vector & ranges) { if(trg[0]%4==0) for(size_t i=0;i & ranges) { Console &con=c->con; const size_t page_size=16; con.clear(); for(size_t i=0;i31)&&(buf[j+i]<128)) //only printable ascii con.print("%c",buf[j+i]); else con.print("."); //con.print("\n"); } con.print("\n"); con.flush(); } void Deinit() { if(memdata.state==STATE_ON) { memdata.state=STATE_OFF; delete [] memdata.buf; delete [] memdata.lbuf; } } DFhackCExport command_result plugin_onupdate ( Core * c ) { mymutex->lock(); if(memdata.state==STATE_OFF) { mymutex->unlock(); return CR_OK; } //Console &con=c->con; uint64_t time2 = GetTimeMs64(); uint64_t delta = time2-timeLast; if(memdata.refresh!=0) if(deltaunlock(); return CR_OK; } timeLast = time2; c->p->read(memdata.addr,memdata.len,memdata.buf); outputHex(memdata.buf,memdata.lbuf,memdata.len,memdata.addr,c,memdata.ranges); memcpy(memdata.lbuf, memdata.buf, memdata.len); if(memdata.refresh==0) Deinit(); mymutex->unlock(); return CR_OK; } DFhackCExport command_result memview (Core * c, vector & parameters) { mymutex->lock(); c->p->getMemRanges(memdata.ranges); memdata.addr=convert(parameters[0],true); if(memdata.addr==0) { Deinit(); memdata.state=STATE_OFF; mymutex->unlock(); return CR_OK; } else { Deinit(); bool isValid=false; for(size_t i=0;icon.printerr("Invalid address:%x\n",memdata.addr); mymutex->unlock(); return CR_OK; } memdata.state=STATE_ON; } if(parameters.size()>1) memdata.len=convert(parameters[1]); else memdata.len=20*16; if(parameters.size()>2) memdata.refresh=convert(parameters[2]); else memdata.refresh=0; uint8_t *buf,*lbuf; memdata.buf=new uint8_t[memdata.len]; memdata.lbuf=new uint8_t[memdata.len]; c->p->getMemRanges(memdata.ranges); mymutex->unlock(); return CR_OK; } DFhackCExport command_result plugin_shutdown ( Core * c ) { mymutex->lock(); Deinit(); delete mymutex; mymutex->unlock(); return CR_OK; }