Beispiel #1
0
        private PyObject HandleTuple(PyTuple tup)
        {
            int items = tup.Items.Count;

            if (items == 6)
            {
                // Only LowLeverVersionExchange
                if (CheckLowLevelVersionExchange(tup) == false)
                {
                    Close();
                }

                if (isNode)
                {
                    // We are a node, the next packets will be handled by the Node class
                    Node n = new Node(new StreamPacketizer(), socket);
                    NodeManager.AddNode(n);

                    forClose = false;
                    Close();
                }

                return(null);
            }
            else if (items == 3)
            {
                if (tup.Items[0].Type == PyObjectType.None)
                {
                    // VipKey
                    VipKeyCommand vk = new VipKeyCommand();

                    if (vk.Decode(tup) == false)
                    {
                        Log.Error("Client", "Wrong vipKey command");
                        Close();

                        return(null);
                    }

                    return(null);
                }
                else
                {
                    // Handshake sent when we are mostly in
                    HandshakeAck ack = new HandshakeAck();

                    ack.live_updates   = new PyList();
                    ack.jit            = session.GetCurrentString("languageID");
                    ack.userid         = session.GetCurrentInt("userid");
                    ack.maxSessionTime = new PyNone();
                    ack.userType       = Common.Constants.AccountType.User;
                    ack.role           = session.GetCurrentInt("role");
                    ack.address        = session.GetCurrentString("address");
                    ack.inDetention    = new PyNone();
                    ack.client_hashes  = new PyList();
                    ack.user_clientid  = session.GetCurrentInt("userid");

                    // We have to send this just before the sessionchange
                    Send(ack.Encode());

                    // Create the client instance
                    Client cli = new Client(new StreamPacketizer(), socket);

                    // Update the Client class session data
                    cli.InitialSession(session);

                    // Set the node id for the client
                    cli.SetNodeID(nodeID);

                    // Send session change
                    cli.SendSessionChange();

                    // Start the client packet reader thread
                    cli.Start();

                    // Now we are completely in, add us to the list
                    ClientManager.AddClient(cli);

                    // Delete ourselves from the list
                    forClose = false;
                    Close();
                }
            }
            else if (items == 2) // PlaceboRequest, QueueCheck and Login packet
            {
                if (tup.Items[0].Type == PyObjectType.None)
                {
                    QueueCheckCommand qc = new QueueCheckCommand();

                    if (qc.Decode(tup) == false)
                    {
                        Log.Error("Client", "Wrong QueueCheck command");
                        Close();

                        return(null);
                    }

                    // Queued logins
                    Send(new PyInt(LoginQueue.queue.Count + 1));
                    SendLowLevelVersionExchange();

                    return(null);
                }
                else if (tup.Items[0].Type == PyObjectType.String)
                {
                    if (tup.Items[0].As <PyString>().Value == "placebo")
                    {
                        // We assume it is a placebo request
                        PlaceboRequest req = new PlaceboRequest();

                        if (req.Decode(tup) == false)
                        {
                            Log.Error("Client", "Wrong placebo request");
                            Close();

                            return(null);
                        }

                        return(new PyString("OK CC"));
                    }
                    else
                    {
                        // Check if the password is hashed or not and ask for plain password
                        AuthenticationReq req = new AuthenticationReq();

                        if (req.Decode(tup) == false)
                        {
                            Log.Error("Client", "Wrong login packet");
                            GPSTransportClosed ex = new GPSTransportClosed("LoginAuthFailed");
                            Send(ex.Encode());
                            Close();
                            return(null);
                        }

                        // The hash is in sha1, we should handle it later
                        if (req.user_password == null)
                        {
                            Log.Trace("Client", "Rejected by server; requesting plain password");
                            return(new PyInt(1)); // Ask for unhashed password( 1 -> Plain, 2 -> Hashed )
                        }

                        request = req;

                        // Login request, add it to the queue and wait until we are accepted or rejected
                        LoginQueue.Enqueue(this);

                        // The login queue will call send the data to the client
                        return(null);
                    }
                }
            }
            else
            {
                Log.Error("Connection", "Unhandled Tuple packet with " + items + " items");
                thr.Abort();

                return(null);
            }

            return(null);
        }
Beispiel #2
0
        public void Run()
        {
            while (true)
            {
                Thread.Sleep(1);

                try
                {
                    byte[] data  = new byte[socket.Available];
                    int    bytes = socket.Recv(data);

                    if (bytes == -1)
                    {
                        throw new DisconnectException();
                    }
                    else if (bytes > 0)
                    {
                        packetizer.QueuePackets(data, bytes);
                        int p = packetizer.ProcessPackets();

                        for (int i = 0; i < p; i++)
                        {
                            byte[]   packet = packetizer.PopItem();
                            PyObject obj    = Unmarshal.Process <PyObject>(packet);

                            if (obj.Type == PyObjectType.ObjectData)
                            {
                                Log.Warning("Node", PrettyPrinter.Print(obj));
                                PyObjectData item = obj as PyObjectData;

                                if (item.Name == "macho.CallRsp")
                                {
                                    PyPacket final = new PyPacket();

                                    if (final.Decode(item) == true)
                                    {
                                        if (final.dest.type == PyAddress.AddrType.Client)
                                        {
                                            try
                                            {
                                                ClientManager.NotifyClient((int)final.userID, obj);
                                            }
                                            catch (Exception)
                                            {
                                                Log.Error("Node", "Trying to send a packet to a non-existing client");
                                            }
                                        }
                                        else if (final.dest.type == PyAddress.AddrType.Node)
                                        {
                                            NodeManager.NotifyNode((int)final.dest.typeID, obj);
                                        }
                                        else if (final.dest.type == PyAddress.AddrType.Broadcast)
                                        {
                                            // This should not be coded like this here, but will do the trick for now
                                            // TODO: Add a ClientManager
                                            ClientManager.NotifyClients(obj);
                                        }
                                    }
                                }
                            }
                            else
                            {
                                Log.Error("Node", "Unknown type");
                            }
                        }
                    }
                }
                catch (SocketException ex)
                {
                    if (ex.ErrorCode != 10035)
                    {
                        break;
                    }
                }
                catch (DisconnectException)
                {
                    Log.Error("Node", "Node " + NodeManager.GetNodeID(this) + " disconnected");
                    break;
                }
                catch (Exception)
                {
                }
            }
        }