Commit 1d33880d authored by Petter Reinholdtsen's avatar Petter Reinholdtsen

New upstream version 0.17

parent ec5932e1
......@@ -58,8 +58,11 @@ local Base64 = {}
-- Imports
----------------------------------------------------------------------------
bit = ie.require("bit")
local bit
local status,err = pcall(function() bit = ie.require 'bit' end)
if not status then
bit = ie.dofile(minetest.get_modpath(minetest.get_current_modname()) .. '/slowbit32.lua')
end
local band, bor, lshift, rshift = bit.band, bit.bor, bit.lshift, bit.rshift
----------------------------------------------------------------------------
......
if minetest.request_insecure_environment then
ie=minetest.request_insecure_environment()
else
ie=_G
end
local bit=ie.require("bit")
local block={}
local function Block(id,meta)
if meta == nil then meta=0 end
return meta * 0x1000 + id
if meta == nil then meta=0 end
return meta * 0x1000 + id
end
local function unBlock(value)
return bit.band(value, 0xFFF),bit.rshift(value, 12)
return value % 0x1000, math.floor(value / 0x1000)
end
block.AIR =Block(0)
......
......@@ -87,13 +87,16 @@ else
remote_address = "*"
end
local server = socket.bind(remote_address, 4711)
local server,err = socket.bind(remote_address, 4711)
assert(server, err)
server:setoption('tcp-nodelay',true)
server:settimeout(0)
local ws_server = nil
if ws then
if not bit or not bit.bxor then bit = ie.require("slowbit32") end
tools = ie.require("tools")
base64 = ie.require("base64")
ws_server = socket.bind(remote_address, 14711)
......@@ -285,9 +288,13 @@ function python(name, args, kill_script)
return true
end
local function sanitize_pipe(s)
return s:gsub("%&", "&"):gsub("%|", "|")
end
minetest.register_on_chat_message(function(name, message)
local id = get_player_id_by_name(name)
table.insert(chat_record, id .. "," .. message:gsub("%|", "|"))
table.insert(chat_record, id .. "," .. sanitize_pipe(message))
return false
end)
......@@ -402,20 +409,20 @@ local block_buffer_p1 = {}
local block_buffer_p2 = {}
function flush_block_buffer()
if #block_buffer >= 50 then
if #block_buffer >= 1 then
local vm = minetest.get_voxel_manip()
local emin,emax = vm:read_from_map(block_buffer_p1,block_buffer_p2)
local area = VoxelArea:new{MinEdge=emin, MaxEdge=emax}
local data = vm:get_data()
local param2 = vm:get_param2_data()
local emin,emax = vm:read_from_map(block_buffer_p1,block_buffer_p2)
local area = VoxelArea:new{MinEdge=emin, MaxEdge=emax}
local data = vm:get_data()
local param2 = vm:get_param2_data()
for i=1,#block_buffer do
local v = block_buffer[i]
local index = area:indexp(v.pos)
data[index] = minetest.get_content_id(v.node.name)
param2[index] = v.node.param2
local v = block_buffer[i]
local index = area:indexp(v.pos)
data[index] = minetest.get_content_id(v.node.name)
param2[index] = v.node.param2
end
vm:set_data(data)
vm:set_param2_data(param2)
vm:set_data(data)
vm:set_param2_data(param2)
vm:update_liquids()
vm:write_to_map()
vm:update_map()
......@@ -524,7 +531,7 @@ function handle_world(cmd, args)
elseif cmd == "getAllNodes" then
local nodes = {}
for name,_ in pairs(minetest.registered_nodes) do
table.insert(nodes,name)
table.insert(nodes,sanitize_pipe(name))
end
return table.concat(nodes,'|')
elseif cmd == "getBlockWithData" or cmd == "getBlock" then
......@@ -535,6 +542,52 @@ function handle_world(cmd, args)
else
return id..","..meta
end
elseif cmd == "getBlocksWithData" or cmd == "getBlocks" or cmd == "getNodes" then
local x1 = math.min(tonumber(args[1]),tonumber(args[4]))
local x2 = math.max(tonumber(args[1]),tonumber(args[4]))
local y1 = math.min(tonumber(args[2]),tonumber(args[5]))
local y2 = math.max(tonumber(args[2]),tonumber(args[5]))
local z1 = math.min(-tonumber(args[3]),-tonumber(args[6]))
local z2 = math.max(-tonumber(args[3]),-tonumber(args[6]))
local data = {}
if cmd == "getBlocksWithData" then
for y = y1,y2 do
for x = x1,x2 do
for z = z1,z2 do
local node = minetest.get_node({x=x,y=y,z=z})
local id, meta = block.node_to_id_meta(node)
table.insert(data, id .. "," .. meta)
end
end
end
elseif cmd == "getNodes" then
for y = y1,y2 do
for x = x1,x2 do
for z = z1,z2 do
local node = minetest.get_node({x=x,y=y,z=z})
table.insert(data, sanitize_pipe(node.name) .. "," .. node.param2)
end
end
end
else
for y = y1,y2 do
for x = x1,x2 do
for z = z1,z2 do
local node = minetest.get_node({x=x,y=y,z=z})
local id, _ = block.node_to_id_meta(node)
table.insert(data, tostring(id))
end
end
end
end
if cmd == "getBlocks" then
return table.concat(data, ",")
else
return table.concat(data, "|")
end
elseif cmd == "getHeight" then
return tonumber(get_height(tonumber(args[1]),-tonumber(args[2])))
elseif cmd == "getPlayerId" then
......@@ -615,8 +668,8 @@ function handle_command(line)
end
local args = {}
for arg in argtext:gmatch("([^,]+)") do
table.insert(args, arg)
for argument in argtext:gmatch("([^,]+)") do
table.insert(args, argument)
end
if cmd:sub(1,6) == "world." then
return handle_world(cmd:sub(7),args)
......@@ -801,4 +854,3 @@ function handle_websocket_header(source,line)
return nil
end
......@@ -22,6 +22,22 @@ from util import flatten,floorFlatten
#def strFloor(*args):
# return [str(int(math.floor(x))) for x in flatten(args)]
def fixPipe(s):
return s.replace('|', '|').replace('&','&')
def stringToBlockWithNBT(s, pipeFix = False):
data = s.split(",")
id = int(data[0])
if len(data) <= 1:
return Block(id)
elif len(data) <= 2:
return Block(id,int(data[1]))
else:
nbt = ','.join(data[2:])
if pipeFix:
nbt = fixPipe(nbt)
return Block(id,int(data[1]),nbt)
class CmdPositioner:
"""Methods for setting and getting positions"""
def __init__(self, connection, packagePrefix):
......@@ -157,7 +173,7 @@ class CmdEvents:
def pollChatPosts(self):
"""Triggered by posts to chat => [ChatEvent]"""
s = self.conn.sendReceive("events.chat.posts")
events = [e for e in s.split("|") if e]
events = [fixPipe(e) for e in s.split("|") if e]
return [ChatEvent.Post(int(e[:e.find(",")]), e[e.find(",") + 1:]) for e in events]
class Minecraft:
......@@ -215,24 +231,38 @@ class Minecraft:
ans = self.conn.receive()
else:
ans = self.conn.sendReceive_flat("world.getBlockWithData", floorFlatten(args))
id,data = (map(int, ans.split(",")[:2]))
commas = 0
for i in range(0,len(ans)):
if ans[i] == ',':
commas += 1
if commas == 2:
if '{' in ans[i+1:]:
return Block(id,data,ans[i+1:])
else:
break
return Block(id,data)
return stringToBlockWithNBT(ans)
"""
@TODO
"""
# must have no NBT tags in any Block instances
def getBlocks(self, *args):
"""Get a cuboid of blocks (x0,y0,z0,x1,y1,z1) => [id:int]"""
return int(self.conn.sendReceive_flat("world.getBlocks", floorFlatten(args)))
"""
Get a cuboid of blocks (x0,y0,z0,x1,y1,z1) => [id:int]
Packed with a y-loop, x-loop, z-loop, in this order.
"""
ans = self.conn.sendReceive_flat("world.getBlocks", floorFlatten(args))
return map(int, ans.split(","))
def getBlocksWithData(self, *args):
"""Get a cuboid of blocks (x0,y0,z0,x1,y1,z1) => [Block(id:int, meta:int)]"""
ans = self.conn.sendReceive_flat("world.getBlocksWithData", floorFlatten(args))
return [Block(*map(int, x.split(",")[:2])) for x in ans.split("|")]
def getBlocksWithNBT(self, *args):
"""Get a cuboid of blocks (x0,y0,z0,x1,y1,z1) => [Block(id, meta, nbt)]"""
if not self.enabledNBT:
self.setting("include_nbt_with_data",1)
self.enabledNBT = True
try:
ans = self.conn.sendReceive_flat("world.getBlocksWithData", floorFlatten(args))
except RequestError:
# retry in case we had a Fail from the setting
ans = self.conn.receive()
else:
ans = self.conn.sendReceive_flat("world.getBlocksWithData", floorFlatten(args))
ans = self.conn.sendReceive_flat("world.getBlocksWithData", floorFlatten(args))
return [stringToBlockWithNBT(x, pipeFix = True) for x in ans.split("|")]
# must have no NBT tags in Block instance
def setBlock(self, *args):
......
-- These are super slow 32-bit operations --
local two31 = 2^31
local two32 = 2^32
local to_binary = function(x)
local pos = two31
local a = ""
if x < 0 then
x = x + two32
end
x = x % two32
for i=1,32 do
if x >= pos then
a = a .. "1"
x = x - pos
else
a = a .. "0"
end
pos = pos / 2
end
return a
end
local from_binary = function(x)
local z = tonumber(x)
if z >= two31 then
return z - two32
else
return z
end
end
local band = function(...)
local a = {}
local arg = {...}
for i = 1,#arg do
a[i] = to_binary(arg[i])
end
local c = ""
for i = 1,32 do
local value = true
for j = 1,#arg do
if a[j]:sub(i,i) == "0" then
value = false
break
end
end
if value then
c = c .. "1"
else
c = c .. "0"
end
end
return from_binary(c)
end
local bor = function(...)
local a = {}
local arg = {...}
for i = 1,#arg do
a[i] = to_binary(arg[i])
end
local c = ""
for i = 1,32 do
local value = false
for j = 1,#arg do
if a[j]:sub(i,i) == "1" then
value = true
break
end
end
if value then
c = c .. "1"
else
c = c .. "0"
end
end
return from_binary(c)
end
local bxor = function(...)
local a = {}
local arg = {...}
for i = 1,#arg do
a[i] = to_binary(arg[i])
end
local c = ""
for i = 1,32 do
local value = false
for j = 1,#arg do
if a[j]:sub(i,i) == "1" then
value = not value
end
end
if value then
c = c .. "1"
else
c = c .. "0"
end
end
return from_binary(c)
end
local bnot = function(x)
local a = to_binary(x)
local c = ""
for i = 1,32 do
if a:sub(i,i) == "0" then
c = c .. "1"
else
c = c .. "0"
end
end
return from_binary(c)
end
local lshift = function(x,n)
return (x * 2^n) % two32
end
local rshift = function(x,n)
return math.floor(x / 2^n)
end
local rol = function(x,n)
local a = to_binary(x)
for i = 1,n do
a = a:sub(2,32) .. a:sub(1,1)
end
return from_binary(a)
end
return {rol=rol, bxor=bxor, bor=bor, band=band, bnot=bnot, lshift=lshift, rshift=rshift}
......@@ -21,8 +21,6 @@ if not status then
socket = ie.require("socket.cx64")
end
ie.module("socket")
-----------------------------------------------------------------------------
-- Exported auxiliar functions
-----------------------------------------------------------------------------
......@@ -49,7 +47,7 @@ function bind(host, port, backlog)
return sock
end
try = newtry()
-- try = newtry()
function choose(table)
return function(name, opt1, opt2)
......@@ -141,3 +139,4 @@ sourcet["default"] = sourcet["until-closed"]
source = choose(sourcet)
return { connect=connect, bind=bind, choose=choose, source=source }
......@@ -4,7 +4,12 @@ else
ie = _G
end
local bit = ie.require 'bit'
local bit
local status,err = pcall(function() bit = ie.require 'bit' end)
if not status then
bit = ie.dofile(minetest.get_modpath(minetest.get_current_modname()) .. '/slowbit32.lua')
end
local rol = bit.rol
local bxor = bit.bxor
local bor = bit.bor
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment