commit 3a50044dcdfe382c2968e707d01833e56894e54e Author: sfan5 Date: Sun Feb 19 17:49:00 2012 +0100 WorldEdit 0.2 diff --git a/worldedit/VERSION b/worldedit/VERSION new file mode 100644 index 0000000..3b04cfb --- /dev/null +++ b/worldedit/VERSION @@ -0,0 +1 @@ +0.2 diff --git a/worldedit/init.lua b/worldedit/init.lua new file mode 100644 index 0000000..e166b84 --- /dev/null +++ b/worldedit/init.lua @@ -0,0 +1,403 @@ +-- Load Table-Save/Load Library | http://lua-users.org/wiki/SaveTableToFile +print("[WorldEdit] Loading Table-Save/Load Library...") +dofile(minetest.get_modpath("worldedit").."/table_save-load.lua") +assert(table.save ~= nil) +assert(table.load ~= nil) +-- Functions +function get_tmp(name) + local f = io.open("wetemp_" .. name .. ".txt", "r") + if f == nil then + return "" + else + return f:read("*all") + end +end +function set_tmp(name,text) + local f = io.open("wetemp_" .. name .. ".txt", "w") + if f == nil then + return false + else + f:write(text) + f:close() + return true + end +end +function to_pos(s) + local pos = {-1,-1,-1} + i = 1 + string.gsub(s,"{(.-)}", function(a) + pos[i] = tonumber(a) + i = i + 1 + end) + return pos +end +function to_pos_str(x,y,z) + return "{" .. x .. "}{" .. y .. "}{" .. z .. "}" +end +function to_pos_userstr(p) + return "(" .. p[1] .. "," .. p[2] .. "," .. p[3] .. ")" +end +function string:split(delimiter) + local result = { } + local from = 1 + local delim_from, delim_to = string.find( self, delimiter, from ) + while delim_from do + table.insert( result, string.sub( self, from , delim_from-1 ) ) + from = delim_to + 1 + delim_from, delim_to = string.find( self, delimiter, from ) + end + table.insert( result, string.sub( self, from ) ) + return result +end +function check_player_we_perms(pname) + local fi = "" + local f = io.open("weperms.txt", "r") + if f ~= nil then + fi = f:read("*all") + f:close() + else + return false + end + local list = {} + i = 1 + string.gsub(fi,"{(.-)}", function(a) + list[i] = a + i = i + 1 + end) + for n = 1, table.getn(list), 1 do + if list[n] == pname then + return true + end + end + return false +end +function sort_pos(pos1,pos2) + if pos1[1] >= pos2[1] then + local temp = pos2[1] + pos2[1] = pos1[1] + pos1[1] = temp + temp = nil + end + if pos1[2] >= pos2[2] then + local temp = pos2[2] + pos2[2] = pos1[2] + pos1[2] = temp + temp = nil + end + if pos1[3] >= pos2[3] then + local temp = pos2[3] + pos2[3] = pos1[3] + pos1[3] = temp + temp = nil + end + return {pos1,pos2} +end +-- Other Code +set_tmp("pos1", to_pos_str(0,0,0)) +set_tmp("pos2", to_pos_str(0,0,0)) +set_tmp("postoset", "-1") +minetest.register_on_chat_message(function(name, message) + local cmd = "//pos1" + if message:sub(0, #cmd) == cmd then + if check_player_we_perms(name) then + local pl = minetest.env:get_player_by_name(name) + local p = pl:getpos() + set_tmp("pos1", to_pos_str(p.x,p.y,p.z)) + minetest.chat_send_player(name, 'P1 was set to '..to_pos_userstr({p.x,p.y,p.z})) + else + minetest.chat_send_player(name, 'You havent got the Permission for that') + end + return true + end + local cmd = "//pos2" + if message:sub(0, #cmd) == cmd then + if check_player_we_perms(name) then + local pl = minetest.env:get_player_by_name(name) + local p = pl:getpos() + set_tmp("pos2", to_pos_str(p.x,p.y,p.z)) + minetest.chat_send_player(name, 'P2 was set to '..to_pos_userstr({p.x,p.y,p.z})) + else + minetest.chat_send_player(name, 'You havent got the Permission for that') + end + return true + end + local cmd = "//p" + if message:sub(0, #cmd) == cmd then + if check_player_we_perms(name) then + local ope = string.match(message, cmd.." (.*)") + if ope == nil then + minetest.chat_send_player(name, 'usage: '..cmd..' [get/set]') + return true + end + if ope == "get" then + local pos1 = to_pos(get_tmp("pos1")) + local pos2 = to_pos(get_tmp("pos2")) + minetest.chat_send_player(name, "P1: ("..pos1[1]..","..pos1[2]..","..pos1[3]..")") + minetest.chat_send_player(name, "P2: ("..pos2[1]..","..pos2[2]..","..pos2[3]..")") + return true + end + if ope == "set" then + set_tmp("postoset", "0") + minetest.chat_send_player(name, "Please select P1 and P2") + return true + end + else + minetest.chat_send_player(name, 'You havent got the Permission for that') + return true + end + end + local cmd = "//set" + if message:sub(0, #cmd) == cmd then + if check_player_we_perms(name) then + local nn = string.match(message, cmd.." (.*)") + if nn == nil then + minetest.chat_send_player(name, 'usage: '..cmd..' [nodename]') + return true + end + local temp = sort_pos(to_pos(get_tmp("pos1")),to_pos(get_tmp("pos2"))) + pos1 = temp[1] + pos2 = temp[2] + temp = nil + local bc = 0 + for x = pos1[1], pos2[1], 1 do + for y = pos1[2], pos2[2], 1 do + for z = pos1[3], pos2[3], 1 do + local np = {x=x, y=y, z=z} + minetest.env:add_node(np, {name=nn}) + bc = bc + 1 + end + end + end + minetest.chat_send_player(name, bc..' Blocks changed') + return true + else + minetest.chat_send_player(name, 'You havent got the Permission for that') + return true + end + end + local cmd = "//replace" + if message:sub(0, #cmd) == cmd then + if check_player_we_perms(name) then + local nn = {} + local tmp = message:gsub(cmd.." ","") + nn = tmp:split(",") + tmp = nil + if nn[2] == nil then + minetest.chat_send_player(name, 'usage: '..cmd..' [nodename],[nodename2]') + return true + end + local temp = sort_pos(to_pos(get_tmp("pos1")),to_pos(get_tmp("pos2"))) + pos1 = temp[1] + pos2 = temp[2] + temp = nil + local bc = 0 + for x = pos1[1], pos2[1], 1 do + for y = pos1[2], pos2[2], 1 do + for z = pos1[3], pos2[3], 1 do + local np = {x=x, y=y, z=z} + local n = minetest.env:get_node(np) + if n.name == "default:"..nn[1] or n.name == nn[1] then + minetest.env:add_node(np, {name=nn[2]}) + bc = bc + 1 + end + end + end + end + minetest.chat_send_player(name, bc..' Blocks replaced') + return true + else + minetest.chat_send_player(name, 'You havent got the Permission for that') + return true + end + return true + end + local cmd = "//stack" + if message:sub(0, #cmd) == cmd then + if check_player_we_perms(name) then + local nn = {} + local tmp = message:gsub(cmd.." ","") + nn = tmp:split(",") + if nn[2] == nil then + minetest.chat_send_player(name, 'Usage: '..cmd..' [direction],[count]') + minetest.chat_send_player(name, 'Valid Directions are: x+ x- y+ y- z+ z-') + return true + end + local temp = sort_pos(to_pos(get_tmp("pos1")),to_pos(get_tmp("pos2"))) + pos1 = temp[1] + pos2 = temp[2] + local bc = 0 + if nn[1] == "x+" then + for c = 1, nn[2], 1 do + local offset_x = (pos2[1] - pos1[1] + 1) * c + for x = pos1[1], pos2[1], 1 do + for y = pos1[2], pos2[2], 1 do + for z = pos1[3], pos2[3], 1 do + local n = minetest.env:get_node({x=x, y=y, z=z}) + minetest.env:add_node({x=x+offset_x, y=y, z=z}, n) + bc = bc + 1 + end + end + end + end + end + if nn[1] == "x-" then + for c = 1, nn[2], 1 do + local offset_x = (pos2[1] - pos1[1] + 1) * c + for x = pos1[1], pos2[1], 1 do + for y = pos1[2], pos2[2], 1 do + for z = pos1[3], pos2[3], 1 do + local n = minetest.env:get_node({x=x, y=y, z=z}) + minetest.env:add_node({x=x-offset_x, y=y, z=z}, n) + bc = bc + 1 + end + end + end + end + end + if nn[1] == "y+" then + for c = 1, nn[2], 1 do + local offset_y = (pos2[2] - pos1[2] + 1) * c + for x = pos1[1], pos2[1], 1 do + for y = pos1[2], pos2[2], 1 do + for z = pos1[3], pos2[3], 1 do + local n = minetest.env:get_node({x=x, y=y, z=z}) + minetest.env:add_node({x=x, y=y+offset_y, z=z}, n) + bc = bc + 1 + end + end + end + end + end + if nn[1] == "y-" then + for c = 1, nn[2], 1 do + local offset_y = (pos2[2] - pos1[2] + 1) * c + for x = pos1[1], pos2[1], 1 do + for y = pos1[2], pos2[2], 1 do + for z = pos1[3], pos2[3], 1 do + local n = minetest.env:get_node({x=x, y=y, z=z}) + minetest.env:add_node({x=x, y=y-offset_y, z=z}, n) + bc = bc + 1 + end + end + end + end + end + if nn[1] == "z+" then + for c = 1, nn[2], 1 do + local offset_z = (pos2[3] - pos1[3] + 1) * c + for x = pos1[1], pos2[1], 1 do + for y = pos1[2], pos2[2], 1 do + for z = pos1[3], pos2[3], 1 do + local n = minetest.env:get_node({x=x, y=y, z=z}) + minetest.env:add_node({x=x, y=y, z=z+offset_z}, n) + bc = bc + 1 + end + end + end + end + end + if nn[1] == "z-" then + for c = 1, nn[2], 1 do + local offset_z = (pos2[3] - pos1[3] + 1) * c + for x = pos1[1], pos2[1], 1 do + for y = pos1[2], pos2[2], 1 do + for z = pos1[3], pos2[3], 1 do + local n = minetest.env:get_node({x=x, y=y, z=z}) + minetest.env:add_node({x=x, y=y, z=z-offset_z}, n) + bc = bc + 1 + end + end + end + end + end + minetest.chat_send_player(name, bc..' Blocks duplicated') + return true + else + minetest.chat_send_player(name, 'You havent got the Permission for that') + return true + end + end + local cmd = "//save" + if message:sub(0, #cmd) == cmd then + if check_player_we_perms(name) == false then + minetest.chat_send_player(name, 'You havent got the Permission for that') + return true + end + local fn = string.match(message, cmd.." (.*)") + if fn == nil then + minetest.chat_send_player(name, 'usage: '..cmd..' [filename]') + return true + end + data = {} + datai = 1 + ---------- + local temp = sort_pos(to_pos(get_tmp("pos1")),to_pos(get_tmp("pos2"))) + pos1 = temp[1] + pos2 = temp[2] + temp = nil + local bs = 0 + for x = pos1[1], pos2[1], 1 do + for y = pos1[2], pos2[2], 1 do + for z = pos1[3], pos2[3], 1 do + local np = {x=x, y=y, z=z} + local np_rel = {x=pos1[1]-x, y=pos1[2]-y, z=pos1[3]-z} -- Relative Position + local n = minetest.env:get_node(np) + if n.name ~= "air" then -- Don't Save air + data[datai] = {np_rel,n} -- data[index] = {position,node_data} + datai = datai + 1 + bs = bs + 1 + end + end + end + end + ---------- + print(dump(data)) + table.save(data, fn) + minetest.chat_send_player(name, bs..' Blocks saved to '..fn) + return true + end + local cmd = "//load" + if message:sub(0, #cmd) == cmd then + if check_player_we_perms(name) == false then + minetest.chat_send_player(name, 'You havent got the Permission for that') + return true + end + local fn = string.match(message, cmd.." (.*)") + if fn == nil then + minetest.chat_send_player(name, 'usage: '..cmd..' [filename]') + return true + end + data = {} + data = table.load(fn) + print(dump(data)) + ---------- + pos1 = to_pos(get_tmp("pos1")) + local bp = 0 + for i = 1, #data, 1 do + local d = data[i] + local np = {x=pos1[1]-d[1].x,y=pos1[2]-d[1].y,z=pos1[3]-d[1].z} + minetest.env:add_node(np,d[2]) + bp = bp + 1 + end + ---------- + minetest.chat_send_player(name, bp..' Blocks pasted at P1') + return true + end +end) +minetest.register_on_punchnode(function(p, node, puncher) + if puncher:get_player_name() ~= nil then + local pn = puncher:get_player_name() + if check_player_we_perms(pn) == false then minetest.chat_send_player(pn, 'You havent got the Permission for that') return end + if get_tmp("postoset") == "1" then + set_tmp("pos2", to_pos_str(p.x,p.y,p.z)) + set_tmp("postoset", "-1") + minetest.chat_send_player(pn, 'P2 was set to '..to_pos_userstr({p.x,p.y,p.z})) + end + if get_tmp("postoset") == "0" then + set_tmp("pos1", to_pos_str(p.x,p.y,p.z)) + set_tmp("postoset", "1") + minetest.chat_send_player(pn, 'P1 was set to '..to_pos_userstr({p.x,p.y,p.z})) + end + end +end) +print("[WorldEdit] Loaded!") diff --git a/worldedit/table_save-load.lua b/worldedit/table_save-load.lua new file mode 100644 index 0000000..ec2230d --- /dev/null +++ b/worldedit/table_save-load.lua @@ -0,0 +1,135 @@ +--[[ + http://lua-users.org/wiki/SaveTableToFile + Save Table to File + Load Table from File + v 1.0 + + Lua 5.2 compatible + + Only Saves Tables, Numbers and Strings + Insides Table References are saved + Does not save Userdata, Metatables, Functions and indices of these + ---------------------------------------------------- + table.save( table , filename ) + + on failure: returns an error msg + + ---------------------------------------------------- + table.load( filename or stringtable ) + + Loads a table that has been saved via the table.save function + + on success: returns a previously saved table + on failure: returns as second argument an error msg + ---------------------------------------------------- + + Licensed under the same terms as Lua itself. +]]-- +do + -- declare local variables + --// exportstring( string ) + --// returns a "Lua" portable version of the string + local function exportstring( s ) + return string.format("%q", s) + end + + --// The Save Function + function table.save( tbl,filename ) + local charS,charE = " ","\n" + local file,err = io.open( filename, "wb" ) + if err then return err end + + -- initiate variables for save procedure + local tables,lookup = { tbl },{ [tbl] = 1 } + file:write( "return {"..charE ) + + for idx,t in ipairs( tables ) do + file:write( "-- Table: {"..idx.."}"..charE ) + file:write( "{"..charE ) + local thandled = {} + + for i,v in ipairs( t ) do + thandled[i] = true + local stype = type( v ) + -- only handle value + if stype == "table" then + if not lookup[v] then + table.insert( tables, v ) + lookup[v] = #tables + end + file:write( charS.."{"..lookup[v].."},"..charE ) + elseif stype == "string" then + file:write( charS..exportstring( v )..","..charE ) + elseif stype == "number" then + file:write( charS..tostring( v )..","..charE ) + end + end + + for i,v in pairs( t ) do + -- escape handled values + if (not thandled[i]) then + + local str = "" + local stype = type( i ) + -- handle index + if stype == "table" then + if not lookup[i] then + table.insert( tables,i ) + lookup[i] = #tables + end + str = charS.."[{"..lookup[i].."}]=" + elseif stype == "string" then + str = charS.."["..exportstring( i ).."]=" + elseif stype == "number" then + str = charS.."["..tostring( i ).."]=" + end + + if str ~= "" then + stype = type( v ) + -- handle value + if stype == "table" then + if not lookup[v] then + table.insert( tables,v ) + lookup[v] = #tables + end + file:write( str.."{"..lookup[v].."},"..charE ) + elseif stype == "string" then + file:write( str..exportstring( v )..","..charE ) + elseif stype == "number" then + file:write( str..tostring( v )..","..charE ) + end + end + end + end + file:write( "},"..charE ) + end + file:write( "}" ) + file:close() + end + + --// The Load Function + function table.load( sfile ) + local ftables,err = loadfile( sfile ) + if err then return _,err end + local tables = ftables() + for idx = 1,#tables do + local tolinki = {} + for i,v in pairs( tables[idx] ) do + if type( v ) == "table" then + tables[idx][i] = tables[v[1]] + end + if type( i ) == "table" and tables[i[1]] then + table.insert( tolinki,{ i,tables[i[1]] } ) + end + end + -- link indices + for _,v in ipairs( tolinki ) do + tables[idx][v[2]],tables[idx][v[1]] = tables[idx][v[1]],nil + end + end + return tables[1] + end +-- close do +end + +-- ChillCode