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

an>is_protected(pos, pname) then minetest.chat_send_player(pname, "Position is protected!") return end local stdata = advtrains.lines.stops[pe] if not stdata then advtrains.lines.stops[pe] = { stn="", track="", doors="R", wait=10, ars={default=true}, } stdata = advtrains.lines.stops[pe] end local stn = advtrains.lines.stations[stdata.stn] local stnname = stn and stn.name or "" local form = "size[8,7]" form = form.."field[0.5,1;7,1;stn;"..attrans("Station Code")..";"..minetest.formspec_escape(stdata.stn).."]" form = form.."field[0.5,2;7,1;stnname;"..attrans("Station Name")..";"..minetest.formspec_escape(stnname).."]" form = form.."label[0.5,3;Door side:]" form = form.."dropdown[0.5,3;2;doors;Left,Right,Closed;"..door_dropdown[stdata.doors].."]" form = form.."dropdown[3,3;1.5;reverse;---,Reverse;"..(stdata.reverse and 2 or 1).."]" form = form.."field[5,3.5;2,1;track;"..attrans("Track")..";"..stdata.track.."]" form = form.."field[5,4.5;2,1;wait;"..attrans("Stop Time")..";"..stdata.wait.."]" form = form.."textarea[0.5,4;4,2;ars;Trains stopping here (ARS rules);"..advtrains.interlocking.ars_to_text(stdata.ars).."]" form = form.."button[0.5,6;7,1;save;"..attrans("Save").."]" minetest.show_formspec(pname, "at_lines_stop_"..pe, form) end minetest.register_on_player_receive_fields(function(player, formname, fields) local pname = player:get_player_name() local pe = string.match(formname, "^at_lines_stop_(............)$") local pos = advtrains.decode_pos(pe) if pos then if minetest.is_protected(pos, pname) then minetest.chat_send_player(pname, "Position is protected!") return end local stdata = advtrains.lines.stops[pe] if fields.save then if fields.stn and stdata.stn ~= fields.stn then if fields.stn ~= "" then local stn = advtrains.lines.stations[fields.stn] if stn then if (stn.owner == pname or minetest.check_player_privs(pname, "train_admin")) then stdata.stn = fields.stn else minetest.chat_send_player(pname, "Station code '"..fields.stn.."' does already exist and is owned by "..stn.owner) end else advtrains.lines.stations[fields.stn] = {name = fields.stnname, owner = pname} stdata.stn = fields.stn end end updatemeta(pos) show_stoprailform(pos, player) return end local stn = advtrains.lines.stations[stdata.stn] if stn and fields.stnname and fields.stnname ~= stn.name then if (stn.owner == pname or minetest.check_player_privs(pname, "train_admin")) then stn.name = fields.stnname else minetest.chat_send_player(pname, "Not allowed to edit station name, owned by "..stn.owner) end end -- dropdowns if fields.doors then stdata.doors = door_dropdown_rev[fields.doors] or "C" end if fields.reverse then stdata.reverse = fields.reverse == "Reverse" end if fields.track then stdata.track = fields.track end if fields.wait then stdata.wait = tonumber(fields.wait) or 10 end if fields.ars then stdata.ars = advtrains.interlocking.text_to_ars(fields.ars) end --TODO: signal updatemeta(pos) show_stoprailform(pos, player) end end end) local adefunc = function(def, preset, suffix, rotation) return { after_place_node=function(pos) local pe = advtrains.encode_pos(pos) advtrains.lines.stops[pe] = { stn="", track="", doors="R", wait=10 } updatemeta(pos) end, after_dig_node=function(pos) local pe = advtrains.encode_pos(pos) advtrains.lines.stops[pe] = nil end, on_rightclick = function(pos, node, player) show_stoprailform(pos, player) end, advtrains = { on_train_approach = function(pos,train_id, train, index) if train.path_cn[index] == 1 then local pe = advtrains.encode_pos(pos) local stdata = advtrains.lines.stops[pe] if stdata and stdata.stn then --TODO REMOVE AFTER SOME TIME (only migration) if not stdata.ars then stdata.ars = {default=true} end if stdata.ars and (stdata.ars.default or advtrains.interlocking.ars_check_rule_match(stdata.ars, train) ) then advtrains.interlocking.lzb_add_oncoming_npr(train, index, 2) local stn = advtrains.lines.stations[stdata.stn] local stnname = stn and stn.name or "Unknown Station" train.text_inside = "Next Stop:\n"..stnname end end end end, on_train_enter = function(pos, train_id, train, index) if train.path_cn[index] == 1 then local pe = advtrains.encode_pos(pos) local stdata = advtrains.lines.stops[pe] if not stdata then return end if stdata.ars and (stdata.ars.default or advtrains.interlocking.ars_check_rule_match(stdata.ars, train) ) then local stn = advtrains.lines.stations[stdata.stn] local stnname = stn and stn.name or "Unknown Station" -- Send ATC command and set text advtrains.atc.train_set_command(train, "B0 W O"..stdata.doors.." D"..stdata.wait.." OC D1 "..(stdata.reverse and "R" or "").." SM", true) train.text_inside = stnname if tonumber(stdata.wait) then minetest.after(tonumber(stdata.wait), function() train.text_inside = "" end) end end end end }, } end advtrains.register_tracks("default", { nodename_prefix="advtrains_line_automation:dtrack_stop", texture_prefix="advtrains_dtrack_stop", models_prefix="advtrains_dtrack", models_suffix=".b3d", shared_texture="advtrains_dtrack_shared_stop.png", description="Station/Stop Rail", formats={}, get_additional_definiton = adefunc, }, advtrains.trackpresets.t_30deg_straightonly)