#! /usr/bin/env python

# -*- coding: utf-8 -*-

import sys

import ssl

import json

import time

import struct

import random

import urllib

import hashlib

import argparse

import itertools

import irc. client

import http. client

from threading import Thread

from whirlpool import Whirlpool

WARFRAME_LCG_MOD = ( 1 << 30 ) - 1

WARFRAME_LCG_SUM = 0x14057B7EF767814F

WARFRAME_LCG_MUL = 0x5851F42D4C957F2D

WARFRAME_ACC_LANG = 'en'

WARFRAME_UPDATE = 3655504949410653275

WARFRAME_IRC_SERVER = 'irc.warframe.com'

WARFRAME_IRC_PORT = random . randint ( 6695 , 6699 )

WARFRAME_LANGUAGES = [

'DE' , 'EN' , 'ES' , 'FR' , 'IT' ,

'JA' , 'KO' , 'PL' , 'PT' , 'RU' ,

'TC' , 'TR' , 'UK' , 'ZH'

]

def Warframe_LogIn ( username , password ) :

data = json. dumps ( { 'email' : username , 'password' : Whirlpool ( password ) . hexdigest ( ) , 'time' : time . time ( ) , 'lang' : WARFRAME_ACC_LANG , 'date' : WARFRAME_UPDATE } )

hConnection = http. client . HTTPSConnection ( 'api.warframe.com' )

hConnection. putrequest ( 'POST' , '/api/login.php' )

hConnection. putheader ( 'Accept' , 'text/plain' )

hConnection. putheader ( 'Connection' , 'keep-alive' )

hConnection. putheader ( 'Content-Type' , 'application/json' )

hConnection. putheader ( 'Content-Length' , str ( len ( data ) ) )

hConnection. endheaders ( )

hConnection. send ( data. encode ( ) )

hResponse = hConnection. getresponse ( )

data = hResponse. read ( )

hConnection. close ( )

if hResponse. status != 200 :

return hResponse. status , data

return True , json. loads ( data. decode ( ) )

finally :

tor_process. kill ( )

def Warframe_ChatAuthenticate ( connection , session , x ) :

data = [ 0 ] * 0x10

ctime = int ( time . time ( ) )

data [ 0 ] = ctime

data [ 1 ] = session [ 'Nonce' ]

for i in range ( 2 , 0x10 ) :

x = ( WARFRAME_LCG_SUM + x*WARFRAME_LCG_MUL ) & ( ( 1 << 64 ) - 1 )

data [ i ] = ( x >> 32 ) & WARFRAME_LCG_MOD

m = hashlib. md5 ( )

m. update ( struct . pack ( 'I' * 0x10 , *data ) )

credentials = 'USER %s 0 * %08x%s' % ( session [ 'id' ] , ctime , m. hexdigest ( ) )

connection. nick ( session [ 'DisplayName' ] )

connection. send_raw ( credentials )

def on_connect ( connection , event ) :

print ( '[INFO] Connected to the server.' )

def on_disconnect ( connection , event ) :

print ( '[INFO] Disconnected from server' )

raise SystemExit ( )

def on_join ( connection , event ) :

print ( '[INFO] %s joinned to %s' % ( event. source , event. target ) )

def on_privnotice ( connection , event ) :

if event. target == 'Auth' and event. arguments and event. arguments [ 0 ] . endswith ( ':***' ) :

global g_SessionData

seed = int ( event. arguments [ 0 ] . split ( ':' ) [ 0 ] , 0x10 )

print ( '[INFO] Authenticating with seed %08X.' % seed )

Warframe_ChatAuthenticate ( connection , g_SessionData , seed )

def on_unaway ( connection , event ) :

print ( '[INFO] Welcome to the server. Joinning main channels...' )

for lang in WARFRAME_LANGUAGES:

connection. join ( '#G_%s' % lang )

connection. join ( '#R_%s' % lang )

connection. join ( '#T_%s' % lang )

def on_privmsg ( connection , event ) :

raw_msg = event. arguments [ 0 ] . encode ( )

try :

event_source = event. source . nick . encode ( ) . decode ( 'utf-8' ) if event. source else 'None'

msg = raw_msg. decode ( 'utf-8' )

print ( 'PRIV|%s: %s' % ( event_source , msg ) )

except :

print ( 'PRIV|%s: %s' % ( event_source , str ( raw_msg ) ) )

def on_pubmsg ( connection , event ) :

raw_msg = event. arguments [ 0 ] . encode ( )

try :

event_target = event. target . encode ( ) . decode ( 'utf-8' ) if event. target else 'None'

event_source = event. source . nick . encode ( ) . decode ( 'utf-8' ) if event. source else 'None'

msg = raw_msg. decode ( 'utf-8' )

print ( u 'PUB|%s[%s]: %s' % ( event_target , event_source , msg ) )

except :

print ( u 'PUB|%s[%s]: %s' % ( event_target , event_source , str ( raw_msg ) ) )

def on_event ( connection , event ) :

if event. type != 'all_raw_messages' :

event_name = event. type . encode ( ) . decode ( 'utf-8' ) if event. type else 'None'

event_target = event. target . encode ( ) . decode ( 'utf-8' ) if event. target else 'None'

event_source = str ( event. source ) . encode ( ) . decode ( 'utf-8' ) if event. source else 'None'

event_args = ', ' . join ( [ arg. encode ( ) . decode ( 'utf-8' ) if arg else 'None' for arg in event. arguments ] )

try :

print ( '[EVENT] [%s->%s]: %s|%s' % ( event_source , event_target , event_name , event_args ) )

except :

pass

def get_args ( ) :

parser = argparse. ArgumentParser ( )

parser . add_argument ( 'email' )

parser . add_argument ( 'password' )

return parser . parse_args ( )

def main ( ) :

global g_SessionData

args = get_args ( )

status , data = Warframe_LogIn ( args. email , args. password )

g_SessionData = data

if status == True :

print ( '[INFO] %s logged in as %s with nonce %u' % ( data [ 'id' ] , data [ 'DisplayName' ] , data [ 'Nonce' ] ) )

else :

print ( '[ERROR] Failure logging in. Error: %s.' % data )

raise SystemExit ( 1 )

ssl_factory = irc. connection . Factory ( wrapper = ssl. wrap_socket )

reactor = irc. client . Reactor ( )

g_DisplayName = data [ 'DisplayName' ]

try :

c = reactor. server ( ) . connect (

random . choice ( data [ 'IRC' ] ) ,

WARFRAME_IRC_PORT ,

g_DisplayName ,

skip_auth = True ,

connect_factory = ssl_factory ,

)

except irc. client . ServerConnectionError :

print ( sys . exc_info ( ) [ 1 ] )

raise SystemExit ( 1 )

if __debug__:

c. add_global_handler ( "all_events" , on_event )

c. add_global_handler ( "join" , on_join )

c. add_global_handler ( "pubmsg" , on_pubmsg )

c. add_global_handler ( "unaway" , on_unaway )

c. add_global_handler ( "privmsg" , on_privmsg )

c. add_global_handler ( "welcome" , on_connect )

c. add_global_handler ( "privnotice" , on_privnotice )

c. add_global_handler ( "disconnect" , on_disconnect )

reactor. process_forever ( )

if __name__ == '__main__' :