Set_node and mapblock implosion fixed, invref in development
* Inventory: Two functions added : is_empty(listname) and get_size(listname), both working in a similar fashion as their minetest API counterpart * Map: - Implosion fixed. The num_name_id_mappings variable is correctly set, all data are written to the correct byte streams. A function is added to check whether a position given to a function (list get/set_node) is correct and the mapblock is loaded. - Data storage type for static object data fixed - MapBlocks now have a get_meta(abspos) method. Abspos is the integer representing the position of the querried metadata inside the mapblock - MapVessels default to forcefully save a flagged mapblock before unloading it - A new method in MapInterface can flag a mapblock as modified. It is used in member methods to deal with the modification cache flags more easily - MapInterface has got another new function to check whether a mapblock is loaded or not and try to load it, all depending on a given position - MapInterface's save method is fixed - MapInterfaces can return a node's metadata using the get_meta(pos) method. It determines what mapblock contains the quierried node, and use the said mapblock's get_meta method to return a NodeMetaRef object * Metadata : Strings are stored as and decoded from arrays of integers, easier to convert from bytes without knowing what is float, what is int, and what is string * Nodes : The position argument in a Node object is now a key argument. The only mandatory parameter is the itemstring * Test : testSetNode now completly working. It doesn't change the node in (0,0,0) anymore. This node is a chest in the test map and is used to test metadata and inventory manipulation in the new invManip function called upon execution of test.py
This commit is contained in:
parent
c64b27d1de
commit
b8cbe3b75b
17
inventory.py
17
inventory.py
@ -129,3 +129,20 @@ class InvRef:
|
||||
data.write("EndInventory\n")
|
||||
|
||||
return data.getvalue()
|
||||
|
||||
# Some stuff from MT
|
||||
def is_empty(self, listname):
|
||||
if not self.lists.get(listname):
|
||||
return True
|
||||
|
||||
for stack in self.lists[listname].values():
|
||||
if stack.get_name() != "":
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def get_size(self, listname):
|
||||
if not self.lists.get(listname):
|
||||
return 0
|
||||
else:
|
||||
return len(self.lists[listname])
|
||||
|
73
map.py
73
map.py
@ -72,6 +72,7 @@ class MapBlock:
|
||||
# Node params
|
||||
node_data = {"param0": [], "param1": [], "param2": []}
|
||||
self.name_id_mappings = self.create_name_id_mappings()
|
||||
self.num_name_id_mappings = len(self.name_id_mappings)
|
||||
|
||||
for node in self.nodes.values():
|
||||
node_data["param0"].append(self.name_id_mappings.index(node.itemstring))
|
||||
@ -109,7 +110,7 @@ class MapBlock:
|
||||
|
||||
writeU32(meta_data, len(meta.data[meta_key]))
|
||||
for b in meta.data[meta_key]:
|
||||
writeU8(data, b)
|
||||
writeU8(meta_data, b)
|
||||
|
||||
for c in meta.get_inventory().to_string():
|
||||
meta_data.write(c.encode("utf8"))
|
||||
@ -134,9 +135,9 @@ class MapBlock:
|
||||
|
||||
# ID mappings starts here
|
||||
writeU8(data, self.name_id_mapping_version)
|
||||
self.num_id_mappings = len(self.name_id_mappings)
|
||||
self.num_name_id_mappings = len(self.name_id_mappings)
|
||||
writeU16(data, self.num_name_id_mappings)
|
||||
for i in range(self.num_id_mappings):
|
||||
for i in range(self.num_name_id_mappings):
|
||||
writeU16(data, i)
|
||||
writeU16(data, len(self.name_id_mappings[i]))
|
||||
for b in self.name_id_mappings[i]:
|
||||
@ -153,22 +154,20 @@ class MapBlock:
|
||||
# EOF.
|
||||
return data.getvalue()
|
||||
|
||||
def get_node(self, mapblockpos):
|
||||
def check_pos(self, mapblockpos):
|
||||
if not self.loaded:
|
||||
raise EmptyMapBlockError
|
||||
|
||||
if mapblockpos < 0 or mapblockpos >= 4096:
|
||||
raise OutOfBordersCoordinates
|
||||
|
||||
def get_node(self, mapblockpos):
|
||||
self.check_pos(mapblockpos)
|
||||
|
||||
return self.nodes[mapblockpos]
|
||||
|
||||
def set_node(self, mapblockpos, node):
|
||||
if not self.loaded:
|
||||
raise EmptyMapBlockError
|
||||
|
||||
if mapblockpos < 0 or mapblockpos >= 4096:
|
||||
raise OutOfBordersCoordinates
|
||||
|
||||
self.check_pos(mapblockpos)
|
||||
|
||||
if self.node_meta.get(mapblockpos):
|
||||
del self.node_meta[mapblockpos]
|
||||
@ -178,7 +177,7 @@ class MapBlock:
|
||||
self.nodes[mapblockpos] = node
|
||||
|
||||
self.name_id_mappings = self.create_name_id_mappings()
|
||||
self.num_id_mappings = len(self.name_id_mappings)
|
||||
self.num_name_id_mappings = len(self.name_id_mappings)
|
||||
return True
|
||||
|
||||
def explode(self, bytelist):
|
||||
@ -375,7 +374,7 @@ class MapBlock:
|
||||
self.static_objects.append({
|
||||
"type": otype,
|
||||
"pos": Pos({'x': pos_x_nodes, 'y': pos_y_nodes, 'z': pos_z_nodes}),
|
||||
"data": odata,
|
||||
"data": str(odata),
|
||||
})
|
||||
|
||||
# u32 timestamp
|
||||
@ -412,11 +411,16 @@ class MapBlock:
|
||||
itemstring = self.name_id_mappings[node_data["param0"][id]]
|
||||
param1 = node_data["param1"][id]
|
||||
param2 = node_data["param2"][id]
|
||||
self.nodes[id] = Node(posFromInt(id, self.mapblocksize), itemstring, param1 = param1, param2 = param2)
|
||||
self.nodes[id] = Node(itemstring, param1 = param1, param2 = param2, pos = posFromInt(id, self.mapblocksize))
|
||||
|
||||
# EOF!
|
||||
self.loaded = True
|
||||
|
||||
def get_meta(self, abspos):
|
||||
self.check_pos(abspos)
|
||||
|
||||
return self.node_meta[abspos]
|
||||
|
||||
class MapVessel:
|
||||
def __init__(self, mapfile, backend = "sqlite3"):
|
||||
self.mapfile = mapfile
|
||||
@ -515,7 +519,11 @@ class MapInterface:
|
||||
self.cache_history = []
|
||||
self.max_cache_size = 100
|
||||
self.mod_cache = []
|
||||
self.force_save_on_unload = False
|
||||
self.force_save_on_unload = True
|
||||
|
||||
def modFlag(self, mapblockpos):
|
||||
if not mapblockpos in self.mod_cache:
|
||||
self.mod_cache.append(mapblockpos)
|
||||
|
||||
def unloadMapBlock(self, blockID):
|
||||
self.mapblocks[blockID] = None
|
||||
@ -554,34 +562,45 @@ class MapInterface:
|
||||
del self.mod_cache[self.mod_cache.index(blockID)]
|
||||
return True
|
||||
|
||||
def get_node(self, pos):
|
||||
mapblock = determineMapBlock(pos)
|
||||
mapblockpos = getMapBlockPos(mapblock)
|
||||
def check_for_pos(self, mapblockpos):
|
||||
if not self.mapblocks.get(mapblockpos):
|
||||
self.loadMapBlock(mapblockpos)
|
||||
|
||||
if not self.mapblocks.get(mapblockpos):
|
||||
self.unloadMapBlock(mapblockpos)
|
||||
return Node(pos, "ignore")
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def get_node(self, pos):
|
||||
mapblock = determineMapBlock(pos)
|
||||
mapblockpos = getMapBlockPos(mapblock)
|
||||
if not self.check_for_pos(mapblockpos):
|
||||
return Node("ignore", pos = pos)
|
||||
|
||||
return self.mapblocks[mapblockpos].get_node((pos.x % 16) + (pos.y % 16) * 16 + (pos.z % 16) * 16 * 16)
|
||||
|
||||
def set_node(self, pos, node):
|
||||
mapblock = determineMapBlock(pos)
|
||||
mapblockpos = getMapBlockPos(mapblock)
|
||||
if not self.mapblocks.get(mapblockpos):
|
||||
self.loadMapBlock(mapblockpos)
|
||||
|
||||
if not self.mapblocks.get(mapblockpos):
|
||||
self.unloadMapBlock(mapblockpos)
|
||||
if not self.check_for_pos(mapblockpos):
|
||||
raise IgnoreContentReplacementError("Pos: " + pos)
|
||||
|
||||
node.pos = pos
|
||||
if not mapblockpos in self.mod_cache:
|
||||
self.mod_cache.append(mapblockpos)
|
||||
self.modFlag(mapblockpos)
|
||||
|
||||
return self.mapblocks[mapblockpos].set_node((pos.x % 16) + (pos.y % 16) * 16 + (pos.z % 16) * 16 * 16, node)
|
||||
|
||||
def save(self):
|
||||
for blockID in self.mod_cache:
|
||||
self.saveMapBlock(blockID)
|
||||
while len(self.mod_cache) > 0:
|
||||
self.saveMapBlock(self.mod_cache[0])
|
||||
self.mod_cache = []
|
||||
|
||||
def get_meta(self, pos):
|
||||
mapblock = determineMapBlock(pos)
|
||||
mapblockpos = getMapBlockPos(mapblock)
|
||||
self.modFlag(mapblockpos)
|
||||
if not self.check_for_pos(mapblockpos):
|
||||
return NodeMetaRef()
|
||||
|
||||
return self.mapblocks[mapblockpos].get_meta(intFromPos(pos, 16))
|
||||
|
15
metadata.py
15
metadata.py
@ -23,10 +23,21 @@ class NodeMetaRef:
|
||||
self.data[key] = val
|
||||
|
||||
def get_string(self, key):
|
||||
return str(self.data.get(key))
|
||||
# Gather the integers into a string
|
||||
data = self.data.get(key)
|
||||
if not data:
|
||||
return None
|
||||
|
||||
res = ""
|
||||
for c in data:
|
||||
if c >= 256 or c < 0:
|
||||
return data # IT IS A NUMBER AAAAAH
|
||||
|
||||
res += chr(c)
|
||||
return res
|
||||
|
||||
def set_string(self, key, val):
|
||||
self.data[key] = str(val)
|
||||
self.data[key] = [ord(b) for b in val]
|
||||
|
||||
def get_int(self, key):
|
||||
return int(self.data.get(key))
|
||||
|
2
nodes.py
2
nodes.py
@ -35,7 +35,7 @@ class NodeTimerRef:
|
||||
return self.active
|
||||
|
||||
class Node:
|
||||
def __init__(self, pos, itemstring, param1 = 0, param2 = 0):
|
||||
def __init__(self, itemstring, param1 = 0, param2 = 0, pos = Pos()):
|
||||
self.pos = pos
|
||||
self.itemstring = itemstring
|
||||
self.param1, self.param2 = param1, param2
|
||||
|
26
test.py
26
test.py
@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python3
|
||||
#!/usr/bin/env python3.4
|
||||
# -*- encoding: utf-8 -*-
|
||||
############################
|
||||
## Tests ran for Python-MT
|
||||
@ -85,20 +85,32 @@ def testGetNode():
|
||||
|
||||
def testSetNode():
|
||||
db = minetest.MapInterface("./map.sqlite")
|
||||
db.force_save_on_unload = True
|
||||
f = open("./dump.bin", "w")
|
||||
dummy = minetest.Node(Pos(), "default:nyancat", 0, 0)
|
||||
print(db.get_node(Pos()))
|
||||
print(db.set_node(Pos(), dummy))
|
||||
dummy = minetest.Node("default:nyancat")
|
||||
|
||||
for y in range(0, 256):
|
||||
for y in range(1, 256):
|
||||
db.set_node(Pos({'x': 0, 'y': y, 'z': 0}), dummy)
|
||||
|
||||
db.save()
|
||||
|
||||
def invManip():
|
||||
db = minetest.MapInterface("./map.sqlite")
|
||||
chest = db.get_meta(Pos({'x': 0, 'y': 0, 'z': 0}))
|
||||
#print(chest)
|
||||
inv = chest.get_inventory()
|
||||
#print(inv)
|
||||
#print(chest.get_string("formspec"))
|
||||
#chest.set_string("formspec", chest.get_string("formspec") + "button[0,0;1,0.5;moo;Moo]")
|
||||
#print(chest.get_string("formspec"))
|
||||
print(inv.is_empty("main"))
|
||||
print(inv.get_size("main"))
|
||||
|
||||
db.save()
|
||||
|
||||
if __name__ == "__main__":
|
||||
#findTheShelves()
|
||||
#testMapBlockLoad()
|
||||
#testSignedEndians()
|
||||
#testGetNode()
|
||||
testSetNode()
|
||||
#testSetNode()
|
||||
invManip()
|
||||
|
Loading…
x
Reference in New Issue
Block a user