Ejemplo n.º 1
0
def json_decode(json_data, debug=False):
    try:
        if(not json_data): raise BadStatusLine;
        json_data = str(json_data).strip();
        if(debug): print json_data;
        elif(is_JSON(json_data)): return eval(json_data);
        else: return json_data;
    
    except(Exception, BadStatusLine):
        Display.errorMsg("Bad json_data received"+('' if not debug else ' ('+str(debug)+')')+". Unable to continue.");
        Display.errorMsg(">>", str(json_data));
        MAR_exit(1);
Ejemplo n.º 2
0
 def requestKey(self, params=None):
     try:
         if params: self.params = params;
         else: self.params = {"nec":1, "python":1};
         response = self.request();
         
         if response != False:
             return response.partition("@");
         else: return False;
     except:
         Display.errorMsg('There was an error while attempting to process your request.');
         return False;
Ejemplo n.º 3
0
 def connect(self):
     try:
         if len(self.baseSite) < 4:
             self._stopSpin();
             if self._silent == False: Display.errorMsg("Invalid connection parameters specified. Check your source code.");
             return False;
         else:
             self._connObject = httplib.HTTPConnection(self.baseSite, timeout=self._timeout);
             self._stopSpin();
             return True;
     except:
         self._stopSpin();
         return False;
Ejemplo n.º 4
0
def block_on_challenge(ignore_response, params, at_end=1, stall_time=60, debug=False, eval_response=True):
    global conn1, heartbeat;
    if(not conn1 or not heartbeat): MAR_exit(2);
    xtime = 0;
    
    # Give them 60 seconds
    while(xtime < stall_time):
        if(xtime == (stall_time-30)): Display.sysMsg('30 seconds remaining...');
        elif(xtime == (stall_time-10)): Display.sysMsg('10 seconds remaining...');

        sleeptime = time.clock();
        
        if(xtime % 5 == 0):
            # Setup our internal environment
            conn1.params = params;
            conn1.makeNulls = True;
            response = conn1.request();
            # print 'tempresp -> ', response
            
            if(response and response != ignore_response):
                if(eval_response): response = json_decode(response, debug);
                conn1.makeNulls = False;
                return response;
            
        sleeptime = 1 - (time.clock() - sleeptime);
        if(sleeptime > 0): time.sleep(sleeptime);
        xtime = xtime + 1;
        
    # We timed-out!
    else:
        if(at_end == 1):
            Display.evnMsg('Request TIMED OUT. Destroying room...');
            conn1.params = {"u":u, "p":p, "python":1, "type":"kil", "SID":SID};
            response = conn1.request();
            Display.sysMsg('Room Destroyed!');
            heartbeat.pauseFlag = False;
            conn1.makeNulls = False;
        return False;
Ejemplo n.º 5
0
import sys, threading, os, time;
from DisplayInterface import Display;

class Autodeath(threading.Thread):
    """ Die after x seconds """
    
    def __init__(self):
        # Clear the timer
        self.countdown = time.clock();
        
        threading.Thread.__init__(self, None, None, "Autodeath Thread");
        self.daemon = True;
        self.start();

    def run(self):
        self.countdown = time.clock();
        while(self.countdown + 30 > time.clock()):
            time.sleep(1);
        os._exit(1);

challenger = sys.argv[1];
if(challenger and 0 < len(challenger) <= 25):
    death = Autodeath();
    Display.sysMsg(('----- MAR Battle Request Warning! -----').center(53));
    Display.sysMsg(time.strftime("%m/%d/%Y @ [%I:%M:%S]").center(51),"\n\n\n");
    Display.evnMsg("You have a pending battle request from " +challenger+"!");
    Display.evnMsg("Type 'Challenge' and then '"+challenger+"'");
    Display.evnMsg("in the main window to accept or do nothing to decline.\n");
    Display.sysMsg('This window will automatically close in 30 seconds.');
    Display.cooked_input('  Press "Enter" to immediately close this window.', True);
Ejemplo n.º 6
0
 def request(self, method="POST"):
     if not self.connect(): self.connect();
     try:
         self._totalRetries = self._retries;
         if  self._connObject:
             while self._retries > 0:
                 self._connObject.request(method, self.target, urllib.urlencode(self.params), self.headers);
                 response = self._connObject.getresponse();
                 
                 self._stopSpin();
                 
                 if not self._failThrough:
                     if response.status == 200:
                         response = response.read().strip();
                         self.close();
                         
                         if response == "MAINTENANCE_MODE":
                             # Server is down for repairs!
                             if self._silent == False: Display.errorMsg("The server is down for maintenance at the moment.");
                             if self._silent == False: Display.errorMsg("Please try again in an hour or so.");
                             sys.exit(1);
                             response = False;
                         if self.makeNulls:
                             response = response.replace("null", "None");
                         return str(response) if response else False;
                     else:
                         if self._silent == False:
                             if self._silent == False: Display.errorMsg("Unable to connect to the server (" + str(response.status) + " " + str(response.reason) + ")!");
                             self._retries = self._retries - 1;
                             if self._retries > 0 and self._silent == False: Display.errorMsg("Re-attempting command (" + str(self._totalRetries-self._retries) + ").");
                             elif self._silent == False: Display.errorMsg("Please attempt to connect again.");
                             return False;
                 else: return response;
         else:
             self._stopSpin();
             if self._silent == False:
                 Display.errorMsg("Error: unable to complete request.\nThe connection object was not initialized correctly.");
                 sys.exit(1);
     except socket.gaierror:
         self._stopSpin();
         self.close();
         if self._silent == False: Display.errorMsg("Unable to connect!\nPlease check your internet connection and try again.");
         return False;
     except httplib.BadStatusLine:
         self.close();
         # raise httplib.BadStatusLine("BadStatusLine");
         Display.errorMsg("Error: Bad Statusline.");
         return False;
     except:
         self.close();
         self._stopSpin();
         return False;
Ejemplo n.º 7
0
 def status(self):
     self._stopSpin();
     if self._silent == False: Display.sysMsg("NetworkInterface module mounted successfully");
Ejemplo n.º 8
0
def MAR_exit(status=0):
    if(status == 0): Display.gameMsg('Program Terminated.');
    else: Display.errorMsg('Program Terminated Unexpectedly ('+str(status)+')!');
    Display.evnMsg('(C) Copyright 2010 - Dark Gray. All Rights Reserved.');
    Display.pause();
    os._exit(status);
Ejemplo n.º 9
0
def checkForCommands(response, actionQueue, opponent):
    global conn1;
    doBreak = False;
    
    if(response == '$Skipped:'+actionQueue['username']):
        conn1.params = {"u":u, "p":p, "python":1, "type":"upd", "SID":SID, 'data':'$ClearGameData'};
        conn1.request();
        Display.errorMsg('Temporarily desynched from the server. Your actions were discarded.');
    elif(response == '$Skipped:'+opponent):
        Display.errorMsg('Your opponent has desynched from the server. You have been declared winner.');
        doBreak = True;
        actionQueue['userdata']['victory'] = True;
        finalEvaluation(actionQueue, opponent);
    elif(response == '$Updated'): Display.gameMsg("Synchronization complete.");
    elif(response == '$Win:'+opponent):
        actionQueue['userdata']['victory'] = False;
        finalEvaluation(actionQueue, opponent);
        doBreak = True;
    elif(response == '$Win:'+actionQueue['username']):
        actionQueue['userdata']['victory'] = True;
        finalEvaluation(actionQueue, opponent);
        doBreak = True;
    else:
        if(response == '$Alive:'+opponent or response == '$Yes' or response == '$Skipped:'+opponent):
            conn1.params = {"u":u, "p":p, "python":1, "type":"upd", "SID":SID, 'data':'$Die'};
            conn1.request();
            Display.errorMsg('Due to your opponent\'s excessive lag, the game has been canceled.');
            
        elif(response == '$Alive:'+actionQueue['username']):
            conn1.params = {"u":u, "p":p, "python":1, "type":"upd", "SID":SID, 'data':'$Die'};
            conn1.request();
            Display.errorMsg('Due to your excessive lag, the game has been canceled.');
            
        elif(response == '$Die'):
            Display.errorMsg('The game has been canceled unexpectedly. Probably due to lag.');
            
        else:
            Display.errorMsg('Bad response from server. Game Over.');
            Display.errorMsg('>>', response);
            
        actionQueue['userdata']['victory'] = -1;
        doBreak = True;
    return (actionQueue, doBreak);
Ejemplo n.º 10
0
def MAR_battle(opponent, first):
    print '';
    global conn1, heartbeat, loggedIn, userdict, userpowers, ascii_uppercase;
    if(not conn1 or not loggedIn or not heartbeat or not userdict or not userpowers or not ascii_uppercase): MAR_exit(3);

    # Letters need re-reversing for some reason. Bad python scoping system is bad and horrible.
    # ascii_uppercase = ascii_uppercase[::-1];
    
    # Finish setting up our environment
    actionQueue = {'username':userdict['username'], 'specialdata':{},
                   'userdata':{
                       'guess':None,
                       'miniTurns':0,
                       'remainingTurns':27,
                       'maxTurns':28,
                       'letterNum':1,
                       'answer':None,
                       'answerStatus1':None,
                       'answerStatus2':None,
                       'skipped': False,
                       'victory': False
                   }};

    # Structure the user's powers into a workable menu object
    powerStructure = [('guess', -1), ('skip', -2)];
    for power in userpowers.keys(): powerStructure.insert(0, (str(power).lower(), str(power)));
    powerStructure = OrderedDict(powerStructure);

    # Begin the game
    while(actionQueue['userdata']['remainingTurns'] > 0 and not actionQueue['userdata']['victory']):
        if(actionQueue['userdata']['letterNum'] <= 4 and not actionQueue['userdata']['victory']):
            # We're up!
            if(first):
                if(not actionQueue['userdata']['skipped']):
                    # Set up our environment
                    if(actionQueue['userdata']['answer'] == None):
                        actionQueue['userdata']['answer'] = ascii_uppercase[randint(0, 25)];
                        Display.gameMsg('--> For you, this is letter '+str(actionQueue['userdata']['letterNum'])+' of 4.');
                    Display.gameMsg('[To use your specials, type the special\'s name and press "enter."]');
                    Display.gameMsg('[To guess, type "guess" followed by your letter guess.]');
                    Display.gameMsg('[To skip your turn, type "skip."]');
                    Display.gameMsg('[You have 60 seconds until your turn is automatically skipped]');
                    
                    # Prompt for selection of powers or guess (60 second time limit)
                    sleeptime = time.clock();
                    i = Display.menu(powerStructure, initMsg='Your move:', prefix='- ', time_limit=60, limit_phrase='skip');

                    # User wants to guess normally
                    if(i == -1):
                        if(actionQueue['userdata']['guess'] != None and actionQueue['userdata']['answerStatus2'] != ''): Display.gameMsg('-> You previous guess was:', actionQueue['userdata']['guess'], '('+actionQueue['userdata']['answerStatus2'][:-1].lower()+')');
                        actionQueue['userdata']['guess'] = Display.timed_input('> Guess a letter, '+actionQueue['username']+': ', 'skip', 60 - (time.clock() - sleeptime));
                        if(actionQueue['userdata']['guess'] == 'skip'): actionQueue['userdata']['skipped'] = True;
                        elif(actionQueue['userdata']['guess'] in ascii_letters):
                            if(actionQueue['userdata']['guess'].upper() == actionQueue['userdata']['answer']):
                                actionQueue['userdata']['miniTurns'] = actionQueue['userdata']['miniTurns'] + 1;
                                Display.gameMsg("You've guessed correctly! (Total", actionQueue['userdata']['miniTurns'], "turns)");
                                actionQueue['userdata']['letterNum'] = actionQueue['userdata']['letterNum'] + 1;
                                if(actionQueue['userdata']['letterNum'] <= 4 and not actionQueue['userdata']['victory']):
                                    MessageBeep(beep); time.sleep(0.1); MessageBeep(beep);
                                    actionQueue['userdata']['answerStatus1'] = actionQueue['username']+" guessed correctly and is onto the next letter! (Letter "+str(actionQueue['userdata']['letterNum'])+" of 4)";
                                    actionQueue['userdata']['answerStatus2'] = '';
                                    actionQueue['userdata']['miniTurns'] = 0;
                                    actionQueue['userdata']['answer'] = None;
                                else:
                                    actionQueue['userdata']['victory'] = True;
                                    finalEvaluation(actionQueue, opponent);
                                    break;
                            else:
                                dist = distanceAlgorithm(ascii_uppercase, actionQueue['userdata']['guess'].upper(), actionQueue['userdata']['answer'], 4.0, 40);
                                actionQueue['userdata']['answerStatus1'] = actionQueue['username']+' guessed incorrectly!';
                                actionQueue['userdata']['answerStatus2'] = "Guess was "+dist;
                                print Display.errorWrapper() + "Incorrect! Your guess was", dist;
                        else:
                            Display.errorMsg("That's not a letter,", actionQueue['username']+". You've lost two turns for that!");
                            actionQueue['userdata']['answerStatus1'] = actionQueue['username']+' entered an invalid response and was penalized!\n  What a fool!';
                            actionQueue['userdata']['answerStatus2'] = 'Guess was invalid.';
                            actionQueue['userdata']['remainingTurns'] = actionQueue['userdata']['remainingTurns'] - 2;
                            actionQueue['userdata']['miniTurns'] = actionQueue['userdata']['miniTurns'] + 1;
                    
                    # User wants to skip their turn
                    elif(i == -2):
                        actionQueue['userdata']['skipped'] = True;
                        actionQueue['userdata']['guess'] = actionQueue['userdata']['answerStatus1'] = None;
                        actionQueue['userdata']['answerStatus2'] = '';
                        actionQueue['userdata']['miniTurns'] = actionQueue['userdata']['miniTurns'] + 1;

                    # A power was chosen, attempt to add it to the specialdata array
                    else:
                        Display.errorMsg('Specials don\'t work yet. Sorry!');
                        actionQueue['userdata']['skipped'] = True;
                        actionQueue['userdata']['guess'] = actionQueue['userdata']['answerStatus1'] = None;
                        actionQueue['userdata']['answerStatus2'] = '';
                        actionQueue['userdata']['miniTurns'] = actionQueue['userdata']['miniTurns'] + 1;
                        # actionQueue['specialdata'] = activatePower(userpowers[i], actionQueue['specialdata']);

                # Evaluate specialdata array & victory conditions
                actionQueue = evaluateQueue(actionQueue);
                Display.gameMsg('Turn ended!');
                Display.gameMsg("You have", (actionQueue['userdata']['remainingTurns'] if actionQueue['userdata']['remainingTurns'] > 0 else 'no'), "turns remaining.");
                Display.gameMsg("Synchronizing with server...");
                conn1.params = {"u":u, "p":p, "python":1, "type":"upd", "SID":SID, 'data':actionQueue};
                response = conn1.request();
                # print 'resp:', response

                if(response == '$UpdateFailed'): Display.errorMsg('Internal Error: server failed to update properly! Report this!');
                if(response == '$LookupError'): Display.errorMsg('Internal Error: server-user lookup error! Report this!');
                else:
                    actionQueue, doBreak = checkForCommands(response, actionQueue, opponent);
                    if(doBreak): break;
                
                actionQueue['userdata']['remainingTurns'] = actionQueue['userdata']['remainingTurns'] - 1;
                actionQueue['userdata']['miniTurns'] = actionQueue['userdata']['miniTurns'] + 1;
                actionQueue['userdata']['skipped'] = False;
                
            # They're up! (wait for 60[+10] seconds)
            else:
                Display.gameMsg('Waiting on', opponent+' (~60 seconds until timeout)...');
                response = block_on_challenge('$NoData', {"u":u, "p":p, "python":1, "type":"bat4", "SID":SID, 'opponent':opponent}, at_end=0, stall_time=70);
                
                if(is_JSON(response)):
                    if(response['userdata']['victory'] or response['userdata']['letterNum'] > 4):
                        print 'incorrect loss action:', response
                        actionQueue['userdata']['victory'] = False;
                        finalEvaluation(actionQueue, opponent);
                        break;
                    else:
                        if(response['userdata']['answerStatus1']):
                            if(response['userdata']['answerStatus1'].find('guessed correctly and is onto')+1): MessageBeep(MB_OK); time.sleep(0.1); MessageBeep(MB_OK);
                            Display.gameMsg('->', response['userdata']['answerStatus1']);
                        else: Display.gameMsg('->', opponent, 'skipped his turn?! Foolish!');
                        evaluateQueue(response, False);
                        Display.sysMsg('Opponent\'s turn ended. Your move!');
                elif(response == False):
                    # Send the "is alive ne?" packet
                    Display.gameMsg('No response from opponent, clearing victory conditions...');
                    conn1.params = {"u":u, "p":p, "python":1, "type":"upd", "SID":SID, 'data':'$Alive:'+opponent};
                    conn1.request();
                    response = block_on_challenge('$NoData', {"u":u, "p":p, "python":1, "type":"bat4", "SID":SID, 'opponent':opponent, "ignore":'$Alive:'+opponent}, at_end=0, stall_time=10, eval_response=False);
                    
                    if(response == '$Yes'):
                        Display.gameMsg('Opponent\'s turn was skipped.');
                        conn1.params = {"u":u, "p":p, "python":1, "type":"upd", "SID":SID, 'data':'$Skip:'+actionQueue['username']};
                        conn1.request();
                        time.sleep(3);

                    elif(response == False or response[0] == '{'):
                        Display.gameMsg('Opponent has disconnected from the server. You win by default.');
                        actionQueue['userdata']['victory'] = True;
                        finalEvaluation(actionQueue, opponent);
                        break;

                    else:   
                        actionQueue, doBreak = checkForCommands(response, actionQueue, opponent);
                        if(doBreak): break;
                else:   
                    actionQueue, doBreak = checkForCommands(response, actionQueue, opponent);
                    if(doBreak): break;

            #Change up the order
            first = not first;
            
        else:
            actionQueue['userdata']['victory'] = True;
            finalEvaluation(actionQueue, opponent);
            break;
    else:
        if(not actionQueue['userdata']['victory']): finalEvaluation(actionQueue, opponent);

    Display.sysMsg('Cleaning up room...');
    conn1.params = {"u":u, "p":p, "python":1, "type":"kil", "SID":SID};
    conn1.request();
    Display.sysMsg('Room cleaned successfully.');
    Display.gameMsg('Returning to main menu...');
    heartbeat.pauseFlag = False;
    conn1.makeNulls = False;
Ejemplo n.º 11
0
def finalEvaluation(data, opponent):
    # print data;
    if(data['userdata']['victory'] != -1):
        if(data['userdata']['victory'] == True):
            MessageBeep(beep); time.sleep(0.1); MessageBeep(beep); time.sleep(0.1); MessageBeep(beep);
            conn1.params = {"u":u, "p":p, "python":1, "type":"upd", "SID":SID, 'data':'$Win:'+data['username']};
            conn1.request();
            xp = str(int(floor(data['userdata']['remainingTurns'] / 4)));
            data2 = xp+',0,1';
            Display.playerMsg('Good job,', data['username']+'!');
            Display.gameMsg("You've defeated", opponent, 'in', (data['userdata']['maxTurns'] - data['userdata']['remainingTurns']), 'turns.');
            Display.gameMsg("You've earned", xp, 'SP point(s)!');
            
        elif(data['userdata']['victory'] == False):
            MessageBeep(MB_OK); time.sleep(0.1); MessageBeep(MB_OK); time.sleep(0.1); MessageBeep(MB_OK);
            conn1.params = {"u":u, "p":p, "python":1, "type":"upd", "SID":SID, 'data':'$Win:'+opponent};
            conn1.request();
            data2 = '1,1,0';
            Display.errorMsg("You failed", data['username']+".");
            Display.errorMsg("You've lost to", opponent+".");
            Display.errorMsg("The correct answer was " + data['userdata']['answer'] + ".");
            Display.gameMsg("You've received 1 SP point.");

        conn1.params = {"u":u, "p":p, "python":1, "type":"psh", "SID":SID, 'data':data2};
        response = conn1.request();
        if(response != False):
            if(response[0:7] == 'Leveled'): Display.gameMsg('-+-+-+-+ Congratulations! You are now level '+response[8:]+' +-+-+-+-');
            elif(response == 'Updated'): Display.gameMsg('Server updated successfully.');
            else: Display.errorMsg('Server update failed! ('+str(response)+')');
        else: Display.errorMsg('Server update failed! (could not establish connection)');
        Display.errorMsg('Game Over.');
Ejemplo n.º 12
0
from DisplayInterface import Display;
from Challenger import Challenger;
from winsound import MessageBeep, MB_OK, MB_ICONASTERISK as beep;

# Establish our connection object
conn1 = NetworkInterface();
conn1.baseSite = "dignityice.com";
conn1.target = "/dg/Xunnamius/house2/pyGameInterface.php";

# Set up our environment
loggedIn = False;
time.clock(); # Clear the timer

# Sound-off!
# No color support in this version for now, so the Display.*Msg distinctions are only code-deep
Display.sysMsg('DO NOT RUN THIS PROGRAM IN THE PYTHON INTERACTIVE CONSOLE (IDLE)! DO NOT!\n\n');
Display.sysMsg('Mini-MAR BETA version', __version__);
conn1.status();
Display.sysMsg('Bernard Dickens - Project II -', __author__);

# Exit MAR
def MAR_exit(status=0):
    if(status == 0): Display.gameMsg('Program Terminated.');
    else: Display.errorMsg('Program Terminated Unexpectedly ('+str(status)+')!');
    Display.evnMsg('(C) Copyright 2010 - Dark Gray. All Rights Reserved.');
    Display.pause();
    os._exit(status);

# Is this JSON-like data?
def is_JSON(data):
    data = str(data).strip();
Ejemplo n.º 13
0
def login():
    global loggedIn, SID;
    if(loggedIn): return 2;

    # We're attempting to log someone in
    u = Display.cooked_input("> Username: "******"> Password:"******"\n  Conversing with server...");

    if(u not in ['Xunnamius']):
        Display.sysMsg("Invalid username/permissions.");
        return False;

    # Package the new data
    conn1.params = {"u":u, "python":1, "type":"", "SID":SID};

    # 1. Split the key in half
    # 2. Place chunks at both the front and the end (double salt)
    # 3. SHA-1 the whole thing again
    eKeyPiece1 = KEY[0:20];
    eKeyPiece2 = KEY[20:40];
    p = str(hashlib.sha1(eKeyPiece1 + hashlib.sha1(hashlib.md5(p).hexdigest()).hexdigest() + eKeyPiece2).hexdigest());
    u = str(hashlib.sha1(eKeyPiece1 + u + eKeyPiece2).hexdigest());
    conn1.params["u"] = u;
    conn1.params["p"] = p;
    conn1.params["type"] = "lin";

    # Authenticate the user's information
    response = conn1.request();
    
    # Alert the user of the result, and display the proper options accordingly
    if response != False:
        if response == "Approved":
            Display.playerMsg("Login Successful.");
            Display.sysMsg('Loading...');
            loggedIn = True;
            return loggedIn;
                
        elif response == "Denied":
            Display.errorMsg("Invalid username/password combination.");
            Display.errorMsg("Remember your username/password is case sensitive!");
            
        elif response == "Malformed":
            Display.errorMsg("You have illegal characters in your username/password.");
            Display.errorMsg("(Usernames are only allowed letters and numbers!)");
            Display.errorMsg("Contact Dark Gray for assistance or create a new account.");
            
        else:
            if(not response): Display.errorMsg("Connection to server was dropped. Please try again.");
            else:
                Display.errorMsg("Error. The response received from server was unrecognizable.");
                Display.errorMsg(">>", response);
                
    else: Display.errorMsg("Connection to server was dropped. Please try again.");
    return False;
Ejemplo n.º 14
0
from collections import OrderedDict;
from NetworkInterface import NetworkInterface;
from DisplayInterface import Display;

# Establish our connection object
conn1 = NetworkInterface();
conn1.baseSite = "dignityice.com";
conn1.target = "/dg/Xunnamius/house2/pyGameInterface.php";

# Set up our environment
usedSpecials = [];
loggedIn = False;
time.clock(); # Clear the timer

# Sound-off!
Display.sysMsg('Mini-MAR BETA\'s GOD CHARACTER MAKER v', __version__);
conn1.status();

# Login to the server
def login():
    global loggedIn, SID;
    if(loggedIn): return 2;

    # We're attempting to log someone in
    u = Display.cooked_input("> Username: "******"> Password:"******"\n  Conversing with server...");

    if(u not in ['Xunnamius']):
from httplib import BadStatusLine
from collections import OrderedDict
from NetworkInterface import NetworkInterface
from DisplayInterface import Display

conn1 = NetworkInterface()
conn1.status()

ascii_uppercase = ascii_uppercase[::-1]

try:
    gameNum = 0
    i = 1
    state = "y"
    # No color support in this version, so the Display.*Msg distinctions are only code-deep
    Display.sysMsg("Bernard Dickens - Letter Guessing Game (Project II) - ", __author__)

    while i == 1:
        i = Display.menu(
            OrderedDict([("free play", False), ("load profile", 1), ("online play", True), ("exit", 2)]),
            initMsg="Please Select Your Gameplay Mode:",
            prefix="# ",
        )
        if i == 1:
            Display.gameMsg("This gameplay mode is not available yet.")

    if i != 2:
        name = Display.cooked_input("What's your name? ")
        while (
            not re.match("^[0-9a-zA-Z_]{4}[0-9a-zA-Z_]*$", name) and 4 <= name <= 25
        ):  # ^[0-9a-zA-Z_]{4,25}$ wasn't working for some odd reason >.<