#!/usr/bin/python

import sys
import time
import socket
import _thread
import errno
import select


HOST = "whale.hacking-lab.com"
PORT = 4242

def getWallPos(text):
    if len(text) > 22:
        pos = text[21:]
        index = pos.find(" ")
        return index + 5 if index > 0 else -1

    return -1

def getCursorPos(text):
    pos = text.replace(" ", "")[27:29]
    if len(pos) > 1 and not pos[1].isdigit():
        pos = pos[0]
    if pos.isdigit():
        return int(pos)
    return -1

wallPositions = [59, 34, 61, 42, 21, 20, 31, 38, 55, 40, 37, 50, 37, 42, 35, 52, 49, 40, 29, 54, 51, 56, 37, 30, 55, 34, 31, 20]
def play():

    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_address = (HOST, PORT)
    sock.connect(server_address)
    sock.settimeout(2)

    vel = 0
    cursorPos = -1
    wallPos = -1
    wallAt = -1
    key = ""
    wallNum = -1

    num = 0
    while True:
        data = sock.recv(128)
        if len(data) > 0:
            num += 1
            if data[0] != 0xFF:
                text = data.decode("utf-8").strip()
                index = text.find("#")
                if index >= 0 and index + 1 < len(text):
                    char = text[index+1]
                    if char.isalnum() or char == "-":
                        key += char

                sys.stdout.write(text)
                sys.stdout.flush()

                newCurPos  = getCursorPos(text)
                newWallPos = getWallPos(text)

                if newCurPos != -1:
                    vel = newCurPos - cursorPos
                    cursorPos = newCurPos

                if newWallPos != -1:
                    wallPos = newWallPos
                    wallAt = num
                    wallNum += 1

                    if wallNum >= len(wallPositions):
                        wallPositions.append(wallPos)

                if wallAt > -1 and num - wallAt >= 20:
                    wallPos = -1
                    wallAt = -1

                if cursorPos != -1:

                    curWallKnown  = wallPos != -1
                    nextWallKnown = wallPos == -1 and len(wallPositions) > wallNum + 1

                    if nextWallKnown:
                        nextWallPos = wallPositions[wallNum + 1]
                    else:
                        nextWallPos = wallPos

                    # We know the next wall:
                    if nextWallPos != -1:
                        leftBound = nextWallPos - 5
                        rightBound = nextWallPos + 5

                        if cursorPos >= leftBound and cursorPos <= rightBound and vel < 0:
                            sock.send(" ".encode("utf-8"))
                        elif cursorPos < leftBound:
                            sock.send(" ".encode("utf-8"))

                    # stay in the mid if we don't know the next wall
                    elif (not curWallKnown and not nextWallKnown and cursorPos < 50):
                        sock.send(" ".encode("utf-8"))

            if num == 1:
                sock.send(bytes.fromhex("fffd03fffb22fffa220301000003620304020f05000007621c08020409421a0a027f0b02150c02170d02120e02160f0211100213110000120000fff0fffd01"))
            elif num == 2:
                sock.send(bytes.fromhex("1b5b32343b3152"))
        else:
            return key

# HV18-9hYf-LSY1-hWdZ-496n-Mbda
key = ""
while len(key) < 29:
    print("Known Walls:", wallPositions, "Key:", key)
    time.sleep(5)
    key = play()
print(key)
