From 3435f430d4d962e051e128e2270002cb63d7050a Mon Sep 17 00:00:00 2001 From: ngdplnk Date: Mon, 29 Jul 2024 23:15:47 -0400 Subject: [PATCH] bump to v24.07.29 before releasing v1.2 --- 1-release/main.py | 976 ++++++++++++++++++++++++++------ 2-development/dev.py | 361 ++++++------ 3-launcher/base.py | 1193 ++++++++++++++++++++++++++++++--------- 3-launcher/build.nsi | 36 +- 3-launcher/icon.ico | Bin 17064 -> 3200 bytes 3-launcher/icon.png | Bin 31464 -> 2772 bytes 3-launcher/launcher.pyw | 18 +- LICENSE | 2 +- README.md | 2 +- SECURITY.md | 3 +- 10 files changed, 1943 insertions(+), 648 deletions(-) diff --git a/1-release/main.py b/1-release/main.py index e335ad1..7c58849 100644 --- a/1-release/main.py +++ b/1-release/main.py @@ -1,6 +1,13 @@ -#!/usr/bin/env python3 +#### SSTOOLS4MC MAIN PROGRAM #### +#### DEVELOPED BY: NGDPLNK #### -# MÓDULOS IMPORTADOS - IMPORTED MODULES +### THINGS TO FIX +# - Download progressbar has a bug that when the console is untabbed, freezes and corrupts the file. +# - In specific conditions, the server startup cancelling with CTRL+C shows an unexpected screen from other function. + +##################### + +# MODULES import os import time import sys @@ -19,14 +26,14 @@ # PATHS APPDATA = os.getenv('APPDATA') -SSTOOLS_FOLDER = os.path.join(APPDATA, "TLSoftware", "SSTools4MC") # type: ignore +SSTOOLS_FOLDER = os.path.join(APPDATA, "SSTools4MC") # type: ignore CONFIG_PATH = os.path.join(SSTOOLS_FOLDER, "config") # type: ignore SAVED_SERVERS = os.path.join(CONFIG_PATH, "saved-servers.cfg") # type: ignore -# MINECRAFT VERSIONS -## 83 VERSIONS ADDED (1.2.1 - 1.20.6) -# LAST UPDATE: 29-04-2024 -MCVERSIONS = { +### MINECRAFT VERSIONS +## 84 STABLE VERSIONS ADDED (1.2.1 - 1.21) +# LAST UPDATE: 29-07-2024 +MCSTABLE = { "1.2.1": "https://assets.minecraft.net/1_2/minecraft_server.jar", "1.2.2": "https://assets.minecraft.net/1_2/minecraft_server.jar", "1.2.3": "https://assets.minecraft.net/1_2/minecraft_server.jar", @@ -113,27 +120,636 @@ "1.20.6": "https://piston-data.mojang.com/v1/objects/145ff0858209bcfc164859ba735d4199aafa1eea/server.jar", "1.21": "https://piston-data.mojang.com/v1/objects/450698d1863ab5180c25d7c804ef0fe6369dd1ba/server.jar" } +## 613 SNAPSHOT VERSIONS ADDED (1.3 - 1.21-rc1) +# LAST UPDATE: 29-07-2024 +MCSNAPSHOT = { + "1.3": "https://launcher.mojang.com/v1/objects/cb21a9aaaf599c94dd7fa1b777b2f0cc37a776c7/server.jar", + "1.4": "https://launcher.mojang.com/v1/objects/9470a2bb0fcb8a426328441a01dba164fbbe52c9/server.jar", + "1.4.1": "https://launcher.mojang.com/v1/objects/baa4e4a7adc3dc9fbfc5ea36f0777b68c9eb7f4a/server.jar", + "1.4.3": "https://launcher.mojang.com/v1/objects/9be68adf6e80721975df12f2445fa24617328d18/server.jar", + "1.5": "https://launcher.mojang.com/v1/objects/aedad5159ef56d69c5bcf77ed141f53430af43c3/server.jar", + "13w16a": "https://launcher.mojang.com/v1/objects/dd76b63bad493e42b303dd8952c240f330251760/server.jar", + "13w16b": "https://launcher.mojang.com/v1/objects/c125111764b5774403ff2183debbb9da4805a64f/server.jar", + "13w17a": "https://launcher.mojang.com/v1/objects/48ece561c3512b2f9c0915dad7c3cb65560ceb39/server.jar", + "13w18a": "https://launcher.mojang.com/v1/objects/6084eae41c6e28d58fe8a1ee4ab4389a392f0139/server.jar", + "13w18b": "https://launcher.mojang.com/v1/objects/af7fd5e8cdc610f1e533ba7963bc39de422df1b6/server.jar", + "13w18c": "https://launcher.mojang.com/v1/objects/3f8dc565567174d777a416f979901e0fee010d2a/server.jar", + "13w19a": "https://launcher.mojang.com/v1/objects/17997ee2d9a3ad1070a74707f58ebb3e3a46ae10/server.jar", + "13w21a": "https://launcher.mojang.com/v1/objects/a04b6f0349b8de64c68a9311b4eaff478e37b558/server.jar", + "13w21b": "https://launcher.mojang.com/v1/objects/f5236a7628c74c22c33f57b50cb755598042aa5b/server.jar", + "13w22a": "https://launcher.mojang.com/v1/objects/94b99928dccee27ad9b1d90bd00e8f68f38f92e4/server.jar", + "13w23a": "https://launcher.mojang.com/v1/objects/b26a278856a6a4703054ad266b79b1ef397676c2/server.jar", + "13w23b": "https://launcher.mojang.com/v1/objects/b6b627c0a5fe9f53a22892f21c473e19617c1c0d/server.jar", + "13w24a": "https://launcher.mojang.com/v1/objects/d0f1eb0455c1bc3f73d5fc7252e282fd614f1f5b/server.jar", + "13w24b": "https://launcher.mojang.com/v1/objects/9c312da9bdcc562dc57e235a7a56900148c77f8d/server.jar", + "13w25a": "https://launcher.mojang.com/v1/objects/e1c2e7376fe489c5eba744b010993c402ab3f3f2/server.jar", + "13w25b": "https://launcher.mojang.com/v1/objects/9f7f205d7c00098d9aa6abd67ce4f93d0eeddcd7/server.jar", + "13w25c": "https://launcher.mojang.com/v1/objects/0f21dbd39728a50843d1b20cf832f26aaada353d/server.jar", + "13w26a": "https://launcher.mojang.com/v1/objects/bafe11faf3419c8813beb948e353912239d50bc1/server.jar", + "1.6": "https://launcher.mojang.com/v1/objects/ee6d5161ac28eef285df571dc1235d48f03c3e88/server.jar", + "13w36a": "https://launcher.mojang.com/v1/objects/8453f031175bac1a92db000befd14f70c8df8fb7/server.jar", + "13w36b": "https://launcher.mojang.com/v1/objects/2b6cdcd2df82ca8f04c1c2c7d77faf4cd25151ea/server.jar", + "13w37a": "https://launcher.mojang.com/v1/objects/c3d3d936394b35f20b871b140f5a8e6079822e51/server.jar", + "1.6.3": "https://launcher.mojang.com/v1/objects/5a4c69bdf7c4a9aa9580096805d8497ba7721e05/server.jar", + "13w37b": "https://launcher.mojang.com/v1/objects/f6322a6791bbeabac94cbaa1cf9b779ad88b120f/server.jar", + "13w38a": "https://launcher.mojang.com/v1/objects/627585cdb9386e7f05cdfb8f092e5a303d4fd5f3/server.jar", + "13w38b": "https://launcher.mojang.com/v1/objects/82588f79a6a61c4c4289a9dc60b7b7b3fedaead9/server.jar", + "13w38c": "https://launcher.mojang.com/v1/objects/03081b4b569174ec68ef9cdd574ee4feca05dea5/server.jar", + "13w39a": "https://launcher.mojang.com/v1/objects/10e8687a623cb3def606fa3855aaed5ef79aac66/server.jar", + "13w39b": "https://launcher.mojang.com/v1/objects/1db7286055aeb35c709d98ace1c9cdc739206d5a/server.jar", + "13w41a": "https://launcher.mojang.com/v1/objects/fbe939a8a9246db801428e33a1c53506af637247/server.jar", + "13w41b": "https://launcher.mojang.com/v1/objects/d0f1808505d59bd69c47d8e0ce01dc5936d34c34/server.jar", + "13w42a": "https://launcher.mojang.com/v1/objects/d7007e5f46bb1ad4f4d38dc8cd2ea54898c6cccb/server.jar", + "13w42b": "https://launcher.mojang.com/v1/objects/1416ebe3d6e6aa62eaae305ce542c39b7dfcb2b9/server.jar", + "13w43a": "https://launcher.mojang.com/v1/objects/0fd72957ddbedd604d2bdf155dd03c8501c48f48/server.jar", + "1.7": "https://launcher.mojang.com/v1/objects/3f031ab8b9cafedeb822febe89d271b72565712c/server.jar", + "1.7.1": "https://launcher.mojang.com/v1/objects/d26d79675147253b7a35dd32dc5dbba0af1be7e2/server.jar", + "13w47a": "https://launcher.mojang.com/v1/objects/f3210daa0a05a88b8b8edadfc8af385ff3f88987/server.jar", + "13w47b": "https://launcher.mojang.com/v1/objects/7c1b69de43b6edf1d20f5030b88df78fd08ad8c7/server.jar", + "13w47c": "https://launcher.mojang.com/v1/objects/5cf618125f87452e665f0097171d089f73dc7e1c/server.jar", + "13w47d": "https://launcher.mojang.com/v1/objects/28982e580acf736120a4f1c3e7418e2a8daa3a8c/server.jar", + "13w47e": "https://launcher.mojang.com/v1/objects/0f08e81b37b2c06ead45f498a7c8efa10a02633a/server.jar", + "13w48a": "https://launcher.mojang.com/v1/objects/8f43e47eb288d3485f7825c422e9c5bcaf6418af/server.jar", + "13w48b": "https://launcher.mojang.com/v1/objects/9ab8a06fe77ed7f553ae3427d304e9f55de339d9/server.jar", + "13w49a": "https://launcher.mojang.com/v1/objects/164c350e011f491f6e12861ee4988ef2ccecfe0e/server.jar", + "14w02a": "https://launcher.mojang.com/v1/objects/b908214fb99891c4f1e77c21b1fcbe4f7cafdd58/server.jar", + "14w02b": "https://launcher.mojang.com/v1/objects/2f873b2fd721c9ed5ef51e80df96d10e5390ee9f/server.jar", + "14w02c": "https://launcher.mojang.com/v1/objects/c844eb4e22c6c0a3b87835fc61a508caeeced1f9/server.jar", + "14w03a": "https://launcher.mojang.com/v1/objects/5cbd5319a7b1198f049286d443148f1b88ff7bc7/server.jar", + "14w03b": "https://launcher.mojang.com/v1/objects/b8bee8cbf485aad0be9789fe58ab266d8fe82215/server.jar", + "14w04a": "https://launcher.mojang.com/v1/objects/bd483603d1b07d3ce3fde76a35abfb0489933d72/server.jar", + "14w04b": "https://launcher.mojang.com/v1/objects/7af6befa241678d09d4031fed5578785dd3c126d/server.jar", + "14w05a": "https://launcher.mojang.com/v1/objects/27abecb729cab3a6e11f635dae2cf9be5f620a75/server.jar", + "14w05b": "https://launcher.mojang.com/v1/objects/d2d2b00952748af9ee8e60f49b9998dcfad3071f/server.jar", + "14w06a": "https://launcher.mojang.com/v1/objects/a6a41979ed198086f2c8ae638f26286b2dc931db/server.jar", + "14w06b": "https://launcher.mojang.com/v1/objects/0591a5e7e299182c6849e705704095d2a1efe1d5/server.jar", + "14w07a": "https://launcher.mojang.com/v1/objects/de78ac487cf3fb6770e8c15f83e2219d4df851ae/server.jar", + "14w08a": "https://launcher.mojang.com/v1/objects/a2716623b9e2c01cf0a1ec44497cc3279fce8f6a/server.jar", + "14w10a": "https://launcher.mojang.com/v1/objects/03503dc8c3f615bf8b65d8e1ebbf923e81162e3e/server.jar", + "14w10b": "https://launcher.mojang.com/v1/objects/2dd525cb725635b94c763c2efa5e1fe931a0d6d6/server.jar", + "14w10c": "https://launcher.mojang.com/v1/objects/d97cc24dad232b5452644facde54c47854283b99/server.jar", + "1.7.6-pre1": "https://launcher.mojang.com/v1/objects/121176f19f38780d0cd04bef87c1296fedb37cd0/server.jar", + "1.7.6-pre2": "https://launcher.mojang.com/v1/objects/5aa5deddbe750a384bdb5ed0652bbda33cf4e5c8/server.jar", + "14w11a": "https://launcher.mojang.com/v1/objects/286924e7082ff1f6baed77a100f73abae81f25e3/server.jar", + "14w11b": "https://launcher.mojang.com/v1/objects/58694879e09c500dccb00751ed85a1d6b983229d/server.jar", + "14w17a": "https://launcher.mojang.com/v1/objects/701dca9511fa3e6b26799d11475fb3a719d6a26a/server.jar", + "14w18a": "https://launcher.mojang.com/v1/objects/48d6b3b47e870f61a95645e2bc1a84a27a1da068/server.jar", + "14w18b": "https://launcher.mojang.com/v1/objects/d7300a576860c056938760153cbf56ed98e9c7f9/server.jar", + "14w19a": "https://launcher.mojang.com/v1/objects/a7df79e00c4d75e3916438658839785a476bd6ac/server.jar", + "1.7.10-pre1": "https://launcher.mojang.com/v1/objects/db79ef4be8b37093c7ca4ddbd54ede2ca21d2a9f/server.jar", + "1.7.10-pre2": "https://launcher.mojang.com/v1/objects/ea9fdacf5b0eadfbec5f8aed89c4da3c6be87060/server.jar", + "1.7.10-pre3": "https://launcher.mojang.com/v1/objects/b9fdcbd17407d9eaeedcf4ff79b3121ee40133db/server.jar", + "1.7.10-pre4": "https://launcher.mojang.com/v1/objects/7c8249c626996c4474afe4f26071a91e7efd825a/server.jar", + "14w20a": "https://launcher.mojang.com/v1/objects/4dfd82a84113cfb7e4b489c52caa68bc3f21198e/server.jar", + "14w20b": "https://launcher.mojang.com/v1/objects/93ff3d1043ecf25eaf7c9626d8cbde7986dde65d/server.jar", + "14w21a": "https://launcher.mojang.com/v1/objects/7e26d5c2feb9df58353b942418640164a8cd0fbd/server.jar", + "14w21b": "https://launcher.mojang.com/v1/objects/b02c5506df94aa5d5200ef063f1bab22ce260c8a/server.jar", + "14w25a": "https://launcher.mojang.com/v1/objects/e22dedab430bc1c0f938a1e1a2811d11fe29f67e/server.jar", + "14w25b": "https://launcher.mojang.com/v1/objects/29209a8e73b6f4afa691d0682aa848c2a1f52dd7/server.jar", + "14w26a": "https://launcher.mojang.com/v1/objects/9d167e0b009b99d637ad102a1cb4f5aeb1501e45/server.jar", + "14w26b": "https://launcher.mojang.com/v1/objects/0b461d7af1194a192f5b7a9a8989bab83f7317b0/server.jar", + "14w26c": "https://launcher.mojang.com/v1/objects/247352905e446c66db85ecb26361a9b5a8eec4ea/server.jar", + "14w27a": "https://launcher.mojang.com/v1/objects/b5350953ff062646d4a61b7c8fb4c0570829843a/server.jar", + "14w27b": "https://launcher.mojang.com/v1/objects/c5be337237224f752b2ea09d3a2a00a00b26e14b/server.jar", + "14w28a": "https://launcher.mojang.com/v1/objects/6987a36f248e88fd8b2366e87fd88834b4a06f7a/server.jar", + "14w28b": "https://launcher.mojang.com/v1/objects/aacec09f5ed0475eb474052a4a55b3ca6edaeecc/server.jar", + "14w29a": "https://launcher.mojang.com/v1/objects/c16a61be653b5921391c55b337640ddfd7a5b472/server.jar", + "14w29b": "https://launcher.mojang.com/v1/objects/b81bb5f919d5489859e9a38c7f6b49e6931a8cc8/server.jar", + "14w30a": "https://launcher.mojang.com/v1/objects/cb7bd4bebcb40c128a571c8f15fe1990b1f50a32/server.jar", + "14w30b": "https://launcher.mojang.com/v1/objects/ee24a6e63b007b9ec97a591afe1a29a6bbbfe143/server.jar", + "14w30c": "https://launcher.mojang.com/v1/objects/2c936d1f410d636a348f100ab926d94d92b743b7/server.jar", + "14w31a": "https://launcher.mojang.com/v1/objects/05fde0b4039104a27df8c7b95d327ecafc06cde7/server.jar", + "14w32a": "https://launcher.mojang.com/v1/objects/d3b96be87d921fa4f95ea43e5283a253b778f24e/server.jar", + "14w32b": "https://launcher.mojang.com/v1/objects/8aa6b045d31cc4a9224ecce602e9f5f748d8f460/server.jar", + "14w32c": "https://launcher.mojang.com/v1/objects/5fee0612322feaf374867336375810580da6fab9/server.jar", + "14w32d": "https://launcher.mojang.com/v1/objects/83d7acb6f94dc606591ebe4d7a06ad29127cd3de/server.jar", + "14w33a": "https://launcher.mojang.com/v1/objects/6c0d06c1b3d8c3365be6e1b9b269725eb4e05ee7/server.jar", + "14w33b": "https://launcher.mojang.com/v1/objects/7e0e5511b0049ba92e5c991b6bd0264932559af2/server.jar", + "14w33c": "https://launcher.mojang.com/v1/objects/5479bbd5f4717d7c8bc8ca895b3e0894e490814e/server.jar", + "14w34a": "https://launcher.mojang.com/v1/objects/e59eecd2f79579f7b87a89b14aa07671eb94c9b1/server.jar", + "14w34b": "https://launcher.mojang.com/v1/objects/7991f32cd598ac7e5a8cf11d91965e597ae148b6/server.jar", + "14w34c": "https://launcher.mojang.com/v1/objects/5ab3e11d059a6f321a1d284d6849b95264d77e66/server.jar", + "14w34d": "https://launcher.mojang.com/v1/objects/0e05b086df677d9802ff5335719149ea90b6f302/server.jar", + "1.8-pre1": "https://launcher.mojang.com/v1/objects/88b759849519ca8a7592a2e90d6891c98f50cc17/server.jar", + "1.8-pre2": "https://launcher.mojang.com/v1/objects/5673d722ac14f571e6a46f368d34b144e90ef8ad/server.jar", + "1.8-pre3": "https://launcher.mojang.com/v1/objects/27fb956fd88ab39205c7c45a39ca4e8820f96cc4/server.jar", + "1.8.1-pre1": "https://launcher.mojang.com/v1/objects/dae8203bc40eb43e15e6e9ed454404f330c591f2/server.jar", + "1.8.1-pre2": "https://launcher.mojang.com/v1/objects/d0b163d9a442e8b49187e4925ef75970ad451f41/server.jar", + "1.8,1-pre3": "https://launcher.mojang.com/v1/objects/22440c0335d95efb7d52d9c844108aa2c69da179/server.jar", + "1.8.1-pre4": "https://launcher.mojang.com/v1/objects/5420c131b360f58ecbeb970127a49b525b28f921/server.jar", + "1.8.1-pre5": "https://launcher.mojang.com/v1/objects/a25350da18085ab12f01ba56ab03c562cc722a40/server.jar", + "1.8.2-pre1": "https://launcher.mojang.com/v1/objects/32320f5d6162cceed3cf618f3c37bde6978eacf2/server.jar", + "1.8.2-pre2": "https://launcher.mojang.com/v1/objects/4c32f01c356568b6c6b3cecf4ab4d0f0e7e14fab/server.jar", + "1.8.2-pre3": "https://launcher.mojang.com/v1/objects/dd98a2d8148cdaa92fc0deb4201186d552201314/server.jar", + "1.8.2-pre4": "https://launcher.mojang.com/v1/objects/b1d4937d5c39c5e1c462d39cc081544170c962b3/server.jar", + "1.8.2-pre5": "https://launcher.mojang.com/v1/objects/0226544b417d842a3a78797784615f11f1262a79/server.jar", + "1.8.2-pre6": "https://launcher.mojang.com/v1/objects/cc40241ef5acc247048b9d351aefa6288de13d8b/server.jar", + "1.8.2-pre7": "https://launcher.mojang.com/v1/objects/61039f9df585c52fbeb2e95d1754852ac00b4344/server.jar", + "15w14a": "https://launcher.mojang.com/v1/objects/f7d2bd26ce7893477fc1ca6e27b671345253bae4/server.jar", + "15w31a": "https://launcher.mojang.com/v1/objects/7799f1f6a486be08185b470a64ca4649e37de578/server.jar", + "15w31b": "https://launcher.mojang.com/v1/objects/67f5af98eeef5f6267aca782ea3a536d50f33bc6/server.jar", + "15w31c": "https://launcher.mojang.com/v1/objects/4fec021cc8110ce87451e22e23e958ce9d8d61f2/server.jar", + "15w32a": "https://launcher.mojang.com/v1/objects/5cb1aa4a4b26979405cea5a181bbe38b72a85add/server.jar", + "15w32b": "https://launcher.mojang.com/v1/objects/53c13fc634c89d408155553ebc8724f4b900fa1f/server.jar", + "15w32c": "https://launcher.mojang.com/v1/objects/6bef1fd3f1cb34b1d6654d93c43abb899072bd24/server.jar", + "15w33a": "https://launcher.mojang.com/v1/objects/b2f50a0daf6fd2e70dac4d7da302524566b57a55/server.jar", + "15w33b": "https://launcher.mojang.com/v1/objects/991c628d7c3ea224d90539297d8c2e9127b2489f/server.jar", + "15w33c": "https://launcher.mojang.com/v1/objects/042b351243f4236d02976ffc1e7f83f93ac932c7/server.jar", + "15w34a": "https://launcher.mojang.com/v1/objects/70103317cd7b973e4f8511a5d8973da20c6654d1/server.jar", + "15w34b": "https://launcher.mojang.com/v1/objects/6ee63157f9201f461e056652831348b9c1a51d8c/server.jar", + "15w34c": "https://launcher.mojang.com/v1/objects/639946a883a6a2636a82641a1fe4c9243c8e633c/server.jar", + "15w34d": "https://launcher.mojang.com/v1/objects/8bf058527fd4bd5d2951e1573d0ff849aedb0197/server.jar", + "15w35a": "https://launcher.mojang.com/v1/objects/a3a1c19d861bce39a129ef18226449ea02afb58a/server.jar", + "15w35b": "https://launcher.mojang.com/v1/objects/e92badd361f83730436c010044099fdf1af60bab/server.jar", + "15w35c": "https://launcher.mojang.com/v1/objects/a0f20e4bdd79e53d923d3fe2853ba11da993e6a1/server.jar", + "15w35d": "https://launcher.mojang.com/v1/objects/ed244d36678d875b979f81dbea05acacb89dc4d1/server.jar", + "15w35e": "https://launcher.mojang.com/v1/objects/04ade8521778da7786ea9c8bbda2fac005229e0f/server.jar", + "15w36a": "https://launcher.mojang.com/v1/objects/ee0b49a2fff99c93b7a216931c11292537eed473/server.jar", + "15w36b": "https://launcher.mojang.com/v1/objects/81ab225579322b61b3a37f7d56f400077c1c5978/server.jar", + "15w36c": "https://launcher.mojang.com/v1/objects/72a23cbf5f21b3589e230164f5c40c1aa7de36cd/server.jar", + "15w36d": "https://launcher.mojang.com/v1/objects/b862ed48ecf134683470145662ac8cb0e1ca7e4d/server.jar", + "15w37a": "https://launcher.mojang.com/v1/objects/0f29d64f94ccc40d01ebc1ddd0c506edca7b5dfb/server.jar", + "15w38a": "https://launcher.mojang.com/v1/objects/9b14cce8545a6f03f16ef52ef8a2725afaea5c1c/server.jar", + "15w38b": "https://launcher.mojang.com/v1/objects/41f8ae90397575214b958bb5ef99d25b541fe366/server.jar", + "15w39a": "https://launcher.mojang.com/v1/objects/871b86fac1a4d71642166e0deba2a4b85780d82a/server.jar", + "15w39b": "https://launcher.mojang.com/v1/objects/031a5a79a1548f54c7bd148f6f3cf9e42fbd3222/server.jar", + "15w39c": "https://launcher.mojang.com/v1/objects/d3f7fb05eef0331941b4161b1f2f2ded7151bbaf/server.jar", + "15w40a": "https://launcher.mojang.com/v1/objects/d3f7fb05eef0331941b4161b1f2f2ded7151bbaf/server.jar", + "15w40b": "https://launcher.mojang.com/v1/objects/adba98d3a02da95106d782991a90a199d38e5d9f/server.jar", + "15w41a": "https://launcher.mojang.com/v1/objects/92fcc884b954fb7e87b163d478fd5ff91bdb1550/server.jar", + "15w41b": "https://launcher.mojang.com/v1/objects/994a048f6a3f8f800f2807545b8401617c553dfc/server.jar", + "15w42a": "https://launcher.mojang.com/v1/objects/d789ab5179e3bb5d298d82570ee123457cfdfb94/server.jar", + "15w43a": "https://piston-data.mojang.com/v1/objects/dfc6b233c097fa377f35972e7c95e3c23c632f3c/server.jar", + "15w43b": "https://piston-data.mojang.com/v1/objects/3154e2f53b1a50159d53f0dc8e4f47857344690f/server.jar", + "15w43c": "https://piston-data.mojang.com/v1/objects/e514e7107639d2e8b285ceff5eaa114379dafba7/server.jar", + "15w44a": "https://piston-data.mojang.com/v1/objects/087cd273ee072bf626f89da4ccbb2841854f39ed/server.jar", + "15w44b": "https://piston-data.mojang.com/v1/objects/7bda3375d5509536766d65cf47b2a17ef42b964a/server.jar", + "15w45a": "https://piston-data.mojang.com/v1/objects/6bae28a2f80749ba7fc379e44acc46ac5fe44920/server.jar", + "15w46a": "https://piston-data.mojang.com/v1/objects/f0f25f22430b0c122308244f210df66ae3ce7894/server.jar", + "15w47a": "https://piston-data.mojang.com/v1/objects/2299e712df1aacb7297d63b75a5299fe35c9b9fd/server.jar", + "15w47b": "https://piston-data.mojang.com/v1/objects/80cfe2c26ef21e10feb1458c46c244caa07ebcf1/server.jar", + "15w47c": "https://piston-data.mojang.com/v1/objects/9ec245a239150ccb0f8cdae430d25ed04899bb51/server.jar", + "15w49a": "https://piston-data.mojang.com/v1/objects/63e4904766e1af15c1a4a412ec3aeb9c5972176d/server.jar", + "15w49b": "https://piston-data.mojang.com/v1/objects/e376081a73fe429c23db41a99a68a4b04c53ba8e/server.jar", + "15w50a": "https://piston-data.mojang.com/v1/objects/3ce8624859c8d38b38d2209e30f4fe76b2866de9/server.jar", + "15w51a": "https://piston-data.mojang.com/v1/objects/4d5f4d2111272d67f2238b83a552599b9b7ad92f/server.jar", + "15w51b": "https://piston-data.mojang.com/v1/objects/4d5f4d2111272d67f2238b83a552599b9b7ad92f/server.jar", + "16w02a": "https://piston-data.mojang.com/v1/objects/c574c54826489e1c04dd54d634da83945824337b/server.jar", + "16w03a": "https://piston-data.mojang.com/v1/objects/c574c54826489e1c04dd54d634da83945824337b/server.jar", + "16w04a": "https://piston-data.mojang.com/v1/objects/8b7d974f3161ddb90b14ff77a668bf0350689bb2/server.jar", + "16w05a": "https://piston-data.mojang.com/v1/objects/d74a9989d7dcd73c90191a65ae09e15b2371ffbd/server.jar", + "16w05b": "https://piston-data.mojang.com/v1/objects/9fdf8a90055b3cf689265cc30bdd9d1faf2c743c/server.jar", + "16w06a": "https://piston-data.mojang.com/v1/objects/c4da6936d6374fd7116900135a2ae664de63d3bf/server.jar", + "16w07a": "https://piston-data.mojang.com/v1/objects/f2bfcb799a616611801ff0295312e563f782ff78/server.jar", + "16w07b": "https://piston-data.mojang.com/v1/objects/f2bfcb799a616611801ff0295312e563f782ff78/server.jar", + "1.9-pre1": "https://piston-data.mojang.com/v1/objects/e166c9863dc5a6444d8260b46423325d4130b429/server.jar", + "1.9-pre2": "https://piston-data.mojang.com/v1/objects/ac6c4226ca5f1f7ea4c6f936f88d1df7c82d3a92/server.jar", + "1.9-pre3": "https://piston-data.mojang.com/v1/objects/db995628b109fd83953ffadb749c2432fac70d9e/server.jar", + "1.9-pre4": "https://piston-data.mojang.com/v1/objects/bbcbe9f89ef3cacd96dfd1df4d88588369fbd767/server.jar", + "1.9.1-pre1": "https://piston-data.mojang.com/v1/objects/04a6ca96d4024050c50570731568b94771ff7910/server.jar", + "1.9.1-pre2": "https://piston-data.mojang.com/v1/objects/bc7000381cec5819aefeea8b68ecc232208ab3ad/server.jar", + "1.9.1-pre3": "https://piston-data.mojang.com/v1/objects/6cf7cb1c561e2915c4370bfb4cf3f5e10058d537/server.jar", + "1.RV-Pre1": "https://piston-data.mojang.com/v1/objects/f51d9489706f603be6be9716407f1dab5f7f2733/server.jar", + "16w14a": "https://piston-data.mojang.com/v1/objects/5616b2213b727241821a137b4ef290c7bbace20a/server.jar", + "16w15a": "https://piston-data.mojang.com/v1/objects/c254bc24caac3f6d5059f2cc64a80ded2e164289/server.jar", + "16w15b": "https://piston-data.mojang.com/v1/objects/5add6bcbd04c20bef6ed5db4431651c0c1282489/server.jar", + "1.9.3-pre1": "https://piston-data.mojang.com/v1/objects/5d7391b36ccbc4ec04a259a3f7c6609232f30762/server.jar", + "1.9.3-pre2": "https://piston-data.mojang.com/v1/objects/41c29ba7fca8d2a0ce3bab620600459e6023458c/server.jar", + "1.9.3-pre3": "https://piston-data.mojang.com/v1/objects/ef902371fa5cbb50288b4801f9e58432c627d8e7/server.jar", + "16w20a": "https://piston-data.mojang.com/v1/objects/2cbcbd735cb48c8cc2bebb7b43c8afa69a923269/server.jar", + "16w21a": "https://piston-data.mojang.com/v1/objects/12d65aa459d3e93643746dce14c100b05fbcdddf/server.jar", + "16w21b": "https://piston-data.mojang.com/v1/objects/6dedac03d0fbfbcabe8ef09b170a577a9f72c6f8/server.jar", + "1.10-pre1": "https://piston-data.mojang.com/v1/objects/c9c34ba406f694e56c1729b465c25e0f63ce9743/server.jar", + "1.10-pre2": "https://piston-data.mojang.com/v1/objects/aa4ec0004eb20a70ef7426816cae992d73718038/server.jar", + "16w32a": "https://piston-data.mojang.com/v1/objects/b1309cff6c574e9487e3413773841ef5eb260587/server.jar", + "16w32b": "https://piston-data.mojang.com/v1/objects/b912ff1468e93003f36cda32db5d70133b517f97/server.jar", + "16w33a": "https://piston-data.mojang.com/v1/objects/dfdda3e5ba769ba0634ad43ca1124a401d6addca/server.jar", + "16w35a": "https://piston-data.mojang.com/v1/objects/16ad43cb3b87b0279028af26201af7651b87c9e0/server.jar", + "16w36a": "https://piston-data.mojang.com/v1/objects/921580b22ce7d48f9d541364a3b04eebb680222e/server.jar", + "16w38a": "https://piston-data.mojang.com/v1/objects/95ffd7c33ad9f978d4a23762978923b96fc0aa7e/server.jar", + "16w39a": "https://piston-data.mojang.com/v1/objects/f5e840e9f37ae7f50c9c979669279bcc68c91fa7/server.jar", + "16w39b": "https://piston-data.mojang.com/v1/objects/07eb3f85fc848ec8e209377aee1f7f574566e130/server.jar", + "16w39c": "https://piston-data.mojang.com/v1/objects/df13c6cbf5fc735896b22f56b1f8940dd11a3b5f/server.jar", + "16w40a": "https://piston-data.mojang.com/v1/objects/64a1a5ba3f347c5e03477b42ac13d10ee193b51c/server.jar", + "16w41a": "https://piston-data.mojang.com/v1/objects/94f47b24edd154d89240e49d9b7371e74f433d19/server.jar", + "16w42a": "https://piston-data.mojang.com/v1/objects/ad6aa39daf88864fcd84b231638e3dc28bde83f3/server.jar", + "16w43a": "https://piston-data.mojang.com/v1/objects/c5cc57bfd0a3462c2634a37c83877e91f25f020b/server.jar", + "16w44a": "https://piston-data.mojang.com/v1/objects/9f30eff92cc234034581f0a1ef40c6d76f6b3e69/server.jar", + "1.11-pre1": "https://piston-data.mojang.com/v1/objects/7e2884f11e3fb52ed1ad82376e3cada3aa95152e/server.jar", + "16w50a": "https://piston-data.mojang.com/v1/objects/d4d30a5433846d205974ace4cf34c9b294e0833f/server.jar", + "17w06a": "https://piston-data.mojang.com/v1/objects/37441cab126ee2a4f292c9bf488c9dd800cff841/server.jar", + "17w13a": "https://piston-data.mojang.com/v1/objects/d3806f89b9c90cbfb78919a3bcc010ad2e5d6ebb/server.jar", + "17w13b": "https://piston-data.mojang.com/v1/objects/7bd51f821ed09b6a1d3a9a9b2fc67b48f1d829c4/server.jar", + "17w14a": "https://piston-data.mojang.com/v1/objects/0530caf1d099fc730ca335a21bcf2fbb58c42c64/server.jar", + "17w15a": "https://piston-data.mojang.com/v1/objects/cc26caa34e1a53326ec374d229db07a0e2a7de17/server.jar", + "17w16a": "https://piston-data.mojang.com/v1/objects/47cfe5d44ccf6333b697da3e82e35bb3725e53d8/server.jar", + "17w16b": "https://piston-data.mojang.com/v1/objects/80601961e590046727791d6b18f51d840ea86e1c/server.jar", + "17w17a": "https://piston-data.mojang.com/v1/objects/3795d253cfef44f1f1467422b4399d1770484dc0/server.jar", + "17w17b": "https://piston-data.mojang.com/v1/objects/7cf669824e4c8340050adcc2125f1ec4cb84feac/server.jar", + "17w18a": "https://piston-data.mojang.com/v1/objects/b1f45946bd74f4e2cf1833324770809ebcd0b7b1/server.jar", + "17w18b": "https://piston-data.mojang.com/v1/objects/915c1833209d588ade3e064577700037093861da/server.jar", + "1.12-pre1": "https://piston-data.mojang.com/v1/objects/ebcafa3e1a3312500893087bf4bfb6c6f335ef0e/server.jar", + "1.12-pre2": "https://piston-data.mojang.com/v1/objects/e5fd1c4202f9b0855d9104b66ba4182d52e79c38/server.jar", + "1.12-pre3": "https://piston-data.mojang.com/v1/objects/c985b2083848efcc8d1658d6cda5644681035f80/server.jar", + "1.12-pre4": "https://piston-data.mojang.com/v1/objects/588bcccfff42acc2cb6f7c6470cd6bc8ba393668/server.jar", + "1.12-pre5": "https://piston-data.mojang.com/v1/objects/40e76b2836c92cd9e05af61bb64046c8650c088d/server.jar", + "1.12-pre6": "https://piston-data.mojang.com/v1/objects/9bc0e57debc61da93c0ea0d97849254db4f4e556/server.jar", + "1.12-pre7": "https://piston-data.mojang.com/v1/objects/a8d79598161edc5f67b606120ea9e62bcefcaaa7/server.jar", + "17w31a": "https://piston-data.mojang.com/v1/objects/00b83b98c91dbe3531342325f72654ef6d7be6eb/server.jar", + "1.12.1-pre1": "https://piston-data.mojang.com/v1/objects/b25c39f4658911169e184f00a24798f6463ded14/server.jar", + "1.12.2-pre1": "https://piston-data.mojang.com/v1/objects/b81c81335e68731d66ccddc21df0c06d7b9b46ab/server.jar", + "1.12.2-pre2": "https://piston-data.mojang.com/v1/objects/641adfb6a646fe12f1fb2715ed4e3167c7ff2f2b/server.jar", + "17w43a": "https://piston-data.mojang.com/v1/objects/6f6869d527140e5531e655bda10911efb65425bb/server.jar", + "17w43b": "https://piston-data.mojang.com/v1/objects/0447782ac5280f8f981c3998609928984213a4c7/server.jar", + "17w45a": "https://piston-data.mojang.com/v1/objects/471b2dfa12e4df234057159ce5ee8320da3c84c1/server.jar", + "17w45b": "https://piston-data.mojang.com/v1/objects/eec0c6c49b1066b648f39e1dcef8c76510a794dc/server.jar", + "17w46a": "https://piston-data.mojang.com/v1/objects/9127416e2341eb8fb7b63636c3ae39efefb2843b/server.jar", + "17w47a": "https://piston-data.mojang.com/v1/objects/0cec7f11d7bf9c36464b1815e5bbcb0afe6db019/server.jar", + "17w47b": "https://piston-data.mojang.com/v1/objects/9b4e7894906f0b379c7300cff0b3e68a4b9db662/server.jar", + "17w48a": "https://piston-data.mojang.com/v1/objects/e132a348243b824ba6f74569c8b1080b77104981/server.jar", + "17w49a": "https://piston-data.mojang.com/v1/objects/561fe37463ef30b4e1ab4c6b1da057d9e2b17801/server.jar", + "17w49b": "https://piston-data.mojang.com/v1/objects/caac50590085014355070ea6381baec0f58aa9f2/server.jar", + "17w50a": "https://piston-data.mojang.com/v1/objects/670c67a4dfbd1070a9be629124ddd8aac8d9b9d9/server.jar", + "18w01a": "https://piston-data.mojang.com/v1/objects/47a8d2bb4db5b5e3db6b7837c9f0fa17ea660448/server.jar", + "18w02a": "https://piston-data.mojang.com/v1/objects/950b737e9cefc9f91f286190166f062d6b0e0105/server.jar", + "18w03a": "https://piston-data.mojang.com/v1/objects/713a291a4da5cad056964c1fcda8c888e154eb73/server.jar", + "18w03b": "https://piston-data.mojang.com/v1/objects/ef8c70a7c9b88c02c64ea01d050614929b7152f6/server.jar", + "18w05a": "https://piston-data.mojang.com/v1/objects/a4029c808cef57bed3228a51dcb7f68edd018a77/server.jar", + "18w06a": "https://piston-data.mojang.com/v1/objects/4e47158fd42d966884a7ffb7440b35d86c038049/server.jar", + "18w07a": "https://piston-data.mojang.com/v1/objects/4e47158fd42d966884a7ffb7440b35d86c038049/server.jar", + "18w07b": "https://piston-data.mojang.com/v1/objects/669811c0df3fedef8a15f1b31c96df966b9aee79/server.jar", + "18w07c": "https://piston-data.mojang.com/v1/objects/52e141870c3c850811710f2ba07eb3e7e583ea92/server.jar", + "18w08a": "https://piston-data.mojang.com/v1/objects/09b2bc558d86878ce69f303ddbd62bf4489db068/server.jar", + "18w08b": "https://piston-data.mojang.com/v1/objects/cdfdcdd799087d9b66f04667f0717a11e28c29cc/server.jar", + "18w09a": "https://piston-data.mojang.com/v1/objects/57dd2fe4a2fdb6e846b978e77442465d2ea27f43/server.jar", + "18w10a": "https://piston-data.mojang.com/v1/objects/7bb1cfb4560d2e99551b22a631b6087d43817a45/server.jar", + "18w10b": "https://piston-data.mojang.com/v1/objects/b45d7194b91327c8fd2c1d0d5a738b80c9600562/server.jar", + "18w10c": "https://piston-data.mojang.com/v1/objects/7c2494311ab74f97623ebf6e2d5beba625a9d5fc/server.jar", + "18w10d": "https://piston-data.mojang.com/v1/objects/28727c7dfb62c56ac48153ab9a25d42115f85f94/server.jar", + "18w11a": "https://piston-data.mojang.com/v1/objects/4286b7cbc4709c8f61c93a77b42c70918376cac3/server.jar", + "18w14a": "https://piston-data.mojang.com/v1/objects/50b4ca8fe7853ae6757a163a80e67cb8437fb082/server.jar", + "18w14b": "https://piston-data.mojang.com/v1/objects/85d6445fc4596e6b69fb00f0d3e5462dfeeb933c/server.jar", + "18w15a": "https://piston-data.mojang.com/v1/objects/3f9534ab77a524593db7a20196e41ae36b23d69d/server.jar", + "18w16a": "https://piston-data.mojang.com/v1/objects/3f9534ab77a524593db7a20196e41ae36b23d69d/server.jar", + "18w19a": "https://piston-data.mojang.com/v1/objects/97ad982d57fb7b7cb9dc28ffd87c79538b1901f6/server.jar", + "18w19b": "https://piston-data.mojang.com/v1/objects/87edb914af0594016fab77eaaa9d25c7f1f1d132/server.jar", + "18w20a": "https://piston-data.mojang.com/v1/objects/108a051216637e0145f6b0e66182b48736595fc3/server.jar", + "18w20b": "https://piston-data.mojang.com/v1/objects/35304e17de5fbe503b10bad50192d14a38e5cec0/server.jar", + "18w20c": "https://piston-data.mojang.com/v1/objects/9e0ffb265e3771dc5c7b56f291b9c9d8f668f48b/server.jar", + "18w21a": "https://piston-data.mojang.com/v1/objects/2022a23da58dc55371b6a182fb1ba59742dc66a2/server.jar", + "18w21b": "https://piston-data.mojang.com/v1/objects/df8cc7cfa4c2d24f31f5997a102f1d6411f038d0/server.jar", + "18w22a": "https://piston-data.mojang.com/v1/objects/077225ee7bca03f521ed8df86fa4740b8e7a3cad/server.jar", + "18w22b": "https://piston-data.mojang.com/v1/objects/cc0b6a96e537528cdaab685c4eaeeaf8ed905b51/server.jar", + "18w22c": "https://piston-data.mojang.com/v1/objects/d66173b86e26e6835e36c63eb2828652186a4698/server.jar", + "1.13-pre1": "https://piston-data.mojang.com/v1/objects/e031e58e1d9e745877404530d39775bf9ffa9a56/server.jar", + "1.13-pre2": "https://piston-data.mojang.com/v1/objects/5b312060d457a1f75846afd3935ec3f140da3942/server.jar", + "1.13-pre3": "https://piston-data.mojang.com/v1/objects/5406f31cb5274ae48938851de697b32976ecb499/server.jar", + "1.13-pre4": "https://piston-data.mojang.com/v1/objects/d57007a8722ed645319666fc56b27690054d8363/server.jar", + "1.13-pre5": "https://piston-data.mojang.com/v1/objects/6d9ede222df5726059aba1b01f99c328bc16f1a5/server.jar", + "1.13-pre6": "https://piston-data.mojang.com/v1/objects/71a2f9a760f0cbcf09d1eae60eebe1ccbb7ea1db/server.jar", + "1.13-pre7": "https://piston-data.mojang.com/v1/objects/6cd8348fadedaa1de5851f449b995c835bb569eb/server.jar", + "1.13-pre8": "https://piston-data.mojang.com/v1/objects/b04f82ae0f3018c4c22a153184b385012c4d0814/server.jar", + "1.13-pre9": "https://piston-data.mojang.com/v1/objects/ee66f5cb1247f4340734a151db4f940bbe04f833/server.jar", + "1.13-pre10": "https://piston-data.mojang.com/v1/objects/2ffcae7a9489d515b0f733430923ef974dffd56b/server.jar", + "18w30a": "https://piston-data.mojang.com/v1/objects/4cfe675115064caad14712c3345660f4069a2e8b/server.jar", + "18w30b": "https://piston-data.mojang.com/v1/objects/373b2fb24db8ed21d25483a986e9eb7f945c5277/server.jar", + "18w31a": "https://piston-data.mojang.com/v1/objects/4646084899fb62a7b9afa6f453fae4e6e786e5a5/server.jar", + "18w32a": "https://piston-data.mojang.com/v1/objects/d36429ccdcaa73cb37b366d608024e3a6a5a20ab/server.jar", + "18w33a": "https://piston-data.mojang.com/v1/objects/e62f0a29e4ab5963488330f29c03ca2914b5b22b/server.jar", + "1.13.1-pre1": "https://piston-data.mojang.com/v1/objects/988fec4e71e5fa1fc29a50230de05a11973d62ab/server.jar", + "1.13.1-pre2": "https://piston-data.mojang.com/v1/objects/c2a4bcf3e244c46f13c39e31e7ef6030564fb6c2/server.jar", + "1.13.2-pre1": "https://piston-data.mojang.com/v1/objects/744df5d6872645a8f919459473e0e02a3571e6bb/server.jar", + "1.13.2-pre2": "https://piston-data.mojang.com/v1/objects/2f39df32f20196b5a6acad117f7d6b404b069c58/server.jar", + "18w43a": "https://piston-data.mojang.com/v1/objects/08ca3aaa7ff61d4ae06d5d63476724a1f32cb6b0/server.jar", + "18w43b": "https://piston-data.mojang.com/v1/objects/ed443be5ff6a304164612c545f0942fd99d53e13/server.jar", + "18w43c": "https://piston-data.mojang.com/v1/objects/b2dc0522b0802cbb8e81d1afd3e46be8819d3c1d/server.jar", + "18w44a": "https://piston-data.mojang.com/v1/objects/e70221701d85ad9ed8be35e042f4c8e52fb627ec/server.jar", + "18w45a": "https://piston-data.mojang.com/v1/objects/a004069d93ebfd9a6d93c57b66becac29f876d4c/server.jar", + "18w46a": "https://piston-data.mojang.com/v1/objects/6681e24d2dc9ba60a6e7d1fbbf25b2af70ff9d1c/server.jar", + "18w47a": "https://piston-data.mojang.com/v1/objects/7066873e9b86cfcd5b66c6a98d2587d95bf94adc/server.jar", + "18w47b": "https://piston-data.mojang.com/v1/objects/fa9d22eea98b62f6663f1aa8a25840e0993485e6/server.jar", + "18w48a": "https://piston-data.mojang.com/v1/objects/f0f04983d197388b05a4647f7a7cf8b5fbbac5d3/server.jar", + "18w48b": "https://piston-data.mojang.com/v1/objects/cfa41132beeb877a093e044aba591d9dae236c38/server.jar", + "18w49a": "https://piston-data.mojang.com/v1/objects/5b6eb767f6708d351e3d1009a44115bb033b854f/server.jar", + "18w50a": "https://piston-data.mojang.com/v1/objects/de0577900a9071758d7f1172dd283bdbe88b7431/server.jar", + "19w02a": "https://piston-data.mojang.com/v1/objects/f8078dd487483a917645f7a5561290e28bd875c4/server.jar", + "19w03a": "https://piston-data.mojang.com/v1/objects/1e80738a5360887bc93a46bdffb07699a45bf5a1/server.jar", + "19w03b": "https://piston-data.mojang.com/v1/objects/a3a358a7566debb17c5332fbc43eb8b84e000997/server.jar", + "19w03c": "https://piston-data.mojang.com/v1/objects/e9fdb18631fc4ff23b06b1e827fb653ac20532fe/server.jar", + "19w04a": "https://piston-data.mojang.com/v1/objects/261edfd76c32c9f675c12264b6fa03f670c3325c/server.jar", + "19w04b": "https://piston-data.mojang.com/v1/objects/7a5a3bbefcb4d27fd9ac30736eee06ae1e2c0991/server.jar", + "19w05a": "https://piston-data.mojang.com/v1/objects/521021450baf9b9b98b0a6d0cb60e97f306f4f57/server.jar", + "19w06a": "https://piston-data.mojang.com/v1/objects/20c069d373e77265aaeeedb733f7051e294325a3/server.jar", + "19w07a": "https://piston-data.mojang.com/v1/objects/d370db01d591576477c3efc940a42926f43bc98f/server.jar", + "19w08a": "https://piston-data.mojang.com/v1/objects/f337f8dfb765f152388d5038a6e0e8830782e5ed/server.jar", + "19w08b": "https://piston-data.mojang.com/v1/objects/f337f8dfb765f152388d5038a6e0e8830782e5ed/server.jar", + "19w09a": "https://piston-data.mojang.com/v1/objects/266d772f79eebe55de3856ae3fe675c0699cd1ca/server.jar", + "19w11a": "https://piston-data.mojang.com/v1/objects/388221ffa9e8e1576e07f9839eadd2ac7bd51cbb/server.jar", + "19w11b": "https://piston-data.mojang.com/v1/objects/1c453ba8ccaabc38d924e7c11fe73c65a1978a33/server.jar", + "19w12a": "https://piston-data.mojang.com/v1/objects/dc1a1dfef026d38dfc04b360653172f5428f86ef/server.jar", + "19w12b": "https://piston-data.mojang.com/v1/objects/37d6d9753b8eac2420e9deba132c38e00c8204c3/server.jar", + "19w13a": "https://piston-data.mojang.com/v1/objects/c63080e9349640fda5820bbe48cacc623c99c496/server.jar", + "19w13b": "https://piston-data.mojang.com/v1/objects/6d395392d8aac9bcde96322831042c77410b0a19/server.jar", + "3D Shareware v1.34": "https://piston-data.mojang.com/v1/objects/ffd306fc2aaa884755c5a6bf9fbd87aed26dd78f/server.jar", + "19w14a": "https://piston-data.mojang.com/v1/objects/a786a10223f5218967bfd42a06f4bee9e9563f56/server.jar", + "19w14b": "https://piston-data.mojang.com/v1/objects/719781c28dbcf7d0576e81fe5e77d75c1f18117f/server.jar", + "1.14 Pre-Release 1": "https://piston-data.mojang.com/v1/objects/6f27430bcd9b06d3dcb5d2966c75d5e491915c9c/server.jar", + "1.14 Pre-Release 2": "https://piston-data.mojang.com/v1/objects/353cc74b9aefd4675730449f50f5c0066063ac3f/server.jar", + "1.14 Pre-Release 3": "https://piston-data.mojang.com/v1/objects/6b747e1338e1aa058146032a659cf654c446552d/server.jar", + "1.14 Pre-Release 4": "https://piston-data.mojang.com/v1/objects/cf967a23b452ab474bf7bcb69fd029a5f8b84bba/server.jar", + "1.14 Pre-Release 5": "https://piston-data.mojang.com/v1/objects/5d550762b9c82ab4fe9f259c14fcf7bf7ed8017a/server.jar", + "1.14.1 Pre-Release 1": "https://piston-data.mojang.com/v1/objects/0bbed1aa2ef4bd4c0d6134461ac3e8eba1dc5f62/server.jar", + "1.14.1 Pre-Release 2": "https://piston-data.mojang.com/v1/objects/ea3a8bee27e1ca4185bf703fb4e414800f533fc9/server.jar", + "1.14.2 Pre-Release 1": "https://piston-data.mojang.com/v1/objects/1aad89bfe7a14bee70de0b07339a2f319771180f/server.jar", + "1.14.2 Pre-Release 2": "https://piston-data.mojang.com/v1/objects/a2cedc73237e999a5d408ecf0923a130d69d45a1/server.jar", + "1.14.2 Pre-Release 3": "https://piston-data.mojang.com/v1/objects/307fb7e6208bd843060b1844857dc5e1d555a1df/server.jar", + "1.14.2 Pre-Release 4": "https://piston-data.mojang.com/v1/objects/6bba54ad86fccc45cc68ba410e738d3b331cdadd/server.jar", + "1.14.3-pre1": "https://piston-data.mojang.com/v1/objects/966984c5d8b5c3604a8838f8fb5635b8b9cd73c7/server.jar", + "1.14.3-pre2": "https://piston-data.mojang.com/v1/objects/64caea4b63611111d775e4558341cb9718a6ff4f/server.jar", + "1.14.3-pre3": "https://piston-data.mojang.com/v1/objects/a46e49e1541cf24a75aabe2756514565de83634a/server.jar", + "1.14.3-pre4": "https://piston-data.mojang.com/v1/objects/d5397db937499277165abb27f8af04885be8b6b6/server.jar", + "1.14.4-pre1": "https://piston-data.mojang.com/v1/objects/774c5619679673ec772b0f01f363d0145a9d6b51/server.jar", + "1.14.4-pre2": "https://piston-data.mojang.com/v1/objects/a7023b92091ca5872d35b17c8aab1c6daa833a69/server.jar", + "1.14.4-pre3": "https://piston-data.mojang.com/v1/objects/b7ed47d4e600c6ead80f4c73c2e080625d07ef6e/server.jar", + "1.14.4-pre4": "https://piston-data.mojang.com/v1/objects/853bf851bda5862b7f68baf93ae86fb90571ceca/server.jar", + "1.14.4-pre5": "https://piston-data.mojang.com/v1/objects/f45379dfa2ecd946a2ed81c354225a4181261333/server.jar", + "1.14.4-pre6": "https://piston-data.mojang.com/v1/objects/d7b8f310278a5ea9efef03b4e441f12524253c5d/server.jar", + "1.14.4-pre7": "https://piston-data.mojang.com/v1/objects/98d1396495562dbb32828ef50bad7112c403c47e/server.jar", + "19w34a": "https://piston-data.mojang.com/v1/objects/288962c67d083e35d4313cf0eba8ad1e27173d17/server.jar", + "19w35a": "https://piston-data.mojang.com/v1/objects/e0bfc54b4b424c43b1fe5b833d68e35d031a481d/server.jar", + "19w36a": "https://piston-data.mojang.com/v1/objects/c042fd138ae280b01ce191937ca917666a15be38/server.jar", + "19w37a": "https://piston-data.mojang.com/v1/objects/e2c6923d9e06f6b98460f0f584567848a70bf71b/server.jar", + "19w38a": "https://piston-data.mojang.com/v1/objects/e40184002fa2e183de5fda0229d0709cfd6bfe8a/server.jar", + "19w38b": "https://piston-data.mojang.com/v1/objects/aff9049db1bcbd44d133ebfbd015dce49dd8383e/server.jar", + "19w39a": "https://piston-data.mojang.com/v1/objects/aff9049db1bcbd44d133ebfbd015dce49dd8383e/server.jar", + "19w40a": "https://piston-data.mojang.com/v1/objects/aff9049db1bcbd44d133ebfbd015dce49dd8383e/server.jar", + "19w41a": "https://piston-data.mojang.com/v1/objects/aff9049db1bcbd44d133ebfbd015dce49dd8383e/server.jar", + "19w42a": "https://piston-data.mojang.com/v1/objects/1f8673dee28ff3a1714e17780f6b91d5372fe440/server.jar", + "19w44a": "https://piston-data.mojang.com/v1/objects/0a68a89351325fbad9b432b3eb24ae944860350e/server.jar", + "19w45a": "https://piston-data.mojang.com/v1/objects/fa9e744ee6e5cccd4000e2269f8dff8ce96ce5a9/server.jar", + "19w45b": "https://piston-data.mojang.com/v1/objects/fa9e744ee6e5cccd4000e2269f8dff8ce96ce5a9/server.jar", + "19w46a": "https://piston-data.mojang.com/v1/objects/3544354ee91fee0439009e71c8e064ec8355600a/server.jar", + "19w46b": "https://piston-data.mojang.com/v1/objects/eded6ea3899b67478780576a3b92c6cac867b501/server.jar", + "1.15-pre1": "https://piston-data.mojang.com/v1/objects/332b3382108e5bdb0b23717082c9b97c54ffc8ad/server.jar", + "1.15-pre2": "https://piston-data.mojang.com/v1/objects/0f0c2e3c25693189374c8a63179e3018ebfdc1ba/server.jar", + "1.15-pre3": "https://piston-data.mojang.com/v1/objects/eedb663e70f49a5592b88197ea68b0f32fd9ce97/server.jar", + "1.15-pre4": "https://piston-data.mojang.com/v1/objects/8f9e23414a01d21e2cd313b2595b164ccfda56aa/server.jar", + "1.15-pre5": "https://piston-data.mojang.com/v1/objects/8f9e23414a01d21e2cd313b2595b164ccfda56aa/server.jar", + "1.15-pre6": "https://piston-data.mojang.com/v1/objects/8d5793fe302feb6c03d3c5e590ef940fc02f2864/server.jar", + "1.15-pre7": "https://piston-data.mojang.com/v1/objects/8d5793fe302feb6c03d3c5e590ef940fc02f2864/server.jar", + "1.15.1-pre1": "https://piston-data.mojang.com/v1/objects/289a247dd42928880769398b049d3890513f2917/server.jar", + "1.15.2-pre1": "https://piston-data.mojang.com/v1/objects/5db50a719dc40d63aa95c6bdc5b302e425f673f2/server.jar", + "1.15.2-pre2": "https://piston-data.mojang.com/v1/objects/f3eae938f3382ffeb8c3af150664d33864561110/server.jar", + "20w06a": "https://piston-data.mojang.com/v1/objects/9b74998642553efe0e4d1aa079dc737b3e4cdc13/server.jar", + "20w07a": "https://piston-data.mojang.com/v1/objects/3944965e1621a5ccbe99292479cc62e07bccd611/server.jar", + "20w08a": "https://piston-data.mojang.com/v1/objects/b46203f7cc23ec786710fdcf6f369935cf92dabb/server.jar", + "20w09a": "https://piston-data.mojang.com/v1/objects/6f1e5ae00b938bbe15560b7174be7a3b4c78c450/server.jar", + "20w10a": "https://piston-data.mojang.com/v1/objects/6f1e5ae00b938bbe15560b7174be7a3b4c78c450/server.jar", + "20w11a": "https://piston-data.mojang.com/v1/objects/6f1e5ae00b938bbe15560b7174be7a3b4c78c450/server.jar", + "20w12a": "https://piston-data.mojang.com/v1/objects/3d9657a172415a163e25096942f5a4d110b984a0/server.jar", + "20w13a": "https://piston-data.mojang.com/v1/objects/16f18c21286a3f566d3d0431d13aa133bebe6eff/server.jar", + "20w13b": "https://piston-data.mojang.com/v1/objects/0e00cff8df2532a1ae252e773552c2fd6c68de80/server.jar", + "20w14infinite": "https://piston-data.mojang.com/v1/objects/c0711cd9608d1af3d6f05ac423dd8f4199780225/server.jar", + "20w14a": "https://piston-data.mojang.com/v1/objects/affcf966ca903156070aa90b63417793a78b2165/server.jar", + "20w15a": "https://piston-data.mojang.com/v1/objects/64ca02e1e9fc7e60eac4aba788580b16eb12f71f/server.jar", + "20w16a": "https://piston-data.mojang.com/v1/objects/754bbd654d8e6bd90cd7a1464a9e68a0624505dd/server.jar", + "20w17a": "https://piston-data.mojang.com/v1/objects/0b7e36b084577fb26148c6341d590ac14606db21/server.jar", + "20w18a": "https://piston-data.mojang.com/v1/objects/4d84832bdc7f62aa96b0d5d5a73b1272e8c474b5/server.jar", + "20w19a": "https://piston-data.mojang.com/v1/objects/fbb3ad3e7b25e78723434434077995855141ff07/server.jar", + "20w20a": "https://piston-data.mojang.com/v1/objects/f06a943eb107494688b4447b97514af6d7311623/server.jar", + "20w20b": "https://piston-data.mojang.com/v1/objects/0393774fb1f9db8288a56dbbcf45022b71f7939f/server.jar", + "20w21a": "https://piston-data.mojang.com/v1/objects/03b8fa357937d0bdb6650ec8cc74506ec2fd91a7/server.jar", + "20w22a": "https://piston-data.mojang.com/v1/objects/c4a62eb36917aaa06dc8e20a2a35264d5fda123b/server.jar", + "1.16-pre1": "https://piston-data.mojang.com/v1/objects/c4a62eb36917aaa06dc8e20a2a35264d5fda123b/server.jar", + "1.16-pre2": "https://piston-data.mojang.com/v1/objects/8daeb71269eb164097d7d7ab1fa93fc93ab125c3/server.jar", + "1.16-pre3": "https://piston-data.mojang.com/v1/objects/0b5653b65bc494fa55349682cebf50abf0d72ad9/server.jar", + "1.16-pre4": "https://piston-data.mojang.com/v1/objects/018cdde89f8ff3831ce27c6c8dbf6831e99e0e75/server.jar", + "1.16-pre5": "https://piston-data.mojang.com/v1/objects/56081523bca4f7074f111d1e8a9fd0a86d072a2b/server.jar", + "1.16-pre6": "https://piston-data.mojang.com/v1/objects/8984939f42371a7e614fa48669e308c4cc9ba228/server.jar", + "1.16-pre7": "https://piston-data.mojang.com/v1/objects/577f7287642309a2a32e80be395329118dfddb3f/server.jar", + "1.16-pre8": "https://piston-data.mojang.com/v1/objects/d6a747371b200216653be9b4140cd2862eddbb0e/server.jar", + "1.16-rc1": "https://piston-data.mojang.com/v1/objects/7213e5ba8fe8d352141cf3dde907c26c43480092/server.jar", + "20w27a": "https://piston-data.mojang.com/v1/objects/40efae0a2412154f44a99f158752b8417b384f06/server.jar", + "20w28a": "https://piston-data.mojang.com/v1/objects/1e36d315d96c29d8d32aa8fecbfb8efa4243a746/server.jar", + "20w29a": "https://piston-data.mojang.com/v1/objects/ea9a65a38e000fe76b51fa36e923c09d5d8fa473/server.jar", + "20w30a": "https://piston-data.mojang.com/v1/objects/ea9a65a38e000fe76b51fa36e923c09d5d8fa473/server.jar", + "1.16.2-pre1": "https://piston-data.mojang.com/v1/objects/d4434bf4f2f0572a4eb54b3da1b1b3069a4e9ef2/server.jar", + "1.16.2-pre2": "https://piston-data.mojang.com/v1/objects/d2cae287324631b2b4bfa609dd01c63cd6d4b78d/server.jar", + "1.16.2-pre3": "https://piston-data.mojang.com/v1/objects/bd47f78f185a525388e446aa44975c147057ebbd/server.jar", + "1.16.2-rc1": "https://piston-data.mojang.com/v1/objects/203e18d79201b5e8c46019074b07e1c3b4c75f57/server.jar", + "1.16.2-rc2": "https://piston-data.mojang.com/v1/objects/45287d794fa2631b8da9b9002696ebe406fbed6b/server.jar", + "1.16.3-rc1": "https://piston-data.mojang.com/v1/objects/562bf3e75afea00875cff4a06165f93056646f32/server.jar", + "1.16.4-pre1": "https://piston-data.mojang.com/v1/objects/28eb6f8c4c05eec278e3e7f9f0379a16adbfb91d/server.jar", + "1.16.4-pre2": "https://piston-data.mojang.com/v1/objects/ceb412d94900167f519100736bc5709853b50b8c/server.jar", + "1.16.4-rc1": "https://piston-data.mojang.com/v1/objects/daf2d997bd6b1725b6d59b48f533a6804d43db33/server.jar", + "20w45a": "https://piston-data.mojang.com/v1/objects/043ec38297d0ec58abd6f636bc92f5664a8ccecb/server.jar", + "20w46a": "https://piston-data.mojang.com/v1/objects/373675677cc57b9294a187a4d0ecab6f340d4189/server.jar", + "20w48a": "https://piston-data.mojang.com/v1/objects/a14d24f89d5a4ec7521b91909caf4fee89c997f4/server.jar", + "20w49a": "https://piston-data.mojang.com/v1/objects/2fc0afe1fd31ca872761efbd2a7f635db234b359/server.jar", + "20w51a": "https://piston-data.mojang.com/v1/objects/fc87ef4c3cf1c815809249cc00ccade233b22cf5/server.jar", + "1.16.5-rc1": "https://piston-data.mojang.com/v1/objects/fc87ef4c3cf1c815809249cc00ccade233b22cf5/server.jar", + "21w03a": "https://piston-data.mojang.com/v1/objects/dbe81ef81e20e76b1458be822026887fef84c541/server.jar", + "21w05a": "https://piston-data.mojang.com/v1/objects/ff10b6f3bb37799e933ff0c2c300626b78ebfb1d/server.jar", + "21w05b": "https://piston-data.mojang.com/v1/objects/f92547a92214ab71a58834e7453ab29a6ab2d192/server.jar", + "21w06a": "https://piston-data.mojang.com/v1/objects/6290ba4b475fca4a74de990c7fd8eccffd9654dd/server.jar", + "21w07a": "https://piston-data.mojang.com/v1/objects/99c3a9744719d0d401af63bb684cf1eb5231a75c/server.jar", + "21w08a": "https://piston-data.mojang.com/v1/objects/d5e31633d884e190e046b8645f802541bec2a5e9/server.jar", + "21w08b": "https://piston-data.mojang.com/v1/objects/801d5e25869bab291077c773913cc2b490427314/server.jar", + "21w10a": "https://piston-data.mojang.com/v1/objects/5998d2c7c15fea04b2541efdcbec4c8cfe5df2a6/server.jar", + "21w11a": "https://piston-data.mojang.com/v1/objects/c828957ad249138129ccbc8749bfd14f01d96a4b/server.jar", + "21w13a": "https://piston-data.mojang.com/v1/objects/36d49b1a6d05f1deac293d477bfa2b4a1babb71c/server.jar", + "21w14a": "https://piston-data.mojang.com/v1/objects/0cb279c49ea3afda25c9d7257bef650e8dc17429/server.jar", + "21w15a": "https://piston-data.mojang.com/v1/objects/0a39422009a7aa01dd185043746c50dc909dc345/server.jar", + "21w16a": "https://piston-data.mojang.com/v1/objects/b8bacc67a9db84db59e2f97e9a9fba3a242480a8/server.jar", + "21w17a": "https://piston-data.mojang.com/v1/objects/ec995f939bb41a785f960985e73821c7044fc32e/server.jar", + "21w18a": "https://piston-data.mojang.com/v1/objects/0b18d883bd1132f761aa715d6a97e29e54a9b8b6/server.jar", + "21w19a": "https://piston-data.mojang.com/v1/objects/d0a9151432af384f5f2ca72e8e43422772158d0e/server.jar", + "21w20a": "https://piston-data.mojang.com/v1/objects/054b2065dd63c3e4227879046beae7acaeb7e8d3/server.jar", + "1.17-pre1": "https://piston-data.mojang.com/v1/objects/80a01a1178bcfb67b42636df3a9cdd275f3cc4d4/server.jar", + "1.17-pre2": "https://piston-data.mojang.com/v1/objects/d8756c67ce3b3fe20d0510afb3e22fa16310b2e6/server.jar", + "1.17-pre3": "https://piston-data.mojang.com/v1/objects/18abbb3f980fc9b05188535db45a67276ea41f90/server.jar", + "1.17-pre4": "https://piston-data.mojang.com/v1/objects/528f491660bc5dc94c0d7911345a97438e5c1d86/server.jar", + "1.17-pre5": "https://piston-data.mojang.com/v1/objects/31bb40019e8d6e64299abafd743f4d3e1a1a68b2/server.jar", + "1.17-rc1": "https://piston-data.mojang.com/v1/objects/31bb40019e8d6e64299abafd743f4d3e1a1a68b2/server.jar", + "1.17-rc2": "https://piston-data.mojang.com/v1/objects/1b6e0511e1e419fdcf5a81e53e36b5558032ee79/server.jar", + "1.17.1-pre1": "https://piston-data.mojang.com/v1/objects/42dfafdd31a1e6edfe59c79ea0e109fede1c8071/server.jar", + "1.17.1-pre2": "https://piston-data.mojang.com/v1/objects/e01e495461ecb834bb6a242bfea608af4f22b955/server.jar", + "1.17.1-pre3": "https://piston-data.mojang.com/v1/objects/04750b5adff60610a5ba2cd3aa8102f7086c9301/server.jar", + "1.17.1-rc1": "https://piston-data.mojang.com/v1/objects/b93cbcf6c65b92621d67b735e8610f7682f54694/server.jar", + "1.17.1-rc2": "https://piston-data.mojang.com/v1/objects/dd9ca1bdc855535cd7ce0565f02285ad4d6d1ae5/server.jar", + "21w37a": "https://piston-data.mojang.com/v1/objects/de695215d83f1f6ec5a19847f6178b84cfde7a26/server.jar", + "21w38a": "https://piston-data.mojang.com/v1/objects/1283dff678ee5efb8e52d2fc77ec9d840317c6ca/server.jar", + "21w39a": "https://piston-data.mojang.com/v1/objects/2b40ef4bf57b2040f7d9affb48c0131b228f954f/server.jar", + "21w40a": "https://piston-data.mojang.com/v1/objects/84496ec4beeeae34a448b99f3e3d890066f6807f/server.jar", + "21w41a": "https://piston-data.mojang.com/v1/objects/8eab49e576b21d6babfc60dcd14c68fac4926ab3/server.jar", + "21w42a": "https://piston-data.mojang.com/v1/objects/cf518e2c80fdaef443d68d50d1ac23a72a0a7d85/server.jar", + "21w43a": "https://piston-data.mojang.com/v1/objects/5c774a8b4e4407133eec7c4e1449c5f35974c589/server.jar", + "21w44a": "https://piston-data.mojang.com/v1/objects/ae583fd57a8c07f2d6fbadce1ce1e1379bf4b32d/server.jar", + "1.18-pre1": "https://piston-data.mojang.com/v1/objects/1c01e11c62ef7ce9b91324b570a1252d07544f18/server.jar", + "1.18-pre2": "https://piston-data.mojang.com/v1/objects/c203586f5d2c02b417f0e104b65a8e5e7625b2f8/server.jar", + "1.18-pre3": "https://piston-data.mojang.com/v1/objects/146d1809368fef552274122d9c380423c38068ab/server.jar", + "1.18-pre4": "https://piston-data.mojang.com/v1/objects/d17d3501f7f9d68793d5a505978ea5b87a208b43/server.jar", + "1.18-pre5": "https://piston-data.mojang.com/v1/objects/c29d03e9c6a21a3234a947e1025793c3cc40c13b/server.jar", + "1.18-pre6": "https://piston-data.mojang.com/v1/objects/97b1c53df11cb8b973f4b522c8f4963b7e31495e/server.jar", + "1.18-pre7": "https://piston-data.mojang.com/v1/objects/fe08544bb92ebe53070ec4a5f161ac19d8e9e4bb/server.jar", + "1.18-pre8": "https://piston-data.mojang.com/v1/objects/051efe8853d00db6bef7f19324da25a465782376/server.jar", + "1.18-rc1": "https://piston-data.mojang.com/v1/objects/81a2baf05f8f5bda41fac1542e7cc9d937bff41b/server.jar", + "1.18-rc2": "https://piston-data.mojang.com/v1/objects/96162b8d0af608bee2febe602bdb46942e85f6d8/server.jar", + "1.18-rc3": "https://piston-data.mojang.com/v1/objects/9a03d2c4ec2c737ce9d17a43d3774cdc0ea21030/server.jar", + "1.18-rc4": "https://piston-data.mojang.com/v1/objects/5889357fe058d867f6e27ee3f033286c430ec91e/server.jar", + "1.18.1-pre1": "https://piston-data.mojang.com/v1/objects/cd99e68b49c8a7db185d053518c6fb135cd04564/server.jar", + "1.18.1-rc1": "https://piston-data.mojang.com/v1/objects/fa98951fb1fa1ca04d8d6283e91e667d91e6410d/server.jar", + "1.18.1-rc2": "https://piston-data.mojang.com/v1/objects/653c704a89fe6437b363cff32ded037d5c0f6ec0/server.jar", + "1.18.1-rc3": "https://piston-data.mojang.com/v1/objects/29c43f3af18e66f8368a16ec89f8e54ecda71d85/server.jar", + "22w03a": "https://piston-data.mojang.com/v1/objects/686320be073916ae97b1ad78d22627809491dfc2/server.jar", + "22w05a": "https://piston-data.mojang.com/v1/objects/e6183efda3cea1871cb090b37ec7e0305d6ebbde/server.jar", + "22w06a": "https://piston-data.mojang.com/v1/objects/60c757a63f21877f8b053904ac76d04ff3cb76ef/server.jar", + "22w07a": "https://piston-data.mojang.com/v1/objects/8131d9e36640d40ce8464c58035f35475579e897/server.jar", + "1.18.2-pre1": "https://piston-data.mojang.com/v1/objects/c3e2734bafdb017efab854b01c66dd795722a332/server.jar", + "1.18.2-pre2": "https://piston-data.mojang.com/v1/objects/888cb380db39a115cfe978c00922d24536bdd2a5/server.jar", + "1.18.2-pre3": "https://piston-data.mojang.com/v1/objects/1c898afff0449eed08ad8036aaa4c652952035de/server.jar", + "1.18.2-rc1": "https://piston-data.mojang.com/v1/objects/2f52c69c90d63c024548ae5c5438ff3156ece6c2/server.jar", + "22w11a": "https://piston-data.mojang.com/v1/objects/a13b9678c60b0a84767e6cef0086c65cadac036e/server.jar", + "22w12a": "https://piston-data.mojang.com/v1/objects/f238cf129a0848effe5037d8aaefe3f1f350b689/server.jar", + "22w13a": "https://piston-data.mojang.com/v1/objects/7c8afca77bb9a73d31cdc70f2f68b4119d581455/server.jar", + "22w13oneblockatatime": "https://piston-data.mojang.com/v1/objects/5f48eea55c7fd1881d9c63835b15dfb5bbcd3a67/server.jar", + "22w14a": "https://piston-data.mojang.com/v1/objects/cf4f3a6492c0a84e2e852fe0ea714080923ab6ad/server.jar", + "22w15a": "https://piston-data.mojang.com/v1/objects/2760f745a00711bcc19bf78d6056019f69318d03/server.jar", + "22w16a": "https://piston-data.mojang.com/v1/objects/8ac6c67599bd30009fdc2f9d0174419b0bc19f8b/server.jar", + "22w16b": "https://piston-data.mojang.com/v1/objects/a54810e8b1a7a043fa54a462309d680ad67da479/server.jar", + "22w17a": "https://piston-data.mojang.com/v1/objects/9b4d5a87b48d7c3784fdfc9d6982543e8d9296df/server.jar", + "22w18a": "https://piston-data.mojang.com/v1/objects/d3259a8939a724c78ebbb995dfc31c1c364464e3/server.jar", + "22w19a": "https://piston-data.mojang.com/v1/objects/c354ac562b44fe5857535935125942ff89616cab/server.jar", + "1.19-pre1": "https://piston-data.mojang.com/v1/objects/1be90ec671e145e56b789de428b63ec43a2d9721/server.jar", + "1.19-pre2": "https://piston-data.mojang.com/v1/objects/6cc6cac49cd862ad9005816eb1ffc7dd4bd066dd/server.jar", + "1.19-pre3": "https://piston-data.mojang.com/v1/objects/0702387c3519cc23a5184893275d00c05abf056d/server.jar", + "1.19-pre4": "https://piston-data.mojang.com/v1/objects/a16331571233081eced58459a33254aa5a984a7d/server.jar", + "1.19-pre5": "https://piston-data.mojang.com/v1/objects/1ba1b6389f00fa40a10af047fd7a76a9c68dba72/server.jar", + "1.19-rc1": "https://piston-data.mojang.com/v1/objects/76ebdba03954e5a2185fb7a1d3a25096eb6bd195/server.jar", + "1.19-rc2": "https://piston-data.mojang.com/v1/objects/d3250b1e5e0e8762ec8ceae034d5f229965d00d3/server.jar", + "22w24a": "https://piston-data.mojang.com/v1/objects/fdad42550c3f0bcdc52680dcebd5b712d32bc5d7/server.jar", + "1.19.1-pre1": "https://piston-data.mojang.com/v1/objects/a4d30a572176e81e115d36ec71bd2e67798ed14e/server.jar", + "1.19.1-rc1": "https://piston-data.mojang.com/v1/objects/71a6d4c634de517ab1b6c2db8b743cbc831d9794/server.jar", + "1.19.1-pre2": "https://piston-data.mojang.com/v1/objects/17354c4963fb0176ad34595927ce62e55ea3daf4/server.jar", + "1.19.1-pre3": "https://piston-data.mojang.com/v1/objects/afbc14b0518843f189ed3ddd00f01b5881ef6513/server.jar", + "1.19.1-pre4": "https://piston-data.mojang.com/v1/objects/0f7f0c876024d0a84cb50547f72fe81dbfbfdb19/server.jar", + "1.19.1-pre5": "https://piston-data.mojang.com/v1/objects/33cdf9ceaaedebb0a71ca5f4d85d4e7198c09b8e/server.jar", + "1.19.1-pre6": "https://piston-data.mojang.com/v1/objects/2cad39169c1a505ffca1049b236a4ddaf62c617d/server.jar", + "1.19.1-rc2": "https://piston-data.mojang.com/v1/objects/5ec09b2700e5e83380a23cb18e66cfdaa931640b/server.jar", + "1.19.1-rc3": "https://piston-data.mojang.com/v1/objects/e7ff323e06ccb32083b7cd2472dce3b9056e2940/server.jar", + "1.19.2-rc1": "https://piston-data.mojang.com/v1/objects/ba8a776dc31a6093a07d3f4fbad1a8d680f8faf3/server.jar", + "1.19.2-rc2": "https://piston-data.mojang.com/v1/objects/93649d39350077f998296138964e4591d4571140/server.jar", + "22w42a": "https://piston-data.mojang.com/v1/objects/008996e2d1e0d49d7f1b477f69106a6d23c5c103/server.jar", + "22w43a": "https://piston-data.mojang.com/v1/objects/6718a5ac0b073644dbdfbd25f8218c68a1b390db/server.jar", + "22w44a": "https://piston-data.mojang.com/v1/objects/ed050b461b7dd347f383176ef03a71bacb844e69/server.jar", + "22w45a": "https://piston-data.mojang.com/v1/objects/d98f05500b14a8884b85e71be9fa1ef0d261029a/server.jar", + "22w46a": "https://piston-data.mojang.com/v1/objects/302ae4acba96e733fdbe144ebe2ba575b2bbf969/server.jar", + "1.19.3-pre1": "https://piston-data.mojang.com/v1/objects/046fee78cd174105cb9b958a8459c0405ab19959/server.jar", + "1.19.3-pre2": "https://piston-data.mojang.com/v1/objects/f8a18aa1e7b658de909470f69553c53d8662dfbe/server.jar", + "1.19.3-pre3": "https://piston-data.mojang.com/v1/objects/323175facb90c05b07dff84b4cff39fd9cab138a/server.jar", + "1.19.3-rc1": "https://piston-data.mojang.com/v1/objects/0c713920eff7358cb01c56979e8d732943bb893b/server.jar", + "1.19.3-rc2": "https://piston-data.mojang.com/v1/objects/138c813e22102e1a82a1be7b76080f40235183fe/server.jar", + "1.19.3-rc3": "https://piston-data.mojang.com/v1/objects/5f459ba58558d797229c819c0314bec84e774ecb/server.jar", + "23w03a": "https://piston-data.mojang.com/v1/objects/b033d57035b293a9eda548db0615c1c89c21ea28/server.jar", + "23w04a": "https://piston-data.mojang.com/v1/objects/2f31a8584ec1e70abd2d8b22d976feb52a6a3e31/server.jar", + "23w05a": "https://piston-data.mojang.com/v1/objects/98cfa3f8f9aef61e1298c9cfd62f6eeaf8abe206/server.jar", + "23w06a": "https://piston-data.mojang.com/v1/objects/daaed1fac98d17bd76f8fd43268f1c1b97230b59/server.jar", + "23w07a": "https://piston-data.mojang.com/v1/objects/b919e6e1683a4b6f37f2717c7841e88e306bdc94/server.jar", + "1.19.4-pre1": "https://piston-data.mojang.com/v1/objects/0bc471b96bb0edbc2f03e6cdc3ad981f7a4f5f8a/server.jar", + "1.19.4-pre2": "https://piston-data.mojang.com/v1/objects/d0b48d637834e879c16de26ffc11226d2d8e6772/server.jar", + "1.19.4-pre3": "https://piston-data.mojang.com/v1/objects/cedc29f7e4927bfe58c96e67495a73c7333c75cd/server.jar", + "1.19.4-pre4": "https://piston-data.mojang.com/v1/objects/711aa1f63c20650789e9740d66ff55c3e8e4f2ae/server.jar", + "1.19.4-rc1": "https://piston-data.mojang.com/v1/objects/c41c9653dc18634f52c010040177deabf9a878f2/server.jar", + "1.19.4-rc2": "https://piston-data.mojang.com/v1/objects/8abd7d9568385ade54cdd8bf77306e637482711b/server.jar", + "1.19.4-rc3": "https://piston-data.mojang.com/v1/objects/905778cc578c5a1757a9358a3feb5c19a0178fec/server.jar", + "23w12a": "https://piston-data.mojang.com/v1/objects/92fdef90109e534d47e378124ab86e2d6d7b3a42/server.jar", + "23w13a": "https://piston-data.mojang.com/v1/objects/701767d4d07aad992e3e2875ae5d1485cebf66e0/server.jar", + "23w13a_or_b": "https://piston-data.mojang.com/v1/objects/6241fc14ce7a659f371683a72aa24c155f60cce1/server.jar", + "23w14a": "https://piston-data.mojang.com/v1/objects/cb67d34c44013759bca77085ae42e3a7b37f265d/server.jar", + "23w16a": "https://piston-data.mojang.com/v1/objects/4a8487f877eb4f3506978fb85faf41a08b570398/server.jar", + "23w17a": "https://piston-data.mojang.com/v1/objects/96e1b9db0f3d90309db34e8ce4fd39b52f6ddaa0/server.jar", + "23w18a": "https://piston-data.mojang.com/v1/objects/240177c763b6009ea81aaf0ef14a73822320856d/server.jar", + "1.20-pre1": "https://piston-data.mojang.com/v1/objects/95ac4bf3d2f4ae57687493f5232d3f58334b85d2/server.jar", + "1.20-pre2": "https://piston-data.mojang.com/v1/objects/fce02f0ed50b4722f8ec58acef06275b91cde08d/server.jar", + "1.20-pre3": "https://piston-data.mojang.com/v1/objects/6adffc7f05724f22b1644ecc191899e4beb33443/server.jar", + "1.20-pre4": "https://piston-data.mojang.com/v1/objects/04b889e29aeffc23d2a3ebdd7e728184d9441e02/server.jar", + "1.20-pre5": "https://piston-data.mojang.com/v1/objects/2b41aed1e7c7fecf11ca15bad03b0fa95eb4fbd9/server.jar", + "1.20-pre6": "https://piston-data.mojang.com/v1/objects/c737b7411fc0b60426a9feca83d09d63f4a86f27/server.jar", + "1.20-pre7": "https://piston-data.mojang.com/v1/objects/ed6ddd61aeb1f529ef626fae9bcb0a5f51491f71/server.jar", + "1.20-rc1": "https://piston-data.mojang.com/v1/objects/0d9315f92842e35fcb6fddb10db3a13675a1ad04/server.jar", + "1.20.1-rc1": "https://piston-data.mojang.com/v1/objects/6890ac51068a05e3fcc4158478247e5a5e47bcac/server.jar", + "23w31a": "https://piston-data.mojang.com/v1/objects/11ef2ae139b0badda80a1ea07c2dd0cf9034a32f/server.jar", + "23w32a": "https://piston-data.mojang.com/v1/objects/bfe1a408d8d809b206369fceab0e8a883226d0a6/server.jar", + "23w33a": "https://piston-data.mojang.com/v1/objects/0254dde460b23861840cff6e80fc7fdbbccad88e/server.jar", + "23w35a": "https://piston-data.mojang.com/v1/objects/6a2ac9eecb377f4894b84de711973edc751d0607/server.jar", + "1.20.2-pre1": "https://piston-data.mojang.com/v1/objects/7fa1c9c59238ee98696da880d361d96c728dd9ea/server.jar", + "1.20.2-pre2": "https://piston-data.mojang.com/v1/objects/cf5d9b2461898afd589274349989be704084a8dd/server.jar", + "1.20.2-pre3": "https://piston-data.mojang.com/v1/objects/3d2eecdda5f6c7260d73aa5c2e5ce1a42e0f24e4/server.jar", + "1.20.2-pre4": "https://piston-data.mojang.com/v1/objects/9f1b8f9918d5d8d59781886f33e5b7b2053d0486/server.jar", + "1.20.2-rc1": "https://piston-data.mojang.com/v1/objects/70dad7e61afc2e255e73842760ef9461a00c852d/server.jar", + "1.20.2-rc2": "https://piston-data.mojang.com/v1/objects/ef01ddc7ee3fd517f55f34259c411323673b6347/server.jar", + "23w40a": "https://piston-data.mojang.com/v1/objects/0f51a81705f4694b92f5273ffa2c52c45f27b7f8/server.jar", + "23w41a": "https://piston-data.mojang.com/v1/objects/e3e4c46324ac42b1789f7ff6e895ae3c843a9819/server.jar", + "23w42a": "https://piston-data.mojang.com/v1/objects/b5f423ba1c4191d133c0284a2b1b36da46f8b5f8/server.jar", + "23w43a": "https://piston-data.mojang.com/v1/objects/135f89e56c2d83d9ef0f7915f0cdf1047737d51a/server.jar", + "23w43b": "https://piston-data.mojang.com/v1/objects/e7f9a4ca5ad3cadee399aa90f1d37f3ee94f292c/server.jar", + "23w44a": "https://piston-data.mojang.com/v1/objects/009b4831cdda78d8f9b235265e45d0bf14a920da/server.jar", + "23w45a": "https://piston-data.mojang.com/v1/objects/9c2b37701bf77ae22df4c32fd6dd1614049ce994/server.jar", + "23w46a": "https://piston-data.mojang.com/v1/objects/2f30bbf9229e2dcbaf148eb9750df1d19ffa6d19/server.jar", + "1.20.3-pre1": "https://piston-data.mojang.com/v1/objects/e5db7e4884f55c4dd986ca7200145759169e0045/server.jar", + "1.20.3-pre2": "https://piston-data.mojang.com/v1/objects/5a76da0ae88eee28ab4c0fa2ffabb837a4572398/server.jar", + "1.20.3-pre3": "https://piston-data.mojang.com/v1/objects/3802cf61288841f29f0af0d7c73ab58094be34cd/server.jar", + "1.20.3-pre4": "https://piston-data.mojang.com/v1/objects/1567e8a24c547ac3a95ce41d24024a94e9c7299c/server.jar", + "1.20.3-rc1": "https://piston-data.mojang.com/v1/objects/64cab4e87f8c2cad74d8bfc23df2cd193b4a615e/server.jar", + "1.20.4-rc1": "https://piston-data.mojang.com/v1/objects/589a0babd82ff5a086e4085aa8a1dc46fecc222d/server.jar", + "23w51a": "https://piston-data.mojang.com/v1/objects/e44e1d8c34f3020b0485ddd1436e91134b7de9a3/server.jar", + "23w51b": "https://piston-data.mojang.com/v1/objects/d443ec98f3f3ee2dc92e0788d6d83d74844feb4f/server.jar", + "24w03a": "https://piston-data.mojang.com/v1/objects/730a3ef2f99f6a822aa504bfee2eb5372d826293/server.jar", + "24w03b": "https://piston-data.mojang.com/v1/objects/5b9a529dc40d8394cbd6203a8ebe66c8e2f86fd4/server.jar", + "24w04a": "https://piston-data.mojang.com/v1/objects/d9f13751240a2fe4e85be1c839d9a4de1413c251/server.jar", + "24w05a": "https://piston-data.mojang.com/v1/objects/cc0f01e6406fa8a2b50c3c06edef74e7a7bf74de/server.jar", + "24w05b": "https://piston-data.mojang.com/v1/objects/189526bf25c06f7c0071aa637bc5f3668a6457d4/server.jar", + "24w06a": "https://piston-data.mojang.com/v1/objects/703cffc390ff71b7900d7a4356f48bc2108b448e/server.jar", + "24w07a": "https://piston-data.mojang.com/v1/objects/94acd52e9b9392e21a06231bdc4f8f0cd6ccb2af/server.jar", + "24w09a": "https://piston-data.mojang.com/v1/objects/7c70922198a2d18e0252c315b55623b822b4e910/server.jar", + "24w10a": "https://piston-data.mojang.com/v1/objects/9f8e96ebe4db0323653111b28df63f66395cb19d/server.jar", + "24w11a": "https://piston-data.mojang.com/v1/objects/00cab0438130dc3e6ae91f53387bb96ae7986d31/server.jar", + "24w12a": "https://piston-data.mojang.com/v1/objects/6f036460d361ce1e645bba365a72be2eed35ec01/server.jar", + "24w13a": "https://piston-data.mojang.com/v1/objects/2fd2113b7b81cc78cb4a76939a6c11840d57036d/server.jar", + "24w14potato": "https://piston-data.mojang.com/v1/objects/2d29eee4f5a71f323d20b36d623e2ec21dab74f7/server.jar", + "24w14a": "https://piston-data.mojang.com/v1/objects/960cb0e5c794b02abdbcdbdc15b4de058b222118/server.jar", + "1.20.5-pre1": "https://piston-data.mojang.com/v1/objects/018c4aa3b1dcd5ac4487456de062072de750f729/server.jar", + "1.20.5-pre2": "https://piston-data.mojang.com/v1/objects/c794b404663758cba43c67d097a25c5d4eb84a37/server.jar", + "1.20.5-pre3": "https://piston-data.mojang.com/v1/objects/5ac067ccc569ef9e2177cf4331c8e82d3e072692/server.jar", + "1.20.5-pre4": "https://piston-data.mojang.com/v1/objects/2793397cf42243a69fca37ff0887e8560a36c583/server.jar", + "1.20.5-rc1": "https://piston-data.mojang.com/v1/objects/ec45f58d589dc1b00b25c6798dd10d2af70867e5/server.jar", + "1.20.5-rc2": "https://piston-data.mojang.com/v1/objects/921814646156d838286dc0634a0031f042c6e0d2/server.jar", + "1.20.5-rc3": "https://piston-data.mojang.com/v1/objects/7d735a8eda6797ed196141b76e96b46546bde091/server.jar", + "1.20.6-rc1": "https://piston-data.mojang.com/v1/objects/a9b9c22721ec3ac516627f30554f21ed7c23efe5/server.jar", + "24w18a": "https://piston-data.mojang.com/v1/objects/22618c686c86be630601e5d9fcf581674105c899/server.jar", + "24w19a": "https://piston-data.mojang.com/v1/objects/8088cca48fece804d29b368ab5bbcc27a540456c/server.jar", + "24w19b": "https://piston-data.mojang.com/v1/objects/447bfe84875399d44d383de7f534e1cc10bae9a5/server.jar", + "24w20a": "https://piston-data.mojang.com/v1/objects/e3b1bcc2d7a09b6f1acfef7090ee64409feb3b94/server.jar", + "24w21a": "https://piston-data.mojang.com/v1/objects/6ba7192e60bedb3ff02db3c57b75f7ea56c63242/server.jar", + "24w21b": "https://piston-data.mojang.com/v1/objects/743d74805b64f83052fe449993f42182f76b129e/server.jar", + "1.21-pre1": "https://piston-data.mojang.com/v1/objects/57e59ee5d8bc6ce664a7d76de45f8df9c110381f/server.jar", + "1.21-pre2": "https://piston-data.mojang.com/v1/objects/3a8da3a1afcfb09d701fa17e405d09cd0c635748/server.jar", + "1.21-pre3": "https://piston-data.mojang.com/v1/objects/96266e18a95faa1c785ac852315e886d0e8bb174/server.jar", + "1.21-pre4": "https://piston-data.mojang.com/v1/objects/14b1a86d9fcfc82c013e82910e8209617c3a721e/server.jar", + "1.21-rc1": "https://piston-data.mojang.com/v1/objects/902101d2fb0f968b9c0ddb8b8cff9afef23f72c7/server.jar" +} # CLS -def limpiar_consola(): - if os.name == 'nt': # En Windows - On Windows - os.system('cls') - else: # For Linux - os.system('clear') +def cls(): + os.system('cls') -# WINDOW TITLE +# CHANGE WINDOW TITLE def window_title(title): - if sys.platform.startswith('win32'): # En Windows - On Windows - ctypes.windll.kernel32.SetConsoleTitleW(title) - elif sys.platform.startswith('linux') or sys.platform.startswith('darwin'): # For Linux - sys.stdout.write(f"\x1b]2;{title}\x07") + os.system(f'title {title}') # BRING WINDOW TO FRONT def front(): - if os.name == 'nt': # For Windows - os.system("echo off && echo ShowConsole && echo on") - else: # For Linux - os.system("wmctrl -a 'Terminal'") + os.system('echo ShowConsole') # ENGLISH def eng(): @@ -143,7 +759,7 @@ def eng(): # SERVER STARTUP def ram(): global servername - limpiar_consola() + cls() sservers = {} if os.path.exists(SAVED_SERVERS): with open(SAVED_SERVERS, 'r') as file: @@ -153,7 +769,7 @@ def ram(): key, value = line.split('<[=]>') sservers[key.strip()] = value.strip() if sservers: - limpiar_consola() + cls() print('Server Launcher for Minecraft\n-------------------------------------\n\n"Your Servers" List\n') server_keys = list(sservers.keys()) for i, key in enumerate(server_keys, start=1): @@ -169,7 +785,7 @@ def ram(): front() servname = os.path.basename(newserv) if newserv == "" or servname == "": - limpiar_consola() + cls() print('Server Launcher for Minecraft\n-------------------------------------\n\nYou must select a folder to save it in "Your Servers" List.') time.sleep(2.5) ram() @@ -181,13 +797,13 @@ def ram(): lines = file.readlines() if servstring not in lines: file.write(servstring) - limpiar_consola() + cls() print(f'Server Launcher for Minecraft\n-------------------------------------\n\nThe server "{servname}" has been saved.') time.sleep(1.5) ram() elif servsel.lower() == "d": def servdel(): - limpiar_consola() + cls() print("Server Launcher for Minecraft\n-------------------------------------\n\nSelect the server to delete from the list.\n") for i, key in enumerate(server_keys, start=1): print(f"({i}) {key}") @@ -219,7 +835,7 @@ def servdel(): for line in lines: if line != servestring: file.write(line) - limpiar_consola() + cls() print(f'Server Launcher for Minecraft\n-------------------------------------\n\nThe server "{servsel}" has been deleted from the list.') time.sleep(1.5) ram() @@ -228,7 +844,7 @@ def servdel(): servdel() elif servsel.lower() == "c": def lisclear(): - limpiar_consola() + cls() yess = colored("Yes","green") noo = colored("No","red") clearconfirm = input(f'Server Launcher for Minecraft\n-------------------------------------\n\nAre you sure you want to clear the "Your Servers" List?\n\n(1) {yess}\n(2) {noo}\n\nSelect one of the options= ') @@ -245,7 +861,7 @@ def lisclear(): os.makedirs(CONFIG_PATH, exist_ok=True) with open(SAVED_SERVERS, 'w') as file: file.write("# Server Launcher for Minecraft\n# Saved servers\n") - limpiar_consola() + cls() print('Server Launcher for Minecraft\n-------------------------------------\n\nThe "Your Servers" List has been cleared.') time.sleep(1.5) ram() @@ -277,7 +893,7 @@ def lisclear(): os.makedirs(CONFIG_PATH, exist_ok=True) with open(SAVED_SERVERS, 'w') as file: file.write("# Server Launcher for Minecraft\n# Saved servers\n") - limpiar_consola() + cls() adds = colored("Add a Server","cyan") saveconfirm = input(f"Server Launcher for Minecraft\n-------------------------------------\n\nThere are no saved servers.\n\n(1) {adds}\n(2) Return to main menu\n\nSelect one of the options= ") try: @@ -294,7 +910,7 @@ def lisclear(): front() servname = os.path.basename(newserv) if newserv == "" or servname == "": - limpiar_consola() + cls() print('Server Launcher for Minecraft\n-------------------------------------\n\nYou must select a folder to save it in "Your Servers" List.') time.sleep(2.5) ram() @@ -306,7 +922,7 @@ def lisclear(): lines = file.readlines() if servstring not in lines: file.write(servstring) - limpiar_consola() + cls() print(f'Server Launcher for Minecraft\n-------------------------------------\n\nThe server "{servname}" has been saved.') time.sleep(1.5) ram() @@ -320,13 +936,13 @@ def lisclear(): os.makedirs(CONFIG_PATH, exist_ok=True) with open(SAVED_SERVERS, 'w') as file: file.write("# Server Launcher for Minecraft\n# Saved servers\n") - limpiar_consola() + cls() input('Server Launcher for Minecraft\n-------------------------------------\n\nThere are no saved servers.\n\nPress ENTER to select a folder with a Server and add it to "Your Servers" list.') newserv = filedialog.askdirectory() front() servname = os.path.basename(newserv) if newserv == "" or servname == "": - limpiar_consola() + cls() print('Server Launcher for Minecraft\n-------------------------------------\n\nYou must select a folder to save it in "Your Servers" List.') time.sleep(2.5) ram() @@ -337,7 +953,7 @@ def lisclear(): lines = file.readlines() if servstring not in lines: file.write(servstring) - limpiar_consola() + cls() print(f'Server Launcher for Minecraft\n-------------------------------------\n\nThe server "{servname}" has been saved.') time.sleep(1.5) ram() @@ -345,7 +961,7 @@ def lisclear(): # CONFIG def config(): global nameserver - limpiar_consola() + cls() props = "server.properties" if os.path.exists(props): global properties @@ -371,7 +987,7 @@ def config(): pvp = colored("ENABLE","green") elif properties["pvp"] == "true": pvp = colored("DISABLE","red") - limpiar_consola() + cls() confsel = input(f'Server Launcher for Minecraft\n-------------------------------------\n\nLets manage "{nameserver}"!\n\n(1) {online} online mode\n(2) {hard} hardcore mode\n(3) {pvp} PvP\n(4) Change gamemode\n(5) Change difficulty\n(6) Change max players limit\n(7) Back\n(8) Return to main menu\n\nSelect one of the options= ') if properties["online-mode"] == "false": online = "ENABLE" @@ -407,7 +1023,7 @@ def config(): for key, value in properties.items(): file.write(f'{key}={value}\n') online = colored("DISABLED","red") - limpiar_consola() + cls() print(f"Server Launcher for Minecraft\n-------------------------------------\n\nOnline mode has been {online}.") time.sleep(1.5) config() @@ -424,7 +1040,7 @@ def config(): for key, value in properties.items(): file.write(f'{key}={value}\n') hard = colored("DISABLED","red") - limpiar_consola() + cls() print(f"Server Launcher for Minecraft\n-------------------------------------\n\nHardcore mode has been {hard}.") time.sleep(1.5) config() @@ -441,7 +1057,7 @@ def config(): for key, value in properties.items(): file.write(f'{key}={value}\n') pvp = colored("DISABLED","red") - limpiar_consola() + cls() print(f"Server Launcher for Minecraft\n-------------------------------------\n\nPvP has been {pvp}.") time.sleep(1.5) config() @@ -461,7 +1077,7 @@ def juego(): creat = colored("CREATIVE","yellow") avent = colored("ADVENTURE","yellow") espect = colored("SPECTATOR","yellow") - limpiar_consola() + cls() modosel = input(f"Server Launcher for Minecraft\n-------------------------------------\n\nThe current game mode is {modo}.\n\n(1) Change to {superv} gamemode\n(2) Change to {creat} gamemode\n(3) Change to {avent} gamemode\n(4) Change to {espect} gamemode\n(5) Go back\n(6) Return to main menu\n\nSelect one of the options= ") try: if any(char in "0123456789+-*/" for char in modosel): @@ -477,7 +1093,7 @@ def juego(): with open('server.properties', 'w') as file: for key, value in properties.items(): file.write(f'{key}={value}\n') - limpiar_consola() + cls() print(f"Server Launcher for Minecraft\n-------------------------------------\n\nGamemode has been set to {superv}.") time.sleep(1.5) juego() @@ -486,7 +1102,7 @@ def juego(): with open('server.properties', 'w') as file: for key, value in properties.items(): file.write(f'{key}={value}\n') - limpiar_consola() + cls() print(f"Server Launcher for Minecraft\n-------------------------------------\n\nGamemode has been set to {creat}.") time.sleep(1.5) juego() @@ -495,7 +1111,7 @@ def juego(): with open('server.properties', 'w') as file: for key, value in properties.items(): file.write(f'{key}={value}\n') - limpiar_consola() + cls() print(f"Server Launcher for Minecraft\n-------------------------------------\n\nGamemode has been set to {avent}.") time.sleep(1.5) juego() @@ -504,7 +1120,7 @@ def juego(): with open('server.properties', 'w') as file: for key, value in properties.items(): file.write(f'{key}={value}\n') - limpiar_consola() + cls() print(f"Server Launcher for Minecraft\n-------------------------------------\n\nGamemode has been set to {espect}.") time.sleep(1.5) juego() @@ -533,7 +1149,7 @@ def difconf(): facil = colored("EASY","yellow") normal = colored("NORMAL","yellow") dificil = colored("HARD","yellow") - limpiar_consola() + cls() difsel = input(f"Server Launcher for Minecraft\n-------------------------------------\n\nThe current difficulty is {dificultad}.\n\n(1) Change difficulty to {pacif}\n(2) Change difficulty to {facil}\n(3) Change difficulty to {normal}\n(4) Change difficulty to {dificil}\n(5) Go back\n(6) Return to main menu\n\nSelect one of the options= ") try: if any(char in "0123456789+-*/" for char in difsel): @@ -549,7 +1165,7 @@ def difconf(): with open('server.properties', 'w') as file: for key, value in properties.items(): file.write(f'{key}={value}\n') - limpiar_consola() + cls() print(f"Server Launcher for Minecraft\n-------------------------------------\n\nDifficulty has been set to {pacif}.") time.sleep(1.5) difconf() @@ -558,7 +1174,7 @@ def difconf(): with open('server.properties', 'w') as file: for key, value in properties.items(): file.write(f'{key}={value}\n') - limpiar_consola() + cls() print(f"Server Launcher for Minecraft\n-------------------------------------\n\nDifficulty has been set to {facil}.") time.sleep(1.5) difconf() @@ -567,7 +1183,7 @@ def difconf(): with open('server.properties', 'w') as file: for key, value in properties.items(): file.write(f'{key}={value}\n') - limpiar_consola() + cls() print(f"Server Launcher for Minecraft\n-------------------------------------\n\nDifficulty has been set to {normal}.") time.sleep(1.5) difconf() @@ -576,7 +1192,7 @@ def difconf(): with open('server.properties', 'w') as file: for key, value in properties.items(): file.write(f'{key}={value}\n') - limpiar_consola() + cls() print(f"Server Launcher for Minecraft\n-------------------------------------\n\nDifficulty has been set to {dificil}.") time.sleep(1.5) difconf() @@ -593,7 +1209,7 @@ def difconf(): def playct(): global properties players = colored(properties["max-players"],"cyan") - limpiar_consola() + cls() newpl = input(f"Server Launcher for Minecraft\n-------------------------------------\n\nThe current player limit is a maximum of {players}.\n\n(N) Go back\n(M) Return to main menu\n\nSelect one of the options or enter the new player limit= ").replace(" ", "") try: if newpl.lower() == "n": @@ -610,7 +1226,7 @@ def playct(): entero = newpl entero = int(entero) if entero <= 0 or entero > 100000: - limpiar_consola() + cls() print(f"Server Launcher for Minecraft\n-------------------------------------\n\nEnter a valid number between 1 and 100,000.") time.sleep(1.5) playct() @@ -620,7 +1236,7 @@ def playct(): for key, value in properties.items(): file.write(f'{key}={value}\n') entero = colored(str(entero),"yellow") - limpiar_consola() + cls() print(f"Server Launcher for Minecraft\n-------------------------------------\n\nThe maximum player limit is now {entero}.") time.sleep(1.5) playct() @@ -636,7 +1252,7 @@ def playct(): except (ValueError, SyntaxError, IndexError, ZeroDivisionError): config() else: - limpiar_consola() + cls() input("Server Launcher for Minecraft\n-------------------------------------\n\nThe server configuration files do not exist yet or are not available.\nYou must start the server properly at least once before you can configure it.\n\nPress ENTER to continue.") run_server() def run_server(): @@ -660,7 +1276,7 @@ def run_server(): vjava = "M" gbormb = colored("GIGABYTES","yellow") nameserver = servername - limpiar_consola() + cls() gbs = 0 rammount = input(f'Server Launcher for Minecraft\n-------------------------------------\n\nYou are about to start the Server "{nameserver}"\n\n(M) Manage Server\n(C) Use RAM in {gbormb}\n(B) Back\n(N) Return to main menu\n\nSelect one of the options or enter the {valor1} of RAM to assing to the server= ').replace(" ", "") try: @@ -668,13 +1284,13 @@ def run_server(): config() if rammount.lower() == "c": if valor == "GB": - limpiar_consola() + cls() print(f"Server Launcher for Minecraft\n-------------------------------------\n\nNow the RAM is on {gbormb}.") time.sleep(1.5) valor = "MB" run_server() elif valor == "MB": - limpiar_consola() + cls() print(f"Server Launcher for Minecraft\n-------------------------------------\n\nNow the RAM is on {gbormb}.") time.sleep(1.5) valor = "GB" @@ -693,12 +1309,12 @@ def run_server(): gbs = rammount gbs = int(gbs) if valor == "GB" and (gbs <= 0 or gbs > 75): - limpiar_consola() + cls() print(f"Server Launcher for Minecraft\n-------------------------------------\n\nEnter a valid amount between 1 and 75 Gigabytes.") time.sleep(1.5) run_server() elif valor == "MB" and (gbs <= 511 or gbs > 76800): - limpiar_consola() + cls() print(f"Server Launcher for Minecraft\n-------------------------------------\n\nEnter a valid amount between 512 and 76,800 Megabytes.") time.sleep(1.5) run_server() @@ -706,7 +1322,7 @@ def run_server(): eula = "eula.txt" with open(eula, "w") as reemplazo: reemplazo.write("eula=true") - limpiar_consola() + cls() print(f"Server Launcher for Minecraft\n-------------------------------------\n\nStarting the server with {gbs}{valor} of RAM.\n") comando_java = f"java -Xmx{gbs}{vjava} -Xms{gbs}{vjava} -jar server.jar nogui" subprocess.run(comando_java, shell=True) @@ -714,14 +1330,14 @@ def run_server(): fecha_cerrado = str(fyh_sistema.strftime("%d/%m/%Y")) hora_cerrado = str(fyh_sistema.strftime("%H:%M:%S")) input("\nPress ENTER to continue.") - limpiar_consola() + cls() input(f"Server Launcher for Minecraft\n-------------------------------------\n\nThe server has closed on {fecha_cerrado} at {hora_cerrado}.\n\nYou can check the console log in the 'logs' folder inside your Server's main folder.\n\nPress ENTER to continue.") ram() except (ValueError, SyntaxError, IndexError, ZeroDivisionError): run_server() run_server() else: - limpiar_consola() + cls() print('Server Launcher for Minecraft\n-------------------------------------\n\n"server.jar" not found in this folder.\n\nAre you sure this is a Server?') time.sleep(2.5) ram() @@ -730,7 +1346,7 @@ def run_server(): def installmenu(): global newserver global foldname - limpiar_consola() + cls() inconfirm = input("Server Launcher for Minecraft\n-------------------------------------\n\nFirst, lets select a folder to save your New Server's files.\n\n(1) Select folder for the new Server\n(2) Cancel\n\nSelect one of the options= ").replace(" ", "") try: if any(char in "0123456789+-*/" for char in inconfirm): @@ -749,7 +1365,7 @@ def reselect(): front() foldname = colored(os.path.basename(newserver), "green") if newserver == "" or foldname == "": - limpiar_consola() + cls() print('Server Launcher for Minecraft\n-------------------------------------\n\nYou must select a folder to save the New Server.') time.sleep(2.5) installmenu() @@ -759,15 +1375,18 @@ def reselect(): def vers_select(): global newserver global foldname - limpiar_consola() - verss = input(f'Server Launcher for Minecraft\n-------------------------------------\n\nYour New Server will be saved in "{foldname}".\n\n(L) List of available versions\n(R) Re-select a folder for the New server\n(N) Return to main menu\n\nSelect one of the options or type the New Server version to install= ').replace(" ", "") + cls() + verss = input(f'Server Launcher for Minecraft\n-------------------------------------\n\nYour New Server will be saved in "{foldname}".\n\n(L) See available versions\n(R) Re-select a folder for the New server\n(N) Return to main menu\n\nSelect one of the options or type the New Server version to install= ').replace(" ", "") try: - def servdownload(versionname): + def servdownload(versionname,type): global newserver global foldname version = versionname.lower() - url = MCVERSIONS[version] - limpiar_consola() + if type == "stable": + url = MCSTABLE[version] + else: + url = MCSNAPSHOT[version] + cls() print(f'Server Launcher for Minecraft\n-------------------------------------\n\nYour New Server is being downloaded.\n\nVersion: {version}\nTarget Folder: "{foldname}"\n\nPlease wait...\n') time.sleep(0.5) os.makedirs(newserver, exist_ok=True) @@ -784,7 +1403,7 @@ def servdownload(versionname): completed = int(50 * total_data / total_size_in_bytes) print("\r[%s%s]" % ('#' * completed, '.' * (50 - completed)), end='') print() - limpiar_consola() + cls() input('Server Launcher for Minecraft\n-------------------------------------\n\nThe server has been installed successfully and added to "Your Servers" list.\n\nPress ENTER to continue.') servname = os.path.basename(newserver) servstring = f"{servname}<[=]>{newserver}\n" @@ -796,7 +1415,7 @@ def servdownload(versionname): eng() except Exception: def erragain(): - limpiar_consola() + cls() yup = colored("Yes","green") nop = colored("No","red") errtry = input(f"Server Launcher for Minecraft\n-------------------------------------\n\nAn error occurred while downloading the server.\nTry again?\n\n(1) {yup}\n(2) {nop}\n\nSelect one of the options= ") @@ -810,7 +1429,7 @@ def erragain(): errtr = errtry errtr = int(errtr) if errtr == 1: - servdownload(version) + servdownload(version,type) elif errtr == 2: eng() else: @@ -823,10 +1442,15 @@ def erragain(): elif verss.lower() == "r": reselect() elif verss.lower() == "l": - def versionl(): - limpiar_consola() - print("Server Launcher for Minecraft\n-------------------------------------\n\nAvailable versions:\n") - for i, version in enumerate(MCVERSIONS, start=1): + def select_list(): + cls() + print("Server Launcher for Minecraft\n-------------------------------------\n") + print("STABLE VERSIONS:") + for i, version in enumerate(MCSTABLE, start=1): + print(f"(-) {version}") + print('') + print("SNAPSHOT VERSIONS:") + for i, version in enumerate(MCSNAPSHOT, start=1): print(f"(-) {version}") listselection = input("\n(B) Back\n(R) Return to main menu\n\nType a version or select one of the options=") try: @@ -834,15 +1458,19 @@ def versionl(): vers_select() elif listselection.lower() == "r": eng() - elif listselection.lower() in MCVERSIONS.keys(): - servdownload(listselection) + elif listselection.lower() in MCSTABLE.keys(): + servdownload(listselection,"stable") + elif listselection.lower() in MCSNAPSHOT.keys(): + servdownload(listselection,"snapshot") else: - versionl() + select_list() except (ValueError, SyntaxError, IndexError, ZeroDivisionError): - versionl() - versionl() - elif verss.lower() in MCVERSIONS.keys(): - servdownload(verss) + select_list() + select_list() + elif verss.lower() in MCSTABLE.keys(): + servdownload(verss,"stable") + elif verss.lower() in MCSNAPSHOT.keys(): + servdownload(verss,"snapshot") else: vers_select() except (ValueError, SyntaxError, IndexError, ZeroDivisionError): @@ -860,8 +1488,8 @@ def versionl(): # LICENSE AND EXTRAS def about(): - limpiar_consola() - copyr = input("Server Launcher for Minecraft\n-------------------------------------\n\nMIT License - Copyright (c) 2024 NGDPL Nk\n\nSSTools4MC v24.06.27 - ADDED SUPPORT FOR 1.21\n\nHelpers:\n@naicoooossj\n@LegalizeNuclearBombs\n\n-------------------------------------\n\n(1) View repository in the browser\n(2) View license in the browser\n(3) Return to main menu\n\nSelect one of the options= ") + cls() + copyr = input("Server Launcher for Minecraft\n-------------------------------------\n\nMIT License - Copyright (c) 2024 ngdplnk\n\nSSTools4MC v24.07.29 - ADDED SUPPORT FOR SNAPSHOT VERSIONS\n\nHelpers:\n@naicoooossj\n@LegalizeNuclearBombs\n\n-------------------------------------\n\n(1) View repository in the browser\n(2) View license in the browser\n(3) Return to main menu\n\nSelect one of the options= ") try: if any(char in "0123456789+-*/" for char in copyr): if not copyr[0].isalpha(): @@ -872,17 +1500,17 @@ def about(): selec = copyr selec = int(selec) if selec == 1: - url = colored("https://github.com/NGDPLNk/SSTools4MC","cyan") - limpiar_consola() + url = colored("https://github.com/ngdplnk/SSTools4MC","cyan") + cls() input(f"Server Launcher for Minecraft\n-------------------------------------\n\nThe repository will open in your browser.\n\n{url}\n\nPress ENTER to continue.") - url = "https://github.com/NGDPLNk/SSTools4MC" + url = "https://github.com/ngdplnk/SSTools4MC" webbrowser.open(url) about() elif selec == 2: - url = colored("https://github.com/NGDPLNk/SSTools4MC/blob/main/LICENSE","cyan") - limpiar_consola() + url = colored("https://github.com/ngdplnk/SSTools4MC/blob/main/LICENSE","cyan") + cls() input(f"Server Launcher for Minecraft\n-------------------------------------\n\nThe license will open in your browser.\n\n{url}\n\nPress ENTER to continue.") - url = "https://github.com/NGDPLNk/SSTools4MC/blob/main/LICENSE" + url = "https://github.com/ngdplnk/SSTools4MC/blob/main/LICENSE" webbrowser.open(url) about() elif selec == 3: @@ -894,8 +1522,8 @@ def about(): # EXIT def exiit(): - limpiar_consola() - print("--------------------------------------------\nThank you for using this tool\nMIT License - Copyright (c) 2024 NGDPL Nk\n--------------------------------------------\n") + cls() + print("--------------------------------------------\nSee ya later!\nMIT License - Copyright (c) 2024 ngdplnk\n--------------------------------------------\n") time.sleep(1.2) sys.exit() @@ -903,7 +1531,7 @@ def exiit(): def menu(): os.makedirs(SSTOOLS_FOLDER, exist_ok=True) os.chdir(SSTOOLS_FOLDER) - limpiar_consola() + cls() seleccion = input("Server Launcher for Minecraft\n-------------------------------------\n\nHi! You are in the main menu.\n\n(1) Start a Server\n(2) Install a New Server\n(3) Extras\n(4) Change Language\n(5) Exit\n\nSelect one of the options= ") try: if any(char in "0123456789+-*/" for char in seleccion): @@ -930,7 +1558,7 @@ def menu(): menu() -# ESPAÑOL +# SPANISH def esp(): # CHANGE WINDOW TITLE window_title("Lanzador de Servidores para Minecraft") @@ -938,7 +1566,7 @@ def esp(): # SERVER STARTUP def ram(): global servername - limpiar_consola() + cls() sservers = {} if os.path.exists(SAVED_SERVERS): with open(SAVED_SERVERS, 'r') as file: @@ -948,7 +1576,7 @@ def ram(): key, value = line.split('<[=]>') sservers[key.strip()] = value.strip() if sservers: - limpiar_consola() + cls() print('Lanzador de Servidores para Minecraft\n-------------------------------------\n\nLista "Tus Servidores"\n') server_keys = list(sservers.keys()) for i, key in enumerate(server_keys, start=1): @@ -964,7 +1592,7 @@ def ram(): front() servname = os.path.basename(newserv) if newserv == "" or servname == "": - limpiar_consola() + cls() print('Lanzador de Servidores para Minecraft\n-------------------------------------\n\nDebes elegir una carpeta para guardarla en la Lista "Tus Servidores".') time.sleep(2.5) ram() @@ -976,13 +1604,13 @@ def ram(): lines = file.readlines() if servstring not in lines: file.write(servstring) - limpiar_consola() + cls() print(f'Lanzador de Servidores para Minecraft\n-------------------------------------\n\nEl Server "{servname}" ha sido guardado.') time.sleep(1.5) ram() elif servsel.lower() == "d": def servdel(): - limpiar_consola() + cls() print("Lanzador de Servidores para Minecraft\n-------------------------------------\n\nSelecciona el Server que eliminarás de la lista.\n") for i, key in enumerate(server_keys, start=1): print(f"({i}) {key}") @@ -1014,7 +1642,7 @@ def servdel(): for line in lines: if line != servestring: file.write(line) - limpiar_consola() + cls() print(f'Lanzador de Servidores para Minecraft\n-------------------------------------\n\nEl Server "{servsel}" ha sido eliminado de la lista.') time.sleep(1.5) ram() @@ -1023,7 +1651,7 @@ def servdel(): servdel() elif servsel.lower() == "c": def lisclear(): - limpiar_consola() + cls() yess = colored("Sí","green") noo = colored("No","red") clearconfirm = input(f'Lanzador de Servidores para Minecraft\n-------------------------------------\n\nEstás seguro de que quieres limpiar la Lista "Tus Servidores"?\n\n(1) {yess}\n(2) {noo}\n\nElige una de las opciones= ') @@ -1040,7 +1668,7 @@ def lisclear(): os.makedirs(CONFIG_PATH, exist_ok=True) with open(SAVED_SERVERS, 'w') as file: file.write("# Lanzador de Servidores para Minecraft\n# Servers guardados\n") - limpiar_consola() + cls() print('Lanzador de Servidores para Minecraft\n-------------------------------------\n\nLa Lista "Tus Servidores" ha sido limpiada.') time.sleep(1.5) ram() @@ -1072,7 +1700,7 @@ def lisclear(): os.makedirs(CONFIG_PATH, exist_ok=True) with open(SAVED_SERVERS, 'w') as file: file.write("# Lanzador de Servidores para Minecraft\n# Servidores Guardados\n") - limpiar_consola() + cls() adds = colored("Añadir un Server","cyan") saveconfirm = input(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nNo tienes ningún Server guardado.\n\n(1) {adds}\n(2) Volver al menú principal\n\nElige una de las opciones= ") try: @@ -1089,7 +1717,7 @@ def lisclear(): front() servname = os.path.basename(newserv) if newserv == "" or servname == "": - limpiar_consola() + cls() print('Lanzador de Servidores para Minecraft\n-------------------------------------\n\nDebes elegir una carpeta para guardarla en la Lista "Tus Servidores".') time.sleep(2.5) ram() @@ -1101,7 +1729,7 @@ def lisclear(): lines = file.readlines() if servstring not in lines: file.write(servstring) - limpiar_consola() + cls() print(f'Lanzador de Servidores para Minecraft\n-------------------------------------\n\nEl Server "{servname}" ha sido guardado.') time.sleep(1.5) ram() @@ -1115,13 +1743,13 @@ def lisclear(): os.makedirs(CONFIG_PATH, exist_ok=True) with open(SAVED_SERVERS, 'w') as file: file.write("# Lanzador de Servidores para Minecraft\n# Servers Guardados\n") - limpiar_consola() + cls() input('Lanzador de Servidores para Minecraft\n-------------------------------------\n\nNo tienes ningún Server guardado.\n\nPresiona ENTER para seleccionar una carpeta con tu Server y guardarlo en la Lista "Tus Servidores".') newserv = filedialog.askdirectory() front() servname = os.path.basename(newserv) if newserv == "" or servname == "": - limpiar_consola() + cls() print('Lanzador de Servidores para Minecraft\n-------------------------------------\n\nDebes elegir una carpeta para guardarla en la Lista "Tus Servidores".') time.sleep(2.5) ram() @@ -1132,7 +1760,7 @@ def lisclear(): lines = file.readlines() if servstring not in lines: file.write(servstring) - limpiar_consola() + cls() print(f'Lanzador de Servidores para Minecraft\n-------------------------------------\n\nEl Server "{servname}" ha sido guardado.') time.sleep(1.5) ram() @@ -1140,7 +1768,7 @@ def lisclear(): # CONFIG def config(): global nameserver - limpiar_consola() + cls() props = "server.properties" if os.path.exists(props): global properties @@ -1166,7 +1794,7 @@ def config(): pvp = colored("ACTIVAR","green") elif properties["pvp"] == "true": pvp = colored("DESACTIVAR","red") - limpiar_consola() + cls() confsel = input(f'Lanzador de Servidores para Minecraft\n-------------------------------------\n\nConfiguremos "{nameserver}"!\n\n(1) {online} modo online\n(2) {hard} modo extremo\n(3) {pvp} PvP\n(4) Cambiar modo de juego\n(5) Cambiar dificultad\n(6) Cambiar el límite de jugadores\n(7) Atrás\n(8) Volver al menú principal\n\nElige una de las opciones= ') if properties["online-mode"] == "false": online = "ENABLE" @@ -1202,7 +1830,7 @@ def config(): for key, value in properties.items(): file.write(f'{key}={value}\n') online = colored("DESACTIVADO","red") - limpiar_consola() + cls() print(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nEl modo online se ha {online}.") time.sleep(1.5) config() @@ -1219,7 +1847,7 @@ def config(): for key, value in properties.items(): file.write(f'{key}={value}\n') hard = colored("DESACTIVADO","red") - limpiar_consola() + cls() print(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nEl modo extremo se ha {hard}.") time.sleep(1.5) config() @@ -1236,7 +1864,7 @@ def config(): for key, value in properties.items(): file.write(f'{key}={value}\n') pvp = colored("DESACTIVADO","red") - limpiar_consola() + cls() print(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nEl PvP se ha {pvp}.") time.sleep(1.5) config() @@ -1256,7 +1884,7 @@ def juego(): creat = colored("CREATIVO","yellow") avent = colored("AVENTURA","yellow") espect = colored("ESPECTADOR","yellow") - limpiar_consola() + cls() modosel = input(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nEl modo de juego actual es {modo}.\n\n(1) Cambiar a modo {superv}\n(2) Cambiar a modo {creat}\n(3) Cambiar a modo {avent}\n(4) Cambiar a modo {espect}\n(5) Atrás\n(6) Volver al menú principal\n\nElige una de las opciones= ") try: if any(char in "0123456789+-*/" for char in modosel): @@ -1272,7 +1900,7 @@ def juego(): with open('server.properties', 'w') as file: for key, value in properties.items(): file.write(f'{key}={value}\n') - limpiar_consola() + cls() print(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nEl modo de juego se ha cambiado a {superv}.") time.sleep(1.5) juego() @@ -1281,7 +1909,7 @@ def juego(): with open('server.properties', 'w') as file: for key, value in properties.items(): file.write(f'{key}={value}\n') - limpiar_consola() + cls() print(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nEl modo de juego se ha cambiado a {creat}.") time.sleep(1.5) juego() @@ -1290,7 +1918,7 @@ def juego(): with open('server.properties', 'w') as file: for key, value in properties.items(): file.write(f'{key}={value}\n') - limpiar_consola() + cls() print(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nEl modo de juego se ha cambiado a {avent}.") time.sleep(1.5) juego() @@ -1299,7 +1927,7 @@ def juego(): with open('server.properties', 'w') as file: for key, value in properties.items(): file.write(f'{key}={value}\n') - limpiar_consola() + cls() print(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nEl modo de juego se ha cambiado a {espect}.") time.sleep(1.5) juego() @@ -1328,7 +1956,7 @@ def difconf(): facil = colored("FÁCIL","yellow") normal = colored("NORMAL","yellow") dificil = colored("DIFÍCIL","yellow") - limpiar_consola() + cls() difsel = input(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nLa dificultad actual es {dificultad}.\n\n(1) Cambiar a dificultad {pacif}\n(2) Cambiar a dificultad {facil}\n(3) Cambiar a dificultad {normal}\n(4) Cambiar a dificultad {dificil}\n(5) Atrás\n(6) Volver al menú principal\n\nElige una de las opciones= ") try: if any(char in "0123456789+-*/" for char in difsel): @@ -1344,7 +1972,7 @@ def difconf(): with open('server.properties', 'w') as file: for key, value in properties.items(): file.write(f'{key}={value}\n') - limpiar_consola() + cls() print(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nLa dificultad se ha cambiado a {pacif}.") time.sleep(1.5) difconf() @@ -1353,7 +1981,7 @@ def difconf(): with open('server.properties', 'w') as file: for key, value in properties.items(): file.write(f'{key}={value}\n') - limpiar_consola() + cls() print(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nLa dificultad se ha cambiado a {facil}.") time.sleep(1.5) difconf() @@ -1362,7 +1990,7 @@ def difconf(): with open('server.properties', 'w') as file: for key, value in properties.items(): file.write(f'{key}={value}\n') - limpiar_consola() + cls() print(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nLa dificultad se ha cambiado a {normal}.") time.sleep(1.5) difconf() @@ -1371,7 +1999,7 @@ def difconf(): with open('server.properties', 'w') as file: for key, value in properties.items(): file.write(f'{key}={value}\n') - limpiar_consola() + cls() print(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nLa dificultad se ha cambiado a {dificil}.") time.sleep(1.5) difconf() @@ -1388,7 +2016,7 @@ def difconf(): def playct(): global properties players = colored(properties["max-players"],"cyan") - limpiar_consola() + cls() newpl = input(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nEl límite de jugadores actual es de {players} jugadores.\n\n(N) Atrás\n(M) Volver al menú principal\n\nElige una de las opciones o ingresa el nuevo límite de jugadores= ").replace(" ", "") try: if newpl.lower() == "n": @@ -1405,7 +2033,7 @@ def playct(): entero = newpl entero = int(entero) if entero <= 0 or entero > 100000: - limpiar_consola() + cls() print(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nIngresa un número válido entre 1 y 100.000.") time.sleep(1.5) playct() @@ -1415,7 +2043,7 @@ def playct(): for key, value in properties.items(): file.write(f'{key}={value}\n') entero = colored(str(entero),"yellow") - limpiar_consola() + cls() print(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nEl límite de jugadores ahora es {entero}.") time.sleep(1.5) playct() @@ -1431,7 +2059,7 @@ def playct(): except (ValueError, SyntaxError, IndexError, ZeroDivisionError): config() else: - limpiar_consola() + cls() input("Lanzador de Servidores para Minecraft\n-------------------------------------\n\nLos achivos de configuración del Server aún no existen o no están disponibles.\nDebes iniciar el Server correctamente al menos 1 vez antes de poder configurarlo.\n\nPresiona ENTER para continuar.") run_server() def run_server(): @@ -1455,7 +2083,7 @@ def run_server(): vjava = "M" gbormb = colored("GIGABYTES","yellow") nameserver = servername - limpiar_consola() + cls() gbs = 0 rammount = input(f'Lanzador de Servidores para Minecraft\n-------------------------------------\n\nEstás a punto de iniciar el Server "{nameserver}"\n\n(M) Configurar Server\n(C) Usar RAM en {gbormb}\n(B) Atrás\n(N) Volver al menú principal\n\nElige una de las opciones o ingresa los {valor1} de RAM para asignar a tu Server= ').replace(" ", "") try: @@ -1463,13 +2091,13 @@ def run_server(): config() if rammount.lower() == "c": if valor == "GB": - limpiar_consola() + cls() print(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nAhora la RAM está en {gbormb}.") time.sleep(1.5) valor = "MB" run_server() elif valor == "MB": - limpiar_consola() + cls() print(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nAhora la RAM está en {gbormb}.") time.sleep(1.5) valor = "GB" @@ -1488,12 +2116,12 @@ def run_server(): gbs = rammount gbs = int(gbs) if valor == "GB" and (gbs <= 0 or gbs > 75): - limpiar_consola() + cls() print(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nIngresa una cantidad válida entre 1 y 75 Gigabytes.") time.sleep(1.5) run_server() elif valor == "MB" and (gbs <= 511 or gbs > 76800): - limpiar_consola() + cls() print(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nIngresa una cantidad válida entre 512 y 76.800 Megabytes.") time.sleep(1.5) run_server() @@ -1501,7 +2129,7 @@ def run_server(): eula = "eula.txt" with open(eula, "w") as reemplazo: reemplazo.write("eula=true") - limpiar_consola() + cls() print(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nIniciando el Server con {gbs}{valor} de RAM.\n") comando_java = f"java -Xmx{gbs}{vjava} -Xms{gbs}{vjava} -jar server.jar nogui" subprocess.run(comando_java, shell=True) @@ -1509,14 +2137,14 @@ def run_server(): fecha_cerrado = str(fyh_sistema.strftime("%d/%m/%Y")) hora_cerrado = str(fyh_sistema.strftime("%H:%M:%S")) input("\nPresiona ENTER para continuar.") - limpiar_consola() + cls() input(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nEl Server se ha cerrado el {fecha_cerrado} a las {hora_cerrado}.\n\nPuedes ver el registro de la consola en la carpeta 'logs' dentro de la carpeta principal de tu Server.\n\nPresiona ENTER para continuar.") ram() except (ValueError, SyntaxError, IndexError, ZeroDivisionError): run_server() run_server() else: - limpiar_consola() + cls() print('Lanzador de Servidores para Minecraft\n-------------------------------------\n\nNo se encuentra "server.jar" en esta carpeta.\n\nEstás seguro que esto es un Server?') time.sleep(2.5) ram() @@ -1525,7 +2153,7 @@ def run_server(): def installmenu(): global newserver global foldname - limpiar_consola() + cls() inconfirm = input("Lanzador de Servidores para Minecraft\n-------------------------------------\n\nPrimero, seleccionemos una carpeta para guardar los archivos de tu Nuevo Server.\n\n(1) Seleccionar una carpeta para el Nuevo Server\n(2) Cancelar\n\nElige una de las opciones= ").replace(" ", "") try: if any(char in "0123456789+-*/" for char in inconfirm): @@ -1544,7 +2172,7 @@ def reselect(): front() foldname = colored(os.path.basename(newserver), "green") if newserver == "" or foldname == "": - limpiar_consola() + cls() print('Lanzador de Servidores para Minecraft\n-------------------------------------\n\nDebes elegir una carpeta para guardar tu Nuevo Server.') time.sleep(2.5) installmenu() @@ -1554,15 +2182,18 @@ def reselect(): def vers_select(): global newserver global foldname - limpiar_consola() - verss = input(f'Lanzador de Servidores para Minecraft\n-------------------------------------\n\nTu Nuevo Server se guardará en "{foldname}".\n\n(L) Lista de versiones disponibles\n(R) Reelegir una carpeta para el Nuevo Server\n(N) Volver al menú principal\n\nElige una de las opciones o escribe la versión para instalar tu Nuevo Server= ').replace(" ", "") + cls() + verss = input(f'Lanzador de Servidores para Minecraft\n-------------------------------------\n\nTu Nuevo Server se guardará en "{foldname}".\n\n(L) Ver versiones disponibles\n(R) Reelegir una carpeta para el Nuevo Server\n(N) Volver al menú principal\n\nElige una de las opciones o escribe la versión para instalar tu Nuevo Server= ').replace(" ", "") try: - def servdownload(versionname): + def servdownload(versionname,type): global newserver global foldname version = versionname.lower() - url = MCVERSIONS[version] - limpiar_consola() + if type == "stable": + url = MCSTABLE[version] + else: + url = MCSNAPSHOT[version] + cls() print(f'Lanzador de Servidores para Minecraft\n-------------------------------------\n\nTu Nuevo Server está siendo descargado.\n\nVersión: {version}\nCarpeta de destino: "{foldname}"\n\nEspera por favor...\n') time.sleep(0.5) os.makedirs(newserver, exist_ok=True) @@ -1579,7 +2210,7 @@ def servdownload(versionname): completed = int(50 * total_data / total_size_in_bytes) print("\r[%s%s]" % ('#' * completed, '.' * (50 - completed)), end='') print() - limpiar_consola() + cls() input('Lanzador de Servidores para Minecraft\n-------------------------------------\n\nTu Nuevo Server se ha instalado correctamente y ha sido añadido a la Lista "Tus Servidores".\n\nPresiona ENTER para continuar.') servname = os.path.basename(newserver) servstring = f"{servname}<[=]>{newserver}\n" @@ -1591,7 +2222,7 @@ def servdownload(versionname): esp() except Exception: def erragain(): - limpiar_consola() + cls() yup = colored("Sí","green") nop = colored("No","red") errtry = input(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nHa ocurrido un error mientras se descargaba tu Nuevo Server.\nReintentar?\n\n(1) {yup}\n(2) {nop}\n\nElige una de las opciones= ") @@ -1605,7 +2236,7 @@ def erragain(): errtr = errtry errtr = int(errtr) if errtr == 1: - servdownload(version) + servdownload(version,type) elif errtr == 2: esp() else: @@ -1618,10 +2249,15 @@ def erragain(): elif verss.lower() == "r": reselect() elif verss.lower() == "l": - def versionl(): - limpiar_consola() - print("Lanzador de Servidores para Minecraft\n-------------------------------------\n\nVersiones disponibles:\n") - for i, version in enumerate(MCVERSIONS, start=1): + def select_list(): + cls() + print("Lanzador de Servidores para Minecraft\n-------------------------------------\n") + print("VERSIONES ESTABLES:") + for i, version in enumerate(MCSTABLE, start=1): + print(f"(-) {version}") + print('') + print("VERSIONES SNAPSHOT:") + for i, version in enumerate(MCSNAPSHOT, start=1): print(f"(-) {version}") listselection = input("\n(B) Atrás\n(R) Volver al menú principal\n\nEscribe una versión o elige una de las opciones=") try: @@ -1629,15 +2265,19 @@ def versionl(): vers_select() elif listselection.lower() == "r": esp() - elif listselection.lower() in MCVERSIONS.keys(): - servdownload(listselection) + elif listselection.lower() in MCSTABLE.keys(): + servdownload(listselection,"stable") + elif listselection.lower() in MCSNAPSHOT.keys(): + servdownload(listselection,"snapshot") else: - versionl() + select_list() except (ValueError, SyntaxError, IndexError, ZeroDivisionError): - versionl() - versionl() - elif verss.lower() in MCVERSIONS.keys(): - servdownload(verss) + select_list() + select_list() + elif verss.lower() in MCSTABLE.keys(): + servdownload(verss,"stable") + elif verss.lower() in MCSNAPSHOT.keys(): + servdownload(verss,"snapshot") else: vers_select() except (ValueError, SyntaxError, IndexError, ZeroDivisionError): @@ -1655,8 +2295,8 @@ def versionl(): # LICENSE AND EXTRAS def about(): - limpiar_consola() - copyr = input("Lanzador de Servidores para Minecraft\n-------------------------------------\n\nMIT License - Copyright (c) 2024 NGDPL Nk\n\nSSTools4MC v24.06.27 - SE AÑADE SOPRTE PARA LA 1.21\n\nHelpers:\n@naicoooossj\n@LegalizeNuclearBombs\n\n-------------------------------------\n\n(1) Ver repositorio en el navegador\n(2) Ver licencia en el navegador\n(3) Volver al menú principal\n\nElige una de las opciones= ") + cls() + copyr = input("Lanzador de Servidores para Minecraft\n-------------------------------------\n\nMIT License - Copyright (c) 2024 ngdplnk\n\nSSTools4MC v24.07.29 - SE AÑADE SOPRTE PARA VERSIONES SNAPSHOT\n\nHelpers:\n@naicoooossj\n@LegalizeNuclearBombs\n\n-------------------------------------\n\n(1) Ver repositorio en el navegador\n(2) Ver licencia en el navegador\n(3) Volver al menú principal\n\nElige una de las opciones= ") try: if any(char in "0123456789+-*/" for char in copyr): if not copyr[0].isalpha(): @@ -1668,14 +2308,14 @@ def about(): selec = int(selec) if selec == 1: url = colored("https://github.com/ngdplnk/SSTools4MC","cyan") - limpiar_consola() + cls() input(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nEl repositorio se abrirá en tu navegador.\n\n{url}\n\nPresiona ENTER para continuar.") url = "https://github.com/ngdplnk/SSTools4MC" webbrowser.open(url) about() elif selec == 2: url = colored("https://github.com/ngdplnk/SSTools4MC/blob/main/LICENSE","cyan") - limpiar_consola() + cls() input(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nLa licencia se abrirá en tu navegador.\n\n{url}\n\nPresiona ENTER para continuar.") url = "https://github.com/ngdplnk/SSTools4MC/blob/main/LICENSE" webbrowser.open(url) @@ -1689,8 +2329,8 @@ def about(): # EXIT def exiit(): - limpiar_consola() - print("--------------------------------------------\nMuchas gracias por usar esta herramienta\nMIT License - Copyright (c) 2024 NGDPL Nk\n--------------------------------------------\n") + cls() + print("--------------------------------------------\nNos vemos pronto!\nMIT License - Copyright (c) 2024 ngdplnk\n--------------------------------------------\n") time.sleep(1.2) sys.exit() @@ -1698,7 +2338,7 @@ def exiit(): def menu(): os.makedirs(SSTOOLS_FOLDER, exist_ok=True) os.chdir(SSTOOLS_FOLDER) - limpiar_consola() + cls() seleccion = input("Lanzador de Servidores para Minecraft\n-------------------------------------\n\nHola! Estás en el menú principal.\n\n(1) Inciar un Server\n(2) Instalar un Nuevo Server\n(3) Extras\n(4) Cambiar Lenguaje\n(5) Salir\n\nElige una de las opciones= ") try: if any(char in "0123456789+-*/" for char in seleccion): @@ -1725,8 +2365,8 @@ def menu(): menu() -# SELECCIÓN DE IDIOMA - LANGUAGE SELECTION -def lang(): +# STARTUP +def startup(): system_lang = locale.getlocale()[0] system_lang = str(system_lang) if system_lang.startswith("es") or system_lang.startswith("Spanish"): @@ -1734,5 +2374,5 @@ def lang(): else: eng() -# INICIAR HERRAMIENTA - RUN TOOL -lang() +# RUN TOOL +startup() diff --git a/2-development/dev.py b/2-development/dev.py index 26b6d84..7c58849 100644 --- a/2-development/dev.py +++ b/2-development/dev.py @@ -1,12 +1,13 @@ -#!/usr/bin/env python3 +#### SSTOOLS4MC MAIN PROGRAM #### +#### DEVELOPED BY: NGDPLNK #### -##################### -### THINGS TO FIX ### +### THINGS TO FIX # - Download progressbar has a bug that when the console is untabbed, freezes and corrupts the file. # - In specific conditions, the server startup cancelling with CTRL+C shows an unexpected screen from other function. + ##################### -# MÓDULOS IMPORTADOS - IMPORTED MODULES +# MODULES import os import time import sys @@ -25,16 +26,14 @@ # PATHS APPDATA = os.getenv('APPDATA') -SSTOOLS_FOLDER = os.path.join(APPDATA, "TLSoftware", "SSTools4MC") # type: ignore +SSTOOLS_FOLDER = os.path.join(APPDATA, "SSTools4MC") # type: ignore CONFIG_PATH = os.path.join(SSTOOLS_FOLDER, "config") # type: ignore SAVED_SERVERS = os.path.join(CONFIG_PATH, "saved-servers.cfg") # type: ignore ### MINECRAFT VERSIONS -## 83 STABLE VERSIONS ADDED (1.2.1 - 1.20.6) -## 613 SNAPSHOT VERSIONS ADDED (1.3 - 1.21-rc1) +## 84 STABLE VERSIONS ADDED (1.2.1 - 1.21) # LAST UPDATE: 29-07-2024 -MCVERSIONS = { - # Stable +MCSTABLE = { "1.2.1": "https://assets.minecraft.net/1_2/minecraft_server.jar", "1.2.2": "https://assets.minecraft.net/1_2/minecraft_server.jar", "1.2.3": "https://assets.minecraft.net/1_2/minecraft_server.jar", @@ -119,8 +118,11 @@ "1.20.4": "https://piston-data.mojang.com/v1/objects/8dd1a28015f51b1803213892b50b7b4fc76e594d/server.jar", "1.20.5": "https://piston-data.mojang.com/v1/objects/79493072f65e17243fd36a699c9a96b4381feb91/server.jar", "1.20.6": "https://piston-data.mojang.com/v1/objects/145ff0858209bcfc164859ba735d4199aafa1eea/server.jar", - "1.21": "https://piston-data.mojang.com/v1/objects/450698d1863ab5180c25d7c804ef0fe6369dd1ba/server.jar", - # Snapshot + "1.21": "https://piston-data.mojang.com/v1/objects/450698d1863ab5180c25d7c804ef0fe6369dd1ba/server.jar" +} +## 613 SNAPSHOT VERSIONS ADDED (1.3 - 1.21-rc1) +# LAST UPDATE: 29-07-2024 +MCSNAPSHOT = { "1.3": "https://launcher.mojang.com/v1/objects/cb21a9aaaf599c94dd7fa1b777b2f0cc37a776c7/server.jar", "1.4": "https://launcher.mojang.com/v1/objects/9470a2bb0fcb8a426328441a01dba164fbbe52c9/server.jar", "1.4.1": "https://launcher.mojang.com/v1/objects/baa4e4a7adc3dc9fbfc5ea36f0777b68c9eb7f4a/server.jar", @@ -738,25 +740,16 @@ } # CLS -def limpiar_consola(): - if os.name == 'nt': # En Windows - On Windows - os.system('cls') - else: # For Linux - os.system('clear') +def cls(): + os.system('cls') -# WINDOW TITLE +# CHANGE WINDOW TITLE def window_title(title): - if sys.platform.startswith('win32'): # En Windows - On Windows - ctypes.windll.kernel32.SetConsoleTitleW(title) - elif sys.platform.startswith('linux') or sys.platform.startswith('darwin'): # For Linux - sys.stdout.write(f"\x1b]2;{title}\x07") + os.system(f'title {title}') # BRING WINDOW TO FRONT def front(): - if os.name == 'nt': # For Windows - os.system("echo off && echo ShowConsole && echo on") - else: # For Linux - os.system("wmctrl -a 'Terminal'") + os.system('echo ShowConsole') # ENGLISH def eng(): @@ -766,7 +759,7 @@ def eng(): # SERVER STARTUP def ram(): global servername - limpiar_consola() + cls() sservers = {} if os.path.exists(SAVED_SERVERS): with open(SAVED_SERVERS, 'r') as file: @@ -776,7 +769,7 @@ def ram(): key, value = line.split('<[=]>') sservers[key.strip()] = value.strip() if sservers: - limpiar_consola() + cls() print('Server Launcher for Minecraft\n-------------------------------------\n\n"Your Servers" List\n') server_keys = list(sservers.keys()) for i, key in enumerate(server_keys, start=1): @@ -792,7 +785,7 @@ def ram(): front() servname = os.path.basename(newserv) if newserv == "" or servname == "": - limpiar_consola() + cls() print('Server Launcher for Minecraft\n-------------------------------------\n\nYou must select a folder to save it in "Your Servers" List.') time.sleep(2.5) ram() @@ -804,13 +797,13 @@ def ram(): lines = file.readlines() if servstring not in lines: file.write(servstring) - limpiar_consola() + cls() print(f'Server Launcher for Minecraft\n-------------------------------------\n\nThe server "{servname}" has been saved.') time.sleep(1.5) ram() elif servsel.lower() == "d": def servdel(): - limpiar_consola() + cls() print("Server Launcher for Minecraft\n-------------------------------------\n\nSelect the server to delete from the list.\n") for i, key in enumerate(server_keys, start=1): print(f"({i}) {key}") @@ -842,7 +835,7 @@ def servdel(): for line in lines: if line != servestring: file.write(line) - limpiar_consola() + cls() print(f'Server Launcher for Minecraft\n-------------------------------------\n\nThe server "{servsel}" has been deleted from the list.') time.sleep(1.5) ram() @@ -851,7 +844,7 @@ def servdel(): servdel() elif servsel.lower() == "c": def lisclear(): - limpiar_consola() + cls() yess = colored("Yes","green") noo = colored("No","red") clearconfirm = input(f'Server Launcher for Minecraft\n-------------------------------------\n\nAre you sure you want to clear the "Your Servers" List?\n\n(1) {yess}\n(2) {noo}\n\nSelect one of the options= ') @@ -868,7 +861,7 @@ def lisclear(): os.makedirs(CONFIG_PATH, exist_ok=True) with open(SAVED_SERVERS, 'w') as file: file.write("# Server Launcher for Minecraft\n# Saved servers\n") - limpiar_consola() + cls() print('Server Launcher for Minecraft\n-------------------------------------\n\nThe "Your Servers" List has been cleared.') time.sleep(1.5) ram() @@ -900,7 +893,7 @@ def lisclear(): os.makedirs(CONFIG_PATH, exist_ok=True) with open(SAVED_SERVERS, 'w') as file: file.write("# Server Launcher for Minecraft\n# Saved servers\n") - limpiar_consola() + cls() adds = colored("Add a Server","cyan") saveconfirm = input(f"Server Launcher for Minecraft\n-------------------------------------\n\nThere are no saved servers.\n\n(1) {adds}\n(2) Return to main menu\n\nSelect one of the options= ") try: @@ -917,7 +910,7 @@ def lisclear(): front() servname = os.path.basename(newserv) if newserv == "" or servname == "": - limpiar_consola() + cls() print('Server Launcher for Minecraft\n-------------------------------------\n\nYou must select a folder to save it in "Your Servers" List.') time.sleep(2.5) ram() @@ -929,7 +922,7 @@ def lisclear(): lines = file.readlines() if servstring not in lines: file.write(servstring) - limpiar_consola() + cls() print(f'Server Launcher for Minecraft\n-------------------------------------\n\nThe server "{servname}" has been saved.') time.sleep(1.5) ram() @@ -943,13 +936,13 @@ def lisclear(): os.makedirs(CONFIG_PATH, exist_ok=True) with open(SAVED_SERVERS, 'w') as file: file.write("# Server Launcher for Minecraft\n# Saved servers\n") - limpiar_consola() + cls() input('Server Launcher for Minecraft\n-------------------------------------\n\nThere are no saved servers.\n\nPress ENTER to select a folder with a Server and add it to "Your Servers" list.') newserv = filedialog.askdirectory() front() servname = os.path.basename(newserv) if newserv == "" or servname == "": - limpiar_consola() + cls() print('Server Launcher for Minecraft\n-------------------------------------\n\nYou must select a folder to save it in "Your Servers" List.') time.sleep(2.5) ram() @@ -960,7 +953,7 @@ def lisclear(): lines = file.readlines() if servstring not in lines: file.write(servstring) - limpiar_consola() + cls() print(f'Server Launcher for Minecraft\n-------------------------------------\n\nThe server "{servname}" has been saved.') time.sleep(1.5) ram() @@ -968,7 +961,7 @@ def lisclear(): # CONFIG def config(): global nameserver - limpiar_consola() + cls() props = "server.properties" if os.path.exists(props): global properties @@ -994,7 +987,7 @@ def config(): pvp = colored("ENABLE","green") elif properties["pvp"] == "true": pvp = colored("DISABLE","red") - limpiar_consola() + cls() confsel = input(f'Server Launcher for Minecraft\n-------------------------------------\n\nLets manage "{nameserver}"!\n\n(1) {online} online mode\n(2) {hard} hardcore mode\n(3) {pvp} PvP\n(4) Change gamemode\n(5) Change difficulty\n(6) Change max players limit\n(7) Back\n(8) Return to main menu\n\nSelect one of the options= ') if properties["online-mode"] == "false": online = "ENABLE" @@ -1030,7 +1023,7 @@ def config(): for key, value in properties.items(): file.write(f'{key}={value}\n') online = colored("DISABLED","red") - limpiar_consola() + cls() print(f"Server Launcher for Minecraft\n-------------------------------------\n\nOnline mode has been {online}.") time.sleep(1.5) config() @@ -1047,7 +1040,7 @@ def config(): for key, value in properties.items(): file.write(f'{key}={value}\n') hard = colored("DISABLED","red") - limpiar_consola() + cls() print(f"Server Launcher for Minecraft\n-------------------------------------\n\nHardcore mode has been {hard}.") time.sleep(1.5) config() @@ -1064,7 +1057,7 @@ def config(): for key, value in properties.items(): file.write(f'{key}={value}\n') pvp = colored("DISABLED","red") - limpiar_consola() + cls() print(f"Server Launcher for Minecraft\n-------------------------------------\n\nPvP has been {pvp}.") time.sleep(1.5) config() @@ -1084,7 +1077,7 @@ def juego(): creat = colored("CREATIVE","yellow") avent = colored("ADVENTURE","yellow") espect = colored("SPECTATOR","yellow") - limpiar_consola() + cls() modosel = input(f"Server Launcher for Minecraft\n-------------------------------------\n\nThe current game mode is {modo}.\n\n(1) Change to {superv} gamemode\n(2) Change to {creat} gamemode\n(3) Change to {avent} gamemode\n(4) Change to {espect} gamemode\n(5) Go back\n(6) Return to main menu\n\nSelect one of the options= ") try: if any(char in "0123456789+-*/" for char in modosel): @@ -1100,7 +1093,7 @@ def juego(): with open('server.properties', 'w') as file: for key, value in properties.items(): file.write(f'{key}={value}\n') - limpiar_consola() + cls() print(f"Server Launcher for Minecraft\n-------------------------------------\n\nGamemode has been set to {superv}.") time.sleep(1.5) juego() @@ -1109,7 +1102,7 @@ def juego(): with open('server.properties', 'w') as file: for key, value in properties.items(): file.write(f'{key}={value}\n') - limpiar_consola() + cls() print(f"Server Launcher for Minecraft\n-------------------------------------\n\nGamemode has been set to {creat}.") time.sleep(1.5) juego() @@ -1118,7 +1111,7 @@ def juego(): with open('server.properties', 'w') as file: for key, value in properties.items(): file.write(f'{key}={value}\n') - limpiar_consola() + cls() print(f"Server Launcher for Minecraft\n-------------------------------------\n\nGamemode has been set to {avent}.") time.sleep(1.5) juego() @@ -1127,7 +1120,7 @@ def juego(): with open('server.properties', 'w') as file: for key, value in properties.items(): file.write(f'{key}={value}\n') - limpiar_consola() + cls() print(f"Server Launcher for Minecraft\n-------------------------------------\n\nGamemode has been set to {espect}.") time.sleep(1.5) juego() @@ -1156,7 +1149,7 @@ def difconf(): facil = colored("EASY","yellow") normal = colored("NORMAL","yellow") dificil = colored("HARD","yellow") - limpiar_consola() + cls() difsel = input(f"Server Launcher for Minecraft\n-------------------------------------\n\nThe current difficulty is {dificultad}.\n\n(1) Change difficulty to {pacif}\n(2) Change difficulty to {facil}\n(3) Change difficulty to {normal}\n(4) Change difficulty to {dificil}\n(5) Go back\n(6) Return to main menu\n\nSelect one of the options= ") try: if any(char in "0123456789+-*/" for char in difsel): @@ -1172,7 +1165,7 @@ def difconf(): with open('server.properties', 'w') as file: for key, value in properties.items(): file.write(f'{key}={value}\n') - limpiar_consola() + cls() print(f"Server Launcher for Minecraft\n-------------------------------------\n\nDifficulty has been set to {pacif}.") time.sleep(1.5) difconf() @@ -1181,7 +1174,7 @@ def difconf(): with open('server.properties', 'w') as file: for key, value in properties.items(): file.write(f'{key}={value}\n') - limpiar_consola() + cls() print(f"Server Launcher for Minecraft\n-------------------------------------\n\nDifficulty has been set to {facil}.") time.sleep(1.5) difconf() @@ -1190,7 +1183,7 @@ def difconf(): with open('server.properties', 'w') as file: for key, value in properties.items(): file.write(f'{key}={value}\n') - limpiar_consola() + cls() print(f"Server Launcher for Minecraft\n-------------------------------------\n\nDifficulty has been set to {normal}.") time.sleep(1.5) difconf() @@ -1199,7 +1192,7 @@ def difconf(): with open('server.properties', 'w') as file: for key, value in properties.items(): file.write(f'{key}={value}\n') - limpiar_consola() + cls() print(f"Server Launcher for Minecraft\n-------------------------------------\n\nDifficulty has been set to {dificil}.") time.sleep(1.5) difconf() @@ -1216,7 +1209,7 @@ def difconf(): def playct(): global properties players = colored(properties["max-players"],"cyan") - limpiar_consola() + cls() newpl = input(f"Server Launcher for Minecraft\n-------------------------------------\n\nThe current player limit is a maximum of {players}.\n\n(N) Go back\n(M) Return to main menu\n\nSelect one of the options or enter the new player limit= ").replace(" ", "") try: if newpl.lower() == "n": @@ -1233,7 +1226,7 @@ def playct(): entero = newpl entero = int(entero) if entero <= 0 or entero > 100000: - limpiar_consola() + cls() print(f"Server Launcher for Minecraft\n-------------------------------------\n\nEnter a valid number between 1 and 100,000.") time.sleep(1.5) playct() @@ -1243,7 +1236,7 @@ def playct(): for key, value in properties.items(): file.write(f'{key}={value}\n') entero = colored(str(entero),"yellow") - limpiar_consola() + cls() print(f"Server Launcher for Minecraft\n-------------------------------------\n\nThe maximum player limit is now {entero}.") time.sleep(1.5) playct() @@ -1259,7 +1252,7 @@ def playct(): except (ValueError, SyntaxError, IndexError, ZeroDivisionError): config() else: - limpiar_consola() + cls() input("Server Launcher for Minecraft\n-------------------------------------\n\nThe server configuration files do not exist yet or are not available.\nYou must start the server properly at least once before you can configure it.\n\nPress ENTER to continue.") run_server() def run_server(): @@ -1283,7 +1276,7 @@ def run_server(): vjava = "M" gbormb = colored("GIGABYTES","yellow") nameserver = servername - limpiar_consola() + cls() gbs = 0 rammount = input(f'Server Launcher for Minecraft\n-------------------------------------\n\nYou are about to start the Server "{nameserver}"\n\n(M) Manage Server\n(C) Use RAM in {gbormb}\n(B) Back\n(N) Return to main menu\n\nSelect one of the options or enter the {valor1} of RAM to assing to the server= ').replace(" ", "") try: @@ -1291,13 +1284,13 @@ def run_server(): config() if rammount.lower() == "c": if valor == "GB": - limpiar_consola() + cls() print(f"Server Launcher for Minecraft\n-------------------------------------\n\nNow the RAM is on {gbormb}.") time.sleep(1.5) valor = "MB" run_server() elif valor == "MB": - limpiar_consola() + cls() print(f"Server Launcher for Minecraft\n-------------------------------------\n\nNow the RAM is on {gbormb}.") time.sleep(1.5) valor = "GB" @@ -1316,12 +1309,12 @@ def run_server(): gbs = rammount gbs = int(gbs) if valor == "GB" and (gbs <= 0 or gbs > 75): - limpiar_consola() + cls() print(f"Server Launcher for Minecraft\n-------------------------------------\n\nEnter a valid amount between 1 and 75 Gigabytes.") time.sleep(1.5) run_server() elif valor == "MB" and (gbs <= 511 or gbs > 76800): - limpiar_consola() + cls() print(f"Server Launcher for Minecraft\n-------------------------------------\n\nEnter a valid amount between 512 and 76,800 Megabytes.") time.sleep(1.5) run_server() @@ -1329,7 +1322,7 @@ def run_server(): eula = "eula.txt" with open(eula, "w") as reemplazo: reemplazo.write("eula=true") - limpiar_consola() + cls() print(f"Server Launcher for Minecraft\n-------------------------------------\n\nStarting the server with {gbs}{valor} of RAM.\n") comando_java = f"java -Xmx{gbs}{vjava} -Xms{gbs}{vjava} -jar server.jar nogui" subprocess.run(comando_java, shell=True) @@ -1337,14 +1330,14 @@ def run_server(): fecha_cerrado = str(fyh_sistema.strftime("%d/%m/%Y")) hora_cerrado = str(fyh_sistema.strftime("%H:%M:%S")) input("\nPress ENTER to continue.") - limpiar_consola() + cls() input(f"Server Launcher for Minecraft\n-------------------------------------\n\nThe server has closed on {fecha_cerrado} at {hora_cerrado}.\n\nYou can check the console log in the 'logs' folder inside your Server's main folder.\n\nPress ENTER to continue.") ram() except (ValueError, SyntaxError, IndexError, ZeroDivisionError): run_server() run_server() else: - limpiar_consola() + cls() print('Server Launcher for Minecraft\n-------------------------------------\n\n"server.jar" not found in this folder.\n\nAre you sure this is a Server?') time.sleep(2.5) ram() @@ -1353,7 +1346,7 @@ def run_server(): def installmenu(): global newserver global foldname - limpiar_consola() + cls() inconfirm = input("Server Launcher for Minecraft\n-------------------------------------\n\nFirst, lets select a folder to save your New Server's files.\n\n(1) Select folder for the new Server\n(2) Cancel\n\nSelect one of the options= ").replace(" ", "") try: if any(char in "0123456789+-*/" for char in inconfirm): @@ -1372,7 +1365,7 @@ def reselect(): front() foldname = colored(os.path.basename(newserver), "green") if newserver == "" or foldname == "": - limpiar_consola() + cls() print('Server Launcher for Minecraft\n-------------------------------------\n\nYou must select a folder to save the New Server.') time.sleep(2.5) installmenu() @@ -1382,15 +1375,18 @@ def reselect(): def vers_select(): global newserver global foldname - limpiar_consola() - verss = input(f'Server Launcher for Minecraft\n-------------------------------------\n\nYour New Server will be saved in "{foldname}".\n\n(L) List of available versions\n(R) Re-select a folder for the New server\n(N) Return to main menu\n\nSelect one of the options or type the New Server version to install= ').replace(" ", "") + cls() + verss = input(f'Server Launcher for Minecraft\n-------------------------------------\n\nYour New Server will be saved in "{foldname}".\n\n(L) See available versions\n(R) Re-select a folder for the New server\n(N) Return to main menu\n\nSelect one of the options or type the New Server version to install= ').replace(" ", "") try: - def servdownload(versionname): + def servdownload(versionname,type): global newserver global foldname version = versionname.lower() - url = MCVERSIONS[version] - limpiar_consola() + if type == "stable": + url = MCSTABLE[version] + else: + url = MCSNAPSHOT[version] + cls() print(f'Server Launcher for Minecraft\n-------------------------------------\n\nYour New Server is being downloaded.\n\nVersion: {version}\nTarget Folder: "{foldname}"\n\nPlease wait...\n') time.sleep(0.5) os.makedirs(newserver, exist_ok=True) @@ -1407,7 +1403,7 @@ def servdownload(versionname): completed = int(50 * total_data / total_size_in_bytes) print("\r[%s%s]" % ('#' * completed, '.' * (50 - completed)), end='') print() - limpiar_consola() + cls() input('Server Launcher for Minecraft\n-------------------------------------\n\nThe server has been installed successfully and added to "Your Servers" list.\n\nPress ENTER to continue.') servname = os.path.basename(newserver) servstring = f"{servname}<[=]>{newserver}\n" @@ -1419,7 +1415,7 @@ def servdownload(versionname): eng() except Exception: def erragain(): - limpiar_consola() + cls() yup = colored("Yes","green") nop = colored("No","red") errtry = input(f"Server Launcher for Minecraft\n-------------------------------------\n\nAn error occurred while downloading the server.\nTry again?\n\n(1) {yup}\n(2) {nop}\n\nSelect one of the options= ") @@ -1433,7 +1429,7 @@ def erragain(): errtr = errtry errtr = int(errtr) if errtr == 1: - servdownload(version) + servdownload(version,type) elif errtr == 2: eng() else: @@ -1446,10 +1442,15 @@ def erragain(): elif verss.lower() == "r": reselect() elif verss.lower() == "l": - def versionl(): - limpiar_consola() - print("Server Launcher for Minecraft\n-------------------------------------\n\nAvailable versions:\n") - for i, version in enumerate(MCVERSIONS, start=1): + def select_list(): + cls() + print("Server Launcher for Minecraft\n-------------------------------------\n") + print("STABLE VERSIONS:") + for i, version in enumerate(MCSTABLE, start=1): + print(f"(-) {version}") + print('') + print("SNAPSHOT VERSIONS:") + for i, version in enumerate(MCSNAPSHOT, start=1): print(f"(-) {version}") listselection = input("\n(B) Back\n(R) Return to main menu\n\nType a version or select one of the options=") try: @@ -1457,15 +1458,19 @@ def versionl(): vers_select() elif listselection.lower() == "r": eng() - elif listselection.lower() in MCVERSIONS.keys(): - servdownload(listselection) + elif listselection.lower() in MCSTABLE.keys(): + servdownload(listselection,"stable") + elif listselection.lower() in MCSNAPSHOT.keys(): + servdownload(listselection,"snapshot") else: - versionl() + select_list() except (ValueError, SyntaxError, IndexError, ZeroDivisionError): - versionl() - versionl() - elif verss.lower() in MCVERSIONS.keys(): - servdownload(verss) + select_list() + select_list() + elif verss.lower() in MCSTABLE.keys(): + servdownload(verss,"stable") + elif verss.lower() in MCSNAPSHOT.keys(): + servdownload(verss,"snapshot") else: vers_select() except (ValueError, SyntaxError, IndexError, ZeroDivisionError): @@ -1483,8 +1488,8 @@ def versionl(): # LICENSE AND EXTRAS def about(): - limpiar_consola() - copyr = input("Server Launcher for Minecraft\n-------------------------------------\n\nMIT License - Copyright (c) 2024 NGDPL Nk\n\nSSTools4MC v24.06.27 - ADDED SUPPORT FOR 1.21\n\nHelpers:\n@naicoooossj\n@LegalizeNuclearBombs\n\n-------------------------------------\n\n(1) View repository in the browser\n(2) View license in the browser\n(3) Return to main menu\n\nSelect one of the options= ") + cls() + copyr = input("Server Launcher for Minecraft\n-------------------------------------\n\nMIT License - Copyright (c) 2024 ngdplnk\n\nSSTools4MC v24.07.29 - ADDED SUPPORT FOR SNAPSHOT VERSIONS\n\nHelpers:\n@naicoooossj\n@LegalizeNuclearBombs\n\n-------------------------------------\n\n(1) View repository in the browser\n(2) View license in the browser\n(3) Return to main menu\n\nSelect one of the options= ") try: if any(char in "0123456789+-*/" for char in copyr): if not copyr[0].isalpha(): @@ -1495,17 +1500,17 @@ def about(): selec = copyr selec = int(selec) if selec == 1: - url = colored("https://github.com/NGDPLNk/SSTools4MC","cyan") - limpiar_consola() + url = colored("https://github.com/ngdplnk/SSTools4MC","cyan") + cls() input(f"Server Launcher for Minecraft\n-------------------------------------\n\nThe repository will open in your browser.\n\n{url}\n\nPress ENTER to continue.") - url = "https://github.com/NGDPLNk/SSTools4MC" + url = "https://github.com/ngdplnk/SSTools4MC" webbrowser.open(url) about() elif selec == 2: - url = colored("https://github.com/NGDPLNk/SSTools4MC/blob/main/LICENSE","cyan") - limpiar_consola() + url = colored("https://github.com/ngdplnk/SSTools4MC/blob/main/LICENSE","cyan") + cls() input(f"Server Launcher for Minecraft\n-------------------------------------\n\nThe license will open in your browser.\n\n{url}\n\nPress ENTER to continue.") - url = "https://github.com/NGDPLNk/SSTools4MC/blob/main/LICENSE" + url = "https://github.com/ngdplnk/SSTools4MC/blob/main/LICENSE" webbrowser.open(url) about() elif selec == 3: @@ -1517,8 +1522,8 @@ def about(): # EXIT def exiit(): - limpiar_consola() - print("--------------------------------------------\nThank you for using this tool\nMIT License - Copyright (c) 2024 NGDPL Nk\n--------------------------------------------\n") + cls() + print("--------------------------------------------\nSee ya later!\nMIT License - Copyright (c) 2024 ngdplnk\n--------------------------------------------\n") time.sleep(1.2) sys.exit() @@ -1526,7 +1531,7 @@ def exiit(): def menu(): os.makedirs(SSTOOLS_FOLDER, exist_ok=True) os.chdir(SSTOOLS_FOLDER) - limpiar_consola() + cls() seleccion = input("Server Launcher for Minecraft\n-------------------------------------\n\nHi! You are in the main menu.\n\n(1) Start a Server\n(2) Install a New Server\n(3) Extras\n(4) Change Language\n(5) Exit\n\nSelect one of the options= ") try: if any(char in "0123456789+-*/" for char in seleccion): @@ -1553,7 +1558,7 @@ def menu(): menu() -# ESPAÑOL +# SPANISH def esp(): # CHANGE WINDOW TITLE window_title("Lanzador de Servidores para Minecraft") @@ -1561,7 +1566,7 @@ def esp(): # SERVER STARTUP def ram(): global servername - limpiar_consola() + cls() sservers = {} if os.path.exists(SAVED_SERVERS): with open(SAVED_SERVERS, 'r') as file: @@ -1571,7 +1576,7 @@ def ram(): key, value = line.split('<[=]>') sservers[key.strip()] = value.strip() if sservers: - limpiar_consola() + cls() print('Lanzador de Servidores para Minecraft\n-------------------------------------\n\nLista "Tus Servidores"\n') server_keys = list(sservers.keys()) for i, key in enumerate(server_keys, start=1): @@ -1587,7 +1592,7 @@ def ram(): front() servname = os.path.basename(newserv) if newserv == "" or servname == "": - limpiar_consola() + cls() print('Lanzador de Servidores para Minecraft\n-------------------------------------\n\nDebes elegir una carpeta para guardarla en la Lista "Tus Servidores".') time.sleep(2.5) ram() @@ -1599,13 +1604,13 @@ def ram(): lines = file.readlines() if servstring not in lines: file.write(servstring) - limpiar_consola() + cls() print(f'Lanzador de Servidores para Minecraft\n-------------------------------------\n\nEl Server "{servname}" ha sido guardado.') time.sleep(1.5) ram() elif servsel.lower() == "d": def servdel(): - limpiar_consola() + cls() print("Lanzador de Servidores para Minecraft\n-------------------------------------\n\nSelecciona el Server que eliminarás de la lista.\n") for i, key in enumerate(server_keys, start=1): print(f"({i}) {key}") @@ -1637,7 +1642,7 @@ def servdel(): for line in lines: if line != servestring: file.write(line) - limpiar_consola() + cls() print(f'Lanzador de Servidores para Minecraft\n-------------------------------------\n\nEl Server "{servsel}" ha sido eliminado de la lista.') time.sleep(1.5) ram() @@ -1646,7 +1651,7 @@ def servdel(): servdel() elif servsel.lower() == "c": def lisclear(): - limpiar_consola() + cls() yess = colored("Sí","green") noo = colored("No","red") clearconfirm = input(f'Lanzador de Servidores para Minecraft\n-------------------------------------\n\nEstás seguro de que quieres limpiar la Lista "Tus Servidores"?\n\n(1) {yess}\n(2) {noo}\n\nElige una de las opciones= ') @@ -1663,7 +1668,7 @@ def lisclear(): os.makedirs(CONFIG_PATH, exist_ok=True) with open(SAVED_SERVERS, 'w') as file: file.write("# Lanzador de Servidores para Minecraft\n# Servers guardados\n") - limpiar_consola() + cls() print('Lanzador de Servidores para Minecraft\n-------------------------------------\n\nLa Lista "Tus Servidores" ha sido limpiada.') time.sleep(1.5) ram() @@ -1695,7 +1700,7 @@ def lisclear(): os.makedirs(CONFIG_PATH, exist_ok=True) with open(SAVED_SERVERS, 'w') as file: file.write("# Lanzador de Servidores para Minecraft\n# Servidores Guardados\n") - limpiar_consola() + cls() adds = colored("Añadir un Server","cyan") saveconfirm = input(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nNo tienes ningún Server guardado.\n\n(1) {adds}\n(2) Volver al menú principal\n\nElige una de las opciones= ") try: @@ -1712,7 +1717,7 @@ def lisclear(): front() servname = os.path.basename(newserv) if newserv == "" or servname == "": - limpiar_consola() + cls() print('Lanzador de Servidores para Minecraft\n-------------------------------------\n\nDebes elegir una carpeta para guardarla en la Lista "Tus Servidores".') time.sleep(2.5) ram() @@ -1724,7 +1729,7 @@ def lisclear(): lines = file.readlines() if servstring not in lines: file.write(servstring) - limpiar_consola() + cls() print(f'Lanzador de Servidores para Minecraft\n-------------------------------------\n\nEl Server "{servname}" ha sido guardado.') time.sleep(1.5) ram() @@ -1738,13 +1743,13 @@ def lisclear(): os.makedirs(CONFIG_PATH, exist_ok=True) with open(SAVED_SERVERS, 'w') as file: file.write("# Lanzador de Servidores para Minecraft\n# Servers Guardados\n") - limpiar_consola() + cls() input('Lanzador de Servidores para Minecraft\n-------------------------------------\n\nNo tienes ningún Server guardado.\n\nPresiona ENTER para seleccionar una carpeta con tu Server y guardarlo en la Lista "Tus Servidores".') newserv = filedialog.askdirectory() front() servname = os.path.basename(newserv) if newserv == "" or servname == "": - limpiar_consola() + cls() print('Lanzador de Servidores para Minecraft\n-------------------------------------\n\nDebes elegir una carpeta para guardarla en la Lista "Tus Servidores".') time.sleep(2.5) ram() @@ -1755,7 +1760,7 @@ def lisclear(): lines = file.readlines() if servstring not in lines: file.write(servstring) - limpiar_consola() + cls() print(f'Lanzador de Servidores para Minecraft\n-------------------------------------\n\nEl Server "{servname}" ha sido guardado.') time.sleep(1.5) ram() @@ -1763,7 +1768,7 @@ def lisclear(): # CONFIG def config(): global nameserver - limpiar_consola() + cls() props = "server.properties" if os.path.exists(props): global properties @@ -1789,7 +1794,7 @@ def config(): pvp = colored("ACTIVAR","green") elif properties["pvp"] == "true": pvp = colored("DESACTIVAR","red") - limpiar_consola() + cls() confsel = input(f'Lanzador de Servidores para Minecraft\n-------------------------------------\n\nConfiguremos "{nameserver}"!\n\n(1) {online} modo online\n(2) {hard} modo extremo\n(3) {pvp} PvP\n(4) Cambiar modo de juego\n(5) Cambiar dificultad\n(6) Cambiar el límite de jugadores\n(7) Atrás\n(8) Volver al menú principal\n\nElige una de las opciones= ') if properties["online-mode"] == "false": online = "ENABLE" @@ -1825,7 +1830,7 @@ def config(): for key, value in properties.items(): file.write(f'{key}={value}\n') online = colored("DESACTIVADO","red") - limpiar_consola() + cls() print(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nEl modo online se ha {online}.") time.sleep(1.5) config() @@ -1842,7 +1847,7 @@ def config(): for key, value in properties.items(): file.write(f'{key}={value}\n') hard = colored("DESACTIVADO","red") - limpiar_consola() + cls() print(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nEl modo extremo se ha {hard}.") time.sleep(1.5) config() @@ -1859,7 +1864,7 @@ def config(): for key, value in properties.items(): file.write(f'{key}={value}\n') pvp = colored("DESACTIVADO","red") - limpiar_consola() + cls() print(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nEl PvP se ha {pvp}.") time.sleep(1.5) config() @@ -1879,7 +1884,7 @@ def juego(): creat = colored("CREATIVO","yellow") avent = colored("AVENTURA","yellow") espect = colored("ESPECTADOR","yellow") - limpiar_consola() + cls() modosel = input(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nEl modo de juego actual es {modo}.\n\n(1) Cambiar a modo {superv}\n(2) Cambiar a modo {creat}\n(3) Cambiar a modo {avent}\n(4) Cambiar a modo {espect}\n(5) Atrás\n(6) Volver al menú principal\n\nElige una de las opciones= ") try: if any(char in "0123456789+-*/" for char in modosel): @@ -1895,7 +1900,7 @@ def juego(): with open('server.properties', 'w') as file: for key, value in properties.items(): file.write(f'{key}={value}\n') - limpiar_consola() + cls() print(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nEl modo de juego se ha cambiado a {superv}.") time.sleep(1.5) juego() @@ -1904,7 +1909,7 @@ def juego(): with open('server.properties', 'w') as file: for key, value in properties.items(): file.write(f'{key}={value}\n') - limpiar_consola() + cls() print(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nEl modo de juego se ha cambiado a {creat}.") time.sleep(1.5) juego() @@ -1913,7 +1918,7 @@ def juego(): with open('server.properties', 'w') as file: for key, value in properties.items(): file.write(f'{key}={value}\n') - limpiar_consola() + cls() print(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nEl modo de juego se ha cambiado a {avent}.") time.sleep(1.5) juego() @@ -1922,7 +1927,7 @@ def juego(): with open('server.properties', 'w') as file: for key, value in properties.items(): file.write(f'{key}={value}\n') - limpiar_consola() + cls() print(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nEl modo de juego se ha cambiado a {espect}.") time.sleep(1.5) juego() @@ -1951,7 +1956,7 @@ def difconf(): facil = colored("FÁCIL","yellow") normal = colored("NORMAL","yellow") dificil = colored("DIFÍCIL","yellow") - limpiar_consola() + cls() difsel = input(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nLa dificultad actual es {dificultad}.\n\n(1) Cambiar a dificultad {pacif}\n(2) Cambiar a dificultad {facil}\n(3) Cambiar a dificultad {normal}\n(4) Cambiar a dificultad {dificil}\n(5) Atrás\n(6) Volver al menú principal\n\nElige una de las opciones= ") try: if any(char in "0123456789+-*/" for char in difsel): @@ -1967,7 +1972,7 @@ def difconf(): with open('server.properties', 'w') as file: for key, value in properties.items(): file.write(f'{key}={value}\n') - limpiar_consola() + cls() print(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nLa dificultad se ha cambiado a {pacif}.") time.sleep(1.5) difconf() @@ -1976,7 +1981,7 @@ def difconf(): with open('server.properties', 'w') as file: for key, value in properties.items(): file.write(f'{key}={value}\n') - limpiar_consola() + cls() print(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nLa dificultad se ha cambiado a {facil}.") time.sleep(1.5) difconf() @@ -1985,7 +1990,7 @@ def difconf(): with open('server.properties', 'w') as file: for key, value in properties.items(): file.write(f'{key}={value}\n') - limpiar_consola() + cls() print(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nLa dificultad se ha cambiado a {normal}.") time.sleep(1.5) difconf() @@ -1994,7 +1999,7 @@ def difconf(): with open('server.properties', 'w') as file: for key, value in properties.items(): file.write(f'{key}={value}\n') - limpiar_consola() + cls() print(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nLa dificultad se ha cambiado a {dificil}.") time.sleep(1.5) difconf() @@ -2011,7 +2016,7 @@ def difconf(): def playct(): global properties players = colored(properties["max-players"],"cyan") - limpiar_consola() + cls() newpl = input(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nEl límite de jugadores actual es de {players} jugadores.\n\n(N) Atrás\n(M) Volver al menú principal\n\nElige una de las opciones o ingresa el nuevo límite de jugadores= ").replace(" ", "") try: if newpl.lower() == "n": @@ -2028,7 +2033,7 @@ def playct(): entero = newpl entero = int(entero) if entero <= 0 or entero > 100000: - limpiar_consola() + cls() print(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nIngresa un número válido entre 1 y 100.000.") time.sleep(1.5) playct() @@ -2038,7 +2043,7 @@ def playct(): for key, value in properties.items(): file.write(f'{key}={value}\n') entero = colored(str(entero),"yellow") - limpiar_consola() + cls() print(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nEl límite de jugadores ahora es {entero}.") time.sleep(1.5) playct() @@ -2054,7 +2059,7 @@ def playct(): except (ValueError, SyntaxError, IndexError, ZeroDivisionError): config() else: - limpiar_consola() + cls() input("Lanzador de Servidores para Minecraft\n-------------------------------------\n\nLos achivos de configuración del Server aún no existen o no están disponibles.\nDebes iniciar el Server correctamente al menos 1 vez antes de poder configurarlo.\n\nPresiona ENTER para continuar.") run_server() def run_server(): @@ -2078,7 +2083,7 @@ def run_server(): vjava = "M" gbormb = colored("GIGABYTES","yellow") nameserver = servername - limpiar_consola() + cls() gbs = 0 rammount = input(f'Lanzador de Servidores para Minecraft\n-------------------------------------\n\nEstás a punto de iniciar el Server "{nameserver}"\n\n(M) Configurar Server\n(C) Usar RAM en {gbormb}\n(B) Atrás\n(N) Volver al menú principal\n\nElige una de las opciones o ingresa los {valor1} de RAM para asignar a tu Server= ').replace(" ", "") try: @@ -2086,13 +2091,13 @@ def run_server(): config() if rammount.lower() == "c": if valor == "GB": - limpiar_consola() + cls() print(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nAhora la RAM está en {gbormb}.") time.sleep(1.5) valor = "MB" run_server() elif valor == "MB": - limpiar_consola() + cls() print(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nAhora la RAM está en {gbormb}.") time.sleep(1.5) valor = "GB" @@ -2111,12 +2116,12 @@ def run_server(): gbs = rammount gbs = int(gbs) if valor == "GB" and (gbs <= 0 or gbs > 75): - limpiar_consola() + cls() print(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nIngresa una cantidad válida entre 1 y 75 Gigabytes.") time.sleep(1.5) run_server() elif valor == "MB" and (gbs <= 511 or gbs > 76800): - limpiar_consola() + cls() print(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nIngresa una cantidad válida entre 512 y 76.800 Megabytes.") time.sleep(1.5) run_server() @@ -2124,7 +2129,7 @@ def run_server(): eula = "eula.txt" with open(eula, "w") as reemplazo: reemplazo.write("eula=true") - limpiar_consola() + cls() print(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nIniciando el Server con {gbs}{valor} de RAM.\n") comando_java = f"java -Xmx{gbs}{vjava} -Xms{gbs}{vjava} -jar server.jar nogui" subprocess.run(comando_java, shell=True) @@ -2132,14 +2137,14 @@ def run_server(): fecha_cerrado = str(fyh_sistema.strftime("%d/%m/%Y")) hora_cerrado = str(fyh_sistema.strftime("%H:%M:%S")) input("\nPresiona ENTER para continuar.") - limpiar_consola() + cls() input(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nEl Server se ha cerrado el {fecha_cerrado} a las {hora_cerrado}.\n\nPuedes ver el registro de la consola en la carpeta 'logs' dentro de la carpeta principal de tu Server.\n\nPresiona ENTER para continuar.") ram() except (ValueError, SyntaxError, IndexError, ZeroDivisionError): run_server() run_server() else: - limpiar_consola() + cls() print('Lanzador de Servidores para Minecraft\n-------------------------------------\n\nNo se encuentra "server.jar" en esta carpeta.\n\nEstás seguro que esto es un Server?') time.sleep(2.5) ram() @@ -2148,7 +2153,7 @@ def run_server(): def installmenu(): global newserver global foldname - limpiar_consola() + cls() inconfirm = input("Lanzador de Servidores para Minecraft\n-------------------------------------\n\nPrimero, seleccionemos una carpeta para guardar los archivos de tu Nuevo Server.\n\n(1) Seleccionar una carpeta para el Nuevo Server\n(2) Cancelar\n\nElige una de las opciones= ").replace(" ", "") try: if any(char in "0123456789+-*/" for char in inconfirm): @@ -2167,7 +2172,7 @@ def reselect(): front() foldname = colored(os.path.basename(newserver), "green") if newserver == "" or foldname == "": - limpiar_consola() + cls() print('Lanzador de Servidores para Minecraft\n-------------------------------------\n\nDebes elegir una carpeta para guardar tu Nuevo Server.') time.sleep(2.5) installmenu() @@ -2177,15 +2182,18 @@ def reselect(): def vers_select(): global newserver global foldname - limpiar_consola() - verss = input(f'Lanzador de Servidores para Minecraft\n-------------------------------------\n\nTu Nuevo Server se guardará en "{foldname}".\n\n(L) Lista de versiones disponibles\n(R) Reelegir una carpeta para el Nuevo Server\n(N) Volver al menú principal\n\nElige una de las opciones o escribe la versión para instalar tu Nuevo Server= ').replace(" ", "") + cls() + verss = input(f'Lanzador de Servidores para Minecraft\n-------------------------------------\n\nTu Nuevo Server se guardará en "{foldname}".\n\n(L) Ver versiones disponibles\n(R) Reelegir una carpeta para el Nuevo Server\n(N) Volver al menú principal\n\nElige una de las opciones o escribe la versión para instalar tu Nuevo Server= ').replace(" ", "") try: - def servdownload(versionname): + def servdownload(versionname,type): global newserver global foldname version = versionname.lower() - url = MCVERSIONS[version] - limpiar_consola() + if type == "stable": + url = MCSTABLE[version] + else: + url = MCSNAPSHOT[version] + cls() print(f'Lanzador de Servidores para Minecraft\n-------------------------------------\n\nTu Nuevo Server está siendo descargado.\n\nVersión: {version}\nCarpeta de destino: "{foldname}"\n\nEspera por favor...\n') time.sleep(0.5) os.makedirs(newserver, exist_ok=True) @@ -2202,7 +2210,7 @@ def servdownload(versionname): completed = int(50 * total_data / total_size_in_bytes) print("\r[%s%s]" % ('#' * completed, '.' * (50 - completed)), end='') print() - limpiar_consola() + cls() input('Lanzador de Servidores para Minecraft\n-------------------------------------\n\nTu Nuevo Server se ha instalado correctamente y ha sido añadido a la Lista "Tus Servidores".\n\nPresiona ENTER para continuar.') servname = os.path.basename(newserver) servstring = f"{servname}<[=]>{newserver}\n" @@ -2214,7 +2222,7 @@ def servdownload(versionname): esp() except Exception: def erragain(): - limpiar_consola() + cls() yup = colored("Sí","green") nop = colored("No","red") errtry = input(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nHa ocurrido un error mientras se descargaba tu Nuevo Server.\nReintentar?\n\n(1) {yup}\n(2) {nop}\n\nElige una de las opciones= ") @@ -2228,7 +2236,7 @@ def erragain(): errtr = errtry errtr = int(errtr) if errtr == 1: - servdownload(version) + servdownload(version,type) elif errtr == 2: esp() else: @@ -2241,10 +2249,15 @@ def erragain(): elif verss.lower() == "r": reselect() elif verss.lower() == "l": - def versionl(): - limpiar_consola() - print("Lanzador de Servidores para Minecraft\n-------------------------------------\n\nVersiones disponibles:\n") - for i, version in enumerate(MCVERSIONS, start=1): + def select_list(): + cls() + print("Lanzador de Servidores para Minecraft\n-------------------------------------\n") + print("VERSIONES ESTABLES:") + for i, version in enumerate(MCSTABLE, start=1): + print(f"(-) {version}") + print('') + print("VERSIONES SNAPSHOT:") + for i, version in enumerate(MCSNAPSHOT, start=1): print(f"(-) {version}") listselection = input("\n(B) Atrás\n(R) Volver al menú principal\n\nEscribe una versión o elige una de las opciones=") try: @@ -2252,15 +2265,19 @@ def versionl(): vers_select() elif listselection.lower() == "r": esp() - elif listselection.lower() in MCVERSIONS.keys(): - servdownload(listselection) + elif listselection.lower() in MCSTABLE.keys(): + servdownload(listselection,"stable") + elif listselection.lower() in MCSNAPSHOT.keys(): + servdownload(listselection,"snapshot") else: - versionl() + select_list() except (ValueError, SyntaxError, IndexError, ZeroDivisionError): - versionl() - versionl() - elif verss.lower() in MCVERSIONS.keys(): - servdownload(verss) + select_list() + select_list() + elif verss.lower() in MCSTABLE.keys(): + servdownload(verss,"stable") + elif verss.lower() in MCSNAPSHOT.keys(): + servdownload(verss,"snapshot") else: vers_select() except (ValueError, SyntaxError, IndexError, ZeroDivisionError): @@ -2278,8 +2295,8 @@ def versionl(): # LICENSE AND EXTRAS def about(): - limpiar_consola() - copyr = input("Lanzador de Servidores para Minecraft\n-------------------------------------\n\nMIT License - Copyright (c) 2024 NGDPL Nk\n\nSSTools4MC v24.06.27 - SE AÑADE SOPRTE PARA LA 1.21\n\nHelpers:\n@naicoooossj\n@LegalizeNuclearBombs\n\n-------------------------------------\n\n(1) Ver repositorio en el navegador\n(2) Ver licencia en el navegador\n(3) Volver al menú principal\n\nElige una de las opciones= ") + cls() + copyr = input("Lanzador de Servidores para Minecraft\n-------------------------------------\n\nMIT License - Copyright (c) 2024 ngdplnk\n\nSSTools4MC v24.07.29 - SE AÑADE SOPRTE PARA VERSIONES SNAPSHOT\n\nHelpers:\n@naicoooossj\n@LegalizeNuclearBombs\n\n-------------------------------------\n\n(1) Ver repositorio en el navegador\n(2) Ver licencia en el navegador\n(3) Volver al menú principal\n\nElige una de las opciones= ") try: if any(char in "0123456789+-*/" for char in copyr): if not copyr[0].isalpha(): @@ -2291,14 +2308,14 @@ def about(): selec = int(selec) if selec == 1: url = colored("https://github.com/ngdplnk/SSTools4MC","cyan") - limpiar_consola() + cls() input(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nEl repositorio se abrirá en tu navegador.\n\n{url}\n\nPresiona ENTER para continuar.") url = "https://github.com/ngdplnk/SSTools4MC" webbrowser.open(url) about() elif selec == 2: url = colored("https://github.com/ngdplnk/SSTools4MC/blob/main/LICENSE","cyan") - limpiar_consola() + cls() input(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nLa licencia se abrirá en tu navegador.\n\n{url}\n\nPresiona ENTER para continuar.") url = "https://github.com/ngdplnk/SSTools4MC/blob/main/LICENSE" webbrowser.open(url) @@ -2312,8 +2329,8 @@ def about(): # EXIT def exiit(): - limpiar_consola() - print("--------------------------------------------\nMuchas gracias por usar esta herramienta\nMIT License - Copyright (c) 2024 NGDPL Nk\n--------------------------------------------\n") + cls() + print("--------------------------------------------\nNos vemos pronto!\nMIT License - Copyright (c) 2024 ngdplnk\n--------------------------------------------\n") time.sleep(1.2) sys.exit() @@ -2321,7 +2338,7 @@ def exiit(): def menu(): os.makedirs(SSTOOLS_FOLDER, exist_ok=True) os.chdir(SSTOOLS_FOLDER) - limpiar_consola() + cls() seleccion = input("Lanzador de Servidores para Minecraft\n-------------------------------------\n\nHola! Estás en el menú principal.\n\n(1) Inciar un Server\n(2) Instalar un Nuevo Server\n(3) Extras\n(4) Cambiar Lenguaje\n(5) Salir\n\nElige una de las opciones= ") try: if any(char in "0123456789+-*/" for char in seleccion): @@ -2348,8 +2365,8 @@ def menu(): menu() -# SELECCIÓN DE IDIOMA - LANGUAGE SELECTION -def lang(): +# STARTUP +def startup(): system_lang = locale.getlocale()[0] system_lang = str(system_lang) if system_lang.startswith("es") or system_lang.startswith("Spanish"): @@ -2357,5 +2374,5 @@ def lang(): else: eng() -# INICIAR HERRAMIENTA - RUN TOOL -lang() +# RUN TOOL +startup() diff --git a/3-launcher/base.py b/3-launcher/base.py index ee34557..7c58849 100644 --- a/3-launcher/base.py +++ b/3-launcher/base.py @@ -1,6 +1,13 @@ -#!/usr/bin/env python3 +#### SSTOOLS4MC MAIN PROGRAM #### +#### DEVELOPED BY: NGDPLNK #### -# MÓDULOS IMPORTADOS - IMPORTED MODULES +### THINGS TO FIX +# - Download progressbar has a bug that when the console is untabbed, freezes and corrupts the file. +# - In specific conditions, the server startup cancelling with CTRL+C shows an unexpected screen from other function. + +##################### + +# MODULES import os import time import sys @@ -19,14 +26,14 @@ # PATHS APPDATA = os.getenv('APPDATA') -SSTOOLS_FOLDER = os.path.join(APPDATA, "TLSoftware", "SSTools4MC") # type: ignore +SSTOOLS_FOLDER = os.path.join(APPDATA, "SSTools4MC") # type: ignore CONFIG_PATH = os.path.join(SSTOOLS_FOLDER, "config") # type: ignore SAVED_SERVERS = os.path.join(CONFIG_PATH, "saved-servers.cfg") # type: ignore -# MINECRAFT VERSIONS -## 81 VERSIONS ADDED (1.2.1 - 1.20.4) -# LAST UPDATE: 23-03-2024 -MCVERSIONS = { +### MINECRAFT VERSIONS +## 84 STABLE VERSIONS ADDED (1.2.1 - 1.21) +# LAST UPDATE: 29-07-2024 +MCSTABLE = { "1.2.1": "https://assets.minecraft.net/1_2/minecraft_server.jar", "1.2.2": "https://assets.minecraft.net/1_2/minecraft_server.jar", "1.2.3": "https://assets.minecraft.net/1_2/minecraft_server.jar", @@ -108,37 +115,641 @@ "1.20.1": "https://piston-data.mojang.com/v1/objects/84194a2f286ef7c14ed7ce0090dba59902951553/server.jar", "1.20.2": "https://piston-data.mojang.com/v1/objects/5b868151bd02b41319f54c8d4061b8cae84e665c/server.jar", "1.20.3": "https://piston-data.mojang.com/v1/objects/4fb536bfd4a83d61cdbaf684b8d311e66e7d4c49/server.jar", - "1.20.4": "https://piston-data.mojang.com/v1/objects/8dd1a28015f51b1803213892b50b7b4fc76e594d/server.jar" + "1.20.4": "https://piston-data.mojang.com/v1/objects/8dd1a28015f51b1803213892b50b7b4fc76e594d/server.jar", + "1.20.5": "https://piston-data.mojang.com/v1/objects/79493072f65e17243fd36a699c9a96b4381feb91/server.jar", + "1.20.6": "https://piston-data.mojang.com/v1/objects/145ff0858209bcfc164859ba735d4199aafa1eea/server.jar", + "1.21": "https://piston-data.mojang.com/v1/objects/450698d1863ab5180c25d7c804ef0fe6369dd1ba/server.jar" +} +## 613 SNAPSHOT VERSIONS ADDED (1.3 - 1.21-rc1) +# LAST UPDATE: 29-07-2024 +MCSNAPSHOT = { + "1.3": "https://launcher.mojang.com/v1/objects/cb21a9aaaf599c94dd7fa1b777b2f0cc37a776c7/server.jar", + "1.4": "https://launcher.mojang.com/v1/objects/9470a2bb0fcb8a426328441a01dba164fbbe52c9/server.jar", + "1.4.1": "https://launcher.mojang.com/v1/objects/baa4e4a7adc3dc9fbfc5ea36f0777b68c9eb7f4a/server.jar", + "1.4.3": "https://launcher.mojang.com/v1/objects/9be68adf6e80721975df12f2445fa24617328d18/server.jar", + "1.5": "https://launcher.mojang.com/v1/objects/aedad5159ef56d69c5bcf77ed141f53430af43c3/server.jar", + "13w16a": "https://launcher.mojang.com/v1/objects/dd76b63bad493e42b303dd8952c240f330251760/server.jar", + "13w16b": "https://launcher.mojang.com/v1/objects/c125111764b5774403ff2183debbb9da4805a64f/server.jar", + "13w17a": "https://launcher.mojang.com/v1/objects/48ece561c3512b2f9c0915dad7c3cb65560ceb39/server.jar", + "13w18a": "https://launcher.mojang.com/v1/objects/6084eae41c6e28d58fe8a1ee4ab4389a392f0139/server.jar", + "13w18b": "https://launcher.mojang.com/v1/objects/af7fd5e8cdc610f1e533ba7963bc39de422df1b6/server.jar", + "13w18c": "https://launcher.mojang.com/v1/objects/3f8dc565567174d777a416f979901e0fee010d2a/server.jar", + "13w19a": "https://launcher.mojang.com/v1/objects/17997ee2d9a3ad1070a74707f58ebb3e3a46ae10/server.jar", + "13w21a": "https://launcher.mojang.com/v1/objects/a04b6f0349b8de64c68a9311b4eaff478e37b558/server.jar", + "13w21b": "https://launcher.mojang.com/v1/objects/f5236a7628c74c22c33f57b50cb755598042aa5b/server.jar", + "13w22a": "https://launcher.mojang.com/v1/objects/94b99928dccee27ad9b1d90bd00e8f68f38f92e4/server.jar", + "13w23a": "https://launcher.mojang.com/v1/objects/b26a278856a6a4703054ad266b79b1ef397676c2/server.jar", + "13w23b": "https://launcher.mojang.com/v1/objects/b6b627c0a5fe9f53a22892f21c473e19617c1c0d/server.jar", + "13w24a": "https://launcher.mojang.com/v1/objects/d0f1eb0455c1bc3f73d5fc7252e282fd614f1f5b/server.jar", + "13w24b": "https://launcher.mojang.com/v1/objects/9c312da9bdcc562dc57e235a7a56900148c77f8d/server.jar", + "13w25a": "https://launcher.mojang.com/v1/objects/e1c2e7376fe489c5eba744b010993c402ab3f3f2/server.jar", + "13w25b": "https://launcher.mojang.com/v1/objects/9f7f205d7c00098d9aa6abd67ce4f93d0eeddcd7/server.jar", + "13w25c": "https://launcher.mojang.com/v1/objects/0f21dbd39728a50843d1b20cf832f26aaada353d/server.jar", + "13w26a": "https://launcher.mojang.com/v1/objects/bafe11faf3419c8813beb948e353912239d50bc1/server.jar", + "1.6": "https://launcher.mojang.com/v1/objects/ee6d5161ac28eef285df571dc1235d48f03c3e88/server.jar", + "13w36a": "https://launcher.mojang.com/v1/objects/8453f031175bac1a92db000befd14f70c8df8fb7/server.jar", + "13w36b": "https://launcher.mojang.com/v1/objects/2b6cdcd2df82ca8f04c1c2c7d77faf4cd25151ea/server.jar", + "13w37a": "https://launcher.mojang.com/v1/objects/c3d3d936394b35f20b871b140f5a8e6079822e51/server.jar", + "1.6.3": "https://launcher.mojang.com/v1/objects/5a4c69bdf7c4a9aa9580096805d8497ba7721e05/server.jar", + "13w37b": "https://launcher.mojang.com/v1/objects/f6322a6791bbeabac94cbaa1cf9b779ad88b120f/server.jar", + "13w38a": "https://launcher.mojang.com/v1/objects/627585cdb9386e7f05cdfb8f092e5a303d4fd5f3/server.jar", + "13w38b": "https://launcher.mojang.com/v1/objects/82588f79a6a61c4c4289a9dc60b7b7b3fedaead9/server.jar", + "13w38c": "https://launcher.mojang.com/v1/objects/03081b4b569174ec68ef9cdd574ee4feca05dea5/server.jar", + "13w39a": "https://launcher.mojang.com/v1/objects/10e8687a623cb3def606fa3855aaed5ef79aac66/server.jar", + "13w39b": "https://launcher.mojang.com/v1/objects/1db7286055aeb35c709d98ace1c9cdc739206d5a/server.jar", + "13w41a": "https://launcher.mojang.com/v1/objects/fbe939a8a9246db801428e33a1c53506af637247/server.jar", + "13w41b": "https://launcher.mojang.com/v1/objects/d0f1808505d59bd69c47d8e0ce01dc5936d34c34/server.jar", + "13w42a": "https://launcher.mojang.com/v1/objects/d7007e5f46bb1ad4f4d38dc8cd2ea54898c6cccb/server.jar", + "13w42b": "https://launcher.mojang.com/v1/objects/1416ebe3d6e6aa62eaae305ce542c39b7dfcb2b9/server.jar", + "13w43a": "https://launcher.mojang.com/v1/objects/0fd72957ddbedd604d2bdf155dd03c8501c48f48/server.jar", + "1.7": "https://launcher.mojang.com/v1/objects/3f031ab8b9cafedeb822febe89d271b72565712c/server.jar", + "1.7.1": "https://launcher.mojang.com/v1/objects/d26d79675147253b7a35dd32dc5dbba0af1be7e2/server.jar", + "13w47a": "https://launcher.mojang.com/v1/objects/f3210daa0a05a88b8b8edadfc8af385ff3f88987/server.jar", + "13w47b": "https://launcher.mojang.com/v1/objects/7c1b69de43b6edf1d20f5030b88df78fd08ad8c7/server.jar", + "13w47c": "https://launcher.mojang.com/v1/objects/5cf618125f87452e665f0097171d089f73dc7e1c/server.jar", + "13w47d": "https://launcher.mojang.com/v1/objects/28982e580acf736120a4f1c3e7418e2a8daa3a8c/server.jar", + "13w47e": "https://launcher.mojang.com/v1/objects/0f08e81b37b2c06ead45f498a7c8efa10a02633a/server.jar", + "13w48a": "https://launcher.mojang.com/v1/objects/8f43e47eb288d3485f7825c422e9c5bcaf6418af/server.jar", + "13w48b": "https://launcher.mojang.com/v1/objects/9ab8a06fe77ed7f553ae3427d304e9f55de339d9/server.jar", + "13w49a": "https://launcher.mojang.com/v1/objects/164c350e011f491f6e12861ee4988ef2ccecfe0e/server.jar", + "14w02a": "https://launcher.mojang.com/v1/objects/b908214fb99891c4f1e77c21b1fcbe4f7cafdd58/server.jar", + "14w02b": "https://launcher.mojang.com/v1/objects/2f873b2fd721c9ed5ef51e80df96d10e5390ee9f/server.jar", + "14w02c": "https://launcher.mojang.com/v1/objects/c844eb4e22c6c0a3b87835fc61a508caeeced1f9/server.jar", + "14w03a": "https://launcher.mojang.com/v1/objects/5cbd5319a7b1198f049286d443148f1b88ff7bc7/server.jar", + "14w03b": "https://launcher.mojang.com/v1/objects/b8bee8cbf485aad0be9789fe58ab266d8fe82215/server.jar", + "14w04a": "https://launcher.mojang.com/v1/objects/bd483603d1b07d3ce3fde76a35abfb0489933d72/server.jar", + "14w04b": "https://launcher.mojang.com/v1/objects/7af6befa241678d09d4031fed5578785dd3c126d/server.jar", + "14w05a": "https://launcher.mojang.com/v1/objects/27abecb729cab3a6e11f635dae2cf9be5f620a75/server.jar", + "14w05b": "https://launcher.mojang.com/v1/objects/d2d2b00952748af9ee8e60f49b9998dcfad3071f/server.jar", + "14w06a": "https://launcher.mojang.com/v1/objects/a6a41979ed198086f2c8ae638f26286b2dc931db/server.jar", + "14w06b": "https://launcher.mojang.com/v1/objects/0591a5e7e299182c6849e705704095d2a1efe1d5/server.jar", + "14w07a": "https://launcher.mojang.com/v1/objects/de78ac487cf3fb6770e8c15f83e2219d4df851ae/server.jar", + "14w08a": "https://launcher.mojang.com/v1/objects/a2716623b9e2c01cf0a1ec44497cc3279fce8f6a/server.jar", + "14w10a": "https://launcher.mojang.com/v1/objects/03503dc8c3f615bf8b65d8e1ebbf923e81162e3e/server.jar", + "14w10b": "https://launcher.mojang.com/v1/objects/2dd525cb725635b94c763c2efa5e1fe931a0d6d6/server.jar", + "14w10c": "https://launcher.mojang.com/v1/objects/d97cc24dad232b5452644facde54c47854283b99/server.jar", + "1.7.6-pre1": "https://launcher.mojang.com/v1/objects/121176f19f38780d0cd04bef87c1296fedb37cd0/server.jar", + "1.7.6-pre2": "https://launcher.mojang.com/v1/objects/5aa5deddbe750a384bdb5ed0652bbda33cf4e5c8/server.jar", + "14w11a": "https://launcher.mojang.com/v1/objects/286924e7082ff1f6baed77a100f73abae81f25e3/server.jar", + "14w11b": "https://launcher.mojang.com/v1/objects/58694879e09c500dccb00751ed85a1d6b983229d/server.jar", + "14w17a": "https://launcher.mojang.com/v1/objects/701dca9511fa3e6b26799d11475fb3a719d6a26a/server.jar", + "14w18a": "https://launcher.mojang.com/v1/objects/48d6b3b47e870f61a95645e2bc1a84a27a1da068/server.jar", + "14w18b": "https://launcher.mojang.com/v1/objects/d7300a576860c056938760153cbf56ed98e9c7f9/server.jar", + "14w19a": "https://launcher.mojang.com/v1/objects/a7df79e00c4d75e3916438658839785a476bd6ac/server.jar", + "1.7.10-pre1": "https://launcher.mojang.com/v1/objects/db79ef4be8b37093c7ca4ddbd54ede2ca21d2a9f/server.jar", + "1.7.10-pre2": "https://launcher.mojang.com/v1/objects/ea9fdacf5b0eadfbec5f8aed89c4da3c6be87060/server.jar", + "1.7.10-pre3": "https://launcher.mojang.com/v1/objects/b9fdcbd17407d9eaeedcf4ff79b3121ee40133db/server.jar", + "1.7.10-pre4": "https://launcher.mojang.com/v1/objects/7c8249c626996c4474afe4f26071a91e7efd825a/server.jar", + "14w20a": "https://launcher.mojang.com/v1/objects/4dfd82a84113cfb7e4b489c52caa68bc3f21198e/server.jar", + "14w20b": "https://launcher.mojang.com/v1/objects/93ff3d1043ecf25eaf7c9626d8cbde7986dde65d/server.jar", + "14w21a": "https://launcher.mojang.com/v1/objects/7e26d5c2feb9df58353b942418640164a8cd0fbd/server.jar", + "14w21b": "https://launcher.mojang.com/v1/objects/b02c5506df94aa5d5200ef063f1bab22ce260c8a/server.jar", + "14w25a": "https://launcher.mojang.com/v1/objects/e22dedab430bc1c0f938a1e1a2811d11fe29f67e/server.jar", + "14w25b": "https://launcher.mojang.com/v1/objects/29209a8e73b6f4afa691d0682aa848c2a1f52dd7/server.jar", + "14w26a": "https://launcher.mojang.com/v1/objects/9d167e0b009b99d637ad102a1cb4f5aeb1501e45/server.jar", + "14w26b": "https://launcher.mojang.com/v1/objects/0b461d7af1194a192f5b7a9a8989bab83f7317b0/server.jar", + "14w26c": "https://launcher.mojang.com/v1/objects/247352905e446c66db85ecb26361a9b5a8eec4ea/server.jar", + "14w27a": "https://launcher.mojang.com/v1/objects/b5350953ff062646d4a61b7c8fb4c0570829843a/server.jar", + "14w27b": "https://launcher.mojang.com/v1/objects/c5be337237224f752b2ea09d3a2a00a00b26e14b/server.jar", + "14w28a": "https://launcher.mojang.com/v1/objects/6987a36f248e88fd8b2366e87fd88834b4a06f7a/server.jar", + "14w28b": "https://launcher.mojang.com/v1/objects/aacec09f5ed0475eb474052a4a55b3ca6edaeecc/server.jar", + "14w29a": "https://launcher.mojang.com/v1/objects/c16a61be653b5921391c55b337640ddfd7a5b472/server.jar", + "14w29b": "https://launcher.mojang.com/v1/objects/b81bb5f919d5489859e9a38c7f6b49e6931a8cc8/server.jar", + "14w30a": "https://launcher.mojang.com/v1/objects/cb7bd4bebcb40c128a571c8f15fe1990b1f50a32/server.jar", + "14w30b": "https://launcher.mojang.com/v1/objects/ee24a6e63b007b9ec97a591afe1a29a6bbbfe143/server.jar", + "14w30c": "https://launcher.mojang.com/v1/objects/2c936d1f410d636a348f100ab926d94d92b743b7/server.jar", + "14w31a": "https://launcher.mojang.com/v1/objects/05fde0b4039104a27df8c7b95d327ecafc06cde7/server.jar", + "14w32a": "https://launcher.mojang.com/v1/objects/d3b96be87d921fa4f95ea43e5283a253b778f24e/server.jar", + "14w32b": "https://launcher.mojang.com/v1/objects/8aa6b045d31cc4a9224ecce602e9f5f748d8f460/server.jar", + "14w32c": "https://launcher.mojang.com/v1/objects/5fee0612322feaf374867336375810580da6fab9/server.jar", + "14w32d": "https://launcher.mojang.com/v1/objects/83d7acb6f94dc606591ebe4d7a06ad29127cd3de/server.jar", + "14w33a": "https://launcher.mojang.com/v1/objects/6c0d06c1b3d8c3365be6e1b9b269725eb4e05ee7/server.jar", + "14w33b": "https://launcher.mojang.com/v1/objects/7e0e5511b0049ba92e5c991b6bd0264932559af2/server.jar", + "14w33c": "https://launcher.mojang.com/v1/objects/5479bbd5f4717d7c8bc8ca895b3e0894e490814e/server.jar", + "14w34a": "https://launcher.mojang.com/v1/objects/e59eecd2f79579f7b87a89b14aa07671eb94c9b1/server.jar", + "14w34b": "https://launcher.mojang.com/v1/objects/7991f32cd598ac7e5a8cf11d91965e597ae148b6/server.jar", + "14w34c": "https://launcher.mojang.com/v1/objects/5ab3e11d059a6f321a1d284d6849b95264d77e66/server.jar", + "14w34d": "https://launcher.mojang.com/v1/objects/0e05b086df677d9802ff5335719149ea90b6f302/server.jar", + "1.8-pre1": "https://launcher.mojang.com/v1/objects/88b759849519ca8a7592a2e90d6891c98f50cc17/server.jar", + "1.8-pre2": "https://launcher.mojang.com/v1/objects/5673d722ac14f571e6a46f368d34b144e90ef8ad/server.jar", + "1.8-pre3": "https://launcher.mojang.com/v1/objects/27fb956fd88ab39205c7c45a39ca4e8820f96cc4/server.jar", + "1.8.1-pre1": "https://launcher.mojang.com/v1/objects/dae8203bc40eb43e15e6e9ed454404f330c591f2/server.jar", + "1.8.1-pre2": "https://launcher.mojang.com/v1/objects/d0b163d9a442e8b49187e4925ef75970ad451f41/server.jar", + "1.8,1-pre3": "https://launcher.mojang.com/v1/objects/22440c0335d95efb7d52d9c844108aa2c69da179/server.jar", + "1.8.1-pre4": "https://launcher.mojang.com/v1/objects/5420c131b360f58ecbeb970127a49b525b28f921/server.jar", + "1.8.1-pre5": "https://launcher.mojang.com/v1/objects/a25350da18085ab12f01ba56ab03c562cc722a40/server.jar", + "1.8.2-pre1": "https://launcher.mojang.com/v1/objects/32320f5d6162cceed3cf618f3c37bde6978eacf2/server.jar", + "1.8.2-pre2": "https://launcher.mojang.com/v1/objects/4c32f01c356568b6c6b3cecf4ab4d0f0e7e14fab/server.jar", + "1.8.2-pre3": "https://launcher.mojang.com/v1/objects/dd98a2d8148cdaa92fc0deb4201186d552201314/server.jar", + "1.8.2-pre4": "https://launcher.mojang.com/v1/objects/b1d4937d5c39c5e1c462d39cc081544170c962b3/server.jar", + "1.8.2-pre5": "https://launcher.mojang.com/v1/objects/0226544b417d842a3a78797784615f11f1262a79/server.jar", + "1.8.2-pre6": "https://launcher.mojang.com/v1/objects/cc40241ef5acc247048b9d351aefa6288de13d8b/server.jar", + "1.8.2-pre7": "https://launcher.mojang.com/v1/objects/61039f9df585c52fbeb2e95d1754852ac00b4344/server.jar", + "15w14a": "https://launcher.mojang.com/v1/objects/f7d2bd26ce7893477fc1ca6e27b671345253bae4/server.jar", + "15w31a": "https://launcher.mojang.com/v1/objects/7799f1f6a486be08185b470a64ca4649e37de578/server.jar", + "15w31b": "https://launcher.mojang.com/v1/objects/67f5af98eeef5f6267aca782ea3a536d50f33bc6/server.jar", + "15w31c": "https://launcher.mojang.com/v1/objects/4fec021cc8110ce87451e22e23e958ce9d8d61f2/server.jar", + "15w32a": "https://launcher.mojang.com/v1/objects/5cb1aa4a4b26979405cea5a181bbe38b72a85add/server.jar", + "15w32b": "https://launcher.mojang.com/v1/objects/53c13fc634c89d408155553ebc8724f4b900fa1f/server.jar", + "15w32c": "https://launcher.mojang.com/v1/objects/6bef1fd3f1cb34b1d6654d93c43abb899072bd24/server.jar", + "15w33a": "https://launcher.mojang.com/v1/objects/b2f50a0daf6fd2e70dac4d7da302524566b57a55/server.jar", + "15w33b": "https://launcher.mojang.com/v1/objects/991c628d7c3ea224d90539297d8c2e9127b2489f/server.jar", + "15w33c": "https://launcher.mojang.com/v1/objects/042b351243f4236d02976ffc1e7f83f93ac932c7/server.jar", + "15w34a": "https://launcher.mojang.com/v1/objects/70103317cd7b973e4f8511a5d8973da20c6654d1/server.jar", + "15w34b": "https://launcher.mojang.com/v1/objects/6ee63157f9201f461e056652831348b9c1a51d8c/server.jar", + "15w34c": "https://launcher.mojang.com/v1/objects/639946a883a6a2636a82641a1fe4c9243c8e633c/server.jar", + "15w34d": "https://launcher.mojang.com/v1/objects/8bf058527fd4bd5d2951e1573d0ff849aedb0197/server.jar", + "15w35a": "https://launcher.mojang.com/v1/objects/a3a1c19d861bce39a129ef18226449ea02afb58a/server.jar", + "15w35b": "https://launcher.mojang.com/v1/objects/e92badd361f83730436c010044099fdf1af60bab/server.jar", + "15w35c": "https://launcher.mojang.com/v1/objects/a0f20e4bdd79e53d923d3fe2853ba11da993e6a1/server.jar", + "15w35d": "https://launcher.mojang.com/v1/objects/ed244d36678d875b979f81dbea05acacb89dc4d1/server.jar", + "15w35e": "https://launcher.mojang.com/v1/objects/04ade8521778da7786ea9c8bbda2fac005229e0f/server.jar", + "15w36a": "https://launcher.mojang.com/v1/objects/ee0b49a2fff99c93b7a216931c11292537eed473/server.jar", + "15w36b": "https://launcher.mojang.com/v1/objects/81ab225579322b61b3a37f7d56f400077c1c5978/server.jar", + "15w36c": "https://launcher.mojang.com/v1/objects/72a23cbf5f21b3589e230164f5c40c1aa7de36cd/server.jar", + "15w36d": "https://launcher.mojang.com/v1/objects/b862ed48ecf134683470145662ac8cb0e1ca7e4d/server.jar", + "15w37a": "https://launcher.mojang.com/v1/objects/0f29d64f94ccc40d01ebc1ddd0c506edca7b5dfb/server.jar", + "15w38a": "https://launcher.mojang.com/v1/objects/9b14cce8545a6f03f16ef52ef8a2725afaea5c1c/server.jar", + "15w38b": "https://launcher.mojang.com/v1/objects/41f8ae90397575214b958bb5ef99d25b541fe366/server.jar", + "15w39a": "https://launcher.mojang.com/v1/objects/871b86fac1a4d71642166e0deba2a4b85780d82a/server.jar", + "15w39b": "https://launcher.mojang.com/v1/objects/031a5a79a1548f54c7bd148f6f3cf9e42fbd3222/server.jar", + "15w39c": "https://launcher.mojang.com/v1/objects/d3f7fb05eef0331941b4161b1f2f2ded7151bbaf/server.jar", + "15w40a": "https://launcher.mojang.com/v1/objects/d3f7fb05eef0331941b4161b1f2f2ded7151bbaf/server.jar", + "15w40b": "https://launcher.mojang.com/v1/objects/adba98d3a02da95106d782991a90a199d38e5d9f/server.jar", + "15w41a": "https://launcher.mojang.com/v1/objects/92fcc884b954fb7e87b163d478fd5ff91bdb1550/server.jar", + "15w41b": "https://launcher.mojang.com/v1/objects/994a048f6a3f8f800f2807545b8401617c553dfc/server.jar", + "15w42a": "https://launcher.mojang.com/v1/objects/d789ab5179e3bb5d298d82570ee123457cfdfb94/server.jar", + "15w43a": "https://piston-data.mojang.com/v1/objects/dfc6b233c097fa377f35972e7c95e3c23c632f3c/server.jar", + "15w43b": "https://piston-data.mojang.com/v1/objects/3154e2f53b1a50159d53f0dc8e4f47857344690f/server.jar", + "15w43c": "https://piston-data.mojang.com/v1/objects/e514e7107639d2e8b285ceff5eaa114379dafba7/server.jar", + "15w44a": "https://piston-data.mojang.com/v1/objects/087cd273ee072bf626f89da4ccbb2841854f39ed/server.jar", + "15w44b": "https://piston-data.mojang.com/v1/objects/7bda3375d5509536766d65cf47b2a17ef42b964a/server.jar", + "15w45a": "https://piston-data.mojang.com/v1/objects/6bae28a2f80749ba7fc379e44acc46ac5fe44920/server.jar", + "15w46a": "https://piston-data.mojang.com/v1/objects/f0f25f22430b0c122308244f210df66ae3ce7894/server.jar", + "15w47a": "https://piston-data.mojang.com/v1/objects/2299e712df1aacb7297d63b75a5299fe35c9b9fd/server.jar", + "15w47b": "https://piston-data.mojang.com/v1/objects/80cfe2c26ef21e10feb1458c46c244caa07ebcf1/server.jar", + "15w47c": "https://piston-data.mojang.com/v1/objects/9ec245a239150ccb0f8cdae430d25ed04899bb51/server.jar", + "15w49a": "https://piston-data.mojang.com/v1/objects/63e4904766e1af15c1a4a412ec3aeb9c5972176d/server.jar", + "15w49b": "https://piston-data.mojang.com/v1/objects/e376081a73fe429c23db41a99a68a4b04c53ba8e/server.jar", + "15w50a": "https://piston-data.mojang.com/v1/objects/3ce8624859c8d38b38d2209e30f4fe76b2866de9/server.jar", + "15w51a": "https://piston-data.mojang.com/v1/objects/4d5f4d2111272d67f2238b83a552599b9b7ad92f/server.jar", + "15w51b": "https://piston-data.mojang.com/v1/objects/4d5f4d2111272d67f2238b83a552599b9b7ad92f/server.jar", + "16w02a": "https://piston-data.mojang.com/v1/objects/c574c54826489e1c04dd54d634da83945824337b/server.jar", + "16w03a": "https://piston-data.mojang.com/v1/objects/c574c54826489e1c04dd54d634da83945824337b/server.jar", + "16w04a": "https://piston-data.mojang.com/v1/objects/8b7d974f3161ddb90b14ff77a668bf0350689bb2/server.jar", + "16w05a": "https://piston-data.mojang.com/v1/objects/d74a9989d7dcd73c90191a65ae09e15b2371ffbd/server.jar", + "16w05b": "https://piston-data.mojang.com/v1/objects/9fdf8a90055b3cf689265cc30bdd9d1faf2c743c/server.jar", + "16w06a": "https://piston-data.mojang.com/v1/objects/c4da6936d6374fd7116900135a2ae664de63d3bf/server.jar", + "16w07a": "https://piston-data.mojang.com/v1/objects/f2bfcb799a616611801ff0295312e563f782ff78/server.jar", + "16w07b": "https://piston-data.mojang.com/v1/objects/f2bfcb799a616611801ff0295312e563f782ff78/server.jar", + "1.9-pre1": "https://piston-data.mojang.com/v1/objects/e166c9863dc5a6444d8260b46423325d4130b429/server.jar", + "1.9-pre2": "https://piston-data.mojang.com/v1/objects/ac6c4226ca5f1f7ea4c6f936f88d1df7c82d3a92/server.jar", + "1.9-pre3": "https://piston-data.mojang.com/v1/objects/db995628b109fd83953ffadb749c2432fac70d9e/server.jar", + "1.9-pre4": "https://piston-data.mojang.com/v1/objects/bbcbe9f89ef3cacd96dfd1df4d88588369fbd767/server.jar", + "1.9.1-pre1": "https://piston-data.mojang.com/v1/objects/04a6ca96d4024050c50570731568b94771ff7910/server.jar", + "1.9.1-pre2": "https://piston-data.mojang.com/v1/objects/bc7000381cec5819aefeea8b68ecc232208ab3ad/server.jar", + "1.9.1-pre3": "https://piston-data.mojang.com/v1/objects/6cf7cb1c561e2915c4370bfb4cf3f5e10058d537/server.jar", + "1.RV-Pre1": "https://piston-data.mojang.com/v1/objects/f51d9489706f603be6be9716407f1dab5f7f2733/server.jar", + "16w14a": "https://piston-data.mojang.com/v1/objects/5616b2213b727241821a137b4ef290c7bbace20a/server.jar", + "16w15a": "https://piston-data.mojang.com/v1/objects/c254bc24caac3f6d5059f2cc64a80ded2e164289/server.jar", + "16w15b": "https://piston-data.mojang.com/v1/objects/5add6bcbd04c20bef6ed5db4431651c0c1282489/server.jar", + "1.9.3-pre1": "https://piston-data.mojang.com/v1/objects/5d7391b36ccbc4ec04a259a3f7c6609232f30762/server.jar", + "1.9.3-pre2": "https://piston-data.mojang.com/v1/objects/41c29ba7fca8d2a0ce3bab620600459e6023458c/server.jar", + "1.9.3-pre3": "https://piston-data.mojang.com/v1/objects/ef902371fa5cbb50288b4801f9e58432c627d8e7/server.jar", + "16w20a": "https://piston-data.mojang.com/v1/objects/2cbcbd735cb48c8cc2bebb7b43c8afa69a923269/server.jar", + "16w21a": "https://piston-data.mojang.com/v1/objects/12d65aa459d3e93643746dce14c100b05fbcdddf/server.jar", + "16w21b": "https://piston-data.mojang.com/v1/objects/6dedac03d0fbfbcabe8ef09b170a577a9f72c6f8/server.jar", + "1.10-pre1": "https://piston-data.mojang.com/v1/objects/c9c34ba406f694e56c1729b465c25e0f63ce9743/server.jar", + "1.10-pre2": "https://piston-data.mojang.com/v1/objects/aa4ec0004eb20a70ef7426816cae992d73718038/server.jar", + "16w32a": "https://piston-data.mojang.com/v1/objects/b1309cff6c574e9487e3413773841ef5eb260587/server.jar", + "16w32b": "https://piston-data.mojang.com/v1/objects/b912ff1468e93003f36cda32db5d70133b517f97/server.jar", + "16w33a": "https://piston-data.mojang.com/v1/objects/dfdda3e5ba769ba0634ad43ca1124a401d6addca/server.jar", + "16w35a": "https://piston-data.mojang.com/v1/objects/16ad43cb3b87b0279028af26201af7651b87c9e0/server.jar", + "16w36a": "https://piston-data.mojang.com/v1/objects/921580b22ce7d48f9d541364a3b04eebb680222e/server.jar", + "16w38a": "https://piston-data.mojang.com/v1/objects/95ffd7c33ad9f978d4a23762978923b96fc0aa7e/server.jar", + "16w39a": "https://piston-data.mojang.com/v1/objects/f5e840e9f37ae7f50c9c979669279bcc68c91fa7/server.jar", + "16w39b": "https://piston-data.mojang.com/v1/objects/07eb3f85fc848ec8e209377aee1f7f574566e130/server.jar", + "16w39c": "https://piston-data.mojang.com/v1/objects/df13c6cbf5fc735896b22f56b1f8940dd11a3b5f/server.jar", + "16w40a": "https://piston-data.mojang.com/v1/objects/64a1a5ba3f347c5e03477b42ac13d10ee193b51c/server.jar", + "16w41a": "https://piston-data.mojang.com/v1/objects/94f47b24edd154d89240e49d9b7371e74f433d19/server.jar", + "16w42a": "https://piston-data.mojang.com/v1/objects/ad6aa39daf88864fcd84b231638e3dc28bde83f3/server.jar", + "16w43a": "https://piston-data.mojang.com/v1/objects/c5cc57bfd0a3462c2634a37c83877e91f25f020b/server.jar", + "16w44a": "https://piston-data.mojang.com/v1/objects/9f30eff92cc234034581f0a1ef40c6d76f6b3e69/server.jar", + "1.11-pre1": "https://piston-data.mojang.com/v1/objects/7e2884f11e3fb52ed1ad82376e3cada3aa95152e/server.jar", + "16w50a": "https://piston-data.mojang.com/v1/objects/d4d30a5433846d205974ace4cf34c9b294e0833f/server.jar", + "17w06a": "https://piston-data.mojang.com/v1/objects/37441cab126ee2a4f292c9bf488c9dd800cff841/server.jar", + "17w13a": "https://piston-data.mojang.com/v1/objects/d3806f89b9c90cbfb78919a3bcc010ad2e5d6ebb/server.jar", + "17w13b": "https://piston-data.mojang.com/v1/objects/7bd51f821ed09b6a1d3a9a9b2fc67b48f1d829c4/server.jar", + "17w14a": "https://piston-data.mojang.com/v1/objects/0530caf1d099fc730ca335a21bcf2fbb58c42c64/server.jar", + "17w15a": "https://piston-data.mojang.com/v1/objects/cc26caa34e1a53326ec374d229db07a0e2a7de17/server.jar", + "17w16a": "https://piston-data.mojang.com/v1/objects/47cfe5d44ccf6333b697da3e82e35bb3725e53d8/server.jar", + "17w16b": "https://piston-data.mojang.com/v1/objects/80601961e590046727791d6b18f51d840ea86e1c/server.jar", + "17w17a": "https://piston-data.mojang.com/v1/objects/3795d253cfef44f1f1467422b4399d1770484dc0/server.jar", + "17w17b": "https://piston-data.mojang.com/v1/objects/7cf669824e4c8340050adcc2125f1ec4cb84feac/server.jar", + "17w18a": "https://piston-data.mojang.com/v1/objects/b1f45946bd74f4e2cf1833324770809ebcd0b7b1/server.jar", + "17w18b": "https://piston-data.mojang.com/v1/objects/915c1833209d588ade3e064577700037093861da/server.jar", + "1.12-pre1": "https://piston-data.mojang.com/v1/objects/ebcafa3e1a3312500893087bf4bfb6c6f335ef0e/server.jar", + "1.12-pre2": "https://piston-data.mojang.com/v1/objects/e5fd1c4202f9b0855d9104b66ba4182d52e79c38/server.jar", + "1.12-pre3": "https://piston-data.mojang.com/v1/objects/c985b2083848efcc8d1658d6cda5644681035f80/server.jar", + "1.12-pre4": "https://piston-data.mojang.com/v1/objects/588bcccfff42acc2cb6f7c6470cd6bc8ba393668/server.jar", + "1.12-pre5": "https://piston-data.mojang.com/v1/objects/40e76b2836c92cd9e05af61bb64046c8650c088d/server.jar", + "1.12-pre6": "https://piston-data.mojang.com/v1/objects/9bc0e57debc61da93c0ea0d97849254db4f4e556/server.jar", + "1.12-pre7": "https://piston-data.mojang.com/v1/objects/a8d79598161edc5f67b606120ea9e62bcefcaaa7/server.jar", + "17w31a": "https://piston-data.mojang.com/v1/objects/00b83b98c91dbe3531342325f72654ef6d7be6eb/server.jar", + "1.12.1-pre1": "https://piston-data.mojang.com/v1/objects/b25c39f4658911169e184f00a24798f6463ded14/server.jar", + "1.12.2-pre1": "https://piston-data.mojang.com/v1/objects/b81c81335e68731d66ccddc21df0c06d7b9b46ab/server.jar", + "1.12.2-pre2": "https://piston-data.mojang.com/v1/objects/641adfb6a646fe12f1fb2715ed4e3167c7ff2f2b/server.jar", + "17w43a": "https://piston-data.mojang.com/v1/objects/6f6869d527140e5531e655bda10911efb65425bb/server.jar", + "17w43b": "https://piston-data.mojang.com/v1/objects/0447782ac5280f8f981c3998609928984213a4c7/server.jar", + "17w45a": "https://piston-data.mojang.com/v1/objects/471b2dfa12e4df234057159ce5ee8320da3c84c1/server.jar", + "17w45b": "https://piston-data.mojang.com/v1/objects/eec0c6c49b1066b648f39e1dcef8c76510a794dc/server.jar", + "17w46a": "https://piston-data.mojang.com/v1/objects/9127416e2341eb8fb7b63636c3ae39efefb2843b/server.jar", + "17w47a": "https://piston-data.mojang.com/v1/objects/0cec7f11d7bf9c36464b1815e5bbcb0afe6db019/server.jar", + "17w47b": "https://piston-data.mojang.com/v1/objects/9b4e7894906f0b379c7300cff0b3e68a4b9db662/server.jar", + "17w48a": "https://piston-data.mojang.com/v1/objects/e132a348243b824ba6f74569c8b1080b77104981/server.jar", + "17w49a": "https://piston-data.mojang.com/v1/objects/561fe37463ef30b4e1ab4c6b1da057d9e2b17801/server.jar", + "17w49b": "https://piston-data.mojang.com/v1/objects/caac50590085014355070ea6381baec0f58aa9f2/server.jar", + "17w50a": "https://piston-data.mojang.com/v1/objects/670c67a4dfbd1070a9be629124ddd8aac8d9b9d9/server.jar", + "18w01a": "https://piston-data.mojang.com/v1/objects/47a8d2bb4db5b5e3db6b7837c9f0fa17ea660448/server.jar", + "18w02a": "https://piston-data.mojang.com/v1/objects/950b737e9cefc9f91f286190166f062d6b0e0105/server.jar", + "18w03a": "https://piston-data.mojang.com/v1/objects/713a291a4da5cad056964c1fcda8c888e154eb73/server.jar", + "18w03b": "https://piston-data.mojang.com/v1/objects/ef8c70a7c9b88c02c64ea01d050614929b7152f6/server.jar", + "18w05a": "https://piston-data.mojang.com/v1/objects/a4029c808cef57bed3228a51dcb7f68edd018a77/server.jar", + "18w06a": "https://piston-data.mojang.com/v1/objects/4e47158fd42d966884a7ffb7440b35d86c038049/server.jar", + "18w07a": "https://piston-data.mojang.com/v1/objects/4e47158fd42d966884a7ffb7440b35d86c038049/server.jar", + "18w07b": "https://piston-data.mojang.com/v1/objects/669811c0df3fedef8a15f1b31c96df966b9aee79/server.jar", + "18w07c": "https://piston-data.mojang.com/v1/objects/52e141870c3c850811710f2ba07eb3e7e583ea92/server.jar", + "18w08a": "https://piston-data.mojang.com/v1/objects/09b2bc558d86878ce69f303ddbd62bf4489db068/server.jar", + "18w08b": "https://piston-data.mojang.com/v1/objects/cdfdcdd799087d9b66f04667f0717a11e28c29cc/server.jar", + "18w09a": "https://piston-data.mojang.com/v1/objects/57dd2fe4a2fdb6e846b978e77442465d2ea27f43/server.jar", + "18w10a": "https://piston-data.mojang.com/v1/objects/7bb1cfb4560d2e99551b22a631b6087d43817a45/server.jar", + "18w10b": "https://piston-data.mojang.com/v1/objects/b45d7194b91327c8fd2c1d0d5a738b80c9600562/server.jar", + "18w10c": "https://piston-data.mojang.com/v1/objects/7c2494311ab74f97623ebf6e2d5beba625a9d5fc/server.jar", + "18w10d": "https://piston-data.mojang.com/v1/objects/28727c7dfb62c56ac48153ab9a25d42115f85f94/server.jar", + "18w11a": "https://piston-data.mojang.com/v1/objects/4286b7cbc4709c8f61c93a77b42c70918376cac3/server.jar", + "18w14a": "https://piston-data.mojang.com/v1/objects/50b4ca8fe7853ae6757a163a80e67cb8437fb082/server.jar", + "18w14b": "https://piston-data.mojang.com/v1/objects/85d6445fc4596e6b69fb00f0d3e5462dfeeb933c/server.jar", + "18w15a": "https://piston-data.mojang.com/v1/objects/3f9534ab77a524593db7a20196e41ae36b23d69d/server.jar", + "18w16a": "https://piston-data.mojang.com/v1/objects/3f9534ab77a524593db7a20196e41ae36b23d69d/server.jar", + "18w19a": "https://piston-data.mojang.com/v1/objects/97ad982d57fb7b7cb9dc28ffd87c79538b1901f6/server.jar", + "18w19b": "https://piston-data.mojang.com/v1/objects/87edb914af0594016fab77eaaa9d25c7f1f1d132/server.jar", + "18w20a": "https://piston-data.mojang.com/v1/objects/108a051216637e0145f6b0e66182b48736595fc3/server.jar", + "18w20b": "https://piston-data.mojang.com/v1/objects/35304e17de5fbe503b10bad50192d14a38e5cec0/server.jar", + "18w20c": "https://piston-data.mojang.com/v1/objects/9e0ffb265e3771dc5c7b56f291b9c9d8f668f48b/server.jar", + "18w21a": "https://piston-data.mojang.com/v1/objects/2022a23da58dc55371b6a182fb1ba59742dc66a2/server.jar", + "18w21b": "https://piston-data.mojang.com/v1/objects/df8cc7cfa4c2d24f31f5997a102f1d6411f038d0/server.jar", + "18w22a": "https://piston-data.mojang.com/v1/objects/077225ee7bca03f521ed8df86fa4740b8e7a3cad/server.jar", + "18w22b": "https://piston-data.mojang.com/v1/objects/cc0b6a96e537528cdaab685c4eaeeaf8ed905b51/server.jar", + "18w22c": "https://piston-data.mojang.com/v1/objects/d66173b86e26e6835e36c63eb2828652186a4698/server.jar", + "1.13-pre1": "https://piston-data.mojang.com/v1/objects/e031e58e1d9e745877404530d39775bf9ffa9a56/server.jar", + "1.13-pre2": "https://piston-data.mojang.com/v1/objects/5b312060d457a1f75846afd3935ec3f140da3942/server.jar", + "1.13-pre3": "https://piston-data.mojang.com/v1/objects/5406f31cb5274ae48938851de697b32976ecb499/server.jar", + "1.13-pre4": "https://piston-data.mojang.com/v1/objects/d57007a8722ed645319666fc56b27690054d8363/server.jar", + "1.13-pre5": "https://piston-data.mojang.com/v1/objects/6d9ede222df5726059aba1b01f99c328bc16f1a5/server.jar", + "1.13-pre6": "https://piston-data.mojang.com/v1/objects/71a2f9a760f0cbcf09d1eae60eebe1ccbb7ea1db/server.jar", + "1.13-pre7": "https://piston-data.mojang.com/v1/objects/6cd8348fadedaa1de5851f449b995c835bb569eb/server.jar", + "1.13-pre8": "https://piston-data.mojang.com/v1/objects/b04f82ae0f3018c4c22a153184b385012c4d0814/server.jar", + "1.13-pre9": "https://piston-data.mojang.com/v1/objects/ee66f5cb1247f4340734a151db4f940bbe04f833/server.jar", + "1.13-pre10": "https://piston-data.mojang.com/v1/objects/2ffcae7a9489d515b0f733430923ef974dffd56b/server.jar", + "18w30a": "https://piston-data.mojang.com/v1/objects/4cfe675115064caad14712c3345660f4069a2e8b/server.jar", + "18w30b": "https://piston-data.mojang.com/v1/objects/373b2fb24db8ed21d25483a986e9eb7f945c5277/server.jar", + "18w31a": "https://piston-data.mojang.com/v1/objects/4646084899fb62a7b9afa6f453fae4e6e786e5a5/server.jar", + "18w32a": "https://piston-data.mojang.com/v1/objects/d36429ccdcaa73cb37b366d608024e3a6a5a20ab/server.jar", + "18w33a": "https://piston-data.mojang.com/v1/objects/e62f0a29e4ab5963488330f29c03ca2914b5b22b/server.jar", + "1.13.1-pre1": "https://piston-data.mojang.com/v1/objects/988fec4e71e5fa1fc29a50230de05a11973d62ab/server.jar", + "1.13.1-pre2": "https://piston-data.mojang.com/v1/objects/c2a4bcf3e244c46f13c39e31e7ef6030564fb6c2/server.jar", + "1.13.2-pre1": "https://piston-data.mojang.com/v1/objects/744df5d6872645a8f919459473e0e02a3571e6bb/server.jar", + "1.13.2-pre2": "https://piston-data.mojang.com/v1/objects/2f39df32f20196b5a6acad117f7d6b404b069c58/server.jar", + "18w43a": "https://piston-data.mojang.com/v1/objects/08ca3aaa7ff61d4ae06d5d63476724a1f32cb6b0/server.jar", + "18w43b": "https://piston-data.mojang.com/v1/objects/ed443be5ff6a304164612c545f0942fd99d53e13/server.jar", + "18w43c": "https://piston-data.mojang.com/v1/objects/b2dc0522b0802cbb8e81d1afd3e46be8819d3c1d/server.jar", + "18w44a": "https://piston-data.mojang.com/v1/objects/e70221701d85ad9ed8be35e042f4c8e52fb627ec/server.jar", + "18w45a": "https://piston-data.mojang.com/v1/objects/a004069d93ebfd9a6d93c57b66becac29f876d4c/server.jar", + "18w46a": "https://piston-data.mojang.com/v1/objects/6681e24d2dc9ba60a6e7d1fbbf25b2af70ff9d1c/server.jar", + "18w47a": "https://piston-data.mojang.com/v1/objects/7066873e9b86cfcd5b66c6a98d2587d95bf94adc/server.jar", + "18w47b": "https://piston-data.mojang.com/v1/objects/fa9d22eea98b62f6663f1aa8a25840e0993485e6/server.jar", + "18w48a": "https://piston-data.mojang.com/v1/objects/f0f04983d197388b05a4647f7a7cf8b5fbbac5d3/server.jar", + "18w48b": "https://piston-data.mojang.com/v1/objects/cfa41132beeb877a093e044aba591d9dae236c38/server.jar", + "18w49a": "https://piston-data.mojang.com/v1/objects/5b6eb767f6708d351e3d1009a44115bb033b854f/server.jar", + "18w50a": "https://piston-data.mojang.com/v1/objects/de0577900a9071758d7f1172dd283bdbe88b7431/server.jar", + "19w02a": "https://piston-data.mojang.com/v1/objects/f8078dd487483a917645f7a5561290e28bd875c4/server.jar", + "19w03a": "https://piston-data.mojang.com/v1/objects/1e80738a5360887bc93a46bdffb07699a45bf5a1/server.jar", + "19w03b": "https://piston-data.mojang.com/v1/objects/a3a358a7566debb17c5332fbc43eb8b84e000997/server.jar", + "19w03c": "https://piston-data.mojang.com/v1/objects/e9fdb18631fc4ff23b06b1e827fb653ac20532fe/server.jar", + "19w04a": "https://piston-data.mojang.com/v1/objects/261edfd76c32c9f675c12264b6fa03f670c3325c/server.jar", + "19w04b": "https://piston-data.mojang.com/v1/objects/7a5a3bbefcb4d27fd9ac30736eee06ae1e2c0991/server.jar", + "19w05a": "https://piston-data.mojang.com/v1/objects/521021450baf9b9b98b0a6d0cb60e97f306f4f57/server.jar", + "19w06a": "https://piston-data.mojang.com/v1/objects/20c069d373e77265aaeeedb733f7051e294325a3/server.jar", + "19w07a": "https://piston-data.mojang.com/v1/objects/d370db01d591576477c3efc940a42926f43bc98f/server.jar", + "19w08a": "https://piston-data.mojang.com/v1/objects/f337f8dfb765f152388d5038a6e0e8830782e5ed/server.jar", + "19w08b": "https://piston-data.mojang.com/v1/objects/f337f8dfb765f152388d5038a6e0e8830782e5ed/server.jar", + "19w09a": "https://piston-data.mojang.com/v1/objects/266d772f79eebe55de3856ae3fe675c0699cd1ca/server.jar", + "19w11a": "https://piston-data.mojang.com/v1/objects/388221ffa9e8e1576e07f9839eadd2ac7bd51cbb/server.jar", + "19w11b": "https://piston-data.mojang.com/v1/objects/1c453ba8ccaabc38d924e7c11fe73c65a1978a33/server.jar", + "19w12a": "https://piston-data.mojang.com/v1/objects/dc1a1dfef026d38dfc04b360653172f5428f86ef/server.jar", + "19w12b": "https://piston-data.mojang.com/v1/objects/37d6d9753b8eac2420e9deba132c38e00c8204c3/server.jar", + "19w13a": "https://piston-data.mojang.com/v1/objects/c63080e9349640fda5820bbe48cacc623c99c496/server.jar", + "19w13b": "https://piston-data.mojang.com/v1/objects/6d395392d8aac9bcde96322831042c77410b0a19/server.jar", + "3D Shareware v1.34": "https://piston-data.mojang.com/v1/objects/ffd306fc2aaa884755c5a6bf9fbd87aed26dd78f/server.jar", + "19w14a": "https://piston-data.mojang.com/v1/objects/a786a10223f5218967bfd42a06f4bee9e9563f56/server.jar", + "19w14b": "https://piston-data.mojang.com/v1/objects/719781c28dbcf7d0576e81fe5e77d75c1f18117f/server.jar", + "1.14 Pre-Release 1": "https://piston-data.mojang.com/v1/objects/6f27430bcd9b06d3dcb5d2966c75d5e491915c9c/server.jar", + "1.14 Pre-Release 2": "https://piston-data.mojang.com/v1/objects/353cc74b9aefd4675730449f50f5c0066063ac3f/server.jar", + "1.14 Pre-Release 3": "https://piston-data.mojang.com/v1/objects/6b747e1338e1aa058146032a659cf654c446552d/server.jar", + "1.14 Pre-Release 4": "https://piston-data.mojang.com/v1/objects/cf967a23b452ab474bf7bcb69fd029a5f8b84bba/server.jar", + "1.14 Pre-Release 5": "https://piston-data.mojang.com/v1/objects/5d550762b9c82ab4fe9f259c14fcf7bf7ed8017a/server.jar", + "1.14.1 Pre-Release 1": "https://piston-data.mojang.com/v1/objects/0bbed1aa2ef4bd4c0d6134461ac3e8eba1dc5f62/server.jar", + "1.14.1 Pre-Release 2": "https://piston-data.mojang.com/v1/objects/ea3a8bee27e1ca4185bf703fb4e414800f533fc9/server.jar", + "1.14.2 Pre-Release 1": "https://piston-data.mojang.com/v1/objects/1aad89bfe7a14bee70de0b07339a2f319771180f/server.jar", + "1.14.2 Pre-Release 2": "https://piston-data.mojang.com/v1/objects/a2cedc73237e999a5d408ecf0923a130d69d45a1/server.jar", + "1.14.2 Pre-Release 3": "https://piston-data.mojang.com/v1/objects/307fb7e6208bd843060b1844857dc5e1d555a1df/server.jar", + "1.14.2 Pre-Release 4": "https://piston-data.mojang.com/v1/objects/6bba54ad86fccc45cc68ba410e738d3b331cdadd/server.jar", + "1.14.3-pre1": "https://piston-data.mojang.com/v1/objects/966984c5d8b5c3604a8838f8fb5635b8b9cd73c7/server.jar", + "1.14.3-pre2": "https://piston-data.mojang.com/v1/objects/64caea4b63611111d775e4558341cb9718a6ff4f/server.jar", + "1.14.3-pre3": "https://piston-data.mojang.com/v1/objects/a46e49e1541cf24a75aabe2756514565de83634a/server.jar", + "1.14.3-pre4": "https://piston-data.mojang.com/v1/objects/d5397db937499277165abb27f8af04885be8b6b6/server.jar", + "1.14.4-pre1": "https://piston-data.mojang.com/v1/objects/774c5619679673ec772b0f01f363d0145a9d6b51/server.jar", + "1.14.4-pre2": "https://piston-data.mojang.com/v1/objects/a7023b92091ca5872d35b17c8aab1c6daa833a69/server.jar", + "1.14.4-pre3": "https://piston-data.mojang.com/v1/objects/b7ed47d4e600c6ead80f4c73c2e080625d07ef6e/server.jar", + "1.14.4-pre4": "https://piston-data.mojang.com/v1/objects/853bf851bda5862b7f68baf93ae86fb90571ceca/server.jar", + "1.14.4-pre5": "https://piston-data.mojang.com/v1/objects/f45379dfa2ecd946a2ed81c354225a4181261333/server.jar", + "1.14.4-pre6": "https://piston-data.mojang.com/v1/objects/d7b8f310278a5ea9efef03b4e441f12524253c5d/server.jar", + "1.14.4-pre7": "https://piston-data.mojang.com/v1/objects/98d1396495562dbb32828ef50bad7112c403c47e/server.jar", + "19w34a": "https://piston-data.mojang.com/v1/objects/288962c67d083e35d4313cf0eba8ad1e27173d17/server.jar", + "19w35a": "https://piston-data.mojang.com/v1/objects/e0bfc54b4b424c43b1fe5b833d68e35d031a481d/server.jar", + "19w36a": "https://piston-data.mojang.com/v1/objects/c042fd138ae280b01ce191937ca917666a15be38/server.jar", + "19w37a": "https://piston-data.mojang.com/v1/objects/e2c6923d9e06f6b98460f0f584567848a70bf71b/server.jar", + "19w38a": "https://piston-data.mojang.com/v1/objects/e40184002fa2e183de5fda0229d0709cfd6bfe8a/server.jar", + "19w38b": "https://piston-data.mojang.com/v1/objects/aff9049db1bcbd44d133ebfbd015dce49dd8383e/server.jar", + "19w39a": "https://piston-data.mojang.com/v1/objects/aff9049db1bcbd44d133ebfbd015dce49dd8383e/server.jar", + "19w40a": "https://piston-data.mojang.com/v1/objects/aff9049db1bcbd44d133ebfbd015dce49dd8383e/server.jar", + "19w41a": "https://piston-data.mojang.com/v1/objects/aff9049db1bcbd44d133ebfbd015dce49dd8383e/server.jar", + "19w42a": "https://piston-data.mojang.com/v1/objects/1f8673dee28ff3a1714e17780f6b91d5372fe440/server.jar", + "19w44a": "https://piston-data.mojang.com/v1/objects/0a68a89351325fbad9b432b3eb24ae944860350e/server.jar", + "19w45a": "https://piston-data.mojang.com/v1/objects/fa9e744ee6e5cccd4000e2269f8dff8ce96ce5a9/server.jar", + "19w45b": "https://piston-data.mojang.com/v1/objects/fa9e744ee6e5cccd4000e2269f8dff8ce96ce5a9/server.jar", + "19w46a": "https://piston-data.mojang.com/v1/objects/3544354ee91fee0439009e71c8e064ec8355600a/server.jar", + "19w46b": "https://piston-data.mojang.com/v1/objects/eded6ea3899b67478780576a3b92c6cac867b501/server.jar", + "1.15-pre1": "https://piston-data.mojang.com/v1/objects/332b3382108e5bdb0b23717082c9b97c54ffc8ad/server.jar", + "1.15-pre2": "https://piston-data.mojang.com/v1/objects/0f0c2e3c25693189374c8a63179e3018ebfdc1ba/server.jar", + "1.15-pre3": "https://piston-data.mojang.com/v1/objects/eedb663e70f49a5592b88197ea68b0f32fd9ce97/server.jar", + "1.15-pre4": "https://piston-data.mojang.com/v1/objects/8f9e23414a01d21e2cd313b2595b164ccfda56aa/server.jar", + "1.15-pre5": "https://piston-data.mojang.com/v1/objects/8f9e23414a01d21e2cd313b2595b164ccfda56aa/server.jar", + "1.15-pre6": "https://piston-data.mojang.com/v1/objects/8d5793fe302feb6c03d3c5e590ef940fc02f2864/server.jar", + "1.15-pre7": "https://piston-data.mojang.com/v1/objects/8d5793fe302feb6c03d3c5e590ef940fc02f2864/server.jar", + "1.15.1-pre1": "https://piston-data.mojang.com/v1/objects/289a247dd42928880769398b049d3890513f2917/server.jar", + "1.15.2-pre1": "https://piston-data.mojang.com/v1/objects/5db50a719dc40d63aa95c6bdc5b302e425f673f2/server.jar", + "1.15.2-pre2": "https://piston-data.mojang.com/v1/objects/f3eae938f3382ffeb8c3af150664d33864561110/server.jar", + "20w06a": "https://piston-data.mojang.com/v1/objects/9b74998642553efe0e4d1aa079dc737b3e4cdc13/server.jar", + "20w07a": "https://piston-data.mojang.com/v1/objects/3944965e1621a5ccbe99292479cc62e07bccd611/server.jar", + "20w08a": "https://piston-data.mojang.com/v1/objects/b46203f7cc23ec786710fdcf6f369935cf92dabb/server.jar", + "20w09a": "https://piston-data.mojang.com/v1/objects/6f1e5ae00b938bbe15560b7174be7a3b4c78c450/server.jar", + "20w10a": "https://piston-data.mojang.com/v1/objects/6f1e5ae00b938bbe15560b7174be7a3b4c78c450/server.jar", + "20w11a": "https://piston-data.mojang.com/v1/objects/6f1e5ae00b938bbe15560b7174be7a3b4c78c450/server.jar", + "20w12a": "https://piston-data.mojang.com/v1/objects/3d9657a172415a163e25096942f5a4d110b984a0/server.jar", + "20w13a": "https://piston-data.mojang.com/v1/objects/16f18c21286a3f566d3d0431d13aa133bebe6eff/server.jar", + "20w13b": "https://piston-data.mojang.com/v1/objects/0e00cff8df2532a1ae252e773552c2fd6c68de80/server.jar", + "20w14infinite": "https://piston-data.mojang.com/v1/objects/c0711cd9608d1af3d6f05ac423dd8f4199780225/server.jar", + "20w14a": "https://piston-data.mojang.com/v1/objects/affcf966ca903156070aa90b63417793a78b2165/server.jar", + "20w15a": "https://piston-data.mojang.com/v1/objects/64ca02e1e9fc7e60eac4aba788580b16eb12f71f/server.jar", + "20w16a": "https://piston-data.mojang.com/v1/objects/754bbd654d8e6bd90cd7a1464a9e68a0624505dd/server.jar", + "20w17a": "https://piston-data.mojang.com/v1/objects/0b7e36b084577fb26148c6341d590ac14606db21/server.jar", + "20w18a": "https://piston-data.mojang.com/v1/objects/4d84832bdc7f62aa96b0d5d5a73b1272e8c474b5/server.jar", + "20w19a": "https://piston-data.mojang.com/v1/objects/fbb3ad3e7b25e78723434434077995855141ff07/server.jar", + "20w20a": "https://piston-data.mojang.com/v1/objects/f06a943eb107494688b4447b97514af6d7311623/server.jar", + "20w20b": "https://piston-data.mojang.com/v1/objects/0393774fb1f9db8288a56dbbcf45022b71f7939f/server.jar", + "20w21a": "https://piston-data.mojang.com/v1/objects/03b8fa357937d0bdb6650ec8cc74506ec2fd91a7/server.jar", + "20w22a": "https://piston-data.mojang.com/v1/objects/c4a62eb36917aaa06dc8e20a2a35264d5fda123b/server.jar", + "1.16-pre1": "https://piston-data.mojang.com/v1/objects/c4a62eb36917aaa06dc8e20a2a35264d5fda123b/server.jar", + "1.16-pre2": "https://piston-data.mojang.com/v1/objects/8daeb71269eb164097d7d7ab1fa93fc93ab125c3/server.jar", + "1.16-pre3": "https://piston-data.mojang.com/v1/objects/0b5653b65bc494fa55349682cebf50abf0d72ad9/server.jar", + "1.16-pre4": "https://piston-data.mojang.com/v1/objects/018cdde89f8ff3831ce27c6c8dbf6831e99e0e75/server.jar", + "1.16-pre5": "https://piston-data.mojang.com/v1/objects/56081523bca4f7074f111d1e8a9fd0a86d072a2b/server.jar", + "1.16-pre6": "https://piston-data.mojang.com/v1/objects/8984939f42371a7e614fa48669e308c4cc9ba228/server.jar", + "1.16-pre7": "https://piston-data.mojang.com/v1/objects/577f7287642309a2a32e80be395329118dfddb3f/server.jar", + "1.16-pre8": "https://piston-data.mojang.com/v1/objects/d6a747371b200216653be9b4140cd2862eddbb0e/server.jar", + "1.16-rc1": "https://piston-data.mojang.com/v1/objects/7213e5ba8fe8d352141cf3dde907c26c43480092/server.jar", + "20w27a": "https://piston-data.mojang.com/v1/objects/40efae0a2412154f44a99f158752b8417b384f06/server.jar", + "20w28a": "https://piston-data.mojang.com/v1/objects/1e36d315d96c29d8d32aa8fecbfb8efa4243a746/server.jar", + "20w29a": "https://piston-data.mojang.com/v1/objects/ea9a65a38e000fe76b51fa36e923c09d5d8fa473/server.jar", + "20w30a": "https://piston-data.mojang.com/v1/objects/ea9a65a38e000fe76b51fa36e923c09d5d8fa473/server.jar", + "1.16.2-pre1": "https://piston-data.mojang.com/v1/objects/d4434bf4f2f0572a4eb54b3da1b1b3069a4e9ef2/server.jar", + "1.16.2-pre2": "https://piston-data.mojang.com/v1/objects/d2cae287324631b2b4bfa609dd01c63cd6d4b78d/server.jar", + "1.16.2-pre3": "https://piston-data.mojang.com/v1/objects/bd47f78f185a525388e446aa44975c147057ebbd/server.jar", + "1.16.2-rc1": "https://piston-data.mojang.com/v1/objects/203e18d79201b5e8c46019074b07e1c3b4c75f57/server.jar", + "1.16.2-rc2": "https://piston-data.mojang.com/v1/objects/45287d794fa2631b8da9b9002696ebe406fbed6b/server.jar", + "1.16.3-rc1": "https://piston-data.mojang.com/v1/objects/562bf3e75afea00875cff4a06165f93056646f32/server.jar", + "1.16.4-pre1": "https://piston-data.mojang.com/v1/objects/28eb6f8c4c05eec278e3e7f9f0379a16adbfb91d/server.jar", + "1.16.4-pre2": "https://piston-data.mojang.com/v1/objects/ceb412d94900167f519100736bc5709853b50b8c/server.jar", + "1.16.4-rc1": "https://piston-data.mojang.com/v1/objects/daf2d997bd6b1725b6d59b48f533a6804d43db33/server.jar", + "20w45a": "https://piston-data.mojang.com/v1/objects/043ec38297d0ec58abd6f636bc92f5664a8ccecb/server.jar", + "20w46a": "https://piston-data.mojang.com/v1/objects/373675677cc57b9294a187a4d0ecab6f340d4189/server.jar", + "20w48a": "https://piston-data.mojang.com/v1/objects/a14d24f89d5a4ec7521b91909caf4fee89c997f4/server.jar", + "20w49a": "https://piston-data.mojang.com/v1/objects/2fc0afe1fd31ca872761efbd2a7f635db234b359/server.jar", + "20w51a": "https://piston-data.mojang.com/v1/objects/fc87ef4c3cf1c815809249cc00ccade233b22cf5/server.jar", + "1.16.5-rc1": "https://piston-data.mojang.com/v1/objects/fc87ef4c3cf1c815809249cc00ccade233b22cf5/server.jar", + "21w03a": "https://piston-data.mojang.com/v1/objects/dbe81ef81e20e76b1458be822026887fef84c541/server.jar", + "21w05a": "https://piston-data.mojang.com/v1/objects/ff10b6f3bb37799e933ff0c2c300626b78ebfb1d/server.jar", + "21w05b": "https://piston-data.mojang.com/v1/objects/f92547a92214ab71a58834e7453ab29a6ab2d192/server.jar", + "21w06a": "https://piston-data.mojang.com/v1/objects/6290ba4b475fca4a74de990c7fd8eccffd9654dd/server.jar", + "21w07a": "https://piston-data.mojang.com/v1/objects/99c3a9744719d0d401af63bb684cf1eb5231a75c/server.jar", + "21w08a": "https://piston-data.mojang.com/v1/objects/d5e31633d884e190e046b8645f802541bec2a5e9/server.jar", + "21w08b": "https://piston-data.mojang.com/v1/objects/801d5e25869bab291077c773913cc2b490427314/server.jar", + "21w10a": "https://piston-data.mojang.com/v1/objects/5998d2c7c15fea04b2541efdcbec4c8cfe5df2a6/server.jar", + "21w11a": "https://piston-data.mojang.com/v1/objects/c828957ad249138129ccbc8749bfd14f01d96a4b/server.jar", + "21w13a": "https://piston-data.mojang.com/v1/objects/36d49b1a6d05f1deac293d477bfa2b4a1babb71c/server.jar", + "21w14a": "https://piston-data.mojang.com/v1/objects/0cb279c49ea3afda25c9d7257bef650e8dc17429/server.jar", + "21w15a": "https://piston-data.mojang.com/v1/objects/0a39422009a7aa01dd185043746c50dc909dc345/server.jar", + "21w16a": "https://piston-data.mojang.com/v1/objects/b8bacc67a9db84db59e2f97e9a9fba3a242480a8/server.jar", + "21w17a": "https://piston-data.mojang.com/v1/objects/ec995f939bb41a785f960985e73821c7044fc32e/server.jar", + "21w18a": "https://piston-data.mojang.com/v1/objects/0b18d883bd1132f761aa715d6a97e29e54a9b8b6/server.jar", + "21w19a": "https://piston-data.mojang.com/v1/objects/d0a9151432af384f5f2ca72e8e43422772158d0e/server.jar", + "21w20a": "https://piston-data.mojang.com/v1/objects/054b2065dd63c3e4227879046beae7acaeb7e8d3/server.jar", + "1.17-pre1": "https://piston-data.mojang.com/v1/objects/80a01a1178bcfb67b42636df3a9cdd275f3cc4d4/server.jar", + "1.17-pre2": "https://piston-data.mojang.com/v1/objects/d8756c67ce3b3fe20d0510afb3e22fa16310b2e6/server.jar", + "1.17-pre3": "https://piston-data.mojang.com/v1/objects/18abbb3f980fc9b05188535db45a67276ea41f90/server.jar", + "1.17-pre4": "https://piston-data.mojang.com/v1/objects/528f491660bc5dc94c0d7911345a97438e5c1d86/server.jar", + "1.17-pre5": "https://piston-data.mojang.com/v1/objects/31bb40019e8d6e64299abafd743f4d3e1a1a68b2/server.jar", + "1.17-rc1": "https://piston-data.mojang.com/v1/objects/31bb40019e8d6e64299abafd743f4d3e1a1a68b2/server.jar", + "1.17-rc2": "https://piston-data.mojang.com/v1/objects/1b6e0511e1e419fdcf5a81e53e36b5558032ee79/server.jar", + "1.17.1-pre1": "https://piston-data.mojang.com/v1/objects/42dfafdd31a1e6edfe59c79ea0e109fede1c8071/server.jar", + "1.17.1-pre2": "https://piston-data.mojang.com/v1/objects/e01e495461ecb834bb6a242bfea608af4f22b955/server.jar", + "1.17.1-pre3": "https://piston-data.mojang.com/v1/objects/04750b5adff60610a5ba2cd3aa8102f7086c9301/server.jar", + "1.17.1-rc1": "https://piston-data.mojang.com/v1/objects/b93cbcf6c65b92621d67b735e8610f7682f54694/server.jar", + "1.17.1-rc2": "https://piston-data.mojang.com/v1/objects/dd9ca1bdc855535cd7ce0565f02285ad4d6d1ae5/server.jar", + "21w37a": "https://piston-data.mojang.com/v1/objects/de695215d83f1f6ec5a19847f6178b84cfde7a26/server.jar", + "21w38a": "https://piston-data.mojang.com/v1/objects/1283dff678ee5efb8e52d2fc77ec9d840317c6ca/server.jar", + "21w39a": "https://piston-data.mojang.com/v1/objects/2b40ef4bf57b2040f7d9affb48c0131b228f954f/server.jar", + "21w40a": "https://piston-data.mojang.com/v1/objects/84496ec4beeeae34a448b99f3e3d890066f6807f/server.jar", + "21w41a": "https://piston-data.mojang.com/v1/objects/8eab49e576b21d6babfc60dcd14c68fac4926ab3/server.jar", + "21w42a": "https://piston-data.mojang.com/v1/objects/cf518e2c80fdaef443d68d50d1ac23a72a0a7d85/server.jar", + "21w43a": "https://piston-data.mojang.com/v1/objects/5c774a8b4e4407133eec7c4e1449c5f35974c589/server.jar", + "21w44a": "https://piston-data.mojang.com/v1/objects/ae583fd57a8c07f2d6fbadce1ce1e1379bf4b32d/server.jar", + "1.18-pre1": "https://piston-data.mojang.com/v1/objects/1c01e11c62ef7ce9b91324b570a1252d07544f18/server.jar", + "1.18-pre2": "https://piston-data.mojang.com/v1/objects/c203586f5d2c02b417f0e104b65a8e5e7625b2f8/server.jar", + "1.18-pre3": "https://piston-data.mojang.com/v1/objects/146d1809368fef552274122d9c380423c38068ab/server.jar", + "1.18-pre4": "https://piston-data.mojang.com/v1/objects/d17d3501f7f9d68793d5a505978ea5b87a208b43/server.jar", + "1.18-pre5": "https://piston-data.mojang.com/v1/objects/c29d03e9c6a21a3234a947e1025793c3cc40c13b/server.jar", + "1.18-pre6": "https://piston-data.mojang.com/v1/objects/97b1c53df11cb8b973f4b522c8f4963b7e31495e/server.jar", + "1.18-pre7": "https://piston-data.mojang.com/v1/objects/fe08544bb92ebe53070ec4a5f161ac19d8e9e4bb/server.jar", + "1.18-pre8": "https://piston-data.mojang.com/v1/objects/051efe8853d00db6bef7f19324da25a465782376/server.jar", + "1.18-rc1": "https://piston-data.mojang.com/v1/objects/81a2baf05f8f5bda41fac1542e7cc9d937bff41b/server.jar", + "1.18-rc2": "https://piston-data.mojang.com/v1/objects/96162b8d0af608bee2febe602bdb46942e85f6d8/server.jar", + "1.18-rc3": "https://piston-data.mojang.com/v1/objects/9a03d2c4ec2c737ce9d17a43d3774cdc0ea21030/server.jar", + "1.18-rc4": "https://piston-data.mojang.com/v1/objects/5889357fe058d867f6e27ee3f033286c430ec91e/server.jar", + "1.18.1-pre1": "https://piston-data.mojang.com/v1/objects/cd99e68b49c8a7db185d053518c6fb135cd04564/server.jar", + "1.18.1-rc1": "https://piston-data.mojang.com/v1/objects/fa98951fb1fa1ca04d8d6283e91e667d91e6410d/server.jar", + "1.18.1-rc2": "https://piston-data.mojang.com/v1/objects/653c704a89fe6437b363cff32ded037d5c0f6ec0/server.jar", + "1.18.1-rc3": "https://piston-data.mojang.com/v1/objects/29c43f3af18e66f8368a16ec89f8e54ecda71d85/server.jar", + "22w03a": "https://piston-data.mojang.com/v1/objects/686320be073916ae97b1ad78d22627809491dfc2/server.jar", + "22w05a": "https://piston-data.mojang.com/v1/objects/e6183efda3cea1871cb090b37ec7e0305d6ebbde/server.jar", + "22w06a": "https://piston-data.mojang.com/v1/objects/60c757a63f21877f8b053904ac76d04ff3cb76ef/server.jar", + "22w07a": "https://piston-data.mojang.com/v1/objects/8131d9e36640d40ce8464c58035f35475579e897/server.jar", + "1.18.2-pre1": "https://piston-data.mojang.com/v1/objects/c3e2734bafdb017efab854b01c66dd795722a332/server.jar", + "1.18.2-pre2": "https://piston-data.mojang.com/v1/objects/888cb380db39a115cfe978c00922d24536bdd2a5/server.jar", + "1.18.2-pre3": "https://piston-data.mojang.com/v1/objects/1c898afff0449eed08ad8036aaa4c652952035de/server.jar", + "1.18.2-rc1": "https://piston-data.mojang.com/v1/objects/2f52c69c90d63c024548ae5c5438ff3156ece6c2/server.jar", + "22w11a": "https://piston-data.mojang.com/v1/objects/a13b9678c60b0a84767e6cef0086c65cadac036e/server.jar", + "22w12a": "https://piston-data.mojang.com/v1/objects/f238cf129a0848effe5037d8aaefe3f1f350b689/server.jar", + "22w13a": "https://piston-data.mojang.com/v1/objects/7c8afca77bb9a73d31cdc70f2f68b4119d581455/server.jar", + "22w13oneblockatatime": "https://piston-data.mojang.com/v1/objects/5f48eea55c7fd1881d9c63835b15dfb5bbcd3a67/server.jar", + "22w14a": "https://piston-data.mojang.com/v1/objects/cf4f3a6492c0a84e2e852fe0ea714080923ab6ad/server.jar", + "22w15a": "https://piston-data.mojang.com/v1/objects/2760f745a00711bcc19bf78d6056019f69318d03/server.jar", + "22w16a": "https://piston-data.mojang.com/v1/objects/8ac6c67599bd30009fdc2f9d0174419b0bc19f8b/server.jar", + "22w16b": "https://piston-data.mojang.com/v1/objects/a54810e8b1a7a043fa54a462309d680ad67da479/server.jar", + "22w17a": "https://piston-data.mojang.com/v1/objects/9b4d5a87b48d7c3784fdfc9d6982543e8d9296df/server.jar", + "22w18a": "https://piston-data.mojang.com/v1/objects/d3259a8939a724c78ebbb995dfc31c1c364464e3/server.jar", + "22w19a": "https://piston-data.mojang.com/v1/objects/c354ac562b44fe5857535935125942ff89616cab/server.jar", + "1.19-pre1": "https://piston-data.mojang.com/v1/objects/1be90ec671e145e56b789de428b63ec43a2d9721/server.jar", + "1.19-pre2": "https://piston-data.mojang.com/v1/objects/6cc6cac49cd862ad9005816eb1ffc7dd4bd066dd/server.jar", + "1.19-pre3": "https://piston-data.mojang.com/v1/objects/0702387c3519cc23a5184893275d00c05abf056d/server.jar", + "1.19-pre4": "https://piston-data.mojang.com/v1/objects/a16331571233081eced58459a33254aa5a984a7d/server.jar", + "1.19-pre5": "https://piston-data.mojang.com/v1/objects/1ba1b6389f00fa40a10af047fd7a76a9c68dba72/server.jar", + "1.19-rc1": "https://piston-data.mojang.com/v1/objects/76ebdba03954e5a2185fb7a1d3a25096eb6bd195/server.jar", + "1.19-rc2": "https://piston-data.mojang.com/v1/objects/d3250b1e5e0e8762ec8ceae034d5f229965d00d3/server.jar", + "22w24a": "https://piston-data.mojang.com/v1/objects/fdad42550c3f0bcdc52680dcebd5b712d32bc5d7/server.jar", + "1.19.1-pre1": "https://piston-data.mojang.com/v1/objects/a4d30a572176e81e115d36ec71bd2e67798ed14e/server.jar", + "1.19.1-rc1": "https://piston-data.mojang.com/v1/objects/71a6d4c634de517ab1b6c2db8b743cbc831d9794/server.jar", + "1.19.1-pre2": "https://piston-data.mojang.com/v1/objects/17354c4963fb0176ad34595927ce62e55ea3daf4/server.jar", + "1.19.1-pre3": "https://piston-data.mojang.com/v1/objects/afbc14b0518843f189ed3ddd00f01b5881ef6513/server.jar", + "1.19.1-pre4": "https://piston-data.mojang.com/v1/objects/0f7f0c876024d0a84cb50547f72fe81dbfbfdb19/server.jar", + "1.19.1-pre5": "https://piston-data.mojang.com/v1/objects/33cdf9ceaaedebb0a71ca5f4d85d4e7198c09b8e/server.jar", + "1.19.1-pre6": "https://piston-data.mojang.com/v1/objects/2cad39169c1a505ffca1049b236a4ddaf62c617d/server.jar", + "1.19.1-rc2": "https://piston-data.mojang.com/v1/objects/5ec09b2700e5e83380a23cb18e66cfdaa931640b/server.jar", + "1.19.1-rc3": "https://piston-data.mojang.com/v1/objects/e7ff323e06ccb32083b7cd2472dce3b9056e2940/server.jar", + "1.19.2-rc1": "https://piston-data.mojang.com/v1/objects/ba8a776dc31a6093a07d3f4fbad1a8d680f8faf3/server.jar", + "1.19.2-rc2": "https://piston-data.mojang.com/v1/objects/93649d39350077f998296138964e4591d4571140/server.jar", + "22w42a": "https://piston-data.mojang.com/v1/objects/008996e2d1e0d49d7f1b477f69106a6d23c5c103/server.jar", + "22w43a": "https://piston-data.mojang.com/v1/objects/6718a5ac0b073644dbdfbd25f8218c68a1b390db/server.jar", + "22w44a": "https://piston-data.mojang.com/v1/objects/ed050b461b7dd347f383176ef03a71bacb844e69/server.jar", + "22w45a": "https://piston-data.mojang.com/v1/objects/d98f05500b14a8884b85e71be9fa1ef0d261029a/server.jar", + "22w46a": "https://piston-data.mojang.com/v1/objects/302ae4acba96e733fdbe144ebe2ba575b2bbf969/server.jar", + "1.19.3-pre1": "https://piston-data.mojang.com/v1/objects/046fee78cd174105cb9b958a8459c0405ab19959/server.jar", + "1.19.3-pre2": "https://piston-data.mojang.com/v1/objects/f8a18aa1e7b658de909470f69553c53d8662dfbe/server.jar", + "1.19.3-pre3": "https://piston-data.mojang.com/v1/objects/323175facb90c05b07dff84b4cff39fd9cab138a/server.jar", + "1.19.3-rc1": "https://piston-data.mojang.com/v1/objects/0c713920eff7358cb01c56979e8d732943bb893b/server.jar", + "1.19.3-rc2": "https://piston-data.mojang.com/v1/objects/138c813e22102e1a82a1be7b76080f40235183fe/server.jar", + "1.19.3-rc3": "https://piston-data.mojang.com/v1/objects/5f459ba58558d797229c819c0314bec84e774ecb/server.jar", + "23w03a": "https://piston-data.mojang.com/v1/objects/b033d57035b293a9eda548db0615c1c89c21ea28/server.jar", + "23w04a": "https://piston-data.mojang.com/v1/objects/2f31a8584ec1e70abd2d8b22d976feb52a6a3e31/server.jar", + "23w05a": "https://piston-data.mojang.com/v1/objects/98cfa3f8f9aef61e1298c9cfd62f6eeaf8abe206/server.jar", + "23w06a": "https://piston-data.mojang.com/v1/objects/daaed1fac98d17bd76f8fd43268f1c1b97230b59/server.jar", + "23w07a": "https://piston-data.mojang.com/v1/objects/b919e6e1683a4b6f37f2717c7841e88e306bdc94/server.jar", + "1.19.4-pre1": "https://piston-data.mojang.com/v1/objects/0bc471b96bb0edbc2f03e6cdc3ad981f7a4f5f8a/server.jar", + "1.19.4-pre2": "https://piston-data.mojang.com/v1/objects/d0b48d637834e879c16de26ffc11226d2d8e6772/server.jar", + "1.19.4-pre3": "https://piston-data.mojang.com/v1/objects/cedc29f7e4927bfe58c96e67495a73c7333c75cd/server.jar", + "1.19.4-pre4": "https://piston-data.mojang.com/v1/objects/711aa1f63c20650789e9740d66ff55c3e8e4f2ae/server.jar", + "1.19.4-rc1": "https://piston-data.mojang.com/v1/objects/c41c9653dc18634f52c010040177deabf9a878f2/server.jar", + "1.19.4-rc2": "https://piston-data.mojang.com/v1/objects/8abd7d9568385ade54cdd8bf77306e637482711b/server.jar", + "1.19.4-rc3": "https://piston-data.mojang.com/v1/objects/905778cc578c5a1757a9358a3feb5c19a0178fec/server.jar", + "23w12a": "https://piston-data.mojang.com/v1/objects/92fdef90109e534d47e378124ab86e2d6d7b3a42/server.jar", + "23w13a": "https://piston-data.mojang.com/v1/objects/701767d4d07aad992e3e2875ae5d1485cebf66e0/server.jar", + "23w13a_or_b": "https://piston-data.mojang.com/v1/objects/6241fc14ce7a659f371683a72aa24c155f60cce1/server.jar", + "23w14a": "https://piston-data.mojang.com/v1/objects/cb67d34c44013759bca77085ae42e3a7b37f265d/server.jar", + "23w16a": "https://piston-data.mojang.com/v1/objects/4a8487f877eb4f3506978fb85faf41a08b570398/server.jar", + "23w17a": "https://piston-data.mojang.com/v1/objects/96e1b9db0f3d90309db34e8ce4fd39b52f6ddaa0/server.jar", + "23w18a": "https://piston-data.mojang.com/v1/objects/240177c763b6009ea81aaf0ef14a73822320856d/server.jar", + "1.20-pre1": "https://piston-data.mojang.com/v1/objects/95ac4bf3d2f4ae57687493f5232d3f58334b85d2/server.jar", + "1.20-pre2": "https://piston-data.mojang.com/v1/objects/fce02f0ed50b4722f8ec58acef06275b91cde08d/server.jar", + "1.20-pre3": "https://piston-data.mojang.com/v1/objects/6adffc7f05724f22b1644ecc191899e4beb33443/server.jar", + "1.20-pre4": "https://piston-data.mojang.com/v1/objects/04b889e29aeffc23d2a3ebdd7e728184d9441e02/server.jar", + "1.20-pre5": "https://piston-data.mojang.com/v1/objects/2b41aed1e7c7fecf11ca15bad03b0fa95eb4fbd9/server.jar", + "1.20-pre6": "https://piston-data.mojang.com/v1/objects/c737b7411fc0b60426a9feca83d09d63f4a86f27/server.jar", + "1.20-pre7": "https://piston-data.mojang.com/v1/objects/ed6ddd61aeb1f529ef626fae9bcb0a5f51491f71/server.jar", + "1.20-rc1": "https://piston-data.mojang.com/v1/objects/0d9315f92842e35fcb6fddb10db3a13675a1ad04/server.jar", + "1.20.1-rc1": "https://piston-data.mojang.com/v1/objects/6890ac51068a05e3fcc4158478247e5a5e47bcac/server.jar", + "23w31a": "https://piston-data.mojang.com/v1/objects/11ef2ae139b0badda80a1ea07c2dd0cf9034a32f/server.jar", + "23w32a": "https://piston-data.mojang.com/v1/objects/bfe1a408d8d809b206369fceab0e8a883226d0a6/server.jar", + "23w33a": "https://piston-data.mojang.com/v1/objects/0254dde460b23861840cff6e80fc7fdbbccad88e/server.jar", + "23w35a": "https://piston-data.mojang.com/v1/objects/6a2ac9eecb377f4894b84de711973edc751d0607/server.jar", + "1.20.2-pre1": "https://piston-data.mojang.com/v1/objects/7fa1c9c59238ee98696da880d361d96c728dd9ea/server.jar", + "1.20.2-pre2": "https://piston-data.mojang.com/v1/objects/cf5d9b2461898afd589274349989be704084a8dd/server.jar", + "1.20.2-pre3": "https://piston-data.mojang.com/v1/objects/3d2eecdda5f6c7260d73aa5c2e5ce1a42e0f24e4/server.jar", + "1.20.2-pre4": "https://piston-data.mojang.com/v1/objects/9f1b8f9918d5d8d59781886f33e5b7b2053d0486/server.jar", + "1.20.2-rc1": "https://piston-data.mojang.com/v1/objects/70dad7e61afc2e255e73842760ef9461a00c852d/server.jar", + "1.20.2-rc2": "https://piston-data.mojang.com/v1/objects/ef01ddc7ee3fd517f55f34259c411323673b6347/server.jar", + "23w40a": "https://piston-data.mojang.com/v1/objects/0f51a81705f4694b92f5273ffa2c52c45f27b7f8/server.jar", + "23w41a": "https://piston-data.mojang.com/v1/objects/e3e4c46324ac42b1789f7ff6e895ae3c843a9819/server.jar", + "23w42a": "https://piston-data.mojang.com/v1/objects/b5f423ba1c4191d133c0284a2b1b36da46f8b5f8/server.jar", + "23w43a": "https://piston-data.mojang.com/v1/objects/135f89e56c2d83d9ef0f7915f0cdf1047737d51a/server.jar", + "23w43b": "https://piston-data.mojang.com/v1/objects/e7f9a4ca5ad3cadee399aa90f1d37f3ee94f292c/server.jar", + "23w44a": "https://piston-data.mojang.com/v1/objects/009b4831cdda78d8f9b235265e45d0bf14a920da/server.jar", + "23w45a": "https://piston-data.mojang.com/v1/objects/9c2b37701bf77ae22df4c32fd6dd1614049ce994/server.jar", + "23w46a": "https://piston-data.mojang.com/v1/objects/2f30bbf9229e2dcbaf148eb9750df1d19ffa6d19/server.jar", + "1.20.3-pre1": "https://piston-data.mojang.com/v1/objects/e5db7e4884f55c4dd986ca7200145759169e0045/server.jar", + "1.20.3-pre2": "https://piston-data.mojang.com/v1/objects/5a76da0ae88eee28ab4c0fa2ffabb837a4572398/server.jar", + "1.20.3-pre3": "https://piston-data.mojang.com/v1/objects/3802cf61288841f29f0af0d7c73ab58094be34cd/server.jar", + "1.20.3-pre4": "https://piston-data.mojang.com/v1/objects/1567e8a24c547ac3a95ce41d24024a94e9c7299c/server.jar", + "1.20.3-rc1": "https://piston-data.mojang.com/v1/objects/64cab4e87f8c2cad74d8bfc23df2cd193b4a615e/server.jar", + "1.20.4-rc1": "https://piston-data.mojang.com/v1/objects/589a0babd82ff5a086e4085aa8a1dc46fecc222d/server.jar", + "23w51a": "https://piston-data.mojang.com/v1/objects/e44e1d8c34f3020b0485ddd1436e91134b7de9a3/server.jar", + "23w51b": "https://piston-data.mojang.com/v1/objects/d443ec98f3f3ee2dc92e0788d6d83d74844feb4f/server.jar", + "24w03a": "https://piston-data.mojang.com/v1/objects/730a3ef2f99f6a822aa504bfee2eb5372d826293/server.jar", + "24w03b": "https://piston-data.mojang.com/v1/objects/5b9a529dc40d8394cbd6203a8ebe66c8e2f86fd4/server.jar", + "24w04a": "https://piston-data.mojang.com/v1/objects/d9f13751240a2fe4e85be1c839d9a4de1413c251/server.jar", + "24w05a": "https://piston-data.mojang.com/v1/objects/cc0f01e6406fa8a2b50c3c06edef74e7a7bf74de/server.jar", + "24w05b": "https://piston-data.mojang.com/v1/objects/189526bf25c06f7c0071aa637bc5f3668a6457d4/server.jar", + "24w06a": "https://piston-data.mojang.com/v1/objects/703cffc390ff71b7900d7a4356f48bc2108b448e/server.jar", + "24w07a": "https://piston-data.mojang.com/v1/objects/94acd52e9b9392e21a06231bdc4f8f0cd6ccb2af/server.jar", + "24w09a": "https://piston-data.mojang.com/v1/objects/7c70922198a2d18e0252c315b55623b822b4e910/server.jar", + "24w10a": "https://piston-data.mojang.com/v1/objects/9f8e96ebe4db0323653111b28df63f66395cb19d/server.jar", + "24w11a": "https://piston-data.mojang.com/v1/objects/00cab0438130dc3e6ae91f53387bb96ae7986d31/server.jar", + "24w12a": "https://piston-data.mojang.com/v1/objects/6f036460d361ce1e645bba365a72be2eed35ec01/server.jar", + "24w13a": "https://piston-data.mojang.com/v1/objects/2fd2113b7b81cc78cb4a76939a6c11840d57036d/server.jar", + "24w14potato": "https://piston-data.mojang.com/v1/objects/2d29eee4f5a71f323d20b36d623e2ec21dab74f7/server.jar", + "24w14a": "https://piston-data.mojang.com/v1/objects/960cb0e5c794b02abdbcdbdc15b4de058b222118/server.jar", + "1.20.5-pre1": "https://piston-data.mojang.com/v1/objects/018c4aa3b1dcd5ac4487456de062072de750f729/server.jar", + "1.20.5-pre2": "https://piston-data.mojang.com/v1/objects/c794b404663758cba43c67d097a25c5d4eb84a37/server.jar", + "1.20.5-pre3": "https://piston-data.mojang.com/v1/objects/5ac067ccc569ef9e2177cf4331c8e82d3e072692/server.jar", + "1.20.5-pre4": "https://piston-data.mojang.com/v1/objects/2793397cf42243a69fca37ff0887e8560a36c583/server.jar", + "1.20.5-rc1": "https://piston-data.mojang.com/v1/objects/ec45f58d589dc1b00b25c6798dd10d2af70867e5/server.jar", + "1.20.5-rc2": "https://piston-data.mojang.com/v1/objects/921814646156d838286dc0634a0031f042c6e0d2/server.jar", + "1.20.5-rc3": "https://piston-data.mojang.com/v1/objects/7d735a8eda6797ed196141b76e96b46546bde091/server.jar", + "1.20.6-rc1": "https://piston-data.mojang.com/v1/objects/a9b9c22721ec3ac516627f30554f21ed7c23efe5/server.jar", + "24w18a": "https://piston-data.mojang.com/v1/objects/22618c686c86be630601e5d9fcf581674105c899/server.jar", + "24w19a": "https://piston-data.mojang.com/v1/objects/8088cca48fece804d29b368ab5bbcc27a540456c/server.jar", + "24w19b": "https://piston-data.mojang.com/v1/objects/447bfe84875399d44d383de7f534e1cc10bae9a5/server.jar", + "24w20a": "https://piston-data.mojang.com/v1/objects/e3b1bcc2d7a09b6f1acfef7090ee64409feb3b94/server.jar", + "24w21a": "https://piston-data.mojang.com/v1/objects/6ba7192e60bedb3ff02db3c57b75f7ea56c63242/server.jar", + "24w21b": "https://piston-data.mojang.com/v1/objects/743d74805b64f83052fe449993f42182f76b129e/server.jar", + "1.21-pre1": "https://piston-data.mojang.com/v1/objects/57e59ee5d8bc6ce664a7d76de45f8df9c110381f/server.jar", + "1.21-pre2": "https://piston-data.mojang.com/v1/objects/3a8da3a1afcfb09d701fa17e405d09cd0c635748/server.jar", + "1.21-pre3": "https://piston-data.mojang.com/v1/objects/96266e18a95faa1c785ac852315e886d0e8bb174/server.jar", + "1.21-pre4": "https://piston-data.mojang.com/v1/objects/14b1a86d9fcfc82c013e82910e8209617c3a721e/server.jar", + "1.21-rc1": "https://piston-data.mojang.com/v1/objects/902101d2fb0f968b9c0ddb8b8cff9afef23f72c7/server.jar" } # CLS -def limpiar_consola(): - if os.name == 'nt': # En Windows - On Windows - os.system('cls') - else: # En sistemas Unix-like - On Unix-like systems - os.system('clear') +def cls(): + os.system('cls') -# WINDOW TITLE +# CHANGE WINDOW TITLE def window_title(title): - if sys.platform.startswith('win32'): # En Windows - On Windows - ctypes.windll.kernel32.SetConsoleTitleW(title) - elif sys.platform.startswith('linux') or sys.platform.startswith('darwin'): # En sistemas Unix-like - On Unix-like systems - sys.stdout.write(f"\x1b]2;{title}\x07") + os.system(f'title {title}') # BRING WINDOW TO FRONT def front(): - if os.name == 'nt': # For Windows - # Get the handle of the console window - h_wnd = ctypes.windll.kernel32.GetConsoleWindow() - - # Bring the console window to the foreground - ctypes.windll.user32.SetForegroundWindow(h_wnd) - else: # For Linux/OS X - # Get the PID of the current process - pid = os.getpid() - - # Use wmctrl to bring the window with the given PID to the front - subprocess.call(['wmctrl', '-ia', str(pid)]) + os.system('echo ShowConsole') # ENGLISH def eng(): @@ -148,7 +759,7 @@ def eng(): # SERVER STARTUP def ram(): global servername - limpiar_consola() + cls() sservers = {} if os.path.exists(SAVED_SERVERS): with open(SAVED_SERVERS, 'r') as file: @@ -158,7 +769,7 @@ def ram(): key, value = line.split('<[=]>') sservers[key.strip()] = value.strip() if sservers: - limpiar_consola() + cls() print('Server Launcher for Minecraft\n-------------------------------------\n\n"Your Servers" List\n') server_keys = list(sservers.keys()) for i, key in enumerate(server_keys, start=1): @@ -174,7 +785,7 @@ def ram(): front() servname = os.path.basename(newserv) if newserv == "" or servname == "": - limpiar_consola() + cls() print('Server Launcher for Minecraft\n-------------------------------------\n\nYou must select a folder to save it in "Your Servers" List.') time.sleep(2.5) ram() @@ -186,13 +797,13 @@ def ram(): lines = file.readlines() if servstring not in lines: file.write(servstring) - limpiar_consola() + cls() print(f'Server Launcher for Minecraft\n-------------------------------------\n\nThe server "{servname}" has been saved.') time.sleep(1.5) ram() elif servsel.lower() == "d": def servdel(): - limpiar_consola() + cls() print("Server Launcher for Minecraft\n-------------------------------------\n\nSelect the server to delete from the list.\n") for i, key in enumerate(server_keys, start=1): print(f"({i}) {key}") @@ -224,7 +835,7 @@ def servdel(): for line in lines: if line != servestring: file.write(line) - limpiar_consola() + cls() print(f'Server Launcher for Minecraft\n-------------------------------------\n\nThe server "{servsel}" has been deleted from the list.') time.sleep(1.5) ram() @@ -233,7 +844,7 @@ def servdel(): servdel() elif servsel.lower() == "c": def lisclear(): - limpiar_consola() + cls() yess = colored("Yes","green") noo = colored("No","red") clearconfirm = input(f'Server Launcher for Minecraft\n-------------------------------------\n\nAre you sure you want to clear the "Your Servers" List?\n\n(1) {yess}\n(2) {noo}\n\nSelect one of the options= ') @@ -250,7 +861,7 @@ def lisclear(): os.makedirs(CONFIG_PATH, exist_ok=True) with open(SAVED_SERVERS, 'w') as file: file.write("# Server Launcher for Minecraft\n# Saved servers\n") - limpiar_consola() + cls() print('Server Launcher for Minecraft\n-------------------------------------\n\nThe "Your Servers" List has been cleared.') time.sleep(1.5) ram() @@ -282,7 +893,7 @@ def lisclear(): os.makedirs(CONFIG_PATH, exist_ok=True) with open(SAVED_SERVERS, 'w') as file: file.write("# Server Launcher for Minecraft\n# Saved servers\n") - limpiar_consola() + cls() adds = colored("Add a Server","cyan") saveconfirm = input(f"Server Launcher for Minecraft\n-------------------------------------\n\nThere are no saved servers.\n\n(1) {adds}\n(2) Return to main menu\n\nSelect one of the options= ") try: @@ -299,7 +910,7 @@ def lisclear(): front() servname = os.path.basename(newserv) if newserv == "" or servname == "": - limpiar_consola() + cls() print('Server Launcher for Minecraft\n-------------------------------------\n\nYou must select a folder to save it in "Your Servers" List.') time.sleep(2.5) ram() @@ -311,7 +922,7 @@ def lisclear(): lines = file.readlines() if servstring not in lines: file.write(servstring) - limpiar_consola() + cls() print(f'Server Launcher for Minecraft\n-------------------------------------\n\nThe server "{servname}" has been saved.') time.sleep(1.5) ram() @@ -325,13 +936,13 @@ def lisclear(): os.makedirs(CONFIG_PATH, exist_ok=True) with open(SAVED_SERVERS, 'w') as file: file.write("# Server Launcher for Minecraft\n# Saved servers\n") - limpiar_consola() + cls() input('Server Launcher for Minecraft\n-------------------------------------\n\nThere are no saved servers.\n\nPress ENTER to select a folder with a Server and add it to "Your Servers" list.') newserv = filedialog.askdirectory() front() servname = os.path.basename(newserv) if newserv == "" or servname == "": - limpiar_consola() + cls() print('Server Launcher for Minecraft\n-------------------------------------\n\nYou must select a folder to save it in "Your Servers" List.') time.sleep(2.5) ram() @@ -342,7 +953,7 @@ def lisclear(): lines = file.readlines() if servstring not in lines: file.write(servstring) - limpiar_consola() + cls() print(f'Server Launcher for Minecraft\n-------------------------------------\n\nThe server "{servname}" has been saved.') time.sleep(1.5) ram() @@ -350,7 +961,7 @@ def lisclear(): # CONFIG def config(): global nameserver - limpiar_consola() + cls() props = "server.properties" if os.path.exists(props): global properties @@ -376,7 +987,7 @@ def config(): pvp = colored("ENABLE","green") elif properties["pvp"] == "true": pvp = colored("DISABLE","red") - limpiar_consola() + cls() confsel = input(f'Server Launcher for Minecraft\n-------------------------------------\n\nLets manage "{nameserver}"!\n\n(1) {online} online mode\n(2) {hard} hardcore mode\n(3) {pvp} PvP\n(4) Change gamemode\n(5) Change difficulty\n(6) Change max players limit\n(7) Back\n(8) Return to main menu\n\nSelect one of the options= ') if properties["online-mode"] == "false": online = "ENABLE" @@ -412,7 +1023,7 @@ def config(): for key, value in properties.items(): file.write(f'{key}={value}\n') online = colored("DISABLED","red") - limpiar_consola() + cls() print(f"Server Launcher for Minecraft\n-------------------------------------\n\nOnline mode has been {online}.") time.sleep(1.5) config() @@ -429,7 +1040,7 @@ def config(): for key, value in properties.items(): file.write(f'{key}={value}\n') hard = colored("DISABLED","red") - limpiar_consola() + cls() print(f"Server Launcher for Minecraft\n-------------------------------------\n\nHardcore mode has been {hard}.") time.sleep(1.5) config() @@ -446,7 +1057,7 @@ def config(): for key, value in properties.items(): file.write(f'{key}={value}\n') pvp = colored("DISABLED","red") - limpiar_consola() + cls() print(f"Server Launcher for Minecraft\n-------------------------------------\n\nPvP has been {pvp}.") time.sleep(1.5) config() @@ -466,7 +1077,7 @@ def juego(): creat = colored("CREATIVE","yellow") avent = colored("ADVENTURE","yellow") espect = colored("SPECTATOR","yellow") - limpiar_consola() + cls() modosel = input(f"Server Launcher for Minecraft\n-------------------------------------\n\nThe current game mode is {modo}.\n\n(1) Change to {superv} gamemode\n(2) Change to {creat} gamemode\n(3) Change to {avent} gamemode\n(4) Change to {espect} gamemode\n(5) Go back\n(6) Return to main menu\n\nSelect one of the options= ") try: if any(char in "0123456789+-*/" for char in modosel): @@ -482,7 +1093,7 @@ def juego(): with open('server.properties', 'w') as file: for key, value in properties.items(): file.write(f'{key}={value}\n') - limpiar_consola() + cls() print(f"Server Launcher for Minecraft\n-------------------------------------\n\nGamemode has been set to {superv}.") time.sleep(1.5) juego() @@ -491,7 +1102,7 @@ def juego(): with open('server.properties', 'w') as file: for key, value in properties.items(): file.write(f'{key}={value}\n') - limpiar_consola() + cls() print(f"Server Launcher for Minecraft\n-------------------------------------\n\nGamemode has been set to {creat}.") time.sleep(1.5) juego() @@ -500,7 +1111,7 @@ def juego(): with open('server.properties', 'w') as file: for key, value in properties.items(): file.write(f'{key}={value}\n') - limpiar_consola() + cls() print(f"Server Launcher for Minecraft\n-------------------------------------\n\nGamemode has been set to {avent}.") time.sleep(1.5) juego() @@ -509,7 +1120,7 @@ def juego(): with open('server.properties', 'w') as file: for key, value in properties.items(): file.write(f'{key}={value}\n') - limpiar_consola() + cls() print(f"Server Launcher for Minecraft\n-------------------------------------\n\nGamemode has been set to {espect}.") time.sleep(1.5) juego() @@ -538,7 +1149,7 @@ def difconf(): facil = colored("EASY","yellow") normal = colored("NORMAL","yellow") dificil = colored("HARD","yellow") - limpiar_consola() + cls() difsel = input(f"Server Launcher for Minecraft\n-------------------------------------\n\nThe current difficulty is {dificultad}.\n\n(1) Change difficulty to {pacif}\n(2) Change difficulty to {facil}\n(3) Change difficulty to {normal}\n(4) Change difficulty to {dificil}\n(5) Go back\n(6) Return to main menu\n\nSelect one of the options= ") try: if any(char in "0123456789+-*/" for char in difsel): @@ -554,7 +1165,7 @@ def difconf(): with open('server.properties', 'w') as file: for key, value in properties.items(): file.write(f'{key}={value}\n') - limpiar_consola() + cls() print(f"Server Launcher for Minecraft\n-------------------------------------\n\nDifficulty has been set to {pacif}.") time.sleep(1.5) difconf() @@ -563,7 +1174,7 @@ def difconf(): with open('server.properties', 'w') as file: for key, value in properties.items(): file.write(f'{key}={value}\n') - limpiar_consola() + cls() print(f"Server Launcher for Minecraft\n-------------------------------------\n\nDifficulty has been set to {facil}.") time.sleep(1.5) difconf() @@ -572,7 +1183,7 @@ def difconf(): with open('server.properties', 'w') as file: for key, value in properties.items(): file.write(f'{key}={value}\n') - limpiar_consola() + cls() print(f"Server Launcher for Minecraft\n-------------------------------------\n\nDifficulty has been set to {normal}.") time.sleep(1.5) difconf() @@ -581,7 +1192,7 @@ def difconf(): with open('server.properties', 'w') as file: for key, value in properties.items(): file.write(f'{key}={value}\n') - limpiar_consola() + cls() print(f"Server Launcher for Minecraft\n-------------------------------------\n\nDifficulty has been set to {dificil}.") time.sleep(1.5) difconf() @@ -598,7 +1209,7 @@ def difconf(): def playct(): global properties players = colored(properties["max-players"],"cyan") - limpiar_consola() + cls() newpl = input(f"Server Launcher for Minecraft\n-------------------------------------\n\nThe current player limit is a maximum of {players}.\n\n(N) Go back\n(M) Return to main menu\n\nSelect one of the options or enter the new player limit= ").replace(" ", "") try: if newpl.lower() == "n": @@ -615,7 +1226,7 @@ def playct(): entero = newpl entero = int(entero) if entero <= 0 or entero > 100000: - limpiar_consola() + cls() print(f"Server Launcher for Minecraft\n-------------------------------------\n\nEnter a valid number between 1 and 100,000.") time.sleep(1.5) playct() @@ -625,7 +1236,7 @@ def playct(): for key, value in properties.items(): file.write(f'{key}={value}\n') entero = colored(str(entero),"yellow") - limpiar_consola() + cls() print(f"Server Launcher for Minecraft\n-------------------------------------\n\nThe maximum player limit is now {entero}.") time.sleep(1.5) playct() @@ -641,7 +1252,7 @@ def playct(): except (ValueError, SyntaxError, IndexError, ZeroDivisionError): config() else: - limpiar_consola() + cls() input("Server Launcher for Minecraft\n-------------------------------------\n\nThe server configuration files do not exist yet or are not available.\nYou must start the server properly at least once before you can configure it.\n\nPress ENTER to continue.") run_server() def run_server(): @@ -665,7 +1276,7 @@ def run_server(): vjava = "M" gbormb = colored("GIGABYTES","yellow") nameserver = servername - limpiar_consola() + cls() gbs = 0 rammount = input(f'Server Launcher for Minecraft\n-------------------------------------\n\nYou are about to start the Server "{nameserver}"\n\n(M) Manage Server\n(C) Use RAM in {gbormb}\n(B) Back\n(N) Return to main menu\n\nSelect one of the options or enter the {valor1} of RAM to assing to the server= ').replace(" ", "") try: @@ -673,13 +1284,13 @@ def run_server(): config() if rammount.lower() == "c": if valor == "GB": - limpiar_consola() + cls() print(f"Server Launcher for Minecraft\n-------------------------------------\n\nNow the RAM is on {gbormb}.") time.sleep(1.5) valor = "MB" run_server() elif valor == "MB": - limpiar_consola() + cls() print(f"Server Launcher for Minecraft\n-------------------------------------\n\nNow the RAM is on {gbormb}.") time.sleep(1.5) valor = "GB" @@ -698,12 +1309,12 @@ def run_server(): gbs = rammount gbs = int(gbs) if valor == "GB" and (gbs <= 0 or gbs > 75): - limpiar_consola() + cls() print(f"Server Launcher for Minecraft\n-------------------------------------\n\nEnter a valid amount between 1 and 75 Gigabytes.") time.sleep(1.5) run_server() elif valor == "MB" and (gbs <= 511 or gbs > 76800): - limpiar_consola() + cls() print(f"Server Launcher for Minecraft\n-------------------------------------\n\nEnter a valid amount between 512 and 76,800 Megabytes.") time.sleep(1.5) run_server() @@ -711,7 +1322,7 @@ def run_server(): eula = "eula.txt" with open(eula, "w") as reemplazo: reemplazo.write("eula=true") - limpiar_consola() + cls() print(f"Server Launcher for Minecraft\n-------------------------------------\n\nStarting the server with {gbs}{valor} of RAM.\n") comando_java = f"java -Xmx{gbs}{vjava} -Xms{gbs}{vjava} -jar server.jar nogui" subprocess.run(comando_java, shell=True) @@ -719,14 +1330,14 @@ def run_server(): fecha_cerrado = str(fyh_sistema.strftime("%d/%m/%Y")) hora_cerrado = str(fyh_sistema.strftime("%H:%M:%S")) input("\nPress ENTER to continue.") - limpiar_consola() + cls() input(f"Server Launcher for Minecraft\n-------------------------------------\n\nThe server has closed on {fecha_cerrado} at {hora_cerrado}.\n\nYou can check the console log in the 'logs' folder inside your Server's main folder.\n\nPress ENTER to continue.") ram() except (ValueError, SyntaxError, IndexError, ZeroDivisionError): run_server() run_server() else: - limpiar_consola() + cls() print('Server Launcher for Minecraft\n-------------------------------------\n\n"server.jar" not found in this folder.\n\nAre you sure this is a Server?') time.sleep(2.5) ram() @@ -735,7 +1346,7 @@ def run_server(): def installmenu(): global newserver global foldname - limpiar_consola() + cls() inconfirm = input("Server Launcher for Minecraft\n-------------------------------------\n\nFirst, lets select a folder to save your New Server's files.\n\n(1) Select folder for the new Server\n(2) Cancel\n\nSelect one of the options= ").replace(" ", "") try: if any(char in "0123456789+-*/" for char in inconfirm): @@ -754,7 +1365,7 @@ def reselect(): front() foldname = colored(os.path.basename(newserver), "green") if newserver == "" or foldname == "": - limpiar_consola() + cls() print('Server Launcher for Minecraft\n-------------------------------------\n\nYou must select a folder to save the New Server.') time.sleep(2.5) installmenu() @@ -764,88 +1375,104 @@ def reselect(): def vers_select(): global newserver global foldname - limpiar_consola() - verss = input(f'Server Launcher for Minecraft\n-------------------------------------\n\nYour New Server will be saved in "{foldname}".\n\n(L) List of available versions\n(R) Re-select a folder for the New server\n(N) Return to main menu\n\nSelect one of the options or type the New Server version to install= ').replace(" ", "") + cls() + verss = input(f'Server Launcher for Minecraft\n-------------------------------------\n\nYour New Server will be saved in "{foldname}".\n\n(L) See available versions\n(R) Re-select a folder for the New server\n(N) Return to main menu\n\nSelect one of the options or type the New Server version to install= ').replace(" ", "") try: + def servdownload(versionname,type): + global newserver + global foldname + version = versionname.lower() + if type == "stable": + url = MCSTABLE[version] + else: + url = MCSNAPSHOT[version] + cls() + print(f'Server Launcher for Minecraft\n-------------------------------------\n\nYour New Server is being downloaded.\n\nVersion: {version}\nTarget Folder: "{foldname}"\n\nPlease wait...\n') + time.sleep(0.5) + os.makedirs(newserver, exist_ok=True) + os.chdir(newserver) + try: + response = requests.get(url, stream=True) + total_size_in_bytes = int(response.headers.get('content-length', 0)) + block_size = 1024 # 1 Kibibyte + total_data = 0 + with open("server.jar", "wb") as file: + for data in response.iter_content(block_size): + total_data += len(data) + file.write(data) + completed = int(50 * total_data / total_size_in_bytes) + print("\r[%s%s]" % ('#' * completed, '.' * (50 - completed)), end='') + print() + cls() + input('Server Launcher for Minecraft\n-------------------------------------\n\nThe server has been installed successfully and added to "Your Servers" list.\n\nPress ENTER to continue.') + servname = os.path.basename(newserver) + servstring = f"{servname}<[=]>{newserver}\n" + os.makedirs(CONFIG_PATH, exist_ok=True) + with open(SAVED_SERVERS, 'r+') as file: + lines = file.readlines() + if servstring not in lines: + file.write(servstring) + eng() + except Exception: + def erragain(): + cls() + yup = colored("Yes","green") + nop = colored("No","red") + errtry = input(f"Server Launcher for Minecraft\n-------------------------------------\n\nAn error occurred while downloading the server.\nTry again?\n\n(1) {yup}\n(2) {nop}\n\nSelect one of the options= ") + try: + if any(char in "0123456789+-*/" for char in errtry): + if not errtry[0].isalpha(): + errtr = eval(errtry) + else: + errtr = errtry + else: + errtr = errtry + errtr = int(errtr) + if errtr == 1: + servdownload(version,type) + elif errtr == 2: + eng() + else: + erragain() + except (ValueError, SyntaxError, IndexError, ZeroDivisionError): + erragain() + erragain() if verss.lower() == "n": eng() elif verss.lower() == "r": reselect() elif verss.lower() == "l": - def versionl(): - limpiar_consola() - print("Server Launcher for Minecraft\n-------------------------------------\n\nAvailable versions:\n") - for i, version in enumerate(MCVERSIONS, start=1): + def select_list(): + cls() + print("Server Launcher for Minecraft\n-------------------------------------\n") + print("STABLE VERSIONS:") + for i, version in enumerate(MCSTABLE, start=1): + print(f"(-) {version}") + print('') + print("SNAPSHOT VERSIONS:") + for i, version in enumerate(MCSNAPSHOT, start=1): print(f"(-) {version}") - listselection = input("\n(B) Back\n(R) Return to main menu\n\nSelect one of the options=") + listselection = input("\n(B) Back\n(R) Return to main menu\n\nType a version or select one of the options=") try: if listselection.lower() == "b": vers_select() elif listselection.lower() == "r": eng() + elif listselection.lower() in MCSTABLE.keys(): + servdownload(listselection,"stable") + elif listselection.lower() in MCSNAPSHOT.keys(): + servdownload(listselection,"snapshot") else: - versionl() + select_list() except (ValueError, SyntaxError, IndexError, ZeroDivisionError): - versionl() - versionl() - elif verss.lower() in MCVERSIONS.keys(): - def servdownload(): - global newserver - global foldname - version = verss.lower() - url = MCVERSIONS[version] - limpiar_consola() - print(f'Server Launcher for Minecraft\n-------------------------------------\n\nYour New Server is being downloaded.\n\nVersion: {version}\nTarget Folder: "{foldname}"\n\nPlease wait...\n') - time.sleep(0.5) - os.makedirs(newserver, exist_ok=True) - os.chdir(newserver) - try: - response = requests.get(url, stream=True) - total_size_in_bytes = int(response.headers.get('content-length', 0)) - block_size = 1024 # 1 Kibibyte - total_data = 0 - with open("server.jar", "wb") as file: - for data in response.iter_content(block_size): - total_data += len(data) - file.write(data) - completed = int(50 * total_data / total_size_in_bytes) - print("\r[%s%s]" % ('#' * completed, '.' * (50 - completed)), end='') - print() - limpiar_consola() - input('Server Launcher for Minecraft\n-------------------------------------\n\nThe server has been installed successfully and added to "Your Servers" list.\n\nPress ENTER to continue.') - servname = os.path.basename(newserver) - servstring = f"{servname}<[=]>{newserver}\n" - os.makedirs(CONFIG_PATH, exist_ok=True) - with open(SAVED_SERVERS, 'r+') as file: - lines = file.readlines() - if servstring not in lines: - file.write(servstring) - eng() - except Exception: - def erragain(): - limpiar_consola() - yup = colored("Yes","green") - nop = colored("No","red") - errtry = input(f"Server Launcher for Minecraft\n-------------------------------------\n\nAn error occurred while downloading the server.\nTry again?\n\n(1) {yup}\n(2) {nop}\n\nSelect one of the options= ") - try: - if any(char in "0123456789+-*/" for char in errtry): - if not errtry[0].isalpha(): - errtr = eval(errtry) - else: - errtr = errtry - else: - errtr = errtry - errtr = int(errtr) - if errtr == 1: - servdownload() - elif errtr == 2: - eng() - else: - erragain() - except (ValueError, SyntaxError, IndexError, ZeroDivisionError): - erragain() - erragain() - servdownload() + select_list() + select_list() + elif verss.lower() in MCSTABLE.keys(): + servdownload(verss,"stable") + elif verss.lower() in MCSNAPSHOT.keys(): + servdownload(verss,"snapshot") + else: + vers_select() except (ValueError, SyntaxError, IndexError, ZeroDivisionError): installmenu() vers_select() @@ -861,8 +1488,8 @@ def erragain(): # LICENSE AND EXTRAS def about(): - limpiar_consola() - copyr = input("Server Launcher for Minecraft\n-------------------------------------\n\nMIT License - Copyright (c) 2024 NGDPL Nk\n\nSSTools4MC v24.04.05-B\n\nHelpers:\n@naicoooossj\n@LegalizeNuclearBombs\n\n-------------------------------------\n\n(1) View repository in the browser\n(2) View license in the browser\n(3) Return to main menu\n\nSelect one of the options= ") + cls() + copyr = input("Server Launcher for Minecraft\n-------------------------------------\n\nMIT License - Copyright (c) 2024 ngdplnk\n\nSSTools4MC v24.07.29 - ADDED SUPPORT FOR SNAPSHOT VERSIONS\n\nHelpers:\n@naicoooossj\n@LegalizeNuclearBombs\n\n-------------------------------------\n\n(1) View repository in the browser\n(2) View license in the browser\n(3) Return to main menu\n\nSelect one of the options= ") try: if any(char in "0123456789+-*/" for char in copyr): if not copyr[0].isalpha(): @@ -873,17 +1500,17 @@ def about(): selec = copyr selec = int(selec) if selec == 1: - url = colored("https://github.com/NGDPLNk/SSTools4MC","cyan") - limpiar_consola() + url = colored("https://github.com/ngdplnk/SSTools4MC","cyan") + cls() input(f"Server Launcher for Minecraft\n-------------------------------------\n\nThe repository will open in your browser.\n\n{url}\n\nPress ENTER to continue.") - url = "https://github.com/NGDPLNk/SSTools4MC" + url = "https://github.com/ngdplnk/SSTools4MC" webbrowser.open(url) about() elif selec == 2: - url = colored("https://github.com/NGDPLNk/SSTools4MC/blob/main/LICENSE","cyan") - limpiar_consola() + url = colored("https://github.com/ngdplnk/SSTools4MC/blob/main/LICENSE","cyan") + cls() input(f"Server Launcher for Minecraft\n-------------------------------------\n\nThe license will open in your browser.\n\n{url}\n\nPress ENTER to continue.") - url = "https://github.com/NGDPLNk/SSTools4MC/blob/main/LICENSE" + url = "https://github.com/ngdplnk/SSTools4MC/blob/main/LICENSE" webbrowser.open(url) about() elif selec == 3: @@ -895,8 +1522,8 @@ def about(): # EXIT def exiit(): - limpiar_consola() - print("--------------------------------------------\nThank you for using this tool\nMIT License - Copyright (c) 2024 NGDPL Nk\n--------------------------------------------\n") + cls() + print("--------------------------------------------\nSee ya later!\nMIT License - Copyright (c) 2024 ngdplnk\n--------------------------------------------\n") time.sleep(1.2) sys.exit() @@ -904,7 +1531,7 @@ def exiit(): def menu(): os.makedirs(SSTOOLS_FOLDER, exist_ok=True) os.chdir(SSTOOLS_FOLDER) - limpiar_consola() + cls() seleccion = input("Server Launcher for Minecraft\n-------------------------------------\n\nHi! You are in the main menu.\n\n(1) Start a Server\n(2) Install a New Server\n(3) Extras\n(4) Change Language\n(5) Exit\n\nSelect one of the options= ") try: if any(char in "0123456789+-*/" for char in seleccion): @@ -931,7 +1558,7 @@ def menu(): menu() -# ESPAÑOL +# SPANISH def esp(): # CHANGE WINDOW TITLE window_title("Lanzador de Servidores para Minecraft") @@ -939,7 +1566,7 @@ def esp(): # SERVER STARTUP def ram(): global servername - limpiar_consola() + cls() sservers = {} if os.path.exists(SAVED_SERVERS): with open(SAVED_SERVERS, 'r') as file: @@ -949,7 +1576,7 @@ def ram(): key, value = line.split('<[=]>') sservers[key.strip()] = value.strip() if sservers: - limpiar_consola() + cls() print('Lanzador de Servidores para Minecraft\n-------------------------------------\n\nLista "Tus Servidores"\n') server_keys = list(sservers.keys()) for i, key in enumerate(server_keys, start=1): @@ -965,7 +1592,7 @@ def ram(): front() servname = os.path.basename(newserv) if newserv == "" or servname == "": - limpiar_consola() + cls() print('Lanzador de Servidores para Minecraft\n-------------------------------------\n\nDebes elegir una carpeta para guardarla en la Lista "Tus Servidores".') time.sleep(2.5) ram() @@ -977,13 +1604,13 @@ def ram(): lines = file.readlines() if servstring not in lines: file.write(servstring) - limpiar_consola() + cls() print(f'Lanzador de Servidores para Minecraft\n-------------------------------------\n\nEl Server "{servname}" ha sido guardado.') time.sleep(1.5) ram() elif servsel.lower() == "d": def servdel(): - limpiar_consola() + cls() print("Lanzador de Servidores para Minecraft\n-------------------------------------\n\nSelecciona el Server que eliminarás de la lista.\n") for i, key in enumerate(server_keys, start=1): print(f"({i}) {key}") @@ -1015,7 +1642,7 @@ def servdel(): for line in lines: if line != servestring: file.write(line) - limpiar_consola() + cls() print(f'Lanzador de Servidores para Minecraft\n-------------------------------------\n\nEl Server "{servsel}" ha sido eliminado de la lista.') time.sleep(1.5) ram() @@ -1024,7 +1651,7 @@ def servdel(): servdel() elif servsel.lower() == "c": def lisclear(): - limpiar_consola() + cls() yess = colored("Sí","green") noo = colored("No","red") clearconfirm = input(f'Lanzador de Servidores para Minecraft\n-------------------------------------\n\nEstás seguro de que quieres limpiar la Lista "Tus Servidores"?\n\n(1) {yess}\n(2) {noo}\n\nElige una de las opciones= ') @@ -1041,7 +1668,7 @@ def lisclear(): os.makedirs(CONFIG_PATH, exist_ok=True) with open(SAVED_SERVERS, 'w') as file: file.write("# Lanzador de Servidores para Minecraft\n# Servers guardados\n") - limpiar_consola() + cls() print('Lanzador de Servidores para Minecraft\n-------------------------------------\n\nLa Lista "Tus Servidores" ha sido limpiada.') time.sleep(1.5) ram() @@ -1073,7 +1700,7 @@ def lisclear(): os.makedirs(CONFIG_PATH, exist_ok=True) with open(SAVED_SERVERS, 'w') as file: file.write("# Lanzador de Servidores para Minecraft\n# Servidores Guardados\n") - limpiar_consola() + cls() adds = colored("Añadir un Server","cyan") saveconfirm = input(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nNo tienes ningún Server guardado.\n\n(1) {adds}\n(2) Volver al menú principal\n\nElige una de las opciones= ") try: @@ -1090,7 +1717,7 @@ def lisclear(): front() servname = os.path.basename(newserv) if newserv == "" or servname == "": - limpiar_consola() + cls() print('Lanzador de Servidores para Minecraft\n-------------------------------------\n\nDebes elegir una carpeta para guardarla en la Lista "Tus Servidores".') time.sleep(2.5) ram() @@ -1102,7 +1729,7 @@ def lisclear(): lines = file.readlines() if servstring not in lines: file.write(servstring) - limpiar_consola() + cls() print(f'Lanzador de Servidores para Minecraft\n-------------------------------------\n\nEl Server "{servname}" ha sido guardado.') time.sleep(1.5) ram() @@ -1116,13 +1743,13 @@ def lisclear(): os.makedirs(CONFIG_PATH, exist_ok=True) with open(SAVED_SERVERS, 'w') as file: file.write("# Lanzador de Servidores para Minecraft\n# Servers Guardados\n") - limpiar_consola() + cls() input('Lanzador de Servidores para Minecraft\n-------------------------------------\n\nNo tienes ningún Server guardado.\n\nPresiona ENTER para seleccionar una carpeta con tu Server y guardarlo en la Lista "Tus Servidores".') newserv = filedialog.askdirectory() front() servname = os.path.basename(newserv) if newserv == "" or servname == "": - limpiar_consola() + cls() print('Lanzador de Servidores para Minecraft\n-------------------------------------\n\nDebes elegir una carpeta para guardarla en la Lista "Tus Servidores".') time.sleep(2.5) ram() @@ -1133,7 +1760,7 @@ def lisclear(): lines = file.readlines() if servstring not in lines: file.write(servstring) - limpiar_consola() + cls() print(f'Lanzador de Servidores para Minecraft\n-------------------------------------\n\nEl Server "{servname}" ha sido guardado.') time.sleep(1.5) ram() @@ -1141,7 +1768,7 @@ def lisclear(): # CONFIG def config(): global nameserver - limpiar_consola() + cls() props = "server.properties" if os.path.exists(props): global properties @@ -1167,7 +1794,7 @@ def config(): pvp = colored("ACTIVAR","green") elif properties["pvp"] == "true": pvp = colored("DESACTIVAR","red") - limpiar_consola() + cls() confsel = input(f'Lanzador de Servidores para Minecraft\n-------------------------------------\n\nConfiguremos "{nameserver}"!\n\n(1) {online} modo online\n(2) {hard} modo extremo\n(3) {pvp} PvP\n(4) Cambiar modo de juego\n(5) Cambiar dificultad\n(6) Cambiar el límite de jugadores\n(7) Atrás\n(8) Volver al menú principal\n\nElige una de las opciones= ') if properties["online-mode"] == "false": online = "ENABLE" @@ -1203,7 +1830,7 @@ def config(): for key, value in properties.items(): file.write(f'{key}={value}\n') online = colored("DESACTIVADO","red") - limpiar_consola() + cls() print(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nEl modo online se ha {online}.") time.sleep(1.5) config() @@ -1220,7 +1847,7 @@ def config(): for key, value in properties.items(): file.write(f'{key}={value}\n') hard = colored("DESACTIVADO","red") - limpiar_consola() + cls() print(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nEl modo extremo se ha {hard}.") time.sleep(1.5) config() @@ -1237,7 +1864,7 @@ def config(): for key, value in properties.items(): file.write(f'{key}={value}\n') pvp = colored("DESACTIVADO","red") - limpiar_consola() + cls() print(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nEl PvP se ha {pvp}.") time.sleep(1.5) config() @@ -1257,7 +1884,7 @@ def juego(): creat = colored("CREATIVO","yellow") avent = colored("AVENTURA","yellow") espect = colored("ESPECTADOR","yellow") - limpiar_consola() + cls() modosel = input(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nEl modo de juego actual es {modo}.\n\n(1) Cambiar a modo {superv}\n(2) Cambiar a modo {creat}\n(3) Cambiar a modo {avent}\n(4) Cambiar a modo {espect}\n(5) Atrás\n(6) Volver al menú principal\n\nElige una de las opciones= ") try: if any(char in "0123456789+-*/" for char in modosel): @@ -1273,7 +1900,7 @@ def juego(): with open('server.properties', 'w') as file: for key, value in properties.items(): file.write(f'{key}={value}\n') - limpiar_consola() + cls() print(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nEl modo de juego se ha cambiado a {superv}.") time.sleep(1.5) juego() @@ -1282,7 +1909,7 @@ def juego(): with open('server.properties', 'w') as file: for key, value in properties.items(): file.write(f'{key}={value}\n') - limpiar_consola() + cls() print(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nEl modo de juego se ha cambiado a {creat}.") time.sleep(1.5) juego() @@ -1291,7 +1918,7 @@ def juego(): with open('server.properties', 'w') as file: for key, value in properties.items(): file.write(f'{key}={value}\n') - limpiar_consola() + cls() print(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nEl modo de juego se ha cambiado a {avent}.") time.sleep(1.5) juego() @@ -1300,7 +1927,7 @@ def juego(): with open('server.properties', 'w') as file: for key, value in properties.items(): file.write(f'{key}={value}\n') - limpiar_consola() + cls() print(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nEl modo de juego se ha cambiado a {espect}.") time.sleep(1.5) juego() @@ -1329,7 +1956,7 @@ def difconf(): facil = colored("FÁCIL","yellow") normal = colored("NORMAL","yellow") dificil = colored("DIFÍCIL","yellow") - limpiar_consola() + cls() difsel = input(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nLa dificultad actual es {dificultad}.\n\n(1) Cambiar a dificultad {pacif}\n(2) Cambiar a dificultad {facil}\n(3) Cambiar a dificultad {normal}\n(4) Cambiar a dificultad {dificil}\n(5) Atrás\n(6) Volver al menú principal\n\nElige una de las opciones= ") try: if any(char in "0123456789+-*/" for char in difsel): @@ -1345,7 +1972,7 @@ def difconf(): with open('server.properties', 'w') as file: for key, value in properties.items(): file.write(f'{key}={value}\n') - limpiar_consola() + cls() print(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nLa dificultad se ha cambiado a {pacif}.") time.sleep(1.5) difconf() @@ -1354,7 +1981,7 @@ def difconf(): with open('server.properties', 'w') as file: for key, value in properties.items(): file.write(f'{key}={value}\n') - limpiar_consola() + cls() print(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nLa dificultad se ha cambiado a {facil}.") time.sleep(1.5) difconf() @@ -1363,7 +1990,7 @@ def difconf(): with open('server.properties', 'w') as file: for key, value in properties.items(): file.write(f'{key}={value}\n') - limpiar_consola() + cls() print(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nLa dificultad se ha cambiado a {normal}.") time.sleep(1.5) difconf() @@ -1372,7 +1999,7 @@ def difconf(): with open('server.properties', 'w') as file: for key, value in properties.items(): file.write(f'{key}={value}\n') - limpiar_consola() + cls() print(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nLa dificultad se ha cambiado a {dificil}.") time.sleep(1.5) difconf() @@ -1389,7 +2016,7 @@ def difconf(): def playct(): global properties players = colored(properties["max-players"],"cyan") - limpiar_consola() + cls() newpl = input(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nEl límite de jugadores actual es de {players} jugadores.\n\n(N) Atrás\n(M) Volver al menú principal\n\nElige una de las opciones o ingresa el nuevo límite de jugadores= ").replace(" ", "") try: if newpl.lower() == "n": @@ -1406,7 +2033,7 @@ def playct(): entero = newpl entero = int(entero) if entero <= 0 or entero > 100000: - limpiar_consola() + cls() print(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nIngresa un número válido entre 1 y 100.000.") time.sleep(1.5) playct() @@ -1416,7 +2043,7 @@ def playct(): for key, value in properties.items(): file.write(f'{key}={value}\n') entero = colored(str(entero),"yellow") - limpiar_consola() + cls() print(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nEl límite de jugadores ahora es {entero}.") time.sleep(1.5) playct() @@ -1432,7 +2059,7 @@ def playct(): except (ValueError, SyntaxError, IndexError, ZeroDivisionError): config() else: - limpiar_consola() + cls() input("Lanzador de Servidores para Minecraft\n-------------------------------------\n\nLos achivos de configuración del Server aún no existen o no están disponibles.\nDebes iniciar el Server correctamente al menos 1 vez antes de poder configurarlo.\n\nPresiona ENTER para continuar.") run_server() def run_server(): @@ -1456,7 +2083,7 @@ def run_server(): vjava = "M" gbormb = colored("GIGABYTES","yellow") nameserver = servername - limpiar_consola() + cls() gbs = 0 rammount = input(f'Lanzador de Servidores para Minecraft\n-------------------------------------\n\nEstás a punto de iniciar el Server "{nameserver}"\n\n(M) Configurar Server\n(C) Usar RAM en {gbormb}\n(B) Atrás\n(N) Volver al menú principal\n\nElige una de las opciones o ingresa los {valor1} de RAM para asignar a tu Server= ').replace(" ", "") try: @@ -1464,13 +2091,13 @@ def run_server(): config() if rammount.lower() == "c": if valor == "GB": - limpiar_consola() + cls() print(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nAhora la RAM está en {gbormb}.") time.sleep(1.5) valor = "MB" run_server() elif valor == "MB": - limpiar_consola() + cls() print(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nAhora la RAM está en {gbormb}.") time.sleep(1.5) valor = "GB" @@ -1489,12 +2116,12 @@ def run_server(): gbs = rammount gbs = int(gbs) if valor == "GB" and (gbs <= 0 or gbs > 75): - limpiar_consola() + cls() print(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nIngresa una cantidad válida entre 1 y 75 Gigabytes.") time.sleep(1.5) run_server() elif valor == "MB" and (gbs <= 511 or gbs > 76800): - limpiar_consola() + cls() print(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nIngresa una cantidad válida entre 512 y 76.800 Megabytes.") time.sleep(1.5) run_server() @@ -1502,7 +2129,7 @@ def run_server(): eula = "eula.txt" with open(eula, "w") as reemplazo: reemplazo.write("eula=true") - limpiar_consola() + cls() print(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nIniciando el Server con {gbs}{valor} de RAM.\n") comando_java = f"java -Xmx{gbs}{vjava} -Xms{gbs}{vjava} -jar server.jar nogui" subprocess.run(comando_java, shell=True) @@ -1510,14 +2137,14 @@ def run_server(): fecha_cerrado = str(fyh_sistema.strftime("%d/%m/%Y")) hora_cerrado = str(fyh_sistema.strftime("%H:%M:%S")) input("\nPresiona ENTER para continuar.") - limpiar_consola() + cls() input(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nEl Server se ha cerrado el {fecha_cerrado} a las {hora_cerrado}.\n\nPuedes ver el registro de la consola en la carpeta 'logs' dentro de la carpeta principal de tu Server.\n\nPresiona ENTER para continuar.") ram() except (ValueError, SyntaxError, IndexError, ZeroDivisionError): run_server() run_server() else: - limpiar_consola() + cls() print('Lanzador de Servidores para Minecraft\n-------------------------------------\n\nNo se encuentra "server.jar" en esta carpeta.\n\nEstás seguro que esto es un Server?') time.sleep(2.5) ram() @@ -1526,7 +2153,7 @@ def run_server(): def installmenu(): global newserver global foldname - limpiar_consola() + cls() inconfirm = input("Lanzador de Servidores para Minecraft\n-------------------------------------\n\nPrimero, seleccionemos una carpeta para guardar los archivos de tu Nuevo Server.\n\n(1) Seleccionar una carpeta para el Nuevo Server\n(2) Cancelar\n\nElige una de las opciones= ").replace(" ", "") try: if any(char in "0123456789+-*/" for char in inconfirm): @@ -1545,7 +2172,7 @@ def reselect(): front() foldname = colored(os.path.basename(newserver), "green") if newserver == "" or foldname == "": - limpiar_consola() + cls() print('Lanzador de Servidores para Minecraft\n-------------------------------------\n\nDebes elegir una carpeta para guardar tu Nuevo Server.') time.sleep(2.5) installmenu() @@ -1555,88 +2182,104 @@ def reselect(): def vers_select(): global newserver global foldname - limpiar_consola() - verss = input(f'Lanzador de Servidores para Minecraft\n-------------------------------------\n\nTu Nuevo Server se guardará en "{foldname}".\n\n(L) Lista de versiones disponibles\n(R) Reelegir una carpeta para el Nuevo Server\n(N) Volver al menú principal\n\nElige una de las opciones o escribe la versión para instalar tu Nuevo Server= ').replace(" ", "") + cls() + verss = input(f'Lanzador de Servidores para Minecraft\n-------------------------------------\n\nTu Nuevo Server se guardará en "{foldname}".\n\n(L) Ver versiones disponibles\n(R) Reelegir una carpeta para el Nuevo Server\n(N) Volver al menú principal\n\nElige una de las opciones o escribe la versión para instalar tu Nuevo Server= ').replace(" ", "") try: + def servdownload(versionname,type): + global newserver + global foldname + version = versionname.lower() + if type == "stable": + url = MCSTABLE[version] + else: + url = MCSNAPSHOT[version] + cls() + print(f'Lanzador de Servidores para Minecraft\n-------------------------------------\n\nTu Nuevo Server está siendo descargado.\n\nVersión: {version}\nCarpeta de destino: "{foldname}"\n\nEspera por favor...\n') + time.sleep(0.5) + os.makedirs(newserver, exist_ok=True) + os.chdir(newserver) + try: + response = requests.get(url, stream=True) + total_size_in_bytes = int(response.headers.get('content-length', 0)) + block_size = 1024 # 1 Kibibyte + total_data = 0 + with open("server.jar", "wb") as file: + for data in response.iter_content(block_size): + total_data += len(data) + file.write(data) + completed = int(50 * total_data / total_size_in_bytes) + print("\r[%s%s]" % ('#' * completed, '.' * (50 - completed)), end='') + print() + cls() + input('Lanzador de Servidores para Minecraft\n-------------------------------------\n\nTu Nuevo Server se ha instalado correctamente y ha sido añadido a la Lista "Tus Servidores".\n\nPresiona ENTER para continuar.') + servname = os.path.basename(newserver) + servstring = f"{servname}<[=]>{newserver}\n" + os.makedirs(CONFIG_PATH, exist_ok=True) + with open(SAVED_SERVERS, 'r+') as file: + lines = file.readlines() + if servstring not in lines: + file.write(servstring) + esp() + except Exception: + def erragain(): + cls() + yup = colored("Sí","green") + nop = colored("No","red") + errtry = input(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nHa ocurrido un error mientras se descargaba tu Nuevo Server.\nReintentar?\n\n(1) {yup}\n(2) {nop}\n\nElige una de las opciones= ") + try: + if any(char in "0123456789+-*/" for char in errtry): + if not errtry[0].isalpha(): + errtr = eval(errtry) + else: + errtr = errtry + else: + errtr = errtry + errtr = int(errtr) + if errtr == 1: + servdownload(version,type) + elif errtr == 2: + esp() + else: + erragain() + except (ValueError, SyntaxError, IndexError, ZeroDivisionError): + erragain() + erragain() if verss.lower() == "n": esp() elif verss.lower() == "r": reselect() elif verss.lower() == "l": - def versionl(): - limpiar_consola() - print("Lanzador de Servidores para Minecraft\n-------------------------------------\n\nVersiones disponibles:\n") - for i, version in enumerate(MCVERSIONS, start=1): + def select_list(): + cls() + print("Lanzador de Servidores para Minecraft\n-------------------------------------\n") + print("VERSIONES ESTABLES:") + for i, version in enumerate(MCSTABLE, start=1): + print(f"(-) {version}") + print('') + print("VERSIONES SNAPSHOT:") + for i, version in enumerate(MCSNAPSHOT, start=1): print(f"(-) {version}") - listselection = input("\n(B) Atrás\n(R) Volver al menú principal\n\nElige una de las opciones=") + listselection = input("\n(B) Atrás\n(R) Volver al menú principal\n\nEscribe una versión o elige una de las opciones=") try: if listselection.lower() == "b": vers_select() elif listselection.lower() == "r": esp() + elif listselection.lower() in MCSTABLE.keys(): + servdownload(listselection,"stable") + elif listselection.lower() in MCSNAPSHOT.keys(): + servdownload(listselection,"snapshot") else: - versionl() + select_list() except (ValueError, SyntaxError, IndexError, ZeroDivisionError): - versionl() - versionl() - elif verss.lower() in MCVERSIONS.keys(): - def servdownload(): - global newserver - global foldname - version = verss.lower() - url = MCVERSIONS[version] - limpiar_consola() - print(f'Lanzador de Servidores para Minecraft\n-------------------------------------\n\nTu Nuevo Server está siendo descargado.\n\nVersión: {version}\nCarpeta de destino: "{foldname}"\n\nEspera por favor...\n') - time.sleep(0.5) - os.makedirs(newserver, exist_ok=True) - os.chdir(newserver) - try: - response = requests.get(url, stream=True) - total_size_in_bytes = int(response.headers.get('content-length', 0)) - block_size = 1024 # 1 Kibibyte - total_data = 0 - with open("server.jar", "wb") as file: - for data in response.iter_content(block_size): - total_data += len(data) - file.write(data) - completed = int(50 * total_data / total_size_in_bytes) - print("\r[%s%s]" % ('#' * completed, '.' * (50 - completed)), end='') - print() - limpiar_consola() - input('Lanzador de Servidores para Minecraft\n-------------------------------------\n\nTu Nuevo Server se ha instalado correctamente y ha sido añadido a la Lista "Tus Servidores".\n\nPresiona ENTER para continuar.') - servname = os.path.basename(newserver) - servstring = f"{servname}<[=]>{newserver}\n" - os.makedirs(CONFIG_PATH, exist_ok=True) - with open(SAVED_SERVERS, 'r+') as file: - lines = file.readlines() - if servstring not in lines: - file.write(servstring) - esp() - except Exception: - def erragain(): - limpiar_consola() - yup = colored("Sí","green") - nop = colored("No","red") - errtry = input(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nHa ocurrido un error mientras se descargaba tu Nuevo Server.\nReintentar?\n\n(1) {yup}\n(2) {nop}\n\nElige una de las opciones= ") - try: - if any(char in "0123456789+-*/" for char in errtry): - if not errtry[0].isalpha(): - errtr = eval(errtry) - else: - errtr = errtry - else: - errtr = errtry - errtr = int(errtr) - if errtr == 1: - servdownload() - elif errtr == 2: - esp() - else: - erragain() - except (ValueError, SyntaxError, IndexError, ZeroDivisionError): - erragain() - erragain() - servdownload() + select_list() + select_list() + elif verss.lower() in MCSTABLE.keys(): + servdownload(verss,"stable") + elif verss.lower() in MCSNAPSHOT.keys(): + servdownload(verss,"snapshot") + else: + vers_select() except (ValueError, SyntaxError, IndexError, ZeroDivisionError): installmenu() vers_select() @@ -1652,8 +2295,8 @@ def erragain(): # LICENSE AND EXTRAS def about(): - limpiar_consola() - copyr = input("Lanzador de Servidores para Minecraft\n-------------------------------------\n\nMIT License - Copyright (c) 2024 NGDPL Nk\n\nSSTools4MC v24.04.05-B\n\nHelpers:\n@naicoooossj\n@LegalizeNuclearBombs\n\n-------------------------------------\n\n(1) Ver repositorio en el navegador\n(2) Ver licencia en el navegador\n(3) Volver al menú principal\n\nElige una de las opciones= ") + cls() + copyr = input("Lanzador de Servidores para Minecraft\n-------------------------------------\n\nMIT License - Copyright (c) 2024 ngdplnk\n\nSSTools4MC v24.07.29 - SE AÑADE SOPRTE PARA VERSIONES SNAPSHOT\n\nHelpers:\n@naicoooossj\n@LegalizeNuclearBombs\n\n-------------------------------------\n\n(1) Ver repositorio en el navegador\n(2) Ver licencia en el navegador\n(3) Volver al menú principal\n\nElige una de las opciones= ") try: if any(char in "0123456789+-*/" for char in copyr): if not copyr[0].isalpha(): @@ -1665,14 +2308,14 @@ def about(): selec = int(selec) if selec == 1: url = colored("https://github.com/ngdplnk/SSTools4MC","cyan") - limpiar_consola() + cls() input(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nEl repositorio se abrirá en tu navegador.\n\n{url}\n\nPresiona ENTER para continuar.") url = "https://github.com/ngdplnk/SSTools4MC" webbrowser.open(url) about() elif selec == 2: url = colored("https://github.com/ngdplnk/SSTools4MC/blob/main/LICENSE","cyan") - limpiar_consola() + cls() input(f"Lanzador de Servidores para Minecraft\n-------------------------------------\n\nLa licencia se abrirá en tu navegador.\n\n{url}\n\nPresiona ENTER para continuar.") url = "https://github.com/ngdplnk/SSTools4MC/blob/main/LICENSE" webbrowser.open(url) @@ -1686,8 +2329,8 @@ def about(): # EXIT def exiit(): - limpiar_consola() - print("--------------------------------------------\nMuchas gracias por usar esta herramienta\nMIT License - Copyright (c) 2024 NGDPL Nk\n--------------------------------------------\n") + cls() + print("--------------------------------------------\nNos vemos pronto!\nMIT License - Copyright (c) 2024 ngdplnk\n--------------------------------------------\n") time.sleep(1.2) sys.exit() @@ -1695,7 +2338,7 @@ def exiit(): def menu(): os.makedirs(SSTOOLS_FOLDER, exist_ok=True) os.chdir(SSTOOLS_FOLDER) - limpiar_consola() + cls() seleccion = input("Lanzador de Servidores para Minecraft\n-------------------------------------\n\nHola! Estás en el menú principal.\n\n(1) Inciar un Server\n(2) Instalar un Nuevo Server\n(3) Extras\n(4) Cambiar Lenguaje\n(5) Salir\n\nElige una de las opciones= ") try: if any(char in "0123456789+-*/" for char in seleccion): @@ -1722,8 +2365,8 @@ def menu(): menu() -# SELECCIÓN DE IDIOMA - LANGUAGE SELECTION -def lang(): +# STARTUP +def startup(): system_lang = locale.getlocale()[0] system_lang = str(system_lang) if system_lang.startswith("es") or system_lang.startswith("Spanish"): @@ -1731,5 +2374,5 @@ def lang(): else: eng() -# INICIAR HERRAMIENTA - RUN TOOL -lang() \ No newline at end of file +# RUN TOOL +startup() diff --git a/3-launcher/build.nsi b/3-launcher/build.nsi index 7e690e8..71e87b0 100644 --- a/3-launcher/build.nsi +++ b/3-launcher/build.nsi @@ -5,13 +5,13 @@ ############################################################ -Caption "SSTools4MC v1.1 Installer" +Caption "SSTools4MC v1.2 Installer" UninstallCaption "SSTools4MC Uninstaller" -!define APP_VERSION "1.1" -!define PRODUCT_VERSION "1.1.0.0" -!define APP_EDITOR "TLSoftware" +!define APP_VERSION "1.2" +!define PRODUCT_VERSION "1.2.0.0" +!define APP_EDITOR "ngdplnk" -Outfile "SSTools4MC_Setup_v1.1.exe" +Outfile "SSTools4MC_Setup_v1.2.exe" SetCompressor /SOLID lzma Icon "${ICON_PATH}" @@ -20,15 +20,15 @@ SilentUninstall silent VIProductVersion "${PRODUCT_VERSION}" VIAddVersionKey "ProductName" "SSTools4MC Launcher" -VIAddVersionKey "CompanyName" "TLSoftware" +VIAddVersionKey "CompanyName" "ngdplnk" VIAddVersionKey "FileDescription" "SSTools4MC Launcher" VIAddVersionKey "FileVersion" "${APP_VERSION}" -VIAddVersionKey "LegalCopyright" "Copyright (C) 2024 TLSoftware" +VIAddVersionKey "LegalCopyright" "Copyright (C) 2024 ngdplnk" VIAddVersionKey "OriginalFilename" "SSTools4MC_Launcher.exe" VIAddVersionKey "Comments" "Created by ${APP_EDITOR}" # Define the installation directory -InstallDir $APPDATA\TLSoftware\SSTools4MC +InstallDir $APPDATA\SSTools4MC Section "MainSection" SEC01 @@ -36,23 +36,23 @@ Section "MainSection" SEC01 SetAutoClose true # Define the directory for the program - SetOutPath $APPDATA\TLSoftware\SSTools4MC + SetOutPath $APPDATA\SSTools4MC # Copy files File /oname=launcher.pyw "${LAUNCHER_PATH}" File /oname=main.py "${BASE_PATH}" # Define the directory for the icon - SetOutPath $APPDATA\TLSoftware\SSTools4MC\assets + SetOutPath $APPDATA\SSTools4MC\assets # Copy the file File /oname=icon.ico "${ICON_PATH}" # Create a desktop shortcut - CreateShortCut "$DESKTOP\SSTools4MC Launcher.lnk" "$APPDATA\TLSoftware\SSTools4MC\launcher.pyw" "" "$APPDATA\TLSoftware\SSTools4MC\assets\icon.ico" 0 + CreateShortCut "$DESKTOP\SSTools4MC Launcher.lnk" "$APPDATA\SSTools4MC\launcher.pyw" "" "$APPDATA\SSTools4MC\assets\icon.ico" 0 # Create a Start Menu shortcut - CreateShortCut "$SMPROGRAMS\SSTools4MC Launcher.lnk" "$APPDATA\TLSoftware\SSTools4MC\launcher.pyw" "" "$APPDATA\TLSoftware\SSTools4MC\assets\icon.ico" 0 + CreateShortCut "$SMPROGRAMS\SSTools4MC Launcher.lnk" "$APPDATA\SSTools4MC\launcher.pyw" "" "$APPDATA\SSTools4MC\assets\icon.ico" 0 # Write the uninstall keys for Add/Remove Programs WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\SSTools4MC" "DisplayName" "SSTools4MC Launcher" @@ -70,7 +70,7 @@ Section "MainSection" SEC01 runProgram: # Run the program if the user clicked "Yes" - ExecShell "" "$APPDATA\TLSoftware\SSTools4MC\launcher.pyw" + ExecShell "" "$APPDATA\SSTools4MC\launcher.pyw" end: @@ -82,9 +82,9 @@ Section "Uninstall" SetAutoClose true # Remove the files - Delete $APPDATA\TLSoftware\SSTools4MC\launcher.pyw - Delete $APPDATA\TLSoftware\SSTools4MC\main.py - Delete $APPDATA\TLSoftware\SSTools4MC\assets\icon.ico + Delete $APPDATA\SSTools4MC\launcher.pyw + Delete $APPDATA\SSTools4MC\main.py + Delete $APPDATA\SSTools4MC\assets\icon.ico # Remove the shortcuts Delete "$DESKTOP\SSTools4MC Launcher.lnk" @@ -97,8 +97,8 @@ Section "Uninstall" DeleteRegKey HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\SSTools4MC" # Remove the directories - RMDir /r $APPDATA\TLSoftware\SSTools4MC\assets - RMDir /r $APPDATA\TLSoftware\SSTools4MC + RMDir /r $APPDATA\SSTools4MC\assets + RMDir /r $APPDATA\SSTools4MC # Show a message when the program is completely uninstalled MessageBox MB_OK|MB_ICONINFORMATION "SSTools4MC has been completely uninstalled." diff --git a/3-launcher/icon.ico b/3-launcher/icon.ico index 67b8bb88941579b6604273c03676a691674adb0a..f163a06969d67e7706183bd374839a1b3e8781d7 100644 GIT binary patch literal 3200 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 literal 17064 zcmYg%byQT}`}Lh+fT262yStGZNY5)o8?)dTf zzW==Uu32-=nmBjnJhAtFo(lk=$Me4f1TX+83IIUHj!9}4k6(afftYI@|q(!$o zo2&JD@9i*#Vo2q5Z@KOVd!6HxI}+uNczZ6n9jy3_Tk@6F z>c}U4h&Y`zdk<_6UUnA1;C{_1Y{rxGT4(EOuYV|gFcoU(FGn&)>?O;f0M}6~mxO|* z$}Ye5PsBGx*hW>*_<9o^6=x|NQFEG;)1|=5(M$k)((jDJxXsqsy|D)aYVd?#Id^kj zYfpc$kzK@M5yN~X^NZ<+I*%cZs;nT$Xx=~$X?N_TC(Kjf>T|V{lG_VtAZD9H4JuK} zz~Y;OXTbPRoTNm|?!EyU;zQEA-Dy(iI0ZbIP5ber^S+QWcuO$!aT74O^9HO*D>yO| zjpj~=Z2Lr*8xpK~@kGHr+z1o2tqYCYAxE%Zyh!N8D5)OQyibgd_6%v1Wk?xq@o zkp!~~mK^hQ2|mH#wZa*2gaY)`ZC;{LLxUfh^{j~})}wy<;?dD1|LP#oFnJL8dq#)b za}RQT7yiDOtT(SsBGnG5^ya}$rq6o z`ma>#sk`72L+ePHsR5d1TTG3`Yuxd$zpu)32Qu8@la(%->2jU^Dp}_YhWEqgeYq;u zaLLQm9_!g3zZfb*&_##)mZFJn&sSHs!X6Zc(hIKF>M)bUs*=r8VLERFT%`Qoj$BZ+ z2T*IgMq#y3377Fid)Pbcq+mC{JI;j73jUfh0k@$ECNA4q(1f1JF$Xf==oZL%A_bIv zyJ}fb>pM7DqC$mhb5(51_PfzBw%3ZCnp~wsq0T(frP-fNd*MPkcf_L;Fy09K0XB|3 zSq6bt_$;26w@F{mP45V&W66G~jl|j2Iuxl#ED#i=;4Y0MMr=k_rU$*nS?)LIx z@SBuo{WYuLMbn+YSzkrrMcS24tD|g`^6Kr;=h462ib&haqwxMR`re>kL8252X-2 zygv<3ZIvDh31wY>NP?XAb>-dscKcGd_}yrGR8+{3jEpxLgSMl_AnYh~D_G;tClWjT znh_%80qNf5%P&K^WqCoV>Lx&#PJ^O2ta~Mnhx%O(gAKPBHmCU?ERL$q>)?Mm3z~i5;N3a*&w0%ga28E z`I8V@;HUg_YrgCo-wU4NmJ40N-F_#s|5Jri4)EooI+}l*P=bB_O^)B0s^oa%Z=h%b zB)Va#pOm^T#v^qTHeY0KYTjTaOwpH2mZMRBe!=yiIKC{-btoN8VY{@(bQpLo7xGp{ zMczAcSiX$5-A?%QLkr<+U2#w#L6l*5uW2b0N4V$V>9LUyuPoUb&tvQ>wRyIHP`__- zWMN?0W+1wq{pprad04t0uPSJlXrfyVTl zqKn$0NvBDU%K49IgGN;teMPpYHF{(k9>R~(LWvTWZZ|yZL(D{+cFjo3e#hJFQK;?A zK=3!S>AKR}HnikXPkz4d3@%r$C<4^`iwycbBgdsn?EzoM$;9fXG&#~_c ziw<#>zi$<{S1;H4f!u>^rB!d7dt~xVWyY`M?1NyF(`9#XVX0u~JYQwDVF9-sg%-G+ zkcJ!-y2&ZNw@rnDA+o=CLnpHP1I_2Df23<7mAu8-HlcYP)eUVreZg|0v$l(1BOx|L z9WhS))aLa?!DoXwAV4?hWIigPMxBJ|?H8dcV4bNrD8yd!v<`v)9^&fkj`xhfj1bfxE|b-8eCS zvQ*pp890lx@(VT+uuEKEQ!fDJdb(2CRFa(Z0<>Xk~$`QCBO z#Tnjy=vDcbSTFCQ4uNC!b)WmWfUh*Hd!PgOVB%AQokYeI+0?;;sr~wazqW?W zcy=Ani1YCVyNNQ2hQ#pAr8qeiYuQ*Box7(jeEAVzE#?mYw5BMC3e>^BGqX28Mf)&uN#Vy^u8EpZ4D>#@F5F9?RNR%N>UR9}U@4C?2tg;qP-7`o zY1S*tQd*&?Fwrqtn@W#De0eSXimPt3rGvVh0V zL0D@xTH<%&XTV}MS9))0S&rsY6GY2oId2v^^(udHJy`v+wzxCLr{wFrw$~wSy<|zJ z*L={*E0mW9O%?9TD=C04FK==*uKOOYAP|^?9aE{e=l57xqB49KKOr&Q9dE|%Sh{69 z(;aNqpy}-9z}=%Vg{S)n-Q3lZh1Yn|1N!%*!(MZq&`aI1%vN*X{Q24@@zrBmUGGY8 z+qyM0xH2spJKw1kH~9JzreQ|)*KeQ46K`@@z!@p7(~;v@S6*l0URX*!8FCs8e-t#FBXR|yTQ&u(&@gOTM zDdO|TVNrwM_tLRqjnl9Qwc}-hL$rC|_wOS5)5bey7=T=Qf%nVx7N62|+-mRpY*+fX zJ&S`qOFX(A=Oa|U3^%jTbFL55MkF_WBshnbvA{FnX;Scd1p~blcRjs|l~j}9rWD>` zK~V`4#0oRpA(b*=@5^=+;h2jz^BETxTScO% zu0Q#}!s$0p9d&x!Y|P$|;KN+-a7`MCxh6M>Ms%0g3$+r+%kRR}u_-Cj^i_Q$=F>!T zM1}XTZD`jofgi{y85$ zF;ZG(0U`{EXK@jf#=yH`uF^|{>gl%us|QQAafgjA5hvIqQz()%^bo@{DgJAG_^{b@ z|DY!xWS|h~fNJm<%kWc9G%(mkB4M!=9!fNyNpJ7c5#A=ObFhAFq(folpwhpqsCDkf zrvN7yslb?vD`GpqEZ~0hnuEuTGokOqxH-d4h$S$uxFU$3s&`m*pWH+xgd>}%$nj)H zDJwDN=A(5x^sxC>^@#ud-1fGF6ZTt+*2MIqQTqfRZqMxpdwuPyb1O;;)mq(w(yOG0 z8r@!5^QN*iU2W^-dP^w@FBD+W6-2~m(FRP&T+nKCtT6 zAXK~P>gZ1|Huo1AT$kX)@%a)!Hyg#snQRwxhx^ch;;!%^7g0(~Nc$gG<}ADmLL#S@ z2&sPK@~By28=%o!Uaq>boZ64l;Wqr%dVPD^k*r<6Ld)yw*pY)%74quUtB;yW)qgkC ziQyJBfIWHEov{$1i?_Y5IvCA~-~Nt-=kmM2D>v{8x{4#YMqALVC0PM!&iTCkbqF4o z4fWrEUA~>93UPOiCqS*LrvC`9&?Z1bA80r&RW$vqcZSe>MZ%Abn^Hg zJgRTygfEnVEsRI*VS3$NB&uV&+JjHRYv#Tb=?e{tZ^Eil^qyKwFNpmn{fI$IX+b*1 zOf{OAzvT-*Xl7^CUJksJcL$ix{=9vQ+vc+#&jPaO@WV<;O)WD=RFtdlL#E0%nJKc| zemlpOLj?SeUI*;)-Y$7XHdlRDOpMcsIjnKvw83e8K^kVU-hMp)7TEsOk_+@ZKnu0< zo*w?vmQy1JIxq~Y4c@cC(@538l_fCXRX3)aIzY*D+L{YYI@TGl_I!C7xyF{C(6{Vu zmz={bXB?)_hXiX{!e3u4{lq_O0w-A3}H766*c5rT&)v7la?ub*-Voq){&%~CF=o(diB3!EkCd;x9fl06Qrdr4-5dzn10dpvcE9{ zd!%p!`98#rsQ_Vjq^K{M@7~Bw4CLqKASY%&g(t-S`7{fg87B$8er_*$niEdHbI6=Y z0Dl;Msr-qDCG==eX+){8woBSj6wuYx)#(ijtyIB6vqUS~G>%PlEbG<7ljkZgRqY{9 z$bMEo$0KPwS2<_G5H$i@o85zZyOl*uyb!jDvPe>@VkpQRjGKv|slxrs-5YhBL^X#V z_VkWvp?viAqSf=moA91siv8OVs{6Y=oEWr)OYEh&2TBO$a}E~EGXb?Pa-}qvm}78R zI$}C3?-!zTG_cgg@Wj1dPTjQ3ktBk8oe0hj113z;-e~v+V0f>{S9bdr2zwyb>S?9#A5ak0=MY)rW-C+3JQCJOK~9q8Fq8$fe5z6Y zcDe1ho-v9J^MUdzKJiksNhN$lCu*P_$ls^r&G`V^Q_Pa%wOXK-Ecvn-{X9_rL+axJ z>=W92)PZX#S@T9#Nioin06PHJNY(=nR;Aac5g$|$&g@4p12@E(ASd>?hNzY-$Z(@= zf>2zQd1KTX+!}s`TmF{XJ>3!_hEq5Q)2XFKzF+p4x99X`$f7Vy*2)@>hElXR;mP_7$fbM^yP19 zy=~lwxB3Jy1&dED;yj`!zQ>)}erVa}Gyn!7W_MSv{R_jFSHM}PzkTo}dSJ)`{UK~2M}lMU|4jkk^CN2d~4|UMCP-fzE1qJyw_%mSG|QUrq5(z%jdM!jVWZ6 zb^FrM!s15{{*{kf(;ReNi}<-NgGV!QGBjocDbiDFkcF&n2O~r}jglfc;g)%| zW`>9CZg`pfCey0(D%T4()JpQHX*1mG?ZqMbSE?nEF2ncZI6I^q(-W*~X2ww-Az7IGphu z8)G*3MA7v&R=vGseghNJh_KJ3DfIhl$KIRiy`@sflqiodyu%pm+gEfM{8?Po(+w$> z^wCSLRiq$Xi#95|YJ=2eqtf9a@)ds$EY)`yCFmml~v$V=>a}Mj9qn^w)D|7P`iUtmC?uLvlc*3G|wReX{@!$A$7zga_N*6)7 zga*+g$no8Z45gruuHs|+4f_3qOpCiC&s|)W%yrc$;st~H{C5uLzU%zWLx;oZ`ja)m zJ-cUGo+-oE=ouQgR4qQj4xdLecZm&z*x*A7CR7%#(m{{3uQ52VnT-D8TJZNHCm9vk zXLw}ONCyfV8bZCA7j9+t?u;H5erqQxk)()v41xzB#LZ zeoFq7#o{fm1BoqP)D1^3yW`Ohgg|#DcW;IfvVkH=@r14YW7*Imt9rswxQsJjRD2w# zQyLd0Oyq3V?eE4?9W6}gt1_`b2ii~tBtbn%3N*LM-C`!Xon5(H(_kTk_NDfZ>&LBO zll~gisI>O(awujndH~Vlni~@*ZL!PV?r4F6!Rg_R_7#EG`m6;0;lA4h>@$~|P+lOK z2?m1`SltL)D;sa6>B#BgY#3Xf1@U)Wqf!eCG#u?%047{Y7Ro8%7?p(95pTN9pJ~JREX=cP3naO3u~0 zgaUm&`ID{=(NhGsDbIP#NyMtvmA@b%Y=7CKR5`LyB7uwx2;m> z-(M`x)#+W~IU3!s&H!%gMxP=R$rBnf>eIX{{!D3q{~Gxy!r81ws~nskaO)dekEt@` zk-*8IHv5ASz;fn$pxz5C!1d5h(xB)Oz?;Jr&dF3r-iLDBF&%4qX8BstEI<*OSUY&V zW&8f!U%uqbOo4vsYGQ*beS+)@O6Z#tHS&5>< zIKQ~J3-7&LR&OXAzmy)oDERbGkg|O@Y~~zi-rv5bSMmrXtcJ3WSLNQ0!yGdDaACbt z`wGYf+>>`6j+bZ&DN+3MR-I0%(kE%wZ%;Rqa-okZovE9*$gevvf{}*}Unr;5={G{r zc!{4dV$fTqVHy7y{U1xGW?C%!jdSOsMi)=B<;^b^TrTd(JnQo4jFOM6DU(WZZ zx#VOCNDz&VSr#yY8|?CFHwf)BZSoPvnvo02&-;v79eYm_o_QC=B`M2>R`5r@ea4&h z^Ld`OO}mcEVz>k|_OvAURAw?VR_#4r{=L?Z@1q@&Mo3uvuhkpIMtQZsCM`G#+zbqB zzMSB$SlJe*@7LZ;>L3m44M_==WhP<((ad$@fx)*9ZujQ+H1+Yo+fnNZ{~mYLe!c^f zT=dn2v4ueA&%lH-Uo)%yLUpg(Jqm_eg;%W%fTt&aklhUxJjZ(R?v@g# zl9H@`l=v&X=)e8^9?`VrE#m+2;{Y3XoBoYFfzTT|mxcD$joB&@tX+gvYQj|g?Hqe! z9PQ~BeOzoGus{r;6@Dle`xfep13o-Ei*Tl29*l&4ar4@oovuOPZuY8w`4G((}utC3HMIUGK`$y3pC zvL7&@p>Mr^J#S*|1wgex{d83G92h!LUSOSnV2g))h@Wf0COJf>`8AnD_%;J`&+06y zq2N2RSds)etJ2<#zmGp?tSw%FL%?MTQtrvhzb^Ud_DEpUsC7Q>QRXMb*LEFn<`cHA zD-8NdHu%xCB_x|k#jFcfUgox;i}!u05jY1Ac07c~=MD1;%5y}Kz_S?`45JC~_ic%M zjg9U{j|3Z?H=m8%#!$z1jp3g28V+O<~j2x^|cr5QQRZdYxepZqJS zuKb@0qwg!ESvpkB1WHF@&-^A`5}QdsQpyrDI1cfM%K+E`(Rp|!V4WX?Hp5$hR}y_5 z!H9-!fiZv++_&0JvQjcIA?$1YROXTX`r54E!<1c52_$|geXTPLT6 zP07^o$qhFl$j1oH7vWt2(U1GBeS5Ppdw9ycvz`*m!vwc#CLj3fKd=6oOc+eRBdaV% zP{;#8;YLak1UsHOVtW4^8OjB6Yde!?AnMN+1Em9_BnFFB=(M(6xXKHn6T^Up*}RHfYq}Yn?PD zl0V#t$g4devIwLEe=WKkiH980D*La>u5Q-K%XJb19==6BrG{!g|LhoeUWHvotbaTM z#Mppvrh+jmBWZ=*%(CI3Cs081-kOgNVZ=+-p)Bd;>f?C1dg)fZ4R(hC9A|OsuP%Kg zp6e#m5VHeA(G2WKT~H$1A`f|B4uj@~p4<~^=M0AZI=rC7u^B^Wu7SGi z@Dx!yXuLDXpalewe9GEqKla6X+@4fu)S_=AGyXnq8+KT?AB~6QT^cL+MIPFtb=F6& z^*ykc@Xzt2C1Gw>AvbG_FLQxizAma{3N%T7K|+fEeCW{$Rvv8`{@9-K|4osd ztA~W?m=sLwh3jtHutNvae|Q9?GR>4j;M}uk2eQ#xdnXI4Olz?X4cfGys-=(%iE_Ok zo{fC@4R*z8BmP4+#}JVJ5(~amTOoT%zmvI%Pw|BLESPS&^o1fJmPW;6bmHL8F0vrn zORyJXhp$aJq{rEGl6G}>qvH15<{ap?fD2VeL8rd-$)3x_4L+pyrW|}>*UZB^!oH*g z_4oaqkuNAW3#it;Wq7qG-37nA^iCt|A*IV#zo^=i0^54=2z5n1=a$ntu@no(zP&p! zHD`fJQiBXKS>Y{c@~sa1TjYC2No1sM68nAEoA6IuUOZqJ%Iaz?xK(kPj<(2ZQKN+! z#r3s5^?PJ)(o0h;@$k#R?UH_r_kiEpOys@{us9z$wIVPS^ANdDIxHjcykX@l(=ape zNTY`%E$=oIx5;VzIcWTDmqXmSCICsM6-k(EEO3^zHCA9IQq*lT+F;evl9=a;8^qHEQo zbxDzuExZF{+weNH_uIs@mNp>ByZZ(dGXEtZ>VW;M+xEBfyLmz+-@mgd+mf3*L6~QgUVNi&n>I1BwOHZktt^c2MjV^_susD4G zYs0qcqkFLfv#h{tL~j_0YVQXaF5P}=@4+5gM;tdS@HWGj1eoWq5EmvNZKFB#HRYsu zgw?SFe&`{W_8mgcI<1McL$Lj^dPrBn-&KKHe&hu^3KcPIdviBtGj^@q=s#drF`RLh zU_1YXbzG(Q_zcsC5u^n$37`j!STV@n@2db2jD_>w$;8Os?<&CD$VUGM#mNR^b}@zd zU%$|#rE&Qn1W@Q9qO1JO)LcN8cFv3(V1=J~0$5OQIWRO4Sgg1I?hGmvLVex+p?K3V zM3FvQ3*ru+Nr6a!NO6Gu2O`x)qsL|Hf-7+#Pia86_pELhR21eTygijjAUx>b@4f5* z$SOo97g7m!mjttv5E1fw&h}P>ghYtA;B|Bt=&bjyg~-EL-~!0AJ;OfcooYL<3%5W|n| zyHWjGmzYOFD-3!MX`~014(oAikHp!jCy5a7M}3uM-&_Q*tGml0AHcXc;5)@Y2?AC) zNH@^_OS~SRBizdT3^19(SX25>e;s^c5!zt{>+{@}qp4)tS<^#!dw)kc3bGA#Hk z_|b6w8*uYI<{YRE4=X$n7Q0`AevT$F;!W_~#@I#+s4uyls)Nh*L|Y~?fiAxi!El_} z03ioP?vv@g&RTqaovvdvR&ac)#QtiY8w^8h1%m3r_I&#uN)}CNGRVZm^Yr*A;}hUT z9wLryz1nsMdJlx9bzLyoMU+mX>xn*>sn#`U7}KQ@{TLBtyb3|Rec7wC;_cD@Mw_7T zd2s8%&*G8)GLML73eJyoCi#kAYN4Ki9N%?!OOWsTO5!GYMBXYKFhG*ky?^idT+$MR z`+~hnr|-XHy1V|o`h~f26l0`VKu60UDj6|Nnzr)%nL?X-1OjbF{}aUsGM`xa=!r3` za}CT6VE#LJn4K0r?CW#3?XQe5_{ZHm(rP9P8+WWaBMto>w4w`|Ij8W4kz&*3|yx?7R6m0>h-?3YEcOE z&=Zi6j?w!H1~22Xb3W5cYi0xm z>5Z3PBDhPwMMSJNkz#aCfeRJBe-NW0UbSbCkRXgi)MAc*^PFj;>uP!s#56s7e=Gau zKLq(%xLWF`rgy@sWc*Vx7Lc`|YTOZg-a_yt@#z4k9zsd{?OZP4RciQSyvas@(*1g+ z#!xL<`(4*pBdg%-Te+|^S@W~8%wL7v_Wn+D`3XdC{8u3lv89OE=T=9gU8)D%)r3JeR8z~V(H zuzZn_WR391GecN4h~F&u_gED+kYdxF)xeD}EDq`B@k5*f(Uz6F`vOg^56k6b;$OpU zLu9u)*CXpagpvLB6kU?54~W8RTlZHh9BHoa+q{N>Y4LGZ*+`DghwJ-u2KX!CFLTnAu?1IiE1Qfp0h(v=2M1_$i8T=iqaeb|4F%}6Ltf!- z#jN6F)mi^CX~b!ub@i>)vIm+r3&70B*rG2~c$rV!f5rP~C0LZ?=U~e^C08=a@!y<5 zQ=nrE8u>^ALO4G=APFu+0&{8JithEds!v@)=YFCiFPGwPBzJe(Iv zt3Ms9>i29@SxI0{mfbj+MqF_9kR}uMkYKG`QVHvBh-BK_FQ1J2gmDb zAy~l4L@pM$0SN1nMXjy96ty9@%p0eAETrU^k`SA7$(_r&|L%(5QdWFeayD~@h6Kko z{&~(J%LJF**EIGw9JP+eZ4nNlvBJLY$PB!=%kz|s<(TL#hAp#S$nrkvr z;{EzkGiG>MDxQfm7V0;*y`dL^xKDHnYb~CF>3)x(9_E7N|2dNOjz1Pv>}rvXw$Lpu zm1@QaYSNO}HFC<|QW%H0NuVq#>Phksa31Q(b2XS-#y35W5Z6hB^Kb{@;U92cZ>Da@ zV>eRVapotC^KW2FTEo0-eqE8KpP`i$>9x6NOi@f3tC}C&5R#<2tG={H!VvZM;tlAN zbEn~((-n+j<;7h>uc(kU+V;>8=c=dc6&Vq(1PfoXM4Y?T(xBHxRzcYk|R4;${j6*MfGowjH64Zsgoe&}GxUO;; z+VuPBsC6y`pBH4Q6`x&bL-eEk6J?wO$xwsz^9d*9bpqKCq9Yd&vAFYo+Nj4`;Jl*& zEgda4xK z`te0i2Vr>2a6`a)YurCiE@xCuU17nLJg4s=wlW${x*Qxzo6yGehXPXqxo;`62Ko4z*E~H;1mp=avOyCeJoyeGhN+K>_jV;3X<7KSjayc4~QM|Q89@ls!7sFt$M?{Tj;mcu&wHYreLZq z*TKc$u=k9$4s$HO3(34(yC=uoFuiX$R?Nk2(y*dK5{r5QSEr;C5) z4Q|{nrK6dNxVvU$eu(HnsTk`Tp-M_G?Ra4fq4l$G>i%#&)K?Wg7kgQ@Ma*p4F5ru& zkqoze?c7eiMIYa1MuP06C%n9oIcp2mz;+z3B-cDx~Hcn;6phzPXx70@}MkpiAnhVLI8cYRES_m4hUTY_2P{s>JH zARkRe+wxiDf*?N0$y03KN0fr1x__uw5r;Q4BsugY9jq?>+>pz@@#KLdJ$q61%|{)w z)tno#AqJOZkCox?QvGyPQ@!|)!U5VCOJ=Op7KyZ%skVjJbE3Bzz zV%I|<&|1GiyUOJWR#wUFQog$}Qr~0j=y<>;i+z3`MWy_%8w**6_Bt1!5r#^4vW-Ajat*1TY1DvrQ~krp<1_&dV6=3JP9@`c)R zUA8Lf^IoK=jXyX`JdPOYhzCW=$M|NX10EK#Sb4`MrC5cwRFIxtg=|1T^s>YdB~y*3 zuWrZ!OYb7ZqD&1*5w*HXpf4~Ja-WPnZF2sT0(j`JKRD4x{4reMkLfiPi*P&ON_`aQ zFIBetib9_vzcpCJg!9owhF1#Z;5-B5=t!;~bW^XaDf%tJF3XS0P#KV6y!yHhptO)b zZjix2-2N=d7Lky*qYZy{J)QH9sh8I#?O4HCw$H(Big))9b z2(UgGIAfI>fd{(i3Tud8(l+-x5PD6BF!Y7_{6i|b?}0;_Vqob(7o80st4Z2IRHZ0v zNIkzf&~7m)%t^~l8^X8nL)wUO?dL&9x@;h^Cv(}{;YTl#ngf4h|FJ1km}7#xF;Nju zAfuS=6Eb9`5y)RPe$~g|DPrJUNbW1y3^oM*1}62Ta{poY8bG0vnsZ=sjMlVRCgxX( z5P{|zJtiHQ;9c;7v<9mE272nIQmB@JPc;*uDNQ z+T%G-z9vM_R8m%!8W7&R@gz~9%`3m0LidhdHE(LjGwAJ1SUpL5$NYO)YjX!ZY$qmb z9b@4a!6Xgwq}i47mP+gU;AL}Cv>-*oSw^5FC{}cdh!2~kLzc96jI<4xxS+x>x5&pR z)mR*70nSg~Hj8V_1ajl(ZITH(GkFY{#dGVA5GH{LE~QExzawOBo@YSEp1+DSQjM(i zLG=b_n|6ZkoyD;{U~0sa1=by0N%t>}JbEST`iu$eXb}z`h0dI}|BFb^Uev&VJVUx+ zeZLQ-QfOpi;x&RCT4;Qt#JK4<3r+&HG|VHMdPv~9)xHv#r-gpy)8&x&pWC{u^SoSm%Br5QLOsv(sDfsg6VnJb{vAFl=_QMlp z$2u&VJr=N+#ujcZ6}$g#bRc%Fq476k^&)MYd3g2m=5rZt#tjGquf)oEyoS&7`X|F& z?E8hPo>(mn1K8nH`%oxCzE!ye&DKw1HfIp_gN+w9>J!Ng=%!2-QG83=b)OZ46I&v!SR!YGbmbU4NHJ z#2x2|kdMm}4eDF;Rr({!#517XR2h?f*EzGr0K56Q>1J_;)^b1F>@>7Nbh|e8Av&^@W3SJ`bPW70(4_u(n6J>_`%KSTg>cg8bzIVYbA_RHa12u6au|>VPaLy>gGaeP zyIvvdQurBSMQWa-;nh`0A70)rx(6N5}eVMpSAJ`u4 z>;L(k0fjKckqtxNT7W+f@39#RKbPx0P3eaT>)HYvv$xsQ&IHP_7_%I2SJA~=!QXXR zq+2Xhwp=}l<>-H;@>@H3&%C1Qy|AYWO|oDqr5I|6uYq+N94^Zk=HgW5QWw6E2GGK$ zJ`1>0qjy9>MaA*5@1Iavm5|17a@+?ft`BGZ5)ls2)#H?%+zJiU8}uUkTpy&%!>Tam z{+nO9fD)^x218-;XgZz`)RD}L6+o?2>D>vU$ zjvnS?WuL64VQNF(Jw*~M*~|A%R@^MhdrU+*zWZ(V2vM0%&g*zVO1>c$qb@88LdIrZ z`I0p|4`hjJmMO(wOsh~TMP!d@q$q1Awh`J_p z!{S1lF;bFZ;Lkk$6)FvC01tSDL*sizd*JZKrbzRgR4VqBfR;e{D5QELfhv#&(Y#fdAa1nXyv7z z#YcKLbcaIRp-oc3W&yH%+2OSxM>bh=Aip!c^{3bBAU8(xcy9VfL7tCOeI1!68YZ_( z+xSen*h@) zwMV+Kh`*2owRL>@EC?bzV(Wt*8V?G#RxDMxsExZF4gIJ4KT1%n=D7Ix>kRQpd=nVO zi}ZIYl1NFrkHkh4cD<2I@w9dV+x9=$?~EKy z6IPeAhGG}r(y=Hssr78xT}n>+53^Mhc(Hzx66=%#Z7HYTL}Q(V$0M%QDy7?4->iR< zm=iU7yP%Q~USgUwB87q3v!9h27SCO{c!VAZh8`7dX-CN{X)8Z;PWBmT7^jj7lK)TC zPgstBP)lwTI?_|y!RZi5S(}QKJ|+COXG>ljBB5Sf+<*!B>82KBY{Q4I3Zz&@RIsGQ zXj2Ui44xYVSSrl3;KWETf zF`1ir8UvNQki6w*JKMcysb|P40o5cELjp zEmG+Zd)df|^RQ-jgjGJXI*gwEIF*^zfjqRQc!T7v!FhKHMOr zhqLeYE==ibYA>UAuH4Y@p=4;B-}heT0uuZuSFN=W_|3!c_OSfyR~W~^3&0wIA7Vjz z`MbXhPe6i^lJ8SZZTzF=T}h&GxA=T&UCTZ^BrlHaC8i)hW-zAUq8$En__vYw!<%C1 zCXRXMxl@F2@AU)nCtCrMx6CAps3g9T`29zhJB$4MZ`05sglB;F19LLx=7c&>P+%J& zWrt0z`mb8KLY7?=;w8h6Wi=M>#NFFT1Y@-(kXRJ5`hoq}*OY%+)K=`(lrO%*Zy#K? z;}jM*J2aba!5C=nrMN5Bk*5`opKxsZ!Nw96r|6*8r5(gb%`N{6yz*1 z1vcjEx9M{~ufLD;AEjJ&tVY%kx#D=l8nP`At4LQ+xlX9zfo$-Q=D!6AH`c?*VYvnD zAu~@SNZ{#^lGR|2Fy;%f$&gs+qT6$952AYUljj!fO`o%v6=CJ@X7rDFe{;L0^Hcv& zBG;Yb1UR0~)umZCFbl|hmR{H%wFhQMPfwa`x9s9?248Zw%Yukj)vprUUUIzg9Nbh^ zrBPw`sIYBasu3D)=aQ|UeNTs4`MUXkD+%n5Wl(AKmp*oQ!;FNEZyy^HvZQuvU3k;~ z{d>x(|H?e;XuA9(5Y7V!R>KI#a2aEWpU=eKKW*SjptY1T%Yz7IKhAPqU&X!1MzoO$TI*3 z?jLa-%4V$4MVTf=n>7V-%hej5u1x&kemZ5^yVY#_@4jU}V9oe>-GP`n^BCNYwjDUQ z%kV?h-Hg%`U2TVXlOA|%j_6DJvB6b_$CCp%H*j<($AR+;l0)m#4xVOMD6_Po7MRuw z3QZ2KJbho-Zua?mKbr4%#k^6pxcS2ZGFPiFz38bV)z5Kqq=;n8P@BT zrBpR>EWHif&)bv0ES7V|YDSV$`?DDih8;@Xht~gS{co?%^I4pW$J-is$OMC@tDnm{ Hr-UW|N@?;R diff --git a/3-launcher/icon.png b/3-launcher/icon.png index bb99bf34dc68083f957a178aa664f1b6a8adf3e1..f11ac8615fe3ab865d5673348c3b15ac6f2282b6 100644 GIT binary patch literal 2772 zcmeAS@N?(olHy`uVBq!ia0y~yU;;9k7&zE~)R&4Yzkn2Hfk$L90|Vb-5N14{zaj-F zC|TkfQ4*Y=R#Ki=l*&+EUaps!mtCBkSdglhUz9%kosAR&16QJ_i(^Q|oVPd5uZk^~ zJpS;0T=o28YNpTRr?pAAM)P!au})oeq`KgNhdQ6kcdtENah|!lVmSd_OIB*M+zQHV z&e+meT(qtHq4f`&^P)BE*&FR%-`)G|)!oNkR`&7B^Zz`2c=8KhT8xF|pV!ar|K5B0 zQnt8n{+|C24ohFwUM6$>*AMgWa(4E6n>CNy-``pL_jLB!H|7bm1IsX1u={%4-s(AWhEFSEmjAE#@*|~+-FRE> z@9({<#qI6)GONw8wf+C#qW%Bs?5g7%E^iI{Cj9^yG9x8)a3z8ZiB$)d;Z*o{d4cj#>apOFMj{u z$LyDl6OKHeXSwEm{pV+2dII0y`JZ9??@dY7F$wVzo^?T?$XA{hKl`4+vkmvJZPgZE zo^Ft`|83aMpX+bu?=JoOYUxYK%&F9aLzw`*U|J`=)?`w5nVzl}G=H#xrua~~` z7~b9%UB17%y6V`9@^|%HbP0l+XkKDd09B literal 31464 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 R0dJ)SsjFziDwQl>{||8isA2#B diff --git a/3-launcher/launcher.pyw b/3-launcher/launcher.pyw index b7e9959..22b952f 100644 --- a/3-launcher/launcher.pyw +++ b/3-launcher/launcher.pyw @@ -1,5 +1,5 @@ -### SSTools4MC Launcher ### -########################### +#### SSTools4MC Launcher #### +#### DEVELOPED BY NGDPLNK #### import requests import os @@ -7,7 +7,7 @@ import locale from tkinter import messagebox APPDATA = os.environ.get("APPDATA") -PROGRAM_PATH = os.path.join(APPDATA, "TLSoftware", "SSTools4MC") # type: ignore +PROGRAM_PATH = os.path.join(APPDATA, "SSTools4MC") # type: ignore ASSETS_PATH = os.path.join(PROGRAM_PATH, "assets") CODE_PATH = os.path.join(PROGRAM_PATH, "main.py") ICON_PATH = os.path.join(PROGRAM_PATH, "assets", "icon.ico") @@ -28,18 +28,12 @@ try: icon = requests.get("https://raw.githubusercontent.com/ngdplnk/SSTools4MC/main/1-release/icon.ico") with open(ICON_PATH, 'wb') as writeicon: writeicon.write(icon.content) - if os.name == 'nt': # Windows - os.system(f"start cmd /c python {CODE_PATH}") - else: # Linux and other Unix-like systems - os.system(f"gnome-terminal -- python3 {CODE_PATH}") + os.system(f"start cmd /c python {CODE_PATH}") except Exception: if os.path.isfile(CODE_PATH): - if os.name == 'nt': # Windows - os.system(f"start cmd /c python {CODE_PATH}") - else: # Linux and other Unix-like systems - os.system(f"gnome-terminal -- python3 {CODE_PATH}") + os.system(f"start cmd /c python {CODE_PATH}") else: - if system_lang.startswith('Spanish') or system_lang.startswith('es'): + if system_lang.startswith('es') or system_lang.startswith('Spanish'): messagebox.showerror("Error", "Conéctate a internet para obtener la última versión de SSTools4MC.") else: messagebox.showerror("Error", "Connect to the internet to get the latest version of SSTools4MC.") \ No newline at end of file diff --git a/LICENSE b/LICENSE index ffbdf22..ac88cbb 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2023 NGDPL Nk +Copyright (c) 2021-2024 ngdplnk Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 5b067e5..58f9d56 100644 --- a/README.md +++ b/README.md @@ -128,4 +128,4 @@ Credits to [Alfredo Creates on Flaticon for creating the icon used in SSTools4MC Thank you for using SSTools4MC! -Licensed under [MIT License](https://opensource.org/license/mit) - Copyright © 2024 @ngdplnk +Licensed under [MIT License](https://opensource.org/license/mit) - Copyright © 2024 ngdplnk diff --git a/SECURITY.md b/SECURITY.md index f846ba4..60a752d 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -33,6 +33,7 @@ Are this versions supported? - PRE-v1.0 → :x: - v1.0 → :x: - v1.1 → ✔️ +- v1.2 → ✔️ ## License and Copyright All tools in this repository are distributed under the MIT License. Please refer to the LICENSE.md file for complete details on the terms of the license and copyright. @@ -42,4 +43,4 @@ This security policy will be reviewed and updated periodically to ensure it alig Thank you for contributing to the security of our project. Your collaboration is essential to maintaining a safe and reliable environment for all users of our Minecraft server tools. -©2024 - TLSoftware - NGDPL Nk +Copyright © 2024 ngdplnk