Compare commits
23 Commits
5.11.0-rc1
...
0.4.12
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7993a403f2 | ||
|
|
b0df67d9c0 | ||
|
|
45ff8569d7 | ||
|
|
82bfa2ee7b | ||
|
|
9ef2e5000f | ||
|
|
678546308e | ||
|
|
6f688c50ee | ||
|
|
bb603ff18e | ||
|
|
4208fdfd22 | ||
|
|
4875213168 | ||
|
|
f92540e8ad | ||
|
|
ec0bf899ed | ||
|
|
2b635a892c | ||
|
|
7f6fc148bd | ||
|
|
878e9f7594 | ||
|
|
c7249f5983 | ||
|
|
7f07858209 | ||
|
|
9e9688fc61 | ||
|
|
93e5ab367a | ||
|
|
60fa5807b9 | ||
|
|
9dbca41385 | ||
|
|
61588a43dd | ||
|
|
e62927ed71 |
@@ -12,14 +12,14 @@ set(VERSION_EXTRA "" CACHE STRING "Stuff to append to version string")
|
||||
# Also remember to set PROTOCOL_VERSION in clientserver.h when releasing
|
||||
set(VERSION_MAJOR 0)
|
||||
set(VERSION_MINOR 4)
|
||||
set(VERSION_PATCH 11)
|
||||
set(VERSION_PATCH 12)
|
||||
set(VERSION_PATCH_ORIG ${VERSION_PATCH})
|
||||
|
||||
if(VERSION_EXTRA)
|
||||
set(VERSION_PATCH ${VERSION_PATCH}-${VERSION_EXTRA})
|
||||
else()
|
||||
# Comment the following line during release
|
||||
set(VERSION_PATCH ${VERSION_PATCH}-dev)
|
||||
#set(VERSION_PATCH ${VERSION_PATCH}-dev)
|
||||
endif()
|
||||
set(VERSION_STRING "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}")
|
||||
|
||||
|
||||
32
README.txt
32
README.txt
@@ -103,18 +103,32 @@ Compiling on GNU/Linux:
|
||||
-----------------------
|
||||
|
||||
Install dependencies. Here's an example for Debian/Ubuntu:
|
||||
$ apt-get install build-essential libirrlicht-dev cmake libbz2-dev libpng12-dev libjpeg8-dev libxxf86vm-dev libgl1-mesa-dev libsqlite3-dev libogg-dev libvorbis-dev libopenal-dev libcurl4-gnutls-dev libfreetype6-dev
|
||||
$ apt-get install build-essential libirrlicht-dev cmake libbz2-dev libpng12-dev libjpeg8-dev libxxf86vm-dev libgl1-mesa-dev libsqlite3-dev libogg-dev libvorbis-dev libopenal-dev libcurl4-gnutls-dev libfreetype6-dev zlib1g-dev libjsoncpp-dev
|
||||
|
||||
Download source, extract (this is the URL to the latest of source repository, which might not work at all times):
|
||||
$ wget https://github.com/minetest/minetest/tarball/master -O master.tar.gz
|
||||
$ tar xf master.tar.gz
|
||||
$ cd minetest-minetest-286edd4 (or similar)
|
||||
You can install git for easily keeping your copy up to date.
|
||||
If you dont want git, read below on how to get the source without git.
|
||||
This is an example for installing git on Debian/Ubuntu:
|
||||
$ apt-get install git-core
|
||||
|
||||
Download minetest_game (otherwise only the "Minimal development test" game is available)
|
||||
Download source (this is the URL to the latest of source repository, which might not work at all times) using git:
|
||||
$ git clone --depth 1 https://github.com/minetest/minetest.git
|
||||
$ cd minetest
|
||||
|
||||
Download minetest_game (otherwise only the "Minimal development test" game is available) using git:
|
||||
$ cd games/
|
||||
$ wget https://github.com/minetest/minetest_game/tarball/master -O minetest_game.tar.gz
|
||||
$ tar xf minetest_game.tar.gz
|
||||
$ mv minetest-minetest_game-* minetest_game
|
||||
$ git clone --depth 1 https://github.com/minetest/minetest_game.git
|
||||
$ cd ..
|
||||
|
||||
Download source, without using git:
|
||||
$ wget https://github.com/minetest/minetest/archive/master.tar.gz
|
||||
$ tar xf master.tar.gz
|
||||
$ cd minetest-master
|
||||
|
||||
Download minetest_game, without using git:
|
||||
$ cd games/
|
||||
$ wget https://github.com/minetest/minetest_game/archive/master.tar.gz
|
||||
$ tar xf master.tar.gz
|
||||
$ mv minetest_game-master minetest_game
|
||||
$ cd ..
|
||||
|
||||
Build a version that runs directly from the source directory:
|
||||
|
||||
@@ -26,7 +26,7 @@ GAMES_TO_COPY = minetest_game
|
||||
# Android Version code
|
||||
# Increase for each build!
|
||||
################################################################################
|
||||
ANDROID_VERSION_CODE = 5
|
||||
ANDROID_VERSION_CODE = 6
|
||||
|
||||
################################################################################
|
||||
# toolchain config for arm old processors
|
||||
|
||||
@@ -545,12 +545,11 @@ function table.copy(t, seen)
|
||||
seen = seen or {}
|
||||
seen[t] = n
|
||||
for k, v in pairs(t) do
|
||||
n[type(k) ~= "table" and k or seen[k] or table.copy(k, seen)] =
|
||||
type(v) ~= "table" and v or seen[v] or table.copy(v, seen)
|
||||
n[(type(k) == "table" and (seen[k] or table.copy(k, seen))) or k] =
|
||||
(type(v) == "table" and (seen[v] or table.copy(v, seen))) or v
|
||||
end
|
||||
return n
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- mainmenu only functions
|
||||
--------------------------------------------------------------------------------
|
||||
@@ -565,7 +564,7 @@ if INIT == "mainmenu" then
|
||||
return nil
|
||||
end
|
||||
|
||||
function fgettext(text, ...)
|
||||
function fgettext_ne(text, ...)
|
||||
text = core.gettext(text)
|
||||
local arg = {n=select('#', ...), ...}
|
||||
if arg.n >= 1 then
|
||||
@@ -587,7 +586,11 @@ if INIT == "mainmenu" then
|
||||
end
|
||||
text = result
|
||||
end
|
||||
return core.formspec_escape(text)
|
||||
return text
|
||||
end
|
||||
|
||||
function fgettext(text, ...)
|
||||
return core.formspec_escape(fgettext_ne(text, ...))
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -570,6 +570,9 @@ core.register_chatcommand("rollback_check", {
|
||||
.. " seconds=86400=24h, limit=5)",
|
||||
privs = {rollback=true},
|
||||
func = function(name, param)
|
||||
if not core.setting_getbool("enable_rollback_recording") then
|
||||
return false, "Rollback functions are disabled."
|
||||
end
|
||||
local range, seconds, limit =
|
||||
param:match("(%d+) *(%d*) *(%d*)")
|
||||
range = tonumber(range) or 0
|
||||
@@ -583,6 +586,10 @@ core.register_chatcommand("rollback_check", {
|
||||
local name = puncher:get_player_name()
|
||||
core.chat_send_player(name, "Checking " .. core.pos_to_string(pos) .. "...")
|
||||
local actions = core.rollback_get_node_actions(pos, range, seconds, limit)
|
||||
if not actions then
|
||||
core.chat_send_player(name, "Rollback functions are disabled")
|
||||
return
|
||||
end
|
||||
local num_actions = #actions
|
||||
if num_actions == 0 then
|
||||
core.chat_send_player(name, "Nobody has touched"
|
||||
@@ -614,6 +621,9 @@ core.register_chatcommand("rollback", {
|
||||
description = "revert actions of a player; default for <seconds> is 60",
|
||||
privs = {rollback=true},
|
||||
func = function(name, param)
|
||||
if not core.setting_getbool("enable_rollback_recording") then
|
||||
return false, "Rollback functions are disabled."
|
||||
end
|
||||
local target_name, seconds = string.match(param, ":([^ ]+) *(%d*)")
|
||||
if not target_name then
|
||||
local player_name = nil
|
||||
|
||||
@@ -16,9 +16,15 @@
|
||||
--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
--------------------------------------------------------------------------------
|
||||
-- Global menu data
|
||||
---------------------------------------------------------------------------------
|
||||
--------------------------------------------------------------------------------
|
||||
menudata = {}
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Local cached values
|
||||
--------------------------------------------------------------------------------
|
||||
local min_supp_proto = core.get_min_supp_proto()
|
||||
local max_supp_proto = core.get_max_supp_proto()
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Menu helper functions
|
||||
--------------------------------------------------------------------------------
|
||||
@@ -42,6 +48,25 @@ function image_column(tooltip, flagname)
|
||||
"1=" .. core.formspec_escape(defaulttexturedir .. "server_flags_" .. flagname .. ".png")
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
function order_favorite_list(list)
|
||||
local res = {}
|
||||
--orders the favorite list after support
|
||||
for i=1,#list,1 do
|
||||
local fav = list[i]
|
||||
if is_server_protocol_compat(fav.proto_min, fav.proto_max) then
|
||||
table.insert(res, fav)
|
||||
end
|
||||
end
|
||||
for i=1,#list,1 do
|
||||
local fav = list[i]
|
||||
if not is_server_protocol_compat(fav.proto_min, fav.proto_max) then
|
||||
table.insert(res, fav)
|
||||
end
|
||||
end
|
||||
return res
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
function render_favorite(spec,render_details)
|
||||
local text = ""
|
||||
@@ -68,6 +93,7 @@ function render_favorite(spec,render_details)
|
||||
end
|
||||
|
||||
local details = ""
|
||||
local grey_out = not is_server_protocol_compat(spec.proto_max, spec.proto_min)
|
||||
|
||||
if spec.clients ~= nil and spec.clients_max ~= nil then
|
||||
local clients_color = ''
|
||||
@@ -87,11 +113,17 @@ function render_favorite(spec,render_details)
|
||||
clients_color = '#ffba97' -- 90-100%: orange
|
||||
end
|
||||
|
||||
if grey_out then
|
||||
clients_color = '#aaaaaa'
|
||||
end
|
||||
|
||||
details = details ..
|
||||
clients_color .. ',' ..
|
||||
render_client_count(spec.clients) .. ',' ..
|
||||
'/,' ..
|
||||
render_client_count(spec.clients_max) .. ','
|
||||
elseif grey_out then
|
||||
details = details .. '#aaaaaa,?,/,?,'
|
||||
else
|
||||
details = details .. ',?,/,?,'
|
||||
end
|
||||
@@ -114,7 +146,7 @@ function render_favorite(spec,render_details)
|
||||
details = details .. "0,"
|
||||
end
|
||||
|
||||
return details .. text
|
||||
return details .. (grey_out and '#aaaaaa,' or ',') .. text
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
@@ -195,7 +227,7 @@ function asyncOnlineFavourites()
|
||||
nil,
|
||||
function(result)
|
||||
if core.setting_getbool("public_serverlist") then
|
||||
menudata.favorites = result
|
||||
menudata.favorites = order_favorite_list(result)
|
||||
core.event_handler("Refresh")
|
||||
end
|
||||
end
|
||||
@@ -225,3 +257,21 @@ function text2textlist(xpos,ypos,width,height,tl_name,textlen,text,transparency)
|
||||
|
||||
return retval
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
function is_server_protocol_compat(proto_min, proto_max)
|
||||
return not ((min_supp_proto > (proto_max or 24)) or (max_supp_proto < (proto_min or 13)))
|
||||
end
|
||||
--------------------------------------------------------------------------------
|
||||
function is_server_protocol_compat_or_error(proto_min, proto_max)
|
||||
if not is_server_protocol_compat(proto_min, proto_max) then
|
||||
gamedata.errormessage = fgettext_ne("Protocol version mismatch, server " ..
|
||||
((proto_min ~= proto_max) and "supports protocols between $1 and $2" or "enforces protocol version $1") ..
|
||||
", we " ..
|
||||
((min_supp_proto ~= max_supp_proto) and "support protocols between version $3 and $4." or "only support protocol version $3"),
|
||||
proto_min or 13, proto_max or 24, min_supp_proto, max_supp_proto)
|
||||
return false
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
local function modname_valid(name)
|
||||
return not name:find("[^a-z0-9_]")
|
||||
end
|
||||
|
||||
local function get_formspec(data)
|
||||
|
||||
@@ -195,10 +198,12 @@ local function handle_buttons(this, fields)
|
||||
for i,mod in ipairs(rawlist) do
|
||||
if not mod.is_modpack and
|
||||
mod.typ ~= "game_mod" then
|
||||
if mod.enabled then
|
||||
worldfile:set("load_mod_"..mod.name, "true")
|
||||
if modname_valid(mod.name) then
|
||||
worldfile:set("load_mod_"..mod.name, tostring(mod.enabled))
|
||||
else
|
||||
worldfile:set("load_mod_"..mod.name, "false")
|
||||
if mod.enabled then
|
||||
gamedata.errormessage = fgettext_ne("Failed to enable mod \"$1\" as it contains disallowed characters. Only chararacters [a-z0-9_] are allowed.", mod.name)
|
||||
end
|
||||
end
|
||||
mods["load_mod_"..mod.name] = nil
|
||||
end
|
||||
|
||||
@@ -90,6 +90,8 @@ local function create_world_buttonhandler(this, fields)
|
||||
|
||||
local message = nil
|
||||
|
||||
core.setting_set("fixed_map_seed", fields["te_seed"])
|
||||
|
||||
if not menudata.worldlist:uid_exists_raw(worldname) then
|
||||
core.setting_set("mg_name",fields["dd_mapgen"])
|
||||
message = core.create_world(worldname,gameindex)
|
||||
@@ -97,8 +99,6 @@ local function create_world_buttonhandler(this, fields)
|
||||
message = fgettext("A world named \"$1\" already exists", worldname)
|
||||
end
|
||||
|
||||
core.setting_set("fixed_map_seed", fields["te_seed"])
|
||||
|
||||
if message ~= nil then
|
||||
gamedata.errormessage = message
|
||||
else
|
||||
|
||||
@@ -139,7 +139,11 @@ local function init_globals()
|
||||
tv_main:add(tab_credits)
|
||||
|
||||
tv_main:set_global_event_handler(main_event_handler)
|
||||
tv_main:set_fixed_size(false)
|
||||
if PLATFORM ~= "Android" then
|
||||
tv_main:set_fixed_size(true)
|
||||
else
|
||||
tv_main:set_fixed_size(false)
|
||||
end
|
||||
|
||||
if not (PLATFORM == "Android") then
|
||||
tv_main:set_tab(core.setting_get("maintab_LAST"))
|
||||
|
||||
@@ -391,7 +391,7 @@ function modstore.getscreenshot(ypos,listentry)
|
||||
listentry.details.screenshot_url == "") then
|
||||
|
||||
if listentry.texturename == nil then
|
||||
listentry.texturename = modstore.basetexturedir .. "no_screenshot.png"
|
||||
listentry.texturename = defaulttexturedir .. "no_screenshot.png"
|
||||
end
|
||||
|
||||
return "image[0,".. ypos .. ";3,2;" ..
|
||||
|
||||
@@ -57,7 +57,7 @@ local function get_formspec(tabview, name, tabdata)
|
||||
end
|
||||
|
||||
if modscreenshot == nil then
|
||||
modscreenshot = modstore.basetexturedir .. "no_screenshot.png"
|
||||
modscreenshot = defaulttexturedir .. "no_screenshot.png"
|
||||
end
|
||||
|
||||
retval = retval
|
||||
@@ -96,7 +96,7 @@ local function get_formspec(tabview, name, tabdata)
|
||||
else
|
||||
--show dependencies
|
||||
|
||||
retval = retval .. ",Depends:,"
|
||||
retval = retval .. "," .. fgettext("Depends:") .. ","
|
||||
|
||||
local toadd = modmgr.get_dependencies(selected_mod.path)
|
||||
|
||||
|
||||
@@ -59,9 +59,10 @@ local function get_formspec(tabview, name, tabdata)
|
||||
"text,align=right;" .. -- clients
|
||||
"text,align=center,padding=0.25;" .. -- "/"
|
||||
"text,align=right,padding=0.25;" .. -- clients_max
|
||||
image_column("Creative mode", "creative") .. ",padding=1;" ..
|
||||
image_column("Damage enabled", "damage") .. ",padding=0.25;" ..
|
||||
image_column("PvP enabled", "pvp") .. ",padding=0.25;" ..
|
||||
image_column(fgettext("Creative mode"), "creative") .. ",padding=1;" ..
|
||||
image_column(fgettext("Damage enabled"), "damage") .. ",padding=0.25;" ..
|
||||
image_column(fgettext("PvP enabled"), "pvp") .. ",padding=0.25;" ..
|
||||
"color,span=1;" ..
|
||||
"text,padding=1]" -- name
|
||||
else
|
||||
retval = retval .. "tablecolumns[text]"
|
||||
@@ -88,7 +89,6 @@ end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
local function main_button_handler(tabview, fields, name, tabdata)
|
||||
|
||||
if fields["te_name"] ~= nil then
|
||||
gamedata.playername = fields["te_name"]
|
||||
core.setting_set("name", fields["te_name"])
|
||||
@@ -98,6 +98,10 @@ local function main_button_handler(tabview, fields, name, tabdata)
|
||||
local event = core.explode_table_event(fields["favourites"])
|
||||
if event.type == "DCL" then
|
||||
if event.row <= #menudata.favorites then
|
||||
if not is_server_protocol_compat_or_error(menudata.favorites[event.row].proto_min,
|
||||
menudata.favorites[event.row].proto_max) then
|
||||
return true
|
||||
end
|
||||
gamedata.address = menudata.favorites[event.row].address
|
||||
gamedata.port = menudata.favorites[event.row].port
|
||||
gamedata.playername = fields["te_name"]
|
||||
@@ -189,7 +193,7 @@ local function main_button_handler(tabview, fields, name, tabdata)
|
||||
local current_favourite = core.get_table_index("favourites")
|
||||
if current_favourite == nil then return end
|
||||
core.delete_favorite(current_favourite)
|
||||
menudata.favorites = core.get_favorites()
|
||||
menudata.favorites = order_favorite_list(core.get_favorites())
|
||||
tabdata.fav_selected = nil
|
||||
|
||||
core.setting_set("address","")
|
||||
@@ -214,6 +218,11 @@ local function main_button_handler(tabview, fields, name, tabdata)
|
||||
|
||||
gamedata.servername = menudata.favorites[fav_idx].name
|
||||
gamedata.serverdescription = menudata.favorites[fav_idx].description
|
||||
|
||||
if not is_server_protocol_compat_or_error(menudata.favorites[fav_idx].proto_min,
|
||||
menudata.favorites[fav_idx].proto_max)then
|
||||
return true
|
||||
end
|
||||
else
|
||||
gamedata.servername = ""
|
||||
gamedata.serverdescription = ""
|
||||
|
||||
@@ -42,9 +42,10 @@ local function get_formspec(tabview, name, tabdata)
|
||||
"text,align=right;" .. -- clients
|
||||
"text,align=center,padding=0.25;" .. -- "/"
|
||||
"text,align=right,padding=0.25;" .. -- clients_max
|
||||
image_column("Creative mode", "creative") .. ",padding=1;" ..
|
||||
image_column("Damage enabled", "damage") .. ",padding=0.25;" ..
|
||||
image_column("PvP enabled", "pvp") .. ",padding=0.25;" ..
|
||||
image_column(fgettext("Creative mode"), "creative") .. ",padding=1;" ..
|
||||
image_column(fgettext("Damage enabled"), "damage") .. ",padding=0.25;" ..
|
||||
image_column(fgettext("PvP enabled"), "pvp") .. ",padding=0.25;" ..
|
||||
"color,span=1;" ..
|
||||
"text,padding=1]" -- name
|
||||
else
|
||||
retval = retval .. "tablecolumns[text]"
|
||||
@@ -87,7 +88,6 @@ local function get_formspec(tabview, name, tabdata)
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
local function main_button_handler(tabview, fields, name, tabdata)
|
||||
|
||||
if fields["btn_start_singleplayer"] then
|
||||
@@ -159,6 +159,11 @@ local function main_button_handler(tabview, fields, name, tabdata)
|
||||
|
||||
gamedata.servername = menudata.favorites[fav_idx].name
|
||||
gamedata.serverdescription = menudata.favorites[fav_idx].description
|
||||
|
||||
if not is_server_protocol_compat_or_error(menudata.favorites[fav_idx].proto_min,
|
||||
menudata.favorites[fav_idx].proto_max) then
|
||||
return true
|
||||
end
|
||||
else
|
||||
gamedata.servername = ""
|
||||
gamedata.serverdescription = ""
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Minetest Lua Modding API Reference 0.4.11
|
||||
Minetest Lua Modding API Reference 0.4.12
|
||||
=========================================
|
||||
* More information at <http://www.minetest.net/>
|
||||
* Developer Wiki: <http://dev.minetest.net/>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Minetest Lua Mainmenu API Reference 0.4.11
|
||||
Minetest Lua Mainmenu API Reference 0.4.12
|
||||
========================================
|
||||
|
||||
Introduction
|
||||
@@ -197,9 +197,11 @@ core.delete_world(index)
|
||||
Helpers:
|
||||
core.gettext(string) -> string
|
||||
^ look up the translation of a string in the gettext message catalog
|
||||
fgettext(string, ...) -> string
|
||||
fgettext_ne(string, ...)
|
||||
^ call core.gettext(string), replace "$1"..."$9" with the given
|
||||
^ extra arguments, call core.formspec_escape and return the result
|
||||
^ extra arguments and return the result
|
||||
fgettext(string, ...) -> string
|
||||
^ same as fgettext_ne(), but calls core.formspec_escape before returning result
|
||||
core.parse_json(string[, nullvalue]) -> something (possible in async calls)
|
||||
^ see core.parse_json (lua_api.txt)
|
||||
dump(obj, dumped={})
|
||||
@@ -211,6 +213,12 @@ string:trim()
|
||||
core.is_yes(arg) (possible in async calls)
|
||||
^ returns whether arg can be interpreted as yes
|
||||
|
||||
Version compat:
|
||||
core.get_min_supp_proto()
|
||||
^ returns the minimum supported network protocol version
|
||||
core.get_max_supp_proto()
|
||||
^ returns the maximum supported network protocol version
|
||||
|
||||
Async:
|
||||
core.handle_async(async_job,parameters,finished)
|
||||
^ execute a function asynchronously
|
||||
|
||||
@@ -252,16 +252,16 @@
|
||||
#freetype = true
|
||||
# Path to TrueTypeFont or bitmap
|
||||
#font_path = fonts/liberationsans.ttf
|
||||
#font_size = 13
|
||||
#font_size = 15
|
||||
# Font shadow offset, if 0 then shadow will not be drawn
|
||||
#font_shadow = 1
|
||||
# Font shadow alpha (opaqueness, between 0 and 255)
|
||||
#font_shadow_alpha = 128
|
||||
#mono_font_path = fonts/liberationmono.ttf
|
||||
#mono_font_size = 13
|
||||
#mono_font_size = 15
|
||||
# This font will be used for certain languages
|
||||
#fallback_font_path = fonts/DroidSansFallbackFull.ttf
|
||||
#fallback_font_size = 13
|
||||
#fallback_font_size = 15
|
||||
#fallback_font_shadow = 1
|
||||
#fallback_font_shadow_alpha = 128
|
||||
# Override language. When no value is provided (default) system language is used.
|
||||
@@ -337,6 +337,7 @@
|
||||
# If true, disable cheat prevention in multiplayer
|
||||
#disable_anticheat = false
|
||||
# If true, actions are recorded for rollback
|
||||
# This option is only read when server starts
|
||||
#enable_rollback_recording = false
|
||||
# Handling for deprecated lua api calls:
|
||||
# "legacy" = (try to) mimic old behaviour (default for release).
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
Name=Minetest
|
||||
GenericName=Minetest
|
||||
Comment=Multiplayer infinite-world block sandbox
|
||||
Comment[fr]=Jeu multijoueurs de type bac à sable avec des mondes infinis
|
||||
Comment[de]=Mehrspieler-Sandkastenspiel mit unendlichen Blockwelten
|
||||
Exec=minetest
|
||||
Icon=minetest-icon
|
||||
Terminal=false
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -45,7 +45,7 @@
|
||||
#define __BYTE_ORDER 0
|
||||
#define __LITTLE_ENDIAN 0
|
||||
#define __BIG_ENDIAN 1
|
||||
#elif __MACH__
|
||||
#elif defined(__MACH__) && defined(__APPLE__)
|
||||
#include <machine/endian.h>
|
||||
#elif defined(__FreeBSD__)
|
||||
#include <sys/endian.h>
|
||||
|
||||
@@ -100,7 +100,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
/*
|
||||
GUI related things
|
||||
*/
|
||||
#define TTF_DEFAULT_FONT_SIZE (14)
|
||||
|
||||
// TODO: implement dpi-based scaling for windows and remove this hack
|
||||
#if defined(_WIN32)
|
||||
#define TTF_DEFAULT_FONT_SIZE (18)
|
||||
#else
|
||||
#define TTF_DEFAULT_FONT_SIZE (15)
|
||||
#endif
|
||||
#define DEFAULT_FONT_SIZE (10)
|
||||
|
||||
#endif
|
||||
|
||||
@@ -361,7 +361,10 @@ void EmergeManager::loadParamsFromSettings(Settings *settings)
|
||||
std::string seed_str;
|
||||
const char *setname = (settings == g_settings) ? "fixed_map_seed" : "seed";
|
||||
|
||||
if (settings->getNoEx(setname, seed_str) && !seed_str.empty()) {
|
||||
if (!settings->getNoEx("seed", seed_str)) {
|
||||
g_settings->getNoEx(setname, seed_str);
|
||||
}
|
||||
if (!seed_str.empty()) {
|
||||
params.seed = read_seed(seed_str.c_str());
|
||||
} else {
|
||||
params.seed =
|
||||
|
||||
15
src/game.cpp
15
src/game.cpp
@@ -1043,7 +1043,11 @@ static inline void create_formspec_menu(GUIFormSpecMenu **cur_formspec,
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __ANDROID__
|
||||
#define SIZE_TAG "size[11,5.5]"
|
||||
#else
|
||||
#define SIZE_TAG "size[11,5.5,true]" // Fixed size on desktop
|
||||
#endif
|
||||
|
||||
static void show_chat_menu(GUIFormSpecMenu **cur_formspec,
|
||||
InventoryManager *invmgr, IGameDef *gamedef,
|
||||
@@ -1074,7 +1078,7 @@ static void show_deathscreen(GUIFormSpecMenu **cur_formspec,
|
||||
std::string(FORMSPEC_VERSION_STRING) +
|
||||
SIZE_TAG
|
||||
"bgcolor[#320000b4;true]"
|
||||
"label[4.85,1.35;You died.]"
|
||||
"label[4.85,1.35;" + gettext("You died.") + "]"
|
||||
"button_exit[4,3;3,0.5;btn_respawn;" + gettext("Respawn") + "]"
|
||||
;
|
||||
|
||||
@@ -1157,7 +1161,7 @@ static void show_pause_menu(GUIFormSpecMenu **cur_formspec,
|
||||
LocalFormspecHandler *txt_dst = new LocalFormspecHandler("MT_PAUSE_MENU");
|
||||
|
||||
create_formspec_menu(cur_formspec, invmgr, gamedef, tsrc, device, fs_src, txt_dst, NULL);
|
||||
|
||||
(*cur_formspec)->setFocus(L"btn_continue");
|
||||
(*cur_formspec)->doPause = true;
|
||||
}
|
||||
|
||||
@@ -3218,10 +3222,13 @@ void Game::updateCamera(VolatileRunFlags *flags, u32 busy_time,
|
||||
v3s16 old_camera_offset = camera->getOffset();
|
||||
|
||||
if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_CAMERA_MODE])) {
|
||||
camera->toggleCameraMode();
|
||||
GenericCAO *playercao = player->getCAO();
|
||||
|
||||
assert(playercao != NULL);
|
||||
// If playercao not loaded, don't change camera
|
||||
if (playercao == NULL)
|
||||
return;
|
||||
|
||||
camera->toggleCameraMode();
|
||||
|
||||
playercao->setVisible(camera->getCameraMode() > CAMERA_MODE_FIRST);
|
||||
}
|
||||
|
||||
@@ -26,24 +26,24 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include "log.h"
|
||||
|
||||
#if USE_GETTEXT && defined(_MSC_VER)
|
||||
#include <WinNls.h>
|
||||
#include <windows.h>
|
||||
#include <map>
|
||||
#include <direct.h>
|
||||
#include "filesys.h"
|
||||
|
||||
#define setlocale(category,localename) \
|
||||
setlocale(category,MSVC_LocaleLookup(localename))
|
||||
#define setlocale(category, localename) \
|
||||
setlocale(category, MSVC_LocaleLookup(localename))
|
||||
|
||||
static std::map<std::wstring,std::wstring> glb_supported_locales;
|
||||
static std::map<std::wstring, std::wstring> glb_supported_locales;
|
||||
|
||||
/******************************************************************************/
|
||||
BOOL CALLBACK UpdateLocaleCallback(LPTSTR pStr)
|
||||
{
|
||||
char* endptr = 0;
|
||||
int LOCALEID = strtol(pStr,&endptr,16);
|
||||
int LOCALEID = strtol(pStr, &endptr,16);
|
||||
|
||||
wchar_t buffer[LOCALE_NAME_MAX_LENGTH];
|
||||
memset(buffer,0,sizeof(buffer));
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
if (GetLocaleInfoW(
|
||||
LOCALEID,
|
||||
LOCALE_SISO639LANGNAME,
|
||||
@@ -52,7 +52,7 @@ BOOL CALLBACK UpdateLocaleCallback(LPTSTR pStr)
|
||||
|
||||
std::wstring name = buffer;
|
||||
|
||||
memset(buffer,0,sizeof(buffer));
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
GetLocaleInfoW(
|
||||
LOCALEID,
|
||||
LOCALE_SISO3166CTRYNAME,
|
||||
@@ -61,7 +61,7 @@ BOOL CALLBACK UpdateLocaleCallback(LPTSTR pStr)
|
||||
|
||||
std::wstring country = buffer;
|
||||
|
||||
memset(buffer,0,sizeof(buffer));
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
GetLocaleInfoW(
|
||||
LOCALEID,
|
||||
LOCALE_SENGLISHLANGUAGENAME,
|
||||
@@ -96,7 +96,7 @@ const char* MSVC_LocaleLookup(const char* raw_shortname) {
|
||||
}
|
||||
|
||||
if (first_use) {
|
||||
EnumSystemLocalesA(UpdateLocaleCallback,LCID_SUPPORTED | LCID_ALTERNATE_SORTS);
|
||||
EnumSystemLocalesA(UpdateLocaleCallback, LCID_SUPPORTED | LCID_ALTERNATE_SORTS);
|
||||
first_use = false;
|
||||
}
|
||||
|
||||
@@ -148,8 +148,8 @@ void init_gettext(const char *path, const std::string &configured_language) {
|
||||
if (current_language_var != configured_language) {
|
||||
STARTUPINFO startupinfo;
|
||||
PROCESS_INFORMATION processinfo;
|
||||
memset(&startupinfo,0,sizeof(startupinfo));
|
||||
memset(&processinfo,0,sizeof(processinfo));
|
||||
memset(&startupinfo, 0, sizeof(startupinfo));
|
||||
memset(&processinfo, 0, sizeof(processinfo));
|
||||
errorstream << "MSVC localization workaround active restating minetest in new environment!" << std::endl;
|
||||
|
||||
std::string parameters = "";
|
||||
@@ -169,7 +169,7 @@ void init_gettext(const char *path, const std::string &configured_language) {
|
||||
|
||||
/** users may start by short name in commandline without extention **/
|
||||
std::string appname = argv[0];
|
||||
if (appname.substr(appname.length() -4) != ".exe") {
|
||||
if (appname.substr(appname.length() - 4) != ".exe") {
|
||||
appname += ".exe";
|
||||
}
|
||||
|
||||
@@ -260,7 +260,7 @@ void init_gettext(const char *path, const std::string &configured_language) {
|
||||
/* no matter what locale is used we need number format to be "C" */
|
||||
/* to ensure formspec parameters are evaluated correct! */
|
||||
|
||||
setlocale(LC_NUMERIC,"C");
|
||||
setlocale(LC_NUMERIC, "C");
|
||||
infostream << "Message locale is now set to: "
|
||||
<< setlocale(LC_ALL, 0) << std::endl;
|
||||
}
|
||||
|
||||
@@ -41,16 +41,19 @@ void init_gettext(const char *path, const std::string &configured_language);
|
||||
extern const wchar_t *narrow_to_wide_c(const char *mbs);
|
||||
extern std::wstring narrow_to_wide(const std::string &mbs);
|
||||
|
||||
|
||||
// You must free the returned string!
|
||||
inline const wchar_t *wgettext(const char *str)
|
||||
{
|
||||
return narrow_to_wide_c(gettext(str));
|
||||
}
|
||||
|
||||
// Gettext under MSVC needs this strange way. Just don't ask...
|
||||
inline std::wstring wstrgettext(const std::string &text)
|
||||
{
|
||||
return narrow_to_wide(gettext(text.c_str()));
|
||||
const wchar_t *tmp = wgettext(text.c_str());
|
||||
std::wstring retval = (std::wstring)tmp;
|
||||
delete[] tmp;
|
||||
return retval;
|
||||
}
|
||||
|
||||
inline std::string strgettext(const std::string &text)
|
||||
|
||||
@@ -99,7 +99,7 @@ GUIChatConsole::GUIChatConsole(
|
||||
{
|
||||
core::dimension2d<u32> dim = m_font->getDimension(L"M");
|
||||
m_fontsize = v2u32(dim.Width, dim.Height);
|
||||
dstream << "Font size: " << m_fontsize.X << " " << m_fontsize.Y << std::endl;
|
||||
m_font->grab();
|
||||
}
|
||||
m_fontsize.X = MYMAX(m_fontsize.X, 1);
|
||||
m_fontsize.Y = MYMAX(m_fontsize.Y, 1);
|
||||
@@ -109,7 +109,10 @@ GUIChatConsole::GUIChatConsole(
|
||||
}
|
||||
|
||||
GUIChatConsole::~GUIChatConsole()
|
||||
{}
|
||||
{
|
||||
if (m_font)
|
||||
m_font->drop();
|
||||
}
|
||||
|
||||
void GUIChatConsole::openConsole(f32 height)
|
||||
{
|
||||
|
||||
@@ -97,6 +97,7 @@ GUIFormSpecMenu::GUIFormSpecMenu(irr::IrrlichtDevice* dev,
|
||||
m_form_src(fsrc),
|
||||
m_text_dst(tdst),
|
||||
m_formspec_version(0),
|
||||
m_focused_element(L""),
|
||||
m_font(NULL)
|
||||
#ifdef __ANDROID__
|
||||
,m_JavaDialogFieldName(L"")
|
||||
@@ -1757,8 +1758,6 @@ void GUIFormSpecMenu::parseElement(parserData* data, std::string element)
|
||||
<<std::endl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
|
||||
{
|
||||
/* useless to regenerate without a screensize */
|
||||
@@ -1775,6 +1774,10 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
|
||||
mydata.table_dyndata[tablename] = table->getDynamicData();
|
||||
}
|
||||
|
||||
//set focus
|
||||
if (!m_focused_element.empty())
|
||||
mydata.focused_fieldname = m_focused_element;
|
||||
|
||||
//preserve focus
|
||||
gui::IGUIElement *focused_element = Environment->getFocus();
|
||||
if (focused_element && focused_element->getParent() == this) {
|
||||
|
||||
@@ -246,13 +246,20 @@ class GUIFormSpecMenu : public GUIModalMenu
|
||||
m_allowclose = value;
|
||||
}
|
||||
|
||||
void lockSize(bool lock,v2u32 basescreensize=v2u32(0,0)) {
|
||||
void lockSize(bool lock,v2u32 basescreensize=v2u32(0,0))
|
||||
{
|
||||
m_lock = lock;
|
||||
m_lockscreensize = basescreensize;
|
||||
}
|
||||
|
||||
void removeChildren();
|
||||
void setInitialFocus();
|
||||
|
||||
void setFocus(std::wstring elementname)
|
||||
{
|
||||
m_focused_element = elementname;
|
||||
}
|
||||
|
||||
/*
|
||||
Remove and re-add (or reposition) stuff
|
||||
*/
|
||||
@@ -348,6 +355,7 @@ class GUIFormSpecMenu : public GUIModalMenu
|
||||
IFormSource *m_form_src;
|
||||
TextDest *m_text_dst;
|
||||
unsigned int m_formspec_version;
|
||||
std::wstring m_focused_element;
|
||||
|
||||
typedef struct {
|
||||
bool explicit_size;
|
||||
|
||||
@@ -156,8 +156,8 @@ void GUIKeyChangeMenu::regenerateGui(v2u32 screensize)
|
||||
}
|
||||
|
||||
{
|
||||
s32 option_x = offset.X + 10;
|
||||
s32 option_y = offset.Y;
|
||||
s32 option_x = offset.X;
|
||||
s32 option_y = offset.Y + 5;
|
||||
u32 option_w = 180;
|
||||
{
|
||||
core::rect<s32> rect(0, 0, option_w, 30);
|
||||
@@ -171,9 +171,9 @@ void GUIKeyChangeMenu::regenerateGui(v2u32 screensize)
|
||||
}
|
||||
|
||||
{
|
||||
s32 option_x = offset.X + 10;
|
||||
s32 option_y = offset.Y;
|
||||
u32 option_w = 220;
|
||||
s32 option_x = offset.X;
|
||||
s32 option_y = offset.Y + 5;
|
||||
u32 option_w = 280;
|
||||
{
|
||||
core::rect<s32> rect(0, 0, option_w, 30);
|
||||
rect += topleft + v2s32(option_x, option_y);
|
||||
|
||||
@@ -103,8 +103,8 @@ void GUIPasswordChange::regenerateGui(v2u32 screensize)
|
||||
*/
|
||||
s32 ypos = 50;
|
||||
{
|
||||
core::rect<s32> rect(0, 0, 110, 20);
|
||||
rect += topleft_client + v2s32(35, ypos+6);
|
||||
core::rect<s32> rect(0, 0, 150, 20);
|
||||
rect += topleft_client + v2s32(25, ypos+6);
|
||||
text = wgettext("Old Password");
|
||||
Environment->addStaticText(text, rect, false, true, this, -1);
|
||||
delete[] text;
|
||||
@@ -119,8 +119,8 @@ void GUIPasswordChange::regenerateGui(v2u32 screensize)
|
||||
}
|
||||
ypos += 50;
|
||||
{
|
||||
core::rect<s32> rect(0, 0, 110, 20);
|
||||
rect += topleft_client + v2s32(35, ypos+6);
|
||||
core::rect<s32> rect(0, 0, 150, 20);
|
||||
rect += topleft_client + v2s32(25, ypos+6);
|
||||
text = wgettext("New Password");
|
||||
Environment->addStaticText(text, rect, false, true, this, -1);
|
||||
delete[] text;
|
||||
@@ -134,8 +134,8 @@ void GUIPasswordChange::regenerateGui(v2u32 screensize)
|
||||
}
|
||||
ypos += 50;
|
||||
{
|
||||
core::rect<s32> rect(0, 0, 110, 20);
|
||||
rect += topleft_client + v2s32(35, ypos+6);
|
||||
core::rect<s32> rect(0, 0, 150, 20);
|
||||
rect += topleft_client + v2s32(25, ypos+6);
|
||||
text = wgettext("Confirm Password");
|
||||
Environment->addStaticText(text, rect, false, true, this, -1);
|
||||
delete[] text;
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#elif __MACH__
|
||||
#elif defined(__MACH__) && defined(__APPLE__)
|
||||
#include <mach/mach.h>
|
||||
#include <mach/task.h>
|
||||
#include <mach/semaphore.h>
|
||||
@@ -43,7 +43,7 @@
|
||||
class Event {
|
||||
#ifdef _WIN32
|
||||
HANDLE hEvent;
|
||||
#elif __MACH__
|
||||
#elif defined(__MACH__) && defined(__APPLE__)
|
||||
semaphore_t sem;
|
||||
#else
|
||||
sem_t sem;
|
||||
|
||||
@@ -24,7 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include <windows.h>
|
||||
#include <assert.h>
|
||||
#define MAX_SEMAPHORE_COUNT 1024
|
||||
#elif __MACH__
|
||||
#elif defined(__MACH__) && defined(__APPLE__)
|
||||
#include <pthread.h>
|
||||
#include <mach/mach.h>
|
||||
#include <mach/task.h>
|
||||
@@ -52,7 +52,7 @@ class JSemaphore {
|
||||
private:
|
||||
#if defined(WIN32)
|
||||
HANDLE m_hSemaphore;
|
||||
#elif __MACH__
|
||||
#elif defined(__MACH__) && defined(__APPLE__)
|
||||
semaphore_t m_semaphore;
|
||||
int semcount;
|
||||
#else
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
#define UNUSED(expr) do { (void)(expr); } while (0)
|
||||
|
||||
#ifdef __MACH__
|
||||
#if defined(__MACH__) && defined(__APPLE__)
|
||||
#undef sem_t
|
||||
#define sem_t semaphore_t
|
||||
#undef sem_init
|
||||
|
||||
@@ -20,13 +20,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include <errno.h>
|
||||
#include <sys/time.h>
|
||||
#include "jthread/jsemaphore.h"
|
||||
#ifdef __MACH__
|
||||
#if defined(__MACH__) && defined(__APPLE__)
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#define UNUSED(expr) do { (void)(expr); } while (0)
|
||||
|
||||
#ifdef __MACH__
|
||||
#if defined(__MACH__) && defined(__APPLE__)
|
||||
#undef sem_t
|
||||
#undef sem_init
|
||||
#undef sem_wait
|
||||
@@ -44,7 +44,7 @@ JSemaphore::JSemaphore() {
|
||||
int sem_init_retval = sem_init(&m_semaphore,0,0);
|
||||
assert(sem_init_retval == 0);
|
||||
UNUSED(sem_init_retval);
|
||||
#ifdef __MACH__
|
||||
#if defined(__MACH__) && defined(__APPLE__)
|
||||
semcount = 0;
|
||||
#endif
|
||||
}
|
||||
@@ -73,7 +73,7 @@ void JSemaphore::Post() {
|
||||
int sem_post_retval = sem_post(&m_semaphore);
|
||||
assert(sem_post_retval == 0);
|
||||
UNUSED(sem_post_retval);
|
||||
#ifdef __MACH__
|
||||
#if defined(__MACH__) && defined(__APPLE__)
|
||||
pthread_mutex_lock(&semcount_mutex);
|
||||
semcount++;
|
||||
pthread_mutex_unlock(&semcount_mutex);
|
||||
@@ -84,7 +84,7 @@ void JSemaphore::Wait() {
|
||||
int sem_wait_retval = sem_wait(&m_semaphore);
|
||||
assert(sem_wait_retval == 0);
|
||||
UNUSED(sem_wait_retval);
|
||||
#ifdef __MACH__
|
||||
#if defined(__MACH__) && defined(__APPLE__)
|
||||
pthread_mutex_lock(&semcount_mutex);
|
||||
semcount--;
|
||||
pthread_mutex_unlock(&semcount_mutex);
|
||||
@@ -92,7 +92,7 @@ void JSemaphore::Wait() {
|
||||
}
|
||||
|
||||
bool JSemaphore::Wait(unsigned int time_ms) {
|
||||
#ifdef __MACH__
|
||||
#if defined(__MACH__) && defined(__APPLE__)
|
||||
mach_timespec_t waittime;
|
||||
waittime.tv_sec = time_ms / 1000;
|
||||
waittime.tv_nsec = 1000000 * (time_ms % 1000);
|
||||
@@ -106,14 +106,14 @@ bool JSemaphore::Wait(unsigned int time_ms) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifndef __MACH__
|
||||
#if !(defined(__MACH__) && defined(__APPLE__))
|
||||
waittime.tv_nsec = ((time_ms % 1000) * 1000 * 1000) + (now.tv_usec * 1000);
|
||||
waittime.tv_sec = (time_ms / 1000) + (waittime.tv_nsec / (1000*1000*1000)) + now.tv_sec;
|
||||
waittime.tv_nsec %= 1000*1000*1000;
|
||||
#endif
|
||||
|
||||
errno = 0;
|
||||
#ifdef __MACH__
|
||||
#if defined(__MACH__) && defined(__APPLE__)
|
||||
int sem_wait_retval = semaphore_timedwait(m_semaphore, waittime);
|
||||
if (sem_wait_retval == KERN_OPERATION_TIMED_OUT) {
|
||||
errno = ETIMEDOUT;
|
||||
@@ -128,7 +128,7 @@ bool JSemaphore::Wait(unsigned int time_ms) {
|
||||
|
||||
if (sem_wait_retval == 0)
|
||||
{
|
||||
#ifdef __MACH__
|
||||
#if defined(__MACH__) && defined(__APPLE__)
|
||||
pthread_mutex_lock(&semcount_mutex);
|
||||
semcount--;
|
||||
pthread_mutex_unlock(&semcount_mutex);
|
||||
@@ -144,7 +144,7 @@ bool JSemaphore::Wait(unsigned int time_ms) {
|
||||
|
||||
int JSemaphore::GetValue() {
|
||||
int retval = 0;
|
||||
#ifdef __MACH__
|
||||
#if defined(__MACH__) && defined(__APPLE__)
|
||||
pthread_mutex_lock(&semcount_mutex);
|
||||
retval = semcount;
|
||||
pthread_mutex_unlock(&semcount_mutex);
|
||||
|
||||
@@ -1863,11 +1863,11 @@ void Map::transformLiquids(std::map<v3s16, MapBlock*> & modified_blocks)
|
||||
|
||||
// Find out whether there is a suspect for this action
|
||||
std::string suspect;
|
||||
if(m_gamedef->rollback()){
|
||||
if(m_gamedef->rollback()) {
|
||||
suspect = m_gamedef->rollback()->getSuspect(p0, 83, 1);
|
||||
}
|
||||
|
||||
if(!suspect.empty()){
|
||||
if(m_gamedef->rollback() && !suspect.empty()){
|
||||
// Blame suspect
|
||||
RollbackScopeActor rollback_scope(m_gamedef->rollback(), suspect, true);
|
||||
// Get old node for rollback
|
||||
|
||||
@@ -60,7 +60,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include <unistd.h>
|
||||
#include <stdint.h> //for uintptr_t
|
||||
|
||||
#if (defined(linux) || defined(__linux)) && !defined(_GNU_SOURCE)
|
||||
#if (defined(linux) || defined(__linux) || defined(__GNU__)) && !defined(_GNU_SOURCE)
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
|
||||
@@ -228,7 +228,7 @@ void initIrrlicht(irr::IrrlichtDevice * );
|
||||
#else // Posix
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#ifdef __MACH__
|
||||
#if defined(__MACH__) && defined(__APPLE__)
|
||||
#include <mach/clock.h>
|
||||
#include <mach/mach.h>
|
||||
#endif
|
||||
@@ -258,7 +258,7 @@ void initIrrlicht(irr::IrrlichtDevice * );
|
||||
{
|
||||
struct timespec ts;
|
||||
// from http://stackoverflow.com/questions/5167269/clock-gettime-alternative-in-mac-os-x
|
||||
#ifdef __MACH__ // OS X does not have clock_gettime, use clock_get_time
|
||||
#if defined(__MACH__) && defined(__APPLE__) // OS X does not have clock_gettime, use clock_get_time
|
||||
clock_serv_t cclock;
|
||||
mach_timespec_t mts;
|
||||
host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock);
|
||||
@@ -358,7 +358,7 @@ inline u32 getDeltaMs(u32 old_time_ms, u32 new_time_ms)
|
||||
inline void setThreadName(const char *name) {
|
||||
pthread_setname_np(name);
|
||||
}
|
||||
#elif defined(_WIN32)
|
||||
#elif defined(_WIN32) || defined(__GNU__)
|
||||
inline void setThreadName(const char* name) {}
|
||||
#else
|
||||
#warning "Unrecognized platform, thread names will not be available."
|
||||
|
||||
@@ -472,6 +472,7 @@ int ModApiMainMenu::l_get_favorites(lua_State *L)
|
||||
|
||||
for (unsigned int i = 0; i < servers.size(); i++)
|
||||
{
|
||||
|
||||
lua_pushnumber(L,index);
|
||||
|
||||
lua_newtable(L);
|
||||
@@ -509,6 +510,18 @@ int ModApiMainMenu::l_get_favorites(lua_State *L)
|
||||
lua_settable(L, top_lvl2);
|
||||
}
|
||||
|
||||
if (servers[i]["proto_min"].asString().size()) {
|
||||
lua_pushstring(L,"proto_min");
|
||||
lua_pushinteger(L,servers[i]["proto_min"].asInt());
|
||||
lua_settable(L, top_lvl2);
|
||||
}
|
||||
|
||||
if (servers[i]["proto_max"].asString().size()) {
|
||||
lua_pushstring(L,"proto_max");
|
||||
lua_pushinteger(L,servers[i]["proto_max"].asInt());
|
||||
lua_settable(L, top_lvl2);
|
||||
}
|
||||
|
||||
if (servers[i]["password"].asString().size()) {
|
||||
lua_pushstring(L,"password");
|
||||
lua_pushboolean(L,servers[i]["password"].asBool());
|
||||
@@ -859,19 +872,19 @@ int ModApiMainMenu::l_extract_zip(lua_State *L)
|
||||
|
||||
unsigned int number_of_files = files_in_zip->getFileCount();
|
||||
|
||||
for (unsigned int i=0; i < number_of_files; i++) {
|
||||
for (unsigned int i=0; i < number_of_files; i++) {
|
||||
std::string fullpath = destination;
|
||||
fullpath += DIR_DELIM;
|
||||
fullpath += files_in_zip->getFullFileName(i).c_str();
|
||||
std::string fullpath_dir = fs::RemoveLastPathComponent(fullpath);
|
||||
|
||||
if (files_in_zip->isDirectory(i)) {
|
||||
if (! fs::CreateAllDirs(fullpath) ) {
|
||||
if (!files_in_zip->isDirectory(i)) {
|
||||
if (!fs::PathExists(fullpath_dir) && !fs::CreateAllDirs(fullpath_dir)) {
|
||||
fs->removeFileArchive(fs->getFileArchiveCount()-1);
|
||||
lua_pushboolean(L,false);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
io::IReadFile* toread = opened_zip->createAndOpenFile(i);
|
||||
|
||||
FILE *targetfile = fopen(fullpath.c_str(),"wb");
|
||||
@@ -883,7 +896,7 @@ int ModApiMainMenu::l_extract_zip(lua_State *L)
|
||||
}
|
||||
|
||||
char read_buffer[1024];
|
||||
unsigned int total_read = 0;
|
||||
long total_read = 0;
|
||||
|
||||
while (total_read < toread->getSize()) {
|
||||
|
||||
@@ -1082,6 +1095,19 @@ int ModApiMainMenu::l_get_screen_info(lua_State *L)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
int ModApiMainMenu::l_get_min_supp_proto(lua_State *L)
|
||||
{
|
||||
lua_pushinteger(L, CLIENT_PROTOCOL_VERSION_MIN);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ModApiMainMenu::l_get_max_supp_proto(lua_State *L)
|
||||
{
|
||||
lua_pushinteger(L, CLIENT_PROTOCOL_VERSION_MAX);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
int ModApiMainMenu::l_do_async_callback(lua_State *L)
|
||||
{
|
||||
@@ -1142,6 +1168,8 @@ void ModApiMainMenu::Initialize(lua_State *L, int top)
|
||||
API_FCT(gettext);
|
||||
API_FCT(get_video_drivers);
|
||||
API_FCT(get_screen_info);
|
||||
API_FCT(get_min_supp_proto);
|
||||
API_FCT(get_max_supp_proto);
|
||||
API_FCT(do_async_callback);
|
||||
}
|
||||
|
||||
|
||||
@@ -137,6 +137,12 @@ class ModApiMainMenu : public ModApiBase {
|
||||
|
||||
static int l_get_video_drivers(lua_State *L);
|
||||
|
||||
//version compatibility
|
||||
static int l_get_min_supp_proto(lua_State *L);
|
||||
|
||||
static int l_get_max_supp_proto(lua_State *L);
|
||||
|
||||
|
||||
// async
|
||||
static int l_do_async_callback(lua_State *L);
|
||||
|
||||
|
||||
@@ -44,6 +44,9 @@ int ModApiRollback::l_rollback_get_node_actions(lua_State *L)
|
||||
int limit = luaL_checknumber(L, 4);
|
||||
Server *server = getServer(L);
|
||||
IRollbackManager *rollback = server->getRollbackManager();
|
||||
if (rollback == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::list<RollbackAction> actions = rollback->getNodeActors(pos, range, seconds, limit);
|
||||
std::list<RollbackAction>::iterator iter = actions.begin();
|
||||
@@ -80,6 +83,13 @@ int ModApiRollback::l_rollback_revert_actions_by(lua_State *L)
|
||||
int seconds = luaL_checknumber(L, 2);
|
||||
Server *server = getServer(L);
|
||||
IRollbackManager *rollback = server->getRollbackManager();
|
||||
|
||||
// If rollback is disabled, tell it's not a success.
|
||||
if (rollback == NULL) {
|
||||
lua_pushboolean(L, false);
|
||||
lua_newtable(L);
|
||||
return 2;
|
||||
}
|
||||
std::list<RollbackAction> actions = rollback->getRevertActions(actor, seconds);
|
||||
std::list<std::string> log;
|
||||
bool success = server->rollbackRevertActions(actions, &log);
|
||||
|
||||
@@ -244,9 +244,6 @@ Server::Server(
|
||||
std::string ban_path = m_path_world + DIR_DELIM "ipban.txt";
|
||||
m_banmanager = new BanManager(ban_path);
|
||||
|
||||
// Create rollback manager
|
||||
m_rollback = new RollbackManager(m_path_world, this);
|
||||
|
||||
ModConfiguration modconf(m_path_world);
|
||||
m_mods = modconf.getMods();
|
||||
std::vector<ModSpec> unsatisfied_mods = modconf.getUnsatisfiedMods();
|
||||
@@ -354,6 +351,12 @@ Server::Server(
|
||||
// Initialize mapgens
|
||||
m_emerge->initMapgens();
|
||||
|
||||
m_enable_rollback_recording = g_settings->getBool("enable_rollback_recording");
|
||||
if (m_enable_rollback_recording) {
|
||||
// Create rollback manager
|
||||
m_rollback = new RollbackManager(m_path_world, this);
|
||||
}
|
||||
|
||||
// Give environment reference to scripting api
|
||||
m_script->initializeEnvironment(m_env);
|
||||
|
||||
@@ -1108,10 +1111,6 @@ void Server::AsyncRunStep(bool initial_step)
|
||||
counter = 0.0;
|
||||
|
||||
m_emerge->startThreads();
|
||||
|
||||
// Update m_enable_rollback_recording here too
|
||||
m_enable_rollback_recording =
|
||||
g_settings->getBool("enable_rollback_recording");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include "filesys.h"
|
||||
#include "porting.h"
|
||||
#include "log.h"
|
||||
#include "clientserver.h"
|
||||
#include "json/json.h"
|
||||
#include "convert_json.h"
|
||||
#include "httpfetch.h"
|
||||
@@ -67,8 +68,11 @@ std::vector<ServerListSpec> getLocal()
|
||||
|
||||
std::vector<ServerListSpec> getOnline()
|
||||
{
|
||||
Json::Value root = fetchJsonValue(
|
||||
(g_settings->get("serverlist_url") + "/list").c_str(), NULL);
|
||||
std::ostringstream geturl;
|
||||
geturl << g_settings->get("serverlist_url") <<
|
||||
"/list?proto_version_min=" << CLIENT_PROTOCOL_VERSION_MIN <<
|
||||
"&proto_version_max=" << CLIENT_PROTOCOL_VERSION_MAX;
|
||||
Json::Value root = fetchJsonValue(geturl.str(), NULL);
|
||||
|
||||
std::vector<ServerListSpec> server_list;
|
||||
|
||||
@@ -205,9 +209,12 @@ void sendAnnounce(const std::string &action,
|
||||
server["address"] = g_settings->get("server_address");
|
||||
}
|
||||
if (action != "delete") {
|
||||
bool strict_checking = g_settings->getBool("strict_protocol_version_checking");
|
||||
server["name"] = g_settings->get("server_name");
|
||||
server["description"] = g_settings->get("server_description");
|
||||
server["version"] = minetest_version_simple;
|
||||
server["proto_min"] = strict_checking ? LATEST_PROTOCOL_VERSION : SERVER_PROTOCOL_VERSION_MIN;
|
||||
server["proto_max"] = strict_checking ? LATEST_PROTOCOL_VERSION : SERVER_PROTOCOL_VERSION_MAX;
|
||||
server["url"] = g_settings->get("server_url");
|
||||
server["creative"] = g_settings->getBool("creative_mode");
|
||||
server["damage"] = g_settings->getBool("enable_damage");
|
||||
|
||||
@@ -62,20 +62,21 @@ int wctomb(char *s, wchar_t wc)
|
||||
|
||||
int mbtowc(wchar_t *pwc, const char *s, size_t n)
|
||||
{
|
||||
wchar_t *intermediate = narrow_to_wide(s);
|
||||
const wchar_t *tmp = narrow_to_wide_c(s);
|
||||
|
||||
if (intermediate.length() > 0) {
|
||||
*pwc = intermediate[0];
|
||||
if (tmp[0] != '\0') {
|
||||
*pwc = tmp[0];
|
||||
return 1;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// You must free the returned string!
|
||||
const wchar_t *narrow_to_wide_c(const char *mbs)
|
||||
{
|
||||
size_t mbl = strlen(mbs);
|
||||
wchar_t wcs = new wchar_t[mbl + 1];
|
||||
wchar_t *wcs = new wchar_t[mbl + 1];
|
||||
|
||||
for (size_t i = 0; i < mbl; i++) {
|
||||
if (((unsigned char) mbs[i] > 31) &&
|
||||
@@ -98,11 +99,13 @@ const wchar_t *narrow_to_wide_c(const char *mbs)
|
||||
{
|
||||
wchar_t *wcs = NULL;
|
||||
#if defined(_WIN32)
|
||||
int wcl = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR) mbs, -1, NULL, 0);
|
||||
if (!wcl)
|
||||
return NULL;
|
||||
wcs = new wchar_t[wcl];
|
||||
MultiByteToWideChar(CP_UTF8, 0, (LPCSTR) mbs, -1, (WCHAR *) wcs, wcl);
|
||||
int nResult = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR) mbs, -1, 0, 0);
|
||||
if (nResult == 0) {
|
||||
errorstream << "gettext: MultiByteToWideChar returned null" << std::endl;
|
||||
} else {
|
||||
wcs = new wchar_t[nResult];
|
||||
MultiByteToWideChar(CP_UTF8, 0, (LPCSTR) mbs, -1, (WCHAR *) wcs, nResult);
|
||||
}
|
||||
#else
|
||||
size_t wcl = mbstowcs(NULL, mbs, 0);
|
||||
if (wcl == (size_t) -1)
|
||||
@@ -120,12 +123,13 @@ const wchar_t *narrow_to_wide_c(const char *mbs)
|
||||
|
||||
std::wstring narrow_to_wide(const std::string& mbs)
|
||||
{
|
||||
const wchar_t *wcs = narrow_to_wide_c(mbs.c_str());
|
||||
if (!wcs)
|
||||
size_t wcl = mbs.size();
|
||||
Buffer<wchar_t> wcs(wcl + 1);
|
||||
size_t l = mbstowcs(*wcs, mbs.c_str(), wcl);
|
||||
if (l == (size_t)(-1))
|
||||
return L"<invalid multibyte string>";
|
||||
std::wstring wstr(wcs);
|
||||
delete [] wcs;
|
||||
return wstr;
|
||||
wcs[l] = 0;
|
||||
return *wcs;
|
||||
}
|
||||
|
||||
#ifdef __ANDROID__
|
||||
|
||||
Reference in New Issue
Block a user