Can you use Python to notify you when FF14 servers are uncongested?

0

In the recently history I wanted to give Final Fantasy 14 another try since you can pay to skip the first chapter which most players find incredibly boring. Featuring tasks such as, Delivering eggs to guards, Delivering eggs to monranguin, And delivering a sword to galfrid.

With that in mind, currently the server my wife is on is “congested” which means there are too many active players which causes queue times when trying to get on the game. To mitigate this they block new player registrations on that server to encourage other servers being used. The issue with using another server is I have to pay 20 bucks to transfer over. and I plan to join this with a friend, which means 40 dollars to transfer. That’s not a massive amount of money, but it feels wasteful if I have to use it anytime soon. So plan B, get notified when the server is uncongested so I can hop on once it’s open.

Action Plan

I want to create a script that scrapes the server status webpage and send me a notification when the server is open.

The world status can be found here. https://na.finalfantasyxiv.com/lodestone/worldstatus/

With this page I should easily be able to tell if a server is congested without launching the game which would add a ton of overhead to checking the server.

The Script

from bs4 import BeautifulSoup
import requests
from datetime import datetime
import time
#This is to send an email
import smtplib
HasNotificationBeenSent = False

#This function accepts a target email and congestion status to send an email
def EmailNotification(TargetEmail, IsCongested):
    # Email credentials
    username = "MyEmail@email.com"
    password = "MyPassword"

    #Get Current time
    now = datetime.now()

    # Email recipient
    recipient = TargetEmail

    # Email message
    if IsCongested == False:
        message = "Server 'Goblin' is no longer congested | " + now.strftime("%H:%M")
    else:
        message = "Server 'Goblin' is congested again | " + now.strftime("%H:%M")

    # Create a new SMTP server object
    server = smtplib.SMTP("smtp.Myemail.com", 465, timeout=15)

    # Start the server's TLS encryption
    server.starttls()

    # Login to the server
    server.login(username, password)

    # Send the email
    server.sendmail(username, recipient, message)

    # Close the server
    server.quit()

#This function is to stop spaming Emails. It will only send 1 email per state change of the server
def NotificationTracker(isCongested):
    global HasNotificationBeenSent
    if HasNotificationBeenSent is False and isCongested is False:
        print("Server not busy notification sent")
        HasNotificationBeenSent = True
        EmailNotification("EmailToNotify@email.com", False)
    elif HasNotificationBeenSent is True and isCongested is True:
        print("busy notification sent")
        HasNotificationBeenSent = False
        EmailNotification("EmailToNotify@email.com", True)
        
        
#This loop is 99% of the logic
while True:    
    # Get the current time
    now = datetime.now()

    # Print the current time
    #print("Current time:", now.strftime("%H:%M:%S"))

    # URL of the website to scrape
    url = "https://na.finalfantasyxiv.com/lodestone/worldstatus/"

    # Send a GET request to the website and retrieve the HTML content
    response = requests.get(url)
    html = response.text

    # Use BeautifulSoup to parse the HTML
    soup = BeautifulSoup(html, 'html.parser')

    # Find the specific element you want In this case we are looking for the Diabolos server
    element = soup.find("p", text="Diabolos")

    # Find the next divider after the specific element
    next_div = element.find_next("div")

    # Find the specific p element within the divider
    p_element = next_div.find("p")

    # Extract the value from the p element. This is "Standard" or "Congested"
    value = p_element.text



    #Call Email Notification
    isCongested = value == "Congested"
    NotificationTracker(isCongested)

    #This prints the current time to the console
    FormattedOutput = now.strftime("%H:%M")+ "|"+ value
    print(FormattedOutput)

    # Append the log to a text file for diagnosis if needed
    with open("Log.txt", "a") as file:
        file.write(FormattedOutput + "\n")

    #wait for one minute
    time.sleep(60)

Issues

  • I’ve found that gmail has begun blocking the smtplib library to send emails, and the alternative was going to be protonmail until they mentioned they wouldn’t offer smtp functionality without a subscription. Because of this I decided to use my own websites hosting email to send emails with it. Plus it looks a little more elegant to have the email coming from icefire555.com.
  • I was worried the website would use bot protection to lock down rapid attempts to scrape the website. As most websites will for DDOS or bot protection. But after running the script once a minute for 24 hours. I can safely assume this is not the case.

    Conclusion

    This solution seems to be working fairly well. My only gripe with it is that it’s not in a docker container so I could run it directly on my server more easily. Currently being Python it’s running under a VM which means unnecessary overhead and the chance windows update will knock down the strip without me knowing.

    About Author

    Leave a Reply

    Your email address will not be published. Required fields are marked *