summaryrefslogtreecommitdiff
path: root/game/python-extra/tmw/login.py
blob: 4199f7e4ba16ae54d303263cd98228c57b2bae78 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
#!/usr/bin/env python3

import struct
import binascii
from .packets_in import in_packets
from .packets_out import out_packets


class Login(object):
    """
        Author: jak1
        License: GPLv2+
        State: Testing (Draft)
        Class Login:
            handles Login Packets (some packets can only get used in the right order!)
            socket: bound login server socket
            debugging: enabled if True, disabled otherwise

            NOTE: does the stored data allready have the right type? may i need to convert/cast them.
    """

    def __init__(self, socket, debugging=False):
        self.socket = socket
        self.debugging = debugging

    def sendServerVersionRequest(self, version=26):
        """
            FIXME: arg? (26 or 28? packet version or client version? [totaly confusing X_X])
        """
        out_packets[0x7530].send_data(self.socket, [version], self.debugging)

    def getServerVersion(self):
        """
            TODO: WIP
        """
        in_packets[0x7531].recv_data(self.socket, 1024, self.debugging)
        in_packets[0x7531].process_data()
        #['H', 'H', 'L', 'L', 'L', '*s']

    def getUpdateHost(self):
        """
            Function: getUpdateHost
                getting the updatehost URL
                returns: updatehost (str)
        """
        in_packets[0x0063].recv_data(self.socket, 1024, self.debugging)
        in_packets[0x0063].process_data()
        return in_packets[0x0063].p_data_list[2]

    def sendLoginRegister(self, username, password, clientversion=26):
        """
            Function: sendLoginRegister
                auth. a registred Useraccount with username and password
                username: login username
                password: login password
                clientversion: client packet version (default=26) 
                    different versions are may not supported rn.
                returns: None
        """
        _flag = 0x03
        out_packets[0x064].send_data(
            self.socket, [clientversion, bytes(username, "ascii"), bytes(password, "ascii"), _flag], self.debugging)

    def getCharLoginData(self):
        """
            Function: getCharLoginData
                gets CharServer auth. data, and all char-servers
                TODO: store session_id_*, account_id, gender, server_name
                returns: servers (dict)
                    structure:
                        "session_id_p1", "session_id_p2", "account_id",
                        "last_ip", "last_login", "gender", 
                        "char_server": [ "host", "port", "server_name", "current_online" ]
        """
        in_packets[0x0ac4].recv_data(self.socket, 1024, self.debugging)
        in_packets[0x0ac4].process_data()
        server_len = 160
        s_count = int(in_packets[0x0ac4].p_len / server_len)
        server = [{}]
        for x in range(s_count):
            offset = x * server_len
            host, port, name, online, twitter, twitter_flag = struct.unpack(
                "<4s H 20s H H H 128x",
                in_packets[0x0ac4].p_data_list[10][offset:offset + server_len])

            host = "{}.{}.{}.{}".format(*(host))
            server[x] = {
                "host": host,
                "port": port,
                "server_name": name,
                "current_online": online
            }
        servers = {
            "session_id_p1": in_packets[0x0ac4].p_data_list[2],
            "session_id_p2": in_packets[0x0ac4].p_data_list[4],
            "account_id": in_packets[0x0ac4].p_data_list[3],
            "last_ip": in_packets[0x0ac4].p_data_list[5],
            "last_login": in_packets[0x0ac4].p_data_list[6],
            "gender": in_packets[0x0ac4].p_data_list[8],
            "char_server": server
        }
        return servers

    def getLoginError(self):
        """
            Function: getLoginError
                NOTE: ONLY CALL FROM LOGIN!
                traceback error codes for failed Login
                returns: (
                    0x00 - The ID is not registered.
                    0x01 - Incorrect Password.
                    0x02 - The ID is expired.
                    0x03 - Rejected from Server.
                    0x04 - You have been blocked by the GM team.
                    0x05 - Client version is too low (client out of date).
                    0x06 - Your are temporarily prohibited from logging in.
                    0x07 - Server is jammed due to over populated.
                    0x08 - No MSG (actually, all states after 9 except 99 are No MSG, use only this)
                    0x63 - This ID has been completely erased.
                ,
                    Message
                ) (tuple(int, str))
        """
        in_packets[0x006a].recv_data(self.socket, 1024, self.debugging)
        in_packets[0x006a].process_data()
        return (in_packets[0x006a].p_data_list[2], in_packets[0x006a].p_data_list[3])

    def getLoginError(self):
        """
            Function: getLoginError
                NOTE: ONLY CALL FROM LOGIN!
                returns: tuple(id(int), error_msg(str))
        """
        in_packets[0x0081].recv_data(self.socket, 3, self.debugging)
        in_packets[0x0081].process_data()
        error_code = in_packets[0x0081].get_list_data()[1]
        errors = {
            0: "Authentication failed.",
            1: "No servers available.",
            2: "Account allready in use.",
            3: "Speed hack detected.",
            4: "Server full.",
            5: "Sorry, you are underaged.",
            7: "",  # just exit with 7 as exit_code
            8: "Duplicated login.",
            9: "To many connections from same ip.",
            10: "Not paid for this time.",
            11: "Pay suspended.",
            12: "Pay changed.",
            13: "Pay wrong ip.",
            14: "Pay game room.",
            15: "Disconnect forced by GM.",
            16: "Ban japan refuse.",
            17: "Ban japan refuse.",
            18: "Remained other account.",
            100: "Ip unfair.",  # translation issue?
            101: "Ip count all.",  # ?!
            102: "Ip count.",  # ?!
            103: "Memory.",
            104: "Memory.",
            105: "Han valid.",
            106: "Ip limited access.",
            107: "Over characters list.",
            108: "Ip blocked.",
            109: "Invalid password count.",
            110: "Not allowed race.",
            113: "Access restricted in hours 00:00 to 06:00.",
            115: "You were banned."
        }

        if error_code not in errors:
            return (error_code, "Unknown connection error.")
        else:
            return (error_code, errors[error_code])