Skip to content

Instantly share code, notes, and snippets.

@AdamG100
Last active September 17, 2025 13:23
Show Gist options
  • Select an option

  • Save AdamG100/ac1906d53194796db44dd86234ff184c to your computer and use it in GitHub Desktop.

Select an option

Save AdamG100/ac1906d53194796db44dd86234ff184c to your computer and use it in GitHub Desktop.

Revisions

  1. AdamG100 revised this gist Sep 17, 2025. No changes.
  2. AdamG100 revised this gist Sep 17, 2025. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion bedrock.py
    Original file line number Diff line number Diff line change
    @@ -155,7 +155,7 @@ def create_game_update(version_type, version, group_name, view_order):
    """
    update = GameUpdate()
    update.Name = "Bedrock Edition {} {}".format(version_type.title(), version)
    update.Comments = ""
    update.Comments = "Updates every 1 hour. Data sourced from mcjarfiles.com"
    update.ImageUrl = IMAGE_URL
    update.GameId = GAME_ID
    update.GroupName = group_name
  3. AdamG100 revised this gist Sep 17, 2025. 1 changed file with 6 additions and 4 deletions.
    10 changes: 6 additions & 4 deletions bedrock.py
    Original file line number Diff line number Diff line change
    @@ -160,8 +160,9 @@ def create_game_update(version_type, version, group_name, view_order):
    update.GameId = GAME_ID
    update.GroupName = group_name
    update.ExtractPath = "/"
    update.WindowsFileName = "{}/get-jar/bedrock/{}/windows/{}".format(API_BASE_URL, version_type, version)
    update.LinuxFileName = "{}/get-jar/bedrock/{}/linux/{}".format(API_BASE_URL, version_type, version)
    # Fixed URLs - removed .zip from the base URL, kept it only after the space
    update.WindowsFileName = "{}/get-jar/bedrock/{}/windows/{} windows.zip".format(API_BASE_URL, version_type, version)
    update.LinuxFileName = "{}/get-jar/bedrock/{}/linux/{} linux.zip".format(API_BASE_URL, version_type, version)
    update.Reinstallable = True
    update.DefaultInstall = False
    update.UserAccess = True
    @@ -289,8 +290,9 @@ def update_latest_version(version_type, latest_version):
    for update in updates:
    if search_text in update.Notes:
    log('Updating latest {} version to {}'.format(version_type, latest_version))
    update.WindowsFileName = "{}/get-jar/bedrock/{}/windows/{}".format(API_BASE_URL, version_type, latest_version)
    update.LinuxFileName = "{}/get-jar/bedrock/{}/linux/{}".format(API_BASE_URL, version_type, latest_version)
    # Fixed URLs - removed .zip from the base URL, kept it only after the space
    update.WindowsFileName = "{}/get-jar/bedrock/{}/windows/{} windows.zip".format(API_BASE_URL, version_type, latest_version)
    update.LinuxFileName = "{}/get-jar/bedrock/{}/linux/{} linux.zip".format(API_BASE_URL, version_type, latest_version)
    update.Save()
    return

  4. AdamG100 revised this gist Sep 9, 2025. 1 changed file with 369 additions and 113 deletions.
    482 changes: 369 additions & 113 deletions bedrock.py
    Original file line number Diff line number Diff line change
    @@ -1,147 +1,403 @@
    import re, urllib.request, json
    import re
    import json
    import gzip
    import clr

    clr.AddReference('TCAdmin.GameHosting.SDK')
    from TCAdmin.GameHosting.SDK.Objects import GameUpdate, GameScript, ServiceEvent

    gameID = 193
    scripts = [
    try:
    # Python 3 style imports
    from urllib.request import Request, urlopen
    from urllib.error import URLError, HTTPError
    except ImportError:
    # Python 2 fallback
    from urllib2 import Request, urlopen, URLError, HTTPError

    # Configuration
    GAME_ID = 193
    API_BASE_URL = 'https://mcjarfiles.com/api'
    IMAGE_URL = "https://media.hyperlayer.net/creeper-icon.png"

    # Script configurations
    SCRIPTS = [
    {
    "Name": "Backup server.properties",
    "Event": ServiceEvent.BeforeUpdateInstall,
    'Contents': "from os import path, rename, remove\nserverproperties = path.join(ThisService.RootDirectory, 'server.properties')\nif path.isfile(serverproperties):\n if path.isfile(serverproperties+'.backup'):\n remove(serverproperties+'.backup')\n rename(serverproperties, serverproperties+'.backup')"
    "Contents": (
    "from os import path, rename, remove\n"
    "serverproperties = path.join(ThisService.RootDirectory, 'server.properties')\n"
    "if path.isfile(serverproperties):\n"
    " if path.isfile(serverproperties+'.backup'):\n"
    " remove(serverproperties+'.backup')\n"
    " rename(serverproperties, serverproperties+'.backup')"
    )
    },
    {
    "Name": "Delete new server.properties, use old file instead",
    "Event": ServiceEvent.AfterUpdateInstall,
    "Contents": "from os import path, rename, remove\nserverproperties = path.join(ThisService.RootDirectory, 'server.properties')\nif path.isfile(serverproperties):\n remove(serverproperties)\nrename(serverproperties+'.backup', serverproperties)"
    "Contents": (
    "from os import path, rename, remove\n"
    "serverproperties = path.join(ThisService.RootDirectory, 'server.properties')\n"
    "if path.isfile(serverproperties):\n"
    " remove(serverproperties)\n"
    "rename(serverproperties+'.backup', serverproperties)"
    )
    }
    ]

    def process_versions(version_type):
    Script.WriteToConsole('Processing {} versions...'.format(version_type))
    def log(message):
    """Helper function for consistent logging"""
    Script.WriteToConsole(message)

    def fetch_versions_from_api(url):
    """
    Fetch and decode versions from API, handling gzipped responses
    # Get existing updates
    updates = GameUpdate.GetUpdates(gameID)
    Args:
    url (str): The API URL to fetch from
    Returns:
    list: List of versions or None if error occurred
    """
    try:
    req = Request(url)
    req.add_header('User-Agent', 'TCAdmin-Script/1.0')
    req.add_header('Accept-Encoding', 'gzip, deflate')

    response = urlopen(req)

    # Check if response is gzipped
    if response.info().get('Content-Encoding') == 'gzip':
    content = gzip.decompress(response.read()).decode('utf-8')
    else:
    content = response.read().decode('utf-8')

    return json.loads(content)

    except (URLError, HTTPError, Exception) as e:
    log('Error fetching from {}: {}'.format(url, str(e)))
    return None

    def get_all_versions_for_type(version_type):
    """
    Fetch versions for both Windows and Linux platforms
    # Fetch versions for both Windows and Linux
    Args:
    version_type (str): 'latest' or 'preview'
    Returns:
    set: Set of all unique versions found
    """
    platforms = ['windows', 'linux']
    all_versions = set()

    for platform in platforms:
    url = '{}/get-versions/bedrock/{}/{}'.format(API_BASE_URL, version_type, platform)
    log('Fetching versions from: {}'.format(url))

    versions_list = fetch_versions_from_api(url)

    if versions_list and isinstance(versions_list, list):
    all_versions.update(versions_list)
    log('Found {} versions for {} {}'.format(len(versions_list), version_type, platform))
    else:
    log('No versions found for {} {}'.format(version_type, platform))

    return all_versions

    def calculate_view_order(version):
    """
    Calculate view order for version sorting (newest first)
    Args:
    version (str): Version string (e.g., "1.19.40.2")
    Returns:
    int: Negative integer for sorting (larger absolute value = newer)
    """
    parts = version.split('.')
    # Ensure we have 4 parts for consistent ordering
    while len(parts) < 4:
    parts.append('0')

    # Zero-pad each part to 3 digits for proper string comparison
    padded_parts = [part.zfill(3) for part in parts]
    return -int(''.join(padded_parts))

    def version_exists(existing_updates, version_type, version):
    """
    Check if a version update already exists
    Args:
    existing_updates: List of existing GameUpdate objects
    version_type (str): 'latest' or 'preview'
    version (str): Version string
    Returns:
    bool: True if version already exists
    """
    update_name = "Bedrock Edition {} {}".format(version_type.title(), version)
    return any(update.Name == update_name for update in existing_updates)

    def create_game_update(version_type, version, group_name, view_order):
    """
    Create a new GameUpdate object
    Args:
    version_type (str): 'latest' or 'preview'
    version (str): Version string
    group_name (str): Update group name
    view_order (int): Sort order value
    Returns:
    GameUpdate: Configured update object
    """
    update = GameUpdate()
    update.Name = "Bedrock Edition {} {}".format(version_type.title(), version)
    update.Comments = ""
    update.ImageUrl = IMAGE_URL
    update.GameId = GAME_ID
    update.GroupName = group_name
    update.ExtractPath = "/"
    update.WindowsFileName = "{}/get-jar/bedrock/{}/windows/{}".format(API_BASE_URL, version_type, version)
    update.LinuxFileName = "{}/get-jar/bedrock/{}/linux/{}".format(API_BASE_URL, version_type, version)
    update.Reinstallable = True
    update.DefaultInstall = False
    update.UserAccess = True
    update.SubAdminAccess = True
    update.ResellerAccess = True
    update.ViewOrder = view_order
    update.GenerateKey()
    return update

    def get_existing_scripts():
    """
    Get existing scripts for the game, with error handling
    Returns:
    list: List of existing GameScript objects, empty list if error
    """
    try:
    # Try different methods to get existing scripts
    if hasattr(GameScript, 'GetScripts'):
    return GameScript.GetScripts(GAME_ID)
    elif hasattr(GameScript, 'GetGameScripts'):
    return GameScript.GetGameScripts(GAME_ID)
    else:
    log('Warning: Could not find method to get existing scripts')
    return []
    except Exception as e:
    log('Error getting existing scripts: {}'.format(str(e)))
    return []

    def script_exists_for_update(update_id, script_name, existing_scripts):
    """
    Check if a script already exists for an update
    Args:
    update_id: The update ID to check
    script_name (str): Name of the script
    existing_scripts (list): List of existing GameScript objects
    Returns:
    bool: True if script already exists
    """
    return any(
    script.UpdateId == update_id and script.Description == script_name
    for script in existing_scripts
    )

    def create_game_script(script_config, update_id):
    """
    Create a new GameScript object
    Args:
    script_config (dict): Script configuration
    update_id: ID of the associated update
    Returns:
    GameScript: Configured script object
    """
    script = GameScript()
    script.Description = script_config["Name"]
    script.ScriptContents = script_config["Contents"]
    script.ServiceEvent = script_config["Event"]
    script.ExecuteAsServiceUser = False
    script.ExecuteInPopup = False
    script.ExecutionOrder = 0
    script.GameId = GAME_ID
    script.IgnoreErrors = False
    script.OperatingSystem = 0 # 0 = Any, 2 = Windows, 4 = Linux
    script.PromptVariables = False
    script.UserAccess = True
    script.SubAdminAccess = True
    script.ResellerAccess = True
    script.ScriptEngineId = 1 # IronPython
    script.UpdateId = update_id
    script.GenerateKey()
    return script

    def add_scripts_to_update(update):
    """
    Add custom scripts to an update, avoiding duplicates
    Args:
    update: GameUpdate object
    """
    log('Adding scripts to update: {}'.format(update.Name))

    # Get existing scripts once per update
    existing_scripts = get_existing_scripts()

    scripts_added = 0
    scripts_skipped = 0

    for script_config in SCRIPTS:
    try:
    url = 'https://mcjarfiles.com/api/get-versions/bedrock/{}/{}'.format(version_type, platform)
    Script.WriteToConsole('Fetching versions from: {}'.format(url))

    # Create request with user agent to avoid 403 errors
    req = urllib.request.Request(url)
    req.add_header('User-Agent', 'TCAdmin-Script/1.0')
    # Check if script already exists for this update
    if script_exists_for_update(update.UpdateId, script_config["Name"], existing_scripts):
    log("Script '{}' already exists for update {}, skipping".format(
    script_config["Name"], update.Name))
    scripts_skipped += 1
    continue

    with urllib.request.urlopen(req) as response:
    versions_list = json.loads(response.read().decode('utf-8'))
    # Create and save the script
    script = create_game_script(script_config, update.UpdateId)
    script.Save()
    log("Added script '{}' for update {}".format(script_config["Name"], update.Name))
    scripts_added += 1

    if versions_list and isinstance(versions_list, list):
    all_versions.update(versions_list)
    Script.WriteToConsole('Found {} versions for {} {}'.format(len(versions_list), version_type, platform))
    else:
    Script.WriteToConsole('No versions found for {} {}'.format(version_type, platform))

    except Exception as e:
    Script.WriteToConsole('Error fetching versions from API for {} {}: {}'.format(version_type, platform, str(e)))
    log("Error adding script '{}' for update {}: {}".format(
    script_config["Name"], update.Name, str(e)))

    log('Added {} scripts to update {}, skipped {} existing scripts'.format(
    scripts_added, update.Name, scripts_skipped))

    def update_latest_version(version_type, latest_version):
    """
    Update the existing "Latest" update with the newest version
    Args:
    version_type (str): 'latest' or 'preview'
    latest_version (str): The newest version string
    """
    updates = GameUpdate.GetUpdates(GAME_ID)
    search_text = 'Latest {} Update'.format(version_type.title())

    for update in updates:
    if search_text in update.Notes:
    log('Updating latest {} version to {}'.format(version_type, latest_version))
    update.WindowsFileName = "{}/get-jar/bedrock/{}/windows/{}".format(API_BASE_URL, version_type, latest_version)
    update.LinuxFileName = "{}/get-jar/bedrock/{}/linux/{}".format(API_BASE_URL, version_type, latest_version)
    update.Save()
    return

    log('No existing latest {} update found to update'.format(version_type))

    def process_versions(version_type):
    """
    Process versions for a given type (latest or preview)
    Args:
    version_type (str): 'latest' or 'preview'
    """
    log('Processing {} versions...'.format(version_type))

    # Get existing updates once at the beginning
    existing_updates = GameUpdate.GetUpdates(GAME_ID)
    log('Found {} existing updates in database'.format(len(existing_updates)))

    # Fetch all versions for this type
    all_versions = get_all_versions_for_type(version_type)

    if not all_versions:
    Script.WriteToConsole('No versions found for {}'.format(version_type))
    log('No versions found for {}'.format(version_type))
    return

    # Convert to sorted list (newest first)
    sorted_versions = sorted(list(all_versions), key=lambda x: [int(i) for i in x.split('.')], reverse=True)
    log('Found {} total versions for {}'.format(len(all_versions), version_type))

    # Sort versions (newest first)
    sorted_versions = sorted(
    list(all_versions),
    key=lambda x: [int(i) for i in x.split('.')],
    reverse=True
    )

    log('Processing {} sorted versions for {}...'.format(len(sorted_versions), version_type))

    # Set group name based on version type - ensure preview and latest are separate
    if version_type == 'latest':
    group_name = "Minecraft: Bedrock Edition Latest"
    elif version_type == 'preview':
    group_name = "Minecraft: Bedrock Edition Preview"
    else:
    group_name = "Minecraft: Bedrock Edition {}".format(version_type.title())
    # Determine group name
    group_name = "Minecraft: Bedrock Edition {}".format(
    "Latest" if version_type == 'latest' else "Preview"
    )

    # Process each version
    for version in sorted_versions:
    # Generate view order
    parts = version.split('.')
    # Ensure we have 4 parts for consistent ordering
    while len(parts) < 4:
    parts.append('0')
    for i in range(len(parts)):
    parts[i] = parts[i].zfill(3)
    view_order = -int(''.join(parts))

    # Skip if an update already exists with the same name
    skip = False
    update_name = "Bedrock Edition {} {}".format(version_type.title(), version)

    for gameUpdate in updates:
    if gameUpdate.Name == update_name:
    Script.WriteToConsole('Skipping version {}'.format(version))
    skip = True
    break

    if not skip:
    update = GameUpdate()
    update.Name = update_name
    update.Comments = ""
    update.ImageUrl = "https://media.hyperlayer.net/creeper-icon.png"
    update.GameId = gameID
    update.GroupName = group_name # This will properly separate preview and latest
    update.ExtractPath = "/"
    update.WindowsFileName = "https://mcjarfiles.com/api/get-jar/bedrock/{}/windows/{}".format(version_type, version)
    update.LinuxFileName = "https://mcjarfiles.com/api/get-jar/bedrock/{}/linux/{}".format(version_type, version)
    update.Reinstallable = True
    update.DefaultInstall = False
    update.UserAccess = True
    update.SubAdminAccess = True
    update.ResellerAccess = True
    update.ViewOrder = view_order
    update.GenerateKey()
    updates_created = 0
    updates_skipped = 0

    for i, version in enumerate(sorted_versions):
    log('Processing version {}/{}: {}'.format(i + 1, len(sorted_versions), version))

    if version_exists(existing_updates, version_type, version):
    log('Skipping version {} - already exists'.format(version))
    updates_skipped += 1
    continue

    try:
    # Create and save the update
    view_order = calculate_view_order(version)
    log('Creating update for version {} with view order {}'.format(version, view_order))

    update = create_game_update(version_type, version, group_name, view_order)
    update.Save()
    Script.WriteToConsole("Added update for Minecraft: Bedrock Edition {} v{}".format(version_type.title(), version))

    # Add custom scripts
    for script in scripts:
    updateScript = GameScript()
    updateScript.Description = script["Name"]
    updateScript.ScriptContents = script["Contents"]
    updateScript.ServiceEvent = script["Event"]
    updateScript.ExecuteAsServiceUser = False
    updateScript.ExecuteInPopup = False
    updateScript.ExecutionOrder = 0
    updateScript.GameId = gameID
    updateScript.IgnoreErrors = False
    updateScript.OperatingSystem = 0 # 0 = Any, 2 = Windows, 4 = Linux
    updateScript.PromptVariables = False
    updateScript.UserAccess = True
    updateScript.SubAdminAccess = True
    updateScript.ResellerAccess = True
    updateScript.ScriptEngineId = 1 # IronPython
    updateScript.UpdateId = update.UpdateId
    updateScript.GenerateKey()
    updateScript.Save()

    # Update the "Latest" update for this version type
    log("Added update for Minecraft: Bedrock Edition {} v{}".format(version_type.title(), version))
    updates_created += 1

    # Add custom scripts (now with duplicate checking)
    add_scripts_to_update(update)

    except Exception as e:
    log('Error creating update for version {}: {}'.format(version, str(e)))

    log('Summary for {}: Created {} new updates, skipped {} existing updates'.format(
    version_type, updates_created, updates_skipped))

    # Update the latest version reference
    if sorted_versions:
    latest_version = sorted_versions[0]
    updates = GameUpdate.GetUpdates(gameID) # Refresh the list

    for latestUpdate in updates:
    if 'Latest {} Update'.format(version_type.title()) in latestUpdate.Notes:
    Script.WriteToConsole('Updating latest {} version to {}'.format(version_type, latest_version))
    latestUpdate.WindowsFileName = "https://mcjarfiles.com/api/get-jar/bedrock/{}/windows/{}".format(version_type, latest_version)
    latestUpdate.LinuxFileName = "https://mcjarfiles.com/api/get-jar/bedrock/{}/linux/{}".format(version_type, latest_version)
    latestUpdate.Save()
    break

    # Process both latest and preview versions
    try:
    process_versions('latest')
    process_versions('preview')
    Script.WriteToConsole('Script execution completed.')
    except Exception as e:
    Script.WriteToConsole('General error: {}'.format(str(e)))
    log('Updating latest version reference...')
    update_latest_version(version_type, sorted_versions[0])

    def main():
    """Main execution function"""
    try:
    log('=' * 60)
    log('Starting Minecraft Bedrock Edition update script...')
    log('Game ID: {}'.format(GAME_ID))
    log('API Base URL: {}'.format(API_BASE_URL))
    log('=' * 60)

    # Process both version types
    log('Beginning processing of latest versions...')
    process_versions('latest')

    log('Beginning processing of preview versions...')
    process_versions('preview')

    log('=' * 60)
    log('Script execution completed successfully.')
    log('=' * 60)

    except Exception as e:
    log('=' * 60)
    log('CRITICAL ERROR during script execution: {}'.format(str(e)))
    log('=' * 60)
    raise

    # Execute main function
    if __name__ == '__main__':
    main()
    else:
    # If not running as main module, call main() directly for TCAdmin environment
    main()
  5. AdamG100 revised this gist Sep 9, 2025. 1 changed file with 133 additions and 88 deletions.
    221 changes: 133 additions & 88 deletions bedrock.py
    Original file line number Diff line number Diff line change
    @@ -1,102 +1,147 @@
    import re, urllib2, json
    import re, urllib.request, json
    import clr
    clr.AddReference('TCAdmin.GameHosting.SDK')
    from TCAdmin.GameHosting.SDK.Objects import GameUpdate, GameScript, ServiceEvent
    from TCAdmin.GameHosting.SDK.Objects import GameUpdate, GameScript, ServiceEvent

    gameID = 193
    scripts = [
    {
    "Name": "Backup server.properties",
    "Event": ServiceEvent.BeforeUpdateInstall,
    'Contents': "from os import path, rename, remove\nserverproperties = path.join(ThisService.RootDirectory, 'server.properties')\nif path.isfile(serverproperties):\n if path.isfile(serverproperties+'.backup'):\n remove(serverproperties+'.backup')\n rename(serverproperties, serverproperties+'.backup')"
    },
    {
    {
    "Name": "Backup server.properties",
    "Event": ServiceEvent.BeforeUpdateInstall,
    'Contents': "from os import path, rename, remove\nserverproperties = path.join(ThisService.RootDirectory, 'server.properties')\nif path.isfile(serverproperties):\n if path.isfile(serverproperties+'.backup'):\n remove(serverproperties+'.backup')\n rename(serverproperties, serverproperties+'.backup')"
    },
    {
    "Name": "Delete new server.properties, use old file instead",
    "Event": ServiceEvent.AfterUpdateInstall,
    "Event": ServiceEvent.AfterUpdateInstall,
    "Contents": "from os import path, rename, remove\nserverproperties = path.join(ThisService.RootDirectory, 'server.properties')\nif path.isfile(serverproperties):\n remove(serverproperties)\nrename(serverproperties+'.backup', serverproperties)"
    }
    ]
    }
    ]

    updates = GameUpdate.GetUpdates(gameID)

    # Fetch versions from your API
    try:
    versions_response = urllib2.urlopen('https://mcjarfiles.com/api/get-versions/bedrock/latest')
    versions_list = json.loads(versions_response.read())
    def process_versions(version_type):
    Script.WriteToConsole('Processing {} versions...'.format(version_type))

    # Get existing updates
    updates = GameUpdate.GetUpdates(gameID)

    if versions_list and isinstance(versions_list, list):
    for version in versions_list:
    #Generate view order
    parts = version.split('.')
    # Ensure we have 4 parts for consistent ordering
    while len(parts) < 4:
    parts.append('0')
    for i in range(len(parts)):
    parts[i] = parts[i].zfill(3)
    view_order = -int(''.join(parts))

    #Skip if an update already exists with the same name
    skip = False
    for gameUpdate in updates:
    if gameUpdate.Name == "Bedrock Edition " + version:
    Script.WriteToConsole('Skipping version {}'.format(version))
    skip = True
    break
    # Fetch versions for both Windows and Linux
    platforms = ['windows', 'linux']
    all_versions = set()

    for platform in platforms:
    try:
    url = 'https://mcjarfiles.com/api/get-versions/bedrock/{}/{}'.format(version_type, platform)
    Script.WriteToConsole('Fetching versions from: {}'.format(url))

    # Create request with user agent to avoid 403 errors
    req = urllib.request.Request(url)
    req.add_header('User-Agent', 'TCAdmin-Script/1.0')

    if not skip:
    update = GameUpdate()
    update.Name = "Bedrock Edition " + version
    update.Comments = ""
    update.ImageUrl = "https://media.hyperlayer.net/creeper-icon.png"
    update.GameId = gameID
    update.GroupName = "Minecraft: Bedrock Edition Latest"
    update.ExtractPath = "/"
    update.WindowsFileName = "https://mcjarfiles.com/api/get-jar/bedrock/latest/windows/{}".format(version)
    update.LinuxFileName = "https://mcjarfiles.com/api/get-jar/bedrock/latest/linux/{}".format(version)
    update.Reinstallable = True
    update.DefaultInstall = False
    update.UserAccess = True
    update.SubAdminAccess = True
    update.ResellerAccess = True
    update.ViewOrder = view_order
    update.GenerateKey()
    update.Save()
    Script.WriteToConsole("Added update for Minecraft: Bedrock Edition v{}".format(version))
    with urllib.request.urlopen(req) as response:
    versions_list = json.loads(response.read().decode('utf-8'))

    if versions_list and isinstance(versions_list, list):
    all_versions.update(versions_list)
    Script.WriteToConsole('Found {} versions for {} {}'.format(len(versions_list), version_type, platform))
    else:
    Script.WriteToConsole('No versions found for {} {}'.format(version_type, platform))

    #Add custom scripts
    for script in scripts:
    updateScript = GameScript()
    updateScript.Description = script["Name"]
    updateScript.ScriptContents = script["Contents"]
    updateScript.ServiceEvent = script["Event"]
    updateScript.ExecuteAsServiceUser = False
    updateScript.ExecuteInPopup = False
    updateScript.ExecutionOrder = 0
    updateScript.GameId = gameID
    updateScript.IgnoreErrors = False
    updateScript.OperatingSystem = 0 #0 = Any, 2 = Windows, 4 = Linux
    updateScript.PromptVariables = False
    updateScript.UserAccess = True
    updateScript.SubAdminAccess = True
    updateScript.ResellerAccess = True
    updateScript.ScriptEngineId = 1 #IronPython
    updateScript.UpdateId = update.UpdateId
    updateScript.GenerateKey()
    updateScript.Save()

    # Update the "Latest" update with the first version in the list (most recent)
    if len(versions_list) > 0:
    latest_version = versions_list[0]
    gameUpdates = set(updates)
    for latestUpdate in gameUpdates:
    if 'Latest Bedrock Update' in latestUpdate.Notes:
    Script.WriteToConsole('Changing the links for the latest Bedrock update to version {}'.format(latest_version))
    latestUpdate.WindowsFileName = "https://mcjarfiles.com/api/get-jar/bedrock/latest/windows/{}".format(latest_version)
    latestUpdate.LinuxFileName = "https://mcjarfiles.com/api/get-jar/bedrock/latest/linux/{}".format(latest_version)
    latestUpdate.Save()
    break
    except Exception as e:
    Script.WriteToConsole('Error fetching versions from API for {} {}: {}'.format(version_type, platform, str(e)))

    if not all_versions:
    Script.WriteToConsole('No versions found for {}'.format(version_type))
    return

    # Convert to sorted list (newest first)
    sorted_versions = sorted(list(all_versions), key=lambda x: [int(i) for i in x.split('.')], reverse=True)

    # Set group name based on version type - ensure preview and latest are separate
    if version_type == 'latest':
    group_name = "Minecraft: Bedrock Edition Latest"
    elif version_type == 'preview':
    group_name = "Minecraft: Bedrock Edition Preview"
    else:
    Script.WriteToConsole('No versions found in API response')
    group_name = "Minecraft: Bedrock Edition {}".format(version_type.title())

    # Process each version
    for version in sorted_versions:
    # Generate view order
    parts = version.split('.')
    # Ensure we have 4 parts for consistent ordering
    while len(parts) < 4:
    parts.append('0')
    for i in range(len(parts)):
    parts[i] = parts[i].zfill(3)
    view_order = -int(''.join(parts))

    # Skip if an update already exists with the same name
    skip = False
    update_name = "Bedrock Edition {} {}".format(version_type.title(), version)

    for gameUpdate in updates:
    if gameUpdate.Name == update_name:
    Script.WriteToConsole('Skipping version {}'.format(version))
    skip = True
    break

    if not skip:
    update = GameUpdate()
    update.Name = update_name
    update.Comments = ""
    update.ImageUrl = "https://media.hyperlayer.net/creeper-icon.png"
    update.GameId = gameID
    update.GroupName = group_name # This will properly separate preview and latest
    update.ExtractPath = "/"
    update.WindowsFileName = "https://mcjarfiles.com/api/get-jar/bedrock/{}/windows/{}".format(version_type, version)
    update.LinuxFileName = "https://mcjarfiles.com/api/get-jar/bedrock/{}/linux/{}".format(version_type, version)
    update.Reinstallable = True
    update.DefaultInstall = False
    update.UserAccess = True
    update.SubAdminAccess = True
    update.ResellerAccess = True
    update.ViewOrder = view_order
    update.GenerateKey()
    update.Save()
    Script.WriteToConsole("Added update for Minecraft: Bedrock Edition {} v{}".format(version_type.title(), version))

    # Add custom scripts
    for script in scripts:
    updateScript = GameScript()
    updateScript.Description = script["Name"]
    updateScript.ScriptContents = script["Contents"]
    updateScript.ServiceEvent = script["Event"]
    updateScript.ExecuteAsServiceUser = False
    updateScript.ExecuteInPopup = False
    updateScript.ExecutionOrder = 0
    updateScript.GameId = gameID
    updateScript.IgnoreErrors = False
    updateScript.OperatingSystem = 0 # 0 = Any, 2 = Windows, 4 = Linux
    updateScript.PromptVariables = False
    updateScript.UserAccess = True
    updateScript.SubAdminAccess = True
    updateScript.ResellerAccess = True
    updateScript.ScriptEngineId = 1 # IronPython
    updateScript.UpdateId = update.UpdateId
    updateScript.GenerateKey()
    updateScript.Save()

    # Update the "Latest" update for this version type
    if sorted_versions:
    latest_version = sorted_versions[0]
    updates = GameUpdate.GetUpdates(gameID) # Refresh the list

    for latestUpdate in updates:
    if 'Latest {} Update'.format(version_type.title()) in latestUpdate.Notes:
    Script.WriteToConsole('Updating latest {} version to {}'.format(version_type, latest_version))
    latestUpdate.WindowsFileName = "https://mcjarfiles.com/api/get-jar/bedrock/{}/windows/{}".format(version_type, latest_version)
    latestUpdate.LinuxFileName = "https://mcjarfiles.com/api/get-jar/bedrock/{}/linux/{}".format(version_type, latest_version)
    latestUpdate.Save()
    break

    # Process both latest and preview versions
    try:
    process_versions('latest')
    process_versions('preview')
    Script.WriteToConsole('Script execution completed.')
    except Exception as e:
    Script.WriteToConsole('Error fetching versions from API: {}'.format(str(e)))
    Script.WriteToConsole('General error: {}'.format(str(e)))
  6. AdamG100 revised this gist Aug 8, 2025. 1 changed file with 7 additions and 7 deletions.
    14 changes: 7 additions & 7 deletions bedrock.py
    Original file line number Diff line number Diff line change
    @@ -47,12 +47,12 @@
    update = GameUpdate()
    update.Name = "Bedrock Edition " + version
    update.Comments = ""
    update.ImageUrl = "https://www.minecraft.net/etc.clientlibs/minecraft/clientlibs/main/resources/img/header/logo.png"
    update.ImageUrl = "https://media.hyperlayer.net/creeper-icon.png"
    update.GameId = gameID
    update.GroupName = "Minecraft: Bedrock Edition"
    update.GroupName = "Minecraft: Bedrock Edition Latest"
    update.ExtractPath = "/"
    update.WindowsFileName = "https://mcjarfiles.com/api/get-jar/bedrock/latest/{}/windows".format(version)
    update.LinuxFileName = "https://mcjarfiles.com/api/get-jar/bedrock/latest/{}/linux".format(version)
    update.WindowsFileName = "https://mcjarfiles.com/api/get-jar/bedrock/latest/windows/{}".format(version)
    update.LinuxFileName = "https://mcjarfiles.com/api/get-jar/bedrock/latest/linux/{}".format(version)
    update.Reinstallable = True
    update.DefaultInstall = False
    update.UserAccess = True
    @@ -86,13 +86,13 @@

    # Update the "Latest" update with the first version in the list (most recent)
    if len(versions_list) > 0:
    latest_version = versions_list[0] # First item should be the latest
    latest_version = versions_list[0]
    gameUpdates = set(updates)
    for latestUpdate in gameUpdates:
    if 'Latest Bedrock Update' in latestUpdate.Notes:
    Script.WriteToConsole('Changing the links for the latest Bedrock update to version {}'.format(latest_version))
    latestUpdate.WindowsFileName = "https://mcjarfiles.com/api/get-jar/bedrock/latest/{}/windows".format(latest_version)
    latestUpdate.LinuxFileName = "https://mcjarfiles.com/api/get-jar/bedrock/latest/{}/linux".format(latest_version)
    latestUpdate.WindowsFileName = "https://mcjarfiles.com/api/get-jar/bedrock/latest/windows/{}".format(latest_version)
    latestUpdate.LinuxFileName = "https://mcjarfiles.com/api/get-jar/bedrock/latest/linux/{}".format(latest_version)
    latestUpdate.Save()
    break
    else:
  7. AdamG100 revised this gist Aug 8, 2025. 1 changed file with 80 additions and 67 deletions.
    147 changes: 80 additions & 67 deletions bedrock.py
    Original file line number Diff line number Diff line change
    @@ -18,72 +18,85 @@
    ]

    updates = GameUpdate.GetUpdates(gameID)
    version_page = urllib2.urlopen('https://minecraft.fandom.com/wiki/Bedrock_Dedicated_Server').read()
    regex_pattern = '<a target=\"_self\" rel=\"nofollow\" class=\"external text\" href=\"https:\/\/minecraft\.azureedge\.net\/bin-win(\-preview)?\/bedrock-server-(?<Version>.*)\.zip\">Windows<\/a>'
    matches = re.findall(regex_pattern, version_page)
    if matches.Count > 0:
    for version in matches:
    release = version[0] # '' or '-preview'
    version = version[1]
    #Generate view order
    parts = version.split('.')
    for i in range(4):
    parts[i] = parts[i].zfill(3)
    view_order=-int(''.join(parts))

    #Skip if an update already exists with the same name
    skip = False
    for gameUpdate in updates:
    if gameUpdate.Name == "Bedrock Edition "+version:
    Script.WriteToConsole('Skipping version {}'.format(version))
    skip = True

    # Fetch versions from your API
    try:
    versions_response = urllib2.urlopen('https://mcjarfiles.com/api/get-versions/bedrock/latest')
    versions_list = json.loads(versions_response.read())

    if not skip:
    update = GameUpdate()
    update.Name = "Bedrock Edition "+version
    update.Comments = ""
    update.ImageUrl = "https://www.minecraft.net/etc.clientlibs/minecraft/clientlibs/main/resources/img/header/logo.png"
    update.GameId = gameID
    update.GroupName = "Minecraft: Bedrock Edition" if release == '' else "Minecraft: Bedrock Edition Preview"
    update.ExtractPath = "/"
    update.WindowsFileName = "https://minecraft.azureedge.net/bin-win{}/bedrock-server-{}.zip".format(release, version)
    update.LinuxFileName = "https://minecraft.azureedge.net/bin-linux{}/bedrock-server-{}.zip".format(release, version)
    update.Reinstallable = True
    update.DefaultInstall = False
    update.UserAccess = True
    update.SubAdminAccess = True
    update.ResellerAccess = True
    update.ViewOrder = view_order
    update.GenerateKey()
    update.Save()
    Script.WriteToConsole("Added update for Minecraft: Bedrock Edition v{}".format(version))

    #Add custom scripts
    for script in scripts:
    updateScript = GameScript()
    updateScript.Description = script["Name"]
    updateScript.ScriptContents = script["Contents"]
    updateScript.ServiceEvent = script["Event"]
    updateScript.ExecuteAsServiceUser = False
    updateScript.ExecuteInPopup = False
    updateScript.ExecutionOrder = 0
    updateScript.GameId = gameID
    updateScript.IgnoreErrors = False
    updateScript.OperatingSystem = 0 #0 = Any, 2 = Windows, 4 = Linux
    updateScript.PromptVariables = False
    updateScript.UserAccess = True
    updateScript.SubAdminAccess = True
    updateScript.ResellerAccess = True
    updateScript.ScriptEngineId = 1 #IronPython
    updateScript.UpdateId = update.UpdateId
    updateScript.GenerateKey()
    updateScript.Save()
    if versions_list and isinstance(versions_list, list):
    for version in versions_list:
    #Generate view order
    parts = version.split('.')
    # Ensure we have 4 parts for consistent ordering
    while len(parts) < 4:
    parts.append('0')
    for i in range(len(parts)):
    parts[i] = parts[i].zfill(3)
    view_order = -int(''.join(parts))

    #Skip if an update already exists with the same name
    skip = False
    for gameUpdate in updates:
    if gameUpdate.Name == "Bedrock Edition " + version:
    Script.WriteToConsole('Skipping version {}'.format(version))
    skip = True
    break

    if not skip:
    update = GameUpdate()
    update.Name = "Bedrock Edition " + version
    update.Comments = ""
    update.ImageUrl = "https://www.minecraft.net/etc.clientlibs/minecraft/clientlibs/main/resources/img/header/logo.png"
    update.GameId = gameID
    update.GroupName = "Minecraft: Bedrock Edition"
    update.ExtractPath = "/"
    update.WindowsFileName = "https://mcjarfiles.com/api/get-jar/bedrock/latest/{}/windows".format(version)
    update.LinuxFileName = "https://mcjarfiles.com/api/get-jar/bedrock/latest/{}/linux".format(version)
    update.Reinstallable = True
    update.DefaultInstall = False
    update.UserAccess = True
    update.SubAdminAccess = True
    update.ResellerAccess = True
    update.ViewOrder = view_order
    update.GenerateKey()
    update.Save()
    Script.WriteToConsole("Added update for Minecraft: Bedrock Edition v{}".format(version))

    #Add custom scripts
    for script in scripts:
    updateScript = GameScript()
    updateScript.Description = script["Name"]
    updateScript.ScriptContents = script["Contents"]
    updateScript.ServiceEvent = script["Event"]
    updateScript.ExecuteAsServiceUser = False
    updateScript.ExecuteInPopup = False
    updateScript.ExecutionOrder = 0
    updateScript.GameId = gameID
    updateScript.IgnoreErrors = False
    updateScript.OperatingSystem = 0 #0 = Any, 2 = Windows, 4 = Linux
    updateScript.PromptVariables = False
    updateScript.UserAccess = True
    updateScript.SubAdminAccess = True
    updateScript.ResellerAccess = True
    updateScript.ScriptEngineId = 1 #IronPython
    updateScript.UpdateId = update.UpdateId
    updateScript.GenerateKey()
    updateScript.Save()

    #Change the links for the "Latest" update
    gameUpdates = set(updates)
    for update in gameUpdates:
    if 'Latest Bedrock Update' in update.Notes:
    Script.WriteToConsole('Changing the links for the latest Bedrock update')
    update.WindowsFileName = "https://minecraft.azureedge.net/bin-win/bedrock-server-{}.zip".format(version)
    update.LinuxFileName = "https://minecraft.azureedge.net/bin-linux/bedrock-server-{}.zip".format(version)
    update.Save()
    # Update the "Latest" update with the first version in the list (most recent)
    if len(versions_list) > 0:
    latest_version = versions_list[0] # First item should be the latest
    gameUpdates = set(updates)
    for latestUpdate in gameUpdates:
    if 'Latest Bedrock Update' in latestUpdate.Notes:
    Script.WriteToConsole('Changing the links for the latest Bedrock update to version {}'.format(latest_version))
    latestUpdate.WindowsFileName = "https://mcjarfiles.com/api/get-jar/bedrock/latest/{}/windows".format(latest_version)
    latestUpdate.LinuxFileName = "https://mcjarfiles.com/api/get-jar/bedrock/latest/{}/linux".format(latest_version)
    latestUpdate.Save()
    break
    else:
    Script.WriteToConsole('No versions found in API response')

    except Exception as e:
    Script.WriteToConsole('Error fetching versions from API: {}'.format(str(e)))
  8. AdamG100 created this gist Feb 22, 2024.
    89 changes: 89 additions & 0 deletions bedrock.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,89 @@
    import re, urllib2, json
    import clr
    clr.AddReference('TCAdmin.GameHosting.SDK')
    from TCAdmin.GameHosting.SDK.Objects import GameUpdate, GameScript, ServiceEvent

    gameID = 193
    scripts = [
    {
    "Name": "Backup server.properties",
    "Event": ServiceEvent.BeforeUpdateInstall,
    'Contents': "from os import path, rename, remove\nserverproperties = path.join(ThisService.RootDirectory, 'server.properties')\nif path.isfile(serverproperties):\n if path.isfile(serverproperties+'.backup'):\n remove(serverproperties+'.backup')\n rename(serverproperties, serverproperties+'.backup')"
    },
    {
    "Name": "Delete new server.properties, use old file instead",
    "Event": ServiceEvent.AfterUpdateInstall,
    "Contents": "from os import path, rename, remove\nserverproperties = path.join(ThisService.RootDirectory, 'server.properties')\nif path.isfile(serverproperties):\n remove(serverproperties)\nrename(serverproperties+'.backup', serverproperties)"
    }
    ]

    updates = GameUpdate.GetUpdates(gameID)
    version_page = urllib2.urlopen('https://minecraft.fandom.com/wiki/Bedrock_Dedicated_Server').read()
    regex_pattern = '<a target=\"_self\" rel=\"nofollow\" class=\"external text\" href=\"https:\/\/minecraft\.azureedge\.net\/bin-win(\-preview)?\/bedrock-server-(?<Version>.*)\.zip\">Windows<\/a>'
    matches = re.findall(regex_pattern, version_page)
    if matches.Count > 0:
    for version in matches:
    release = version[0] # '' or '-preview'
    version = version[1]
    #Generate view order
    parts = version.split('.')
    for i in range(4):
    parts[i] = parts[i].zfill(3)
    view_order=-int(''.join(parts))

    #Skip if an update already exists with the same name
    skip = False
    for gameUpdate in updates:
    if gameUpdate.Name == "Bedrock Edition "+version:
    Script.WriteToConsole('Skipping version {}'.format(version))
    skip = True

    if not skip:
    update = GameUpdate()
    update.Name = "Bedrock Edition "+version
    update.Comments = ""
    update.ImageUrl = "https://www.minecraft.net/etc.clientlibs/minecraft/clientlibs/main/resources/img/header/logo.png"
    update.GameId = gameID
    update.GroupName = "Minecraft: Bedrock Edition" if release == '' else "Minecraft: Bedrock Edition Preview"
    update.ExtractPath = "/"
    update.WindowsFileName = "https://minecraft.azureedge.net/bin-win{}/bedrock-server-{}.zip".format(release, version)
    update.LinuxFileName = "https://minecraft.azureedge.net/bin-linux{}/bedrock-server-{}.zip".format(release, version)
    update.Reinstallable = True
    update.DefaultInstall = False
    update.UserAccess = True
    update.SubAdminAccess = True
    update.ResellerAccess = True
    update.ViewOrder = view_order
    update.GenerateKey()
    update.Save()
    Script.WriteToConsole("Added update for Minecraft: Bedrock Edition v{}".format(version))

    #Add custom scripts
    for script in scripts:
    updateScript = GameScript()
    updateScript.Description = script["Name"]
    updateScript.ScriptContents = script["Contents"]
    updateScript.ServiceEvent = script["Event"]
    updateScript.ExecuteAsServiceUser = False
    updateScript.ExecuteInPopup = False
    updateScript.ExecutionOrder = 0
    updateScript.GameId = gameID
    updateScript.IgnoreErrors = False
    updateScript.OperatingSystem = 0 #0 = Any, 2 = Windows, 4 = Linux
    updateScript.PromptVariables = False
    updateScript.UserAccess = True
    updateScript.SubAdminAccess = True
    updateScript.ResellerAccess = True
    updateScript.ScriptEngineId = 1 #IronPython
    updateScript.UpdateId = update.UpdateId
    updateScript.GenerateKey()
    updateScript.Save()

    #Change the links for the "Latest" update
    gameUpdates = set(updates)
    for update in gameUpdates:
    if 'Latest Bedrock Update' in update.Notes:
    Script.WriteToConsole('Changing the links for the latest Bedrock update')
    update.WindowsFileName = "https://minecraft.azureedge.net/bin-win/bedrock-server-{}.zip".format(version)
    update.LinuxFileName = "https://minecraft.azureedge.net/bin-linux/bedrock-server-{}.zip".format(version)
    update.Save()