diff --git a/CHANGELOG.md b/CHANGELOG.md
index 39681811..7e462a61 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,21 @@
 # Changelog
 
+## --- [4.0.8] - 2022/08/05
+### New features
+- Add Crafty Version Check and notification ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/411))
+### Bug fixes
+- Fix SU status not sticking on user creation ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/410))
+- Handle Missing Java From Win Registry ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/413))
+- Disable restart while server is backing up ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/414))
+- Fix server creation with serverjars API ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/415))
+- Fix API Key delete confirmations ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/416))
+### Tweaks
+- Add next run to schedule info ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/417))
+### Lang
+- Updated `es_ES` ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/412))
+- Added `pl_PL` ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/412))
+<br><br>
+
 ## --- [4.0.7] - 2022/07/18
 ### New features
 - Task toggle ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/398))
diff --git a/README.md b/README.md
index 40fd9026..021d6f3f 100644
--- a/README.md
+++ b/README.md
@@ -2,11 +2,11 @@
 
 [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
 [![Supported Python Versions](https://shields.io/badge/python-3.8%20%7C%203.9%20%7C%203.10%20-blue)](https://www.python.org)
-[![Version(temp-hardcoded)](https://img.shields.io/badge/release-v4.0.7--beta-orange)](https://gitlab.com/crafty-controller/crafty-4/-/releases)
+[![Version(temp-hardcoded)](https://img.shields.io/badge/release-v4.0.8--beta-orange)](https://gitlab.com/crafty-controller/crafty-4/-/releases)
 [![Code Quality(temp-hardcoded)](https://img.shields.io/badge/code%20quality-10-brightgreen)](https://gitlab.com/crafty-controller/crafty-4)
 [![Build Status](https://gitlab.com/crafty-controller/crafty-4/badges/master/pipeline.svg)](https://gitlab.com/crafty-controller/crafty-4/-/commits/master)
 
-# Crafty Controller 4.0.7-beta
+# Crafty Controller 4.0.8-beta
 > Python based Control Panel for your Minecraft Server
 
 ## What is Crafty Controller?
diff --git a/app/classes/minecraft/serverjars.py b/app/classes/minecraft/serverjars.py
index b1fc9580..a5eb11ba 100644
--- a/app/classes/minecraft/serverjars.py
+++ b/app/classes/minecraft/serverjars.py
@@ -51,7 +51,7 @@ class ServerJars:
 
     def get_serverjar_data(self):
         data = self._read_cache()
-        return data.get("servers")
+        return data.get("types")
 
     def _check_api_alive(self):
         logger.info("Checking serverjars.com API status")
@@ -70,6 +70,39 @@ class ServerJars:
         logger.error("unable to contact serverjars.com api")
         return False
 
+    def manual_refresh_cache(self):
+        cache_file = self.helper.serverjar_cache
+
+        # debug override
+        # cache_old = True
+
+        # if the API is down... we bomb out
+        if not self._check_api_alive():
+            return False
+
+        logger.info("Manual Refresh requested.")
+        now = datetime.now()
+        data = {
+            "last_refreshed": now.strftime("%m/%d/%Y, %H:%M:%S"),
+            "types": {},
+        }
+
+        jar_types = self._get_server_type_list()
+        data["types"].update(jar_types)
+        for s in data["types"]:
+            data["types"].update({s: dict.fromkeys(data["types"].get(s), {})})
+            for j in data["types"].get(s):
+                versions = self._get_jar_details(j, s)
+                data["types"][s].update({j: versions})
+        # save our cache
+        try:
+            with open(cache_file, "w", encoding="utf-8") as f:
+                f.write(json.dumps(data, indent=4))
+                logger.info("Cache file refreshed")
+
+        except Exception as e:
+            logger.error(f"Unable to update serverjars.com cache file: {e}")
+
     def refresh_cache(self):
 
         cache_file = self.helper.serverjar_cache
@@ -88,22 +121,18 @@ class ServerJars:
         if cache_old:
             logger.info("Cache file is over 1 day old, refreshing")
             now = datetime.now()
-            data = {"last_refreshed": now.strftime("%m/%d/%Y, %H:%M:%S"), "servers": {}}
+            data = {
+                "last_refreshed": now.strftime("%m/%d/%Y, %H:%M:%S"),
+                "types": {},
+            }
 
             jar_types = self._get_server_type_list()
-
-            # for each jar type
-            for j in jar_types:
-
-                # for each server
-                for s in jar_types.get(j):
-                    # jar versions for this server
-                    versions = self._get_jar_details(s)
-
-                    # add these versions (a list) to the dict with
-                    # a key of the server type
-                    data["servers"].update({s: versions})
-
+            data["types"].update(jar_types)
+            for s in data["types"]:
+                data["types"].update({s: dict.fromkeys(data["types"].get(s), {})})
+                for j in data["types"].get(s):
+                    versions = self._get_jar_details(j, s)
+                    data["types"][s].update({j: versions})
             # save our cache
             try:
                 with open(cache_file, "w", encoding="utf-8") as f:
@@ -113,8 +142,8 @@ class ServerJars:
             except Exception as e:
                 logger.error(f"Unable to update serverjars.com cache file: {e}")
 
-    def _get_jar_details(self, jar_type="servers"):
-        url = f"/api/fetchAll/{jar_type}"
+    def _get_jar_details(self, server_type, jar_type="servers"):
+        url = f"/api/fetchAll/{jar_type}/{server_type}"
         response = self._get_api_result(url)
         temp = []
         for v in response:
@@ -127,19 +156,19 @@ class ServerJars:
         response = self._get_api_result(url)
         return response
 
-    def download_jar(self, server, version, path, server_id):
+    def download_jar(self, jar, server, version, path, server_id):
         update_thread = threading.Thread(
             name=f"server_download-{server_id}-{server}-{version}",
             target=self.a_download_jar,
             daemon=True,
-            args=(server, version, path, server_id),
+            args=(jar, server, version, path, server_id),
         )
         update_thread.start()
 
-    def a_download_jar(self, server, version, path, server_id):
+    def a_download_jar(self, jar, server, version, path, server_id):
         # delaying download for server register to finish
         time.sleep(3)
-        fetch_url = f"{self.base_url}/api/fetchJar/{server}/{version}"
+        fetch_url = f"{self.base_url}/api/fetchJar/{jar}/{server}/{version}"
         server_users = PermissionsServers.get_server_user_list(server_id)
 
         # We need to make sure the server is registered before
diff --git a/app/classes/models/management.py b/app/classes/models/management.py
index 085bdd37..c3eed588 100644
--- a/app/classes/models/management.py
+++ b/app/classes/models/management.py
@@ -115,6 +115,7 @@ class Schedules(BaseModel):
     cron_string = CharField(default="")
     parent = IntegerField(null=True)
     delay = IntegerField(default=0)
+    next_run = CharField(default="")
 
     class Meta:
         table_name = "schedules"
@@ -285,6 +286,7 @@ class HelpersManagement:
                 Schedules.cron_string: cron_string,
                 Schedules.parent: parent,
                 Schedules.delay: delay,
+                Schedules.next_run: "",
             }
         ).execute()
         return sch_id
diff --git a/app/classes/shared/helpers.py b/app/classes/shared/helpers.py
index e1d9c3c0..40a57219 100644
--- a/app/classes/shared/helpers.py
+++ b/app/classes/shared/helpers.py
@@ -20,6 +20,7 @@ import itertools
 from datetime import datetime
 from socket import gethostname
 from contextlib import redirect_stderr, suppress
+from packaging import version as pkg_version
 
 from app.classes.shared.null_writer import NullWriter
 from app.classes.shared.console import Console
@@ -75,6 +76,7 @@ class Helpers:
 
         self.websocket_helper = WebSocketHelper(self)
         self.translation = Translation(self)
+        self.update_available = False
 
     @staticmethod
     def auto_installer_fix(ex):
@@ -82,6 +84,29 @@ class Helpers:
         print(f"Import Error: Unable to load {ex.name} module")
         installer.do_install()
 
+    def check_remote_version(self):
+        """
+        Check if the remote version is newer than the local version
+        Returning remote version if it is newer, otherwise False.
+        """
+        try:
+            # Get tags from Gitlab, select the latest and parse the semver
+            response = get(
+                "https://gitlab.com/api/v4/projects/20430749/repository/tags"
+            )
+            if response.status_code == 200:
+                remote_version = pkg_version.parse(json.loads(response.text)[0]["name"])
+
+            # Get local version data from the file and parse the semver
+            local_version = pkg_version.parse(self.get_version_string())
+
+            if remote_version > local_version:
+                return remote_version
+
+        except Exception as e:
+            logger.error(f"Unable to check for new crafty version! \n{e}")
+        return False
+
     @staticmethod
     def find_java_installs():
         # If we're windows return oracle java versions,
diff --git a/app/classes/shared/main_controller.py b/app/classes/shared/main_controller.py
index c6c3cfb6..393aa475 100644
--- a/app/classes/shared/main_controller.py
+++ b/app/classes/shared/main_controller.py
@@ -422,6 +422,7 @@ class Controller:
 
     def create_jar_server(
         self,
+        jar: str,
         server: str,
         version: str,
         name: str,
@@ -493,7 +494,7 @@ class Controller:
 
         # download the jar
         self.server_jars.download_jar(
-            server, version, os.path.join(server_dir, server_file), new_id
+            jar, server, version, os.path.join(server_dir, server_file), new_id
         )
 
         return new_id
diff --git a/app/classes/shared/server.py b/app/classes/shared/server.py
index 2391b827..008fe989 100644
--- a/app/classes/shared/server.py
+++ b/app/classes/shared/server.py
@@ -247,11 +247,20 @@ class ServerInstance:
                     "Oracle Java detected. Changing start command to avoid re-exec."
                 )
                 which_java_raw = self.helper.which_java()
-                java_path = which_java_raw + "\\bin\\java"
+                try:
+                    java_path = which_java_raw + "\\bin\\java"
+                except TypeError:
+                    logger.warning(
+                        "Could not find java in the registry even though"
+                        " Oracle java is installed. Re-exec expected, but we have no"
+                        " other options. CPU stats will not work for process."
+                    )
+                    java_path = ""
                 if str(which_java_raw) != str(self.helper.get_servers_root_dir) or str(
                     self.helper.get_servers_root_dir
                 ) in str(which_java_raw):
-                    self.server_command[0] = java_path
+                    if java_path != "":
+                        self.server_command[0] = java_path
                 else:
                     logger.critcal(
                         "Possible attack detected. User attempted to exec "
@@ -647,6 +656,13 @@ class ServerInstance:
             self.helper.websocket_helper.broadcast_user(user, "send_start_reload", {})
 
     def restart_threaded_server(self, user_id):
+        bu_conf = HelpersManagement.get_backup_config(self.server_id)
+        if self.is_backingup and bu_conf["shutdown"]:
+            logger.info(
+                "Restart command detected. Supressing - server has"
+                " backup shutdown enabled and server is currently backing up."
+            )
+            return
         # if not already running, let's just start
         if not self.check_running():
             self.run_threaded_server(user_id)
diff --git a/app/classes/shared/tasks.py b/app/classes/shared/tasks.py
index 9876abc2..2e2540ea 100644
--- a/app/classes/shared/tasks.py
+++ b/app/classes/shared/tasks.py
@@ -3,7 +3,7 @@ import time
 import logging
 import threading
 import asyncio
-import datetime
+from datetime import datetime
 
 from tzlocal import get_localzone
 from tzlocal.utils import ZoneInfoNotFoundError
@@ -192,6 +192,15 @@ class TasksManager:
     def scheduler_thread(self):
         schedules = HelpersManagement.get_schedules_enabled()
         self.scheduler.add_listener(self.schedule_watcher, mask=EVENT_JOB_EXECUTED)
+        self.scheduler.start()
+        self.check_for_updates()
+        self.scheduler.add_job(
+            self.check_for_updates,
+            "interval",
+            hours=12,
+            id="update_watcher",
+            start_date=datetime.now(),
+        )
         # self.scheduler.add_job(
         #    self.scheduler.print_jobs, "interval", seconds=10, id="-1"
         # )
@@ -201,7 +210,7 @@ class TasksManager:
             if schedule.interval != "reaction":
                 if schedule.cron_string != "":
                     try:
-                        self.scheduler.add_job(
+                        new_job = self.scheduler.add_job(
                             HelpersManagement.add_command,
                             CronTrigger.from_crontab(
                                 schedule.cron_string, timezone=str(self.tz)
@@ -215,6 +224,7 @@ class TasksManager:
                             ],
                         )
                     except Exception as e:
+                        new_job = "error"
                         Console.error(f"Failed to schedule task with error: {e}.")
                         Console.warning("Removing failed task from DB.")
                         logger.error(f"Failed to schedule task with error: {e}.")
@@ -225,7 +235,7 @@ class TasksManager:
                         )
                 else:
                     if schedule.interval_type == "hours":
-                        self.scheduler.add_job(
+                        new_job = self.scheduler.add_job(
                             HelpersManagement.add_command,
                             "cron",
                             minute=0,
@@ -239,7 +249,7 @@ class TasksManager:
                             ],
                         )
                     elif schedule.interval_type == "minutes":
-                        self.scheduler.add_job(
+                        new_job = self.scheduler.add_job(
                             HelpersManagement.add_command,
                             "cron",
                             minute="*/" + str(schedule.interval),
@@ -253,7 +263,7 @@ class TasksManager:
                         )
                     elif schedule.interval_type == "days":
                         curr_time = schedule.start_time.split(":")
-                        self.scheduler.add_job(
+                        new_job = self.scheduler.add_job(
                             HelpersManagement.add_command,
                             "cron",
                             day="*/" + str(schedule.interval),
@@ -267,7 +277,18 @@ class TasksManager:
                                 schedule.command,
                             ],
                         )
-        self.scheduler.start()
+            if new_job != "error":
+                task = self.controller.management.get_scheduled_task_model(
+                    int(new_job.id)
+                )
+                self.controller.management.update_scheduled_task(
+                    task.schedule_id,
+                    {
+                        "next_run": str(
+                            new_job.next_run_time.strftime("%m/%d/%Y, %H:%M:%S")
+                        )
+                    },
+                )
         jobs = self.scheduler.get_jobs()
         logger.info("Loaded schedules. Current enabled schedules: ")
         for item in jobs:
@@ -298,7 +319,7 @@ class TasksManager:
         if job_data["enabled"] and job_data["interval_type"] != "reaction":
             if job_data["cron_string"] != "":
                 try:
-                    self.scheduler.add_job(
+                    new_job = self.scheduler.add_job(
                         HelpersManagement.add_command,
                         CronTrigger.from_crontab(
                             job_data["cron_string"], timezone=str(self.tz)
@@ -312,6 +333,7 @@ class TasksManager:
                         ],
                     )
                 except Exception as e:
+                    new_job = "error"
                     Console.error(f"Failed to schedule task with error: {e}.")
                     Console.warning("Removing failed task from DB.")
                     logger.error(f"Failed to schedule task with error: {e}.")
@@ -320,7 +342,7 @@ class TasksManager:
                     self.controller.management_helper.delete_scheduled_task(sch_id)
             else:
                 if job_data["interval_type"] == "hours":
-                    self.scheduler.add_job(
+                    new_job = self.scheduler.add_job(
                         HelpersManagement.add_command,
                         "cron",
                         minute=0,
@@ -334,7 +356,7 @@ class TasksManager:
                         ],
                     )
                 elif job_data["interval_type"] == "minutes":
-                    self.scheduler.add_job(
+                    new_job = self.scheduler.add_job(
                         HelpersManagement.add_command,
                         "cron",
                         minute="*/" + str(job_data["interval"]),
@@ -348,7 +370,7 @@ class TasksManager:
                     )
                 elif job_data["interval_type"] == "days":
                     curr_time = job_data["start_time"].split(":")
-                    self.scheduler.add_job(
+                    new_job = self.scheduler.add_job(
                         HelpersManagement.add_command,
                         "cron",
                         day="*/" + str(job_data["interval"]),
@@ -364,6 +386,14 @@ class TasksManager:
                     )
             logger.info("Added job. Current enabled schedules: ")
             jobs = self.scheduler.get_jobs()
+            if new_job != "error":
+                task = self.controller.management.get_scheduled_task_model(
+                    int(new_job.id)
+                )
+                self.controller.management.update_scheduled_task(
+                    task.schedule_id,
+                    {"next_run": new_job.next_run_time.strftime("%m/%d/%Y, %H:%M:%S")},
+                )
             for item in jobs:
                 logger.info(f"JOB: {item}")
 
@@ -418,7 +448,7 @@ class TasksManager:
         if job_data["enabled"] and job_data["interval"] != "reaction":
             if job_data["cron_string"] != "":
                 try:
-                    self.scheduler.add_job(
+                    new_job = self.scheduler.add_job(
                         HelpersManagement.add_command,
                         CronTrigger.from_crontab(
                             job_data["cron_string"], timezone=str(self.tz)
@@ -432,12 +462,13 @@ class TasksManager:
                         ],
                     )
                 except Exception as e:
+                    new_job = "error"
                     Console.error(f"Failed to schedule task with error: {e}.")
                     Console.info("Removing failed task from DB.")
                     self.controller.management_helper.delete_scheduled_task(sch_id)
             else:
                 if job_data["interval_type"] == "hours":
-                    self.scheduler.add_job(
+                    new_job = self.scheduler.add_job(
                         HelpersManagement.add_command,
                         "cron",
                         minute=0,
@@ -451,7 +482,7 @@ class TasksManager:
                         ],
                     )
                 elif job_data["interval_type"] == "minutes":
-                    self.scheduler.add_job(
+                    new_job = self.scheduler.add_job(
                         HelpersManagement.add_command,
                         "cron",
                         minute="*/" + str(job_data["interval"]),
@@ -465,7 +496,7 @@ class TasksManager:
                     )
                 elif job_data["interval_type"] == "days":
                     curr_time = job_data["start_time"].split(":")
-                    self.scheduler.add_job(
+                    new_job = self.scheduler.add_job(
                         HelpersManagement.add_command,
                         "cron",
                         day="*/" + str(job_data["interval"]),
@@ -479,6 +510,14 @@ class TasksManager:
                             job_data["command"],
                         ],
                     )
+            if new_job != "error":
+                task = self.controller.management.get_scheduled_task_model(
+                    int(new_job.id)
+                )
+                self.controller.management.update_scheduled_task(
+                    task.schedule_id,
+                    {"next_run": new_job.next_run_time.strftime("%m/%d/%Y, %H:%M:%S")},
+                )
         else:
             try:
                 self.scheduler.get_job(str(sch_id))
@@ -506,6 +545,15 @@ class TasksManager:
                 if task.one_time:
                     self.remove_job(task.schedule_id)
                     logger.info("one time task detected. Deleting...")
+                else:
+                    self.controller.management.update_scheduled_task(
+                        task.schedule_id,
+                        {
+                            "next_run": self.scheduler.get_job(
+                                event.job_id
+                            ).next_run_time.strftime("%m/%d/%Y, %H:%M:%S")
+                        },
+                    )
                 # check for any child tasks for this. It's kind of backward,
                 # but this makes DB management a lot easier. One to one
                 # instead of one to many.
@@ -606,6 +654,16 @@ class TasksManager:
                     )
             time.sleep(1)
 
+    def check_for_updates(self):
+        logger.info("Checking for Crafty updates...")
+        self.helper.update_available = self.helper.check_remote_version()
+        if self.helper.update_available:
+            logger.info(f"Found new version {self.helper.update_available}")
+        else:
+            logger.info(
+                "No updates found! You are on the most up to date Crafty version."
+            )
+
     def log_watcher(self):
         self.controller.servers.check_for_old_logs()
         self.scheduler.add_job(
diff --git a/app/classes/web/ajax_handler.py b/app/classes/web/ajax_handler.py
index 44ba6b34..42dc4275 100644
--- a/app/classes/web/ajax_handler.py
+++ b/app/classes/web/ajax_handler.py
@@ -454,6 +454,14 @@ class AjaxHandler(BaseHandler):
             self.helper.backup_select(path, exec_user["user_id"])
             return
 
+        elif page == "jar_cache":
+            if not superuser:
+                self.redirect("/panel/error?error=Not a super user")
+                return
+
+            self.controller.server_jars.manual_refresh_cache()
+            return
+
     @tornado.web.authenticated
     def delete(self, page):
         api_key, _, exec_user = self.current_user
diff --git a/app/classes/web/panel_handler.py b/app/classes/web/panel_handler.py
index fd4c2367..b5a07eb3 100644
--- a/app/classes/web/panel_handler.py
+++ b/app/classes/web/panel_handler.py
@@ -284,7 +284,7 @@ class PanelHandler(BaseHandler):
 
         page_data: t.Dict[str, t.Any] = {
             # todo: make this actually pull and compare version data
-            "update_available": False,
+            "update_available": self.helper.update_available,
             "serverTZ": tz,
             "version_data": self.helper.get_version_string(),
             "user_data": exec_user,
@@ -1878,15 +1878,12 @@ class PanelHandler(BaseHandler):
                 # We don't want that. Automatically make them stay super user
                 # since we know they are.
                 if str(exec_user["user_id"]) != str(user_id):
-                    superuser = bleach.clean(self.get_argument("superuser", "0"))
+                    superuser = int(bleach.clean(self.get_argument("superuser", "0")))
                 else:
-                    superuser = "1"
+                    superuser = 1
             else:
-                superuser = "0"
-            if superuser == "1":
-                superuser = True
-            else:
-                superuser = False
+                superuser = 0
+
             if not exec_user["superuser"]:
                 if username is None or username == "":
                     self.redirect("/panel/error?error=Invalid username")
@@ -2062,13 +2059,9 @@ class PanelHandler(BaseHandler):
             )
             # We don't want a non-super user to be able to create a super user.
             if superuser:
-                new_superuser = bleach.clean(self.get_argument("superuser", "0"))
+                new_superuser = int(bleach.clean(self.get_argument("superuser", "0")))
             else:
-                new_superuser = "0"
-            if superuser == "1":
-                new_superuser = True
-            else:
-                new_superuser = False
+                new_superuser = 0
 
             if EnumPermissionsCrafty.USER_CONFIG not in exec_user_crafty_permissions:
                 self.redirect(
diff --git a/app/classes/web/server_handler.py b/app/classes/web/server_handler.py
index e4e10a04..df4ba684 100644
--- a/app/classes/web/server_handler.py
+++ b/app/classes/web/server_handler.py
@@ -92,10 +92,12 @@ class ServerHandler(BaseHandler):
         template = "public/404.html"
 
         page_data = {
+            "update_available": self.helper.update_available,
             "version_data": self.helper.get_version_string(),
             "user_data": exec_user,
             "user_role": exec_user_role,
             "roles": list_roles,
+            "super_user": exec_user["superuser"],
             "user_crafty_permissions": exec_user_crafty_permissions,
             "crafty_permissions": {
                 "Server_Creation": EnumPermissionsCrafty.SERVER_CREATION,
@@ -386,14 +388,20 @@ class ServerHandler(BaseHandler):
                 # deletes temp dir
                 FileHelpers.del_dirs(zip_path)
             else:
-                if len(server_parts) != 2:
+                if len(server_parts) != 3:
                     self.redirect("/panel/error?error=Invalid server data")
                     return
-                server_type, server_version = server_parts
+                jar_type, server_type, server_version = server_parts
                 # TODO: add server type check here and call the correct server
                 # add functions if not a jar
                 new_server_id = self.controller.create_jar_server(
-                    server_type, server_version, server_name, min_mem, max_mem, port
+                    jar_type,
+                    server_type,
+                    server_version,
+                    server_name,
+                    min_mem,
+                    max_mem,
+                    port,
                 )
                 self.controller.management.add_to_audit_log(
                     exec_user["user_id"],
diff --git a/app/config/version.json b/app/config/version.json
index 1ae57135..1d4ec0c1 100644
--- a/app/config/version.json
+++ b/app/config/version.json
@@ -1,6 +1,6 @@
 {
   "major": 4,
   "minor": 0,
-  "sub": 7,
+  "sub": 8,
   "meta": "beta"
 }
diff --git a/app/frontend/templates/footer.html b/app/frontend/templates/footer.html
index fec76eba..65840cb8 100644
--- a/app/frontend/templates/footer.html
+++ b/app/frontend/templates/footer.html
@@ -1,12 +1,27 @@
 <!-- partial:partials/_footer.html -->
   <footer class="footer">
     <div class="container-fluid ">
-
-<span class="text-muted d-block text-center text-sm-left d-sm-inline-block">{{ translate('footer', 'copyright', data['lang']) }} © 2021 - <span x-data x-text="new Date().getFullYear()"></span> <a href="https://craftycontrol.com/" target="_blank">Crafty Controller</a>. {{ translate('footer', 'allRightsReserved', data['lang']) }}.</span>
-
-<span class="float-none float-sm-right d-block mt-1 mt-sm-0 text-center">{{ translate('footer', 'version', data['lang']) }}: {{ data['version_data'] }}
-      </span>
+      <span class="text-muted d-block text-center text-sm-left d-sm-inline-block">{{ translate('footer', 'copyright', data['lang']) }} © 2021 - <span x-data x-text="new Date().getFullYear()"></span> <a href="https://craftycontrol.com/" target="_blank">Crafty Controller</a>. {{ translate('footer', 'allRightsReserved', data['lang']) }}.</span>
+      <span class="float-none float-sm-right d-block mt-1 mt-sm-0">&nbsp;&nbsp;{{ translate('footer', 'version', data['lang']) }}: {{ data['version_data'] }}</span>
+      {% if data['update_available'] %}
+        <span class="float-none float-sm-right d-block mt-1 mt-sm-0"><a target="_blank" class="blink-text" href="https://gitlab.com/crafty-controller/crafty-4/-/releases">Update Available!</a></span>
+      {% end %}
     </div>
-
+    <style>
+      a:hover {
+        text-decoration: none;
+      }
+      .blink-text{
+        color: #000;
+        font-weight: bold;
+        font-size: 2rem;
+        animation: blinkingText 2s infinite;
+	    }
+      @keyframes blinkingText{
+        0%		{ color: grey;}
+        50%   { color: red;}
+        100%	{ color: grey;}
+      }
+    </style>
   </footer>
 <!-- partial -->
diff --git a/app/frontend/templates/panel/panel_edit_user_apikeys.html b/app/frontend/templates/panel/panel_edit_user_apikeys.html
index d0d650b5..062cf8d9 100644
--- a/app/frontend/templates/panel/panel_edit_user_apikeys.html
+++ b/app/frontend/templates/panel/panel_edit_user_apikeys.html
@@ -15,7 +15,7 @@
             <div class="page-header">
                 <h4 class="page-title">
                     {{ translate('apiKeys', 'pageTitle', data['lang']) }} - {{ data['user']['user_id'] }}
-                    <br/>
+                    <br />
                     <small>UID: {{ data['user']['user_id'] }}</small>
                 </h4>
             </div>
@@ -32,14 +32,12 @@
                     <ul class="nav nav-tabs col-md-12 tab-simple-styled " role="tablist">
                         <li class="nav-item">
                             <a class="nav-link" href="/panel/edit_user?id={{ data['user']['user_id'] }}&subpage=config"
-                               role="tab"
-                               aria-selected="false">
+                                role="tab" aria-selected="false">
                                 <i class="fas fa-cogs"></i>{{ translate('apiKeys', 'config', data['lang']) }}</a>
                         </li>
                         <li class="nav-item">
                             <a class="nav-link active" href="/panel/edit_user_apikeys?id={{ data['user']['user_id'] }}"
-                               role="tab"
-                               aria-selected="true">
+                                role="tab" aria-selected="true">
                                 <i class="fas fa-key"></i>{{ translate('apiKeys', 'apiKeys', data['lang']) }}</a>
                         </li>
                     </ul>
@@ -48,56 +46,60 @@
                         <div class="col-md-7 col-sm-12">
                             <div class="card">
                                 <div class="card-header header-sm d-flex justify-content-between align-items-center">
-                                    <h4 class="card-title"><i class="fas fa-key"></i>{{ translate('apiKeys', 'apiKeys', data['lang']) }}</h4>
+                                    <h4 class="card-title"><i class="fas fa-key"></i>{{ translate('apiKeys', 'apiKeys',
+                                        data['lang']) }}</h4>
                                 </div>
                                 <div class="card-body">
                                     <div class="form-group">
                                         <div class="table-responsive">
                                             <table class="table table-hover">
                                                 <thead>
-                                                <tr class="rounded">
-                                                    <!--<th>ID</th>-->
-                                                    <th>{{ translate('apiKeys', 'name', data['lang']) }}</th>
-                                                    <th>{{ translate('apiKeys', 'created', data['lang']) }}</th>
-                                                    <th>{{ translate('apiKeys', 'superUser', data['lang']) }}</th>
-                                                    <th>{{ translate('apiKeys', 'perms', data['lang']) }}</th>
-                                                    <th>{{ translate('apiKeys', 'buttons', data['lang']) }}</th>
-                                                </tr>
+                                                    <tr class="rounded">
+                                                        <!--<th>ID</th>-->
+                                                        <th>{{ translate('apiKeys', 'name', data['lang']) }}</th>
+                                                        <th>{{ translate('apiKeys', 'created', data['lang']) }}</th>
+                                                        <th>{{ translate('apiKeys', 'superUser', data['lang']) }}</th>
+                                                        <th>{{ translate('apiKeys', 'perms', data['lang']) }}</th>
+                                                        <th>{{ translate('apiKeys', 'buttons', data['lang']) }}</th>
+                                                    </tr>
                                                 </thead>
                                                 <tbody>
-                                                {% for apikey in data['api_keys'] %}
-                                                <tr>
-                                                    <!--<td>{-{ apikey.token_id }-}</td>-->
-                                                    <td>{{ apikey.name }}</td>
-                                                    <td>{{ apikey.created.strftime('%d/%m/%Y %H:%M:%S') }}</td>
-                                                    <td>
-                                                        {% if apikey.superuser %}
-                                                        <span class="text-success">
-                                <i class="fas fa-check-square"></i> {{ translate('apiKeys', 'yes', data['lang']) }}
-                              </span>
-                                                        {% else %}
-                                                        <span class="text-danger">
-                                <i class="far fa-times-square"></i> {{ translate('apiKeys', 'no', data['lang']) }}
-                              </span>
-                                                        {% end %}
-                                                    </td>
-                                                    <td>{{ translate('apiKeys', 'server', data['lang']) }} {{ apikey.server_permissions }}
-                                                        {{ translate('apiKeys', 'crafty', data['lang']) }} {{ apikey.crafty_permissions }}</td>
-                                                    <td>
-                                                        <button
-                                                                class="btn btn-danger delete-api-key"
+                                                    {% for apikey in data['api_keys'] %}
+                                                    <tr>
+                                                        <!--<td>{-{ apikey.token_id }-}</td>-->
+                                                        <td>{{ apikey.name }}</td>
+                                                        <td>{{ apikey.created.strftime('%d/%m/%Y %H:%M:%S') }}</td>
+                                                        <td>
+                                                            {% if apikey.superuser %}
+                                                            <span class="text-success">
+                                                                <i class="fas fa-check-square"></i> {{
+                                                                translate('apiKeys', 'yes', data['lang']) }}
+                                                            </span>
+                                                            {% else %}
+                                                            <span class="text-danger">
+                                                                <i class="far fa-times-square"></i> {{
+                                                                translate('apiKeys', 'no', data['lang']) }}
+                                                            </span>
+                                                            {% end %}
+                                                        </td>
+                                                        <td>{{ translate('apiKeys', 'server', data['lang']) }} {{
+                                                            apikey.server_permissions }}
+                                                            {{ translate('apiKeys', 'crafty', data['lang']) }} {{
+                                                            apikey.crafty_permissions }}</td>
+                                                        <td>
+                                                            <button class="btn btn-danger delete-api-key"
                                                                 data-key-id="{{ apikey.token_id }}"
-                                                                data-key-name="{{ apikey.name }}"
-                                                        >{{ translate('panelConfig', 'delete', data['lang']) }}</button>
-                                                        <button
-                                                                class="btn btn-outline-primary get-a-token"
+                                                                data-key-name="{{ apikey.name }}">{{
+                                                                translate('panelConfig', 'delete', data['lang'])
+                                                                }}</button>
+                                                            <button class="btn btn-outline-primary get-a-token"
                                                                 data-key-id="{{ apikey.token_id }}"
-                                                                data-key-name="{{ apikey.name }}"
-                                                        >{{ translate('apiKeys', 'getToken', data['lang']) }}
-                                                        </button>
-                                                    </td>
-                                                </tr>
-                                                {% end %}
+                                                                data-key-name="{{ apikey.name }}">{{
+                                                                translate('apiKeys', 'getToken', data['lang']) }}
+                                                            </button>
+                                                        </td>
+                                                    </tr>
+                                                    {% end %}
                                                 </tbody>
                                             </table>
                                         </div>
@@ -109,68 +111,69 @@
                         <div class="col-md-5 col-sm-12">
                             <div class="card">
                                 <div class="card-header header-sm d-flex justify-content-between align-items-center">
-                                    <h4 class="card-title"><i class="fas fa-plus"></i> {{ translate('apiKeys', 'createNew', data['lang']) }}</h4>
+                                    <h4 class="card-title"><i class="fas fa-plus"></i> {{ translate('apiKeys',
+                                        'createNew', data['lang']) }}</h4>
                                 </div>
                                 <div class="card-body">
                                     <form id="user_form" class="forms-sample" method="post"
-                                          action="/panel/edit_user_apikeys">
+                                        action="/panel/edit_user_apikeys">
                                         {% raw xsrf_form_html() %}
                                         <input type="hidden" name="id" value="{{ data['user']['user_id'] }}">
 
                                         <div class="form-group">
-                                            <label class="form-label" for="username">{{ translate('apiKeys', 'name', data['lang']) }}<small
-                                                    class="text-muted ml-1"> - {{ translate('apiKeys', 'nameDesc', data['lang']) }}</small> </label>
+                                            <label class="form-label" for="username">{{ translate('apiKeys', 'name',
+                                                data['lang']) }}<small class="text-muted ml-1"> - {{
+                                                    translate('apiKeys', 'nameDesc', data['lang']) }}</small> </label>
                                             <input type="text" class="form-control" name="name" id="name"
-                                                   placeholder="API Key">
+                                                placeholder="API Key">
                                         </div>
 
                                         <table class="table table-hover mb-3">
                                             <thead>
-                                            <tr class="rounded">
-                                                <th>{{ translate('apiKeys', 'permName', data['lang']) }}</th>
-                                                <th>{{ translate('apiKeys', 'auth', data['lang']) }}</th>
-                                            </tr>
+                                                <tr class="rounded">
+                                                    <th>{{ translate('apiKeys', 'permName', data['lang']) }}</th>
+                                                    <th>{{ translate('apiKeys', 'auth', data['lang']) }}</th>
+                                                </tr>
                                             </thead>
                                             <tbody>
-                                            {% for permission in data['server_permissions_all'] %}
-                                            <tr>
-                                                <td><label
-                                                        for="permission_{{ permission.name }}">{{ permission.name }}</label>
-                                                </td>
-                                                <td>
-                                                    <input type="checkbox" class=""
-                                                           id="permission_{{ permission.name }}"
-                                                           name="permission_{{ permission.name }}" value="1">
-                                                </td>
-                                            </tr>
-                                            {% end %}
-                                            {% for permission in data['crafty_permissions_all'] %}
-                                            <tr>
-                                                <td><label
-                                                        for="permission_{{ permission.name }}">{{ permission.name }}</label>
-                                                </td>
-                                                <td>
-                                                    <input type="checkbox" class=""
-                                                           id="permission_{{ permission.name }}"
-                                                           name="permission_{{ permission.name }}" value="1">
-                                                </td>
-                                            </tr>
-                                            {% end %}
+                                                {% for permission in data['server_permissions_all'] %}
+                                                <tr>
+                                                    <td><label for="permission_{{ permission.name }}">{{ permission.name
+                                                            }}</label>
+                                                    </td>
+                                                    <td>
+                                                        <input type="checkbox" class=""
+                                                            id="permission_{{ permission.name }}"
+                                                            name="permission_{{ permission.name }}" value="1">
+                                                    </td>
+                                                </tr>
+                                                {% end %}
+                                                {% for permission in data['crafty_permissions_all'] %}
+                                                <tr>
+                                                    <td><label for="permission_{{ permission.name }}">{{ permission.name
+                                                            }}</label>
+                                                    </td>
+                                                    <td>
+                                                        <input type="checkbox" class=""
+                                                            id="permission_{{ permission.name }}"
+                                                            name="permission_{{ permission.name }}" value="1">
+                                                    </td>
+                                                </tr>
+                                                {% end %}
 
                                             </tbody>
                                         </table>
 
                                         <label for="superuser">Superuser</label>
-                                        <input type="checkbox" class="" id="superuser"
-                                               name="superuser" value="1">
+                                        <input type="checkbox" class="" id="superuser" name="superuser" value="1">
 
-                                        <br/>
+                                        <br />
 
                                         <button type="submit" class="btn btn-success mr-2"><i class="fas fa-plus"></i>
                                             Create
                                         </button>
-                                        <button type="reset" class="btn btn-light"><i
-                                                class="fas fa-undo-alt"></i> {{ translate('panelConfig', 'cancel', data['lang']) }}
+                                        <button type="reset" class="btn btn-light"><i class="fas fa-undo-alt"></i> {{
+                                            translate('panelConfig', 'cancel', data['lang']) }}
                                         </button>
                                     </form>
                                 </div>
@@ -216,15 +219,17 @@
                     }
                 },
                 callback: function (result) {
-                    var token = getCookie("_xsrf")
-                    $.ajax({
-                        type: "DELETE",
-                        headers: {'X-XSRFToken': token},
-                        url: '/panel/remove_apikey?id=' + keyId,
-                        success: function (data) {
-                            location.reload();
-                        },
-                    });
+                    if (result) {
+                        var token = getCookie("_xsrf")
+                        $.ajax({
+                            type: "DELETE",
+                            headers: { 'X-XSRFToken': token },
+                            url: '/panel/remove_apikey?id=' + keyId,
+                            success: function (data) {
+                                location.reload();
+                            },
+                        });
+                    }
                 }
             });
         })
@@ -234,7 +239,7 @@
             var token = getCookie("_xsrf")
             $.ajax({
                 type: "POST",
-                headers: {'X-XSRFToken': token},
+                headers: { 'X-XSRFToken': token },
                 url: '/panel/get_token?id=' + keyId,
                 success: function (data) {
                     bootbox.alert({
@@ -249,4 +254,4 @@
 
 </script>
 
-{% end %}
+{% end %}
\ No newline at end of file
diff --git a/app/frontend/templates/panel/server_schedules.html b/app/frontend/templates/panel/server_schedules.html
index 2d965ad7..0898d881 100644
--- a/app/frontend/templates/panel/server_schedules.html
+++ b/app/frontend/templates/panel/server_schedules.html
@@ -14,7 +14,8 @@
     <div class="col-12">
       <div class="page-header">
         <h4 class="page-title">
-          {{ translate('serverDetails', 'serverDetails', data['lang']) }} - {{ data['server_stats']['server_id']['server_name'] }}
+          {{ translate('serverDetails', 'serverDetails', data['lang']) }} - {{
+          data['server_stats']['server_id']['server_name'] }}
           <br />
           <small>UUID: {{ data['server_stats']['server_id']['server_uuid'] }}</small>
         </h4>
@@ -46,23 +47,23 @@
                   <h4 class="card-title"><i class="fas fa-calendar"></i> Scheduled Tasks</h4>
                   {% if data['user_data']['hints'] %}
                   <span class="too_small" title="{{ translate('serverSchedules', 'cannotSee', data['lang']) }}" ,
-                        data-content="{{ translate('serverSchedules', 'cannotSeeOnMobile', data['lang']) }}" ,
-                        data-placement="bottom"></span>
+                    data-content="{{ translate('serverSchedules', 'cannotSeeOnMobile', data['lang']) }}" ,
+                    data-placement="bottom"></span>
                   {% end %}
                   <div><button
-                            onclick="location.href=`/panel/add_schedule?id={{ data['server_stats']['server_id']['server_id'] }}`"
-                            class="btn btn-info">Create New Schedule <i class="fas fa-pencil-alt"></i></button></div>
+                      onclick="location.href=`/panel/add_schedule?id={{ data['server_stats']['server_id']['server_id'] }}`"
+                      class="btn btn-info">Create New Schedule <i class="fas fa-pencil-alt"></i></button></div>
                 </div>
                 <div class="card-body">
                   <table class="table table-hover d-none d-lg-block responsive-table" id="schedule_table" width="100%"
-                         style="table-layout:fixed;">
+                    style="table-layout:fixed;">
                     <thead>
                       <tr class="rounded">
                         <th style="width: 2%; min-width: 10px;">ID</th>
                         <th style="width: 23%; min-width: 50px;">Action</th>
                         <th style="width: 40%; min-width: 50px;">Command</th>
                         <th style="width: 10%; min-width: 50px;">Interval</th>
-                        <th style="width: 10%; min-width: 50px;">Start Time</th>
+                        <th style="width: 10%; min-width: 50px;">Next Run</th>
                         <th style="width: 10%; min-width: 50px;">Enabled</th>
                         <th style="width: 10%; min-width: 50px;">Edit</th>
                       </tr>
@@ -91,13 +92,17 @@
                           {% end %}
                         </td>
                         <td id="{{schedule.start_time}}" class="action">
-                          <p>{{schedule.start_time}}</p>
+                          <p>{{schedule.next_run}}</p>
                         </td>
                         <td id="{{schedule.enabled}}" class="action">
-                            <input style="width: 10px !important;" type="checkbox" class="schedule-enabled-toggle" data-schedule-id="{{schedule.schedule_id}}" data-schedule-enabled="{{ 'true' if schedule.enabled else 'false' }}">
+                          <input style="width: 10px !important;" type="checkbox" class="schedule-enabled-toggle"
+                            data-schedule-id="{{schedule.schedule_id}}"
+                            data-schedule-enabled="{{ 'true' if schedule.enabled else 'false' }}">
                         </td>
                         <td id="{{schedule.action}}" class="action">
-                          <button onclick="window.location.href='/panel/edit_schedule?id={{ data['server_stats']['server_id']['server_id'] }}&sch_id={{schedule.schedule_id}}'" class="btn btn-info">
+                          <button
+                            onclick="window.location.href='/panel/edit_schedule?id={{ data['server_stats']['server_id']['server_id'] }}&sch_id={{schedule.schedule_id}}'"
+                            class="btn btn-info">
                             <i class="fas fa-pencil-alt"></i>
                           </button>
                           <br>
@@ -111,7 +116,8 @@
                     </tbody>
                   </table>
                   <hr />
-                  <table class="table table-hover d-block d-lg-none" id="mini_schedule_table" width="100%" style="table-layout:fixed;">
+                  <table class="table table-hover d-block d-lg-none" id="mini_schedule_table" width="100%"
+                    style="table-layout:fixed;">
                     <thead>
                       <tr class="rounded">
                         <th style="width: 25%; min-width: 50px;">Action</th>
@@ -141,7 +147,8 @@
                         </td>
                       </tr>
                       <!-- Modal -->
-                      <div class="modal fade" id="task_details_{{schedule.schedule_id}}" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
+                      <div class="modal fade" id="task_details_{{schedule.schedule_id}}" tabindex="-1" role="dialog"
+                        aria-labelledby="exampleModalLabel" aria-hidden="true">
                         <div class="modal-dialog" role="document">
                           <div class="modal-content">
                             <div class="modal-header">
@@ -177,17 +184,22 @@
                                   {% end %}
                                 </li>
                                 <li id="{{schedule.start_time}}" class="action" style="border-top: .1em solid gray;">
-                                  <h4>Start Time</h4>
-                                  <p>{{schedule.start_time}}</p>
+                                  <h4>Next Run</h4>
+                                  <p>{{schedule.next_run}}</p>
                                 </li>
-                                <li id="{{schedule.enabled}}" class="action" style="border-top: .1em solid gray; border-bottom: .1em solid gray">
+                                <li id="{{schedule.enabled}}" class="action"
+                                  style="border-top: .1em solid gray; border-bottom: .1em solid gray">
                                   <h4>Enabled</h4>
-                                  <input type="checkbox" class="schedule-enabled-toggle" data-schedule-id="{{schedule.schedule_id}}" data-schedule-enabled="{{ 'true' if schedule.enabled else 'false' }}">
+                                  <input type="checkbox" class="schedule-enabled-toggle"
+                                    data-schedule-id="{{schedule.schedule_id}}"
+                                    data-schedule-enabled="{{ 'true' if schedule.enabled else 'false' }}">
                                 </li>
                               </ul>
                             </div>
                             <div class="modal-footer">
-                              <button onclick="window.location.href='/panel/edit_schedule?id={{ data['server_stats']['server_id']['server_id'] }}&sch_id={{schedule.schedule_id}}'" class="btn btn-info">
+                              <button
+                                onclick="window.location.href='/panel/edit_schedule?id={{ data['server_stats']['server_id']['server_id'] }}&sch_id={{schedule.schedule_id}}'"
+                                class="btn btn-info">
                                 <i class="fas fa-pencil-alt"></i> Edit
                               </button>
                               <button data-sch={{ schedule.schedule_id }} class="btn btn-danger del_button">
@@ -215,12 +227,15 @@
       color: white !important;
       ;
     }
+
     .toggle-handle {
       background-color: white !important;
     }
+
     .toggle-on {
       color: black !important;
     }
+
     .toggle {
       height: 0px !important;
     }
@@ -250,7 +265,7 @@
 {% block js %}
 <script>
 
-  function debounce(func, timeout = 300){
+  function debounce(func, timeout = 300) {
     let timer;
     return (...args) => {
       clearTimeout(timer);
@@ -265,17 +280,17 @@
       onstyle: 'success',
       offstyle: 'danger',
     })
-    $('.schedule-enabled-toggle').each(function() {
+    $('.schedule-enabled-toggle').each(function () {
       const enabled = JSON.parse(this.getAttribute('data-schedule-enabled'));
       $(this).bootstrapToggle(enabled ? 'on' : 'off')
     })
-    $('.schedule-enabled-toggle').change(function() {
+    $('.schedule-enabled-toggle').change(function () {
       const id = this.getAttribute('data-schedule-id');
       const enabled = this.checked;
 
       fetch(`/api/v2/servers/{{data['server_id']}}/tasks/${id}`, {
         method: 'PATCH',
-        body: JSON.stringify({enabled}),
+        body: JSON.stringify({ enabled }),
         headers: {
           'Content-Type': 'application/json',
         },
@@ -420,4 +435,4 @@
 
 </script>
 
-{% end %}
+{% end %}
\ No newline at end of file
diff --git a/app/frontend/templates/server/wizard.html b/app/frontend/templates/server/wizard.html
index 293eff32..53b045bf 100644
--- a/app/frontend/templates/server/wizard.html
+++ b/app/frontend/templates/server/wizard.html
@@ -32,13 +32,32 @@
               <div class="row">
                 <div class="col-sm-12">
                   <div class="form-group">
-                    <label for="server_type">{{ translate('serverWizard', 'serverType', data['lang']) }}</label>
-                    <select required class="form-control form-control-lg select-css" id="server_type" name="server_type"
-                            onchange="serverTypeChange(this)">
-                      <option value="">{{ translate('serverWizard', 'selectType', data['lang']) }}</option>
-                      {% for s in data['server_types'] %}
-                      <option value="{{ s }}">{{ s.capitalize() }}</option>
+                    <label for="server_jar">{{ translate('serverWizard', 'serverType', data['lang'])
+                      }}</label>
+                    {% if data['super_user'] %}
+                    <select style="width: 90%;" required class="form-control form-control-lg select-css" id="server_jar"
+                      name="server_jar" onchange="serverJarChange(this)">
+                      {% else %}
+                      <select required class="form-control form-control-lg select-css" id="server_jar" name="server_jar"
+                        onchange="serverJarChange(this)">
+                        {% end %}
+                        <option value="None">{{ translate('serverWizard', 'selectType', data['lang']) }}</option>
+                        {% for s in data['server_types'] %}
+                        <option value="{{ s }}">{{ s.capitalize() }}</option>
+                        {% end %}
+                      </select>
+                      {% if data['super_user'] %}
+                      &nbsp;&nbsp;<i onclick="refreshCache()" id="refresh-cache" class="refresh-class fas fa-sync"></i>
                       {% end %}
+                  </div>
+                </div>
+
+                <div class="col-sm-12">
+                  <div class="form-group">
+                    <label for="server_type">{{ translate('serverWizard', 'serverSelect', data['lang']) }}</label>
+                    <select required class="form-control form-control-lg select-css" id="server_type" name="server_type"
+                      onchange="serverTypeChange(this)">
+                      <option value="">{{ translate('serverWizard', 'selectServer', data['lang']) }}</option>
                     </select>
                   </div>
                 </div>
@@ -56,14 +75,14 @@
                   <div class="form-group">
                     <label for="server_name">{{ translate('serverWizard', 'serverName', data['lang']) }}</label>
                     <input type="text" class="form-control" id="server_name" name="server_name"
-                           placeholder="{{ translate('serverWizard', 'myNewServer', data['lang']) }}" required>
+                      placeholder="{{ translate('serverWizard', 'myNewServer', data['lang']) }}" required>
                   </div>
                 </div>
 
               </div>
               <br />
               <h4 class="card-title">{{ translate('serverWizard', 'quickSettings', data['lang']) }} <small
-                       style="text-transform: none;"> - {{ translate('serverWizard', 'quickSettingsDescription',
+                  style="text-transform: none;"> - {{ translate('serverWizard', 'quickSettingsDescription',
                   data['lang']) }}</small></h4>
               <hr>
               <div class="row">
@@ -73,7 +92,7 @@
                     <label for="min_memory1">{{ translate('serverWizard', 'minMem', data['lang']) }} <small> - {{
                         translate('serverWizard', 'sizeInGB', data['lang']) }}</small></label>
                     <input type="number" class="form-control" id="min_memory1" name="min_memory" value="1" step="0.5"
-                           min="0.5" required>
+                      min="0.5" required>
                   </div>
                 </div>
 
@@ -82,7 +101,7 @@
                     <label for="max_memory1">{{ translate('serverWizard', 'maxMem', data['lang']) }} <small> - {{
                         translate('serverWizard', 'sizeInGB', data['lang']) }}</small></label>
                     <input type="number" class="form-control" id="max_memory1" name="max_memory" value="2" step="0.5"
-                           min="0.5" required>
+                      min="0.5" required>
                   </div>
                 </div>
 
@@ -91,7 +110,7 @@
                     <label for="port1">{{ translate('serverWizard', 'serverPort', data['lang']) }} <small> - {{
                         translate('serverWizard', 'defaultPort', data['lang']) }}</small></label>
                     <input type="number" class="form-control" id="port1" name="port" value="25565" step="1" min="1"
-                           required>
+                      required>
                   </div>
                 </div>
                 <div class="col-sm-12">
@@ -100,7 +119,7 @@
                       <div class="card">
                         <div class="card-header p-2" id="Role-1">
                           <p class="mb-0 p-0" data-toggle="collapse" data-target="#collapseRole-1" aria-expanded="true"
-                             aria-controls="collapseRole-1">
+                            aria-controls="collapseRole-1">
                             <i class="fas fa-chevron-down"></i> {{ translate('serverWizard', 'addRole', data['lang']) }}
                             <small style="text-transform: none;"> - {{ translate('serverWizard', 'autoCreate',
                               data['lang']) }}</small>
@@ -111,7 +130,7 @@
                             <div class="form-group">
                               {% for r in data['roles'] %}
                               <span class="d-block menu-option"><label><input name="{{ r['role_id'] }}"
-                                         type="checkbox">&nbsp;
+                                    type="checkbox">&nbsp;
                                   {{ r['role_name'].capitalize() }}</label></span>
                               {% end %}
                             </div>
@@ -152,7 +171,7 @@
                   <div class="form-group">
                     <label for="server_name">{{ translate('serverWizard', 'serverName', data['lang']) }}</label>
                     <input type="text" class="form-control" id="server_name" name="server_name" value=""
-                           placeholder="{{ translate('serverWizard', 'myNewServer', data['lang']) }}" required>
+                      placeholder="{{ translate('serverWizard', 'myNewServer', data['lang']) }}" required>
                   </div>
                 </div>
 
@@ -161,7 +180,7 @@
                     <label for="server">{{ translate('serverWizard', 'serverPath', data['lang']) }} <small>{{
                         translate('serverWizard', 'absoluteServerPath', data['lang']) }}</small></label>
                     <input type="text" class="form-control" id="server_path" name="server_path"
-                           placeholder="/var/opt/server" required>
+                      placeholder="/var/opt/server" required>
                   </div>
                 </div>
 
@@ -169,7 +188,7 @@
                   <div class="form-group">
                     <label for="server_jar">{{ translate('serverWizard', 'serverJar', data['lang']) }}</label>
                     <input type="text" class="form-control" id="server_jar" name="server_jar" value=""
-                           placeholder="paper.jar" required>
+                      placeholder="paper.jar" required>
                   </div>
                 </div>
 
@@ -178,7 +197,7 @@
               </div>
               <br />
               <h4 class="card-title">{{ translate('serverWizard', 'quickSettings', data['lang']) }} <small
-                       style="text-transform: none;"> - {{ translate('serverWizard', 'quickSettingsDescription',
+                  style="text-transform: none;"> - {{ translate('serverWizard', 'quickSettingsDescription',
                   data['lang']) }}</small></h4>
               <hr>
               <div class="row">
@@ -188,7 +207,7 @@
                     <label for="min_memory2">{{ translate('serverWizard', 'minMem', data['lang']) }} <small> - {{
                         translate('serverWizard', 'sizeInGB', data['lang']) }}</small></label>
                     <input type="number" class="form-control" id="min_memory2" name="min_memory" value="1" step="0.5"
-                           min="0.5" required>
+                      min="0.5" required>
                   </div>
                 </div>
 
@@ -197,7 +216,7 @@
                     <label for="max_memory2">{{ translate('serverWizard', 'maxMem', data['lang']) }} <small> - {{
                         translate('serverWizard', 'sizeInGB', data['lang']) }}</small></label>
                     <input type="number" class="form-control" id="max_memory2" name="max_memory" value="2" step="0.5"
-                           min="0.5" required>
+                      min="0.5" required>
                   </div>
                 </div>
 
@@ -206,7 +225,7 @@
                     <label for="port2">{{ translate('serverWizard', 'serverPort', data['lang']) }} <small> - {{
                         translate('serverWizard', 'defaultPort', data['lang']) }}</small></label>
                     <input type="number" class="form-control" id="port2" name="port" value="25565" step="1" min="1"
-                           required>
+                      required>
                   </div>
                 </div>
                 <div class="col-sm-12">
@@ -215,7 +234,7 @@
                       <div class="card">
                         <div class="card-header p-2" id="Role-2">
                           <p class="mb-0 p-0" data-toggle="collapse" data-target="#collapseRole-2" aria-expanded="true"
-                             aria-controls="collapseRole-2">
+                            aria-controls="collapseRole-2">
                             <i class="fas fa-chevron-down"></i> {{ translate('serverWizard', 'addRole', data['lang']) }}
                             <small style="text-transform: none;"> - {{ translate('serverWizard', 'autoCreate',
                               data['lang']) }}</small>
@@ -226,7 +245,7 @@
                             <div class="form-group">
                               {% for r in data['roles'] %}
                               <span class="d-block menu-option"><label><input name="{{ r['role_id'] }}"
-                                         type="checkbox">&nbsp;
+                                    type="checkbox">&nbsp;
                                   {{ r['role_name'].capitalize() }}</label></span>
                               {% end %}
                             </div>
@@ -266,7 +285,7 @@
                   <div class="form-group">
                     <label for="server_name">{{ translate('serverWizard', 'serverName', data['lang']) }}</label>
                     <input type="text" class="form-control" id="server_name" name="server_name" value=""
-                           placeholder="{{ translate('serverWizard', 'myNewServer', data['lang']) }}" required>
+                      placeholder="{{ translate('serverWizard', 'myNewServer', data['lang']) }}" required>
                   </div>
                 </div>
 
@@ -275,7 +294,7 @@
                     <label for="server">{{ translate('serverWizard', 'zipPath', data['lang']) }} <small>{{
                         translate('serverWizard', 'absoluteZipPath', data['lang']) }}</small></label>
                     <input type="text" class="form-control" id="server_path" name="server_path"
-                           placeholder="/var/opt/server.zip" required>
+                      placeholder="/var/opt/server.zip" required>
                   </div>
                 </div>
 
@@ -294,7 +313,7 @@
                   <div class="form-group">
                     <label for="server_jar">{{ translate('serverWizard', 'serverJar', data['lang']) }}</label>
                     <input type="text" class="form-control" id="server_jar" name="server_jar" value=""
-                           placeholder="paper.jar" required>
+                      placeholder="paper.jar" required>
                   </div>
                 </div>
               </div>
@@ -303,7 +322,7 @@
 
               <div class="col-sm-3">
                 <h4 class="card-title">{{ translate('serverWizard', 'quickSettings', data['lang']) }} <small
-                         style="text-transform: none;"> - {{ translate('serverWizard', 'quickSettingsDescription',
+                    style="text-transform: none;"> - {{ translate('serverWizard', 'quickSettingsDescription',
                     data['lang']) }}</small></h4>
                 <hr>
                 <div class="row">
@@ -313,7 +332,7 @@
                       <label for="min_memory3">{{ translate('serverWizard', 'minMem', data['lang']) }} <small> - {{
                           translate('serverWizard', 'sizeInGB', data['lang']) }}</small></label>
                       <input type="number" class="form-control" id="min_memory3" name="min_memory" value="1" step="0.5"
-                             min="0.5" required>
+                        min="0.5" required>
                     </div>
                   </div>
 
@@ -322,7 +341,7 @@
                       <label for="max_memory3">{{ translate('serverWizard', 'maxMem', data['lang']) }} <small> - {{
                           translate('serverWizard', 'sizeInGB', data['lang']) }}</small></label>
                       <input type="number" class="form-control" id="max_memory3" name="max_memory" value="2" step="0.5"
-                             min="0.5" required>
+                        min="0.5" required>
                     </div>
                   </div>
 
@@ -331,7 +350,7 @@
                       <label for="port3">{{ translate('serverWizard', 'serverPort', data['lang']) }} <small> - {{
                           translate('serverWizard', 'defaultPort', data['lang']) }}</small></label>
                       <input type="number" class="form-control" id="port3" name="port" value="25565" step="1" min="1"
-                             required>
+                        required>
                     </div>
                   </div>
 
@@ -341,7 +360,7 @@
                         <div class="card">
                           <div class="card-header p-2" id="Role-3">
                             <p class="mb-0 p-0" data-toggle="collapse" data-target="#collapseRole-3"
-                               aria-expanded="true" aria-controls="collapseRole-3">
+                              aria-expanded="true" aria-controls="collapseRole-3">
                               <i class="fas fa-chevron-down"></i> {{ translate('serverWizard', 'addRole', data['lang'])
                               }} <small style="text-transform: none;"> - {{ translate('serverWizard', 'autoCreate',
                                 data['lang']) }}</small>
@@ -352,7 +371,7 @@
                               <div class="form-group">
                                 {% for r in data['roles'] %}
                                 <span class="d-block menu-option"><label><input name="{{ r['role_id'] }}"
-                                           type="checkbox">&nbsp;
+                                      type="checkbox">&nbsp;
                                     {{ r['role_name'].capitalize() }}</label></span>
                                 {% end %}
                               </div>
@@ -368,7 +387,7 @@
                     </div>
                   </div>
                   <div class="modal fade" id="dir_select" tabindex="-1" role="dialog" aria-labelledby="dir_select"
-                       aria-hidden="true">
+                    aria-hidden="true">
                     <div class="modal-dialog" role="document">
                       <div class="modal-content">
                         <div class="modal-header">
@@ -380,7 +399,7 @@
                         </div>
                         <div class="modal-body">
                           <div class="tree-ctx-item" id="main-tree-div" data-path=""
-                               style="overflow: scroll; max-height:75%;">
+                            style="overflow: scroll; max-height:75%;">
                             <input type="radio" id="main-tree-input" name="root_path" value="" checked>
                             <span id="main-tree" class="files-tree-title tree-caret-down root-dir" data-path="">
                               <i class="far fa-folder"></i>
@@ -401,7 +420,7 @@
                   </div>
                 </div>
                 <button id="zip_submit" type="submit" title="You must select server root dir first" disabled
-                        class="btn btn-primary mr-2">{{ translate('serverWizard', 'importServerButton', data['lang'])
+                  class="btn btn-primary mr-2">{{ translate('serverWizard', 'importServerButton', data['lang'])
                   }}</button>
                 <button type="reset" class="btn btn-danger mr-2">{{ translate('serverWizard', 'resetForm', data['lang'])
                   }}</button>
@@ -414,6 +433,10 @@
     </div>
   </div>
   <style>
+    .refresh-class:hover {
+      cursor: grab;
+    }
+
     .scroll {
       max-height: 12em;
       overflow-y: auto;
@@ -673,6 +696,25 @@
       });
     }
 
+    function refreshCache() {
+      var token = getCookie("_xsrf")
+      document.getElementById("refresh-cache").classList.add("fa-spin")
+      $.ajax({
+        type: "POST",
+        headers: { 'X-XSRFToken': token },
+        url: '/ajax/jar_cache',
+        success: function () {
+          document.getElementById("refresh-cache").classList.remove("fa-sync");
+          document.getElementById("refresh-cache").classList.remove("fa-spin");
+          document.getElementById("refresh-cache").classList.add("fa-check");
+
+          setTimeout(function () {
+            location.reload();
+          }, 2000);
+        },
+      });
+    }
+
   </script>
   <script type="text/javascript">
     var text = '{% raw data["js_server_types"] %}';
@@ -682,11 +724,21 @@
     */
     function serverTypeChange(selectObj) {
       // get the index of the selected option
-      var idx = selectObj.selectedIndex;
+      var idx = document.getElementById('server_type').selectedIndex;
       // get the value of the selected option
-      var which = selectObj.options[idx].value;
+      var cSelect = document.getElementById("server");
+      try {
+        var which = document.getElementById('server_type').options[idx].value;
+      } catch {
+        while (cSelect.options.length > 0) {
+          cSelect.remove(0);
+        }
+        return;
+      }
+      let server_type = which.split('|')[0];
+      let server = which.split('|')[1];
       // use the selected option value to retrieve the list of items from the serverTypesLists array
-      cList = serverTypesLists[which];
+      let cList = serverTypesLists[server_type];
       // get the country select element via its known id
       var cSelect = document.getElementById("server");
       // remove the current options from the country select
@@ -696,7 +748,7 @@
       }
       var newOption;
       // create new options ordered by ascending
-      cList.forEach(type => {
+      cList[server].forEach(type => {
         newOption = document.createElement("option");
         newOption.value = which + "|" + type;  // assumes option string and value are the same
         newOption.text = type;
@@ -709,5 +761,47 @@
         }
       })
     }
+
+    function serverJarChange(selectObj) {
+      let type_select = document.getElementById('server_jar')
+      let tidx = type_select.selectedIndex;
+      let val = type_select.options[tidx].value;
+      if (val == 'None') {
+        var jcSelect = document.getElementById("server_type");
+        while (jcSelect.options.length > 0) {
+          jcSelect.remove(0);
+        }
+        serverTypeChange(selectObj);
+        return;
+      }
+      // get the index of the selected option
+      var jidx = selectObj.selectedIndex;
+      // get the value of the selected option
+      var jwhich = selectObj.options[jidx].value;
+      // use the selected option value to retrieve the list of items from the serverTypesLists array
+      jcList = Object.keys(serverTypesLists[jwhich]);
+      // get the country select element via its known id
+      var jcSelect = document.getElementById("server_type");
+      // remove the current options from the country select
+      var jlen = jcSelect.options.length;
+      while (jcSelect.options.length > 0) {
+        jcSelect.remove(0);
+      }
+      var jnewOption;
+      // create new options ordered by ascending
+      jcList.forEach(type => {
+        jnewOption = document.createElement("option");
+        jnewOption.value = jwhich + "|" + type;  // assumes option string and value are the same
+        jnewOption.text = type;
+        // add the new option
+        try {
+          jcSelect.add(jnewOption);  // this will fail in DOM browsers but is needed for IE
+        }
+        catch (e) {
+          jcSelect.appendChild(jnewOption);
+        }
+      })
+      serverTypeChange(selectObj);
+    }
   </script>
   {% end %}
\ No newline at end of file
diff --git a/app/migrations/20220804_schedule_next_run.py b/app/migrations/20220804_schedule_next_run.py
new file mode 100644
index 00000000..4fa423c7
--- /dev/null
+++ b/app/migrations/20220804_schedule_next_run.py
@@ -0,0 +1,16 @@
+# Generated by database migrator
+import peewee
+
+
+def migrate(migrator, database, **kwargs):
+    migrator.add_columns("schedules", next_run=peewee.CharField(default=""))
+    """
+    Write your migrations here.
+    """
+
+
+def rollback(migrator, database, **kwargs):
+    migrator.drop_columns("schedules", ["next_run"])
+    """
+    Write your rollback migrations here.
+    """
diff --git a/app/translations/en_EN.json b/app/translations/en_EN.json
index a930bfd0..041e4615 100644
--- a/app/translations/en_EN.json
+++ b/app/translations/en_EN.json
@@ -480,7 +480,8 @@
         "save": "Save",
         "selectRole": "Select Role(s)",
         "selectRoot": "Select Archive Root Dir",
-        "selectType": "Select a Type",
+        "selectType": "Server Type (Vanilla, Servers, Modded, etc.)",
+        "selectServer": "Select a Server",
         "selectVersion": "Select a Version",
         "selectZipDir": "Select the directory in the archive you want us to unzip files from",
         "serverJar": "Server Executable File",
@@ -488,6 +489,7 @@
         "serverPath": "Server Path",
         "serverPort": "Server Port",
         "serverType": "Server Type",
+        "serverSelect": "Server Select",
         "serverVersion": "Server Version",
         "sizeInGB": "Size in GB",
         "zipPath": "Server Path"
@@ -538,4 +540,4 @@
         "userSettings": "User Settings",
         "uses": "Number of uses allowed (-1==No Limit)"
     }
-}
+}
\ No newline at end of file
diff --git a/app/translations/es_ES_incomplete.json b/app/translations/es_ES.json
similarity index 64%
rename from app/translations/es_ES_incomplete.json
rename to app/translations/es_ES.json
index 182b2c07..28f8d6e1 100644
--- a/app/translations/es_ES_incomplete.json
+++ b/app/translations/es_ES.json
@@ -11,12 +11,48 @@
         "noAccess": "No tienes acceso a este recurso"
     },
     "apiKeys": {
+        "apiKeys": "Claves API",
+        "auth": "Autorizado? ",
+        "buttons": "Botones",
+        "config": "Configuración",
+        "crafty": "Crafty: ",
+        "created": "Creado",
+        "createNew": "Crear un nuevo API Token",
         "deleteKeyConfirmation": "¿Quieres eliminar esta clave de API? Esto no se puede deshacer.",
-        "deleteKeyConfirmationTitle": "¿Eliminar la clave API ${keyId}?"
+        "deleteKeyConfirmationTitle": "¿Eliminar la clave API ${keyId}?",
+        "getToken": "Conseguir un Token",
+        "name": "Nombre",
+        "nameDesc": "Como te gustaria llamar a este API token? ",
+        "no": "No",
+        "pageTitle": "Editar las Claves API",
+        "permName": "Nombre del Permiso",
+        "perms": "Permisos",
+        "server": "Servidor: ",
+        "superUser": "Super User",
+        "yes": "Si"
     },
     "base": {
         "doesNotWorkWithoutJavascript": "<strong>Aviso: </strong>¡Crafty no funciona correctamente cuando JavaScript no está habilitado!"
     },
+    "credits": {
+        "developmentTeam": "Equipo de desarrollo",
+        "hugeDesc": "Un enorme",
+        "pageDescription": "Sin esta gente, Crafty no existiría",
+        "pageTitle": "Créditos",
+        "patreonDesc": "Patreon / Ko-fi supporters!",
+        "patreonOther": "Otro",
+        "patreonSupporter": "A nuestros Patreon / Ko-fi Supporters",
+        "patreonUpdate": "Última Actualización:",
+        "retiredStaff": "Staff retirado",
+        "subscriberName": "Nombre",
+        "subscriptionLevel": "Nivel",
+        "supportTeam": "Equipo de soporte y documentación",
+        "thankYou": "GRACIAS",
+        "translationDesc": "a nuestra comunidad, que tradujo!",
+        "translationName": "Nombre",
+        "translationTitle": "Traducciones de Idiomas",
+        "translator": "Traductores"
+    },
     "dashboard": {
         "actions": "Acciones",
         "allServers": "Todos los servidores",
@@ -30,10 +66,12 @@
         "cannotSeeOnMobile": "¿No puedes verlo todo en móvil?",
         "cannotSeeOnMobile2": "Intenta desplazar la tabla desde los lados..",
         "clone": "Clonar",
+        "cloneConfirm": "¿Está seguro de que desea clonar este servidor? Este proceso puede llevar un tiempo",
         "cpuCores": "Nucleos de CPU",
         "cpuCurFreq": "Reloj de CPU Actual",
         "cpuMaxFreq": "Reloj de CPU Maximo",
         "cpuUsage": "Uso de CPU",
+        "crashed": "Crashed",
         "dashboard": "Panel de control",
         "delay-explained": "El agente/servicio ha iniciado recientemente y está retrasando el inicio de la instancia del servidor de Minecraft.",
         "host": "Host",
@@ -53,13 +91,13 @@
         "sendingCommand": "Enviando tu comando",
         "server": "Server",
         "servers": "Servers",
+        "size": "Tamaño del directorio del servidor",
         "start": "Iniciar",
         "starting": "Inicio-retrasado",
         "status": "Estado",
         "stop": "Detener",
         "version": "Versión",
-        "welcome": "Bienvenido a Crafty Controller",
-        "world": "Mundo"
+        "welcome": "Bienvenido a Crafty Controller"
     },
     "datatables": {
         "i18n": {
@@ -133,9 +171,13 @@
         "eulaAgree": "Estás de acuerdo?",
         "eulaMsg": "Debes aceptar el EULA. Una copia del EULA de Mojang esta vinculada debajo de este mensaje.",
         "eulaTitle": "Aceptar EULA",
+        "fileTooLarge": "Subida fallida. Carga de archivo demasiado grande. Póngase en contacto con el administrador del sistema para obtener ayuda.",
         "hereIsTheError": "Aquí está el error.",
         "internet": "Hemos detectado que la maquina ejecutando Crafty no tiene acceso a internet. Las conexiones de clientes al servidor podrían estar limitadas.",
+        "no-file": "No se puede localizar el archivo solicitado. Verifique dos veces la ruta. Capaz Crafty no tiene los permisos adecuados?",
         "noJava": "Server {} fallo al iniciar con código de error: Detectamos que Java no esta instalado, Por favor instale java y inicie el servidor.",
+        "not-downloaded": "Parece que no podemos encontrar su archivo ejecutable. Capaz no ha terminado de descargarse o los permisos están configurados como ejecutables.",
+        "portReminder": "Detectamos que es la primera vez que se inicia {}. Asegúrese de configurar el puerto {} A través de su router/firewall para hacer el servidor accesible.",
         "start-error": "Servidor {} fallo al iniciar con código de error: {}",
         "terribleFailure": "¡Un terrible error!"
     },
@@ -150,16 +192,68 @@
         "password": "Contraseña",
         "username": "Usuario"
     },
+    "notify": {
+        "activityLog": "Registros de actividad",
+        "backupComplete": "Backup completado de manera exitosa en el servidor {}",
+        "backupStarted": "Backup iniciado para el servidor {}",
+        "downloadLogs": "Descargar registros de soporte?",
+        "finishedPreparing": "Terminamos la preparación de tus registros de soporte. Por favor presione el boton para descargar.",
+        "logout": "Cerrar Sesión",
+        "preparingLogs": " Por favor espere mientras preparamos los registros. Le enviaremos una notificación cuando estén listos. Esto puede tomar un rato en implementaciones grandes.",
+        "supportLogs": "Registros de soporte"
+    },
     "panelConfig": {
+        "adminControls": "Controles de administrador",
+        "allowedServers": "Servidores Habilitados",
+        "assignedRoles": "Roles asignados",
         "cancel": "Cancelar",
+        "clearComms": "Limpiar comandos sin ejecutar.",
         "delete": "Eliminar",
-        "save": "Guardar"
+        "edit": "Editar",
+        "enabled": "Habilitado",
+        "newRole": "Agregar un nuevo rol",
+        "newUser": "Agregar nuevo Usuario",
+        "pageTitle": "Configuración del panel",
+        "role": "Rol",
+        "roles": "Roles",
+        "roleUsers": "Usuarios del rol",
+        "save": "Guardar",
+        "superConfirm": "Proceder solamente si queres que este usuario tenga acceso a TODO(todas las cuentas de usuarios, servidores, configuración del panel, etc...) Hasta puede quitarte tu permiso de superuser.",
+        "superConfirmTitle": "Habilitar superusers? Estas seguro?",
+        "user": "Usuario",
+        "users": "Usuarios"
+    },
+    "rolesConfig": {
+        "config": "Configuracion de roles",
+        "configDesc": "Aca podes cambiar la configuracion de los roles",
+        "configUpdate": "Actualizado: ",
+        "created": "Creado: ",
+        "delRole": "Eliminar Rol",
+        "doesNotExist": "No podes elminiar algo que todavia no existe",
+        "pageTitle": "Editar Rol",
+        "pageTitleNew": "Nuevo Rol",
+        "permAccess": "Acceso?",
+        "permName": "Nombre de los permisos",
+        "permsServer": "Permisos que tiene este rol para esos servidores específicos.",
+        "roleConfigArea": "Zona de configuración de roles",
+        "roleDesc": "Como te gustaria llamar a este rol?",
+        "roleName": "Nombre del rol: ",
+        "rolePerms": "Permisos del rol",
+        "roleServers": "Servidores Habilitados",
+        "roleTitle": "Configuración de Roles",
+        "roleUserName": "Nombre de usuario",
+        "roleUsers": "Usuarios del rol: ",
+        "serverAccess": "Acceso?",
+        "serverName": "Nombre del servidor",
+        "serversDesc": "Servidores a los que este rol puede acceder"
     },
     "serverBackups": {
         "backupAtMidnight": "¿Copia de seguridad automática a medianoche?",
         "backupNow": "¡Haga una copia de seguridad ahora!",
         "backupTask": "Se ha iniciado una tarea de copia de seguridad.",
         "cancel": "Cancelar",
+        "clickExclude": "Click para seleccionar las Exclusiones",
+        "compress": "Comprimir el Backup",
         "confirm": "Confirmar",
         "confirmDelete": "¿Quieres eliminar esta copia de seguridad? Esto no se puede deshacer.",
         "confirmRestore": "Esta seguro de que quiere restaurar desde este backup. Todos los archivos actuales del servidor seran cambiados al estado del backup y seran irrecuperables.",
@@ -167,6 +261,9 @@
         "delete": "Eliminar",
         "destroyBackup": "¿Destruir copia de seguridad \" + file_to_del + \"?",
         "download": "Descargar",
+        "excludedBackups": "Rutas Excluidas: ",
+        "excludedChoose": "Elija las rutas que desea excluir de sus backups",
+        "exclusionsTitle": "Exclusiones del backup.",
         "maxBackups": "Máxima cantidad de Copias de seguridad",
         "maxBackupsDesc": "Crafty no almacenará más de N copias de seguridad, eliminando la más antigua (Ingrese 0 para mantenerlas todas)",
         "options": "Opciones",
@@ -174,6 +271,7 @@
         "restore": "Restaurar",
         "restoring": "Restaurando copia de seguridad. Esto puede tomar un tiempo. Sea paciente.",
         "save": "Guardar",
+        "shutdown": "Apague el servidor durante la duración de la copia del backup.",
         "size": "Tamaño",
         "storageLocation": "Ubicación de almacenamiento",
         "storageLocationDesc": "¿Dónde quieres almacenar las copias de seguridad?"
@@ -183,6 +281,8 @@
         "bePatientDeleteFiles": "Tenga paciencia mientras eliminamos su servidor del panel de Crafty y eliminamos todos los archivos. Esta pantalla se cerrará en unos momentos.",
         "bePatientUpdate": "Tenga paciencia mientras actualizamos el servidor. El tiempo de descarga puede variar según la velocidad del Internet...<br /> Esta pantalla se actualizará en unos momentos.",
         "cancel": "Cancelar",
+        "crashTime": "Tiempo de espera por crash",
+        "crashTimeDesc": "Cuanto tiempo se debe esperar después de que crafty considere su servidor como crasheado?",
         "deleteFilesQuestion": "¿Eliminar archivos del servidor de la máquina?",
         "deleteFilesQuestionMessage": "¿Le gustaría que Crafty elimine todos los archivos del servidor de la máquina host? <br><br><strong>Esto incluye backups del servidor.</strong>",
         "deleteServer": "Eliminar Servidor",
@@ -190,6 +290,9 @@
         "deleteServerQuestionMessage": "¿Estás seguro de que desea eliminar este servidor? Después de esto no hay vuelta atrás...",
         "exeUpdateURL": "URL de actualización para el ejecutable del Servidor",
         "exeUpdateURLDesc": "URL de descarga directa para actualizaciones.",
+        "javaNoChange": "No sobrescribir",
+        "javaVersion": "Sobrescribir versión de Java.",
+        "javaVersionDesc": "Si vas a sobrescribir la versión de Java, Asegúrese de que ponga la localizacion de java con ' ' (comillas).",
         "noDelete": "No, vuelve atrás.",
         "noDeleteFiles": "No, solo remover del panel.",
         "removeOldLogsAfter": "Eliminar registros antiguos después de",
@@ -266,11 +369,13 @@
         "fileReadError": "Error de lectura del archivo",
         "files": "Archivos",
         "keybindings": "Atajos de teclado",
+        "loadingRecords": "Cargando Archivos...",
         "noDelete": "No",
         "noscript": "El administrador de archivos no funciona sin JavaScript ",
         "rename": "Renombrar",
         "renameItemQuestion": "Cuál debería ser el nuevo nombre?",
         "save": "Guardar",
+        "size": "Alternar tamaño del editor.",
         "stayHere": "NO SALGA DE ESTA PÁGINA",
         "unsupportedLanguage": "Advertencia: este no es un tipo de archivo admitido",
         "unzip": "Descomprimir (UnZip)",
@@ -284,6 +389,41 @@
         "loadingBannedPlayers": "Cargando jugadores baneados",
         "players": "Jugadores"
     },
+    "serverScheduleConfig": {
+        "backup": "Backup del Servidor",
+        "basic": "Básico",
+        "children": "Tareas 'hijos' enlazados: ",
+        "command": "Comando",
+        "command-explain": "Que comandó quiere que sea ejecutado, no incluya el '/'",
+        "cron": "Cron",
+        "cron-explain": "Ponga su configuración de cron. -- NOTA: Pagina recomendada: 'https://crontab.guru'",
+        "custom": "Comando Customizado",
+        "days": "Días",
+        "enabled": "Habilitado",
+        "hours": "Horas",
+        "interval": "Intervalo",
+        "interval-explain": "Con qué frecuencia quieres que se ejecute esta tarea?",
+        "minutes": "Minutos",
+        "offset": "Retraso",
+        "offset-explain": "Cuanto tiempo se debe esperar para ejecutar esta tarea después de la primera? (En Segundos).",
+        "one-time": "Borrar después de su ejecución?",
+        "parent": "Seleccione una tarea programada 'padre'",
+        "parent-explain": "Qué tarea programada debería activar esta?",
+        "reaction": "Reaccion",
+        "restart": "Reiniciar el Servidor",
+        "start": "Iniciar el Servidor",
+        "stop": "Apagar el Servidor",
+        "time": "Horario",
+        "time-explain": "A que hora quiere que la tarea programada se ejecute?"
+    },
+    "serverSchedules": {
+        "areYouSure": "Borrar tarea programada?",
+        "cancel": "Cancelar",
+        "cannotSee": "No puede pude ver todo?",
+        "cannotSeeOnMobile": "Intente hacer clic en una tarea programada para obtener todos los detalles.",
+        "confirm": "Confirmar",
+        "confirmDelete": "Estás seguro de que desea eliminar esta tarea programada? Esto no se puede deshacer."
+    },
     "serverStats": {
         "cpuUsage": "Uso de CPU",
         "description": "Descripción",
@@ -295,6 +435,7 @@
         "serverStarted": "Servidor Iniciado",
         "serverStatus": "Estado del Servidor",
         "serverTime": "Hora UTC",
+        "serverTimeZone": "Zona horaria del servidor",
         "serverUptime": "Actividad del Servidor",
         "starting": "Inicio-retrasado",
         "unableToConnect": "No se pudo conectar",
@@ -303,6 +444,7 @@
     "serverTerm": {
         "commandInput": "Introducir tu comando",
         "delay-explained": "El agente/servicio ha recientemente iniciado y está retrasando el inicio de la instancia del servidor de Minecraft.",
+        "downloading": "Descargando...",
         "restart": "Reiniciar",
         "sendCommand": "Enviar comando",
         "start": "Iniciar",
@@ -318,8 +460,11 @@
         "autoCreate": "Si no se selecciona ninguno, ¡Crafty creara uno!",
         "bePatient": "Por favor tenga paciencia, ya que estamos ' + (importing ? 'import' :  'download') + ' el servidor.",
         "buildServer": "Construir Servidor!",
+        "clickRoot": "Click aquí para seleccionar el directorio raiz.",
+        "close": "Cerrar",
         "defaultPort": "25565 (Por defecto)",
         "downloading": "Descargando Servidor...",
+        "explainRoot": "Por favor, haga click en el botón de abajo para seleccionar el directorio raiz de su servidor.",
         "importing": "Importando Servidor...",
         "importServer": "Importar Servidor existente",
         "importServerButton": "Importar Servidor!",
@@ -331,9 +476,12 @@
         "quickSettings": "Ajustes rápidos",
         "quickSettingsDescription": "No te preocupes, puedes cambiarlos más tarde.",
         "resetForm": "Limpiar formulario",
+        "save": "Guardar",
         "selectRole": "Seleccionar Grupo(s)",
+        "selectRoot": "Seleccione el directorio raíz del archivo.",
         "selectType": "Selecciona un tipo",
         "selectVersion": "Selecciona una versión",
+        "selectZipDir": "Seleccione el directorio donde quiere que se extraigan los archivos.",
         "serverJar": "Archivo Jar del servidor",
         "serverName": "Nombre del servidor",
         "serverPath": "Dirección del servidor",
@@ -351,5 +499,42 @@
         "navigation": "Navegación",
         "newServer": "Crear nuevo Servidor",
         "servers": "Servers"
+    },
+    "userConfig": {
+        "apiKey": "Claves API",
+        "auth": "Autorizado? ",
+        "config": "Configuración",
+        "configArea": "Area de Configuracion de Usuarios",
+        "configAreaDesc": "Aca modificas la configuración de todos tus usuarios.",
+        "confirmDelete": "Está seguro de que quiere borrar a este usuario? Esta acción es irreversible.",
+        "craftyPermDesc": "Permisos de Crafty que tiene este usuario.",
+        "craftyPerms": "Permisos de Crafty: ",
+        "created": "Creado: ",
+        "deleteUser": "Borrar Usuario: ",
+        "deleteUserB": "Borrar Usuario",
+        "delSuper": "No puedes borrar un super user",
+        "enabled": "Habilitado",
+        "gravDesc": "Este mail se va a usar solamente para conseguir el Gravatar. Crafty no va a usar esta información bajo ninguna circunstancia más que para conseguir el Gravatar™",
+        "gravEmail": "Gravatar™ Email",
+        "lastIP": "Ultima IP: ",
+        "lastLogin": "Última Sesión: ",
+        "lastUpdate": "Última Actualización: ",
+        "leaveBlank": "Para editar el usuario sin cambiar la contraseña, no completar nada.",
+        "member": "Miembro?",
+        "notExist": "No se puede borrar algo que no existe!",
+        "pageTitle": "Editar Usuario.",
+        "pageTitleNew": "Crear Usuario.",
+        "password": "Nueva Contraseña",
+        "permName": "Nombre del Permiso",
+        "repeat": "Repita la contraseña.",
+        "roleName": "Nombre del rol.",
+        "super": "Super User",
+        "userLang": "Idioma del usuario.",
+        "userName": "Nombre de usuario.",
+        "userNameDesc": "Como quieres llamar a este usuario?",
+        "userRoles": "Roles del usuario.",
+        "userRolesDesc": "Roles que tiene este usuario.",
+        "userSettings": "Configuracion de Usuario.",
+        "uses": "Número de usos habilitados. (-1 == sin límite)."
     }
 }
diff --git a/app/translations/pl_PL.json b/app/translations/pl_PL.json
new file mode 100644
index 00000000..90d42e7a
--- /dev/null
+++ b/app/translations/pl_PL.json
@@ -0,0 +1,540 @@
+{
+    "404": {
+        "contact": "Podrzebujesz pomocy? Zapraszamy na serwer discord Crafty Controler",
+        "notFound": "Strony nie znaleziono",
+        "unableToFind": "Nie znaleźliśmy strony której szukasz. Spróbój ponownie, albo wróć się o stronę i ją odśwież"
+    },
+    "accessDenied": {
+        "accessDenied": "Nie posiadasz do tego dostępu",
+        "contact": "Podrzebujesz pomocy? Zapraszamy na serwer discord Crafty Controler",
+        "contactAdmin": "Skontaktuj się z administratorem aby uzyskać dostęp, jeśli myślisz że powinieneś mieć dostęp, skontaktuj się z supportem.",
+        "noAccess": "Nie masz dostępu do tych zasobów"
+    },
+    "apiKeys": {
+        "apiKeys": "Klucze API",
+        "auth": "Authorized? ",
+        "buttons": "Przyciski",
+        "config": "Config",
+        "crafty": "Crafty: ",
+        "created": "Stworzono",
+        "createNew": "Stwórz nowy klucz API",
+        "deleteKeyConfirmation": "Czy chcesz usunąć ten klucz API? Nie można tego cofnąć.",
+        "deleteKeyConfirmationTitle": "Usunąć Klucz API ${keyId}?",
+        "getToken": "Zdobądź token",
+        "name": "Nazwa",
+        "nameDesc": "Jak chcesz nazwać ten klucz API? ",
+        "no": "Nie",
+        "pageTitle": "Edytuj klucze API użytkownika",
+        "permName": "Nazwa permisji",
+        "perms": "Permisje",
+        "server": "Serwer: ",
+        "superUser": "Super użytkownik",
+        "yes": "Tak"
+    },
+    "base": {
+        "doesNotWorkWithoutJavascript": "<strong>Uwaga: </strong>Crafty nie działa gdy JavaScript jest wyłączone!"
+    },
+    "credits": {
+        "developmentTeam": "Drużyna Deweloperów",
+        "hugeDesc": "Wielkie",
+        "pageDescription": "Bez tych ludzi nie miał być Craftiego!",
+        "pageTitle": "Podziękowania",
+        "patreonDesc": "dla naszych ludzi wsparcia z Patreon / Ko-fi!",
+        "patreonOther": "Inne",
+        "patreonSupporter": "Patreon / Ko-fi Wsparcie",
+        "patreonUpdate": "Ostatni Update:",
+        "retiredStaff": "Wycofany personel",
+        "subscriberName": "Nazwa",
+        "subscriptionLevel": "Poziom",
+        "supportTeam": "Pomoc i Drużyna Dokumentacji",
+        "thankYou": "DZIĘKUJEMY WAM",
+        "translationDesc": "dla naszej społeczności która tłumaczy!",
+        "translationName": "Nazwa",
+        "translationTitle": "Język tłumaczenia",
+        "translator": "Tłumacze"
+    },
+    "dashboard": {
+        "actions": "Akcje",
+        "allServers": "Wszystkie serwery",
+        "avg": "Avg",
+        "backups": "Backupy",
+        "bePatientClone": "Poczekaj, gdy my klonujemy serwer.<br /> Strona za chwilę się odświeży",
+        "bePatientRestart": "Poczekaj, gdy my restartujemy twój serwer.<br /> Strona za chwilę się odświeży",
+        "bePatientStart": "Poczekaj, gdy my właczamy twój serwer.<br /> Strona za chwilę się odświeży",
+        "bePatientStop": "Poczekaj, gdy my zatrzymujemy twój serwer.<br /> Strona za chwilę się odświeży",
+        "cannotSee": "Nie widzisz wszystkiego?",
+        "cannotSeeOnMobile": "Nie widzisz wszystkiego na telefonie?",
+        "cannotSeeOnMobile2": "Spróbój obrócić telefon poziomo.",
+        "clone": "Klonuj",
+        "cloneConfirm": "Jesteś pewien że chcesz skonować ten serwer? To trochę zajmie.",
+        "cpuCores": "Rdzenie procesora",
+        "cpuCurFreq": "GHz Procesora",
+        "cpuMaxFreq": "Maksymalne GHz Procesora",
+        "cpuUsage": "Użycie procesora",
+        "crashed": "Zcrashował",
+        "dashboard": "Dashboard",
+        "delay-explained": "Crafty niedawno się odpalił, właczanie serwera będzie trochę opóźnione",
+        "host": "Host",
+        "kill": "Zabij proces",
+        "killing": "Zabijanie procesu...",
+        "lastBackup": "Ostatni:",
+        "max": "Maks.",
+        "memUsage": "Użycie RAMu",
+        "motd": "Wiadomość dnia",
+        "newServer": "Stwórz nowy serwer",
+        "nextBackup": "Next:",
+        "no-servers": "Nie posiadasz żadnych serwerów. Aby zacząć, kliknij",
+        "offline": "Wyłączony",
+        "online": "Włączony",
+        "players": "Gracze",
+        "restart": "Restart",
+        "sendingCommand": "Wysyłanie twojej komendy",
+        "server": "Serwer",
+        "servers": "Serwery",
+        "size": "Rozmiar serwera",
+        "start": "Start",
+        "starting": "Opóźniony-Start",
+        "status": "Status",
+        "stop": "Zatrzymaj",
+        "version": "Wersja",
+        "welcome": "Witamy w Crafty Controller"
+    },
+    "datatables": {
+        "i18n": {
+            "aria": {
+                "sortAscending": ": aktywuj, aby sortować kolumny w góre",
+                "sortDescending": ": aktywuj, aby sortować kolumny w dół"
+            },
+            "buttons": {
+                "collection": "Kolekcja <span class='ui-button-icon-primary ui-icon ui-icon-triangle-1-s'/>",
+                "colvis": "Widoczność kolumn",
+                "colvisRestore": "Przywróć widoczność",
+                "copy": "Kopiuj",
+                "copyKeys": "Wciśnij ctrl albo u2318 + C aby skopiować tabelę danych do schowka.<br><br>Aby anulować, kliknij tą wiadomość albo wciśnij escape.",
+                "copySuccess": {
+                    "1": "Skopiowano 1 rząd do schowka",
+                    "_": "Skopiowano %d rządów do schowka"
+                },
+                "copyTitle": "Kopiuj do schowka",
+                "csv": "CSV",
+                "excel": "Eksel",
+                "pageLength": {
+                    "1": "Pokaż 1 rząd",
+                    "-1": "Pokaż wszystkie rzędy",
+                    "_": "Pokaż %d rządów"
+                },
+                "pdf": "PDF",
+                "print": "Wydrukuj"
+            },
+            "decimal": "",
+            "emptyTable": "Brak danych w tej tabeli danych",
+            "info": "Pokazywanie _START_ to _END_ of _TOTAL_ wejść",
+            "infoEmpty": "Pokazywanie 0 do 0 z 0 wejść",
+            "infoFiltered": "(filtered from _MAX_ total entries)",
+            "infoPostFix": "",
+            "lengthMenu": "Pokazuj _MENU_ entries",
+            "loadingRecords": "Wczytywanie...",
+            "paginate": {
+                "first": "Pierwsze",
+                "last": "Ostatnie",
+                "next": "Następne",
+                "previous": "Poprzednie"
+            },
+            "processing": "Przetwarzanie...",
+            "search": "Szukaj:",
+            "select": {
+                "cells": {
+                    "0": "Kliknij na komórkę aby ją zaznaczyć",
+                    "1": "%d komórka zaznaczonych",
+                    "_": "%d komórek zaznaczonych"
+                },
+                "columns": {
+                    "0": "Kliknij na kolumnę aby ją zaznaczyć",
+                    "1": "%d kolumna zaznaczona",
+                    "_": "%d kolumn zaznaczonych"
+                },
+                "rows": {
+                    "0": "Click on a row to select it",
+                    "1": "%d row selected",
+                    "_": "%d rows selected"
+                }
+            },
+            "thousands": ",",
+            "zeroRecords": "Nie znaleziono pasujacego wyniku"
+        }
+    },
+    "error": {
+        "contact": "Podrzebujesz pomocy? Zapraszamy na serwer discord Crafty Controler",
+        "embarassing": "Oh, więc, to jest żenujące.",
+        "error": "Błąd!",
+        "eulaAgree": "Czy się zgadzasz?",
+        "eulaMsg": "Musisz się zgodzić na EULA. Kopia EULA Mojangu jest zalinkowana pod tą wiadomością.",
+        "eulaTitle": "Zgódź się na EULA",
+        "fileTooLarge": "Upload nie udany. Plik jest za duży. Skontaktuj się z administratorem dla pomocy.",
+        "hereIsTheError": "Tu jest problem",
+        "internet": "Zauważyliśmy że Crafty nie ma dostępu do internetu. Połączenie klientów z Craftym może być utrudnione.",
+        "no-file": "Nie możemy znaleść żądanego pliku. Sprawdź ścieżkę. Czy Crafty ma odpowiednie uprawnienia?",
+        "noJava": "Serwer {} nie mógł się odpalić z powodu: Zauważyliśmy że Java nie jest zainstalowana. Proszę zainstaluj Javę, a następnie włącz serwer.",
+        "not-downloaded": "Nie możemy znaleść twojego pliku serwera. Czy skończył się pobierać? Czy permisje są ustawione na wykonywanle?",
+        "portReminder": "Zauważyliśmy że to jest pierwszy raz {} kiedy był włączony. Upewnij się że otworzyłeś port {} na swoim routerze/firewallu aby korzystać z tego poza domem.",
+        "start-error": "Serwer {} nie mógł się odpalić z powodu: {}",
+        "terribleFailure": "Okropny błąd!"
+    },
+    "footer": {
+        "allRightsReserved": "Wszelkie Prawa zastrzeżone",
+        "copyright": "Copyright",
+        "version": "Wersja"
+    },
+    "login": {
+        "forgotPassword": "Zapomniałem hasła",
+        "login": "Zaloguj się",
+        "password": "Hasło",
+        "username": "Nazwa użytkownika"
+    },
+    "notify": {
+        "activityLog": "Logi Aktywności",
+        "backupComplete": "Backup zakończony poprawnie dla serwera {}",
+        "backupStarted": "Backup zaczęty dla serwera {}",
+        "downloadLogs": "Pobrać Logi Supportu?",
+        "finishedPreparing": "Skończyliśmy przygotowywać logi supportu. Kliknij tutaj, aby je pobrać",
+        "logout": "Wyloguj się",
+        "preparingLogs": " Poczekaj kiedy my przygotowujemy twoje logi ... Wyślemy ci powiadomienie kiedy będą gotowe. To trochę zajmie na dużych serwerach.",
+        "supportLogs": "Logi Pomocnicze"
+    },
+    "panelConfig": {
+        "adminControls": "Ustawienia Admina",
+        "allowedServers": "Zezwolone serwery",
+        "assignedRoles": "Przypisane role",
+        "cancel": "Anuluj",
+        "clearComms": "Wyczyść nie wykonane komendy",
+        "delete": "Usuń",
+        "edit": "Edytuj",
+        "enabled": "Wlączone",
+        "match": "Hasła muszą być takie same",
+        "newRole": "Dodaj nową role",
+        "newUser": "Dodaj nowego użytkownika",
+        "pageTitle": "Ustawienia Panelu",
+        "role": "Role",
+        "roles": "Roles",
+        "roleUsers": "Role użytkownika",
+        "save": "Zapisz",
+        "superConfirm": "Zapisz jeśli chcesz aby ten użytkownik miał dostęp do WSZYSTKIEGO (wszyscy użytkownicy, konta, serwery, ustawienia panelu, itp.). Mogą oni nawet usunąć twoje prawa SuperUżytkownika.",
+        "superConfirmTitle": "Włączyć SuperUżytkownika? Jesteś pewien?",
+        "user": "Użytkownik",
+        "users": "użytkownicy"
+    },
+    "rolesConfig": {
+        "config": "Zarządzanie rolami",
+        "configDesc": "Tu możesz zmienić konfiguracje roli",
+        "configUpdate": "Ostatnio aktualizowane: ",
+        "created": "Stworzone: ",
+        "delRole": "Usuń role",
+        "doesNotExist": "Nie możesz usunąć czegoś co nie istnieje",
+        "pageTitle": "Edytuj role",
+        "pageTitleNew": "Nowa rola",
+        "permAccess": "Dostęp?",
+        "permName": "Nazwa permisji",
+        "permsServer": "Permisje tej roli dla tych wyspecializowanych serwerów",
+        "roleConfigArea": "Ustawienia ról",
+        "roleDesc": "Jak chciałbyć nazwać te rolę?",
+        "roleName": "Nazwa roli: ",
+        "rolePerms": "Permisje roli",
+        "roleServers": "Zezwolone serwery",
+        "roleTitle": "Ustawienia roli",
+        "roleUserName": "Nazwa użytkownika",
+        "roleUsers": "Dostęp do ról: ",
+        "serverAccess": "Dostęp?",
+        "serverName": "Nazwa serwera",
+        "serversDesc": "Serwery które mają tą role mają dostęp"
+    },
+    "serverBackups": {
+        "backupAtMidnight": "Auto-backup o północy?",
+        "backupNow": "Backup Teraz!",
+        "backupTask": "Backup został rozpoczęty.",
+        "cancel": "Anuluj",
+        "clickExclude": "Kliknij aby zaznaczyć wyjątki",
+        "compress": "Skompresuj backup",
+        "confirm": "Akceptuj",
+        "confirmDelete": "Czy chcesz usunąć ten backup? Nie można tego cofnąć.",
+        "confirmRestore": "Czy jesteś pewien że chcesz przywrócić z tego backupu. Wszystkie pliki powrócą do stanu z backupu.",
+        "currentBackups": "Backupy Teraz",
+        "delete": "Usuń",
+        "destroyBackup": "Zniszcz Backup \" + file_to_del + \"?",
+        "download": "Pobierz",
+        "excludedBackups": "Wykluczone ścieżki: ",
+        "excludedChoose": "Wybierz ścieżki do wykluczenia z backupu",
+        "exclusionsTitle": "Wykluczenia backupu",
+        "maxBackups": "Maks. Backupów",
+        "maxBackupsDesc": "Crafty nie będzie zbierał więcej niż N backupów, zacznie usuwać od nadstarszych (wpisz 0, aby zatrzymać nieskończoną ilość)",
+        "options": "Opcje",
+        "path": "Ścieżka",
+        "restore": "Przywróć",
+        "restoring": "Przywracanie backupu. To trochę zajmie. Bądź cierpliwy.",
+        "save": "Zapisz",
+        "shutdown": "Wyłącz serwer na czas backupu",
+        "size": "Rozmiar",
+        "storageLocation": "Ścieżka zapisywania",
+        "storageLocationDesc": "Gdzie chcesz trzymać backupy?"
+    },
+    "serverConfig": {
+        "bePatientDelete": "Poczekaj, aż usuniemy twój serwer. Strona za chwilę się zamknie.",
+        "bePatientDeleteFiles": "Poczekaj, aż usuniemy twój serwer i jego pliki. Strona za chwilę się zamknie.",
+        "bePatientUpdate": "Poczekaj kiedy my aktualizujemy twój serwer. Pobieranie zależy od prędkości twojego internetu.<br /> Strona się odświeży za chwile.",
+        "cancel": "Anuluj",
+        "crashTime": "Crash wyszedł poza limit czasu",
+        "crashTimeDesc": "How long should we wait before we consider your server as crashed?",
+        "deleteFilesQuestion": "Usuń pliki serwera z maszyny?",
+        "deleteFilesQuestionMessage": "Czy chcesz aby Crafty usunął wszystkie pliki tego serwera? <br><br><strong>To zawiera backupy.</strong>",
+        "deleteServer": "Usuń serwer",
+        "deleteServerQuestion": "Usunąć serwer?",
+        "deleteServerQuestionMessage": "Jesteś pewien że chcesz usunąć ten serwer? To jest nie odwracalne...",
+        "exeUpdateURL": "URL pliku egzekucyjnego serwera",
+        "exeUpdateURLDesc": "Bezpośredni link dla aktualizacji.",
+        "javaNoChange": "Nie nadpisuj",
+        "javaVersion": "Nadpisz wersję Javy",
+        "javaVersionDesc": "Jeśli chcesz nadpisać wersję javy. Upewnij się że twoja wersja javy w 'komendzie egzekucyjnej' jest zawinięta w cytaty (podstatowa zmienna 'java' jest wykluczona )",
+        "noDelete": "Nie, wróć się",
+        "noDeleteFiles": "Nie, tylko usuń z panelu",
+        "removeOldLogsAfter": "Usuń stare logi po",
+        "removeOldLogsAfterDesc": "Ile dni musi mieć log aby został usunięty (0 oznacza że nie będziemy usuwać)",
+        "save": "Zapisz",
+        "sendingDelete": "Usuwanie serwera",
+        "sendingRequest": "Wysyłanie twojej prośby...",
+        "serverAutoStart": "Auto-Włączanie serwera",
+        "serverAutostartDelay": "Opóźnienie auto-włączenia serwera",
+        "serverAutostartDelayDesc": "Opóźnienie auto-włączenia (Jeśli włączone poniżej)",
+        "serverCrashDetection": "Detekcja Crashu serwera",
+        "serverExecutable": "Plik egzekucyjny",
+        "serverExecutableDesc": "Plik egzekucyjnego serwera",
+        "serverExecutionCommand": "Komenda włączania serwera",
+        "serverExecutionCommandDesc": "Co będzie odpalone w ukrytej konsoli",
+        "serverIP": "IP serwera",
+        "serverIPDesc": "IP, na jakim Crafty powinien połączyć dla statystyk (Spróbój prawdziwe ip zamiast 127.0.0.1 jeśli masz problemy)",
+        "serverLogLocation": "Lokalizacja logów serwera",
+        "serverLogLocationDesc": "Ścieżka do logów serwera",
+        "serverName": "Nazwa serwera",
+        "serverNameDesc": "Jak chciałbyć nazwać ten serwer",
+        "serverPath": "Ścieżka serwera",
+        "serverPathDesc": "Pełna ścieżka serwera (nie licząc pliku startu serwera)",
+        "serverPort": "Port serwera",
+        "serverPortDesc": "Port na jakim Crafty ma szukać statystyk",
+        "serverStopCommand": "Komenda wyłączenia serwera",
+        "serverStopCommandDesc": "Komenda, którą wyśle crafty aby wyłączyć serwer",
+        "stopBeforeDeleting": "Zatrzymaj serwer przed jego usunięciem",
+        "update": "Aktualizuj plik serwera",
+        "yesDelete": "Tak, usuń",
+        "yesDeleteFiles": "Tak, usuń pliki"
+    },
+    "serverConfigHelp": {
+        "desc": "Tutaj możesz zmienić konfigurację serwera",
+        "perms": [
+            "<code>Nie</code> zalecamy zmieniania ścieżek serwera którymi zarządza Crafty.",
+            "Zmienianie ścieżek <code>MOŻE</code> zniszczyć rzeczy, szczególnie na Linuksie i podobnych systemach gdzie permisje plików są bardziej zamknięte.",
+            "<br /><br/>",
+            "Jeśli czujesz że musisz zmienić to, gdzie twój serwer się znajduje, możesz to zrobić, pod warunkiem że dasz mu permisję \"crafty\" do odczytu i zapisu w ścieżce serwera.",
+            "<br />",
+            "<br />",
+            "Na Linuksie najlepiej jest to zrobić wpisując taką komendę:<br />",
+            "<code>",
+            "    sudo chown crafty:crafty /ścieżka/do/twojego/serwera -R<br />",
+            "    sudo chmod 2775 /ścieżka/do/twojego/serwera -R<br />",
+            "</code>"
+        ],
+        "title": "Konfiguracja serwera"
+    },
+    "serverDetails": {
+        "backup": "Backup",
+        "config": "Konfiguracja",
+        "files": "Pliki",
+        "logs": "Logi",
+        "playerControls": "Player Management",
+        "schedule": "Harmonogram",
+        "serverDetails": "Detale serwera",
+        "terminal": "Konsola"
+    },
+    "serverFiles": {
+        "clickUpload": "Kliknij tutaj, aby wybrać twoje pliki",
+        "close": "Zamknij",
+        "createDir": "Nowa ścieżka",
+        "createDirQuestion": "Jak chcesz nazwać nową ścieżkę?",
+        "createFile": "Nowy plik",
+        "createFileQuestion": "Jak chcesz nazwać nowy plik?",
+        "default": "Domyślne",
+        "delete": "Usuń",
+        "deleteItemQuestion": "Czy jesteś pewien że chcesz usunąć \" + name + \"?",
+        "deleteItemQuestionMessage": "Usuwasz \\\"\" + path + \"\\\"!<br/><br/>Ta akcja jest nieodwracalna i zostanie usunięta na zawsze!",
+        "download": "Pobierz",
+        "editingFile": "Edytuję plik",
+        "error": "Error while getting files",
+        "fileReadError": "Error odczytu pliku",
+        "files": "Pliki",
+        "keybindings": "Skróty klawiszowe",
+        "loadingRecords": "Wczytywanie plików...",
+        "noDelete": "Nie",
+        "noscript": "Przeglądarka plików nie działa bez Javascript",
+        "rename": "Zmień nazwę",
+        "renameItemQuestion": "Jaka ma być nowa nazwa?",
+        "save": "Zapisz",
+        "size": "Włącz zmienianie rozmiaru edytora",
+        "stayHere": "NIE WYCHODŹ Z TEJ STRONY!",
+        "unsupportedLanguage": "Uwaga: To nie jest wspierany typ pliku",
+        "unzip": "Unzip",
+        "upload": "Upload",
+        "uploadTitle": "Wyślij pliki do: ",
+        "waitUpload": "Poczekaj, aż wyślemy twoje pliki... To może chwilkę zająć.",
+        "yesDelete": "Tak, zdaję sobie sprawę z konsekfencji"
+    },
+    "serverPlayerManagement": {
+        "bannedPlayers": "Zbanowani gracze",
+        "loadingBannedPlayers": "Wczytuję zbanowanych graczy",
+        "players": "Gracze"
+    },
+    "serverScheduleConfig": {
+        "backup": "Backup Serwera",
+        "basic": "Podstawowy",
+        "children": "Połączone zadania podrzędne: ",
+        "command": "Komenda",
+        "command-explain": "Jaką komendę chcesz abyśmy wykonali? Nie pisz '/' z przodu",
+        "cron": "Cron",
+        "cron-explain": "Tutaj wpisz cron string -- Uwaga: 0 = Poniedziałek jest ostatnią opcją.",
+        "custom": "Własna komenda",
+        "days": "dni",
+        "enabled": "Włączony",
+        "hours": "Godziny",
+        "interval": "Interwał",
+        "interval-explain": "Jak często mamy to wykonywać?",
+        "minutes": "Minuty",
+        "offset": "Opóźnienie przesunięcia",
+        "offset-explain": "Ile powinniśmy poczekać po wykonaniu pierwszego zadania? (W sekundach)",
+        "one-time": "Usuń po wykonaniu",
+        "parent": "Wybierz harmonogram rodzica",
+        "parent-explain": "Który harmonogram powinien wykonywać ten?",
+        "reaction": "Reakcja",
+        "restart": "Restart Serwera",
+        "start": "Start Serwera",
+        "stop": "Wyłącz Serwer",
+        "time": "Czas",
+        "time-explain": "O jakim czasie ma wykonać się ten harmonogram?"
+    },
+    "serverSchedules": {
+        "areYouSure": "Usuń zaplanowane (zadanie)?",
+        "cancel": "Anuluj",
+        "cannotSee": "Nie widzisz wszystkiego?",
+        "cannotSeeOnMobile": "Spróbój kliknąć na zadanie dla detali.",
+        "confirm": "Zapisz",
+        "confirmDelete": "Czy chcesz usunąć ten zaplanowany task? Jest to nieodwracalne."
+    },
+    "serverStats": {
+        "cpuUsage": "Użycie procesora",
+        "description": "Opis",
+        "errorCalculatingUptime": "Błąd obliczania czasu pracy",
+        "memUsage": "Użycie RAMu",
+        "offline": "Wyłączony",
+        "online": "Włączony",
+        "players": "Gracze",
+        "serverStarted": "Włączono serwer",
+        "serverStatus": "Status serwera",
+        "serverTime": "Czas UTC",
+        "serverTimeZone": "Strefa czasowa serwera",
+        "serverUptime": "Server Uptime",
+        "starting": "Opóźniony-Start",
+        "unableToConnect": "Nie można połączyć",
+        "version": "Wersja"
+    },
+    "serverTerm": {
+        "commandInput": "Wpisz swoją komendę",
+        "delay-explained": "Crafty niedawno się odpalił, właczanie serwera będzie trochę opóźnione",
+        "downloading": "Pobieranie...",
+        "restart": "Restart",
+        "sendCommand": "Wyślij komendę",
+        "start": "Start",
+        "starting": "Opóźniony-Start",
+        "stop": "Zatrzymaj",
+        "stopScroll": "Zatrzymaj Auto-przewijanie",
+        "updating": "Aktualizowanie..."
+    },
+    "serverWizard": {
+        "absoluteServerPath": "Pełna ścieżka serwera",
+        "absoluteZipPath": "Pełna ścieżka serwera",
+        "addRole": "Dodaj serwer do ról/roli",
+        "autoCreate": " Jeśli żadnej nie zaznaczysz, crafty stworzy nową!",
+        "bePatient": "Proszę, poczekaj kiedy ' + (importing ? 'importujemy' :  'pobieramy') + ' serwer",
+        "buildServer": "Zbuduj serwer!",
+        "clickRoot": "Kilknij tutaj aby zaznaczyć główną ścieżkę",
+        "close": "Zamknij",
+        "defaultPort": "25565 podstawowy",
+        "downloading": "Pobieranie serwera...",
+        "explainRoot": "Proszę, kliknij przycisk poniżej aby zaznaczyć główną ścieżkę w tym archiwum",
+        "importing": "Importowanie serwera...",
+        "importServer": "Importuj egzystujący serwer",
+        "importServerButton": "Importuj serwer!",
+        "importZip": "Importuj z ZIPa",
+        "maxMem": "Maks. RAMu",
+        "minMem": "Min. RAMu",
+        "myNewServer": "Mój nowy serwer",
+        "newServer": "Stwórz nowy serwer",
+        "quickSettings": "Szybkie ustawienia",
+        "quickSettingsDescription": "Nie martw się, możesz te ustawienia zmienić później",
+        "resetForm": "Resetuj formę",
+        "save": "Zapisz",
+        "selectRole": "Zaznacz rolę (lub kilka)",
+        "selectRoot": "Wybierz archiwum głównej ścieżki | (TBF, Select Archive Root Dir)",
+        "selectType": "Wybierz typ serwera",
+        "selectVersion": "Wybiesz wersje",
+        "selectZipDir": "Wybierz ścieżkę w archiwóm którą chcesz abyśmy wypakowali",
+        "serverJar": "Plik egzekucyjny serwera",
+        "serverName": "Nazwa serwera",
+        "serverPath": "Ścieżka serwera",
+        "serverPort": "Port serwera",
+        "serverType": "Typ serwera",
+        "serverVersion": "Wersja serwera",
+        "sizeInGB": "Wielkość w GB",
+        "zipPath": "Server Path"
+    },
+    "sidebar": {
+        "contribute": "Współpracuj",
+        "credits": "Podziękowania",
+        "dashboard": "Panel",
+        "documentation": "Dokumentacja",
+        "navigation": "Nawigacja",
+        "newServer": "Stwórz nowy serwer",
+        "servers": "Serwery"
+    },
+    "userConfig": {
+        "apiKey": "Klucze API",
+        "auth": "Autoryzacja? ",
+        "config": "Ustawienia",
+        "configArea": "Ustawienia użytkownika",
+        "configAreaDesc": "Tutaj możesz zmienić ustawienia użytkownika",
+        "confirmDelete": "Jesteś pewien że chcesz usunąć tego użytkownika ? To jest nieodwracalne.",
+        "craftyPermDesc": "Ten użytkownik ma dostęp do ustawień Craftiego takich jak: ",
+        "craftyPerms": "Ustawienia Craftiego: ",
+        "created": "Stworzono: ",
+        "deleteUser": "Usuń użytkownika: ",
+        "deleteUserB": "Usuń użytkownika",
+        "delSuper": "Nie możesz usunąć SuperUżytkownika",
+        "enabled": "Enabled",
+        "gravDesc": "To jest email tylko używany do  Gravatar™. Crafty nie użyje pod żadnymi okolicznościami twojego adresu email, niż sprawdzenie ikony Gravatar™ ",
+        "gravEmail": "Gravatar™ Email",
+        "lastIP": "Ostatnie IP: ",
+        "lastLogin": "Ostatni login: ",
+        "lastUpdate": "Ostatni update: ",
+        "leaveBlank": "Jeśli chcesz zmienić użytkownika bez zmieniania hasła, nic nie wpisuj.",
+        "member": "Użytkownik?",
+        "notExist": "Nie możesz usunąć czegoś, co nie istnieje!",
+        "pageTitle": "Edytuj użytkownika",
+        "pageTitleNew": "Stwórz użytkownika",
+        "password": "Nowe hasło",
+        "permName": "Nazwa permisji",
+        "repeat": "Powtórz hasło",
+        "roleName": "Nazwa roli",
+        "super": "SuperUżytkownik",
+        "userLang": "Język użytkownika",
+        "userName": "Nazwa użytkownika",
+        "userNameDesc": "Jak chcesz nazwać tego użytkownika?",
+        "userRoles": "Role użytkownika",
+        "userRolesDesc": "Role, które ten użytkownik posiada.",
+        "userSettings": "Ustawienia użytkownika",
+        "uses": "Ilość użyć (-1==Bez limitu)"
+    }
+}
diff --git a/main.py b/main.py
index 45fd67f2..f41c1d74 100644
--- a/main.py
+++ b/main.py
@@ -7,8 +7,9 @@ import argparse
 import logging.config
 import signal
 import peewee
-from app.classes.shared.file_helpers import FileHelpers
+from packaging import version as pkg_version
 
+from app.classes.shared.file_helpers import FileHelpers
 from app.classes.shared.import3 import Import3
 from app.classes.shared.console import Console
 from app.classes.shared.helpers import Helpers
@@ -225,6 +226,19 @@ if __name__ == "__main__":
         controller_setup_thread.join()
 
         Console.info("Crafty has fully started and is now ready for use!")
+
+        # Check if new version available
+        remote_ver = helper.check_remote_version()
+        if remote_ver:
+            notice = f"""
+                A new version of Crafty is available!
+                {'/' * 37}
+                New version available: {remote_ver}
+                Current version: {pkg_version.parse(helper.get_version_string())}
+                {'/' * 37}
+                """
+            Console.yellow(notice)
+
         crafty_prompt.prompt = f"Crafty Controller v{helper.get_version_string()} > "
         try:
             logger.info("Removing old temp dirs")