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); }
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) { } } }