Add some bug and warning fixes as well as some enchantment from mthread branch

This commit is contained in:
Rochet2
2015-08-08 15:36:43 +03:00
parent 301869b8fb
commit 1bc22faa7f
6 changed files with 95 additions and 114 deletions

View File

@@ -136,32 +136,24 @@ public:
ASSERT(E); ASSERT(E);
ASSERT(name); ASSERT(name);
// check that metatable isn't already there
luaL_getmetatable(E->L, name);
ASSERT(lua_isnoneornil(E->L, -1));
// check that metatable isn't already there // check that metatable isn't already there
lua_getglobal(E->L, name); lua_getglobal(E->L, name);
ASSERT(lua_isnoneornil(E->L, -1)); ASSERT(lua_isnoneornil(E->L, -1));
// pop metatable and methodtable values // pop nil
lua_pop(E->L, 2); lua_pop(E->L, 1);
tname = name; tname = name;
manageMemory = gc; manageMemory = gc;
// create methodtable for userdata of this type // create metatable for userdata of this type
lua_newtable(E->L); lua_newtable(E->L);
int methods = lua_gettop(E->L); int metatable = lua_gettop(E->L);
// push methodtable to stack to be accessed and modified by users // push methodtable to stack to be accessed and modified by users
lua_pushvalue(E->L, methods); lua_pushvalue(E->L, metatable);
lua_setglobal(E->L, tname); lua_setglobal(E->L, tname);
// create metatable for userdatas of this type
ASSERT(luaL_newmetatable(E->L, tname));
int metatable = lua_gettop(E->L);
// tostring // tostring
lua_pushcfunction(E->L, ToString); lua_pushcfunction(E->L, ToString);
lua_setfield(E->L, metatable, "__tostring"); lua_setfield(E->L, metatable, "__tostring");
@@ -171,13 +163,9 @@ public:
lua_setfield(E->L, metatable, "__gc"); lua_setfield(E->L, metatable, "__gc");
// make methods accessible through metatable // make methods accessible through metatable
lua_pushvalue(E->L, methods); lua_pushvalue(E->L, metatable);
lua_setfield(E->L, metatable, "__index"); lua_setfield(E->L, metatable, "__index");
// make new indexes saved to methods
lua_pushvalue(E->L, methods);
lua_setfield(E->L, metatable, "__newindex");
// make new indexes saved to methods // make new indexes saved to methods
lua_pushcfunction(E->L, Add); lua_pushcfunction(E->L, Add);
lua_setfield(E->L, metatable, "__add"); lua_setfield(E->L, metatable, "__add");
@@ -232,14 +220,14 @@ public:
// special method to get the object type // special method to get the object type
lua_pushcfunction(E->L, GetType); lua_pushcfunction(E->L, GetType);
lua_setfield(E->L, methods, "GetObjectType"); lua_setfield(E->L, metatable, "GetObjectType");
// special method to decide object invalidation at end of call // special method to decide object invalidation at end of call
lua_pushcfunction(E->L, SetInvalidation); lua_pushcfunction(E->L, SetInvalidation);
lua_setfield(E->L, methods, "SetInvalidation"); lua_setfield(E->L, metatable, "SetInvalidation");
// pop methods and metatable // pop metatable
lua_pop(E->L, 2); lua_pop(E->L, 1);
} }
template<typename C> template<typename C>
@@ -250,12 +238,7 @@ public:
ASSERT(methodTable); ASSERT(methodTable);
// get metatable // get metatable
luaL_getmetatable(E->L, tname); lua_getglobal(E->L, tname);
ASSERT(lua_istable(E->L, -1));
// get method table
lua_getfield(E->L, -1, "__index");
lua_remove(E->L, -2);
ASSERT(lua_istable(E->L, -1)); ASSERT(lua_istable(E->L, -1));
for (; methodTable && methodTable->name && methodTable->mfunc; ++methodTable) for (; methodTable && methodTable->name && methodTable->mfunc; ++methodTable)
@@ -267,7 +250,7 @@ public:
lua_settable(E->L, -3); lua_settable(E->L, -3);
} }
lua_remove(E->L, -1); lua_pop(E->L, 1);
} }
static int Push(lua_State* L, T const* obj) static int Push(lua_State* L, T const* obj)
@@ -278,12 +261,12 @@ public:
return 1; return 1;
} }
//if (!manageMemory) void* obj_voidptr = static_cast<void*>(const_cast<T*>(obj));
//{
lua_getglobal(L, ELUNA_OBJECT_STORE); lua_getglobal(L, ELUNA_OBJECT_STORE);
ASSERT(lua_istable(L, -1)); ASSERT(lua_istable(L, -1));
lua_pushfstring(L, "%p", obj); lua_pushlightuserdata(L, obj_voidptr);
lua_gettable(L, -2); lua_rawget(L, -2);
if (ElunaObject* elunaObj = Eluna::CHECKTYPE(L, -1, tname, false)) if (ElunaObject* elunaObj = Eluna::CHECKTYPE(L, -1, tname, false))
{ {
// set userdata valid // set userdata valid
@@ -293,39 +276,35 @@ public:
lua_remove(L, -2); lua_remove(L, -2);
return 1; return 1;
} }
lua_remove(L, -1); lua_pop(L, 1);
// left userdata_table in stack // left userdata_table in stack
//}
// Create new userdata // Create new userdata
ElunaObject** ptrHold = static_cast<ElunaObject**>(lua_newuserdata(L, sizeof(ElunaObject*))); ElunaObject** ptrHold = static_cast<ElunaObject**>(lua_newuserdata(L, sizeof(ElunaObject*)));
if (!ptrHold) if (!ptrHold)
{ {
ELUNA_LOG_ERROR("%s could not create new userdata", tname); ELUNA_LOG_ERROR("%s could not create new userdata", tname);
lua_pop(L, 2 /*manageMemory ? 1 : 2*/); lua_pop(L, 2);
lua_pushnil(L); lua_pushnil(L);
return 1; return 1;
} }
*ptrHold = new ElunaObject((void*)(obj), manageMemory); *ptrHold = new ElunaObject(obj_voidptr, manageMemory);
// Set metatable for it // Set metatable for it
luaL_getmetatable(L, tname); lua_getglobal(L, tname);
if (!lua_istable(L, -1)) if (!lua_istable(L, -1))
{ {
ELUNA_LOG_ERROR("%s missing metatable", tname); ELUNA_LOG_ERROR("%s missing metatable", tname);
lua_pop(L, 3 /*manageMemory ? 2 : 3*/); lua_pop(L, 3);
lua_pushnil(L); lua_pushnil(L);
return 1; return 1;
} }
lua_setmetatable(L, -2); lua_setmetatable(L, -2);
//if (!manageMemory) lua_pushlightuserdata(L, obj_voidptr);
//{
lua_pushfstring(L, "%p", obj);
lua_pushvalue(L, -2); lua_pushvalue(L, -2);
lua_settable(L, -4); lua_rawset(L, -4);
lua_remove(L, -2); lua_remove(L, -2);
//}
return 1; return 1;
} }
@@ -335,31 +314,6 @@ public:
if (!elunaObj) if (!elunaObj)
return NULL; return NULL;
//if (!manageMemory)
//{
// // Check pointer validity
// lua_rawgeti(L, LUA_REGISTRYINDEX, sEluna->userdata_table);
// lua_pushfstring(L, "%p", (*ptrHold)->GetObj());
// lua_gettable(L, -2);
// lua_remove(L, -2);
// bool valid = lua_isuserdata(L, -1) != 0;
// lua_remove(L, -1);
// if (!valid)
// {
// char buff[256];
// snprintf(buff, 256, "%s expected, got pointer to nonexisting object (%s). This should never happen", tname, luaL_typename(L, narg));
// if (error)
// {
// luaL_argerror(L, narg, buff);
// }
// else
// {
// ELUNA_LOG_ERROR("%s", buff);
// }
// return NULL;
// }
//}
if (!elunaObj->IsValid()) if (!elunaObj->IsValid())
{ {
char buff[256]; char buff[256];

View File

@@ -131,7 +131,7 @@ void ElunaUtil::EncodeData(const unsigned char* data, size_t input_length, std::
unsigned char* ElunaUtil::DecodeData(const char *data, size_t *output_length) unsigned char* ElunaUtil::DecodeData(const char *data, size_t *output_length)
{ {
if (decoding_table['B'] == 0) if (decoding_table[(unsigned char)'B'] == 0)
build_decoding_table(); build_decoding_table();
size_t input_length = strlen(data); size_t input_length = strlen(data);
@@ -162,10 +162,10 @@ unsigned char* ElunaUtil::DecodeData(const char *data, size_t *output_length)
for (size_t i = 0, j = 0; i < input_length;) for (size_t i = 0, j = 0; i < input_length;)
{ {
uint32_t sextet_a = data[i] == '=' ? 0 & i++ : decoding_table[data[i++]]; uint32_t sextet_a = data[i] == '=' ? 0 & i++ : decoding_table[(unsigned char)data[i++]];
uint32_t sextet_b = data[i] == '=' ? 0 & i++ : decoding_table[data[i++]]; uint32_t sextet_b = data[i] == '=' ? 0 & i++ : decoding_table[(unsigned char)data[i++]];
uint32_t sextet_c = data[i] == '=' ? 0 & i++ : decoding_table[data[i++]]; uint32_t sextet_c = data[i] == '=' ? 0 & i++ : decoding_table[(unsigned char)data[i++]];
uint32_t sextet_d = data[i] == '=' ? 0 & i++ : decoding_table[data[i++]]; uint32_t sextet_d = data[i] == '=' ? 0 & i++ : decoding_table[(unsigned char)data[i++]];
uint32_t triple = (sextet_a << (3 * 6)) uint32_t triple = (sextet_a << (3 * 6))
+ (sextet_b << (2 * 6)) + (sextet_b << (2 * 6))

View File

@@ -238,21 +238,39 @@ namespace LuaGameObject
/** /**
* Removes [GameObject] from the world * Removes [GameObject] from the world
* *
* The object is no longer reachable after this and it is not respawned.
*
* @param bool deleteFromDB : if true, it will delete the [GameObject] from the database * @param bool deleteFromDB : if true, it will delete the [GameObject] from the database
*/ */
int RemoveFromWorld(Eluna* /*E*/, lua_State* L, GameObject* go) int RemoveFromWorld(Eluna* /*E*/, lua_State* L, GameObject* go)
{ {
bool deldb = Eluna::CHECKVAL<bool>(L, 2, false); bool deldb = Eluna::CHECKVAL<bool>(L, 2, false);
// cs_gobject.cpp copy paste
ObjectGuid ownerGuid = go->GetOwnerGUID();
if (ownerGuid)
{
Unit* owner = ObjectAccessor::GetUnit(*go, ownerGuid);
if (!owner || !ownerGuid.IsPlayer())
return 0;
owner->RemoveGameObject(go, false);
}
go->SetRespawnTime(0);
go->Delete();
if (deldb) if (deldb)
go->DeleteFromDB(); go->DeleteFromDB();
go->RemoveFromWorld();
Eluna::CHECKOBJ<ElunaObject>(L, 1)->Invalidate();
return 0; return 0;
} }
/** /**
* Changes uses a door or a button type [GameObject] * Activates a door or a button/lever
* *
* @param uint32 delay : cooldown time in seconds to restore the [GameObject] back to normal * @param uint32 delay = 0 : cooldown time in seconds to restore the [GameObject] back to normal. 0 for infinite duration
*/ */
int UseDoorOrButton(Eluna* /*E*/, lua_State* L, GameObject* go) int UseDoorOrButton(Eluna* /*E*/, lua_State* L, GameObject* go)
{ {
@@ -265,32 +283,35 @@ namespace LuaGameObject
/** /**
* Despawns a [GameObject] * Despawns a [GameObject]
* *
* @param uint32 delay : time in seconds to despawn * The gameobject may be automatically respawned by the core
*/ */
int Despawn(Eluna* /*E*/, lua_State* L, GameObject* go) int Despawn(Eluna* /*E*/, lua_State* L, GameObject* go)
{ {
uint32 delay = Eluna::CHECKVAL<uint32>(L, 2, 1); go->SetLootState(GO_JUST_DEACTIVATED);
if (!delay)
delay = 1;
go->SetSpawnedByDefault(false);
go->SetRespawnTime(delay);
return 0; return 0;
} }
/** /**
* Respawns a [GameObject] * Respawns a [GameObject]
*
* @param uint32 delay : time of respawn in seconds
*/ */
int Respawn(Eluna* /*E*/, lua_State* L, GameObject* go) int Respawn(Eluna* /*E*/, lua_State* L, GameObject* go)
{ {
uint32 delay = Eluna::CHECKVAL<uint32>(L, 2, 1); go->Respawn();
if (!delay) return 0;
delay = 1; }
go->SetSpawnedByDefault(true); /**
go->SetRespawnTime(delay); * Sets the respawn or despawn time for the gameobject.
*
* Respawn time is also used as despawn time depending on gameobject settings
*
* @param int32 delay = 0 : cooldown time in seconds to respawn or despawn the object. 0 means never
*/
int SetRespawnTime(Eluna* /*E*/, lua_State* L, GameObject* go)
{
int32 respawn = Eluna::CHECKVAL<int32>(L, 2);
go->SetRespawnTime(respawn);
return 0; return 0;
} }
}; };

View File

@@ -178,6 +178,8 @@ CreatureUniqueBindings(NULL)
Eluna::~Eluna() Eluna::~Eluna()
{ {
ASSERT(IsInitialized());
CloseLua(); CloseLua();
delete eventMgr; delete eventMgr;
@@ -901,13 +903,14 @@ ElunaObject* Eluna::CHECKTYPE(lua_State* luastate, int narg, const char* tname,
{ {
if (lua_getmetatable(luastate, narg)) if (lua_getmetatable(luastate, narg))
{ {
luaL_getmetatable(luastate, tname); lua_getglobal(luastate, tname);
if (lua_rawequal(luastate, -1, -2) == 1) bool equal = lua_rawequal(luastate, -1, -2) == 1;
lua_pop(luastate, 2);
if (equal)
{ {
valid = true; valid = true;
ptrHold = static_cast<ElunaObject**>(lua_touserdata(luastate, narg)); ptrHold = static_cast<ElunaObject**>(lua_touserdata(luastate, narg));
} }
lua_pop(luastate, 2);
} }
} }
@@ -916,7 +919,7 @@ ElunaObject* Eluna::CHECKTYPE(lua_State* luastate, int narg, const char* tname,
if (error) if (error)
{ {
char buff[256]; char buff[256];
snprintf(buff, 256, "bad argument : %s expected, got %s", tname ? tname : "userdata", luaL_typename(luastate, narg)); snprintf(buff, 256, "bad argument : %s expected, got %s", tname ? tname : "ElunaObject", luaL_typename(luastate, narg));
luaL_argerror(luastate, narg, buff); luaL_argerror(luastate, narg, buff);
} }
return NULL; return NULL;

View File

@@ -867,6 +867,7 @@ ElunaRegister<GameObject> GameObjectMethods[] =
// Setters // Setters
{ "SetGoState", &LuaGameObject::SetGoState }, { "SetGoState", &LuaGameObject::SetGoState },
{ "SetLootState", &LuaGameObject::SetLootState }, { "SetLootState", &LuaGameObject::SetLootState },
{ "SetRespawnTime", &LuaGameObject::SetRespawnTime },
// Boolean // Boolean
{ "IsTransport", &LuaGameObject::IsTransport }, { "IsTransport", &LuaGameObject::IsTransport },

View File

@@ -71,7 +71,7 @@ static void buf_init(lua_State *L, mar_Buffer *buf)
if (!(buf->data = (char*)malloc(buf->size))) luaL_error(L, "Out of memory!"); if (!(buf->data = (char*)malloc(buf->size))) luaL_error(L, "Out of memory!");
} }
static void buf_done(lua_State* L, mar_Buffer *buf) static void buf_done(lua_State* /*L*/, mar_Buffer *buf)
{ {
free(buf->data); free(buf->data);
} }
@@ -85,9 +85,11 @@ static int buf_write(lua_State* L, const char* str, size_t len, mar_Buffer *buf)
while (new_size - cur_head <= len) { while (new_size - cur_head <= len) {
new_size = new_size << 1; new_size = new_size << 1;
} }
if (!(buf->data = (char*)realloc(buf->data, new_size))) { char* data = (char*)realloc(buf->data, new_size);
luaL_error(L, "Out of memory!"); if (!data) {
return luaL_error(L, "Out of memory!");
} }
buf->data = data;
buf->size = new_size; buf->size = new_size;
} }
memcpy(&buf->data[buf->head], str, len); memcpy(&buf->data[buf->head], str, len);
@@ -95,7 +97,7 @@ static int buf_write(lua_State* L, const char* str, size_t len, mar_Buffer *buf)
return 0; return 0;
} }
static const char* buf_read(lua_State *L, mar_Buffer *buf, size_t *len) static const char* buf_read(lua_State* /*L*/, mar_Buffer *buf, size_t *len)
{ {
if (buf->seek < buf->head) { if (buf->seek < buf->head) {
buf->seek = buf->head; buf->seek = buf->head;
@@ -225,7 +227,7 @@ static void mar_encode_value(lua_State *L, mar_Buffer *buf, int val, size_t *idx
buf_done(L, &rec_buf); buf_done(L, &rec_buf);
lua_pop(L, 1); lua_pop(L, 1);
lua_newtable(L); lua_createtable(L, ar.nups, 0);
for (i = 1; i <= ar.nups; i++) { for (i = 1; i <= ar.nups; i++) {
const char* upvalue_name = lua_getupvalue(L, -2, i); const char* upvalue_name = lua_getupvalue(L, -2, i);
if (strcmp("_ENV", upvalue_name) == 0) { if (strcmp("_ENV", upvalue_name) == 0) {
@@ -469,7 +471,7 @@ static int mar_decode_table(lua_State *L, const char* buf, size_t len, size_t *i
while (p - buf < (ptrdiff_t)len) { while (p - buf < (ptrdiff_t)len) {
mar_decode_value(L, buf, len, &p, idx); mar_decode_value(L, buf, len, &p, idx);
mar_decode_value(L, buf, len, &p, idx); mar_decode_value(L, buf, len, &p, idx);
lua_settable(L, -3); lua_rawset(L, -3);
} }
return 1; return 1;
} }