aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--builtin/game/features.lua1
-rw-r--r--doc/lua_api.txt14
-rw-r--r--src/client/client.cpp3
-rw-r--r--src/client/game.cpp2
-rw-r--r--src/gui/guiFormSpecMenu.cpp9
-rw-r--r--src/gui/guiFormSpecMenu.h4
-rw-r--r--src/network/networkprotocol.h12
-rw-r--r--src/network/serverpackethandler.cpp3
-rw-r--r--src/remoteplayer.h3
-rw-r--r--src/script/lua_api/l_server.cpp4
-rw-r--r--src/server.cpp9
11 files changed, 54 insertions, 10 deletions
diff --git a/builtin/game/features.lua b/builtin/game/features.lua
index cf21303c7..51d21e86c 100644
--- a/builtin/game/features.lua
+++ b/builtin/game/features.lua
@@ -13,6 +13,7 @@ core.features = {
object_use_texture_alpha = true,
object_independent_selectionbox = true,
httpfetch_binary_data = true,
+ formspec_version_element = true,
}
function core.has_feature(arg)
diff --git a/doc/lua_api.txt b/doc/lua_api.txt
index 7fae20603..b809e18c3 100644
--- a/doc/lua_api.txt
+++ b/doc/lua_api.txt
@@ -1959,6 +1959,15 @@ Examples
Elements
--------
+### `formspec_version[<version>]`
+
+* Set the formspec version to a certain number. If not specified,
+ version 1 is assumed.
+* Must be specified before `size` element.
+* Clients older than this version can neither show newer elements nor display
+ elements with new arguments correctly.
+* Available since feature `formspec_version_element`.
+
### `size[<W>,<H>,<fixed_size>]`
* Define the size of the menu in inventory slots
@@ -1995,6 +2004,7 @@ Elements
### `real_coordinates[<bool>]`
+* INFORMATION: Enable it automatically using `formspec_version` version 2 or newer.
* When set to true, all following formspec elements will use the new coordinate system.
* If used immediately after `size`, `position`, `anchor`, and `no_prepend` elements
(if present), the form size will use the new coordinate system.
@@ -2114,6 +2124,7 @@ Elements
image shall be sized 8 times 16px times 4 times 16px
* If `auto_clip` is `true`, the background is clipped to the formspec size
(`x` and `y` are used as offset values, `w` and `h` are ignored)
+* Available since formspec version 2
### `pwdfield[<X>,<Y>;<W>,<H>;<name>;<label>]`
@@ -3788,6 +3799,8 @@ Utilities
-- Specifies whether binary data can be uploaded or downloaded using
-- the HTTP API (5.1.0)
httpfetch_binary_data = true,
+ -- Whether formspec_version[<version>] may be used (5.1.0)
+ formspec_version_element = true,
}
* `minetest.has_feature(arg)`: returns `boolean, missing_features`
@@ -3807,6 +3820,7 @@ Utilities
avg_jitter = 0.03, -- average packet time jitter
connection_uptime = 200, -- seconds since client connected
protocol_version = 32, -- protocol version used by client
+ formspec_version = 2, -- supported formspec version
-- following information is available on debug build only!!!
-- DO NOT USE IN MODS
--ser_vers = 26, -- serialization version used by client
diff --git a/src/client/client.cpp b/src/client/client.cpp
index 9535acc8e..f6be3186f 100644
--- a/src/client/client.cpp
+++ b/src/client/client.cpp
@@ -1222,12 +1222,13 @@ void Client::sendRespawn()
void Client::sendReady()
{
NetworkPacket pkt(TOSERVER_CLIENT_READY,
- 1 + 1 + 1 + 1 + 2 + sizeof(char) * strlen(g_version_hash));
+ 1 + 1 + 1 + 1 + 2 + sizeof(char) * strlen(g_version_hash) + 2);
pkt << (u8) VERSION_MAJOR << (u8) VERSION_MINOR << (u8) VERSION_PATCH
<< (u8) 0 << (u16) strlen(g_version_hash);
pkt.putRawString(g_version_hash, (u16) strlen(g_version_hash));
+ pkt << (u16)FORMSPEC_API_VERSION;
Send(&pkt);
}
diff --git a/src/client/game.cpp b/src/client/game.cpp
index b5508f2cb..bc35ade85 100644
--- a/src/client/game.cpp
+++ b/src/client/game.cpp
@@ -4055,7 +4055,7 @@ void Game::showPauseMenu()
float ypos = simple_singleplayer_mode ? 0.7f : 0.1f;
std::ostringstream os;
- os << FORMSPEC_VERSION_STRING << SIZE_TAG
+ os << FORMSPEC_VERSION_STRING << SIZE_TAG
<< "button_exit[4," << (ypos++) << ";3,0.5;btn_continue;"
<< strgettext("Continue") << "]";
diff --git a/src/gui/guiFormSpecMenu.cpp b/src/gui/guiFormSpecMenu.cpp
index e02abf018..f291b4e87 100644
--- a/src/gui/guiFormSpecMenu.cpp
+++ b/src/gui/guiFormSpecMenu.cpp
@@ -2167,6 +2167,9 @@ void GUIFormSpecMenu::parseElement(parserData* data, const std::string &element)
if (element.empty())
return;
+ if (parseVersionDirect(element))
+ return;
+
std::vector<std::string> parts = split(element,'[');
// ugly workaround to keep compatibility
@@ -2503,7 +2506,7 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
}
/* Copy of the "real_coordinates" element for after the form size. */
- mydata.real_coordinates = false;
+ mydata.real_coordinates = m_formspec_version >= 2;
for (; i < elements.size(); i++) {
std::vector<std::string> parts = split(elements[i], '[');
std::string name = trim(parts[0]);
@@ -2648,10 +2651,14 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
if (enable_prepends) {
// Backup the coordinates so that prepends can use the coordinates of choice.
bool rc_backup = mydata.real_coordinates;
+ bool version_backup = m_formspec_version;
mydata.real_coordinates = false; // Old coordinates by default.
+
std::vector<std::string> prepend_elements = split(m_formspec_prepend, ']');
for (const auto &element : prepend_elements)
parseElement(&mydata, element);
+
+ m_formspec_version = version_backup;
mydata.real_coordinates = rc_backup; // Restore coordinates
}
diff --git a/src/gui/guiFormSpecMenu.h b/src/gui/guiFormSpecMenu.h
index e4dc66151..46df0930c 100644
--- a/src/gui/guiFormSpecMenu.h
+++ b/src/gui/guiFormSpecMenu.h
@@ -472,7 +472,7 @@ protected:
private:
IFormSource *m_form_src;
TextDest *m_text_dst;
- u32 m_formspec_version = 0;
+ u16 m_formspec_version = 1;
std::string m_focused_element = "";
JoystickController *m_joystick;
@@ -591,7 +591,7 @@ public:
void setForm(const std::string &formspec)
{
- m_formspec = FORMSPEC_VERSION_STRING + formspec;
+ m_formspec = formspec;
}
const std::string &getForm() const
diff --git a/src/network/networkprotocol.h b/src/network/networkprotocol.h
index 05737d0a9..f603ed6c5 100644
--- a/src/network/networkprotocol.h
+++ b/src/network/networkprotocol.h
@@ -198,6 +198,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
PROTOCOL VERSION 38:
Incremental inventory sending mode
Unknown inventory serialization fields no longer throw an error
+ Mod-specific formspec version
*/
#define LATEST_PROTOCOL_VERSION 38
@@ -219,7 +220,16 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#define PASSWORD_SIZE 28 // Maximum password length. Allows for
// base64-encoded SHA-1 (27+\0).
-#define FORMSPEC_API_VERSION 1
+/*
+ Changes by FORMSPEC_API_VERSION:
+
+ FORMSPEC VERSION 1:
+ (too much)
+ FORMSPEC VERSION 2:
+ Forced real coordinates
+ background[]: 9-slice scaling parameters
+*/
+#define FORMSPEC_API_VERSION 2
#define FORMSPEC_VERSION_STRING "formspec_version[" TOSTRING(FORMSPEC_API_VERSION) "]"
#define TEXTURENAME_ALLOWED_CHARS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_.-"
diff --git a/src/network/serverpackethandler.cpp b/src/network/serverpackethandler.cpp
index 6cb3b3520..9999a1690 100644
--- a/src/network/serverpackethandler.cpp
+++ b/src/network/serverpackethandler.cpp
@@ -386,6 +386,9 @@ void Server::handleCommand_ClientReady(NetworkPacket* pkt)
peer_id, major_ver, minor_ver, patch_ver,
full_ver);
+ if (pkt->getRemainingBytes() >= 2)
+ *pkt >> playersao->getPlayer()->formspec_version;
+
const std::vector<std::string> &players = m_clients.getPlayerNames();
NetworkPacket list_pkt(TOCLIENT_UPDATE_PLAYER_LIST, 0, peer_id);
list_pkt << (u8) PLAYER_LIST_INIT << (u16) players.size();
diff --git a/src/remoteplayer.h b/src/remoteplayer.h
index 260504fb4..831bfe956 100644
--- a/src/remoteplayer.h
+++ b/src/remoteplayer.h
@@ -130,6 +130,9 @@ public:
u16 protocol_version = 0;
+ // v1 for clients older than 5.1.0-dev
+ u16 formspec_version = 1;
+
session_t getPeerId() const { return m_peer_id; }
void setPeerId(session_t peer_id) { m_peer_id = peer_id; }
diff --git a/src/script/lua_api/l_server.cpp b/src/script/lua_api/l_server.cpp
index 6017a5475..7c083e652 100644
--- a/src/script/lua_api/l_server.cpp
+++ b/src/script/lua_api/l_server.cpp
@@ -233,6 +233,10 @@ int ModApiServer::l_get_player_information(lua_State *L)
lua_pushnumber(L, prot_vers);
lua_settable(L, table);
+ lua_pushstring(L, "formspec_version");
+ lua_pushnumber(L, player->formspec_version);
+ lua_settable(L, table);
+
#ifndef NDEBUG
lua_pushstring(L,"serialization_version");
lua_pushnumber(L, ser_vers);
diff --git a/src/server.cpp b/src/server.cpp
index f6bf491be..6a51139d9 100644
--- a/src/server.cpp
+++ b/src/server.cpp
@@ -1568,7 +1568,7 @@ void Server::SendChatMessage(session_t peer_id, const ChatMessage &message)
void Server::SendShowFormspecMessage(session_t peer_id, const std::string &formspec,
const std::string &formname)
{
- NetworkPacket pkt(TOCLIENT_SHOW_FORMSPEC, 0 , peer_id);
+ NetworkPacket pkt(TOCLIENT_SHOW_FORMSPEC, 0, peer_id);
if (formspec.empty()){
//the client should close the formspec
//but make sure there wasn't another one open in meantime
@@ -1579,7 +1579,7 @@ void Server::SendShowFormspecMessage(session_t peer_id, const std::string &forms
pkt.putLongString("");
} else {
m_formspec_state_data[peer_id] = formname;
- pkt.putLongString(FORMSPEC_VERSION_STRING + formspec);
+ pkt.putLongString(formspec);
}
pkt << formname;
@@ -1908,7 +1908,8 @@ void Server::SendPlayerInventoryFormspec(session_t peer_id)
return;
NetworkPacket pkt(TOCLIENT_INVENTORY_FORMSPEC, 0, peer_id);
- pkt.putLongString(FORMSPEC_VERSION_STRING + player->inventory_formspec);
+ pkt.putLongString(player->inventory_formspec);
+
Send(&pkt);
}
@@ -1920,7 +1921,7 @@ void Server::SendPlayerFormspecPrepend(session_t peer_id)
return;
NetworkPacket pkt(TOCLIENT_FORMSPEC_PREPEND, 0, peer_id);
- pkt << FORMSPEC_VERSION_STRING + player->formspec_prepend;
+ pkt << player->formspec_prepend;
Send(&pkt);
}