Compare commits

..

988 Commits
5.0.0 ... 5.3.0

Author SHA1 Message Date
sfan5
057f0b82c2 Bump version to 5.3.0 2020-07-09 22:04:20 +02:00
sfan5
70df3d54f3 Quick workaround for crashing destructor on Mingw32
closes #10137
2020-07-09 22:01:46 +02:00
sfan5
21de17e3b6 Fix ContentDB menu icons not appearing on Windows 2020-07-08 23:37:14 +02:00
sfan5
b4c25872f1 Make util/bump_version.sh work again 2020-07-08 23:11:41 +02:00
rubenwardy
5f3f806d67 Translated using Weblate (Slovak)
Currently translated at 12.8% (174 of 1350 strings)
2020-07-08 22:51:18 +02:00
daretmavi
352529e749 Translated using Weblate (Slovak)
Currently translated at 12.8% (174 of 1350 strings)
2020-07-08 22:51:18 +02:00
sfan5
3c175707eb Translated using Weblate (Galician)
Currently translated at 0.5% (8 of 1350 strings)
2020-07-08 22:51:18 +02:00
sfan5
b7129f63c4 Translated using Weblate (Basque)
Currently translated at 17.5% (237 of 1350 strings)
2020-07-08 22:51:18 +02:00
sfan5
3547c47ee7 Translated using Weblate (Serbian (cyrillic))
Currently translated at 26.2% (354 of 1350 strings)
2020-07-08 22:51:18 +02:00
sfan5
ab175e259e Translated using Weblate (Dutch)
Currently translated at 78.9% (1066 of 1350 strings)
2020-07-08 22:51:18 +02:00
sfan5
9889f57cbc Translated using Weblate (Czech)
Currently translated at 55.7% (753 of 1350 strings)
2020-07-08 22:51:18 +02:00
daretmavi
550549d56b Added translation using Weblate (Slovak) 2020-07-08 22:51:18 +02:00
TZTarzan
6ca7d42969 Translated using Weblate (Thai)
Currently translated at 60.8% (822 of 1350 strings)
2020-07-08 22:51:18 +02:00
Tirifto
4324b93615 Translated using Weblate (Esperanto)
Currently translated at 96.5% (1304 of 1350 strings)
2020-07-08 22:51:18 +02:00
Miniontoby
55c30596e3 Translated using Weblate (Dutch)
Currently translated at 78.8% (1065 of 1350 strings)
2020-07-08 22:51:18 +02:00
Estébastien Robespi
4f59bebd37 Translated using Weblate (French)
Currently translated at 98.9% (1336 of 1350 strings)
2020-07-08 22:51:18 +02:00
Yaya - Nurul Azeera Hidayah @ Muhammad Nur Hidayat Yasuyoshi
1e05ef1803 Translated using Weblate (Malay (Jawi))
Currently translated at 7.4% (100 of 1350 strings)
2020-07-08 22:51:18 +02:00
Agastya
38d0253b7e Translated using Weblate (Hindi)
Currently translated at 33.1% (448 of 1350 strings)
2020-07-08 22:51:18 +02:00
Wuzzy
63800fe843 Translated using Weblate (Galician)
Currently translated at 0.5% (7 of 1350 strings)
2020-07-08 22:51:18 +02:00
Wuzzy
e07090cd7e Translated using Weblate (Dutch)
Currently translated at 78.3% (1058 of 1350 strings)
2020-07-08 22:51:18 +02:00
Agustin Calderon
fd9e7abf0e Translated using Weblate (Spanish)
Currently translated at 69.9% (944 of 1350 strings)
2020-07-08 22:51:18 +02:00
Wuzzy
b3867a4b4c Translated using Weblate (Czech)
Currently translated at 55.7% (752 of 1350 strings)
2020-07-08 22:51:18 +02:00
Yaya - Nurul Azeera Hidayah @ Muhammad Nur Hidayat Yasuyoshi
f30331af39 Added translation using Weblate (Malay (Jawi)) 2020-07-08 22:51:18 +02:00
Maksim Gamarnik
e2878567ca Translated using Weblate (Ukrainian)
Currently translated at 42.6% (576 of 1350 strings)
2020-07-08 22:51:18 +02:00
Hamlet
6da65f1ba9 Translated using Weblate (Italian)
Currently translated at 100.0% (1350 of 1350 strings)
2020-07-08 22:51:18 +02:00
Muhammad Rifqi Priyo Susanto
dcdc6b762f Translated using Weblate (Indonesian)
Currently translated at 99.6% (1345 of 1350 strings)
2020-07-08 22:51:18 +02:00
GunChleoc
387a3493c5 Translated using Weblate (Gaelic)
Currently translated at 18.1% (245 of 1350 strings)
2020-07-08 22:51:18 +02:00
runs
5435442ce7 Translated using Weblate (Galician)
Currently translated at 0.4% (6 of 1350 strings)
2020-07-08 22:51:18 +02:00
abidin toumi
d9fe830810 Translated using Weblate (Arabic)
Currently translated at 12.8% (173 of 1350 strings)
2020-07-08 22:51:18 +02:00
Fontan 030
b0019b876a Translated using Weblate (Kazakh)
Currently translated at 2.5% (34 of 1350 strings)
2020-07-08 22:51:18 +02:00
Andrii Muliar
822fdb60bc Translated using Weblate (Ukrainian)
Currently translated at 42.0% (568 of 1350 strings)
2020-07-08 22:51:18 +02:00
Fixer
6a58fc0e3c Translated using Weblate (Ukrainian)
Currently translated at 42.0% (568 of 1350 strings)
2020-07-08 22:51:18 +02:00
Giov4
184cbaade7 Translated using Weblate (Italian)
Currently translated at 100.0% (1350 of 1350 strings)
2020-07-08 22:51:18 +02:00
Hamlet
34a20b358c Translated using Weblate (Italian)
Currently translated at 100.0% (1350 of 1350 strings)
2020-07-08 22:51:18 +02:00
Shuli
cbd964e572 Translated using Weblate (Italian)
Currently translated at 100.0% (1350 of 1350 strings)
2020-07-08 22:51:18 +02:00
Ács Zoltán
b706049981 Translated using Weblate (Hungarian)
Currently translated at 77.1% (1042 of 1350 strings)
2020-07-08 22:51:18 +02:00
GunChleoc
719b0e9850 Added translation using Weblate (Gaelic) 2020-07-08 22:51:18 +02:00
runs
ac0f168e10 Added translation using Weblate (Galician) 2020-07-08 22:51:18 +02:00
Jacques Lagrange
4c05453cbe Translated using Weblate (Italian)
Currently translated at 93.7% (1266 of 1350 strings)
2020-07-08 22:51:18 +02:00
Shuli
de35541465 Translated using Weblate (Italian)
Currently translated at 93.7% (1266 of 1350 strings)
2020-07-08 22:51:18 +02:00
Hamlet
5564babc94 Translated using Weblate (Italian)
Currently translated at 93.7% (1266 of 1350 strings)
2020-07-08 22:51:18 +02:00
Maksim Gamarnik
3ebfe0ccfd Translated using Weblate (Ukrainian)
Currently translated at 41.4% (560 of 1350 strings)
2020-07-08 22:51:17 +02:00
Maksim Gamarnik
6e51935aa9 Translated using Weblate (Russian)
Currently translated at 92.0% (1243 of 1350 strings)
2020-07-08 22:51:17 +02:00
Guus Seldenthuis
2675fb93ac Translated using Weblate (Dutch)
Currently translated at 78.4% (1059 of 1350 strings)
2020-07-08 22:51:17 +02:00
Allan Nordhøy
ecc66ccf40 Translated using Weblate (Norwegian Bokmål)
Currently translated at 56.8% (768 of 1350 strings)
2020-07-08 22:51:17 +02:00
Yaya - Nurul Azeera Hidayah @ Muhammad Nur Hidayat Yasuyoshi
6e12846ad8 Translated using Weblate (Malay)
Currently translated at 100.0% (1350 of 1350 strings)
2020-07-08 22:51:17 +02:00
monolifed
99541ab294 Translated using Weblate (Turkish)
Currently translated at 100.0% (1350 of 1350 strings)
2020-07-08 22:51:17 +02:00
Oğuz Ersen
6e5fc82f9a Translated using Weblate (Turkish)
Currently translated at 100.0% (1350 of 1350 strings)
2020-07-08 22:51:17 +02:00
BreadW
7c52a53aeb Translated using Weblate (Japanese)
Currently translated at 100.0% (1350 of 1350 strings)
2020-07-08 22:51:17 +02:00
runs
faf1985953 Translated using Weblate (Spanish)
Currently translated at 67.8% (916 of 1350 strings)
2020-07-08 22:51:17 +02:00
Jose Reina Leon
68cc9583da Translated using Weblate (Spanish)
Currently translated at 67.8% (916 of 1350 strings)
2020-07-08 22:51:17 +02:00
runs
12dd01b731 Translated using Weblate (Spanish)
Currently translated at 67.8% (916 of 1350 strings)
2020-07-08 22:51:17 +02:00
Wuzzy
b3f78c57a8 Translated using Weblate (German)
Currently translated at 100.0% (1350 of 1350 strings)
2020-07-08 22:51:17 +02:00
rubenwardy
42b0d612ef Fix build due to revert error 2020-07-07 19:31:14 +01:00
TheTermos
ebb721a476 Fix player controls only being applied for the first move 2020-07-07 19:09:23 +02:00
rubenwardy
6e4d8de104 Revert "Verify database connection on interval (#9665)"
Fixes #10113

This reverts commit 5c588f89e7.
2020-07-07 17:50:52 +01:00
Paramat
dc6318b84a Apply camera smoothing to 'air stepheight' (#10025)
Recent changes to collision code have changed the behaviour of the 'touching_ground'
bool in movement code. This had the effect of disabling camera smoothing when
'air stepheight' occurred when jumping onto a node while pressing forwards against
the node, causing an unpleasant sharp camera movement.

Rewrite the conditions for camera smoothing such that it is applied when jumping.
2020-07-05 23:45:21 +01:00
v-rob
da71313e1d Don't stop style parsing on unknown property (#10143) 2020-07-03 18:33:23 +02:00
Wuzzy
3f702fa1a9 Fix undeclared global in devtest (#10133) 2020-07-02 19:05:06 +02:00
hecktest
7be082f9a8 Fix bone-attached entities (#10015) 2020-06-26 00:06:29 +02:00
rubenwardy
3014e8b33b Release test build to Android beta program 2020-06-25 15:40:37 +01:00
Pierre-Yves Rollo
ee6c499ff8 Fix wrong use of guiScalingImageButton in formspecs buttons (#10094) 2020-06-24 11:35:06 +02:00
Maksim
646af2ef5f Android: fix maxAspectRatio (should be float) (#10080) 2020-06-23 19:00:34 +01:00
v-rob
f7c78993f6 Document deprecation of *_hovered and *_pressed styles (#10092) 2020-06-23 17:59:02 +01:00
adrido
d7a2113893 Disable pgsql in VS 2019 workflow 2020-06-22 18:18:15 +02:00
rubenwardy
4cb18d4874 Fix HTTP API not being available in async mainmenu (#10086) 2020-06-22 14:40:04 +01:00
rubenwardy
e99415e0c5 Android: Fix asset upgrade by renaming license file (#10073) 2020-06-20 14:52:24 +01:00
rubenwardy
0f1f8e4a0f Add warning when disabling secure.enable_security (#9943) 2020-06-20 13:21:38 +01:00
Maksim
a2199bf622 Android: fix TMPFolder path (#10052) 2020-06-20 12:06:30 +02:00
SmallJoker
57df895cf9 ParticleSpawner: Fix crash when attaching to invisible entity 2020-06-19 19:29:47 +02:00
sfan5
495f7198ef content_cao: Fix behavior of legacy "textures" field for wielditems 2020-06-18 19:36:06 +02:00
rubenwardy
469e8d8b7e Add .nomedia file to Android assets (#10047) 2020-06-18 18:24:38 +01:00
rubenwardy
8ebeed53ad Android: Fix only right strafe working (#10046) 2020-06-18 01:43:43 +01:00
oilboi
a1b444bb61 Fix typo (#10043) 2020-06-17 18:59:02 +01:00
Danila Shutov
3a6dfda358 Make shading of CAOs optional (#10033) 2020-06-16 20:48:31 +01:00
updatepo.sh
0a1181f763 Update translation files 2020-06-13 23:22:32 +02:00
updatepo.sh
0ba19a08b8 Update minetest.conf.example, settings_translation_file.cpp 2020-06-13 23:22:32 +02:00
darkcloudcat
c013a24787 Translated using Weblate (Vietnamese)
Currently translated at 2.5% (33 of 1288 strings)
2020-06-13 23:22:32 +02:00
Fontan 030
24e58b7546 Translated using Weblate (Kazakh)
Currently translated at 1.8% (24 of 1288 strings)
2020-06-13 23:22:32 +02:00
ferrumcccp
8aa1a36beb Translated using Weblate (Chinese (Simplified))
Currently translated at 92.9% (1197 of 1288 strings)
2020-06-13 23:22:32 +02:00
Yangjun Wang
e0c094f414 Translated using Weblate (Chinese (Simplified))
Currently translated at 90.1% (1161 of 1288 strings)
2020-06-13 23:22:32 +02:00
IFRFSX
0785802269 Translated using Weblate (Chinese (Simplified))
Currently translated at 90.1% (1161 of 1288 strings)
2020-06-13 23:22:32 +02:00
青草
b8b3cec9eb Translated using Weblate (Chinese (Simplified))
Currently translated at 90.1% (1161 of 1288 strings)
2020-06-13 23:22:32 +02:00
ferrumcccp
2b42319cb8 Translated using Weblate (Chinese (Simplified))
Currently translated at 90.1% (1161 of 1288 strings)
2020-06-13 23:22:32 +02:00
Mikołaj Zaremba
978d9a667e Translated using Weblate (Polish)
Currently translated at 77.6% (1000 of 1288 strings)
2020-06-13 23:22:32 +02:00
Muhammad Rifqi Priyo Susanto
60f635e335 Translated using Weblate (Indonesian)
Currently translated at 97.5% (1256 of 1288 strings)
2020-06-13 23:13:44 +02:00
Ács Zoltán
7a8ba99c75 Translated using Weblate (Hungarian)
Currently translated at 70.8% (912 of 1288 strings)
2020-06-13 23:13:44 +02:00
Uko Koknevics
d7106c4d5f Translated using Weblate (Latvian)
Currently translated at 31.8% (410 of 1288 strings)
2020-06-13 23:13:44 +02:00
Uko Koknevics
d69d6fe003 Added translation using Weblate (Latvian) 2020-06-13 23:13:44 +02:00
Rostyslav
849f7efac5 Translated using Weblate (Ukrainian)
Currently translated at 42.0% (541 of 1288 strings)
2020-06-13 23:13:44 +02:00
Damian Wojsław
f86c7f5db6 Translated using Weblate (Polish)
Currently translated at 77.4% (997 of 1288 strings)
2020-06-13 23:13:44 +02:00
Dominik Kacprzak
a72a900c82 Translated using Weblate (Polish)
Currently translated at 77.4% (997 of 1288 strings)
2020-06-13 23:13:44 +02:00
WaldiS
e9052d6060 Translated using Weblate (Polish)
Currently translated at 77.4% (997 of 1288 strings)
2020-06-13 23:13:44 +02:00
Miniontoby
b0500f9db9 Translated using Weblate (Dutch)
Currently translated at 83.1% (1071 of 1288 strings)
2020-06-13 23:13:44 +02:00
you can't know
f664ff1285 Translated using Weblate (Dutch)
Currently translated at 69.4% (894 of 1288 strings)
2020-06-13 23:13:44 +02:00
dave90dave
197ab7570f Translated using Weblate (Dutch)
Currently translated at 69.4% (894 of 1288 strings)
2020-06-13 23:13:44 +02:00
Oscar
17ebb72ebe Translated using Weblate (Dutch)
Currently translated at 69.4% (894 of 1288 strings)
2020-06-13 23:13:44 +02:00
Miniontoby
c4a7c8a420 Translated using Weblate (Dutch)
Currently translated at 69.4% (894 of 1288 strings)
2020-06-13 23:13:44 +02:00
NicHan
4e3dba902e Translated using Weblate (French)
Currently translated at 96.7% (1246 of 1288 strings)
2020-06-13 23:13:44 +02:00
runs
c5b22bf6da Translated using Weblate (Spanish)
Currently translated at 67.9% (875 of 1288 strings)
2020-06-13 23:13:44 +02:00
aitzol berasategi
47081a5338 Translated using Weblate (Basque)
Currently translated at 18.6% (240 of 1288 strings)
2020-06-13 23:13:44 +02:00
Mivik
cdd1dc8b82 Translated using Weblate (Chinese (Simplified))
Currently translated at 89.1% (1148 of 1288 strings)
2020-06-13 23:13:43 +02:00
f0roots
8e44cdcddb Translated using Weblate (Romanian)
Currently translated at 42.7% (551 of 1288 strings)
2020-06-13 23:13:43 +02:00
Balázs Vámos
329b62a02c Translated using Weblate (Hungarian)
Currently translated at 70.7% (911 of 1288 strings)
2020-06-13 23:13:43 +02:00
restcoser
c13919d3b4 Translated using Weblate (Lithuanian)
Currently translated at 15.3% (198 of 1288 strings)
2020-06-13 23:13:43 +02:00
Dominik Kacprzak
e882cbb9ac Translated using Weblate (Polish)
Currently translated at 77.1% (994 of 1288 strings)
2020-06-13 23:13:43 +02:00
Anonymous
7f7706a538 Translated using Weblate (Russian)
Currently translated at 96.0% (1237 of 1288 strings)
2020-06-13 23:13:43 +02:00
Andrei Stepanov
6f3fc76db3 Translated using Weblate (Russian)
Currently translated at 96.0% (1237 of 1288 strings)
2020-06-13 23:13:43 +02:00
Janar Leas
3d17394410 Translated using Weblate (Estonian)
Currently translated at 30.4% (392 of 1288 strings)
2020-06-13 23:13:43 +02:00
Anonymous
4fcc671742 Translated using Weblate (Russian)
Currently translated at 95.4% (1230 of 1288 strings)
2020-06-13 23:13:43 +02:00
Andrei Stepanov
5fb86768e8 Translated using Weblate (Russian)
Currently translated at 95.4% (1230 of 1288 strings)
2020-06-13 23:13:43 +02:00
Anonymous
f0513a9d46 Translated using Weblate (Russian)
Currently translated at 95.3% (1228 of 1288 strings)
2020-06-13 23:13:43 +02:00
Andrei Stepanov
51656cd96d Translated using Weblate (Russian)
Currently translated at 95.3% (1228 of 1288 strings)
2020-06-13 23:13:43 +02:00
Matteo Gheza
1c6970ace0 Translated using Weblate (Italian)
Currently translated at 95.4% (1229 of 1288 strings)
2020-06-13 23:13:43 +02:00
Roman Ondráček
372506bc94 Translated using Weblate (Czech)
Currently translated at 58.9% (759 of 1288 strings)
2020-06-13 23:13:43 +02:00
Marek Sebera
f0e31ee1be Translated using Weblate (Czech)
Currently translated at 58.9% (759 of 1288 strings)
2020-06-13 23:13:43 +02:00
Anonymous
082d48e644 Translated using Weblate (Czech)
Currently translated at 58.9% (759 of 1288 strings)
2020-06-13 23:13:43 +02:00
Jeannette L
2f8492949a Translated using Weblate (French)
Currently translated at 96.6% (1245 of 1288 strings)
2020-06-13 23:13:43 +02:00
Muhammad Nur Hidayat Yasuyoshi
c3306c469a Translated using Weblate (Malay)
Currently translated at 100.0% (1288 of 1288 strings)
2020-06-13 23:13:43 +02:00
ERDwaYbR
eeb85c304b Translated using Weblate (Chinese (Simplified))
Currently translated at 87.8% (1132 of 1288 strings)
2020-06-13 23:13:43 +02:00
pitchblack
5de7d1c346 Translated using Weblate (Russian)
Currently translated at 94.8% (1222 of 1288 strings)
2020-06-13 23:13:43 +02:00
anonymous
fee4ac710c Translated using Weblate (Polish)
Currently translated at 77.0% (993 of 1288 strings)
2020-06-13 23:13:43 +02:00
William Desportes
9feae63557 Translated using Weblate (French)
Currently translated at 96.6% (1245 of 1288 strings)
2020-06-13 23:13:43 +02:00
An0n3m0us
604acbfd29 Translated using Weblate (Hungarian)
Currently translated at 69.9% (901 of 1288 strings)
2020-06-13 23:13:43 +02:00
SwampTurtle
ff42264d07 Translated using Weblate (Dutch)
Currently translated at 61.1% (788 of 1288 strings)
2020-06-13 23:13:43 +02:00
anonymous
caac1e131b Translated using Weblate (Dutch)
Currently translated at 61.1% (788 of 1288 strings)
2020-06-13 23:13:43 +02:00
Larissa Piklor
ec26fab3b6 Translated using Weblate (Romanian)
Currently translated at 18.7% (242 of 1288 strings)
2020-06-13 23:13:43 +02:00
Larissa Piklor
e2e27fa04b Translated using Weblate (Hungarian)
Currently translated at 69.8% (900 of 1288 strings)
2020-06-13 23:13:43 +02:00
Oğuz Ersen
e27ff020ee Translated using Weblate (Turkish)
Currently translated at 100.0% (1288 of 1288 strings)
2020-06-13 23:13:43 +02:00
Ács Zoltán
d6a2e4136b Translated using Weblate (Hungarian)
Currently translated at 69.6% (897 of 1288 strings)
2020-06-13 23:13:43 +02:00
Eyekay49
0f44dbe60d Translated using Weblate (Hindi)
Currently translated at 6.5% (85 of 1288 strings)
2020-06-13 23:13:43 +02:00
sfan5
586ad0d24b Added translation using Weblate (Hindi) 2020-06-13 23:09:04 +02:00
Lars Müller
e7e065f553 Exposing the zoom key to Lua API (#9903)
Co-authored-by: Raul Ferriz <raul.ferriz@gmail.com>
2020-06-13 22:46:20 +02:00
sfan5
2424dfe007 Server pushing media at runtime (#9961) 2020-06-13 19:03:26 +02:00
luk3yx
982a030f33 Add LevelDB player database (#9982) 2020-06-12 18:54:20 +02:00
sfan5
3f0cbbc372 Use multiple light positions for CAO lighting 2020-06-11 21:13:26 +02:00
sfan5
f89794108c content_cao: Do not expire visuals for texture updates 2020-06-11 21:12:36 +02:00
sfan5
80d9e9c183 Fix build error on Ubuntu 16.04 (again) 2020-06-10 11:46:14 +02:00
sfan5
64380cf92e Fix build error on Ubuntu 16.04 2020-06-10 10:58:13 +02:00
Danila Shutov
fe3e69eb40 Fix broken coloring of wielditems (#9969)
Fixes a regression that appeared in 5.3.0-dev.
2020-06-09 21:38:09 +02:00
NetherEran
7148834440 Some vector functions useful for working with rotations (#9572)
* added vector.rotate

* added vector.forward_from_rotation and vector.up_from_rotation

* added vector.forward_up_to_rotatiton

* fixed some bugs and formatting with vector functions

* shortened name of some new vector functions and added documentation

* made vector.rotate not require a unit vector as axis

* fixed crash with vector.forward_up_to_rot

* renamed new vector functions, made vector.rotate apply a rotation matrix, old vector.rotate is now called vector.rotate_around_axis

* documented vector function changes

* removed some whitespace to appease luacheck

* implemented and fixed optimization of vector.rotate_around_axis by SmallJoker

* added some unit tests for rotation vector functions

* clarified that rotation vectors are in radians and according to the left hand rule

* hopefully appeased luacheck

* renamed rotation_to_horizontal to forward_at_rotation, rotation_to_vertical to up_at_rotation

* handled cases where sin or cos are 0 in rotation vector functions

* added more comments

* clarified documentation of rotation vector functions

* added more unit tests

* changed way in which vector.rotate_around_axis is adjusted for left handed coordinate systems

* made vector.rotate_around_axis actually left handed

* unrolled matrix multiplication

* removed vector.forward_at_rotation and vector.up_at_rotation

* prettified vector.rotate_around_axis, made previous commits not break anything

* removed references to removed vector.forward_at_rotation and vector.up_at_rotation

* removed documentation of removed vector functions

* clarified documentation and fixed styling of rotation vector functions

* restyled comments minorly

* spelling fixes and some hopefully better comments

* allowed 'up' to be missing from vector.directions_to_rotation and removed requirement for unit vectors as arguments

* made vector.rotate_around_axis() right handed again for consistency

* documented previous changes

* made matrix multiplication actually multiply

* renamed vector.directions_to_rotation() to vector.dir_to_rotation()

* optimized a distance comparison

* Fixed potential false positive in unit tests.

Co-authored-by: NetherEran <nethereran@hotmail.com>
2020-06-09 19:38:39 +02:00
Paul Ouellette
b16f841756 LuaItemStack: Add __tostring metamethod (#8785)
* LuaItemStack: Add __tostring metamethod

* Clean up LuaItemStack::checkobject
2020-06-09 19:37:25 +02:00
hecktest
09e285f38c Fix player-to-object attachment teleport bug (#10008)
Fixes two bugs:

 * The camera offset was not applied to an object while detaching, briefly placing the irrlicht matrixnode in world space.
 *  When attaching, the matrixnode's absolute position was evaluated without evaluating the parent first, resulting in zeroed positions.
2020-06-09 19:36:47 +02:00
MoNTE48
b9f618746c TouchScreenGUI: fix some bugs, cleanup 2020-06-09 19:35:25 +02:00
MoNTE48
0d8e5bf587 TouchScreen Control: fix some bugs, cleanup 2020-06-09 19:35:25 +02:00
Maksim
756dc89ede Fix real keyboard movements on touchscreen devices 2020-06-09 19:35:25 +02:00
MoNTE48
3cee55f2b4 Hide tooltip after ETIE_LEFT_UP (for touch control) 2020-06-09 19:35:25 +02:00
sfan5
a21f9bb7e6 devtest: Improve tool and formspec usability
also fix the yawsprite test entity
2020-06-08 21:17:40 +02:00
sfan5
0ab580810c Reset touching_ground when in free_move
This corrects local player animation after enabling fly while standing on ground.
2020-06-07 20:45:26 +02:00
Paul Ouellette
09f9e465e7 Fix Lua panic when error() message is not a string 2020-06-07 18:14:40 +02:00
Danila Shutov
fe1f72ab0a Recalculate mesh normals for CAOs (#10000) 2020-06-07 18:14:00 +02:00
SmallJoker
8fc9e7eb11 GenericCAO: Fix glow not working since a08d18a 2020-06-07 14:17:32 +02:00
Vitaliy
e746607d0f Restore visual_scale support for nodeboxes (and allfaces) (#9906) 2020-06-06 22:25:18 +02:00
rubenwardy
36099ba947 Fix incorrect extension used for ContentDB thumbnails 2020-06-06 18:31:39 +01:00
rubenwardy
60bab8b2d7 Add HTTP API to main menu (#9998) 2020-06-06 17:17:08 +01:00
Maksim
7ec0e3df35 Fix HUD scaling (#9721)
This resolves HUD scaling issues on Android and desktops with custom DPI settings.
2020-06-05 21:42:33 +02:00
ANAND
08c0b7696a TestBan: Clean up properly after completing test (#9994) 2020-06-05 20:04:14 +02:00
Bektur
87b25e583d Show Toast in UI thread and fix unpacking on Android 10 (#9900) 2020-06-05 02:22:19 +01:00
rubenwardy
850af80089 Add buttons to ContentDB in game bar and configure world (#9944) 2020-06-04 21:53:26 +01:00
SmallJoker
c1e01bc638 Move shared parameters sending to UnitSAO (#9968)
Better header sorting by topic
Make UnitSAO-specific parameters private
Skip redundant recursive entity sending code (since ~5.2.0)
2020-06-04 19:31:46 +02:00
sfan5
0e698e63b3 Fix autoscale_mode segfault if tile doesn't have texture
closes #9965
2020-06-01 21:19:35 +02:00
SmallJoker
42a9b45c21 Lua API: Log incorrect parameter types as error (#9954)
Incorrect parameter types are logged as errors, taking coercion into account.
This is a workaround to ensure mod compatibility.
Duplicate warnings are ignored per server instance.
2020-06-01 19:02:15 +02:00
SmallJoker
a08d18acad ContentCAO: Update light of all attached entities (#9975) 2020-06-01 19:01:47 +02:00
Hugues Ross
f849917bbe imageScaleNNAA: Fix image clipping on rect- instead of image dimensions (#9896)
Fixes GUI scaling filters applied on animated images and 9slice backgrounds.
2020-06-01 15:22:04 +02:00
Wuzzy
51de4ae297 Devtest: Fix missing/incorrect liquid properties (#9955) 2020-05-30 00:46:57 +01:00
sfan5
4c8e1c3200 Clean up CAO nametag handling and remove deprecated AO_CMD
AO_CMD_UPDATE_NAMETAG_ATTRIBUTES was deprecated in
9eee3c3f46 (0.4.14)
2020-05-29 22:54:50 +02:00
sfan5
db7c262ee8 content_cao: Do not expire visuals when not necessary
fixes #6572
2020-05-29 22:54:50 +02:00
MoNTE48
34862a6442 Add disable_jump check for the player's feet 2020-05-29 22:53:58 +02:00
Wuzzy
65a6a316d0 Add minetest.is_creative_enabled 2020-05-29 22:45:40 +02:00
rubenwardy
9a64a9fd94 Update ContentDB dialog (#9949) 2020-05-29 00:52:48 +01:00
sfan5
471e567657 Value copy / allocation optimizations mostly in server, SAO and serialize code 2020-05-27 21:58:40 +02:00
sfan5
2fd5f38c45 Change item entity collisionbox so that they don't sink into the ground 2020-05-27 21:58:20 +02:00
sfan5
03dae5fba6 Fix falling entity not falling through players 2020-05-27 21:58:20 +02:00
rubenwardy
f90ca96c73 Make ContentDB downloads not block the UI (#9948) 2020-05-27 17:02:09 +01:00
sfan5
58f523e363 Fix liquids refusing to flow in X+ or Z+ in some cases (#9874)
Applies when a different:
- falling liquid is neighboring
- liquid is below
2020-05-26 23:17:23 +01:00
Paramat
ba553e22e4 Devtest game: Update biome registrations (#9936) 2020-05-26 23:11:33 +01:00
rubenwardy
8713924811 Fix devtest being ignored by .gitignore 2020-05-26 22:33:16 +01:00
Wuzzy
1afd6d682a Devtest: Fix crash in player unittest (#9937)
Happened if player unittests run when player has exactly 3 HP
2020-05-26 19:49:02 +02:00
Wuzzy
083b285f43 Rename “Minimal development test” to “Development Test” (#9928) 2020-05-26 00:17:52 +02:00
Paramat
b546e8938d L-System trees: Remove hardcoded use of 'mapgen_dirt' alias (#9931)
Games often and increasingly do not use this mapgen alias, as it
is only required for Mapgen V6. Such games were triggering the
recently added error message.

Even if this mapgen alias was defined, dirt nodes placed under a
wide trunk were inconsistent with biomes that do not use dirt
surface nodes.

Place trunk nodes below a wide trunk instead of 'mapgen_dirt'.
On sloping ground, the trunk then extends down to the surface,
instead of the surface rising up to meet the trunk. This looks
more natural and does not alter the terrain.
2020-05-25 21:11:57 +01:00
SmallJoker
5311a27523 Silence GCC warning in mapblock_mesh
Fixes following warning:
  warning: ‘waving’ may be used uninitialized in this function [-Wmaybe-uninitialized]
2020-05-25 19:10:23 +02:00
rubenwardy
212a1123e0 Fix build on FreeBSD, broken since open_url 2020-05-24 15:31:06 +01:00
rubenwardy
b3c79906d4 Add engine version string to ContentDB API request (#9890) 2020-05-24 14:46:50 +01:00
Wuzzy
6456aba73f Replacement for Minimal Development Test (PR) (#9450) 2020-05-24 14:46:26 +01:00
SmallJoker
a9b74f4c39 Add chat_font_size setting (#9736)
Default font sizes are used when the setting value is 0 or below (clamped by Settings).
2020-05-24 14:24:13 +02:00
sfan5
f51cf7c68a Fix two bugs in content_cao
fixes #9889 (backface_culling with visual = "cube")
fixes #9916 (crash with visual = "upright_sprite")
2020-05-24 11:48:51 +02:00
sfan5
5430770b68 Fix constant re-queueing of emerges that will always be unsuccessful 2020-05-24 11:48:33 +02:00
sfan5
a9d6be8b6f Fix documentation of emergequeue_limit settings 2020-05-24 11:48:33 +02:00
ANAND
8ee2ece3c9 lua_api.txt: Fix minor typo (#9917) 2020-05-24 11:48:19 +02:00
sfan5
10c3002aea Optimize particlespawner sending by not sending to distant players 2020-05-23 22:52:21 +02:00
sfan5
9d6e7e48d6 Implement spawning particles with node texture appearance 2020-05-23 22:52:21 +02:00
sorcerykid
15ba75e4cf Add on_authplayer callback and 'last_login' to on_joinplayer (#9574)
Replace on_auth_fail callback with more versatile on_authplayer
    Better clarify account login process in Lua API documentation
    Change initial timestamp for newly registered accounts to -1
2020-05-23 13:25:29 +02:00
Awkor
037422fdba Modernize include guards and add missing ones (#9898) 2020-05-23 13:23:05 +02:00
Lejo1
e79bc40c0a Check for valid base64 before decoding (#9904) 2020-05-22 14:26:22 +02:00
SmallJoker
7ab0c0662a MacOS: Fix environ not being found 2020-05-22 14:24:55 +02:00
sfan5
1357ea1da2 Cleanup of particle & particlespawner structures and code (#9893) 2020-05-22 13:23:25 +02:00
Paramat
1bcdc2d7e9 Various documentation fixes in settingtypes.txt (#9910)
Fix incorrect value of 'mgv7_floatland_density'.
Use correct spelling of 'persistence'.
Move '3d_paralax_strength' into correct section (3D mode).
Refer to 'active_object_send_range_blocks' instead of non-existent 'active_object_range'.
2020-05-22 01:32:20 +01:00
Vitaliy
82e4137893 Cache liquid alternative IDs (#8053) 2020-05-20 22:52:10 +01:00
Paramat
42fcfb75e8 Allow more than 255 biomes, document new maximum (#9855)
Change biomemap data type from u8 to u16.
New technical (not practical) maximum is 65535 biomes.
2020-05-20 22:16:14 +01:00
sfan5
c47a680db7 Stop wasting memory on identical textures when texture filtering is disabled 2020-05-20 22:55:51 +02:00
sfan5
732c8008f4 CSM: Fix crashing minetest.get_item_def()
fixes #9884
2020-05-20 20:15:09 +02:00
Wuzzy
c94d37827d Rework functionality of leveled nodes (#9852)
Co-authored-by: sfan5 <sfan5@live.de>
Co-authored-by: SmallJoker <SmallJoker@users.noreply.github.com>
2020-05-19 21:08:37 +02:00
LoneWolfHT
7d3972a504 Add ability to scale HUD text (#9814)
Add 'size' property to HUD text elements that is used for relative font size calculations.
2020-05-19 19:10:39 +02:00
sfan5
0fc51db772 Add missing sao->isGone() checks
fixes #9883
2020-05-18 23:23:25 +02:00
sfan5
11723cffe0 builtin: Move common/async_event.lua to mainmenu/async_event.lua
It only works in the context of the mainmenu.
2020-05-17 21:37:01 +02:00
sfan5
52430d34d3 content_mapblock: Move static initialization out of functions 2020-05-17 21:37:01 +02:00
sfan5
be38a44ffe Client: Add sum and average to packetcounter 2020-05-17 21:37:01 +02:00
rubenwardy
a9c3a42323 Add core.open_url() to main menu API (#8592) 2020-05-17 19:09:10 +01:00
ANAND
c1ce4be756 Make automatic_rotate relative, allow setting rotation (#8468)
automatic_rotate does not make sense if it is absolute. Make it relative.

To avoid bouncing, set_rotation did not update the client when automatic_rotate was set. That's no longer necessary because the new spinning method applies the rotation on top of the current one, and the updates are necessary for set_rotation to actually transform the object.

Co-authored-by: ANAND <ClobberXD@gmail.com>

Co-authored-by: Pedro Gimeno <pgimeno@users.noreply.notabug.org>
2020-05-16 21:42:31 +02:00
Wuzzy
ab745685c7 Error msg if trying to teleport attached player (#9824) 2020-05-16 21:41:41 +02:00
sfan5
a08251a61e Log protocol ver on mismatched client connect too 2020-05-16 12:03:36 +02:00
Paramat
af0f7ac4a2 Add new Mapgen V7 floatland implementation (#9296)
Floatland structure is vertically-compressed 3D noise.
Uses a lacunarity of 1.618 (the golden ratio) for high quality
noise.
Floatlands appear between user-settable Y limits, with smooth
tapering at each limit.
Simple user-settable density adjustment.
Shadow propagation is disabled in and just below floatlands, no
shadows are cast on the world surface.
Can be reconfigured to create a solid upper world layer between
the Y limits, lakes/seas can be optionally added to this.
2020-05-14 22:27:54 +01:00
sfan5
d76785b4c7 network: Replace a fatal_error with just error logging 2020-05-14 21:18:26 +02:00
sfan5
36d35f2fe3 CSM: Bugfixes to camera:get_pos() and camera:get_fov()
closes #9857
2020-05-14 21:16:45 +02:00
TheTermos
6ef7ad09bb Collision detection - #9343 follow-up (#9764)
* truncate speed to prevent inf result

* code styling

* change truncate() input parameters
2020-05-14 19:28:27 +02:00
SmallJoker
836dd4a1e4 Add chat_log_level setting (#9223)
Log all higher levels in LogOutputBuffer
Move StreamLogOutput::logRaw to source file like LogOutputBuffer::logRaw for compiling speed
2020-05-14 19:26:15 +02:00
rubenwardy
2d7e000cfe Item Entity: Add message to moveresult assertion (#9797) 2020-05-14 17:54:17 +02:00
Yaman Qalieh
6c607e2082 Allow placing auto-rotating nodes on other nodes in on_rightclick (#9859) 2020-05-13 13:57:05 +02:00
Zughy
4e997e9d04 Document inf value in rollback commands (#9789) 2020-05-13 13:56:26 +02:00
Wuzzy
7ec76e530d Add mapgen settings to world creation dialog (#9254) 2020-05-12 02:52:52 +01:00
Lars Müller
9ba24f89f5 Damage texture modifier (#9833)
Adds a new object property "damage_texture_modifier"
2020-05-11 21:41:36 +02:00
Wuzzy
6e1372bd89 Add support for statbar “off state” icons (#9462)
This adds support for optional “off state” icons for statbars. “off state icons” can be used to denote the lack of something, like missing hearts or bubbles.

Add "off state" textures to the builtin statbars.

Co-authored-by: SmallJoker <mk939@ymail.com>
2020-05-11 21:40:45 +02:00
Hugo Locurcio
88bb8e57e6 Request the dedicated GPU when starting Minetest from the .desktop file (#9827)
See <https://www.hadess.net/2020/05/dual-gpu-support-launch-on-discrete-gpu.html>
for more information about this newly added `.desktop` entry property.
2020-05-10 13:37:30 +02:00
TheTermos
7cb53791c3 Color gradient for default and 'regular' type sky (#9502)
* add regular sky gradient

* add regular sky gradient

* Update sky.cpp

* change default day sky colors
2020-05-09 17:14:56 +02:00
Paul Ouellette
b6242498aa Always use same default tabheader height (#9319)
Previously the default tabheader height was different when using
real coordinates. This resulted in the height of tabs changing when
switching tabs in sfinv if some tabs used real coordinates.
2020-05-09 17:14:29 +02:00
Loïc Blot
454dbf83a9 Server class code cleanups (#9769)
* Server::overrideDayNightRatio doesn't require to return bool
There is no sense to sending null player, the caller should send a valid object

* Server::init: make private & cleanup
This function is always called before start() and loads some variables which can be loaded in constructor directly.
Make it private and call it directly in start

* Split Server inventory responsibility to a dedicated object

This splits permit to found various historical issues:
* duplicate lookups on player connection
* sending inventory to non related player when a player connects
* non friendly lookups on detached inventories ownership

This reduce the detached inventory complexity and also increased the
lookup performance in a quite interesting way for servers with thousands
of inventories.
2020-05-07 22:38:41 +02:00
sfan5
650168cada Fix Server triggering wrong errors if environment init fails 2020-05-07 22:02:22 +02:00
Jozef Behran
4f9ccd89b3 Get rid of non-ascii characters in the debug display code (#8821) 2020-05-06 21:35:18 +02:00
v-rob
664800b2ad FormSpec: Add universal style selector * (#9718) 2020-05-06 19:36:02 +02:00
Maksim
4f9a5f67ee Android: porting_android.cpp refactoring (#9687)
* Android: porting_android.cpp refactoring

* Replace assert to FATAL_ERROR_IF
2020-05-06 14:25:57 +02:00
sfan5
e8e5d282da Enable collide_with_objects for falling entities
falling nodes intentionally still fall through players
fixes #5313
2020-05-06 14:03:52 +02:00
sfan5
723926a995 Rewrite falling entity to make use of collision info
fixes #4781, fixes #9293
2020-05-06 14:03:52 +02:00
sfan5
b6b80f55c8 Expose collided objects in moveresult
closes #9787
2020-05-06 14:03:52 +02:00
sfan5
cb159f8d8a Fix crash when exiting server during running mapgen
easily reproducible with a high num_emerge_threads and /emergeblocks
2020-05-05 20:19:47 +02:00
sfan5
f3e87c53a5 Fix thread safety of PcgRandom use in BiomeGen 2020-05-05 19:26:59 +02:00
sfan5
ab06880525 Update num_emerge_threads description 2020-05-05 19:26:59 +02:00
sfan5
c28fbd06a8 Fix remaining issues with mapgen scriptapi 2020-05-05 19:26:59 +02:00
sfan5
3c65d1acec Give the Mapgen on each EmergeThread its own Biome/Ore/Deco/SchemManager copy 2020-05-05 19:26:59 +02:00
sfan5
2062c80e21 Allow ObjDefManager instances to be cloned 2020-05-05 19:26:59 +02:00
sfan5
d1c6cc72cc Server: Improve some log messages (#9820) 2020-05-05 17:05:11 +02:00
adrido
f34c62c47f Add MSVC build (#9740)
* Add MSVC build
2020-05-05 08:42:55 +02:00
Loïc Blot
f1a05d0f71 Fix broken client if openal cannot be opened (#9804) 2020-05-05 08:38:18 +02:00
SmallJoker
cad5b987ad Sky API: Rename *_tint to fog_*_tint for consistency 2020-05-05 08:37:04 +02:00
SmallJoker
1b6f40c356 Rename moveresult speed to velocity 2020-05-05 08:37:04 +02:00
oilboi
3ed5619d9a Fix small typo (#9813) 2020-05-05 08:35:55 +02:00
Maksim
373bad16c0 Android: some java-part improvements (#9760)
Replace Log to Toast.
Start Native only after successful unpacking.
Light refactoring in CopyZipTask.
Update NDK version.

Co-authored-by: ubulem <berkut87@gmail.com>
2020-05-04 08:47:00 +02:00
Wuzzy
66c182531c Change default keys for cam/minimap to C/V (#9779) 2020-05-04 08:45:31 +02:00
Hugues Ross
cb9a44ef89 Add 'content_offset' and 'padding' style properties for buttons (#9661)
* Add padding and content_offset style properties to buttons
2020-05-02 13:32:02 +02:00
Wuzzy
5c96f57782 Add a convention about z_index (#9701) 2020-05-02 13:12:02 +02:00
Lejo
808eb4c571 Auto delete MetaData when = 0 (#8770)
* Auto delete MetaData when = 0
2020-05-02 12:57:04 +02:00
sfan5
61d93988d8 ci: Update Github Actions workflows (#9774) 2020-05-02 12:52:51 +02:00
ANAND
e0ea87f1f3 set_fov: Add support for time-based transitions (#9705) 2020-05-02 12:52:11 +02:00
sfan5
ac368af4fe Allow connection info to be missing from minetest.get_player_information() (#9739)
fixes #9352
This reverts commit 23c907befe.
2020-05-01 21:44:28 +02:00
Lejo
74d9b6010f Give the online lua mainmenu also the client_list and mods (#8691) 2020-05-01 16:47:17 +02:00
Juozas
3f275d799c Fix gettext detection and locale building (#9772)
broken since a368e7e
2020-04-29 12:49:55 +02:00
Loic Blot
00323e8fce Add docker build stage on Github actions 2020-04-29 07:48:08 +02:00
Loic Blot
56bababcdf Add MetricsBackend with prometheus counter support 2020-04-29 07:48:08 +02:00
ANAND
a36c9c3e93 Fix breath_bar scaling; delay breath_bar hiding by one second (#8271)
PLAYER_MAX_BREATH_DEFAULT was earlier set to 11, so that 10 bubbles are shown before the breath bar disappears.

Now, PLAYER_MAX_BREATH_DEFAULT is set to 10, and the breath_bar scaling code in builtin has been tweaked to show all 10 bubbles before hiding the breath_bar
2020-04-28 19:30:57 +02:00
orbea
a368e7e793 cmake: Silence warnings. (#9750)
Fixes https://github.com/minetest/minetest/issues/9734
2020-04-28 16:34:18 +02:00
sfan5
b9377f26a1 Rewrite builtin item entity to use collision info
fixes #8967
2020-04-27 20:45:46 +02:00
sfan5
3475759d1a Expose collision information to LuaEntity on_step 2020-04-27 20:45:46 +02:00
k.h.lai
aef59f2ad9 Remove /LTCG from when compiling with clang-cl (#9765)
Remove /LTCG from CMAKE_EXE_LINKER_FLAGS_RELEASE when compiling with clang on Windows
2020-04-27 20:44:52 +02:00
sfan5
ca8957f500 Fix detection of in-place path_locale when RUN_IN_PLACE=0
broken by 2349d31bae (side effect)
fixes #9745
2020-04-27 17:50:05 +02:00
sfan5
13a8ea2dac Add STATIC_LOCALEDIR to BUILD_INFO and move it to version.cpp 2020-04-27 17:50:05 +02:00
Loïc Blot
91c4f7f0ea Forbid object:attach(obj, ...) (#9762)
Fixes #9761
2020-04-27 11:27:27 +02:00
SmallJoker
be71e70a91 Script: Enforce type checks if not nil (#9748)
* Script: Enforce type checks if not nil
2020-04-27 07:02:39 +02:00
sfan5
515d38a702 Fix truncation warning for F1000_MIN, F1000_MAX 2020-04-27 06:58:34 +02:00
sfan5
8a03097450 script: Put getGuiEngine() inside a client-only #ifdef 2020-04-27 06:58:34 +02:00
sfan5
d3f50f216f builtin: Correctly indicate failure in /spawnentity 2020-04-27 06:58:34 +02:00
sfan5
f6f6dd140f script: Fix add_entity returning unusable ref if object deleted in on_activate 2020-04-27 06:58:34 +02:00
Loïc Blot
e564bf8ead Add PostgreSQL authentication backend (#9756)
* Add PostgreSQL authentication backend
2020-04-27 06:54:48 +02:00
David Leal
2fe4641c1e Add new command /revokeme <priv> (#9584) 2020-04-26 21:15:05 +02:00
sfan5
68f45fc130 Remove unused lookup table from noise.cpp
closes #9757
2020-04-26 19:52:09 +02:00
sfan5
eca6ee911a Fix mapgen settings in minetest.conf being ignored (#9737)
broken since e8a8185d24
2020-04-26 19:32:29 +02:00
theviper121
e1fc72c6f3 Fix UpdateBonePosition() breaking animations (#9577) 2020-04-26 19:32:04 +02:00
v-rob
bc60e44d80 Add animated_image to clickthrough elements (#9724) 2020-04-25 16:55:21 +02:00
sfan5
8b45f6a5f3 Fix DPI scaling on Windows
the manifest appears to be very sensitive to changes
closes #9744
2020-04-25 14:00:11 +02:00
sfan5
73180a73da mapblock_mesh: Optimize a few things (#9713) 2020-04-25 12:39:17 +02:00
Paul Ouellette
49ed0ca00a Ensure game is shutdown if server throws exception (#9742) 2020-04-25 09:42:18 +02:00
Pierre-Yves Rollo
6cc5c7cbb4 Simplify how parseElement splits element string (#9726) 2020-04-25 07:48:04 +02:00
EvidenceB Kidscode
cee3c5e73d Add server side translations capability (#9733)
* Add server side translations capability
2020-04-25 07:20:00 +02:00
luk3yx
914dbeaa0b Add LevelDB auth database. (#9476)
* Add leveldb auth database.
2020-04-23 13:07:19 +02:00
SmallJoker
ce5b0932f8 Camera: Fix shootline line offsets II (#9730) 2020-04-23 12:16:36 +02:00
Maksim
6ba44d7452 Android: add OpenGL ES 2 support (#9715)
.. and bump gradle to 3.6.3
2020-04-22 20:03:46 +02:00
HybridDog
5355cb1d87 minetest.serialize: Reversible number serialization (#9722)
* minetest.serialize: Reversible number to string conversion

The %a format is not supported in Lua 5.1.
This commit also adds two tests for number serialization.
2020-04-22 16:43:48 +02:00
HybridDog
4361bfcb4d Fix configuration caching in log_deprecated (#9697)
* Fix configuration caching in log_deprecated

The configured variable was never set to true.
I've set the variables to thread_local because the configuration should be reloaded after reentering the world from mainmenu.
2020-04-22 00:07:12 +02:00
sfan5
8ef239b448 Improve protocol-level receiving code (#9617) 2020-04-20 23:22:00 +02:00
Loïc Blot
c2ac7b1a83 Fix build badge since switching to github actions 2020-04-20 20:22:23 +02:00
Loïc Blot
27a485a472 Replace travis with github actions (#9641)
* Move outside of travis to Github actions

This will permit to have better integrated CI workflow than the previous
travis one.
2020-04-20 20:18:40 +02:00
sfan5
338195ff25 Fix alias handling of get_content_id (#9712)
fixes #9632
2020-04-19 19:07:54 +02:00
Danila Shutov
cdbe3c5e57 Reuse object_shader for "wielditem" and "item" entity drawtypes (#9537) 2020-04-19 18:47:13 +02:00
SmallJoker
c87d52a5fa Shaders: Complete 478e753. OpenGL 4.3 compatiblity 2020-04-18 18:36:47 +02:00
sfan5
87829cd744 script: Move SAO usability check so that it covers all functions (#9698)
see also 91eef646a5
2020-04-18 17:21:58 +02:00
DS
4fb6b6afa7 Formspec: allow lists to change size and existence while the formspec is open (#9700)
Fixes #9640.
2020-04-18 17:21:10 +02:00
DS
241bf44260 Apply a scrollbar's default value to scroll containers (#9699)
Fixes #9691.
2020-04-18 17:20:20 +02:00
HybridDog
7b57d3f613 serverpackethandler: Reduce pkt->getPeerId() invocations and more (#9689) 2020-04-18 17:19:53 +02:00
Maksim
23c6d0c31f Android: fix handling non-latin characters on older Android devices (#9309) 2020-04-17 23:46:30 +02:00
Paramat
4e2473ec49 Document which noise APIs add world seed to noiseparams seed (#9693) 2020-04-17 10:24:51 +02:00
Wuzzy
e88719bcdd Rename "subgame" to "game" in 2 error messages (#9680) 2020-04-17 08:10:28 +02:00
Loïc Blot
7539267d37 Add an option to disable unittest build, & disable them on Docker build (#9677) 2020-04-16 20:43:49 +02:00
Loïc Blot
093e79ea78 Drop -Wabi useless flag (#9676) 2020-04-16 19:21:47 +02:00
Maksim
57038b3cb4 Android: fix formspec input for AArch64 devices (#9685) 2020-04-16 19:19:47 +02:00
SmallJoker
45999b74e6 Camera: Fix shooting line offsets (#9681)
Removes duplicated offset calculations from Game and use whatever the Camera class returns.
This keeps the eye position nicely in sync, and gets rid of duplicated code.
2020-04-16 18:32:07 +02:00
sfan5
5cbe8437a8 Swap out -ffast-math for a safe subset of optimization flags (#9682)
It caused more trouble than its worth.
fixes #3943, fixes #5330
2020-04-16 10:23:48 +02:00
Loïc Blot
e8ac5a31cf Optimize get_objects_inside_radius calls (#9671)
* Optimize getObjectsInsideRadius calls

our previous implementation calls the ActiveObjectMgr to return ids and then lookup those ids in the same map and test each object
Instead now we call the global map to return the pointers directly and we ask filtering when building the list using lamba.

This drop double looping over ranges of active objects (and then filtered one) and drop x lookups on the map regarding the first call results
2020-04-16 08:25:48 +02:00
Maksim
62ae7adab2 Android: add Android Studio support, completely redone java part (#9066) 2020-04-15 16:27:40 +02:00
sfan5
8ae8c1600a Fix parsing JSON with large integers (#9674) 2020-04-15 08:01:28 +02:00
Loïc Blot
5c588f89e7 Verify database connection on interval (#9665) 2020-04-15 08:01:11 +02:00
DS
62c62f3829 Add all src folders to doxygen (#9603) 2020-04-14 21:22:49 +02:00
sfan5
032d90b9f6 Update wireshark dissector (#9621) 2020-04-14 21:22:19 +02:00
sfan5
2d5bd3bf79 scriptapi: Some small optimizations to value pushing (#9669) 2020-04-14 20:44:18 +02:00
SmallJoker
7c43cf47c3 PostgreSQL: Fix listAllLoadableBlocks returning the same block
Suggested change from https://github.com/minetest/minetest/issues/9670#issuecomment-613563738
2020-04-14 20:42:40 +02:00
Hugues Ross
5cf6318117 Refactor texture overrides and add new features (#9600)
* Refactor texture overrides, and add new features:

- Texture overrides can support multiple targets in one line
- Texture override files can have comment lines
- Item images/wield images can be overridden

* Formatting changes

* Address soime feedback

- Pass vectors by const reference
- Log syntax errors as warnings
- Remove 'C' prefix from TextureOverrideSource

* Simplify override target checks with an inline helper function

* make linter happy

* Apply feedback suggestions

Co-Authored-By: rubenwardy <rw@rubenwardy.com>

* Remove remaining != 0 checks

* Update copyright notice

Co-authored-by: sfan5 <sfan5@live.de>
Co-authored-by: rubenwardy <rw@rubenwardy.com>
2020-04-14 20:41:29 +02:00
Wuzzy
7e21b3cd48 Remove sound menu and show proper msgs if sound is off (#9069) 2020-04-13 20:26:54 +02:00
SmallJoker
27d611fe55 Add default stack size setting (#8873)
New setting "default_stack_max" to alter the default stack sizes of all items when desired.

Co-authored-by: Pascal Abresch <nep@packageloss.eu>
2020-04-13 10:53:10 +02:00
DS
0ac999ded7 Add scroll_container formspec element (redo) (#9101)
New formspec elements:

 - `scroll_container[<X>,<Y>;<W>,<H>;<scrollbar name>;<orientation>;<scroll factor>]`
 - `scroll_container_end[]`

Other elements can be embedded in this element. Scrollbar must be placed manually.
2020-04-13 10:50:07 +02:00
SmallJoker
6cf15cf872 GUIFormSpecMenu: Add basic element highlighing debug feature (#9423)
Activated using F5
2020-04-12 12:02:32 +02:00
ㄗㄠˋ ㄑㄧˊ
d7e706ac9d Dockerfile: use alpine to reduce size (#9226)
* Dockerfile: use alpine to reduce size

* Fix the UID & GID + alpine version + rights

* Reduce the junk when we copy, only copy needed files

* Build in the right cmake place & permit customize mtg version

* Latest build fixes

Co-authored-by: Loïc Blot <nerzhul@users.noreply.github.com>
2020-04-12 11:00:56 +02:00
Testman
b55dd5d82f Update README copyright to current year (#9566) 2020-04-12 01:53:23 +02:00
Wuzzy
a24d3b3600 Play 'player_jump' when player jumps (#9373) 2020-04-12 00:50:40 +01:00
rubenwardy
3833396cfa Fix delayed error message in start game tab 2020-04-12 00:12:18 +01:00
Lars Müller
af2e6a6a10 Improve waypoints and add image variant (#9480) 2020-04-11 22:09:46 +01:00
Hugues Ross
f780bae05c Formspecs: Add state-selection to style elements (#9378) 2020-04-11 21:39:30 +01:00
sfan5
ba3587e776 Fix broken config check in 659245a 2020-04-11 21:29:57 +02:00
Paul Ouellette
840b17ce63 Update API site build (#9622) 2020-04-11 20:38:39 +02:00
sfan5
40df3931d8 Implement DPI scaling for Windows (#9586) 2020-04-11 20:03:59 +02:00
Loïc Blot
5cc06e4748 Reduce ServerEnvironment propagation (#9642)
ServerEnvironment is a huge class with many accessors. In various places it's not needed

Remove it to reduce the ServerEnvironment view.

Idea here is to reduce size of some of our objects to transport lightweight managers and permit easier testing

Pathfinder is now tied to a generic map, not a ServerMap, it can be
ported to client
2020-04-11 19:59:43 +02:00
Loic Blot
5146086a64 Drop content_sao.{cpp,h}
Move LuaEntitySAO to a new dedicated file
Drop TestSAO (useless object)
Drop the old static startup initialized SAO factory, which was pretty useless.
This factory was using a std::map for 2 elements, now just use a simple condition owned by ServerEnvironment, which will be lightweight, that will also drop a one time useful test on each LuaEntitySAO creation. This should reduce server load on massive SAO creation
2020-04-11 16:07:17 +02:00
Loic Blot
894a34aef4 Move PlayerSAO to dedicated files 2020-04-11 16:07:17 +02:00
Loic Blot
c99e8df07f pass clang-format 2020-04-11 16:07:17 +02:00
Loic Blot
2a7267febf Add vscode cmake plugin files to gitignore 2020-04-11 16:07:17 +02:00
Loic Blot
6d43736172 Move serveractiveobject & unitsao
Move serverobject.{cpp,h} to server/serveractiveobject.{cpp,h}
Move UnitSAO class to dedicated files
2020-04-11 16:07:17 +02:00
SmallJoker
01b3f26c7b Formspec: No spec ID for static text labels
Fixes #9634
2020-04-11 15:31:02 +02:00
Alex
fbf74dc524 Use TILE_MATERIAL_ALPHA for use_texture_alpha entity flag (#9639)
Fixes #9637.
2020-04-11 13:45:14 +02:00
sfan5
1292bdbbce Various features and fixes 2020-04-11 13:12:51 +02:00
sfan5
5f3a17eb65 Implement minetest.sound_fade() 2020-04-11 13:12:51 +02:00
sfan5
054c5dfaa3 scriptapi: Sort out ServerEnvironment / Environment distinction properly
The API implementation is shared between CSM and SSM.
Functions should retrieve a plain env when they do not
need any server-specific functions.
2020-04-11 13:12:51 +02:00
sfan5
f105bc8dc2 A few initialization cleanups 2020-04-11 13:12:51 +02:00
Wuzzy
aa3cf400e2 Print error if invalid mapgen alias was detected (#9579) 2020-04-10 20:36:16 +02:00
Loïc Blot
35e778ee9f Move clientsimpleobject.h to client folder (#9630)
This file is only called from client folder, retrieve its friends :)
2020-04-10 20:10:51 +02:00
Loïc Blot
f648fb76ae Drop genericobject.{cpp,h} (#9629)
* Drop genericobject.{cpp,h}

This file is not for generic object but for ActiveObject message passing.
Put ownership of the various commands to the right objects and cleanup the related code.

* Protect ServerActiveObject::m_messages_out

* typo fix
2020-04-10 19:49:20 +02:00
Hugo Locurcio
2349d31bae Install the locale directory in a standard location without subfolder (#9618)
Other established FOSS projects don't seem to be doing this.
2020-04-10 16:08:48 +02:00
Loïc Blot
12275e235a Automated build changes (#9619)
* Automated build changes
* drop a useless ubuntu non lts version
* update gitlab ci syntax to modern one
* add debian 10 step on the gitlab ci pipeline
* switch docker build to Debian 10
* add .gradle folder to gitignore
2020-04-09 20:46:06 +02:00
TheTermos
3ad5388c6d Collision various fixes (#9343) 2020-04-08 22:45:05 +02:00
DS
c1742b0901 Allow to select en as language in settings menu (#9604)
fixes #9599
2020-04-08 22:44:52 +02:00
sfan5
d6ad587ab8 Travis: Build clang jobs with LuaJIT enabled for better coverage 2020-04-08 21:21:53 +02:00
sfan5
659245acc7 Work around LuaJIT issues on aarch64 (#9614)
- Move the text segment below the 47-bit limit, needed for script_exception_wrapper which must be lightuserdata
- Replace CUSTOM_RIDX_SCRIPTAPI with full userdata
2020-04-08 20:14:08 +02:00
sfan5
de73f989eb Overall improvements to log messages (#9598)
Hide some unnecessarily verbose ones behind --trace or disable them entirely.
Remove duplicate ones. Improve their contents in some places.
2020-04-08 20:13:23 +02:00
sfan5
3494475df1 Miscellaneous networking improvements (#9611)
fixes #2862
2020-04-08 20:12:58 +02:00
rubenwardy
143a37e947 Clarify use of minetest.request_insecure_environment() (#9597) 2020-04-06 16:54:27 +02:00
Hugo Locurcio
f45ba78a72 Allow relative directories for screenshot_path, tweak default path (#9122)
This will likely be more intuitive for users and should play better
with sandboxed distributions such as Flatpak.

In addition, the screenshot directory will now be created if it doesn't
exist already.
2020-04-06 16:54:12 +02:00
Danila Shutov
661b4a1837 Add tone mapping for entities (#9521)
fixes #9301
2020-04-06 16:06:40 +02:00
Wren Turkal
f91124a0c0 Add allowed_mapgens option in game.conf. (#9263)
The game.conf has a disallowed_mapgens option. However, some games
require a certain mapgen to be used, like the CTF plugin. This change
adds an option to specify allowed mapgens so that the setting can be
specified in a way that needn't be updated as map generators are added
to Minetest.
2020-04-06 16:06:16 +02:00
Wuzzy
faedde08f9 Some minor Lua API documentation clarifications (#9461)
See #5854
2020-04-06 16:05:27 +02:00
sfan5
528b162d9f Continue with 5.3.0-dev 2020-04-05 18:31:52 +02:00
sfan5
24147d99c0 Bump version to 5.2.0 2020-04-05 18:31:50 +02:00
rubenwardy
09b8f5d1be Update credits for 5.2.0 (#9593) 2020-04-05 18:30:44 +02:00
BreadW
40dccc0f54 Translated using Weblate (Japanese)
Currently translated at 100.0% (1288 of 1288 strings)
2020-04-05 17:27:48 +02:00
sfan5
7aec5f43be Translated using Weblate (German)
Currently translated at 100.0% (1288 of 1288 strings)
2020-04-05 17:27:48 +02:00
Oğuz Ersen
e6e1c1281d Translated using Weblate (Turkish)
Currently translated at 100.0% (1288 of 1288 strings)
2020-04-05 17:25:55 +02:00
Pierre-Yves Rollo
0eb3072819 Hypertext: Fix hovercolor not working in global tag (#9582) 2020-04-05 15:04:41 +02:00
sfan5
ea30b89d3f Builtin: Make item entities glow less (#9594)
minor adjustment to #9200
2020-04-04 21:27:30 +02:00
SmallJoker
d5c4412536 Revert collision tweaks #9365 and #9327 (#9591)
This reverts commit df74d369a3.
This reverts commit 908e762479.

Restores the original collision detection bugs to release 5.2.0 prior the large collision detection fix.
2020-04-04 21:27:23 +02:00
Pierre-Yves Rollo
86a0e991ef Fix cursor still visible after closing formspec while on HyperText (#9583) 2020-04-04 16:17:15 +02:00
LNJ
307d7376cf Fix 'the the' typos in comments (#9554) 2020-04-04 15:52:41 +02:00
sfan5
b8d29ab0af Fix failing build due to translation file error 2020-04-04 00:16:18 +02:00
sfan5
fe21aa1f4a Utility script to help with Weblate commit import 2020-04-03 23:26:07 +02:00
updatepo.sh
b6d2c34a15 Update translation files 2020-04-03 23:19:54 +02:00
updatepo.sh
6940e5a191 Update minetest.conf.example, settings_translation_file.cpp 2020-04-03 23:19:36 +02:00
Allan Nordhøy
65884816be Translated using Weblate (Indonesian)
Currently translated at 92.0% (1185 of 1288 strings)
2020-04-03 23:15:52 +02:00
sfan5
e223d7cf57 Translated using Weblate (Hungarian)
Currently translated at 59.6% (768 of 1288 strings)
2020-04-03 23:15:52 +02:00
Allan Nordhøy
11f4525865 Translated using Weblate (French)
Currently translated at 96.0% (1237 of 1288 strings)
2020-04-03 23:15:52 +02:00
THANOS SIOURDAKIS
965e2028de Translated using Weblate (Greek)
Currently translated at 1.7% (22 of 1288 strings)
2020-04-03 23:15:52 +02:00
Tiller Luna
be0200b215 Translated using Weblate (Russian)
Currently translated at 94.4% (1217 of 1288 strings)
2020-04-03 23:15:52 +02:00
anonymous
96696cd1c0 Translated using Weblate (Russian)
Currently translated at 94.6% (1219 of 1288 strings)
2020-04-03 23:15:52 +02:00
sfan5
82a08213f0 Translated using Weblate (Norwegian Nynorsk)
Currently translated at 30.9% (398 of 1288 strings)
2020-04-03 23:15:52 +02:00
sfan5
19b8f12e79 Translated using Weblate (Swedish)
Currently translated at 32.1% (414 of 1288 strings)
2020-04-03 23:15:52 +02:00
sfan5
665b90a3c4 Translated using Weblate (Esperanto)
Currently translated at 99.3% (1279 of 1288 strings)
2020-04-03 23:15:52 +02:00
sfan5
c08ced0928 Translated using Weblate (Ukrainian)
Currently translated at 41.3% (533 of 1288 strings)
2020-04-03 23:15:52 +02:00
ssantos
c71e54fa6d Translated using Weblate (Portuguese)
Currently translated at 95.8% (1234 of 1288 strings)
2020-04-03 23:15:52 +02:00
sfan5
391432eb9e Translated using Weblate (Polish)
Currently translated at 77.0% (992 of 1288 strings)
2020-04-03 23:15:52 +02:00
Liet Kynes
39c4df6b80 Translated using Weblate (Norwegian Bokmål)
Currently translated at 60.0% (774 of 1288 strings)
2020-04-03 23:15:52 +02:00
Allan Nordhøy
ad2e2d3f08 Translated using Weblate (Norwegian Bokmål)
Currently translated at 60.0% (774 of 1288 strings)
2020-04-03 23:15:52 +02:00
sfan5
9003ddb8d6 Translated using Weblate (Danish)
Currently translated at 47.8% (616 of 1288 strings)
2020-04-03 23:15:52 +02:00
Liet Kynes
7ea3dfd290 Translated using Weblate (Norwegian Bokmål)
Currently translated at 54.0% (696 of 1288 strings)
2020-04-03 23:15:52 +02:00
anonymous
0a1725d345 Translated using Weblate (Norwegian Bokmål)
Currently translated at 42.7% (551 of 1288 strings)
2020-04-03 23:15:52 +02:00
Liet Kynes
9ae2b7c8a6 Translated using Weblate (Norwegian Bokmål)
Currently translated at 42.7% (551 of 1288 strings)
2020-04-03 23:15:52 +02:00
Tirifto
cee3a3fd63 Translated using Weblate (Esperanto)
Currently translated at 99.3% (1279 of 1288 strings)
2020-04-03 23:15:52 +02:00
Gmail a - 2 - a Boxa
50b30de407 Translated using Weblate (Romanian)
Currently translated at 18.6% (240 of 1288 strings)
2020-04-03 23:15:52 +02:00
wzy2006
bfe91e0b8f Translated using Weblate (Chinese (Simplified))
Currently translated at 88.0% (1134 of 1288 strings)
2020-04-03 23:15:52 +02:00
Robin Townsend
a5ec71f758 Translated using Weblate (Lojban)
Currently translated at 12.7% (164 of 1288 strings)
2020-04-03 23:15:52 +02:00
Robin Townsend
6831836d0d Translated using Weblate (German)
Currently translated at 100.0% (1288 of 1288 strings)
2020-04-03 23:15:52 +02:00
Gao Tiesuan
316f1e028d Translated using Weblate (Chinese (Simplified))
Currently translated at 86.8% (1118 of 1288 strings)
2020-04-03 23:15:52 +02:00
Lucas Burlingham
02fd884d04 Translated using Weblate (French)
Currently translated at 93.5% (1205 of 1288 strings)
2020-04-03 23:15:52 +02:00
abidin toumi
facce8b966 Translated using Weblate (Arabic)
Currently translated at 6.9% (89 of 1288 strings)
2020-04-03 23:15:52 +02:00
Ács Zoltán
ad2de3ad95 Translated using Weblate (Hungarian)
Currently translated at 59.5% (767 of 1288 strings)
2020-04-03 23:15:52 +02:00
Gao Tiesuan
214d99a4d0 Translated using Weblate (Esperanto)
Currently translated at 92.5% (1192 of 1288 strings)
2020-04-03 23:15:52 +02:00
Vojtěch Šamla
0ed27ffd37 Translated using Weblate (Czech)
Currently translated at 48.3% (623 of 1288 strings)
2020-04-03 23:15:52 +02:00
An0n3m0us
fa9278963b Translated using Weblate (Arabic)
Currently translated at 6.1% (79 of 1288 strings)
2020-04-03 23:15:52 +02:00
An0n3m0us
548efbf16f Translated using Weblate (Lithuanian)
Currently translated at 15.2% (196 of 1288 strings)
2020-04-03 23:15:52 +02:00
Hugo Locurcio
668d834583 Translated using Weblate (French)
Currently translated at 92.3% (1189 of 1288 strings)
2020-04-03 23:15:52 +02:00
JDiaz
811acbc8fd Translated using Weblate (Spanish)
Currently translated at 67.9% (875 of 1288 strings)
2020-04-03 23:15:52 +02:00
Muhammad Nur Hidayat Yasuyoshi
4d3e2f8d69 Translated using Weblate (Malay)
Currently translated at 100.0% (1288 of 1288 strings)
2020-04-03 23:15:52 +02:00
An0n3m0us
2a1ad6a903 Translated using Weblate (Hungarian)
Currently translated at 59.7% (769 of 1288 strings)
2020-04-03 23:15:52 +02:00
universales
e94ba07a69 Translated using Weblate (Spanish)
Currently translated at 67.7% (872 of 1288 strings)
2020-04-03 23:15:51 +02:00
pan93412
2de515f311 Translated using Weblate (Chinese (Traditional))
Currently translated at 68.9% (888 of 1288 strings)
2020-04-03 23:15:51 +02:00
monolifed
2048377c78 Translated using Weblate (Turkish)
Currently translated at 100.0% (1288 of 1288 strings)
2020-04-03 23:15:51 +02:00
BreadW
af076ba747 Translated using Weblate (Japanese)
Currently translated at 100.0% (1288 of 1288 strings)
2020-04-03 23:15:51 +02:00
Wuzzy
f055e9bdc3 Translated using Weblate (German)
Currently translated at 100.0% (1288 of 1288 strings)
2020-04-03 23:15:51 +02:00
Paramat
45a2ca0af2 Add warning to set_sky() docs about unstable dawn and night sky colours (#9578)
Also clean up confusing double meaning usage of the word 'skybox'.
2020-04-03 02:57:15 +01:00
Elias Åström
3d6b55d3e9 Fix texture distortion for flowing liquids (#9561)
Previously textures of the side faces on flowing liquid nodes would
become distorted on different axis depending on the liquid level.  This
is because the nodes always had the same texture coordinates, even when
the generated face could have different sizes.  This solves that problem
by adjusting the texture coordinates for the vertices making up the top
of the faces, so the textures will not look compressed for smaller
faces.
2020-04-02 19:24:35 +02:00
DS
d7825bca1b Fix GUI element click-through by changing visibility (#9534)
This adds a vector that holds pointers to elements that should only be visible while being drawn.

In the guifsmenu's draw func, all elements in this vector are made visible and invisible again. Apart from there, they are always invisible. (Well they are still visible before the first drawn, does this matter? If yes, it could be fixed easily with some lines of code everywhere.)
2020-03-31 18:34:42 +01:00
v-rob
9953145a4e Formspec: Mark hypertext and markup language as unstable 2020-03-28 21:54:19 +01:00
ANAND
13b228513e Ignore near_plane setting on non-Android platforms (#8749)
Camera's near-plane will be hard-coded to 0.1 on all non-Android platforms. The upper-bound of this setting has been reduced to 0.25, as 0.5 is just way too high.
2020-03-28 21:53:55 +01:00
sfan5
c6d6358b92 Travis: Correct Linux dependencies so that PostgreSQL is found by CMake 2020-03-28 13:04:15 +01:00
sfan5
04961491c1 Fix crash on wielditem/item entities
bug was introduced in f3032a637c
2020-03-28 12:56:48 +01:00
sfan5
3c0d309643 Improve documentation of minetest.get_node_drops()
Also remove the comment saying it could be removed or modified.
2020-03-26 20:35:05 +01:00
Pierre-Yves Rollo
49a558574f Hypertext: Fix alignment tags adding unwanted newlines (#9548) 2020-03-26 19:56:35 +01:00
SmallJoker
a0998754a7 Connection: Fix deadlock in debug mode (#9550) 2020-03-26 19:13:50 +01:00
Dave Chu
f7c7353a9a Fix small typos in lua_api.txt (#9546) 2020-03-25 11:44:20 +01:00
Danila Shutov
f3032a637c Fix incorrect light updates for wielditem and item visuals (#9540)
An alternative to #9537
2020-03-23 21:57:44 +01:00
Wuzzy
625b100593 Add comments for translators (#9510)
* Add translator comments for "special" strings

* Add translator comments for some "tricky" strings
2020-03-20 09:41:07 +01:00
Danila Shutov
5c1b72544a Fix entity lighting (#9514)
fixes #9482
2020-03-16 22:58:13 +01:00
Danila Shutov
ca646487f2 Transform texture UVs with provided tex. matrix (#9515)
fixes #9481
2020-03-16 22:57:46 +01:00
sfan5
5a31d56c9f Fix mouse events sent to wrong GUI elements when dragging 2020-03-16 22:57:10 +01:00
v-rob
13ad8e2a09 Formspecs: Add starting frame to animated_image (#9411) 2020-03-16 22:56:48 +01:00
Wuzzy
1441281809 Fix some chatcommands not returning a value (#9503) 2020-03-14 15:01:22 +01:00
sfan5
8546d6089a Update clang-tidy configuration and scripts 2020-03-12 00:10:09 +01:00
sfan5
7908b20dd9 buildbot: Update to newer MinGW gcc 9.2 2020-03-12 00:10:09 +01:00
sfan5
245876cddb Update travis build infrastructure
Ubuntu 14.04 -> 18.04
clang-format, clang-tidy 7 -> 8
clang 3.6 -> 3.9
clang 7 -> 9
2020-03-12 00:10:09 +01:00
SmallJoker
766d160ffb guiHyperText: Fix blinky cursor on link hover (#9392)
Change legacy size/position calculations to 'textarea'
2020-03-11 19:09:50 +01:00
HybridDog
fd4daefb29 minetest.get_content_id: error if the node does not exist (#9458)
If a mod creator makes a typing mistake, this function now causes an error instead of returning the id of "ignore".
2020-03-11 16:25:14 +01:00
DS
b42493fb4c Fix memory leak in GUIHyperText (#9489) 2020-03-10 20:32:38 +01:00
sfan5
7a7bfdca7c minetest,get_connected_players: Return empty table at load time (#9493) 2020-03-10 20:32:04 +01:00
SmallJoker
7da4f9ef20 GUIFormSpecMenu: Remove field_close_on_enter warning (#9501) 2020-03-10 20:30:55 +01:00
Nicolas Abril
30d795b4b2 Remove unnecessary checks before delete (#9500)
Co-authored-by: Nicolas Abril <nicolasabril@alunos.utfpr.edu.br>
2020-03-10 20:30:42 +01:00
Maksim
0cb34ce158 Fix 2 log messages when player joined to game (#9477) 2020-03-08 18:24:32 +01:00
Jean-Patrick Guerrero
c49575ef97 Improve arm physics (#9485) 2020-03-08 18:21:55 +01:00
Jordan Snelling
b9a0626d88 Fix star visilibity and documentation (since 946c03c6)
Fix memory leak (unused allocation)
Fix star rendering
Rename sky color struct
Fix stars on android
Remove extraneous .data() from android star draw
2020-03-08 16:13:36 +01:00
SmallJoker
23c907befe Workaround for get_player_information
'-1' as value is handled as an error. If there are no RTT updates upon fast connect, set_player_information returned nil.
2020-03-08 13:21:15 +01:00
Jean-Patrick Guerrero
0e88176db8 GUIHyperText: Fix bug with UTF8 chars in action name + simplify UTF8 stringw conversion (#9437)
Co-authored-by: Pierre-Yves Rollo <dev@pyrollo.com>
2020-03-07 14:01:11 +01:00
Wuzzy
ce8cdc0333 Cleanup global namespace pollution in builtin (#9451) 2020-03-06 20:19:14 +00:00
sfan5
9ca0b3739c Fix memory leak in protocol 38 set_sky 2020-03-05 22:36:21 +01:00
sfan5
db95ff2286 Fix linking failures when compiled with Clang 9 2020-03-05 22:05:18 +01:00
sfan5
e774d8ca2f Fixes around ServerActiveObject on_punch handling 2020-03-05 22:04:23 +01:00
sfan5
8d6a0b917c Fix potential security issue(s), documentation on minetest.deserialize() (#9369)
Also adds an unittest
2020-03-05 22:03:04 +01:00
sfan5
ef09e8a4d6 Fix code style to make clang-format happy 2020-03-05 20:55:29 +01:00
Jordach
946c03c69b set_sky improvements, set_sun, set_moon and set_stars 2020-03-05 20:12:19 +01:00
Wuzzy
580e7e8eb9 Fix pathfinder bugs: returning nil frequently, broken A*, jump through solid nodes (#9339)
* Fix pathfinder fail when startpos is over air
* Note down pathfinder restrictions
* Implement real A* search
* Pathfinder: Implement buildPath non-recursively
* Update find_path documentation
* Pathfinder: Check if jump path is unobstructed
* Pathfinder: Fix drop check first checking upwards
* Pathfinder: Return nil if source or dest are solid
* Pathfinder: Use priority queue for open list
2020-03-05 12:09:44 +01:00
sfan5
6d8e2d2483 Fix core.get_player_by_name() returning unusable ObjectRef
Followup to the previous commit.
2020-03-03 21:21:41 +01:00
sfan5
1761d7d0f8 Fix core.get_connected_players() returning unusable ObjectRefs
This bug is only exposed by 91eef646a5
independent of the move of get_connected_players from Lua to C++.
Previously, there would be a small time window where the SAO had
its peer ID set to PEER_ID_INEXISTENT but the RemotePlayer was
still linked to the SAO, resulting in an ObjectRef that crashed
on certain function calls (#9387).
2020-03-03 21:21:41 +01:00
v-rob
7dffd08c1a Add multiple element selection to style and style_type (#9380) 2020-03-01 14:39:57 +00:00
DS
0c08f948d7 GUIInventoryList: fix dropping items when clicking outside of formspec window (#9422) 2020-02-26 12:18:05 +01:00
Warr1024
244121b964 Allow texture modifiers in hotbar textures. (#9271) 2020-02-26 10:26:24 +01:00
Gao Tiesuan
8ddb6718e3 Fix incorrect spelling in lua_api.txt (#9431) 2020-02-26 02:27:54 +00:00
sfan5
e2fc93022b Fix potential problem with core.get_connected_players() 2020-02-25 16:08:47 +01:00
sfan5
6be7150cd5 Documementation: Add advice on lifetime of ObjectRefs 2020-02-23 22:24:12 +01:00
sfan5
217f3a42f4 Documentation: More precise description of ObjectRef:remove() 2020-02-23 22:24:12 +01:00
sfan5
2bb7d3aa99 Profiler: Fix wrong function name for entities 2020-02-23 22:24:12 +01:00
sfan5
0b8d3f99a5 Move core.get_connected_players() implementation to C++
Keeping the ObjectRefs around in a table isn't ideal and this allows
removing the somewhat nonsensical is_player_connected() added in 86ef7147.
2020-02-23 22:24:12 +01:00
sfan5
c657fb343f Refactor Script API's log_deprecated 2020-02-23 22:24:12 +01:00
sfan5
4da057cc49 Script API: Document ObjectRef handling in a comment 2020-02-23 22:24:12 +01:00
Paramat
2df226bb41 Lua_api.txt: Add documentation of VoxelArea 'ystride', 'zstride' (#9415) 2020-02-22 01:11:33 +00:00
Wuzzy
d507047443 Falling nodes: Add support for facedir, colorfacedir, wallmounted, colorwallmounted, color, airlike, signlike, torchlike and glow (#9205) 2020-02-22 01:10:17 +00:00
SmallJoker
e8a8185d24 Settings: Fix game minetest.conf flags overriding defaults (#9404)
The game minetest.conf flags directly overwrote the global minetest.conf default values, resulting in unwanted erased mapgen flags.

* Fix set_mapgen_setting
2020-02-17 19:26:32 +01:00
Danila Shutov
6958071f49 Basic model shading (#9374) 2020-02-16 20:37:28 +01:00
SmallJoker
478e753298 Shaders: Fix OpenGL < 4.3 compatibility 2020-02-16 14:14:34 +01:00
SmallJoker
3f675490df Builtin: Fix error by digging unknown nodes 2020-02-16 14:13:52 +01:00
Hugues Ross
7ce21788f8 Add animated_image[] formspec element (#9258) 2020-02-15 15:33:18 +00:00
SmallJoker
ee7d357602 Key settings: Clear with escape (#8282)
Key ESCAPE -> Cancel change
Key DELETE -> Remove entry
2020-02-14 20:36:58 +01:00
Maksim
71899e11d2 Update embedded mini-gmp to version 6.2.0 (#9396) 2020-02-14 20:36:41 +01:00
Wuzzy
ff769e7df5 Add missing paramtype2 documentation (#9397) 2020-02-13 23:27:20 +01:00
Wuzzy
ac5f53e364 Fix param2 set to 240 if liquid source was renewed 2020-02-13 20:38:13 +01:00
TheTermos
df74d369a3 Collision detection tweak #2 (#9365) 2020-02-13 20:13:07 +01:00
Paramat
c2f48eab4d Display an error when a noise parameter has too many octaves (#9394)
Display an error and throw exception when one or more octaves of
a noise has spread < 1, causing random looking broken noise.
2020-02-12 23:15:07 +00:00
sfan5
2d5e0ce5ba Update some libraries for buildbot 2020-02-12 22:25:36 +01:00
sfan5
91eef646a5 Script API: Check that SAOs are still usable before attempting to use them 2020-02-11 19:21:12 +01:00
Paramat
b14aa1c847 Warn of biome ID re-allocation when unregistering or clearing biomes (#9359) 2020-02-03 00:31:00 +00:00
SmallJoker
4eb3baa51e StaticText: Reset background on EnrichedString change (#9340)
This also fixes the F6 profiler background color -> now controlled by EnrichedString
2020-02-01 20:41:32 +01:00
sfan5
7d29611c1b Convert sound_play uses in builtin to ephemeral 2020-02-01 20:31:41 +01:00
sfan5
c10e188594 Let node 'place' and 'dug' sounds be heard by other players 2020-02-01 20:31:41 +01:00
sfan5
ace3c76112 Improve core.sound_play with ephemeral sounds and player exclusion 2020-02-01 20:31:41 +01:00
HybridDog
ea5e231959 Add table.shuffle (#8299) 2020-02-01 16:09:45 +01:00
Ben Deutsch
2b3490db1f Add limit parameter to decompressZlib
This can prevent untrusted data, such as sent over the network,
from consuming all memory with a specially crafted payload.
2020-02-01 14:05:26 +01:00
DS
1116918dbb Formspec: Create a new class for inventorylists (#9287) 2020-02-01 13:55:13 +01:00
TheTermos
908e762479 Collision temporary fix for issue #6886 2020-01-27 19:30:11 +01:00
Hugues Ross
60544ac56f Add 9-slice background support to button formspec elements (#9290) 2020-01-26 19:35:26 +00:00
SmallJoker
cde2a7f6f2 Settings: Add get_flags API for mapgen flags (mg_flags, mgv6_spflags, ...) (#9284)
Unified flags handling in C++ and Lua Settings API
     -> Reading only, for now. Writing can be implemented later, if needed.
API function to read the currently active flags
     -> was impossible from Lua

Co-authored-by: Wuzzy <wuzzy2@mail.ru>
2020-01-25 16:56:54 +01:00
SmallJoker
9cb3219f34 EnrichedString: Fix substr segfault caused by non-formatted text 2020-01-24 21:06:30 +01:00
rubenwardy
987b2c5f37 Update translation sources 2020-01-24 18:34:11 +00:00
rubenwardy
e80c0bdea5 Update settingtypes.txt for new languages 2020-01-24 18:34:11 +00:00
IFRFSX
5e929c6b7f Translated using Weblate (Chinese (Simplified))
Currently translated at 65.1% (830 of 1274 strings)
2020-01-24 18:34:11 +00:00
Evert Prants
53123bbb6b Translated using Weblate (Estonian)
Currently translated at 30.0% (382 of 1274 strings)
2020-01-24 18:34:11 +00:00
rubenwardy
73241423fb Translated using Weblate (Japanese (Kansai))
Currently translated at 0.2% (2 of 1274 strings)
2020-01-24 18:34:11 +00:00
rubenwardy
d4b8075c35 Translated using Weblate (Burmese)
Currently translated at 0.2% (2 of 1274 strings)
2020-01-24 18:34:11 +00:00
rubenwardy
5e6e46f059 Translated using Weblate (Kazakh)
Currently translated at 0.2% (2 of 1274 strings)
2020-01-24 18:34:11 +00:00
rubenwardy
992705b4db Translated using Weblate (Arabic)
Currently translated at 6.1% (78 of 1274 strings)
2020-01-24 18:34:11 +00:00
rubenwardy
384ad7dec4 Translated using Weblate (Vietnamese)
Currently translated at 2.5% (32 of 1274 strings)
2020-01-24 18:34:11 +00:00
rubenwardy
8bf790b70e Translated using Weblate (Portuguese)
Currently translated at 100.0% (1274 of 1274 strings)
2020-01-24 18:34:11 +00:00
rubenwardy
0e4ad952da Translated using Weblate (Basque)
Currently translated at 15.1% (193 of 1274 strings)
2020-01-24 18:34:11 +00:00
rubenwardy
231ea6cbce Translated using Weblate (Greek)
Currently translated at 1.4% (18 of 1274 strings)
2020-01-24 18:34:11 +00:00
rubenwardy
527fabdac1 Translated using Weblate (Filipino)
Currently translated at 0.2% (2 of 1274 strings)
2020-01-24 18:34:11 +00:00
rubenwardy
ab3aef666b Translated using Weblate (Thai)
Currently translated at 66.9% (852 of 1274 strings)
2020-01-24 18:34:11 +00:00
rubenwardy
c2d0d9027c Translated using Weblate (Lao)
Currently translated at 0.2% (2 of 1274 strings)
2020-01-24 18:34:11 +00:00
Osoitz
85b03f3fd3 Translated using Weblate (Basque)
Currently translated at 15.1% (192 of 1274 strings)
2020-01-24 18:34:11 +00:00
Dhimas Wnz
73f89e59ed Translated using Weblate (Indonesian)
Currently translated at 96.9% (1234 of 1274 strings)
2020-01-24 18:34:11 +00:00
THANOS SIOURDAKIS
70601008da Translated using Weblate (Greek)
Currently translated at 1.3% (17 of 1274 strings)
2020-01-24 18:34:11 +00:00
universales
fb0d672373 Translated using Weblate (Spanish)
Currently translated at 61.9% (789 of 1274 strings)
2020-01-24 18:34:11 +00:00
Osoitz
4c020bb6fc Translated using Weblate (Basque)
Currently translated at 9.7% (123 of 1274 strings)
2020-01-24 18:34:11 +00:00
Osoitz
117397a5fc Added translation using Weblate (Basque) 2020-01-24 18:34:11 +00:00
Hotower
82f577c740 Translated using Weblate (Chinese (Simplified))
Currently translated at 65.1% (830 of 1274 strings)
2020-01-24 18:34:11 +00:00
Stas Kies
7909701389 Translated using Weblate (German)
Currently translated at 100.0% (1274 of 1274 strings)
2020-01-24 18:34:11 +00:00
abidin toumi
899bc0eb0d Translated using Weblate (Arabic)
Currently translated at 6.0% (77 of 1274 strings)
2020-01-24 18:34:11 +00:00
zaoqi
5233f81660 Translated using Weblate (Chinese (Simplified))
Currently translated at 65.1% (830 of 1274 strings)
2020-01-24 18:34:11 +00:00
Yangjun Wang
4d792186b8 Translated using Weblate (Chinese (Simplified))
Currently translated at 63.2% (805 of 1274 strings)
2020-01-24 18:34:11 +00:00
Ács Zoltán
5e5ed606b1 Translated using Weblate (Hungarian)
Currently translated at 61.9% (789 of 1274 strings)
2020-01-24 18:34:11 +00:00
Tirifto
240f5d4f19 Translated using Weblate (Esperanto)
Currently translated at 97.2% (1238 of 1274 strings)
2020-01-24 18:34:11 +00:00
Petter Reinholdtsen
c69e3ed6e8 Translated using Weblate (Norwegian Bokmål)
Currently translated at 43.3% (552 of 1274 strings)
2020-01-24 18:34:11 +00:00
Luboš Nečas
271ca52f0a Translated using Weblate (Czech)
Currently translated at 48.8% (622 of 1274 strings)
2020-01-24 18:34:11 +00:00
Tirifto
03843cf5d3 Translated using Weblate (Esperanto)
Currently translated at 94.9% (1209 of 1274 strings)
2020-01-24 18:34:11 +00:00
ramon.venson
4d4ea46b2e Translated using Weblate (Portuguese (Brazil))
Currently translated at 96.9% (1235 of 1274 strings)
2020-01-24 18:34:11 +00:00
Daniel Mancini
6cb9e26f38 Translated using Weblate (Portuguese (Brazil))
Currently translated at 96.9% (1235 of 1274 strings)
2020-01-24 18:34:11 +00:00
Andrei Stepanov
6b754bfe3b Translated using Weblate (Russian)
Currently translated at 100.0% (1274 of 1274 strings)
2020-01-24 18:34:11 +00:00
Andrei Stepanov
d3bd7c5c0f Translated using Weblate (Russian)
Currently translated at 100.0% (1274 of 1274 strings)
2020-01-24 18:34:11 +00:00
Andrei Stepanov
30ea18a127 Translated using Weblate (Russian)
Currently translated at 100.0% (1274 of 1274 strings)
2020-01-24 18:34:11 +00:00
Andrei Stepanov
b1c4037eec Translated using Weblate (Russian)
Currently translated at 100.0% (1274 of 1274 strings)
2020-01-24 18:34:11 +00:00
Andrei Stepanov
5648e7ac46 Translated using Weblate (Russian)
Currently translated at 100.0% (1274 of 1274 strings)
2020-01-24 18:34:11 +00:00
Matej Mlinar
ef8afb06d1 Translated using Weblate (Slovenian)
Currently translated at 43.9% (559 of 1274 strings)
2020-01-24 18:34:11 +00:00
abidin toumi
66ec4f3d01 Translated using Weblate (Arabic)
Currently translated at 5.7% (73 of 1274 strings)
2020-01-24 18:34:11 +00:00
Fixer
af28afdac4 Translated using Weblate (Ukrainian)
Currently translated at 42.1% (536 of 1274 strings)
2020-01-24 18:34:11 +00:00
Andrei Stepanov
662dd157ed Translated using Weblate (Russian)
Currently translated at 81.9% (1044 of 1274 strings)
2020-01-24 18:34:11 +00:00
abidin toumi
43db70f480 Translated using Weblate (Arabic)
Currently translated at 5.6% (71 of 1274 strings)
2020-01-24 18:34:11 +00:00
abidin toumi
cc667ba7aa Translated using Weblate (Arabic)
Currently translated at 4.2% (53 of 1274 strings)
2020-01-24 18:34:11 +00:00
Andrei Stepanov
23484ff0cf Translated using Weblate (Russian)
Currently translated at 81.7% (1041 of 1274 strings)
2020-01-24 18:34:11 +00:00
abidin toumi
068c70bb9e Added translation using Weblate (Arabic) 2020-01-24 18:34:11 +00:00
Viktar Vauchkevich
cde683a4c7 Translated using Weblate (Belarusian)
Currently translated at 100.0% (1274 of 1274 strings)
2020-01-24 18:34:11 +00:00
Julien Maulny
f35dd3b2a8 Translated using Weblate (French)
Currently translated at 97.0% (1236 of 1274 strings)
2020-01-24 18:34:11 +00:00
Jacques Lagrange
31002669c1 Translated using Weblate (Italian)
Currently translated at 100.0% (1274 of 1274 strings)
2020-01-24 18:34:11 +00:00
Krock
8751915bd2 Translated using Weblate (Japanese (Kansai))
Currently translated at 0.1% (1 of 1274 strings)
2020-01-24 18:34:11 +00:00
Krock
4a58f2525a Translated using Weblate (Dhivehi)
Currently translated at 8.2% (105 of 1274 strings)
2020-01-24 18:34:11 +00:00
Krock
e045ed9ebf Translated using Weblate (Chinese (Simplified))
Currently translated at 63.0% (803 of 1274 strings)
2020-01-24 18:34:11 +00:00
Krock
c0c76219fe Translated using Weblate (Burmese)
Currently translated at 0.1% (1 of 1274 strings)
2020-01-24 18:34:11 +00:00
Krock
a431f5e757 Translated using Weblate (Kyrgyz)
Currently translated at 8.6% (110 of 1274 strings)
2020-01-24 18:34:11 +00:00
Krock
94af88bdba Translated using Weblate (Slovenian)
Currently translated at 42.0% (535 of 1274 strings)
2020-01-24 18:34:11 +00:00
Krock
527d29de25 Translated using Weblate (Kannada)
Currently translated at 3.0% (38 of 1274 strings)
2020-01-24 18:34:11 +00:00
Krock
bc29596458 Translated using Weblate (Kazakh)
Currently translated at 0.1% (1 of 1274 strings)
2020-01-24 18:34:11 +00:00
Krock
ac9f83197f Translated using Weblate (Norwegian Nynorsk)
Currently translated at 31.2% (398 of 1274 strings)
2020-01-24 18:34:11 +00:00
Krock
7a3d8ec522 Translated using Weblate (Italian)
Currently translated at 96.9% (1234 of 1274 strings)
2020-01-24 18:34:11 +00:00
Krock
601906064a Translated using Weblate (Hebrew)
Currently translated at 4.3% (55 of 1274 strings)
2020-01-24 18:34:11 +00:00
Krock
b83ca324f9 Translated using Weblate (Hungarian)
Currently translated at 61.9% (788 of 1274 strings)
2020-01-24 18:34:11 +00:00
Krock
105fff174c Translated using Weblate (Estonian)
Currently translated at 14.4% (183 of 1274 strings)
2020-01-24 18:34:11 +00:00
Krock
a36eae7546 Translated using Weblate (Esperanto)
Currently translated at 79.6% (1014 of 1274 strings)
2020-01-24 18:34:11 +00:00
Krock
645b4ce58b Translated using Weblate (Greek)
Currently translated at 1.1% (14 of 1274 strings)
2020-01-24 18:34:11 +00:00
Krock
199eee5be0 Translated using Weblate (Danish)
Currently translated at 49.5% (631 of 1274 strings)
2020-01-24 18:34:11 +00:00
Krock
4a89b1d71f Translated using Weblate (Portuguese (Brazil))
Currently translated at 96.4% (1228 of 1274 strings)
2020-01-24 18:34:11 +00:00
Krock
5e983a1d6e Translated using Weblate (Filipino)
Currently translated at 0.1% (1 of 1274 strings)
2020-01-24 18:34:11 +00:00
Krock
811326e2a7 Translated using Weblate (Thai)
Currently translated at 66.8% (851 of 1274 strings)
2020-01-24 18:34:11 +00:00
Krock
29d5d9987b Translated using Weblate (Lithuanian)
Currently translated at 15.4% (196 of 1274 strings)
2020-01-24 18:34:11 +00:00
Krock
1c6a93f4be Translated using Weblate (Lao)
Currently translated at 0.1% (1 of 1274 strings)
2020-01-24 18:34:11 +00:00
Allan Nordhøy
8fddab5118 Translated using Weblate (Italian)
Currently translated at 96.9% (1234 of 1274 strings)
2020-01-24 18:34:11 +00:00
Mateusz Mendel
6bb6521eee Translated using Weblate (Polish)
Currently translated at 81.1% (1033 of 1274 strings)
2020-01-24 18:34:11 +00:00
Vicente Carrasco Alvarez
22f7dd3bd9 Translated using Weblate (Spanish)
Currently translated at 61.5% (783 of 1274 strings)
2020-01-24 18:34:11 +00:00
Mateusz Mendel
5ed9e6ac49 Translated using Weblate (Polish)
Currently translated at 81.1% (1033 of 1274 strings)
2020-01-24 18:34:11 +00:00
Muhammad Nur Hidayat Yasuyoshi
b6e7a064de Translated using Weblate (Malay)
Currently translated at 100.0% (1274 of 1274 strings)
2020-01-24 18:34:11 +00:00
Mattias Münster
7417d01ede Translated using Weblate (Swedish)
Currently translated at 32.7% (417 of 1274 strings)
2020-01-24 18:34:11 +00:00
Jacques Lagrange
8a9e9d76de Translated using Weblate (Italian)
Currently translated at 96.9% (1234 of 1274 strings)
2020-01-24 18:34:11 +00:00
Ács Zoltán
497368c664 Translated using Weblate (Hungarian)
Currently translated at 61.9% (788 of 1274 strings)
2020-01-24 18:34:11 +00:00
ssantos
b82e0b3803 Translated using Weblate (Portuguese)
Currently translated at 100.0% (1274 of 1274 strings)
2020-01-24 18:34:11 +00:00
BreadW
831d192bb2 Translated using Weblate (Japanese)
Currently translated at 100.0% (1274 of 1274 strings)
2020-01-24 18:34:11 +00:00
Wuzzy
b6c246b638 Translated using Weblate (German)
Currently translated at 100.0% (1274 of 1274 strings)
2020-01-24 18:34:11 +00:00
nautilusx
2054198c64 Translated using Weblate (German)
Currently translated at 100.0% (1274 of 1274 strings)
2020-01-24 18:34:11 +00:00
monolifed
71360b2d3a Translated using Weblate (Turkish)
Currently translated at 100.0% (1274 of 1274 strings)
2020-01-24 18:34:11 +00:00
Oguz Ersen
17fd82cee1 Translated using Weblate (Turkish)
Currently translated at 100.0% (1274 of 1274 strings)
2020-01-24 18:34:11 +00:00
sfan5
273cdb38a9 CMakeLists: Remove some redundant declarations and flags 2020-01-23 21:29:40 +01:00
sfan5
c8583f9a5e Organize and sort out some library dependency issues 2020-01-23 21:29:40 +01:00
SmallJoker
a1da9caecf EnrichedString: Fix uninitialized variable m_default_length 2020-01-23 20:14:46 +01:00
SmallJoker
1892ff3c0d StaticText/EnrichedString: Styling support (#9187)
* StaticText/EnrichedString: Styling support

* Fix tooltip fg/bgcolor

* Fix default color for substr(), add unittests
2020-01-22 19:09:11 +01:00
Zaoqi
fab3f5f7c8 Remove zh_* from GETTEXT_BLACKLISTED_LOCALES (#9229) 2020-01-22 19:08:07 +01:00
Wuzzy
e05b7dbb3c Remove unused weight property from objects (#9320) 2020-01-22 10:19:27 +01:00
Hugues Ross
3dfb6ecbb2 Formspec: Don't start a button click when the pointer isn't on top (#9332) 2020-01-22 10:18:09 +01:00
Wuzzy
0877587cce Resized torchlike sprite now attaches to surface (#9303) 2020-01-20 19:17:54 +00:00
ANAND
468eb4bf57 lua_api.txt: Improve privs_to_string and string_to_privs documentation (#9228) 2020-01-19 11:16:54 +01:00
ANAND
e8fd1ce623 Replace stray tab with whitespace in guiFormSpecMenu.cpp (#9317) 2020-01-18 16:50:57 +00:00
rubenwardy
1173ff0c13 Add Lua unit tests to builtin using busted (#9184) 2020-01-18 02:09:18 +00:00
rubenwardy
6d472b1840 Fix syntax error in Dockerfile 2020-01-17 19:14:58 +00:00
Hugues Ross
680aaa1bd5 Make clipping of formspec elements more consistent (#9262) 2020-01-16 18:41:07 +00:00
lhofhansl
cea4fd2b27 Increase star count to 1000 and decrease radius slightly (#9307)
* Increase star count to 1000 and decrease radius slightly.
* Adjust star width.
2020-01-16 17:12:34 +01:00
Maksim
c396800629 Android: fix cyrillic characters, update iconv lib (#9117) 2020-01-13 07:10:15 +01:00
Montandalar
8d75c118d9 Map download: Escape ':' to '_' (#9235)
This is necessary under Windows systems, and direct IPv6 connections.
Windows universally disallows ':' from occuring in filenames.

Other disallowed characters on Windows:

	\ / * ? " < > |

are not relevant to hostnames, IPv4 or IPv6 addresses.

Anyone who has got an existing server map saved on Linux with ':' in
the world save will want to keep that save.
2020-01-11 20:47:34 +01:00
DS
4c8af5492b Formspec: change the appeareance of the cursor on fields and co. (#8665) 2020-01-11 20:17:11 +01:00
Wuzzy
3189e4466b Add missing entity documentation (#9297) 2020-01-09 19:48:16 +01:00
Wuzzy
f4f7c7a11b Improve Lua API documentation on sounds (#9265) 2020-01-08 21:27:54 +00:00
DS
7c0e0c34ec Formspec: Fix clicking on tooltip-obstructed elements (#9266) 2020-01-04 15:45:22 +01:00
HybridDog
f9c7e46a34 Add table.key_value_swap (#9248) 2020-01-04 15:44:48 +01:00
Wuzzy
3ad92baa9c Tweak default textures (#9237) 2020-01-04 15:44:31 +01:00
Paramat
c162340973 Remove Mapgen V7 floatlands in preparation for new implementation (#9238)
Preserve the floatland flag of existing worlds, to be used again
when the new implementation is added.
2020-01-04 01:23:57 +00:00
Montandalar
44458896d9 Use appropriate LC_ locale macro for Windows (#9230)
* Wrap LC_ macro in ifdef

Windows does not have LC_MESSAGES in locale.h, so use LC_ALL on that platform
2019-12-24 19:13:22 +01:00
Wuzzy
876a15bd75 Fix item eat sound not played if last item (#9239) 2019-12-24 19:12:46 +01:00
Wuzzy
7199dc7559 Document permissible group ratings (#9236) 2019-12-24 19:12:31 +01:00
Lars Hofhansl
9c28acd29b Allow wave_heights up to two nodes. #9220 2019-12-21 06:33:59 -08:00
Lejo
37f771a95b Fix the player information version_string return value (#8616)
* Give more player information

* Correct lua_api.txt

* Correct keys in lua_api.txt

* Improve Code

* Only Bugfix+ser_vers

* Correct doc

* Fix double
2019-12-20 19:16:29 +01:00
ANAND
ec3224dce2 /privs: Delimit output list of privs with commas (#9224) 2019-12-20 19:15:40 +01:00
Wuzzy
4b9fabf172 Builtin: Make dropped light_source nodes glow (#9200) 2019-12-19 19:41:44 +01:00
Bluebird
80af58c8c5 Make core.item_place_node return position of placed node. (#7713) 2019-12-18 19:21:24 +01:00
Zaoqi
39a1e6660e Dockerfile: correct apt clean + git clone --depth 1 + remove .git (#8697) 2019-12-17 14:34:21 +01:00
sfan5
db7e59f472 Correct documentation around minetest.item_place
The code that calls minetest.item_place_object was removed
in 2013 in commit fc61c8809b.
2019-12-16 21:24:34 +01:00
Hugues Ross
b50dc43f67 Don't override the FGIMG style property if the image parameter is null 2019-12-16 19:26:57 +01:00
Hugues Ross
e42faae8d9 Remove the dependency on FGIMG/BGIMG from the hovered/pressed variants
- Make guiButtonImage support null images properly
2019-12-16 19:26:57 +01:00
Hugues Ross
bd4b8d40b3 StyleSpec: 0-initialize the property_set array 2019-12-16 19:26:57 +01:00
SmallJoker
41ff0f6679 Lua API: Document HP, breath and damage limits (#9080) 2019-12-15 18:55:01 +01:00
Zaoqi
03e1f23a5e Add Alpine build dependencies in README (#9206) 2019-12-15 17:10:25 +01:00
SmallJoker
c3d0aab0bc GUIFormSpecMenu: Fix legacy sorting using std::stable_sort 2019-12-14 21:28:07 +01:00
rubenwardy
8e63d22d64 Fix spaces breaking formspec_version[] tag 2019-12-09 21:05:07 +00:00
Hugues Ross
9284313d17 Refactor to centralize GUIButton styling/rendering code (#9090) 2019-12-09 20:06:51 +00:00
SmallJoker
a462181e5f guiConfirmRegistration: Fix hidden error message 2019-12-09 20:01:16 +01:00
DS
8f73ec6c6c Formspec: make bgcolor element less confusing and allow setting fullscreen color (#8996) 2019-12-08 18:59:30 +01:00
rubenwardy
d3255f92d7 Fix luacheck errors 2019-12-07 23:50:12 +01:00
rubenwardy
51b4ddc4c9 Run luacheck in travis 2019-12-07 23:50:12 +01:00
Paul Ouellette
27ce6d0ecc Clean up craft replacements docs 2019-12-07 23:46:24 +01:00
SmallJoker
103d9c5c53 Renaming the function wasn't enough 2019-12-07 15:55:49 +01:00
SmallJoker
aa8df112ff Attachments: Fix interpolation from (0,0,0) after detach
GenericCAO::getPosition() did not take the camera offset into account
LocalPlayer attachment cleanup: Use sane getParent() function
Make that getPosition() (GenericCAO and LocalPlayer) always return the absolute position
2019-12-07 15:12:26 +01:00
rubenwardy
51f230895c Fix failing build due to code style error 2019-12-06 23:00:54 +00:00
v-rob
4f45bfd08b Add scrollbaroptions FormSpec element (#8530) 2019-12-06 20:51:10 +00:00
Zaoqi
9a5d43a4f5 Fix android build due to omitted file in src files 2019-12-06 20:50:45 +00:00
Pierre-Yves Rollo
cf7fda0083 Add z-index management to HUD 2019-12-06 20:31:26 +00:00
SmallJoker
f6de86ce4b Fix LocalPlayer-bound sound playback broken by 81c2370 2019-12-05 20:52:30 +01:00
Nils Dagsson Moskopp
ef8bf3cf35 Fix Debian build dependencies in README
This patch replaces the statement in the README about a build dependency of the
minetest binary on the package “build-essential” with a corresponding statement
about build dependencies on the three packages “g++”, “make”, and “libc6-dev”.

Though often used as a shorthand, “build-essential” is not a package used to
install packages that are essential for building software – “build-essential”
depends on packages that are essential for building Debian packages. Therefore,
the dependency on “build-essential” implies a dependency on a lot of packages that
are not actually necessary to build minetest (e.g. the Perl programming language).
2019-12-02 10:49:39 +01:00
ANAND
4b6bff46e1 Use a safer implementation of gsub in core.chat_format_message (#9133)
This search-and-replace implementation does not use Lua pattern-matching
2019-11-25 20:03:34 +01:00
sfan5
0b2f0914cc Improve client-side packet receiving 2019-11-25 20:00:24 +01:00
paramat
154080c883 Caves: Fix shadowing of 'large_cave_depth' to avoid confusion 2019-11-23 01:41:27 +00:00
paramat
ec5f591014 Dungeons: Move duplicated y limit checks to generation function 2019-11-23 01:41:27 +00:00
SmallJoker
b50a166bb0 Formspec: Fix priorities for version < 3 (#9121)
* Formspec: Fix priorities for version < 3

1) Introduce 'priority' to 'FieldSpec'
2) Sort elements based on 'priority'
3) Assign 'name' to the Item Image Button's image to show tooltips again
2019-11-20 19:39:10 +01:00
Lars Hofhansl
60bff1e6cb Waves generated with Perlin-type noise #8994 2019-11-19 19:42:52 -08:00
Paramat
b3c245bb46 Move duplicated mapgen parameters to class MapgenBasic (#9134)
'large_cave_depth', 'dungeon_ymin' and 'dungeon_ymax' are duplicated across many mapgens so should have been in class MapgenBasic from the start.
2019-11-19 19:59:17 +00:00
sfan5
c10952b574 Rework packet receiving in ServerThread
Notably it tries to receive all queued packets
between server steps, not just one.
2019-11-19 20:27:20 +01:00
Paramat
97764600e2 Randomwalk cave liquids: Remove deprecated 'lava depth' parameter (#9105)
Low-disruption first step towards removing the hardcoded cave liquid
code. Since MT 5.0.0 cave liquids can be defined and located by
biome definitions instead.
In games that do not yet use biome definitions to define and locate
cave liquids (MTGame does), lava will now appear below
y = water_level - 256 instead of below 'lava depth' (usually y = -256).
Therefore no change in most mapgens if using the default 'lava depth'.
2019-11-18 23:40:01 +00:00
William Breathitt Gray
706b6aad06 Fix find_path for newer jsoncpp installations
The upstream JsonCpp project has renamed the `json/features.h` file to
`json/json_features.h`. This patch fixes the JsonCpp installation search
by looking for `json/allocator.h` which has not been renamed on newer
versions of JsonCpp.

Fixes: https://github.com/minetest/minetest/issues/9119
2019-11-17 11:39:49 +01:00
sfan5
49365b25d9 Optimize semaphore wait with zero timeout on POSIX 2019-11-14 20:20:14 +01:00
sfan5
b5f5e00b29 Install client_lua_api.txt documentation too
fixes #9104
2019-11-11 14:06:48 +01:00
sfan5
02111e4961 Fix clang-tidy and lint travis checks 2019-11-11 14:06:48 +01:00
sfan5
c44318a253 [CSM] Fix and improve minetest.get_language()
Previously this method would accidentally reset the locale
and break everything.
2019-11-11 14:06:48 +01:00
sfan5
2c4cf508a9 [CSM] Implement minetest.get_csm_restrictions()
fixes #8068
2019-11-11 14:06:48 +01:00
sfan5
3f271564e0 Run on_item_use CSM callback even if item is not marked usable
Mods may want to to handle item interaction even if the item
is not marked usable (= server-side callback exists).
2019-11-11 14:06:48 +01:00
sfan5
682b9de824 Fix camera:get_offset() in CSM 2019-11-11 14:06:48 +01:00
sfan5
b57dc70769 [CSM] Expose more env functions 2019-11-11 14:06:48 +01:00
sfan5
b0260b5ec8 Refactor CSM restriction code a bit
This also fixes find_node_near restrictions being ineffective.
2019-11-11 14:06:48 +01:00
sfan5
4d668f32a6 Call on_secondary_use when object is right-clicked 2019-11-10 13:12:31 +01:00
Paramat
3b0df9760b Randomwalk caves: Extend beyond mapchunk vertically also (#9094)
Previously, randomwalk caves only extended beyond the mapchunk
borders horizontally, preventing vertical overlap and
interconnection.
2019-11-10 01:41:20 +00:00
sfan5
d961ece144 Be lenient with extra slashes for CSM paths 2019-11-09 16:08:38 +01:00
sfan5
485b669840 [CSM] Remove non-functional minetest.get_day_count() 2019-11-09 16:08:38 +01:00
sfan5
7e649f985c Corrections to client_lua_api.txt 2019-11-09 16:08:38 +01:00
sfan5
b1f2a69382 Introduce get_modpath() for CSM 2019-11-09 16:08:38 +01:00
sfan5
82a2e02323 Load client mods into memory before execution.
Preperation for server-sent CSM which will eventually need this.
2019-11-09 16:08:38 +01:00
sfan5
5ab546f99b Refactor loading of Lua code with mod security 2019-11-09 16:08:38 +01:00
Loic Blot
17191a60fb Add arm64-v8a but it's not sufficient for 64bit build 2019-11-09 12:51:10 +01:00
Loic Blot
f35533a953 Bump to version code 25 2019-11-09 11:38:54 +01:00
MoNTE48
7f023de5cb Android: build fixes & compat fixes 2019-11-09 11:24:49 +01:00
Paramat
dfd5f7cb10 Silence invalid Clang Format report (#9095) 2019-11-09 03:01:22 +00:00
Paramat
29a4a8e5af Tunnels: Completely disable generation when 'cave width' >= 10.0 (#9093)
Previously, the only way to disable the 3D noise tunnels was to set
'cave width' > 1.0, however doing so did not disable the very intensive
noise calculations or the generation loop.
All the other types of cave generation (randomwalk caves, caverns)
can already be independently and completely disabled.
This feature is now needed more because the small randomwalk caves are
now available for use as an alternative to the 3D noise tunnels.
2019-11-09 02:09:52 +00:00
Paul Ouellette
d11bfa3ef5 Make core.get_favorites("local") ignore duplicates (#7926) 2019-11-08 22:18:20 +01:00
Paramat
2a74727857 Randomwalk caves: Add parameters for number, proportion flooded. Allow small caves (#8928)
Add mapgen parameters to set the range of the random number of
randomwalk caves per mapchunk, and to set the proportion that are
flooded with liquids.
Default values are, for now, unchanged from the previous hardcoded
values.

Add parameters to allow small randomwalk caves
Disabled by default for now as they have never been present in the
non-mgv6 mapgens.
2019-11-08 03:09:43 +00:00
DS
5506e97ed8 Formspec: draw order and clipping for all elements (#8740) 2019-11-07 20:11:01 +01:00
sfan5
15a030ec9f Improve documentation around banning (#9088)
* Fix ban chatcommand description
* Correct ban API documentation
2019-11-05 19:24:51 +01:00
SmallJoker
2907c0f3a2 Android: Fix broken double-tap after 49 days uptime 2019-11-03 12:59:12 +01:00
SmallJoker
388ea737f5 Clean up font caching, fix bitmap fonts 2019-11-03 11:45:33 +01:00
Pierre-Yves Rollo
72416a6a1f Formspec: add hypertext element 2019-11-03 11:45:33 +01:00
DS
8697090b35 Add debug.txt.1 to .gitignore (#9081)
This should have been done in #8904.
2019-11-02 19:29:14 +01:00
Alistair Findlay
5f835a72b2 Builtin: Improve /clearobjects message (#9084) 2019-11-02 19:28:55 +01:00
random-geek
f2e62298a5 Change some usages of "deprecated" to "obsolete" (#9062)
"Deprecated" means that something is still in use, but is unsupported and needs to be removed.
"Obsolete" means it is already out of use.
2019-10-29 19:23:12 +01:00
Wuzzy
8ee16180c7 Add help texts for settings that lack one (#9007) 2019-10-25 21:29:02 +01:00
random-geek
53ebd803c6 Change some rough/inappropriate language in comments (#9061) 2019-10-24 01:17:00 +01:00
Paramat
1f142ec06f Improve light curve parameter limits and documentation (#9054)
Revert gamma upper limit to 3.0 because that was raised based on
a misunderstanding and had no benefit. A sane upper limit is
needed as players on a competitive server tend to use the maximum.
Set gamma lower limit to 0.33 for consistency with 3.0.
Set sane limits on alpha, beta, boost and enforce these in code
to limit values entered in minetest.conf and to avoid easy cheating
by editing settingtypes.txt.
Improve documentation and 'readable' setting names.
Clarify that gamma does not significantly affect natural night light.
light.cpp: Various codestyle and comment improvements.
2019-10-24 01:08:49 +01:00
random-geek
cd35949cd0 Remove legacy file format documentation 2019-10-23 20:53:24 +02:00
random-geek
2f3c96b38d Remove legacy flat-file map code 2019-10-23 20:53:24 +02:00
Dmitry Marakasov
2ecf57c640 Fix build issue due to conflicting s64 type definitions (#9064)
See comment in irrlichttypes.h and https://sourceforge.net/p/irrlicht/bugs/433/
2019-10-23 20:28:55 +02:00
Paul Ouellette
904b05b0d3 Allow calling ItemStack with no arguments (#8783) 2019-10-23 19:48:19 +02:00
Wuzzy
524442fc5e Add 4 missing fallback/default textures (#8845)
Processed using 'optipng -o7 -strip all '
2019-10-23 19:48:06 +02:00
SmallJoker
a978278bfb Formspecs: Reset version number on rebuild 2019-10-20 12:44:52 +02:00
Paramat
79440605ec Make natural night light as bright as MT 0.4.16 (#9053) 2019-10-18 21:54:44 +01:00
Warr1024
15b6922ae6 Correction for alpha blending issues in texture mod compositing (#9029) 2019-10-18 19:17:35 +02:00
sfan5
b7e358703f Don't install fonts on ENABLE_CLIENT=0 configurations 2019-10-14 21:24:23 +02:00
Paramat
2dd4f8d3fe Settingtypes.txt: Various improvements (#9047) 2019-10-14 03:30:54 +01:00
Aaron Suen
0df646e068 Fix rotate_node to return the correct itemstack.
All on_* hooks that return an itemstack are NOT guaranteed to
modify and return the original stack.  We cannot count on the
behavior of the existing builtin definitions not to be overridden
by game/mod logic.
2019-10-13 17:11:00 +02:00
Paramat
47d0779365 Randomwalk caves: Reduce 'insure' value from 10 to 2 (#9035)
This value reduces how far randomwalk caves can extend into the
mapchunk padding, to avoid 'out of voxelmanip' cave nodes which cause
flattened cave walls.
Testing shows that a value of 2 (instead of 10) is enough to make
'out of area' nodes extremely rare.
Reducing this value results in a higher chance of overlap and
connection with caves of neighbour mapchunks.
2019-10-13 00:18:23 +01:00
Hugues Ross
69a2099c04 Add more visual feedback for button states (#8916)
- Add style properties for overriding the the hovered/pressed state
  - By default, hovered buttons are a lighter version of the base color
  - By default, pressed buttons are a darker version of the base color
- Add hovered bg image support for image buttons (style property)
2019-10-12 18:44:23 +02:00
sfan5
894008ce6f Continue with 5.2.0-dev 2019-10-12 15:49:06 +02:00
sfan5
4e4fb4db2a Bump version to 5.1.0 2019-10-12 15:48:58 +02:00
updatepo.sh
ffe7f96d24 Update minetest.conf.example 2019-10-12 14:29:24 +02:00
updatepo.sh
22e04d9919 Update translation strings 2019-10-12 14:29:24 +02:00
Translators
d7045d2b7e Update from Weblate (hacky) 2019-10-12 14:29:24 +02:00
Paramat
f483a1a9b2 Fix isDead()/autoforward crash (#9031)
Crash occurred in singleplayer when leaving a world with
autoforward enabled then re-entering a world.
2019-10-09 19:39:50 +01:00
SmallJoker
cbcb9e0b1c ContentCAO: Fix segfault on quit (attached) 2019-10-09 20:03:31 +02:00
ANAND
b49dfa92ce Revert Client::sendPlayerPos optimization (part of 81c7f0a) (#9025)
Comment out the if statement that prevents sending TOSERVER_PLAYERPOS if the player is dead.
2019-10-08 20:36:56 +02:00
sfan5
825579b43d Fix upright_sprite lighting when colors are set
fixes #9020
2019-10-06 17:19:42 +02:00
SmallJoker
dee22104b7 Revert "Fix the bgcolor formspec element (#8716)" (#9018)
This reverts commit 1db3d252cf.
Temporary solution until a compatible solution is found to define both - formspec and fullscreen backgrounds.
2019-10-06 14:50:45 +02:00
sfan5
dde0628976 Fix warnings in guiButton.h 2019-10-05 18:15:26 +02:00
Warr1024
ad96df191b Merge pull request #8166 from Warr1024/fix7020
Fix (or workaround?) for 'Falling nodes with node inventory cause crash when unloaded'
2019-10-05 15:46:57 +02:00
Jacob Lifshay
76032159bd Fix unwanted detaching when damage = 0 2019-10-05 15:45:05 +02:00
SmallJoker
81c2370c8b Attachments: Fix attachments to temporary removed objects (#8989)
Does not clear the parent's attachment information when the child is deleted locally.
Either it was removed permanently, or just temporary - we don't know, but it's up to the server to send a *detach from child" packet for the parent.
2019-10-02 19:11:27 +02:00
James Tobin
251038e136 README: Add dependencies for Arch Linux (#8998)
Added Arch Linux dependency list (including base-devel which covers many of them)
2019-10-01 19:09:59 +02:00
Wuzzy
7fafe656a1 All Settings: Set min limit for crtitical settings (#9000) 2019-10-01 19:09:37 +02:00
Paramat
653d7b8112 Document node drop tool filtering by string matching as deprecated (#9009) 2019-09-30 21:34:43 +01:00
SmallJoker
61e9c1b0dd Textures: Load base pack only as last fallback (#8974) 2019-09-29 19:57:29 +02:00
SmallJoker
c2458d3d3a label[]: Fix broken colors since 2c9edef 2019-09-29 14:52:41 +02:00
ANAND
3799ffd9d5 Move Quicktune code to util/ (#8871) 2019-09-29 13:41:13 +02:00
rubenwardy
07bdd6049b Fix error message caused by adding new parameter to background (#8922)
Adds background9[] element to keep backwards compatibility in formspec prepends.
2019-09-29 13:40:59 +02:00
DS
16865a5bf6 Allow grep-ing for on_grant and on_revoke (#8958)
Just two code comments are added.
2019-09-29 13:40:15 +02:00
Muhammad Rifqi Priyo Susanto
b79741c90f All settings: Fix missing flags checkbox caused by 'possible flags' order (#8997)
Previously, the 'rivers' checkbox was missing for mgcarpathian, caused by the 'possible flags' order: 'caverns,nocaverns,rivers,norivers'.
Also reorder mgcarpathian 'possible flags', but only for consistency.
2019-09-27 19:13:08 +01:00
lhofhansl
5fde69798c Simple shader fixes. (#8991)
1. Pass current camera offset to shader, so shader have access to the global coordinates
2. Pass animation timer to fragment shader. C++ code is already there, just wasn't declared in the shader
3. Delay animation timer wrap-around (from 100s to about 16 minutes)
2019-09-26 13:57:39 -07:00
HybridDog
9e95bac75d Automatically enable depends of mods when enabling the mods in the world config menu (#3473) 2019-09-26 21:03:54 +02:00
SmallJoker
26b39f1eae Fix some reference counters (memleak) (#8981)
Fix some reference counters (memleak)
Map::dispatchEvent: Allocation safety using references
2019-09-24 19:05:28 +02:00
sfan5
d77ea76476 Fix broken build
The variable name changed but this didn't cause merge conflicts, so it wasn't caught before.
2019-09-23 00:28:26 +02:00
Hugo Locurcio
d364b6d0a6 Rename "private messages" to "direct messages" (#8971)
These messages can be read by server administrators, which makes them
not actually private.
2019-09-22 21:48:36 +01:00
DS-Minetest
cf78e37da3 Move the code for meta formspec into bool Game::nodePlacement(const ItemDefinition &selected_def, 2019-09-22 22:12:49 +02:00
sfan5
70f9e1aafa Punchwear (improved) (#8959) 2019-09-22 22:12:21 +02:00
SmallJoker
fec30e37ac Fix AreaStore's IDs persistence (#8888)
Improve documentation
Read old formats
Fix free ID function. Return first gap in map
2019-09-21 17:54:52 +02:00
SmallJoker
5fa614d97e Wieldhand: Specify which ItemStack to use (#8961)
Makes 'get_wield_item' to return the "main" ItemStack
2019-09-21 11:44:24 +02:00
Anand S
47da640d77 Add support for per-player FOV overrides and multipliers 2019-09-19 20:14:16 +02:00
sfan5
5c9983400f Remove incorrect MutexAutoLock
The line declared a variable "m_con" instead of locking m_con.
getClient() doesn't need this anyway, so remove it.
2019-09-19 16:46:41 +02:00
DS-Minetest
0b5c5499ec Trigger on_place in many situations even if prediction failed 2019-09-19 16:36:02 +02:00
Tim Myers
c413eeb026 Also print help commands to chat for server terminal (#8869) 2019-09-19 00:37:56 +02:00
Linjie Pan
6a7f5c0985 Fix misuse of AsyncTask (#8799) 2019-09-19 00:37:06 +02:00
SmallJoker
4271889ef8 Settings: Prevent mutex deadlock in remove() (#7803) 2019-09-18 18:48:41 +02:00
SmallJoker
94a5df795c Inventory: Properly revert client predictions (#8945)
Caused by incremental inventory sending
Previously everything was overwritten by serializing the entire inventory
2019-09-18 18:47:09 +02:00
Hugo Locurcio
05a7da6279 Improve undersampling settings
The setting now accepts values between 1 and 8 in the
Advanced Settings menu.
Values 0 and 1 now behave the same way (setting it to 1 won't
disable MSAA anymore), so there's no need to expose 0 as a value.

This closes #8939.
2019-09-17 19:06:51 +02:00
SmallJoker
e0a85fae01 Inventory: Undo prediction on drop 2019-09-17 19:02:01 +02:00
DS
1db3d252cf Fix the bgcolor formspec element (#8716) 2019-09-15 17:14:31 +01:00
rubenwardy
1ea9bfc6f7 Fix formspec version backup in prepends losing data 2019-09-15 16:56:11 +01:00
Paramat
23bd5630d0 Dungeons: Clean up parameters, improve structure variety (#8918)
While preserving the general character of dungeon structure.
Slightly increase the range of standard room horizontal size, while
preserving the average horizontal size.
Return to classic maximum large room size of 16x16x16.
Make 1 in 4 dungeons have a 1 in 8 chance for each room being 'large',
making multiple large rooms possible for the first time.
Make 1 in 8 dungeons allow diagonal corridors, to make these a little
more common.
Make corridor width vary from 1 to 2, but forced to 2 if diagonal
corridors are allowed, to make them passable.
Add some comments.
2019-09-14 23:02:07 +01:00
SmallJoker
1de4ca1f9d Built-in formspecs: Force version 1 2019-09-14 20:42:54 +02:00
ANAND
8e42a25e57 client.h: Add missing const's 2019-09-14 20:16:55 +02:00
ANAND
16d6ca3937 LocalPlayer: Fix code-style 2019-09-14 20:16:55 +02:00
ANAND
eea082ee3f client.cpp: Fix code-style in Client::sendPlayerPos 2019-09-14 20:16:55 +02:00
ANAND
e2d6445f2a Fix LocalPlayer::isDead always returning false if player is immortal 2019-09-14 20:16:55 +02:00
ANAND
81c7f0ae04 Send ActiveObjects once right after Init2 2019-09-14 20:16:55 +02:00
SmallJoker
9acd36bf99 Formspecs: Introduce formspec_version to mods 2019-09-14 19:43:08 +02:00
SmallJoker
b0baa698a4 CSM: Fix itemstack:get_meta() 'metadata' indexing error 2019-09-14 19:42:30 +02:00
SmallJoker
23677be951 Load CSM environment after the restrictions are known
Safety-guards for CSM callbacks to abort on a bad implementation
Only run callbacks when the mods are loaded (and with it: builtin)

Duplication checks inside constructors
2019-09-14 19:42:25 +02:00
SmallJoker
720aedb467 InventoryManager: Fix virtual function overload warning 2019-09-09 20:35:45 +02:00
SmallJoker
fae6242d4e Send cumulated inventory changes only each step (#8856)
Applies to player and detached inventories
2019-09-09 19:19:54 +02:00
updatepo.sh
a57f951e02 Update minetest.conf.example 2019-09-09 19:18:30 +02:00
updatepo.sh
ae92bbe508 Update translation strings 2019-09-09 19:18:30 +02:00
Translators
0f758a182b Update from Weblate 2019-09-09 19:18:30 +02:00
Paramat
4682c7be5d Dungeons: Remove non-functional 'projecting dungeons' setting (#8897) 2019-09-08 17:51:34 +01:00
SmallJoker
e97cbcf34d Lua API documentation: Various fixes (#8914)
Remove unusable 'minetest.setting_*' from client_lua_api.txt
lua_api.txt:
- Define the 'mod.conf' format
- More precise 'settingtypes.txt' format reference
- Document special sound files 'player_*damage'
- Group, sort and add 'not_in_creative_inventory' special group
- Define the 'Settings' format
- Warning about incorrect byte saving in 'StorageRef'
- Note about non-persistent player definitions fields
- Better 'leveldiff' and 'level' group description
2019-09-08 18:43:49 +02:00
ANAND
52e3b4bc72 lua_api.txt: Improve privilege definition (#8912) 2019-09-08 12:34:44 +02:00
HybridDog
36bfc67574 Move debug.txt after it grows too big (#8904)
Before opening the file for writing, its file size is tested. If it exceeds 50 MB, it is moved to debut.txt.1, otherwise the log is appended to the old messages. An old debut.txt.1 is removed if it already exists.
2019-09-07 19:38:54 +02:00
SmallJoker
2c9edefde3 label[]: Fix cut-off translated text 2019-09-07 11:15:12 +02:00
sfan5
ea9b241c13 Fix Irrlicht 1.9 support 2019-09-06 18:29:29 +02:00
Paul m. p. P
5c97eeabac doc/client_lua_api: Clarify how client side api and mods start (#8822) 2019-09-05 13:06:22 +02:00
sfan5
c9ec1a8580 Force item entities out of solid nodes (simpler) (#8885) 2019-09-04 22:21:40 +02:00
sfan5
4582691104 Fix Inventory::moveItemSomewhere() 2019-09-03 20:16:36 +02:00
SmallJoker
f3acdd3914 Inventory: Handle removeItem leftovers (#8884) 2019-09-02 19:30:36 +02:00
Muhammad Rifqi Priyo Susanto
cd1d01b8b4 'All Settings': Don't use checkboxes for 'no...' mapgen flags (#7847) 2019-09-01 22:43:41 +01:00
DS
0013f064ad Various fixes to lua_api.txt (#8878) 2019-09-01 20:12:22 +02:00
ANAND
095f26a4f8 particles.cpp: Fix code-style
Mainly spacing and pointer placement
2019-08-31 19:05:53 +02:00
ANAND
96762af3ce clientobject.h: Fix code-style 2019-08-31 19:05:53 +02:00
Pedro Gimeno
9543b84970 Fix rotation of attached particlespawner
Co-authored-by: ANAND <ClobberXD@gmail.com>
2019-08-31 19:05:53 +02:00
DS
049256573b Document world format version 28 (private nodemeta) (#8857) 2019-08-31 14:47:12 +02:00
DS
f3fd85aafb Document luaentity pitch and roll in world format (#8864) 2019-08-30 19:40:32 +02:00
Beha
99ca72e9df Clarify docs regarding pointed_thing and get_pointed_thing_position (#8766) 2019-08-30 19:40:08 +02:00
Paramat
4291961e09 Various settingtypes.txt improvements (#8867)
Improve 'readable' setting names for waving water settings.
Change 'near plane' to 'near clipping plane'.
Document physics settings.

mgv6_spflags:
Change 'new biome system' to 'snowbiomes flag' for clarity.
Add missing 'noflat' flag to default flags.
2019-08-28 01:39:33 +01:00
SmallJoker
1d3f5af7c0 Inventory: Fix missing setModified calls
Previously inv:remove_item and inv:set_list did not trigger an inventory update
2019-08-25 09:46:54 +02:00
Paramat
b53a60c8d5 Mapgen v6: Various mudflow code improvements and bugfixes (#8805)
Calculate 'i' inside 'y' loop to avoid 'i' and 'y' becoming
out of step due to the uses of 'continue'.
Simplify calculation of 'p2d' when coordinates are inverted.
Remove some unnecessary and unreliable 'index out of
voxelmanip' checks.
Move calculation of '&em' out of loops.
For 'Loop further down until not air' code, use y coordinate
to detect being out of voxelmanip, instead of checking index
which did not detect that.
Add and improve comments.
Indent the 'for (;; y--) {' loop.
Improve format and fix codestyle issues.
2019-08-24 20:06:31 +01:00
SmallJoker
fbc8724d59 fontengine: Fix non-gettext builds 2019-08-24 19:11:50 +02:00
SmallJoker
0b4f424f41 Inventory: Send dirty lists where appropriate (#8742)
This change reduces the amount of sent data towards clients. Inventory lists that are already known to the player are skipped, saving quite some data over time.

Raises protocol version to 38 to ensure correct backwards-compatible code.
2019-08-24 19:07:38 +02:00
Paul Ouellette
008b80fe1c Add ItemStack:get_description() to get tooltip (#8847) 2019-08-24 18:38:02 +02:00
sfan5
efbac7e446 Improve occlusion culling in corridors with additional check 2019-08-24 18:37:25 +02:00
sfan5
e8716ffede Restore approximate occlusion check
While less precise, it worked better which is what matters in the end.
2019-08-24 01:41:55 +02:00
DS
b14aa305ce Make Mapgen::spreadLight use a queue (#8838) 2019-08-23 22:16:50 +02:00
Wuzzy
9c725609c3 Fix default hand definition not using wieldhand.png 2019-08-23 19:17:50 +02:00
SmallJoker
6ada090bb0 Occlusion: Check for light_propagates and do mapblock bounds checks 2019-08-23 19:17:43 +02:00
SmallJoker
7d016b4efd Occlusion: Begin cleanup 2019-08-23 19:17:43 +02:00
sfan5
ba8fb774c1 Revert "Don't send position update packet if player is dead"
This reverts commit fb6f1fdcbe.
2019-08-21 15:30:52 +02:00
Paramat
b52a79076d Add player sprite textures back into the engine as a fallback (#8823)
'player.png' and 'player_back.png' are hardcoded into the engine as
the default appearence of the player object, so the textures should
be present in the engine.
This results in a functional fallback sprite player for when a game
has no player appearence related code.
2019-08-20 21:09:44 +01:00
ANAND
75d44ef1e8 lua_api.txt: Add link to Minetest Modding Book (#8826) 2019-08-20 21:15:12 +02:00
SmallJoker
b8131c3415 remove_detached_inventory: Fix segfault during mod load 2019-08-20 19:42:21 +02:00
ANAND
fb6f1fdcbe Don't send position update packet if player is dead 2019-08-20 18:49:06 +02:00
ANAND
3c395d908f Disable autoforward if player is dead 2019-08-20 18:48:28 +02:00
theviper121
ded5da7800 Restore intended functionality to minimap markers (#8819) 2019-08-19 19:18:11 +02:00
Unknown
dea5a152b2 Find LuaJIT headers on vcpkg
luajit headers were moved into a subdirectory to avoid conflicts with plain lua
2019-08-18 18:25:00 +02:00
SmallJoker
d73e458db6 ClientInterface: Use recursive mutex to prevent freeze in on_newplayer() (#8808) 2019-08-17 13:27:28 +02:00
sfan5
13b22e2afb Remove unused function in ReliablePacketBuffer 2019-08-16 20:03:53 +02:00
sfan5
428a4c86e3 Minor refactor of IncomingSplitBuffer 2019-08-16 20:03:53 +02:00
sfan5
fc2f55d931 Drop m_list_size from ReliablePacketBuffer
It's not required and, worse, can lead to bugs.
2019-08-16 20:03:53 +02:00
Paramat
d7c10b66d3 Mapgen v6: Fix mudflow iteration and iterate twice (#8795)
In MapgenV6::flowMud(), the previous implementation of coordinate
inversion caused the 2 inverted mudflow iterations (out of the 3
iterations) to not loop over the area, so only 1 non-inverted
iteration occurred.

Fix this bug but only iterate mudflow twice, as mapgen v6 has only
had 1 iteration for many years. There is now a good balance of 1
non-inverted iteration and 1 inverted iteration.
2019-08-15 20:32:28 +01:00
sfan5
2db0e93f73 network: Stricter handling of split packets 2019-08-15 20:15:22 +02:00
sfan5
c4491165da network: Fix crash in ReliablePacketBuffer on mismatching packets
In the error condition the exception would be thrown before m_list_size
is decremented, causing a nullptr dereference in e.g. popFirst().
2019-08-15 19:18:54 +02:00
DS
082066e813 Fix undeclared global warning because of _ (#8798) 2019-08-14 23:35:47 +02:00
upsilon
b2065756cf Add function minetest.read_schematic 2019-08-14 13:15:41 +02:00
Jozef Behran
bf22184d6e Fix unnecessary exception use in 3 more methods (#8791)
* Fix unnecessary exception use in Server::SendBlocks

The code in this method calls getBlockNoCreate and then
messes around with try...catch to skip blocks which are not
in the memory. Additionally, it repeatedly calls
m_env.getMap() inside this loop. Speed the code up by
extracting the m_env.getMap() out of the loop and getting
rid of the try...catch.

* Fix unnecessary exception use in Server::SendBlock

Another unnecessary try...catch is slowing down
Server::SendBlock. Remove that to speed it up and get a nice
side effect of simplifying the code in question.

* Fix unnecessary exception use in MMVManip::initialEmerge

Remove another unneeded exception usage from
MMVManip::initialEmerge to speed that code up and simplify
it but be careful to not remove the braces as there is a
TimeTaker in use there.
2019-08-13 20:02:50 +02:00
Jozef Behran
72b7a957af Fix unnecessary exception use in Map::getSectorXXX (#8792)
The Map::getSectorNoGenerate throws an exception but no other
code is really dependent on that. Fix the odd instance of
misuse in ClientMap::emergeSector and remove the exception
throwing version of the method along with the "NoEx" suffixes
in the names of these methods.
2019-08-13 19:58:27 +02:00
SmallJoker
539f016c1b Better F6 profiler (#8750)
Update the profiler names to make more sense of what they actually represent
Move the profiler code from header to its source file
Use monospace font to align lines
Format the statistics line to align better with surrounding values
Refresh the profiler each 3 seconds (roughly)
2019-08-13 19:56:55 +02:00
Jozef Behran
e9ceead81d Fix unnecessary exception use in Map::isNodeUnderground
The isNodeUnderground calls getBlockNoCreate which calls
getBlockNoCreateNoEx and throws InvalidPositionException
if the returned value is nullptr, which isNodeUnderground
then catches to return "false". Remove the try..catch in
isNodeUnderground by calling getBlockNoCreateNoEx instead
of getBlockNoCreate and checking the returned value for
nullptr.
2019-08-13 19:40:59 +02:00
Jozef Behran
833e60d8d2 Fix compare between pointer and 0 in unittests
Pointers shall be set to nullptr, not 0, according to the
coding standards. By implication they shall be compared with
nullptr, not 0, too. Fix this code to match that.
2019-08-13 14:44:32 +02:00
Beha
2f879e8bbd Clear old item groups when they are overridden. (#8753)
This fixes overridden items keeping their old groups in the group to
items mapping even after their groups have been changed in lua.
It also prevents a more widespread issue where overriding an item
will add its content ID *twice* to the mapping, resulting in odd
behaviour in features such as ABMs.
2019-08-12 19:18:52 +02:00
rubenwardy
91114b562f Add support for set_formspec_prepend in main menu (#8611) 2019-08-12 19:16:35 +02:00
Rogier
a067d40454 Handle multiple deserialization of a block's entities
This fix consists of two parts:
- Clear the list of stored entities. This has no side-effects.
- Catch the case where active entities exist and print a message.
  Clearing the active entitiy list has side-effects that should
  be handled. (those entities are known to the environment and
  to clients).

  As avoiding those side-effects is more complex, and as this
  problem is not expected to occur (with PR #4847 merged), there
  is no real incentive to implement this ATM.

This issue was a contributing factor to bug #4217. With the other
contributing factor removed (PR #4847), this commit makes sure this
factor does not go unnoticed if it ever happens again.
2019-08-12 19:14:07 +02:00
hannesa2
33fdd48a76 Update Gradle to 5.5.1 (#8771) 2019-08-12 18:59:53 +02:00
Jozef Behran
49f1006183 Fix breakage of non-GLES2 setups (#8774)
The commit 526a9e4b66 breaks
the non-GLES2 setups because the code that is intended to
handle that is behind "elseif()" which is interpreted as
"elseif(false)" and thus the code never gets executed. Fix
that by changing the offending line to else().

Additionally, to avoid breaking the server only build
(which shall not have a dependency on GL/GLU/GLES at all),
enclose the entire block code in if(BUILD_CLIENT).
2019-08-10 23:32:46 +02:00
Paul Ouellette
120155f312 Fix some issues with minetest.clear_craft (#8712)
* Fix some issues with minetest.clear_craft

- Fix memory leak
- Fix crafts with an output count not being cleared when clearing by
  input.
- Fix recipe list being reversed when clearing by input.

* Add CraftInput::empty()
2019-08-10 23:28:00 +02:00
Jozef Behran
86d7f84b89 Merge pull request #8776 from osjc/FixGetNode
Finish getNode cleanup
2019-08-10 19:45:44 +02:00
sfan5
291e7730cf Add player knockback on punch to builtin 2019-08-10 19:44:27 +02:00
sfan5
cf64054390 Implement adding velocity to player from Lua
The intended usecase is knockback, but there's potential for more.
2019-08-10 19:44:27 +02:00
SmallJoker
b19400aa74 Builtin UI: Move box element to ensure correct draw order 2019-08-08 19:33:43 +02:00
ANAND
d1c27c7e80 Allow customizing chat message format (#8529) 2019-08-08 17:04:46 +01:00
ANAND
cc610c74a7 guiVolumeChange: Fix child not being removed 2019-08-08 18:03:35 +02:00
Paramat
37923920a0 Avoid crash caused by, and improve, 'findSpawnPos()' (#8728)
Avoid an unsuitable spawn position (which if outside mapgen limits can
cause a crash) if the main 0-3999 loop reaches its end. Fallback to a
spawn at 0,0,0.
Check the mapgen-returned 'spawn_level' value for being outside limits.
When 'air_count' reaches 2, move back down 1 to spawn in the lower
empty node.
If the spawn position is disallowed by 'objectpos_over_limit()', 'break'
from loop instead of 'continue' because positions above are probably
also over limit.
Reset 'air_count' to 0 if an obstruction is found, to make 'air_count'
consecutive empty nodes.
Allow spawn in 'airlike' drawtype nodes such as mod-added vacuum,
alien atmospheres, fog etc.
Add clarifying comments and improve codestyle.
2019-08-07 22:07:51 +01:00
SmallJoker
0c533dc436 Game: Fix double BS multiplication 2019-08-07 21:23:01 +02:00
Beha
8ffe95913b Fix usage of wrong variable in builtin chat command handling (#8762)
This was introduced in commit 8e75785 and resulted in chat commands not
returning their output text.
2019-08-07 19:32:40 +01:00
ANAND
e788ee283f Client::Interact: Use InteractAction enum instead of numeric constants
This replaces the magic numbers used as interaction modes both client-side and server-side, primarily for the sake of ease-of-readability.
2019-08-07 19:21:14 +02:00
SmallJoker
e462a9a5ef Unify wield item handling (#8677)
This moves the wield item functions to Player and the tool utils for range calculation
Also 'local_inventory' was removed due to redundancy in Client
2019-08-07 19:16:31 +02:00
ANAND
003af74213 guiConfirmRegistration: Set focus to text field (#8761) 2019-08-07 19:15:46 +02:00
ANAND
fa6bc699bc Hide chat when console is open (#8656) 2019-08-07 19:15:33 +02:00
DS
1cef09ff10 Fix inventory_overlay for nodes without inventory_image (#8433) 2019-08-07 12:07:30 +02:00
sfan5
19426387d4 Optimize usage of TOSERVER_GOTBLOCKS packet 2019-08-07 11:32:16 +02:00
Beha
4d7f296717 Do not add group values of zero to group lists. (#8751)
This fixes an issue where when the engine looked up groups (for example,
in ABM node names), NodeDefManager's m_group_to_items would contain nodes
with a group value of zero, resulting in nodes with flammable = 0 being
burned by a fire mod with a group:flammable checking ABM.

It brings consistency to the behaviour described in the api
documentation, where zero and nil groups should be the same.
2019-08-07 10:48:04 +02:00
SmallJoker
233cb86e86 Clean up and fix freetype=false crashes (#8641)
A IGUIFont of type bitmap/vector cannot be converted to CGUITTFont
Fixes various segfaults in gameplay
Shorter font cache code, cleaned up (?)
2019-08-06 21:33:13 +02:00
rubenwardy
8e757859d6 Add luacheck to check builtin (#7895) 2019-08-06 19:30:18 +01:00
Paramat
8da35c22d1 Mapgen Flat: Fix and improve getSpawnLevelAtPoint() (#8756)
Previously, this wrongly returned ground level (a position containing
a solid node) as spawn level.
Return ground level + 2 (+ 2 to spawn above biome 'dust' nodes).
Improve codestyle and make more consistent with generateTerrain().
2019-08-06 02:30:28 +01:00
sfan5
ac856b20bf Update curl dependency in buildbot 2019-08-05 22:48:13 +02:00
sfan5
800fa2d8e7 Fix binary-string confusion in client network code 2019-08-04 20:40:35 +02:00
sfan5
d0246cfdcc Clean up FindOpenGLES2.cmake 2019-08-04 16:12:52 +02:00
sfan5
6c2ded4cac Unify GLES support in gui scaling filter 2019-08-04 16:12:52 +02:00
sfan5
ca363d3ef8 Unify OpenGL ES support 2019-08-04 16:12:52 +02:00
sfan5
526a9e4b66 Let ENABLE_GLES appear in cmake_config.h and change its functionality 2019-08-04 16:12:52 +02:00
rubenwardy
4f7fa8d417 Add formspec testing to test mod in minimal 2019-08-03 19:36:30 +01:00
rubenwardy
9541165752 Add styles to most elements 2019-08-03 19:36:30 +01:00
rubenwardy
ec3795a55c Add style[] tag with button support 2019-08-03 19:36:30 +01:00
rubenwardy
d1a1c5cbf0 Add custom colorable GUIButton implementation 2019-08-03 19:36:30 +01:00
rubenwardy
41ad0f4f20 Fix negative offsets not being supported by container[] 2019-08-03 16:20:15 +01:00
SmallJoker
3ad9a8f3a9 Builtin: Forward old return values
Was forgotten in 69bf964.
2019-08-02 10:20:41 +02:00
Beha
1a97d06b5a Correct ServerActiveObject's virtual getArmorGroups() to be const.
Due to commit ec3142a , UnitSAO's getArmorGroups() did not match
ServerActiveObject's, notably resulting in the lua get_armor_groups() call
returning nothing.
2019-08-01 18:14:37 +02:00
SmallJoker
3ceef8e6a0 Mainmenu: Use textarea in error formspecs 2019-08-01 15:56:28 +02:00
Wuzzy
ec3142af99 Group "immortal" also protects players from damage
Document new meaning of immortal=1 for players

Disable breathing if player is immortal

Hide builtin statbars if player immortal (delayed)

Co-authored-by: ClobberXD <ClobberXD@gmail.com>
2019-08-01 14:45:23 +02:00
sfan5
3296952ae5 Allow toolcaps to override the built-in times for dig_immediate 2019-07-31 18:28:21 +02:00
Paramat
245e628d40 Silence invalid clang format warnings in guiScrollBar.cpp (#8724) 2019-07-31 01:30:17 +01:00
Methacrylon
cdc7eb2d4c Sky: Refactor of moon and sun drawing (#8683)
Split sun and moon render parts from the main render function.
2019-07-30 20:25:47 +02:00
Beha
b8aaef704d Move the clamping of hp/breath when their maximums change to read_object_properties(). (#8689)
This prevents set_properties() calls that have nothing to do with hp_max or breath_max overriding the saved hp before another mod has the chance to set a player's intended hp_max (such as in on_joinplayer).
2019-07-30 17:29:45 +02:00
Zaoqi
2dd645134e README: make -j$(nproc) (#8699) 2019-07-30 09:36:03 +02:00
DS-Minetest
115ef6c09c Rename guiScrollBar to GUIScrollBar 2019-07-29 21:45:39 +02:00
SmallJoker
4aa9a669cb ContentCAO: Fix broken attachments on join (#8701)
What happened:
1) Object data is received. Client begins to read the data
2) Client initializes all its children (gob_cmd_update_infant)
3) Children try to attach to parent (yet not added)
4) Parent initializes, is added to the environment

And somewhere in between, Irrlicht wrecks up the attachments due to the missing matrix node.

The solution here is to:
1) Use the same structure as ServerActiveObject
2) Attach all children after the parent is really initialized
2019-07-29 19:14:07 +02:00
Beha
50052fced5 lua_api.txt clarifications regarding mapgen object index IDs and handles. (#8713) 2019-07-29 14:09:29 +02:00
DS-Minetest
705630e7d0 guiScrollBar: move directly to clicked pos if clicked into tray 2019-07-28 21:43:07 +02:00
SmallJoker
8efa1de835 Check for 'action' field in ABMs & LBMs 2019-07-27 21:13:47 +02:00
Paul Ouellette
fe6c666da2 Prefix RecipePriority elements with PRIORITY_ 2019-07-27 14:42:41 +02:00
Paul Ouellette
395b1b3346 Initialize priority in CraftDefinition constructors
The priority is used by getCraftResult, which may be used before
initHash is called.
2019-07-27 14:42:41 +02:00
Paul Ouellette
b994a35d97 minimal: Move get_craft_result tests to test mod 2019-07-27 14:42:41 +02:00
Pierre-Yves Rollo
c3daf2a8be Fix missing item images clipping in formspecs (#8652)
* Fix clipping of itemimage

* Code style

* More code styling
2019-07-26 19:44:29 +02:00
Alex
a8446d29e8 Document 'wield_item' entity property (#8694) 2019-07-26 19:43:54 +02:00
adrido
af72876921 Make FindCURL ready for vcpkg (#8295)
This allows to find and use curl with the vcpkg toolchain file.
2019-07-26 19:43:43 +02:00
Paramat
ce87ef397f Initialise 'seabed_height' to avoid compilation warning (#8715) 2019-07-26 17:51:53 +01:00
Paramat
0cde6fc552 Re-order mapgens in mainmenu and 'all settings' mapgen selection (#8705)
v6 always last to discourage selection.
Special mapgens flat, fractal, singlenode, next to last. Of these, singlenode
last to discourage selection.
Of the remaining, v5 last due to age, v7 first due to being the default.
2019-07-25 20:46:28 +01:00
Paramat
245a31d6b7 Mgfractal: Make non-fractal terrain optional (#8702)
Enabled by default.
Only allow spawn on fractal, not on seabed terrain.
Various codestyle and comment improvements.
2019-07-25 19:58:35 +01:00
y
ecd20de64d Removed debug.upvaluejoin to prevent leak of insecure environment 2019-07-24 11:43:09 +02:00
Zaoqi
a1401696df Update README.md (#8700) 2019-07-21 00:59:37 +01:00
SmallJoker
69bf964241 Add /help formspec for commands and privileges (#8385)
* Trigger for 'all' as well
* Add description textarea, double-click to copy
2019-07-20 18:22:32 +02:00
Paramat
9e00584730 Improve documentation of mapgen aliases (#8693) 2019-07-20 02:54:42 +01:00
Paramat
76824bac9f Document the deprecation of hardcoded cave liquids (#8692) 2019-07-20 01:03:52 +01:00
sfan5
a6f7848352 travis: Disable macOS build
The build often hits the 50m time limit or fails with spurious errors.
It can be re-enabled when/if we figure out how to solve this.
2019-07-17 15:36:51 +02:00
Lars Hofhansl
9fe3246154 Optimize getting active objects a bit. #8674 2019-07-16 15:55:17 -07:00
HybridDog
41229696be Use vector.dot and vector.cross in vector.angle 2019-07-16 21:44:42 +02:00
HybridDog
71db715ba5 Add vector.dot and vector.cross
Mostly copied from MarkuBu's code
2019-07-16 21:44:42 +02:00
Paramat
458f617575 Dungeons: Make multiple large rooms possible (#8678)
Re-add the random size range for large rooms.
Remove 'first_room_large' bool.
Add 'large_room_chance' parameter that can disable large rooms,
specify 1 large room, or specify a chance for large rooms.
If 1 or a chance is specified, the first generated room is large,
to take advantage of the intersection checks that are done for the
1st room only.
2019-07-16 20:39:58 +01:00
SmallJoker
47492386ec Docs: Clarify where to check for 'protection_bypass' (#8675) 2019-07-14 13:23:38 +02:00
Paramat
0c31946943 Move more dungeon parameter selection to mapgens (#8653)
Move 'num_dungeons' to 'DungeonParams'.
Add new parameter 'num_rooms' to replace 'rooms_min' and 'rooms_max',
so that the mapgen has complete control over the number of rooms.
Add new bool 'first_room_large' so that the mapgen chooses this
instead of a hardcoded 1 in 4 chance.
Add new parameter 'room_size_large' to replace 'room_size_large_min'
and 'room_size_large_max', so that the mapgen has complete control
over this.
2019-07-09 20:38:51 +01:00
DS-Minetest
140aeabd87 Do predict when sneak-place to node with on_rightclick 2019-07-08 14:21:27 +02:00
Lars Hofhansl
0971a14a57 Improve ABM time budget handling. #8645 2019-07-07 23:23:00 -07:00
ANAND
3a8ac9b031 Document ObjectRef:remove under Lua entity (#8659)
This was previously documented under the general ObjectRef section with a note that this won't work on players. So I think this would fit better with Lua entity-only methods.

This PR also changes the title of the Lua entity-only section from `LuaEntitySAO-only` to `Lua entity only`.
2019-07-08 03:27:56 +01:00
Hugo Locurcio
9b067efb99 Improve grammar and formatting in the README
This also clarifies the fact that Minetest saves `minetest.conf`
when closing Minetest for the first time, rather than when starting it
for the first time.

This also fixes the default key for the pitch move mode which is now P.
2019-07-05 04:56:15 +01:00
Paramat
95371c16e9 Update biome definition dungeon node documentation (#8650) 2019-07-01 22:21:17 +01:00
Paramat
bb14b7e956 Dungeongen: Remove most hardcoded dungeon nodes (#8594)
Biome-defined dungeon nodes was added as a feature to MT 5.0.0.
So now remove most of the hardcoded dungeon node code that assumes a
game has stone, sandstone, desert stone, and no other stone types.
If biome-defined dungeon nodes are not found, dungeon nodes fall back
to the 'cobble' mapgen alias if present, if not present they fall back
to biome-defined 'stone'.
Remove now-unnecessary mapgen aliases from MapgenBasic. Non-mgv6 games
now only need to define 3 to 5 mapgen aliases.

Document dungeon parameters.

Make c_lava_source fallback to c_water_source as both are used as cave
liquids.
2019-06-30 22:55:20 +01:00
Vitaliy
93f7e10e0d Optimize and unify mesh processing (#7851) 2019-06-28 03:22:16 +01:00
v-rob
5e7004e7af Add compatible, consistent coordinate system to FormSpecs. (#8524) 2019-06-27 13:40:49 +01:00
ANAND
91d244c522 Increase upper limit of display_gamma to 10 (#8618) 2019-06-27 04:04:12 +01:00
rubenwardy
429a989648 Add support for 9-sliced backgrounds (#8600)
9-slice textures are commonly used in GUIs to allow scaling them to match any resolution without distortion.

https://en.wikipedia.org/wiki/9-slice_scaling
2019-06-22 16:03:54 +02:00
SmallJoker
4e3c1916f7 Fix segfault on quitting with open node formspec (#8608) 2019-06-21 21:00:30 +02:00
Pierre-Yves Rollo
39c54e13c3 Improve buildbot script
PR created under the employment of EvidenceBKidscode

* Variables to set git repositories urls (allows to build from another repo)
* Variables to set git branch to build from (allows to build from non-master branch)
* Variables to change built name
* Make -j uses the proper number of processors (autodetect)
* Changed toolchain from win32 to adpat it to non-debian distros
2019-06-21 01:46:00 +01:00
Markus Mattes
e3738c2f61 Fix handling of --color and --worldlist command line arguments
They verify the provided value and error if a wrong value got provided
command line description for color was differnt on win32 but  code did not handle any differenc
extended the command line description for world and worldname that it is clear that they only start a local game if used with --go

Fixes #7875
2019-06-21 01:29:35 +01:00
Markus Mattes
7eb110d503 Exclude vscode editor files from source 2019-06-21 01:29:35 +01:00
Vilhelm Prytz
cf9108433c Update README copyright notice to 2019 (#8606) 2019-06-19 01:09:16 +01:00
Paramat
5d4850a7ce Mapgen Carpathian: Add optional rivers (#7977)
Rivers are disabled by default and will not be added to existing worlds.
Rewrite getSpawnLevelAtPoint() to be simpler and more consistent with
generateTerrain().
2019-06-19 01:06:08 +01:00
stujones11
95a37efc31 Android: Use system provided path for default TMPFolder setting (#8505) 2019-06-15 15:12:59 +02:00
rubenwardy
f2c73def4b Update Github templates (#8593) 2019-06-13 15:09:15 +01:00
Paul Ouellette
4c11574e9d Use CDB author and name in installed package's config (#8550)
They are used for tracking the package, so should match ContentDB.
2019-06-10 19:49:00 +02:00
SmallJoker
f1f9361bc8 Settings: Disallow space characters entirely
Lua API:
> Setting names can't contain whitespace or any of ="{}#
2019-06-10 18:30:59 +02:00
SmallJoker
e2f8f4da83 Formspecs: Close on metadata removal (#8348)
Formspecs will now close as soon the formspec string in the node metadata turns invalid.
2019-06-10 13:01:07 +02:00
SmallJoker
e40be619f2 Add disable_jump to liquids and ladders (#7688)
Remove second nodedef check by improving the colliding node detection
Also remove the 2nd check in old_move, correct standing node a bit
2019-06-10 13:00:35 +02:00
adrido
bd6f1cca9d Add compatibility to vcpkg buildsystem (#8317) 2019-06-10 02:56:55 +01:00
Thomas Rudin
9a07792f4d Save forceloaded blocks file periodically (#8535)
saves the forceloaded blocks periodically.
checks every 10 seconds if the forceloaded blocks got changed in-game
and persists them on-disk if that's the case
2019-06-10 01:07:33 +01:00
SmallJoker
a687efa6df Damage: Play no damage sound when immortal (#8350)
Add isImmortal server-side for proper enable_damage handling
Rework log messages
2019-06-09 11:25:41 +02:00
DS
2ba6785f09 Remove modstore leftovers. Fix core.show_path_select_dialog documentation (#8572)
This was forgotten in #5852.
2019-06-07 22:12:20 +02:00
SmallJoker
cb00632e23 HTTP API: Allow binary downloads and headers (#8573)
Add minetest.features.httpfetch_binary_data
2019-06-06 19:13:29 +02:00
Paramat
7379aa74cf Dungeons: Settable density noise, move number calculation to mapgens (#8473)
Add user-settable noise parameters for dungeon density to each mapgen,
except V6 which hardcodes this noise parameter.

Move the calculation of number of dungeons generated in a mapchunk out
of dungeongen.cpp and into mapgen code, to allow mapgens to generate
any desired number of dungeons in a mapchunk, instead of being forced
to have number of dungeons determined by a density noise.

This is more flexible and allows mapgens to use dungeon generation to
create custom structures, such as occasional mega-dungeons.
2019-06-01 20:50:43 +01:00
SmallJoker
a1459a9eac Fix persistent ^[brighten after damage again (#5739)
The old texture modifier is restored by passing `m_previous_texture_modifier`.
Either copy it manually or let the function parameter do that.

Victims so far:
8e0b80a Apr 2018
eb2bda7 May 2019
2019-05-26 09:54:26 +02:00
David G
40dadecb6e override.txt: Fix crash due to CRLF endings (#8439) 2019-05-25 18:01:55 +02:00
SmallJoker
627a96cd99 Do not drag-place stack into 'craftpreview' slot (#8514) 2019-05-25 17:41:35 +02:00
stujones11
b917ea4723 Add IGUIScrollbar implementation with variable bar sizes (#8507) 2019-05-24 16:42:05 +01:00
SmallJoker
a2848c9cde Fix forgotten PlayerSAO cast in a90f2ef 2019-05-21 21:37:47 +02:00
DS
9d09c87f13 Make autoforward simulate the 'up' key (#8249) 2019-05-21 19:50:00 +01:00
ANAND ツ
a90f2efb12 Check for out-of-bounds breath when setting breath_max (#8493) 2019-05-21 19:37:58 +02:00
Paul Ouellette
920bd3b16f Fix API site build (#8551) 2019-05-21 19:37:10 +02:00
SmallJoker
cfef466d4e l_mapgen.cpp: Fix LINT broken since b1b40fe 2019-05-21 19:16:01 +02:00
HybridDog
12e3d3d12f Prioritise craft recipes
When multiple recipes are applicable, the recipes are prioritised in this order:
toolrepair < shapeless with groups < shapeless < shaped with groups < shaped
For cooking and fuel, items are prioritised over item groups
2019-05-20 20:59:51 +02:00
HybridDog
1604b949fd Test crafting hash type only once for a recipe 2019-05-20 20:59:36 +02:00
Paramat
b1b40fef16 Allow multiple cave liquids in a biome definition (#8481)
This allows games to specify biome cave liquids and avoid the old
hardcoded behaviour, but preserves the ability to have multiple
cave liquids in one biome, such as lava and water.

When multiple cave liquids are defined by the biome definition,
make each entire cave use a randomly chosen liquid, instead of
every small cave segment using a randomly chosen liquid.

Plus an optimisation:
Don't place nodes if cave liquid is defined as 'air'
2019-05-18 21:13:14 +01:00
Carles Pastor Badosa
6cb6aea969 Add content_rating tag to appdata (#8538)
This tag allows software stores (KDE discover, etc) to filter and know whether applications are suitable for young users.
2019-05-18 17:19:56 +02:00
Jozef Behran
eb2bda7d0b Optimize string (mis)handling (#8128)
* Optimize statbar drawing

The texture name of the statbar is a string passed by value.
That slows down the client and creates litter in the heap
as the content of the string is allocated there. Convert the
offending parameter to a const reference to avoid the
performance hit.

* Optimize texture cache

There is an unnecessary temporary created when the texture
path is being generated. This slows down the cache each time
a new texture is encountered and it needs to be loaded into
the cache. Additionally, the heap litter created by this
unnecessary temporary is particularly troublesome here as
the following code then piles another string (the resulting
full path of the texture) on top of it, followed by the
texture itself, which both are quite long term objects as
they are subsequently inserted into the cache where they can
remain for quite a while (especially if the texture turns
out to be a common one like dirt, grass or stone).

Use std::string.append to get rid of the temporary which
solves both issues (speed and heap fragmentation).

* Optimize animations in client

Each time an animated node is updated, an unnecessary copy of
the texture name is created, littering the heap with lots of
fragments. This can be specifically troublesome when looking
at oceans or large lava lakes as both of these nodes are
usually animated (the lava animation is pretty visible).
Convert the parameter of GenericCAO::updateTextures to a
const reference to get rid of the unnecessary copy.

There is a comment stating "std::string copy is mandatory as
mod can be a class member and there is a swap on those class
members ... do NOT pass by reference", reinforcing the
belief that the unnecessary copy is in fact necessary.
However one of the first things the code of the method does
is to assign the parameter to its class member, creating
another copy. By rearranging the code a little bit this
"another copy" can then be used by the subsequent code,
getting rid of the need to pass the parameter by value and
thus saving that copying effort.

* Optimize chat console history handling

The GUIChatConsole::replaceAndAddToHistory was getting the
line to work on by value which turns out to be unnecessary.
Get rid of that unnecessary copy by converting the parameter
to a const reference.

* Optimize gui texture setting

The code used to set the texture for GUI components was
getting the name of the texture by value, creating
unnecessary performance bottleneck for mods/games with
heavily textured GUIs. Get rid of the bottleneck by passing
the texture name as a const reference.

* Optimize sound playing code in GUIEngine

The GUIEngine's code receives the specification of the sound
to be played by value, which turns out to be most likely a
mistake as the underlying sound manager interface receives
the same thing by reference. Convert the offending parameter
to a const reference to get rid of the rather bulky copying
effort and the associated performance hit.

* Silence CLANG TIDY warnings for unit tests

Change "std::string" to "const std::string &" to avoid an
unnecessary local value copy, silencing the CLANG TIDY
process.

* Optimize formspec handling

The "formspec prepend" parameter was passed to the formspec
handling code by value, creating unnecessary copy of
std::string and slowing down the game if mods add things like
textured backgrounds for the player inventory and/or other
forms. Get rid of that performance bottleneck by converting
the parameter to a const reference.

* Optimize hotbar image handling

The code that sets the background images for the hotbar is
getting the name of the image by value, creating an
unnecessary std::string copying effort. Fix that by
converting the relevant parameters to const references.

* Optimize inventory deserialization

The inventory manager deserialization code gets the
serialized version of the inventory by value, slowing the
server and the client down when there are inventory updates.
This can get particularly troublesome with pipeworks which
adds nodes that can mess around with inventories
automatically or with mods that have mobs with inventories
that actively use them.

* Optimize texture scaling cache

There is an io::path parameter passed by value in the
procedure used to add images converted from textures,
leading to slowdown when the image is not yet created and
the conversion is thus needed. The performance hit is
quite significant as io::path is similar to std::string
so convert the parameter to a const reference to get rid of
it.

* Optimize translation file loader

Use "std::string::append" when calculating the final index
for the translation table to avoid unnecessary temporary
strings. This speeds the translation file loader up
significantly as std::string uses heap allocation which
tends to be rather slow. Additionally, the heap is no
longer being littered by these unnecessary string
temporaries, increasing performance of code that gets
executed after the translation file loader finishes.

* Optimize server map saving

When the directory structure for the world data is created
during server map saving, an unnecessary value passing of
the directory name slows things down. Remove that overhead
by converting the offending parameter to a const reference.
2019-05-18 17:19:13 +02:00
ANAND ︻气デ═一
568694122c Revert "Inventory: Make addItem for empty ItemStacks respect max stack size" (#8519)
Revert commit e6a9e60
2019-05-12 18:07:15 +01:00
ANAND ︻气デ═一
06a749c386 Move HTTP request logging to infostream (#8526) 2019-05-12 17:55:14 +01:00
ANAND ︻气デ═一
8e3b63bd28 Define operators == and != for ItemStack 2019-05-11 18:48:27 +02:00
ANAND
72feab081c builtin/../register.lua: Abort make_wrap_deregistration if param is invalid 2019-05-04 12:56:19 +02:00
ANAND
96f250ed8f minimal: Fix crash due to assertion fail 2019-05-03 14:44:05 +02:00
ANAND
e32a630937 Better document behavior of on_punchplayer
Esp. the fact that it's invoked even if the punched player is dead
2019-04-29 14:08:34 +02:00
ANAND
c4578aefe7 PlayerSAO::setHP - Don't call on_hpchange callbacks if HP hasn't changed 2019-04-29 14:08:34 +02:00
Paramat
ad8d68c06a Remove unnecessary CSM warning (#8485) 2019-04-28 00:44:26 +01:00
sofar
b839a6dd54 Force send a mapblock to a player (#8140)
* Force send a mapblock to a player.

Send a single mapblock to a specific remote player.

This is badly needed for mods and games where players are teleported
into terrain which may be not generated, loaded, or modified
significantly since the last player visit.

In all these cases, the player currently ends up in void, air, or
inside blocks which not only looks bad, but has the effect that the
player might end up falling and then the server needs to correct for
the player position again later, which is a hack.

The best solution is to send at least the single mapblock that the
player will be teleported to. I've tested this with ITB which does this
all the time, and I can see it functioning as expected (it even shows
a half loaded entry hallway, as the further blocks aren't loaded yet).

The parameter is a blockpos (table of x, y, z), not a regular pos.

The function may return false if the call failed. This is most likely
due to the target position not being generated or emerged yet, or
another internal failure, such as the player not being initialized.

* Always send mapblock on teleport or respawn.

This avoids the need for mods to send a mapblock on teleport or
respawn, since any call to `player:set_pos()` will pass this code.
2019-04-28 00:42:13 +01:00
ANAND
d71e1e0949 Improve readability of debug menu by using '|' (#8488)
* Improve readability of debug menu by using '|'

* Restore whitespace to separate yaw and cardinal direction

Co-Authored-By: ClobberXD <ClobberXD@gmail.com>
2019-04-27 12:45:44 +02:00
ANAND
d0f0ceaf66 Range-limit value passed to PlayerSAO::set{HP|Breath} (#8264) 2019-04-27 12:45:20 +02:00
Muhammad Rifqi Priyo Susanto
695d9edcd4 Use player as starting point instead of camera when pointing node (#8261)
Same pointing area on both camera modes.
This fix is inapplicable for non-crosshair input.
2019-04-27 12:44:56 +02:00
SmallJoker
f409f44765 Correct the checkbox selection box position (#8246)
Remove m_btn_height dependency, replace with the text and checkbox size.
2019-04-27 00:56:31 +01:00
ANAND
66ecfb5916 CMakeLists.txt: Remove references to Minecraft and Infiniminer (#8487) 2019-04-26 19:07:32 +02:00
stujones11
cff1e9ca27 Android: Clear chat open flag on cancel or completion (#8478) 2019-04-19 12:06:47 +02:00
paramat
38b94f248a Attend to review, re-arrange blank lines, update lua_api.txt 2019-04-14 22:21:51 +01:00
Pedro Gimeno
12a63021d0 Fix regression in automatic_face_movement_max_rotation_per_sec
Values <= 0 should make the yaw change instant. This worked in 0.4.16 but was broken in 089f594582.

Per bug report by oil_boi_minetest on IRC.
2019-04-14 22:21:51 +01:00
Jozef Behran
007ce24a11 Various network performance improvements (#8125)
* Optimize packet construction functions

Some of the functions that construct packets in
connection.cpp are using a const reference to get the raw
packet data to package and others use a value passed
parameter to do that. The ones that use the value passed
parameter suffer from performance hit as the rather bulky
packet data gets a temporary copy when the parameter is
passed before it lands at its final destination inside the
newly constructed packet. The unnecessary temporary copy
hurts quite badly as the underlying class (SharedBuffer)
actually allocates the space for the data in the heap.

Fix the performance hit by converting all of these value
passed parameters to const references. I believe that this
is what the author of the relevant code actually intended
to do as there is a couple of packet construction helper
functions that already use a const reference to get the
raw data.

* Optimize packet sender thread class

Most of the data sending methods of the packet sender thread
class use a value passed parameter for the packet data to be
sent. This causes the rather bulky data to be allocated on
the heap and copied, slowing the packet sending down. Convert
these parameters to const references to avoid the performance
hit.

* Optimize packet receiver thread class

The packet receiver and processor thread class has many
methods (mostly packet handlers) that receive the packed data
by value. This causes a performance hit that is actually
worse than the one caused by the packet sender methods
because the packet is first handed to the processPacket
method which looks at the packet type stored in the header
and then delegates the actual handling to one of the
handlers. Both, processPacket and all the handlers get the
packet data by value, leading to at least two unnecessary
copies of the data (with malloc and all the slow bells and
whistles of bulky classes).

As there already is a few methods that use a const reference
parameter for the packet data, convert all this value passed
packets to const references.
2019-04-14 21:56:38 +01:00
Paramat
4d2ad7c2b2 World start time: Move to first full light (day night ratio = 1000) (#8410)
6125 is the time of first full light according to 'get_node_light()',
and the time of first full light visually when basic shaders are on.
This is the optimum default new world start time, taking all possible
games into account.
The previous time assumed a game similar to Minetest Game. Games
should set this setting themselves according to their needs.
2019-04-13 01:46:38 +01:00
Vitaliy
faa419fc8b Add Irrlicht-specific smart pointer (#6814) 2019-04-12 17:27:39 +01:00
Paul Ouellette
bb7afd306a Add Mkdocs API site (#8133)
* Add MkDocs API site
2019-04-12 14:29:29 +02:00
Paul Ouellette
22ad820aa4 Add node field to PlayerHPChangeReason table (#8368) 2019-04-11 20:45:39 +01:00
Paramat
1e5f2e0f13 Nodedef 'drop' documentation: Improve, add tool filtering (#8458) 2019-04-09 03:20:27 +01:00
ANAND
8306f7d2e2 util/hex.h: Remove whitespace-only line (#8460) 2019-04-08 19:40:02 +01:00
Paramat
0cc85a7dc6 daynightratio.h: Improve codestyle, minor optimisations (#8453) 2019-04-08 00:37:52 +01:00
Paramat
a222ff4c02 Android settings: Use 'simple' leaves instead of 'fancy' (#8440)
'Fancy' leaves are intensive to render.
Also remove the unnecessary duplicated setting of 'chunksize'.
2019-04-07 19:20:00 +01:00
Jozef Behran
0c90ab4f6c Optimize random turns in dungeongen (#8129)
It turns out there is no need to return the new value and
preserve the old one in random_turn, the procedure can be
made to modify the value in-place. This saves quite a bunch
of parameter and return value copying.
2019-04-07 19:08:27 +02:00
adrido
25f231a0e0 Find PostgreSQL correctly (#8435) 2019-04-07 18:45:25 +02:00
starling13
1db4ae96b1 util/hex.h: Reserve result space in hex_encode()
Reserve enough space for the result of hex_encode() to eliminate reallocations
2019-04-07 12:01:42 +02:00
ANAND
3deaa7cf57 Add deprecation warnings for ObjectRef:get/set_attribute (#8443) 2019-04-07 12:00:57 +02:00
Paramat
5b8363af00 Stabilise 'day night ratio' to fix object brightness flicker (#8417)
Previously, when basic shaders were enabled, the function
time_to_daynight_ratio() returned values jumping between 149 and 150
between times 4375 and 4625, and values jumping between 999 and 1000
between times 6125 and 6375, (and the corresponding times at sunset)
due to tiny float errors in the interpolation code.

This caused the light level returned by blend_light() to jump between
14 and 15, which became noticeable recently as those light levels were
given different visual brightnesses.

Add early returns to avoid the problematic interpolation, and to
avoid unnecessary running of the loop.
2019-04-04 23:30:10 +01:00
ANAND
d111865890 Change sign of pitch angle in debug menu (#8438)
Co-Authored-By: ClobberXD <ClobberXD@gmail.com>
2019-04-04 22:42:18 +01:00
rubenwardy
4f7674d448 Change pitch fly binding to 'P', add to change keys menu (#8314) 2019-04-03 21:37:30 +01:00
Loic Blot
a4677496f3 Fix comments 2019-03-31 20:49:39 +02:00
Loïc Blot
64bdd4b509 Create ServerThread earlier in the startup process 2019-03-31 20:49:39 +02:00
Loïc Blot
b55fc3d773 mapgen: drop mapgen id from child mapgens.
This id must be owned by the child mapgen and never be set to a misc value by a developer

Also use nullptr in some places
2019-03-31 20:49:39 +02:00
Loïc Blot
b3716a03a6 EmergeManager::initMapgens use FATAL_ERROR if and drop boolean return
We never handle the boolean return, also init twice is a coding error, not a runtime error
2019-03-31 20:49:39 +02:00
HybridDog
ab322fc5aa Use unordered_map instead of map for craft definitions (#8432) 2019-03-31 19:26:17 +02:00
DS
ad75dba87b Optimize core.after in a simple way (#8351) 2019-03-27 21:05:50 +01:00
Paramat
42e1a12714 Require 'waving = 3' in a nodedef to apply the liquid waving shader (#8418)
Makes the liquid waving shader per-nodedef like waving leaves/plants,
instead of being applied to all liquids.
Like the waving leaves/plants shaders, the liquid waving shader can
also be applied to meshes and nodeboxes.

Derived from a PR by t0ny2.
2019-03-27 00:18:43 +00:00
Paramat
5e7662ca16 Dungeons: Do not remove nodes that have 'is_ground_content = false' (#8423)
Like randomwalk caves, preserve nodes that have 'is_ground_content = false',
to avoid dungeons that generate out beyond the edge of a mapchunk destroying
nodes added by mods in 'register_on_generated()'.

Issue discovered by, and original PR by, argyle77.
2019-03-26 03:56:57 +00:00
rubenwardy
d0a1a29ab3 Prevent multi-line chat messages server-side (#8420) 2019-03-26 01:18:52 +00:00
Paramat
38ea0890ec Document 'highly unstable' mapgens instead of 'stable' mapgens (#8404) 2019-03-20 04:37:33 +00:00
sfan5
5b99abb847 Fix texture rotation for wallmounted nodeboxes
fixes #8358
2019-03-19 22:36:51 +01:00
sfan5
426bdba7fb httpfetch: Disable IPv6 here too if requested by settings (#8399) 2019-03-18 15:06:27 +01:00
Paramat
c0fb5dd317 num_emerge_threads: Initialise value to cope with setting syntax error (#8396) 2019-03-18 11:19:53 +01:00
paramat
77cfc4fcd1 num_emerge_threads: Fix documentation of automatic selection 2019-03-17 22:27:36 +01:00
Wuzzy
9f1b98b997 Add newline before itemstring in item tooltip (#8213) 2019-03-17 13:55:02 +01:00
ANAND
d50feb89de core.after: Improve assertion message (#8388) 2019-03-17 10:25:47 +01:00
ANAND
7f1c2b8a00 Builtin: Add vector.angle(). Returns the angle between 2 vectors (#7738) 2019-03-17 02:05:03 +00:00
Paramat
eadcbe474a Lua_api.txt: Document blockpos, coordinate conversion, map terminology (#8376)
Also fix and improve LVM 'calc_lighting()' warning.
2019-03-16 05:04:11 +00:00
Paramat
ee57b63008 num_emerge_threads: Warn of crashes when > 1 (#8357) 2019-03-14 13:49:33 +01:00
Loïc Blot
02a23892f9 LINT fixes since recent tooling update 2019-03-14 12:30:13 +01:00
Loïc Blot
a6a04c4b5b Update our tooling (Clang 5 -> 7, GCC 7 -> 8)
This change permits to use up-to-date compilers, clang-tidy and
clang-format

It also refactor the tidy/format step to drop the binary selection from
scripts and perform it directly in travis
2019-03-14 12:30:13 +01:00
Paramat
aafbdd442f Valleys mapgen code rewrite (#8101)
Shorter, simpler, clearer and more consistent with other mapgens,
while preserving functionality.
Base terrain shape is unchanged.
With the 'vary river depth' option disabled, river surface level
is unchanged.
Behaviour of the 4 heat/humidity/river depth options is very
slightly changed due to bugfixes and code cleanup (the mapgen is
'unstable').
Apply heat and humidity gradients above water_level instead of
above y = 0.
2019-03-14 00:27:16 +00:00
Loïc Blot
e22a69d61a Drop GUIConfirmRegistration::m_address unused field 2019-03-12 16:53:21 +01:00
rubenwardy
38f6e7a198 Fix cast from const by accessing string data directly (#8354)
Fixes #8327
2019-03-12 08:58:02 +01:00
rubenwardy
1e3e4fb649 HPChange Reason: Fix push after free, and type being overwritten (#8359)
* HPChange Reason: Fix push after free, and type being overwritten

Fixes #8227 and #8344
2019-03-12 08:56:56 +01:00
rubenwardy
3b25b807f3 Fix serialization of std::time_t by casting to u64 first (#8353)
Fixes #8332
2019-03-10 18:53:02 +00:00
DS
77961aa73d Document the float special group (#8306) 2019-03-10 11:16:35 +01:00
Ragulan R
c8914664a3 Display pitch angle in debug menu (#8321) 2019-03-10 11:16:27 +01:00
Paramat
0b492f82f7 Confirm registration GUI: Remove positional strings to fix Windows bug (#8258)
Positional strings don't work on some Windows builds.
Remove server address string, leave player name string present.
2019-03-10 01:49:03 +00:00
HybridDog
431d8a9b83 Abort when trying to set a not registered node (#7011)
I removed the MapNode constructor which takes a nodename and gives the node's id or CONTENT_IGNORE
The code which used this constructor (two places) now handles the situation of not registered nodes correctly:
* minetest.set_node and similar functions make minetest crash when a not registered node is passed
* reverting a node with rollback aborts if the node is not registered
2019-03-07 08:31:25 +01:00
HybridDog
3066d76e33 World config: Make depends easier to read (#7396)
* Do not always show every depends textfieds

When there are no dependencies, it does not longer show an empty list.

* Adjust the list height to avoid a scrollbar when possible

* change minimum height and no dependencies message

* Do not get depends for modpacks
2019-03-07 08:23:03 +01:00
Jozef Behran
bb35d06225 Optimize string handling in path search (#8098)
Use "append" method to construct the various game paths
instead of wasteful string concatenation. Additionally, use a
temporary to extract and reuse a result of a few common
subexpressions to further reduce the overhead.
2019-03-07 08:20:33 +01:00
Jozef Behran
007c8440d7 Optimize interaction distance checker (#8193)
The "what" parameter is being passed by value, most likely by
accident as the type is "const std::string". Convert it to a
reference by adding the missing "&".
2019-03-07 08:19:13 +01:00
sfan5
557afdc429 Update a few dependency versions for buildbot (#8319) 2019-03-07 08:17:01 +01:00
rubenwardy
ac86d04784 Fix detach inventory serialisation (#8331) 2019-03-07 07:41:21 +01:00
rubenwardy
82c6363559 Fix incorrect string length check after cast 2019-03-06 22:24:39 +00:00
rubenwardy
c735497a65 Fix clang tidy error due to incorrect use of quotes for character 2019-03-06 14:41:37 +00:00
Paramat
1c87d57e1d Change 'num_emerge_threads' default to 1 (#8303) 2019-03-05 22:58:38 +00:00
HybridDog
a7c5dc50e5 Add math.factorial (#8298) 2019-03-05 10:11:21 +01:00
Loic Blot
250420e566 Add Android keystore to the repository
Password is not included :)
2019-03-05 08:35:15 +01:00
DS
60ab2d94f0 Add sounds for falling and attached nodes (#7719)
* Add sounds for falling and attached nodes

The sound specified in `node_definition.sounds.fall` is used.
When a falling node is spawned at a position or an attached node drops, the sound is played at this position.

* allow all sorts of soundspecs
2019-03-05 08:17:48 +01:00
HybridDog
ee698770b9 Fix --color command line parameter ignorance (#7173)
* Fix color command line parameter ignorance

* coloured log: Support detecting the tty on windows

* Print an error message when setting something invalid as color mode instead of silently using mode never

* Revert "coloured log: Support detecting the tty on windows"

This reverts commit 4c9fc6366487ac0e6799e181796ca594797bb6f8.
It didn't work for travis and belongs to a separate PR

* Allow adjusting the log color with an environment variable

If --color is not passed to minetest,  is used to decide on the log colorization.
Minetest settings can not be used instead of an environment variable because logs may appear before loading them.

* fix empty if body
2019-03-05 08:14:33 +01:00
Benjamin Lindley
e19565c170 Replace for loop with call to standard library function (#8194)
This loop makes multiple passes over m_stack (type std::list) in order to remove all elements with a specified value. Replacing the loop with a call to std::list::remove does the same job, but in only one pass.
2019-03-05 08:13:15 +01:00
rubenwardy
5d2624ab82 Hide uninstall package button on unmodifiable paths (#8255) 2019-03-05 08:12:58 +01:00
sofar
b5defcffba Add referer to remote media requests. (#8135)
This sends the following header to a remote media server:

    Referer: minetest://<server_name>:port

This was verified with CTF and the Minetest Public Remove Media
server. If the servername was a plain IPv6 address it will
contain `:` characters and will be encapsulated in `[]` to
be a valid URI.
2019-03-05 08:12:02 +01:00
sofar
61e5fbab72 getS16NoEx() returns true unless syntactical error in conf. (#8304)
The getS16NoEx() handler will return true unless there is a
`[num_emerge_threads]` line in the `minetest.conf` at which
point the excption handler part is reached. Due to the fact that
`defaultsettings.cpp` has a default value set for this setting,
that never will happen.

Because of this, the code will never check the number of threads on
the system, and keep `nthreads = 0`. If that happens, the value is
changed to `1` and only 1 emerge thread will be used.

The default should be set to `1` instead, due to the potential unsafe
consequences for the standard sqlite map files, but that should be a
separate commit that also adds documentation for that setting. This
commit focuses on removing this `hiding` bug instead.
2019-03-05 08:11:13 +01:00
sfan5
51662dabb4 Continue with 5.1.0-dev 2019-03-04 23:43:18 +01:00
1078 changed files with 189759 additions and 60026 deletions

View File

@@ -13,6 +13,7 @@ BraceWrapping:
AfterUnion: true
BeforeCatch: false
BeforeElse: false
FixNamespaceComments: false
AllowShortIfStatementsOnASingleLine: false
IndentCaseLabels: false
AccessModifierOffset: -8

View File

@@ -1,4 +1,5 @@
Checks: '-*,modernize-use-emplace,modernize-use-default-member-init,modernize-use-equals-delete,modernize-use-equals-default,modernize-return-braced-init-list,modernize-loop-convert,modernize-avoid-bind,misc-throw-by-value-catch-by-reference,misc-string-compare,misc-inefficient-algorithm,misc-inaccurate-erase,misc-incorrect-roundings,misc-unconventional-assign-operator,bugprone-suspicious-memset-usage,performance-*'
Checks: '-*,modernize-use-emplace,modernize-avoid-bind,misc-throw-by-value-catch-by-reference,misc-unconventional-assign-operator,performance-*'
WarningsAsErrors: '-*,modernize-use-emplace,performance-type-promotion-in-math-fn,performance-faster-string-find,performance-implicit-cast-in-loop'
CheckOptions:
- key: modernize-use-default-member-init.UseAssignment
value: True
- key: performance-unnecessary-value-param.AllowedTypes
value: v[23]f;v[23][su](16|32)

View File

@@ -1,10 +1,11 @@
##### Issue type
<!-- Pick one below and delete others -->
- Bug report
- Feature request
- Documentation issue
- Build issue
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: Unconfirmed bug
assignees: ''
---
##### Minetest version
<!--
Paste Minetest version between quotes below

View File

@@ -0,0 +1,25 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: Feature request
assignees: ''
---
## Problem
A clear and concise description of what the problem is.
ie: Why is this needed?
Ex. I'm always frustrated when [...]
## Solutions
A clear and concise description of what you want to happen.
## Alternatives
A clear and concise description of any alternative solutions or features you've considered.
## Additional context
Add any other context or screenshots about the feature request here.

19
.github/PULL_REQUEST_TEMPLATE.md vendored Normal file
View File

@@ -0,0 +1,19 @@
Add compact, short information about your PR for easier understanding:
- Goal of the PR
- How does the PR work?
- Does it resolve any reported issue?
- If not a bug fix, why is this PR needed? What usecases does it solve?
## To do
This PR is a Work in Progress / Ready for Review.
<!-- ^ delete one -->
- [ ] List
- [ ] Things
- [ ] To do
## How to test
<!-- Example code or instructions -->

20
.github/SECURITY.md vendored Normal file
View File

@@ -0,0 +1,20 @@
# Security Policy
## Supported Versions
We only support the latest stable version for security issues.
See the [releases page](https://github.com/minetest/minetest/releases).
## Reporting a Vulnerability
We ask that you report vulnerabilities privately, by contacting a core developer,
to give us time to fix them. You can do that by emailing one of the following addresses:
* celeron55@gmail.com
* rubenwardy@minetest.net
Depending on severity, we will either create a private issue for the vulnerability
and release a patch version of Minetest, or give you permission to file the issue publicly.
For more information on the justification of this policy, see
[Responsible Disclosure](https://en.wikipedia.org/wiki/Responsible_disclosure).

289
.github/workflows/build.yml vendored Normal file
View File

@@ -0,0 +1,289 @@
name: build
# build on c/cpp changes or workflow changes
on:
push:
paths:
- 'lib/**.[ch]'
- 'lib/**.cpp'
- 'src/**.[ch]'
- 'src/**.cpp'
- '**/CMakeLists.txt'
- 'cmake/Modules/**'
- 'util/buildbot/**'
- 'util/ci/**'
- '.github/workflows/**.yml'
pull_request:
paths:
- 'lib/**.[ch]'
- 'lib/**.cpp'
- 'src/**.[ch]'
- 'src/**.cpp'
- '**/CMakeLists.txt'
- 'cmake/Modules/**'
- 'util/buildbot/**'
- 'util/ci/**'
- '.github/workflows/**.yml'
jobs:
# This is our minor gcc compiler
gcc_6:
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2
- name: Install deps
run: |
sudo apt-get install g++-6 gcc-6 -qyy
source ./util/ci/common.sh
install_linux_deps
- name: Build
run: |
./util/ci/build.sh
env:
CC: gcc-6
CXX: g++-6
- name: Test
run: |
./bin/minetest --run-unittests
# This is the current gcc compiler (available in bionic)
gcc_8:
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2
- name: Install deps
run: |
sudo apt-get install g++-8 gcc-8 -qyy
source ./util/ci/common.sh
install_linux_deps
- name: Build
run: |
./util/ci/build.sh
env:
CC: gcc-8
CXX: g++-8
- name: Test
run: |
./bin/minetest --run-unittests
# This is our minor clang compiler
clang_3_9:
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2
- name: Install deps
run: |
sudo apt-get install clang-3.9 -qyy
source ./util/ci/common.sh
install_linux_deps
- name: Build
run: |
./util/ci/build.sh
env:
CC: clang-3.9
CXX: clang++-3.9
- name: Test
run: |
./bin/minetest --run-unittests
# This is the current clang version
clang_9:
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2
- name: Install deps
run: |
sudo apt-get install clang-9 valgrind -qyy
source ./util/ci/common.sh
install_linux_deps
env:
WITH_LUAJIT: 1
- name: Build
run: |
./util/ci/build.sh
env:
CC: clang-9
CXX: clang++-9
- name: Test
run: |
./bin/minetest --run-unittests
- name: Valgrind
run: |
valgrind --leak-check=full --leak-check-heuristics=all --undef-value-errors=no --error-exitcode=9 ./bin/minetest --run-unittests
# Build with prometheus-cpp (server-only)
clang_9_prometheus:
name: "clang_9 (PROMETHEUS=1)"
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2
- name: Install deps
run: |
sudo apt-get install clang-9 -qyy
source ./util/ci/common.sh
install_linux_deps
- name: Build prometheus-cpp
run: |
./util/ci/build_prometheus_cpp.sh
- name: Build
run: |
./util/ci/build.sh
env:
CC: clang-9
CXX: clang++-9
CMAKE_FLAGS: "-DENABLE_PROMETHEUS=1 -DBUILD_CLIENT=0"
- name: Test
run: |
./bin/minetestserver --run-unittests
# Build without freetype (client-only)
clang_9_no_freetype:
name: "clang_9 (FREETYPE=0)"
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2
- name: Install deps
run: |
sudo apt-get install clang-9 -qyy
source ./util/ci/common.sh
install_linux_deps
- name: Build
run: |
./util/ci/build.sh
env:
CC: clang-9
CXX: clang++-9
CMAKE_FLAGS: "-DENABLE_FREETYPE=0 -DBUILD_SERVER=0"
- name: Test
run: |
./bin/minetest --run-unittests
docker:
name: "Docker image"
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2
- name: Build docker image
run: |
docker build .
win32:
name: "MinGW cross-compiler (32-bit)"
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2
- name: Install compiler
run: |
sudo apt-get install gettext -qyy
wget http://minetest.kitsunemimi.pw/mingw-w64-i686_9.2.0_ubuntu18.04.tar.xz -O mingw.tar.xz
sudo tar -xaf mingw.tar.xz -C /usr
- name: Build
run: |
EXISTING_MINETEST_DIR=$PWD ./util/buildbot/buildwin32.sh winbuild
env:
NO_MINETEST_GAME: 1
NO_PACKAGE: 1
win64:
name: "MinGW cross-compiler (64-bit)"
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2
- name: Install compiler
run: |
sudo apt-get install gettext -qyy
wget http://minetest.kitsunemimi.pw/mingw-w64-x86_64_9.2.0_ubuntu18.04.tar.xz -O mingw.tar.xz
sudo tar -xaf mingw.tar.xz -C /usr
- name: Build
run: |
EXISTING_MINETEST_DIR=$PWD ./util/buildbot/buildwin64.sh winbuild
env:
NO_MINETEST_GAME: 1
NO_PACKAGE: 1
msvc:
name: VS 2019 ${{ matrix.config.arch }}-${{ matrix.type }}
runs-on: windows-2019
env:
VCPKG_VERSION: c7ab9d3110813979a873b2dbac630a9ab79850dc
# 2020.04
vcpkg_packages: irrlicht zlib curl[winssl] openal-soft libvorbis libogg sqlite3 freetype luajit
strategy:
fail-fast: false
matrix:
config:
- {
arch: x86,
generator: "-G'Visual Studio 16 2019' -A Win32",
vcpkg_triplet: x86-windows
}
- {
arch: x64,
generator: "-G'Visual Studio 16 2019' -A x64",
vcpkg_triplet: x64-windows
}
type: [portable]
# type: [portable, installer]
# The installer type is working, but disabled, to save runner jobs.
# Enable it, when working on the installer.
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Restore from cache and run vcpkg
uses: lukka/run-vcpkg@v2
with:
vcpkgArguments: ${{env.vcpkg_packages}}
vcpkgDirectory: '${{ github.workspace }}\vcpkg'
appendedCacheKey: ${{ matrix.config.vcpkg_triplet }}
vcpkgGitCommitId: ${{ env.VCPKG_VERSION }}
vcpkgTriplet: ${{ matrix.config.vcpkg_triplet }}
- name: CMake
run: |
cmake ${{matrix.config.generator}} `
-DCMAKE_TOOLCHAIN_FILE="${{ github.workspace }}\vcpkg\scripts\buildsystems\vcpkg.cmake" `
-DCMAKE_BUILD_TYPE=Release `
-DENABLE_POSTGRESQL=OFF `
-DRUN_IN_PLACE=${{ contains(matrix.type, 'portable') }} .
- name: Build
run: cmake --build . --config Release
- name: CPack
run: |
If ($env:TYPE -eq "installer")
{
cpack -G WIX -B "$env:GITHUB_WORKSPACE\Package"
}
ElseIf($env:TYPE -eq "portable")
{
cpack -G ZIP -B "$env:GITHUB_WORKSPACE\Package"
}
env:
TYPE: ${{matrix.type}}
- name: Package Clean
run: rm -r $env:GITHUB_WORKSPACE\Package\_CPack_Packages
- uses: actions/upload-artifact@v1
with:
name: msvc-${{ matrix.config.arch }}-${{ matrix.type }}
path: .\Package\

54
.github/workflows/cpp_lint.yml vendored Normal file
View File

@@ -0,0 +1,54 @@
name: cpp_lint
# lint on c/cpp changes or workflow changes
on:
push:
paths:
- 'lib/**.[ch]'
- 'lib/**.cpp'
- 'src/**.[ch]'
- 'src/**.cpp'
- '**/CMakeLists.txt'
- 'cmake/Modules/**'
- 'util/ci/**'
- '.github/workflows/**.yml'
pull_request:
paths:
- 'lib/**.[ch]'
- 'lib/**.cpp'
- 'src/**.[ch]'
- 'src/**.cpp'
- '**/CMakeLists.txt'
- 'cmake/Modules/**'
- 'util/ci/**'
- '.github/workflows/**.yml'
jobs:
clang_format:
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2
- name: Install clang-format
run: |
sudo apt-get install clang-format-9 -qyy
- name: Run clang-format
run: |
source ./util/ci/lint.sh
perform_lint
env:
CLANG_FORMAT: clang-format-9
clang_tidy:
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2
- name: Install deps
run: |
sudo apt-get install clang-tidy-9 -qyy
source ./util/ci/common.sh
install_linux_deps
- name: Run clang-tidy
run: |
./util/ci/clang-tidy.sh

32
.github/workflows/lua_lint.yml vendored Normal file
View File

@@ -0,0 +1,32 @@
name: lua_lint
# Lint on lua changes on builtin or if workflow changed
on:
push:
paths:
- 'builtin/**.lua'
- '.github/workflows/**.yml'
pull_request:
paths:
- 'builtin/**.lua'
- '.github/workflows/**.yml'
jobs:
luacheck:
name: "Builtin Luacheck and Unit Tests"
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2
- name: Install luarocks
run: |
sudo apt-get install luarocks -qyy
- name: Install luarocks tools
run: |
luarocks install --local luacheck
luarocks install --local busted
- name: Run checks
run: |
$HOME/.luarocks/bin/luacheck builtin
$HOME/.luarocks/bin/busted builtin

43
.gitignore vendored
View File

@@ -1,8 +1,9 @@
## Editors and Development environments
## Editors and development environments
*~
*.swp
*.bak*
*.orig
.DS_Store
# Vim
*.vim
# Kate
@@ -21,11 +22,16 @@
tags
!tags/
gtags.files
.idea/*
.idea
# Codelite
*.project
# Visual Studio Code & plugins
.vscode/
build/.cmake/
# Gradle
.gradle
## Files related to minetest development cycle
## Files related to Minetest development cycle
/*.patch
*.diff
# GNU Patch reject file
@@ -34,7 +40,7 @@ gtags.files
## Non-static Minetest directories or symlinks to these
/bin/
/games/*
!/games/minimal/
!/games/devtest/
/cache
/textures/*
!/textures/base/
@@ -53,8 +59,9 @@ gtags.files
## Configuration/log files
minetest.conf
debug.txt
debug.txt.1
## Other files generated by minetest
## Other files generated by Minetest
screenshot_*.png
testbm.txt
@@ -63,20 +70,19 @@ doc/Doxyfile
doc/html/
doc/doxygen_*
## MkDocs files
public/
doc/mkdocs/docs/*.md
doc/mkdocs/mkdocs.yml
## Build files
CMakeFiles
Makefile
!build/android/Makefile
build/android/path.cfg
build/android/*.apk
build/android/.externalNativeBuild
cmake_install.cmake
CMakeCache.txt
CPackConfig.cmake
CPackSourceConfig.cmake
src/test_config.h
src/android_version.h
src/android_version_githash.h
src/cmake_config.h
src/cmake_config_githash.h
src/unittest/test_world/world.mt
@@ -98,16 +104,5 @@ cmake_config.h
cmake_config_githash.h
CMakeDoxy*
compile_commands.json
## Android build files
build/android/src/main/assets
build/android/build
build/android/deps
build/android/libs
build/android/jni/lib
build/android/jni/src
build/android/src/main/jniLibs
build/android/obj
build/android/local.properties
build/android/.gradle
timestamp
*.apk
*.zip

View File

@@ -12,7 +12,7 @@ variables:
MINETEST_GAME_REPO: "https://github.com/minetest/minetest_game.git"
CONTAINER_IMAGE: registry.gitlab.com/$CI_PROJECT_PATH
.build_template: &build_definition
.build_template:
stage: build
script:
- mkdir cmakebuild
@@ -27,7 +27,7 @@ variables:
paths:
- artifact/*
.debpkg_template: &debpkg_template
.debpkg_template:
stage: package
before_script:
- apt-get update -y
@@ -47,7 +47,7 @@ variables:
paths:
- ./*.deb
.debpkg_install: &debpkg_install
.debpkg_install:
stage: deploy
before_script:
- apt-get update -y
@@ -62,7 +62,7 @@ variables:
# Jessie
build:debian-8:
<<: *build_definition
extends: .build_template
image: debian:8
before_script:
- echo "deb http://ppa.launchpad.net/ubuntu-toolchain-r/test/ubuntu trusty main" > /etc/apt/sources.list.d/uptodate-toolchain.list
@@ -74,46 +74,70 @@ build:debian-8:
CXX: g++-6
package:debian-8:
extends: .debpkg_template
image: debian:8
dependencies:
- build:debian-8
variables:
LEVELDB_PKG: libleveldb1
<<: *debpkg_template
deploy:debian-8:
extends: .debpkg_install
image: debian:8
dependencies:
- package:debian-8
variables:
LEVELDB_PKG: libleveldb1
<<: *debpkg_install
# Stretch
build:debian-9:
<<: *build_definition
extends: .build_template
image: debian:9
before_script:
- apt-get update -y
- apt-get -y install build-essential libirrlicht-dev cmake libbz2-dev libpng-dev libjpeg-dev libxxf86vm-dev libgl1-mesa-dev libsqlite3-dev libogg-dev libvorbis-dev libopenal-dev libcurl4-gnutls-dev libfreetype6-dev zlib1g-dev libgmp-dev libjsoncpp-dev
package:debian-9:
extends: .debpkg_template
image: debian:9
dependencies:
- build:debian-9
variables:
LEVELDB_PKG: libleveldb1v5
<<: *debpkg_template
deploy:debian-9:
extends: .debpkg_install
image: debian:9
dependencies:
- package:debian-9
variables:
LEVELDB_PKG: libleveldb1v5
<<: *debpkg_install
# Stretch
build:debian-10:
extends: .build_template
image: debian:10
before_script:
- apt-get update -y
- apt-get -y install build-essential libirrlicht-dev cmake libbz2-dev libpng-dev libjpeg-dev libxxf86vm-dev libgl1-mesa-dev libsqlite3-dev libogg-dev libvorbis-dev libopenal-dev libcurl4-gnutls-dev libfreetype6-dev zlib1g-dev libgmp-dev libjsoncpp-dev
package:debian-10:
extends: .debpkg_template
image: debian:10
dependencies:
- build:debian-10
variables:
LEVELDB_PKG: libleveldb1d
deploy:debian-10:
extends: .debpkg_install
image: debian:10
dependencies:
- package:debian-10
variables:
LEVELDB_PKG: libleveldb1d
##
## Ubuntu
##
@@ -121,7 +145,7 @@ deploy:debian-9:
# Trusty
build:ubuntu-14.04:
<<: *build_definition
extends: .build_template
image: ubuntu:trusty
before_script:
- echo "deb http://ppa.launchpad.net/ubuntu-toolchain-r/test/ubuntu trusty main" > /etc/apt/sources.list.d/uptodate-toolchain.list
@@ -133,102 +157,53 @@ build:ubuntu-14.04:
CXX: g++-6
package:ubuntu-14.04:
extends: .debpkg_template
image: ubuntu:trusty
dependencies:
- build:ubuntu-14.04
variables:
LEVELDB_PKG: libleveldb1
<<: *debpkg_template
deploy:ubuntu-14.04:
extends: .debpkg_install
image: ubuntu:trusty
dependencies:
- package:ubuntu-14.04
variables:
LEVELDB_PKG: libleveldb1
<<: *debpkg_install
# Xenial
build:ubuntu-16.04:
<<: *build_definition
extends: .build_template
image: ubuntu:xenial
before_script:
- apt-get update -y
- apt-get -y install build-essential libirrlicht-dev cmake libbz2-dev libpng-dev libjpeg-dev libxxf86vm-dev libgl1-mesa-dev libsqlite3-dev libogg-dev libvorbis-dev libopenal-dev libcurl4-gnutls-dev libfreetype6-dev zlib1g-dev libgmp-dev libjsoncpp-dev
package:ubuntu-16.04:
extends: .debpkg_template
image: ubuntu:xenial
dependencies:
- build:ubuntu-16.04
variables:
LEVELDB_PKG: libleveldb1v5
<<: *debpkg_template
deploy:ubuntu-16.04:
extends: .debpkg_install
image: ubuntu:xenial
dependencies:
- package:ubuntu-16.04
variables:
LEVELDB_PKG: libleveldb1v5
<<: *debpkg_install
# Yakkety
#build:ubuntu-16.10:
# <<: *build_definition
# image: ubuntu:yakkety
# before_script:
# - apt-get update -y
# - apt-get -y install build-essential libirrlicht-dev cmake libbz2-dev libpng-dev libjpeg-dev libxxf86vm-dev libgl1-mesa-dev libsqlite3-dev libogg-dev libvorbis-dev libopenal-dev libcurl4-gnutls-dev libfreetype6-dev zlib1g-dev libgmp-dev libjsoncpp-dev
#package:ubuntu-16.10:
# image: ubuntu:yakkety
# dependencies:
# - build:ubuntu-16.10
# variables:
# LEVELDB_PKG: libleveldb1v5
# <<: *debpkg_template
#deploy:ubuntu-16.10:
# image: ubuntu:yakkety
# dependencies:
# - package:ubuntu-16.10
# variables:
# LEVELDB_PKG: libleveldb1v5
# <<: *debpkg_install
# Zesty
#build:ubuntu-17.04:
# <<: *build_definition
# image: ubuntu:zesty
# before_script:
# - apt-get update -y
# - apt-get -y install build-essential libirrlicht-dev cmake libbz2-dev libpng-dev libjpeg-dev libxxf86vm-dev libgl1-mesa-dev libsqlite3-dev libogg-dev libvorbis-dev libopenal-dev libcurl4-gnutls-dev libfreetype6-dev zlib1g-dev libgmp-dev libjsoncpp-dev
#package:ubuntu-17.04:
# image: ubuntu:zesty
# dependencies:
# - build:ubuntu-17.04
# variables:
# LEVELDB_PKG: libleveldb1v5
# <<: *debpkg_template
#deploy:ubuntu-17.04:
# image: ubuntu:zesty
# dependencies:
# - package:ubuntu-17.04
# variables:
# LEVELDB_PKG: libleveldb1v5
# <<: *debpkg_install
##
## Fedora
##
# Do we need to support this old version ?
build:fedora-24:
<<: *build_definition
extends: .build_template
image: fedora:24
before_script:
- dnf -y install make automake gcc gcc-c++ kernel-devel cmake libcurl* openal* libvorbis* libXxf86vm-devel libogg-devel freetype-devel mesa-libGL-devel zlib-devel jsoncpp-devel irrlicht-devel bzip2-libs gmp-devel sqlite-devel luajit-devel leveldb-devel ncurses-devel doxygen spatialindex-devel bzip2-devel
@@ -238,17 +213,16 @@ build:fedora-24:
## Mingw for Windows
##
.generic_win_template: &generic_win_template
image: ubuntu:xenial
.generic_win_template:
image: ubuntu:bionic
before_script:
- apt-get update -y
- apt-get install -y p7zip-full wget unzip git cmake gettext
- wget http://minetest.kitsunemimi.pw/mingw-w64-${WIN_ARCH}_7.1.1_ubuntu14.04.7z -O mingw.7z > /dev/null
- sed -e "s|%PREFIX%|${WIN_ARCH}-w64-mingw32|" -e "s|%ROOTPATH%|/usr/${WIN_ARCH}-w64-mingw32|" < util/travis/toolchain_mingw.cmake.in > ${TOOLCHAIN_OUTPUT}
- 7z x -y -o/usr mingw.7z > /dev/null
- apt-get install -y wget xz-utils unzip git cmake gettext
- wget -q http://minetest.kitsunemimi.pw/mingw-w64-${WIN_ARCH}_9.2.0_ubuntu18.04.tar.xz -O mingw.tar.xz
- tar -xaf mingw.tar.xz -C /usr
.build_win_template: &build_win_template
<<: *generic_win_template
.build_win_template:
extends: .generic_win_template
stage: build
artifacts:
when: on_success
@@ -256,8 +230,8 @@ build:fedora-24:
paths:
- build/*
.package_win_template: &package_win_template
<<: *generic_win_template
.package_win_template:
extends: .generic_win_template
stage: package
script:
- cd build/minetest/_build
@@ -275,40 +249,36 @@ build:fedora-24:
- minetest-win-*/*
build:win32:
<<: *build_win_template
extends: .build_win_template
script:
- ./util/buildbot/buildwin32.sh build
variables:
NO_PACKAGE: "1"
WIN_ARCH: "i686"
TOOLCHAIN_OUTPUT: "util/buildbot/toolchain_mingw.cmake"
package:win32:
<<: *package_win_template
extends: .package_win_template
dependencies:
- build:win32
variables:
NO_PACKAGE: "1"
WIN_ARCH: "i686"
TOOLCHAIN_OUTPUT: "util/buildbot/toolchain_mingw.cmake"
build:win64:
<<: *build_win_template
extends: .build_win_template
script:
- ./util/buildbot/buildwin64.sh build
variables:
NO_PACKAGE: "1"
WIN_ARCH: "x86_64"
TOOLCHAIN_OUTPUT: "util/buildbot/toolchain_mingw64.cmake"
package:win64:
<<: *package_win_template
extends: .package_win_template
dependencies:
- build:win64
variables:
NO_PACKAGE: "1"
WIN_ARCH: "x86_64"
TOOLCHAIN_OUTPUT: "util/buildbot/toolchain_mingw64.cmake"
package:docker:
stage: package
@@ -322,3 +292,19 @@ package:docker:
- docker push ${CONTAINER_IMAGE}/server:$CI_COMMIT_SHA
- docker push ${CONTAINER_IMAGE}/server:$CI_COMMIT_REF_NAME
- docker push ${CONTAINER_IMAGE}/server:latest
pages:
stage: deploy
image: python:3.8
before_script:
- pip install git+https://github.com/Python-Markdown/markdown.git
- pip install git+https://github.com/mkdocs/mkdocs.git
- pip install pygments
script:
- cd doc/mkdocs && ./build.sh
artifacts:
paths:
- public
only:
- master

74
.luacheckrc Normal file
View File

@@ -0,0 +1,74 @@
unused_args = false
allow_defined_top = true
ignore = {
"131", -- Unused global variable
"431", -- Shadowing an upvalue
"432", -- Shadowing an upvalue argument
}
read_globals = {
"ItemStack",
"INIT",
"DIR_DELIM",
"dump", "dump2",
"fgettext", "fgettext_ne",
"vector",
"VoxelArea",
"profiler",
"Settings",
string = {fields = {"split", "trim"}},
table = {fields = {"copy", "getn", "indexof", "insert_all"}},
math = {fields = {"hypot"}},
}
globals = {
"core",
"gamedata",
os = { fields = { "tempfolder" } },
"_",
}
files["builtin/client/register.lua"] = {
globals = {
debug = {fields={"getinfo"}},
}
}
files["builtin/common/misc_helpers.lua"] = {
globals = {
"dump", "dump2", "table", "math", "string",
"fgettext", "fgettext_ne", "basic_dump", "game", -- ???
"file_exists", "get_last_folder", "cleanup_path", -- ???
},
}
files["builtin/common/vector.lua"] = {
globals = { "vector" },
}
files["builtin/game/voxelarea.lua"] = {
globals = { "VoxelArea" },
}
files["builtin/game/init.lua"] = {
globals = { "profiler" },
}
files["builtin/common/filterlist.lua"] = {
globals = {
"filterlist",
"compare_worlds", "sort_worlds_alphabetic", "sort_mod_list", -- ???
},
}
files["builtin/mainmenu"] = {
globals = {
"gamedata",
},
read_globals = {
"PLATFORM",
},
}

View File

@@ -1,109 +0,0 @@
language: cpp
before_install: ./util/travis/before_install.sh
script: ./util/travis/script.sh
sudo: required
dist: trusty
group: edge
notifications:
email: false
matrix:
fast_finish: true
include:
- env: LINT=1
compiler: clang
os: linux
addons:
apt:
packages: ['clang-format-5.0']
sources: &sources
- llvm-toolchain-trusty-5.0
- env: CLANG_TIDY=1
compiler: clang
os: linux
script: ./util/travis/clangtidy.sh
addons:
apt:
packages: ['clang-tidy-5.0']
sources: &sources
- llvm-toolchain-trusty-5.0
- env: PLATFORM=Win32
compiler: gcc
os: linux
addons:
apt:
packages: ['gcc-mingw-w64-i686', 'g++-mingw-w64-i686', 'binutils-mingw-w64-i686']
sources: &sources
- ubuntu-toolchain-r-test
- sourceline: 'deb http://mirrors.kernel.org/ubuntu xenial main universe'
- env: PLATFORM=Win64
compiler: gcc
os: linux
addons:
apt:
packages: ['gcc-mingw-w64-x86-64', 'g++-mingw-w64-x86-64', 'binutils-mingw-w64-x86-64']
sources: &sources
- ubuntu-toolchain-r-test
- sourceline: 'deb http://mirrors.kernel.org/ubuntu xenial main universe'
- env: PLATFORM=Unix
compiler: clang
os: osx
osx_image: xcode8
- env: PLATFORM=Unix COMPILER=gcc-6
compiler: gcc
os: linux
addons:
apt:
packages: ['gcc-6', 'g++-6']
sources: &sources
- ubuntu-toolchain-r-test
- env: PLATFORM=Unix COMPILER=gcc-7
compiler: gcc
os: linux
addons:
apt:
packages: ['gcc-7', 'g++-7']
sources: &sources
- ubuntu-toolchain-r-test
- env: PLATFORM=Unix COMPILER=clang-3.6
compiler: clang
os: linux
addons:
apt:
packages: ['clang-3.6', 'clang++-3.6']
sources: &sources
- llvm-toolchain-trusty-3.6
- env: PLATFORM=Unix COMPILER=clang-5.0
compiler: clang
os: linux
addons:
apt:
packages: ['clang-5.0', 'clang++-5.0']
sources: &sources
- llvm-toolchain-trusty-5.0
- env: PLATFORM=Unix COMPILER=clang-5.0 FREETYPE=0
compiler: clang
os: linux
addons:
apt:
packages: ['clang-5.0', 'clang++-5.0']
sources: &sources
- llvm-toolchain-trusty-5.0
- env: PLATFORM=Unix COMPILER=clang-5.0 VALGRIND=1
compiler: clang
os: linux
addons:
apt:
packages: ['valgrind', 'clang-5.0', 'clang++-5.0']
sources: &sources
- llvm-toolchain-trusty-5.0

View File

@@ -16,7 +16,7 @@ set(CLANG_MINIMUM_VERSION "3.4")
# Also remember to set PROTOCOL_VERSION in network/networkprotocol.h when releasing
set(VERSION_MAJOR 5)
set(VERSION_MINOR 0)
set(VERSION_MINOR 3)
set(VERSION_PATCH 0)
set(VERSION_EXTRA "" CACHE STRING "Stuff to append to version string")
@@ -49,6 +49,7 @@ set(RUN_IN_PLACE ${DEFAULT_RUN_IN_PLACE} CACHE BOOL
set(BUILD_CLIENT TRUE CACHE BOOL "Build client")
set(BUILD_SERVER FALSE CACHE BOOL "Build server")
set(BUILD_UNITTESTS TRUE CACHE BOOL "Build unittests")
set(WARN_ALL TRUE CACHE BOOL "Enable -Wall for Release build")
@@ -102,7 +103,7 @@ elseif(UNIX) # Linux, BSD etc
set(XDG_APPS_DIR "${CMAKE_INSTALL_PREFIX}/share/applications")
set(APPDATADIR "${CMAKE_INSTALL_PREFIX}/share/metainfo")
set(ICONDIR "${CMAKE_INSTALL_PREFIX}/share/icons")
set(LOCALEDIR "${CMAKE_INSTALL_PREFIX}/share/${PROJECT_NAME}/locale")
set(LOCALEDIR "${CMAKE_INSTALL_PREFIX}/share/locale")
endif()
endif()
@@ -166,22 +167,22 @@ endif()
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/games/minetest_game" DESTINATION "${SHAREDIR}/games/"
COMPONENT "SUBGAME_MINETEST_GAME" OPTIONAL PATTERN ".git*" EXCLUDE )
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/games/minimal" DESTINATION "${SHAREDIR}/games/"
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/games/devtest" DESTINATION "${SHAREDIR}/games/"
COMPONENT "SUBGAME_MINIMAL" OPTIONAL PATTERN ".git*" EXCLUDE )
if(BUILD_CLIENT)
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/client/shaders" DESTINATION "${SHAREDIR}/client")
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/textures/base/pack" DESTINATION "${SHAREDIR}/textures/base")
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/fonts" DESTINATION "${SHAREDIR}")
if(RUN_IN_PLACE)
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/clientmods" DESTINATION "${SHAREDIR}")
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/client/serverlist" DESTINATION "${SHAREDIR}/client")
endif()
endif()
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/fonts" DESTINATION "${SHAREDIR}")
install(FILES "README.md" DESTINATION "${DOCDIR}" COMPONENT "Docs")
install(FILES "doc/lua_api.txt" DESTINATION "${DOCDIR}" COMPONENT "Docs")
install(FILES "doc/client_lua_api.txt" DESTINATION "${DOCDIR}" COMPONENT "Docs")
install(FILES "doc/menu_lua_api.txt" DESTINATION "${DOCDIR}" COMPONENT "Docs")
install(FILES "doc/texture_packs.txt" DESTINATION "${DOCDIR}" COMPONENT "Docs")
install(FILES "doc/world_format.txt" DESTINATION "${DOCDIR}" COMPONENT "Docs")
@@ -232,7 +233,7 @@ add_subdirectory(src)
# CPack
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "An InfiniMiner/Minecraft inspired game")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "A free open-source voxel game engine with easy modding and game creation.")
set(CPACK_PACKAGE_VERSION_MAJOR ${VERSION_MAJOR})
set(CPACK_PACKAGE_VERSION_MINOR ${VERSION_MINOR})
set(CPACK_PACKAGE_VERSION_PATCH ${VERSION_PATCH})
@@ -253,8 +254,8 @@ cpack_add_component(SUBGAME_MINETEST_GAME
)
cpack_add_component(SUBGAME_MINIMAL
DISPLAY_NAME "Minimal development test"
DESCRIPTION "A minimal subgame helping to develop the engine."
DISPLAY_NAME "Development Test"
DESCRIPTION "A minimal test game helping to develop the engine."
DISABLED #DISABLED does not mean it is disabled, and is just not selected by default.
GROUP "Subgames"
)
@@ -325,4 +326,3 @@ if(DOXYGEN_FOUND)
COMMENT "Generating API documentation with Doxygen" VERBATIM
)
endif()

View File

@@ -1,31 +1,59 @@
FROM debian:stretch
FROM alpine:3.11
USER root
RUN apt-get update -y && \
apt-get -y install build-essential libirrlicht-dev cmake libbz2-dev libpng-dev libjpeg-dev \
libsqlite3-dev libcurl4-gnutls-dev zlib1g-dev libgmp-dev libjsoncpp-dev git && \
apt-get clean && rm -rf /var/cache/apt/archives/* && \
rm -rf /var/lib/apt/lists/*
ENV MINETEST_GAME_VERSION master
COPY . /usr/src/minetest
COPY .git /usr/src/minetest/.git
COPY CMakeLists.txt /usr/src/minetest/CMakeLists.txt
COPY README.md /usr/src/minetest/README.md
COPY minetest.conf.example /usr/src/minetest/minetest.conf.example
COPY builtin /usr/src/minetest/builtin
COPY cmake /usr/src/minetest/cmake
COPY doc /usr/src/minetest/doc
COPY fonts /usr/src/minetest/fonts
COPY lib /usr/src/minetest/lib
COPY misc /usr/src/minetest/misc
COPY po /usr/src/minetest/po
COPY src /usr/src/minetest/src
COPY textures /usr/src/minetest/textures
RUN mkdir -p /usr/src/minetest/cmakebuild && cd /usr/src/minetest/cmakebuild && \
cmake -DCMAKE_INSTALL_PREFIX=/usr/local -DCMAKE_BUILD_TYPE=Release -DRUN_IN_PLACE=FALSE \
WORKDIR /usr/src/minetest
RUN apk add --no-cache git build-base irrlicht-dev cmake bzip2-dev libpng-dev \
jpeg-dev libxxf86vm-dev mesa-dev sqlite-dev libogg-dev \
libvorbis-dev openal-soft-dev curl-dev freetype-dev zlib-dev \
gmp-dev jsoncpp-dev postgresql-dev ca-certificates && \
git clone --depth=1 -b ${MINETEST_GAME_VERSION} https://github.com/minetest/minetest_game.git ./games/minetest_game && \
rm -fr ./games/minetest_game/.git
WORKDIR /usr/src/
RUN git clone --recursive https://github.com/jupp0r/prometheus-cpp/ && \
mkdir prometheus-cpp/build && \
cd prometheus-cpp/build && \
cmake .. \
-DCMAKE_INSTALL_PREFIX=/usr/local \
-DCMAKE_BUILD_TYPE=Release \
-DENABLE_TESTING=0 && \
make -j2 && \
make install
WORKDIR /usr/src/minetest
RUN mkdir build && \
cd build && \
cmake .. \
-DCMAKE_INSTALL_PREFIX=/usr/local \
-DCMAKE_BUILD_TYPE=Release \
-DBUILD_SERVER=TRUE \
-DBUILD_CLIENT=FALSE \
-DENABLE_SYSTEM_JSONCPP=1 \
.. && \
make -j2 && \
rm -Rf ../games/minetest_game && git clone https://github.com/minetest/minetest_game ../games/minetest_game && \
make install
-DENABLE_PROMETHEUS=TRUE \
-DBUILD_UNITTESTS=FALSE \
-DBUILD_CLIENT=FALSE && \
make -j2 && \
make install
FROM debian:stretch
FROM alpine:3.11
USER root
RUN groupadd minetest && useradd -m -g minetest -d /var/lib/minetest minetest && \
apt-get update -y && \
apt-get -y install libcurl3-gnutls libjsoncpp1 liblua5.1-0 libluajit-5.1-2 libpq5 libsqlite3-0 \
libstdc++6 zlib1g libc6
RUN apk add --no-cache sqlite-libs curl gmp libstdc++ libgcc libpq && \
adduser -D minetest --uid 30000 -h /var/lib/minetest && \
chown -R minetest:minetest /var/lib/minetest
WORKDIR /var/lib/minetest
@@ -33,8 +61,8 @@ COPY --from=0 /usr/local/share/minetest /usr/local/share/minetest
COPY --from=0 /usr/local/bin/minetestserver /usr/local/bin/minetestserver
COPY --from=0 /usr/local/share/doc/minetest/minetest.conf.example /etc/minetest/minetest.conf
USER minetest
USER minetest:minetest
EXPOSE 30000/udp
EXPOSE 30000/udp 30000/tcp
CMD ["/usr/local/bin/minetestserver", "--config", "/etc/minetest/minetest.conf"]

View File

@@ -21,6 +21,12 @@ ShadowNinja:
paramat:
textures/base/pack/menu_header.png
textures/base/pack/next_icon.png
textures/base/pack/prev_icon.png
rubenwardy, paramat:
textures/base/pack/start_icon.png
textures/base/pack/end_icon.png
erlehmann:
misc/minetest-icon-24x24.png

302
README.md
View File

@@ -1,17 +1,17 @@
Minetest
========
[![Build Status](https://travis-ci.org/minetest/minetest.svg?branch=master)](https://travis-ci.org/minetest/minetest)
![Build Status](https://github.com/minetest/minetest/workflows/build/badge.svg)
[![Translation status](https://hosted.weblate.org/widgets/minetest/-/svg-badge.svg)](https://hosted.weblate.org/engage/minetest/?utm_source=widget)
[![License](https://img.shields.io/badge/license-LGPLv2.1%2B-blue.svg)](https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html)
Minetest is a free open-source voxel game engine with easy modding and game creation.
Copyright (C) 2010-2018 Perttu Ahola <celeron55@gmail.com>
Copyright (C) 2010-2020 Perttu Ahola <celeron55@gmail.com>
and contributors (see source file comments and the version control log)
In case you downloaded the source code:
---------------------------------------
In case you downloaded the source code
--------------------------------------
If you downloaded the Minetest Engine source code in which this file is
contained, you probably want to download the [Minetest Game](https://github.com/minetest/minetest_game/)
project too. See its README.txt for more information.
@@ -65,19 +65,19 @@ Some can be changed in the key config dialog in the settings tab.
| + | Increase view range |
| - | Decrease view range |
| K | Enable/disable fly mode (needs fly privilege) |
| L | Enable/disable pitch move mode |
| P | Enable/disable pitch move mode |
| J | Enable/disable fast mode (needs fast privilege) |
| H | Enable/disable noclip mode (needs noclip privilege) |
| E | Move fast in fast mode |
| C | Cycle through camera modes |
| V | Cycle through minimap modes |
| Shift + V | Change minimap orientation |
| F1 | Hide/show HUD |
| F2 | Hide/show chat |
| F3 | Disable/enable fog |
| F4 | Disable/enable camera update (Mapblocks are not updated anymore when disabled, disabled in release builds) |
| F5 | Cycle through debug information screens |
| F6 | Cycle through profiler info screens |
| F7 | Cycle through camera modes |
| F9 | Cycle through minimap modes |
| Shift + F9 | Change minimap orientation |
| F10 | Show/hide console |
| F12 | Take screenshot |
@@ -92,13 +92,13 @@ Locations:
Where each location is on each platform:
* Windows .zip / RUN_IN_PLACE source:
* bin = `bin`
* share = `.`
* user = `.`
* `bin` = `bin`
* `share` = `.`
* `user` = `.`
* Windows installed:
* $bin = `C:\Program Files\Minetest\bin (Depends on the install location)`
* $share = `C:\Program Files\Minetest (Depends on the install location)`
* $user = `%Appdata%\Minetest`
* `bin` = `C:\Program Files\Minetest\bin (Depends on the install location)`
* `share` = `C:\Program Files\Minetest (Depends on the install location)`
* `user` = `%APPDATA%\Minetest`
* Linux installed:
* `bin` = `/usr/bin`
* `share` = `/usr/share/minetest`
@@ -110,18 +110,18 @@ Where each location is on each platform:
Worlds can be found as separate folders in: `user/worlds/`
Configuration file:
-------------------
Configuration file
------------------
- Default location:
`user/minetest.conf`
- It is created by Minetest when it is ran the first time.
- This file is created by closing Minetest for the first time.
- A specific file can be specified on the command line:
`--config <path-to-file>`
- A run-in-place build will look for the configuration file in
`location_of_exe/../minetest.conf` and also `location_of_exe/../../minetest.conf`
Command-line options:
---------------------
Command-line options
--------------------
- Use `--help`
Compiling
@@ -140,13 +140,21 @@ Compiling
| GMP | 5.0.0+ | Bundled mini-GMP is used if not present |
| JsonCPP | 1.0.0+ | Bundled JsonCPP is used if not present |
For Debian/Ubuntu:
For Debian/Ubuntu users:
sudo apt install build-essential libirrlicht-dev cmake libbz2-dev libpng-dev libjpeg-dev libxxf86vm-dev libgl1-mesa-dev libsqlite3-dev libogg-dev libvorbis-dev libopenal-dev libcurl4-gnutls-dev libfreetype6-dev zlib1g-dev libgmp-dev libjsoncpp-dev
sudo apt install g++ make libc6-dev libirrlicht-dev cmake libbz2-dev libpng-dev libjpeg-dev libxxf86vm-dev libgl1-mesa-dev libsqlite3-dev libogg-dev libvorbis-dev libopenal-dev libcurl4-gnutls-dev libfreetype6-dev zlib1g-dev libgmp-dev libjsoncpp-dev
For Fedora users:
sudo dnf install make automake gcc gcc-c++ kernel-devel cmake libcurl-devel openal-soft-devel libvorbis-devel libXxf86vm-devel libogg-devel freetype-devel mesa-libGL-devel zlib-devel jsoncpp-devel irrlicht-devel bzip2-libs gmp-devel sqlite-devel luajit-devel leveldb-devel ncurses-devel doxygen spatialindex-devel bzip2-devel
For Arch users:
sudo pacman -S base-devel libcurl-gnutls cmake libxxf86vm irrlicht libpng sqlite libogg libvorbis openal freetype2 jsoncpp gmp luajit leveldb ncurses
For Alpine users:
sudo apk add build-base irrlicht-dev cmake bzip2-dev libpng-dev jpeg-dev libxxf86vm-dev mesa-dev sqlite-dev libogg-dev libvorbis-dev openal-soft-dev curl-dev freetype-dev zlib-dev gmp-dev jsoncpp-dev luajit-dev
#### Download
@@ -165,7 +173,7 @@ Download source (this is the URL to the latest of source repository, which might
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:
Download minetest_game (otherwise only the "Development Test" game is available) using Git:
git clone --depth 1 https://github.com/minetest/minetest_game.git games/minetest_game
@@ -188,21 +196,21 @@ Download minetest_game, without using Git:
Build a version that runs directly from the source directory:
cmake . -DRUN_IN_PLACE=TRUE
make -j <number of processors>
make -j$(nproc)
Run it:
./bin/minetest
- Use `cmake . -LH` to see all CMake options and their current state
- Use `cmake . -LH` to see all CMake options and their current state.
- If you want to install it system-wide (or are making a distribution package),
you will want to use `-DRUN_IN_PLACE=FALSE`
- You can build a bare server by specifying `-DBUILD_SERVER=TRUE`
- You can disable the client build by specifying `-DBUILD_CLIENT=FALSE`
- You can select between Release and Debug build by `-DCMAKE_BUILD_TYPE=<Debug or Release>`
- Debug build is slower, but gives much more useful output in a debugger
- If you build a bare server, you don't need to have Irrlicht installed.
- In that case use `-DIRRLICHT_SOURCE_DIR=/the/irrlicht/source`
you will want to use `-DRUN_IN_PLACE=FALSE`.
- You can build a bare server by specifying `-DBUILD_SERVER=TRUE`.
- You can disable the client build by specifying `-DBUILD_CLIENT=FALSE`.
- You can select between Release and Debug build by `-DCMAKE_BUILD_TYPE=<Debug or Release>`.
- Debug build is slower, but gives much more useful output in a debugger.
- If you build a bare server you don't need to have Irrlicht installed.
- In that case use `-DIRRLICHT_SOURCE_DIR=/the/irrlicht/source`.
### CMake options
@@ -210,6 +218,7 @@ General options and their default values:
BUILD_CLIENT=TRUE - Build Minetest client
BUILD_SERVER=FALSE - Build Minetest server
BUILD_UNITTESTS=TRUE - Build unittest sources
CMAKE_BUILD_TYPE=Release - Type of build (Release vs. Debug)
Release - Release build
Debug - Debug build
@@ -220,13 +229,14 @@ General options and their default values:
ENABLE_CURSES=ON - Build with (n)curses; Enables a server side terminal (command line option: --terminal)
ENABLE_FREETYPE=ON - Build with FreeType2; Allows using TTF fonts
ENABLE_GETTEXT=ON - Build with Gettext; Allows using translations
ENABLE_GLES=OFF - Search for Open GLES headers & libraries and use them
ENABLE_GLES=OFF - Build for OpenGL ES instead of OpenGL (requires support by Irrlicht)
ENABLE_LEVELDB=ON - Build with LevelDB; Enables use of LevelDB map backend
ENABLE_POSTGRESQL=ON - Build with libpq; Enables use of PostgreSQL map backend (PostgreSQL 9.5 or greater recommended)
ENABLE_REDIS=ON - Build with libhiredis; Enables use of Redis map backend
ENABLE_SPATIAL=ON - Build with LibSpatial; Speeds up AreaStores
ENABLE_SOUND=ON - Build with OpenAL, libogg & libvorbis; in-game sounds
ENABLE_LUAJIT=ON - Build with LuaJIT (much faster than non-JIT Lua)
ENABLE_PROMETHEUS=OFF - Build with Prometheus metrics exporter (listens on tcp/30000 by default)
ENABLE_SYSTEM_GMP=ON - Use GMP from system (much faster than bundled mini-gmp)
ENABLE_SYSTEM_JSONCPP=OFF - Use JsonCPP from system
OPENGL_GL_PREFERENCE=LEGACY - Linux client build only; See CMake Policy CMP0072 for reference
@@ -259,7 +269,7 @@ Library specific options:
LEVELDB_LIBRARY - Only when building with LevelDB; path to libleveldb.a/libleveldb.so/libleveldb.dll.a
LEVELDB_DLL - Only when building with LevelDB on Windows; path to libleveldb.dll
PostgreSQL_INCLUDE_DIR - Only when building with PostgreSQL; directory that contains libpq-fe.h
POSTGRESQL_LIBRARY - Only when building with PostgreSQL; path to libpq.a/libpq.so
PostgreSQL_LIBRARY - Only when building with PostgreSQL; path to libpq.a/libpq.so/libpq.lib
REDIS_INCLUDE_DIR - Only when building with Redis; directory that contains hiredis.h
REDIS_LIBRARY - Only when building with Redis; path to libhiredis.a/libhiredis.so
SPATIAL_INCLUDE_DIR - Only when building with LibSpatial; directory that contains spatialindex/SpatialIndex.h
@@ -284,183 +294,93 @@ Library specific options:
VORBIS_LIBRARY - Only if building with sound; path to libvorbis.a/libvorbis.so/libvorbis.dll.a
XXF86VM_LIBRARY - Only on Linux; path to libXXf86vm.a/libXXf86vm.so
ZLIB_DLL - Only on Windows; path to zlib1.dll
ZLIBWAPI_DLL - Only on Windows; path to zlibwapi.dll
ZLIB_INCLUDE_DIR - Directory that contains zlib.h
ZLIB_LIBRARY - Path to libz.a/libz.so/zlibwapi.lib
ZLIB_LIBRARY - Path to libz.a/libz.so/zlib.lib
### Compiling on Windows
* This section is outdated. In addition to what is described here:
* In addition to minetest, you need to download [minetest_game](https://github.com/minetest/minetest_game).
* If you wish to have sound support, you need libogg, libvorbis and libopenal
### Requirements
* You need:
* CMake:
http://www.cmake.org/cmake/resources/software.html
* A compiler
* MinGW: http://www.mingw.org/
* or Visual Studio: http://msdn.microsoft.com/en-us/vstudio/default
* Irrlicht SDK 1.7:
http://irrlicht.sourceforge.net/downloads.html
* Zlib headers (zlib125.zip)
http://www.winimage.com/zLibDll/index.html
* Zlib library (zlibwapi.lib and zlibwapi.dll from zlib125dll.zip):
http://www.winimage.com/zLibDll/index.html
* SQLite3 headers and library
https://www.sqlite.org/download.html
* Optional: gettext library and tools:
http://gnuwin32.sourceforge.net/downlinks/gettext.php
* This is used for other UI languages. Feel free to leave it out.
* And, of course, Minetest:
http://minetest.net/download
* Steps:
* Select a directory called DIR hereafter in which you will operate.
* Make sure you have CMake and a compiler installed.
* Download all the other stuff to DIR and extract them into there.
("extract here", not "extract to packagename/")
* NOTE: zlib125dll.zip needs to be extracted into zlib125dll
* NOTE: You need to extract sqlite3.h & sqlite3ext.h from the SQLite 3
source and sqlite3.dll & sqlite3.def from the SQLite 3 precompiled
binaries into "sqlite3" directory, and generate sqlite3.lib using
command "LIB /DEF:sqlite3.def /OUT:sqlite3.lib"
* All those packages contain a nice base directory in them, which
should end up being the direct subdirectories of DIR.
* You will end up with a directory structure like this (+=dir, -=file):
-----------------
+ DIR
* zlib-1.2.5.tar.gz
* zlib125dll.zip
* irrlicht-1.8.3.zip
* sqlite-amalgamation-3130000.zip (SQLite3 headers)
* sqlite-dll-win32-x86-3130000.zip (SQLite3 library for 32bit system)
* 110214175330.zip (or whatever, this is the minetest source)
+ zlib-1.2.5
* zlib.h
+ win32
...
+ zlib125dll
* readme.txt
+ dll32
...
+ irrlicht-1.8.3
+ lib
+ include
...
+ sqlite3
sqlite3.h
sqlite3ext.h
sqlite3.lib
sqlite3.dll
+ gettext (optional)
+bin
+include
+lib
+ minetest
+ src
+ doc
* CMakeLists.txt
...
-----------------
* Start up the CMake GUI
* Select "Browse Source..." and select DIR/minetest
* Now, if using MSVC:
* Select "Browse Build..." and select DIR/minetest-build
* Else if using MinGW:
* Select "Browse Build..." and select DIR/minetest
* Select "Configure"
* Select your compiler
* It will warn about missing stuff, ignore that at this point. (later don't)
* Make sure the configuration is as follows
(note that the versions may differ for you):
- [Visual Studio 2015 or newer](https://visualstudio.microsoft.com)
- [CMake](https://cmake.org/download/)
- [vcpkg](https://github.com/Microsoft/vcpkg)
- [Git](https://git-scm.com/downloads)
BUILD_CLIENT [X]
BUILD_SERVER [ ]
CMAKE_BUILD_TYPE Release
CMAKE_INSTALL_PREFIX DIR/minetest-install
IRRLICHT_SOURCE_DIR DIR/irrlicht-1.8.3
RUN_IN_PLACE [X]
WARN_ALL [ ]
ZLIB_DLL DIR/zlib125dll/dll32/zlibwapi.dll
ZLIB_INCLUDE_DIR DIR/zlib-1.2.5
ZLIB_LIBRARIES DIR/zlib125dll/dll32/zlibwapi.lib
GETTEXT_BIN_DIR DIR/gettext/bin
GETTEXT_INCLUDE_DIR DIR/gettext/include
GETTEXT_LIBRARIES DIR/gettext/lib/intl.lib
GETTEXT_MSGFMT DIR/gettext/bin/msgfmt
### Compiling and installing the dependencies
* If CMake complains it couldn't find SQLITE3, choose "Advanced" box on the
right top corner, then specify the location of SQLITE3_INCLUDE_DIR and
SQLITE3_LIBRARY manually.
* If you want to build 64-bit minetest, you will need to build 64-bit version
of irrlicht engine manually, as only 32-bit pre-built library is provided.
* Hit "Configure"
* Hit "Configure" once again 8)
* If something is still coloured red, you have a problem.
* Hit "Generate"
If using MSVC:
* Open the generated minetest.sln
* The project defaults to the "Debug" configuration. Make very sure to
select "Release", unless you want to debug some stuff (it's slower
and might not even work at all)
* Build the ALL_BUILD project
* Build the INSTALL project
* You should now have a working game with the executable in
DIR/minetest-install/bin/minetest.exe
* Additionally you may create a zip package by building the PACKAGE
project.
If using MinGW:
* Using the command line, browse to the build directory and run 'make'
(or mingw32-make or whatever it happens to be)
* You may need to copy some of the downloaded DLLs into bin/, see what
running the produced executable tells you it doesn't have.
* You should now have a working game with the executable in
DIR/minetest/bin/minetest.exe
It is highly recommended to use vcpkg as package manager.
### Bat script to build Windows releases of Minetest
#### a) Using vcpkg to install dependencies
This is how we build Windows releases.
After you successfully built vcpkg you can easily install the required libraries:
```powershell
vcpkg install irrlicht zlib curl[winssl] openal-soft libvorbis libogg sqlite3 freetype luajit --triplet x64-windows
```
set sourcedir=%CD%
set installpath="C:\tmp\minetest_install"
set irrlichtpath="C:\tmp\irrlicht-1.7.2"
- `curl` is optional, but required to read the serverlist, `curl[winssl]` is required to use the content store.
- `openal-soft`, `libvorbis` and `libogg` are optional, but required to use sound.
- `freetype` is optional, it allows true-type font rendering.
- `luajit` is optional, it replaces the integrated Lua interpreter with a faster just-in-time interpreter.
set builddir=%sourcedir%\bvc10
mkdir %builddir%
pushd %builddir%
cmake %sourcedir% -G "Visual Studio 10" -DIRRLICHT_SOURCE_DIR=%irrlichtpath% -DRUN_IN_PLACE=TRUE -DCMAKE_INSTALL_PREFIX=%installpath%
if %errorlevel% neq 0 goto fail
"C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe" ALL_BUILD.vcxproj /p:Configuration=Release
if %errorlevel% neq 0 goto fail
"C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe" INSTALL.vcxproj /p:Configuration=Release
if %errorlevel% neq 0 goto fail
"C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe" PACKAGE.vcxproj /p:Configuration=Release
if %errorlevel% neq 0 goto fail
popd
echo Finished.
exit /b 0
There are other optional libraries, but they are not tested if they can build and link correctly.
:fail
popd
echo Failed.
exit /b 1
Use `--triplet` to specify the target triplet, e.g. `x64-windows` or `x86-windows`.
### Windows Installer using WIX Toolset
#### b) Compile the dependencies on your own
This is outdated and not recommended. Follow the instructions on https://dev.minetest.net/Build_Win32_Minetest_including_all_required_libraries#VS2012_Build
### Compile Minetest
#### a) Using the vcpkg toolchain and CMake GUI
1. Start up the CMake GUI
2. Select **Browse Source...** and select DIR/minetest
3. Select **Browse Build...** and select DIR/minetest-build
4. Select **Configure**
5. Choose the right visual Studio version and target platform. It has to match the version of the installed dependencies
6. Choose **Specify toolchain file for cross-compiling**
7. Click **Next**
8. Select the vcpkg toolchain file e.g. `D:/vcpkg/scripts/buildsystems/vcpkg.cmake`
9. Click Finish
10. Wait until cmake have generated the cash file
11. If there are any errors, solve them and hit **Configure**
12. Click **Generate**
13. Click **Open Project**
14. Compile Minetest inside Visual studio.
#### b) Using the vcpkg toolchain and the commandline
Run the following script in PowerShell:
```powershell
cmake . -G"Visual Studio 15 2017 Win64" -DCMAKE_TOOLCHAIN_FILE=D:/vcpkg/scripts/buildsystems/vcpkg.cmake -DCMAKE_BUILD_TYPE=Release -DENABLE_GETTEXT=0 -DENABLE_CURSES=0
cmake --build . --config Release
```
Make sure that the right compiler is selected and the path to the vcpkg toolchain is correct.
#### c) Using your own compiled libraries
**This is outdated and not recommended**
Follow the instructions on https://dev.minetest.net/Build_Win32_Minetest_including_all_required_libraries#VS2012_Build
### Windows Installer using WiX Toolset
Requirements:
* Visual Studio 2017
* Wix Toolset
* [Visual Studio 2017](https://visualstudio.microsoft.com/)
* [WiX Toolset](https://wixtoolset.org/)
In Visual Studio 2017 Installer select "Optional Features" -> "Wix Toolset"
In the Visual Studio 2017 Installer select **Optional Features -> WiX Toolset**.
Build the binaries like described above, but make sure you unselect "RUN_IN_PLACE".
Build the binaries as described above, but make sure you unselect `RUN_IN_PLACE`.
Open the generated Project file with VS. Right click "PACKAGE" and choose "Generate".
Open the generated project file with Visual Studio. Right-click **Package** and choose **Generate**.
It may take some minutes to generate the installer.
Docker
------
We provide Minetest server docker images using the Gitlab mirror registry.
We provide Minetest server Docker images using the GitLab mirror registry.
Images are built on each commit and available using the following tag scheme:
@@ -468,20 +388,20 @@ Images are built on each commit and available using the following tag scheme:
* `registry.gitlab.com/minetest/minetest/server:<branch/tag>` (current branch or current tag)
* `registry.gitlab.com/minetest/minetest/server:<commit-id>` (current commit id)
If you want to test it on a docker server, you can easily run:
If you want to test it on a Docker server you can easily run:
sudo docker run registry.gitlab.com/minetest/minetest/server:<docker tag>
If you want to use it in a production environment you should use volumes bound to the docker host
If you want to use it in a production environment you should use volumes bound to the Docker host
to persist data and modify the configuration:
sudo docker create -v /home/minetest/data/:/var/lib/minetest/ -v /home/minetest/conf/:/etc/minetest/ registry.gitlab.com/minetest/minetest/server:master
Data will be written to `/home/minetest/data` on the host, and configuration will be read from `/home/minetest/conf/minetest.conf`.
Note: If you don't understand the previous commands, please read the official Docker documentation before use.
**Note:** If you don't understand the previous commands please read the official Docker documentation before use.
You can also host your minetest server inside a Kubernetes cluster. See our example implementation in `misc/kubernetes.yml`.
You can also host your Minetest server inside a Kubernetes cluster. See our example implementation in [`misc/kubernetes.yml`](misc/kubernetes.yml).
Version scheme

11
build/android/.gitignore vendored Normal file
View File

@@ -0,0 +1,11 @@
*.iml
.externalNativeBuild
.gradle
app/build
app/release
app/src/main/assets
build
local.properties
native/.*
native/build
native/deps

View File

@@ -1,766 +0,0 @@
# build options
OS := $(shell uname)
# compile with GPROF
# GPROF = 1
# build for build platform
API = 14
APP_PLATFORM = android-$(API)
ANDR_ROOT = $(shell pwd)
PROJ_ROOT = $(shell realpath $(ANDR_ROOT)/../..)
APP_ROOT = $(ANDR_ROOT)/src/main
VERSION_MAJOR := $(shell cat $(PROJ_ROOT)/CMakeLists.txt | \
grep ^set\(VERSION_MAJOR\ | sed 's/)/ /' | cut -f2 -d' ')
VERSION_MINOR := $(shell cat $(PROJ_ROOT)/CMakeLists.txt | \
grep ^set\(VERSION_MINOR\ | sed 's/)/ /' | cut -f2 -d' ')
VERSION_PATCH := $(shell cat $(PROJ_ROOT)/CMakeLists.txt | \
grep ^set\(VERSION_PATCH\ | sed 's/)/ /' | cut -f2 -d' ')
################################################################################
# toolchain config for arm new processors
################################################################################
TARGET_HOST = arm-linux
TARGET_ABI = armeabi-v7a
TARGET_LIBDIR = armeabi-v7a
TARGET_TOOLCHAIN = arm-linux-androideabi-
TARGET_CFLAGS_ADDON = -mfloat-abi=softfp -mfpu=vfpv3 -O3
TARGET_CXXFLAGS_ADDON = $(TARGET_CFLAGS_ADDON)
TARGET_ARCH = armv7
CROSS_CC = clang
CROSS_CXX = clang++
COMPILER_VERSION = clang
HAVE_LEVELDB = 0
################################################################################
# toolchain config for little endian mips
################################################################################
#TARGET_HOST = mipsel-linux
#TARGET_ABI = mips
#TARGET_LIBDIR = mips
#TARGET_TOOLCHAIN = mipsel-linux-android-
#TARGET_ARCH = mips32
#CROSS_CC = mipsel-linux-android-gcc
#CROSS_CXX = mipsel-linux-android-g++
#COMPILER_VERSION = 4.9
#HAVE_LEVELDB = 0
################################################################################
# toolchain config for x86
################################################################################
#TARGET_HOST = x86-linux
#TARGET_ABI = x86
#TARGET_LIBDIR = x86
#TARGET_TOOLCHAIN = x86-
#TARGET_ARCH = x86
#CROSS_CC = clang
#CROSS_CXX = clang++
#COMPILER_VERSION = clang
#HAVE_LEVELDB = 0
################################################################################
ASSETS_TIMESTAMP = deps/assets_timestamp
LEVELDB_DIR = $(ANDR_ROOT)/deps/leveldb/
LEVELDB_LIB = $(LEVELDB_DIR)libleveldb.a
LEVELDB_TIMESTAMP = $(LEVELDB_DIR)/timestamp
LEVELDB_TIMESTAMP_INT = $(ANDR_ROOT)/deps/leveldb_timestamp
LEVELDB_URL_GIT = https://github.com/google/leveldb
LEVELDB_COMMIT = 2d0320a458d0e6a20fff46d5f80b18bfdcce7018
OPENAL_DIR = $(ANDR_ROOT)/deps/openal-soft/
OPENAL_LIB = $(OPENAL_DIR)libs/$(TARGET_ABI)/libopenal.so
OPENAL_TIMESTAMP = $(OPENAL_DIR)/timestamp
OPENAL_TIMESTAMP_INT = $(ANDR_ROOT)/deps/openal_timestamp
OPENAL_URL_GIT = https://github.com/apportable/openal-soft
OGG_DIR = $(ANDR_ROOT)/deps/libvorbis-libogg-android/
OGG_LIB = $(OGG_DIR)libs/$(TARGET_ABI)/libogg.so
VORBIS_LIB = $(OGG_DIR)libs/$(TARGET_ABI)/libogg.so
OGG_TIMESTAMP = $(OGG_DIR)timestamp
OGG_TIMESTAMP_INT = $(ANDR_ROOT)/deps/ogg_timestamp
OGG_URL_GIT = https://gitlab.com/minetest/libvorbis-libogg-android
IRRLICHT_REVISION = 5150
IRRLICHT_DIR = $(ANDR_ROOT)/deps/irrlicht/
IRRLICHT_LIB = $(IRRLICHT_DIR)lib/Android/libIrrlicht.a
IRRLICHT_TIMESTAMP = $(IRRLICHT_DIR)timestamp
IRRLICHT_TIMESTAMP_INT = $(ANDR_ROOT)/deps/irrlicht_timestamp
IRRLICHT_URL_SVN = https://svn.code.sf.net/p/irrlicht/code/branches/ogl-es@$(IRRLICHT_REVISION)
OPENSSL_VERSION = 1.0.2n
OPENSSL_BASEDIR = openssl-$(OPENSSL_VERSION)
OPENSSL_DIR = $(ANDR_ROOT)/deps/$(OPENSSL_BASEDIR)/
OPENSSL_LIB = $(OPENSSL_DIR)/libssl.a
OPENSSL_TIMESTAMP = $(OPENSSL_DIR)timestamp
OPENSSL_TIMESTAMP_INT = $(ANDR_ROOT)/deps/openssl_timestamp
OPENSSL_URL = https://www.openssl.org/source/openssl-$(OPENSSL_VERSION).tar.gz
CURL_VERSION = 7.60.0
CURL_DIR = $(ANDR_ROOT)/deps/curl-$(CURL_VERSION)
CURL_LIB = $(CURL_DIR)/lib/.libs/libcurl.a
CURL_TIMESTAMP = $(CURL_DIR)/timestamp
CURL_TIMESTAMP_INT = $(ANDR_ROOT)/deps/curl_timestamp
CURL_URL_HTTP = https://curl.haxx.se/download/curl-${CURL_VERSION}.tar.bz2
FREETYPE_DIR = $(ANDR_ROOT)/deps/freetype2-android/
FREETYPE_LIB = $(FREETYPE_DIR)/Android/obj/local/$(TARGET_ABI)/libfreetype2-static.a
FREETYPE_TIMESTAMP = $(FREETYPE_DIR)timestamp
FREETYPE_TIMESTAMP_INT = $(ANDR_ROOT)/deps/freetype_timestamp
FREETYPE_URL_GIT = https://github.com/cdave1/freetype2-android
ICONV_VERSION = 1.14
ICONV_DIR = $(ANDR_ROOT)/deps/libiconv/
ICONV_LIB = $(ICONV_DIR)/lib/.libs/libiconv.so
ICONV_TIMESTAMP = $(ICONV_DIR)timestamp
ICONV_TIMESTAMP_INT = $(ANDR_ROOT)/deps/iconv_timestamp
ICONV_URL_HTTP = https://ftp.gnu.org/pub/gnu/libiconv/libiconv-$(ICONV_VERSION).tar.gz
SQLITE3_FOLDER = sqlite-amalgamation-3240000
SQLITE3_URL = https://www.sqlite.org/2018/$(SQLITE3_FOLDER).zip
ANDROID_SDK = $(shell grep '^sdk\.dir' local.properties | sed 's/^.*=[[:space:]]*//')
ANDROID_NDK = $(shell grep '^ndk\.dir' local.properties | sed 's/^.*=[[:space:]]*//')
#use interim target variable to switch leveldb on or off
ifeq ($(HAVE_LEVELDB),1)
LEVELDB_TARGET = $(LEVELDB_LIB)
endif
.PHONY : debug release reconfig delconfig \
leveldb_download clean_leveldb leveldb\
irrlicht_download clean_irrlicht irrlicht \
clean_assets assets sqlite3_download \
freetype_download clean_freetype freetype \
apk clean_apk \
clean_all clean prep_srcdir \
install_debug install_release envpaths all \
$(ASSETS_TIMESTAMP) $(LEVELDB_TIMESTAMP) \
$(OPENAL_TIMESTAMP) $(OGG_TIMESTAMP) \
$(IRRLICHT_TIMESTAMP) $(CURL_TIMESTAMP) \
$(OPENSSL_TIMESTAMP) \
$(ANDR_ROOT)/jni/src/android_version.h \
$(ANDR_ROOT)/jni/src/android_version_githash.h
debug : local.properties
export NDEBUG=; \
export BUILD_TYPE=debug; \
$(MAKE) apk
all : debug release
release : local.properties
@export NDEBUG=1; \
export BUILD_TYPE=release; \
$(MAKE) apk
reconfig: delconfig
@$(MAKE) local.properties
delconfig:
$(RM) local.properties
local.properties:
@echo "Please specify path of ANDROID NDK"; \
echo "e.g. $$HOME/Android/Sdk/ndk-bundle/"; \
read ANDROID_NDK ; \
if [ ! -d $$ANDROID_NDK ] ; then \
echo "$$ANDROID_NDK is not a valid folder"; \
exit 1; \
fi; \
echo "ndk.dir = $$ANDROID_NDK" > local.properties; \
echo "Please specify path of ANDROID SDK"; \
echo "e.g. $$HOME/Android/Sdk/"; \
read SDKFLDR ; \
if [ ! -d $$SDKFLDR ] ; then \
echo "$$SDKFLDR is not a valid folder"; \
exit 1; \
fi; \
echo "sdk.dir = $$SDKFLDR" >> local.properties;
$(OPENAL_TIMESTAMP) : openal_download
@LAST_MODIF=$$(find ${OPENAL_DIR} -type f -printf '%T@ %p\n' | sort -n | tail -1 | cut -f2- -d" "); \
if [ $$(basename $$LAST_MODIF) != "timestamp" ] ; then \
touch ${OPENAL_TIMESTAMP}; \
fi
openal_download :
@if [ ! -d ${OPENAL_DIR} ] ; then \
echo "openal sources missing, downloading..."; \
mkdir -p ${ANDR_ROOT}/deps; \
cd ${ANDR_ROOT}/deps ; \
git clone ${OPENAL_URL_GIT} || exit 1; \
fi
openal : $(OPENAL_LIB)
$(OPENAL_LIB): $(OPENAL_TIMESTAMP)
+ @REFRESH=0; \
if [ ! -e ${OPENAL_TIMESTAMP_INT} ] ; then \
REFRESH=1; \
fi; \
if [ ${OPENAL_TIMESTAMP} -nt ${OPENAL_TIMESTAMP_INT} ] ; then \
REFRESH=1; \
fi; \
if [ $$REFRESH -ne 0 ] ; then \
echo "changed timestamp for openal detected building..."; \
cd ${OPENAL_DIR}; \
export APP_PLATFORM=${APP_PLATFORM}; \
export TARGET_ABI=${TARGET_ABI}; \
export TARGET_CFLAGS_ADDON="${TARGET_CFLAGS_ADDON}"; \
export TARGET_CXXFLAGS_ADDON="${TARGET_CXXFLAGS_ADDON}"; \
export COMPILER_VERSION=${COMPILER_VERSION}; \
${ANDROID_NDK}/ndk-build \
NDK_APPLICATION_MK=${ANDR_ROOT}/jni/Deps.mk || exit 1; \
touch ${OPENAL_TIMESTAMP}; \
touch ${OPENAL_TIMESTAMP_INT}; \
else \
echo "nothing to be done for openal"; \
fi
clean_openal :
$(RM) -rf ${OPENAL_DIR}
$(OGG_TIMESTAMP) : ogg_download
@LAST_MODIF=$$(find ${OGG_DIR} -type f -printf '%T@ %p\n' | sort -n | tail -1 | cut -f2- -d" "); \
if [ $$(basename $$LAST_MODIF) != "timestamp" ] ; then \
touch ${OGG_TIMESTAMP}; \
fi
ogg_download :
@if [ ! -d ${OGG_DIR} ] ; then \
echo "ogg sources missing, downloading..."; \
mkdir -p ${ANDR_ROOT}/deps; \
cd ${ANDR_ROOT}/deps ; \
git clone ${OGG_URL_GIT}|| exit 1; \
cd libvorbis-libogg-android ; \
patch -p1 < ${ANDR_ROOT}/patches/libvorbis-libogg-fpu.patch || exit 1; \
fi
ogg : $(OGG_LIB)
$(OGG_LIB): $(OGG_TIMESTAMP)
+ @REFRESH=0; \
if [ ! -e ${OGG_TIMESTAMP_INT} ] ; then \
echo "${OGG_TIMESTAMP_INT} doesn't exist"; \
REFRESH=1; \
fi; \
if [ ${OGG_TIMESTAMP} -nt ${OGG_TIMESTAMP_INT} ] ; then \
REFRESH=1; \
fi; \
if [ $$REFRESH -ne 0 ] ; then \
echo "changed timestamp for ogg detected building..."; \
cd ${OGG_DIR}; \
export APP_PLATFORM=${APP_PLATFORM}; \
export TARGET_ABI=${TARGET_ABI}; \
${ANDROID_NDK}/build/tools/make-standalone-toolchain.sh \
--toolchain=${TARGET_TOOLCHAIN}${COMPILER_VERSION} \
--platform=${APP_PLATFORM} \
--install-dir=$${TOOLCHAIN}; \
touch ${OGG_TIMESTAMP}; \
touch ${OGG_TIMESTAMP_INT}; \
else \
echo "nothing to be done for libogg/libvorbis"; \
fi
clean_ogg :
$(RM) -rf ${OGG_DIR}
$(OPENSSL_TIMESTAMP) : openssl_download
@LAST_MODIF=$$(find ${OPENSSL_DIR} -type f -printf '%T@ %p\n' | sort -n | tail -1 | cut -f2- -d" "); \
if [ $$(basename $$LAST_MODIF) != "timestamp" ] ; then \
touch ${OPENSSL_TIMESTAMP}; \
fi
openssl_download :
@if [ ! -d ${OPENSSL_DIR} ] ; then \
echo "openssl sources missing, downloading..."; \
mkdir -p ${ANDR_ROOT}/deps; \
cd ${ANDR_ROOT}/deps ; \
wget ${OPENSSL_URL} || exit 1; \
tar -xzf ${OPENSSL_BASEDIR}.tar.gz; \
cd ${OPENSSL_BASEDIR}; \
patch -p1 < ${ANDR_ROOT}/patches/openssl_arch.patch; \
sed -i 's/-mandroid //g' Configure; \
fi
openssl : $(OPENSSL_LIB)
$(OPENSSL_LIB): $(OPENSSL_TIMESTAMP)
@REFRESH=0; \
if [ ! -e ${OPENSSL_TIMESTAMP_INT} ] ; then \
echo "${OPENSSL_TIMESTAMP_INT} doesn't exist"; \
REFRESH=1; \
fi; \
if [ ${OPENSSL_TIMESTAMP} -nt ${OPENSSL_TIMESTAMP_INT} ] ; then \
REFRESH=1; \
fi; \
if [ $$REFRESH -ne 0 ] ; then \
echo "changed timestamp for openssl detected building..."; \
cd ${OPENSSL_DIR}; \
ln -s ${OPENSSL_DIR} ../openssl; \
export TOOLCHAIN=/tmp/ndk-${TARGET_HOST}-openssl; \
${ANDROID_NDK}/build/tools/make-standalone-toolchain.sh \
--toolchain=${TARGET_TOOLCHAIN}${COMPILER_VERSION} \
--platform=${APP_PLATFORM} \
--stl=libc++ \
--install-dir=$${TOOLCHAIN}; \
export PATH="$${TOOLCHAIN}/bin:$${PATH}"; \
export CFLAGS="$${CFLAGS} ${TARGET_CFLAGS_ADDON}"; \
export LDFLAGS="$${LDFLAGS} ${TARGET_LDFLAGS_ADDON}"; \
CC=${CROSS_CC} ./Configure -DL_ENDIAN no-asm android-${TARGET_ARCH} \
-D__ANDROID_API__=$(API); \
CC=${CROSS_CC} ANDROID_DEV=/tmp/ndk-${TARGET_HOST} make depend; \
CC=${CROSS_CC} ANDROID_DEV=/tmp/ndk-${TARGET_HOST} make build_libs; \
touch ${OPENSSL_TIMESTAMP}; \
touch ${OPENSSL_TIMESTAMP_INT}; \
$(RM) -rf $${TOOLCHAIN}; \
else \
echo "nothing to be done for openssl"; \
fi
clean_openssl :
$(RM) -rf ${OPENSSL_DIR}; \
$(RM) -rf $(ANDR_ROOT)/deps/${OPENSSL_BASEDIR}.tar.gz; \
$(RM) -rf $(ANDR_ROOT)/deps/openssl
$(LEVELDB_TIMESTAMP) : leveldb_download
@LAST_MODIF=$$(find ${LEVELDB_DIR} -type f -printf '%T@ %p\n' | sort -n | tail -1 | cut -f2- -d" "); \
if [ $$(basename $$LAST_MODIF) != "timestamp" ] ; then \
touch ${LEVELDB_TIMESTAMP}; \
fi
leveldb_download :
@if [ ! -d ${LEVELDB_DIR} ] ; then \
echo "leveldb sources missing, downloading..."; \
mkdir -p ${ANDR_ROOT}/deps; \
cd ${ANDR_ROOT}/deps ; \
git clone ${LEVELDB_URL_GIT} || exit 1; \
cd ${LEVELDB_DIR} || exit 1; \
git checkout ${LEVELDB_COMMIT} || exit 1; \
fi
leveldb : $(LEVELDB_LIB)
ifeq ($(HAVE_LEVELDB),1)
$(LEVELDB_LIB): $(LEVELDB_TIMESTAMP)
@REFRESH=0; \
if [ ! -e ${LEVELDB_TIMESTAMP_INT} ] ; then \
REFRESH=1; \
fi; \
if [ ${LEVELDB_TIMESTAMP} -nt ${LEVELDB_TIMESTAMP_INT} ] ; then \
REFRESH=1; \
fi; \
if [ $$REFRESH -ne 0 ] ; then \
echo "changed timestamp for leveldb detected building..."; \
cd deps/leveldb; \
export CROSS_PREFIX=${TARGET_TOOLCHAIN}; \
export TOOLCHAIN=/tmp/ndk-${TARGET_HOST}-leveldb; \
${ANDROID_NDK}/build/tools/make-standalone-toolchain.sh \
--toolchain=${TARGET_TOOLCHAIN}${COMPILER_VERSION} \
--platform=${APP_PLATFORM} \
--stl=libc++ \
--install-dir=$${TOOLCHAIN}; \
export PATH="$${TOOLCHAIN}/bin:$${PATH}"; \
export CC=${CROSS_CC}; \
export CXX=${CROSS_CXX}; \
export CFLAGS="$${CFLAGS} ${TARGET_CFLAGS_ADDON}"; \
export CPPFLAGS="$${CPPFLAGS} ${TARGET_CXXFLAGS_ADDON}"; \
export LDFLAGS="$${LDFLAGS} ${TARGET_LDFLAGS_ADDON}"; \
export TARGET_OS=OS_ANDROID_CROSSCOMPILE; \
$(MAKE) || exit 1; \
touch ${LEVELDB_TIMESTAMP}; \
touch ${LEVELDB_TIMESTAMP_INT}; \
$(RM) -rf $${TOOLCHAIN}; \
else \
echo "nothing to be done for leveldb"; \
fi
endif
clean_leveldb :
./gradlew cleanLevelDB
$(FREETYPE_TIMESTAMP) : freetype_download
@LAST_MODIF=$$(find ${FREETYPE_DIR} -type f -printf '%T@ %p\n' | sort -n | tail -1 | cut -f2- -d" "); \
if [ $$(basename $$LAST_MODIF) != "timestamp" ] ; then \
touch ${FREETYPE_TIMESTAMP}; \
fi
freetype_download :
@if [ ! -d ${FREETYPE_DIR} ] ; then \
echo "freetype sources missing, downloading..."; \
mkdir -p ${ANDR_ROOT}/deps; \
cd deps; \
git clone ${FREETYPE_URL_GIT} || exit 1; \
fi
freetype : $(FREETYPE_LIB)
$(FREETYPE_LIB) : $(FREETYPE_TIMESTAMP)
+ @REFRESH=0; \
if [ ! -e ${FREETYPE_TIMESTAMP_INT} ] ; then \
REFRESH=1; \
fi; \
if [ ! -e ${FREETYPE_LIB} ] ; then \
REFRESH=1; \
fi; \
if [ ${FREETYPE_TIMESTAMP} -nt ${FREETYPE_TIMESTAMP_INT} ] ; then \
REFRESH=1; \
fi; \
if [ $$REFRESH -ne 0 ] ; then \
mkdir -p ${FREETYPE_DIR}; \
echo "changed timestamp for freetype detected building..."; \
cd ${FREETYPE_DIR}/Android/jni; \
export APP_PLATFORM=${APP_PLATFORM}; \
export TARGET_ABI=${TARGET_ABI}; \
export TARGET_CFLAGS_ADDON="${TARGET_CFLAGS_ADDON}"; \
export TARGET_CXXFLAGS_ADDON="${TARGET_CXXFLAGS_ADDON}"; \
export COMPILER_VERSION=${COMPILER_VERSION}; \
${ANDROID_NDK}/ndk-build \
NDK_APPLICATION_MK=${ANDR_ROOT}/jni/Deps.mk || exit 1; \
touch ${FREETYPE_TIMESTAMP}; \
touch ${FREETYPE_TIMESTAMP_INT}; \
else \
echo "nothing to be done for freetype"; \
fi
clean_freetype :
./gradlew cleanFreetype
$(ICONV_TIMESTAMP) : iconv_download
@LAST_MODIF=$$(find ${ICONV_DIR} -type f -printf '%T@ %p\n' | sort -n | tail -1 | cut -f2- -d" "); \
if [ $$(basename $$LAST_MODIF) != "timestamp" ] ; then \
touch ${ICONV_TIMESTAMP}; \
fi
iconv_download :
@if [ ! -d ${ICONV_DIR} ] ; then \
echo "iconv sources missing, downloading..."; \
mkdir -p ${ANDR_ROOT}/deps; \
cd ${ANDR_ROOT}/deps; \
wget ${ICONV_URL_HTTP} || exit 1; \
tar -xzf libiconv-${ICONV_VERSION}.tar.gz || exit 1; \
rm libiconv-${ICONV_VERSION}.tar.gz; \
ln -s libiconv-${ICONV_VERSION} libiconv; \
cd ${ICONV_DIR}; \
patch -p1 < ${ANDR_ROOT}/patches/libiconv_android.patch; \
patch -p1 < ${ANDR_ROOT}/patches/libiconv_stdio.patch; \
fi
iconv : $(ICONV_LIB)
$(ICONV_LIB) : $(ICONV_TIMESTAMP)
@REFRESH=0; \
if [ ! -e ${ICONV_TIMESTAMP_INT} ] ; then \
REFRESH=1; \
fi; \
if [ ! -e ${ICONV_LIB} ] ; then \
REFRESH=1; \
fi; \
if [ ${ICONV_TIMESTAMP} -nt ${ICONV_TIMESTAMP_INT} ] ; then \
REFRESH=1; \
fi; \
if [ $$REFRESH -ne 0 ] ; then \
mkdir -p ${ICONV_DIR}; \
echo "changed timestamp for iconv detected building..."; \
cd ${ICONV_DIR}; \
export TOOLCHAIN=/tmp/ndk-${TARGET_HOST}-iconv; \
${ANDROID_NDK}/build/tools/make-standalone-toolchain.sh \
--toolchain=${TARGET_TOOLCHAIN}${COMPILER_VERSION} \
--platform=${APP_PLATFORM} \
--stl=libc++ \
--install-dir=$${TOOLCHAIN}; \
export PATH="$${TOOLCHAIN}/bin:$${PATH}"; \
export CFLAGS="$${CFLAGS} ${TARGET_CFLAGS_ADDON}"; \
export LDFLAGS="$${LDFLAGS} ${TARGET_LDFLAGS_ADDON} -lstdc++"; \
export CC=${CROSS_CC}; \
export CXX=${CROSS_CXX}; \
export TARGET_OS=OS_ANDROID_CROSSCOMPILE; \
./configure --host=${TARGET_HOST} || exit 1; \
sed -i 's/LIBICONV_VERSION_INFO) /LIBICONV_VERSION_INFO) -avoid-version /g' lib/Makefile; \
grep "iconv_LDFLAGS" src/Makefile; \
$(MAKE) -s || exit 1; \
touch ${ICONV_TIMESTAMP}; \
touch ${ICONV_TIMESTAMP_INT}; \
rm -rf ${TOOLCHAIN}; \
else \
echo "nothing to be done for iconv"; \
fi
clean_iconv :
./gradlew cleanIconv
#Note: Texturehack patch is required for gpu's not supporting color format
# correctly. Known bad GPU:
# -geforce on emulator
# -Vivante Corporation GC1000 core (e.g. Galaxy Tab 3)
irrlicht_download :
@if [ ! -d "deps/irrlicht" ] ; then \
echo "irrlicht sources missing, downloading..."; \
mkdir -p ${ANDR_ROOT}/deps; \
cd deps; \
svn co ${IRRLICHT_URL_SVN} irrlicht || exit 1; \
cd irrlicht; \
patch -p1 < ${ANDR_ROOT}/patches/irrlicht-touchcount.patch || exit 1; \
patch -p1 < ${ANDR_ROOT}/patches/irrlicht-back_button.patch || exit 1; \
patch -p1 < ${ANDR_ROOT}/patches/irrlicht-texturehack.patch || exit 1; \
patch -p1 < ${ANDR_ROOT}/patches/irrlicht-native_activity.patch || exit 1; \
fi
$(IRRLICHT_TIMESTAMP) : irrlicht_download
@LAST_MODIF=$$(find ${IRRLICHT_DIR} -type f -printf '%T@ %p\n' | sort -n | tail -1 | cut -f2- -d" "); \
if [ $$(basename $$LAST_MODIF) != "timestamp" ] ; then \
touch ${IRRLICHT_TIMESTAMP}; \
fi
irrlicht : $(IRRLICHT_LIB)
$(IRRLICHT_LIB): $(IRRLICHT_TIMESTAMP) $(FREETYPE_LIB)
+ @REFRESH=0; \
if [ ! -e ${IRRLICHT_TIMESTAMP_INT} ] ; then \
REFRESH=1; \
fi; \
if [ ! -e ${IRRLICHT_LIB} ] ; then \
REFRESH=1; \
fi; \
if [ ${IRRLICHT_TIMESTAMP} -nt ${IRRLICHT_TIMESTAMP_INT} ] ; then \
REFRESH=1; \
fi; \
if [ $$REFRESH -ne 0 ] ; then \
mkdir -p ${IRRLICHT_DIR}; \
echo "changed timestamp for irrlicht detected building..."; \
cd deps/irrlicht/source/Irrlicht/Android; \
export APP_PLATFORM=${APP_PLATFORM}; \
export TARGET_ABI=${TARGET_ABI}; \
export TARGET_CFLAGS_ADDON="${TARGET_CFLAGS_ADDON}"; \
export TARGET_CXXFLAGS_ADDON="${TARGET_CXXFLAGS_ADDON}"; \
export COMPILER_VERSION=${COMPILER_VERSION}; \
${ANDROID_NDK}/ndk-build \
NDK_APPLICATION_MK=${ANDR_ROOT}/jni/Deps.mk || exit 1; \
touch ${IRRLICHT_TIMESTAMP}; \
touch ${IRRLICHT_TIMESTAMP_INT}; \
else \
echo "nothing to be done for irrlicht"; \
fi
clean_irrlicht :
./gradlew cleanIrrlicht
$(CURL_TIMESTAMP) : curl_download
@LAST_MODIF=$$(find ${CURL_DIR} -type f -printf '%T@ %p\n' | sort -n | tail -1 | cut -f2- -d" "); \
if [ $$(basename $$LAST_MODIF) != "timestamp" ] ; then \
touch ${CURL_TIMESTAMP}; \
fi
curl_download :
@if [ ! -d "deps/curl-${CURL_VERSION}" ] ; then \
echo "curl sources missing, downloading..."; \
mkdir -p ${ANDR_ROOT}/deps; \
cd deps; \
wget ${CURL_URL_HTTP} || exit 1; \
tar -xjf curl-${CURL_VERSION}.tar.bz2 || exit 1; \
rm curl-${CURL_VERSION}.tar.bz2; \
ln -s curl-${CURL_VERSION} curl; \
fi
curl : $(CURL_LIB)
$(CURL_LIB): $(CURL_TIMESTAMP) $(OPENSSL_LIB)
@REFRESH=0; \
if [ ! -e ${CURL_TIMESTAMP_INT} ] ; then \
REFRESH=1; \
fi; \
if [ ! -e ${CURL_LIB} ] ; then \
REFRESH=1; \
fi; \
if [ ${CURL_TIMESTAMP} -nt ${CURL_TIMESTAMP_INT} ] ; then \
REFRESH=1; \
fi; \
if [ $$REFRESH -ne 0 ] ; then \
mkdir -p ${CURL_DIR}; \
echo "changed timestamp for curl detected building..."; \
cd deps/curl-${CURL_VERSION}; \
export CROSS_PREFIX=${TARGET_TOOLCHAIN}; \
export TOOLCHAIN=/tmp/ndk-${TARGET_HOST}-curl; \
${ANDROID_NDK}/build/tools/make-standalone-toolchain.sh \
--toolchain=${TARGET_TOOLCHAIN}${COMPILER_VERSION} \
--platform=${APP_PLATFORM} \
--stl=libc++ \
--install-dir=$${TOOLCHAIN}; \
export PATH="$${TOOLCHAIN}/bin:$${PATH}"; \
export CC=${CROSS_CC}; \
export CXX=${CROSS_CXX}; \
export TARGET_OS=OS_ANDROID_CROSSCOMPILE; \
export CPPFLAGS="$${CPPFLAGS} -I${OPENSSL_DIR}/include ${TARGET_CFLAGS_ADDON}"; \
export CFLAGS="$${CFLAGS} ${TARGET_CFLAGS_ADDON}"; \
export LDFLAGS="$${LDFLAGS} -L${OPENSSL_DIR} ${TARGET_LDFLAGS_ADDON}"; \
./configure --host=${TARGET_HOST} --disable-shared --enable-static --with-ssl; \
$(MAKE) -s || exit 1; \
touch ${CURL_TIMESTAMP}; \
touch ${CURL_TIMESTAMP_INT}; \
$(RM) -rf $${TOOLCHAIN}; \
else \
echo "nothing to be done for curl"; \
fi
clean_curl :
./gradlew cleanCURL
sqlite3_download: deps/${SQLITE3_FOLDER}/sqlite3.c
deps/${SQLITE3_FOLDER}/sqlite3.c :
cd deps; \
wget ${SQLITE3_URL}; \
unzip ${SQLITE3_FOLDER}.zip; \
ln -s ${SQLITE3_FOLDER} sqlite; \
cd ${SQLITE3_FOLDER};
clean_sqlite3:
./gradlew cleanSQLite3
$(ASSETS_TIMESTAMP) : $(IRRLICHT_LIB)
@mkdir -p ${ANDR_ROOT}/deps; \
for DIRNAME in {builtin,client,doc,fonts,games,mods,po,textures}; do \
LAST_MODIF=$$(find ${PROJ_ROOT}/${DIRNAME} -type f -printf '%T@ %p\n' | sort -n | tail -1 | cut -f2- -d" "); \
if [ $$(basename $$LAST_MODIF) != "timestamp" ]; then \
touch ${PROJ_ROOT}/${DIRNAME}/timestamp; \
touch ${ASSETS_TIMESTAMP}; \
echo ${DIRNAME} changed $$LAST_MODIF; \
fi; \
done; \
LAST_MODIF=$$(find ${IRRLICHT_DIR}/media -type f -printf '%T@ %p\n' | sort -n | tail -1 | cut -f2- -d" "); \
if [ $$(basename $$LAST_MODIF) != "timestamp" ] ; then \
touch ${IRRLICHT_DIR}/media/timestamp; \
touch ${ASSETS_TIMESTAMP}; \
fi; \
if [ ${PROJ_ROOT}/minetest.conf.example -nt ${ASSETS_TIMESTAMP} ] ; then \
echo "conf changed"; \
touch ${ASSETS_TIMESTAMP}; \
fi; \
if [ ${PROJ_ROOT}/README.txt -nt ${ASSETS_TIMESTAMP} ] ; then \
touch ${ASSETS_TIMESTAMP}; \
fi; \
if [ ! -e $(ASSETS_TIMESTAMP) ] ; then \
touch $(ASSETS_TIMESTAMP); \
fi
assets : $(ASSETS_TIMESTAMP)
@REFRESH=0; \
if [ ! -e ${ASSETS_TIMESTAMP}.old ] ; then \
REFRESH=1; \
fi; \
if [ ${ASSETS_TIMESTAMP} -nt ${ASSETS_TIMESTAMP}.old ] ; then \
REFRESH=1; \
fi; \
if [ ! -d ${APP_ROOT}/assets ] ; then \
REFRESH=1; \
fi; \
if [ $$REFRESH -ne 0 ] ; then \
echo "assets changed, refreshing..."; \
$(MAKE) clean_assets; \
./gradlew copyAssets; \
cp -r ${IRRLICHT_DIR}/media/Shaders ${APP_ROOT}/assets/Minetest/media; \
cd ${APP_ROOT}/assets || exit 1; \
find . -name "timestamp" -exec rm {} \; ; \
find . -name "*.blend" -exec rm {} \; ; \
find . -name "*~" -exec rm {} \; ; \
find . -type d -path "*.git" -exec rm -rf {} \; ; \
find . -type d -path "*.svn" -exec rm -rf {} \; ; \
find . -type f -path "*.gitignore" -exec rm -rf {} \; ; \
ls -R | grep ":$$" | sed -e 's/:$$//' -e 's/\.//' -e 's/^\///' > "index.txt"; \
find -L Minetest > filelist.txt; \
cp ${ANDR_ROOT}/${ASSETS_TIMESTAMP} ${ANDR_ROOT}/${ASSETS_TIMESTAMP}.old; \
else \
echo "nothing to be done for assets"; \
fi
clean_assets :
./gradlew cleanAssets
apk: local.properties assets $(ICONV_LIB) $(IRRLICHT_LIB) $(CURL_LIB) $(LEVELDB_TARGET) \
$(OPENAL_LIB) $(OGG_LIB) prep_srcdir $(ANDR_ROOT)/jni/src/android_version.h \
$(ANDR_ROOT)/jni/src/android_version_githash.h sqlite3_download
+ @export TARGET_LIBDIR=${TARGET_LIBDIR}; \
export HAVE_LEVELDB=${HAVE_LEVELDB}; \
export APP_PLATFORM=${APP_PLATFORM}; \
export TARGET_ABI=${TARGET_ABI}; \
export TARGET_CFLAGS_ADDON="${TARGET_CFLAGS_ADDON}"; \
export TARGET_CXXFLAGS_ADDON="${TARGET_CXXFLAGS_ADDON}"; \
export COMPILER_VERSION=${COMPILER_VERSION}; \
export GPROF=${GPROF}; \
${ANDROID_NDK}/ndk-build || exit 1; \
if [ ! -e ${APP_ROOT}/jniLibs ]; then \
ln -s ${ANDR_ROOT}/libs ${APP_ROOT}/jniLibs || exit 1; \
fi; \
export VERSION_STR="${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}" && \
export BUILD_TYPE_C=$$(echo "$${BUILD_TYPE}" | sed 's/./\U&/') && \
./gradlew assemble$$BUILD_TYPE_C && \
echo "APK stored at: build/outputs/apk/$$BUILD_TYPE/Minetest-$$BUILD_TYPE.apk" && \
echo "You can install it with \`make install_$$BUILD_TYPE\`"
# These Intentionally doesn't depend on their respective build steps,
# because it takes a while to verify that everything's up-to-date.
install_debug:
${ANDROID_SDK}/platform-tools/adb install -r build/outputs/apk/debug/Minetest-debug.apk
install_release:
${ANDROID_SDK}/platform-tools/adb install -r build/outputs/apk/release/Minetest-release.apk
prep_srcdir :
@if [ ! -e ${ANDR_ROOT}/jni/src ]; then \
ln -s ${PROJ_ROOT}/src ${ANDR_ROOT}/jni/src; \
fi; \
if [ ! -e ${ANDR_ROOT}/jni/lib ]; then \
ln -s ${PROJ_ROOT}/lib ${ANDR_ROOT}/jni/lib; \
fi
clean_apk :
./gradlew clean
clean_all :
./gradlew cleanAll
$(ANDR_ROOT)/jni/src/android_version_githash.h : prep_srcdir
@export VERSION_FILE=${ANDR_ROOT}/jni/src/android_version_githash.h; \
export VERSION_FILE_NEW=$${VERSION_FILE}.new; \
{ \
echo "#ifndef ANDROID_MT_VERSION_GITHASH_H"; \
echo "#define ANDROID_MT_VERSION_GITHASH_H"; \
export GITHASH=$$(git rev-parse --short=8 HEAD); \
export VERSION_STR="${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}"; \
echo "#define VERSION_GITHASH \"$$VERSION_STR-$$GITHASH-Android\""; \
echo "#endif"; \
} > "$${VERSION_FILE_NEW}"; \
if ! cmp -s $${VERSION_FILE} $${VERSION_FILE_NEW}; then \
echo "android_version_githash.h changed, updating..."; \
mv "$${VERSION_FILE_NEW}" "$${VERSION_FILE}"; \
else \
rm "$${VERSION_FILE_NEW}"; \
fi
$(ANDR_ROOT)/jni/src/android_version.h : prep_srcdir
@export VERSION_FILE=${ANDR_ROOT}/jni/src/android_version.h; \
export VERSION_FILE_NEW=$${VERSION_FILE}.new; \
{ \
echo "#ifndef ANDROID_MT_VERSION_H"; \
echo "#define ANDROID_MT_VERSION_H"; \
echo "#define VERSION_MAJOR ${VERSION_MAJOR}"; \
echo "#define VERSION_MINOR ${VERSION_MINOR}"; \
echo "#define VERSION_PATCH ${VERSION_PATCH}"; \
echo "#define VERSION_STRING STR(VERSION_MAJOR) \".\" STR(VERSION_MINOR) \
\".\" STR(VERSION_PATCH)"; \
echo "#endif"; \
} > $${VERSION_FILE_NEW}; \
if ! cmp -s $${VERSION_FILE} $${VERSION_FILE_NEW}; then \
echo "android_version.h changed, updating..."; \
mv "$${VERSION_FILE_NEW}" "$${VERSION_FILE}"; \
else \
rm "$${VERSION_FILE_NEW}"; \
fi
clean : clean_apk clean_assets

View File

@@ -0,0 +1,111 @@
apply plugin: 'com.android.application'
android {
compileSdkVersion 29
buildToolsVersion '29.0.3'
ndkVersion '21.1.6352462'
defaultConfig {
applicationId 'net.minetest.minetest'
minSdkVersion 16
targetSdkVersion 29
versionName "${versionMajor}.${versionMinor}.${versionPatch}"
versionCode project.versionCode
}
Properties props = new Properties()
props.load(new FileInputStream(file('../local.properties')))
if (props.getProperty('keystore') != null) {
signingConfigs {
release {
storeFile file(props['keystore'])
storePassword props['keystore.password']
keyAlias props['key']
keyPassword props['key.password']
}
}
buildTypes {
release {
minifyEnabled true
signingConfig signingConfigs.release
}
}
}
// for multiple APKs
splits {
abi {
enable true
reset()
include 'armeabi-v7a', 'arm64-v8a'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
task prepareAssets() {
def assetsFolder = "build/assets"
def projRoot = "../../.."
def gameToCopy = "minetest_game"
copy {
from "${projRoot}/minetest.conf.example", "${projRoot}/README.md" into assetsFolder
}
copy {
from "${projRoot}/doc/lgpl-2.1.txt" into "${assetsFolder}"
}
copy {
from "${projRoot}/builtin" into "${assetsFolder}/builtin"
}
/*copy {
// ToDo: fix Minetest shaders that currently don't work with OpenGL ES
from "${projRoot}/client/shaders" into "${assetsFolder}/client/shaders"
}*/
copy {
from "../native/deps/Android/Irrlicht/shaders" into "${assetsFolder}/client/shaders/Irrlicht"
}
copy {
from "${projRoot}/fonts" include "*.ttf" into "${assetsFolder}/fonts"
}
copy {
from "${projRoot}/games/${gameToCopy}" into "${assetsFolder}/games/${gameToCopy}"
}
/*copy {
// ToDo: fix broken locales
from "${projRoot}/po" into "${assetsFolder}/po"
}*/
copy {
from "${projRoot}/textures" into "${assetsFolder}/textures"
}
file("${assetsFolder}/.nomedia").text = "";
task zipAssets(type: Zip) {
archiveName "Minetest.zip"
from "${assetsFolder}"
destinationDir file("src/main/assets")
}
}
preBuild.dependsOn zipAssets
// Map for the version code that gives each ABI a value.
import com.android.build.OutputFile
def abiCodes = ['armeabi-v7a': 0, 'arm64-v8a': 1]
android.applicationVariants.all { variant ->
variant.outputs.each {
output ->
def abiName = output.getFilter(OutputFile.ABI)
output.versionCodeOverride = abiCodes.get(abiName, 0) + variant.versionCode
}
}
dependencies {
implementation project(':native')
implementation 'androidx.appcompat:appcompat:1.1.0'
}

View File

@@ -1,30 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="net.minetest.minetest"
android:installLocation="auto">
<uses-feature
android:glEsVersion="0x00010000"
android:required="true" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!--
`android:requestLegacyExternalStorage="true"` is workaround for using `/sdcard`
instead of the `getFilesDir()` patch for assets. Check link below for more information:
https://developer.android.com/training/data-storage/compatibility
-->
<application
android:allowBackup="true"
android:allowBackup="false"
android:icon="@mipmap/ic_launcher"
android:label="${project}"
android:resizeableActivity="false">
android:label="@string/label"
android:resizeableActivity="false"
android:requestLegacyExternalStorage="true"
tools:ignore="UnusedAttribute">
<meta-data
android:name="android.max_aspect"
android:value="2.1" />
android:value="3.0" />
<activity
android:name=".MainActivity"
android:configChanges="orientation|keyboardHidden|navigation|screenSize"
android:label="${project}"
android:launchMode="singleTask"
android:maxAspectRatio="3.0"
android:screenOrientation="sensorLandscape"
android:theme="@style/AppTheme">
<intent-filter>
@@ -32,11 +36,13 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".MtNativeActivity"
android:name=".GameActivity"
android:configChanges="orientation|keyboard|keyboardHidden|navigation|screenSize|smallestScreenSize"
android:hardwareAccelerated="true"
android:launchMode="singleTask"
android:maxAspectRatio="3.0"
android:screenOrientation="sensorLandscape"
android:theme="@style/AppTheme">
<intent-filter>
@@ -44,16 +50,18 @@
</intent-filter>
<meta-data
android:name="android.app.lib_name"
android:value="minetest" />
android:value="Minetest" />
</activity>
<activity
android:name=".MinetestTextEntry"
android:configChanges="keyboardHidden|orientation|screenSize"
android:theme="@style/Theme.Dialog"
android:windowSoftInputMode="stateAlwaysHidden"/>
<activity
android:name=".MinetestAssetCopy"
android:screenOrientation="sensorLandscape"
android:theme="@style/AppTheme"/>
android:name=".InputDialogActivity"
android:maxAspectRatio="3.0"
android:theme="@style/InputTheme" />
<service
android:name=".UnzipService"
android:enabled="true"
android:exported="false" />
</application>
</manifest>

View File

@@ -0,0 +1,82 @@
/*
Minetest
Copyright (C) 2014-2020 MoNTE48, Maksim Gamarnik <MoNTE48@mail.ua>
Copyright (C) 2014-2020 ubulem, Bektur Mambetov <berkut87@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.
*/
package net.minetest.minetest;
import android.content.Intent;
import android.os.AsyncTask;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.ref.WeakReference;
public class CopyZipTask extends AsyncTask<String, Void, String> {
private final WeakReference<AppCompatActivity> activityRef;
CopyZipTask(AppCompatActivity activity) {
activityRef = new WeakReference<>(activity);
}
protected String doInBackground(String... params) {
copyAsset(params[0]);
return params[0];
}
@Override
protected void onPostExecute(String result) {
startUnzipService(result);
}
private void copyAsset(String zipName) {
String filename = zipName.substring(zipName.lastIndexOf("/") + 1);
try (InputStream in = activityRef.get().getAssets().open(filename);
OutputStream out = new FileOutputStream(zipName)) {
copyFile(in, out);
} catch (IOException e) {
AppCompatActivity activity = activityRef.get();
if (activity != null) {
activity.runOnUiThread(() -> Toast.makeText(activityRef.get(), e.getLocalizedMessage(), Toast.LENGTH_LONG).show());
}
cancel(true);
}
}
private void copyFile(InputStream in, OutputStream out) throws IOException {
byte[] buffer = new byte[1024];
int read;
while ((read = in.read(buffer)) != -1)
out.write(buffer, 0, read);
}
private void startUnzipService(String file) {
Intent intent = new Intent(activityRef.get(), UnzipService.class);
intent.putExtra(UnzipService.EXTRA_KEY_IN_FILE, file);
AppCompatActivity activity = activityRef.get();
if (activity != null) {
activity.startService(intent);
}
}
}

View File

@@ -0,0 +1,126 @@
/*
Minetest
Copyright (C) 2014-2020 MoNTE48, Maksim Gamarnik <MoNTE48@mail.ua>
Copyright (C) 2014-2020 ubulem, Bektur Mambetov <berkut87@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.
*/
package net.minetest.minetest;
import android.app.NativeActivity;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.view.WindowManager;
public class GameActivity extends NativeActivity {
static {
System.loadLibrary("c++_shared");
System.loadLibrary("Minetest");
}
private int messageReturnCode;
private String messageReturnValue;
public static native void putMessageBoxResult(String text);
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
messageReturnCode = -1;
messageReturnValue = "";
}
private void makeFullScreen() {
if (Build.VERSION.SDK_INT >= 19)
this.getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
}
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus)
makeFullScreen();
}
@Override
protected void onResume() {
super.onResume();
makeFullScreen();
}
@Override
public void onBackPressed() {
// Ignore the back press so Minetest can handle it
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 101) {
if (resultCode == RESULT_OK) {
String text = data.getStringExtra("text");
messageReturnCode = 0;
messageReturnValue = text;
} else
messageReturnCode = 1;
}
}
public void showDialog(String acceptButton, String hint, String current, int editType) {
Intent intent = new Intent(this, InputDialogActivity.class);
Bundle params = new Bundle();
params.putString("acceptButton", acceptButton);
params.putString("hint", hint);
params.putString("current", current);
params.putInt("editType", editType);
intent.putExtras(params);
startActivityForResult(intent, 101);
messageReturnValue = "";
messageReturnCode = -1;
}
public int getDialogState() {
return messageReturnCode;
}
public String getDialogValue() {
messageReturnCode = -1;
return messageReturnValue;
}
public float getDensity() {
return getResources().getDisplayMetrics().density;
}
public int getDisplayHeight() {
return getResources().getDisplayMetrics().heightPixels;
}
public int getDisplayWidth() {
return getResources().getDisplayMetrics().widthPixels;
}
public void openURL(String url) {
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(browserIntent);
}
}

View File

@@ -0,0 +1,98 @@
/*
Minetest
Copyright (C) 2014-2020 MoNTE48, Maksim Gamarnik <MoNTE48@mail.ua>
Copyright (C) 2014-2020 ubulem, Bektur Mambetov <berkut87@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.
*/
package net.minetest.minetest;
import android.app.Activity;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.text.InputType;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import java.util.Objects;
public class InputDialogActivity extends AppCompatActivity {
private AlertDialog alertDialog;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle b = getIntent().getExtras();
int editType = Objects.requireNonNull(b).getInt("editType");
String hint = b.getString("hint");
String current = b.getString("current");
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
EditText editText = new EditText(this);
builder.setView(editText);
editText.requestFocus();
editText.setHint(hint);
editText.setText(current);
final InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
Objects.requireNonNull(imm).toggleSoftInput(InputMethodManager.SHOW_FORCED,
InputMethodManager.HIDE_IMPLICIT_ONLY);
if (editType == 3)
editText.setInputType(InputType.TYPE_CLASS_TEXT |
InputType.TYPE_TEXT_VARIATION_PASSWORD);
else
editText.setInputType(InputType.TYPE_CLASS_TEXT);
editText.setOnKeyListener((view, KeyCode, event) -> {
if (KeyCode == KeyEvent.KEYCODE_ENTER) {
imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);
pushResult(editText.getText().toString());
return true;
}
return false;
});
alertDialog = builder.create();
if (!this.isFinishing())
alertDialog.show();
alertDialog.setOnCancelListener(dialog -> {
pushResult(editText.getText().toString());
setResult(Activity.RESULT_CANCELED);
alertDialog.dismiss();
makeFullScreen();
finish();
});
}
private void pushResult(String text) {
Intent resultData = new Intent();
resultData.putExtra("text", text);
setResult(AppCompatActivity.RESULT_OK, resultData);
alertDialog.dismiss();
makeFullScreen();
finish();
}
private void makeFullScreen() {
if (Build.VERSION.SDK_INT >= 19)
this.getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
}
}

View File

@@ -0,0 +1,153 @@
/*
Minetest
Copyright (C) 2014-2020 MoNTE48, Maksim Gamarnik <MoNTE48@mail.ua>
Copyright (C) 2014-2020 ubulem, Bektur Mambetov <berkut87@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.
*/
package net.minetest.minetest;
import android.Manifest;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static net.minetest.minetest.UnzipService.ACTION_FAILURE;
import static net.minetest.minetest.UnzipService.ACTION_PROGRESS;
import static net.minetest.minetest.UnzipService.ACTION_UPDATE;
import static net.minetest.minetest.UnzipService.FAILURE;
import static net.minetest.minetest.UnzipService.SUCCESS;
public class MainActivity extends AppCompatActivity {
private final static int versionCode = BuildConfig.VERSION_CODE;
private final static int PERMISSIONS = 1;
private static final String[] REQUIRED_SDK_PERMISSIONS =
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE};
private static final String SETTINGS = "MinetestSettings";
private static final String TAG_VERSION_CODE = "versionCode";
private ProgressBar mProgressBar;
private TextView mTextView;
private SharedPreferences sharedPreferences;
private final BroadcastReceiver myReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
int progress = 0;
if (intent != null)
progress = intent.getIntExtra(ACTION_PROGRESS, 0);
if (progress >= 0) {
if (mProgressBar != null) {
mProgressBar.setVisibility(View.VISIBLE);
mProgressBar.setProgress(progress);
}
mTextView.setVisibility(View.VISIBLE);
} else if (progress == FAILURE) {
Toast.makeText(MainActivity.this, intent.getStringExtra(ACTION_FAILURE), Toast.LENGTH_LONG).show();
finish();
} else if (progress == SUCCESS)
startNative();
}
};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
IntentFilter filter = new IntentFilter(ACTION_UPDATE);
registerReceiver(myReceiver, filter);
mProgressBar = findViewById(R.id.progressBar);
mTextView = findViewById(R.id.textView);
sharedPreferences = getSharedPreferences(SETTINGS, Context.MODE_PRIVATE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
checkPermission();
else
checkAppVersion();
}
private void checkPermission() {
final List<String> missingPermissions = new ArrayList<>();
for (final String permission : REQUIRED_SDK_PERMISSIONS) {
final int result = ContextCompat.checkSelfPermission(this, permission);
if (result != PackageManager.PERMISSION_GRANTED)
missingPermissions.add(permission);
}
if (!missingPermissions.isEmpty()) {
final String[] permissions = missingPermissions
.toArray(new String[0]);
ActivityCompat.requestPermissions(this, permissions, PERMISSIONS);
} else {
final int[] grantResults = new int[REQUIRED_SDK_PERMISSIONS.length];
Arrays.fill(grantResults, PackageManager.PERMISSION_GRANTED);
onRequestPermissionsResult(PERMISSIONS, REQUIRED_SDK_PERMISSIONS, grantResults);
}
}
@Override
public void onRequestPermissionsResult(int requestCode,
@NonNull String[] permissions, @NonNull int[] grantResults) {
if (requestCode == PERMISSIONS) {
for (int grantResult : grantResults) {
if (grantResult != PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, R.string.not_granted, Toast.LENGTH_LONG).show();
finish();
}
}
checkAppVersion();
}
}
private void checkAppVersion() {
if (sharedPreferences.getInt(TAG_VERSION_CODE, 0) == versionCode)
startNative();
else
new CopyZipTask(this).execute(getCacheDir() + "/Minetest.zip");
}
private void startNative() {
sharedPreferences.edit().putInt(TAG_VERSION_CODE, versionCode).apply();
Intent intent = new Intent(this, GameActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
}
@Override
public void onBackPressed() {
// Prevent abrupt interruption when copy game files from assets
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(myReceiver);
}
}

View File

@@ -0,0 +1,157 @@
/*
Minetest
Copyright (C) 2014-2020 MoNTE48, Maksim Gamarnik <MoNTE48@mail.ua>
Copyright (C) 2014-2020 ubulem, Bektur Mambetov <berkut87@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.
*/
package net.minetest.minetest;
import android.app.IntentService;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Environment;
import android.widget.Toast;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
public class UnzipService extends IntentService {
public static final String ACTION_UPDATE = "net.minetest.minetest.UPDATE";
public static final String ACTION_PROGRESS = "net.minetest.minetest.PROGRESS";
public static final String ACTION_FAILURE = "net.minetest.minetest.FAILURE";
public static final String EXTRA_KEY_IN_FILE = "file";
public static final int SUCCESS = -1;
public static final int FAILURE = -2;
private final int id = 1;
private NotificationManager mNotifyManager;
private boolean isSuccess = true;
private String failureMessage;
public UnzipService() {
super("net.minetest.minetest.UnzipService");
}
private void isDir(String dir, String location) {
File f = new File(location, dir);
if (!f.isDirectory())
f.mkdirs();
}
@Override
protected void onHandleIntent(Intent intent) {
createNotification();
unzip(intent);
}
private void createNotification() {
String name = "net.minetest.minetest";
String channelId = "Minetest channel";
String description = "notifications from Minetest";
Notification.Builder builder;
if (mNotifyManager == null)
mNotifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
int importance = NotificationManager.IMPORTANCE_LOW;
NotificationChannel mChannel = null;
if (mNotifyManager != null)
mChannel = mNotifyManager.getNotificationChannel(channelId);
if (mChannel == null) {
mChannel = new NotificationChannel(channelId, name, importance);
mChannel.setDescription(description);
// Configure the notification channel, NO SOUND
mChannel.setSound(null, null);
mChannel.enableLights(false);
mChannel.enableVibration(false);
mNotifyManager.createNotificationChannel(mChannel);
}
builder = new Notification.Builder(this, channelId);
} else {
builder = new Notification.Builder(this);
}
builder.setContentTitle(getString(R.string.notification_title))
.setSmallIcon(R.mipmap.ic_launcher)
.setContentText(getString(R.string.notification_description));
mNotifyManager.notify(id, builder.build());
}
private void unzip(Intent intent) {
String zip = intent.getStringExtra(EXTRA_KEY_IN_FILE);
isDir("Minetest", Environment.getExternalStorageDirectory().toString());
String location = Environment.getExternalStorageDirectory() + File.separator + "Minetest" + File.separator;
int per = 0;
int size = getSummarySize(zip);
File zipFile = new File(zip);
int readLen;
byte[] readBuffer = new byte[8192];
try (FileInputStream fileInputStream = new FileInputStream(zipFile);
ZipInputStream zipInputStream = new ZipInputStream(fileInputStream)) {
ZipEntry ze;
while ((ze = zipInputStream.getNextEntry()) != null) {
if (ze.isDirectory()) {
++per;
isDir(ze.getName(), location);
} else {
publishProgress(100 * ++per / size);
try (OutputStream outputStream = new FileOutputStream(location + ze.getName())) {
while ((readLen = zipInputStream.read(readBuffer)) != -1) {
outputStream.write(readBuffer, 0, readLen);
}
}
}
zipFile.delete();
}
} catch (IOException e) {
isSuccess = false;
failureMessage = e.getLocalizedMessage();
}
}
private void publishProgress(int progress) {
Intent intentUpdate = new Intent(ACTION_UPDATE);
intentUpdate.putExtra(ACTION_PROGRESS, progress);
if (!isSuccess) intentUpdate.putExtra(ACTION_FAILURE, failureMessage);
sendBroadcast(intentUpdate);
}
private int getSummarySize(String zip) {
int size = 0;
try {
ZipFile zipSize = new ZipFile(zip);
size += zipSize.size();
} catch (IOException e) {
Toast.makeText(this, e.getLocalizedMessage(), Toast.LENGTH_LONG).show();
}
return size;
}
@Override
public void onDestroy() {
super.onDestroy();
mNotifyManager.cancel(id);
publishProgress(isSuccess ? SUCCESS : FAILURE);
}
}

View File

Before

Width:  |  Height:  |  Size: 83 B

After

Width:  |  Height:  |  Size: 83 B

View File

@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/background"
android:tileMode="repeat" />
android:tileMode="repeat" />

View File

@@ -0,0 +1,30 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bg">
<ProgressBar
android:id="@+id/progressBar"
style="@style/CustomProgressBar"
android:layout_width="match_parent"
android:layout_height="30dp"
android:layout_centerInParent="true"
android:layout_marginLeft="90dp"
android:layout_marginRight="90dp"
android:indeterminate="false"
android:max="100"
android:visibility="gone" />
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/progressBar"
android:layout_centerInParent="true"
android:background="@android:color/transparent"
android:text="@string/loading"
android:textColor="#FEFEFE"
android:visibility="gone" />
</RelativeLayout>

View File

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 5.6 KiB

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="label">Minetest</string>
<string name="loading">Loading&#8230;</string>
<string name="not_granted">Required permission wasn\'t granted, Minetest can\'t run without it</string>
<string name="notification_title">Loading Minetest</string>
<string name="notification_description">Less than 1 minute&#8230;</string>
</resources>

View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools">
<style name="AppTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
<item name="windowActionBar">false</item>
<item name="android:windowFullscreen">true</item>
<item name="android:windowBackground">@drawable/bg</item>
<item name="android:windowLayoutInDisplayCutoutMode" tools:targetApi="p">shortEdges</item>
</style>
<style name="InputTheme" parent="Theme.AppCompat.DayNight.Dialog">
<item name="windowNoTitle">true</item>
<item name="android:windowBackground">@android:color/transparent</item>
</style>
<style name="CustomProgressBar" parent="@style/Widget.AppCompat.ProgressBar.Horizontal">
<item name="android:indeterminateOnly">false</item>
<item name="android:minHeight">10dip</item>
<item name="android:maxHeight">20dip</item>
</style>
</resources>

View File

@@ -1,170 +1,34 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
project.ext.set("versionMajor", 5) // Version Major
project.ext.set("versionMinor", 3) // Version Minor
project.ext.set("versionPatch", 0) // Version Patch
project.ext.set("versionExtra", "-dev") // Version Extra
project.ext.set("versionCode", 30) // Android Version Code
// NOTE: +2 after each release!
// +1 for ARM and +1 for ARM64 APK's, because
// each APK must have a larger `versionCode` than the previous
buildscript {
repositories {
maven { url 'https://maven.google.com' }
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.1.3'
classpath 'com.android.tools.build:gradle:3.6.3'
classpath 'org.ajoberstar.grgit:grgit-gradle:4.0.2'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
maven { url 'https://maven.google.com' }
google()
jcenter()
}
}
def curl_version = "7.60.0"
def irrlicht_revision = "5150"
def openal_version = "1.18.2"
def openssl_version = "1.0.2n"
def sqlite3_version = "3240000"
apply plugin: "com.android.application"
android {
compileSdkVersion 28
buildToolsVersion "28.0.3"
defaultConfig {
versionCode 23
versionName "${System.env.VERSION_STR}.${versionCode}"
minSdkVersion 14
targetSdkVersion 28
applicationId "net.minetest.minetest"
manifestPlaceholders = [package: "net.minetest.minetest", project: project.name]
ndk {
// Specifies the ABI configurations of your native
// libraries Gradle should build and package with your APK.
// abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
abiFilters 'armeabi-v7a', 'x86'
}
}
lintOptions {
disable "OldTargetApi", "GoogleAppIndexingWarning"
}
Properties props = new Properties()
props.load(new FileInputStream(file("local.properties")))
if (props.getProperty("keystore") != null) {
signingConfigs {
release {
storeFile file(props["keystore"])
storePassword props["keystore.password"]
keyAlias props["key"]
keyPassword props["key.password"]
}
}
buildTypes {
release {
signingConfig signingConfigs.release
}
}
}
}
task cleanAssets(type: Delete) {
delete 'src/main/assets'
}
task copyAssets {
dependsOn 'cleanAssets'
mkdir "src/main/assets"
def mtAssetsFolder = "src/main/assets/Minetest"
def projRoot = "../.."
def gameToCopy = "minetest_game"
doLast {
mkdir "${mtAssetsFolder}"
mkdir "${mtAssetsFolder}/client"
mkdir "${mtAssetsFolder}/fonts"
mkdir "${mtAssetsFolder}/games"
mkdir "${mtAssetsFolder}/media"
copy {
from "${projRoot}/minetest.conf.example", "${projRoot}/README.md" into mtAssetsFolder
}
copy {
from "${projRoot}/doc/lgpl-2.1.txt" into "${mtAssetsFolder}/LICENSE.txt"
}
copy {
from "${projRoot}/builtin" into "${mtAssetsFolder}/builtin"
}
copy {
from "${projRoot}/client/shaders" into "${mtAssetsFolder}/client/shaders"
}
copy {
from "${projRoot}/fonts" include "*.ttf" into "${mtAssetsFolder}/fonts"
}
copy {
from "${projRoot}/games/${gameToCopy}" into "${mtAssetsFolder}/games/${gameToCopy}"
}
copy {
from "${projRoot}/po" into "${mtAssetsFolder}/po"
}
copy {
from "${projRoot}/textures" into "${mtAssetsFolder}/textures"
}
}
}
task cleanIconv(type: Delete) {
delete 'deps/libiconv'
}
task cleanIrrlicht(type: Delete) {
delete 'deps/irrlicht'
}
task cleanLevelDB(type: Delete) {
delete 'deps/leveldb'
}
task cleanCURL(type: Delete) {
delete 'deps/curl'
delete 'deps/curl-' + curl_version
}
task cleanOpenSSL(type: Delete) {
delete 'deps/openssl'
delete 'deps/openssl-' + openssl_version
delete 'deps/openssl-' + openssl_version + '.tar.gz'
}
task cleanOpenAL(type: Delete) {
delete 'deps/openal-soft'
}
task cleanFreetype(type: Delete) {
delete 'deps/freetype2-android'
}
task cleanOgg(type: Delete) {
delete 'deps/libvorbis-libogg-android'
}
task cleanSQLite3(type: Delete) {
delete 'deps/sqlite-amalgamation-' + sqlite3_version
delete 'deps/sqlite-amalgamation-' + sqlite3_version + '.zip'
}
task cleanAll(type: Delete, dependsOn: [clean, cleanAssets, cleanIconv,
cleanFreetype, cleanIrrlicht, cleanLevelDB, cleanSQLite3, cleanCURL,
cleanOpenSSL, cleanOpenAL, cleanOgg]) {
delete 'deps'
delete 'gen'
delete 'libs'
delete 'obj'
delete 'bin'
delete 'Debug'
delete 'and_env'
}
dependencies {
implementation 'com.android.support:support-v4:28.0.0'
task clean(type: Delete) {
delete rootProject.buildDir
}

View File

@@ -0,0 +1,11 @@
<#if isLowMemory>
org.gradle.jvmargs=-Xmx4G -XX:MaxPermSize=2G -XX:+HeapDumpOnOutOfMemoryError
<#else>
org.gradle.jvmargs=-Xmx16G -XX:MaxPermSize=8G -XX:+HeapDumpOnOutOfMemoryError
</#if>
org.gradle.daemon=true
org.gradle.parallel=true
org.gradle.parallel.threads=8
org.gradle.configureondemand=true
android.enableJetifier=true
android.useAndroidX=true

Binary file not shown.

View File

@@ -1,6 +1,2 @@
#Mon Oct 15 00:47:03 CEST 2018
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip
#Mon Apr 06 00:06:16 CEST 2020
distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-all.zip

22
build/android/gradlew vendored
View File

@@ -1,5 +1,21 @@
#!/usr/bin/env sh
#
# Copyright 2015 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
##
## Gradle start up script for UN*X
@@ -28,7 +44,7 @@ APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
@@ -109,8 +125,8 @@ if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
# For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`

View File

@@ -1,3 +1,19 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@@ -14,7 +30,7 @@ set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome

View File

@@ -1,434 +0,0 @@
LOCAL_PATH := $(call my-dir)/..
#LOCAL_ADDRESS_SANITIZER:=true
include $(CLEAR_VARS)
LOCAL_MODULE := Irrlicht
LOCAL_SRC_FILES := deps/irrlicht/lib/Android/libIrrlicht.a
include $(PREBUILT_STATIC_LIBRARY)
ifeq ($(HAVE_LEVELDB), 1)
include $(CLEAR_VARS)
LOCAL_MODULE := LevelDB
LOCAL_SRC_FILES := deps/leveldb/libleveldb.a
include $(PREBUILT_STATIC_LIBRARY)
endif
include $(CLEAR_VARS)
LOCAL_MODULE := curl
LOCAL_SRC_FILES := deps/curl/lib/.libs/libcurl.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := freetype
LOCAL_SRC_FILES := deps/freetype2-android/Android/obj/local/$(TARGET_ARCH_ABI)/libfreetype2-static.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := iconv
LOCAL_SRC_FILES := deps/libiconv/lib/.libs/libiconv.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := openal
LOCAL_SRC_FILES := deps/openal-soft/libs/$(TARGET_LIBDIR)/libopenal.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := ogg
LOCAL_SRC_FILES := deps/libvorbis-libogg-android/libs/$(TARGET_LIBDIR)/libogg.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := vorbis
LOCAL_SRC_FILES := deps/libvorbis-libogg-android/libs/$(TARGET_LIBDIR)/libvorbis.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := ssl
LOCAL_SRC_FILES := deps/openssl/libssl.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := crypto
LOCAL_SRC_FILES := deps/openssl/libcrypto.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := minetest
LOCAL_CPP_FEATURES += exceptions
ifdef GPROF
GPROF_DEF=-DGPROF
endif
LOCAL_CFLAGS := -D_IRR_ANDROID_PLATFORM_ \
-DHAVE_TOUCHSCREENGUI \
-DUSE_CURL=1 \
-DUSE_SOUND=1 \
-DUSE_FREETYPE=1 \
-DUSE_LEVELDB=$(HAVE_LEVELDB) \
$(GPROF_DEF) \
-pipe -fstrict-aliasing
ifndef NDEBUG
LOCAL_CFLAGS += -g -D_DEBUG -O0 -fno-omit-frame-pointer
else
LOCAL_CFLAGS += $(TARGET_CFLAGS_ADDON)
endif
ifdef GPROF
PROFILER_LIBS := android-ndk-profiler
LOCAL_CFLAGS += -pg
endif
# LOCAL_CFLAGS += -fsanitize=address
# LOCAL_LDFLAGS += -fsanitize=address
ifeq ($(TARGET_ABI),x86)
LOCAL_CFLAGS += -fno-stack-protector
endif
LOCAL_C_INCLUDES := \
jni/src \
jni/src/script \
jni/lib/gmp \
jni/lib/lua/src \
jni/lib/jsoncpp \
jni/src/cguittfont \
deps/irrlicht/include \
deps/libiconv/include \
deps/freetype2-android/include \
deps/curl/include \
deps/openal-soft/jni/OpenAL/include \
deps/libvorbis-libogg-android/jni/include \
deps/leveldb/include \
deps/sqlite/
LOCAL_SRC_FILES := \
jni/src/ban.cpp \
jni/src/chat.cpp \
jni/src/client/activeobjectmgr.cpp \
jni/src/client/camera.cpp \
jni/src/client/client.cpp \
jni/src/client/clientenvironment.cpp \
jni/src/client/clientlauncher.cpp \
jni/src/client/clientmap.cpp \
jni/src/client/clientmedia.cpp \
jni/src/client/clientobject.cpp \
jni/src/client/clouds.cpp \
jni/src/client/content_cao.cpp \
jni/src/client/content_cso.cpp \
jni/src/client/content_mapblock.cpp \
jni/src/client/filecache.cpp \
jni/src/client/fontengine.cpp \
jni/src/client/game.cpp \
jni/src/client/gameui.cpp \
jni/src/client/guiscalingfilter.cpp \
jni/src/client/hud.cpp \
jni/src/clientiface.cpp \
jni/src/client/imagefilters.cpp \
jni/src/client/inputhandler.cpp \
jni/src/client/joystick_controller.cpp \
jni/src/client/keycode.cpp \
jni/src/client/localplayer.cpp \
jni/src/client/mapblock_mesh.cpp \
jni/src/client/mesh.cpp \
jni/src/client/meshgen/collector.cpp \
jni/src/client/mesh_generator_thread.cpp \
jni/src/client/minimap.cpp \
jni/src/client/particles.cpp \
jni/src/client/render/anaglyph.cpp \
jni/src/client/render/core.cpp \
jni/src/client/render/factory.cpp \
jni/src/client/renderingengine.cpp \
jni/src/client/render/interlaced.cpp \
jni/src/client/render/pageflip.cpp \
jni/src/client/render/plain.cpp \
jni/src/client/render/sidebyside.cpp \
jni/src/client/render/stereo.cpp \
jni/src/client/shader.cpp \
jni/src/client/sky.cpp \
jni/src/client/sound.cpp \
jni/src/client/sound_openal.cpp \
jni/src/client/tile.cpp \
jni/src/client/wieldmesh.cpp \
jni/src/collision.cpp \
jni/src/content/content.cpp \
jni/src/content_mapnode.cpp \
jni/src/content/mods.cpp \
jni/src/content_nodemeta.cpp \
jni/src/content/packages.cpp \
jni/src/content_sao.cpp \
jni/src/content/subgames.cpp \
jni/src/convert_json.cpp \
jni/src/craftdef.cpp \
jni/src/database/database.cpp \
jni/src/database/database-dummy.cpp \
jni/src/database/database-files.cpp \
jni/src/database/database-leveldb.cpp \
jni/src/database/database-sqlite3.cpp \
jni/src/debug.cpp \
jni/src/defaultsettings.cpp \
jni/src/emerge.cpp \
jni/src/environment.cpp \
jni/src/face_position_cache.cpp \
jni/src/filesys.cpp \
jni/src/genericobject.cpp \
jni/src/gettext.cpp \
jni/src/gui/guiChatConsole.cpp \
jni/src/gui/guiConfirmRegistration.cpp \
jni/src/gui/guiEditBoxWithScrollbar.cpp \
jni/src/gui/guiEngine.cpp \
jni/src/gui/guiFormSpecMenu.cpp \
jni/src/gui/guiKeyChangeMenu.cpp \
jni/src/gui/guiPasswordChange.cpp \
jni/src/gui/guiPathSelectMenu.cpp \
jni/src/gui/guiTable.cpp \
jni/src/gui/guiVolumeChange.cpp \
jni/src/gui/intlGUIEditBox.cpp \
jni/src/gui/modalMenu.cpp \
jni/src/gui/profilergraph.cpp \
jni/src/gui/touchscreengui.cpp \
jni/src/httpfetch.cpp \
jni/src/hud.cpp \
jni/src/inventory.cpp \
jni/src/inventorymanager.cpp \
jni/src/irrlicht_changes/CGUITTFont.cpp \
jni/src/irrlicht_changes/static_text.cpp \
jni/src/itemdef.cpp \
jni/src/itemstackmetadata.cpp \
jni/src/light.cpp \
jni/src/log.cpp \
jni/src/main.cpp \
jni/src/mapblock.cpp \
jni/src/map.cpp \
jni/src/mapgen/cavegen.cpp \
jni/src/mapgen/dungeongen.cpp \
jni/src/mapgen/mapgen_carpathian.cpp \
jni/src/mapgen/mapgen.cpp \
jni/src/mapgen/mapgen_flat.cpp \
jni/src/mapgen/mapgen_fractal.cpp \
jni/src/mapgen/mapgen_singlenode.cpp \
jni/src/mapgen/mapgen_v5.cpp \
jni/src/mapgen/mapgen_v6.cpp \
jni/src/mapgen/mapgen_v7.cpp \
jni/src/mapgen/mapgen_valleys.cpp \
jni/src/mapgen/mg_biome.cpp \
jni/src/mapgen/mg_decoration.cpp \
jni/src/mapgen/mg_ore.cpp \
jni/src/mapgen/mg_schematic.cpp \
jni/src/mapgen/treegen.cpp \
jni/src/mapnode.cpp \
jni/src/mapsector.cpp \
jni/src/map_settings_manager.cpp \
jni/src/metadata.cpp \
jni/src/modchannels.cpp \
jni/src/nameidmapping.cpp \
jni/src/nodedef.cpp \
jni/src/nodemetadata.cpp \
jni/src/nodetimer.cpp \
jni/src/noise.cpp \
jni/src/objdef.cpp \
jni/src/object_properties.cpp \
jni/src/pathfinder.cpp \
jni/src/player.cpp \
jni/src/porting_android.cpp \
jni/src/porting.cpp \
jni/src/profiler.cpp \
jni/src/quicktune.cpp \
jni/src/raycast.cpp \
jni/src/reflowscan.cpp \
jni/src/remoteplayer.cpp \
jni/src/rollback.cpp \
jni/src/rollback_interface.cpp \
jni/src/serialization.cpp \
jni/src/server/activeobjectmgr.cpp \
jni/src/server.cpp \
jni/src/serverenvironment.cpp \
jni/src/serverlist.cpp \
jni/src/server/mods.cpp \
jni/src/serverobject.cpp \
jni/src/settings.cpp \
jni/src/staticobject.cpp \
jni/src/tileanimation.cpp \
jni/src/tool.cpp \
jni/src/translation.cpp \
jni/src/unittest/test_authdatabase.cpp \
jni/src/unittest/test_collision.cpp \
jni/src/unittest/test_compression.cpp \
jni/src/unittest/test_connection.cpp \
jni/src/unittest/test.cpp \
jni/src/unittest/test_filepath.cpp \
jni/src/unittest/test_gameui.cpp \
jni/src/unittest/test_inventory.cpp \
jni/src/unittest/test_mapnode.cpp \
jni/src/unittest/test_map_settings_manager.cpp \
jni/src/unittest/test_nodedef.cpp \
jni/src/unittest/test_noderesolver.cpp \
jni/src/unittest/test_noise.cpp \
jni/src/unittest/test_objdef.cpp \
jni/src/unittest/test_profiler.cpp \
jni/src/unittest/test_random.cpp \
jni/src/unittest/test_schematic.cpp \
jni/src/unittest/test_serialization.cpp \
jni/src/unittest/test_settings.cpp \
jni/src/unittest/test_socket.cpp \
jni/src/unittest/test_utilities.cpp \
jni/src/unittest/test_voxelalgorithms.cpp \
jni/src/unittest/test_voxelmanipulator.cpp \
jni/src/util/areastore.cpp \
jni/src/util/auth.cpp \
jni/src/util/base64.cpp \
jni/src/util/directiontables.cpp \
jni/src/util/enriched_string.cpp \
jni/src/util/ieee_float.cpp \
jni/src/util/numeric.cpp \
jni/src/util/pointedthing.cpp \
jni/src/util/serialize.cpp \
jni/src/util/sha1.cpp \
jni/src/util/srp.cpp \
jni/src/util/string.cpp \
jni/src/util/timetaker.cpp \
jni/src/version.cpp \
jni/src/voxelalgorithms.cpp \
jni/src/voxel.cpp
# intentionally kept out (we already build openssl itself): jni/src/util/sha256.c
# Network
LOCAL_SRC_FILES += \
jni/src/network/address.cpp \
jni/src/network/connection.cpp \
jni/src/network/networkpacket.cpp \
jni/src/network/clientopcodes.cpp \
jni/src/network/clientpackethandler.cpp \
jni/src/network/connectionthreads.cpp \
jni/src/network/serveropcodes.cpp \
jni/src/network/serverpackethandler.cpp \
jni/src/network/socket.cpp \
# lua api
LOCAL_SRC_FILES += \
jni/src/script/common/c_content.cpp \
jni/src/script/common/c_converter.cpp \
jni/src/script/common/c_internal.cpp \
jni/src/script/common/c_types.cpp \
jni/src/script/common/helper.cpp \
jni/src/script/cpp_api/s_async.cpp \
jni/src/script/cpp_api/s_base.cpp \
jni/src/script/cpp_api/s_client.cpp \
jni/src/script/cpp_api/s_entity.cpp \
jni/src/script/cpp_api/s_env.cpp \
jni/src/script/cpp_api/s_inventory.cpp \
jni/src/script/cpp_api/s_item.cpp \
jni/src/script/cpp_api/s_mainmenu.cpp \
jni/src/script/cpp_api/s_modchannels.cpp \
jni/src/script/cpp_api/s_node.cpp \
jni/src/script/cpp_api/s_nodemeta.cpp \
jni/src/script/cpp_api/s_player.cpp \
jni/src/script/cpp_api/s_security.cpp \
jni/src/script/cpp_api/s_server.cpp \
jni/src/script/lua_api/l_areastore.cpp \
jni/src/script/lua_api/l_auth.cpp \
jni/src/script/lua_api/l_base.cpp \
jni/src/script/lua_api/l_camera.cpp \
jni/src/script/lua_api/l_client.cpp \
jni/src/script/lua_api/l_craft.cpp \
jni/src/script/lua_api/l_env.cpp \
jni/src/script/lua_api/l_inventory.cpp \
jni/src/script/lua_api/l_item.cpp \
jni/src/script/lua_api/l_itemstackmeta.cpp\
jni/src/script/lua_api/l_localplayer.cpp \
jni/src/script/lua_api/l_mainmenu.cpp \
jni/src/script/lua_api/l_mapgen.cpp \
jni/src/script/lua_api/l_metadata.cpp \
jni/src/script/lua_api/l_minimap.cpp \
jni/src/script/lua_api/l_modchannels.cpp \
jni/src/script/lua_api/l_nodemeta.cpp \
jni/src/script/lua_api/l_nodetimer.cpp \
jni/src/script/lua_api/l_noise.cpp \
jni/src/script/lua_api/l_object.cpp \
jni/src/script/lua_api/l_playermeta.cpp \
jni/src/script/lua_api/l_particles.cpp \
jni/src/script/lua_api/l_particles_local.cpp\
jni/src/script/lua_api/l_rollback.cpp \
jni/src/script/lua_api/l_server.cpp \
jni/src/script/lua_api/l_settings.cpp \
jni/src/script/lua_api/l_sound.cpp \
jni/src/script/lua_api/l_http.cpp \
jni/src/script/lua_api/l_storage.cpp \
jni/src/script/lua_api/l_util.cpp \
jni/src/script/lua_api/l_vmanip.cpp \
jni/src/script/scripting_client.cpp \
jni/src/script/scripting_server.cpp \
jni/src/script/scripting_mainmenu.cpp
#freetype2 support
#LOCAL_SRC_FILES += jni/src/cguittfont/xCGUITTFont.cpp
# GMP
LOCAL_SRC_FILES += jni/lib/gmp/mini-gmp.c
# Lua
LOCAL_SRC_FILES += \
jni/lib/lua/src/lapi.c \
jni/lib/lua/src/lauxlib.c \
jni/lib/lua/src/lbaselib.c \
jni/lib/lua/src/lcode.c \
jni/lib/lua/src/ldblib.c \
jni/lib/lua/src/ldebug.c \
jni/lib/lua/src/ldo.c \
jni/lib/lua/src/ldump.c \
jni/lib/lua/src/lfunc.c \
jni/lib/lua/src/lgc.c \
jni/lib/lua/src/linit.c \
jni/lib/lua/src/liolib.c \
jni/lib/lua/src/llex.c \
jni/lib/lua/src/lmathlib.c \
jni/lib/lua/src/lmem.c \
jni/lib/lua/src/loadlib.c \
jni/lib/lua/src/lobject.c \
jni/lib/lua/src/lopcodes.c \
jni/lib/lua/src/loslib.c \
jni/lib/lua/src/lparser.c \
jni/lib/lua/src/lstate.c \
jni/lib/lua/src/lstring.c \
jni/lib/lua/src/lstrlib.c \
jni/lib/lua/src/ltable.c \
jni/lib/lua/src/ltablib.c \
jni/lib/lua/src/ltm.c \
jni/lib/lua/src/lundump.c \
jni/lib/lua/src/lvm.c \
jni/lib/lua/src/lzio.c \
jni/lib/lua/src/print.c
# SQLite3
LOCAL_SRC_FILES += deps/sqlite/sqlite3.c
# Threading
LOCAL_SRC_FILES += \
jni/src/threading/event.cpp \
jni/src/threading/semaphore.cpp \
jni/src/threading/thread.cpp
# JSONCPP
LOCAL_SRC_FILES += jni/lib/jsoncpp/jsoncpp.cpp
LOCAL_SHARED_LIBRARIES := iconv openal ogg vorbis
LOCAL_STATIC_LIBRARIES := Irrlicht freetype curl ssl crypto android_native_app_glue $(PROFILER_LIBS)
ifeq ($(HAVE_LEVELDB), 1)
LOCAL_STATIC_LIBRARIES += LevelDB
endif
LOCAL_LDLIBS := -lEGL -llog -lGLESv1_CM -lGLESv2 -lz -landroid
include $(BUILD_SHARED_LIBRARY)
# at the end of Android.mk
ifdef GPROF
$(call import-module,android-ndk-profiler)
endif
$(call import-module,android/native_app_glue)

View File

@@ -1,9 +0,0 @@
APP_PLATFORM := ${APP_PLATFORM}
APP_ABI := ${TARGET_ABI}
APP_STL := c++_shared
APP_MODULES := minetest
ifndef NDEBUG
APP_OPTIM := debug
endif
APP_CPPFLAGS += -fexceptions -std=c++11 -frtti

View File

@@ -1,7 +0,0 @@
APP_PLATFORM := ${APP_PLATFORM}
APP_ABI := ${TARGET_ABI}
APP_STL := c++_shared
APP_DEPRECATED_HEADERS := true
APP_CFLAGS += ${TARGET_CFLAGS_ADDON}
APP_CPPFLAGS += ${TARGET_CXXFLAGS_ADDON} -fexceptions -std=c++11

View File

@@ -1,8 +0,0 @@
APP_PLATFORM := ${APP_PLATFORM}
APP_ABI := ${TARGET_ABI}
APP_STL := c++_shared
APP_DEPRECATED_HEADERS := true
APP_MODULES := Irrlicht
APP_CLAFGS += ${TARGET_CFLAGS_ADDON}
APP_CPPFLAGS += ${TARGET_CXXFLAGS_ADDON} -fexceptions

Binary file not shown.

View File

@@ -0,0 +1,59 @@
apply plugin: 'com.android.library'
import org.ajoberstar.grgit.Grgit
android {
compileSdkVersion 29
buildToolsVersion '29.0.3'
ndkVersion '21.1.6352462'
defaultConfig {
minSdkVersion 16
targetSdkVersion 29
externalNativeBuild {
ndkBuild {
arguments '-j8',
"versionMajor=${versionMajor}",
"versionMinor=${versionMinor}",
"versionPatch=${versionPatch}",
"versionExtra=${versionExtra}"
}
}
}
externalNativeBuild {
ndkBuild {
path file('jni/Android.mk')
}
}
// supported architectures
splits {
abi {
enable true
reset()
include 'armeabi-v7a', 'arm64-v8a'//, 'x86'
}
}
buildTypes {
release {
externalNativeBuild {
ndkBuild {
arguments 'NDEBUG=1'
}
}
}
}
}
task cloneGitRepo() {
def destination = file('deps')
if(!destination.exists()) {
def grgit = Grgit.clone(
dir: destination,
uri: 'https://github.com/minetest/minetest_android_deps_binaries'
)
grgit.close()
}
}
preBuild.dependsOn cloneGitRepo

View File

@@ -0,0 +1,219 @@
LOCAL_PATH := $(call my-dir)/..
#LOCAL_ADDRESS_SANITIZER:=true
include $(CLEAR_VARS)
LOCAL_MODULE := Curl
LOCAL_SRC_FILES := deps/Android/Curl/${NDK_TOOLCHAIN_VERSION}/$(APP_ABI)/libcurl.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := Freetype
LOCAL_SRC_FILES := deps/Android/Freetype/${NDK_TOOLCHAIN_VERSION}/$(APP_ABI)/libfreetype.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := Irrlicht
LOCAL_SRC_FILES := deps/Android/Irrlicht/${NDK_TOOLCHAIN_VERSION}/$(APP_ABI)/libIrrlicht.a
include $(PREBUILT_STATIC_LIBRARY)
#include $(CLEAR_VARS)
#LOCAL_MODULE := LevelDB
#LOCAL_SRC_FILES := deps/Android/LevelDB/${NDK_TOOLCHAIN_VERSION}/$(APP_ABI)/libleveldb.a
#include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := LuaJIT
LOCAL_SRC_FILES := deps/Android/LuaJIT/${NDK_TOOLCHAIN_VERSION}/$(APP_ABI)/libluajit.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := mbedTLS
LOCAL_SRC_FILES := deps/Android/mbedTLS/${NDK_TOOLCHAIN_VERSION}/$(APP_ABI)/libmbedtls.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := mbedx509
LOCAL_SRC_FILES := deps/Android/mbedTLS/${NDK_TOOLCHAIN_VERSION}/$(APP_ABI)/libmbedx509.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := mbedcrypto
LOCAL_SRC_FILES := deps/Android/mbedTLS/${NDK_TOOLCHAIN_VERSION}/$(APP_ABI)/libmbedcrypto.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := OpenAL
LOCAL_SRC_FILES := deps/Android/OpenAL-Soft/${NDK_TOOLCHAIN_VERSION}/$(APP_ABI)/libopenal.a
include $(PREBUILT_STATIC_LIBRARY)
# You can use `OpenSSL and Crypto` instead `mbedTLS mbedx509 mbedcrypto`,
#but it increase APK size on ~0.7MB
#include $(CLEAR_VARS)
#LOCAL_MODULE := OpenSSL
#LOCAL_SRC_FILES := deps/Android/OpenSSL/${NDK_TOOLCHAIN_VERSION}/$(APP_ABI)/libssl.a
#include $(PREBUILT_STATIC_LIBRARY)
#include $(CLEAR_VARS)
#LOCAL_MODULE := Crypto
#LOCAL_SRC_FILES := deps/Android/OpenSSL/${NDK_TOOLCHAIN_VERSION}/$(APP_ABI)/libcrypto.a
#include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := Vorbis
LOCAL_SRC_FILES := deps/Android/Vorbis/${NDK_TOOLCHAIN_VERSION}/$(APP_ABI)/libvorbis.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := Minetest
LOCAL_CFLAGS += \
-DJSONCPP_NO_LOCALE_SUPPORT \
-DHAVE_TOUCHSCREENGUI \
-DENABLE_GLES=1 \
-DUSE_CURL=1 \
-DUSE_SOUND=1 \
-DUSE_FREETYPE=1 \
-DUSE_LEVELDB=0 \
-DUSE_LUAJIT=1 \
-DVERSION_MAJOR=${versionMajor} \
-DVERSION_MINOR=${versionMinor} \
-DVERSION_PATCH=${versionPatch} \
-DVERSION_EXTRA=${versionExtra} \
$(GPROF_DEF)
ifdef NDEBUG
LOCAL_CFLAGS += -DNDEBUG=1
endif
ifdef GPROF
GPROF_DEF := -DGPROF
PROFILER_LIBS := android-ndk-profiler
LOCAL_CFLAGS += -pg
endif
LOCAL_C_INCLUDES := \
../../../src \
../../../src/script \
../../../lib/gmp \
../../../lib/jsoncpp \
deps/Android/Curl/include \
deps/Android/Freetype/include \
deps/Android/Irrlicht/include \
deps/Android/LevelDB/include \
deps/Android/libiconv/include \
deps/Android/libiconv/libcharset/include \
deps/Android/LuaJIT/src \
deps/Android/OpenAL-Soft/include \
deps/Android/sqlite \
deps/Android/Vorbis/include
LOCAL_SRC_FILES := \
$(wildcard ../../../src/client/*.cpp) \
$(wildcard ../../../src/client/*/*.cpp) \
$(wildcard ../../../src/content/*.cpp) \
../../../src/database/database.cpp \
../../../src/database/database-dummy.cpp \
../../../src/database/database-files.cpp \
../../../src/database/database-sqlite3.cpp \
$(wildcard ../../../src/gui/*.cpp) \
$(wildcard ../../../src/irrlicht_changes/*.cpp) \
$(wildcard ../../../src/mapgen/*.cpp) \
$(wildcard ../../../src/network/*.cpp) \
$(wildcard ../../../src/script/*.cpp) \
$(wildcard ../../../src/script/*/*.cpp) \
$(wildcard ../../../src/server/*.cpp) \
$(wildcard ../../../src/threading/*.cpp) \
$(wildcard ../../../src/util/*.c) \
$(wildcard ../../../src/util/*.cpp) \
../../../src/ban.cpp \
../../../src/chat.cpp \
../../../src/clientiface.cpp \
../../../src/collision.cpp \
../../../src/content_mapnode.cpp \
../../../src/content_nodemeta.cpp \
../../../src/convert_json.cpp \
../../../src/craftdef.cpp \
../../../src/debug.cpp \
../../../src/defaultsettings.cpp \
../../../src/emerge.cpp \
../../../src/environment.cpp \
../../../src/face_position_cache.cpp \
../../../src/filesys.cpp \
../../../src/gettext.cpp \
../../../src/httpfetch.cpp \
../../../src/hud.cpp \
../../../src/inventory.cpp \
../../../src/inventorymanager.cpp \
../../../src/itemdef.cpp \
../../../src/itemstackmetadata.cpp \
../../../src/light.cpp \
../../../src/log.cpp \
../../../src/main.cpp \
../../../src/map.cpp \
../../../src/map_settings_manager.cpp \
../../../src/mapblock.cpp \
../../../src/mapnode.cpp \
../../../src/mapsector.cpp \
../../../src/metadata.cpp \
../../../src/modchannels.cpp \
../../../src/nameidmapping.cpp \
../../../src/nodedef.cpp \
../../../src/nodemetadata.cpp \
../../../src/nodetimer.cpp \
../../../src/noise.cpp \
../../../src/objdef.cpp \
../../../src/object_properties.cpp \
../../../src/particles.cpp \
../../../src/pathfinder.cpp \
../../../src/player.cpp \
../../../src/porting.cpp \
../../../src/porting_android.cpp \
../../../src/profiler.cpp \
../../../src/raycast.cpp \
../../../src/reflowscan.cpp \
../../../src/remoteplayer.cpp \
../../../src/rollback.cpp \
../../../src/rollback_interface.cpp \
../../../src/serialization.cpp \
../../../src/server.cpp \
../../../src/serverenvironment.cpp \
../../../src/serverlist.cpp \
../../../src/settings.cpp \
../../../src/staticobject.cpp \
../../../src/texture_override.cpp \
../../../src/tileanimation.cpp \
../../../src/tool.cpp \
../../../src/translation.cpp \
../../../src/version.cpp \
../../../src/voxel.cpp \
../../../src/voxelalgorithms.cpp
# LevelDB backend is disabled
# ../../../src/database/database-leveldb.cpp
# GMP
LOCAL_SRC_FILES += ../../../lib/gmp/mini-gmp.c
# JSONCPP
LOCAL_SRC_FILES += ../../../lib/jsoncpp/jsoncpp.cpp
# iconv
LOCAL_SRC_FILES += \
deps/Android/libiconv/lib/iconv.c \
deps/Android/libiconv/libcharset/lib/localcharset.c
# SQLite3
LOCAL_SRC_FILES += deps/Android/sqlite/sqlite3.c
LOCAL_STATIC_LIBRARIES += Curl Freetype Irrlicht OpenAL mbedTLS mbedx509 mbedcrypto Vorbis LuaJIT android_native_app_glue $(PROFILER_LIBS) #LevelDB
#OpenSSL Crypto
LOCAL_LDLIBS := -lEGL -lGLESv1_CM -lGLESv2 -landroid -lOpenSLES
include $(BUILD_SHARED_LIBRARY)
ifdef GPROF
$(call import-module,android-ndk-profiler)
endif
$(call import-module,android/native_app_glue)

View File

@@ -0,0 +1,32 @@
APP_PLATFORM := ${APP_PLATFORM}
APP_ABI := ${TARGET_ABI}
APP_STL := c++_shared
NDK_TOOLCHAIN_VERSION := clang
APP_SHORT_COMMANDS := true
APP_MODULES := Minetest
APP_CPPFLAGS := -Ofast -fvisibility=hidden -fexceptions -Wno-deprecated-declarations -Wno-extra-tokens
ifeq ($(APP_ABI),armeabi-v7a)
APP_CPPFLAGS += -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 -mthumb
endif
#ifeq ($(APP_ABI),x86)
#APP_CPPFLAGS += -march=i686 -mtune=intel -mssse3 -mfpmath=sse -m32 -funroll-loops
#endif
ifndef NDEBUG
APP_CPPFLAGS := -g -D_DEBUG -O0 -fno-omit-frame-pointer -fexceptions
endif
APP_CFLAGS := $(APP_CPPFLAGS) -Wno-parentheses-equality #-Werror=shorten-64-to-32
APP_CXXFLAGS := $(APP_CPPFLAGS) -frtti -std=gnu++17
APP_LDFLAGS := -Wl,--no-warn-mismatch,--gc-sections,--icf=safe
ifeq ($(APP_ABI),arm64-v8a)
APP_LDFLAGS := -Wl,--no-warn-mismatch,--gc-sections
endif
ifndef NDEBUG
APP_LDFLAGS :=
endif

View File

@@ -0,0 +1 @@
<manifest package="net.minetest" />

View File

@@ -1,20 +0,0 @@
--- irrlicht/source/Irrlicht/Android/CIrrDeviceAndroid.cpp.orig 2015-08-29 15:43:09.000000000 +0300
+++ irrlicht/source/Irrlicht/Android/CIrrDeviceAndroid.cpp 2016-05-13 21:36:22.880388505 +0300
@@ -486,7 +486,7 @@
event.KeyInput.Char = 0;
}
- device->postEventFromUser(event);
+ status = device->postEventFromUser(event);
}
break;
default:
@@ -543,7 +543,7 @@
KeyMap[1] = KEY_LBUTTON; // AKEYCODE_SOFT_LEFT
KeyMap[2] = KEY_RBUTTON; // AKEYCODE_SOFT_RIGHT
KeyMap[3] = KEY_HOME; // AKEYCODE_HOME
- KeyMap[4] = KEY_BACK; // AKEYCODE_BACK
+ KeyMap[4] = KEY_CANCEL; // AKEYCODE_BACK
KeyMap[5] = KEY_UNKNOWN; // AKEYCODE_CALL
KeyMap[6] = KEY_UNKNOWN; // AKEYCODE_ENDCALL
KeyMap[7] = KEY_KEY_0; // AKEYCODE_0

View File

@@ -1,13 +0,0 @@
--- irrlicht/source/Irrlicht/CEGLManager.cpp.orig 2018-09-11 18:19:51.453403631 +0300
+++ irrlicht/source/Irrlicht/CEGLManager.cpp 2018-09-11 18:36:24.603471869 +0300
@@ -9,6 +9,10 @@
#include "irrString.h"
#include "os.h"
+#if defined(_IRR_COMPILE_WITH_ANDROID_DEVICE_)
+#include <android/native_activity.h>
+#endif
+
namespace irr
{
namespace video

View File

@@ -1,240 +0,0 @@
--- irrlicht/source/Irrlicht/COGLESTexture.cpp.orig 2014-06-22 17:01:13.266568869 +0200
+++ irrlicht/source/Irrlicht/COGLESTexture.cpp 2014-06-22 17:03:59.298572810 +0200
@@ -366,112 +366,140 @@
void(*convert)(const void*, s32, void*) = 0;
getFormatParameters(ColorFormat, InternalFormat, filtering, PixelFormat, PixelType, convert);
- // make sure we don't change the internal format of existing images
- if (!newTexture)
- InternalFormat = oldInternalFormat;
-
- Driver->setActiveTexture(0, this);
-
- if (Driver->testGLError())
- os::Printer::log("Could not bind Texture", ELL_ERROR);
-
- // mipmap handling for main texture
- if (!level && newTexture)
- {
- // auto generate if possible and no mipmap data is given
- if (!IsCompressed && HasMipMaps && !mipmapData && Driver->queryFeature(EVDF_MIP_MAP_AUTO_UPDATE))
- {
- if (Driver->getTextureCreationFlag(ETCF_OPTIMIZED_FOR_SPEED))
- glHint(GL_GENERATE_MIPMAP_HINT, GL_FASTEST);
- else if (Driver->getTextureCreationFlag(ETCF_OPTIMIZED_FOR_QUALITY))
- glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST);
- else
- glHint(GL_GENERATE_MIPMAP_HINT, GL_DONT_CARE);
+ bool retry = false;
+
+ do {
+ if (retry) {
+ InternalFormat = GL_RGBA;
+ PixelFormat = GL_RGBA;
+ convert = CColorConverter::convert_A8R8G8B8toA8B8G8R8;
+ }
+ // make sure we don't change the internal format of existing images
+ if (!newTexture)
+ InternalFormat = oldInternalFormat;
- glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
- AutomaticMipmapUpdate=true;
- }
+ Driver->setActiveTexture(0, this);
- // enable bilinear filter without mipmaps
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering);
- }
+ if (Driver->testGLError())
+ os::Printer::log("Could not bind Texture", ELL_ERROR);
- // now get image data and upload to GPU
+ // mipmap handling for main texture
+ if (!level && newTexture)
+ {
+ // auto generate if possible and no mipmap data is given
+ if (!IsCompressed && HasMipMaps && !mipmapData && Driver->queryFeature(EVDF_MIP_MAP_AUTO_UPDATE))
+ {
+ if (Driver->getTextureCreationFlag(ETCF_OPTIMIZED_FOR_SPEED))
+ glHint(GL_GENERATE_MIPMAP_HINT, GL_FASTEST);
+ else if (Driver->getTextureCreationFlag(ETCF_OPTIMIZED_FOR_QUALITY))
+ glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST);
+ else
+ glHint(GL_GENERATE_MIPMAP_HINT, GL_DONT_CARE);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
+ AutomaticMipmapUpdate=true;
+ }
+
+ // enable bilinear filter without mipmaps
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering);
+ }
- u32 compressedImageSize = IImage::getCompressedImageSize(ColorFormat, image->getDimension().Width, image->getDimension().Height);
+ // now get image data and upload to GPU
- void* source = image->lock();
+ u32 compressedImageSize = IImage::getCompressedImageSize(ColorFormat, image->getDimension().Width, image->getDimension().Height);
- IImage* tmpImage = 0;
+ void* source = image->lock();
- if (convert)
- {
- tmpImage = new CImage(image->getColorFormat(), image->getDimension());
- void* dest = tmpImage->lock();
- convert(source, image->getDimension().getArea(), dest);
- image->unlock();
- source = dest;
- }
+ IImage* tmpImage = 0;
- if (newTexture)
- {
- if (IsCompressed)
+ if (convert)
{
- glCompressedTexImage2D(GL_TEXTURE_2D, 0, InternalFormat, image->getDimension().Width,
- image->getDimension().Height, 0, compressedImageSize, source);
+ tmpImage = new CImage(image->getColorFormat(), image->getDimension());
+ void* dest = tmpImage->lock();
+ convert(source, image->getDimension().getArea(), dest);
+ image->unlock();
+ source = dest;
}
- else
- glTexImage2D(GL_TEXTURE_2D, level, InternalFormat, image->getDimension().Width,
- image->getDimension().Height, 0, PixelFormat, PixelType, source);
- }
- else
- {
- if (IsCompressed)
+
+ if (newTexture)
{
- glCompressedTexSubImage2D(GL_TEXTURE_2D, level, 0, 0, image->getDimension().Width,
- image->getDimension().Height, PixelFormat, compressedImageSize, source);
+ if (IsCompressed)
+ {
+ glCompressedTexImage2D(GL_TEXTURE_2D, 0, InternalFormat, image->getDimension().Width,
+ image->getDimension().Height, 0, compressedImageSize, source);
+ }
+ else
+ glTexImage2D(GL_TEXTURE_2D, level, InternalFormat, image->getDimension().Width,
+ image->getDimension().Height, 0, PixelFormat, PixelType, source);
}
else
- glTexSubImage2D(GL_TEXTURE_2D, level, 0, 0, image->getDimension().Width,
- image->getDimension().Height, PixelFormat, PixelType, source);
- }
-
- if (convert)
- {
- tmpImage->unlock();
- tmpImage->drop();
- }
- else
- image->unlock();
-
- if (!level && newTexture)
- {
- if (IsCompressed && !mipmapData)
{
- if (image->hasMipMaps())
- mipmapData = static_cast<u8*>(image->lock())+compressedImageSize;
+ if (IsCompressed)
+ {
+ glCompressedTexSubImage2D(GL_TEXTURE_2D, level, 0, 0, image->getDimension().Width,
+ image->getDimension().Height, PixelFormat, compressedImageSize, source);
+ }
else
- HasMipMaps = false;
+ glTexSubImage2D(GL_TEXTURE_2D, level, 0, 0, image->getDimension().Width,
+ image->getDimension().Height, PixelFormat, PixelType, source);
}
- regenerateMipMapLevels(mipmapData);
-
- if (HasMipMaps) // might have changed in regenerateMipMapLevels
+ if (convert)
{
- // enable bilinear mipmap filter
- GLint filteringMipMaps = GL_LINEAR_MIPMAP_NEAREST;
-
- if (filtering != GL_LINEAR)
- filteringMipMaps = GL_NEAREST_MIPMAP_NEAREST;
+ tmpImage->unlock();
+ tmpImage->drop();
+ }
+ else
+ image->unlock();
+
+ if (glGetError() != GL_NO_ERROR) {
+ static bool warned = false;
+ if ((!retry) && (ColorFormat == ECF_A8R8G8B8)) {
+
+ if (!warned) {
+ os::Printer::log("Your driver claims to support GL_BGRA but fails on trying to upload a texture, converting to GL_RGBA and trying again", ELL_ERROR);
+ warned = true;
+ }
+ }
+ else if (retry) {
+ os::Printer::log("Neither uploading texture as GL_BGRA nor, converted one using GL_RGBA succeeded", ELL_ERROR);
+ }
+ retry = !retry;
+ continue;
+ } else {
+ retry = false;
+ }
- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filteringMipMaps);
- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering);
+ if (!level && newTexture)
+ {
+ if (IsCompressed && !mipmapData)
+ {
+ if (image->hasMipMaps())
+ mipmapData = static_cast<u8*>(image->lock())+compressedImageSize;
+ else
+ HasMipMaps = false;
+ }
+
+ regenerateMipMapLevels(mipmapData);
+
+ if (HasMipMaps) // might have changed in regenerateMipMapLevels
+ {
+ // enable bilinear mipmap filter
+ GLint filteringMipMaps = GL_LINEAR_MIPMAP_NEAREST;
+
+ if (filtering != GL_LINEAR)
+ filteringMipMaps = GL_NEAREST_MIPMAP_NEAREST;
+
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filteringMipMaps);
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering);
+ }
}
- }
- if (Driver->testGLError())
- os::Printer::log("Could not glTexImage2D", ELL_ERROR);
+ if (Driver->testGLError())
+ os::Printer::log("Could not glTexImage2D", ELL_ERROR);
+ }
+ while(retry);
}
--- irrlicht/source/Irrlicht/COGLESTexture.cpp.orig 2014-06-25 00:28:50.820501856 +0200
+++ irrlicht/source/Irrlicht/COGLESTexture.cpp 2014-06-25 00:08:37.712544692 +0200
@@ -422,6 +422,9 @@
source = dest;
}
+ //clear old error
+ glGetError();
+
if (newTexture)
{
if (IsCompressed)

View File

@@ -1,30 +0,0 @@
--- irrlicht.orig/include/IEventReceiver.h 2014-06-03 19:43:50.433713133 +0200
+++ irrlicht/include/IEventReceiver.h 2014-06-03 19:44:36.993711489 +0200
@@ -375,6 +375,9 @@
// Y position of simple touch.
s32 Y;
+ // number of current touches
+ s32 touchedCount;
+
//! Type of touch event.
ETOUCH_INPUT_EVENT Event;
};
--- irrlicht.orig/source/Irrlicht/Android/CIrrDeviceAndroid.cpp 2014-06-03 19:43:50.505713130 +0200
+++ irrlicht/source/Irrlicht/Android/CIrrDeviceAndroid.cpp 2014-06-03 19:45:37.265709359 +0200
@@ -315,6 +315,7 @@
event.TouchInput.ID = AMotionEvent_getPointerId(androidEvent, i);
event.TouchInput.X = AMotionEvent_getX(androidEvent, i);
event.TouchInput.Y = AMotionEvent_getY(androidEvent, i);
+ event.TouchInput.touchedCount = AMotionEvent_getPointerCount(androidEvent);
device->postEventFromUser(event);
}
@@ -326,6 +327,7 @@
event.TouchInput.ID = AMotionEvent_getPointerId(androidEvent, pointerIndex);
event.TouchInput.X = AMotionEvent_getX(androidEvent, pointerIndex);
event.TouchInput.Y = AMotionEvent_getY(androidEvent, pointerIndex);
+ event.TouchInput.touchedCount = AMotionEvent_getPointerCount(androidEvent);
device->postEventFromUser(event);
}

View File

@@ -1,39 +0,0 @@
--- a/libcharset/lib/localcharset.c 2015-06-10 11:55:25.933870724 +0200
+++ b/libcharset/lib/localcharset.c 2015-06-10 11:55:39.578063493 +0200
@@ -47,7 +47,7 @@
#if !defined WIN32_NATIVE
# include <unistd.h>
-# if HAVE_LANGINFO_CODESET
+# if HAVE_LANGINFO_CODESET && !(defined __ANDROID__)
# include <langinfo.h>
# else
# if 0 /* see comment below */
@@ -124,7 +124,7 @@ get_charset_aliases (void)
cp = charset_aliases;
if (cp == NULL)
{
-#if !(defined DARWIN7 || defined VMS || defined WIN32_NATIVE || defined __CYGWIN__)
+#if !(defined DARWIN7 || defined VMS || defined WIN32_NATIVE || defined __CYGWIN__ || defined __ANDROID__)
const char *dir;
const char *base = "charset.alias";
char *file_name;
@@ -338,6 +338,9 @@ get_charset_aliases (void)
"CP54936" "\0" "GB18030" "\0"
"CP65001" "\0" "UTF-8" "\0";
# endif
+# if defined __ANDROID__
+ cp = "*" "\0" "UTF-8" "\0";
+# endif
#endif
charset_aliases = cp;
@@ -361,7 +364,7 @@ locale_charset (void)
const char *codeset;
const char *aliases;
-#if !(defined WIN32_NATIVE || defined OS2)
+#if !(defined WIN32_NATIVE || defined OS2 || defined __ANDROID__)
# if HAVE_LANGINFO_CODESET

View File

@@ -1,13 +0,0 @@
--- a/srclib/stdio.in.h 2011-08-07 15:42:06.000000000 +0200
+++ b/srclib/stdio.in.h 2015-06-10 09:27:58.129056262 +0200
@@ -695,8 +696,9 @@ _GL_CXXALIASWARN (gets);
/* It is very rare that the developer ever has full control of stdin,
so any use of gets warrants an unconditional warning. Assume it is
always declared, since it is required by C89. */
-_GL_WARN_ON_USE (gets, "gets is a security hole - use fgets instead");
+/*_GL_WARN_ON_USE (gets, "gets is a security hole - use fgets instead");*/
+#define gets(a) fgets( a, sizeof(*(a)), stdin)
#endif
#if @GNULIB_OBSTACK_PRINTF@ || @GNULIB_OBSTACK_PRINTF_POSIX@

View File

@@ -1,37 +0,0 @@
--- libvorbis-libogg-android/jni/libvorbis-jni/Android.mk.orig 2014-06-17 19:22:50.621559073 +0200
+++ libvorbis-libogg-android/jni/libvorbis-jni/Android.mk 2014-06-17 19:38:20.641581140 +0200
@@ -4,9 +4,6 @@
LOCAL_MODULE := vorbis-jni
LOCAL_CFLAGS += -I$(LOCAL_PATH)/../include -fsigned-char
-ifeq ($(TARGET_ARCH),arm)
- LOCAL_CFLAGS += -march=armv6 -marm -mfloat-abi=softfp -mfpu=vfp
-endif
LOCAL_SHARED_LIBRARIES := libogg libvorbis
--- libvorbis-libogg-android/jni/libvorbis/Android.mk.orig 2014-06-17 19:22:39.077558797 +0200
+++ libvorbis-libogg-android/jni/libvorbis/Android.mk 2014-06-17 19:38:52.121581887 +0200
@@ -4,9 +4,6 @@
LOCAL_MODULE := libvorbis
LOCAL_CFLAGS += -I$(LOCAL_PATH)/../include -ffast-math -fsigned-char
-ifeq ($(TARGET_ARCH),arm)
- LOCAL_CFLAGS += -march=armv6 -marm -mfloat-abi=softfp -mfpu=vfp
-endif
LOCAL_SHARED_LIBRARIES := libogg
LOCAL_SRC_FILES := \
--- libvorbis-libogg-android/jni/libogg/Android.mk.orig 2014-06-17 19:22:33.965558675 +0200
+++ libvorbis-libogg-android/jni/libogg/Android.mk 2014-06-17 19:38:25.337581252 +0200
@@ -4,10 +4,6 @@
LOCAL_MODULE := libogg
LOCAL_CFLAGS += -I$(LOCAL_PATH)/../include -ffast-math -fsigned-char
-ifeq ($(TARGET_ARCH),arm)
- LOCAL_CFLAGS += -march=armv6 -marm -mfloat-abi=softfp -mfpu=vfp
-endif
-
LOCAL_SRC_FILES := \
bitwise.c \

View File

@@ -1,13 +0,0 @@
--- openssl-1.0.2e.orig/Configure 2015-12-03 15:04:23.000000000 +0100
+++ openssl-1.0.2e/Configure 2015-12-14 21:01:40.351265968 +0100
@@ -464,8 +464,10 @@
# Android: linux-* but without pointers to headers and libs.
"android","gcc:-mandroid -I\$(ANDROID_DEV)/include -B\$(ANDROID_DEV)/lib -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${no_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
"android-x86","gcc:-mandroid -I\$(ANDROID_DEV)/include -B\$(ANDROID_DEV)/lib -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:".eval{my $asm=${x86_elf_asm};$asm=~s/:elf/:android/;$asm}.":dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"android-arm","gcc:-march=armv4 -mandroid -I\$(ANDROID_DEV)/include -B\$(ANDROID_DEV)/lib -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${armv4_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
"android-armv7","gcc:-march=armv7-a -mandroid -I\$(ANDROID_DEV)/include -B\$(ANDROID_DEV)/lib -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${armv4_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
"android-mips","gcc:-mandroid -I\$(ANDROID_DEV)/include -B\$(ANDROID_DEV)/lib -O3 -Wall::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${mips32_asm}:o32:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"android-mips32","gcc:-mandroid -I\$(ANDROID_DEV)/include -B\$(ANDROID_DEV)/lib -O3 -Wall::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${mips32_asm}:o32:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
#### *BSD [do see comment about ${BSDthreads} above!]
"BSD-generic32","gcc:-O3 -fomit-frame-pointer -Wall::${BSDthreads}:::BN_LLONG RC2_CHAR RC4_INDEX DES_INT DES_UNROLL:${no_asm}:dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",

View File

@@ -1 +1,2 @@
rootProject.name = "Minetest"
include ':app', ':native'

View File

@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.SET_DEBUG_APP" />
</manifest>

View File

@@ -1,79 +0,0 @@
package net.minetest.minetest;
import android.Manifest;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class MainActivity extends Activity {
private final static int PERMISSIONS = 1;
private static final String[] REQUIRED_SDK_PERMISSIONS = new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
checkPermission();
} else {
next();
}
}
protected void checkPermission() {
final List<String> missingPermissions = new ArrayList<String>();
// check required permission
for (final String permission : REQUIRED_SDK_PERMISSIONS) {
final int result = ContextCompat.checkSelfPermission(this, permission);
if (result != PackageManager.PERMISSION_GRANTED) {
missingPermissions.add(permission);
}
}
if (!missingPermissions.isEmpty()) {
// request permission
final String[] permissions = missingPermissions
.toArray(new String[missingPermissions.size()]);
ActivityCompat.requestPermissions(this, permissions, PERMISSIONS);
} else {
final int[] grantResults = new int[REQUIRED_SDK_PERMISSIONS.length];
Arrays.fill(grantResults, PackageManager.PERMISSION_GRANTED);
onRequestPermissionsResult(PERMISSIONS, REQUIRED_SDK_PERMISSIONS,
grantResults);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[],
@NonNull int[] grantResults) {
switch (requestCode) {
case PERMISSIONS:
for (int index = 0; index < permissions.length; index++) {
if (grantResults[index] != PackageManager.PERMISSION_GRANTED) {
// permission not granted - toast and exit
Toast.makeText(this, R.string.not_granted, Toast.LENGTH_LONG).show();
finish();
return;
}
}
// permission were granted - run
next();
break;
}
}
public void next() {
Intent intent = new Intent(this, MtNativeActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
}
}

View File

@@ -1,373 +0,0 @@
package net.minetest.minetest;
import android.app.Activity;
import android.content.res.AssetFileDescriptor;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.Display;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.TextView;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.Iterator;
import java.util.Vector;
public class MinetestAssetCopy extends Activity {
ProgressBar m_ProgressBar;
TextView m_Filename;
copyAssetTask m_AssetCopy;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.assetcopy);
m_ProgressBar = findViewById(R.id.progressBar1);
m_Filename = findViewById(R.id.textView1);
Display display = getWindowManager().getDefaultDisplay();
m_ProgressBar.getLayoutParams().width = (int) (display.getWidth() * 0.8);
m_ProgressBar.invalidate();
/* check if there's already a copy in progress and reuse in case it is*/
MinetestAssetCopy prevActivity =
(MinetestAssetCopy) getLastNonConfigurationInstance();
if (prevActivity != null) {
m_AssetCopy = prevActivity.m_AssetCopy;
} else {
m_AssetCopy = new copyAssetTask();
m_AssetCopy.execute();
}
}
@Override
protected void onResume() {
super.onResume();
makeFullScreen();
}
public void makeFullScreen() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
this.getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
);
}
}
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus) {
makeFullScreen();
}
}
/* preserve asset copy background task to prevent restart of copying */
/* this way of doing it is not recommended for latest android version */
/* but the recommended way isn't available on android 2.x */
public Object onRetainNonConfigurationInstance() {
return this;
}
private class copyAssetTask extends AsyncTask<String, Integer, String> {
boolean m_copy_started = false;
String m_Foldername = "media";
Vector<String> m_foldernames;
Vector<String> m_filenames;
Vector<String> m_tocopy;
Vector<String> m_asset_size_unknown;
private long getFullSize(String filename) {
long size = 0;
try {
InputStream src = getAssets().open(filename);
byte[] buf = new byte[4096];
int len = 0;
while ((len = src.read(buf)) > 0) {
size += len;
}
} catch (IOException e) {
e.printStackTrace();
}
return size;
}
@Override
protected String doInBackground(String... files) {
m_foldernames = new Vector<String>();
m_filenames = new Vector<String>();
m_tocopy = new Vector<String>();
m_asset_size_unknown = new Vector<String>();
String baseDir =
Environment.getExternalStorageDirectory().getAbsolutePath()
+ "/";
// prepare temp folder
File TempFolder = new File(baseDir + "Minetest/tmp/");
if (!TempFolder.exists()) {
TempFolder.mkdir();
} else {
File[] todel = TempFolder.listFiles();
for (int i = 0; i < todel.length; i++) {
Log.v("MinetestAssetCopy", "deleting: " + todel[i].getAbsolutePath());
todel[i].delete();
}
}
// add a .nomedia file
try {
OutputStream dst = new FileOutputStream(baseDir + "Minetest/.nomedia");
dst.close();
} catch (IOException e) {
Log.e("MinetestAssetCopy", "Failed to create .nomedia file");
e.printStackTrace();
}
// build lists from prepared data
BuildFolderList();
BuildFileList();
// scan filelist
ProcessFileList();
// doing work
m_copy_started = true;
m_ProgressBar.setMax(m_tocopy.size());
for (int i = 0; i < m_tocopy.size(); i++) {
try {
String filename = m_tocopy.get(i);
publishProgress(i);
boolean asset_size_unknown = false;
long filesize = -1;
if (m_asset_size_unknown.contains(filename)) {
File testme = new File(baseDir + "/" + filename);
if (testme.exists()) {
filesize = testme.length();
}
asset_size_unknown = true;
}
InputStream src;
try {
src = getAssets().open(filename);
} catch (IOException e) {
Log.e("MinetestAssetCopy", "Copying file: " + filename + " FAILED (not in assets)");
e.printStackTrace();
continue;
}
// Transfer bytes from in to out
byte[] buf = new byte[1024];
int len = src.read(buf, 0, 1024);
/* following handling is crazy but we need to deal with */
/* compressed assets.Flash chips limited livetime due to */
/* write operations, we can't allow large files to destroy */
/* users flash. */
if (asset_size_unknown) {
if ((len > 0) && (len < buf.length) && (len == filesize)) {
src.close();
continue;
}
if (len == buf.length) {
src.close();
long size = getFullSize(filename);
if (size == filesize) {
continue;
}
src = getAssets().open(filename);
len = src.read(buf, 0, 1024);
}
}
if (len > 0) {
int total_filesize = 0;
OutputStream dst;
try {
dst = new FileOutputStream(baseDir + "/" + filename);
} catch (IOException e) {
Log.e("MinetestAssetCopy", "Copying file: " + baseDir +
"/" + filename + " FAILED (couldn't open output file)");
e.printStackTrace();
src.close();
continue;
}
dst.write(buf, 0, len);
total_filesize += len;
while ((len = src.read(buf)) > 0) {
dst.write(buf, 0, len);
total_filesize += len;
}
dst.close();
Log.v("MinetestAssetCopy", "Copied file: " +
m_tocopy.get(i) + " (" + total_filesize +
" bytes)");
} else if (len < 0) {
Log.e("MinetestAssetCopy", "Copying file: " +
m_tocopy.get(i) + " failed, size < 0");
}
src.close();
} catch (IOException e) {
Log.e("MinetestAssetCopy", "Copying file: " +
m_tocopy.get(i) + " failed");
e.printStackTrace();
}
}
return "";
}
/**
* update progress bar
*/
protected void onProgressUpdate(Integer... progress) {
if (m_copy_started) {
boolean shortened = false;
String todisplay = m_tocopy.get(progress[0]);
m_ProgressBar.setProgress(progress[0]);
m_Filename.setText(todisplay);
} else {
boolean shortened = false;
String todisplay = m_Foldername;
String full_text = "scanning " + todisplay + " ...";
m_Filename.setText(full_text);
}
}
/**
* check all files and folders in filelist
*/
protected void ProcessFileList() {
String FlashBaseDir =
Environment.getExternalStorageDirectory().getAbsolutePath();
Iterator itr = m_filenames.iterator();
while (itr.hasNext()) {
String current_path = (String) itr.next();
String FlashPath = FlashBaseDir + "/" + current_path;
if (isAssetFolder(current_path)) {
/* store information and update gui */
m_Foldername = current_path;
publishProgress(0);
/* open file in order to check if it's a folder */
File current_folder = new File(FlashPath);
if (!current_folder.exists()) {
if (!current_folder.mkdirs()) {
Log.e("MinetestAssetCopy", "\t failed create folder: " +
FlashPath);
} else {
Log.v("MinetestAssetCopy", "\t created folder: " +
FlashPath);
}
}
continue;
}
/* if it's not a folder it's most likely a file */
boolean refresh = true;
File testme = new File(FlashPath);
long asset_filesize = -1;
long stored_filesize = -1;
if (testme.exists()) {
try {
AssetFileDescriptor fd = getAssets().openFd(current_path);
asset_filesize = fd.getLength();
fd.close();
} catch (IOException e) {
refresh = true;
m_asset_size_unknown.add(current_path);
Log.e("MinetestAssetCopy", "Failed to open asset file \"" +
FlashPath + "\" for size check");
}
stored_filesize = testme.length();
if (asset_filesize == stored_filesize) {
refresh = false;
}
}
if (refresh) {
m_tocopy.add(current_path);
}
}
}
/**
* read list of folders prepared on package build
*/
protected void BuildFolderList() {
try {
InputStream is = getAssets().open("index.txt");
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
String line = reader.readLine();
while (line != null) {
m_foldernames.add(line);
line = reader.readLine();
}
is.close();
} catch (IOException e1) {
Log.e("MinetestAssetCopy", "Error on processing index.txt");
e1.printStackTrace();
}
}
/**
* read list of asset files prepared on package build
*/
protected void BuildFileList() {
long entrycount = 0;
try {
InputStream is = getAssets().open("filelist.txt");
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
String line = reader.readLine();
while (line != null) {
m_filenames.add(line);
line = reader.readLine();
entrycount++;
}
is.close();
} catch (IOException e1) {
Log.e("MinetestAssetCopy", "Error on processing filelist.txt");
e1.printStackTrace();
}
}
protected void onPostExecute(String result) {
finish();
}
protected boolean isAssetFolder(String path) {
return m_foldernames.contains(path);
}
}
}

View File

@@ -1,87 +0,0 @@
package net.minetest.minetest;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.text.InputType;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnKeyListener;
import android.widget.EditText;
public class MinetestTextEntry extends Activity {
private final int MultiLineTextInput = 1;
private final int SingleLineTextInput = 2;
private final int SingleLinePasswordInput = 3;
public AlertDialog mTextInputDialog;
public EditText mTextInputWidget;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle b = getIntent().getExtras();
String acceptButton = b.getString("EnterButton");
String hint = b.getString("hint");
String current = b.getString("current");
int editType = b.getInt("editType");
AlertDialog.Builder builder = new AlertDialog.Builder(this);
mTextInputWidget = new EditText(this);
mTextInputWidget.setHint(hint);
mTextInputWidget.setText(current);
mTextInputWidget.setMinWidth(300);
if (editType == SingleLinePasswordInput) {
mTextInputWidget.setInputType(InputType.TYPE_CLASS_TEXT |
InputType.TYPE_TEXT_VARIATION_PASSWORD);
} else {
mTextInputWidget.setInputType(InputType.TYPE_CLASS_TEXT);
}
builder.setView(mTextInputWidget);
if (editType == MultiLineTextInput) {
builder.setPositiveButton(acceptButton, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
pushResult(mTextInputWidget.getText().toString());
}
});
}
builder.setOnCancelListener(new DialogInterface.OnCancelListener() {
public void onCancel(DialogInterface dialog) {
cancelDialog();
}
});
mTextInputWidget.setOnKeyListener(new OnKeyListener() {
@Override
public boolean onKey(View view, int KeyCode, KeyEvent event) {
if (KeyCode == KeyEvent.KEYCODE_ENTER) {
pushResult(mTextInputWidget.getText().toString());
return true;
}
return false;
}
});
mTextInputDialog = builder.create();
mTextInputDialog.show();
}
public void pushResult(String text) {
Intent resultData = new Intent();
resultData.putExtra("text", text);
setResult(Activity.RESULT_OK, resultData);
mTextInputDialog.dismiss();
finish();
}
public void cancelDialog() {
setResult(Activity.RESULT_CANCELED);
mTextInputDialog.dismiss();
finish();
}
}

View File

@@ -1,111 +0,0 @@
package net.minetest.minetest;
import android.app.NativeActivity;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.view.WindowManager;
public class MtNativeActivity extends NativeActivity {
static {
System.loadLibrary("c++_shared");
System.loadLibrary("openal");
System.loadLibrary("ogg");
System.loadLibrary("vorbis");
System.loadLibrary("iconv");
System.loadLibrary("minetest");
}
private int m_MessagReturnCode;
private String m_MessageReturnValue;
public static native void putMessageBoxResult(String text);
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
m_MessagReturnCode = -1;
m_MessageReturnValue = "";
}
@Override
protected void onResume() {
super.onResume();
makeFullScreen();
}
public void makeFullScreen() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
this.getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
);
}
}
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus) {
makeFullScreen();
}
}
public void copyAssets() {
Intent intent = new Intent(this, MinetestAssetCopy.class);
startActivity(intent);
}
public void showDialog(String acceptButton, String hint, String current,
int editType) {
Intent intent = new Intent(this, MinetestTextEntry.class);
Bundle params = new Bundle();
params.putString("acceptButton", acceptButton);
params.putString("hint", hint);
params.putString("current", current);
params.putInt("editType", editType);
intent.putExtras(params);
startActivityForResult(intent, 101);
m_MessageReturnValue = "";
m_MessagReturnCode = -1;
}
/* ugly code to workaround putMessageBoxResult not beeing found */
public int getDialogState() {
return m_MessagReturnCode;
}
public String getDialogValue() {
m_MessagReturnCode = -1;
return m_MessageReturnValue;
}
public float getDensity() {
return getResources().getDisplayMetrics().density;
}
public int getDisplayWidth() {
return getResources().getDisplayMetrics().widthPixels;
}
public int getDisplayHeight() {
return getResources().getDisplayMetrics().heightPixels;
}
@Override
protected void onActivityResult(int requestCode, int resultCode,
Intent data) {
if (requestCode == 101) {
if (resultCode == RESULT_OK) {
String text = data.getStringExtra("text");
m_MessagReturnCode = 0;
m_MessageReturnValue = text;
} else {
m_MessagReturnCode = 1;
}
}
}
}

View File

@@ -1,24 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ProgressBar
android:id="@+id/progressBar1"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="30dp"
android:layout_centerInParent="true"
android:layout_marginLeft="90dp"
android:layout_marginRight="90dp" />
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/progressBar1"
android:layout_centerInParent="true"
android:text="@string/preparing_media" />
</RelativeLayout>

View File

@@ -1,12 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="AppTheme" parent="@android:style/android:Theme.Material.Light.NoActionBar.Fullscreen">
<item name="android:windowNoTitle">true</item>
<item name="android:windowAnimationStyle">@null</item>
<item name="android:windowBackground">@drawable/bg</item>
</style>
<style name="Theme.Dialog" parent="@android:style/Theme.Material.Light.Dialog.NoActionBar"/>
</resources>

View File

@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="preparing_media">Preparing media&#8230;</string>
<string name="not_granted">Required permission wasn\'t granted, Minetest can\'t run without it</string>
</resources>

View File

@@ -1,12 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="AppTheme" parent="@android:style/android:Theme.Holo.Light.NoActionBar.Fullscreen">
<item name="android:windowNoTitle">true</item>
<item name="android:windowAnimationStyle">@null</item>
<item name="android:windowBackground">@drawable/bg</item>
</style>
<style name="Theme.Dialog" parent="@android:style/android:Theme.Holo.Light.Dialog.NoActionBar"/>
</resources>

View File

@@ -16,7 +16,7 @@ core.register_on_sending_chat_message(function(message)
end
local cmd, param = string.match(message, "^%.([^ ]+) *(.*)")
param = param or ""
param = param or ""
if not cmd then
core.display_chat_message(core.gettext("-!- Empty command"))
@@ -26,9 +26,9 @@ core.register_on_sending_chat_message(function(message)
local cmd_def = core.registered_chatcommands[cmd]
if cmd_def then
core.set_last_run_mod(cmd_def.mod_origin)
local _, message = cmd_def.func(param)
if message then
core.display_chat_message(message)
local _, result = cmd_def.func(param)
if result then
core.display_chat_message(result)
end
else
core.display_chat_message(core.gettext("-!- Invalid command: ") .. cmd)

View File

@@ -1,33 +1,41 @@
local jobs = {}
local time = 0.0
local time_next = math.huge
core.register_globalstep(function(dtime)
time = time + dtime
if #jobs < 1 then
if time < time_next then
return
end
time_next = math.huge
-- Iterate backwards so that we miss any new timers added by
-- a timer callback, and so that we don't skip the next timer
-- in the list if we remove one.
-- a timer callback.
for i = #jobs, 1, -1 do
local job = jobs[i]
if time >= job.expire then
core.set_last_run_mod(job.mod_origin)
job.func(unpack(job.arg))
table.remove(jobs, i)
local jobs_l = #jobs
jobs[i] = jobs[jobs_l]
jobs[jobs_l] = nil
elseif job.expire < time_next then
time_next = job.expire
end
end
end)
function core.after(after, func, ...)
assert(tonumber(after) and type(func) == "function",
"Invalid core.after invocation")
"Invalid minetest.after invocation")
local expire = time + after
jobs[#jobs + 1] = {
func = func,
expire = time + after,
expire = expire,
arg = {...},
mod_origin = core.get_last_run_mod()
}
time_next = math.min(time_next, expire)
end

View File

@@ -250,7 +250,6 @@ end
--------------------------------------------------------------------------------
function compare_worlds(world1,world2)
if world1.path ~= world2.path then
return false
end

View File

@@ -0,0 +1,152 @@
local COLOR_BLUE = "#7AF"
local COLOR_GREEN = "#7F7"
local COLOR_GRAY = "#BBB"
local LIST_FORMSPEC = [[
size[13,6.5]
label[0,-0.1;%s]
tablecolumns[color;tree;text;text]
table[0,0.5;12.8,5.5;list;%s;0]
button_exit[5,6;3,1;quit;%s]
]]
local LIST_FORMSPEC_DESCRIPTION = [[
size[13,7.5]
label[0,-0.1;%s]
tablecolumns[color;tree;text;text]
table[0,0.5;12.8,4.8;list;%s;%i]
box[0,5.5;12.8,1.5;#000]
textarea[0.3,5.5;13.05,1.9;;;%s]
button_exit[5,7;3,1;quit;%s]
]]
local formspec_escape = core.formspec_escape
local check_player_privs = core.check_player_privs
-- CHAT COMMANDS FORMSPEC
local mod_cmds = {}
local function load_mod_command_tree()
mod_cmds = {}
for name, def in pairs(core.registered_chatcommands) do
mod_cmds[def.mod_origin] = mod_cmds[def.mod_origin] or {}
local cmds = mod_cmds[def.mod_origin]
-- Could be simplified, but avoid the priv checks whenever possible
cmds[#cmds + 1] = { name, def }
end
local sorted_mod_cmds = {}
for modname, cmds in pairs(mod_cmds) do
table.sort(cmds, function(a, b) return a[1] < b[1] end)
sorted_mod_cmds[#sorted_mod_cmds + 1] = { modname, cmds }
end
table.sort(sorted_mod_cmds, function(a, b) return a[1] < b[1] end)
mod_cmds = sorted_mod_cmds
end
core.after(0, load_mod_command_tree)
local function build_chatcommands_formspec(name, sel, copy)
local rows = {}
rows[1] = "#FFF,0,Command,Parameters"
local description = "For more information, click on any entry in the list.\n" ..
"Double-click to copy the entry to the chat history."
for i, data in ipairs(mod_cmds) do
rows[#rows + 1] = COLOR_BLUE .. ",0," .. formspec_escape(data[1]) .. ","
for j, cmds in ipairs(data[2]) do
local has_priv = check_player_privs(name, cmds[2].privs)
rows[#rows + 1] = ("%s,1,%s,%s"):format(
has_priv and COLOR_GREEN or COLOR_GRAY,
cmds[1], formspec_escape(cmds[2].params))
if sel == #rows then
description = cmds[2].description
if copy then
core.chat_send_player(name, ("Command: %s %s"):format(
core.colorize("#0FF", "/" .. cmds[1]), cmds[2].params))
end
end
end
end
return LIST_FORMSPEC_DESCRIPTION:format(
"Available commands: (see also: /help <cmd>)",
table.concat(rows, ","), sel or 0,
description, "Close"
)
end
-- PRIVILEGES FORMSPEC
local function build_privs_formspec(name)
local privs = {}
for priv_name, def in pairs(core.registered_privileges) do
privs[#privs + 1] = { priv_name, def }
end
table.sort(privs, function(a, b) return a[1] < b[1] end)
local rows = {}
rows[1] = "#FFF,0,Privilege,Description"
local player_privs = core.get_player_privs(name)
for i, data in ipairs(privs) do
rows[#rows + 1] = ("%s,0,%s,%s"):format(
player_privs[data[1]] and COLOR_GREEN or COLOR_GRAY,
data[1], formspec_escape(data[2].description))
end
return LIST_FORMSPEC:format(
"Available privileges:",
table.concat(rows, ","),
"Close"
)
end
-- DETAILED CHAT COMMAND INFORMATION
core.register_on_player_receive_fields(function(player, formname, fields)
if formname ~= "__builtin:help_cmds" or fields.quit then
return
end
local event = minetest.explode_table_event(fields.list)
if event.type ~= "INV" then
local name = player:get_player_name()
core.show_formspec(name, "__builtin:help_cmds",
build_chatcommands_formspec(name, event.row, event.type == "DCL"))
end
end)
local help_command = core.registered_chatcommands["help"]
local old_help_func = help_command.func
help_command.func = function(name, param)
local admin = core.settings:get("name")
-- If the admin ran help, put the output in the chat buffer as well to
-- work with the server terminal
if param == "privs" then
core.show_formspec(name, "__builtin:help_privs",
build_privs_formspec(name))
if name ~= admin then
return true
end
end
if param == "" or param == "all" then
core.show_formspec(name, "__builtin:help_cmds",
build_chatcommands_formspec(name))
if name ~= admin then
return true
end
end
return old_help_func(name, param)
end

View File

@@ -5,7 +5,7 @@
local string_sub, string_find = string.sub, string.find
--------------------------------------------------------------------------------
function basic_dump(o)
local function basic_dump(o)
local tp = type(o)
if tp == "number" then
return tostring(o)
@@ -20,6 +20,8 @@ function basic_dump(o)
-- dump's output is intended for humans.
--elseif tp == "function" then
-- return string.format("loadstring(%q)", string.dump(o))
elseif tp == "userdata" then
return tostring(o)
else
return string.format("<%s>", tp)
end
@@ -128,6 +130,7 @@ function dump(o, indent, nested, level)
if t ~= "table" then
return basic_dump(o)
end
-- Contains table -> true/nil of currently nested tables
nested = nested or {}
if nested[o] then
@@ -136,10 +139,11 @@ function dump(o, indent, nested, level)
nested[o] = true
indent = indent or "\t"
level = level or 1
local t = {}
local ret = {}
local dumped_indexes = {}
for i, v in ipairs(o) do
t[#t + 1] = dump(v, indent, nested, level + 1)
ret[#ret + 1] = dump(v, indent, nested, level + 1)
dumped_indexes[i] = true
end
for k, v in pairs(o) do
@@ -148,7 +152,7 @@ function dump(o, indent, nested, level)
k = "["..dump(k, indent, nested, level + 1).."]"
end
v = dump(v, indent, nested, level + 1)
t[#t + 1] = k.." = "..v
ret[#ret + 1] = k.." = "..v
end
end
nested[o] = nil
@@ -157,10 +161,10 @@ function dump(o, indent, nested, level)
local end_indent_str = "\n"..string.rep(indent, level - 1)
return string.format("{%s%s%s}",
indent_str,
table.concat(t, ","..indent_str),
table.concat(ret, ","..indent_str),
end_indent_str)
end
return "{"..table.concat(t, ", ").."}"
return "{"..table.concat(ret, ", ").."}"
end
--------------------------------------------------------------------------------
@@ -198,28 +202,11 @@ function table.indexof(list, val)
return -1
end
assert(table.indexof({"foo", "bar"}, "foo") == 1)
assert(table.indexof({"foo", "bar"}, "baz") == -1)
--------------------------------------------------------------------------------
if INIT ~= "client" then
function file_exists(filename)
local f = io.open(filename, "r")
if f == nil then
return false
else
f:close()
return true
end
end
end
--------------------------------------------------------------------------------
function string:trim()
return (self:gsub("^%s*(.-)%s*$", "%1"))
end
assert(string.trim("\n \t\tfoo bar\t ") == "foo bar")
--------------------------------------------------------------------------------
function math.hypot(x, y)
local t
@@ -244,61 +231,17 @@ function math.sign(x, tolerance)
end
--------------------------------------------------------------------------------
function get_last_folder(text,count)
local parts = text:split(DIR_DELIM)
if count == nil then
return parts[#parts]
function math.factorial(x)
assert(x % 1 == 0 and x >= 0, "factorial expects a non-negative integer")
if x >= 171 then
-- 171! is greater than the biggest double, no need to calculate
return math.huge
end
local retval = ""
for i=1,count,1 do
retval = retval .. parts[#parts - (count-i)] .. DIR_DELIM
local v = 1
for k = 2, x do
v = v * k
end
return retval
end
--------------------------------------------------------------------------------
function cleanup_path(temppath)
local parts = temppath:split("-")
temppath = ""
for i=1,#parts,1 do
if temppath ~= "" then
temppath = temppath .. "_"
end
temppath = temppath .. parts[i]
end
parts = temppath:split(".")
temppath = ""
for i=1,#parts,1 do
if temppath ~= "" then
temppath = temppath .. "_"
end
temppath = temppath .. parts[i]
end
parts = temppath:split("'")
temppath = ""
for i=1,#parts,1 do
if temppath ~= "" then
temppath = temppath .. ""
end
temppath = temppath .. parts[i]
end
parts = temppath:split(" ")
temppath = ""
for i=1,#parts,1 do
if temppath ~= "" then
temppath = temppath
end
temppath = temppath .. parts[i]
end
return temppath
return v
end
function core.formspec_escape(text)
@@ -349,7 +292,8 @@ if INIT == "game" then
return
end
local undef = core.registered_nodes[unode.name]
if undef and undef.on_rightclick then
local sneaking = placer and placer:get_player_control().sneak
if undef and undef.on_rightclick and not sneaking then
return undef.on_rightclick(pointed_thing.under, unode, placer,
itemstack, pointed_thing)
end
@@ -393,9 +337,8 @@ if INIT == "game" then
end
local old_itemstack = ItemStack(itemstack)
local new_itemstack, removed = core.item_place_node(
itemstack, placer, pointed_thing, param2, prevent_after_place
)
local new_itemstack = core.item_place_node(itemstack, placer,
pointed_thing, param2, prevent_after_place)
return infinitestacks and old_itemstack or new_itemstack
end
@@ -404,19 +347,12 @@ if INIT == "game" then
--Wrapper for rotate_and_place() to check for sneak and assume Creative mode
--implies infinite stacks when performing a 6d rotation.
--------------------------------------------------------------------------------
local creative_mode_cache = core.settings:get_bool("creative_mode")
local function is_creative(name)
return creative_mode_cache or
core.check_player_privs(name, {creative = true})
end
core.rotate_node = function(itemstack, placer, pointed_thing)
local name = placer and placer:get_player_name() or ""
local invert_wall = placer and placer:get_player_control().sneak or false
core.rotate_and_place(itemstack, placer, pointed_thing,
is_creative(name),
{invert_wall = invert_wall}, true)
return itemstack
return core.rotate_and_place(itemstack, placer, pointed_thing,
core.is_creative_enabled(name),
{invert_wall = invert_wall}, true)
end
end
@@ -506,9 +442,6 @@ function core.string_to_pos(value)
return nil
end
assert(core.string_to_pos("10.0, 5, -2").x == 10)
assert(core.string_to_pos("( 10.0, 5, -2)").z == -2)
assert(core.string_to_pos("asd, 5, -2)") == nil)
--------------------------------------------------------------------------------
function core.string_to_area(value)
@@ -561,6 +494,29 @@ function table.insert_all(t, other)
end
function table.key_value_swap(t)
local ti = {}
for k,v in pairs(t) do
ti[v] = k
end
return ti
end
function table.shuffle(t, from, to, random)
from = from or 1
to = to or #t
random = random or math.random
local n = to - from + 1
while n > 1 do
local r = from + n-1
local l = from + random(0, n-1)
t[l], t[r] = t[r], t[l]
n = n-1
end
end
--------------------------------------------------------------------------------
-- mainmenu only functions
--------------------------------------------------------------------------------
@@ -741,6 +697,3 @@ function core.privs_to_string(privs, delim)
end
return table.concat(list, delim)
end
assert(core.string_to_privs("a,b").b == true)
assert(core.privs_to_string({a=true,b=true}) == "a,b")

View File

@@ -120,15 +120,8 @@ function core.serialize(x)
elseif tp == "function" then
return string.format("loadstring(%q)", string.dump(x))
elseif tp == "number" then
-- Serialize integers with string.format to prevent
-- scientific notation, which doesn't preserve
-- precision and breaks things like node position
-- hashes. Serialize floats normally.
if math.floor(x) == x then
return string.format("%d", x)
else
return tostring(x)
end
-- Serialize numbers reversibly with string.format
return string.format("%.17g", x)
elseif tp == "table" then
local vals = {}
local idx_dumped = {}
@@ -177,13 +170,16 @@ end
-- Deserialization
local env = {
loadstring = loadstring,
}
local function safe_loadstring(...)
local func, err = loadstring(...)
if func then
setfenv(func, {})
return func
end
return nil, err
end
local safe_env = {
loadstring = function() end,
}
local function dummy_func() end
function core.deserialize(str, safe)
if type(str) ~= "string" then
@@ -195,7 +191,10 @@ function core.deserialize(str, safe)
end
local f, err = loadstring(str)
if not f then return nil, err end
setfenv(f, safe and safe_env or env)
-- The environment is recreated every time so deseralized code cannot
-- pollute it with permanent references.
setfenv(f, {loadstring = safe and dummy_func or safe_loadstring})
local good, data = pcall(f)
if good then
@@ -204,18 +203,3 @@ function core.deserialize(str, safe)
return nil, data
end
end
-- Unit tests
local test_in = {cat={sound="nyan", speed=400}, dog={sound="woof"}}
local test_out = core.deserialize(core.serialize(test_in))
assert(test_in.cat.sound == test_out.cat.sound)
assert(test_in.cat.speed == test_out.cat.speed)
assert(test_in.dog.sound == test_out.dog.sound)
test_in = {escape_chars="\n\r\t\v\\\"\'", non_european="θשׁ٩∂"}
test_out = core.deserialize(core.serialize(test_in))
assert(test_in.escape_chars == test_out.escape_chars)
assert(test_in.non_european == test_out.non_european)

View File

@@ -0,0 +1,73 @@
_G.core = {}
dofile("builtin/common/misc_helpers.lua")
describe("string", function()
it("trim()", function()
assert.equal("foo bar", string.trim("\n \t\tfoo bar\t "))
end)
describe("split()", function()
it("removes empty", function()
assert.same({ "hello" }, string.split("hello"))
assert.same({ "hello", "world" }, string.split("hello,world"))
assert.same({ "hello", "world" }, string.split("hello,world,,,"))
assert.same({ "hello", "world" }, string.split(",,,hello,world"))
assert.same({ "hello", "world", "2" }, string.split("hello,,,world,2"))
assert.same({ "hello ", " world" }, string.split("hello :| world", ":|"))
end)
it("keeps empty", function()
assert.same({ "hello" }, string.split("hello", ",", true))
assert.same({ "hello", "world" }, string.split("hello,world", ",", true))
assert.same({ "hello", "world", "" }, string.split("hello,world,", ",", true))
assert.same({ "hello", "", "", "world", "2" }, string.split("hello,,,world,2", ",", true))
assert.same({ "", "", "hello", "world", "2" }, string.split(",,hello,world,2", ",", true))
assert.same({ "hello ", " world | :" }, string.split("hello :| world | :", ":|"))
end)
it("max_splits", function()
assert.same({ "one" }, string.split("one", ",", true, 2))
assert.same({ "one,two,three,four" }, string.split("one,two,three,four", ",", true, 0))
assert.same({ "one", "two", "three,four" }, string.split("one,two,three,four", ",", true, 2))
assert.same({ "one", "", "two,three,four" }, string.split("one,,two,three,four", ",", true, 2))
assert.same({ "one", "two", "three,four" }, string.split("one,,,,,,two,three,four", ",", false, 2))
end)
it("pattern", function()
assert.same({ "one", "two" }, string.split("one,two", ",", false, -1, true))
assert.same({ "one", "two", "three" }, string.split("one2two3three", "%d", false, -1, true))
end)
end)
end)
describe("privs", function()
it("from string", function()
assert.same({ a = true, b = true }, core.string_to_privs("a,b"))
end)
it("to string", function()
assert.equal("one", core.privs_to_string({ one=true }))
local ret = core.privs_to_string({ a=true, b=true })
assert(ret == "a,b" or ret == "b,a")
end)
end)
describe("pos", function()
it("from string", function()
assert.same({ x = 10, y = 5.1, z = -2}, core.string_to_pos("10.0, 5.1, -2"))
assert.same({ x = 10, y = 5.1, z = -2}, core.string_to_pos("( 10.0, 5.1, -2)"))
assert.is_nil(core.string_to_pos("asd, 5, -2)"))
end)
it("to string", function()
assert.equal("(10.1,5.2,-2.3)", core.pos_to_string({ x = 10.1, y = 5.2, z = -2.3}))
end)
end)
describe("table", function()
it("indexof()", function()
assert.equal(1, table.indexof({"foo", "bar"}, "foo"))
assert.equal(-1, table.indexof({"foo", "bar"}, "baz"))
end)
end)

View File

@@ -0,0 +1,56 @@
_G.core = {}
_G.setfenv = require 'busted.compatibility'.setfenv
dofile("builtin/common/serialize.lua")
describe("serialize", function()
it("works", function()
local test_in = {cat={sound="nyan", speed=400}, dog={sound="woof"}}
local test_out = core.deserialize(core.serialize(test_in))
assert.same(test_in, test_out)
end)
it("handles characters", function()
local test_in = {escape_chars="\n\r\t\v\\\"\'", non_european="θשׁ٩∂"}
local test_out = core.deserialize(core.serialize(test_in))
assert.same(test_in, test_out)
end)
it("handles precise numbers", function()
local test_in = 0.2695949158945771
local test_out = core.deserialize(core.serialize(test_in))
assert.same(test_in, test_out)
end)
it("handles big integers", function()
local test_in = 269594915894577
local test_out = core.deserialize(core.serialize(test_in))
assert.same(test_in, test_out)
end)
it("handles recursive structures", function()
local test_in = { hello = "world" }
test_in.foo = test_in
local test_out = core.deserialize(core.serialize(test_in))
assert.same(test_in, test_out)
end)
it("strips functions in safe mode", function()
local test_in = {
func = function(a, b)
error("test")
end,
foo = "bar"
}
local str = core.serialize(test_in)
assert.not_nil(str:find("loadstring"))
local test_out = core.deserialize(str, true)
assert.is_nil(test_out.func)
assert.equals(test_out.foo, "bar")
end)
end)

View File

@@ -0,0 +1,188 @@
_G.vector = {}
dofile("builtin/common/vector.lua")
describe("vector", function()
describe("new()", function()
it("constructs", function()
assert.same({ x = 0, y = 0, z = 0 }, vector.new())
assert.same({ x = 1, y = 2, z = 3 }, vector.new(1, 2, 3))
assert.same({ x = 3, y = 2, z = 1 }, vector.new({ x = 3, y = 2, z = 1 }))
local input = vector.new({ x = 3, y = 2, z = 1 })
local output = vector.new(input)
assert.same(input, output)
assert.are_not.equal(input, output)
end)
it("throws on invalid input", function()
assert.has.errors(function()
vector.new({ x = 3 })
end)
assert.has.errors(function()
vector.new({ d = 3 })
end)
end)
end)
it("equal()", function()
local function assertE(a, b)
assert.is_true(vector.equals(a, b))
end
local function assertNE(a, b)
assert.is_false(vector.equals(a, b))
end
assertE({x = 0, y = 0, z = 0}, {x = 0, y = 0, z = 0})
assertE({x = -1, y = 0, z = 1}, {x = -1, y = 0, z = 1})
local a = { x = 2, y = 4, z = -10 }
assertE(a, a)
assertNE({x = -1, y = 0, z = 1}, a)
end)
it("add()", function()
assert.same({ x = 2, y = 4, z = 6 }, vector.add(vector.new(1, 2, 3), { x = 1, y = 2, z = 3 }))
end)
-- This function is needed because of floating point imprecision.
local function almost_equal(a, b)
if type(a) == "number" then
return math.abs(a - b) < 0.00000000001
end
return vector.distance(a, b) < 0.000000000001
end
describe("rotate_around_axis()", function()
it("rotates", function()
assert.True(almost_equal({x = -1, y = 0, z = 0},
vector.rotate_around_axis({x = 1, y = 0, z = 0}, {x = 0, y = 1, z = 0}, math.pi)))
assert.True(almost_equal({x = 0, y = 1, z = 0},
vector.rotate_around_axis({x = 0, y = 0, z = 1}, {x = 1, y = 0, z = 0}, math.pi / 2)))
assert.True(almost_equal({x = 4, y = 1, z = 1},
vector.rotate_around_axis({x = 4, y = 1, z = 1}, {x = 4, y = 1, z = 1}, math.pi / 6)))
end)
it("keeps distance to axis", function()
local rotate1 = {x = 1, y = 3, z = 1}
local axis1 = {x = 1, y = 3, z = 2}
local rotated1 = vector.rotate_around_axis(rotate1, axis1, math.pi / 13)
assert.True(almost_equal(vector.distance(axis1, rotate1), vector.distance(axis1, rotated1)))
local rotate2 = {x = 1, y = 1, z = 3}
local axis2 = {x = 2, y = 6, z = 100}
local rotated2 = vector.rotate_around_axis(rotate2, axis2, math.pi / 23)
assert.True(almost_equal(vector.distance(axis2, rotate2), vector.distance(axis2, rotated2)))
local rotate3 = {x = 1, y = -1, z = 3}
local axis3 = {x = 2, y = 6, z = 100}
local rotated3 = vector.rotate_around_axis(rotate3, axis3, math.pi / 2)
assert.True(almost_equal(vector.distance(axis3, rotate3), vector.distance(axis3, rotated3)))
end)
it("rotates back", function()
local rotate1 = {x = 1, y = 3, z = 1}
local axis1 = {x = 1, y = 3, z = 2}
local rotated1 = vector.rotate_around_axis(rotate1, axis1, math.pi / 13)
rotated1 = vector.rotate_around_axis(rotated1, axis1, -math.pi / 13)
assert.True(almost_equal(rotate1, rotated1))
local rotate2 = {x = 1, y = 1, z = 3}
local axis2 = {x = 2, y = 6, z = 100}
local rotated2 = vector.rotate_around_axis(rotate2, axis2, math.pi / 23)
rotated2 = vector.rotate_around_axis(rotated2, axis2, -math.pi / 23)
assert.True(almost_equal(rotate2, rotated2))
local rotate3 = {x = 1, y = -1, z = 3}
local axis3 = {x = 2, y = 6, z = 100}
local rotated3 = vector.rotate_around_axis(rotate3, axis3, math.pi / 2)
rotated3 = vector.rotate_around_axis(rotated3, axis3, -math.pi / 2)
assert.True(almost_equal(rotate3, rotated3))
end)
it("is right handed", function()
local v_before1 = {x = 0, y = 1, z = -1}
local v_after1 = vector.rotate_around_axis(v_before1, {x = 1, y = 0, z = 0}, math.pi / 4)
assert.True(almost_equal(vector.normalize(vector.cross(v_after1, v_before1)), {x = 1, y = 0, z = 0}))
local v_before2 = {x = 0, y = 3, z = 4}
local v_after2 = vector.rotate_around_axis(v_before2, {x = 1, y = 0, z = 0}, 2 * math.pi / 5)
assert.True(almost_equal(vector.normalize(vector.cross(v_after2, v_before2)), {x = 1, y = 0, z = 0}))
local v_before3 = {x = 1, y = 0, z = -1}
local v_after3 = vector.rotate_around_axis(v_before3, {x = 0, y = 1, z = 0}, math.pi / 4)
assert.True(almost_equal(vector.normalize(vector.cross(v_after3, v_before3)), {x = 0, y = 1, z = 0}))
local v_before4 = {x = 3, y = 0, z = 4}
local v_after4 = vector.rotate_around_axis(v_before4, {x = 0, y = 1, z = 0}, 2 * math.pi / 5)
assert.True(almost_equal(vector.normalize(vector.cross(v_after4, v_before4)), {x = 0, y = 1, z = 0}))
local v_before5 = {x = 1, y = -1, z = 0}
local v_after5 = vector.rotate_around_axis(v_before5, {x = 0, y = 0, z = 1}, math.pi / 4)
assert.True(almost_equal(vector.normalize(vector.cross(v_after5, v_before5)), {x = 0, y = 0, z = 1}))
local v_before6 = {x = 3, y = 4, z = 0}
local v_after6 = vector.rotate_around_axis(v_before6, {x = 0, y = 0, z = 1}, 2 * math.pi / 5)
assert.True(almost_equal(vector.normalize(vector.cross(v_after6, v_before6)), {x = 0, y = 0, z = 1}))
end)
end)
describe("rotate()", function()
it("rotates", function()
assert.True(almost_equal({x = -1, y = 0, z = 0},
vector.rotate({x = 1, y = 0, z = 0}, {x = 0, y = math.pi, z = 0})))
assert.True(almost_equal({x = 0, y = -1, z = 0},
vector.rotate({x = 1, y = 0, z = 0}, {x = 0, y = 0, z = math.pi / 2})))
assert.True(almost_equal({x = 1, y = 0, z = 0},
vector.rotate({x = 1, y = 0, z = 0}, {x = math.pi / 123, y = 0, z = 0})))
end)
it("is counterclockwise", function()
local v_before1 = {x = 0, y = 1, z = -1}
local v_after1 = vector.rotate(v_before1, {x = math.pi / 4, y = 0, z = 0})
assert.True(almost_equal(vector.normalize(vector.cross(v_after1, v_before1)), {x = 1, y = 0, z = 0}))
local v_before2 = {x = 0, y = 3, z = 4}
local v_after2 = vector.rotate(v_before2, {x = 2 * math.pi / 5, y = 0, z = 0})
assert.True(almost_equal(vector.normalize(vector.cross(v_after2, v_before2)), {x = 1, y = 0, z = 0}))
local v_before3 = {x = 1, y = 0, z = -1}
local v_after3 = vector.rotate(v_before3, {x = 0, y = math.pi / 4, z = 0})
assert.True(almost_equal(vector.normalize(vector.cross(v_after3, v_before3)), {x = 0, y = 1, z = 0}))
local v_before4 = {x = 3, y = 0, z = 4}
local v_after4 = vector.rotate(v_before4, {x = 0, y = 2 * math.pi / 5, z = 0})
assert.True(almost_equal(vector.normalize(vector.cross(v_after4, v_before4)), {x = 0, y = 1, z = 0}))
local v_before5 = {x = 1, y = -1, z = 0}
local v_after5 = vector.rotate(v_before5, {x = 0, y = 0, z = math.pi / 4})
assert.True(almost_equal(vector.normalize(vector.cross(v_after5, v_before5)), {x = 0, y = 0, z = 1}))
local v_before6 = {x = 3, y = 4, z = 0}
local v_after6 = vector.rotate(v_before6, {x = 0, y = 0, z = 2 * math.pi / 5})
assert.True(almost_equal(vector.normalize(vector.cross(v_after6, v_before6)), {x = 0, y = 0, z = 1}))
end)
end)
it("dir_to_rotation()", function()
-- Comparing rotations (pitch, yaw, roll) is hard because of certain ambiguities,
-- e.g. (pi, 0, pi) looks exactly the same as (0, pi, 0)
-- So instead we convert the rotation back to vectors and compare these.
local function forward_at_rot(rot)
return vector.rotate(vector.new(0, 0, 1), rot)
end
local function up_at_rot(rot)
return vector.rotate(vector.new(0, 1, 0), rot)
end
local rot1 = vector.dir_to_rotation({x = 1, y = 0, z = 0}, {x = 0, y = 1, z = 0})
assert.True(almost_equal({x = 1, y = 0, z = 0}, forward_at_rot(rot1)))
assert.True(almost_equal({x = 0, y = 1, z = 0}, up_at_rot(rot1)))
local rot2 = vector.dir_to_rotation({x = 1, y = 1, z = 0}, {x = 0, y = 0, z = 1})
assert.True(almost_equal({x = 1/math.sqrt(2), y = 1/math.sqrt(2), z = 0}, forward_at_rot(rot2)))
assert.True(almost_equal({x = 0, y = 0, z = 1}, up_at_rot(rot2)))
for i = 1, 1000 do
local rand_vec = vector.new(math.random(), math.random(), math.random())
if vector.length(rand_vec) ~= 0 then
local rot_1 = vector.dir_to_rotation(rand_vec)
local rot_2 = {
x = math.atan2(rand_vec.y, math.sqrt(rand_vec.z * rand_vec.z + rand_vec.x * rand_vec.x)),
y = -math.atan2(rand_vec.x, rand_vec.z),
z = 0
}
assert.True(almost_equal(rot_1, rot_2))
end
end
end)
end)

View File

@@ -70,6 +70,25 @@ function vector.direction(pos1, pos2)
})
end
function vector.angle(a, b)
local dotp = vector.dot(a, b)
local cp = vector.cross(a, b)
local crossplen = vector.length(cp)
return math.atan2(crossplen, dotp)
end
function vector.dot(a, b)
return a.x * b.x + a.y * b.y + a.z * b.z
end
function vector.cross(a, b)
return {
x = a.y * b.z - a.z * b.y,
y = a.z * b.x - a.x * b.z,
z = a.x * b.y - a.y * b.x
}
end
function vector.add(a, b)
if type(b) == "table" then
return {x = a.x + b.x,
@@ -122,3 +141,96 @@ function vector.sort(a, b)
return {x = math.min(a.x, b.x), y = math.min(a.y, b.y), z = math.min(a.z, b.z)},
{x = math.max(a.x, b.x), y = math.max(a.y, b.y), z = math.max(a.z, b.z)}
end
local function sin(x)
if x % math.pi == 0 then
return 0
else
return math.sin(x)
end
end
local function cos(x)
if x % math.pi == math.pi / 2 then
return 0
else
return math.cos(x)
end
end
function vector.rotate_around_axis(v, axis, angle)
local cosangle = cos(angle)
local sinangle = sin(angle)
axis = vector.normalize(axis)
-- https://en.wikipedia.org/wiki/Rodrigues%27_rotation_formula
local dot_axis = vector.multiply(axis, vector.dot(axis, v))
local cross = vector.cross(v, axis)
return vector.new(
cross.x * sinangle + (v.x - dot_axis.x) * cosangle + dot_axis.x,
cross.y * sinangle + (v.y - dot_axis.y) * cosangle + dot_axis.y,
cross.z * sinangle + (v.z - dot_axis.z) * cosangle + dot_axis.z
)
end
function vector.rotate(v, rot)
local sinpitch = sin(-rot.x)
local sinyaw = sin(-rot.y)
local sinroll = sin(-rot.z)
local cospitch = cos(rot.x)
local cosyaw = cos(rot.y)
local cosroll = math.cos(rot.z)
-- Rotation matrix that applies yaw, pitch and roll
local matrix = {
{
sinyaw * sinpitch * sinroll + cosyaw * cosroll,
sinyaw * sinpitch * cosroll - cosyaw * sinroll,
sinyaw * cospitch,
},
{
cospitch * sinroll,
cospitch * cosroll,
-sinpitch,
},
{
cosyaw * sinpitch * sinroll - sinyaw * cosroll,
cosyaw * sinpitch * cosroll + sinyaw * sinroll,
cosyaw * cospitch,
},
}
-- Compute matrix multiplication: `matrix` * `v`
return vector.new(
matrix[1][1] * v.x + matrix[1][2] * v.y + matrix[1][3] * v.z,
matrix[2][1] * v.x + matrix[2][2] * v.y + matrix[2][3] * v.z,
matrix[3][1] * v.x + matrix[3][2] * v.y + matrix[3][3] * v.z
)
end
function vector.dir_to_rotation(forward, up)
forward = vector.normalize(forward)
local rot = {x = math.asin(forward.y), y = -math.atan2(forward.x, forward.z), z = 0}
if not up then
return rot
end
assert(vector.dot(forward, up) < 0.000001,
"Invalid vectors passed to vector.dir_to_rotation().")
up = vector.normalize(up)
-- Calculate vector pointing up with roll = 0, just based on forward vector.
local forwup = vector.rotate({x = 0, y = 1, z = 0}, rot)
-- 'forwup' and 'up' are now in a plane with 'forward' as normal.
-- The angle between them is the absolute of the roll value we're looking for.
rot.z = vector.angle(forwup, up)
-- Since vector.angle never returns a negative value or a value greater
-- than math.pi, rot.z has to be inverted sometimes.
-- To determine wether this is the case, we rotate the up vector back around
-- the forward vector and check if it worked out.
local back = vector.rotate_around_axis(up, forward, -rot.z)
-- We don't use vector.equals for this because of floating point imprecision.
if (back.x - forwup.x) * (back.x - forwup.x) +
(back.y - forwup.y) * (back.y - forwup.y) +
(back.z - forwup.z) * (back.z - forwup.z) > 0.0000001 then
rot.z = -rot.z
end
return rot
end

View File

@@ -67,3 +67,22 @@ function dialog_create(name,get_formspec,buttonhandler,eventhandler)
ui.add(self)
return self
end
function messagebox(name, message)
return dialog_create(name,
function()
return ([[
formspec_version[3]
size[8,3]
textarea[0.375,0.375;7.25,1.2;;;%s]
button[3,1.825;2,0.8;ok;%s]
]]):format(message, fgettext("OK"))
end,
function(this, fields)
if fields.ok then
this:delete()
return true
end
end,
nil)
end

View File

@@ -54,52 +54,39 @@ end
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
local function wordwrap_quickhack(str)
local res = ""
local ar = str:split("\n")
for i = 1, #ar do
local text = ar[i]
-- Hack to add word wrapping.
-- TODO: Add engine support for wrapping in formspecs
while #text > 80 do
if res ~= "" then
res = res .. ","
end
res = res .. core.formspec_escape(string.sub(text, 1, 79))
text = string.sub(text, 80, #text)
end
if res ~= "" then
res = res .. ","
end
res = res .. core.formspec_escape(text)
end
return res
end
--------------------------------------------------------------------------------
function ui.update()
local formspec = ""
local formspec = {}
-- handle errors
if gamedata ~= nil and gamedata.reconnect_requested then
formspec = wordwrap_quickhack(gamedata.errormessage or "")
formspec = "size[12,5]" ..
"label[0.5,0;" .. fgettext("The server has requested a reconnect:") ..
"]textlist[0.2,0.8;11.5,3.5;;" .. formspec ..
"]button[6,4.6;3,0.5;btn_reconnect_no;" .. fgettext("Main menu") .. "]" ..
"button[3,4.6;3,0.5;btn_reconnect_yes;" .. fgettext("Reconnect") .. "]"
local error_message = core.formspec_escape(
gamedata.errormessage or "<none available>")
formspec = {
"size[14,8]",
"real_coordinates[true]",
"box[0.5,1.2;13,5;#000]",
("textarea[0.5,1.2;13,5;;%s;%s]"):format(
fgettext("The server has requested a reconnect:"), error_message),
"button[2,6.6;4,1;btn_reconnect_yes;" .. fgettext("Reconnect") .. "]",
"button[8,6.6;4,1;btn_reconnect_no;" .. fgettext("Main menu") .. "]"
}
elseif gamedata ~= nil and gamedata.errormessage ~= nil then
formspec = wordwrap_quickhack(gamedata.errormessage)
local error_message = core.formspec_escape(gamedata.errormessage)
local error_title
if string.find(gamedata.errormessage, "ModError") then
error_title = fgettext("An error occurred in a Lua script, such as a mod:")
error_title = fgettext("An error occurred in a Lua script:")
else
error_title = fgettext("An error occurred:")
end
formspec = "size[12,5]" ..
"label[0.5,0;" .. error_title ..
"]textlist[0.2,0.8;11.5,3.5;;" .. formspec ..
"]button[4.5,4.6;3,0.5;btn_error_confirm;" .. fgettext("Ok") .. "]"
formspec = {
"size[14,8]",
"real_coordinates[true]",
"box[0.5,1.2;13,5;#000]",
("textarea[0.5,1.2;13,5;;%s;%s]"):format(
error_title, error_message),
"button[5,6.6;4,1;btn_error_confirm;" .. fgettext("OK") .. "]"
}
else
local active_toplevel_ui_elements = 0
for key,value in pairs(ui.childlist) do
@@ -107,8 +94,8 @@ function ui.update()
local retval = value:get_formspec()
if retval ~= nil and retval ~= "" then
active_toplevel_ui_elements = active_toplevel_ui_elements +1
formspec = formspec .. retval
active_toplevel_ui_elements = active_toplevel_ui_elements + 1
table.insert(formspec, retval)
end
end
end
@@ -120,7 +107,7 @@ function ui.update()
local retval = value:get_formspec()
if retval ~= nil and retval ~= "" then
formspec = formspec .. retval
table.insert(formspec, retval)
end
end
end
@@ -135,10 +122,10 @@ function ui.update()
core.log("warning", "no toplevel ui element "..
"active; switching to default")
ui.childlist[ui.default]:show()
formspec = ui.childlist[ui.default]:get_formspec()
formspec = {ui.childlist[ui.default]:get_formspec()}
end
end
core.update_formspec(formspec)
core.update_formspec(table.concat(formspec))
end
--------------------------------------------------------------------------------

View File

@@ -41,7 +41,6 @@ core.builtin_auth_handler = {
return {
password = auth_entry.password,
privileges = privileges,
-- Is set to nil if unknown
last_login = auth_entry.last_login,
}
end,
@@ -53,7 +52,7 @@ core.builtin_auth_handler = {
name = name,
password = password,
privileges = core.string_to_privs(core.settings:get("default_privs")),
last_login = os.time(),
last_login = -1, -- Defer login time calculation until record_login (called by on_joinplayer)
})
end,
delete_auth = function(name)

View File

@@ -1,4 +1,43 @@
-- Minetest: builtin/game/chatcommands.lua
-- Minetest: builtin/game/chat.lua
-- Helper function that implements search and replace without pattern matching
-- Returns the string and a boolean indicating whether or not the string was modified
local function safe_gsub(s, replace, with)
local i1, i2 = s:find(replace, 1, true)
if not i1 then
return s, false
end
return s:sub(1, i1 - 1) .. with .. s:sub(i2 + 1), true
end
--
-- Chat message formatter
--
-- Implemented in Lua to allow redefinition
function core.format_chat_message(name, message)
local error_str = "Invalid chat message format - missing %s"
local str = core.settings:get("chat_message_format")
local replaced
-- Name
str, replaced = safe_gsub(str, "@name", name)
if not replaced then
error(error_str:format("@name"), 2)
end
-- Timestamp
str = safe_gsub(str, "@timestamp", os.date("%H:%M:%S", os.time()))
-- Insert the message into the string only after finishing all other processing
str, replaced = safe_gsub(str, "@message", message)
if not replaced then
error(error_str:format("@message"), 2)
end
return str
end
--
-- Chat command handler
@@ -27,9 +66,9 @@ core.register_on_chat_message(function(name, message)
local has_privs, missing_privs = core.check_player_privs(name, cmd_def.privs)
if has_privs then
core.set_last_run_mod(cmd_def.mod_origin)
local success, message = cmd_def.func(name, param)
if message then
core.chat_send_player(name, message)
local _, result = cmd_def.func(name, param)
if result then
core.chat_send_player(name, result)
end
else
core.chat_send_player(name, "You don't have permission"
@@ -76,6 +115,7 @@ core.register_chatcommand("me", {
privs = {shout=true},
func = function(name, param)
core.chat_send_all("* " .. name .. " " .. param)
return true
end,
})
@@ -102,7 +142,7 @@ core.register_chatcommand("privs", {
end
return true, "Privileges of " .. name .. ": "
.. core.privs_to_string(
core.get_player_privs(name), ' ')
core.get_player_privs(name), ", ")
end,
})
@@ -125,10 +165,10 @@ core.register_chatcommand("haspriv", {
if core.check_player_privs(player_name, privs) then
table.insert(players_with_priv, player_name)
end
end
end
return true, "Players online with the \"" .. param .. "\" privilege: " ..
table.concat(players_with_priv, ", ")
end
end
})
local function handle_grant_command(caller, grantname, grantprivstr)
@@ -161,6 +201,7 @@ local function handle_grant_command(caller, grantname, grantprivstr)
return false, privs_unknown
end
for priv, _ in pairs(grantprivs) do
-- call the on_grant callbacks
core.run_priv_callbacks(grantname, priv, caller, "grant")
end
core.set_player_privs(grantname, privs)
@@ -198,56 +239,76 @@ core.register_chatcommand("grantme", {
end,
})
local function handle_revoke_command(caller, revokename, revokeprivstr)
local caller_privs = core.get_player_privs(caller)
if not (caller_privs.privs or caller_privs.basic_privs) then
return false, "Your privileges are insufficient."
end
if not core.get_auth_handler().get_auth(revokename) then
return false, "Player " .. revokename .. " does not exist."
end
local revokeprivs = core.string_to_privs(revokeprivstr)
local privs = core.get_player_privs(revokename)
local basic_privs =
core.string_to_privs(core.settings:get("basic_privs") or "interact,shout")
for priv, _ in pairs(revokeprivs) do
if not basic_privs[priv] and not caller_privs.privs then
return false, "Your privileges are insufficient."
end
end
if revokeprivstr == "all" then
revokeprivs = privs
privs = {}
else
for priv, _ in pairs(revokeprivs) do
privs[priv] = nil
end
end
for priv, _ in pairs(revokeprivs) do
-- call the on_revoke callbacks
core.run_priv_callbacks(revokename, priv, caller, "revoke")
end
core.set_player_privs(revokename, privs)
core.log("action", caller..' revoked ('
..core.privs_to_string(revokeprivs, ', ')
..') privileges from '..revokename)
if revokename ~= caller then
core.chat_send_player(revokename, caller
.. " revoked privileges from you: "
.. core.privs_to_string(revokeprivs, ' '))
end
return true, "Privileges of " .. revokename .. ": "
.. core.privs_to_string(
core.get_player_privs(revokename), ' ')
end
core.register_chatcommand("revoke", {
params = "<name> (<privilege> | all)",
description = "Remove privileges from player",
privs = {},
func = function(name, param)
if not core.check_player_privs(name, {privs=true}) and
not core.check_player_privs(name, {basic_privs=true}) then
return false, "Your privileges are insufficient."
end
local revoke_name, revoke_priv_str = string.match(param, "([^ ]+) (.+)")
if not revoke_name or not revoke_priv_str then
local revokename, revokeprivstr = string.match(param, "([^ ]+) (.+)")
if not revokename or not revokeprivstr then
return false, "Invalid parameters (see /help revoke)"
elseif not core.get_auth_handler().get_auth(revoke_name) then
return false, "Player " .. revoke_name .. " does not exist."
end
local revoke_privs = core.string_to_privs(revoke_priv_str)
local privs = core.get_player_privs(revoke_name)
local basic_privs =
core.string_to_privs(core.settings:get("basic_privs") or "interact,shout")
for priv, _ in pairs(revoke_privs) do
if not basic_privs[priv] and
not core.check_player_privs(name, {privs=true}) then
return false, "Your privileges are insufficient."
end
end
if revoke_priv_str == "all" then
revoke_privs = privs
privs = {}
else
for priv, _ in pairs(revoke_privs) do
privs[priv] = nil
end
end
return handle_revoke_command(name, revokename, revokeprivstr)
end,
})
for priv, _ in pairs(revoke_privs) do
core.run_priv_callbacks(revoke_name, priv, name, "revoke")
core.register_chatcommand("revokeme", {
params = "<privilege> | all",
description = "Revoke privileges from yourself",
privs = {},
func = function(name, param)
if param == "" then
return false, "Invalid parameters (see /help revokeme)"
end
core.set_player_privs(revoke_name, privs)
core.log("action", name..' revoked ('
..core.privs_to_string(revoke_privs, ', ')
..') privileges from '..revoke_name)
if revoke_name ~= name then
core.chat_send_player(revoke_name, name
.. " revoked privileges from you: "
.. core.privs_to_string(revoke_privs, ' '))
end
return true, "Privileges of " .. revoke_name .. ": "
.. core.privs_to_string(
core.get_player_privs(revoke_name), ' ')
return handle_revoke_command(name, name, param)
end,
})
@@ -261,11 +322,12 @@ core.register_chatcommand("setpassword", {
toname = param:match("^([^ ]+) *$")
raw_password = nil
end
if not toname then
return false, "Name field required"
end
local act_str_past = "?"
local act_str_pres = "?"
local act_str_past, act_str_pres
if not raw_password then
core.set_player_password(toname, "")
act_str_past = "cleared"
@@ -277,13 +339,14 @@ core.register_chatcommand("setpassword", {
act_str_past = "set"
act_str_pres = "sets"
end
if toname ~= name then
core.chat_send_player(toname, "Your password was "
.. act_str_past .. " by " .. name)
end
core.log("action", name .. " " .. act_str_pres
.. " password of " .. toname .. ".")
core.log("action", name .. " " .. act_str_pres ..
" password of " .. toname .. ".")
return true, "Password of player \"" .. toname .. "\" " .. act_str_past
end,
@@ -367,36 +430,42 @@ core.register_chatcommand("teleport", {
return pos, false
end
local teleportee = nil
local p = {}
p.x, p.y, p.z = string.match(param, "^([%d.-]+)[, ] *([%d.-]+)[, ] *([%d.-]+)$")
p.x = tonumber(p.x)
p.y = tonumber(p.y)
p.z = tonumber(p.z)
if p.x and p.y and p.z then
local lm = 31000
if p.x < -lm or p.x > lm or p.y < -lm or p.y > lm or p.z < -lm or p.z > lm then
return false, "Cannot teleport out of map bounds!"
end
teleportee = core.get_player_by_name(name)
local teleportee = core.get_player_by_name(name)
if teleportee then
if teleportee:get_attach() then
return false, "Can't teleport, you're attached to an object!"
end
teleportee:set_pos(p)
return true, "Teleporting to "..core.pos_to_string(p)
end
end
local teleportee = nil
local p = nil
local target_name = nil
target_name = param:match("^([^ ]+)$")
teleportee = core.get_player_by_name(name)
local target_name = param:match("^([^ ]+)$")
local teleportee = core.get_player_by_name(name)
p = nil
if target_name then
local target = core.get_player_by_name(target_name)
if target then
p = target:get_pos()
end
end
if teleportee and p then
if teleportee:get_attach() then
return false, "Can't teleport, you're attached to an object!"
end
p = find_free_position_near(p)
teleportee:set_pos(p)
return true, "Teleporting to " .. target_name
@@ -407,9 +476,9 @@ core.register_chatcommand("teleport", {
return false, "You don't have permission to teleport other players (missing bring privilege)"
end
local teleportee = nil
local p = {}
local teleportee_name = nil
teleportee = nil
p = {}
local teleportee_name
teleportee_name, p.x, p.y, p.z = param:match(
"^([^ ]+) +([%d.-]+)[, ] *([%d.-]+)[, ] *([%d.-]+)$")
p.x, p.y, p.z = tonumber(p.x), tonumber(p.y), tonumber(p.z)
@@ -417,15 +486,16 @@ core.register_chatcommand("teleport", {
teleportee = core.get_player_by_name(teleportee_name)
end
if teleportee and p.x and p.y and p.z then
if teleportee:get_attach() then
return false, "Can't teleport, player is attached to an object!"
end
teleportee:set_pos(p)
return true, "Teleporting " .. teleportee_name
.. " to " .. core.pos_to_string(p)
end
local teleportee = nil
local p = nil
local teleportee_name = nil
local target_name = nil
teleportee = nil
p = nil
teleportee_name, target_name = string.match(param, "^([^ ]+) +([^ ]+)$")
if teleportee_name then
teleportee = core.get_player_by_name(teleportee_name)
@@ -437,6 +507,9 @@ core.register_chatcommand("teleport", {
end
end
if teleportee and p then
if teleportee:get_attach() then
return false, "Can't teleport, player is attached to an object!"
end
p = find_free_position_near(p)
teleportee:set_pos(p)
return true, "Teleporting " .. teleportee_name
@@ -459,7 +532,8 @@ core.register_chatcommand("set", {
core.settings:set(setname, setvalue)
return true, setname .. " = " .. setvalue
end
local setname, setvalue = string.match(param, "([^ ]+) (.+)")
setname, setvalue = string.match(param, "([^ ]+) (.+)")
if setname and setvalue then
if not core.settings:get(setname) then
return false, "Failed. Use '/set -n <name> <value>' to create a new setting."
@@ -467,14 +541,16 @@ core.register_chatcommand("set", {
core.settings:set(setname, setvalue)
return true, setname .. " = " .. setvalue
end
local setname = string.match(param, "([^ ]+)")
setname = string.match(param, "([^ ]+)")
if setname then
local setvalue = core.settings:get(setname)
setvalue = core.settings:get(setname)
if not setvalue then
setvalue = "<not set>"
end
return true, setname .. " = " .. setvalue
end
return false, "Invalid parameters (see /help set)."
end,
})
@@ -672,8 +748,9 @@ core.register_chatcommand("spawnentity", {
end
end
p.y = p.y + 1
core.add_entity(p, entityname)
return true, ("%q spawned."):format(entityname)
local obj = core.add_entity(p, entityname)
local msg = obj and "%q spawned." or "%q failed to spawn."
return true, msg:format(entityname)
end,
})
@@ -692,7 +769,7 @@ core.register_chatcommand("pulverize", {
end
core.log("action", name .. " pulverized \"" ..
wielded_item:get_name() .. " " .. wielded_item:get_count() .. "\"")
player:set_wielded_item(nil)
player:set_wielded_item(nil)
return true, "An item was pulverized."
end,
})
@@ -712,7 +789,7 @@ core.register_chatcommand("rollback_check", {
params = "[<range>] [<seconds>] [<limit>]",
description = "Check who last touched a node or a node near it"
.. " within the time specified by <seconds>. Default: range = 0,"
.. " seconds = 86400 = 24h, limit = 5",
.. " seconds = 86400 = 24h, limit = 5. Set <seconds> to inf for no time limit",
privs = {rollback=true},
func = function(name, param)
if not core.settings:get_bool("enable_rollback_recording") then
@@ -763,7 +840,7 @@ core.register_chatcommand("rollback_check", {
core.register_chatcommand("rollback", {
params = "(<name> [<seconds>]) | (:<actor> [<seconds>])",
description = "Revert actions of a player. Default for <seconds> is 60",
description = "Revert actions of a player. Default for <seconds> is 60. Set <seconds> to inf for no time limit",
privs = {rollback=true},
func = function(name, param)
if not core.settings:get_bool("enable_rollback_recording") then
@@ -771,7 +848,7 @@ core.register_chatcommand("rollback", {
end
local target_name, seconds = string.match(param, ":([^ ]+) *(%d*)")
if not target_name then
local player_name = nil
local player_name
player_name, seconds = string.match(param, "([^ ]+) *(%d*)")
if not player_name then
return false, "Invalid parameters. See /help rollback"
@@ -875,12 +952,13 @@ core.register_chatcommand("shutdown", {
core.chat_send_all("*** Server shutting down (operator request).")
end
core.request_shutdown(message:trim(), core.is_yes(reconnect), delay)
return true
end,
})
core.register_chatcommand("ban", {
params = "[<name> | <IP_address>]",
description = "Ban player or show ban list",
params = "[<name>]",
description = "Ban the IP of a player or show the ban list",
privs = {ban=true},
func = function(name, param)
if param == "" then
@@ -892,7 +970,7 @@ core.register_chatcommand("ban", {
end
end
if not core.get_player_by_name(param) then
return false, "No such player."
return false, "Player is not online."
end
if not core.ban_player(param) then
return false, "Failed to ban player."
@@ -905,7 +983,7 @@ core.register_chatcommand("ban", {
core.register_chatcommand("unban", {
params = "<name> | <IP_address>",
description = "Remove player ban",
description = "Remove IP ban belonging to a player/IP",
privs = {ban=true},
func = function(name, param)
if not core.unban_player_or_ip(param) then
@@ -951,18 +1029,19 @@ core.register_chatcommand("clearobjects", {
core.log("action", name .. " clears all objects ("
.. options.mode .. " mode).")
core.chat_send_all("Clearing all objects. This may take long."
.. " You may experience a timeout. (by "
core.chat_send_all("Clearing all objects. This may take a long time."
.. " You may experience a timeout. (by "
.. name .. ")")
core.clear_objects(options)
core.log("action", "Object clearing done.")
core.chat_send_all("*** Cleared all objects.")
return true
end,
})
core.register_chatcommand("msg", {
params = "<name> <message>",
description = "Send a private message",
description = "Send a direct message to a player",
privs = {shout=true},
func = function(name, param)
local sendto, message = param:match("^(%S+)%s(.+)$")
@@ -973,9 +1052,9 @@ core.register_chatcommand("msg", {
return false, "The player " .. sendto
.. " is not online."
end
core.log("action", "PM from " .. name .. " to " .. sendto
core.log("action", "DM from " .. name .. " to " .. sendto
.. ": " .. message)
core.chat_send_player(sendto, "PM from " .. name .. ": "
core.chat_send_player(sendto, "DM from " .. name .. ": "
.. message)
return true, "Message sent."
end,
@@ -989,7 +1068,7 @@ core.register_chatcommand("last-login", {
param = name
end
local pauth = core.get_auth_handler().get_auth(param)
if pauth and pauth.last_login then
if pauth and pauth.last_login and pauth.last_login ~= -1 then
-- Time in UTC, ISO 8601 format
return true, "Last login time was " ..
os.date("!%Y-%m-%dT%H:%M:%SZ", pauth.last_login)

View File

@@ -24,7 +24,7 @@ core.MAP_BLOCKSIZE = 16
-- Default maximal HP of a player
core.PLAYER_MAX_HP_DEFAULT = 20
-- Default maximal breath of a player
core.PLAYER_MAX_BREATH_DEFAULT = 11
core.PLAYER_MAX_BREATH_DEFAULT = 10
-- light.h
-- Maximum value for node 'light_source' parameter

View File

@@ -20,7 +20,7 @@ function core.node_metadata_inventory_move_allow_all()
end
function core.add_to_creative_inventory(itemstring)
core.log("deprecated", "core.add_to_creative_inventory: This function is deprecated and does nothing.")
core.log("deprecated", "core.add_to_creative_inventory is obsolete and does nothing.")
end
--
@@ -70,3 +70,19 @@ core.setting_get = setting_proxy("get")
core.setting_setbool = setting_proxy("set_bool")
core.setting_getbool = setting_proxy("get_bool")
core.setting_save = setting_proxy("write")
--
-- core.register_on_auth_fail
--
function core.register_on_auth_fail(func)
core.log("deprecated", "core.register_on_auth_fail " ..
"is obsolete and should be replaced by " ..
"core.register_on_authplayer instead.")
core.register_on_authplayer(function (player_name, ip, is_success)
if not is_success then
func(player_name, ip)
end
end)
end

View File

@@ -1,6 +1,36 @@
-- Minetest: builtin/item.lua
local builtin_shared = ...
local SCALE = 0.667
local facedir_to_euler = {
{y = 0, x = 0, z = 0},
{y = -math.pi/2, x = 0, z = 0},
{y = math.pi, x = 0, z = 0},
{y = math.pi/2, x = 0, z = 0},
{y = math.pi/2, x = -math.pi/2, z = math.pi/2},
{y = math.pi/2, x = math.pi, z = math.pi/2},
{y = math.pi/2, x = math.pi/2, z = math.pi/2},
{y = math.pi/2, x = 0, z = math.pi/2},
{y = -math.pi/2, x = math.pi/2, z = math.pi/2},
{y = -math.pi/2, x = 0, z = math.pi/2},
{y = -math.pi/2, x = -math.pi/2, z = math.pi/2},
{y = -math.pi/2, x = math.pi, z = math.pi/2},
{y = 0, x = 0, z = math.pi/2},
{y = 0, x = -math.pi/2, z = math.pi/2},
{y = 0, x = math.pi, z = math.pi/2},
{y = 0, x = math.pi/2, z = math.pi/2},
{y = math.pi, x = math.pi, z = math.pi/2},
{y = math.pi, x = math.pi/2, z = math.pi/2},
{y = math.pi, x = 0, z = math.pi/2},
{y = math.pi, x = -math.pi/2, z = math.pi/2},
{y = math.pi, x = math.pi, z = 0},
{y = -math.pi/2, x = math.pi, z = 0},
{y = 0, x = math.pi, z = 0},
{y = math.pi/2, x = math.pi, z = 0}
}
local gravity = tonumber(core.settings:get("movement_gravity")) or 9.81
--
-- Falling stuff
@@ -8,25 +38,156 @@ local builtin_shared = ...
core.register_entity(":__builtin:falling_node", {
initial_properties = {
visual = "wielditem",
visual_size = {x = 0.667, y = 0.667},
visual = "item",
visual_size = {x = SCALE, y = SCALE, z = SCALE},
textures = {},
physical = true,
is_visible = false,
collide_with_objects = false,
collide_with_objects = true,
collisionbox = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
},
node = {},
meta = {},
floats = false,
set_node = function(self, node, meta)
self.node = node
self.meta = meta or {}
self.object:set_properties({
is_visible = true,
textures = {node.name},
})
meta = meta or {}
if type(meta.to_table) == "function" then
meta = meta:to_table()
end
for _, list in pairs(meta.inventory or {}) do
for i, stack in pairs(list) do
if type(stack) == "userdata" then
list[i] = stack:to_string()
end
end
end
local def = core.registered_nodes[node.name]
if not def then
-- Don't allow unknown nodes to fall
core.log("info",
"Unknown falling node removed at "..
core.pos_to_string(self.object:get_pos()))
self.object:remove()
return
end
self.meta = meta
-- Cache whether we're supposed to float on water
self.floats = core.get_item_group(node.name, "float") ~= 0
-- Set entity visuals
if def.drawtype == "torchlike" or def.drawtype == "signlike" then
local textures
if def.tiles and def.tiles[1] then
local tile = def.tiles[1]
if type(tile) == "table" then
tile = tile.name
end
if def.drawtype == "torchlike" then
textures = { "("..tile..")^[transformFX", tile }
else
textures = { tile, "("..tile..")^[transformFX" }
end
end
local vsize
if def.visual_scale then
local s = def.visual_scale
vsize = {x = s, y = s, z = s}
end
self.object:set_properties({
is_visible = true,
visual = "upright_sprite",
visual_size = vsize,
textures = textures,
glow = def.light_source,
})
elseif def.drawtype ~= "airlike" then
local itemstring = node.name
if core.is_colored_paramtype(def.paramtype2) then
itemstring = core.itemstring_with_palette(itemstring, node.param2)
end
-- FIXME: solution needed for paramtype2 == "leveled"
local vsize
if def.visual_scale then
local s = def.visual_scale * SCALE
vsize = {x = s, y = s, z = s}
end
self.object:set_properties({
is_visible = true,
wield_item = itemstring,
visual_size = vsize,
glow = def.light_source,
})
end
-- Set collision box (certain nodeboxes only for now)
local nb_types = {fixed=true, leveled=true, connected=true}
if def.drawtype == "nodebox" and def.node_box and
nb_types[def.node_box.type] then
local box = table.copy(def.node_box.fixed)
if type(box[1]) == "table" then
box = #box == 1 and box[1] or nil -- We can only use a single box
end
if box then
if def.paramtype2 == "leveled" and (self.node.level or 0) > 0 then
box[5] = -0.5 + self.node.level / 64
end
self.object:set_properties({
collisionbox = box
})
end
end
-- Rotate entity
if def.drawtype == "torchlike" then
self.object:set_yaw(math.pi*0.25)
elseif (node.param2 ~= 0 and (def.wield_image == ""
or def.wield_image == nil))
or def.drawtype == "signlike"
or def.drawtype == "mesh"
or def.drawtype == "normal"
or def.drawtype == "nodebox" then
if (def.paramtype2 == "facedir" or def.paramtype2 == "colorfacedir") then
local fdir = node.param2 % 32
-- Get rotation from a precalculated lookup table
local euler = facedir_to_euler[fdir + 1]
if euler then
self.object:set_rotation(euler)
end
elseif (def.paramtype2 == "wallmounted" or def.paramtype2 == "colorwallmounted") then
local rot = node.param2 % 8
local pitch, yaw, roll = 0, 0, 0
if rot == 1 then
pitch, yaw = math.pi, math.pi
elseif rot == 2 then
pitch, yaw = math.pi/2, math.pi/2
elseif rot == 3 then
pitch, yaw = math.pi/2, -math.pi/2
elseif rot == 4 then
pitch, yaw = math.pi/2, math.pi
elseif rot == 5 then
pitch, yaw = math.pi/2, 0
end
if def.drawtype == "signlike" then
pitch = pitch - math.pi/2
if rot == 0 then
yaw = yaw + math.pi/2
elseif rot == 1 then
yaw = yaw - math.pi/2
end
elseif def.drawtype == "mesh" or def.drawtype == "normal" then
if rot >= 0 and rot <= 1 then
roll = roll + math.pi
else
yaw = yaw + math.pi
end
end
self.object:set_rotation({x=pitch, y=yaw, z=roll})
end
end
end,
get_staticdata = function(self)
@@ -39,6 +200,7 @@ core.register_entity(":__builtin:falling_node", {
on_activate = function(self, staticdata)
self.object:set_armor_groups({immortal = 1})
self.object:set_acceleration({x = 0, y = -gravity, z = 0})
local ds = core.deserialize(staticdata)
if ds and ds.node then
@@ -50,85 +212,159 @@ core.register_entity(":__builtin:falling_node", {
end
end,
on_step = function(self, dtime)
-- Set gravity
local acceleration = self.object:get_acceleration()
if not vector.equals(acceleration, {x = 0, y = -10, z = 0}) then
self.object:set_acceleration({x = 0, y = -10, z = 0})
try_place = function(self, bcp, bcn)
local bcd = core.registered_nodes[bcn.name]
-- Add levels if dropped on same leveled node
if bcd and bcd.paramtype2 == "leveled" and
bcn.name == self.node.name then
local addlevel = self.node.level
if (addlevel or 0) <= 0 then
addlevel = bcd.leveled
end
if core.add_node_level(bcp, addlevel) < addlevel then
return true
elseif bcd.buildable_to then
-- Node level has already reached max, don't place anything
return true
end
end
-- Turn to actual node when colliding with ground, or continue to move
local pos = self.object:get_pos()
-- Position of bottom center point
local bcp = {x = pos.x, y = pos.y - 0.7, z = pos.z}
-- 'bcn' is nil for unloaded nodes
local bcn = core.get_node_or_nil(bcp)
-- Delete on contact with ignore at world edges
if bcn and bcn.name == "ignore" then
self.object:remove()
return
-- Decide if we're replacing the node or placing on top
local np = vector.new(bcp)
if bcd and bcd.buildable_to and
(not self.floats or bcd.liquidtype == "none") then
core.remove_node(bcp)
else
np.y = np.y + 1
end
local bcd = bcn and core.registered_nodes[bcn.name]
if bcn and
(not bcd or bcd.walkable or
(core.get_item_group(self.node.name, "float") ~= 0 and
bcd.liquidtype ~= "none")) then
if bcd and bcd.leveled and
bcn.name == self.node.name then
local addlevel = self.node.level
if not addlevel or addlevel <= 0 then
addlevel = bcd.leveled
-- Check what's here
local n2 = core.get_node(np)
local nd = core.registered_nodes[n2.name]
-- If it's not air or liquid, remove node and replace it with
-- it's drops
if n2.name ~= "air" and (not nd or nd.liquidtype == "none") then
if nd and nd.buildable_to == false then
nd.on_dig(np, n2, nil)
-- If it's still there, it might be protected
if core.get_node(np).name == n2.name then
return false
end
if core.add_node_level(bcp, addlevel) == 0 then
else
core.remove_node(np)
end
end
-- Create node
local def = core.registered_nodes[self.node.name]
if def then
core.add_node(np, self.node)
if self.meta then
core.get_meta(np):from_table(self.meta)
end
if def.sounds and def.sounds.place then
core.sound_play(def.sounds.place, {pos = np}, true)
end
end
core.check_for_falling(np)
return true
end,
on_step = function(self, dtime, moveresult)
-- Fallback code since collision detection can't tell us
-- about liquids (which do not collide)
if self.floats then
local pos = self.object:get_pos()
local bcp = vector.round({x = pos.x, y = pos.y - 0.7, z = pos.z})
local bcn = core.get_node(bcp)
local bcd = core.registered_nodes[bcn.name]
if bcd and bcd.liquidtype ~= "none" then
if self:try_place(bcp, bcn) then
self.object:remove()
return
end
elseif bcd and bcd.buildable_to and
(core.get_item_group(self.node.name, "float") == 0 or
bcd.liquidtype == "none") then
core.remove_node(bcp)
return
end
local np = {x = bcp.x, y = bcp.y + 1, z = bcp.z}
-- Check what's here
local n2 = core.get_node(np)
local nd = core.registered_nodes[n2.name]
-- If it's not air or liquid, remove node and replace it with
-- it's drops
if n2.name ~= "air" and (not nd or nd.liquidtype == "none") then
core.remove_node(np)
if nd and nd.buildable_to == false then
-- Add dropped items
local drops = core.get_node_drops(n2, "")
for _, dropped_item in pairs(drops) do
core.add_item(np, dropped_item)
end
assert(moveresult)
if not moveresult.collides then
return -- Nothing to do :)
end
local bcp, bcn
local player_collision
if moveresult.touching_ground then
for _, info in ipairs(moveresult.collisions) do
if info.type == "object" then
if info.axis == "y" and info.object:is_player() then
player_collision = info
end
end
-- Run script hook
for _, callback in pairs(core.registered_on_dignodes) do
callback(np, n2)
elseif info.axis == "y" then
bcp = info.node_pos
bcn = core.get_node(bcp)
break
end
end
-- Create node and remove entity
local def = core.registered_nodes[self.node.name]
if def then
core.add_node(np, self.node)
if self.meta then
local meta = core.get_meta(np)
meta:from_table(self.meta)
end
if def.sounds and def.sounds.place and def.sounds.place.name then
core.sound_play(def.sounds.place, {pos = np})
end
end
if not bcp then
-- We're colliding with something, but not the ground. Irrelevant to us.
if player_collision then
-- Continue falling through players by moving a little into
-- their collision box
-- TODO: this hack could be avoided in the future if objects
-- could choose who to collide with
local vel = self.object:get_velocity()
self.object:set_velocity({
x = vel.x,
y = player_collision.old_velocity.y,
z = vel.z
})
self.object:set_pos(vector.add(self.object:get_pos(),
{x = 0, y = -0.5, z = 0}))
end
return
elseif bcn.name == "ignore" then
-- Delete on contact with ignore at world edges
self.object:remove()
core.check_for_falling(np)
return
end
local vel = self.object:get_velocity()
if vector.equals(vel, {x = 0, y = 0, z = 0}) then
local npos = self.object:get_pos()
self.object:set_pos(vector.round(npos))
local failure = false
local pos = self.object:get_pos()
local distance = vector.apply(vector.subtract(pos, bcp), math.abs)
if distance.x >= 1 or distance.z >= 1 then
-- We're colliding with some part of a node that's sticking out
-- Since we don't want to visually teleport, drop as item
failure = true
elseif distance.y >= 2 then
-- Doors consist of a hidden top node and a bottom node that is
-- the actual door. Despite the top node being solid, the moveresult
-- almost always indicates collision with the bottom node.
-- Compensate for this by checking the top node
bcp.y = bcp.y + 1
bcn = core.get_node(bcp)
local def = core.registered_nodes[bcn.name]
if not (def and def.walkable) then
failure = true -- This is unexpected, fail
end
end
-- Try to actually place ourselves
if not failure then
failure = not self:try_place(bcp, bcn)
end
if failure then
local drops = core.get_node_drops(self.node, "")
for _, item in pairs(drops) do
core.add_item(pos, item)
end
end
self.object:remove()
end
})
@@ -137,10 +373,16 @@ local function convert_to_falling_node(pos, node)
if not obj then
return false
end
-- remember node level, the entities' set_node() uses this
node.level = core.get_node_level(pos)
local meta = core.get_meta(pos)
local metatable = meta and meta:to_table() or {}
local def = core.registered_nodes[node.name]
if def and def.sounds and def.sounds.fall then
core.sound_play(def.sounds.fall, {pos = pos}, true)
end
obj:get_luaentity():set_node(node, metatable)
core.remove_node(pos)
return true
@@ -170,6 +412,9 @@ local function drop_attached_node(p)
drops = drop_stacks
def.preserve_metadata(pos_copy, node_copy, oldmeta, drops)
end
if def and def.sounds and def.sounds.fall then
core.sound_play(def.sounds.fall, {pos = p}, true)
end
core.remove_node(p)
for _, item in pairs(drops) do
local pos = {
@@ -214,18 +459,23 @@ function core.check_single_for_falling(p)
-- Only spawn falling node if node below is loaded
local n_bottom = core.get_node_or_nil(p_bottom)
local d_bottom = n_bottom and core.registered_nodes[n_bottom.name]
if d_bottom and
(core.get_item_group(n.name, "float") == 0 or
d_bottom.liquidtype == "none") and
(n.name ~= n_bottom.name or (d_bottom.leveled and
core.get_node_level(p_bottom) <
core.get_node_max_level(p_bottom))) and
(not d_bottom.walkable or d_bottom.buildable_to) then
convert_to_falling_node(p, n)
return true
if d_bottom then
local same = n.name == n_bottom.name
-- Let leveled nodes fall if it can merge with the bottom node
if same and d_bottom.paramtype2 == "leveled" and
core.get_node_level(p_bottom) <
core.get_node_max_level(p_bottom) then
convert_to_falling_node(p, n)
return true
end
-- Otherwise only if the bottom node is considered "fall through"
if not same and
(not d_bottom.walkable or d_bottom.buildable_to) and
(core.get_item_group(n.name, "float") == 0 or
d_bottom.liquidtype == "none") then
convert_to_falling_node(p, n)
return true
end
end
end

View File

@@ -12,6 +12,11 @@ core.features = {
no_chat_message_prediction = true,
object_use_texture_alpha = true,
object_independent_selectionbox = true,
httpfetch_binary_data = true,
formspec_version_element = true,
area_store_persistent_ids = true,
pathfinder_works = true,
object_step_has_moveresult = true,
}
function core.has_feature(arg)

View File

@@ -8,6 +8,9 @@ local blocks_forceloaded
local blocks_temploaded = {}
local total_forceloaded = 0
-- true, if the forceloaded blocks got changed (flag for persistence on-disk)
local forceload_blocks_changed = false
local BLOCKSIZE = core.MAP_BLOCKSIZE
local function get_blockpos(pos)
return {
@@ -31,6 +34,9 @@ local function get_relevant_tables(transient)
end
function core.forceload_block(pos, transient)
-- set changed flag
forceload_blocks_changed = true
local blockpos = get_blockpos(pos)
local hash = core.hash_node_position(blockpos)
local relevant_table, other_table = get_relevant_tables(transient)
@@ -51,6 +57,9 @@ function core.forceload_block(pos, transient)
end
function core.forceload_free_block(pos, transient)
-- set changed flag
forceload_blocks_changed = true
local blockpos = get_blockpos(pos)
local hash = core.hash_node_position(blockpos)
local relevant_table, other_table = get_relevant_tables(transient)
@@ -95,6 +104,28 @@ core.after(5, function()
end
end)
core.register_on_shutdown(function()
-- persists the currently forceloaded blocks to disk
local function persist_forceloaded_blocks()
write_file(wpath.."/force_loaded.txt", blocks_forceloaded)
end)
end
-- periodical forceload persistence
local function periodically_persist_forceloaded_blocks()
-- only persist if the blocks actually changed
if forceload_blocks_changed then
persist_forceloaded_blocks()
-- reset changed flag
forceload_blocks_changed = false
end
-- recheck after some time
core.after(10, periodically_persist_forceloaded_blocks)
end
-- persist periodically
core.after(5, periodically_persist_forceloaded_blocks)
-- persist on shutdown
core.register_on_shutdown(persist_forceloaded_blocks)

View File

@@ -1,36 +1,38 @@
local scriptpath = core.get_builtin_path()
local commonpath = scriptpath.."common"..DIR_DELIM
local gamepath = scriptpath.."game"..DIR_DELIM
local commonpath = scriptpath .. "common" .. DIR_DELIM
local gamepath = scriptpath .. "game".. DIR_DELIM
-- Shared between builtin files, but
-- not exposed to outer context
local builtin_shared = {}
dofile(commonpath.."vector.lua")
dofile(commonpath .. "vector.lua")
dofile(gamepath.."constants.lua")
assert(loadfile(gamepath.."item.lua"))(builtin_shared)
dofile(gamepath.."register.lua")
dofile(gamepath .. "constants.lua")
assert(loadfile(gamepath .. "item.lua"))(builtin_shared)
dofile(gamepath .. "register.lua")
if core.settings:get_bool("profiler.load") then
profiler = dofile(scriptpath.."profiler"..DIR_DELIM.."init.lua")
profiler = dofile(scriptpath .. "profiler" .. DIR_DELIM .. "init.lua")
end
dofile(commonpath .. "after.lua")
dofile(gamepath.."item_entity.lua")
dofile(gamepath.."deprecated.lua")
dofile(gamepath.."misc.lua")
dofile(gamepath.."privileges.lua")
dofile(gamepath.."auth.lua")
dofile(gamepath .. "item_entity.lua")
dofile(gamepath .. "deprecated.lua")
dofile(gamepath .. "misc.lua")
dofile(gamepath .. "privileges.lua")
dofile(gamepath .. "auth.lua")
dofile(commonpath .. "chatcommands.lua")
dofile(gamepath.."chatcommands.lua")
dofile(gamepath.."static_spawn.lua")
dofile(gamepath.."detached_inventory.lua")
assert(loadfile(gamepath.."falling.lua"))(builtin_shared)
dofile(gamepath.."features.lua")
dofile(gamepath.."voxelarea.lua")
dofile(gamepath.."forceloading.lua")
dofile(gamepath.."statbars.lua")
dofile(gamepath .. "chat.lua")
dofile(commonpath .. "information_formspecs.lua")
dofile(gamepath .. "static_spawn.lua")
dofile(gamepath .. "detached_inventory.lua")
assert(loadfile(gamepath .. "falling.lua"))(builtin_shared)
dofile(gamepath .. "features.lua")
dofile(gamepath .. "voxelarea.lua")
dofile(gamepath .. "forceloading.lua")
dofile(gamepath .. "statbars.lua")
dofile(gamepath .. "knockback.lua")
profiler = nil

View File

@@ -206,7 +206,6 @@ function core.get_node_drops(node, toolname)
-- Extended drop table
local got_items = {}
local got_count = 0
local _, item, tool
for _, item in ipairs(drop.items) do
local good_rarity = true
local good_tool = true
@@ -251,11 +250,6 @@ local function user_name(user)
return user and user:get_player_name() or ""
end
local function is_protected(pos, name)
return core.is_protected(pos, name) and
not minetest.check_player_privs(name, "protection_bypass")
end
-- Returns a logging function. For empty names, does not log.
local function make_log(name)
return name ~= "" and core.log or function() end
@@ -265,7 +259,7 @@ function core.item_place_node(itemstack, placer, pointed_thing, param2,
prevent_after_place)
local def = itemstack:get_definition()
if def.type ~= "node" or pointed_thing.type ~= "node" then
return itemstack, false
return itemstack, nil
end
local under = pointed_thing.under
@@ -278,7 +272,7 @@ function core.item_place_node(itemstack, placer, pointed_thing, param2,
if not oldnode_under or not oldnode_above then
log("info", playername .. " tried to place"
.. " node in unloaded position " .. core.pos_to_string(above))
return itemstack, false
return itemstack, nil
end
local olddef_under = core.registered_nodes[oldnode_under.name]
@@ -290,7 +284,7 @@ function core.item_place_node(itemstack, placer, pointed_thing, param2,
log("info", playername .. " tried to place"
.. " node in invalid position " .. core.pos_to_string(above)
.. ", replacing " .. oldnode_above.name)
return itemstack, false
return itemstack, nil
end
-- Place above pointed node
@@ -302,18 +296,15 @@ function core.item_place_node(itemstack, placer, pointed_thing, param2,
place_to = {x = under.x, y = under.y, z = under.z}
end
if is_protected(place_to, playername) then
if core.is_protected(place_to, playername) then
log("action", playername
.. " tried to place " .. def.name
.. " at protected position "
.. core.pos_to_string(place_to))
core.record_protection_violation(place_to, playername)
return itemstack
return itemstack, nil
end
log("action", playername .. " places node "
.. def.name .. " at " .. core.pos_to_string(place_to))
local oldnode = core.get_node(place_to)
local newnode = {name = def.name, param1 = 0, param2 = param2 or 0}
@@ -339,7 +330,7 @@ function core.item_place_node(itemstack, placer, pointed_thing, param2,
z = above.z - placer_pos.z
}
newnode.param2 = core.dir_to_facedir(dir)
log("action", "facedir: " .. newnode.param2)
log("info", "facedir: " .. newnode.param2)
end
end
@@ -367,12 +358,23 @@ function core.item_place_node(itemstack, placer, pointed_thing, param2,
not builtin_shared.check_attached_node(place_to, newnode) then
log("action", "attached node " .. def.name ..
" can not be placed at " .. core.pos_to_string(place_to))
return itemstack, false
return itemstack, nil
end
log("action", playername .. " places node "
.. def.name .. " at " .. core.pos_to_string(place_to))
-- Add node and update
core.add_node(place_to, newnode)
-- Play sound if it was done by a player
if playername ~= "" and def.sounds and def.sounds.place then
core.sound_play(def.sounds.place, {
pos = place_to,
exclude_player = playername,
}, true)
end
local take_item = true
-- Run callback
@@ -401,9 +403,10 @@ function core.item_place_node(itemstack, placer, pointed_thing, param2,
if take_item then
itemstack:take_item()
end
return itemstack, true
return itemstack, place_to
end
-- deprecated, item_place does not call this
function core.item_place_object(itemstack, placer, pointed_thing)
local pos = core.get_pointed_thing_position(pointed_thing, true)
if pos ~= nil then
@@ -421,14 +424,15 @@ function core.item_place(itemstack, placer, pointed_thing, param2)
local nn = n.name
if core.registered_nodes[nn] and core.registered_nodes[nn].on_rightclick then
return core.registered_nodes[nn].on_rightclick(pointed_thing.under, n,
placer, itemstack, pointed_thing) or itemstack, false
placer, itemstack, pointed_thing) or itemstack, nil
end
end
-- Place if node, otherwise do nothing
if itemstack:get_definition().type == "node" then
return core.item_place_node(itemstack, placer, pointed_thing, param2)
end
return itemstack
return itemstack, nil
end
function core.item_secondary_use(itemstack, placer)
@@ -466,12 +470,15 @@ function core.do_item_eat(hp_change, replace_with_item, itemstack, user, pointed
return result
end
end
local def = itemstack:get_definition()
if itemstack:take_item() ~= nil then
user:set_hp(user:get_hp() + hp_change)
local def = itemstack:get_definition()
if def and def.sound and def.sound.eat then
minetest.sound_play(def.sound.eat, { pos = user:get_pos(), max_hear_distance = 16 })
core.sound_play(def.sound.eat, {
pos = user:get_pos(),
max_hear_distance = 16
}, true)
end
if replace_with_item then
@@ -552,7 +559,7 @@ function core.node_dig(pos, node, digger)
return
end
if is_protected(pos, diggername) then
if core.is_protected(pos, diggername) then
log("action", diggername
.. " tried to dig " .. node.name
.. " at protected position "
@@ -575,10 +582,13 @@ function core.node_dig(pos, node, digger)
wielded = wdef.after_use(wielded, digger, node, dp) or wielded
else
-- Wear out tool
if not core.settings:get_bool("creative_mode") then
if not core.is_creative_enabled(diggername) then
wielded:add_wear(dp.wear)
if wielded:get_count() == 0 and wdef.sound and wdef.sound.breaks then
core.sound_play(wdef.sound.breaks, {pos = pos, gain = 0.5})
core.sound_play(wdef.sound.breaks, {
pos = pos,
gain = 0.5
}, true)
end
end
end
@@ -610,6 +620,14 @@ function core.node_dig(pos, node, digger)
-- Remove node and update
core.remove_node(pos)
-- Play sound if it was done by a player
if diggername ~= "" and def and def.sounds and def.sounds.dug then
core.sound_play(def.sounds.dug, {
pos = pos,
exclude_player = diggername,
}, true)
end
-- Run callback
if def and def.after_dig_node then
-- Copy pos and node because callback can modify them
@@ -619,15 +637,10 @@ function core.node_dig(pos, node, digger)
end
-- Run script hook
local _, callback
for _, callback in ipairs(core.registered_on_dignodes) do
local origin = core.callback_origins[callback]
if origin then
core.set_last_run_mod(origin.mod)
--print("Running " .. tostring(callback) ..
-- " (a " .. origin.name .. " callback in " .. origin.mod .. ")")
else
--print("No data associated with callback")
end
-- Copy pos and node because callback can modify them
@@ -662,6 +675,8 @@ end
-- Item definition defaults
--
local default_stack_max = tonumber(minetest.settings:get("default_stack_max")) or 99
core.nodedef_default = {
-- Item properties
type="node",
@@ -671,7 +686,7 @@ core.nodedef_default = {
inventory_image = "",
wield_image = "",
wield_scale = {x=1,y=1,z=1},
stack_max = 99,
stack_max = default_stack_max,
usable = false,
liquids_pointable = false,
tool_capabilities = nil,
@@ -735,7 +750,7 @@ core.craftitemdef_default = {
inventory_image = "",
wield_image = "",
wield_scale = {x=1,y=1,z=1},
stack_max = 99,
stack_max = default_stack_max,
liquids_pointable = false,
tool_capabilities = nil,
@@ -773,7 +788,7 @@ core.noneitemdef_default = { -- This is used for the hand and unknown items
inventory_image = "",
wield_image = "",
wield_scale = {x=1,y=1,z=1},
stack_max = 99,
stack_max = default_stack_max,
liquids_pointable = false,
tool_capabilities = nil,

View File

@@ -27,15 +27,17 @@ core.register_entity(":__builtin:item", {
visual = "wielditem",
visual_size = {x = 0.4, y = 0.4},
textures = {""},
spritediv = {x = 1, y = 1},
initial_sprite_basepos = {x = 0, y = 0},
is_visible = false,
},
itemstring = "",
moving_state = true,
slippery_state = false,
physical_state = true,
-- Item expiry
age = 0,
-- Pushing item out of solid nodes
force_out = nil,
force_out_start = nil,
set_item = function(self, item)
local stack = ItemStack(item or self.itemstring)
@@ -52,18 +54,18 @@ core.register_entity(":__builtin:item", {
local max_count = stack:get_stack_max()
local count = math.min(stack:get_count(), max_count)
local size = 0.2 + 0.1 * (count / max_count) ^ (1 / 3)
local coll_height = size * 0.75
local def = core.registered_nodes[itemname]
local glow = def and math.floor(def.light_source / 2 + 0.5)
self.object:set_properties({
is_visible = true,
visual = "wielditem",
textures = {itemname},
visual_size = {x = size, y = size},
collisionbox = {-size, -coll_height, -size,
size, coll_height, size},
selectionbox = {-size, -size, -size, size, size, size},
collisionbox = {-size, -size, -size, size, size, size},
automatic_rotate = math.pi * 0.5 * 0.2 / size,
wield_item = self.itemstring,
glow = glow,
})
end,
@@ -131,7 +133,25 @@ core.register_entity(":__builtin:item", {
return true
end,
on_step = function(self, dtime)
enable_physics = function(self)
if not self.physical_state then
self.physical_state = true
self.object:set_properties({physical = true})
self.object:set_velocity({x=0, y=0, z=0})
self.object:set_acceleration({x=0, y=-gravity, z=0})
end
end,
disable_physics = function(self)
if self.physical_state then
self.physical_state = false
self.object:set_properties({physical = false})
self.object:set_velocity({x=0, y=0, z=0})
self.object:set_acceleration({x=0, y=0, z=0})
end
end,
on_step = function(self, dtime, moveresult)
self.age = self.age + dtime
if time_to_live > 0 and self.age > time_to_live then
self.itemstring = ""
@@ -152,46 +172,125 @@ core.register_entity(":__builtin:item", {
return
end
local vel = self.object:get_velocity()
local def = node and core.registered_nodes[node.name]
local is_moving = (def and not def.walkable) or
vel.x ~= 0 or vel.y ~= 0 or vel.z ~= 0
local is_slippery = false
if def and def.walkable then
local slippery = core.get_item_group(node.name, "slippery")
is_slippery = slippery ~= 0
if is_slippery and (math.abs(vel.x) > 0.2 or math.abs(vel.z) > 0.2) then
-- Horizontal deceleration
local slip_factor = 4.0 / (slippery + 4)
self.object:set_acceleration({
x = -vel.x * slip_factor,
y = 0,
z = -vel.z * slip_factor
})
elseif vel.y == 0 then
is_moving = false
if self.force_out then
-- This code runs after the entity got a push from the is_stuck code.
-- It makes sure the entity is entirely outside the solid node
local c = self.object:get_properties().collisionbox
local s = self.force_out_start
local f = self.force_out
local ok = (f.x > 0 and pos.x + c[1] > s.x + 0.5) or
(f.y > 0 and pos.y + c[2] > s.y + 0.5) or
(f.z > 0 and pos.z + c[3] > s.z + 0.5) or
(f.x < 0 and pos.x + c[4] < s.x - 0.5) or
(f.z < 0 and pos.z + c[6] < s.z - 0.5)
if ok then
-- Item was successfully forced out
self.force_out = nil
self:enable_physics()
return
end
end
if self.moving_state == is_moving and
self.slippery_state == is_slippery then
-- Do not update anything until the moving state changes
if not self.physical_state then
return -- Don't do anything
end
assert(moveresult,
"Collision info missing, this is caused by an out-of-date/buggy mod or game")
if not moveresult.collides then
-- future TODO: items should probably decelerate in air
return
end
self.moving_state = is_moving
self.slippery_state = is_slippery
if is_moving then
self.object:set_acceleration({x = 0, y = -gravity, z = 0})
else
self.object:set_acceleration({x = 0, y = 0, z = 0})
self.object:set_velocity({x = 0, y = 0, z = 0})
-- Push item out when stuck inside solid node
local is_stuck = false
local snode = core.get_node_or_nil(pos)
if snode then
local sdef = core.registered_nodes[snode.name] or {}
is_stuck = (sdef.walkable == nil or sdef.walkable == true)
and (sdef.collision_box == nil or sdef.collision_box.type == "regular")
and (sdef.node_box == nil or sdef.node_box.type == "regular")
end
--Only collect items if not moving
if is_moving then
if is_stuck then
local shootdir
local order = {
{x=1, y=0, z=0}, {x=-1, y=0, z= 0},
{x=0, y=0, z=1}, {x= 0, y=0, z=-1},
}
-- Check which one of the 4 sides is free
for o = 1, #order do
local cnode = core.get_node(vector.add(pos, order[o])).name
local cdef = core.registered_nodes[cnode] or {}
if cnode ~= "ignore" and cdef.walkable == false then
shootdir = order[o]
break
end
end
-- If none of the 4 sides is free, check upwards
if not shootdir then
shootdir = {x=0, y=1, z=0}
local cnode = core.get_node(vector.add(pos, shootdir)).name
if cnode == "ignore" then
shootdir = nil -- Do not push into ignore
end
end
if shootdir then
-- Set new item moving speed accordingly
local newv = vector.multiply(shootdir, 3)
self:disable_physics()
self.object:set_velocity(newv)
self.force_out = newv
self.force_out_start = vector.round(pos)
return
end
end
node = nil -- ground node we're colliding with
if moveresult.touching_ground then
for _, info in ipairs(moveresult.collisions) do
if info.axis == "y" then
node = core.get_node(info.node_pos)
break
end
end
end
-- Slide on slippery nodes
local def = node and core.registered_nodes[node.name]
local keep_movement = false
if def then
local slippery = core.get_item_group(node.name, "slippery")
local vel = self.object:get_velocity()
if slippery ~= 0 and (math.abs(vel.x) > 0.1 or math.abs(vel.z) > 0.1) then
-- Horizontal deceleration
local factor = math.min(4 / (slippery + 4) * dtime, 1)
self.object:set_velocity({
x = vel.x * (1 - factor),
y = 0,
z = vel.z * (1 - factor)
})
keep_movement = true
end
end
if not keep_movement then
self.object:set_velocity({x=0, y=0, z=0})
end
if self.moving_state == keep_movement then
-- Do not update anything until the moving state changes
return
end
self.moving_state = keep_movement
-- Only collect items if not moving
if self.moving_state then
return
end
-- Collect the items around to merge with

View File

@@ -0,0 +1,46 @@
-- can be overriden by mods
function core.calculate_knockback(player, hitter, time_from_last_punch, tool_capabilities, dir, distance, damage)
if damage == 0 or player:get_armor_groups().immortal then
return 0.0
end
local m = 8
-- solve m - m*e^(k*4) = 4 for k
local k = -0.17328
local res = m - m * math.exp(k * damage)
if distance < 2.0 then
res = res * 1.1 -- more knockback when closer
elseif distance > 4.0 then
res = res * 0.9 -- less when far away
end
return res
end
local function vector_absmax(v)
local max, abs = math.max, math.abs
return max(max(abs(v.x), abs(v.y)), abs(v.z))
end
core.register_on_punchplayer(function(player, hitter, time_from_last_punch, tool_capabilities, unused_dir, damage)
if player:get_hp() == 0 then
return -- RIP
end
-- Server::handleCommand_Interact() adds eye offset to one but not the other
-- so the direction is slightly off, calculate it ourselves
local dir = vector.subtract(player:get_pos(), hitter:get_pos())
local d = vector.length(dir)
if d ~= 0.0 then
dir = vector.divide(dir, d)
end
local k = core.calculate_knockback(player, hitter, time_from_last_punch, tool_capabilities, dir, d, damage)
local kdir = vector.multiply(dir, k)
if vector_absmax(kdir) < 1.0 then
return -- barely noticeable, so don't even send
end
player:add_player_velocity(kdir)
end)

View File

@@ -40,9 +40,6 @@ function core.check_player_privs(name, ...)
end
local player_list = {}
function core.send_join_message(player_name)
if not core.is_singleplayer() then
core.chat_send_all("*** " .. player_name .. " joined the game.")
@@ -61,8 +58,7 @@ end
core.register_on_joinplayer(function(player)
local player_name = player:get_player_name()
player_list[player_name] = player
if not minetest.is_singleplayer() then
if not core.is_singleplayer() then
local status = core.get_server_status(player_name, true)
if status and status ~= "" then
core.chat_send_player(player_name, status)
@@ -74,22 +70,10 @@ end)
core.register_on_leaveplayer(function(player, timed_out)
local player_name = player:get_player_name()
player_list[player_name] = nil
core.send_leave_message(player_name, timed_out)
end)
function core.get_connected_players()
local temp_table = {}
for index, value in pairs(player_list) do
if value:is_player_connected() then
temp_table[#temp_table + 1] = value
end
end
return temp_table
end
function core.is_player(player)
-- a table being a player is also supported because it quacks sufficiently
-- like a player if it has the is_player function
@@ -180,6 +164,12 @@ function core.record_protection_violation(pos, name)
end
end
-- To be overridden by Creative mods
local creative_mode_cache = core.settings:get_bool("creative_mode")
function core.is_creative_enabled(name)
return creative_mode_cache
end
-- Checks if specified volume intersects a protected volume

View File

@@ -18,7 +18,7 @@ function core.register_privilege(name, param)
def.description = "(no description)"
end
end
local def = {}
local def
if type(param) == "table" then
def = param
else

View File

@@ -79,6 +79,7 @@ end
function core.register_abm(spec)
-- Add to core.registered_abms
assert(type(spec.action) == "function", "Required field 'action' of type function")
core.registered_abms[#core.registered_abms + 1] = spec
spec.mod_origin = core.get_current_modname() or "??"
end
@@ -86,6 +87,7 @@ end
function core.register_lbm(spec)
-- Add to core.registered_lbms
check_modname_prefix(spec.name)
assert(type(spec.action) == "function", "Required field 'action' of type function")
core.registered_lbms[#core.registered_lbms + 1] = spec
spec.mod_origin = core.get_current_modname() or "??"
end
@@ -254,6 +256,18 @@ function core.register_tool(name, tooldef)
end
-- END Legacy stuff
-- This isn't just legacy, but more of a convenience feature
local toolcaps = tooldef.tool_capabilities
if toolcaps and toolcaps.punch_attack_uses == nil then
for _, cap in pairs(toolcaps.groupcaps or {}) do
local level = (cap.maxlevel or 0) - 1
if (cap.uses or 0) ~= 0 and level >= 0 then
toolcaps.punch_attack_uses = cap.uses * (3 ^ level)
break
end
end
end
core.register_item(name, tooldef)
end
@@ -301,18 +315,17 @@ end
-- Alias the forbidden item names to "" so they can't be
-- created via itemstrings (e.g. /give)
local name
for name in pairs(forbidden_item_names) do
core.registered_aliases[name] = ""
register_alias_raw(name, "")
end
-- Deprecated:
-- Obsolete:
-- Aliases for core.register_alias (how ironic...)
--core.alias_node = core.register_alias
--core.alias_tool = core.register_alias
--core.alias_craftitem = core.register_alias
-- core.alias_node = core.register_alias
-- core.alias_tool = core.register_alias
-- core.alias_craftitem = core.register_alias
--
-- Built-in node definitions. Also defined in C.
@@ -361,9 +374,9 @@ core.register_node(":ignore", {
drop = "",
groups = {not_in_creative_inventory=1},
on_place = function(itemstack, placer, pointed_thing)
minetest.chat_send_player(
core.chat_send_player(
placer:get_player_name(),
minetest.colorize("#FF0000",
core.colorize("#FF0000",
"You can't place 'ignore' nodes!"))
return ""
end,
@@ -372,6 +385,7 @@ core.register_node(":ignore", {
-- The hand (bare definition)
core.register_item(":", {
type = "none",
wield_image = "wieldhand.png",
groups = {not_in_creative_inventory=1},
})
@@ -411,10 +425,6 @@ function core.run_callbacks(callbacks, mode, ...)
local origin = core.callback_origins[callbacks[i]]
if origin then
core.set_last_run_mod(origin.mod)
--print("Running " .. tostring(callbacks[i]) ..
-- " (a " .. origin.name .. " callback in " .. origin.mod .. ")")
else
--print("No data associated with callback")
end
local cb_ret = callbacks[i](...)
@@ -514,11 +524,17 @@ local function make_registration_wrap(reg_fn_name, clear_fn_name)
end
local function make_wrap_deregistration(reg_fn, clear_fn, list)
local unregister = function (unregistered_key)
local unregister = function (key)
if type(key) ~= "string" then
error("key is not a string", 2)
end
if not list[key] then
error("Attempt to unregister non-existent element - '" .. key .. "'", 2)
end
local temporary_list = table.copy(list)
clear_fn()
for k,v in pairs(temporary_list) do
if unregistered_key ~= k then
if key ~= k then
reg_fn(v)
end
end
@@ -529,7 +545,7 @@ end
core.registered_on_player_hpchanges = { modifiers = { }, loggers = { } }
function core.registered_on_player_hpchange(player, hp_change, reason)
local last = false
local last
for i = #core.registered_on_player_hpchanges.modifiers, 1, -1 do
local func = core.registered_on_player_hpchanges.modifiers[i]
hp_change, last = func(player, hp_change, reason)
@@ -564,7 +580,8 @@ core.registered_biomes = make_registration_wrap("register_biome", "cle
core.registered_ores = make_registration_wrap("register_ore", "clear_registered_ores")
core.registered_decorations = make_registration_wrap("register_decoration", "clear_registered_decorations")
core.unregister_biome = make_wrap_deregistration(core.register_biome, core.clear_registered_biomes, core.registered_biomes)
core.unregister_biome = make_wrap_deregistration(core.register_biome,
core.clear_registered_biomes, core.registered_biomes)
core.registered_on_chat_messages, core.register_on_chat_message = make_registration()
core.registered_globalsteps, core.register_globalstep = make_registration()
@@ -590,9 +607,9 @@ core.registered_on_item_eats, core.register_on_item_eat = make_registration()
core.registered_on_punchplayers, core.register_on_punchplayer = make_registration()
core.registered_on_priv_grant, core.register_on_priv_grant = make_registration()
core.registered_on_priv_revoke, core.register_on_priv_revoke = make_registration()
core.registered_on_authplayers, core.register_on_authplayer = make_registration()
core.registered_can_bypass_userlimit, core.register_can_bypass_userlimit = make_registration()
core.registered_on_modchannel_message, core.register_on_modchannel_message = make_registration()
core.registered_on_auth_fail, core.register_on_auth_fail = make_registration()
core.registered_on_player_inventory_actions, core.register_on_player_inventory_action = make_registration()
core.registered_allow_player_inventory_actions, core.register_allow_player_inventory_action = make_registration()

View File

@@ -1,26 +1,28 @@
-- cache setting
local enable_damage = core.settings:get_bool("enable_damage")
local health_bar_definition =
{
local health_bar_definition = {
hud_elem_type = "statbar",
position = { x=0.5, y=1 },
position = {x = 0.5, y = 1},
text = "heart.png",
text2 = "heart_gone.png",
number = core.PLAYER_MAX_HP_DEFAULT,
item = core.PLAYER_MAX_HP_DEFAULT,
direction = 0,
size = { x=24, y=24 },
offset = { x=(-10*24)-25, y=-(48+24+16)},
size = {x = 24, y = 24},
offset = {x = (-10 * 24) - 25, y = -(48 + 24 + 16)},
}
local breath_bar_definition =
{
local breath_bar_definition = {
hud_elem_type = "statbar",
position = { x=0.5, y=1 },
position = {x = 0.5, y = 1},
text = "bubble.png",
text2 = "bubble_gone.png",
number = core.PLAYER_MAX_BREATH_DEFAULT,
item = core.PLAYER_MAX_BREATH_DEFAULT * 2,
direction = 0,
size = { x=24, y=24 },
offset = {x=25,y=-(48+24+16)},
size = {x = 24, y = 24},
offset = {x = 25, y= -(48 + 24 + 16)},
}
local hud_ids = {}
@@ -28,10 +30,10 @@ local hud_ids = {}
local function scaleToDefault(player, field)
-- Scale "hp" or "breath" to the default dimensions
local current = player["get_" .. field](player)
local nominal = core["PLAYER_MAX_".. field:upper() .. "_DEFAULT"]
local nominal = core["PLAYER_MAX_" .. field:upper() .. "_DEFAULT"]
local max_display = math.max(nominal,
math.max(player:get_properties()[field .. "_max"], current))
return current / max_display * nominal
math.max(player:get_properties()[field .. "_max"], current))
return current / max_display * nominal
end
local function update_builtin_statbars(player)
@@ -50,10 +52,12 @@ local function update_builtin_statbars(player)
end
local hud = hud_ids[name]
if flags.healthbar and enable_damage then
local immortal = player:get_armor_groups().immortal == 1
if flags.healthbar and enable_damage and not immortal then
local number = scaleToDefault(player, "hp")
if hud.id_healthbar == nil then
local hud_def = table.copy(health_bar_definition)
if hud.id_healthbar == nil then
local hud_def = table.copy(health_bar_definition)
hud_def.number = number
hud.id_healthbar = player:hud_add(hud_def)
else
@@ -64,19 +68,28 @@ local function update_builtin_statbars(player)
hud.id_healthbar = nil
end
local show_breathbar = flags.breathbar and enable_damage and not immortal
local breath = player:get_breath()
local breath_max = player:get_properties().breath_max
if flags.breathbar and enable_damage and
player:get_breath() < breath_max then
if show_breathbar and breath <= breath_max then
local number = 2 * scaleToDefault(player, "breath")
if hud.id_breathbar == nil then
local hud_def = table.copy(breath_bar_definition)
if not hud.id_breathbar and breath < breath_max then
local hud_def = table.copy(breath_bar_definition)
hud_def.number = number
hud.id_breathbar = player:hud_add(hud_def)
else
elseif hud.id_breathbar then
player:hud_change(hud.id_breathbar, "number", number)
end
elseif hud.id_breathbar then
player:hud_remove(hud.id_breathbar)
end
if hud.id_breathbar and (not show_breathbar or breath == breath_max) then
minetest.after(1, function(player_name, breath_bar)
local player = minetest.get_player_by_name(player_name)
if player then
player:hud_remove(breath_bar)
end
end, name, hud.id_breathbar)
hud.id_breathbar = nil
end
end
@@ -116,7 +129,7 @@ local function player_event_handler(player,eventname)
end
end
if eventname == "hud_changed" then
if eventname == "hud_changed" or eventname == "properties_changed" then
update_builtin_statbars(player)
return true
end
@@ -124,14 +137,14 @@ local function player_event_handler(player,eventname)
return false
end
function core.hud_replace_builtin(name, definition)
function core.hud_replace_builtin(hud_name, definition)
if type(definition) ~= "table" or
definition.hud_elem_type ~= "statbar" then
return false
end
if name == "health" then
if hud_name == "health" then
health_bar_definition = definition
for name, ids in pairs(hud_ids) do
@@ -145,7 +158,7 @@ function core.hud_replace_builtin(name, definition)
return true
end
if name == "breath" then
if hud_name == "breath" then
breath_bar_definition = definition
for name, ids in pairs(hud_ids) do

View File

@@ -36,6 +36,7 @@ dofile(commonpath .. "misc_helpers.lua")
if INIT == "game" then
dofile(gamepath .. "init.lua")
assert(not core.get_http_api)
elseif INIT == "mainmenu" then
local mm_script = core.settings:get("main_menu_script")
if mm_script and mm_script ~= "" then

View File

@@ -8,15 +8,7 @@ local function handle_job(jobid, serialized_retval)
core.async_jobs[jobid] = nil
end
if core.register_globalstep then
core.register_globalstep(function(dtime)
for i, job in ipairs(core.get_finished_jobs()) do
handle_job(job.jobid, job.retval)
end
end)
else
core.async_event_handler = handle_job
end
core.async_event_handler = handle_job
function core.handle_async(func, parameter, callback)
-- Serialize function

View File

@@ -93,9 +93,9 @@ function render_serverlist_row(spec, is_favorite)
end
end
local details = ""
local grey_out = not is_server_protocol_compat(spec.proto_min, spec.proto_max)
local details
if is_favorite then
details = "1,"
else
@@ -118,11 +118,11 @@ function render_serverlist_row(spec, is_favorite)
end
if spec.clients and spec.clients_max then
local clients_color = ''
local clients_percent = 100 * spec.clients / spec.clients_max
-- Choose a color depending on how many clients are connected
-- (relatively to clients_max)
local clients_color
if grey_out then clients_color = '#aaaaaa'
elseif spec.clients == 0 then clients_color = '' -- 0 players: default/white
elseif clients_percent <= 60 then clients_color = '#a1e587' -- 0-60%: green
@@ -171,6 +171,7 @@ os.tempfolder = function()
local filetocheck = os.tmpname()
os.remove(filetocheck)
-- luacheck: ignore
-- https://blogs.msdn.microsoft.com/vcblog/2014/06/18/c-runtime-crt-features-fixes-and-breaking-changes-in-visual-studio-14-ctp1/
-- The C runtime (CRT) function called by os.tmpname is tmpnam.
-- Microsofts tmpnam implementation in older CRT / MSVC releases is defective.

View File

@@ -23,7 +23,49 @@ local function modname_valid(name)
return not name:find("[^a-z0-9_]")
end
local function init_data(data)
data.list = filterlist.create(
pkgmgr.preparemodlist,
pkgmgr.comparemod,
function(element, uid)
if element.name == uid then
return true
end
end,
function(element, criteria)
if criteria.hide_game and
element.is_game_content then
return false
end
if criteria.hide_modpackcontents and
element.modpack ~= nil then
return false
end
return true
end,
{
worldpath = data.worldspec.path,
gameid = data.worldspec.gameid
})
if data.selected_mod > data.list:size() then
data.selected_mod = 0
end
data.list:set_filtercriteria({
hide_game = data.hide_gamemods,
hide_modpackcontents = data.hide_modpackcontents
})
data.list:add_sort_mechanism("alphabetic", sort_mod_list)
data.list:set_sortmode("alphabetic")
end
local function get_formspec(data)
if not data.list then
init_data(data)
end
local mod = data.list:get_list()[data.selected_mod] or {name = ""}
local retval =
@@ -31,8 +73,6 @@ local function get_formspec(data)
"label[0.5,0;" .. fgettext("World:") .. "]" ..
"label[1.75,0;" .. data.worldspec.name .. "]"
local hard_deps, soft_deps = pkgmgr.get_dependencies(mod.path)
if mod.is_modpack or mod.type == "game" then
local info = minetest.formspec_escape(
core.get_content_info(mod.path).description)
@@ -46,21 +86,55 @@ local function get_formspec(data)
retval = retval ..
"textarea[0.25,0.7;5.75,7.2;;" .. info .. ";]"
else
local hard_deps, soft_deps = pkgmgr.get_dependencies(mod.path)
local hard_deps_str = table.concat(hard_deps, ",")
local soft_deps_str = table.concat(soft_deps, ",")
retval = retval ..
"label[0,0.7;" .. fgettext("Mod:") .. "]" ..
"label[0.75,0.7;" .. mod.name .. "]" ..
"label[0,1.25;" .. fgettext("Dependencies:") .. "]" ..
"textlist[0,1.75;5,2.125;world_config_depends;" .. hard_deps ..
";0]" ..
"label[0,3.875;" .. fgettext("Optional dependencies:") .. "]" ..
"textlist[0,4.375;5,1.8;world_config_optdepends;" ..
soft_deps .. ";0]"
"label[0.75,0.7;" .. mod.name .. "]"
if hard_deps_str == "" then
if soft_deps_str == "" then
retval = retval ..
"label[0,1.25;" ..
fgettext("No (optional) dependencies") .. "]"
else
retval = retval ..
"label[0,1.25;" .. fgettext("No hard dependencies") ..
"]" ..
"label[0,1.75;" .. fgettext("Optional dependencies:") ..
"]" ..
"textlist[0,2.25;5,4;world_config_optdepends;" ..
soft_deps_str .. ";0]"
end
else
if soft_deps_str == "" then
retval = retval ..
"label[0,1.25;" .. fgettext("Dependencies:") .. "]" ..
"textlist[0,1.75;5,4;world_config_depends;" ..
hard_deps_str .. ";0]" ..
"label[0,6;" .. fgettext("No optional dependencies") .. "]"
else
retval = retval ..
"label[0,1.25;" .. fgettext("Dependencies:") .. "]" ..
"textlist[0,1.75;5,2.125;world_config_depends;" ..
hard_deps_str .. ";0]" ..
"label[0,3.9;" .. fgettext("Optional dependencies:") ..
"]" ..
"textlist[0,4.375;5,1.8;world_config_optdepends;" ..
soft_deps_str .. ";0]"
end
end
end
retval = retval ..
"button[3.25,7;2.5,0.5;btn_config_world_save;" ..
fgettext("Save") .. "]" ..
"button[5.75,7;2.5,0.5;btn_config_world_cancel;" ..
fgettext("Cancel") .. "]"
fgettext("Cancel") .. "]" ..
"button[9,7;2.5,0.5;btn_config_world_cdb;" ..
fgettext("Find More Mods") .. "]"
if mod.name ~= "" and not mod.is_game_content then
if mod.is_modpack then
@@ -169,6 +243,16 @@ local function handle_buttons(this, fields)
return true
end
if fields.btn_config_world_cdb then
this.data.list = nil
local dlg = create_store_dlg("mod")
dlg:set_parent(this)
this:hide()
dlg:show()
return true
end
if fields.btn_enable_all_mods then
local list = this.data.list:get_raw_list()
@@ -218,43 +302,5 @@ function create_configure_world_dlg(worldidx)
return
end
dlg.data.list = filterlist.create(
pkgmgr.preparemodlist,
pkgmgr.comparemod,
function(element, uid)
if element.name == uid then
return true
end
end,
function(element, criteria)
if criteria.hide_game and
element.is_game_content then
return false
end
if criteria.hide_modpackcontents and
element.modpack ~= nil then
return false
end
return true
end,
{
worldpath = dlg.data.worldspec.path,
gameid = dlg.data.worldspec.gameid
}
)
if dlg.data.selected_mod > dlg.data.list:size() then
dlg.data.selected_mod = 0
end
dlg.data.list:set_filtercriteria({
hide_game = dlg.data.hide_gamemods,
hide_modpackcontents = dlg.data.hide_modpackcontents
})
dlg.data.list:add_sort_mechanism("alphabetic", sort_mod_list)
dlg.data.list:set_sortmode("alphabetic")
return dlg
end

View File

@@ -1,5 +1,5 @@
--Minetest
--Copyright (C) 2018 rubenwardy
--Copyright (C) 2018-20 rubenwardy
--
--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
@@ -15,8 +15,17 @@
--with this program; if not, write to the Free Software Foundation, Inc.,
--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
if not minetest.get_http_api then
function create_store_dlg()
return messagebox("store",
fgettext("ContentDB is not available when Minetest was compiled without cURL"))
end
return
end
local store = { packages = {}, packages_full = {} }
local package_dialog = {}
local http = minetest.get_http_api()
-- Screenshot
local screenshot_dir = core.get_cache_path() .. DIR_DELIM .. "cdb"
@@ -44,19 +53,15 @@ local filter_types_type = {
}
local function download_package(param)
if core.download_file(param.package.url, param.filename) then
return {
package = param.package,
filename = param.filename,
successful = true,
}
else
core.log("error", "downloading " .. dump(param.package.url) .. " failed")
return {
package = param.package,
successful = false,
}
end
@@ -70,9 +75,9 @@ local function start_install(calling_dialog, package)
local function callback(result)
if result.successful then
local path, msg = pkgmgr.install(result.package.type,
result.filename, result.package.name,
result.package.path)
local path, msg = pkgmgr.install(package.type,
result.filename, package.name,
package.path)
if not path then
gamedata.errormessage = msg
else
@@ -80,36 +85,33 @@ local function start_install(calling_dialog, package)
local conf_path
local name_is_title = false
if result.package.type == "mod" then
if package.type == "mod" then
local actual_type = pkgmgr.get_folder_type(path)
if actual_type.type == "modpack" then
conf_path = path .. DIR_DELIM .. "modpack.conf"
else
conf_path = path .. DIR_DELIM .. "mod.conf"
end
elseif result.package.type == "game" then
elseif package.type == "game" then
conf_path = path .. DIR_DELIM .. "game.conf"
name_is_title = true
elseif result.package.type == "txp" then
elseif package.type == "txp" then
conf_path = path .. DIR_DELIM .. "texture_pack.conf"
end
if conf_path then
local conf = Settings(conf_path)
local function set_def(key, value)
if conf:get(key) == nil then
conf:set(key, value)
end
end
if name_is_title then
set_def("name", result.package.title)
conf:set("name", package.title)
else
set_def("title", result.package.title)
set_def("name", result.package.name)
conf:set("title", package.title)
conf:set("name", package.name)
end
set_def("description", result.package.short_description)
set_def("author", result.package.author)
conf:set("release", result.package.release)
if not conf:get("description") then
conf:set("description", package.short_description)
end
conf:set("author", package.author)
conf:set("release", package.release)
conf:write()
end
end
@@ -118,37 +120,22 @@ local function start_install(calling_dialog, package)
gamedata.errormessage = fgettext("Failed to download $1", package.name)
end
if gamedata.errormessage == nil then
core.button_handler({btn_hidden_close_download=result})
else
core.button_handler({btn_hidden_close_download={successful=false}})
end
package.downloading = false
ui.update()
end
package.downloading = true
if not core.handle_async(download_package, params, callback) then
core.log("error", "ERROR: async event failed")
gamedata.errormessage = fgettext("Failed to download $1", package.name)
return
end
end
local new_dlg = dialog_create("store_downloading",
function(data)
return "size[7,2]label[0.25,0.75;" ..
fgettext("Downloading and installing $1, please wait...", data.title) .. "]"
end,
function(this,fields)
if fields["btn_hidden_close_download"] ~= nil then
this:delete()
return true
end
return false
end,
nil)
new_dlg:set_parent(calling_dialog)
new_dlg.data.title = package.title
calling_dialog:hide()
new_dlg:show()
local function get_file_extension(path)
local parts = path:split(".")
return parts[#parts]
end
local function get_screenshot(package)
@@ -159,8 +146,9 @@ local function get_screenshot(package)
end
-- Get tmp screenshot path
local ext = get_file_extension(package.thumbnail)
local filepath = screenshot_dir .. DIR_DELIM ..
package.type .. "-" .. package.author .. "-" .. package.name .. ".png"
("%s-%s-%s.%s"):format(package.type, package.author, package.name, ext)
-- Return if already downloaded
local file = io.open(filepath, "r")
@@ -198,85 +186,12 @@ local function get_screenshot(package)
return defaulttexturedir .. "loading_screenshot.png"
end
function package_dialog.get_formspec()
local package = package_dialog.package
store.update_paths()
local formspec = {
"size[9,4;true]",
"image[0,1;4.5,3;", core.formspec_escape(get_screenshot(package)), ']',
"label[3.8,1;",
minetest.colorize(mt_color_green, core.formspec_escape(package.title)), "\n",
minetest.colorize('#BFBFBF', "by " .. core.formspec_escape(package.author)), "]",
"textarea[4,2;5.3,2;;;", core.formspec_escape(package.short_description), "]",
"button[0,0;2,1;back;", fgettext("Back"), "]",
}
if not package.path then
formspec[#formspec + 1] = "button[7,0;2,1;install;"
formspec[#formspec + 1] = fgettext("Install")
formspec[#formspec + 1] = "]"
elseif package.installed_release < package.release then
-- The install_ action also handles updating
formspec[#formspec + 1] = "button[7,0;2,1;install;"
formspec[#formspec + 1] = fgettext("Update")
formspec[#formspec + 1] = "]"
formspec[#formspec + 1] = "button[5,0;2,1;uninstall;"
formspec[#formspec + 1] = fgettext("Uninstall")
formspec[#formspec + 1] = "]"
else
formspec[#formspec + 1] = "button[7,0;2,1;uninstall;"
formspec[#formspec + 1] = fgettext("Uninstall")
formspec[#formspec + 1] = "]"
end
return table.concat(formspec, "")
end
function package_dialog.handle_submit(this, fields)
if fields.back then
this:delete()
return true
end
if fields.install then
start_install(this, package_dialog.package)
return true
end
if fields.uninstall then
local dlg_delmod = create_delete_content_dlg(package_dialog.package)
dlg_delmod:set_parent(this)
this:hide()
dlg_delmod:show()
return true
end
return false
end
function package_dialog.create(package)
package_dialog.package = package
return dialog_create("package_view",
package_dialog.get_formspec,
package_dialog.handle_submit,
nil)
end
function store.load()
local tmpdir = os.tempfolder()
local target = tmpdir .. DIR_DELIM .. "packages.json"
assert(core.create_dir(tmpdir))
local base_url = core.settings:get("contentdb_url")
local show_nonfree = core.settings:get_bool("show_nonfree_packages")
local version = core.get_version()
local base_url = core.settings:get("contentdb_url")
local url = base_url ..
"/api/packages/?type=mod&type=game&type=txp&protocol_version=" ..
core.get_max_supp_proto()
core.get_max_supp_proto() .. "&engine_version=" .. version.string
for _, item in pairs(core.settings:get("contentdb_flag_blacklist"):split(",")) do
item = item:trim()
@@ -285,31 +200,29 @@ function store.load()
end
end
core.download_file(url, target)
local timeout = tonumber(minetest.settings:get("curl_file_download_timeout"))
local response = http.fetch_sync({ url = url, timeout = timeout })
if not response.succeeded then
return
end
local file = io.open(target, "r")
if file then
store.packages_full = core.parse_json(file:read("*all")) or {}
file:close()
store.packages_full = core.parse_json(response.data) or {}
for _, package in pairs(store.packages_full) do
package.url = base_url .. "/packages/" ..
for _, package in pairs(store.packages_full) do
package.url = base_url .. "/packages/" ..
package.author .. "/" .. package.name ..
"/releases/" .. package.release .. "/download/"
local name_len = #package.name
if package.type == "game" and name_len > 5 and package.name:sub(name_len - 4) == "_game" then
package.id = package.author .. "/" .. package.name:sub(1, name_len - 5)
else
package.id = package.author .. "/" .. package.name
end
local name_len = #package.name
if package.type == "game" and name_len > 5 and package.name:sub(name_len - 4) == "_game" then
package.id = package.author:lower() .. "/" .. package.name:sub(1, name_len - 5)
else
package.id = package.author:lower() .. "/" .. package.name
end
store.packages = store.packages_full
store.loaded = true
end
core.delete_dir(tmpdir)
store.packages = store.packages_full
store.loaded = true
end
function store.update_paths()
@@ -317,22 +230,22 @@ function store.update_paths()
pkgmgr.refresh_globals()
for _, mod in pairs(pkgmgr.global_mods:get_list()) do
if mod.author then
mod_hash[mod.author .. "/" .. mod.name] = mod
mod_hash[mod.author:lower() .. "/" .. mod.name] = mod
end
end
local game_hash = {}
pkgmgr.update_gamelist()
for _, game in pairs(pkgmgr.games) do
if game.author then
game_hash[game.author .. "/" .. game.id] = game
if game.author ~= "" then
game_hash[game.author:lower() .. "/" .. game.id] = game
end
end
local txp_hash = {}
for _, txp in pairs(pkgmgr.get_texture_packs()) do
if txp.author then
txp_hash[txp.author .. "/" .. txp.name] = txp
txp_hash[txp.author:lower() .. "/" .. txp.name] = txp
end
end
@@ -399,34 +312,35 @@ function store.get_formspec(dlgdata)
cur_page = 1
end
local W = 15.75
local H = 9.5
local formspec
if #store.packages_full > 0 then
formspec = {
"size[12,7;true]",
"formspec_version[3]",
"size[15.75,9.5]",
"position[0.5,0.55]",
"field[0.2,0.1;7.8,1;search_string;;",
core.formspec_escape(search_string), "]",
"container[0.375,0.375]",
"field[0,0;10.225,0.8;search_string;;", core.formspec_escape(search_string), "]",
"field_close_on_enter[search_string;false]",
"button[7.7,-0.2;2,1;search;",
fgettext("Search"), "]",
"dropdown[9.7,-0.1;2.4;type;",
table.concat(filter_types_titles, ","),
";", filter_type, "]",
-- "textlist[0,1;2.4,5.6;a;",
-- table.concat(taglist, ","), "]",
"button[10.225,0;2,0.8;search;", fgettext("Search"), "]",
"dropdown[12.6,0;2.4,0.8;type;", table.concat(filter_types_titles, ","), ";", filter_type, "]",
"container_end[]",
-- Page nav buttons
"container[0,",
num_per_page + 1.5, "]",
"button[-0.1,0;3,1;back;",
fgettext("Back to Main Menu"), "]",
"button[7.1,0;1,1;pstart;<<]",
"button[8.1,0;1,1;pback;<]",
"label[9.2,0.2;",
tonumber(cur_page), " / ",
tonumber(dlgdata.pagemax), "]",
"button[10.1,0;1,1;pnext;>]",
"button[11.1,0;1,1;pend;>>]",
"container[0,", H - 0.8 - 0.375, "]",
"button[0.375,0;4,0.8;back;", fgettext("Back to Main Menu"), "]",
"container[", W - 0.375 - 0.8*4 - 2, ",0]",
"image_button[0,0;0.8,0.8;", core.formspec_escape(defaulttexturedir), "start_icon.png;pstart;]",
"image_button[0.8,0;0.8,0.8;", core.formspec_escape(defaulttexturedir), "prev_icon.png;pback;]",
"style[pagenum;border=false]",
"button[1.6,0;2,0.8;pagenum;", tonumber(cur_page), " / ", tonumber(dlgdata.pagemax), "]",
"image_button[3.6,0;0.8,0.8;", core.formspec_escape(defaulttexturedir), "next_icon.png;pnext;]",
"image_button[4.4,0;0.8,0.8;", core.formspec_escape(defaulttexturedir), "end_icon.png;pend;]",
"container_end[]",
"container_end[]",
}
@@ -437,73 +351,84 @@ function store.get_formspec(dlgdata)
end
else
formspec = {
"size[12,7;true]",
"size[12,7]",
"position[0.5,0.55]",
"label[4,3;", fgettext("No packages could be retrieved"), "]",
"button[-0.1,",
num_per_page + 1.5,
";3,1;back;",
fgettext("Back to Main Menu"), "]",
"container[0,", H - 0.8 - 0.375, "]",
"button[0,0;4,0.8;back;", fgettext("Back to Main Menu"), "]",
"container_end[]",
}
end
local start_idx = (cur_page - 1) * num_per_page + 1
for i=start_idx, math.min(#store.packages, start_idx+num_per_page-1) do
local package = store.packages[i]
formspec[#formspec + 1] = "container[0.5,"
formspec[#formspec + 1] = (i - start_idx) * 1.1 + 1
formspec[#formspec + 1] = "container[0.375,"
formspec[#formspec + 1] = (i - start_idx) * 1.375 + (2*0.375 + 0.8)
formspec[#formspec + 1] = "]"
-- image
formspec[#formspec + 1] = "image[-0.4,0;1.5,1;"
formspec[#formspec + 1] = "image[0,0;1.5,1;"
formspec[#formspec + 1] = core.formspec_escape(get_screenshot(package))
formspec[#formspec + 1] = "]"
-- title
formspec[#formspec + 1] = "label[1,-0.1;"
formspec[#formspec + 1] = "label[1.875,0.1;"
formspec[#formspec + 1] = core.formspec_escape(
minetest.colorize(mt_color_green, package.title) ..
minetest.colorize("#BFBFBF", " by " .. package.author))
formspec[#formspec + 1] = "]"
-- description
if package.path and package.installed_release < package.release then
formspec[#formspec + 1] = "textarea[1.25,0.3;7.5,1;;;"
else
formspec[#formspec + 1] = "textarea[1.25,0.3;9,1;;;"
end
formspec[#formspec + 1] = core.formspec_escape(package.short_description)
formspec[#formspec + 1] = "]"
-- buttons
if not package.path then
formspec[#formspec + 1] = "button[9.9,0;1.5,1;install_"
local description_width = W - 0.375*5 - 1 - 2*1.5
formspec[#formspec + 1] = "container["
formspec[#formspec + 1] = W - 0.375*2
formspec[#formspec + 1] = ",0.1]"
if package.downloading then
formspec[#formspec + 1] = "style[download;border=false]"
formspec[#formspec + 1] = "button[-3.5,0;2,0.8;download;"
formspec[#formspec + 1] = fgettext("Downloading...")
formspec[#formspec + 1] = "]"
elseif not package.path then
formspec[#formspec + 1] = "button[-3,0;1.5,0.8;install_"
formspec[#formspec + 1] = tostring(i)
formspec[#formspec + 1] = ";"
formspec[#formspec + 1] = fgettext("Install")
formspec[#formspec + 1] = "]"
else
if package.installed_release < package.release then
description_width = description_width - 1.5
-- The install_ action also handles updating
formspec[#formspec + 1] = "button[8.4,0;1.5,1;install_"
formspec[#formspec + 1] = "button[-4.5,0;1.5,0.8;install_"
formspec[#formspec + 1] = tostring(i)
formspec[#formspec + 1] = ";"
formspec[#formspec + 1] = fgettext("Update")
formspec[#formspec + 1] = "]"
end
formspec[#formspec + 1] = "button[9.9,0;1.5,1;uninstall_"
formspec[#formspec + 1] = "button[-3,0;1.5,0.8;uninstall_"
formspec[#formspec + 1] = tostring(i)
formspec[#formspec + 1] = ";"
formspec[#formspec + 1] = fgettext("Uninstall")
formspec[#formspec + 1] = "]"
end
--formspec[#formspec + 1] = "button[9.9,0;1.5,1;view_"
--formspec[#formspec + 1] = tostring(i)
--formspec[#formspec + 1] = ";"
--formspec[#formspec + 1] = fgettext("View")
--formspec[#formspec + 1] = "]"
formspec[#formspec + 1] = "button[-1.5,0;1.5,0.8;view_"
formspec[#formspec + 1] = tostring(i)
formspec[#formspec + 1] = ";"
formspec[#formspec + 1] = fgettext("View")
formspec[#formspec + 1] = "]"
formspec[#formspec + 1] = "container_end[]"
-- description
formspec[#formspec + 1] = "textarea[1.855,0.3;"
formspec[#formspec + 1] = tostring(description_width)
formspec[#formspec + 1] = ",0.8;;;"
formspec[#formspec + 1] = core.formspec_escape(package.short_description)
formspec[#formspec + 1] = "]"
formspec[#formspec + 1] = "container_end[]"
end
@@ -580,10 +505,9 @@ function store.handle_submit(this, fields)
end
if fields["view_" .. i] then
local dlg = package_dialog.create(package)
dlg:set_parent(this)
this:hide()
dlg:show()
local url = ("%s/packages/%s?protocol_version=%d"):format(
core.settings:get("contentdb_url"), package.id, core.get_max_supp_proto())
core.open_url(url)
return true
end
end
@@ -598,6 +522,17 @@ function create_store_dlg(type)
search_string = ""
cur_page = 1
if type then
-- table.indexof does not work on tables that contain `nil`
for i, v in pairs(filter_types_type) do
if v == type then
filter_type = i
break
end
end
end
store.filter_packages(search_string)
return dialog_create("store",

View File

@@ -17,32 +17,144 @@
local worldname = ""
local function table_to_flags(ftable)
-- Convert e.g. { jungles = true, caves = false } to "jungles,nocaves"
local str = {}
for flag, is_set in pairs(ftable) do
str[#str + 1] = is_set and flag or ("no" .. flag)
end
return table.concat(str, ",")
end
-- Same as check_flag but returns a string
local function strflag(flags, flag)
return (flags[flag] == true) and "true" or "false"
end
local cb_caverns = { "caverns", fgettext("Caverns"), "caverns",
fgettext("Very large caverns deep in the underground") }
local tt_sea_rivers = fgettext("Sea level rivers")
local flag_checkboxes = {
v5 = {
cb_caverns,
},
v7 = {
cb_caverns,
{ "ridges", fgettext("Rivers"), "ridges", tt_sea_rivers },
{ "mountains", fgettext("Mountains"), "mountains" },
{ "floatlands", fgettext("Floatlands (experimental)"), "floatlands",
fgettext("Floating landmasses in the sky") },
},
carpathian = {
cb_caverns,
{ "rivers", fgettext("Rivers"), "rivers", tt_sea_rivers },
},
valleys = {
{ "altitude-chill", fgettext("Altitude chill"), "altitude_chill",
fgettext("Reduces heat with altitude") },
{ "altitude-dry", fgettext("Altitude dry"), "altitude_dry",
fgettext("Reduces humidity with altitude") },
{ "humid-rivers", fgettext("Humid rivers"), "humid_rivers",
fgettext("Increases humidity around rivers") },
{ "vary-river-depth", fgettext("Vary river depth"), "vary_river_depth",
fgettext("Low humidity and high heat causes shallow or dry rivers") },
},
flat = {
{ "hills", fgettext("Hills"), "hills" },
{ "lakes", fgettext("Lakes"), "lakes" },
},
fractal = {
{ "terrain", fgettext("Additional terrain"), "terrain",
fgettext("Generate non-fractal terrain: Oceans and underground") },
},
v6 = {
{ "trees", fgettext("Trees and jungle grass"), "trees" },
{ "flat", fgettext("Flat terrain"), "flat" },
{ "mudflow", fgettext("Mud flow"), "mudflow",
fgettext("Terrain surface erosion") },
-- Biome settings are in mgv6_biomes below
},
}
local mgv6_biomes = {
{
fgettext("Temperate, Desert, Jungle, Tundra, Taiga"),
{jungles = true, snowbiomes = true}
},
{
fgettext("Temperate, Desert, Jungle"),
{jungles = true, snowbiomes = false}
},
{
fgettext("Temperate, Desert"),
{jungles = false, snowbiomes = false}
},
}
local function create_world_formspec(dialogdata)
-- Error out when no games found
if #pkgmgr.games == 0 then
return "size[12.25,3,true]" ..
"box[0,0;12,2;#ff8800]" ..
"textarea[0.3,0;11.7,2;;;"..
fgettext("You have no games installed.") .. "\n" ..
fgettext("Download one from minetest.net") .. "]" ..
"button[4.75,2.5;3,0.5;world_create_cancel;" .. fgettext("Cancel") .. "]"
end
local mapgens = core.get_mapgen_names()
local current_seed = core.settings:get("fixed_map_seed") or ""
local current_mg = core.settings:get("mg_name")
local gameid = core.settings:get("menu_last_game")
local game, gameidx = nil , 0
local flags = {
main = core.settings:get_flags("mg_flags"),
v5 = core.settings:get_flags("mgv5_spflags"),
v6 = core.settings:get_flags("mgv6_spflags"),
v7 = core.settings:get_flags("mgv7_spflags"),
fractal = core.settings:get_flags("mgfractal_spflags"),
carpathian = core.settings:get_flags("mgcarpathian_spflags"),
valleys = core.settings:get_flags("mgvalleys_spflags"),
flat = core.settings:get_flags("mgflat_spflags"),
}
local gameidx = 0
if gameid ~= nil then
game, gameidx = pkgmgr.find_by_gameid(gameid)
local _
_, gameidx = pkgmgr.find_by_gameid(gameid)
if gameidx == nil then
gameidx = 0
end
end
local game_by_gameidx = core.get_game(gameidx)
local disallowed_mapgen_settings = {}
if game_by_gameidx ~= nil then
local gamepath = game_by_gameidx.path
local gameconfig = Settings(gamepath.."/game.conf")
local allowed_mapgens = (gameconfig:get("allowed_mapgens") or ""):split()
for key, value in pairs(allowed_mapgens) do
allowed_mapgens[key] = value:trim()
end
local disallowed_mapgens = (gameconfig:get("disallowed_mapgens") or ""):split()
for key, value in pairs(disallowed_mapgens) do
disallowed_mapgens[key] = value:trim()
end
if #allowed_mapgens > 0 then
for i = #mapgens, 1, -1 do
if table.indexof(allowed_mapgens, mapgens[i]) == -1 then
table.remove(mapgens, i)
end
end
end
if disallowed_mapgens then
for i = #mapgens, 1, -1 do
if table.indexof(disallowed_mapgens, mapgens[i]) > 0 then
@@ -50,49 +162,193 @@ local function create_world_formspec(dialogdata)
end
end
end
local ds = (gameconfig:get("disallowed_mapgen_settings") or ""):split()
for _, value in pairs(ds) do
disallowed_mapgen_settings[value:trim()] = true
end
end
local mglist = ""
local selindex = 1
local selindex
local i = 1
local first_mg
for k,v in pairs(mapgens) do
if not first_mg then
first_mg = v
end
if current_mg == v then
selindex = i
end
i = i + 1
mglist = mglist .. v .. ","
end
if not selindex then
selindex = 1
current_mg = first_mg
end
mglist = mglist:sub(1, -2)
current_seed = core.formspec_escape(current_seed)
local retval =
"size[11.5,6.5,true]" ..
"label[2,0;" .. fgettext("World name") .. "]"..
"field[4.5,0.4;6,0.5;te_world_name;;" .. minetest.formspec_escape(worldname) .. "]" ..
local mg_main_flags = function(mapgen, y)
if mapgen == "singlenode" then
return "", y
end
if disallowed_mapgen_settings["mg_flags"] then
return "", y
end
"label[2,1;" .. fgettext("Seed") .. "]"..
"field[4.5,1.4;6,0.5;te_seed;;".. current_seed .. "]" ..
local form = "checkbox[0," .. y .. ";flag_mg_caves;" ..
fgettext("Caves") .. ";"..strflag(flags.main, "caves").."]"
y = y + 0.5
"label[2,2;" .. fgettext("Mapgen") .. "]"..
"dropdown[4.2,2;6.3;dd_mapgen;" .. mglist .. ";" .. selindex .. "]" ..
form = form .. "checkbox[0,"..y..";flag_mg_dungeons;" ..
fgettext("Dungeons") .. ";"..strflag(flags.main, "dungeons").."]"
y = y + 0.5
"label[2,3;" .. fgettext("Game") .. "]"..
"textlist[4.2,3;5.8,2.3;games;" .. pkgmgr.gamelist() ..
";" .. gameidx .. ";true]" ..
local d_name = fgettext("Decorations")
local d_tt
if mapgen == "v6" then
d_tt = fgettext("Structures appearing on the terrain (no effect on trees and jungle grass created by v6)")
else
d_tt = fgettext("Structures appearing on the terrain, typically trees and plants")
end
form = form .. "checkbox[0,"..y..";flag_mg_decorations;" ..
d_name .. ";" ..
strflag(flags.main, "decorations").."]" ..
"tooltip[flag_mg_decorations;" ..
d_tt ..
"]"
y = y + 0.5
"button[3.25,6;2.5,0.5;world_create_confirm;" .. fgettext("Create") .. "]" ..
"button[5.75,6;2.5,0.5;world_create_cancel;" .. fgettext("Cancel") .. "]"
if #pkgmgr.games == 0 then
retval = retval .. "box[2,4;8,1;#ff8800]label[2.25,4;" ..
fgettext("You have no games installed.") .. "]label[2.25,4.4;" ..
fgettext("Download one from minetest.net") .. "]"
elseif #pkgmgr.games == 1 and pkgmgr.games[1].id == "minimal" then
retval = retval .. "box[1.75,4;8.7,1;#ff8800]label[2,4;" ..
fgettext("Warning: The minimal development test is meant for developers.") .. "]label[2,4.4;" ..
fgettext("Download a game, such as Minetest Game, from minetest.net") .. "]"
form = form .. "tooltip[flag_mg_caves;" ..
fgettext("Network of tunnels and caves")
.. "]"
return form, y
end
local mg_specific_flags = function(mapgen, y)
if not flag_checkboxes[mapgen] then
return "", y
end
if disallowed_mapgen_settings["mg"..mapgen.."_spflags"] then
return "", y
end
local form = ""
for _,tab in pairs(flag_checkboxes[mapgen]) do
local id = "flag_mg"..mapgen.."_"..tab[1]
form = form .. ("checkbox[0,%f;%s;%s;%s]"):
format(y, id, tab[2], strflag(flags[mapgen], tab[3]))
if tab[4] then
form = form .. "tooltip["..id..";"..tab[4].."]"
end
y = y + 0.5
end
if mapgen ~= "v6" then
-- No special treatment
return form, y
end
-- Special treatment for v6 (add biome widgets)
-- Biome type (jungles, snowbiomes)
local biometype
if flags.v6.snowbiomes == true then
biometype = 1
elseif flags.v6.jungles == true then
biometype = 2
else
biometype = 3
end
y = y + 0.3
form = form .. "label[0,"..(y+0.1)..";" .. fgettext("Biomes") .. "]"
y = y + 0.6
form = form .. "dropdown[0,"..y..";6.3;mgv6_biomes;"
for b=1, #mgv6_biomes do
form = form .. mgv6_biomes[b][1]
if b < #mgv6_biomes then
form = form .. ","
end
end
form = form .. ";" .. biometype.. "]"
-- biomeblend
y = y + 0.55
form = form .. "checkbox[0,"..y..";flag_mgv6_biomeblend;" ..
fgettext("Biome blending") .. ";"..strflag(flags.v6, "biomeblend").."]" ..
"tooltip[flag_mgv6_biomeblend;" ..
fgettext("Smooth transition between biomes") .. "]"
return form, y
end
current_seed = core.formspec_escape(current_seed)
local y_start = 0.0
local y = y_start
local str_flags, str_spflags
local label_flags, label_spflags = "", ""
y = y + 0.3
str_flags, y = mg_main_flags(current_mg, y)
if str_flags ~= "" then
label_flags = "label[0,"..y_start..";" .. fgettext("Mapgen flags") .. "]"
y_start = y + 0.4
else
y_start = 0.0
end
y = y_start + 0.3
str_spflags = mg_specific_flags(current_mg, y)
if str_spflags ~= "" then
label_spflags = "label[0,"..y_start..";" .. fgettext("Mapgen-specific flags") .. "]"
end
-- Warning if only devtest is installed
local devtest_only = ""
local gamelist_height = 2.3
if #pkgmgr.games == 1 and pkgmgr.games[1].id == "devtest" then
devtest_only = "box[0,0;5.8,1.7;#ff8800]" ..
"textarea[0.3,0;6,1.8;;;"..
fgettext("Warning: The Development Test is meant for developers.") .. "\n" ..
fgettext("Download a game, such as Minetest Game, from minetest.net") .. "]"
gamelist_height = 0.5
end
local retval =
"size[12.25,7,true]" ..
-- Left side
"container[0,0]"..
"field[0.3,0.6;6,0.5;te_world_name;" ..
fgettext("World name") ..
";" .. core.formspec_escape(worldname) .. "]" ..
"field[0.3,1.7;6,0.5;te_seed;" ..
fgettext("Seed") ..
";".. current_seed .. "]" ..
"label[0,2;" .. fgettext("Mapgen") .. "]"..
"dropdown[0,2.5;6.3;dd_mapgen;" .. mglist .. ";" .. selindex .. "]" ..
"label[0,3.35;" .. fgettext("Game") .. "]"..
"textlist[0,3.85;5.8,"..gamelist_height..";games;" ..
pkgmgr.gamelist() .. ";" .. gameidx .. ";false]" ..
"container[0,4.5]" ..
devtest_only ..
"container_end[]" ..
"container_end[]" ..
-- Right side
"container[6.2,0]"..
label_flags .. str_flags ..
label_spflags .. str_spflags ..
"container_end[]"..
-- Menu buttons
"button[3.25,6.5;3,0.5;world_create_confirm;" .. fgettext("Create") .. "]" ..
"button[6.25,6.5;3,0.5;world_create_cancel;" .. fgettext("Cancel") .. "]"
return retval
end
@@ -111,10 +367,10 @@ local function create_world_buttonhandler(this, fields)
local random_world_name = "Unnamed" .. random_number
worldname = random_world_name
end
local message = nil
core.settings:set("fixed_map_seed", fields["te_seed"])
local message
if not menudata.worldlist:uid_exists_raw(worldname) then
core.settings:set("mg_name",fields["dd_mapgen"])
message = core.create_world(worldname,gameindex)
@@ -149,11 +405,53 @@ local function create_world_buttonhandler(this, fields)
return true
end
for k,v in pairs(fields) do
local split = string.split(k, "_", nil, 3)
if split and split[1] == "flag" then
local setting
if split[2] == "mg" then
setting = "mg_flags"
else
setting = split[2].."_spflags"
end
-- We replaced the underscore of flag names with a dash.
local flag = string.gsub(split[3], "-", "_")
local ftable = core.settings:get_flags(setting)
if v == "true" then
ftable[flag] = true
else
ftable[flag] = false
end
local flags = table_to_flags(ftable)
core.settings:set(setting, flags)
return true
end
end
if fields["world_create_cancel"] then
this:delete()
return true
end
if fields["mgv6_biomes"] then
local entry = minetest.formspec_escape(fields["mgv6_biomes"])
for b=1, #mgv6_biomes do
if entry == mgv6_biomes[b][1] then
local ftable = core.settings:get_flags("mgv6_spflags")
ftable.jungles = mgv6_biomes[b][2].jungles
ftable.snowbiomes = mgv6_biomes[b][2].snowbiomes
local flags = table_to_flags(ftable)
core.settings:set("mgv6_spflags", flags)
return true
end
end
end
if fields["dd_mapgen"] then
core.settings:set("mg_name", fields["dd_mapgen"])
return true
end
return false
end
@@ -165,6 +463,6 @@ function create_create_world_dlg(update_worldlistfilter)
create_world_buttonhandler,
nil)
retval.update_worldlist_filter = update_worldlistfilter
return retval
end

View File

@@ -22,6 +22,7 @@ local function delete_content_formspec(dialogdata)
"size[11.5,4.5,true]" ..
"label[2,2;" ..
fgettext("Are you sure you want to delete \"$1\"?", dialogdata.content.name) .. "]"..
"style[dlg_delete_content_confirm;bgcolor=red]" ..
"button[3.25,3.5;2.5,0.5;dlg_delete_content_confirm;" .. fgettext("Delete") .. "]" ..
"button[5.75,3.5;2.5,0.5;dlg_delete_content_cancel;" .. fgettext("Cancel") .. "]"

Some files were not shown because too many files have changed in this diff Show More