joinspec.lua 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. joinspec = joinspec or {}
  2. joinspec.modpath = minetest.get_modpath("welcome_msg")
  3. -- Localize for performance.
  4. local vector_round = vector.round
  5. local math_floor = math.floor
  6. local PRIORITY_MESSAGE = "Fight Big Tech Censorship!"
  7. local PRIORITY_X_OFFSET = 1.4
  8. joinspec.data = {
  9. warning = "Welcome to the frontier, Stranger! You have arrived on Enyekala (Must Test), a complex, detailed survival-mode game built on top of the Minetest Engine (https://www.minetest.net/).\n\n" ..
  10. "Please read this text, as it contains important information about this server. You will need to scroll this text to read all of it. Once you have closed this formspec, you can reshow it by typing “/info” in the chat, without quotes.\n\n" ..
  11. "This is a heavily modded, hard-core PvP & PvE survival server. " ..
  12. "The only way to find greatness is to survive, mine, build, and fight your way up! " ..
  13. "There is no creative mode.\n\n" ..
  14. "As a new adventurer, you start in a dry and dreary place the old-timers call “The Outback”. This is the dimension of the Unreal, because nothing here lasts, and in time, all is forgotten …. Leaving this realm, and finding your way to the true world, is akin to a test of skill. If you can escape this place then it may be that you have a chance to overcome the much harder challenge of survival in the natural realm. Many will not make the attempt. For them, the place of the Unreal is reality enough, and there is no need to seek anything else. You, O Adventuring Stranger, must make your choice.\n\n" ..
  15. "Upon appearing in the Outback, your first order of business is to obtain a stone pick. Most stone here is unsuitable, but if you go rock prospecting you’ll find the right kind. You can pluck the dry shrubs to find sticks. Once you have a stone pick, you should locate some iron and build an iron pick. Craft yourself some armor while you’re at it, and the best sword you can lay hands on. Eventually, you will need to discover how to locate flint so that you can construct a flint and steel. This is what you’ll need in order to activate the dimensional gateway, which is your way out. The portal chamber is well-guarded, so you will need to fight your way through. In order to activate the portal, you must stand physically inside of it, and strike the obsidian with your flint and steel. The dimensional transfer takes a little time, and more guards may appear in the meanwhile, so you must be quick. Finally, if you get stuck in the Outback without suitable tools, you can use /spawn to return yourself to the spawnpoint.\n\n" ..
  16. "The above is a coarse outline of your path through the Outback. The patient adventurer may wish to make some detours. Survival in the overworld is much harder than making a living in the Outback. The better your supplies that you bring with you through the dimensional gate, the better your chances in the overworld will be. Consider stockpiling food, weaponry, rare items, farming materials, and most importantly, a BED. Keep in mind that the dimensional gateway is UNSTABLE. The portal’s exit coordinates change once every " .. randspawn.min_days .. " to " .. randspawn.max_days .. " realtime days, and you cannot rely on there being much (or even any) infrastructure to support you once you arrive at the other side! Until you meet others, this is hard-core PvE survival.\n\n" ..
  17. "Here is a warning: wait until sunrise to use the Outback’s dimensional gate. Do not use it at night!\n\n" ..
  18. "You may read the server’s webpage at http://arklegacy.duckdns.org/. " ..
  19. "On this site you will find the server rules, as well as an additional introduction to the world, a FAQ, " ..
  20. "some gameplay tips, and of course some maps of various locations. The website does not cover everything about Must Test—indeed it cannot—and part of the experience is about exploring, experimenting, and discovering undocumented stuff. Feel free to ask questions of the old-timers—but be careful! If you annoy them too much, you’d better beware lest they feed you to a Dungeon Master …. >:)\n\n" ..
  21. "Due to the way the mapgen generates ores (among other things), trade with other players comes highly recommended; " ..
  22. "sell what you don’t need and buy what you do. It is rare for one person to have convenient access to all available resources on this server, though with enough effort it can be done.\n\n" ..
  23. "Minegeld is currency here. " ..
  24. "You can trade gold, silver and copper ingots for minegeld at the Wild North Precious Metal Exchange, " ..
  25. "which is located in the northeast quarter of the city at 1238, -8748. Some long-time inhabitants have commissioned banks out of their own resources, which you can use as well.\n\n" ..
  26. "In order to register and preserve your account and player data, " ..
  27. "you must obtain a Proof of Citizenship. The recipe is in the craft guide. Once you have crafted your Proof of Citizenship (PoC) you must keep it in your MAIN inventory at all times. Without it, the server will erase your account. This happens every Sunday when the system is purged of excess player data. Note that later you can upgrade your PoC to a Key, which provides a number of useful features for experienced adventurers, as well as a way to communicate with offline players (via in-game mail).\n\n" ..
  28. "This server makes use of the latest Minetest APIs, therefore a recent client is recommended.",
  29. version = minetest.get_version(),
  30. }
  31. local COLOR_ORANGE = core.get_color_escape_sequence("#ff3621")
  32. function joinspec.on_joinplayer(player)
  33. -- Do not show joinspec to players who are dead on join.
  34. -- It causes the 'respawn' formspec (shown automatically by the client)
  35. -- to disappear, and the player can never respawn.
  36. local pname = player:get_player_name()
  37. local pos = player:get_pos()
  38. if player:get_hp() > 0 then
  39. local result = passport.player_registered(pname)
  40. local haskey = passport.player_has_key(pname)
  41. joinspec.show_formspec(pname, result, haskey)
  42. else
  43. minetest.log("error", "Player " .. pname .. " joined while dead! Not showing welcome formspec.")
  44. -- Force respawn player in Outback (bypass bed code for simplicity's sake)
  45. -- if player joins while dead. This nixes a 'disconnect on death' hack.
  46. -- An uncracked client will still display the respawn formspec, and the
  47. -- player will respawn again in their bed after pressing the button.
  48. randspawn.reposition_player(pname, pos)
  49. end
  50. if rc.current_realm_at_pos(pos) == "abyss" then
  51. -- If player logs in (or spawns) in the Outback, then show them the reset
  52. -- timeout after 30 seconds.
  53. minetest.after(30, function()
  54. local days1 = math_floor(serveressentials.get_outback_timeout() / (60*60*24))
  55. local days2 = math_floor(randspawn.get_spawn_reset_timeout() / (60*60*24))
  56. local s1 = "s"
  57. local s2 = "s"
  58. if days1 == 1 then s1 = "" end
  59. if days2 == 1 then s2 = "" end
  60. minetest.chat_send_player(pname,
  61. core.get_color_escape_sequence("#ffff00") ..
  62. "# Server: In " .. days1 .. " day" .. s1 ..", the dry winds of the Outback will cease. Then all begins again.")
  63. minetest.chat_send_player(pname,
  64. core.get_color_escape_sequence("#ffff00") ..
  65. "# Server: The unstable Dimensional Gate will shift its exit location in " .. days2 .. " day" .. s2 .. ".")
  66. end)
  67. end
  68. end
  69. function joinspec.generate_formspec(pname, returningplayer, haskey)
  70. local formspec = ""
  71. if returningplayer then
  72. -- Returning player.
  73. formspec = formspec ..
  74. "size[7,4.9]" ..
  75. default.gui_bg ..
  76. default.gui_bg_img ..
  77. default.gui_slots
  78. formspec = formspec ..
  79. "box[0,0;6.8,2;#101010FF]" ..
  80. "image[0.4,0.1;7.3,2.1;musttest_game_logo.png]"
  81. formspec = formspec ..
  82. "label[0,2.1;Server: ‘Must Test’ @ minetest:arklegacy.duckdns.org:30000]"
  83. formspec = formspec ..
  84. "label[0,2.6;Greetings <" .. pname .. ">. Welcome back to the frontier!]"
  85. local logintime = "Your last login time is unknown!"
  86. local pauth = core.get_auth_handler().get_auth(pname)
  87. if pauth and pauth.last_login then
  88. local days = math_floor((os.time() - pauth.last_login) / (60 * 60 * 24))
  89. logintime = "Your last login was on " .. os.date("!%Y/%m/%d, %H:%M UTC", pauth.last_login) .. " "
  90. if days <= 0 then
  91. logintime = logintime .. "(Today)"
  92. elseif days == 1 then
  93. logintime = logintime .. "(Yesterday)"
  94. else
  95. logintime = logintime .. "(" .. days .. " Days Ago)"
  96. end
  97. end
  98. logintime = minetest.formspec_escape(logintime)
  99. formspec = formspec ..
  100. "label[0,3.1;" .. logintime .. "]"
  101. -- Exit buttons.
  102. formspec = formspec ..
  103. "button[0,3.8;2,1;wrongserver;Not Now]" ..
  104. "button[2,3.8;2,1;trading;Trading]" ..
  105. "button[5,3.8;2,1;playgame;Proceed!]"
  106. if haskey then
  107. formspec = formspec ..
  108. "button[4,3.8;1,1;passport;Key]"
  109. end
  110. formspec = formspec ..
  111. "label[" .. PRIORITY_X_OFFSET .. ",4.7;" .. minetest.formspec_escape(COLOR_ORANGE ..
  112. "Priority: " .. PRIORITY_MESSAGE) .. "]"
  113. else
  114. -- New player.
  115. formspec = formspec ..
  116. "size[7,8.3]" ..
  117. default.gui_bg ..
  118. default.gui_bg_img ..
  119. default.gui_slots
  120. formspec = formspec ..
  121. "box[0,0;6.8,2;#101010FF]" ..
  122. "image[0.4,0.1;7.3,2.1;musttest_game_logo.png]"
  123. local warning = minetest.formspec_escape(joinspec.data.warning)
  124. formspec = formspec ..
  125. "textarea[0.3,2.3;7,5.6;warning;;" .. warning .. "]"
  126. -- Exit buttons.
  127. formspec = formspec ..
  128. "button[0,7.3;2,1;wrongserver;" .. minetest.formspec_escape("I’m Scared ...") .. "]" ..
  129. "button[2,7.3;2,1;trading;Tradernet]" ..
  130. "button[4,7.3;3,1;playgame;Accept Challenge!]"
  131. formspec = formspec ..
  132. "label[" .. PRIORITY_X_OFFSET .. ",8.1;" .. minetest.formspec_escape(COLOR_ORANGE ..
  133. "Priority: " .. PRIORITY_MESSAGE) .. "]"
  134. end
  135. return formspec
  136. end
  137. function joinspec.show_formspec(pname, returningplayer, haskey)
  138. local formspec = joinspec.generate_formspec(pname, returningplayer, haskey)
  139. minetest.show_formspec(pname, "joinspec:main", formspec)
  140. end
  141. function joinspec.on_receive_fields(player, formname, fields)
  142. if formname ~= "joinspec:main" then
  143. return
  144. end
  145. local pname = player:get_player_name()
  146. if fields.playgame then
  147. minetest.close_formspec(pname, "joinspec:main")
  148. end
  149. if fields.wrongserver then
  150. minetest.kick_player(pname, "You pressed the 'Leave Server' button. ;-)")
  151. minetest.chat_send_all("# Server: <" .. rename.gpn(pname) .. "> was kicked off the server.")
  152. end
  153. if fields.passport then
  154. passport.open_keys[pname] = true
  155. ambiance.sound_play("fancy_chime1", player:get_pos(), 1.0, 20, "", false)
  156. passport.show_formspec(pname)
  157. end
  158. if fields.trading then
  159. local pos = vector_round(player:get_pos())
  160. ads.show_formspec(pos, pname, false)
  161. end
  162. return true
  163. end
  164. function joinspec.show_info(pname, param)
  165. joinspec.show_formspec(pname, false)
  166. end
  167. if not joinspec.run_once then
  168. minetest.register_on_joinplayer(function(...)
  169. return joinspec.on_joinplayer(...)
  170. end)
  171. minetest.register_on_player_receive_fields(function(...)
  172. return joinspec.on_receive_fields(...)
  173. end)
  174. minetest.register_chatcommand("info", {
  175. params = "",
  176. description = "(Re)show the server's welcome formspec, with basic server information.",
  177. privs = {},
  178. func = function(...)
  179. joinspec.show_info(...)
  180. return true
  181. end,
  182. })
  183. local c = "joinspec:core"
  184. local f = joinspec.modpath .. "/joinspec.lua"
  185. reload.register_file(c, f, false)
  186. joinspec.run_once = true
  187. end