Fix leak and possible segfault in minetest.set_mapgen_params

This commit is contained in:
kwolekr 2013-12-08 01:37:41 -05:00
parent 83cc882335
commit 3cc45fd8ad
1 changed files with 42 additions and 40 deletions

View File

@ -81,45 +81,45 @@ struct EnumString ModApiMapgen::es_Rotation[] =
int ModApiMapgen::l_get_mapgen_object(lua_State *L) int ModApiMapgen::l_get_mapgen_object(lua_State *L)
{ {
const char *mgobjstr = lua_tostring(L, 1); const char *mgobjstr = lua_tostring(L, 1);
int mgobjint; int mgobjint;
if (!string_to_enum(es_MapgenObject, mgobjint, mgobjstr ? mgobjstr : "")) if (!string_to_enum(es_MapgenObject, mgobjint, mgobjstr ? mgobjstr : ""))
return 0; return 0;
enum MapgenObject mgobj = (MapgenObject)mgobjint; enum MapgenObject mgobj = (MapgenObject)mgobjint;
EmergeManager *emerge = getServer(L)->getEmergeManager(); EmergeManager *emerge = getServer(L)->getEmergeManager();
Mapgen *mg = emerge->getCurrentMapgen(); Mapgen *mg = emerge->getCurrentMapgen();
if (!mg) if (!mg)
return 0; return 0;
size_t maplen = mg->csize.X * mg->csize.Z; size_t maplen = mg->csize.X * mg->csize.Z;
int nargs = 1; int nargs = 1;
switch (mgobj) { switch (mgobj) {
case MGOBJ_VMANIP: { case MGOBJ_VMANIP: {
ManualMapVoxelManipulator *vm = mg->vm; ManualMapVoxelManipulator *vm = mg->vm;
// VoxelManip object // VoxelManip object
LuaVoxelManip *o = new LuaVoxelManip(vm, true); LuaVoxelManip *o = new LuaVoxelManip(vm, true);
*(void **)(lua_newuserdata(L, sizeof(void *))) = o; *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
luaL_getmetatable(L, "VoxelManip"); luaL_getmetatable(L, "VoxelManip");
lua_setmetatable(L, -2); lua_setmetatable(L, -2);
// emerged min pos // emerged min pos
push_v3s16(L, vm->m_area.MinEdge); push_v3s16(L, vm->m_area.MinEdge);
// emerged max pos // emerged max pos
push_v3s16(L, vm->m_area.MaxEdge); push_v3s16(L, vm->m_area.MaxEdge);
nargs = 3; nargs = 3;
break; } break; }
case MGOBJ_HEIGHTMAP: { case MGOBJ_HEIGHTMAP: {
if (!mg->heightmap) if (!mg->heightmap)
return 0; return 0;
lua_newtable(L); lua_newtable(L);
for (size_t i = 0; i != maplen; i++) { for (size_t i = 0; i != maplen; i++) {
lua_pushinteger(L, mg->heightmap[i]); lua_pushinteger(L, mg->heightmap[i]);
@ -129,7 +129,7 @@ int ModApiMapgen::l_get_mapgen_object(lua_State *L)
case MGOBJ_BIOMEMAP: { case MGOBJ_BIOMEMAP: {
if (!mg->biomemap) if (!mg->biomemap)
return 0; return 0;
lua_newtable(L); lua_newtable(L);
for (size_t i = 0; i != maplen; i++) { for (size_t i = 0; i != maplen; i++) {
lua_pushinteger(L, mg->biomemap[i]); lua_pushinteger(L, mg->biomemap[i]);
@ -140,14 +140,14 @@ int ModApiMapgen::l_get_mapgen_object(lua_State *L)
case MGOBJ_HUMIDMAP: case MGOBJ_HUMIDMAP:
if (strcmp(emerge->params->mg_name.c_str(), "v7")) if (strcmp(emerge->params->mg_name.c_str(), "v7"))
return 0; return 0;
MapgenV7 *mgv7 = (MapgenV7 *)mg; MapgenV7 *mgv7 = (MapgenV7 *)mg;
float *arr = (mgobj == MGOBJ_HEATMAP) ? float *arr = (mgobj == MGOBJ_HEATMAP) ?
mgv7->noise_heat->result : mgv7->noise_humidity->result; mgv7->noise_heat->result : mgv7->noise_humidity->result;
if (!arr) if (!arr)
return 0; return 0;
lua_newtable(L); lua_newtable(L);
for (size_t i = 0; i != maplen; i++) { for (size_t i = 0; i != maplen; i++) {
lua_pushnumber(L, arr[i]); lua_pushnumber(L, arr[i]);
@ -155,7 +155,7 @@ int ModApiMapgen::l_get_mapgen_object(lua_State *L)
} }
break; } break; }
} }
return nargs; return nargs;
} }
@ -167,25 +167,25 @@ int ModApiMapgen::l_set_mapgen_params(lua_State *L)
return 0; return 0;
EmergeManager *emerge = getServer(L)->getEmergeManager(); EmergeManager *emerge = getServer(L)->getEmergeManager();
if (emerge->mapgen.size()) if (!emerge || emerge->mapgen.size())
return 0; return 0;
MapgenParams *oparams = new MapgenParams; MapgenParams *oparams = new MapgenParams;
u32 paramsmodified = 0; u32 paramsmodified = 0;
u32 flagmask = 0; u32 flagmask = 0;
lua_getfield(L, 1, "mgname"); lua_getfield(L, 1, "mgname");
if (lua_isstring(L, -1)) { if (lua_isstring(L, -1)) {
oparams->mg_name = std::string(lua_tostring(L, -1)); oparams->mg_name = std::string(lua_tostring(L, -1));
paramsmodified |= MGPARAMS_SET_MGNAME; paramsmodified |= MGPARAMS_SET_MGNAME;
} }
lua_getfield(L, 1, "seed"); lua_getfield(L, 1, "seed");
if (lua_isnumber(L, -1)) { if (lua_isnumber(L, -1)) {
oparams->seed = lua_tointeger(L, -1); oparams->seed = lua_tointeger(L, -1);
paramsmodified |= MGPARAMS_SET_SEED; paramsmodified |= MGPARAMS_SET_SEED;
} }
lua_getfield(L, 1, "water_level"); lua_getfield(L, 1, "water_level");
if (lua_isnumber(L, -1)) { if (lua_isnumber(L, -1)) {
oparams->water_level = lua_tointeger(L, -1); oparams->water_level = lua_tointeger(L, -1);
@ -197,18 +197,20 @@ int ModApiMapgen::l_set_mapgen_params(lua_State *L)
std::string flagstr = std::string(lua_tostring(L, -1)); std::string flagstr = std::string(lua_tostring(L, -1));
oparams->flags = readFlagString(flagstr, flagdesc_mapgen); oparams->flags = readFlagString(flagstr, flagdesc_mapgen);
paramsmodified |= MGPARAMS_SET_FLAGS; paramsmodified |= MGPARAMS_SET_FLAGS;
lua_getfield(L, 1, "flagmask"); lua_getfield(L, 1, "flagmask");
if (lua_isstring(L, -1)) { if (lua_isstring(L, -1)) {
flagstr = std::string(lua_tostring(L, -1)); flagstr = std::string(lua_tostring(L, -1));
flagmask = readFlagString(flagstr, flagdesc_mapgen); flagmask = readFlagString(flagstr, flagdesc_mapgen);
} }
} }
delete emerge->luaoverride_params;
emerge->luaoverride_params = oparams; emerge->luaoverride_params = oparams;
emerge->luaoverride_params_modified = paramsmodified; emerge->luaoverride_params_modified = paramsmodified;
emerge->luaoverride_flagmask = flagmask; emerge->luaoverride_flagmask = flagmask;
return 0; return 0;
} }
@ -240,7 +242,7 @@ int ModApiMapgen::l_register_biome(lua_State *L)
"air"); "air");
b->nname_dust_water = getstringfield_default(L, index, "node_dust_water", b->nname_dust_water = getstringfield_default(L, index, "node_dust_water",
"mapgen_water_source"); "mapgen_water_source");
b->depth_top = getintfield_default(L, index, "depth_top", 1); b->depth_top = getintfield_default(L, index, "depth_top", 1);
b->depth_filler = getintfield_default(L, index, "depth_filler", 3); b->depth_filler = getintfield_default(L, index, "depth_filler", 3);
b->height_min = getintfield_default(L, index, "height_min", 0); b->height_min = getintfield_default(L, index, "height_min", 0);
@ -254,7 +256,7 @@ int ModApiMapgen::l_register_biome(lua_State *L)
b->c_water = CONTENT_IGNORE; b->c_water = CONTENT_IGNORE;
b->c_dust = CONTENT_IGNORE; b->c_dust = CONTENT_IGNORE;
b->c_dust_water = CONTENT_IGNORE; b->c_dust_water = CONTENT_IGNORE;
verbosestream << "register_biome: " << b->name << std::endl; verbosestream << "register_biome: " << b->name << std::endl;
bmgr->addBiome(b); bmgr->addBiome(b);
@ -277,7 +279,7 @@ int ModApiMapgen::l_register_decoration(lua_State *L)
"decoration placement type"; "decoration placement type";
return 0; return 0;
} }
Decoration *deco = createDecoration(decotype); Decoration *deco = createDecoration(decotype);
if (!deco) { if (!deco) {
errorstream << "register_decoration: decoration placement type " errorstream << "register_decoration: decoration placement type "
@ -295,11 +297,11 @@ int ModApiMapgen::l_register_decoration(lua_State *L)
delete deco; delete deco;
return 0; return 0;
} }
lua_getfield(L, index, "noise_params"); lua_getfield(L, index, "noise_params");
deco->np = read_noiseparams(L, -1); deco->np = read_noiseparams(L, -1);
lua_pop(L, 1); lua_pop(L, 1);
lua_getfield(L, index, "biomes"); lua_getfield(L, index, "biomes");
if (lua_istable(L, -1)) { if (lua_istable(L, -1)) {
lua_pushnil(L); lua_pushnil(L);
@ -313,7 +315,7 @@ int ModApiMapgen::l_register_decoration(lua_State *L)
} }
lua_pop(L, 1); lua_pop(L, 1);
} }
switch (decotype) { switch (decotype) {
case DECO_SIMPLE: { case DECO_SIMPLE: {
DecoSimple *dsimple = (DecoSimple *)deco; DecoSimple *dsimple = (DecoSimple *)deco;
@ -323,7 +325,7 @@ int ModApiMapgen::l_register_decoration(lua_State *L)
dsimple->deco_height = getintfield_default(L, index, "height", 1); dsimple->deco_height = getintfield_default(L, index, "height", 1);
dsimple->deco_height_max = getintfield_default(L, index, "height_max", 0); dsimple->deco_height_max = getintfield_default(L, index, "height_max", 0);
dsimple->nspawnby = getintfield_default(L, index, "num_spawn_by", -1); dsimple->nspawnby = getintfield_default(L, index, "num_spawn_by", -1);
lua_getfield(L, index, "decoration"); lua_getfield(L, index, "decoration");
if (lua_istable(L, -1)) { if (lua_istable(L, -1)) {
lua_pushnil(L); lua_pushnil(L);
@ -340,7 +342,7 @@ int ModApiMapgen::l_register_decoration(lua_State *L)
dsimple->deco_name = std::string("air"); dsimple->deco_name = std::string("air");
} }
lua_pop(L, 1); lua_pop(L, 1);
if (dsimple->deco_height <= 0) { if (dsimple->deco_height <= 0) {
errorstream << "register_decoration: simple decoration height" errorstream << "register_decoration: simple decoration height"
" must be greater than 0" << std::endl; " must be greater than 0" << std::endl;
@ -380,7 +382,7 @@ int ModApiMapgen::l_register_decoration(lua_State *L)
return 0; return 0;
} }
lua_pop(L, -1); lua_pop(L, -1);
if (!dschem->filename.empty() && !dschem->loadSchematicFile()) { if (!dschem->filename.empty() && !dschem->loadSchematicFile()) {
errorstream << "register_decoration: failed to load schematic file '" errorstream << "register_decoration: failed to load schematic file '"
<< dschem->filename << "'" << std::endl; << dschem->filename << "'" << std::endl;
@ -390,7 +392,7 @@ int ModApiMapgen::l_register_decoration(lua_State *L)
break; } break; }
case DECO_LSYSTEM: { case DECO_LSYSTEM: {
//DecoLSystem *decolsystem = (DecoLSystem *)deco; //DecoLSystem *decolsystem = (DecoLSystem *)deco;
break; } break; }
} }
@ -474,7 +476,7 @@ int ModApiMapgen::l_create_schematic(lua_State *L)
v3s16 p1 = read_v3s16(L, 1); v3s16 p1 = read_v3s16(L, 1);
v3s16 p2 = read_v3s16(L, 2); v3s16 p2 = read_v3s16(L, 2);
sortBoxVerticies(p1, p2); sortBoxVerticies(p1, p2);
std::vector<std::pair<v3s16, u8> > prob_list; std::vector<std::pair<v3s16, u8> > prob_list;
if (lua_istable(L, 3)) { if (lua_istable(L, 3)) {
lua_pushnil(L); lua_pushnil(L);
@ -483,7 +485,7 @@ int ModApiMapgen::l_create_schematic(lua_State *L)
lua_getfield(L, -1, "pos"); lua_getfield(L, -1, "pos");
v3s16 pos = read_v3s16(L, -1); v3s16 pos = read_v3s16(L, -1);
lua_pop(L, 1); lua_pop(L, 1);
u8 prob = getintfield_default(L, -1, "prob", MTSCHEM_PROB_ALWAYS); u8 prob = getintfield_default(L, -1, "prob", MTSCHEM_PROB_ALWAYS);
prob_list.push_back(std::make_pair(pos, prob)); prob_list.push_back(std::make_pair(pos, prob));
} }
@ -491,7 +493,7 @@ int ModApiMapgen::l_create_schematic(lua_State *L)
lua_pop(L, 1); lua_pop(L, 1);
} }
} }
std::vector<std::pair<s16, u8> > slice_prob_list; std::vector<std::pair<s16, u8> > slice_prob_list;
if (lua_istable(L, 5)) { if (lua_istable(L, 5)) {
lua_pushnil(L); lua_pushnil(L);
@ -516,7 +518,7 @@ int ModApiMapgen::l_create_schematic(lua_State *L)
} }
dschem.applyProbabilities(p1, &prob_list, &slice_prob_list); dschem.applyProbabilities(p1, &prob_list, &slice_prob_list);
dschem.saveSchematicFile(ndef); dschem.saveSchematicFile(ndef);
actionstream << "create_schematic: saved schematic file '" actionstream << "create_schematic: saved schematic file '"
<< dschem.filename << "'." << std::endl; << dschem.filename << "'." << std::endl;
@ -536,11 +538,11 @@ int ModApiMapgen::l_place_schematic(lua_State *L)
v3s16 p = read_v3s16(L, 1); v3s16 p = read_v3s16(L, 1);
if (!read_schematic(L, 2, &dschem, getServer(L))) if (!read_schematic(L, 2, &dschem, getServer(L)))
return 0; return 0;
int rot = ROTATE_0; int rot = ROTATE_0;
if (lua_isstring(L, 3)) if (lua_isstring(L, 3))
string_to_enum(es_Rotation, rot, std::string(lua_tostring(L, 3))); string_to_enum(es_Rotation, rot, std::string(lua_tostring(L, 3)));
dschem.rotation = (Rotation)rot; dschem.rotation = (Rotation)rot;
if (lua_istable(L, 4)) { if (lua_istable(L, 4)) {
@ -568,7 +570,7 @@ int ModApiMapgen::l_place_schematic(lua_State *L)
} }
dschem.resolveNodeNames(ndef); dschem.resolveNodeNames(ndef);
} }
dschem.placeStructure(map, p); dschem.placeStructure(map, p);
return 1; return 1;