jackpoz

ArcEmu LuaEngine LHA fix

Aug 6th, 2011
184
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. Index: src/scripts/src/LuaEngine/LUAEngine.cpp
  2. ===================================================================
  3. --- src/scripts/src/LuaEngine/LUAEngine.cpp (revision 4445)
  4. +++ src/scripts/src/LuaEngine/LUAEngine.cpp (working copy)
  5. @@ -280,9 +280,9 @@
  6.     if(unit != NULL && unit->IsUnit())
  7.         pUnit = TO_UNIT(unit);
  8.     if(L == NULL)
  9. -       ArcLuna<Unit>::push(lu, pUnit);
  10. +       ArcSole<Unit>::push(lu, pUnit);
  11.     else
  12. -       ArcLuna<Unit>::push(L, pUnit);
  13. +       ArcSole<Unit>::push(L, pUnit);
  14.  }
  15.  void LuaEngine::PushGo(Object* go, lua_State* L)
  16.  {
  17. @@ -290,9 +290,9 @@
  18.     if(go != NULL && go->IsGameObject())
  19.         pGo = TO< GameObject* >(go);
  20.     if(L == NULL)
  21. -       ArcLuna<GameObject>::push(lu, pGo);
  22. +       ArcSole<GameObject>::push(lu, pGo);
  23.     else
  24. -       ArcLuna<GameObject>::push(L, pGo);
  25. +       ArcSole<GameObject>::push(L, pGo);
  26.  }
  27.  void LuaEngine::PushItem(Object* item, lua_State* L)
  28.  {
  29. @@ -586,9 +586,9 @@
  30.  
  31.     RegisterGlobalFunctions(lu);
  32.  
  33. -   ArcLuna<Unit>::Register(lu);
  34. +   ArcSole<Unit>::Register(lu);
  35.     ArcLuna<Item>::Register(lu);
  36. -   ArcLuna<GameObject>::Register(lu);
  37. +   ArcSole<GameObject>::Register(lu);
  38.     ArcLuna<WorldPacket>::Register(lu);
  39.     ArcLuna<TaxiPath>::Register(lu);
  40.     ArcLuna<Spell>::Register(lu);
  41. Index: src/scripts/src/LuaEngine/LUAEngine.h
  42. ===================================================================
  43. --- src/scripts/src/LuaEngine/LUAEngine.h   (revision 4445)
  44. +++ src/scripts/src/LuaEngine/LUAEngine.h   (working copy)
  45. @@ -301,13 +301,13 @@
  46.         //Wrappers
  47.         ARCEMU_INLINE Unit* CheckUnit(lua_State* L, int narg)
  48.         {
  49. -           if(L == NULL) return ArcLuna<Unit>::check(lu, narg);
  50. -           else return ArcLuna<Unit>::check(L, narg);
  51. +           if(L == NULL) return ArcSole<Unit>::check(lu, narg);
  52. +           else return ArcSole<Unit>::check(L, narg);
  53.         }
  54.         ARCEMU_INLINE GameObject* CheckGo(lua_State* L, int narg)
  55.         {
  56. -           if(L == NULL) return ArcLuna<GameObject>::check(lu, narg);
  57. -           else return ArcLuna<GameObject>::check(L, narg);
  58. +           if(L == NULL) return ArcSole<GameObject>::check(lu, narg);
  59. +           else return ArcSole<GameObject>::check(L, narg);
  60.         }
  61.         ARCEMU_INLINE Item* CheckItem(lua_State* L, int narg)
  62.         {
  63. @@ -326,8 +326,8 @@
  64.         }
  65.         ARCEMU_INLINE Object* CheckObject(lua_State* L, int narg)
  66.         {
  67. -           if(L == NULL) return ArcLuna<Object>::check(lu, narg);
  68. -           else return ArcLuna<Object>::check(L, narg);
  69. +           if(L == NULL) return ArcSole<Object>::check(lu, narg);
  70. +           else return ArcSole<Object>::check(L, narg);
  71.         }
  72.         ARCEMU_INLINE TaxiPath* CheckTaxiPath(lua_State* L, int narg)
  73.         {
  74. @@ -775,6 +775,205 @@
  75.                     return 1;
  76.                 }
  77.         };
  78. +
  79. +       //As opposed to ArcLuna, this is meant to bring some light to this Lua Engine plagued by crashes since r1, caused by pushing on the stack Object*
  80. +       //references that could point to free'd memory. It will push object* (and derived types) as guid + mapid + instanceid.
  81. +       template <typename T>
  82. +       class ArcSole
  83. +       {
  84. +           private:
  85. +               uint64 guid;
  86. +               uint32 mapId;
  87. +               int32 instanceId;
  88. +
  89. +               T* Get()
  90. +               {
  91. +                   Object* object = NULL;
  92. +                   MapMgr* mapMgr = sInstanceMgr.GetMapMgr(mapId);
  93. +                   if(mapMgr == NULL)
  94. +                   {
  95. +                       //if mapMgr is NULL then it's probably an instance
  96. +                       Instance * instance = sInstanceMgr.GetInstanceByIds(mapId, instanceId);
  97. +                       if(instance != NULL)
  98. +                           object = instance->m_mapMgr->_GetObject(guid);
  99. +                   }
  100. +                   else
  101. +                       object = mapMgr->_GetObject(guid);
  102. +                   return TO<T*>(object);
  103. +               }
  104. +           public:
  105. +               typedef int (*mfp)(lua_State *L, T* ptr);
  106. +               typedef struct { const char *name; mfp mfunc; } RegType;
  107. +
  108. +               static void Register(lua_State *L)
  109. +               {
  110. +                   lua_newtable(L);
  111. +                   int methods = lua_gettop(L);
  112. +
  113. +                   luaL_newmetatable(L, GetTClassName<T>());
  114. +                   int metatable = lua_gettop(L);
  115. +
  116. +                   luaL_newmetatable(L,"DO NOT TRASH");
  117. +                   lua_pop(L,1);
  118. +
  119. +                   // store method table in globals so that
  120. +                   // scripts can add functions written in Lua.
  121. +                   lua_pushvalue(L, methods);
  122. +                   lua_setglobal(L,GetTClassName<T>());
  123. +
  124. +                   // hide metatable from Lua getmetatable()
  125. +                   lua_pushvalue(L, methods);
  126. +                   lua_setfield(L, metatable, "__metatable");
  127. +
  128. +                   lua_pushcfunction(L,index);
  129. +                   lua_setfield(L, metatable, "__index");
  130. +
  131. +                   lua_pushcfunction(L, tostring_T);
  132. +                   lua_setfield(L, metatable, "__tostring");
  133. +
  134. +                   //nil gc method because world will take care of created Objects
  135. +                   lua_pushnil(L);
  136. +                   lua_setfield(L, metatable, "__gc");
  137. +
  138. +                   lua_newtable(L);                // mt for method table
  139. +                   lua_setmetatable(L, methods);
  140. +
  141. +                   // fill method table with methods from class T
  142. +                   for (RegType *l = ((RegType*)GetMethodTable<T>()); l->name; l++)
  143. +                   {
  144. +                       lua_pushstring(L, l->name);
  145. +                       lua_pushlightuserdata(L, (void*)l);
  146. +                       lua_pushcclosure(L, thunk, 1);
  147. +                       lua_settable(L, methods);
  148. +                   }
  149. +                   lua_pop(L, 2);  // drop metatable and method table
  150. +               }
  151. +
  152. +               // push onto the Lua stack a userdata containing a pointer to T object
  153. +               static int push(lua_State *L, T *obj, bool gc=false)
  154. +               {
  155. +                   if(obj == NULL)
  156. +                   {
  157. +                       lua_pushnil(L);
  158. +                       return lua_gettop(L);
  159. +                   }
  160. +
  161. +                   luaL_getmetatable(L, GetTClassName<T>());  // lookup metatable in Lua registry
  162. +                   if (lua_isnil(L, -1)) luaL_error(L, "%s missing metatable", GetTClassName<T>());
  163. +                   int mt = lua_gettop(L);
  164. +                   ArcSole* holder = TO<ArcSole*>(lua_newuserdata(L,sizeof(ArcSole)));
  165. +                   int ud = lua_gettop(L);
  166. +                   if(holder != NULL)
  167. +                   {
  168. +                       holder->guid = obj->GetGUID();
  169. +                       holder->mapId = obj->GetMapId();
  170. +                       holder->instanceId = obj->GetInstanceID();
  171. +
  172. +                       lua_pushvalue(L, mt);
  173. +                       lua_setmetatable(L, -2);
  174. +                       char name[32];
  175. +                       tostring(name,obj);
  176. +                       lua_getfield(L,LUA_REGISTRYINDEX,"DO NOT TRASH");
  177. +                       if(lua_isnil(L,-1) )
  178. +                       {
  179. +                           luaL_newmetatable(L,"DO NOT TRASH");
  180. +                           lua_pop(L,1);
  181. +                       }
  182. +                       lua_getfield(L,LUA_REGISTRYINDEX,"DO NOT TRASH");
  183. +                       if(gc == false)
  184. +                       {
  185. +                           lua_pushboolean(L,1);
  186. +                           lua_setfield(L,-2,name);
  187. +                       }
  188. +                       lua_pop(L,1);
  189. +                   }
  190. +                   lua_settop(L,ud);
  191. +                   lua_replace(L, mt);
  192. +                   lua_settop(L, mt);
  193. +                   return mt;  // index of userdata containing pointer to T object
  194. +               }
  195. +
  196. +               // get userdata from Lua stack and return pointer to T object
  197. +               static T *check(lua_State *L, int narg)
  198. +               {
  199. +                   ArcSole* holder = TO<ArcSole*>(lua_touserdata(L,narg));
  200. +                   if(holder == NULL)
  201. +                       return NULL;
  202. +                   return holder->Get();
  203. +               }
  204. +
  205. +           private:
  206. +               // member function dispatcher
  207. +               static int thunk(lua_State *L)
  208. +               {
  209. +                   // stack has userdata, followed by method args
  210. +                   T *obj = check(L, 1);  // get 'self', or if you prefer, 'this'
  211. +                   lua_remove(L, 1);  // remove self so member function args start at index 1
  212. +                   // get member function from upvalue
  213. +                   RegType *l = static_cast<RegType*>(lua_touserdata(L, lua_upvalueindex(1)));
  214. +                   //return (obj->*(l->mfunc))(L);  // call member function
  215. +                   return l->mfunc(L,obj);
  216. +               }
  217. +
  218. +               static int tostring_T (lua_State *L)
  219. +               {
  220. +                   char buff[32];
  221. +                   T ** ptrHold = (T**)lua_touserdata(L,1);
  222. +                   T *obj = *ptrHold;
  223. +                   sprintf(buff, "%p", obj);
  224. +                   lua_pushfstring(L, "%s (%s)", GetTClassName<T>(), buff);
  225. +                   return 1;
  226. +               }
  227. +               ARCEMU_INLINE static void tostring(char * buff,void * obj)
  228. +               {
  229. +                   sprintf(buff,"%p",obj);
  230. +               }
  231. +               static int index(lua_State * L)
  232. +               {
  233. +                   /*Paroxysm : the table obj and the missing key are currently on the stack(index 1 & 2) */
  234. +                   lua_getglobal(L,GetTClassName<T>());
  235. +                   // string form of the key.
  236. +                   const char * key = lua_tostring(L,2);
  237. +                   if(lua_istable(L,-1) )
  238. +                   {
  239. +                       lua_pushvalue(L,2);
  240. +                       lua_rawget(L,-2);
  241. +                       //If the key were looking for is not in the table, retrieve its' metatables' index value.
  242. +                       if(lua_isnil(L,-1))
  243. +                       {
  244. +                           lua_getmetatable(L,-2);
  245. +                           if(lua_istable(L,-1) )
  246. +                           {
  247. +                               lua_getfield(L,-1,"__index");
  248. +                               if(lua_isfunction(L,-1) )
  249. +                               {
  250. +                                   lua_pushvalue(L,1);
  251. +                                   lua_pushvalue(L,2);
  252. +                                   lua_pcall(L,2,1,0);
  253. +                               }
  254. +                               else if(lua_istable(L,-1) )
  255. +                                   lua_getfield(L,-1,key);
  256. +                               else
  257. +                                   lua_pushnil(L);
  258. +                           }
  259. +                           else
  260. +                               lua_pushnil(L);
  261. +                       }
  262. +                       else if(lua_istable(L,-1) )
  263. +                       {
  264. +                           lua_pushvalue(L,2);
  265. +                           lua_rawget(L,-2);
  266. +                       }
  267. +                   }
  268. +                   else
  269. +                       lua_pushnil(L);
  270. +
  271. +                   lua_insert(L,1);
  272. +                   lua_settop(L,1);
  273. +                   return 1;
  274. +               }
  275. +       };
  276. +
  277.         class GUID_MGR
  278.         {
  279.                 static const char* GetName() { return "WoWGUID"; }
RAW Paste Data