9 Commits

11 changed files with 434 additions and 57 deletions

View File

@ -21,9 +21,10 @@ if(WIN32)
set(BINDIR ".")
set(DOCDIR ".")
else()
set(SHAREDIR "${CMAKE_INSTALL_PREFIX}/share/minetest") # an extra dir. for just one file doesn't seem useful
set(SHAREDIR "${CMAKE_INSTALL_PREFIX}/share/minetest") # reuse Minetest share dir
set(BINDIR "${CMAKE_INSTALL_PREFIX}/bin")
set(DOCDIR "${CMAKE_INSTALL_PREFIX}/share/doc/${PROJECT_NAME}")
set(MANDIR "${CMAKE_INSTALL_PREFIX}/share/man")
endif()
set(CUSTOM_SHAREDIR "" CACHE STRING "Directory to install data files into")
@ -78,6 +79,40 @@ if(NOT SQLITE3_LIBRARY OR NOT SQLITE3_INCLUDE_DIR)
message(FATAL_ERROR "sqlite3 not found!")
endif(NOT SQLITE3_LIBRARY OR NOT SQLITE3_INCLUDE_DIR)
# Libraries: postgresql
option(ENABLE_POSTGRESQL "Enable PostgreSQL backend" TRUE)
set(USE_POSTGRESQL 0)
if(ENABLE_POSTGRESQL)
find_program(POSTGRESQL_CONFIG_EXECUTABLE pg_config DOC "pg_config")
find_library(POSTGRESQL_LIBRARY pq)
if(POSTGRESQL_CONFIG_EXECUTABLE)
execute_process(COMMAND ${POSTGRESQL_CONFIG_EXECUTABLE} --includedir-server
OUTPUT_VARIABLE POSTGRESQL_SERVER_INCLUDE_DIRS
OUTPUT_STRIP_TRAILING_WHITESPACE)
execute_process(COMMAND ${POSTGRESQL_CONFIG_EXECUTABLE}
OUTPUT_VARIABLE POSTGRESQL_CLIENT_INCLUDE_DIRS
OUTPUT_STRIP_TRAILING_WHITESPACE)
# This variable is case sensitive for the cmake PostgreSQL module
set(PostgreSQL_ADDITIONAL_SEARCH_PATHS ${POSTGRESQL_SERVER_INCLUDE_DIRS} ${POSTGRESQL_CLIENT_INCLUDE_DIRS})
endif()
find_package("PostgreSQL")
if(POSTGRESQL_FOUND)
set(USE_POSTGRESQL 1)
message(STATUS "PostgreSQL backend enabled")
# This variable is case sensitive, don't try to change it to POSTGRESQL_INCLUDE_DIR
message(STATUS "PostgreSQL includes: ${PostgreSQL_INCLUDE_DIR}")
include_directories(${PostgreSQL_INCLUDE_DIR})
set(POSTGRESQL_LIBRARY ${PostgreSQL_LIBRARIES})
else()
message(STATUS "PostgreSQL not found.")
set(POSTGRESQL_LIBRARY "")
endif()
endif(ENABLE_POSTGRESQL)
# Libraries: leveldb
set(USE_LEVELDB 0)
@ -148,6 +183,10 @@ set(mapper_SRCS
db-sqlite3.cpp
)
if(USE_POSTGRESQL)
set(mapper_SRCS ${mapper_SRCS} db-postgresql.cpp)
endif(USE_POSTGRESQL)
if(USE_LEVELDB)
set(mapper_SRCS ${mapper_SRCS} db-leveldb.cpp)
endif(USE_LEVELDB)
@ -163,6 +202,7 @@ add_executable(minetestmapper
target_link_libraries(
minetestmapper
${SQLITE3_LIBRARY}
${POSTGRESQL_LIBRARY}
${LEVELDB_LIBRARY}
${REDIS_LIBRARY}
${LIBGD_LIBRARY}
@ -176,6 +216,9 @@ install(FILES "AUTHORS" DESTINATION "${DOCDIR}")
install(FILES "COPYING" DESTINATION "${DOCDIR}")
install(FILES "README.rst" DESTINATION "${DOCDIR}")
install(FILES "colors.txt" DESTINATION "${SHAREDIR}")
if(UNIX)
install(FILES "minetestmapper.6" DESTINATION "${MANDIR}/man6")
endif()
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Overview mapper for Minetest")
set(CPACK_PACKAGE_VERSION_MAJOR ${VERSION_MAJOR})

View File

@ -9,6 +9,8 @@ struct Color {
Color() : r(0), g(0), b(0), a(0) {};
Color(u8 r, u8 g, u8 b) : r(r), g(g), b(b), a(255) {};
Color(u8 r, u8 g, u8 b, u8 a) : r(r), g(g), b(b), a(a) {};
inline Color noAlpha() const { return Color(r, g, b); }
u8 r, g, b, a;
};

View File

@ -12,13 +12,24 @@ Requirements
* libgd
* sqlite3
* leveldb (optional, set ENABLE_LEVELDB=1 in CMake to enable leveldb support)
* hiredis (optional, set ENABLE_REDIS=1 in CMake to enable redis support)
* leveldb (optional, set ENABLE_LEVELDB=1 in CMake to enable)
* hiredis (optional, set ENABLE_REDIS=1 in CMake to enable)
* Postgres libraries (optional, set ENABLE_POSTGRES=1 in CMake to enable)
e.g. on Debian:
^^^^^^^^^^^^^^^
sudo apt-get install libgd-dev libsqlite3-dev libleveldb-dev libhiredis-dev
sudo apt-get install libgd-dev libsqlite3-dev libleveldb-dev libhiredis-dev libpq-dev
Windows
^^^^^^^
Minetestmapper for Windows can be downloaded here: https://github.com/minetest/minetestmapper/releases
After extracting the archive somewhere minetestmapper will be available from cmd.exe:
::
cd C:\Users\yourname\Desktop\example\path
minetestmapper.exe --help
Compilation
-----------
@ -76,7 +87,7 @@ max-y:
Don't draw nodes above this y value, e.g. ``--max-y 75``
backend:
Use specific map backend, supported: *sqlite3*, *leveldb*, *redis*, e.g. ``--backend leveldb``
Use specific map backend; supported: *sqlite3*, *leveldb*, *redis*, *postgresql*, e.g. ``--backend leveldb``
geometry:
Limit area to specific geometry (*x:y+w+h* where x and y specify the lower left corner), e.g. ``--geometry -800:-800+1600+1600``

View File

@ -13,6 +13,9 @@
#include "ZlibDecompressor.h"
#include "util.h"
#include "db-sqlite3.h"
#if USE_POSTGRESQL
#include "db-postgresql.h"
#endif
#if USE_LEVELDB
#include "db-leveldb.h"
#endif
@ -283,6 +286,10 @@ void TileGenerator::openDb(const std::string &input)
if(backend == "sqlite3")
m_db = new DBSQLite3(input);
#if USE_POSTGRESQL
else if(backend == "postgresql")
m_db = new DBPostgreSQL(input);
#endif
#if USE_LEVELDB
else if(backend == "leveldb")
m_db = new DBLevelDB(input);
@ -387,7 +394,9 @@ void TileGenerator::renderMap()
//uint8_t flags = data[1];
size_t dataOffset = 0;
if (version >= 22)
if (version >= 27)
dataOffset = 6;
else if (version >= 22)
dataOffset = 4;
else
dataOffset = 2;
@ -526,7 +535,7 @@ void TileGenerator::renderMapBlock(const ustring &mapBlock, const BlockPos &pos,
continue;
}
} else {
setZoomed(imageX, imageY, c);
setZoomed(imageX, imageY, c.noAlpha());
m_readPixels[z] |= (1 << x);
}
if(!(m_readInfo[z] & (1 << x))) {

View File

@ -1,11 +1,14 @@
==FILE== mods/dumpnodes/init.lua
local function nd_get_tiles(nd)
if nd.tiles then
return nd.tiles
elseif nd.tile_images then
return nd.tile_images
return nd.tiles or nd.tile_images
end
local function nd_get_tile(nd, n)
local tile = nd_get_tiles(nd)[n]
if type(tile) == 'table' then
tile = tile.name
end
return nil
return tile
end
local function pairs_s(dict)
@ -20,19 +23,19 @@ end
minetest.register_chatcommand("dumpnodes", {
params = "",
description = "",
func = function(plname, param)
func = function(player, param)
local n = 0
local ntbl = {}
for _, nn in pairs_s(minetest.registered_nodes) do
local nd = minetest.registered_nodes[nn]
local prefix, name = nn:match('(.*):(.*)')
if prefix == nil or name == nil or prefix == '' or name == '' then
if prefix == nil or name == nil then
print("ignored(1): " .. nn)
else
if ntbl[prefix] == nil then
ntbl[prefix] = {}
end
ntbl[prefix][name] = nd
ntbl[prefix][name] = true
end
end
local out, err = io.open('nodes.txt', 'wb')
@ -40,20 +43,17 @@ minetest.register_chatcommand("dumpnodes", {
return true, "io.open(): " .. err
end
for _, prefix in pairs_s(ntbl) do
local nodes = ntbl[prefix]
out:write('# ' .. prefix .. '\n')
for _, name in pairs_s(nodes) do
local nd = nodes[name]
if nd.drawtype ~= 'airlike' and nd_get_tiles(nd) ~= nil then
local tl = nd_get_tiles(nd)[1]
if type(tl) == 'table' then
tl = tl.name
end
tl = (tl .. '^'):match('(.-)^')
out:write(prefix .. ':' .. name .. ' ' .. tl .. '\n')
n = n + 1
for _, name in pairs_s(ntbl[prefix]) do
local nn = prefix .. ":" .. name
local nd = minetest.registered_nodes[nn]
if nd.drawtype == 'airlike' or nd_get_tiles(nd) == nil then
print("ignored(2): " .. nn)
else
print("ignored(2): " .. prefix .. ':' .. name)
local tl = nd_get_tile(nd, 1)
tl = (tl .. '^'):match('(.-)^') -- strip modifiers
out:write(nn .. ' ' .. tl .. '\n')
n = n + 1
end
end
out:write('\n')
@ -67,7 +67,7 @@ minetest.register_chatcommand("dumpnodes", {
import sys
from PIL import Image
def tsum(a, b):
def tadd(a, b):
return tuple(sum(e) for e in zip(a, b))
if len(sys.argv) < 2:
@ -75,8 +75,7 @@ if len(sys.argv) < 2:
print("Usage: %s <input>" % sys.argv[0])
exit(1)
inp = Image.open(sys.argv[1])
inp = inp.convert('RGBA')
inp = Image.open(sys.argv[1]).convert('RGBA')
ind = inp.load()
cl = (0, 0, 0)
@ -84,39 +83,36 @@ counted = 0
for x in range(inp.size[0]):
for y in range(inp.size[1]):
px = ind[x, y]
if px[3] < 128:
continue
cl = tsum(cl, px[:3])
counted = counted + 1
if px[3] < 128: continue # alpha
cl = tadd(cl, px[:3])
counted += 1
if counted == 0:
sys.stderr.write("didn't find avg. color for %s\n" % sys.argv[1])
sys.stderr.write("did not find avg color for %s\n" % sys.argv[1])
print("0 0 0")
exit(0)
cl = tuple(int(n / counted) for n in cl)
print("%d %d %d" % cl)
else:
cl = tuple(int(n / counted) for n in cl)
print("%d %d %d" % cl)
==SCRIPT==
#!/bin/bash -e
AVGCOLOR_PATH=/path/to/avgcolor.py
MTGAME_PATH=/path/to/minetest_game
GAME_PATH=/path/to/minetest_game
MODS_PATH= # path to "mods" folder, only set if you have loaded mods
NODESTXT_PATH=./nodes.txt
COLORSTXT_PATH=./colors.txt
while read -r line; do
set -- junk $line
shift
set -- junk $line; shift
if [[ -z "$1" || $1 == "#" ]]; then
echo $line
continue
echo "$line"; continue
fi
tex=$(find $MTGAME_PATH -type f -name "$2")
tex=$(find $GAME_PATH -type f -name "$2")
[[ -z "$tex" && -n "$MODS_PATH" ]] && tex=$(find $MODS_PATH -type f -name "$2")
if [ -z "$tex" ]; then
echo "skip $1: texture not found" >&2
continue
fi
echo $1 $(python $AVGCOLOR_PATH "$tex")
echo "$1" $(python $AVGCOLOR_PATH "$tex")
echo "ok $1" >&2
done < $NODESTXT_PATH > $COLORSTXT_PATH
# Use nicer colors for water and lava:
@ -128,8 +124,8 @@ sed -re 's/^doors:(.*glass[^ ]*) ([0-9 ]+)$/doors:\1 \2 64 16/g' $COLORSTXT_PATH
# Fix xpanes color:
sed -re 's/^xpanes:((pane|bar)(_flat)?) [0-9 ]+$/xpanes:\1 194 194 227 64 16/g' $COLORSTXT_PATH -i
==INSTRUCTIONS==
1) Make sure avgcolors.py outputs the usage instructions
1) Make sure avgcolors.py works (outputs the usage instructions when run)
2) Add the dumpnodes mod to Minetest
3) Create a world and load dumpnodes & all mods you want to generate colors for
4) Execute /dumpnodes ingame
5) Run the script to generate colors.txt (make sure to replace /path/to/... with the actual paths)
5) Run the script to generate colors.txt (make sure to adjust the PATH variables at the top)

View File

@ -3,6 +3,7 @@
#ifndef CMAKE_CONFIG_H
#define CMAKE_CONFIG_H
#define USE_POSTGRESQL @USE_POSTGRESQL@
#define USE_LEVELDB @USE_LEVELDB@
#define USE_REDIS @USE_REDIS@

View File

@ -14,13 +14,14 @@ carts:rail 143 123 90
# default
default:acacia_bush_leaves 90 124 55
default:acacia_bush_sapling 85 118 58
default:acacia_bush_stem 84 76 69
default:acacia_leaves 108 147 67
default:acacia_sapling 87 116 61
default:acacia_tree 188 109 90
default:acacia_wood 146 60 37
default:apple 145 20 9
default:aspen_leaves 66 89 38
default:aspen_leaves 70 104 27
default:aspen_sapling 82 110 43
default:aspen_tree 218 197 166
default:aspen_wood 209 198 169
@ -28,10 +29,13 @@ default:bookshelf 128 99 55
default:brick 117 71 69
default:bronzeblock 185 110 15
default:bush_leaves 34 52 29
default:bush_sapling 65 60 40
default:bush_stem 45 33 23
default:cactus 52 116 15
default:chest 140 108 65
default:chest_locked 140 108 65
default:chest_locked_open 140 108 65
default:chest_open 140 108 65
default:clay 182 182 182
default:cloud 255 255 255
default:coalblock 57 57 57
@ -42,6 +46,9 @@ default:coral_orange 191 62 12
default:coral_skeleton 235 230 214
default:desert_cobble 146 95 76
default:desert_sand 206 165 98
default:desert_sandstone 195 152 92
default:desert_sandstone_block 192 151 94
default:desert_sandstone_brick 191 151 94
default:desert_stone 129 79 60
default:desert_stone_block 130 79 60
default:desert_stonebrick 129 79 60
@ -50,7 +57,8 @@ default:dirt 95 64 39
default:dirt_with_dry_grass 187 148 77
default:dirt_with_grass 66 112 31
default:dirt_with_grass_footsteps 66 112 31
default:dirt_with_snow 223 224 236
default:dirt_with_rainforest_litter 74 38 8
default:dirt_with_snow 224 225 238
default:dry_grass_1 208 172 87
default:dry_grass_2 210 174 87
default:dry_grass_3 210 174 87
@ -84,6 +92,7 @@ default:lava_flowing 255 100 0
default:lava_source 255 100 0
default:leaves 34 52 29
default:mese 220 220 0
default:mese_post_light 131 102 57
default:meselamp 211 213 139
default:mossycobble 86 90 68
default:obsidian 19 21 24
@ -105,8 +114,11 @@ default:sapling 65 59 40
default:sign_wall_steel 144 144 144
default:sign_wall_wood 145 101 64
default:silver_sand 193 191 179
default:snow 223 224 236
default:snowblock 223 224 236
default:silver_sandstone 195 192 181
default:silver_sandstone_block 192 190 179
default:silver_sandstone_brick 190 188 178
default:snow 224 225 238
default:snowblock 224 225 238
default:steelblock 194 194 194
default:stone 97 94 93
default:stone_block 99 96 95
@ -116,7 +128,9 @@ default:stone_with_diamond 97 94 93
default:stone_with_gold 97 94 93
default:stone_with_iron 97 94 93
default:stone_with_mese 97 94 93
default:stone_with_tin 97 94 93
default:stonebrick 99 96 95
default:tinblock 149 149 149
default:torch 120 98 67
default:torch_ceiling 120 98 67
default:torch_wall 120 98 67
@ -190,10 +204,6 @@ flowers:tulip 130 99 36
flowers:viola 106 60 159
flowers:waterlily 102 158 61
# nyancat
nyancat:nyancat 198 111 167
nyancat:nyancat_rainbow 123 100 94
# stairs
stairs:slab_acacia_wood 146 60 37
stairs:slab_aspen_wood 209 198 169
@ -202,10 +212,14 @@ stairs:slab_bronzeblock 185 110 15
stairs:slab_cobble 88 84 82
stairs:slab_copperblock 192 126 63
stairs:slab_desert_cobble 146 95 76
stairs:slab_desert_sandstone 195 152 92
stairs:slab_desert_sandstone_block 192 151 94
stairs:slab_desert_sandstone_brick 191 151 94
stairs:slab_desert_stone 129 79 60
stairs:slab_desert_stone_block 130 79 60
stairs:slab_desert_stonebrick 129 79 60
stairs:slab_goldblock 230 201 29
stairs:slab_ice 167 206 247
stairs:slab_junglewood 54 37 11
stairs:slab_mossycobble 86 90 68
stairs:slab_obsidian 19 21 24
@ -215,6 +229,10 @@ stairs:slab_pine_wood 221 184 128
stairs:slab_sandstone 197 193 143
stairs:slab_sandstone_block 195 190 141
stairs:slab_sandstonebrick 193 189 140
stairs:slab_silver_sandstone 195 192 181
stairs:slab_silver_sandstone_block 192 190 179
stairs:slab_silver_sandstone_brick 190 188 178
stairs:slab_snowblock 224 225 238
stairs:slab_steelblock 194 194 194
stairs:slab_stone 97 94 93
stairs:slab_stone_block 99 96 95
@ -228,10 +246,14 @@ stairs:stair_bronzeblock 185 110 15
stairs:stair_cobble 88 84 82
stairs:stair_copperblock 192 126 63
stairs:stair_desert_cobble 146 95 76
stairs:stair_desert_sandstone 195 152 92
stairs:stair_desert_sandstone_block 192 151 94
stairs:stair_desert_sandstone_brick 191 151 94
stairs:stair_desert_stone 129 79 60
stairs:stair_desert_stone_block 130 79 60
stairs:stair_desert_stonebrick 129 79 60
stairs:stair_goldblock 230 201 29
stairs:stair_ice 167 206 247
stairs:stair_junglewood 54 37 11
stairs:stair_mossycobble 86 90 68
stairs:stair_obsidian 19 21 24
@ -241,6 +263,10 @@ stairs:stair_pine_wood 221 184 128
stairs:stair_sandstone 197 193 143
stairs:stair_sandstone_block 195 190 141
stairs:stair_sandstonebrick 193 189 140
stairs:stair_silver_sandstone 195 192 181
stairs:stair_silver_sandstone_block 192 190 179
stairs:stair_silver_sandstone_brick 190 188 178
stairs:stair_snowblock 224 225 238
stairs:stair_steelblock 194 194 194
stairs:stair_stone 97 94 93
stairs:stair_stone_block 99 96 95

View File

@ -9,6 +9,7 @@
#ifdef USE_CMAKE_CONFIG_H
#include "cmake_config.h"
#else
#define USE_POSTGRESQL 0
#define USE_LEVELDB 0
#define USE_REDIS 0

168
db-postgresql.cpp Normal file
View File

@ -0,0 +1,168 @@
#include <stdexcept>
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <arpa/inet.h>
#include "db-postgresql.h"
#include "util.h"
#include "types.h"
#define ARRLEN(x) (sizeof(x) / sizeof((x)[0]))
DBPostgreSQL::DBPostgreSQL(const std::string &mapdir)
{
std::ifstream ifs((mapdir + "/world.mt").c_str());
if(!ifs.good())
throw std::runtime_error("Failed to read world.mt");
std::string const connect_string = get_setting("pgsql_connection", ifs);
ifs.close();
db = PQconnectdb(connect_string.c_str());
if (PQstatus(db) != CONNECTION_OK) {
throw std::runtime_error(std::string(
"PostgreSQL database error: ") +
PQerrorMessage(db)
);
}
prepareStatement(
"get_block_pos",
"SELECT posX, posY, posZ FROM blocks"
);
prepareStatement(
"get_blocks_z",
"SELECT posX, posY, data FROM blocks WHERE posZ = $1::int4"
);
checkResults(PQexec(db, "START TRANSACTION;"));
checkResults(PQexec(db, "SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;"));
}
DBPostgreSQL::~DBPostgreSQL()
{
try {
checkResults(PQexec(db, "COMMIT;"));
} catch (std::exception& caught) {
std::cerr << "could not finalize: " << caught.what() << std::endl;
}
PQfinish(db);
}
std::vector<BlockPos> DBPostgreSQL::getBlockPos()
{
std::vector<BlockPos> positions;
PGresult *results = execPrepared(
"get_block_pos", 0,
NULL, NULL, NULL, false, false
);
int numrows = PQntuples(results);
for (int row = 0; row < numrows; ++row)
positions.push_back(pg_to_blockpos(results, row, 0));
PQclear(results);
return positions;
}
void DBPostgreSQL::getBlocksOnZ(std::map<int16_t, BlockList> &blocks, int16_t zPos)
{
int32_t const z = htonl(zPos);
const void *args[] = { &z };
const int argLen[] = { sizeof(z) };
const int argFmt[] = { 1 };
PGresult *results = execPrepared(
"get_blocks_z", ARRLEN(args), args,
argLen, argFmt, false
);
int numrows = PQntuples(results);
for (int row = 0; row < numrows; ++row) {
BlockPos position;
position.x = pg_binary_to_int(results, row, 0);
position.y = pg_binary_to_int(results, row, 1);
position.z = zPos;
Block const b(
position,
ustring(
reinterpret_cast<unsigned char*>(
PQgetvalue(results, row, 2)
),
PQgetlength(results, row, 2)
)
);
blocks[position.x].push_back(b);
}
PQclear(results);
}
PGresult *DBPostgreSQL::checkResults(PGresult *res, bool clear)
{
ExecStatusType statusType = PQresultStatus(res);
switch (statusType) {
case PGRES_COMMAND_OK:
case PGRES_TUPLES_OK:
break;
case PGRES_FATAL_ERROR:
throw std::runtime_error(
std::string("PostgreSQL database error: ") +
PQresultErrorMessage(res)
);
default:
throw std::runtime_error(
"Unhandled PostgreSQL result code"
);
}
if (clear)
PQclear(res);
return res;
}
void DBPostgreSQL::prepareStatement(const std::string &name, const std::string &sql)
{
checkResults(PQprepare(db, name.c_str(), sql.c_str(), 0, NULL));
}
PGresult *DBPostgreSQL::execPrepared(
const char *stmtName, const int paramsNumber,
const void **params,
const int *paramsLengths, const int *paramsFormats,
bool clear, bool nobinary
)
{
return checkResults(PQexecPrepared(db, stmtName, paramsNumber,
(const char* const*) params, paramsLengths, paramsFormats,
nobinary ? 1 : 0), clear
);
}
int DBPostgreSQL::pg_to_int(PGresult *res, int row, int col)
{
return atoi(PQgetvalue(res, row, col));
}
int DBPostgreSQL::pg_binary_to_int(PGresult *res, int row, int col)
{
int32_t* raw = reinterpret_cast<int32_t*>(PQgetvalue(res, row, col));
return ntohl(*raw);
}
BlockPos DBPostgreSQL::pg_to_blockpos(PGresult *res, int row, int col)
{
BlockPos result;
result.x = pg_to_int(res, row, col);
result.y = pg_to_int(res, row, col + 1);
result.z = pg_to_int(res, row, col + 2);
return result;
}

29
db-postgresql.h Normal file
View File

@ -0,0 +1,29 @@
#ifndef _DB_POSTGRESQL_H
#define _DB_POSTGRESQL_H
#include "db.h"
#include <libpq-fe.h>
class DBPostgreSQL : public DB {
public:
DBPostgreSQL(const std::string &mapdir);
virtual std::vector<BlockPos> getBlockPos();
virtual void getBlocksOnZ(std::map<int16_t, BlockList> &blocks, int16_t zPos);
virtual ~DBPostgreSQL();
protected:
PGresult *checkResults(PGresult *res, bool clear = true);
void prepareStatement(const std::string &name, const std::string &sql);
PGresult *execPrepared(
const char *stmtName, const int paramsNumber,
const void **params,
const int *paramsLengths = NULL, const int *paramsFormats = NULL,
bool clear = true, bool nobinary = true
);
int pg_to_int(PGresult *res, int row, int col);
int pg_binary_to_int(PGresult *res, int row, int col);
BlockPos pg_to_blockpos(PGresult *res, int row, int col);
private:
PGconn *db;
};
#endif // _DB_POSTGRESQL_H

91
minetestmapper.6 Normal file
View File

@ -0,0 +1,91 @@
.TH MINETESTMAPPER 6
.SH NAME
minetestmapper \- generate an overview image of a Minetest map
.SH SYNOPSIS
.B minetestmapper
\fB\-i\fR \fIworld_path\fR
\fB\-o\fR \fIoutput_image\fR
.PP
See additional optional parameters below.
.SH DESCRIPTION
.B minetestmapper
generates an overview image of a minetest map. This is a port of
the original minetestmapper.py to C++, that is both faster and
provides more funtionality than the deprecated Python script.
.SH MANDATORY PARAMETERS
.TP
.BR \-i " " \fIworld_path\fR
Input world path.
.TP
.BR \-o " " \fIoutput_image\fR
Path to output image. (only PNG supported currently)
.SH OPTIONAL PARAMETERS
.TP
.BR \-\-bgcolor " " \fIcolor\fR
Background color of image, e.g. "--bgcolor #ffffff"
.TP
.BR \-\-scalecolor " " \fIcolor\fR
Color of scale, e.g. "--scalecolor #000000"
.TP
.BR \-\-playercolor " " \fIcolor\fR
Color of player indicators, e.g. "--playercolor #ff0000"
.TP
.BR \-\-origincolor " " \fIcolor\fR
Color of origin indicator, e.g. "--origincolor #ff0000"
.TP
.BR \-\-drawscale
Draw tick marks
.TP
.BR \-\-drawplayers
Draw player indicators
.TP
.BR \-\-draworigin
Draw origin indicator
.TP
.BR \-\-drawalpha
Allow nodes to be drawn with transparency
.TP
.BR \-\-noshading
Don't draw shading on nodes
.TP
.BR \-\-min-y " " \fInumber\fR
Don't draw nodes below this y value, e.g. "--min-y -25"
.TP
.BR \-\-max-y " " \fInumber\fR
Don't draw nodes above this y value, e.g. "--max-y 75"
.TP
.BR \-\-backend " " \fIbackend\fR
Use specific map backend; supported: *sqlite3*, *leveldb*, *redis*, *postgresql*, e.g. "--backend leveldb"
.TP
.BR \-\-geometry " " \fIgeometry\fR
Limit area to specific geometry (*x:y+w+h* where x and y specify the lower left corner), e.g. "--geometry -800:-800+1600+1600"
.TP
.BR \-\-zoom " " \fIfactor\fR
Zoom the image by using more than one pixel per node, e.g. "--zoom 4"
.TP
.BR \-\-colors " " \fIpath\fR
Forcefully set path to colors.txt file (it's autodetected otherwise), e.g. "--colors ../minetest/mycolors.txt"
.TP
.BR \-\-scales " " \fIedges\fR
Draw scales on specified image edges (letters *t b l r* meaning top, bottom, left and right), e.g. "--scales tbr"
.SH MORE INFORMATION
Website: https://github.com/minetest/minetestmapper
.SH MAN PAGE AUTHOR
Daniel Moerner