aboutsummaryrefslogtreecommitdiff
path: root/src/serialization.h
blob: 86da31486f2fffd8e6504a06122d0f1dfa15d5b4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
/*
Minetest
Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#ifndef SERIALIZATION_HEADER
#define SERIALIZATION_HEADER

#include "irrlichttypes.h"
#include "exceptions.h"
#include <iostream>
#include "util/pointer.h"

/*
	Map format serialization version
	--------------------------------

	For map data (blocks, nodes, sectors).
	
	NOTE: The goal is to increment this so that saved maps will be
	      loadable by any version. Other compatibility is not
		  maintained.
		  
	0: original networked test with 1-byte nodes
	1: update with 2-byte nodes
	2: lighting is transmitted in param
	3: optional fetching of far blocks
	4: block compression
	5: sector objects NOTE: block compression was left accidentally out
	6: failed attempt at switching block compression on again
	7: block compression switched on again
	8: server-initiated block transfers and all kinds of stuff
	9: block objects
	10: water pressure
	11: zlib'd blocks, block flags
	12: UnlimitedHeightmap now uses interpolated areas
	13: Mapgen v2
	14: NodeMetadata
	15: StaticObjects
	16: larger maximum size of node metadata, and compression
	17: MapBlocks contain timestamp
	18: new generator (not really necessary, but it's there)
	19: new content type handling
	20: many existing content types translated to extended ones
	21: dynamic content type allocation
	22: minerals removed, facedir & wallmounted changed
	23: new node metadata format
	24: 16-bit node ids and node timers (never released as stable)
	25: Improved node timer format
	26: Never written; read the same as 25
*/
// This represents an uninitialized or invalid format
#define SER_FMT_VER_INVALID 255
// Highest supported serialization version
#define SER_FMT_VER_HIGHEST_READ 26
// Saved on disk version
#define SER_FMT_VER_HIGHEST_WRITE 25
// Lowest supported serialization version
#define SER_FMT_VER_LOWEST 0

#define ser_ver_supported(v) (v >= SER_FMT_VER_LOWEST && v <= SER_FMT_VER_HIGHEST_READ)

/*
	Misc. serialization functions
*/

void compressZlib(SharedBuffer<u8> data, std::ostream &os);
void compressZlib(const std::string &data, std::ostream &os);
void decompressZlib(std::istream &is, std::ostream &os);

// These choose between zlib and a self-made one according to version
void compress(SharedBuffer<u8> data, std::ostream &os, u8 version);
//void compress(const std::string &data, std::ostream &os, u8 version);
void decompress(std::istream &is, std::ostream &os, u8 version);

#endif

pan> LogLevel { LL_NONE, // Special level that is always printed LL_ERROR, LL_WARNING, LL_ACTION, // In-game actions LL_INFO, LL_VERBOSE, LL_MAX, }; typedef u8 LogLevelMask; #define LOGLEVEL_TO_MASKLEVEL(x) (1 << x) class Logger { public: void addOutput(ILogOutput *out); void addOutput(ILogOutput *out, LogLevel lev); void addOutputMasked(ILogOutput *out, LogLevelMask mask); void addOutputMaxLevel(ILogOutput *out, LogLevel lev); LogLevelMask removeOutput(ILogOutput *out); void setLevelSilenced(LogLevel lev, bool silenced); void registerThread(const std::string &name); void deregisterThread(); void log(LogLevel lev, const std::string &text); // Logs without a prefix void logRaw(LogLevel lev, const std::string &text); void setTraceEnabled(bool enable) { m_trace_enabled = enable; } bool getTraceEnabled() { return m_trace_enabled; } static LogLevel stringToLevel(const std::string &name); static const std::string getLevelLabel(LogLevel lev); private: void logToOutputsRaw(LogLevel, const std::string &line); void logToOutputs(LogLevel, const std::string &combined, const std::string &time, const std::string &thread_name, const std::string &payload_text); const std::string getThreadName(); std::vector<ILogOutput *> m_outputs[LL_MAX]; // Should implement atomic loads and stores (even though it's only // written to when one thread has access currently). // Works on all known architectures (x86, ARM, MIPS). volatile bool m_silenced_levels[LL_MAX]; std::map<std::thread::id, std::string> m_thread_names; mutable std::mutex m_mutex; bool m_trace_enabled; }; class ILogOutput { public: virtual void logRaw(LogLevel, const std::string &line) = 0; virtual void log(LogLevel, const std::string &combined, const std::string &time, const std::string &thread_name, const std::string &payload_text) = 0; }; class ICombinedLogOutput : public ILogOutput { public: void log(LogLevel lev, const std::string &combined, const std::string &time, const std::string &thread_name, const std::string &payload_text) { logRaw(lev, combined); } }; class StreamLogOutput : public ICombinedLogOutput { public: StreamLogOutput(std::ostream &stream) : m_stream(stream) { #if !defined(_WIN32) is_tty = isatty(fileno(stdout)); #else is_tty = false; #endif } void logRaw(LogLevel lev, const std::string &line) { static const std::string use_logcolor = g_settings->get("log_color"); bool colored = use_logcolor == "detect" ? is_tty : use_logcolor == "yes"; if (colored) switch (lev) { case LL_ERROR: // error is red m_stream << "\033[91m"; break; case LL_WARNING: // warning is yellow m_stream << "\033[93m"; break; case LL_INFO: // info is a bit dark m_stream << "\033[37m"; break; case LL_VERBOSE: // verbose is darker than info m_stream << "\033[2m"; break; default: // action is white colored = false; } m_stream << line << std::endl; if (colored) // reset to white color m_stream << "\033[0m"; } private: std::ostream &m_stream; bool is_tty; }; class FileLogOutput : public ICombinedLogOutput { public: void open(const std::string &filename); void logRaw(LogLevel lev, const std::string &line) { m_stream << line << std::endl; } private: std::ofstream m_stream; }; class LogOutputBuffer : public ICombinedLogOutput { public: LogOutputBuffer(Logger &logger, LogLevel lev) : m_logger(logger) { m_logger.addOutput(this, lev); } ~LogOutputBuffer() { m_logger.removeOutput(this); } void logRaw(LogLevel lev, const std::string &line) { m_buffer.push(line); } bool empty() { return m_buffer.empty(); } std::string get() { if (empty()) return ""; std::string s = m_buffer.front(); m_buffer.pop(); return s; } private: std::queue<std::string> m_buffer; Logger &m_logger; }; extern StreamLogOutput stdout_output; extern StreamLogOutput stderr_output; extern std::ostream null_stream; extern std::ostream *dout_con_ptr; extern std::ostream *derr_con_ptr; extern std::ostream *dout_server_ptr; extern std::ostream *derr_server_ptr; #ifndef SERVER extern std::ostream *dout_client_ptr; extern std::ostream *derr_client_ptr; #endif extern Logger g_logger; // Writes directly to all LL_NONE log outputs for g_logger with no prefix. extern std::ostream rawstream; extern std::ostream errorstream; extern std::ostream warningstream; extern std::ostream actionstream; extern std::ostream infostream; extern std::ostream verbosestream; extern std::ostream dstream; #define TRACEDO(x) do { \ if (g_logger.getTraceEnabled()) { \ x; \ } \ } while (0) #define TRACESTREAM(x) TRACEDO(verbosestream x) #define dout_con (*dout_con_ptr) #define derr_con (*derr_con_ptr) #define dout_server (*dout_server_ptr) #ifndef SERVER #define dout_client (*dout_client_ptr) #endif