You are browsing as a guest. Sign up (or log in) to start making projects!

timon

@timon

Joined June 8th, 2026

  • 29Devlogs
  • 10Projects
  • 6Ships
  • 75Votes
Open comments for this post

1h 41m 53s logged

Whats new:

-An extra inventory tab for the items that the mods adds
-Registered the crafting recipe
-Feature of sapphire added


The creation of the new Tab was pretty easy. I only needed to register it with
“CreativeModeTab = Registry.register”
then just add every item in this format:

output.accept(ModItems.SAPPHIRE)
output.accept(ModItems.MOONSTONE)


The custom recipes were a bit more difficult.

I created SapphireUpgradeRecipe. It scans the crafting grid to check if the center slot has an item with durability, surrounded by Sapphires. Inside assemble(), it copies the item and calculates a +20% increase to its MAX_DAMAGE.

I first was confused because i thought damage would be the damage you are dealing with it (just like in the ItemEdit Plugin or Paper)
Though, the damage on the item is meant. So basically the durability.

val currentMax = result.maxDamage
val newMax = currentMax + ceil(currentMax * 0.20).toInt().coerceAtLeast(1)
result.set(DataComponents.MAX_DAMAGE, newMax)


In MoonstoneUpgradeRecipe, when you craft a item with 8 Moonstones around it, it attaches a custom NBT marker (crystalcave_moonstone_upgrade) to the item’s data components.
I will add a ServerTickEvents event loop in the future which then will target every monster in a 64 block radius or soemthing like that.

0
0
3
Open comments for this post

1h 5m 6s logged

I registered new blocks and items. It was difficult to find how to register these. In my mods before ive never added new blocks biomes ore anything like that.
As the unobfuscated versions of minecraft arent out that long, it is difficult to find good documentations of the class names.

I first tried fabrics AbstractBlock settings which looked like this:

val SAPPHIRE_ORE = registerBlock(
“sapphire_ore”,
Block(AbstractBlock.Settings.create()
.mapColor(MapColor.STONE_GRAY)
.instrument(Instrument.BASE_DRUM)
.requiresTool()
.strength(3.0f, 3.0f)
.sounds(BlockSoundGroup.STONE))
)

After asking Gemini and telling it that I am working with the latest minecraft version (and that it is NOT 1.21.4) I made the system use lateinit var and an helper function.

1
0
8
Ship Pending review

I created a terminal based password manager with integrated 2FA TOTP authentication written in Python. It can store passwords, generate random passwords, scan QR codes for 2FA setup and display current TOTP codes.
I started this project, because it annoyed me that everytime I had to Authenticate with TOTP, I needed to grab my phone.
With this, i just need to click a few times on my PC and i have my current TOTP Security Code.

The most challenging parts were implementing secure encryption, with the master password system, and adding TOTP authentification. I havent done anything before with encryption except in school a bit and i needed to look up, what methods are common what is good what not.

I am proud that i learned alot through this project. I could use a bit of my school knowledge which made me happy that moment and I like that it is done now.

(More details in the readme...) To test the project you need Python installed and have to install the required dependencies. After starting the program, they can create a master password and use the menu to add, search, and manage password entries.

  • 5 devlogs
  • 16h
Try project → See source code →
Open comments for this post

3h 30m 21s logged

Completed the 2FA implementation and added QR code support. You can now import the 2FA QR Code and you will see the current secret code.
The biggest challenge was reading QR codes right everytime. I didnt know that opencv only reads qr codes with a white border, so some qr code did work and some didnt. This is why i added:

white = [255, 255, 255]
img_with_border = cv2.copyMakeBorder(
img, 20, 20, 20, 20,
borderType=cv2.BORDER_CONSTANT,
value=white
)

Which adds a white border around the qr code.

0
0
3
Open comments for this post

4h 20m 49s logged

I started working in the implementation for 2FA totp code generator. This works because the totp qr code wont change for the account so you can implement it once in the password manager. I updated the tables to show a new 2FA column. The program can now generate a TOTP code if a secret is available. I also started adding QR code support so users can import their 2FA setup instead of entering the secret manually. Right now not every qr code is working and im trying to figure out why for like an hour…

current_code = generate_current_totp(details.get(“totp_secret”, “-”))

Also my muffin head wrote everything in german.. Needed to change it again…

0
0
1
Open comments for this post

3h 35m 36s logged

I added a dictionary where the .json file will be saved, so its not in the same folder as the .py.
For that i used the package PlatformDirs:

dirs = PlatformDirs(“TokenShield”, ensure_exists=True)

After texting i noticed, that there is no way in chaning the master password and no way in deleting a entry.
Entry Deletion (Option 4): Users can now completely remove an app entry from their vault. It also has a confirmation (y/n) to prevent accidental deletion

Master Password Change (Option 5): Added a way to update the master password. It decrypts the vault using the old password and generates a new one.

It was challenging to make the password change. I had to ensure the vault was fully decrypted first, then generate a brand new random (os.urandom(16)) for encryptiom and immediately re encrypt everything with the new key.

0
0
2
Open comments for this post

2h 33m 43s logged

I replaced all of the saving code that saved the pw in cleartext with real encryption to make it secure.

I used the cryptography library and Imported Fernet and hashing tools (PBKDF2HMAC) to do the encryption.

I also used Key Derivation and Added a function that takes the master password and hashes it 480.000 times and also with a random salt.

I uses AES-256 which takes a 256-bit and uses it to encrypt your vault data by transforming it into 128 bit blocks. Also gemini helped me with that.

kdf = PBKDF2HMAC(
algorithm=hashes.SHA256(),
length=32, # 32 bytes = 256 bits
salt=salt,
iterations=480000,
)
aes_key = base64.urlsafe_b64encode(kdf.derive(master_password.encode()))

0
0
4
Open comments for this post

2h 12m 28s logged

I started with a raw prototype. I built a simple terminal menu, a basic random password generator using Python’s secrets module, and a straightforward way to load and save unencrypted JSON data. It worked, but it was completely replaceable by any other online website…

Next, I integrated that you can add your own passwords, usernames and notes. I also The rich library to make the terminal look beautiful with custom tables. I also implemented the search feature so users could find specific accounts instead of just looking at everything, and I replaced the passwords in the main list (••••••••) and you need to search fot the specific programm. I think its better this way but others might disagree.

I added the getpass module so that when you type a password and spedifically the main password, the characters are completely hidden in the terminal.

Right now, the app is not fully encrypted yet, but I build a structure that will hopefulyl help me.

For the readability Instead of saving accounts directly at the top level of the JSON file, I moved them into a dedicated entries dictionary.

Master Password Integration: The app now requires a master password immediately upon boot. It checks this password against the JSON file before unlocking the menu.

Right now everything is just in the json file in clear text. i want to change that for the next devlog.
Right Now:

def load_vault(master_password: str) -> dict:
“”“Loads the vault and checks the password in plain text (Simulated).”””
if not os.path.exists(DB_FILE):
return {“cipher”: “VERSCHLÜSSELUNG_CIPHER”, “entries”: {}}

with open(DB_FILE, "r") as f:
    data = json.load(f)

# Checking the password in plain text for now
if data.get("passwort_schutz") != master_password:
    console.print("\n[bold red] Wrong password![/bold red]\n")
    return None

return {"cipher": data.get("cipher", "VERSCHLÜSSELUNG_CIPHER"), "entries": data.get("entries", {})}
0
0
3
Open comments for this post

2h 1m 1s logged

I rebuilt it to the correct size and hopefully an centered display. I am also working on a design. I use Figma for the first time and that resizing tool is horrible in my opinion. When you rezise it by the window, it wont be native and if you do it by the reszising tool, then the new smaller or bigger size wil lekome 1x. I personally dont like that. Maybe others do

0
0
2
Open comments for this post

1h 42m 41s logged

The whole Record a timelapse was really weird for me and it didnt work that well but now I can show much things in one post…

I started with getting in Idea. I looked at other projects and insipred myself there for the layout. For the design i wanted to do something with Ninjago (cause when i look at it i will always see this holy tuffness..). I decided to go with 4 Keys, 2 Rotary Encoders and the OLED Display. I also used a matrix and i used the matrix not only for the rotary encoders knob pressing but also for the spinning so i ended up sving 3 Pins. In the first picture you see how it looked with only pressing matrix and in the second with the spinning too.

0
0
0
Ship

So i built a browser landing / new tab page. I didnt want it to be completely different because its still there to look something up. I added quick notes (whoch store in local data), weather widget and a simple clock. I chose the name Init system as its the first process that starts after the kernel and i think it matches to a new tab page as its also the first thing yk. i hope that makes sense. Feel free to use any of the code and maybe even learn from it :)

Try project → See source code →
Open comments for this post

1h 12m 24s logged

I added the weather widget. I had never worked with browser location data (navigator.geolocation) before, so getting the coordinates took a bit. Also it was pretty annoying to type all that cause the API sends back numbers like 67 (im so funny) instead of just saying “Rain”.
The docs helped me alot: https://open-meteo.com/en/docs

0
0
7
Open comments for this post

1h 57m 45s logged

The general design is done, just the javascript isnt done yet. I wanted the website to be a tab website that still can be used as the normal browser one so i added a search bar. You can also see the date and time really easy in the center and if you need the seconds its in the top right. I am now working on the notes thing down there.

The Clock was pretty easy as i just did a website where i did kinda the same. The notes thing is a bit more difficult but i also just did something in this way with my Homeserver dashboard 😅

0
0
2
Ship Pending review

I wanted to share a small library I just built as an addon for the Kyori Adventure API. I mainly make Paper pluginsand typing out ⁠Component.text()⁠ over and over for every time with hex colors is getting annoying. I wanted it simple and fast for my plugin projects.
That's why I created this! It adds a super easy ⁠cmp⁠ shortcut and automatically fixes missing ⁠#⁠ tags in hex codes so things dont break. For combining you use the ⁠+⁠ operator to append text.
This was my first time actually making a library. At the beginning it was pretty difficult. Though it was pretty easy now thinking back (the 2 hours lol) I would be super happy if anyone wants to check it out or even build onto it.

  • 1 devlog
  • 2h
Try project → See source code →
Open comments for this post

1h 42m logged

I actually finished it in one sitting so this is just everything but here I go: I made a library as an addon to the adventure api. I made it because it helps me with paper plugin making. started with a shortcut function called ⁠cmp⁠. You can now just type cmp instead of component.text. If you forget the ⁠#⁠ in a hex code (like ⁠”FF5555”⁠), Adventure usually breaks. The lib now checks for this and fixes it automatically.
You can now just use ⁠+⁠ to append components.

0
0
2
Ship

I built a utility hub featuring two main categories Chance & Decisions and Time & Progress. The idea came to me because I was constantly switching between different sites for tools. I realized that while I use these features every week, I always end up on a completely different website every time I search for them. So I decided to build a central hub where everything is in one place.
Im proud that I learned much JavaScript. Especially because the website includes multiple sites that some use similar but slightly different js code. It was a great way for me to learn even more becuase there were small differences which was perfect for the beginning!
Ofcourse everyone can / should use the code for themselves and maybe learn from it or create new things. ( Even though I can probably learn even more...). You can always add Issues in github and I will tryto fix them :) (i hope there arent any..)

  • 5 devlogs
  • 17h
  • 3.33x multiplier
  • 58 Stardust
Try project → See source code →
Open comments for this post

2h 50m 47s logged

I finished the Spin the wheel.
The logic itself wasnt too bad, but handeling with multipleclicks i didnt get that at first. If you clicked the “Turn” button while the wheel was already spinning, the animations would stack, the timer would go crazy, and the wheel would just glitch out.

I had to completely clean up the animation loop. (with ai troubleshooting) Now, every single time you hit that button, it instantly cancels the previous requestAnimationFrame and starts new again.

Once the wheel was done, I built two more tools. A Local Time clock and a World Time dashboard. While building them, I learned much… I used to write way too much code formatting dates and strings manually. Then I found out JavaScript has a built-in code for this:

document.getElementById(‘live-uhr’).textContent = now.toLocaleTimeString();

I dont even know how I didnt know about this..
Though, I do now…

0
0
9
Open comments for this post

9h 23m 14s logged

This is gonna be a big devlog, since i forgot to make one in between. I added two new features and i am currently working on the next one.

  1. Coinflip
    It is a minimalist coinflip feature where you just click a button and a animation comes which tells heads or tails. There was a Problem. At first when you would click throw multiple times while still in animation, the logic wouldnt work and the results from the first press of the button would come during the the animation of the (for example) fourth throw. To fix that i added

let isFlipping = false;
and
if (isFlipping) return; in the main function.

  1. How many days till
    You put in a date and it calcualtes for you, how many days, hours and minutes it is till that date (00:00 time). The problem was with the time zones so i added:

const targetDate = new Date(targetDateInput.value + “T00 : 00 : 00); (dont wonder it would be without spaces between the zeors but it wont let me here in the devlog menu)

The third one will be a spin the wheel feature, where you can add your own names and it will pick one. Though, im currently struggeling with the java script…

so that the browser would always assume local time midnight!

0
0
6
Open comments for this post

2h 46m 30s logged

Final homepage (probably). I finished how to topics will look in the grid and i am currently working on the first site “Random Number”. Its just an easy random number, where you pick the min and max number. The design of the element is nearly done and then im going to work on the java script for the Randomness :)

0
0
6
Open comments for this post

5h 36m 19s logged

At first, adding or deleting service cards required manually hardcoding HTML into the index.html file. Now, the dashboard is fully dynamic! You can manage your services directly via the “+ Add Service” button / ui and all data is instantly saved in the browser’s localStorage,

Though, when moving from hardcoded files to user inputs, you openup two dangerous vulnerabilities: XSS (Cross-Site Scripting) and URL Script Injection (e.g. entering javascript:alert(‘test’) into the URL field to execute code). To fix that, I changed the saving logic. Here is what I added:

if (!url.toLowerCase().startsWith(‘http://’) && !url.toLowerCase().startsWith(‘https://’)) {

return alert(’The URL must start with http:// or https:// ’);

}

So now it has to start with http:// or https:// and you cant add code because it would just open a website.

0
0
5
Loading more…

Followers

Loading…