MineColabImproved Ipynb
MineColabImproved Ipynb
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "view-in-github",
"colab_type": "text"
},
"source": [
"<a
href=\"https://colab.research.google.com/github/N-aksif-N/MineColab_Improved/blob/
free-config/MineColabImproved.ipynb\" target=\"_parent\"><img
src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In
Colab\"/></a>"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "fw-Co7bC4Y9Y"
},
"source": [
"<p>\n",
" <img style=\"display: block; margin-left: auto; margin-right: auto;\"
src=\"https://raw.githubusercontent.com/N-aksif-N/MineColab/master/minecolab.png\"
alt=\"\" width=\"170\" height=\"136\" />\n",
"</p>\n",
"\n",
"<h1 style=\"text-align: center;\">\n",
" <span style=\"color: #00ffff;\">MineColab</span>\n",
"</h1>\n",
"\n",
"<hr />\n",
" <h2 style=\"text-align: center;\">\n",
" <span style=\"color: #99ccff;\">Forked By N-Aksif</span>\n",
" </h2>\n",
"\n",
" <h2 style=\"text-align: center;\">\n",
" <span style=\"color: #FFFFFF;\">Run Minecraft Server On Google
Colab</span>\n",
" </h2>\n",
" </span>\n",
" </h2>\n",
" <a href=\"https://github.com/N-aksif-N/MineColab/tree/main\"
target=\"_parent\"><img src=\"https://img.shields.io/badge/github-%23121011.svg?
style=for-the-badge&logo=github&logoColor=white\" align=\"right\" alt=\"Open In
Github\"></a>\n",
" <!-- Badges: https://ileriayo.github.io/markdown-badges/ -->"
]
},
{
"cell_type": "markdown",
"metadata": {
"colab_type": "toc",
"id": "_WIUEffnqCjt"
},
"source": [
">[🔥 Starting](#scrollTo=Ei7_3ODcUdm_)\n",
"\n",
">[▶ or 🛑 Console](#scrollTo=JMgdsuPcUuEv)\n",
"\n",
">[⚓ Options](#scrollTo=HD4lBUT9RcS-)\n",
"\n",
">[📎 Log](#scrollTo=hfUxmQTgUF8Z)\n",
"\n",
">[📰 Software](#scrollTo=JkGq3KakW-Bc)\n",
"\n",
">[🎈 Plugins, mods](#scrollTo=QaNRBRuK8seq)\n",
"\n",
">[📁 File Management](#scrollTo=F7efc3oOqTVQ)\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "ieiauFISqV0_"
},
"source": [
"----"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"cellView": "form",
"id": "FsUiL7tzc4Cp"
},
"outputs": [],
"source": [
"# @markdown ##**[❗] Set up** {display-mode: \"form\"}\n",
"\n",
"# @markdown Check out [wiki of this project](https://github.com/N-aksif-
N/MineColab_Improved/wiki) for more explanations\n",
"from requests import get\n",
"from time import sleep\n",
"from json import load, dump\n",
"from os.path import exists\n",
"from os import makedirs\n",
"from IPython.display import clear_output\n",
"%pip install -q jproperties\n",
"%pip install -q rich\n",
"from rich import print\n",
"%pip install -q pyngrok\n",
"%pip install -q BeautifulSoup4\n",
"%pip install -q ruamel.yaml\n",
"if exists('/content/drive') == False:\n",
" from google.colab import drive\n",
" drive.mount('/content/drive')\n",
"drive_path = '/content/drive/MyDrive/minecraft'\n",
"SERVERCONFIG = f'{drive_path}/server_list.txt'\n",
"#---------------------------------------------------------------------------------
---------------------------------------------------#\n",
"def LOG(*args, sep=''):\n",
" check = False\n",
" args = list(args)\n",
" for i in range(len(args)):\n",
" args[i] = str(args[i])\n",
" if '\\n' in args[i]: args[i] = args[i].replace('\\n', '');
args.insert(0, '\\n[bold green][ LOG ][/bold green] '); check = True; break\n",
" if check == False: args.insert(0, '[bold green][ LOG ][/bold green] ')\
n",
" print(sep.join(map(str, args)))\n",
"def ERROR(*args, sep=''):\n",
" %cd $drive_path\n",
" clear_output()\n",
" check = False\n",
" args = list(args)\n",
" for i in range(len(args)):\n",
" args[i] = str(args[i])\n",
" if '\\n' in args[i]: args[i] = args[i].replace('\\n', '');
args.insert(0, '\\n[ ERROR ] '); check = True; break\n",
" if check == False: args.insert(0, '[ ERROR ] ')\n",
" raise Exception(sep.join(map(str, args)))\n",
"def INFO(*args, sep=''):\n",
" check = False\n",
" args = list(args)\n",
" for i in range(len(args)):\n",
" args[i] = str(args[i])\n",
" if '\\n' in args[i]: args[i] = args[i].replace('\\n', '');
args.insert(0, '\\n[bold blue][ INFO ][/bold blue] '); check = True; break\n",
" if check == False: args.insert(0, '[bold blue][ INFO ][/bold blue] ')\
n",
" print(sep.join(map(str, args)))\n",
"def MKDIR(path):\n",
" try:\n",
" makedirs(path, exist_ok = True)\n",
" LOG(f'Directory {path} created')\n",
" except: ERROR(f'Directory {path} already existed')\n",
"\n",
"def GET(url):\n",
" r = get(url)\n",
" # Check gate\n",
" if r.status_code == 200:\n",
" return r\n",
" else: ERROR('Error '+ str(r.status_code) + \"! Most likely you entered
an unsupported version. Try running the code again if you think that shouldn't have
happened.\")\n",
"def DOWNLOAD_FILE(url, path, file_name):\n",
" # Check gate\n",
" if exists( path+ '/' + file_name): LOG(f'File {file_name} already
existed')\n",
" else:\n",
" # Download file into file_name thourgh url\n",
" r = GET(url)\n",
" LOG('\\nDownloading ' + file_name)\n",
" with open(path + '/' + file_name, 'wb') as f:\n",
" f.write(r.content)\n",
"\n",
"def COLABCONFIG(server_name):\n",
" return f\"{drive_path}/{server_name}/colabconfig.txt\"\n",
"def COLABCONFIG_LOAD(server_name):\n",
" if exists(COLABCONFIG(server_name)): return
load(open(COLABCONFIG(server_name)))\n",
" else: ERROR('Please checking whether you deleted your colabconfig file
or not.')\n",
"\n",
"def SERVER_IN_USE(server_name):\n",
" if exists(f'{drive_path}/{server_name}') and server_name != '': return
server_name\n",
" else:\n",
" serverconfig = load(open(SERVERCONFIG))\n",
" if serverconfig['server_in_use'] != '': return
serverconfig['server_in_use']\n",
" else: ERROR('Please create a minecraft server first!')\n",
"# The jar file name\n",
"def JAR_LIST_RUN(server_version):\n",
" return {'generic': 'server.jar', 'vanilla':'server.jar','snapshot':
'server.jar', # NORMAL\n",
" 'purpur' : 'server.jar', 'paper': 'server.jar', 'velocity' :
'server.jar', # PLUGINS\n",
" 'fabric' : 'server.jar', # forge doesn't include in this
category # MODS\n",
" 'arclight' : 'server.jar', 'mohist': 'server.jar', 'banner':
'server.jar'} # HYBRID\n",
"\n",
"#---------------------------------------------------------------------------------
---------------------------------------------------#\n",
"\n",
"!sudo apt update &>/dev/null &&echo 'apt cache successfully updated' ||
echo \"apt cache update failed, you might receive stale packages\"\n",
"!sudo apt upgrade &>/dev/null &&echo 'apt cache successfully upgraded' ||
echo \"apt cache upgrade failed, you might receive stale packages\"\n",
"!export DISPLAY=:0.0\n",
"if exists(drive_path) == False:\n",
" !mkdir -p $drive_path &>/dev/null&\n",
" sleep(40)\n",
"if exists(SERVERCONFIG) == False:\n",
" dump({\"server_list\": [], \"server_in_use\": \"\", \"ngrok_proxy\" :
{'authtoken' : '', \"region\" : ''}, \"zrok_proxy\": {\"authtoken\": ''},
'localtonet_proxy': {\"authtoken\": ''}, 'localxpose_proxy': {\"authtoken\": ''}},
open(SERVERCONFIG, 'w'))\n",
"%cd $drive_path\n",
"LOG('Completed')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"cellView": "form",
"id": "uRz1WuKUk5zw"
},
"outputs": [],
"source": [
"# @markdown ####**Choosing minecraft server**\n",
"# @markdown ##### Helping to set the defualt server_name.\n",
"from os import listdir\n",
"from json import load, dump\n",
"from os.path import exists\n",
"%cd $drive_path\n",
"\n",
"serverconfig = load(open(SERVERCONFIG))\n",
"if serverconfig['server_list'] == []: ERROR(' Creating your minecraft
server before choosing')\n",
"else:\n",
" LOG('\\nAivailable servers:\\n')\n",
" for server in listdir(drive_path):\n",
" if server != 'server_list.txt' and server != 'logs':\n",
" INFO(server)\n",
" server = input('Your minecraft server: ')\n",
" if exists(f'{drive_path}/{server}') == False: ERROR('You choose the
wrong server choose again')\n",
" if server in serverconfig['server_list']: serverconfig['server_in_use']
= server\n",
" else: serverconfig['server_list'].append(server);
serverconfig['server_in_use'] = server\n",
" dump(serverconfig, open(SERVERCONFIG, 'w'))\n",
" LOG('Completed')"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "isidTr9WdOpz"
},
"source": [
"---"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "Ei7_3ODcUdm_"
},
"source": [
"# 🔥 **Starting**\n",
"---\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"cellView": "form",
"collapsed": true,
"id": "2SXjmXvf4vn0"
},
"outputs": [],
"source": [
"from requests import get\n",
"from bs4 import BeautifulSoup\n",
"from time import sleep\n",
"from os.path import exists\n",
"from json import load, dump\n",
"drive_path = '/content/drive/MyDrive/minecraft'\n",
"SERVERCONFIG = f'{drive_path}/server_list.txt'\n",
"\n",
"# @markdown ####**Create your server file**\n",
"server_name = \"\" # @param {type:\"string\"}\n",
"server_type = \"vanilla\" # default server type -- Please don't change
this !!\n",
"# Change to empty strings to get the full list of avalable version\n",
"# Remember to set the versions variable in install server function to
'vanilla - latest_version'\n",
"# if you wanna to install the latest server.jar\n",
"version = 'vanilla - latest_version' # Defualt: = 'vanilla -
latest_version'\n",
"# @markdown ####Standard tunnel services ( Available tunnels: [ngrok]
(https://ngrok.com/), [cloudfare-argo](https://www.cloudflare.com/) or [zrok.io]
(https://zrok.io/) or [playit.gg](https://playit.gg/) and
[localtonet](https://localtonet.com))\n",
"tunnel_service = 'ngrok' #@param ['ngrok', 'argo', 'zrok', 'playit',
'localtonet', 'localxpose']\n",
"\n",
"# GUIDANCE\n",
"choice = input('Do you want to show(s)/hide(h) tunnels info? - ')\n",
"if 's' in choice: clear_output(); print(\"\\n\\n-
**[Ngrok](https://ngrok.com)**\\n + Follow the prompts.\\n + The IP will change
whenever you restart the server.\\n\\n- **[Cloudflare's
argo](https://www.cloudflare.com/)** :\\n - If the 'Your free tunnel has
started!' notification appears => Done.\\n - Access to your server:\\n 1.
Download [Cloudflared
client](https://github.com/cloudflare/cloudflared/releases/).\\n 2. Launch the
binary with `<your Cloudflare file name> access tcp --hostname <tunnel_address> --
url 127.0.0.1:25565` (note: tunnel_address is your address which has been set on
your Cloudflare).\\n 4. Finally, connect to `127.0.0.1:25565` from the minecraft
client which is located in that machine.\\n\\n-
**[Localtonet](https://localtonet.com/)**:\\n 1. Navigate to
[TCP-UDG](https://localtonet.com/tunnel/tcpudp) page. Select TCP in Protocol
Types.\\n 2. Get your authtoken from
[Authtoken](https://localtonet.com/usertoken).\\n 3. Pick the server you'd like
your tunnel to operate on.\\n 4. Input the IP and Port values the tunnel will
listen to, in this case, for Minecraft, it's typically IP: 127.0.0.1 and Port:
25565.\\n 5. Finally, create and start your tunnel by pressing the Start button.\\
n - Read more on
[how-to-use-localtonet-with-minecraft](https://localtonet.com/documents/using-
localtonet-with-minecraft)\\n\\n- **[Zrok](https://zrok.io/)**:\\n 1. Download the
zrok app through [link](https://docs.zrok.io/docs/getting-started/)\\n 2. Open the
shell. Type `zrok invite` to sign up and get the authtoken\\n 3. Follow the
prompts\\n 4. Acess to https://api.zrok.io to get fully management\\n - Read
more on https://docs.zrok.io/docs/getting-started. \\n\\n-
**[PlayIt](https://playit.gg/)**: follow the prompts.\"); sleep(20)\n",
"clear_output()\n",
"\n",
"#---------------------------------------------------------------------------------
- SNALL FUNCTION
-----------------------------------------------------------------------------------
-#\n",
"\n",
"def SERVERSJAR(server_type, version, all = False, jar = False):\n",
" #Get the download URL (jar) AND return the detailed versions for each
software (all)\n",
" if all:\n",
" Server_Jars_All = {\n",
" 'paper': 'https://api.papermc.io/v2/projects/paper', 'velocity':
'https://api.papermc.io/v2/projects/velocity',\n",
" 'purpur': 'https://api.purpurmc.org/v2/purpur',\n",
" 'mohist': 'https://mohistmc.com/api/v2/projects/mohist', 'banner':
'https://mohistmc.com/api/v2/projects/banner'\n",
" }\n",
" if server_type == 'vanilla' or server_type=='snapshot':\n",
" rJSON =
GET('https://launchermeta.mojang.com/mc/game/version_manifest.json').json()\n",
" if server_type == 'vanilla': server_type = 'release'\n",
" if version != 'vanilla - latest_version': server_version =
[hit[\"id\"] for hit in rJSON[\"versions\"] if hit[\"type\"] == server_type]\n",
" else:\n",
" return rJSON['latest']['release']\n",
"\n",
" elif server_type == 'paper' or server_type == 'velocity' or
server_type == 'purpur' or server_type == 'mohist' or server_type == 'banner':\n",
" rJSON = GET(Server_Jars_All[server_type]).json()\n",
" server_version = [hit for hit in rJSON[\"versions\"]]\n",
"\n",
" elif server_type == 'fabric':\n",
" rJSON = GET('https://meta.fabricmc.net/v2/versions/game').json()\n",
" server_version = [hit['version'] for hit in rJSON if hit['stable']
== True]\n",
"\n",
" elif server_type == 'forge':\n",
" rJSON =
GET('https://files.minecraftforge.net/net/minecraftforge/forge/index.html')\n",
" soup = BeautifulSoup(rJSON.content, \"html.parser\")\n",
" server_version = [tag.text for tag in soup.find_all('a') if '.' in
tag.text and '\\n' not in tag.text]\n",
"\n",
" else:\n",
" LOG('Before going deeper, please check out
https://github.com/IzzelAliz/Arclight')\n",
" rJSON =
GET('https://files.hypoglycemia.icu/v1/files/arclight/minecraft').json()['files']\
n",
" server_version = [hit['name'] for hit in rJSON]\n",
" return server_version\n",
"\n",
" elif jar == True and version != None:\n",
" # RETURN DOWNLOAD URL\n",
" if server_type == 'vanilla' or server_type=='snapshot':\n",
" rJSON =
GET('https://launchermeta.mojang.com/mc/game/version_manifest.json').json()\n",
" if server_type == 'vanilla': server_type = 'release'\n",
" for hit in rJSON[\"versions\"]:\n",
" if hit[\"type\"] == server_type and hit['id'] == version:\n",
" return GET(hit['url']).json()[\"downloads\"]['server']['url']\
n",
"\n",
" elif server_type == 'paper' or server_type == 'velocity':\n",
" build =
GET(f'https://api.papermc.io/v2/projects/{server_type}/versions/{version}').json()
[\"builds\"][-1]\n",
" jar_name =
GET(f'https://api.papermc.io/v2/projects/{server_type}/versions/{version}/builds/
{build}').json()[\"downloads\"][\"application\"][\"name\"]\n",
" return
f'https://api.papermc.io/v2/projects/{server_type}/versions/{version}/builds/
{build}/downloads/{jar_name}'\n",
"\n",
" elif server_type == 'purpur':\n",
" build = GET(f'https://api.purpurmc.org/v2/purpur/{version}').json()
[\"builds\"][\"latest\"]\n",
" return
f'https://api.purpurmc.org/v2/purpur/{version}/{build}/download'\n",
"\n",
" elif server_type == 'mohist' or server_type == 'banner':\n",
" return
GET(f'https://mohistmc.com/api/v2/projects/{server_type}/{version}/builds').json()
[\"builds\"][-1][\"url\"]\n",
"\n",
" elif server_type == 'fabric':\n",
" installerVersion =
GET('https://meta.fabricmc.net/v2/versions/installer').json()[0][\"version\"]\n",
" fabricVersion =
GET(f'https://meta.fabricmc.net/v2/versions/loader/{version}').json()[0]
[\"loader\"][\"version\"]\n",
" return \"https://meta.fabricmc.net/v2/versions/loader/\" + version +
\"/\" + fabricVersion + \"/\" + installerVersion + \"/server/jar\"\n",
"\n",
" elif server_type == 'forge':\n",
" rJSON =
GET(f'https://files.minecraftforge.net/net/minecraftforge/forge/index_{version}.htm
l')\n",
" soup = BeautifulSoup(rJSON.content, \"html.parser\")\n",
" tag = soup.find('a', title=\"Installer\"); tag = str(tag); tag =
tag[tag.find('\"') + 1 :]\n",
" link = tag[:tag.find('\"')]; link = link[link.find('=') + 1:]; link
= link[link.find('=') + 1:]\n",
" return link\n",
"\n",
" else:\n",
" rJSON =
GET(f'https://files.hypoglycemia.icu/v1/files/arclight/minecraft/{version}/
loaders').json()\n",
" LOG('Available type: '); print([hit['name'] for hit in
rJSON['files']])\n",
" build = input(' Type: '); choice = input('Stable(st) or
Snapshot(sn): ')\n",
" if 'sn' in choice.lower(): choice = 'latest-snapshot';\n",
" else: choice = \"latest-stable\";\n",
" return
f'https://files.hypoglycemia.icu/v1/files/arclight/minecraft/{version}/loaders/
{build}/{choice}'\n",
" else: ERROR('Wrong given arguments')\n",
"\n",
"#---------------------------------------------------------------------------------
- MAIN CODE
-----------------------------------------------------------------------------------
-#\n",
"\n",
"# Auditing whether file is existed.\n",
"if exists(f'{drive_path}/{server_name}') == False:\n",
" # Create folder\n",
" MKDIR(f'{drive_path}/{server_name}')\n",
" LOG('Wait for 40 seconds')\n",
" sleep(40)\n",
" # Get version\n",
" if version == '':\n",
" # Print available version => get version (string variable)\n",
" LOG(f'Latest versions/builds for {server_type}')\n",
" server_version = SERVERSJAR(server_type, version, all = True)\n",
" print('\\n Available version/builds:\\n', server_version)\n",
" version = input('Server versions: ')\n",
" while version == '':\n",
" LOG(\"Invalid versions\")\n",
" print('\\n Available version/builds:\\n', server_version)\n",
" version = input('Server version: ')\n",
" version = version\n",
" elif version == 'vanilla - latest_version': version =
SERVERSJAR(server_type, version, all = True)\n",
"\n",
" # Load serverconfig\n",
" serverconfig = load(open(SERVERCONFIG))\n",
" serverconfig['server_list'] += [server_name]\n",
" serverconfig['server_in_use'] = server_name\n",
" if serverconfig['ngrok_proxy'] ==
{\"authtoken\": \"\", \"region\": \"\"} and tunnel_service == 'ngrok':\n",
" LOG('Get your authtoken from
https://dashboard.ngrok.com/get-started/your-authtoken')\n",
" serverconfig['ngrok_proxy']['authtoken'] = input('Your authtoken: ')\
n",
" LOG('Available Regions:', ' ap - Asia/Pacific (Singapore)', ' au -
Australia (Sydney)', ' eu - Europa (Frankfurt - Germany)', ' in - India (Mumbai)',
' jp - Japan (Tokyo)', ' sa - America (São Paulo - Brazil)', ' us - United States
(Ohio)', sep='\\n')\n",
" serverconfig['ngrok_proxy']['region'] = input('Region: ')\n",
" elif tunnel_service == 'zrok' and serverconfig['zrok_proxy'] ==
{'authtoken': ''}:\n",
" # Settings variable\n",
" serverconfig['zrok_proxy']['authtoken'] = input('Your zrok token: ')\
n",
" elif tunnel_service == 'localtonet' and serverconfig['localtonet_proxy']
== {'authtoken': ''}: LOG('Get your authtoken from
https://localtonet.com/usertoken'); serverconfig['localtonet_proxy']['authtoken'] =
input('Your localtonet token: ')\n",
" elif tunnel_service == 'localxpose' and serverconfig['localxpose_proxy']
== {'authtoken': ''}: LOG('Get your authtoken from
https://localxpose.io/dashboard/access'); serverconfig['localxpose_proxy']
['authtoken'] = input('Your localxpose token: ')\n",
" dump(serverconfig, open(SERVERCONFIG, 'w'))\n",
" # Set up colabconfig\n",
" colabconfig = {\"server_type\": server_type, \"server_version\":
version, \"tunnel_service\" : tunnel_service}\n",
" dump(colabconfig, open(COLABCONFIG(server_name),'w'))\n",
" # Download jar file\n",
" if server_type == 'forge': jarname = 'forge-installer.jar' # The jar
file name (forge need a special process)\n",
" else: jarname = JAR_LIST_RUN(version)[server_type]\n",
" DOWNLOAD_FILE(url= SERVERSJAR(server_type, version, jar = True), path =
f\"{drive_path}/{server_name}\", file_name= jarname)\n",
" sleep(40)\n",
" LOG('\\nCompleted!')\n",
"else: ERROR('Lol, you have already installed this server file')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"cellView": "form",
"id": "ElfueDQX0Bex"
},
"outputs": [],
"source": [
"from os.path import exists\n",
"from time import sleep\n",
"from json import load, dump\n",
"# @markdown ####**Delete server**\n",
"server_name = '' # Get default server\n",
"\n",
"serverconfig = load(open(SERVERCONFIG));\n",
"if server_name == '': server_name = serverconfig['server_in_use']\n",
"if serverconfig['server_list'] == []: ERROR(\"You haven't installed
yet.\")\n",
"else:\n",
"\n",
" # Auditing whether file is existed.\n",
" if exists(f'{drive_path}/{server_name}') == False: ERROR(\"You haven't
installed yet.\")\n",
" LOG(f'Deleting {server_name}...')\n",
"\n",
" # Delete folder without noticable\n",
" !rm -rf \"{drive_path}/{server_name}\" >/dev/null\n",
"\n",
" # Remove the folder name in server config txt files\n",
" serverconfig['server_list'].remove(server_name)\n",
" if serverconfig['server_in_use'] == server_name:\n",
" try: serverconfig['server_in_use']= serverconfig['server_list'][0]\n",
" except: serverconfig['server_in_use'] = ''\n",
" dump(serverconfig, open(SERVERCONFIG, 'w'))\n",
"\n",
" LOG('Wait for a while.')\n",
" sleep(40)\n",
" LOG('Completed')"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "jii1sC2uUWvk"
},
"source": [
"-----------------------------------------------------"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "JMgdsuPcUuEv"
},
"source": [
"# ▶ **or** 🛑 **Console**\n",
"---\n",
"The main console for your minecraft server"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "lqtMoYg0dUmu",
"cellView": "form"
},
"outputs": [],
"source": [
"# @markdown\n",
"from os import pathsep, environ\n",
"from os.path import exists, join, expanduser\n",
"from pyngrok import conf, ngrok\n",
"from IPython.display import clear_output\n",
"from json import loads\n",
"from ruamel.yaml import YAML\n",
"yaml = YAML()\n",
"\n",
"# Variables\n",
"server_name = ''\n",
"server_name = SERVER_IN_USE(server_name)\n",
"colabconfig = COLABCONFIG_LOAD(server_name)\n",
"serverconfig = load(open(SERVERCONFIG))\n",
"_type = colabconfig[\"server_type\"]\n",
"version = colabconfig[\"server_version\"]\n",
"tunnel_service = colabconfig[\"tunnel_service\"]\n",
"\n",
"dynmap_check = False\n",
"#---------------------------------------------------------------------------------
- SNALL FUNCTION
-----------------------------------------------------------------------------------
-#\n",
"\n",
"def CONNECT_NGROK(port, type_, proxy):\n",
" # Get serverconfig['ngrok_proxy'] : dict includes (authtoken, region)\
n",
" token = proxy['authtoken']\n",
" !ngrok authtoken $token\n",
" region = proxy['region']\n",
" conf.get_default().region = region\n",
" url = ngrok.connect (port, type_)\n",
" if type_ == 'tcp': return 'Your server address is ' +
((str(url).split('\"')[1::2])[0]).replace('tcp://', '')\n",
" else: return url\n",
"def CONFIG_ZROK(serverconfig):\n",
" # Enable zrok\n",
" result = ! ./tunnel/zrok/zrok status\n",
" if 'To create a local environment' in str(result): LOG('Status: \\n');
print(result)\n",
" else:\n",
" # Creating zrok directory\n",
" zrok_dir = \"tunnel/zrok\" ; zrok_tar =
'zrok_0.4.32_linux_amd64.tar.gz';\n",
" if exists(zrok_dir) == False:\n",
" MKDIR(zrok_dir); DOWNLOAD_FILE(url =
'https://github.com/openziti/zrok/releases/download/v0.4.32/zrok_0.4.32_linux_amd64
.tar.gz', path = zrok_dir , file_name = zrok_tar)\n",
" ! tar -xf $zrok_dir/$zrok_tar -C $zrok_dir > /dev/null
&&echo \"Installing zrok done\" || echo \"Installing zrok failed\"\n",
" ! chmod 777 $zrok_dir/zrok\n",
" LOG('Status: \\n')\n",
" if exists(f'{zrok_dir}/zrok'):\n",
" ! ./$zrok_dir/zrok version\n",
" ! ./$zrok_dir/zrok status\n",
" LOG(\"Acess to https://api.zrok.io to get fully management. \\
nDisabling zrok before enable. Don't care too much about this.\\n\")\n",
" token = serverconfig['zrok_proxy']['authtoken']\n",
" ! ./$zrok_dir/zrok enable $token --headless >/dev/null && wait &&
echo 'ZROK ENABLED' || echo 'ZROK NOT ENABLED. Try run the server again.'\n",
"def RUNCOMMAND(server_name, serverconfig, version, _type, tunnel_service,
hide = False):\n",
" # Creating directories:\n",
" # tunnel - include all the tunnel sevice\n",
" # logs - include the tunnel logs\n",
" MKDIR(f'{drive_path}/logs')\n",
" if exists(f'{drive_path}/{server_name}/tunnel') == False:
MKDIR(f'{drive_path}/{server_name}/tunnel')\n",
" # Get all the improving java arguments\n",
" java_ver = !java -version 2>&1 | awk -F[\\\"\\.] -v OFS=. 'NR==1{print
$2}'\n",
" args = \" -Xms8G -Xmx8G\"\n",
" if _type == \"paper\" or _type == 'purpur' or _type == 'arclight':\n",
" # Improving paper cilent (purpur is an alternative).\n",
" # For more detailed: https://docs.papermc.io/paper/aikars-flags\n",
" args += ' -XX:+UseG1GC -XX:+ParallelRefProcEnabled -
XX:MaxGCPauseMillis=200 -XX:+UnlockExperimentalVMOptions -XX:+DisableExplicitGC -
XX:+AlwaysPreTouch -XX:G1NewSizePercent=30 -XX:G1MaxNewSizePercent=40 -
XX:G1HeapRegionSize=8M -XX:G1ReservePercent=20 -XX:G1HeapWastePercent=5 -
XX:G1MixedGCCountTarget=4 -XX:InitiatingHeapOccupancyPercent=15 -
XX:G1MixedGCLiveThresholdPercent=90 -XX:G1RSetUpdatingPauseTimePercent=5 -
XX:SurvivorRatio=32 -XX:+PerfDisableSharedMem -XX:MaxTenuringThreshold=1 -
Dusing.aikars.flags=https://mcflags.emc.gs -Daikars.new.flags=true'\n",
" elif _type == \"velocity\":\n",
" # Java argument for velocity server\n",
" # For more detailed: https://docs.papermc.io/velocity/tuning\n",
" args += ' -XX:+UseG1GC -XX:G1HeapRegionSize=4M -XX:
+UnlockExperimentalVMOptions -XX:+ParallelRefProcEnabled -XX:+AlwaysPreTouch -
XX:MaxInlineLevel=15'\n",
" # GC_LOGGING\n",
" if java_ver[0] == \"1\": args += ' -Xloggc:gc.log -verbose:gc -XX:
+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -XX:
+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=1M'\n",
" # else: args +=
'-Xlog:gc*:logs/gc.log:time,uptime:filecount=5,filesize=1M' # GC_Logging may not
worked in java 11 and above\n",
"\n",
" # Forge need to open and run it before starting server. => Using
command instead.\n",
" if _type == 'forge':\n",
" !java -jar forge-installer.jar --installServer >/dev/null\n",
" jar_name = ''\n",
" if _type == 'forge':\n",
" a = !ls -1 | grep .jar\n",
" for i in a:\n",
" if 'forge' in i and 'installer' not in i: jar_name = i\n",
" else: jar_name = JAR_LIST_RUN(version)[_type]\n",
"\n",
" # Set up run server cmd\n",
" cmd = ''\n",
" if exists(f'{drive_path}/{server_name}/run.sh') == True and _type !=
'arclight':\n",
" with open(f'{drive_path}/{server_name}/run.sh', 'r') as f: cmd =
f.read()\n",
" if cmd != '': cmd =
cmd[cmd.find('java'): ].replace('@user_jvm_args.txt', args); cmd =
cmd.replace('\"$@\"', 'nogui \"$@\"')\n",
" else: cmd = f'java -server {args} -jar {jar_name} nogui'\n",
"\n",
" if hide == True:\n",
" if _type == 'forge' or _type == 'arclight':\n",
" # Make run.sh running\n",
" if exists(f'{drive_path}/{server_name}/eula.txt') == True:
LOG('Run the server aigain to finished installing.')\n",
" if _type != 'mohist' and _type != 'banner':\n",
" # Install needed file: eula.txt and so on.\n",
" ! $cmd > /dev/null\n",
"\n",
" else:\n",
" # Starting tunneling and run java file.\n",
" LOG(f'Starting server ({tunnel_service})...')\n",
" LOG('Stop server => /stop')\n",
" log_path = f'{drive_path}/{server_name}/tunnel/{tunnel_service}'\n",
" !mkdir -p $log_path/logs\n",
" log_path =
f'{drive_path}/{server_name}/tunnel/{tunnel_service}/logs'\n",
"\n",
" if tunnel_service == \"ngrok\":\n",
" LOG(CONNECT_NGROK(type_= 'tcp', port= 25565, proxy =
serverconfig['ngrok_proxy']))\n",
" ! $cmd\n",
"\n",
" elif tunnel_service == \"playit\":\n",
" # Download playit\n",
" ! command -v playit || curl -SsL
https://playit-cloud.github.io/ppa/key.gpg | gpg --dearmor | sudo tee
/etc/apt/trusted.gpg.d/playit.gpg > /dev/null && echo \"deb
[signed-by=/etc/apt/trusted.gpg.d/playit.gpg]
https://playit-cloud.github.io/ppa/data ./\" | sudo tee
/etc/apt/sources.list.d/playit-cloud.list && sudo apt -qq update && sudo apt
install playit >/dev/null && echo \"Playit.gg installed\" || echo \"Failed to
install playit\"\n",
" # Run server\n",
" LOG('Playit will run automatically in the background. To stop the
playit service, run sudo systemctl stop playit ')\n",
" ! playit setup\n",
" LOG('Starting: ')\n",
" ! playit &> /content/drive/MyDrive/minecraft/logs/playit.txt &
$cmd\n",
"\n",
" elif tunnel_service == \"zrok\":\n",
" global dynmap_check\n",
" CONFIG_ZROK(serverconfig);\n",
" if dynmap_check == False:\n",
" ! ./tunnel/zrok/zrok share private --backend-mode tcpTunnel
127.0.0.1:25565 --headless &> {log_path}/zrok.txt & sleep 40 && python -c \"with
open(f'/content/drive/MyDrive/minecraft/logs/zrok.txt', 'r') as f: content =
f.read(); content = content[content.find('}') + 1 : ]; from json import loads; json
= loads(content[content.find('{'): content.find('}') + 1]); print('[ LOG ] ' +
json['msg'])\"\n",
" LOG('Starting: '); sleep(40)\n",
" ! $cmd\n",
" else:\n",
" ! ./tunnel/zrok/zrok share private --backend-mode tcpTunnel
127.0.0.1:25565 --headless &> {log_path}/zrok.txt & sleep 40 && python -c \"with
open(f'/content/drive/MyDrive/minecraft/logs/zrok.txt', 'r') as f: content =
f.read(); content = content[content.find('}') + 1 : ]; from json import loads; json
= loads(content[content.find('{'): content.find('}') + 1]); print('[ LOG ] ' +
json['msg'])\" & ./tunnel/zrok/zrok share public localhost:8123 --headless
&>logs/zrok2.txt & sleep 40 && python -c \"with
open(f'/content/drive/MyDrive/minecraft/logs/zrok2.txt', 'r') as f: content =
f.read(); content = content[content.find('}') + 1 : ]; from json import loads; json
= loads(content[content.find('{'): content.find('}') + 1]); print('Your dynmap
webserver: ', json['msg'][json['msg'].find('zrok') :])\"\n",
" LOG('Starting: '); sleep(40)\n",
" ! $cmd\n",
"\n",
" elif tunnel_service == 'localtonet':\n",
" localtonet_path =
f'{drive_path}/{server_name}/tunnel/localtonet/localtonet'\n",
" if exists(localtonet_path) == False:\n",
" ! mkdir -p tunnel/localtonet\n",
" try:\n",
" DOWNLOAD_FILE(url =
'https://localtonet.com/download/localtonet-linux-x64.zip', path =
f'{drive_path}/{server_name}/tunnel/localtonet', file_name = 'localtonet-linux-
x64.zip')\n",
" LOG('Download successfull!')\n",
" except:\n",
" ERROR('LocalToNet could not be downloaded! Try again later or
contact us.')\n",
" sleep(4)\n",
" ! sudo unzip -o tunnel/localtonet/localtonet-linux-x64.zip >
/dev/null && echo 'Unzipped successfully!' || echo 'Failed to unzip.'\n",
" sleep(4)\n",
" ! chmod 777 tunnel/localtonet/localtonet\n",
" ! chmod +x tunnel/localtonet/localtonet\n",
" LOG('Starting: '); token = serverconfig['localtonet_proxy']
['authtoken']\n",
" ! ./tunnel/localtonet/localtonet authtoken $token &>
{log_path}/localtonet.txt & sleep 4 && echo 'Locatonet tunnel started! Start the
UDP_TCP connection on the dashboard: https://localtonet.com/tunnel/tcpudp' || echo
'Failed to start Locatonet tunnel.'\n",
" ! $cmd\n",
"\n",
" elif tunnel_service == 'argo':\n",
" # Download argo\n",
" if exists(f'{drive_path}/{server_name}/tunnel/cloudflared-linux-
amd64') == False:\n",
" DOWNLOAD_FILE(url =
'https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-
linux-amd64', path = f'{drive_path}/{server_name}/tunnel', file_name= 'cloudflared-
linux-amd64')\n",
" ! chmod 777 tunnel/cloudflared-linux-amd64\n",
" # Run server\n",
" ! ./tunnel/cloudflared-linux-amd64 tunnel --url
tcp://127.0.0.1:25565 && echo 'Your free tunnel has started!' && $cmd\n",
" elif tunnel_service == 'localxpose':\n",
" ERROR('This tunnel is in develop... Try again with a new
version.')\n",
"\n",
" if exists(f'{drive_path}/{server_name}/tunnel/localxpose/loclx')
== False:\n",
" ! mkdir tunnel/localxpose\n",
" DOWNLOAD_FILE(url =
'https://api.localxpose.io/api/v2/downloads/loclx-linux-amd64.zip', path =
f'{drive_path}/{server_name}/tunnel', file_name= 'loclx-linux-amd64.zip')\n",
" sleep(40)\n",
" ! unzip -o tunnel/loclx-linux-amd64.zip\n",
" ! chmod 777 tunnel/localxpose/loclx\n",
" ! chmod +x tunnel/localxpose/loclx\n",
" LOG('Starting: ');\n",
" token = serverconfig['localxpose_proxy']['authtoken']\n",
" ! export ACCESS_TOKEN={token}\n",
" ! ./tunnel/localxpose/loclx account login $token &>
{log_path}/localxpose.txt && loclx tunnel tcp --port 25565\n",
" ! echo 'LocalXpose tunnel started! Start the UDP_TCP connection on
the dashboard: https://localxpose.io/dashboard' && $cmd\n",
"\n",
"def GEYSER_CONFIG(server_name, colabconfig, _type):\n",
" if 'Geysermc' in colabconfig:\n",
" if 'fabric' in _type: path =
f'{drive_path}/{server_name}/config/Geyser-Fabric/config.yml'\n",
" elif'paper' in _type or 'purpur' in _type: path =
f'{drive_path}/{server_name}/plugins/Geyser-Spigot/config.yml'\n",
" else:\n",
" LOG('Check out https://wiki.geysermc.org/floodgate/setup/ for
installing Floodgate on servers behind the proxy'); LOG('Note for Fabric behind a
Velocity proxy: You will need to configure FabricProxyLite to allow the Fabric
server to receive data from Velocity.'); LOG('After done settings, copy the key.pem
file in the proxy Floodgate config folder to all backend servers’ Floodgate config
folder.'); LOG('DO NOT DISTRIBUTE THIS KEY TO ANYBODY! This key is what allows for
Bedrock accounts to bypass the Java Edition authentication, and if anyone gets
ahold of this, they can wreak havoc on your server.')\n",
" path =
f'{drive_path}/{server_name}/plugins/Geyser-Velocity/config.yml'\n",
" # To get the requirement\n",
" if exists(path):\n",
" LOG('Config geyser plugin')\n",
" # Configuring\n",
" with open(path, 'r') as file:\n",
" config = yaml.load(file);\n",
" config['bedrock']['clone-remote-port'] = 'true';\n",
" config['auth-type'] = 'floodgate';\n",
" yaml.dump(config, sys.stdout)\n",
" # Clear notification\n",
" colabconfig.pop('Geysermc')\n",
" dump(colabconfig, open(COLABCONFIG(server_name),'w'))\n",
" LOG('Config done. Check out
https://wiki.geysermc.org/geyser/playit-gg for setting tunnels \\n - Verify whether
connections from other networks are possible by running geyser connectiontest
<ip>:<port> in the console.')\n",
"def SUPPORT_DYNMAP(colabconfig):\n",
" if exists(f'{drive_path}/{server_name}/mods/dynmap-server.jar') or
exists(f'{drive_path}/{server_name}/plugins/dynmap-server.jar'):\n",
" if colabconfig['tunnel_service'] == 'ngrok': LOG('\\n YOUR
WEB_SERVER (dynmap): \\n'); LOG(CONNECT_NGROK(type_= 'http', port= 8123, proxy =
serverconfig['ngrok_proxy']))\n",
" elif colabconfig['tunnel_service'] == 'playit': LOG('Access to
https://playit.gg/support/add-dynmap-to-minecraft/ then head over to step 5. DO
IT!!!!!!!')\n",
" elif colabconfig['tunnel_service'] == 'localtonet': LOG('GUIDE: \\n
- Go to https://localtonet.com/tunnel/http \\n - Select Process Type for your
needs. (Random Sub Domain, Custom Sub Domain, Custom Domain)\\n - Select your
authtoken. Get it from https://localtonet.com/usertoken. And then select the Server
you want your tunnel to run on.\\n Enter the IP: 127.0.0.1 and Port: 8123 values
that the tunnel will listen to\\n - Create and Start your tunnel by pressing the
Start Button from the list.')\n",
" elif colabconfig['tunnel_service'] == 'zrok':\n",
" global dynmap_check\n",
" dynmap_check = True\n",
"\n",
"def INSTALL_JAVA(version):\n",
" # Adoptopen jdk -- optional\n",
" # !wget -qO -
https://adoptopenjdk.jfrog.io/adoptopenjdk/api/gpg/key/public | sudo apt-key add -\
n",
" # !sudo add-apt-repository --yes
https://adoptopenjdk.jfrog.io/adoptopenjdk/deb/ &>/dev/null || echo \"Failed to add
repo. Still can be ignored if openjdk gets installed.\"\n",
"\n",
" # Java 8 is required to run Minecraft versions 1.12 through 1.17. Java
17 is required to run Minecraft version 1.18 and up.\n",
" if version >= '1.20.5':\n",
" ! sudo apt-get install -y openjdk-21-jre-headless > /dev/null &&
echo 'Openjdk21 is working correctly, you are good to go.' || \"Openjdk21 doesn't
seem to be installed or isn't working, falling back to java 11\\nYou might
experience reduced performance. Minecraft 1.20.5 and above might fail to launch.\"\
n",
" environ[\"JAVA_HOME\"] =
\"/usr/lib/jvm/java-21-openjdk-amd64/bin/java\"\n",
" ! update-alternatives --set java /usr/lib/jvm/java-21-openjdk-
amd64/bin/java\n",
" elif version >= \"1.17\":\n",
" ! sudo apt-get -y install openjdk-17-jre-headless > /dev/null &&
echo 'Openjdk17 is working correctly, you are good to go.' || \"Openjdk17 doesn't
seem to be installed or isn't working, falling back to java 11\\nYou might
experience reduced performance. Minecraft 1.18 and above might fail to launch.\"\
n",
" environ[\"JAVA_HOME\"] = \"/usr/lib/jvm/java-17-openjdk-amd64\"\n",
" ! update-alternatives --set java /usr/lib/jvm/java-17-openjdk-
amd64/bin/java\n",
" else:\n",
" ! sudo apt-get -y install openjdk-8-jre-headless > /dev/null &&
echo 'Openjdk8 is working correctly, you are good to go.' || echo \"Openjdk8
doesn't seem to be installed or isn't working, falling back to java 11\\nYou might
experience reduced performance. Minecraft 1.18 and above might fail to launch.\"\
n",
" environ[\"JAVA_HOME\"] = \"/usr/lib/jvm/java-8-openjdk-amd64\"\n",
" ! update-alternatives --set java
/usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java\n",
"def EXIT_NGROK():\n",
" # Exiting ngrok tunnel helps improve the performance\n",
" tunnels = ngrok.get_tunnels()\n",
" for tunnel in tunnels: ngrok.disconnect(tunnel.public_url)\n",
" ngrok.kill()\n",
" LOG(\"Ngrok closed.\")\n",
"\n",
"#---------------------------------------------------------------------------------
- MAIN CODE
-----------------------------------------------------------------------------------
-#\n",
"# Cd to server path\n",
"%cd $drive_path/$server_name\n",
"# Install java acording to the version of server.jar\n",
"INSTALL_JAVA(version)\n",
"# Install necessary files\n",
"if exists(f'{drive_path}/{server_name}/eula.txt') == False:\n",
" LOG(\"\\n[Note: Downloading essentials files takes approximately 10-15
minutes. Please wait for a little bit.]\")\n",
" RUNCOMMAND(server_name, serverconfig, version, _type, tunnel_service,
hide = True)\n",
"with open(f'{drive_path}/{server_name}/eula.txt', 'w') as f:\n",
" # Accept EULA\n",
" LOG('\\nAccepting Eula.')\n",
" f.seek(0)\n",
" f.write('eula=true')\n",
"# See what changes in the folder\n",
"LOG(\"\\nFiles:\")\n",
"!ls -a\n",
"# Run minecraft server\n",
"SUPPORT_DYNMAP(colabconfig)\n",
"RUNCOMMAND(server_name, serverconfig, version, _type, tunnel_service)\n",
"GEYSER_CONFIG(server_name, colabconfig, _type)\n",
"# Stop minecraft server => Exit tunnel => Cd to home\n",
"LOG(\"Finalized server.\")\n",
"if colabconfig['tunnel_service'] == 'ngrok': EXIT_NGROK()\n",
"if colabconfig['tunnel_service'] == 'zrok':\n",
" ! ./tunnel/zrok/zrok disable >/dev/null\n",
"%cd $drive_path"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "Y0BWJEDQOH7J"
},
"source": [
"---"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "HD4lBUT9RcS-"
},
"source": [
"# ⚓ **Options**\n",
"---\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"cellView": "form",
"id": "XO3WG0U6qPi2",
"collapsed": true
},
"outputs": [],
"source": [
"from jproperties import Properties\n",
"from os.path import exists\n",
"from google.colab import files as fls\n",
"!pip install pillow\n",
"from PIL import Image\n",
"\n",
"# @markdown ####**Server_custom**\n",
"choice = 'server_motd' # @param [\"server_motd\", \"server_icon\"]\n",
"\n",
"file_path = f'{drive_path}/server-icon.png'\n",
"file_dest = f'{drive_path}/{server_name}/'\n",
"\n",
"# Default server\n",
"server_name = SERVER_IN_USE(server_name = '')\n",
"if exists(f\"{drive_path}/{server_name}/server.properties\") == False:
ERROR(' Running your minecraft server before editing properties')\n",
"else:\n",
" LOG('Server: ' + server_name)\n",
" sleep(4)\n",
" # Add server icon file\n",
" if choice == 'server_icon':\n",
" if exists(f\"{drive_path}/{server_name}/server-icon.png\"): LOG('There
is an existing server_icon.png file. If you wanna to change it, press ENTER. If
not, stop the cell.'); input()\n",
" url = input('Download_url (left empty to upload manually): ')\n",
" if url != '':\n",
" try:\n",
" DOWNLOAD_FILE(url= url, path= f'{drive_path}', file_name= 'server-
icon.png')\n",
" except:\n",
" INFO('Check that the image is available on the internet! You can
try https://imgbb.com or https://postimages.org/ and obtain the direct link.')\n",
" ERROR('Failed to download. Forbidden / Not accesible.')\n",
" Image.open(file_path).resize((64, 64)).save(file_dest + 'server-
icon.png')\n",
" sleep(4)\n",
" !rm '{file_path}'\n",
" else:\n",
" uploaded = fls.upload()\n",
" file_ = uploaded.keys()\n",
" try:\n",
" file_ = [fn for fn in uploaded.keys()][0]\n",
" !cp '{file_}' server-icon.png\n",
" !rm '{file_}'\n",
" Image.open(file_path).resize((64, 64)).save(file_dest + 'server-
icon.png')\n",
" sleep(10)\n",
" !rm '{file_path}'\n",
" except: ERROR(\"You didn't upload server-icon.png\")\n",
" else:\n",
" LOG('Get MOTD from https://mctools.org/motd-creator')\n",
" server_properties = Properties()\n",
" with open(f\"{drive_path}/{server_name}/server.properties\", \"rb\")
as f:\n",
" server_properties.load(f, \"utf-8\")\n",
" server_properties[\"motd\"] = input('Your MOTD : ')\n",
" with open(f\"{drive_path}/{server_name}/server.properties\", \"wb\")
as f:\n",
" server_properties.store(f, encoding=\"utf-8\")\n",
" LOG('Completed')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"cellView": "form",
"id": "pCJfyMhXRnJS"
},
"outputs": [],
"source": [
"from jproperties import Properties\n",
"from os.path import exists\n",
"\n",
"# @markdown ####**Server properties**\n",
"Slots = 20 # @param {type:\"slider\", min:0, max:100, step:1}\n",
"Gamemode = \"survival\" # @param
[\"survival\", \"creative\", \"adventure\", \"spectator\"]\n",
"Difficulty = \"hard\" # @param
[\"peaceful\", \"easy\", \"normal\", \"hard\"]\n",
"Cracked = True # @param {type:\"boolean\"}\n",
"PVP = True # @param {type:\"boolean\"}\n",
"Command_block = True # @param {type:\"boolean\"}\n",
"Fly = True # @param {type:\"boolean\"}\n",
"Animals = True # @param {type:\"boolean\"}\n",
"Monsters = True # @param {type:\"boolean\"}\n",
"Villagers = True # @param {type:\"boolean\"}\n",
"Nether = True # @param {type:\"boolean\"}\n",
"Force_gamemode = False # @param {type:\"boolean\"}\n",
"Spawn_protection = 16 # @param {type:\"slider\", min:0, max:100, step:1}\
n",
"\n",
"#---------------------------------------------------------------------------------
- MAIN CODE
-----------------------------------------------------------------------------------
-#\n",
"\n",
"server_name = SERVER_IN_USE(server_name = '')\n",
"if exists(f\"{drive_path}/{server_name}/server.properties\") == False:
ERROR(' Running your minecraft server before editing properties')\n",
"else:\n",
" LOG('Changing server.properties')\n",
" server_properties = Properties() # Download file\n",
" with open(f\"{drive_path}/{server_name}/server.properties\", \"rb\") as
f:\n",
" server_properties.load(f, \"utf-8\")\n",
" # Configuring\n",
" server_properties[\"max-players\"] = str(Slots)\n",
" server_properties[\"gamemode\"] = Gamemode\n",
" server_properties[\"difficulty\"] = Difficulty\n",
" dict_ = {'pvp': PVP, 'enable-command-block': Command_block, 'allow-
flight': Fly, 'spawn-animals': Animals, 'spawn-monsters': Monsters,\n",
" 'spawn-npcs': Villagers, 'allow-nether': Nether, 'force-
gamemode': Force_gamemode, 'spawn-protection': Spawn_protection, \"online-mode\" :
Cracked}\n",
" for keys, value in dict_.items(): server_properties[keys] =
str(value).lower()\n",
" # Saving\n",
" with open(f\"{drive_path}/{server_name}/server.properties\", \"wb\") as
f:\n",
" server_properties.store(f, encoding=\"utf-8\")\n",
" LOG('Completed')"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "Ilo0sMqq90On"
},
"source": [
"---"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "hfUxmQTgUF8Z"
},
"source": [
"# 📎 **Log**\n",
"---\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"cellView": "form",
"id": "6MYwvnY_UNzS"
},
"outputs": [],
"source": [
"from os.path import exists\n",
"\n",
"# @markdown ####**Shows latest log of your minecraft server**\n",
"# Getting server_folder\n",
"server_name = SERVER_IN_USE(server_name = '')\n",
"# Check log\n",
"if exists(f'/content/drive/My
Drive/minecraft/{server_name}/logs/latest.log'):\n",
" LOG(f'Server {server_name}')\n",
" # Open and get log content\n",
" with open(f'/content/drive/My
Drive/minecraft/{server_name}/logs/latest.log', 'r') as f: content = f.read();
print(content); LOG('\\nTry access to https://mclo.gs to see problems and the way
to deal with.')\n",
"else: ERROR(\"Error: File didn't exists\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "QBzBdOXfUK1a"
},
"source": [
"---\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "JkGq3KakW-Bc"
},
"source": [
"# 📰 **Software**\n",
"---\n",
"Change the software (vanilla) to others platforms\n",
"\n",
"---"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "G4CT_TwV9ZiM"
},
"source": [
"\n",
"+ Please checking whether your minecraft server is in Gdrive or not.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"cellView": "form",
"collapsed": true,
"id": "Fy5-YjJMPV3S"
},
"outputs": [],
"source": [
"from json import load, dump\n",
"from requests import get\n",
"from bs4 import BeautifulSoup\n",
"from os.path import exists\n",
"from time import sleep\n",
"\n",
"# @markdown #### **Choosing server type**\n",
"server_type = \"vanilla\" # @param
[\"vanilla\", \"snapshot\", \"paper\", \"purpur\", \"forge\", \"fabric\",
'velocity', 'arclight','mohist', 'banner']\n",
"# @markdown #### **Standard turnel service** ( Aivailable turnel: [ngrok]
(https://ngrok.com/), [cloudfare-argo](https://www.cloudflare.com/) or [zrok.io]
(https://zrok.io/) or [playit.gg](https://playit.gg/) and
[localtonet](https://localtonet.com))\n",
"tunnel_service = 'ngrok' #@param ['ngrok', 'argo', 'zrok', 'playit',
'localtonet', 'serveo', 'localxpose']\n",
"\n",
"serverconfig = load(open(SERVERCONFIG)); server_name =
serverconfig['server_in_use']; colabconfig = load(open(COLABCONFIG(server_name)))\
n",
"\n",
"# GUIDANCE\n",
"choice = input('Do you want to show(s)/hide(h) tunnels info? - ')\n",
"if 's' in choice: clear_output(); print(\"\\n\\n-
**[Ngrok](https://ngrok.com)**\\n + Follow the prompts.\\n + The IP will change
whenever you restart the server.\\n\\n- **[Cloudflare's
argo](https://www.cloudflare.com/)** :\\n - If the 'Your free tunnel has
started!' notification appears => Done.\\n - Access to your server:\\n 1.
Download [Cloudflared
client](https://github.com/cloudflare/cloudflared/releases/).\\n 2. Launch the
binary with `<your Cloudflare file name> access tcp --hostname <tunnel_address> --
url 127.0.0.1:25565` (note: tunnel_address is your address which has been set on
your Cloudflare).\\n 4. Finally, connect to `127.0.0.1:25565` from the minecraft
client which is located in that machine.\\n\\n-
**[Localtonet](https://localtonet.com/)**:\\n 1. Navigate to
[TCP-UDG](https://localtonet.com/tunnel/tcpudp) page. Select TCP in Protocol
Types.\\n 2. Get your authtoken from
[Authtoken](https://localtonet.com/usertoken).\\n 3. Pick the server you'd like
your tunnel to operate on.\\n 4. Input the IP and Port values the tunnel will
listen to, in this case, for Minecraft, it's typically IP: 127.0.0.1 and Port:
25565.\\n 5. Finally, create and start your tunnel by pressing the Start button.\\
n - Read more on
[how-to-use-localtonet-with-minecraft](https://localtonet.com/documents/using-
localtonet-with-minecraft)\\n\\n- **[Zrok](https://zrok.io/)**:\\n 1. Download the
zrok app through [link](https://docs.zrok.io/docs/getting-started/)\\n 2. Open the
shell. Type `zrok invite` to sign up and get the authtoken\\n 3. Follow the
prompts\\n 4. Acess to https://api.zrok.io to get fully management\\n - Read
more on https://docs.zrok.io/docs/getting-started. \\n\\n-
**[PlayIt](https://playit.gg/)**: follow the prompts.\"); sleep(20)\n",
"clear_output()\n",
"\n",
"#---------------------------------------------------------------------------------
- DELETE SERVER
-----------------------------------------------------------------------------------
-#\n",
"\n",
"if serverconfig['server_list'] == []: ERROR(\"You haven't installed
yet.\")\n",
"else:\n",
" # Auditing whether file is existed.\n",
" if exists(f'{drive_path}/{server_name}') == False: ERROR(\"You haven't
installed yet.\")\n",
" LOG(f'Deleting {server_name}...')\n",
"\n",
" # Delete folder without noticable\n",
" !rm -rf \"{drive_path}/{server_name}\" >/dev/null\n",
"\n",
" # Remove the folder name in server config txt files\n",
" serverconfig['server_list'].remove(server_name)\n",
" if serverconfig['server_in_use'] == server_name:\n",
" try: serverconfig['server_in_use']= serverconfig['server_list'][0]\n",
" except: serverconfig['server_in_use'] = ''\n",
" dump(serverconfig, open(SERVERCONFIG, 'w'))\n",
"\n",
" LOG('Wait for a while.'); sleep(40); LOG('Completed')\n",
"\n",
"#---------------------------------------------------------------------------------
- SLEEPING
-----------------------------------------------------------------------------------
-#\n",
"\n",
"sleep(40); version = '';\n",
"if tunnel_service == 'default': tunnel_service =
colabconfig['tunnel_service']\n",
"\n",
"#---------------------------------------------------------------------------------
- INSTALL SERVER
-----------------------------------------------------------------------------------
-#\n",
"\n",
"def SERVERSJAR(server_type, version, all = False, jar = False):\n",
" #Get the download URL (jar) AND return the detailed versions for each
software (all)\n",
" if all:\n",
" Server_Jars_All = {\n",
" 'paper': 'https://api.papermc.io/v2/projects/paper', 'velocity':
'https://api.papermc.io/v2/projects/velocity',\n",
" 'purpur': 'https://api.purpurmc.org/v2/purpur',\n",
" 'mohist': 'https://mohistmc.com/api/v2/projects/mohist', 'banner':
'https://mohistmc.com/api/v2/projects/banner'\n",
" }\n",
" if server_type == 'vanilla' or server_type=='snapshot':\n",
" rJSON =
GET('https://launchermeta.mojang.com/mc/game/version_manifest.json').json()\n",
" if server_type == 'vanilla': server_type = 'release'\n",
" if version != 'vanilla - latest_version': server_version =
[hit[\"id\"] for hit in rJSON[\"versions\"] if hit[\"type\"] == server_type]\n",
" else:\n",
" return rJSON['latest']['release']\n",
"\n",
" elif server_type == 'paper' or server_type == 'velocity' or
server_type == 'purpur' or server_type == 'mohist' or server_type == 'banner':\n",
" rJSON = GET(Server_Jars_All[server_type]).json()\n",
" server_version = [hit for hit in rJSON[\"versions\"]]\n",
"\n",
" elif server_type == 'fabric':\n",
" rJSON = GET('https://meta.fabricmc.net/v2/versions/game').json()\n",
" server_version = [hit['version'] for hit in rJSON if hit['stable']
== True]\n",
"\n",
" elif server_type == 'forge':\n",
" rJSON =
GET('https://files.minecraftforge.net/net/minecraftforge/forge/index.html')\n",
" soup = BeautifulSoup(rJSON.content, \"html.parser\")\n",
" server_version = [tag.text for tag in soup.find_all('a') if '.' in
tag.text and '\\n' not in tag.text]\n",
"\n",
" else:\n",
" LOG('Before going deeper, please check out
https://github.com/IzzelAliz/Arclight')\n",
" rJSON =
GET('https://files.hypoglycemia.icu/v1/files/arclight/minecraft').json()['files']\
n",
" server_version = [hit['name'] for hit in rJSON]\n",
" return server_version\n",
"\n",
" elif jar == True and version != None:\n",
" # RETURN DOWNLOAD URL\n",
" if server_type == 'vanilla' or server_type=='snapshot':\n",
" rJSON =
GET('https://launchermeta.mojang.com/mc/game/version_manifest.json').json()\n",
" if server_type == 'vanilla': server_type = 'release'\n",
" for hit in rJSON[\"versions\"]:\n",
" if hit[\"type\"] == server_type and hit['id'] == version:\n",
" return GET(hit['url']).json()[\"downloads\"]['server']['url']\
n",
"\n",
" elif server_type == 'paper' or server_type == 'velocity':\n",
" build =
GET(f'https://api.papermc.io/v2/projects/{server_type}/versions/{version}').json()
[\"builds\"][-1]\n",
" jar_name =
GET(f'https://api.papermc.io/v2/projects/{server_type}/versions/{version}/builds/
{build}').json()[\"downloads\"][\"application\"][\"name\"]\n",
" return
f'https://api.papermc.io/v2/projects/{server_type}/versions/{version}/builds/
{build}/downloads/{jar_name}'\n",
"\n",
" elif server_type == 'purpur':\n",
" build = GET(f'https://api.purpurmc.org/v2/purpur/{version}').json()
[\"builds\"][\"latest\"]\n",
" return
f'https://api.purpurmc.org/v2/purpur/{version}/{build}/download'\n",
"\n",
" elif server_type == 'mohist' or server_type == 'banner':\n",
" return
GET(f'https://mohistmc.com/api/v2/projects/{server_type}/{version}/builds').json()
[\"builds\"][-1][\"url\"]\n",
"\n",
" elif server_type == 'fabric':\n",
" installerVersion =
GET('https://meta.fabricmc.net/v2/versions/installer').json()[0][\"version\"]\n",
" fabricVersion =
GET(f'https://meta.fabricmc.net/v2/versions/loader/{version}').json()[0]
[\"loader\"][\"version\"]\n",
" return \"https://meta.fabricmc.net/v2/versions/loader/\" + version +
\"/\" + fabricVersion + \"/\" + installerVersion + \"/server/jar\"\n",
"\n",
" elif server_type == 'forge':\n",
" rJSON =
GET(f'https://files.minecraftforge.net/net/minecraftforge/forge/index_{version}.htm
l')\n",
" soup = BeautifulSoup(rJSON.content, \"html.parser\")\n",
" tag = soup.find('a', title=\"Installer\"); tag = str(tag); tag =
tag[tag.find('\"') + 1 :]\n",
" link = tag[:tag.find('\"')]; link = link[link.find('=') + 1:]; link
= link[link.find('=') + 1:]\n",
" return link\n",
"\n",
" else:\n",
" rJSON =
GET(f'https://files.hypoglycemia.icu/v1/files/arclight/minecraft/{version}/
loaders').json()\n",
" LOG('Available type: '); print([hit['name'] for hit in
rJSON['files']])\n",
" build = input(' Type: '); choice = input('Stable(st) or
Snapshot(sn): ')\n",
" if 'sn' in choice.lower(): choice = 'latest-snapshot';\n",
" else: choice = \"latest-stable\";\n",
" return
f'https://files.hypoglycemia.icu/v1/files/arclight/minecraft/{version}/loaders/
{build}/{choice}'\n",
" else: ERROR('Wrong given arguments')\n",
"\n",
"#---------------------------------------------------------------------------------
- MAIN CODE
-----------------------------------------------------------------------------------
-#\n",
"\n",
"# Auditing whether file is existed.\n",
"if exists(f'{drive_path}/{server_name}') == False:\n",
" # Create folder\n",
" MKDIR(f'{drive_path}/{server_name}')\n",
" LOG('Wait for 40 seconds')\n",
" sleep(40)\n",
" # Get version\n",
" if version == '':\n",
" # Print available version => get version (string variable)\n",
" LOG(f'Latest versions/builds for {server_type}')\n",
" server_version = SERVERSJAR(server_type, version, all = True)\n",
" print('\\n Available version/builds:\\n', server_version)\n",
" version = input('Server versions: ')\n",
" while version == '':\n",
" LOG(\"Invalid versions\")\n",
" print('\\n Available version/builds:\\n', server_version)\n",
" version = input('Server version: ')\n",
" version = version\n",
" elif version == 'vanilla - latest_version': version =
SERVERSJAR(server_type, version, all = True)\n",
"\n",
" # Load serverconfig\n",
" serverconfig = load(open(SERVERCONFIG))\n",
" serverconfig['server_list'] += [server_name]\n",
" serverconfig['server_in_use'] = server_name\n",
" if serverconfig['ngrok_proxy'] ==
{\"authtoken\": \"\", \"region\": \"\"} and tunnel_service == 'ngrok':\n",
" LOG('Get your authtoken from
https://dashboard.ngrok.com/get-started/your-authtoken')\n",
" serverconfig['ngrok_proxy']['authtoken'] = input('Your authtoken: ')\
n",
" LOG('Available Regions:', ' ap - Asia/Pacific (Singapore)', ' au -
Australia (Sydney)', ' eu - Europa (Frankfurt - Germany)', ' in - India (Mumbai)',
' jp - Japan (Tokyo)', ' sa - America (São Paulo - Brazil)', ' us - United States
(Ohio)', sep='\\n')\n",
" serverconfig['ngrok_proxy']['region'] = input('Region: ')\n",
" elif tunnel_service == 'zrok' and serverconfig['zrok_proxy'] ==
{'authtoken': ''}:\n",
" # Settings variable\n",
" serverconfig['zrok_proxy']['authtoken'] = input('Your zrok token: ')\
n",
" elif tunnel_service == 'localtonet' and serverconfig['localtonet_proxy']
== {'authtoken': ''}: LOG('Get your authtoken from
https://localtonet.com/usertoken'); serverconfig['localtonet_proxy']['authtoken'] =
input('Your localtonet token: ')\n",
" elif tunnel_service == 'localxpose' and serverconfig['localxpose_proxy']
== {'authtoken': ''}: LOG('Get your authtoken from
https://localxpose.io/dashboard/access'); serverconfig['localxpose_proxy']
['authtoken'] = input('Your localxpose token: ')\n",
" dump(serverconfig, open(SERVERCONFIG, 'w'))\n",
" # Set up colabconfig\n",
" colabconfig = {\"server_type\": server_type, \"server_version\":
version, \"tunnel_service\" : tunnel_service}\n",
" dump(colabconfig, open(COLABCONFIG(server_name),'w'))\n",
" # Download jar file\n",
" if server_type == 'forge': jarname = 'forge-installer.jar' # The jar
file name (forge need a special process)\n",
" else: jarname = JAR_LIST_RUN(version)[server_type]\n",
" DOWNLOAD_FILE(url= SERVERSJAR(server_type, version, jar = True), path =
f\"{drive_path}/{server_name}\", file_name= jarname)\n",
" sleep(40)\n",
" LOG('\\nCompleted!')\n",
"else: ERROR('Lol, you have already installed this server file')"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "o8xY7ru09mE3"
},
"source": [
"---"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "QaNRBRuK8seq"
},
"source": [
"# 🎈 **Plugins, mods**\n",
"\n",
"####Download modpack/mod/plugin from
[curseforge](https://www.curseforge.com/Minecraft) and
[modrinth](https://modrinth.com/)\n",
"---\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"cellView": "form",
"id": "QvFvnjIRIU0c"
},
"outputs": [],
"source": [
"from pyngrok import conf, ngrok\n",
"from os import environ, pathsep, listdir\n",
"from zipfile import ZipFile\n",
"from requests import get, post\n",
"from time import sleep\n",
"from json import load, dump, loads\n",
"from google.colab import files as fls\n",
"\n",
"# @markdown ####**Your download choice**\n",
"choice = 'search' #@param ['search', 'url', 'upload_file',
'install_geysermc', 'dynmap support']\n",
"\n",
"#@markdown #### **Your search name**\n",
"search_name_or_url = '' # @param {type: 'string'}\n",
"\n",
"# @markdown #####Choose the place to download mod/modpack/plugin\n",
"software = 'Curseforge' # @param [\"Curseforge\", \"Modrinth\"]\n",
"\n",
"# @markdown ####**Details:**\n",
"# @markdown\n",
"# @markdown ##### (none -> don't search (version -- doesn't wellcoming to
do this), default -> set up according to colabconfig file)\n",
"categories = 'none' #@param ['none', 'default', 'vanilla', 'fabric',
'forge', 'paper', 'purpur']\n",
"versions = \"default\" # @param [\"default\"] {allow-input: true}\n",
"project_types = 'none' # @param ['none', 'default', 'mods', 'plugins',
'modpacks']\n",
"index = 'none' #@param ['none', 'relevance', 'downloads', 'follows',
'newest', 'updated']\n",
"\n",
"# CHecking and setting variable\n",
"server_name = SERVER_IN_USE(server_name = '')\n",
"if exists(f\"{drive_path}/{server_name}/server.properties\") == False:
ERROR(' Running your minecraft server before editing properties')\n",
"else:\n",
" colabconfig = COLABCONFIG_LOAD(server_name)\n",
" if versions == 'default': versions = colabconfig[\"server_version\"]\n",
" if categories == 'default': categories = colabconfig['server_type']\n",
" if project_types == 'default':\n",
" if 'fabric' in categories or 'forge' in categories : project_types =
'mods'\n",
" elif 'paper' in categories or 'purpur' in categories : project_types =
'plugins'\n",
" elif 'arclight' in categories or 'mohist' in categories or 'banner':
project_types = input('Project type (mods or plugins or modpacks) : ');\n",
" else: project_types = 'tmp';\n",
" if 'arclight' in categories or 'mohist' in categories or 'banner' in
categories or 'vanilla' in categories or 'snapshot' in categories: categories =
'none';\n",
" elif 'paper' in categories or 'purpur' in categories: ERROR(f'Hmm,
maybe you install the wrong types. Your server_type (currently) is {categories}')
if project_types == 'mods' else print('') ;\n",
" elif 'fabric' in categories or 'forge' in categories: ERROR(f'Hmm,
maybe you install the wrong types. Your server_type (currently) is {categories}')
if project_types == 'plugins' else print('');\n",
"if 'vanilla' in categories or 'snapshot' in categories: ERROR(f'Hmm,
maybe you install the wrong types. Your server_type (currently) is {categories}')
if project_types == \"modpacks\" else print('');\n",
"path = f'{drive_path}/{server_name}/{project_types}'\n",
"if exists(path) == False:\n",
" MKDIR(path)\n",
" sleep(40)\n",
"url = ''\n",
"if choice == 'url':\n",
" if 'http' in search_name_or_url or 'https' in search_name_or_url: url =
search_name_or_url\n",
" else: url = input('Url: ')\n",
"search_name = search_name_or_url\n",
"\n",
"# I will not do remove the class file. Because:\n",
"# 1. It is hard and very slow to extract them all\n",
"# 2. It will broken in some specific runtime\n",
"\n",
"#---------------------------------------------------------------------------------
-- MAIN CODE
---------------------------------------------------------------------------#\n",
"\n",
"class Download_:\n",
" def __init__(self, choice, url, server_name, categories, versions,
proj_types, index):\n",
" self.server_name = SERVER_IN_USE(server_name)\n",
" if exists(f\"{drive_path}/{self.server_name}/server.properties\") ==
False: ERROR(' Running your minecraft server before editing properties')\n",
" else:\n",
" self.colabconfig = COLABCONFIG_LOAD(self.server_name)\n",
" self.categories = categories\n",
" self.versions = versions\n",
" self.proj_types = proj_types\n",
" self.index = index\n",
" self.path = f'{drive_path}/{self.server_name}/{self.proj_types}'\n",
" self.choice = choice\n",
" self.url = url\n",
" def FACETS(self, software):\n",
" # Get all the syntax\n",
" categories = ''; index = ''; versions = ''\n",
" if software == 'Modrinth':\n",
" facets = \"[\"\n",
" if self.categories != 'none': facets += '[\"categories:' +
self.categories + '\"]';\n",
" if facets != '[' and self.versions != 'none': facets += \",\" +
'[\"versions:' + self.versions +'\"]'\n",
" elif self.versions != 'none': facets += '[\"versions:' +
self.versions + '\"]';\n",
" if self.proj_types == 'mods': proj_types = 'mod'\n",
" elif self.proj_types == 'plugins': proj_types = 'plugin'\n",
" if facets != '[' and self.proj_types != 'tmp': facets += \",\" +
'[\"project_type:' + proj_types + '\"]'\n",
" elif self.proj_types != 'tmp': facets += '[\"project_type:' +
proj_types + '\"]'\n",
" facets += \"]\"; facetsInURL = \"\";\n",
" if facets != \"[]\": facetsInURL += f'&facets={facets}'\n",
" if self.index != \"none\": facetsInURL += f'&index={self.index}'\n",
" return facetsInURL\n",
" else:\n",
" if self.categories != 'none':\n",
" if self.categories == 'fabric': categories = 4 #Fabric\n",
" elif self.categories == 'forge': categories = 1 #Forge\n",
" elif self.categories == 'quilt': categories = 5 # quilt\n",
" categories = f\"&modLoaderType={categories}\"\n",
" if self.index != \"none\":\n",
" if self.index == \"relevance\": index = 1 # Featured\n",
" elif self.index == \"downloads\": index = 6 #TotalDownloads\n",
" elif self.index == \"follows\": index = 2 #Popularity\n",
" elif self.index == \"newest\": index = 11 #ReleasedDate\n",
" elif self.index == \"updated\": index = 3 #LastUpdated\n",
" index = f\"&sortField={index}\"\n",
" if self.versions != \"none\": versions =
f\"&gameVersion={self.versions}\"\n",
" return categories + versions + index\n",
" def SEARCH(self, search_name, software):\n",
" project = {}\n",
" LOG(f'\\nSearching for the related of {search_name} ...\\n')\n",
" facetsInURL = self.FACETS(software)\n",
" if software == \"Modrinth\":\n",
" # Get syntax and get data\n",
" rJSON = GET(f'https://api.modrinth.com/v2/search?query={search_name}
{facetsInURL}').json()\n",
" # Get the list of all relevant project\n",
" for hit in rJSON['hits']:\n",
" # Auditing if it for server or not.\n",
" if hit['server_side'] == 'optional' or hit['server_side'] ==
'required':\n",
" # Get a full list title : description\n",
" print(hit['slug'], \" : \", hit['description'])\n",
" project[hit['slug']] = hit['project_id']\n",
" elif software == 'Curseforge':\n",
" LOG(f\"Curseforge doesn't have the exact searching key for cilent-
side or server-side => you may get errors when running this {self.proj_types}\")\
n",
" # Because I haven't found any corresponded of project types in the
search engine of Curseforge, I don't use it for searching.\n",
" # The gameid of Minecraft is 432\n",
" rJSON = GET(f\"https://api.curse.tools/v1/cf/mods/search?
gameId=432&searchFilter={search_name}{facetsInURL}\").json()\n",
" # Get the list of all relevant project\n",
" for hit in rJSON[\"data\"]:\n",
" # Get a full list name: summary\n",
" print(hit[\"name\"], ' : ', hit[\"summary\"])\n",
" project[hit['name']] = str(hit[\"id\"])\n",
" # Checking whether your search name wrong or not. If yes => Get the
name of project => Get project id\n",
" project_names =''\n",
" if project == {}: ERROR(f\"\\nSomething went wrong. Please check your
search name.\")\n",
" else:\n",
" LOG('\\nType the project_name you want to download')\n",
" project_names= input('Project_name: ')\n",
" while project_names not in project:\n",
" LOG('\\nWrong project_names please type aigain. If you want to
quit, type \"None\".')\n",
" project_names= input('\\nProject_name: ')\n",
" if project_names == 'None': ERROR('Stopping...')\n",
" return [project, project_names]\n",
" def MODPACK(self, file_name, software):\n",
" # settings up\n",
" sleep(40)\n",
" %cd $drive_path\n",
" server_name = self.server_name\n",
" path_drive = file_name\n",
" while path_drive.find('.') != -1: path_drive =
path_drive[path_drive.find('.')+1:]\n",
" path_drive = file_name[: file_name.find('.' + path_drive)]\n",
" if exists(f'{drive_path}/{self.server_name}/tmp/{path_drive}') ==
False:\n",
" MKDIR(f'{self.server_name}/tmp/{path_drive}')\n",
" sleep(40)\n",
" # Unzipping modpack\n",
" ! unzip -q '{server_name}/tmp/{file_name}' -d
'{server_name}/tmp/{path_drive}' > /dev/null &&echo 'Unzip done' || echo 'Failed to
unzip'\n",
" sleep(30)\n",
" # Copy the directory in orverrides and paste it (overrides includes
the config files of the developer)\n",
" try:\n",
" for fln in listdir(f'{server_name}/tmp/{path_drive}/overrides'):\n",
" ! mv -f '{server_name}/tmp/{path_drive}/overrides/{fln}'
'{drive_path}/{server_name}' > /dev/null && echo 'Moving done' || echo 'Failed to
move'\n",
" sleep(40)\n",
" except: pass\n",
" # Each page give the difference file json. The file json give full
details.\n",
" # (Modrinth: modrinth.index.json- Download link, Curseforge:
manifest.json - fileID, projectID) for mods which is included in modpack.\n",
" if software == 'Modrinth':\n",
" with ZipFile(f'{server_name}/tmp/{file_name}') as myzip:\n",
" manifest = loads(myzip.read('modrinth.index.json'))['files']\n",
" for file_ in manifest:\n",
" path_ = file_[\"path\"].split(\"/\")[0]; file_name_ =
file_[\"path\"].split(\"/\")[1]\n",
" DOWNLOAD_FILE(url = file_[\"downloads\"][0], path =
f'{drive_path}/{self.server_name}/{path_}', file_name = file_name_)\n",
" else:\n",
" with ZipFile(f'{server_name}/tmp/{file_name}') as myzip:\n",
" manifest = loads(myzip.read('manifest.json'))['files']\n",
" for file_ in manifest:\n",
" project_id = file_[\"projectID\"]; fileID =
str(file_[\"fileID\"]); rJSON =
GET(f'https://api.curse.tools/v1/cf/mods/{project_id}/files/{fileID}').json()
[\"data\"]\n",
" DOWNLOAD_FILE(url =
f'https://www.curseforge.com/api/v1/mods/{project_id}/files/{fileID}/download',
path = f'{drive_path}/{self.server_name}/mods', file_name = rJSON[\"fileName\"])\
n",
" def Install_(self, search_name, software):\n",
" LOG(f'Acessing: {self.server_name}')\n",
" if self.choice == 'url':\n",
" url = self.url\n",
" # Find file_name in download url\n",
" filename = input('File name (optional) : ')\n",
" if filename == '':\n",
" filename = url[url.find(\"/\") + 1:]\n",
" while filename.find(\"/\")!= -1: filename =
filename[filename.find(\"/\") + 1:]\n",
" else:\n",
" format = input('Format : ')\n",
" if f\".{format}\" not in filename: filename += f\".{format}\"\n",
" # Download file\n",
" if ' ' in filename: filename = filename.replace(' ', '_')\n",
" DOWNLOAD_FILE(url= url, path = self.path, file_name= filename)\n",
" if self.proj_types == 'tmp': self.MODPACK(file_name= filename,
software= software); sleep(40)\n",
" LOG('\\nCompleted')\n",
" elif self.choice == 'upload_file':\n",
" uploaded = fls.upload()\n",
" try:\n",
" file_ = [fn for fn in uploaded.keys()][0] # Get the name of the
uploaded file\n",
" filename = input('File name (optinal)') # The file name which you
want to be\n",
" if filename != '':\n",
" format = input('Format : ')\n",
" if format != '' and f\".{format}\" not in filename: filename +=
f\".{format}\"\n",
" else: format = file_[file_.find('.'):]\n",
" try:\n",
" ! sudo mv -f '{drive_path}/{file_}' '{self.path}/{filename}.
{format}'\n",
" except: ERROR(\"Lol, you didn't upload file yet.\")\n",
" else:\n",
" ! sudo mv -f '{drive_path}/{file_}' '{self.path}/{file_}'\n",
" if self.proj_types == 'tmp': self.MODPACK(file_name= filename,
software= software); sleep(40)\n",
" LOG('\\nCompleted.')\n",
" except: ERROR(\"Lol, you didn't upload file yet.\")\n",
" elif self.choice == 'search':\n",
" a = self.SEARCH(search_name, software)\n",
" project = a[0]; project_names = a[1]; check = False;\n",
" project_id = project[project_names]\n",
" if software == 'Modrinth': rJSON =
GET(f'https://api.modrinth.com/v2/project/{project_id}/version').json()\n",
" else: rJSON =
GET(f'https://api.curse.tools/v1/cf/mods/{project_id}').json()['data']
['latestFilesIndexes'];\n",
" for data in rJSON:\n",
" if software == 'Curseforge': gameversions= data[\"gameVersion\"]\
n",
" else: gameversions = data[\"game_versions\"]\n",
" if self.versions in gameversions:\n",
" if software == 'Curseforge': files = data['filename']; url =
f'https://www.curseforge.com/api/v1/mods/{project_id}/files/' + str(data['fileId'])
+ '/download'\n",
" else: files = data['files'][0]['filename']; url = data['files']
[0]['url']\n",
" if ' ' in files: files = files.replace(' ', '_')\n",
" DOWNLOAD_FILE(url= url, path = self.path, file_name= files)\n",
" check = True\n",
" if check == True and self.proj_types == 'tmp':
self.MODPACK(file_name= files, software= software); LOG('\\nCompleted.'); break\n",
" elif check: LOG('\\nCompleted.'); break\n",
" if check == False: ERROR(f\"It seems that {self.software} doesn't
support this {self.proj_types}\")\n",
" elif choice == 'install_geysermc':\n",
" if self.categories != 'none' and self.colabconfig['tunnel_service']
== 'playit' and self.categories != 'forge':\n",
" if 'velocity' in self.categories:\n",
" rJSON =
GET('https://api.papermc.io/v2/projects/velocity').json()['versions']\n",
" if self.versions not in rJSON: ERROR('Not found versions')\n",
" if exists(f'{drive_path}/{server_name}/plugins') == False:\n",
" MKDIR(f'{drive_path}/{server_name}/plugins')\n",
" sleep(40)\n",
" plugin = ['ViaVersion', 'ViaBackwards']\n",
" for plugins in plugin:\n",
" rJSON =
GET(f'https://hangar.papermc.io/api/v1/projects/{plugins}/versions').json()
['result']; check = False\n",
" if self.categories.upper() in rJSON[0]
['platformDependenciesFormatted']:\n",
" for hit in rJSON:\n",
" if self.versions in hit['platformDependencies']
[self.categories.upper()]:\n",
" DOWNLOAD_FILE(url = hit[\"downloads\"]
[self.categories.upper()][\"downloadUrl\"], path =
f'{drive_path}/{self.server_name}/plugins', file_name = hit['downloads']
[self.categories.upper()][\"fileInfo\"]['name'])\n",
" check = True; break\n",
" if check == False: LOG(f\"{plugins} can't be downloaded in
your velocity server. You can try to install and upload it through website\")\n",
" else: LOG(f'Installing {plugins} done. Try to install for
more supporter version')\n",
" else: LOG(f\"{plugins} can't be downloaded in your velocity
server. You can try to install and upload it through website\")\n",
" DOWNLOAD_FILE(url =
'https://download.geysermc.org/v2/projects/geyser/versions/latest/builds/latest/
downloads/velocity', path = f'{drive_path}/{server_name}/plugins', file_name =
'Geyser-Velocity.jar')\n",
" LOG('You only need to install Floodgate on the BungeeCord or
Velocity proxy server, unless you want to use the Floodgate API on the backend
servers. Additionally, it will display Bedrock edition skins properly.')\n",
" LOG('For more details. Check out
https://wiki.geysermc.org/floodgate/setup/')\n",
" DOWNLOAD_FILE(url =
'https://download.geysermc.org/v2/projects/floodgate/versions/latest/builds/
latest/downloads/velocity', path = f'{drive_path}/{server_name}/plugins', file_name
= 'floodgate-velocity.jar')\n",
" elif 'fabric' in self.categories:\n",
" rJSON = GET('https://meta.fabricmc.net/v2/versions/game').json()
['version']\n",
" # warningserver_version\n",
" if self.versions < rJSON and self.versions >= '1.17':\n",
" LOG('Geyser-Fabric run only on 1.21.')\n",
" LOG('To use Geyser with an older server version, you can use
Geyser on a BungeeCord/Velocity proxy or Geyser-paper instead')\n",
" else: ERROR(f\"Your server_type isn't compatible for running
Geyser_MC\")\n",
" LOG('Geyser only works with server-side mods. Mods that require
a client-side install will not work!')\n",
" LOG('Download geyser mc mods')\n",
" DOWNLOAD_FILE(url =
'https://download.geysermc.org/v2/projects/geyser/versions/latest/builds/latest/
downloads/fabric', path = f'{drive_path}/{self.server_name}/mods', file_name=
'Geyser-Fabric.jar')\n",
" # Geyser mc mod require fabric api.\n",
" LOG('Download Fabric api (requirement)')\n",
" rJSON =
GET(f'https://api.modrinth.com/v2/project/P7dR8mSH/version').json()\n",
" check = False\n",
" for data in rJSON:\n",
" if self.versions in data[\"game_versions\"]:\n",
" files = data['files'][0]; url = files['url']\n",
" DOWNLOAD_FILE(url= url, path = self.path, file_name=
files['filename']); check = True\n",
" if check: break\n",
" if check == False: ERROR(f\"It seems that theresn't fabric api
for this minecraft version\")\n",
" LOG('Download floodgate')\n",
" rJSON =
GET(f'https://api.modrinth.com/v2/project/bWrNNfkb/version').json()\n",
" check = False\n",
" for data in rJSON:\n",
" if versions in data[\"game_versions\"]:\n",
" files = data['files'][0]; url = files['url']\n",
" DOWNLOAD_FILE(url= url, path = self.path, file_name=
files['filename']); check = True\n",
" if check: break\n",
" if check == False: ERROR(f\"It seems that theresn't fabric api
for this minecraft version\")\n",
" elif 'paper' in self.categories or 'purpur' in self.categories:\
n",
" rJSON = GET('https://api.papermc.io/v2/projects/paper').json()
['versions'][-1]\n",
" if self.versions < rJSON and self.versions >= '1.17':\n",
" plugin = ['ViaVersion', 'ViaBackwards']\n",
" for plugins in plugin:\n",
" rJSON =
GET(f'https://hangar.papermc.io/api/v1/projects/{plugins}/versions').json()
['result']; check = False\n",
" if self.categories.upper() in rJSON[0]
['platformDependenciesFormatted']:\n",
" for hit in rJSON:\n",
" if self.versions in hit['platformDependencies']
[self.categories.upper()]:\n",
" DOWNLOAD_FILE(url = hit[\"downloads\"]
[self.categories.upper()][\"downloadUrl\"], path =
f'{drive_path}/{self.server_name}/plugins', file_name = hit['downloads']
[self.categories.upper()][\"fileInfo\"]['name'])\n",
" check = True; break\n",
" if check == False: LOG(f\"{plugins} can't be downloaded in
your velocity server. You can try to install and upload it through website\")\n",
" else: LOG(f'Installing {plugins} done. Try to install for
more supporter version')\n",
" else: LOG(f\"{plugins} can't be downloaded in your velocity
server. You can try to install and upload it through website\")\n",
" else: ERROR(f\"Your server_type isn't compatible for running
Geyser_MC\")\n",
" LOG('Download geyser mc plugin')\n",
" DOWNLOAD_FILE(url =
'https://download.geysermc.org/v2/projects/geyser/versions/latest/builds/latest/
downloads/spigot', path = f'{drive_path}/{self.server_name}/plugins', file_name=
'Geyser-Spigot.jar')\n",
" LOG('Download floodgate')\n",
" DOWNLOAD_FILE(url =
'https://download.geysermc.org/v2/projects/floodgate/versions/latest/builds/
latest/downloads/spigot', path = f'{drive_path}/{self.server_name}/plugins',
file_name = 'floodgate-spigot.jar')\n",
" # Set up notification\n",
" self.colabconfig['Geysermc']= 'notdone'\n",
" dump(self.colabconfig, open(COLABCONFIG(self.server_name),'w'))\
n",
" # Ping\n",
" LOG('\\nInstalling done. Try to rerun the server to
configuration.')\n",
" else: ERROR(f\"Your server_type isn't compatible for running
Geyser_MC\")\n",
" elif choice == 'dynmap support':\n",
" if self.categories == 'paper' or self.categories == 'purpur' or
self.categories == 'fabric' or self.categories == 'forge':\n",
" if self.colabconfig['tunnel_service'] != 'ngrok' or
self.colabconfig['tunnel_service'] != 'playit' or
self.colabconfig['tunnel_service'] != 'localtonet' or
self.colabconfig['tunnel_service'] !='zrok': ERROR('The server is not compatible to
use dynmap')\n",
" if self.categories == 'fabric' or self.categories == 'forge':
software = 'Curseforge'\n",
" else: software = 'Modrinth'\n",
" check = False\n",
" if software == 'Modrinth': project_id = 'fRQREgAc'; rJSON =
GET(f'https://api.modrinth.com/v2/project/{project_id}/version').json()\n",
" else: project_id = '59433'; rJSON =
GET(f'https://api.curse.tools/v1/cf/mods/{project_id}').json()['data']
['latestFilesIndexes'];\n",
" for data in rJSON:\n",
" if software == 'Curseforge': gameversions=
data[\"gameVersion\"]\n",
" else: gameversions = data[\"game_versions\"]\n",
" if self.versions in gameversions:\n",
" if software == 'Curseforge' and self.catergories in
ganeversions[0]: url =
f'https://www.curseforge.com/api/v1/mods/{project_id}/files/' + str(data['fileId'])
+ '/download'\n",
" elif self.categories in data['loaders']: url = data['files']
[0]['url']\n",
" DOWNLOAD_FILE(url= url, path = self.path, file_name= 'dynmap-
server.jar')\n",
" check = True\n",
" if check: LOG('\\nCheck
https://github.com/webbukkit/dynmap/wiki/Installation-Setup-of-Dynmap-on-Linux for
more informations.'); LOG('\\nWe have done the step 1 in the set up dynmap guide.
Enjoy!'); break\n",
" if check == False: ERROR(f\"It seems that there is an error in
installing dynmap plugin/mod\")\n",
" else: ERROR('Wrong choice')\n",
"\n",
"#---------------------------------------------------------------------------------
-- RUNNING
---------------------------------------------------------------------------#\n",
"\n",
"Download_(choice = choice, url = url, server_name = server_name,
categories = categories, versions= versions, proj_types= project_types, index=
index).Install_( search_name = search_name.lower(), software = software)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "9Moa0zB_aJhR"
},
"source": [
"---"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "F7efc3oOqTVQ"
},
"source": [
"# **📁 File Management**\n",
"---\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"cellView": "form",
"id": "5feHpc86boU2"
},
"outputs": [],
"source": [
"from os.path import exists\n",
"from time import sleep\n",
"\n",
"# @markdown #### **Back up server or file?**\n",
"server_name= SERVER_IN_USE(server_name= '')\n",
"path = '/content/drive/MyDrive/minecraft' # Default path. Change to any
location you wanna\n",
"choice = 'server' # @param ['server', 'file']\n",
"file_name = ''; file_backup = ''; server_backup = ''\n",
"if choice == 'server':\n",
" server_backup = input('Server back up name: ')\n",
"else: file_name = input('File name'); file_backup = input('File back up
name: ')\n",
"\n",
"# Settings path\n",
"if file_name != '':\n",
" path1 = path + f'/{server_name}/' + file_name\n",
" if server_backup != '':\n",
" if exists(f'{drive_path}/{server_backup}') == False:\n",
" !mkdir '{drive_path}/{server_backup}'\n",
" sleep(40)\n",
" if file_backup != '' and server_backup != '': path2 = path +
f'/{server_backup}/' + file_backup\n",
" elif file_backup != '' and server_backup == '': path2 = path +
f'/{server_name}/' + file_backup\n",
" elif file_backup == '' and server_backup != '': path2 = path +
f'/{server_backup}/' + '(back-up)'\n",
" else: path2 = path + f'/{server_name}/' + '(back-up)'\n",
"else:\n",
" path1 = path + f'/{server_name}'\n",
" if server_backup != '': path2 = path + f'/{server_backup}'\n",
" else: path2 = path + f'/{server_name}' + '(back-up)'\n",
"# Checking and zipping\n",
"if exists(path1) == False: ERROR(' Creating your minecraft server before
backing up files')\n",
"if exists(path2) == True: ERROR(' Back up path exists')\n",
"# Zipping\n",
"!zip -r '{path2}.zip' '{path1}' && echo \"Zipping done!\" ||
echo \"Zipping faled.\"\n",
"# Download\n",
"INFO('We recommend you to download manually on Google Drive, anyways.')\
n",
"choice = input('Download your file? (y/n) : ')\n",
"if choice == 'y': fls.download(f'{path2}.zip')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "pHeR_15TCFCY",
"cellView": "form"
},
"outputs": [],
"source": [
"from google.colab import files as fls\n",
"from os import listdir\n",
"\n",
"%cd $drive_path\n",
"# @markdown #### **World map uploader**\n",
"choice = 'upload_file' # @param ['upload_file', 'url']\n",
"world = 'see all available' # @param ['see all available', 'world',
'world_nether', 'world_the_end']\n",
"server_name = SERVER_IN_USE(server_name = '')\n",
"print(server_name)\n",
"\n",
"if exists(f\"{drive_path}/{server_name}/world\") == False: ERROR('Running
your minecraft server')\n",
"else:\n",
" INFO(\"This only applied on .zip files. Others will work too but won't
be supported\")\n",
" if world == 'see all available':\n",
" world_ = [i for i in listdir(f'{drive_path}/{server_name}') if 'world'
in i]\n",
" LOG('All world file found: ')\n",
" for world in world_: print(' - ', world)\n",
" world = input('World file: ')\n",
" if choice == 'url':\n",
" # Download file\n",
" INFO('Check that the .ZIP file or .ZIP file URL is direct to the world
files.')\n",
" sleep(4)\n",
" url = input('Download link : ')\n",
" DOWNLOAD_FILE(url= url, path= f\"{drive_path}/{server_name}\",
file_name= 'tmp.zip')\n",
" # Unzipping\n",
" !sudo unzip {drive_path}/{server_name}/tmp.zip -d $world >/dev/null\
n",
" !rm -rf \"{drive_path}/{server_name}/tmp.zip\" >/dev/null\n",
" else:\n",
" %cd $drive_path/$server_name\n",
" # Download file\n",
" uploaded = fls.upload()\n",
" try:\n",
" file_name = [fn for fn in uploaded.keys()][0] # Get the name of the
uploaded file\n",
" # Unzipping\n",
" zip_path = f'{drive_path}/{server_name}/{file_name}'\n",
" !rm -rf \"{drive_path}/{server_name}/world\"
\"{drive_path}/{server_name}/world_nether\"
\"{drive_path}/{server_name}/world_the_end\"\n",
" !sudo unzip '{zip_path}' -d '{world}' > /dev/null && echo \"Unzipped
successfully\" || echo \"Failed to unzip. Your file musn't has special characters
like / ? ( ) among others. Check and try again. If you think this is an error
contact us by our discord: https://discord.gg/XRFWV9EREu\"\n",
" !rm -rf \"{drive_path}/{server_name}/{file_name}\" >/dev/null\n",
" except: ERROR(\"Lol, you didn't upload file yet.\")\n",
" %cd $drive_path"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "9ECTRTK01_Hj"
},
"source": [
"# **⚡ Server Improvement**\n",
"---"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"cellView": "form",
"id": "48UfuSw9328G"
},
"outputs": [],
"source": [
"from jproperties import Properties\n",
"from os.path import exists\n",
"from time import sleep\n",
"from ruamel.yaml import YAML\n",
"import sys\n",
"yaml = YAML()\n",
"\n",
"# @markdown #### **Improve the tps of your server.**\n",
"# @markdown ##### Some plugins/mods/settings will be affeted after running
this function. Thinking carefully.\n",
"\n",
"#---------------------------------------------------------------------------------
- MAIN CODE
-----------------------------------------------------------------------------------
-#\n",
"\n",
"server_name = SERVER_IN_USE(server_name = ''); colabconfig =
COLABCONFIG_LOAD(server_name)\n",
"if exists(f'{drive_path}/{server_name}/plugins') == True or
exists(f'{drive_path}/{server_name}/mods') == True:\n",
" if exists(f'{drive_path}/{server_name}/plugins') == True: path =
f'{drive_path}/{server_name}/plugins'\n",
" elif exists(f'{drive_path}/{server_name}/mods') == True: path =
f'{drive_path}/{server_name}/mods'\n",
" choice = input('Chunky (y/n) :')\n",
" if 'y' in choice.lower():\n",
" LOG('Installing chunky.'); LOG('Any plugin/software that
enables/disables/reloads plugins on runtime. See this
https://github.com/YouHaveTrouble/minecraft-optimization#plugins-enablingdisabling-
other-plugins to understand why.')\n",
" check = False; project_id = 'fALzjamp'; rJSON =
GET(f'https://api.modrinth.com/v2/project/{project_id}/version').json()\n",
" for data in rJSON:\n",
" gameversions = data[\"game_versions\"]\n",
" if colabconfig['server_version'] in gameversions and
colabconfig['server_type'] in data['loaders']: url = data['files'][0]['url'];
DOWNLOAD_FILE(url= url, path = path, file_name= 'chunky.jar'); check = True\n",
" if check: break\n",
" if check == False: ERROR(f\"It seems that there is an error in
installing chunky.jar\")\n",
"\n",
"if exists(f\"{drive_path}/{server_name}/server.properties\") == False:
ERROR(' Running your minecraft server before editing properties')\n",
"else:\n",
" LOG('Changing server.properties')\n",
" server_properties = Properties()\n",
" with open(f\"{drive_path}/{server_name}/server.properties\", \"rb\") as
f:\n",
" server_properties.load(f, \"utf-8\")\n",
" server_properties[\"sync-chunk-writes\"] = 'false'\n",
" server_properties['network-compression-threshold'] = '-1'\n",
" server_properties['simulation-distance'] = '4'\n",
" server_properties['view-distance'] = '7'\n",
" with open(f\"{drive_path}/{server_name}/server.properties\", \"wb\") as
f:\n",
" server_properties.store(f, encoding=\"utf-8\")\n",
"\n",
"LOG('List of yaml files which have been edited: \\n')\n",
"if exists(f'{drive_path}/{server_name}/purpur.yml'):\n",
" with open(f'{drive_path}/{server_name}/purpur.yml', 'r') as file_:\n",
" config = yaml.load(file_)\n",
" config['use-alternate-keepalive'] = 'true'\n",
" config['player']['teleport-if-outside-border'] = 'true'\n",
" yaml.dump(config, sys.stdout)\n",
"\n",
"if exists(f'{drive_path}/{server_name}/spigot.yml'):\n",
" with open(f'{drive_path}/{server_name}/spigot.yml') as file_:\n",
" config = yaml.load(file_)\n",
" config['world-settings']['default']['view-distance'] = 'default'\n",
" config['world-settings']['default']['mob-spawn-range'] = 3\n",
" config['world-settings']['default']['entity-activation-range']
['animals'] = 16\n",
" config['world-settings']['default']['entity-activation-range']
['monsters'] = 24\n",
" config['world-settings']['default']['entity-activation-range']
['raiders'] = 48\n",
" config['world-settings']['default']['entity-activation-range']['misc'] =
8\n",
" config['world-settings']['default']['entity-activation-range']['water']
= 8\n",
" config['world-settings']['default']['entity-activation-range']
['villagers'] = 16\n",
" config['world-settings']['default']['entity-activation-range']['flying-
monsters'] = 48\n",
" config['world-settings']['default']['entity-tracking-range'] =
{'players': 48, 'animals': 48, 'monsters': 48, 'misc': 32, 'other': 64}\n",
" config['world-settings']['default']['merge-radius'] = {'item': 3.5,
'exp': 4.0}\n",
" yaml.dump(config, sys.stdout)\n",
"\n",
"if exists(f'{drive_path}/{server_name}/config/paper-world-defaults.yml'):\
n",
" with open(f'{drive_path}/{server_name}/config/paper-world-defaults.yml')
as file_:\n",
" config = yaml.load(file_)\n",
" config['chunks']['delay-chunk-unloads-by'] -'10s'\n",
" config['chunks']['max-auto-save-chunks-per-tick'] = 10\n",
" config['chunks']['prevent-moving-into-unloaded-chunks'] = 'true'\n",
" config['chunks']['entity-per-chunk-save-limit'] = {'area_effect_cloud':
8, 'arrow': 16, 'dragon_fireball': 3, 'egg': 8, 'ender_pearl': 8,\n",
" 'experience_bottle':
3, 'experience_orb': 16, 'eye_of_ender': 8, 'fireball': 8, 'firework_rocket': 8,\
n",
" 'llama_spit': 3,
'potion': 8, 'shulker_bullet': 8, 'small_fireball': 8, 'snowball': 8,
'spectral_arrow': 16,\n",
" 'trident': 16,
'wither_skull': 4}\n",
" config['entities']['spawning']['non-player-arrow-despawn-rate'] = 20\n",
" config['entities']['spawning']['despawn-ranges'] = {'ambient': {'hard':
72, 'soft': 30}, 'axolotl': {'hard': 72, 'soft': 30}, 'creature': {'hard': 72,
'soft': 30}, 'misc': {'hard': 72, 'soft': 30},\n",
" 'monster': { 'hard':
72, 'soft': 30}, 'underground_water_creature': {'hard': 72, 'soft': 30},
'water_ambient': {'hard': 72, 'soft': 30}, 'water_creature': {'hard': 72, 'soft':
30}}\n",
" config['entities']['spawning']['per-player-mob-spawns'] = 'true'\n",
" config['entities']['spawning']['alt-item-despawn-rate'] = {'enabled':
'true', 'items': {'cobblestone': 300, 'netherrack': 300, 'sand': 300, 'red_sand':
300, 'gravel': 300, 'dirt': 300, 'short_grass': 300, 'pumpkin': 300, 'melon_slice':
300, 'kelp': 300,\n",
"
'bamboo': 300, 'sugar_cane': 300, 'twisting_vines': 300, 'weeping_vines': 300,
'oak_leaves': 300, 'spruce_leaves': 300, 'birch_leaves': 300, 'jungle_leaves':
300,\n",
"
'acacia_leaves': 300, 'dark_oak_leaves': 300, 'mangrove_leaves': 300, 'cactus':
300, 'diorite': 300, 'granite': 300, 'andesite': 300, 'scaffolding': 600}}\n",
" config['misc']['update-pathfinding-on-block-update'] = 'false'\n",
" config['misc']['redstone-implementation'] = 'ALTERNATE_CURRENT'\n",
" config['collisions']['max-entity-collisions'] = 2\n",
" config['collisions']['fix-climbing-bypassing-cramming-rule']= 'true'\n",
" config['environment']['optimize-explosions'] = 'true'\n",
" config['environment']['nether-ceiling-void-damage-height'] = 127\n",
" yaml.dump(config, sys.stdout)\n",
"\n",
"if exists(f'{drive_path}/{server_name}/bukkit.yml'):\n",
" with open(f'{drive_path}/{server_name}/bukkit.yml') as file_:\n",
" config = yaml.load(file_)\n",
" config['spawn-limits'] = {'monsters': 20, 'animals': 5, 'water-animals':
2, 'water-ambient': 2, 'water-underground-creature': 3, 'axolotls': 3, 'ambient':
1}\n",
" config['ticks-per'] = {'monster-spawns': 10, 'animal-spawns': 400,
'water-spawns': 400, 'water-ambient-spawns': 400, 'water-underground-creature-
spawns': 400, 'axolotl-spawns': 400, 'ambient-spawns': 400}\n",
" yaml.dump(config, sys.stdout)\n",
"\n",
"choice = input('More guide (y/n) ?')\n",
"if 'y' in choice.lower():\n",
" if exists(f'{drive_path}/{server_name}/plugins'):\n",
" LOG('NOTICES: ')\n",
" LOG('Plugins removing ground items is not necessary. If you download
those plugins, please remove them')\n",
" LOG(\"Mob stacker plugins: \\n It's really hard to justify using
one.\\n Stacking naturally spawned entities causes more lag than not stacking them
at all due to the server constantly trying to spawn more mobs.\\n The only
'acceptable' use case is for spawners on servers with a large amount of
spawners.\")\n",
" LOG('Plugins enabling/disabling other plugins:\\n Anything that
enables or disables plugins on runtime is extremely dangerous.\\n Loading a plugin
like that can cause fatal errors with tracking data and disabling a plugin can lead
to errors due to removing dependency. \\n The /reload command suffers from exact
same issues and you can read more about them in
https://madelinemiller.dev/blog/problem-with-reload/')\n",
"\n",
" LOG('HOW TO MEASURE LAG: ')\n",
" if colabconfig['server_type'] == 'paper':\n",
" LOG(\"Paper offers a /mspt command that will tell you how much time
the server took to calculate recent ticks. If the first and second value you see
are lower than 50, then congratulations!\\n Your server is not lagging! If the
third value is over 50 then it means there was at least 1 tick that took longer.
That's completely normal and happens from time to time, so don't panic.\")\n",
" if exists(f'{drive_path}/{server_name}/plugins'):\n",
" LOG(\"Spark (https://spark.lucko.me/) is a plugin that allows you to
profile your server's CPU and memory usage. You can read on how to use it on its
wiki.\\n There's also a guide on how to find the cause of lag spikes here:
https://spark.lucko.me/docs/guides/Finding-lag-spikes\")\n",
" LOG(\"Way to see what might be going on when your server is lagging are
Timings. Timings is a tool that lets you see exactly what tasks are taking the
longest.\\n It's the most basic troubleshooting tool and if you ask for help
regarding lag you will most likely be asked for your Timings. Timings is known to
have a serious performance impact on servers, it's recommended to use the Spark
plugin over Timings and use Purpur or Pufferfish to disable Timings all
together.\")\n",
" LOG(\"To get Timings of your server, you just need to execute the
/timings paste command and click the link you're provided with.\\n You can share
this link with other people to let them help you. It's also easy to misread if you
don't know what you're doing. \")\n",
" LOG(\"There is a detailed video tutorial by Aikar
(https://www.youtube.com/watch?v=T4J0A9l7bfQ) on how to read them.\")\n",
"\n",
" LOG('Minecraft exploits and how to fix them: To see how to fix exploits
that can cause lag spikes or crashes on a Minecraft server, refer to
https://github.com/YouHaveTrouble/minecraft-exploits-and-how-to-fix-them')\n",
"\n",
"LOG('Completed')"
]
}
],
"metadata": {
"colab": {
"cell_execution_strategy": "setup",
"provenance": [],
"include_colab_link": true
},
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.12"
}
},
"nbformat": 4,
"nbformat_minor": 0
}