From 2dd6e44c3cda0707e00468957d8eb04102cac3db Mon Sep 17 00:00:00 2001 From: rainer Date: Thu, 12 Feb 2026 12:51:00 +0100 Subject: [PATCH] init --- .github/workflows/pre-commit.yml | 25 +++++ .luacheckrc | 31 ++++++ .pre-commit-config.yaml | 19 ++++ LICENSE.txt | 21 ++++ README.md | 11 ++ init.lua | 148 +++++++++++++++++++++++++ locale/envelopes.de.tr | 19 ++++ mod.conf | 7 ++ textures/envelopes_envelope_blank.png | Bin 0 -> 561 bytes textures/envelopes_envelope_opened.png | Bin 0 -> 634 bytes textures/envelopes_envelope_sealed.png | Bin 0 -> 569 bytes 11 files changed, 281 insertions(+) create mode 100644 .github/workflows/pre-commit.yml create mode 100644 .luacheckrc create mode 100644 .pre-commit-config.yaml create mode 100644 LICENSE.txt create mode 100644 README.md create mode 100644 init.lua create mode 100644 locale/envelopes.de.tr create mode 100644 mod.conf create mode 100644 textures/envelopes_envelope_blank.png create mode 100644 textures/envelopes_envelope_opened.png create mode 100644 textures/envelopes_envelope_sealed.png diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml new file mode 100644 index 0000000..9d5b459 --- /dev/null +++ b/.github/workflows/pre-commit.yml @@ -0,0 +1,25 @@ +name: pre-commit +on: [push, pull_request, workflow_dispatch] + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@master + - uses: actions/setup-python@master + + - name: install luarocks + run: sudo apt-get install -y luarocks + + - name: luacheck install + run: luarocks install --local luacheck + + - name: add luacheck path + run: echo "$HOME/.luarocks/bin" >> $GITHUB_PATH + + - name: Install pre-commit + run: pip3 install pre-commit + + - name: Run pre-commit + run: pre-commit run --all-files diff --git a/.luacheckrc b/.luacheckrc new file mode 100644 index 0000000..644efe9 --- /dev/null +++ b/.luacheckrc @@ -0,0 +1,31 @@ +std = "lua51+luajit+minetest+envelopes" +unused_args = false +max_line_length = 120 + +stds.minetest = { + read_globals = { + "DIR_DELIM", + "minetest", + "core", + "dump", + "vector", + "nodeupdate", + "VoxelManip", + "VoxelArea", + "PseudoRandom", + "ItemStack", + "default", + "table", + "math", + "string", + } +} + +stds.envelopes = { + globals = { + "envelopes", + }, + read_globals = { + "canonical_name", + }, +} diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..1b81d73 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,19 @@ +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v3.3.0 + hooks: + - id: fix-byte-order-marker + - id: end-of-file-fixer + - id: trailing-whitespace + + - id: mixed-line-ending + args: [ --fix=lf ] + + - repo: local + hooks: + - id: luacheck + name: luacheck + language: system + entry: luacheck + pass_filenames: false + args: [-q,.] diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..7546a59 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 archfan + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..93f2046 --- /dev/null +++ b/README.md @@ -0,0 +1,11 @@ +# minetest-envelopes +Envelope mod for Minetest. https://minetest.net/ + +# How to use +Blank envelopes are crafted with 6 paper. Punch with a blank envelope to open the letter-wrting formspec, which +allows you to specify an addressee, letter text, and an optional "Attn." field which will be displayed in the +envelope description. Once writing is complete, the envelope is sealed by pressing the "Seal" button. The blank +envelope is then replaced by a sealed envelope which shows the sender, addressee, and optionally the Attn. field in +the description. If the addressee punches with the sealed envelope, it will become an opened envelope, which, once +punched, shows a formspec with the text. While a sealed envelope is only openable by the addressee, an opened +envelope can be read by anyone - thus, secret correspondence should be pulverized. diff --git a/init.lua b/init.lua new file mode 100644 index 0000000..c1a8b36 --- /dev/null +++ b/init.lua @@ -0,0 +1,148 @@ +if minetest.get_translator then + S = minetest.get_translator(minetest.get_current_modname()) +else + -- Fallback for older Minetest versions + S = function(str) return str end +end + +local f = string.format + +local has_canonical_name = minetest.get_modpath("canonical_name") + +minetest.register_craftitem("envelopes:envelope_blank", { + description = S("Blank Envelope"), + inventory_image = "envelopes_envelope_blank.png", + on_use = function(itemstack, user, pointed_thing) + minetest.show_formspec(user:get_player_name(), "envelopes:input", + "size[5.5,5.5]" .. + "field[2,0.5;3.5,1;addressee;"..S("Addressee")..";]" .. + "label[0,0;"..S("Write a letter").."]" .. + "textarea[0.5,1.5;5,3;text;"..S("Text")..";]" .. + "field[3,4.8;2.5,1;attn;"..S("Attn. (Optional)")..";]" .. + "button_exit[0.25,4.5;2,1;exit;"..S("Seal").."]") + return itemstack + end +}) + +minetest.register_craftitem("envelopes:envelope_sealed", { + description = S("Sealed Envelope"), + inventory_image = "envelopes_envelope_sealed.png", + stack_max = 1, + groups = {not_in_creative_inventory = 1}, + on_use = function(itemstack, user, pointed_thing) + local user_name = user:get_player_name() + local meta = itemstack:get_meta() + local addressee = meta:get_string("receiver") + + if has_canonical_name then + addressee = canonical_name.get(addressee) + end + + if user_name == addressee then + local open_env = ItemStack("envelopes:envelope_opened") + local open_meta = open_env:get_meta() + open_meta:set_string("sender", meta:get_string("sender")) + open_meta:set_string("receiver", meta:get_string("receiver")) + open_meta:set_string("text", meta:get_string("text")) + local desc = S("Opened Envelope") .. "\n" .. S("To: @1", meta:get_string("receiver")) .. "\n" .. S("From: @1", meta:get_string("sender")) + open_meta:set_string("description", desc) + if meta:get_string("attn") ~= "" then + open_meta:set_string("attn", meta:get_string("attn")) + desc = desc .. "\n" .. S("Attn: @1", meta:get_string("attn")) + open_meta:set_string("description", desc) + end + return open_env + + else + minetest.chat_send_player(user_name, S("The seal can only be opened by @1!", addressee)) + return itemstack + end + end +}) + +minetest.register_craftitem("envelopes:envelope_opened", { + description = S("Opened Envelope"), + inventory_image = "envelopes_envelope_opened.png", + stack_max = 1, + groups = {not_in_creative_inventory = 1}, + on_use = function(itemstack, user, pointed_thing) + local meta = itemstack:get_meta() + local sender = meta:get_string("sender") + local receiver = meta:get_string("receiver") + local text = meta:get_string("text") + local attn = meta:get_string("attn") or "" + local form = + "size[5,5]" .. + "label[0,0;" .. S("A letter from @1 to @2", sender, receiver) + if attn ~= "" then + form = form .. "\n" .. S("Attn: @1", attn) + end + form = form .. "\n" .. text .. "]" .. "button_exit[0,4;2,1;exit;"..S("Close").."]" + minetest.show_formspec(user:get_player_name(), "envelope:display", form) + end +}) + +minetest.register_on_player_receive_fields(function(player, formname, fields) + if formname ~= "envelopes:input" or not minetest.is_player(player) then + return false + end + + local sender_name = player:get_player_name() + + local addressee = (fields.addressee or ""):trim() + local text = (fields.text or ""):trim() + local attn = (fields.attn or ""):trim() + + if addressee == "" or text == "" then + minetest.chat_send_player(sender_name, S("Please fill out all required fields.")) + return true + end + + if has_canonical_name then + addressee = canonical_name.get(addressee) or addressee + end + + if not minetest.player_exists(addressee) then + minetest.chat_send_player(sender_name, S("Unknown addressee: @1", addressee)) + return true + end + + local inv = player:get_inventory() + local letter = ItemStack("envelopes:envelope_sealed") + local blank = ItemStack("envelopes:envelope_blank") + local meta = letter:get_meta() + + meta:set_string("sender", sender_name) + meta:set_string("receiver", addressee) + meta:set_string("text", text) + + local desc = S("Sealed Envelope") .. "\n" .. S("To: @1", addressee) .. "\n" .. S("From: @1", sender_name) + + if attn ~= "" then + meta:set_string("attn", attn) + desc = desc .. "\n" .. S("Attn: @1", attn) + end + + meta:set_string("description", desc) + + if inv:room_for_item("main", letter) and inv:contains_item("main", blank) then + inv:add_item("main", letter) + inv:remove_item("main", blank) + else + minetest.chat_send_player(sender_name, S("Unable to create letter! Check your inventory space.")) + end + + return true +end) + +if minetest.get_modpath("default") then + minetest.register_craft({ + type = "shaped", + output = "envelopes:envelope_blank 1", + recipe = { + {"", "", ""}, + {"default:paper", "default:paper", "default:paper"}, + {"default:paper", "default:paper", "default:paper"} + } + }) +end diff --git a/locale/envelopes.de.tr b/locale/envelopes.de.tr new file mode 100644 index 0000000..bfdf84d --- /dev/null +++ b/locale/envelopes.de.tr @@ -0,0 +1,19 @@ +# textdomain: envelopes + +Blank Envelope=Leerer Umschlag +Sealed Envelope=Versiegelter Umschlag +Opened Envelope=Geöffneter Umschlag +Write a letter=Brief schreiben +Addressee=Empfänger +Text=Text +Attn. (Optional)=Betreff (Optional) +Seal=Versiegeln +Close=Schließen +To: @1=An: @1 +From: @1=Von: @1 +Attn: @1=Betreff: @1 +The seal can only be opened by @1!=Das Siegel kann nur von @1 geöffnet werden! +A letter from @1 to @2=Ein Brief von @1 an @2 +Please fill out all required fields.=Bitte fülle alle benötigten Felder aus. +Unknown addressee: @1=Unbekannter Empfänger: @1 +Unable to create letter! Check your inventory space.=Brief konnte nicht erstellt werden! Überprüfe dein Inventar. diff --git a/mod.conf b/mod.conf new file mode 100644 index 0000000..297483f --- /dev/null +++ b/mod.conf @@ -0,0 +1,7 @@ +name = envelopes +title = Envelopes +description = Provides envelopes and sealed letters, which can only be opened by the addressee. +author = archfan7411 +license = MIT +version = 2022-10-25 +optional_depends = default, canonical_name diff --git a/textures/envelopes_envelope_blank.png b/textures/envelopes_envelope_blank.png new file mode 100644 index 0000000000000000000000000000000000000000..f50902b6a5af13c5cf2f5495697784c1e3745270 GIT binary patch literal 561 zcmV-10?z%3P)e zSad^gZEa<4bO1wgWnpw>WFU8GbZ8()Nlj2!fese{00EgvL_t(I%e9j~YrPH+cpsq^?JRRAa9?|d_Jd2r2@tn06^DutX3;}31Hhcsj3Rk z^S~H`EX#=F80B&qEu#bObRF{Dx{2!enx3?Ygl?)N+D^*Uy=8T|;j-EN4Y z2>bmWNs@puhD;`dAP8{1Ug3Ejs?{ni%c7@%Mx!BYw_6YqE|&{9=KuiLb#XeKkjv$8 zJRVW2)i9Y%=xGP7R!eXk2fptk2m;8mj3|l_MG?X<1m_%w!{Hl5_!_C-?~|r!2*VIb zlHl=pKv5K&&u3(_StyEv-EId>)1d3R@U&UOFlf14lIyzU`#!~SOpGxiBI2AA5z%ls zq^Ai!)a`buR4PG|Boqn-NRkB3InwDgMxzm$&8F}x000Jq0ja8rd_E6R6hTC=EDP;+ zTX^}kJDme zSad^gZEa<4bO1wgWnpw>WFU8GbZ8()Nlj2!fese{00H7jL_t(I%e9j+OCv!P$A4?i zWmgv>3lU5qX%<47wX^k0Sf(<~eu)(M66v%E$aYFPv9L2~MAI1Tth5-&8c3WCv+KJe zaqqnIj^mDdFwF3n`OUol{2%;dSf3>?E-s`}sW7^``;aehZ2{0|GytgA>(-Ya4_{qf z$-%(^y% zBuQwu+e^q^NUAkDO_#IQA78LoESOHGJU%{>Wf{g8Ha9m>N)biTH^}QdBxSnNU=85# z@X)%wy+uUOT9fBF0NrjEfGCPkN)hg@%1K`f-3kqkj*hJHc#Kkt$z+1(c|=iEK!8G% zRO{kPfAT@E*OMR!NRoss%XoWx!}on=vl-=b8Q=GLcz7TP0ve6Rr#>Q%V;K&I^7Qm1 zN-3Go=VFWz5s^I4MMUK6>`Z>?M1Yf%6RFqh*tSizTE(_)@;t|NUCz(XX*QeIZvg9b@)!5nDp;Rg%B3xcx(rUG=KW>)e<6{|*$8vLXBXJzdUv*r+-=G`P)e zSad^gZEa<4bO1wgWnpw>WFU8GbZ8()Nlj2!fese{00E&%L_t(I%e9leisAqig-^Cf z;S-3J+gXW?#effx)@~XLn+^VePaw=&SVh}_Aec%~i8fk@X%yWei6}ZEf@mR0lz6t; zk==D&WMRJUUhX{{?ho)8G@DHthQViQzx17mEeA+bv~TrlKf391fIa znZEC{)9E}GsaC5r41>L1kL&fC$K#Qzs?xS??shw_Rx6TZtJQieq9_Wx-7ZbjB z8^AY!wr$gK9Bwunl4PUN_)SFkH7J!zjKyMTzP#Y;&)giqxA%8kuU7y-Fc?I;-G(Gd z!rdA(nT%kX=AApsvM?Txv0N^Z%jMvC9;VYN?;L!fsw%&~z5)PpyBz|707OwlKA*qU zNRotPGARg;W>TqC7>Pt6iXuXx5JXXg@B1hgi%29ANTpK3UoY{4bUH1}=W}?T2iJ9R zI-TG+4&w3nt@$a+