Merge pull request #751 from PeridexisErrant/remove-dfusion
Remove dfusion, df2mc, mapexport, dwarfexportdevelop
						commit
						b71c1b9e7c
					
				| @ -1,11 +0,0 @@ | ||||
| include_directories(include) | ||||
| 
 | ||||
| FILE(GLOB DFUSION_CPPS src/*.c*) | ||||
| set( | ||||
|     DFUSION_CPPS_ALL | ||||
|     dfusion.cpp | ||||
|     ${DFUSION_CPPS} | ||||
| ) | ||||
| FILE(GLOB DFUSION_HS include/*) | ||||
| SET_SOURCE_FILES_PROPERTIES( ${DFUSION_HS} PROPERTIES HEADER_FILE_ONLY TRUE ) | ||||
| DFHACK_PLUGIN(dfusion  ${DFUSION_CPPS_ALL} ${DFUSION_HS} LINK_LIBRARIES lua dfhack-tinythread) | ||||
| @ -1,88 +0,0 @@ | ||||
| #include "Core.h" | ||||
| #include "Export.h" | ||||
| #include "PluginManager.h" | ||||
| #include "MemAccess.h" | ||||
| #include "MiscUtils.h" | ||||
| #include <vector> | ||||
| #include <string> | ||||
| 
 | ||||
| #include "luamain.h" | ||||
| #include "lua_Process.h" | ||||
| #include "lua_Hexsearch.h" | ||||
| #include "lua_Misc.h" | ||||
| 
 | ||||
| #include "DataDefs.h" | ||||
| #include "LuaTools.h" | ||||
| 
 | ||||
| using std::vector; | ||||
| using std::string; | ||||
| using namespace DFHack; | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| DFHACK_PLUGIN("dfusion") | ||||
| 
 | ||||
| static int loadObjectFile(lua_State* L) | ||||
| { | ||||
|     std::string path; | ||||
| 
 | ||||
|     path=luaL_checkstring(L,1); | ||||
| 
 | ||||
|     OutFile::File f(path); | ||||
|     lua_newtable(L); | ||||
|     int table_pos=lua_gettop(L); | ||||
|     size_t size=f.GetTextSize(); | ||||
|     Lua::Push(L,size); | ||||
|     lua_setfield(L,table_pos,"data_size"); | ||||
|     char* buf=new char[size]; | ||||
|     f.GetText(buf); | ||||
| 
 | ||||
|     //Lua::PushDFObject(L,DFHack::,buf);
 | ||||
|     //Lua::Push(L,buf);
 | ||||
|     lua_pushlightuserdata(L,buf); | ||||
|     lua_setfield(L,table_pos,"data"); | ||||
|     const OutFile::vSymbol &symbols=f.GetSymbols(); | ||||
|     lua_newtable(L); | ||||
|     for(size_t i=0;i<symbols.size();i++) | ||||
|     { | ||||
|         Lua::Push(L,i); | ||||
|         lua_newtable(L); | ||||
|         Lua::Push(L,symbols[i].name); | ||||
|         lua_setfield(L,-2,"name"); | ||||
|         Lua::Push(L,symbols[i].pos); | ||||
|         lua_setfield(L,-2,"pos"); | ||||
| 
 | ||||
| 
 | ||||
|         lua_settable(L,-3); | ||||
|     } | ||||
|     lua_setfield(L,table_pos,"symbols"); | ||||
|     return 1; | ||||
| } | ||||
| static int markAsExecutable(lua_State* L) | ||||
| { | ||||
|     unsigned addr=luaL_checkunsigned(L,1); | ||||
|     std::vector<DFHack::t_memrange> ranges; | ||||
|     DFHack::Core::getInstance().p->getMemRanges(ranges); | ||||
|     for(size_t i=0;i<ranges.size();i++) | ||||
|     { | ||||
|         if(ranges[i].isInRange((void*)addr)) | ||||
|         { | ||||
|             DFHack::t_memrange newperm=ranges[i]; | ||||
|             newperm.execute=true; | ||||
|             DFHack::Core::getInstance().p->setPermisions(ranges[i],newperm); | ||||
|             return 0; | ||||
|         } | ||||
|     } | ||||
|     lua_pushlstring(L,"Memory range not found",23); | ||||
|     lua_error(L); | ||||
|     return 0; | ||||
| } | ||||
| DFHACK_PLUGIN_LUA_COMMANDS { | ||||
|     DFHACK_LUA_COMMAND(loadObjectFile), | ||||
|     DFHACK_LUA_COMMAND(markAsExecutable), | ||||
|     DFHACK_LUA_END | ||||
| }; | ||||
| DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands) | ||||
| { | ||||
|     return CR_OK; | ||||
| } | ||||
| @ -1,126 +0,0 @@ | ||||
| #ifndef OUTFILE_H | ||||
| #define OUTFILE_H | ||||
| #include <string> | ||||
| #include <fstream> | ||||
| #include <iostream> | ||||
| #include <map> | ||||
| #include <vector> | ||||
| namespace OutFile | ||||
| { | ||||
| struct Header | ||||
| { | ||||
|         unsigned short machinetype; | ||||
|         unsigned short sectioncount; | ||||
|         unsigned long time; | ||||
|         unsigned long symbolptr; | ||||
|         unsigned long symbolcount; | ||||
|         unsigned short opthead; | ||||
|         unsigned short flags; | ||||
|      void PrintData() | ||||
|     { | ||||
|         std::cout<<"Symbol start:"<<symbolptr<<"\n"; | ||||
|     } | ||||
| }; | ||||
| struct Section | ||||
| { | ||||
|     char name[8]; | ||||
|     unsigned long Vsize; | ||||
|     unsigned long Vstart; | ||||
|     unsigned long size; | ||||
|     unsigned long start; | ||||
|     unsigned long ptrRel; | ||||
|     unsigned long ptrLine; | ||||
|     unsigned short numRel; | ||||
|     unsigned short numLine; | ||||
|     unsigned long flags; | ||||
|     void PrintData() | ||||
|     { | ||||
|         std::cout<<name<<" size:"<<size<<" start:"<<start<<"\n"; | ||||
|     } | ||||
| }; | ||||
| struct Symbol | ||||
| { | ||||
| 
 | ||||
|     std::string name; | ||||
|     unsigned long pos; | ||||
|     unsigned short sectnumb; | ||||
|     unsigned short type; | ||||
|     unsigned char storageclass; | ||||
|     unsigned char auxsymbs; | ||||
|     //char unk2[6];
 | ||||
|     void Read(std::iostream &s,unsigned long strptr) | ||||
|     { | ||||
|         union | ||||
|         { | ||||
|             char buf[8]; | ||||
|             struct | ||||
|             { | ||||
|             unsigned long zeros; | ||||
|             unsigned long strptr; | ||||
|             }; | ||||
| 
 | ||||
|         }data; | ||||
| 
 | ||||
|         s.read((char*)&data,8); | ||||
|         s.read((char*)&pos,4); | ||||
|         s.read((char*)§numb,2); | ||||
|         s.read((char*)&type,2); | ||||
|         s.read((char*)&storageclass,1); | ||||
|         s.read((char*)&auxsymbs,1); | ||||
|         if(data.zeros!=0) | ||||
|         { | ||||
|             name=data.buf; | ||||
|             name=name.substr(0,8); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             //name="";
 | ||||
|             //std::cout<<"Name in symbol table\n";
 | ||||
|             char buf[256]; | ||||
|             s.seekg(strptr+data.strptr); | ||||
|             s.get(buf,256,'\0'); | ||||
|             name=buf; | ||||
|         } | ||||
| 
 | ||||
|         //s.seekp(6,std::ios::cur);
 | ||||
|     } | ||||
|     void PrintData() | ||||
|     { | ||||
|         std::cout<<name<<" section:"<<sectnumb<<" pos:"<<pos<<"\n"; | ||||
|     } | ||||
| }; | ||||
| struct Relocation | ||||
| { | ||||
|     unsigned long  ptr; | ||||
|     unsigned long  tblIndex; | ||||
|     unsigned short type; | ||||
| }; | ||||
| typedef std::vector<Symbol> vSymbol; | ||||
| class File | ||||
| { | ||||
| public: | ||||
|     File(std::string path); | ||||
|     virtual ~File(); | ||||
| 
 | ||||
|     void GetText(char *ptr); | ||||
|     size_t GetTextSize(); | ||||
|     void LoadSymbols(); | ||||
|     const vSymbol& GetSymbols(){LoadSymbols();return symbols;}; | ||||
|     void PrintSymbols(); | ||||
|     void PrintRelocations(); | ||||
| protected: | ||||
| private: | ||||
|     typedef std::map<std::string,Section> secMap; | ||||
| 
 | ||||
|     secMap sections; | ||||
|     vSymbol symbols; | ||||
|     Section &GetSection(std::string name); | ||||
| 
 | ||||
|     std::fstream mystream; | ||||
|     Header myhead; | ||||
|    // Section Text;
 | ||||
|     //Section Data;
 | ||||
|    // Section Bss;
 | ||||
| }; | ||||
| } | ||||
| #endif // OUTFILE_H
 | ||||
| @ -1,37 +0,0 @@ | ||||
| #ifndef HEXSEARCH_H | ||||
| #define HEXSEARCH_H | ||||
| #include <vector> | ||||
| #include "Core.h" //for some reason process.h needs core | ||||
| #include "MemAccess.h" | ||||
| 
 | ||||
| //(not yet)implemented using Boyer-Moore algorithm
 | ||||
| 
 | ||||
| class Hexsearch | ||||
| { | ||||
| public: | ||||
|     typedef std::vector<int> SearchArgType; | ||||
|     enum SearchConst  //TODO add more
 | ||||
|     { | ||||
|         ANYBYTE=0x101,DWORD_,ANYDWORD,ADDRESS | ||||
|     }; | ||||
| 
 | ||||
|     Hexsearch(const SearchArgType &args,char * startpos,char * endpos); | ||||
|     ~Hexsearch(); | ||||
| 
 | ||||
|     void Reset(){pos_=startpos_;}; | ||||
|     void SetStart(char * pos){pos_=pos;}; | ||||
| 
 | ||||
|     void * FindNext(); | ||||
|     std::vector<void *> FindAll(); | ||||
| 
 | ||||
| private: | ||||
|     bool Compare(int a,int b); | ||||
|     void ReparseArgs(); | ||||
|     SearchArgType args_; | ||||
|     char * pos_,* startpos_,* endpos_; | ||||
|     std::vector<int> BadCharShifts,GoodSuffixShift; | ||||
|     void PrepareGoodSuffixTable(); | ||||
|     void PrepareBadCharShift(); | ||||
| }; | ||||
| 
 | ||||
| #endif | ||||
| @ -1,33 +0,0 @@ | ||||
| #ifndef LUA_HEXSEARCH_H | ||||
| #define LUA_HEXSEARCH_H | ||||
| #include "hexsearch.h" | ||||
| 
 | ||||
| #include "luamain.h" | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| namespace lua | ||||
| { | ||||
| 
 | ||||
| class Hexsearch | ||||
| { | ||||
|     int tblid; | ||||
|     ::Hexsearch *p; | ||||
| public: | ||||
|     Hexsearch(lua_State *L,int id); | ||||
|     ~Hexsearch(); | ||||
| 
 | ||||
|     int GetTableId(){return tblid;}; | ||||
| 
 | ||||
|     int find(lua_State *L); | ||||
|     int findall(lua_State *L); | ||||
|     int reset(lua_State *L); | ||||
| 
 | ||||
|     DEF_LUNE(Hexsearch); | ||||
| }; | ||||
| void RegisterHexsearch(lua::state &st); | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| #endif | ||||
| @ -1,46 +0,0 @@ | ||||
| #ifndef LUA_MISC_H | ||||
| #define LUA_MISC_H | ||||
| 
 | ||||
| #include <map> | ||||
| 
 | ||||
| #include "Core.h" | ||||
| #include <MemAccess.h> | ||||
| #include "luamain.h" | ||||
| #include "OutFile.h" | ||||
| #include "LuaTools.h" | ||||
| 
 | ||||
| namespace lua | ||||
| { | ||||
| 
 | ||||
| typedef std::map<std::string,void *> mapPlugs; | ||||
| 
 | ||||
| class PlugManager | ||||
| { | ||||
|     public: | ||||
| 
 | ||||
|         mapPlugs GetList(){return plugs;}; | ||||
|         uint32_t AddNewPlug(std::string name,uint32_t size,uint32_t loc=0); | ||||
|         uint32_t FindPlugin(std::string name); | ||||
| 
 | ||||
|         static PlugManager &GetInst() | ||||
|         { | ||||
|             void *p; | ||||
|             p=DFHack::Core::getInstance().GetData("dfusion_manager"); | ||||
|             if(p==0) | ||||
|             { | ||||
|                 p=new PlugManager; | ||||
|                 DFHack::Core::getInstance().RegisterData(p,"dfusion_manager"); | ||||
|             } | ||||
|             return *static_cast<PlugManager*>(p); | ||||
|         }; | ||||
|     protected: | ||||
|     private: | ||||
|         PlugManager(){}; | ||||
|         mapPlugs plugs; | ||||
| }; | ||||
| 
 | ||||
| void RegisterMisc(lua::state &st); | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
| @ -1,13 +0,0 @@ | ||||
| #ifndef LUA_PROCESS_H | ||||
| #define LUA_PROCESS_H | ||||
| 
 | ||||
| #include "Core.h" | ||||
| #include <MemAccess.h> | ||||
| 
 | ||||
| #include "luamain.h" | ||||
| 
 | ||||
| namespace lua | ||||
| { | ||||
| void RegisterProcess(lua::state &st); | ||||
| } | ||||
| #endif | ||||
| @ -1,40 +0,0 @@ | ||||
| #ifndef LUAMAIN_H | ||||
| #define LUAMAIN_H | ||||
| #include <string> | ||||
| using std::string; | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| #include "lua.h" | ||||
| #include "lauxlib.h" | ||||
| #include "lualib.h" | ||||
| 
 | ||||
| 
 | ||||
| #include "lune.h" | ||||
| #include "luaxx.hpp" | ||||
| 
 | ||||
| namespace lua | ||||
| { | ||||
|     //global lua state singleton
 | ||||
|     class glua | ||||
|     { | ||||
|     public: | ||||
|         static state &Get(); | ||||
|     private: | ||||
|         glua(); | ||||
|         static glua *ptr; | ||||
|         state mystate; | ||||
|     }; | ||||
|     //registers basic lua commands
 | ||||
|     void RegBasics(lua::state &L); | ||||
|     //dumps lua function trace, useless unless called from lua.
 | ||||
|     string DebugDump(lua::state &L); | ||||
|     //register functions, first registers into global scope, second into current table
 | ||||
|     void RegFunctions(lua::state &L,luaL_Reg const *arr); | ||||
|     void RegFunctionsLocal(lua::state &L,luaL_Reg const *arr); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| #endif // LUAMAIN_H
 | ||||
| @ -1,530 +0,0 @@ | ||||
| /* vim: set et sw=3 tw=0 fo=croqlaw cino=t0:
 | ||||
|  * | ||||
|  * Luaxx, the C++ Lua wrapper library. | ||||
|  * Copyright (c) 2006-2008 Matthew Nicholson | ||||
|  * | ||||
|  * Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|  * of this software and associated documentation files (the "Software"), to | ||||
|  * deal in the Software without restriction, including without limitation the | ||||
|  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or | ||||
|  * sell copies of the Software, and to permit persons to whom the Software is | ||||
|  * furnished to do so, subject to the following conditions: | ||||
|  * | ||||
|  * The above copyright notice and this permission notice shall be included in | ||||
|  * all copies or substantial portions of the Software. | ||||
|  * | ||||
|  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||||
|  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||||
|  * IN THE SOFTWARE. | ||||
|  */ | ||||
| 
 | ||||
| #ifndef LUAXX_H | ||||
| #define LUAXX_H | ||||
| 
 | ||||
| #define lua_Integer_long 1 | ||||
| #define lua_Integer_int 1 | ||||
| 
 | ||||
| 
 | ||||
| #include "lua.h" | ||||
| #include "lauxlib.h" | ||||
| #include "lualib.h" | ||||
| 
 | ||||
| 
 | ||||
| #include <string> | ||||
| #include <vector> | ||||
| #include <new> | ||||
| #include <exception> | ||||
| 
 | ||||
| /** @file
 | ||||
|  * Luaxx header file. | ||||
|  */ | ||||
| 
 | ||||
| /** @mainpage Luaxx
 | ||||
|  * | ||||
|  * Luaxx is a thin wrapper around the Lua C API.  The wrapper adds some | ||||
|  * convenience functions and integrates well with modern C++. | ||||
|  * | ||||
|  * Luaxx is not designed like toLua, instead Luaxx is more of a 1 to 1 | ||||
|  * logical mapping of the lua API in C++.  For example: in C you would write | ||||
|  * 'lua_pushnumber(L, 3)', in C++ with Luaxx you would write | ||||
|  * 'L.push(3)'. | ||||
|  * | ||||
|  * Every thing is contained in the 'lua' namespace and exceptions are thrown | ||||
|  * when a lua API function returns an error.  Most of the functionality is | ||||
|  * contained in the lua::state class, which can be passed directly to lua C API | ||||
|  * functions (the compiler will automatically use the internal lua_State | ||||
|  * pointer).  See the documentation for that class for more information. | ||||
|  */ | ||||
| 
 | ||||
| namespace lua | ||||
| { | ||||
|     void StackDump(lua_State *L); | ||||
|    /** A generic lua exception.
 | ||||
|     */ | ||||
|    class exception : public std::exception { | ||||
|       public: | ||||
|          /// Constructor.
 | ||||
|          exception() : std::exception() { } | ||||
|          /// Constructor.
 | ||||
|          explicit exception(const char* desc) : std::exception(), description(desc) { } | ||||
|          virtual ~exception() throw() { } | ||||
|          /** Get a description of the error.
 | ||||
|           * @returns a C-string describing the error | ||||
|           */ | ||||
|          virtual const char* what() const throw() { | ||||
|             return description.c_str(); | ||||
|          } | ||||
|       private: | ||||
|          std::string description; | ||||
|    }; | ||||
| 
 | ||||
|    /** A lua runtime error.
 | ||||
|     * This is thrown when there was an error executing some lua code. | ||||
|     * @note This is not an std::runtime error. | ||||
|     */ | ||||
|    class runtime_error : public exception { | ||||
|       public: | ||||
|          /// Constructor.
 | ||||
|          runtime_error() : exception() { } | ||||
|          /// Constructor.
 | ||||
|          explicit runtime_error(const char* desc) : exception(desc) { } | ||||
|          virtual ~runtime_error() throw() { } | ||||
|    }; | ||||
| 
 | ||||
|    /** A syntax error.
 | ||||
|     */ | ||||
|    class syntax_error : public exception { | ||||
|       public: | ||||
|          /// Constructor.
 | ||||
|          syntax_error() : exception() { } | ||||
|          /// Constructor.
 | ||||
|          explicit syntax_error(const char* desc) : exception(desc) { } | ||||
|          virtual ~syntax_error() throw() { } | ||||
|    }; | ||||
| 
 | ||||
|    /** An error loading a lua file.
 | ||||
|     * This is thrown when a call to lua::loadfile failed because the file could | ||||
|     * not be opened or read. | ||||
|     */ | ||||
|    class file_error : public exception { | ||||
|       public: | ||||
|          /// Constructor.
 | ||||
|          file_error() : exception() { } | ||||
|          /// Constructor.
 | ||||
|          explicit file_error(const char* desc) : exception(desc) { } | ||||
|          virtual ~file_error() throw() { } | ||||
|    }; | ||||
| 
 | ||||
|    /** A memory allocation error.
 | ||||
|     */ | ||||
|    class bad_alloc : public exception, std::bad_alloc { | ||||
|       public: | ||||
|          /// Constructor.
 | ||||
|          bad_alloc() : lua::exception(), std::bad_alloc() { } | ||||
|          /// Constructor.
 | ||||
|          explicit bad_alloc(const char* desc) : lua::exception(desc), std::bad_alloc() { } | ||||
|          virtual ~bad_alloc() throw() { } | ||||
|    }; | ||||
| 
 | ||||
|    /** An error converting a lua type.
 | ||||
|     */ | ||||
|    class bad_conversion : public exception { | ||||
|       public: | ||||
|          /// Constructor.
 | ||||
|          bad_conversion() : exception() { } | ||||
|          /// Constructor.
 | ||||
|          explicit bad_conversion(const char* desc) : exception(desc) { } | ||||
|          virtual ~bad_conversion() throw() { } | ||||
|    }; | ||||
| 
 | ||||
|    /// A Lua table (this class does not have any data).
 | ||||
|    class table { }; | ||||
|    /// A Lua nil (this class does not have any data).
 | ||||
|    class nil { }; | ||||
|    /// A lua function (not a cfunction).
 | ||||
|    class function { }; | ||||
|    /// A lua userdatum
 | ||||
|    class userdata { }; | ||||
|    /// A lua light userdatum
 | ||||
|    class lightuserdata { }; | ||||
| 
 | ||||
|    typedef lua_CFunction cfunction;  ///< A cfunction on the lua statck
 | ||||
|    typedef lua_Integer integer;      ///< The default lua integer type
 | ||||
|    typedef lua_Number number;        ///< The default lua number type
 | ||||
|    typedef lua_Reader reader;        ///< The type of function used by lua_load
 | ||||
|    const int multiret = LUA_MULTRET; ///< LUA_MULTIRET
 | ||||
| 
 | ||||
|    /** This is the Luaxx equivalent of lua_State.
 | ||||
|     * The functions provided by this class, closely resemble those of the Lua C | ||||
|     * API. | ||||
|     */ | ||||
|     void StackDump(lua_State *L); | ||||
|    class state { | ||||
|       public: | ||||
|          state(); | ||||
|          state(lua_State* L); | ||||
|          state(const state& t) | ||||
|          { | ||||
|              managed=false; | ||||
|              L=t.L; | ||||
|          } | ||||
|          state& operator = (const state& t); | ||||
|          ~state(); | ||||
| 
 | ||||
|          operator lua_State*(); | ||||
| 
 | ||||
|          state& push(); | ||||
|          state& push(nil); | ||||
|          state& push(bool boolean); | ||||
|          template<typename T> state& push(T number); | ||||
|          state& push(const char* s, size_t length); | ||||
|          state& push(const char* s); | ||||
|          state& push(const std::string& s); | ||||
|          state& push(cfunction f); | ||||
|          state& push(table); | ||||
|          state& push(void* p); | ||||
|          template<typename T> state& pushlightuserdata(T p); | ||||
| 
 | ||||
|          template<typename T> state& to(T& number, int index = -1); | ||||
|          template<typename T> state& touserdata(T& p, int index = -1); | ||||
| 
 | ||||
|          template<typename T> T as(T default_value, int index = -1); | ||||
|          template<typename T> T as(int index = -1); | ||||
|          template<typename T> T vpop() | ||||
|          { | ||||
|              T ret; | ||||
|              ret=as<T>(); | ||||
|              pop(); | ||||
|              return ret; | ||||
|          } | ||||
|          template<typename T> bool is(int index = -1); | ||||
| 
 | ||||
|          state& check(int narg); | ||||
| #ifndef lua_Integer_int | ||||
|          state& check(int& i, int narg); | ||||
| #endif | ||||
|          state& check(integer& i, int narg); | ||||
| #ifndef lua_Integer_long | ||||
|          state& check(long& l, int narg); | ||||
| #endif | ||||
|          state& check(std::string& s, int narg); | ||||
|          state& check(number& n, int narg); | ||||
| 
 | ||||
|          template<typename msg_t> void error(msg_t message); | ||||
| #if 0 | ||||
|          template<> void error(const std::string& message); | ||||
| #endif | ||||
| 
 | ||||
|          state& pcall(int nargs = 0, int nresults = 0, int on_error = 0); | ||||
|          state& call(int nargs = 0, int nresults = 0); | ||||
| 
 | ||||
|          state& checkstack(int size); | ||||
|          state& settop(int index); | ||||
|          int gettop(); | ||||
|          int size(); | ||||
|          bool empty(); | ||||
| 
 | ||||
|          state& insert(int index); | ||||
|          state& replace(int index); | ||||
|          state& remove(int index); | ||||
|          state& pop(int elements = 1); | ||||
| 
 | ||||
|          state& pushvalue(int index); | ||||
| 
 | ||||
|          state& newtable(); | ||||
|          bool newmetatable(const std::string& tname); | ||||
|          template<typename userdata_t> userdata_t* newuserdata(); | ||||
|          void* newuserdata(size_t nbytes); | ||||
| 
 | ||||
|          state& gettable(int index = -2); | ||||
|          state& getfield(const std::string& k, int index = -1); | ||||
|          state& settable(int index = -3); | ||||
|          state& setfield(const std::string& k, int index = -2); | ||||
|          state& getmetatable(const std::string& tname); | ||||
|          bool getmetatable(int index); | ||||
| 
 | ||||
|          bool next(int index = -2); | ||||
| 
 | ||||
|          state& getglobal(const std::string& name); | ||||
|          state& setglobal(const std::string& name); | ||||
| 
 | ||||
|          state& loadfile(const std::string& filename); | ||||
|          state& loadstring(const std::string& s); | ||||
| 
 | ||||
|          template<typename iterator_t> state& load(iterator_t begin, iterator_t end); | ||||
| 
 | ||||
|          size_t objlen(int index = -1); | ||||
| 
 | ||||
|       private: | ||||
|          lua_State* L; | ||||
|          bool managed; | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|          int throw_error(int code); | ||||
|    }; | ||||
| 
 | ||||
|    // template functions
 | ||||
| 
 | ||||
|    /** Push a number onto the stack.
 | ||||
|     * @tparam T the numeric type to push (should be automatically determined, | ||||
|     * if there is no specialization for the desired type, lua_pushnumber() will | ||||
|     * be used, and may fail) | ||||
|     * @param number the number to push | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    template<typename T> | ||||
|    state& state::push(T number) { | ||||
|       lua_pushnumber(L, number); | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Push a light userdatum on to the stack.
 | ||||
|     * @tparam T the type of data to push (should be automatically determined) | ||||
|     * @param p the pointer to push | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    template<typename T> | ||||
|    state& state::pushlightuserdata(T p) { | ||||
|       lua_pushlightuserdata(L, p); | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Check if the given index is of the given type (defaults to using
 | ||||
|     * lua_isnumber()). | ||||
|     * @tparam T the type to check for (the default, if no specializations | ||||
|     * match, does lua_isnumber()) | ||||
|     * @param index the index to check | ||||
|     * @note the default version (used if no specialization is matched) will | ||||
|     * check if the given value is a number | ||||
|     * @returns whether the value at the given index is a nil | ||||
|     */ | ||||
|    template<typename T> | ||||
|    bool state::is(int index) { | ||||
|       return lua_isnumber(L, index); | ||||
|    } | ||||
| 
 | ||||
|    /** Get the value at index as the given numeric type.
 | ||||
|     * @tparam T they numeric type to static_cast<T>() the numeric value on the | ||||
|     * stack to | ||||
|     * @param number where to store the value | ||||
|     * @param index the index to get | ||||
|     * @note This function does \em not pop the value from the stack. | ||||
|     * @todo Instead of throwing an exception here, we may just return an | ||||
|     * error code. | ||||
|     * @throws lua::bad_conversion if the value on the stack could not be | ||||
|     * converted to the indicated type | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    template<typename T> | ||||
|    state& state::to(T& number, int index) { | ||||
|       if (lua_isnumber(L, index)) | ||||
|          number = static_cast<T>(lua_tonumber(L, index)); | ||||
|       else | ||||
|          throw bad_conversion("Cannot convert non 'number' value to number"); | ||||
| 
 | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Get the value at index as (light) userdata.
 | ||||
|     * @tparam T the type of data pointed to (pointer is returned as | ||||
|     * reinterpret_cast<T>()) | ||||
|     * @param p the pointer to store the value in | ||||
|     * @param index the index to get | ||||
|     * @note This function does \em not pop the value from the stack. | ||||
|     * @todo Instead of throwing an exception here, we may just return an | ||||
|     * error code. | ||||
|     * @throws lua::bad_conversion if the value on the stack could not be | ||||
|     * converted to the indicated type | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    template<typename T> | ||||
|    state& state::touserdata(T& p, int index) { | ||||
|       if (lua_isuserdata(L, index)) | ||||
|          p = reinterpret_cast<T>(lua_touserdata(L, index)); | ||||
|       else | ||||
|          throw bad_conversion("Cannot convert non 'userdata' or 'lightuserdata' value to userdata"); | ||||
| 
 | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Get the value at index as the given type.
 | ||||
|     * @tparam T the type to retrieve the value on the stack as (the default | ||||
|     * template function uses lua_tonumber(), specializations may cause | ||||
|     * different behavior) | ||||
|     * @param default_value this value is returned if the conversion fails | ||||
|     * @param index the index to get | ||||
|     * @note This function does \em not pop the value from the stack. | ||||
|     * @returns the indicated value from the stack or the default value if | ||||
|     * the conversion fails | ||||
|     */ | ||||
|    template<typename T> | ||||
|    T state::as(T default_value, int index) { | ||||
|       if (lua_isnumber(L, index)) | ||||
|          return static_cast<T>(lua_tonumber(L, index)); | ||||
|       else | ||||
|          return default_value; | ||||
|    } | ||||
| 
 | ||||
|    /** Get the value at index as the given type.
 | ||||
|     * @tparam T the expected type of the value | ||||
|     * @param index the index to get | ||||
|     * | ||||
|     * @note This function does \em not pop the value from the stack. | ||||
|     * @note The default version of this function uses lua_tonumber() but | ||||
|     * specializations may cause different behavior. | ||||
|     * | ||||
|     * @todo Instead of throwing an exception here, we may just return an | ||||
|     * error code. | ||||
|     * | ||||
|     * @throws lua::bad_conversion if the value on the stack could not be | ||||
|     * converted to the indicated type | ||||
|     * | ||||
|     * This function will return the value on the stack as the given type.  If | ||||
|     * the value is not of the given type <em>no conversion will be | ||||
|     * performed</em> and lua::bad_conversion will be thrown.  There are some | ||||
|     * exceptions to this rule, for example, numbers will be converted to | ||||
|     * strings and vice-versa (conversion is only performed if the matching | ||||
|     * lua_is*() function returns true).  The state::to() function should be | ||||
|     * used to perform automatic conversion. | ||||
|     * | ||||
|     * @returns the indicated value as the given type if possible | ||||
|     */ | ||||
|    template<typename T> | ||||
|    T state::as(int index) { | ||||
|       if (lua_isnumber(L, index)) | ||||
|          return static_cast<T>(lua_tonumber(L, index)); | ||||
|       else | ||||
|          throw bad_conversion("Cannot convert non 'number' value to number"); | ||||
|    } | ||||
| 
 | ||||
|    /** Create a new userdatum on the stack.
 | ||||
|     * @tparam userdata_t the type of the userdata (will be passed to sizeof()) | ||||
|     * | ||||
|     * This function creates a new userdatum on the stack the size of | ||||
|     * userdata_t and return a pointer to it. | ||||
|     * @returns a pointer to the new userdatum | ||||
|     */ | ||||
|    template<typename userdata_t> | ||||
|    userdata_t* state::newuserdata() { | ||||
|       return reinterpret_cast<userdata_t*>(lua_newuserdata(L, sizeof(userdata_t))); | ||||
|    } | ||||
| 
 | ||||
|    /** Generate a Lua error.
 | ||||
|     * @tparam msg_t the type of error message data (should be automatically | ||||
|     * determined) | ||||
|     * @param message the error message/value | ||||
|     * @note This function is used to raise errors from lua::cfunctions. | ||||
|     * @note This function never returns, instead it throws an exception | ||||
|     * caught by the intepreter. | ||||
|     */ | ||||
|    template<typename msg_t> | ||||
|    void state::error(msg_t message) { | ||||
|       push(message); | ||||
|       lua_error(L); | ||||
|    } | ||||
| 
 | ||||
|    /** Load a sequence of data as a Lua chunk.
 | ||||
|     * @tparam iterator_t the type of iterator to use (should be automatically | ||||
|     * determined) | ||||
|     * @param begin an iterator to the start of the sequence | ||||
|     * @param end an iterator to the end of the sequence (one past the | ||||
|     * end) | ||||
|     * | ||||
|     * This function takes a sequence of data and attempts to convert it | ||||
|     * into a Lua chunk.  The type of data passed must be able to be | ||||
|     * converted into an 8-bit char. | ||||
|     * | ||||
|     * @note This function should automatically detect if the data is text | ||||
|     * or binary. | ||||
|     * | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    template<typename iterator_t> | ||||
|    state& state::load(iterator_t begin, iterator_t end) { | ||||
|       // convert the data to characters
 | ||||
|       std::vector<char> chunk(begin, end); | ||||
| 
 | ||||
|       // Here we use the address of the first element of our vector.
 | ||||
|       // This works because the data in std::vectors is contiguous.
 | ||||
|       throw_error(luaL_loadbuffer(L, &(*chunk.begin()), chunk.size(), NULL)); | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
| 
 | ||||
|    // template specializations
 | ||||
|    template<> state& state::to(bool& boolean, int index); | ||||
|    template<> state& state::to(std::string& string, int index); | ||||
| 
 | ||||
|    template<> bool state::as(bool default_value, int index); | ||||
|    template<> std::string state::as(std::string default_value, int index); | ||||
|    template<> bool state::as(int index); | ||||
|    template<> std::string state::as(int index); | ||||
| 
 | ||||
|    template<> bool state::is<nil>(int index); | ||||
|    template<> bool state::is<bool>(int index); | ||||
|    template<> bool state::is<std::string>(int index); | ||||
|    template<> bool state::is<table>(int index); | ||||
|    template<> bool state::is<cfunction>(int index); | ||||
|    template<> bool state::is<function>(int index); | ||||
|    template<> bool state::is<userdata>(int index); | ||||
|    template<> bool state::is<lightuserdata>(int index); | ||||
| 
 | ||||
| 
 | ||||
|    // inline functions
 | ||||
| 
 | ||||
|    /** Convert a lua::state to a lua_State*.
 | ||||
|     * This operator allows lua::state to behave like a lua_State | ||||
|     * pointer. | ||||
|     * | ||||
|     * @note This should be used as a last result to interoperate with C | ||||
|     * code.  This may be removed in future versions of Luaxx. | ||||
|     */ | ||||
|    inline state::operator lua_State*() { | ||||
|       return L; | ||||
|    } | ||||
| 
 | ||||
|    /** Throws exceptions for error return codes.
 | ||||
|     * @param code the return code | ||||
|     * | ||||
|     * This function throws an exception based on the error it was passed. | ||||
|     * If it is passed a 0 it will not throw anything. | ||||
|     * | ||||
|     * @todo In the future this function may check an exception mask | ||||
|     * before throwing an error. | ||||
|     * | ||||
|     * @returns the code it was passed | ||||
|     */ | ||||
|    inline int state::throw_error(int code) { | ||||
|       std::string error; | ||||
| 
 | ||||
|       // below, we package lua errors into exceptions
 | ||||
|       switch (code) { | ||||
|          case 0: | ||||
|             break; | ||||
|          case LUA_ERRSYNTAX: | ||||
|             to(error).pop(); | ||||
|             throw syntax_error(error.c_str()); | ||||
|          case LUA_ERRMEM: | ||||
|             to(error).pop(); | ||||
|             throw bad_alloc(error.c_str()); | ||||
|          case LUA_ERRRUN: | ||||
|             to(error).pop(); | ||||
|             throw runtime_error(error.c_str()); | ||||
|          case LUA_ERRFILE: | ||||
|             to(error).pop(); | ||||
|             throw file_error(error.c_str()); | ||||
|          default: | ||||
|             to(error).pop(); | ||||
|             throw exception(error.c_str()); | ||||
|       } | ||||
|       return code; | ||||
|    } | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
| @ -1,360 +0,0 @@ | ||||
| #ifndef LUNE_H | ||||
| #define LUNE_H | ||||
| 
 | ||||
| 
 | ||||
| #include "lua.h" | ||||
| #include "lauxlib.h" | ||||
| #include "lualib.h" | ||||
| 
 | ||||
| 
 | ||||
| #include "luaxx.hpp" | ||||
| #include <string> | ||||
| 
 | ||||
| namespace lua | ||||
| { | ||||
|     class object | ||||
|     { | ||||
|         state &myst; | ||||
|         int myref; | ||||
|     public: | ||||
|         object(state &myst):myst(myst) | ||||
|         { | ||||
|             myref=luaL_ref(myst,LUA_REGISTRYINDEX); | ||||
|         } | ||||
|         ~object() | ||||
|         { | ||||
|             luaL_unref(myst,LUA_REGISTRYINDEX,myref); | ||||
|         } | ||||
|         void Get() | ||||
|         { | ||||
|             lua_rawgeti(myst,LUA_REGISTRYINDEX,myref); | ||||
|         } | ||||
|         state &GetState(){return myst;}; | ||||
|     }; | ||||
| 
 | ||||
|     class local_object | ||||
|     { | ||||
|         state myst; | ||||
|         int myref; | ||||
|         static object *mytbl; | ||||
|     public: | ||||
|         local_object(lua_State *L) | ||||
|         { | ||||
| 
 | ||||
|             myst=state(L); | ||||
|             //LOG<<"Creating local object...\n";
 | ||||
|             //StackDump(L);
 | ||||
|             if(!mytbl) | ||||
|             { | ||||
|                 //LOG<<" Metable...\n";
 | ||||
|                 myst.newtable(); //2
 | ||||
|                 if(myst.newmetatable("WEAKTABLE"))//3
 | ||||
|                 { | ||||
|                     //StackDump(L);
 | ||||
|                     myst.push("kv"); //4
 | ||||
|                     myst.setfield("__mode");//3
 | ||||
|                     //LOG<<" Setting Metable...\n";
 | ||||
|                     //StackDump(L);
 | ||||
|                 } | ||||
|                 //LOG<<" Attaching to holder...\n";
 | ||||
| 
 | ||||
|                 //myst.setfield("__metatable");//2
 | ||||
|                 lua_setmetatable(myst,-1); | ||||
|                 mytbl=new object(myst); | ||||
|                 //StackDump(L);
 | ||||
|                 //LOG<<" Done Metatable...\n";
 | ||||
|             } | ||||
|             //StackDump(L);
 | ||||
|             mytbl->Get(); | ||||
|             //LOG<<" Got my table...\n";
 | ||||
|             //StackDump(L);
 | ||||
|             myst.insert(-2); | ||||
|             myref=luaL_ref(myst,-2); | ||||
|             //LOG<<"Before pop:";
 | ||||
|             //StackDump(L);
 | ||||
|             myst.pop(1); | ||||
|             GetTable(); | ||||
|             //LOG<<"========Done...\n"<<"Ref="<<myref<<"\n";
 | ||||
|             //mytbl->Get();
 | ||||
|             //StackDump(L);
 | ||||
|             //LOG<<"===========================\n";
 | ||||
|         } | ||||
|         ~local_object() | ||||
|         { | ||||
|             //LOG<<"Deleting local object...\n";
 | ||||
|             ReleaseTable(); | ||||
|         } | ||||
|         void ReleaseTable() | ||||
|         { | ||||
|             mytbl->Get(); | ||||
|             int pos=myst.gettop(); | ||||
|             luaL_unref(myst,pos,myref); | ||||
|             myst.remove(pos); | ||||
|         } | ||||
|         state GetState(){return myst;} | ||||
|         void GetTable() | ||||
|         { | ||||
|             //LOG<<"Getting ref="<<myref<<"\n";
 | ||||
|             //StackDump(myst);
 | ||||
|             //LOG<<"Tbl preget\n";
 | ||||
|             mytbl->Get(); | ||||
|             int pos=myst.gettop(); | ||||
|             //StackDump(myst);
 | ||||
|             //LOG<<"Tbl get\n";
 | ||||
|             //int pos=myst.gettop();
 | ||||
|             lua_rawgeti(myst,pos,myref); | ||||
|             //StackDump(myst);
 | ||||
|             //LOG<<"Done\n";
 | ||||
|             myst.remove(pos); | ||||
|         } | ||||
|     protected: | ||||
| 
 | ||||
|     }; | ||||
| }; | ||||
| 
 | ||||
| template <typename T,bool GC=true> | ||||
| class Lune | ||||
| { | ||||
| public: | ||||
|     typedef struct | ||||
|     { | ||||
|         T *pT; | ||||
|         int tableref; | ||||
|     } userdataType; | ||||
| 
 | ||||
|     typedef int (T::*mfp)(lua_State *L); | ||||
|     typedef struct | ||||
|     { | ||||
|         const char *name; | ||||
|         mfp mfunc; | ||||
|     } RegType; | ||||
| 
 | ||||
|     static void Register(lua_State *L) | ||||
|     { | ||||
|         lua_newtable(L); | ||||
|         int methods = lua_gettop(L); | ||||
| 
 | ||||
|         luaL_newmetatable(L, T::className); | ||||
|         int metatable = lua_gettop(L); | ||||
| 
 | ||||
|         // store method table in globals so that
 | ||||
|         // scripts can add functions written in Lua.
 | ||||
|         lua_pushvalue(L, methods); | ||||
|         lua_setglobal(L, T::className); | ||||
| 
 | ||||
|         lua_pushliteral(L, "__metatable"); | ||||
|         lua_pushvalue(L, methods); | ||||
|         lua_settable(L, metatable);  // hide metatable from Lua getmetatable()
 | ||||
| 
 | ||||
|         lua_pushliteral(L, "__index"); | ||||
|         lua_pushcfunction(L, index_T); | ||||
|         lua_settable(L, metatable); | ||||
| 
 | ||||
|         //lua_pushliteral(L, "__name");
 | ||||
|         //lua_pushstring(L, T::className);
 | ||||
|         //lua_settable(L, metatable);
 | ||||
| 
 | ||||
|         lua_pushliteral(L, "__newindex"); | ||||
|         lua_pushcfunction(L, newindex_T); | ||||
|         lua_settable(L, metatable); | ||||
| 
 | ||||
|         lua_pushliteral(L, "__instances"); | ||||
|         lua_newtable(L); | ||||
|         lua_settable(L, metatable); | ||||
|         if(GC) | ||||
|         { | ||||
|             lua_pushliteral(L, "__gc"); | ||||
|             lua_pushcfunction(L, gc_T); | ||||
|             lua_settable(L, metatable); | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         lua_newtable(L);                // metatable for method table
 | ||||
|         int mt = lua_gettop(L); | ||||
|         lua_pushliteral(L, "__call"); | ||||
|         lua_pushcfunction(L, new_T); | ||||
|         lua_pushliteral(L, "new"); | ||||
|         lua_pushvalue(L, -2);           // dup new_T function
 | ||||
|         lua_settable(L, methods);       // add new_T to method table
 | ||||
|         lua_settable(L, mt);            // mt.__call = new_T
 | ||||
|         lua_setmetatable(L, methods); | ||||
|         //LOG<<"lune: registered class \""<<T::className<<"\"\n";
 | ||||
|         // fill method table with methods from class T
 | ||||
|         for (RegType *l = T::methods; l->name; l++) | ||||
|         { | ||||
|             /* edited by Snaily: shouldn't it be const RegType *l ... ? */ | ||||
|             lua_pushstring(L, l->name); | ||||
|             lua_pushlightuserdata(L, (void*)l); | ||||
|             lua_pushcclosure(L, thunk, 1); | ||||
|             lua_settable(L, methods); | ||||
|             //LOG<<"lune:    method \""<<l->name<<"\"\n";
 | ||||
|         } | ||||
| 
 | ||||
|         lua_pop(L, 2);  // drop metatable and method table
 | ||||
|     }; | ||||
|     static void GetTable(lua_State *L,T *p) | ||||
|     { | ||||
|         GetTableEx(L,p->GetTableId()); | ||||
|     } | ||||
|     static void GetTableEx(lua_State *L,int id) | ||||
|     { | ||||
|         lua::state s(L); | ||||
|         s.getmetatable(T::className); | ||||
|         s.getfield("__instances"); | ||||
|         int ins=s.gettop(); | ||||
|         lua_rawgeti(L, ins, id); | ||||
|         s.insert(-3); | ||||
|         s.pop(2); | ||||
|     } | ||||
|     static T *check(lua_State *L, int narg) | ||||
|     { | ||||
|         userdataType *ud = | ||||
|             static_cast<userdataType*>(luaL_checkudata(L, narg, T::className)); //TODO FIX THIs..
 | ||||
|         //(lua_touserdata(L, narg));//
 | ||||
|         if(!ud) luaL_error(L, "Bad argument %d: expected type %s", narg, T::className); | ||||
|         return ud->pT;  // pointer to T object
 | ||||
|     } | ||||
| protected: | ||||
| private: | ||||
| 
 | ||||
|     static int RegTable(lua_State *L) | ||||
|     { | ||||
|        // LOG<<"Regging....\n";
 | ||||
|         //lua::StackDump(L);
 | ||||
| 
 | ||||
|         lua::state s(L); | ||||
|         int ssize=s.gettop(); | ||||
|         //s.getglobal(T::className);
 | ||||
|         s.getmetatable(T::className); | ||||
|         s.getfield("__instances"); | ||||
|         int ins=s.gettop(); | ||||
|         s.newtable(); | ||||
|         int id=luaL_ref(L,ins); | ||||
|         //LOG<<"After reg:\n";
 | ||||
|         //lua::StackDump(L);
 | ||||
|         s.settop(ssize); | ||||
|         return id; | ||||
|     } | ||||
|     static void UnregTable(lua_State *L,int id) | ||||
|     { | ||||
|         lua::state s(L); | ||||
|         s.getmetatable(T::className); | ||||
|         s.getfield("__instances"); | ||||
|         int ins=s.gettop(); | ||||
|         //LOG<<"Unreg table id:"<<id<<"stack dump:\n";
 | ||||
|         //lua::StackDump(L);
 | ||||
|         luaL_unref(L,ins,id); | ||||
|     } | ||||
|     static int index_T(lua_State *L)  // calls with (table, key), return value
 | ||||
|     { | ||||
|         lua::state st(L); | ||||
|         std::string key=st.as<std::string>(-1); | ||||
|         T *p=check(L,1); | ||||
|         GetTable(L,p); | ||||
|         st.insert(-2); | ||||
|         //LOG<<"Index:\n";
 | ||||
|         //lua::StackDump(L);
 | ||||
|         lua_rawget(L,-2); //try getting from normal table
 | ||||
|         if(st.is<lua::nil>()) //failed
 | ||||
|         { | ||||
|             st.pop(2); | ||||
|             st.getglobal(T::className); //try class tables then
 | ||||
|             st.push(key); | ||||
|             st.gettable(); | ||||
|         } | ||||
|         return 1; | ||||
|     } | ||||
|     static int newindex_T(lua_State *L) | ||||
|     { | ||||
|         //LOG<<"New index....\n";
 | ||||
|         //lua::StackDump(L);
 | ||||
| 
 | ||||
|         lua::state st(L); | ||||
|         T *p=check(L,1); | ||||
|         GetTable(L,p); | ||||
|         //st.insert(-3);
 | ||||
|         //LOG<<"Before set:\n";
 | ||||
|         st.insert(-3); | ||||
|         //lua::StackDump(L);
 | ||||
|         lua_rawset(L,-3); | ||||
|         return 0; | ||||
|     } | ||||
|     static int thunk(lua_State *L) | ||||
|     { | ||||
|         //LOG<<"Size of stack:"<<lua_gettop(L)<<"\n";
 | ||||
|         //lua::StackDump(L);
 | ||||
|         if(lua_gettop(L)<1) | ||||
|             luaL_error(L,"Member function called without 'self'"); | ||||
|         //LOG<<"Size of stack after:"<<lua_gettop(L)<<"\n";
 | ||||
|         // stack has userdata, followed by method args
 | ||||
|         T *obj = check(L, 1);  // get 'self', or if you prefer, 'this'
 | ||||
|         //T *obj=static_cast<userdataType*>(lua_touserdata(L,1))->pT;
 | ||||
|         lua_remove(L, 1);  // remove self so member function args start at index 1
 | ||||
|         // get member function from upvalue
 | ||||
|         RegType *l = static_cast<RegType*>(lua_touserdata(L, lua_upvalueindex(1))); | ||||
|         return (obj->*(l->mfunc))(L);  // call member function
 | ||||
|     } | ||||
|     static int gc_T(lua_State *L) | ||||
|     { | ||||
|         //lua_getfield(L,,"__ud");
 | ||||
|         //LOG<<"Garbage collecting.\n";
 | ||||
|         //lua::StackDump(L);
 | ||||
|         userdataType *ud = static_cast<userdataType*>(lua_touserdata(L, 1)); | ||||
|         T *obj = ud->pT; | ||||
| 
 | ||||
|         delete obj;  // call destructor for T objects
 | ||||
|         UnregTable(L,ud->tableref); | ||||
|         return 0; | ||||
|     } | ||||
|     static int new_T(lua_State *L) | ||||
|     { | ||||
|         //LOG<<"Pre build:"<<lua_gettop(L)<<"\n";
 | ||||
|         //lua::StackDump(L);
 | ||||
|         lua_remove(L, 1);   // use classname:new(), instead of classname.new()
 | ||||
|         //lua_newtable(L);
 | ||||
|         int id=RegTable(L); | ||||
|         //LOG<<"Registred as:"<<id<<"\n";
 | ||||
|         //int ssize=lua_gettop(L);
 | ||||
|         T *obj = new T(L,id);  // call constructor for T objects
 | ||||
|         lua_settop(L,0); //no need for parameters later.
 | ||||
|         //LOG<<"Post build:"<<lua_gettop(L)<<"\t";
 | ||||
|         //lua::StackDump(L);
 | ||||
|         //LOG<<"TSOP\n";
 | ||||
| 
 | ||||
|         userdataType *ud = | ||||
|             static_cast<userdataType*>(lua_newuserdata(L, sizeof(userdataType))); | ||||
|         //lua::StackDump(L);
 | ||||
|         luaL_getmetatable(L, T::className);  // lookup metatable in Lua registry
 | ||||
|         lua_setmetatable(L,-2); | ||||
|         //LOG<<"metatable set\n";
 | ||||
| 
 | ||||
|         //lua::StackDump(L);
 | ||||
|         GetTable(L,obj); | ||||
|         lua_pushliteral(L,"__obj"); | ||||
|         lua_pushvalue(L,-3); | ||||
|         lua_settable(L,-3); | ||||
|         lua_pop(L,1); | ||||
|         //LOG<<"Object referenced\n";
 | ||||
|         //lua::StackDump(L);
 | ||||
|         //T *p = new(ud) T(L);  // call constructor for T objects
 | ||||
|         //lua::StackDump(L);
 | ||||
|         ud->pT = obj;  // store pointer to object in userdata
 | ||||
|         ud->tableref=id; | ||||
|         //luaL_getmetatable(L, T::className);  // lookup metatable in Lua registry
 | ||||
|         //lua_setmetatable(L, tableindex);
 | ||||
|         //lua::StackDump(L);
 | ||||
|         //LOG<<"Push done\n";
 | ||||
|         return 1;  // userdata containing pointer to T object
 | ||||
|     } | ||||
|     Lune() {}; //non constructable...
 | ||||
| }; | ||||
| #define method(class, name) {#name, &class::name} | ||||
| #define DEF_LUNE(class) static const char className[];\ | ||||
|                          static Lune<class>::RegType methods[]; | ||||
| #define DEF_LUNE_NOGC(class) static const char className[];\ | ||||
|                          static Lune<class,false>::RegType methods[]; | ||||
| #define IMP_LUNE(class,lua_name) const char class::className[]=#lua_name; | ||||
| #define LUNE_METHODS_START(class) Lune<class>::RegType class::methods[] = { | ||||
| #define LUNE_METHODS_START_NOGC(class) Lune<class,false>::RegType class::methods[] = { | ||||
| #define LUNE_METHODS_END() {0,0}} | ||||
| #endif // LUNE_H
 | ||||
| @ -1,12 +0,0 @@ | ||||
| Dfusion plugin offers four DFhack commands: 'dfusion', 'dfuse' and 'lua', 'runlua'. | ||||
| lua: | ||||
| Runs an interactive lua console. For more on lua commands see [http://www.lua.org/manual/5.1/manual.html Lua reference manual] or google "lua". Also this command could be ran with filepath as an argument. Then it runs that file as a lua script file. E.g. ''lua dfusion/temp.lua'' runs a file  <your df path>/dfusion/temp.lua. | ||||
| runlua: | ||||
| Similar to ''lua <filename>'' but not interactive, to be used with hotkeys | ||||
| dfusion: | ||||
| First this command runs all plugins' init.lua part then show a menu. Type number to run specified plugin. | ||||
| dfuse: | ||||
| Similar to dfusion but not interactive. To be used with hotkeys (later will have command support). | ||||
| 
 | ||||
| Also dfuse/dfusion runs an init script located at 'save directory/dfusion/init.lua'. And 'initcustom.lua' if it exists | ||||
| More info http://dwarffortresswiki.org/index.php/Utility:DFusion | ||||
| @ -1,102 +0,0 @@ | ||||
| #include "OutFile.h" | ||||
| #include <stdexcept> | ||||
| using namespace OutFile; | ||||
| File::File(std::string path) | ||||
| { | ||||
|     //mystream.exceptions ( std::fstream::eofbit | std::fstream::failbit | std::fstream::badbit );
 | ||||
|     mystream.open(path.c_str(),std::fstream::binary|std::ios::in|std::ios::out); | ||||
| 
 | ||||
| 
 | ||||
|     if(mystream) | ||||
|     { | ||||
|         mystream.read((char*)&myhead,sizeof(myhead)); | ||||
|         for(unsigned i=0;i<myhead.sectioncount;i++) | ||||
|         { | ||||
|             Section x; | ||||
|             mystream.read((char*)&x,sizeof(Section)); | ||||
|             sections[x.name]=x; | ||||
|         } | ||||
|         //std::cout<<"Sizeof:"<<sizeof(Section)<<"\n";
 | ||||
|       /*myhead.PrintData();
 | ||||
|       for(auto it=sections.begin();it!=sections.end();it++) | ||||
|       { | ||||
|           it->second.PrintData(); | ||||
|       }*/ | ||||
| 
 | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         throw std::runtime_error("Error opening file!"); | ||||
|     } | ||||
| } | ||||
| Section &File::GetSection(std::string name) | ||||
| { | ||||
|     return sections[name]; | ||||
| } | ||||
| void File::GetText(char *ptr) | ||||
| { | ||||
|     Section &s=GetSection(".text"); | ||||
|     mystream.seekg(s.start); | ||||
| 
 | ||||
|     mystream.read(ptr,s.size); | ||||
| } | ||||
| size_t File::GetTextSize() | ||||
| { | ||||
|     Section &s=GetSection(".text"); | ||||
|     return s.size; | ||||
| } | ||||
| void File::PrintRelocations() | ||||
| { | ||||
|     for(auto it=sections.begin();it!=sections.end();it++) | ||||
|       { | ||||
|           std::cout<<it->first<<":\n"; | ||||
|           for(unsigned i=0;i<it->second.numRel;i++) | ||||
|           { | ||||
|               Relocation r; | ||||
|               mystream.seekg(it->second.ptrRel+10*i); | ||||
|               mystream.read((char*)&r,10); | ||||
|               std::cout<<r.ptr<<" -- "<<r.tblIndex<<":"<</*symbols[r.tblIndex].name<<*/" type:"<<r.type<<"\n"; | ||||
|           } | ||||
|       } | ||||
| } | ||||
| void File::PrintSymbols() | ||||
| { | ||||
| 
 | ||||
|     std::cout<<"Sizeof symbol:"<<sizeof(Symbol)<<std::endl; | ||||
|     std::cout<<"Symbol count:"<<myhead.symbolcount<<std::endl; | ||||
|     for(unsigned i=0;i<myhead.symbolcount;i++) | ||||
|     { | ||||
|         mystream.seekg(myhead.symbolptr+i*18); | ||||
|         Symbol s; | ||||
|         std::cout<<i<<"\t"; | ||||
|         s.Read(mystream,myhead.symbolptr+18*myhead.symbolcount); | ||||
| 
 | ||||
|         //mystream.read((char*)&s,sizeof(Symbol));
 | ||||
|         s.PrintData(); | ||||
|         symbols.push_back(s); | ||||
|         if(s.auxsymbs>0) | ||||
|         { | ||||
|             i+=s.auxsymbs; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| void File::LoadSymbols() | ||||
| { | ||||
|     symbols.clear(); | ||||
|     for(unsigned i=0;i<myhead.symbolcount;i++) | ||||
|     { | ||||
|         mystream.seekg(myhead.symbolptr+i*18); | ||||
|         Symbol s; | ||||
|         s.Read(mystream,myhead.symbolptr+18*myhead.symbolcount); | ||||
|         symbols.push_back(s); | ||||
|         if(s.auxsymbs>0) | ||||
|         { | ||||
|             i+=s.auxsymbs; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| File::~File() | ||||
| { | ||||
| 
 | ||||
| } | ||||
| @ -1,116 +0,0 @@ | ||||
| #include "hexsearch.h" | ||||
| 
 | ||||
| 
 | ||||
| Hexsearch::Hexsearch(const SearchArgType &args,char * startpos,char * endpos):args_(args),pos_(startpos),startpos_(startpos),endpos_(endpos) | ||||
| { | ||||
|     ReparseArgs(); | ||||
| } | ||||
| Hexsearch::~Hexsearch() | ||||
| { | ||||
| 
 | ||||
| } | ||||
| inline bool Hexsearch::Compare(int a,int b) | ||||
| { | ||||
|     if(b==Hexsearch::ANYBYTE) | ||||
|         return true; | ||||
|     if(a==b) | ||||
|         return true; | ||||
|     return false; | ||||
| } | ||||
| void Hexsearch::ReparseArgs() | ||||
| { | ||||
|     union | ||||
|     { | ||||
|         uint32_t val; | ||||
|         uint8_t bytes[4]; | ||||
|     }B; | ||||
|     SearchArgType targ; | ||||
|     targ=args_; | ||||
|     args_.clear(); | ||||
|     for(size_t i=0;i<targ.size();) | ||||
|     { | ||||
|         if(targ[i]==DWORD_) | ||||
|         { | ||||
|             i++; | ||||
|             B.val=targ[i]; | ||||
|             for(int j=0;j<4;j++) | ||||
|             { | ||||
|                 args_.push_back(B.bytes[j]); | ||||
|             } | ||||
|             i++; | ||||
|         } | ||||
|         else if (targ[i]==ANYDWORD) | ||||
|         { | ||||
|             i++; | ||||
|             for(int j=0;j<4;j++) | ||||
|                 args_.push_back(ANYBYTE); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             args_.push_back(targ[i]); | ||||
|             i++; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| void * Hexsearch::FindNext() //TODO rewrite using Boyer-Moore algorithm
 | ||||
| { | ||||
|     DFHack::Core &inst=DFHack::Core::getInstance(); | ||||
|     DFHack::Process *p=inst.p; | ||||
|     uint8_t *buf; | ||||
|     buf=new uint8_t[args_.size()]; | ||||
|     while(pos_<endpos_) | ||||
|     { | ||||
|         bool found=true; | ||||
|         p->readByte(pos_,buf[0]); | ||||
|         if(Compare(buf[0],args_[0])) | ||||
|         { | ||||
|             p->read(pos_,args_.size(),buf); | ||||
|             for(size_t i=0;i<args_.size();i++) | ||||
|             { | ||||
|                 if(!Compare(buf[i],args_[i])) | ||||
|                 { | ||||
|                     pos_+=i; | ||||
|                     found=false; | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
|             if(found) | ||||
|             { | ||||
|                 pos_+=args_.size(); | ||||
|                 delete [] buf; | ||||
|                 return pos_-args_.size(); | ||||
|             } | ||||
|         } | ||||
|         pos_ = pos_ + 1; | ||||
|     } | ||||
|     delete [] buf; | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| std::vector<void *> Hexsearch::FindAll() | ||||
| { | ||||
|     std::vector<void *> ret; | ||||
|     void * cpos=pos_; | ||||
|     while(cpos!=0) | ||||
|     { | ||||
|         cpos=FindNext(); | ||||
|         if(cpos!=0) | ||||
|             ret.push_back(cpos); | ||||
|     } | ||||
|     return ret; | ||||
| } | ||||
| void Hexsearch::PrepareBadCharShift() | ||||
| { | ||||
|     BadCharShifts.resize(256,-1); | ||||
|     int i=0; | ||||
|     for(SearchArgType::reverse_iterator it=args_.rbegin();it!=args_.rend();it++) | ||||
|     { | ||||
|         BadCharShifts[*it]=i; | ||||
|         i++; | ||||
|     } | ||||
| } | ||||
| void Hexsearch::PrepareGoodSuffixTable() | ||||
| { | ||||
|     GoodSuffixShift.resize(args_.size()+1,0); | ||||
| 
 | ||||
| } | ||||
| @ -1,61 +0,0 @@ | ||||
| #include "lua_Hexsearch.h" | ||||
| int lua::Hexsearch::find(lua_State *L) | ||||
| { | ||||
|     lua::state st(L); | ||||
|     void * pos=p->FindNext(); | ||||
|     st.push(reinterpret_cast<size_t>(pos)); | ||||
|     return 1; | ||||
| } | ||||
| int lua::Hexsearch::findall(lua_State *L) | ||||
| { | ||||
|     lua::state st(L); | ||||
|     std::vector<void *> pos=p->FindAll(); | ||||
|     st.newtable(); | ||||
|     for(unsigned i=0;i<pos.size();i++) | ||||
|     { | ||||
|         st.push(i+1); | ||||
|         st.push(reinterpret_cast<size_t>(pos[i])); | ||||
|         st.settable(); | ||||
|     } | ||||
|     return 1; | ||||
| } | ||||
| lua::Hexsearch::Hexsearch(lua_State *L,int id):tblid(id) | ||||
| { | ||||
|     lua::state st(L); | ||||
|     char * start,* end; | ||||
|     ::Hexsearch::SearchArgType args; | ||||
|     start= (char *)st.as<uint32_t>(1); | ||||
|     end=(char *)st.as<uint32_t>(2); | ||||
|     for(int i=3;i<=st.gettop();i++) | ||||
|     { | ||||
|         args.push_back(st.as<int>(i)); | ||||
|     } | ||||
|     p=new ::Hexsearch(args,start,end); | ||||
| } | ||||
| lua::Hexsearch::~Hexsearch() | ||||
| { | ||||
|     delete p; | ||||
| } | ||||
| int lua::Hexsearch::reset(lua_State *L) | ||||
| { | ||||
|     lua::state st(L); | ||||
|     p->Reset(); | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| IMP_LUNE(lua::Hexsearch,hexsearch); | ||||
| LUNE_METHODS_START(lua::Hexsearch) | ||||
|     method(lua::Hexsearch,find), | ||||
|     method(lua::Hexsearch,findall), | ||||
|     method(lua::Hexsearch,reset), | ||||
| LUNE_METHODS_END(); | ||||
| #define __ADDCONST(name) st.push(::Hexsearch::  name); st.setglobal(#name) | ||||
| void lua::RegisterHexsearch(lua::state &st) | ||||
| { | ||||
| 
 | ||||
|     Lune<lua::Hexsearch>::Register(st); | ||||
|     __ADDCONST(ANYBYTE); | ||||
|     __ADDCONST(ANYDWORD); | ||||
|     __ADDCONST(DWORD_); | ||||
| } | ||||
| #undef __ADDCONST | ||||
| @ -1,154 +0,0 @@ | ||||
| #include "lua_Misc.h" | ||||
| uint32_t lua::PlugManager::AddNewPlug(std::string name,uint32_t size,uint32_t loc) | ||||
| { | ||||
|     void *p; | ||||
|     if(size!=0) | ||||
|         p=new unsigned char[size]; | ||||
|     else | ||||
|         p=(void*)loc; | ||||
|     plugs[name]=p; | ||||
|     return (uint32_t)p; | ||||
| } | ||||
| uint32_t lua::PlugManager::FindPlugin(std::string name) | ||||
| { | ||||
|     mapPlugs::iterator it=plugs.find(name); | ||||
|     if(it!=plugs.end()) | ||||
|         return (uint32_t)it->second; | ||||
|     else | ||||
|         return 0; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| static int LoadMod(lua_State *L) | ||||
| { | ||||
|     lua::state st(L); | ||||
|     std::string modfile=st.as<std::string>(1); | ||||
|     std::string modname=st.as<std::string>(2); | ||||
|     uint32_t size_add=st.as<uint32_t>(0,3); | ||||
|     OutFile::File f(modfile); | ||||
|     uint32_t size=f.GetTextSize(); | ||||
|     uint32_t pos=lua::PlugManager::GetInst().AddNewPlug(modname,size+size_add); | ||||
|     char *buf; | ||||
|     buf=new char[size]; | ||||
|     f.GetText(buf); | ||||
|     //std::cout<<"poking @:"<<std::hex<<pos<<"size :"<<size<<std::endl;
 | ||||
|     DFHack::Core::getInstance().p->write((void *) pos,size,(uint8_t*)buf); | ||||
|     delete [] buf; | ||||
|     st.push(pos); | ||||
|     st.push(size); | ||||
|     return 2; | ||||
| } | ||||
| static int LoadObj(lua_State *L) | ||||
| { | ||||
|     lua::state st(L); | ||||
|     std::string modfile=st.as<std::string>(1); | ||||
|     OutFile::File f(modfile); | ||||
|     size_t s=f.GetTextSize(); | ||||
|     void *p=st.newuserdata(s); //TODO does it leak memory??
 | ||||
|     f.GetText((char*)p); | ||||
|     st.push(s); | ||||
|     return 2; | ||||
| } | ||||
| static int FindMarker(lua_State *L) // marker, void ptr, size, start
 | ||||
| { | ||||
|     lua::state st(L); | ||||
|     union | ||||
|     { | ||||
|         unsigned char bytes[4]; | ||||
|         size_t mark; | ||||
|     }M; | ||||
|     M.mark=st.as<size_t>(1); | ||||
|     unsigned char *p=(unsigned char *)lua_touserdata(L, 2);//st.as<lua::userdata>(2);
 | ||||
|     size_t size=st.as<size_t>(3); | ||||
|     size_t start=st.as<size_t>(4); | ||||
|     for(size_t i=start;i<size;i++) | ||||
|     { | ||||
|         bool ok; | ||||
|         ok=true; | ||||
|         if(p[i]==M.bytes[0]) | ||||
|         { | ||||
|             for(size_t j=0;j<4;j++) | ||||
|             { | ||||
|                 if(p[i+j]!=M.bytes[j]) | ||||
|                 { | ||||
|                     ok=false; | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
|             if(ok) | ||||
|             { | ||||
|                 st.push(i); | ||||
|                 return 1; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     return 0; | ||||
| } | ||||
| static int LoadObjSymbols(lua_State *L) | ||||
| { | ||||
|     lua::state st(L); | ||||
|     std::string modfile=st.as<std::string>(1); | ||||
|     OutFile::File f(modfile); | ||||
|     OutFile::vSymbol vec=f.GetSymbols(); | ||||
|     OutFile::Symbol S; | ||||
| 
 | ||||
|     st.newtable(); | ||||
|     for(size_t i=0;i<vec.size();i++) | ||||
|     { | ||||
|         st.push(i); | ||||
|         S=vec[i]; | ||||
|         st.newtable(); | ||||
|         st.push(S.name); | ||||
|         st.setfield("name"); | ||||
|         st.push(S.pos); | ||||
|         st.setfield("pos"); | ||||
|         st.settable(); | ||||
|     } | ||||
| 
 | ||||
|     return 1; | ||||
| } | ||||
| static int NewMod(lua_State *L) | ||||
| { | ||||
|     lua::state st(L); | ||||
|     std::string modname=st.as<std::string>(1); | ||||
|     size_t size=st.as<size_t>(2); | ||||
|     size_t loc=st.as<size_t>(3,0); | ||||
|     uint32_t pos=lua::PlugManager::GetInst().AddNewPlug(modname,size,loc); | ||||
|     st.push(pos); | ||||
|     return 1; | ||||
| } | ||||
| static int GetMod(lua_State *L) | ||||
| { | ||||
|     lua::state st(L); | ||||
|     std::string modname=st.as<std::string>(1); | ||||
|     uint32_t pos=lua::PlugManager::GetInst().FindPlugin(modname); | ||||
|     if(pos==0) | ||||
|         st.push(); | ||||
|     else | ||||
|         st.push(pos); | ||||
|     return 1; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| const luaL_Reg lua_misc_func[]= | ||||
| { | ||||
|     {"loadmod",LoadMod}, | ||||
|     {"getmod",GetMod}, | ||||
|     {"loadobj",LoadObj}, | ||||
|     {"loadobjsymbols",LoadObjSymbols}, | ||||
|     {"findmarker",FindMarker}, | ||||
|     {"newmod",NewMod}, | ||||
|     {NULL,NULL} | ||||
| }; | ||||
| void lua::RegisterMisc(lua::state &st) | ||||
| { | ||||
|     st.getglobal("engine"); | ||||
|     if(st.is<lua::nil>()) | ||||
|     { | ||||
|         st.pop(); | ||||
|         st.newtable(); | ||||
|     } | ||||
|     lua::RegFunctionsLocal(st, lua_misc_func); | ||||
|     st.setglobal("engine"); | ||||
| } | ||||
| @ -1,269 +0,0 @@ | ||||
| #include "lua_Process.h" | ||||
| 
 | ||||
| static DFHack::Process* GetProcessPtr(lua::state &st) | ||||
| { | ||||
|     return DFHack::Core::getInstance().p; | ||||
| } | ||||
| 
 | ||||
| static int lua_Process_readDWord(lua_State *S) | ||||
| { | ||||
|     lua::state st(S); | ||||
|     DFHack::Process* c=GetProcessPtr(st); | ||||
|     uint32_t ret=c->readDWord( (void *) st.as<uint32_t>(1)); | ||||
|     st.push(ret); | ||||
|     return 1; | ||||
| } | ||||
| static int lua_Process_writeDWord(lua_State *S) | ||||
| { | ||||
|     lua::state st(S); | ||||
|     DFHack::Process* c=GetProcessPtr(st); | ||||
|     c->writeDWord((void *) st.as<uint32_t>(1),st.as<uint32_t>(2)); | ||||
|     return 0; | ||||
| } | ||||
| static int lua_Process_readFloat(lua_State *S) | ||||
| { | ||||
|     lua::state st(S); | ||||
|     DFHack::Process* c=GetProcessPtr(st); | ||||
|     float ret=c->readFloat((void *) st.as<uint32_t>(1)); | ||||
|     st.push(ret); | ||||
|     return 1; | ||||
| } | ||||
| 
 | ||||
| static int lua_Process_readWord(lua_State *S) | ||||
| { | ||||
|     lua::state st(S); | ||||
|     DFHack::Process* c=GetProcessPtr(st); | ||||
|     uint16_t ret=c->readWord((void *) st.as<uint32_t>(1)); | ||||
|     st.push(ret); | ||||
|     return 1; | ||||
| } | ||||
| 
 | ||||
| static int lua_Process_writeWord(lua_State *S) | ||||
| { | ||||
|     lua::state st(S); | ||||
|     DFHack::Process* c=GetProcessPtr(st); | ||||
|     c->writeWord((void *) st.as<uint32_t>(1),st.as<uint16_t>(2)); | ||||
|     return 0; | ||||
| } | ||||
| static int lua_Process_readByte(lua_State *S) | ||||
| { | ||||
|     lua::state st(S); | ||||
|     DFHack::Process* c=GetProcessPtr(st); | ||||
|     uint8_t ret=c->readByte((void *) st.as<uint32_t>(1)); | ||||
|     st.push(ret); | ||||
|     return 1; | ||||
| } | ||||
| 
 | ||||
| static int lua_Process_writeByte(lua_State *S) | ||||
| { | ||||
|     lua::state st(S); | ||||
|     DFHack::Process* c=GetProcessPtr(st); | ||||
|     c->writeByte((void *) st.as<uint32_t>(1),st.as<uint8_t>(2)); | ||||
|     return 0; | ||||
| } | ||||
| static int lua_Process_read(lua_State *S) | ||||
| { | ||||
|     lua::state st(S); | ||||
|     DFHack::Process* c=GetProcessPtr(st); | ||||
|     size_t len=st.as<uint32_t>(2); | ||||
|     uint8_t* buf; | ||||
| 
 | ||||
|     if(!st.is<lua::nil>(3)) | ||||
|         buf=(uint8_t*)lua_touserdata(st,3); | ||||
|     else | ||||
|         buf=new uint8_t[len]; | ||||
|     c->read((void *) st.as<uint32_t>(1),len,buf); | ||||
|     st.pushlightuserdata(buf); | ||||
|     return 1; | ||||
| } | ||||
| static int lua_Process_write(lua_State *S) | ||||
| { | ||||
|     lua::state st(S); | ||||
|     DFHack::Process* c=GetProcessPtr(st); | ||||
|     c-> write((void *) st.as<uint32_t>(1),st.as<uint32_t>(2),static_cast<uint8_t*>(lua_touserdata(st,3))); | ||||
|     return 0; | ||||
| } | ||||
| static int lua_Process_readSTLString (lua_State *S) | ||||
| { | ||||
|     lua::state st(S); | ||||
|     DFHack::Process* c=GetProcessPtr(st); | ||||
|     std::string r=c->readSTLString((void *) st.as<uint32_t>(1)); | ||||
|     st.push(r); | ||||
|     return 1; | ||||
| } | ||||
| 
 | ||||
| static int lua_Process_writeSTLString(lua_State *S) | ||||
| { | ||||
|     lua::state st(S); | ||||
|     DFHack::Process* c=GetProcessPtr(st); | ||||
|     c->writeSTLString((void *) st.as<uint32_t>(1),st.as<std::string>(2)); | ||||
|     return 0; | ||||
| } | ||||
| static int lua_Process_copySTLString(lua_State *S) | ||||
| { | ||||
|     lua::state st(S); | ||||
|     DFHack::Process* c=GetProcessPtr(st); | ||||
|     c->copySTLString((void *) st.as<uint32_t>(1),st.as<uint32_t>(2)); | ||||
|     return 0; | ||||
| } | ||||
| static int lua_Process_doReadClassName(lua_State *S) | ||||
| { | ||||
|     lua::state st(S); | ||||
|     DFHack::Process* c=GetProcessPtr(st); | ||||
|     std::string r=c->doReadClassName((void*)st.as<size_t>(1)); | ||||
|     st.push(r); | ||||
|     return 1; | ||||
| } | ||||
| static int lua_Process_readClassName(lua_State *S) | ||||
| { | ||||
|     lua::state st(S); | ||||
|     DFHack::Process* c=GetProcessPtr(st); | ||||
|     std::string r=c->readClassName((void*)st.as<size_t>(1)); | ||||
|     st.push(r); | ||||
|     return 1; | ||||
| } | ||||
| static int lua_Process_readCString (lua_State *S) | ||||
| { | ||||
|     lua::state st(S); | ||||
|     DFHack::Process* c=GetProcessPtr(st); | ||||
|     std::string r=c->readCString((void *) st.as<uint32_t>(1)); | ||||
|     st.push(r); | ||||
|     return 1; | ||||
| } | ||||
| static int lua_Process_isSuspended(lua_State *S) | ||||
| { | ||||
|     lua::state st(S); | ||||
|     DFHack::Process* c=GetProcessPtr(st); | ||||
|     st.push(c->isSuspended()); | ||||
|     return 1; | ||||
| } | ||||
| static int lua_Process_isIdentified(lua_State *S) | ||||
| { | ||||
|     lua::state st(S); | ||||
|     DFHack::Process* c=GetProcessPtr(st); | ||||
|     st.push(c->isIdentified()); | ||||
|     return 1; | ||||
| } | ||||
| static int lua_Process_getMemRanges(lua_State *S) | ||||
| { | ||||
|     lua::state st(S); | ||||
|     DFHack::Process* c=GetProcessPtr(st); | ||||
|     std::vector<DFHack::t_memrange> ranges; | ||||
|     c->getMemRanges(ranges); | ||||
|     st.newtable(); | ||||
|     for(size_t i=0;i<ranges.size();i++) | ||||
|     { | ||||
|         st.push(i); | ||||
|         st.newtable(); | ||||
|         st.push((uint32_t)ranges[i].start); // WARNING!! lua has only 32bit numbers, possible loss of data!!
 | ||||
|         st.setfield("start"); | ||||
|         st.push((uint32_t)ranges[i].end); | ||||
|         st.setfield("end"); | ||||
|         st.push(std::string(ranges[i].name)); | ||||
|         st.setfield("name"); | ||||
|         st.push(ranges[i].read); | ||||
|         st.setfield("read"); | ||||
|         st.push(ranges[i].write); | ||||
|         st.setfield("write"); | ||||
|         st.push(ranges[i].execute); | ||||
|         st.setfield("execute"); | ||||
|         st.push(ranges[i].shared); | ||||
|         st.setfield("shared"); | ||||
|         st.push(ranges[i].valid); | ||||
|         st.setfield("valid"); | ||||
|         st.settable(); | ||||
|     } | ||||
|     return 1; | ||||
| } | ||||
| static int lua_Process_getBase(lua_State *S) | ||||
| { | ||||
|     lua::state st(S); | ||||
|     DFHack::Process* c=GetProcessPtr(st); | ||||
|     uint32_t base=c->getBase(); | ||||
|     st.push(base); | ||||
|     return 1; | ||||
| } | ||||
| /*static int lua_Process_getPID(lua_State *S)
 | ||||
| { | ||||
|     lua::state st(S); | ||||
|     DFHack::Process* c=GetProcessPtr(st); | ||||
|     int ret=c->getPID(); | ||||
|     st.push(ret); | ||||
|     return 1; | ||||
| }*/ | ||||
| static int lua_Process_getPath(lua_State *S) | ||||
| { | ||||
|     lua::state st(S); | ||||
|     DFHack::Process* c=GetProcessPtr(st); | ||||
|     std::string ret=c->getPath(); | ||||
|     st.push(ret); | ||||
|     return 1; | ||||
| } | ||||
| static int lua_Process_setPermisions(lua_State *S) | ||||
| { | ||||
|     lua::state st(S); | ||||
|     DFHack::Process* c=GetProcessPtr(st); | ||||
|     DFHack::t_memrange range,trange; | ||||
| 
 | ||||
|     st.getfield("start",1); | ||||
|     range.start= (void *)st.as<uint64_t>(); | ||||
|     st.pop(); | ||||
|     st.getfield("end",1); | ||||
|     range.end= (void *)st.as<uint64_t>(); | ||||
|     st.pop(); | ||||
| 
 | ||||
|     st.getfield("read",2); | ||||
|     trange.read=st.as<bool>(); | ||||
|     st.pop(); | ||||
|     st.getfield("write",2); | ||||
|     trange.write=st.as<bool>(); | ||||
|     st.pop(); | ||||
|     st.getfield("execute",2); | ||||
|     trange.execute=st.as<bool>(); | ||||
|     st.pop(); | ||||
| 
 | ||||
|     c->setPermisions(range,trange); | ||||
| 
 | ||||
|     return 0; | ||||
| } | ||||
| #define PROC_FUNC(name) {#name,lua_Process_ ## name} | ||||
| const luaL_Reg lua_process_func[]= | ||||
| { | ||||
|     PROC_FUNC(readDWord), | ||||
|     PROC_FUNC(writeDWord), | ||||
|     PROC_FUNC(readFloat), | ||||
|     PROC_FUNC(readWord), | ||||
|     PROC_FUNC(writeWord), | ||||
|     PROC_FUNC(readByte), | ||||
|     PROC_FUNC(writeByte), | ||||
|     PROC_FUNC(read), | ||||
|     PROC_FUNC(write), | ||||
|     PROC_FUNC(readSTLString), | ||||
|     PROC_FUNC(writeSTLString), | ||||
|     PROC_FUNC(copySTLString), | ||||
|     PROC_FUNC(doReadClassName), | ||||
|     PROC_FUNC(readClassName), | ||||
|     PROC_FUNC(readCString ), | ||||
|     PROC_FUNC(isSuspended), | ||||
|     PROC_FUNC(isIdentified), | ||||
|     PROC_FUNC(getMemRanges), | ||||
|     PROC_FUNC(getBase), | ||||
|     //PROC_FUNC(getPID), //not implemented
 | ||||
|     PROC_FUNC(getPath), | ||||
|     PROC_FUNC(setPermisions), | ||||
|     {NULL,NULL} | ||||
| }; | ||||
| #undef PROC_FUNC | ||||
| void lua::RegisterProcess(lua::state &st) | ||||
| { | ||||
|     st.getglobal("Process"); | ||||
|     if(st.is<lua::nil>()) | ||||
|     { | ||||
|         st.pop(); | ||||
|         st.newtable(); | ||||
|     } | ||||
| 
 | ||||
|     lua::RegFunctionsLocal(st, lua_process_func); | ||||
| 
 | ||||
|     st.setglobal("Process"); | ||||
| } | ||||
| @ -1,69 +0,0 @@ | ||||
| #include "luamain.h" | ||||
| #include <vector> | ||||
| 
 | ||||
| 
 | ||||
| lua::glua* lua::glua::ptr=0; | ||||
| lua::glua::glua() | ||||
| { | ||||
|     RegBasics(mystate); | ||||
| } | ||||
| lua::state &lua::glua::Get() | ||||
| { | ||||
|     if(!glua::ptr) | ||||
|         glua::ptr=new glua(); | ||||
|     return glua::ptr->mystate; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| int lua_Ver_Lua(lua_State *L) | ||||
| { | ||||
|     lua::state st(L); | ||||
|     st.push(LUA_RELEASE); | ||||
|     return 1; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| static const struct luaL_Reg lua_basic_lib [] = | ||||
| { | ||||
|     {"getluaver", lua_Ver_Lua}, | ||||
|     {NULL, NULL}  /* sentinel */ | ||||
| }; | ||||
| void lua::RegBasics(lua::state &L) | ||||
| { | ||||
|     luaL_openlibs(L); | ||||
|     RegFunctions(L,lua_basic_lib); | ||||
| } | ||||
| 
 | ||||
| void lua::RegFunctions(lua::state &L,luaL_Reg const*arr) | ||||
| { | ||||
|     luaL_Reg const *cur=arr; | ||||
|     while(cur->name!=NULL) | ||||
|     { | ||||
|         lua_pushcfunction(L, cur->func); | ||||
|         lua_setglobal(L, cur->name); | ||||
| 
 | ||||
|         cur++; | ||||
|     } | ||||
| } | ||||
| void lua::RegFunctionsLocal(lua::state &L,luaL_Reg const*arr) | ||||
| { | ||||
|     luaL_Reg const *cur=arr; | ||||
|     while(cur->name!=NULL) | ||||
|     { | ||||
|         lua_pushcfunction(L, cur->func); | ||||
|         //lua_setglobal(L, cur->name);
 | ||||
|         L.setfield(cur->name); | ||||
| 
 | ||||
|         cur++; | ||||
|     } | ||||
| } | ||||
| string lua::DebugDump(lua::state &L) | ||||
| { | ||||
|     L.getglobal("debug"); | ||||
|     L.getfield("traceback"); | ||||
|     L.call(0,1); | ||||
|     string ret=L.as<string>(); | ||||
|     //cout<<"StackTrace:"<<ret<<endl;
 | ||||
|     L.settop(0); | ||||
|     return ret; | ||||
| } | ||||
| @ -1,836 +0,0 @@ | ||||
| /* vim: set et sw=3 tw=0 fo=croqlaw cino=t0:
 | ||||
|  * | ||||
|  * Luaxx, the C++ Lua wrapper library. | ||||
|  * Copyright (c) 2006-2008 Matthew Nicholson | ||||
|  * | ||||
|  * Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|  * of this software and associated documentation files (the "Software"), to | ||||
|  * deal in the Software without restriction, including without limitation the | ||||
|  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or | ||||
|  * sell copies of the Software, and to permit persons to whom the Software is | ||||
|  * furnished to do so, subject to the following conditions: | ||||
|  * | ||||
|  * The above copyright notice and this permission notice shall be included in | ||||
|  * all copies or substantial portions of the Software. | ||||
|  * | ||||
|  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||||
|  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||||
|  * IN THE SOFTWARE. | ||||
|  */ | ||||
| 
 | ||||
| #include <luaxx.hpp> | ||||
| #include <iostream> | ||||
| #define LOG std::cout | ||||
| /** @file
 | ||||
|  * Luaxx implementation file. | ||||
|  */ | ||||
| 
 | ||||
| namespace lua | ||||
| { | ||||
|     void StackDump(lua_State *L) | ||||
|     { | ||||
|         int i; | ||||
|         int top = lua_gettop(L); | ||||
|         for (i = 1; i <= top; i++)    /* repeat for each level */ | ||||
|         { | ||||
|             int t = lua_type(L, i); | ||||
|             LOG<<i<<":"; | ||||
|             switch (t) | ||||
|             { | ||||
| 
 | ||||
|             case LUA_TSTRING:  /* strings */ | ||||
|                 LOG<<"str ="<<lua_tostring(L, i)<<"\n"; | ||||
|                 break; | ||||
| 
 | ||||
|             case LUA_TBOOLEAN:  /* booleans */ | ||||
|                 LOG<<"bool="<<(lua_toboolean(L, i) ? "true" : "false")<<"\n"; | ||||
|                 break; | ||||
| 
 | ||||
|             case LUA_TNUMBER:  /* numbers */ | ||||
|                 LOG<<"num ="<<lua_tonumber(L, i)<<"\n"; | ||||
|                 break; | ||||
|             case LUA_TTABLE: | ||||
| 
 | ||||
|                 LOG<<lua_typename(L, t); | ||||
|                 { | ||||
|                     //LOG<<"PRE TOP:"<< lua_gettop(L)<<"\n";
 | ||||
|                     lua_getglobal(L,"PrintTable"); | ||||
|                     //lua_insert(L,-2);
 | ||||
|                     lua_pushvalue(L,i); | ||||
|                     lua_pcall(L,1,0,0); | ||||
|                     //LOG<<"POST TOP:"<< lua_gettop(L)<<"\n";
 | ||||
|                 } | ||||
| 
 | ||||
|                 break; | ||||
|             default:  /* other values */ | ||||
|                 LOG<<lua_typename(L, t); | ||||
|                 { | ||||
|                     //LOG<<"PRE TOP:"<< lua_gettop(L)<<"\n";
 | ||||
|                     lua_getglobal(L,"tostring"); | ||||
|                     //lua_insert(L,-2);
 | ||||
|                     lua_pushvalue(L,i); | ||||
|                     lua_pcall(L,1,1,0); | ||||
|                     LOG<<"="; | ||||
|                     LOG<<lua_tostring(L,-1)<<"\n"; | ||||
|                     lua_pop(L,1); | ||||
|                     //LOG<<"POST TOP:"<< lua_gettop(L)<<"\n";
 | ||||
|                 } | ||||
| 
 | ||||
|                 break; | ||||
| 
 | ||||
|             } | ||||
| 
 | ||||
|         } | ||||
|         LOG<<"\n";  /* end the listing */ | ||||
|         LOG<<"==============================\n"; | ||||
|     } | ||||
| #undef LOG | ||||
|    /// Construct our lua environment.
 | ||||
|    state::state() : L(luaL_newstate()), managed(true) { | ||||
|       if (L == NULL) | ||||
|          throw bad_alloc("Error creating lua state"); | ||||
|    } | ||||
| 
 | ||||
|    /** Construct our lua environment from an existing lua_State.
 | ||||
|     * @param L the existing state to use. | ||||
|     * | ||||
|     * This function differs from the normal constructor as it sets a flag | ||||
|     * that prevents lua_close() from being called when this class is | ||||
|     * destroyed. | ||||
|     */ | ||||
|    state::state(lua_State* L) : | ||||
|       L(L), managed(false) { | ||||
|    } | ||||
|    state& state::operator = (const state& t) | ||||
|     { | ||||
|              if(managed) | ||||
|                 lua_close(L); | ||||
|              managed=false; | ||||
|              L=t.L; | ||||
| 			 return *this; | ||||
|         } | ||||
|    /// Destroy our lua environment.
 | ||||
|    state::~state() { | ||||
|       if (managed) | ||||
|          lua_close(L); | ||||
|    } | ||||
| 
 | ||||
|    /** Push a nil onto the stack.
 | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    state& state::push() { | ||||
|       lua_pushnil(L); | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Push a nil onto the stack.
 | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    state& state::push(nil) { | ||||
|       lua_pushnil(L); | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Push a boolean onto the stack.
 | ||||
|     * @param boolean the value to push | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    state& state::push(bool boolean) { | ||||
|       lua_pushboolean(L, boolean); | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Push a C-style string onto the stack.
 | ||||
|     * @param s the string to push | ||||
|     * @param length the length of the string | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    state& state::push(const char* s, size_t length) { | ||||
|       lua_pushlstring(L, s, length); | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Push a C-style string onto the stack.
 | ||||
|     * @param s the string to push | ||||
|     * @note This must be a '0' terminated string. | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    state& state::push(const char* s) { | ||||
|       lua_pushstring(L, s); | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Push an std::string onto the stack.
 | ||||
|     * @param s the string to push | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    state& state::push(const std::string& s) { | ||||
|       lua_pushlstring(L, s.c_str(), s.size()); | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Push an C function onto the stack.
 | ||||
|     * @param f the function to push | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    state& state::push(cfunction f) { | ||||
|       lua_pushcfunction(L, f); | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Create a new table on to the stack.
 | ||||
|     * @see state::newtable() | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    state& state::push(table) { | ||||
|       lua_newtable(L); | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Push a light userdatum on to the stack.
 | ||||
|     * @param p the pointer to push | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    state& state::push(void* p) { | ||||
|       lua_pushlightuserdata(L, p); | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Get the value at index as a string.
 | ||||
|     * @param default_value this value is returned if the conversion fails | ||||
|     * @param index the index to get | ||||
|     * @note This function does \em not pop the value from the stack. | ||||
|     * | ||||
|     * @note lua::state::as(std::string()) will convert the value at the | ||||
|     * indicated index to a string <em>on the stack</em>.  This can | ||||
|     * confuse lua::state::next(); | ||||
|     * | ||||
|     * @returns the indicated value from the stack or the default value if the | ||||
|     * conversion fails | ||||
|     */ | ||||
|    template<> | ||||
|    std::string state::as(std::string default_value, int index) { | ||||
|       if (lua_isstring(L, index)) | ||||
|       { | ||||
|          size_t len; | ||||
|          const char *str = lua_tolstring(L, index, &len); | ||||
|          return std::string(str, len); | ||||
|       } | ||||
|       else | ||||
|          return default_value; | ||||
|    } | ||||
| 
 | ||||
|    /** Check an argument of the current function.
 | ||||
|     * @param narg the argument number to check | ||||
|     * | ||||
|     * This function will throw a lua error if there is no argument at the | ||||
|     * given position. | ||||
|     * | ||||
|     * @note This function is meant to be called from with in a lua::cfunction. | ||||
|     * The error throw is internal to the lua interpreter.  When compiled as | ||||
|     * C++, a C++ exception is thrown, so the stack is properly unwound.  This | ||||
|     * exception is not meant to be caught. | ||||
|     */ | ||||
|    state& state::check(int narg) { | ||||
|       luaL_checkany(L, narg); | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
| #ifndef lua_Integer_int | ||||
|    /** Check an argument of the current function.
 | ||||
|     * @param i the int to hold the returned value | ||||
|     * @param narg the argument number to check | ||||
|     * | ||||
|     * This function checks if the given argument number is an int. | ||||
|     * | ||||
|     * @note This function is meant to be called from with in a | ||||
|     * lua::cfunction.  The error throw is internal to the lua intrepeter. | ||||
|     * When compiled as C++, a C++ exception is thrown, so the stack is | ||||
|     * properly unwound.  This exception is not meant to be caught. | ||||
|     */ | ||||
|    state& state::check(int& i, int narg) { | ||||
|       i = luaL_checkint(L, narg); | ||||
|       return *this; | ||||
|    } | ||||
| #endif | ||||
| 
 | ||||
|    /** Check an argument of the current function.
 | ||||
|     * @param i the lua::integer (lua_Integer) to hold the returned value | ||||
|     * @param narg the argument number to check | ||||
|     * | ||||
|     * This function checks if the given argument number is an integer. | ||||
|     * | ||||
|     * @note This is different from lua::check(int(), ...).  It returns a | ||||
|     * lua::integer (lua_Integer), which may not be an int. | ||||
|     * | ||||
|     * @note This function is meant to be called from with in a | ||||
|     * lua::cfunction.  The error throw is internal to the lua intrepeter. | ||||
|     * When compiled as C++, a C++ exception is thrown, so the stack is | ||||
|     * properly unwound.  This exception is not meant to be caught. | ||||
|     */ | ||||
|    state& state::check(integer& i, int narg) { | ||||
|       i = luaL_checkinteger(L, narg); | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
| #ifndef lua_Integer_long | ||||
|    /** Check an argument of the current function.
 | ||||
|     * @param l the long to hold the returned value | ||||
|     * @param narg the argument number to check | ||||
|     * | ||||
|     * This function checks if the given argument number is a long. | ||||
|     * | ||||
|     * @note This function is meant to be called from with in a | ||||
|     * lua::cfunction.  The error throw is internal to the lua intrepeter. | ||||
|     * When compiled as C++, a C++ exception is thrown, so the stack is | ||||
|     * properly unwound.  This exception is not meant to be caught. | ||||
|     */ | ||||
|    state& state::check(long& l, int narg) { | ||||
|       l = luaL_checklong(L, narg); | ||||
|       return *this; | ||||
|    } | ||||
| #endif | ||||
| 
 | ||||
|    /** Check an argument of the current function.
 | ||||
|     * @param s the string to hold the returned value | ||||
|     * @param narg the argument number to check | ||||
|     * | ||||
|     * This function checks if the given argument number is a string. | ||||
|     * | ||||
|     * @note This function is meant to be called from with in a | ||||
|     * lua::cfunction.  The error throw is internal to the lua intrepeter. | ||||
|     * When compiled as C++, a C++ exception is thrown, so the stack is | ||||
|     * properly unwound.  This exception is not meant to be caught. | ||||
|     */ | ||||
|    state& state::check(std::string& s, int narg) { | ||||
|       const char* c; | ||||
|       size_t l; | ||||
|       c = luaL_checklstring(L, narg, &l); | ||||
| 
 | ||||
|       s.assign(c, l); | ||||
| 
 | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Check an argument of the current function.
 | ||||
|     * @param n the lua::number (lua_Number) to hold the returned value | ||||
|     * @param narg the argument number to check | ||||
|     * | ||||
|     * This function checks if the given argument number is a lua::number | ||||
|     * (lua_Number, a double by default). | ||||
|     * | ||||
|     * @note This function is meant to be called from with in a lua::cfunction. | ||||
|     * The error throw is internal to the lua interpreter.  When compiled as | ||||
|     * C++, a C++ exception is thrown, so the stack is properly unwound.  This | ||||
|     * exception is not meant to be caught. | ||||
|     */ | ||||
|    state& state::check(number& n, int narg) { | ||||
|       n = luaL_checknumber(L, narg); | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
| #if 0 | ||||
|    /** [specialization] Generate a Lua error (T = std::string).
 | ||||
|     */ | ||||
|    template<> | ||||
|    void state::error(const std::string& message) { | ||||
|       push(message); | ||||
|       lua_error(L); | ||||
|    } | ||||
| #endif | ||||
| 
 | ||||
|    /** Call a lua function.
 | ||||
|     * @param nargs the number of args to pass to the function | ||||
|     * @param nresults the number of values to return from the function | ||||
|     * @param on_error A stack index where the error handling function is | ||||
|     * stored. | ||||
|     * @note The error handling function must be pushed in the stack | ||||
|     * before the function to be called and its arguments. | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    state& state::pcall(int nargs, int nresults, int on_error) { | ||||
|       throw_error(lua_pcall(L, nargs, nresults, on_error)); | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Call a lua function in unprotected mode.
 | ||||
|     * @param nargs the number of args to pass to the function | ||||
|     * @param nresults the number of values to return from the function | ||||
|     * stored. | ||||
|     * @note If there is an error in the call the program will terminate. | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    state& state::call(int nargs, int nresults) { | ||||
|       lua_call(L, nargs, nresults); | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Ensure the stack is at least the given size.
 | ||||
|     * @param size the size to use | ||||
|     * | ||||
|     * If the stack is smaller than the given size, it will grow to the | ||||
|     * specified size. | ||||
|     * | ||||
|     * @exception lua::exception Thrown if the operation fails. | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    state& state::checkstack(int size) { | ||||
|       if (!lua_checkstack(L, size)) | ||||
|          throw lua::exception("Error growing the stack"); | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Set a new index as the top of the stack.
 | ||||
|     * @param index the index to use as the new top | ||||
|     * @note If the previous top was higher than the new one, top values | ||||
|     * are discarded.  Otherwise this function pushs nils on to the stack | ||||
|     * to get the proper size. | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    state& state::settop(int index) { | ||||
|       lua_settop(L, index); | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Get the number of elements in the stack.
 | ||||
|     * @note This value is also the index of the top element. | ||||
|     * @returns the number of elements in the stack | ||||
|     */ | ||||
|    int state::gettop() { | ||||
|       return lua_gettop(L); | ||||
|    } | ||||
| 
 | ||||
|    /** Get the number of elements in the stack.
 | ||||
|     * @note This value is also the index of the top element. | ||||
|     * @returns the number of elements in the stack | ||||
|     */ | ||||
|    int state::size() { | ||||
|       return lua_gettop(L); | ||||
|    } | ||||
| 
 | ||||
|    /** Check if the stack is empty.
 | ||||
|     * @returns true if the stack is empty, false otherwise | ||||
|     */ | ||||
|    bool state::empty() { | ||||
|       return !lua_gettop(L); | ||||
|    } | ||||
| 
 | ||||
|    /** Move the top element to the given index.
 | ||||
|     * @param index the index to insert at | ||||
|     * @note All elements on top of the given index are shifted up to open | ||||
|     * space for this element. | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    state& state::insert(int index) { | ||||
|       lua_insert(L, index); | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Replace the given index with the top element.
 | ||||
|     * @param index the index to replae | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    state& state::replace(int index) { | ||||
|       lua_replace(L, index); | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Remove the given index from the stack.
 | ||||
|     * @param index the index to remove | ||||
|     * @note Elements are shifted down to fill in the empty spot. | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    state& state::remove(int index) { | ||||
|       lua_remove(L, index); | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Remove the given number of elemens from the stack.
 | ||||
|     * @param elements the number of elements to remove | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    state& state::pop(int elements) { | ||||
|       lua_pop(L, elements); | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Push a copy of the element at the given index to the top of the
 | ||||
|     * stack. | ||||
|     * @param index the index of the element to copy | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    state& state::pushvalue(int index) { | ||||
|       lua_pushvalue(L, index); | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Create a new table on the stack.
 | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    state& state::newtable() { | ||||
|       lua_newtable(L); | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Create a new metatable and add it to the registry.
 | ||||
|     * @param tname the name to use for the new metatable in the registry | ||||
|     * | ||||
|     * This function creates a new metatable and adds it to the registry | ||||
|     * with the given key.  This function also pushes the new metatable | ||||
|     * onto the stack. | ||||
|     * | ||||
|     * @note Regardless of the return value, the new metatable is always pushed | ||||
|     * on to the stack. | ||||
|     * | ||||
|     * @return true if a new metatable was created, false if the registry | ||||
|     * alread has a key with the given name. | ||||
|     */ | ||||
|    bool state::newmetatable(const std::string& tname) { | ||||
|       return luaL_newmetatable(L, tname.c_str()); | ||||
|    } | ||||
| 
 | ||||
|    /** Create a new userdatum on the stack.
 | ||||
|     * @param nbytes the size of the new userdatum | ||||
|     * @return a pointer to the new userdatum | ||||
|     */ | ||||
|    void* state::newuserdata(size_t nbytes) { | ||||
|       return lua_newuserdata(L, nbytes); | ||||
|    } | ||||
| 
 | ||||
|    /** Get a value from a table on the stack.
 | ||||
|     * @param index the index the table is stored at | ||||
|     * | ||||
|     * This function gets a value from the table at the given index and | ||||
|     * pushes it onto the stack. | ||||
|     * | ||||
|     * @note You should have already pushed the key used to reference this | ||||
|     * value onto the stack before calling this function. | ||||
|     * | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    state& state::gettable(int index) { | ||||
|       lua_gettable(L, index); | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Get a value from a table on the stack.
 | ||||
|     * @param k the key | ||||
|     * @param index the index the table is stored at | ||||
|     * | ||||
|     * This function gets a value from the table at the given index and | ||||
|     * pushes it onto the stack. | ||||
|     * | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    state& state::getfield(const std::string& k, int index) { | ||||
|       lua_getfield(L, index, k.c_str()); | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Set a value in a table.
 | ||||
|     * @param index the index the table is stored at | ||||
|     * | ||||
|     * This function sets a value in a table stored at the given index. | ||||
|     * | ||||
|     * @note The key and value to be used should have already been pushed | ||||
|     * on the stack in that order. | ||||
|     * | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    state& state::settable(int index) { | ||||
|       lua_settable(L, index); | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Set a field in a table.
 | ||||
|     * @param k the key | ||||
|     * @param index the index the table is stored at | ||||
|     * | ||||
|     * This function sets a value in a table stored at the given index. | ||||
|     * | ||||
|     * @note The value to be used should be on the top of the stack. | ||||
|     * | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    state& state::setfield(const std::string& k, int index) { | ||||
|       lua_setfield(L, index, k.c_str()); | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Get the metatable associated with the given registry entry.
 | ||||
|     * @param tname the name in the registry | ||||
|     * | ||||
|     * This function gets the metatable associated with the given key in | ||||
|     * the registry.  The resulting metatable is pushed onto the stack. | ||||
|     * | ||||
|     * @note This function uses luaL_getmetatable() internally. | ||||
|     * | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    state& state::getmetatable(const std::string& tname) { | ||||
|       luaL_getmetatable(L, tname.c_str()); | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Get the metatable of the value at the given index.
 | ||||
|     * @param index the index the value is stored at | ||||
|     * | ||||
|     * This function pushes on to the stack the metatabe of the value at | ||||
|     * the given index. | ||||
|     * | ||||
|     * @note This function uses lua_getmetatable() internally. | ||||
|     * | ||||
|     * @returns false if the value at the given index does not have a | ||||
|     * metatable or if the index is not valid | ||||
|     */ | ||||
|    bool state::getmetatable(int index) { | ||||
|       return lua_getmetatable(L, index); | ||||
|    } | ||||
| 
 | ||||
|    /** Get the next key value pair from a table on the stack.
 | ||||
|     * @param index the stack index the table is at | ||||
|     * | ||||
|     * This function pops a key from the stack and pushes the next key | ||||
|     * value pair to the stack.  The key will be stored at index -2 and | ||||
|     * the value will be at index -1.  The key is expected to be on the | ||||
|     * top of the stack. | ||||
|     * | ||||
|     * @note While traversing a table, do not call | ||||
|     * lua::state::to(std::string()) directly on a key, unless you know | ||||
|     * that the key is actually a string.  lua::state::to(std::string()) | ||||
|     * changes the value at the given index; this confuses the next call | ||||
|     * to lua::state::next(). | ||||
|     * | ||||
|     * <strong>While Loop Example:</strong> | ||||
|     * @code | ||||
|     * while(L.next() != 0) { | ||||
|     *    // do stuff
 | ||||
|     *    L.pop(); | ||||
|     * } | ||||
|     * @endcode | ||||
|     * | ||||
|     * <strong>For Loop Example:</strong> | ||||
|     * @code | ||||
|     * for(L.push(lua::nil()); L.next(); L.pop()) { | ||||
|     *    // do stuff
 | ||||
|     * } | ||||
|     * @endcode | ||||
|     * | ||||
|     * @returns true as long as there are remaining items in the table | ||||
|     */ | ||||
|    bool state::next(int index) { | ||||
|       return lua_next(L, index); | ||||
|    } | ||||
| 
 | ||||
|    /** Load a global symbol onto the stack.
 | ||||
|     * @param name the name of the global to load | ||||
|     * | ||||
|     * This function loads a global symbol onto the stack from the lua | ||||
|     * state. | ||||
|     * | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    state& state::getglobal(const std::string& name) { | ||||
|       lua_getglobal(L, name.c_str()); | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Set a global symbol.
 | ||||
|     * @param name the name of the global to set | ||||
|     * | ||||
|     * This function sets/creates a global symbol from the value above it | ||||
|     * on the stack. | ||||
|     * | ||||
|     * @note You should have pushed the value of the symbol onto the stack | ||||
|     * before calling this function. | ||||
|     * | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    state& state::setglobal(const std::string& name) { | ||||
|       lua_setglobal(L, name.c_str()); | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Load a file as a Lua chunk.
 | ||||
|     * @param filename the name of the file to load | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    state& state::loadfile(const std::string& filename) { | ||||
|       throw_error(luaL_loadfile(L, filename.c_str())); | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Load a string as a Lua chunk.
 | ||||
|     * @param s the string to load | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    state& state::loadstring(const std::string& s) { | ||||
|       throw_error(luaL_loadstring(L, s.c_str())); | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Get the length of a value on the stack.
 | ||||
|     * @param index the index the value is stored at | ||||
|     * @returns the length of the indicated value | ||||
|     */ | ||||
|    size_t state::objlen(int index) { | ||||
|       return lua_rawlen(L, index); | ||||
|    } | ||||
| 
 | ||||
|    /** Get the value at index as a bool.
 | ||||
|     * @param boolean where to store the value | ||||
|     * @param index the index to get | ||||
|     * @note This function does \em not pop the value from the stack. | ||||
|     * @todo Instead of throwing an exception here, we may just return an | ||||
|     * error code. | ||||
|     * @throws lua::bad_conversion if the value on the stack could not be | ||||
|     * converted to the indicated type | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    template<> | ||||
|    state& state::to(bool& boolean, int index) { | ||||
|       if (lua_isboolean(L, index)) | ||||
|          boolean = lua_toboolean(L, index); | ||||
|       else | ||||
|          throw bad_conversion("Cannot convert non 'boolean' value to bool"); | ||||
| 
 | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Get the value at index as a string.
 | ||||
|     * @param string where to store the value | ||||
|     * @param index the index to get | ||||
|     * @note This function does \em not pop the value from the stack. | ||||
|     * @todo Instead of throwing an exception here, we may just return an | ||||
|     * error code. | ||||
|     * | ||||
|     * @note lua::state::to(std::string()) will convert the value at the | ||||
|     * indicated index to a string <em>on the stack</em>.  This can | ||||
|     * confuse lua::state::next(); | ||||
|     * | ||||
|     * @throws lua::bad_conversion if the value on the stack could not be | ||||
|     * converted to the indicated type | ||||
|     * @returns a reference to this lua::state | ||||
|     */ | ||||
|    template<> | ||||
|    state& state::to(std::string& string, int index) { | ||||
|       if (lua_isstring(L, index)) | ||||
|       { | ||||
|           size_t len; | ||||
|           const char *str = lua_tolstring(L, index, &len); | ||||
|           string.replace(0, std::string::npos, str, len); | ||||
|       } | ||||
|       else | ||||
|          throw bad_conversion("Cannot convert value to string"); | ||||
| 
 | ||||
|       return *this; | ||||
|    } | ||||
| 
 | ||||
|    /** Get the value at index as a bool.
 | ||||
|     * @param default_value this value is returned if the conversion fails | ||||
|     * @param index the index to get | ||||
|     * @note This function does \em not pop the value from the stack. | ||||
|     * @returns the indicated value from the stack or the default value if the | ||||
|     * conversion fails | ||||
|     */ | ||||
|    template<> | ||||
|    bool state::as(bool default_value, int index) { | ||||
|       if (lua_isboolean(L, index)) | ||||
|          return lua_toboolean(L, index); | ||||
|       else | ||||
|          return default_value; | ||||
|    } | ||||
| 
 | ||||
|    /** [specialization] Get the value at index as a bool (T = bool).
 | ||||
|     */ | ||||
|    template<> | ||||
|    bool state::as(int index) { | ||||
|       if (lua_isboolean(L, index)) | ||||
|          return lua_toboolean(L, index); | ||||
|       else | ||||
|          throw bad_conversion("Cannot convert non 'boolean' value to bool"); | ||||
|    } | ||||
| 
 | ||||
|    /** [specialization] Get the value at index as a string (T = std::string).
 | ||||
|     * @note lua::state::as(std::string()) will convert the value at the | ||||
|     * indicated index to a string <em>on the stack</em>.  This can confuse | ||||
|     * lua::state::next(); | ||||
|     */ | ||||
|    template<> | ||||
|    std::string state::as(int index) { | ||||
|       if (lua_isstring(L, index)) | ||||
|       { | ||||
|           size_t len; | ||||
|           const char *str = lua_tolstring(L, index, &len); | ||||
|           return std::string(str, len); | ||||
|       } | ||||
|       else | ||||
|          throw bad_conversion("Cannot convert value to string"); | ||||
|    } | ||||
| 
 | ||||
|    /** [specialization] Check if the given index is a nil (T = lua::nil).
 | ||||
|     */ | ||||
|    template<> | ||||
|    bool state::is<nil>(int index) { | ||||
|       return lua_isnil(L, index); | ||||
|    } | ||||
| 
 | ||||
|    /** [specialization] Check if the given index is a boolean (T = bool).
 | ||||
|     */ | ||||
|    template<> | ||||
|    bool state::is<bool>(int index) { | ||||
|       return lua_isboolean(L, index); | ||||
|    } | ||||
| 
 | ||||
|    /** [specialization] Check if the given index is a string (T = std::string).
 | ||||
|     */ | ||||
|    template<> | ||||
|    bool state::is<std::string>(int index) { | ||||
|       return lua_isstring(L, index); | ||||
|    } | ||||
| 
 | ||||
|    /** [specialization] Check if the given index is a table (T = lua::table).
 | ||||
|     */ | ||||
|    template<> | ||||
|    bool state::is<table>(int index) { | ||||
|       return lua_istable(L, index); | ||||
|    } | ||||
| 
 | ||||
|    /** [specialization] Check if the given index is a C function (T =
 | ||||
|     * lua::cfunction). | ||||
|     */ | ||||
|    template<> | ||||
|    bool state::is<cfunction>(int index) { | ||||
|       return lua_iscfunction(L, index); | ||||
|    } | ||||
| 
 | ||||
|    /** [specialization] Check if the given index is a function (T =
 | ||||
|     * lua::function). | ||||
|     */ | ||||
|    template<> | ||||
|    bool state::is<function>(int index) { | ||||
|       return lua_isfunction(L, index); | ||||
|    } | ||||
| 
 | ||||
|    /** [specialization] Check if the given index is userdata (T =
 | ||||
|     * lua::userdata). | ||||
|     */ | ||||
|    template<> | ||||
|    bool state::is<userdata>(int index) { | ||||
|       return lua_isuserdata(L, index); | ||||
|    } | ||||
| 
 | ||||
|    /** [specialization] Check if the given index is light userdata (T =
 | ||||
|     * lua::lightuserdata). | ||||
|     */ | ||||
|    template<> | ||||
|    bool state::is<lightuserdata>(int index) { | ||||
|       return lua_islightuserdata(L, index); | ||||
|    } | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| @ -1,2 +0,0 @@ | ||||
| #include "lune.h" | ||||
| lua::object *lua::local_object::mytbl=0; | ||||
| @ -1 +0,0 @@ | ||||
| Subproject commit 5b167d2ba89b877d80e0609feae8771aeaef356d | ||||
| @ -1,31 +0,0 @@ | ||||
| PROJECT (export) | ||||
| # A list of source files | ||||
| SET(PROJECT_SRCS | ||||
|     dwarfexport.cpp | ||||
| ) | ||||
| # A list of headers | ||||
| SET(PROJECT_HDRS | ||||
|     dwarfexport.h | ||||
| ) | ||||
| SET_SOURCE_FILES_PROPERTIES( ${PROJECT_HDRS} PROPERTIES HEADER_FILE_ONLY TRUE) | ||||
| 
 | ||||
| # mash them together (headers are marked as headers and nothing will try to compile them) | ||||
| LIST(APPEND PROJECT_SRCS ${PROJECT_HDRS}) | ||||
| 
 | ||||
| #linux | ||||
| IF(UNIX) | ||||
|     add_definitions(-DLINUX_BUILD) | ||||
|     SET(PROJECT_LIBS | ||||
|         # add any extra linux libs here | ||||
|         ${PROJECT_LIBS} | ||||
|     ) | ||||
| # windows | ||||
| ELSE(UNIX) | ||||
|     SET(PROJECT_LIBS | ||||
|         # add any extra linux libs here | ||||
|         ${PROJECT_LIBS} | ||||
|         $(NOINHERIT) | ||||
|     ) | ||||
| ENDIF(UNIX) | ||||
| # this makes sure all the stuff is put in proper places and linked to dfhack | ||||
| DFHACK_PLUGIN(dwarfexport ${PROJECT_SRCS} LINK_LIBRARIES ${PROJECT_LIBS}) | ||||
| @ -1,244 +0,0 @@ | ||||
| // some headers required for a plugin. Nothing special, just the basics.
 | ||||
| #include <vector> | ||||
| #include <string> | ||||
| #include <fstream> | ||||
| #include <iostream> | ||||
| using namespace std; | ||||
| 
 | ||||
| #define DFHACK_WANT_MISCUTILS | ||||
| #include <Core.h> | ||||
| #include <VersionInfo.h> | ||||
| #include <Console.h> | ||||
| #include <Export.h> | ||||
| #include <PluginManager.h> | ||||
| #include <modules/Units.h> | ||||
| #include <modules/Translation.h> | ||||
| 
 | ||||
| #include <df/ui.h> | ||||
| #include <df/world.h> | ||||
| #include <df/unit.h> | ||||
| #include <df/unit_soul.h> | ||||
| #include <df/unit_labor.h> | ||||
| #include <df/unit_skill.h> | ||||
| /*
 | ||||
| dwarfexport | ||||
| =========== | ||||
| Export dwarves to RuneSmith-compatible XML; also unused by modern tools. | ||||
| */ | ||||
| 
 | ||||
| using namespace DFHack; | ||||
| using df::global::ui; | ||||
| using df::global::world; | ||||
| 
 | ||||
| // our own, empty header.
 | ||||
| #include "dwarfexport.h" | ||||
| #include <df/personality_facet_type.h> | ||||
| 
 | ||||
| 
 | ||||
| // Here go all the command declarations...
 | ||||
| // mostly to allow having the mandatory stuff on top of the file and commands on the bottom
 | ||||
| command_result export_dwarves (color_ostream &con, std::vector <std::string> & parameters); | ||||
| 
 | ||||
| DFHACK_PLUGIN("dwarfexport"); | ||||
| 
 | ||||
| // Mandatory init function. If you have some global state, create it here.
 | ||||
| DFhackCExport command_result plugin_init (color_ostream &con, std::vector <PluginCommand> &commands) | ||||
| { | ||||
|     // Fill the command list with your commands.
 | ||||
|     commands.push_back(PluginCommand("dwarfexport", | ||||
|                                      "Export dwarves to RuneSmith-compatible XML.", | ||||
|                                      export_dwarves /*,
 | ||||
|                                      true or false - true means that the command can't be used from non-interactive user interface'*/)); | ||||
|     return CR_OK; | ||||
| } | ||||
| 
 | ||||
| // This is called right before the plugin library is removed from memory.
 | ||||
| DFhackCExport command_result plugin_shutdown (color_ostream &con) | ||||
| { | ||||
|     return CR_OK; | ||||
| } | ||||
| 
 | ||||
| static const char* physicals[] = { | ||||
|     "Strength", | ||||
|     "Agility", | ||||
|     "Toughness", | ||||
|     "Endurance", | ||||
|     "Recuperation", | ||||
|     "DiseaseResistance", | ||||
| }; | ||||
| 
 | ||||
| static const char* mentals[] = { | ||||
|     "AnalyticalAbility", | ||||
|     "Focus", | ||||
|     "Willpower", | ||||
|     "Creatvity", //Speeling deliberate
 | ||||
|     "Intuition", | ||||
|     "Patience", | ||||
|     "Memory", | ||||
|     "LinguisticAbility", | ||||
|     "SpatialSense", | ||||
|     "Musicality", | ||||
|     "KinaestheticSense", | ||||
|     "Empathy", | ||||
|     "SocialAwareness", | ||||
| }; | ||||
| 
 | ||||
| static void element(const char* name, const char* content, ostream& out, const char* extra_indent="") { | ||||
|     out << extra_indent << "    <" << name << ">" << content << "</" << name << ">" << endl; | ||||
| } | ||||
| 
 | ||||
| static void element(const char* name, const uint32_t content, ostream& out, const char* extra_indent="") { | ||||
|     out << extra_indent << "    <" << name << ">" << content << "</" << name << ">" << endl; | ||||
| } | ||||
| 
 | ||||
| static void printAttributes(color_ostream &con, df::unit* cre, ostream& out) { | ||||
|     out << "    <Attributes>" << endl; | ||||
|     for (int i = 0; i < NUM_CREATURE_PHYSICAL_ATTRIBUTES; i++) { | ||||
|         element(physicals[i], cre->body.physical_attrs[i].value, out, "  "); | ||||
|     } | ||||
| 
 | ||||
|     df::unit_soul * s = cre->status.current_soul; | ||||
|     if (s) { | ||||
|         for (int i = 0; i < NUM_CREATURE_MENTAL_ATTRIBUTES; i++) { | ||||
|             element(mentals[i], s->mental_attrs[i].value, out, "  "); | ||||
|         } | ||||
|     } | ||||
|     out << "    </Attributes>" << endl; | ||||
| } | ||||
| 
 | ||||
| static void printTraits(color_ostream &con, df::unit* cre, ostream& out) | ||||
| { | ||||
| 
 | ||||
|     out << "    <Traits>" << endl; | ||||
|     df::unit_soul * s = cre->status.current_soul; | ||||
|     if (s) | ||||
|     { | ||||
|         FOR_ENUM_ITEMS(personality_facet_type,index) | ||||
|         { | ||||
|             out << "      <Trait name='" << ENUM_KEY_STR(personality_facet_type, index) << | ||||
|                 "' value='" << s->traits[index] << "'>"; | ||||
|             //FIXME: needs reimplementing trait string generation
 | ||||
|             /*
 | ||||
|             string trait = con->vinfo->getTrait(i, s->traits[i]); | ||||
|             if (!trait.empty()) { | ||||
|                 out << trait.c_str(); | ||||
|             } | ||||
|             */ | ||||
|             out << "</Trait>" << endl; | ||||
| 
 | ||||
|         } | ||||
|     } | ||||
|     out << "    </Traits>" << endl; | ||||
| } | ||||
| 
 | ||||
| static int32_t getCreatureAge(df::unit* cre) | ||||
| { | ||||
|     int32_t yearDifference = *df::global::cur_year - cre->relations.birth_year; | ||||
| 
 | ||||
|     // If the birthday this year has not yet passed, subtract one year.
 | ||||
|     // ASSUMPTION: birth_time is on the same scale as cur_year_tick
 | ||||
|     if (cre->relations.birth_time >= *df::global::cur_year_tick) { | ||||
|         yearDifference--; | ||||
|     } | ||||
| 
 | ||||
|     return yearDifference; | ||||
| } | ||||
| 
 | ||||
| static void printLabors(color_ostream &con, df::unit* cre, ostream& out) | ||||
| { | ||||
|     // Using British spelling here, consistent with Runesmith
 | ||||
|     out << "  <Labours>" << endl; | ||||
|     FOR_ENUM_ITEMS(unit_labor, iCount) | ||||
|     { | ||||
|         if (cre->status.labors[iCount]) { | ||||
|             // Get the caption for the labor index.
 | ||||
|             element("Labour", ENUM_ATTR_STR(unit_labor, caption, iCount), out); | ||||
|         } | ||||
|     } | ||||
|     out << "  </Labours>" << endl; | ||||
| } | ||||
| 
 | ||||
| static void printSkill(color_ostream &con, df::unit_skill* skill, ostream& out) | ||||
| { | ||||
|     out << "    <Skill>" << endl; | ||||
| 
 | ||||
|     element("Name", ENUM_ATTR_STR(job_skill, caption, skill->id), out); | ||||
|     element("Level", skill->rating, out); | ||||
| 
 | ||||
|     out << "    </Skill>" << endl; | ||||
| } | ||||
| 
 | ||||
| static void printSkills(color_ostream &con, df::unit* cre, ostream& out) | ||||
| { | ||||
| 
 | ||||
|     std::vector<df::unit_skill* > vSkills = cre->status.current_soul->skills; | ||||
| 
 | ||||
|     out << "  <Skills>" << endl; | ||||
|     for (int iCount = 0; iCount < vSkills.size(); iCount++) | ||||
|     { | ||||
|         printSkill(con, vSkills.at(iCount), out); | ||||
|     } | ||||
| 
 | ||||
|     out << "  </Skills>" << endl; | ||||
| } | ||||
| 
 | ||||
| // GDC needs:
 | ||||
| // Name
 | ||||
| // Nickname
 | ||||
| // Sex
 | ||||
| // Attributes
 | ||||
| // Traits
 | ||||
| static void export_dwarf(color_ostream &con, df::unit* cre, ostream& out) { | ||||
|     string info = cre->name.first_name; | ||||
|     info += " "; | ||||
|     info += Translation::TranslateName(&cre->name, false); | ||||
|     info[0] = toupper(info[0]); | ||||
|     con.print("Exporting %s\n", info.c_str()); | ||||
| 
 | ||||
|     out << "  <Creature>" << endl; | ||||
|     element("Name", info.c_str(), out); | ||||
|     element("Nickname", cre->name.nickname.c_str(), out); | ||||
|     element("Sex", cre->sex == 0 ? "Female" : "Male", out); | ||||
|     element("Age", getCreatureAge(cre), out);       // Added age, active labors, and skills March 9, 2012
 | ||||
|     printAttributes(con, cre, out); | ||||
|     printTraits(con, cre, out); | ||||
|     printLabors(con, cre, out); | ||||
|     printSkills(con, cre, out); | ||||
| 
 | ||||
|     out << "  </Creature>" << endl; | ||||
| } | ||||
| 
 | ||||
| command_result export_dwarves (color_ostream &con, std::vector <std::string> & parameters) | ||||
| { | ||||
|     string filename; | ||||
|     if (parameters.size() == 1) { | ||||
|         filename = parameters[0]; | ||||
|     } else { | ||||
|         con.print("export <filename>\n"); | ||||
|         return CR_OK; | ||||
|     } | ||||
| 
 | ||||
|     ofstream outf(filename.c_str()); | ||||
|     if (!outf) { | ||||
|         con.printerr("Failed to open file %s\n", filename.c_str()); | ||||
|         return CR_FAILURE; | ||||
|     } | ||||
| 
 | ||||
|     CoreSuspender suspend; | ||||
| 
 | ||||
|     uint32_t race = ui->race_id; | ||||
|     uint32_t civ = ui->civ_id; | ||||
| 
 | ||||
|     outf << "<?xml version='1.0' encoding='ibm850'?>" << endl << "<Creatures>" << endl; | ||||
| 
 | ||||
|     for (int i = 0; i < world->units.all.size(); ++i) | ||||
|     { | ||||
|         df::unit* cre = world->units.all[i]; | ||||
|         if (cre->race == race && cre->civ_id == civ) { | ||||
|             export_dwarf(con, cre, outf); | ||||
|         } | ||||
|     } | ||||
|     outf << "</Creatures>" << endl; | ||||
| 
 | ||||
|     return CR_OK; | ||||
| } | ||||
| @ -1 +0,0 @@ | ||||
| #pragma once | ||||
| @ -1,241 +0,0 @@ | ||||
| -- Stuff used by dfusion | ||||
| local _ENV = mkmodule('plugins.dfusion') | ||||
| 
 | ||||
| local ms=require("memscan") | ||||
| 
 | ||||
| local marker={0xDE,0xAD,0xBE,0xEF} | ||||
| --utility functions | ||||
| function dwordToTable(dword) | ||||
|     local b={bit32.extract(dword,0,8),bit32.extract(dword,8,8),bit32.extract(dword,16,8),bit32.extract(dword,24,8)} | ||||
|     return b | ||||
| end | ||||
| function concatTables(t1,t2) | ||||
|     for k,v in pairs(t2) do | ||||
|         table.insert(t1,v) | ||||
|     end | ||||
| end | ||||
| function makeCall(from,to) | ||||
|     local ret={0xe8} | ||||
|     concatTables(ret,dwordToTable(to-from-5)) | ||||
|     return ret | ||||
| end | ||||
| -- A reversable binary patch | ||||
| patches={} | ||||
| BinaryPatch=defclass(BinaryPatch) | ||||
| BinaryPatch.ATTRS {pre_data=DEFAULT_NIL,data=DEFAULT_NIL,address=DEFAULT_NIL,name=DEFAULT_NIL} | ||||
| function BinaryPatch:init(args) | ||||
|     self.is_applied=false | ||||
|     if args.pre_data==nil or args.data==nil or args.address==nil or args.name==nil then | ||||
|         error("Invalid parameters to binary patch") | ||||
|     end | ||||
|     if patches[self.name]~=nil then | ||||
|         error("Patch already exist") | ||||
|     end | ||||
| 
 | ||||
|     for k,v in ipairs(args.data) do | ||||
|         if args.pre_data[k]==nil then | ||||
|             error("can't edit without revert data") | ||||
|         end | ||||
|     end | ||||
| end | ||||
| function BinaryPatch:postinit(args) | ||||
|     patches[args.name]=self | ||||
| end | ||||
| function BinaryPatch:test() | ||||
|     local arr=ms.CheckedArray.new('uint8_t',self.address,self.address+#self.pre_data) | ||||
|     for k,v in ipairs(self.pre_data) do | ||||
|         if arr[k-1]~=v then | ||||
|             return false | ||||
|         end | ||||
|     end | ||||
|     return true | ||||
| end | ||||
| function BinaryPatch:apply() | ||||
|     if not self:test() then | ||||
|         error(string.format("pre-data for binary patch does not match expected")) | ||||
|     end | ||||
| 
 | ||||
|     local post_buf=df.new('uint8_t',#self.pre_data) | ||||
|     for k,v in ipairs(self.pre_data) do | ||||
|         if self.data[k]==nil then | ||||
|             post_buf[k-1]=v | ||||
|         else | ||||
|             post_buf[k-1]=self.data[k] | ||||
|         end | ||||
|     end | ||||
|     local ret=dfhack.with_finalize(function() post_buf:delete() end,dfhack.internal.patchMemory,self.address,post_buf,#self.pre_data) | ||||
|     if not ret then | ||||
|         error("Patch application failed!") | ||||
|     end | ||||
|     self.is_applied=true | ||||
| end | ||||
| function BinaryPatch:repatch(newdata) | ||||
|     if newdata==nil then newdata=self.data end | ||||
|     self:remove() | ||||
|     self.data=newdata | ||||
|     self:apply() | ||||
| end | ||||
| function BinaryPatch:remove(delete) | ||||
|     if delete==nil then | ||||
|         delete=true | ||||
|     end | ||||
|     if not self.is_applied then | ||||
|         error("can't remove BinaryPatch, not applied.") | ||||
|     end | ||||
|     local arr=ms.CheckedArray.new('uint8_t',self.address,self.address+#self.pre_data) | ||||
| 
 | ||||
|     local post_buf=df.new('uint8_t',#self.pre_data) | ||||
|     for k,v in pairs(self.pre_data) do | ||||
|             post_buf[k-1]=v | ||||
|     end | ||||
|     local ret=dfhack.with_finalize(function() post_buf:delete() end,dfhack.internal.patchMemory,self.address,post_buf,#self.pre_data) | ||||
|     if not ret then | ||||
|         error("Patch remove failed!") | ||||
|     end | ||||
|     self.is_applied=false | ||||
|     if delete then | ||||
|         patches[self.name]=nil | ||||
|     end | ||||
| 
 | ||||
| end | ||||
| 
 | ||||
| function BinaryPatch:__gc() | ||||
|     if self.is_applied then | ||||
|         self:remove() | ||||
|     end | ||||
| end | ||||
| -- A binary hack (obj file) loader/manager | ||||
| -- has to have: a way to get offsets for marked areas (for post load modification) or some way to do that pre-load | ||||
| -- page managing (including excecute/write flags for DEP and the like) | ||||
| -- TODO plugin state enum, a way to modify post install (could include repatching code...) | ||||
| plugins=plugins or {} | ||||
| BinaryPlugin=defclass(BinaryPlugin) | ||||
| BinaryPlugin.ATTRS {filename=DEFAULT_NIL,reloc_table={},name=DEFAULT_NIL} | ||||
| function BinaryPlugin:init(args) | ||||
| 
 | ||||
| end | ||||
| function BinaryPlugin:postinit(args) | ||||
|     if self.name==nil then error("Not a valid plugin name!") end | ||||
|     if plugins[args.name]==nil then | ||||
|         plugins[self.name]=self | ||||
|     else | ||||
|         error("Trying to create a same plugin") | ||||
|     end | ||||
|     self.allocated_object={} | ||||
|     self:load() | ||||
| end | ||||
| function BinaryPlugin:get_or_alloc(name,typename,arrsize) | ||||
|     if self.allocated_object[name]~=nil then | ||||
|         return self.allocated_object[name] | ||||
|     else | ||||
|         return self:allocate(name,typename,arrsize) | ||||
|     end | ||||
| end | ||||
| function BinaryPlugin:allocate(name,typename,arrsize) | ||||
|     local trg | ||||
|     if df[typename]==nil then | ||||
|         trg=df.new(typename,arrsize) | ||||
|         self.allocated_object[name]=trg | ||||
|     else | ||||
|         trg=df[typename]:new(arrsize) | ||||
|         self.allocated_object[name]=trg | ||||
|     end | ||||
|     return trg | ||||
| end | ||||
| function BinaryPlugin:load() | ||||
|     local obj=loadObjectFile(self.filename) | ||||
|     self.data=df.reinterpret_cast("uint8_t",obj.data) | ||||
|     self.size=obj.data_size | ||||
|     for _,v in pairs(obj.symbols) do | ||||
|         if string.sub(v.name,1,5)=="mark_" then | ||||
|             local new_pos=self:find_marker(v.pos) | ||||
|             self.reloc_table[string.sub(v.name,6)]=new_pos | ||||
|         end | ||||
|     end | ||||
| end | ||||
| function BinaryPlugin:find_marker(start_pos) | ||||
|     local matched=0 | ||||
|     for i=start_pos,self.size do | ||||
|         if self.data[i]==marker[4-matched] then | ||||
|             matched=matched+1 | ||||
|             if matched == 4 then | ||||
|                 return i-4 | ||||
|             end | ||||
|         end | ||||
|     end | ||||
| end | ||||
| 
 | ||||
| function BinaryPlugin:set_marker_dword(marker,dword) -- i hope Toady does not make a 64bit version... | ||||
|     if self.reloc_table[marker]==nil then | ||||
|         error("marker ".. marker.. " not found") | ||||
|     end | ||||
|     local b=dwordToTable(dword) | ||||
|     local off=self.reloc_table[marker] | ||||
|     for k,v in ipairs(b) do | ||||
|         self.data[off+k]=b[k] | ||||
|     end | ||||
| end | ||||
| function BinaryPlugin:move_to_df() | ||||
|     local _,addr=df.sizeof(self.data) | ||||
|     markAsExecutable(addr) | ||||
|     return addr | ||||
| end | ||||
| function BinaryPlugin:print_data() | ||||
|     local out="" | ||||
|     for i=0,self.size do | ||||
|         out=out..string.format(" %02x",self.data[i]) | ||||
|         if math.modf(i,16)==15 then | ||||
|             print(out) | ||||
|             out="" | ||||
|         end | ||||
|     end | ||||
|     print(out) | ||||
| end | ||||
| function BinaryPlugin:status() | ||||
|     return "invalid, base class only!" | ||||
| end | ||||
| function BinaryPlugin:__gc() | ||||
|     for k,v in pairs(self.allocated_object) do | ||||
|         df.delete(v) | ||||
|     end | ||||
|     if self.unload then | ||||
|         self:unload() | ||||
|     end | ||||
|     self.data:delete() | ||||
| end | ||||
| -- a Menu for some stuff. Maybe add a posibility of it working as a gui, or a gui adaptor? | ||||
| -- Todo add hints, and parse them to make a "smart" choice of parameters to pass | ||||
| SimpleMenu=defclass(SimpleMenu) | ||||
| SimpleMenu.ATTRS{title=DEFAULT_NIL} | ||||
| function SimpleMenu:init(args) | ||||
|     self.items={} | ||||
| end | ||||
| function SimpleMenu:add(name,entry,hints) | ||||
|     table.insert(self.items,{entry,name,hints}) | ||||
| end | ||||
| function SimpleMenu:display() | ||||
|     print("Select choice (q exits):") | ||||
|     for p,c in pairs(self.items) do | ||||
|         print(string.format("%3d).%s",p,c[2])) | ||||
|     end | ||||
|     local ans | ||||
|     repeat | ||||
|         local r | ||||
|         r=dfhack.lineedit() | ||||
|         if r==nil then return end | ||||
|         if r=='q' then return end | ||||
|         ans=tonumber(r) | ||||
| 
 | ||||
|         if ans==nil or not(ans<=#self.items and ans>0) then | ||||
|             print("Invalid choice.") | ||||
|         end | ||||
| 
 | ||||
|     until ans~=nil and (ans<=#self.items and ans>0) | ||||
|     if type(self.items[ans][1])=="function" then | ||||
|         self.items[ans][1]() | ||||
|     else | ||||
|         self.items[ans][1]:display() | ||||
|     end | ||||
| end | ||||
| 
 | ||||
| return _ENV | ||||
| @ -1,172 +0,0 @@ | ||||
| local _ENV = mkmodule('plugins.dfusion.adv_tools') | ||||
| local dfu=require("plugins.dfusion") | ||||
| local tools=require("plugins.dfusion.tools") | ||||
| menu=dfu.SimpleMenu() | ||||
| function Reincarnate(trg_unit,swap_soul) --only for adventurer i guess | ||||
|     if swap_soul==nil then | ||||
|         swap_soul=true | ||||
|     end | ||||
|     local adv=trg_unit or df.global.world.units.active[0] | ||||
|     if adv.flags1.dead==false then | ||||
|         qerror("You are not dead (yet)!") | ||||
|     end | ||||
|     local hist_fig=dfhack.units.getNemesis(adv).figure | ||||
|     if hist_fig==nil then | ||||
|         qerror("No historical figure for adventurer...") | ||||
|     end | ||||
|     local events=df.global.world.history.events | ||||
|     local trg_hist_fig | ||||
|     for i=#events-1,0,-1 do -- reverse search because almost always it will be last entry | ||||
|         if df.history_event_hist_figure_diedst:is_instance(events[i]) then | ||||
|             --print("is instance:"..i) | ||||
|             if events[i].victim_hf==hist_fig.id then | ||||
|                 --print("Is same id:"..i) | ||||
|                 trg_hist_fig=events[i].slayer_hf | ||||
|                 if trg_hist_fig then | ||||
|                     trg_hist_fig=df.historical_figure.find(trg_hist_fig) | ||||
|                 end | ||||
|                 break | ||||
|             end | ||||
|         end | ||||
|     end | ||||
|     if trg_hist_fig ==nil then | ||||
|         qerror("Slayer not found") | ||||
|     end | ||||
| 
 | ||||
|     local trg_unit=trg_hist_fig.unit_id | ||||
|     if trg_unit==nil then | ||||
|         qerror("Unit id not found!") | ||||
|     end | ||||
|     local trg_unit_final=df.unit.find(trg_unit) | ||||
| 
 | ||||
|     change_adv(trg_unit_final) | ||||
|     if swap_soul then --actually add a soul... | ||||
|         t_soul=adv.status.current_soul | ||||
|         adv.status.current_soul=df.NULL | ||||
|         adv.status.souls:resize(0) | ||||
|         trg_unit_final.status.current_soul=t_soul | ||||
|         trg_unit_final.status.souls:insert(#trg_unit_final.status.souls,t_soul) | ||||
|     end | ||||
| end | ||||
| menu:add("Reincarnate",Reincarnate,{{df.unit,"optional"}})-- bool, optional | ||||
| function change_adv(unit,nemesis) | ||||
|     if nemesis==nil then | ||||
|         nemesis=true --default value is nemesis switch too. | ||||
|     end | ||||
|     if unit==nil then | ||||
|         unit=dfhack.gui.getSelectedUnit()--getCreatureAtPointer() | ||||
|     end | ||||
|     if unit==nil then | ||||
|         error("Invalid unit!") | ||||
|     end | ||||
|     local other=df.global.world.units.active | ||||
|     local unit_indx | ||||
|     for k,v in pairs(other) do | ||||
|         if v==unit then | ||||
|             unit_indx=k | ||||
|             break | ||||
|         end | ||||
|     end | ||||
|     if unit_indx==nil then | ||||
|         error("Unit not found in array?!") --should not happen | ||||
|     end | ||||
|     other[unit_indx]=other[0] | ||||
|     other[0]=unit | ||||
|     if nemesis then --basicly copied from advtools plugin... | ||||
|         local nem=dfhack.units.getNemesis(unit) | ||||
|         local other_nem=dfhack.units.getNemesis(other[unit_indx]) | ||||
|         if other_nem then | ||||
|             other_nem.flags[0]=false | ||||
|             other_nem.flags[1]=true | ||||
|         end | ||||
|         if nem then | ||||
|             nem.flags[0]=true | ||||
|             nem.flags[2]=true | ||||
|             for k,v in pairs(df.global.world.nemesis.all) do | ||||
|                 if v.id==nem.id then | ||||
|                     df.global.ui_advmode.player_id=k | ||||
|                 end | ||||
|             end | ||||
|         else | ||||
|             qerror("Current unit does not have nemesis record, further working not guaranteed") | ||||
|         end | ||||
|     end | ||||
| end | ||||
| menu:add("Change adventurer",change_adv) | ||||
| function log_pos() | ||||
|     local adv=df.global.world.units.active[0] | ||||
| 
 | ||||
|     local wmap=df.global.world.map | ||||
|     local sub_pos={x=adv.pos.x,y=adv.pos.y,z=adv.pos.z} | ||||
|     local region_pos={x=wmap.region_x,y=wmap.region_y,z=wmap.region_z} | ||||
|     local pos={x=sub_pos.x+region_pos.x*48,y=sub_pos.y+region_pos.y*48,z=sub_pos.z+region_pos.z} | ||||
|     local state | ||||
|     if adv.flags1.dead then | ||||
|         state="dead" | ||||
|     else | ||||
|         state="live n kicking" | ||||
|     end | ||||
|     local message=string.format("%s %s at pos={%d,%d,%d} region={%d,%d,%d}",dfhack.TranslateName(adv.name),state,pos.x,pos.y,pos.z,region_pos.x,region_pos.y,region_pos.z) | ||||
|     print(message) | ||||
|     local path="deaths_"..df.global.world.cur_savegame.save_dir..".txt" | ||||
|     local f=io.open(path,"a") | ||||
|     f:write(message) | ||||
|     f:close() | ||||
| end | ||||
| menu:add("Log adventurers position",log_pos) | ||||
| function addSite(x,y,rgn_max_x,rgn_min_x,rgn_max_y,rgn_min_y,civ_id,name,sitetype) | ||||
|     if x==nil or y==nil then | ||||
|         x=(df.global.world.map.region_x+1)/16 | ||||
|         y=(df.global.world.map.region_y+1)/16 | ||||
|     end | ||||
|     if name==nil then | ||||
|         name=dfhack.lineedit("Site name:")or "Hacked site" | ||||
|     end | ||||
|     if sitetype==nil then | ||||
|         sitetype=tonumber(dfhack.lineedit("Site type (numeric):")) or 7 | ||||
|     end | ||||
|     rgn_max_x=rgn_max_x or (df.global.world.map.region_x+1)%16 | ||||
|     rgn_max_y=rgn_max_y or (df.global.world.map.region_y+1)%16 | ||||
|     rgn_min_y=rgn_min_y or rgn_max_y | ||||
|     rgn_min_x=rgn_min_x or rgn_max_x | ||||
|     print("Region:",rgn_max_x,rgn_min_x,rgn_max_y,rgn_min_y) | ||||
| --[=[ | ||||
| <angavrilov> global = pos*16 + rgn | ||||
| <angavrilov> BUT | ||||
| <angavrilov> for cities global is usually 17x17, i.e. max size | ||||
| <angavrilov> while rgn designates a small bit in the middle | ||||
| <angavrilov> for stuff like forts that formula holds exactly | ||||
| ]=]-- | ||||
|     local wd=df.global.world.world_data | ||||
|     local nsite=df.world_site:new() | ||||
|     nsite.name.first_name=name | ||||
|     nsite.name.has_name=true | ||||
|     nsite.pos:assign{x=x,y=y} | ||||
|     nsite.rgn_max_x=rgn_max_x | ||||
|     nsite.rgn_min_x=rgn_min_x | ||||
|     nsite.rgn_min_y=rgn_min_y | ||||
|     nsite.rgn_max_y=rgn_max_y | ||||
|     nsite.global_max_x=nsite.pos.x*16+nsite.rgn_max_x | ||||
|     nsite.global_min_x=nsite.pos.x*16+nsite.rgn_min_x | ||||
|     nsite.global_max_y=nsite.pos.y*16+nsite.rgn_max_y | ||||
|     nsite.global_min_y=nsite.pos.y*16+nsite.rgn_min_y | ||||
|     nsite.id=wd.next_site_id | ||||
|     nsite.civ_id=civ_id or -1 | ||||
|     nsite.cur_owner_id=civ_id or -1 | ||||
|     nsite.type=sitetype --lair = 7 | ||||
|     nsite.flags:resize(23) | ||||
|     --nsite.flags[4]=true | ||||
|     --nsite.flags[5]=true | ||||
|     --nsite.flags[6]=true | ||||
|     nsite.index=#wd.sites+1 | ||||
|     wd.sites:insert("#",nsite) | ||||
|     wd.next_site_id=wd.next_site_id+1 | ||||
|     --might not be needed... | ||||
|     --[[local unk130=df.world_site_unk130:new() | ||||
|     unk130.index=#wd.site_unk130+1 | ||||
|     wd.site_unk130:insert("#",unk130) | ||||
|     --wd.next_site_unk136_id=wd.next_site_unk136_id+1--]] | ||||
|     return nsite | ||||
| end | ||||
| menu:add("Create site at current location",addSite) | ||||
| return _ENV | ||||
| @ -1,124 +0,0 @@ | ||||
| local _ENV = mkmodule('plugins.dfusion.embark') | ||||
| local dfu=require("plugins.dfusion") | ||||
| local ms=require("memscan") | ||||
| local MAX_RACES=100 | ||||
| CustomEmbark=defclass(CustomEmbark,dfu.BinaryPlugin) | ||||
| local myos=dfhack.getOSType() | ||||
| if myos=="windows" then | ||||
|     CustomEmbark.ATTRS{filename="hack/lua/plugins/dfusion/embark.o",name="CustomEmbark",race_caste_data=DEFAULT_NIL} | ||||
|     function CustomEmbark:parseRaces(races) | ||||
|         if #races<7 then | ||||
|             error("caste and race count must be bigger than 6") | ||||
|         end | ||||
|         if #races>MAX_RACES then | ||||
|             error("caste and race count must be less then "..MAX_RACES) | ||||
|         end | ||||
|         local n_to_id=require("plugins.dfusion.tools").build_race_names() | ||||
| 
 | ||||
|         local ids={} | ||||
|         for k,v in pairs(races) do | ||||
|             local race=v[1] or v | ||||
|             ids[k]={} | ||||
|             ids[k][1]=n_to_id[race] | ||||
|             if ids[k][1]==nil then qerror(race.." not found!") end | ||||
|             ids[k][2]=v[2] or -1 | ||||
|         end | ||||
|         self.race_caste_data=ids | ||||
|     end | ||||
|     function CustomEmbark:install(race_caste_data) | ||||
|         local stoff=dfhack.internal.getAddress('start_dwarf_count') | ||||
|         if race_caste_data~=nil then | ||||
|             self:parseRaces(race_caste_data) | ||||
|         end | ||||
| 
 | ||||
|         if stoff==nil then | ||||
|             error("address for start_dwarf_count not found!") | ||||
|         end | ||||
|         local _,race_id_offset=df.sizeof(df.global.ui:_field("race_id")) | ||||
|         print(string.format("start=%08x",stoff)) | ||||
|         local needle={0x0f,0xb7,0x0d} --movzx eax,dword ptr [race_id] | ||||
|         local tmp_table=dfu.dwordToTable(race_id_offset) | ||||
|         for k,v in ipairs(tmp_table) do | ||||
|             table.insert(needle,v) | ||||
|         end | ||||
| 
 | ||||
|         local mem=ms.get_code_segment() | ||||
|         print(mem.uint8_t:addr2idx(stoff)) | ||||
|         print(mem.uint8_t:find(needle,mem.uint8_t:addr2idx(stoff))) | ||||
|         local _,trg_offset=mem.uint8_t:find(needle,mem.uint8_t:addr2idx(stoff),nil)--maybe endoff=stoff+bignumber | ||||
|         if trg_offset==nil then | ||||
|             error("address for race_load not found") | ||||
|         end | ||||
|         local call_data={0x90,0x90} | ||||
|         local _,data_offset=df.sizeof(self.data) | ||||
|         dfu.concatTables(call_data,dfu.makeCall(trg_offset+2,data_offset)) | ||||
|         self.call_patch=self.call_patch or dfu.BinaryPatch{pre_data=needle,data=call_data,address=trg_offset,name="custom_embark_call_patch"} | ||||
|         needle={0x83,0xc8,0xff} -- or eax, 0xFF | ||||
|         local _,caste_offset=mem.uint8_t:find(needle,mem.uint8_t:addr2idx(trg_offset),nil) | ||||
|         if caste_offset==nil or caste_offset-stoff>1000 then | ||||
|             error("Caste change code not found or found too far!") | ||||
|         end | ||||
| 
 | ||||
|         self.disable_castes=self.disable_castes or dfu.BinaryPatch{pre_data={0x83,0xc8,0xff},data={0x90,0x90,0x90},address=caste_offset,name="custom_embark_caste_disable"} | ||||
|         self.disable_castes:apply() | ||||
| 
 | ||||
| 
 | ||||
|         self:setEmbarkParty(self.race_caste_data) | ||||
|         local caste_array=self:get_or_alloc("caste_array","uint16_t",MAX_RACES) | ||||
|         local race_array=self:get_or_alloc("race_array","uint16_t",MAX_RACES) | ||||
| 
 | ||||
|         local race_array_off,caste_array_off | ||||
|         local _ | ||||
|         _,race_array_off=df.sizeof(race_array) | ||||
|         _,caste_array_off=df.sizeof(caste_array) | ||||
|         self:set_marker_dword("race",caste_array_off) --hehe... mixed them up i guess... | ||||
|         self:set_marker_dword("caste",race_array_off) | ||||
| 
 | ||||
|         self:move_to_df() | ||||
|         self.call_patch:apply() | ||||
|         self.installed=true | ||||
|     end | ||||
| 
 | ||||
|     function CustomEmbark:setEmbarkParty(racesAndCastes) | ||||
|         local stoff=dfhack.internal.getAddress('start_dwarf_count') | ||||
| 
 | ||||
| 
 | ||||
|         if self.dwarfcount== nil then | ||||
|             self.dwarfcount=dfu.BinaryPatch{pre_data=dfu.dwordToTable(7),data=dfu.dwordToTable(#self.race_caste_data),address=stoff,name="custom_embark_embarkcount"} | ||||
|             self.dwarfcount:apply() | ||||
|         else | ||||
|             self.dwarfcount:repatch(dfu.dwordToTable(#self.race_caste_data)) | ||||
|         end | ||||
|         local caste_array=self:get_or_alloc("caste_array","uint16_t",MAX_RACES) | ||||
|         local race_array=self:get_or_alloc("race_array","uint16_t",MAX_RACES) | ||||
| 
 | ||||
|         for k,v in ipairs(self.race_caste_data) do | ||||
|             caste_array[k-1]=v[2] or -1 | ||||
|             race_array[k-1]=v[1] | ||||
|         end | ||||
|     end | ||||
|     function CustomEmbark:status() | ||||
|         if self.installed then | ||||
|             return "valid, installed" | ||||
|         else | ||||
|             return "valid, not installed" | ||||
|         end | ||||
|     end | ||||
|     function CustomEmbark:uninstall() | ||||
|         if self.installed then | ||||
|             self.call_patch:remove() | ||||
|             self.disable_castes:remove() | ||||
|             self.dwarfcount:remove() | ||||
|         end | ||||
|     end | ||||
|     function CustomEmbark:unload() | ||||
|         self:uninstall() | ||||
|         if Embark~=nil then | ||||
|             Embark=nil | ||||
|         end | ||||
|     end | ||||
|     Embark=Embark or CustomEmbark() | ||||
| else | ||||
|     CustomEmbark.status=function() return"invalid, os not supported" end | ||||
| end | ||||
| return _ENV | ||||
											
												Binary file not shown.
											
										
									
								| @ -1,121 +0,0 @@ | ||||
| local _ENV = mkmodule('plugins.dfusion.friendship') | ||||
| local dfu=require("plugins.dfusion") | ||||
| local ms=require("memscan") | ||||
| 
 | ||||
| local MAX_RACES=100 | ||||
| local MAX_CODE_DIST=250 | ||||
| FriendshipRainbow=defclass(FriendshipRainbow,dfu.BinaryPlugin) | ||||
| FriendshipRainbow.name="FriendshipRainbow" | ||||
| -- os independant... I think... | ||||
| FriendshipRainbow.ATTRS{filename="hack/lua/plugins/dfusion/friendship.o",name="FriendshipRainbow",race_data=DEFAULT_NIL} | ||||
| FriendshipRainbow.class_status="valid, not installed" | ||||
| function FriendshipRainbow:findall_needles(codesg,needle) -- todo move to memscan.lua | ||||
|     local cidx,caddr=codesg.uint8_t:find(needle) | ||||
|     local ret={} | ||||
|     while cidx~=nil do | ||||
|        table.insert(ret,{cidx,caddr}) | ||||
|        cidx,caddr=codesg.uint8_t:find(needle,cidx+1) | ||||
|     end | ||||
|     return ret | ||||
| end | ||||
| function FriendshipRainbow:find_one(codesg,needle,crace) | ||||
|     dfu.concatTables(needle,dfu.dwordToTable(crace)) | ||||
|     return self:findall_needles(codesg,needle) | ||||
| end | ||||
| function FriendshipRainbow:find_all() | ||||
|     local code=ms.get_code_segment() | ||||
|     local locations={} | ||||
|     local _,crace=df.sizeof(df.global.ui:_field("race_id")) | ||||
| 
 | ||||
|     dfu.concatTables(locations,self:find_one(code,{0x66,0xa1},crace)) --mov ax,[ptr] | ||||
|     dfu.concatTables(locations,self:find_one(code,{0xa1},crace)) --mov ax,[ptr] | ||||
|     local registers= | ||||
|     {0x05, -- (e)ax | ||||
|     0x1d, --ebx | ||||
|     0x0d, --ecx | ||||
|     0x15, --edx | ||||
|     0x35, --esi | ||||
|     0x3d, --edi | ||||
|     --0x25, --esp not used? | ||||
|     --0x2d, --ebp not used? | ||||
|     } | ||||
|     for k,reg in ipairs(registers) do | ||||
| 
 | ||||
|         dfu.concatTables(locations,self:find_one(code,{0x0f,0xbf,reg},crace)) --movsx reg,[ptr] | ||||
|         dfu.concatTables(locations,self:find_one(code,{0x66,0x8b,reg},crace)) --mov reg,[ptr] | ||||
|     end | ||||
| 
 | ||||
|     return self:filter_locations(code,locations) | ||||
| end | ||||
| function FriendshipRainbow:filter_locations(codesg,locations) | ||||
|     local ret={} | ||||
|     local registers={0x80,0x83,0x81,0x82,0x86,0x87, | ||||
|                      0x98,0x9b,0x99,0x9a,0x9e,0x9f, | ||||
|                      0x88,0x8b,0x89,0x8a,0x8e,0x8f, | ||||
|                      0x90,0x93,0x91,0x92,0x96,0x97, | ||||
|                      0xb0,0xb3,0xb1,0xb2,0xb6,0xb7, | ||||
|                      0xb8,0xbb,0xb9,0xba,0xbe,0xbf} | ||||
|     for _,entry in ipairs(locations) do | ||||
|         for _,r in ipairs(registers) do | ||||
| 
 | ||||
|             local idx,addr=codesg.uint8_t:find({0x39,r,0x8c,0x00,0x00,0x00}, | ||||
|                 codesg.uint8_t:addr2idx(entry[2]),codesg.uint8_t:addr2idx(entry[2])+MAX_CODE_DIST) | ||||
|             if addr then | ||||
|                 table.insert(ret,{addr,r}) | ||||
|                 break | ||||
|             end | ||||
|             idx,addr=codesg.uint8_t:find({0x3b,r,0x8c,0x00,0x00,0x00}, | ||||
|                 codesg.uint8_t:addr2idx(entry[2]),codesg.uint8_t:addr2idx(entry[2])+MAX_CODE_DIST) | ||||
|             if addr then | ||||
|                 table.insert(ret,{addr,r}) | ||||
|                 break | ||||
|             end | ||||
|         end | ||||
|     end | ||||
|     return ret | ||||
| end | ||||
| function FriendshipRainbow:patchCalls(target) | ||||
|     local addrs=self:find_all() | ||||
|     local swaps={} | ||||
|     for k,adr in ipairs(addrs) do | ||||
|         local newval=dfu.makeCall(adr[1],target) | ||||
|         table.insert(newval,adr[2]) | ||||
|         for t,val in ipairs(newval) do | ||||
|             swaps[adr[1]+t-1]=val | ||||
|         end | ||||
|     end | ||||
|     dfhack.internal.patchBytes(swaps) | ||||
| end | ||||
| function FriendshipRainbow:set_races(arr) | ||||
|     local n_to_id=require("plugins.dfusion.tools").build_race_names() | ||||
|     local ids={} | ||||
|     for k,v in ipairs(self.race_data) do -- to check if all races are valid. | ||||
|         ids[k]=n_to_id[v] | ||||
|     end | ||||
|     for k,v in ipairs(ids) do | ||||
|         arr[k-1]=ids[k] | ||||
|     end | ||||
| end | ||||
| function FriendshipRainbow:install(races) | ||||
|         self.race_data=races or self.race_data | ||||
|         if #self.race_data<1 then | ||||
|             error("race count must be bigger than 0") | ||||
|         end | ||||
|         if #self.race_data>MAX_RACES then | ||||
|             error("race count must be less then "..MAX_RACES) | ||||
|         end | ||||
|         local rarr=self:allocate("race_array",'uint16_t',MAX_RACES) | ||||
|         local _,rarr_offset=df.sizeof(rarr) | ||||
|         self:set_marker_dword("racepointer",rarr_offset) | ||||
|         self:set_races(rarr) | ||||
|         self:set_marker_dword("racecount",#self.race_data) | ||||
|         local safe_loc=self:allocate("safe_loc",'uint32_t',1) | ||||
|         local _1,safe_loc_offset=df.sizeof(safe_loc) | ||||
|         self:set_marker_dword("safeloc1",safe_loc_offset) | ||||
|         self:set_marker_dword("safeloc2",safe_loc_offset) | ||||
|         local addr=self:move_to_df() | ||||
|         self:patchCalls(addr) | ||||
|         self.installed=true | ||||
| end | ||||
| Friendship=Friendship or FriendshipRainbow() | ||||
| return _ENV | ||||
											
												Binary file not shown.
											
										
									
								| @ -1 +0,0 @@ | ||||
| as  -anl --32 -o friendship.o friendship.asm | ||||
| @ -1,7 +0,0 @@ | ||||
| .intel_syntax | ||||
| mov eax , [esp+0x1C] # loop counter | ||||
| mark_caste: | ||||
| movsx ecx, word ptr[eax*2+0xdeadbeef] | ||||
| mark_race: | ||||
| movzx eax,word ptr [eax*2+0xDEADBEEF] | ||||
| ret | ||||
| @ -1,106 +0,0 @@ | ||||
| .intel_syntax | ||||
| push eax | ||||
| mov eax,[esp+0x04] | ||||
| push ebx | ||||
| pushfd | ||||
| mov eax,[eax] # get a byte after the call this procedure to analyze what register holds cr ptr | ||||
| jmptbl: | ||||
| cmp al,0x81 | ||||
| jz regC | ||||
| cmp al,0x82 | ||||
| jz regD | ||||
| cmp al,0x83 | ||||
| jz regB | ||||
| cmp al,0x85 | ||||
| jz regBP | ||||
| cmp al,0x86 | ||||
| jz regESI | ||||
| cmp al,0x87 | ||||
| jz regEDI | ||||
| cmp al,0x88 | ||||
| jz regA | ||||
| cmp al,0x8A | ||||
| jz regD | ||||
| cmp al,0x8B | ||||
| jz regB | ||||
| cmp al,0x8D | ||||
| jz regBP | ||||
| cmp al,0x8E | ||||
| jz regESI | ||||
| cmp al,0x8F | ||||
| jz regEDI | ||||
| cmp al,0x90 | ||||
| jz regA | ||||
| cmp al,0x91 | ||||
| jz regC | ||||
| cmp al,0x93 | ||||
| jz regB | ||||
| cmp al,0x95 | ||||
| jz regBP | ||||
| cmp al,0x96 | ||||
| jz regESI | ||||
| cmp al,0x97 | ||||
| jz regEDI | ||||
| jmp fail | ||||
| regA: | ||||
| mov eax, [esp+0x8] | ||||
| mov eax, [eax+0x8c] | ||||
| jmp compare | ||||
| regC: | ||||
| mov eax, [ecx+0x8c] | ||||
| jmp compare | ||||
| regB: | ||||
| mov eax, [ebx+0x8c] | ||||
| jmp compare | ||||
| regD: | ||||
| mov eax, [edx+0x8c] | ||||
| jmp compare | ||||
| regBP: | ||||
| mov eax, [ebp+0x8c] | ||||
| jmp compare | ||||
| regESI: | ||||
| mov eax, [esi+0x8c] | ||||
| jmp compare | ||||
| regEDI: | ||||
| mov eax, [edi+0x8c] | ||||
| #jmp compare | ||||
| compare: | ||||
| push ecx | ||||
| mark_racepointer: | ||||
| mov ebx,0xDEADBEEF #write a pointer to the list of allowed races | ||||
| mark_racecount: | ||||
| mov ecx,0xDEADBEEF #write a number of allowed races | ||||
| loop1: | ||||
| cmp word[ebx+ecx*2],ax | ||||
| jz endok | ||||
| dec ecx | ||||
| cmp ecx ,-1 | ||||
| jnz loop1 | ||||
| pop ecx | ||||
| popfd | ||||
| jmp fail | ||||
| endok: | ||||
| pop ecx | ||||
| popfd | ||||
| cmp eax,eax | ||||
| jmp endfinal | ||||
| fail: | ||||
| 
 | ||||
| xor ebx,ebx | ||||
| xor eax,eax | ||||
| inc eax | ||||
| cmp eax,ebx | ||||
| endfinal: | ||||
| 
 | ||||
| pop ebx | ||||
| pop eax | ||||
| mark_safeloc1: | ||||
| mov [0xDEADBEEF],eax #write a pointer to safe location (usually after this) | ||||
| pop eax | ||||
| pushfd | ||||
| inc eax #skip one instruction | ||||
| popfd | ||||
| push eax | ||||
| mark_safeloc2: | ||||
| mov eax,[0xDEADBEEF] #write a pointer to safe location (same as above) | ||||
| ret | ||||
| @ -1,243 +0,0 @@ | ||||
| local _ENV = mkmodule('plugins.dfusion.tools') | ||||
| local dfu=require("plugins.dfusion") | ||||
| local ms=require "memscan" | ||||
| menu=dfu.SimpleMenu() | ||||
| RaceNames={} | ||||
| function build_race_names() | ||||
|     if #RaceNames~=0 then | ||||
|         return RaceNames | ||||
|     else | ||||
|         for k,v in pairs(df.global.world.raws.creatures.all) do | ||||
|             RaceNames[v.creature_id]=k | ||||
|         end | ||||
|         dfhack.onStateChange.invalidate_races=function(change_id) --todo does this work? | ||||
|             if change_id==SC_WORLD_UNLOADED then | ||||
|                 dfhack.onStateChange.invalidate_races=nil | ||||
|                 RaceNames={} | ||||
|             end | ||||
|         end | ||||
|         return RaceNames | ||||
|     end | ||||
| end | ||||
| function setrace(name) | ||||
|     local RaceTable=build_race_names() | ||||
|     print("Your current race is:"..df.global.world.raws.creatures.all[df.global.ui.race_id].creature_id) | ||||
|     local id | ||||
|     if name == nil then | ||||
|         print("Type new race's token name in full caps (q to quit):") | ||||
|         repeat | ||||
|             local entry=dfhack.lineedit() | ||||
|             if entry=="q" then | ||||
|                 return | ||||
|             end | ||||
|             id=RaceTable[entry] | ||||
|         until id~=nil | ||||
|     else | ||||
|         id=RaceTable[name] | ||||
|         if id==nil then | ||||
|             error("Name not found!") | ||||
|         end | ||||
|     end | ||||
|     df.global.ui.race_id=id | ||||
| end | ||||
| menu:add("Set current race",setrace) | ||||
| function GiveSentience(names) | ||||
|     local RaceTable=build_race_names() --slow.If loaded don't load again | ||||
|     local id,ids | ||||
|     if names ==nil then | ||||
|         ids={} | ||||
|         print("Type race's  token name in full caps to give sentience to:") | ||||
|         repeat | ||||
|             id=dfhack.lineedit() | ||||
|             id=RaceTable[entry] | ||||
|             if id~=nil then | ||||
|                 table.insert(ids,id) | ||||
|             end | ||||
|         until id==nil | ||||
| 
 | ||||
|     else | ||||
|         ids={} | ||||
|         for _,name in pairs(names) do | ||||
|             id=RaceTable[name] | ||||
|             table.insert(ids,id) | ||||
|         end | ||||
|     end | ||||
|     for _,id in pairs(ids) do | ||||
|         local races=df.global.world.raws.creatures.all | ||||
| 
 | ||||
|         local castes=races[id].caste | ||||
|         print(string.format("Caste count:%i",#castes)) | ||||
|         for i =0,#castes-1 do | ||||
| 
 | ||||
|             print("Caste name:"..castes[i].caste_id.."...") | ||||
| 
 | ||||
|             local flags=castes[i].flags | ||||
|             --print(string.format("%x",flagoffset)) | ||||
|             if flags.CAN_SPEAK then | ||||
|                 print("\tis sentient.") | ||||
|             else | ||||
|                 print("\tnon sentient. Allocating IQ...") | ||||
|                 flags.CAN_SPEAK=true | ||||
|             end | ||||
|         end | ||||
|     end | ||||
| end | ||||
| menu:add("Give Sentience",GiveSentience) | ||||
| function MakeFollow(unit,trgunit) | ||||
|     if unit == nil then | ||||
|         unit=dfhack.gui.getSelectedUnit() | ||||
|     end | ||||
|     if unit== nil then | ||||
|         error("Invalid creature") | ||||
|     end | ||||
|     if trgunit==nil then | ||||
|         trgunit=df.global.world.units.active[0] | ||||
|     end | ||||
|     unit.relations.group_leader_id=trgunit.id | ||||
|     local u_nem=dfhack.units.getNemesis(unit) | ||||
|     local t_nem=dfhack.units.getNemesis(trgunit) | ||||
|     if u_nem then | ||||
|         u_nem.group_leader_id=t_nem.id | ||||
|     end | ||||
|     if t_nem and u_nem then | ||||
|         t_nem.companions:insert(#t_nem.companions,u_nem.id) | ||||
|     end | ||||
| end | ||||
| menu:add("Make creature follow",MakeFollow) | ||||
| function project(unit,trg) --TODO add to menu? | ||||
|     if unit==nil then | ||||
|         unit=getCreatureAtPointer() | ||||
|     end | ||||
| 
 | ||||
|     if unit==nil then | ||||
|         error("Failed to project unit. Unit not selected/valid") | ||||
|     end | ||||
|     -- todo: add projectile to world, point to unit, add flag to unit, add gen-ref to projectile. | ||||
|     local p=df.proj_unitst:new() | ||||
|     local startpos={x=unit.pos.x,y=unit.pos.y,z=unit.pos.z} | ||||
|     p.origin_pos=startpos | ||||
|     p.target_pos=trg | ||||
|     p.cur_pos=startpos | ||||
|     p.prev_pos=startpos | ||||
|     p.unit=unit | ||||
|     --- wtf stuff | ||||
|     p.unk14=100 | ||||
|     p.unk16=-1 | ||||
|     p.unk23=-1 | ||||
|     p.fall_delay=5 | ||||
|     p.fall_counter=5 | ||||
|     p.collided=true | ||||
|     -- end wtf | ||||
|     local citem=df.global.world.proj_list | ||||
|     local maxid=1 | ||||
|     local newlink=df.proj_list_link:new() | ||||
|     newlink.item=p | ||||
|     while citem.item~= nil do | ||||
|         if citem.item.id>maxid then maxid=citem.item.id end | ||||
|         if citem.next ~= nil then | ||||
|             citem=citem.next | ||||
|         else | ||||
|             break | ||||
|         end | ||||
|     end | ||||
|     p.id=maxid+1 | ||||
|     newlink.prev=citem | ||||
|     citem.next=newlink | ||||
|     local proj_ref=df.general_ref_projectile:new() | ||||
|     proj_ref.projectile_id=p.id | ||||
|     unit.general_refs:insert(#unit.general_refs,proj_ref) | ||||
|     unit.flags1.projectile=true | ||||
| end | ||||
| function empregnate(unit) | ||||
|     if unit==nil then | ||||
|         unit=dfhack.gui.getSelectedUnit() | ||||
|     end | ||||
|     if unit==nil then | ||||
|         error("Failed to empregnate. Unit not selected/valid") | ||||
|     end | ||||
|     if unit.curse then | ||||
|         unit.curse.add_tags2.STERILE=false | ||||
|     end | ||||
|     local genes = unit.appearance.genes | ||||
|     if unit.relations.pregnancy_genes == nil then | ||||
|         print("creating preg ptr.") | ||||
|         if false then | ||||
|             print(string.format("%x %x",df.sizeof(unit.relations:_field("pregnancy_genes")))) | ||||
|             return | ||||
|         end | ||||
|         unit.relations.pregnancy_genes = { new = true, assign = genes } | ||||
|     end | ||||
|     local ngenes = unit.relations.pregnancy_genes | ||||
|     if #ngenes.appearance ~= #genes.appearance or #ngenes.colors ~= #genes.colors then | ||||
|         print("Array sizes incorrect, fixing.") | ||||
|         ngenes:assign(genes); | ||||
|     end | ||||
|     print("Setting preg timer.") | ||||
|     unit.relations.pregnancy_timer=10 | ||||
|     unit.relations.pregnancy_caste=1 | ||||
| end | ||||
| menu:add("Empregnate",empregnate) | ||||
| function healunit(unit) | ||||
|     if unit==nil then | ||||
|         unit=dfhack.gui.getSelectedUnit() | ||||
|     end | ||||
| 
 | ||||
|     if unit==nil then | ||||
|         error("Failed to Heal unit. Unit not selected/valid") | ||||
|     end | ||||
| 
 | ||||
|     unit.body.wounds:resize(0) -- memory leak here :/ | ||||
|     unit.body.blood_count=unit.body.blood_max | ||||
|     --set flags for standing and grasping... | ||||
|     unit.status2.limbs_stand_max=4 | ||||
|     unit.status2.limbs_stand_count=4 | ||||
|     unit.status2.limbs_grasp_max=4 | ||||
|     unit.status2.limbs_grasp_count=4 | ||||
|     --should also set temperatures, and flags for breath etc... | ||||
|     unit.flags1.dead=false | ||||
|     unit.flags2.calculated_bodyparts=false | ||||
|     unit.flags2.calculated_nerves=false | ||||
|     unit.flags2.circulatory_spray=false | ||||
|     unit.flags2.vision_good=true | ||||
|     unit.flags2.vision_damaged=false | ||||
|     unit.flags2.vision_missing=false | ||||
|     unit.counters.winded=0 | ||||
|     unit.counters.unconscious=0 | ||||
|     for k,v in pairs(unit.body.components) do | ||||
|         for kk,vv in pairs(v) do | ||||
|             if k == 'body_part_status' then v[kk].whole = 0  else v[kk] = 0 end | ||||
|         end | ||||
|     end | ||||
| end | ||||
| menu:add("Heal unit",healunit) | ||||
| function powerup(unit,labor_rating,military_rating,skills) | ||||
|     if unit==nil then | ||||
|         unit=dfhack.gui.getSelectedUnit() | ||||
|     end | ||||
|     if unit==nil then | ||||
|         error("Failed to power up unit. Unit not selected/valid") | ||||
|     end | ||||
| 
 | ||||
|     if unit.status.current_soul== nil then | ||||
|         error("Failed to power up unit. Unit has no soul") | ||||
|     end | ||||
|     local utils = require 'utils' | ||||
|     labor_rating = labor_rating or 15 | ||||
|     military_rating = military_rating or 70 | ||||
| 
 | ||||
|     skill =skill or { 0,2,3,4,5,6,7,8,9,10,11,12,13,14,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,41,42,43,44,45,46,47,48,49,54,55,57,58,59,60,61,62,63,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,95,96,97,98,99,100,101,102,103,104,105,109,110,111,112,113,114,115 } | ||||
|     local military = { 38,39,41,42,43,44,45,46,54,99,100,101,102,103,104,105 } | ||||
| 
 | ||||
|     for sk,sv in ipairs(skill) do | ||||
|     local new_rating = labor_rating | ||||
|     for _,v in ipairs(military) do | ||||
|       if v == sv then | ||||
|         local new_rating = military_rating | ||||
|       end | ||||
|     end | ||||
|     utils.insert_or_update(unit.status.current_soul.skills, { new = true, id = sv, rating = new_rating, experience = (new_rating * 500) + (new_rating * (new_rating - 1)) * 50}, 'id') | ||||
|     end | ||||
| 
 | ||||
| end | ||||
| menu:add("Power up",powerup) | ||||
| return _ENV | ||||
| @ -1 +0,0 @@ | ||||
| proto/*.pb.* | ||||
| @ -1,43 +0,0 @@ | ||||
| PROJECT(mapexport) | ||||
| 
 | ||||
| # add *our* headers here. | ||||
| SET(PROJECT_HDRS | ||||
| ) | ||||
| 
 | ||||
| SET(PROJECT_SRCS | ||||
| mapexport.cpp | ||||
| ) | ||||
| 
 | ||||
| SET(PROJECT_PROTOS | ||||
| ${CMAKE_CURRENT_SOURCE_DIR}/proto/Tile.proto | ||||
| ${CMAKE_CURRENT_SOURCE_DIR}/proto/Plant.proto | ||||
| ${CMAKE_CURRENT_SOURCE_DIR}/proto/Block.proto | ||||
| ${CMAKE_CURRENT_SOURCE_DIR}/proto/Material.proto | ||||
| ${CMAKE_CURRENT_SOURCE_DIR}/proto/Map.proto | ||||
| ) | ||||
| 
 | ||||
| #Create new lists of what sources and headers protoc will output after we invoke it | ||||
| STRING(REPLACE ".proto" ".pb.cc;" PROJECT_PROTO_SRCS ${PROJECT_PROTOS}) | ||||
| STRING(REPLACE ".proto" ".pb.h;" PROJECT_PROTO_HDRS ${PROJECT_PROTOS}) | ||||
| 
 | ||||
| SET_SOURCE_FILES_PROPERTIES( ${PROJECT_PROTO_HDRS} PROPERTIES GENERATED TRUE) | ||||
| SET_SOURCE_FILES_PROPERTIES( ${PROJECT_PROTO_SRCS} PROPERTIES GENERATED TRUE) | ||||
| 
 | ||||
| LIST(APPEND PROJECT_HDRS ${PROJECT_PROTO_HDRS}) | ||||
| LIST(APPEND PROJECT_SRCS ${PROJECT_PROTO_SRCS}) | ||||
| 
 | ||||
| SET_SOURCE_FILES_PROPERTIES( ${PROJECT_HDRS} PROPERTIES HEADER_FILE_ONLY TRUE) | ||||
| LIST(APPEND PROJECT_SRCS ${PROJECT_HDRS}) | ||||
| 
 | ||||
| #Generate sources from our proto files and store them in the source tree | ||||
| ADD_CUSTOM_COMMAND( | ||||
| OUTPUT ${PROJECT_PROTO_SRCS} ${PROJECT_PROTO_HDRS} | ||||
| COMMAND protoc-bin -I=${CMAKE_CURRENT_SOURCE_DIR}/proto/ --cpp_out=${CMAKE_CURRENT_SOURCE_DIR}/proto/ ${PROJECT_PROTOS} | ||||
| DEPENDS protoc-bin ${PROJECT_PROTOS} | ||||
| ) | ||||
| 
 | ||||
| IF(WIN32) | ||||
|     DFHACK_PLUGIN(mapexport ${PROJECT_SRCS} ${PROJECT_HDRS} LINK_LIBRARIES protobuf-lite) | ||||
| ELSE() | ||||
|     DFHACK_PLUGIN(mapexport ${PROJECT_SRCS} ${PROJECT_HDRS} LINK_LIBRARIES protobuf-lite) | ||||
| ENDIF() | ||||
| @ -1,325 +0,0 @@ | ||||
| #include "Core.h" | ||||
| #include "Console.h" | ||||
| #include "Export.h" | ||||
| #include "PluginManager.h" | ||||
| #include "modules/MapCache.h" | ||||
| using namespace DFHack; | ||||
| 
 | ||||
| #include <fstream> | ||||
| #include <google/protobuf/io/coded_stream.h> | ||||
| #include <google/protobuf/io/zero_copy_stream_impl.h> | ||||
| #include <google/protobuf/io/gzip_stream.h> | ||||
| using namespace google::protobuf::io; | ||||
| 
 | ||||
| #include "DataDefs.h" | ||||
| #include "df/world.h" | ||||
| #include "df/plant.h" | ||||
| #include "modules/Constructions.h" | ||||
| 
 | ||||
| #include "proto/Map.pb.h" | ||||
| #include "proto/Block.pb.h" | ||||
| 
 | ||||
| using namespace DFHack; | ||||
| using df::global::world; | ||||
| /*
 | ||||
| mapexport | ||||
| ========= | ||||
| Export the current loaded map as a file. This was used by visualizers for | ||||
| DF 0.34.11, but is now basically obsolete. | ||||
| */ | ||||
| 
 | ||||
| typedef std::vector<df::plant *> PlantList; | ||||
| 
 | ||||
| command_result mapexport (color_ostream &out, std::vector <std::string> & parameters); | ||||
| 
 | ||||
| DFHACK_PLUGIN("mapexport"); | ||||
| 
 | ||||
| DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands) | ||||
| { | ||||
|     GOOGLE_PROTOBUF_VERIFY_VERSION; | ||||
|     commands.push_back(PluginCommand("mapexport", "Exports the current map to a file.", mapexport, true)); | ||||
|     return CR_OK; | ||||
| } | ||||
| 
 | ||||
| DFhackCExport command_result plugin_shutdown ( color_ostream &out ) | ||||
| { | ||||
|     return CR_OK; | ||||
| } | ||||
| 
 | ||||
| static dfproto::Tile::TileMaterialType toProto(df::tiletype_material mat) | ||||
| { | ||||
|     /*
 | ||||
|      * This is surely ugly, but casting enums without officially | ||||
|      * defined numerical values to protobuf enums is against the | ||||
|      * way protobufs are supposed to be used, because it defeats | ||||
|      * the backward compatible nature of the protocols. | ||||
|      */ | ||||
|     switch (mat) | ||||
|     { | ||||
| #define CONVERT(name) case tiletype_material::name: return dfproto::Tile::name; | ||||
|         case tiletype_material::NONE: | ||||
|         CONVERT(AIR) | ||||
|         case tiletype_material::PLANT: | ||||
|         CONVERT(SOIL) | ||||
|         CONVERT(STONE) | ||||
|         CONVERT(FEATURE) | ||||
|         CONVERT(LAVA_STONE) | ||||
|         CONVERT(MINERAL) | ||||
|         CONVERT(FROZEN_LIQUID) | ||||
|         CONVERT(CONSTRUCTION) | ||||
|         CONVERT(GRASS_LIGHT) | ||||
|         CONVERT(GRASS_DARK) | ||||
|         CONVERT(GRASS_DRY) | ||||
|         CONVERT(GRASS_DEAD) | ||||
|         CONVERT(HFS) | ||||
|         CONVERT(CAMPFIRE) | ||||
|         CONVERT(FIRE) | ||||
|         CONVERT(ASHES) | ||||
|         case tiletype_material::MAGMA: | ||||
|             return dfproto::Tile::MAGMA_TYPE; | ||||
|         CONVERT(DRIFTWOOD) | ||||
|         CONVERT(POOL) | ||||
|         CONVERT(BROOK) | ||||
|         CONVERT(RIVER) | ||||
| #undef CONVERT | ||||
|     } | ||||
|     return dfproto::Tile::AIR; | ||||
| } | ||||
| 
 | ||||
| command_result mapexport (color_ostream &out, std::vector <std::string> & parameters) | ||||
| { | ||||
|     bool showHidden = false; | ||||
| 
 | ||||
|     int filenameParameter = 1; | ||||
| 
 | ||||
|     for(size_t i = 0; i < parameters.size();i++) | ||||
|     { | ||||
|         if(parameters[i] == "help" || parameters[i] == "?") | ||||
|         { | ||||
|             out.print("Exports the currently visible map to a file.\n" | ||||
|                          "Usage: mapexport [options] <filename>\n" | ||||
|                          "Example: mapexport all embark.dfmap\n" | ||||
|                          "Options:\n" | ||||
|                          "   all   - Export the entire map, not just what's revealed.\n" | ||||
|             ); | ||||
|             return CR_OK; | ||||
|         } | ||||
|         if (parameters[i] == "all") | ||||
|         { | ||||
|             showHidden = true; | ||||
|             filenameParameter++; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     CoreSuspender suspend; | ||||
| 
 | ||||
|     uint32_t x_max=0, y_max=0, z_max=0; | ||||
| 
 | ||||
|     if (!Maps::IsValid()) | ||||
|     { | ||||
|         out.printerr("Map is not available!\n"); | ||||
|         return CR_FAILURE; | ||||
|     } | ||||
| 
 | ||||
|     if (parameters.size() < filenameParameter) | ||||
|     { | ||||
|         out.printerr("Please supply a filename.\n"); | ||||
|         return CR_FAILURE; | ||||
|     } | ||||
| 
 | ||||
|     std::string filename = parameters[filenameParameter-1]; | ||||
|     if (filename.rfind(".dfmap") == std::string::npos) filename += ".dfmap"; | ||||
|     out << "Writing to " << filename << "..." << std::endl; | ||||
| 
 | ||||
|     std::ofstream output_file(filename.c_str(), std::ios::out | std::ios::trunc | std::ios::binary); | ||||
|     if (!output_file.is_open()) | ||||
|     { | ||||
|         out.printerr("Couldn't open the output file.\n"); | ||||
|         return CR_FAILURE; | ||||
|     } | ||||
|     ZeroCopyOutputStream *raw_output = new OstreamOutputStream(&output_file); | ||||
|     GzipOutputStream *zip_output = new GzipOutputStream(raw_output); | ||||
|     CodedOutputStream *coded_output = new CodedOutputStream(zip_output); | ||||
| 
 | ||||
|     coded_output->WriteLittleEndian32(0x50414DDF); //Write our file header
 | ||||
| 
 | ||||
|     Maps::getSize(x_max, y_max, z_max); | ||||
|     MapExtras::MapCache map; | ||||
|     DFHack::Materials *mats = Core::getInstance().getMaterials(); | ||||
| 
 | ||||
|     out << "Writing  map info..." << std::endl; | ||||
| 
 | ||||
|     dfproto::Map protomap; | ||||
|     protomap.set_x_size(x_max); | ||||
|     protomap.set_y_size(y_max); | ||||
|     protomap.set_z_size(z_max); | ||||
| 
 | ||||
|     out << "Writing material dictionary..." << std::endl; | ||||
| 
 | ||||
|     for (size_t i = 0; i < world->raws.inorganics.size(); i++) | ||||
|     { | ||||
|         dfproto::Material *protomaterial = protomap.add_inorganic_material(); | ||||
|         protomaterial->set_index(i); | ||||
|         protomaterial->set_name(world->raws.inorganics[i]->id); | ||||
|     } | ||||
| 
 | ||||
|     for (size_t i = 0; i < world->raws.plants.all.size(); i++) | ||||
|     { | ||||
|         dfproto::Material *protomaterial = protomap.add_organic_material(); | ||||
|         protomaterial->set_index(i); | ||||
|         protomaterial->set_name(world->raws.plants.all[i]->id); | ||||
|     } | ||||
| 
 | ||||
|     std::map<df::coord,std::pair<uint32_t,uint16_t> > constructionMaterials; | ||||
|     if (Constructions::isValid()) | ||||
|     { | ||||
|         for (uint32_t i = 0; i < Constructions::getCount(); i++) | ||||
|         { | ||||
|             df::construction *construction = Constructions::getConstruction(i); | ||||
|             constructionMaterials[construction->pos] = std::make_pair(construction->mat_index, construction->mat_type); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     coded_output->WriteVarint32(protomap.ByteSize()); | ||||
|     protomap.SerializeToCodedStream(coded_output); | ||||
| 
 | ||||
|     DFHack::t_feature blockFeatureGlobal; | ||||
|     DFHack::t_feature blockFeatureLocal; | ||||
| 
 | ||||
|     out.print("Writing map block information"); | ||||
| 
 | ||||
|     for(uint32_t z = 0; z < z_max; z++) | ||||
|     { | ||||
|         for(uint32_t b_y = 0; b_y < y_max; b_y++) | ||||
|         { | ||||
|             for(uint32_t b_x = 0; b_x < x_max; b_x++) | ||||
|             { | ||||
|                 if (b_x == 0 && b_y == 0 && z % 10 == 0) out.print("."); | ||||
|                 // Get the map block
 | ||||
|                 df::coord2d blockCoord(b_x, b_y); | ||||
|                 MapExtras::Block *b = map.BlockAt(DFHack::DFCoord(b_x, b_y, z)); | ||||
|                 if (!b || !b->is_valid()) | ||||
|                 { | ||||
|                     continue; | ||||
|                 } | ||||
| 
 | ||||
|                 dfproto::Block protoblock; | ||||
|                 protoblock.set_x(b_x); | ||||
|                 protoblock.set_y(b_y); | ||||
|                 protoblock.set_z(z); | ||||
| 
 | ||||
|                 // Find features
 | ||||
|                 b->GetGlobalFeature(&blockFeatureGlobal); | ||||
|                 b->GetLocalFeature(&blockFeatureLocal); | ||||
| 
 | ||||
|                 int global_z = df::global::world->map.region_z + z; | ||||
| 
 | ||||
|                 // Iterate over all the tiles in the block
 | ||||
|                 for(uint32_t y = 0; y < 16; y++) | ||||
|                 { | ||||
|                     for(uint32_t x = 0; x < 16; x++) | ||||
|                     { | ||||
|                         df::coord2d coord(x, y); | ||||
|                         df::tile_designation des = b->DesignationAt(coord); | ||||
|                         df::tile_occupancy occ = b->OccupancyAt(coord); | ||||
| 
 | ||||
|                         // Skip hidden tiles
 | ||||
|                         if (!showHidden && des.bits.hidden) | ||||
|                         { | ||||
|                             continue; | ||||
|                         } | ||||
| 
 | ||||
|                         dfproto::Tile *prototile = protoblock.add_tile(); | ||||
|                         prototile->set_x(x); | ||||
|                         prototile->set_y(y); | ||||
| 
 | ||||
|                         // Check for liquid
 | ||||
|                         if (des.bits.flow_size) | ||||
|                         { | ||||
|                             prototile->set_liquid_type((dfproto::Tile::LiquidType)des.bits.liquid_type); | ||||
|                             prototile->set_flow_size(des.bits.flow_size); | ||||
|                         } | ||||
| 
 | ||||
|                         df::tiletype type = b->tiletypeAt(coord); | ||||
|                         prototile->set_type((dfproto::Tile::TileType)tileShape(type)); | ||||
|                         prototile->set_tile_material(toProto(tileMaterial(type))); | ||||
| 
 | ||||
|                         df::coord map_pos = df::coord(b_x*16+x,b_y*16+y,z); | ||||
| 
 | ||||
|                         switch (tileMaterial(type)) | ||||
|                         { | ||||
|                         case tiletype_material::SOIL: | ||||
|                         case tiletype_material::STONE: | ||||
|                             prototile->set_material_type(0); | ||||
|                             prototile->set_material_index(b->layerMaterialAt(coord)); | ||||
|                             break; | ||||
|                         case tiletype_material::MINERAL: | ||||
|                             prototile->set_material_type(0); | ||||
|                             prototile->set_material_index(b->veinMaterialAt(coord)); | ||||
|                             break; | ||||
|                         case tiletype_material::FEATURE: | ||||
|                             if (blockFeatureLocal.type != -1 && des.bits.feature_local) | ||||
|                             { | ||||
|                                 if (blockFeatureLocal.type == feature_type::deep_special_tube | ||||
|                                         && blockFeatureLocal.main_material == 0) // stone
 | ||||
|                                 { | ||||
|                                     prototile->set_material_type(0); | ||||
|                                     prototile->set_material_index(blockFeatureLocal.sub_material); | ||||
|                                 } | ||||
|                                 if (blockFeatureGlobal.type != -1 && des.bits.feature_global | ||||
|                                         && blockFeatureGlobal.type == feature_type::feature_underworld_from_layer | ||||
|                                         && blockFeatureGlobal.main_material == 0) // stone
 | ||||
|                                 { | ||||
|                                     prototile->set_material_type(0); | ||||
|                                     prototile->set_material_index(blockFeatureGlobal.sub_material); | ||||
|                                 } | ||||
|                             } | ||||
|                             break; | ||||
|                         case tiletype_material::CONSTRUCTION: | ||||
|                             if (constructionMaterials.find(map_pos) != constructionMaterials.end()) | ||||
|                             { | ||||
|                                 prototile->set_material_index(constructionMaterials[map_pos].first); | ||||
|                                 prototile->set_material_type(constructionMaterials[map_pos].second); | ||||
|                             } | ||||
|                             break; | ||||
|                         default: | ||||
|                             break; | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
| 
 | ||||
|                 if (b->getRaw()) | ||||
|                 { | ||||
|                     PlantList *plants = &b->getRaw()->plants; | ||||
|                     for (PlantList::const_iterator it = plants->begin(); it != plants->end(); it++) | ||||
|                     { | ||||
|                         const df::plant & plant = *(*it); | ||||
|                         df::coord2d loc(plant.pos.x, plant.pos.y); | ||||
|                         loc = loc % 16; | ||||
|                         if (showHidden || !b->DesignationAt(loc).bits.hidden) | ||||
|                         { | ||||
|                             dfproto::Plant *protoplant = protoblock.add_plant(); | ||||
|                             protoplant->set_x(loc.x); | ||||
|                             protoplant->set_y(loc.y); | ||||
|                             protoplant->set_is_shrub(plant.flags.bits.is_shrub); | ||||
|                             protoplant->set_material(plant.material); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
| 
 | ||||
|                 coded_output->WriteVarint32(protoblock.ByteSize()); | ||||
|                 protoblock.SerializeToCodedStream(coded_output); | ||||
|             } // block x
 | ||||
|             // Clean uneeded memory
 | ||||
|             map.trash(); | ||||
|         } // block y
 | ||||
|     } // z
 | ||||
| 
 | ||||
|     delete coded_output; | ||||
|     delete zip_output; | ||||
|     delete raw_output; | ||||
| 
 | ||||
|     mats->Finish(); | ||||
|     out.print("\nMap succesfully exported!\n"); | ||||
|     return CR_OK; | ||||
| } | ||||
| @ -1,14 +0,0 @@ | ||||
| package dfproto; | ||||
| option optimize_for = LITE_RUNTIME; | ||||
| 
 | ||||
| import "Tile.proto"; | ||||
| import "Plant.proto"; | ||||
| 
 | ||||
| message Block | ||||
| { | ||||
|     required uint32 x = 1; | ||||
|     required uint32 y = 2; | ||||
|     required uint32 z = 3; | ||||
|     repeated Tile tile = 4; | ||||
|     repeated Plant plant = 5; | ||||
| } | ||||
| @ -1,13 +0,0 @@ | ||||
| package dfproto; | ||||
| option optimize_for = LITE_RUNTIME; | ||||
| 
 | ||||
| import "Material.proto"; | ||||
| 
 | ||||
| message Map | ||||
| { | ||||
|     required uint32 x_size = 1; | ||||
|     required uint32 y_size = 2; | ||||
|     required uint32 z_size = 3; | ||||
|     repeated Material inorganic_material = 4; | ||||
|     repeated Material organic_material = 5; | ||||
| } | ||||
| @ -1,8 +0,0 @@ | ||||
| package dfproto; | ||||
| option optimize_for = LITE_RUNTIME; | ||||
| 
 | ||||
| message Material | ||||
| { | ||||
|     required uint32 index= 1; | ||||
|     required string name = 2; | ||||
| } | ||||
| @ -1,10 +0,0 @@ | ||||
| package dfproto; | ||||
| option optimize_for = LITE_RUNTIME; | ||||
| 
 | ||||
| message Plant | ||||
| { | ||||
|     required uint32 x = 1; | ||||
|     required uint32 y = 2; | ||||
|     required bool is_shrub = 3; | ||||
|     optional uint32 material = 4; | ||||
| } | ||||
| @ -1,63 +0,0 @@ | ||||
| package dfproto; | ||||
| option optimize_for = LITE_RUNTIME; | ||||
| 
 | ||||
| message Tile | ||||
| { | ||||
|     enum TileType | ||||
|     { | ||||
|         EMPTY = 0; | ||||
|         FLOOR = 1; | ||||
|         BOULDER = 2; | ||||
|         PEBBLES = 3; | ||||
|         WALL = 4; | ||||
|         FORTIFICATION = 5; | ||||
|         STAIR_UP = 6; | ||||
|         STAIR_DOWN = 7; | ||||
|         STAIR_UPDOWN = 8; | ||||
|         RAMP = 9; | ||||
|         RAMP_TOP = 10; | ||||
|         BROOK_BED = 11; | ||||
|         BROOK_TOP = 12; | ||||
|         TREE = 13; | ||||
|         SAPLING = 14; | ||||
|         SHRUB = 15; | ||||
|         ENDLESS_PIT = 16; | ||||
|     } | ||||
|     enum LiquidType | ||||
|     { | ||||
|         WATER = 0; | ||||
|         MAGMA = 1; | ||||
|     } | ||||
|     enum TileMaterialType | ||||
|     { | ||||
|         AIR = 0; | ||||
|         SOIL = 1; | ||||
|         STONE = 2; | ||||
|         FEATURE = 3; | ||||
|         LAVA_STONE = 4; | ||||
|         MINERAL = 5; | ||||
|         FROZEN_LIQUID = 6; | ||||
|         CONSTRUCTION = 7; | ||||
|         GRASS_LIGHT = 8; | ||||
|         GRASS_DARK = 9; | ||||
|         GRASS_DRY = 10; | ||||
|         GRASS_DEAD = 11; | ||||
|         HFS = 12; | ||||
|         CAMPFIRE = 13; | ||||
|         FIRE = 14; | ||||
|         ASHES = 15; | ||||
|         MAGMA_TYPE = 16; | ||||
|         DRIFTWOOD = 17; | ||||
|         POOL = 18; | ||||
|         BROOK = 19; | ||||
|         RIVER = 20; | ||||
|     } | ||||
|     required uint32 x = 1; | ||||
|     required uint32 y = 2; | ||||
|     required TileType type = 3; | ||||
|     optional TileMaterialType tile_material = 4; | ||||
|     optional uint32 material_index = 5; | ||||
|     optional uint32 material_type = 6; | ||||
|     optional LiquidType liquid_type = 7; | ||||
|     optional uint32 flow_size = 8; | ||||
| } | ||||
| @ -1,22 +0,0 @@ | ||||
| -- a collection of misc lua scripts | ||||
| --[[=begin | ||||
| 
 | ||||
| dfusion | ||||
| ======= | ||||
| Interface to a lecacy script system. | ||||
| 
 | ||||
| =end]] | ||||
| 
 | ||||
| local dfu=require("plugins.dfusion") | ||||
| local myos=dfhack.getOSType() | ||||
| args={...} | ||||
| mainmenu=dfu.SimpleMenu() | ||||
| function runsave() | ||||
|     local path=string.format("data/save/%s/dfhack.lua",df.global.world.cur_savegame.save_dir) | ||||
|     print("doing file:"..path) | ||||
|     loadfile(path)() | ||||
| end | ||||
| mainmenu:add("Run save script",runsave) | ||||
| mainmenu:add("Adventurer tools",require("plugins.dfusion.adv_tools").menu) | ||||
| mainmenu:add("Misc tools",require("plugins.dfusion.tools").menu) | ||||
| mainmenu:display() | ||||
		Loading…
	
		Reference in New Issue