Пример #1
0
        private void ReceiveNodeInitialState(PyDataType ar)
        {
            if (ar is PyObjectData == false)
            {
                throw new Exception($"Expected PyObjectData for machoNet.nodeInfo but got {ar.GetType()}");
            }

            PyObjectData info = ar as PyObjectData;

            if (info.Name != "machoNet.nodeInfo")
            {
                throw new Exception($"Expected PyObjectData of type machoNet.nodeInfo but got {info.Name}");
            }

            // Update our local info
            NodeInfo nodeinfo = info;

            this.Container.NodeID = nodeinfo.nodeID;

            Log.Debug("Found machoNet.nodeInfo, our new node id is " + nodeinfo.nodeID.ToString("X4"));

            // load the specified solar systems
            this.SystemManager.LoadSolarSystems(nodeinfo.solarSystems);

            // finally set the new packet handler
            this.Socket.SetReceiveCallback(ReceiveNormalPacketCallback);
        }
Пример #2
0
        /// <summary>
        /// Converts a KeyVal to a normal PyDictionary
        /// </summary>
        /// <param name="from">The KeyVal to convert to a dictionary</param>
        /// <returns>The information in the keyval</returns>
        /// <exception cref="InvalidCastException">If the type is not a keyval</exception>
        public static PyDictionary ToDictionary(PyObjectData from)
        {
            if (from.Name != OBJECT_NAME)
            {
                throw new InvalidCastException($"Trying to cast a {from.Name} to a {OBJECT_NAME}");
            }

            return(from.Arguments as PyDictionary);
        }
Пример #3
0
        private void ProcessObjectData(PyObjectData data)
        {
            this.mStringBuilder.AppendFormat("[PyObjectData {0}]", data.Name.Value);
            this.mStringBuilder.AppendLine();
            this.mIndentation++;

            this.Process(data.Arguments);

            this.mIndentation--;
        }
Пример #4
0
        private PyObject HandleObject(PyObjectData dat)
        {
            // Only exceptions should be this type
            PyException ex = new PyException();

            if (ex.Decode(dat) == false)
            {
                Log.Error("Connection", "Unhandled PyObjectData packet");
                return(null);
            }

            Log.Error("Connection", "Got an exception packet of type: " + ex.exception_type + ". " + ex.message);
            throw new DisconnectException();
        }
Пример #5
0
        public PyDataType DeleteContract(PyInteger contractID, PyObjectData keyVal, CallInformation call)
        {
            using MySqlConnection connection = this.MarketDB.AcquireMarketLock();
            try
            {
                // get contract type and status

                // get the items back to where they belong (if any)

                //
            }
            finally
            {
                this.MarketDB.ReleaseMarketLock(connection);
            }
            return(null);
        }
Пример #6
0
        public PyList FetchLiveUpdates()
        {
            try
            {
                MySqlConnection connection = null;
                MySqlDataReader reader     = Database.Query(ref connection,
                                                            "SELECT updateID, updateName, description, machoVersionMin, machoVersionMax, buildNumberMin, buildNumberMax, methodName, objectID, codeType, code, OCTET_LENGTH(code) as codeLength FROM eveLiveUpdates"
                                                            );

                using (connection)
                    using (reader)
                    {
                        PyList result = new PyList();

                        while (reader.Read())
                        {
                            PyDictionary entry = new PyDictionary();
                            PyDictionary code  = new PyDictionary();

                            // read the blob for the liveupdate
                            byte[] buffer = new byte[reader.GetUInt32(11)];
                            reader.GetBytes(10, 0, buffer, 0, buffer.Length);

                            code["code"]       = buffer;
                            code["codeType"]   = reader.GetString(9);
                            code["methodName"] = reader.GetString(7);
                            code["objectID"]   = reader.GetString(8);

                            entry["code"] = new PyObjectData("util.KeyVal", code);

                            result.Add(
                                new PyObjectData("util.KeyVal", entry)
                                );
                        }

                        return(result);
                    }
            }
            catch (Exception)
            {
                Log.Error($"Cannot prepare live-updates information for client");
                throw;
            }
        }
Пример #7
0
        public bool Decode(PyObject data)
        {
            if (data.Type != PyObjectType.ObjectData)
            {
                Log.Error("ClientSessionData", "Wrong container type");
                return(false);
            }

            PyObjectData container = data as PyObjectData;

            if (container.Name != "macho.sessionInitialState")
            {
                Log.Error("ClientSessionData", "Wrong container name/type");
                return(false);
            }

            PyTuple args = container.Arguments as PyTuple;

            if (args.Items.Count != 2)
            {
                Log.Error("ClientSessionData", "Wrong args count");
                return(false);
            }

            if (args.Items[0].Type != PyObjectType.Dict)
            {
                Log.Error("ClientSessionData", "Arguments first element is not PyDict");
                return(false);
            }

            session = args.Items[0] as PyDict;

            if ((args.Items[1] is PyInt) == false)
            {
                Log.Error("ClientSessionData", "Arguments second element is not PyInt");
                return(false);
            }

            clientID = (args.Items[1] as PyInt).Value;

            return(true);
        }
Пример #8
0
        public bool Decode(PyObject info)
        {
            if (info.Type != PyObjectType.ObjectData)
            {
                Log.Error("NodeInfo", "Wrong type for ObjectData");
                return(false);
            }

            PyObjectData data = info.As <PyObjectData>();

            if (data.Name != "machoNet.nodeInfo")
            {
                Log.Error("NodeInfo", "Wrong object name, expected machoNet.nodeInfo but got " + data.Name);
                return(false);
            }

            if (data.Arguments.Type != PyObjectType.Tuple)
            {
                Log.Error("NodeInfo", "Wrong type for ObjectData arguments, expected Tuple");
                return(false);
            }

            PyTuple args = data.Arguments.As <PyTuple>();

            if (args.Items[0].Type != PyObjectType.Long)
            {
                Log.Error("NodeInfo", "Wrong type for tuple0 item0, expected int");
                return(false);
            }

            nodeID = args.Items[0].As <PyInt>().Value;

            if (args.Items[1].Type != PyObjectType.List)
            {
                Log.Error("NodeInfo", "Wrong type for tuple0 item1, expected list");
                return(false);
            }

            solarSystems = args.Items[1].As <PyList>();

            return(true);
        }
Пример #9
0
        static void Main(string[] args)
        {
            Log.Init("evesharp");
            Log.Info("Main", "Starting node...");

            Log.Info("Database", "Loading database.conf file");

            string[] lines = File.ReadAllLines("database.conf");

            Database.Database.Username = lines[0];
            Database.Database.Password = lines[1];
            Database.Database.Host     = lines[2];
            Database.Database.DB       = lines[3];

            Log.Trace("Database", "Connecting to database...");

            if (Database.Database.Init() == false)
            {
                Log.Error("Main", "Cannot connect to database");
                while (true)
                {
                    ;
                }
            }

            /*
             * SHA1 sha1 = SHA1.Create();
             * byte[] hash = sha1.ComputeHash(Encoding.ASCII.GetBytes("password"));
             * char[] strHash = new char[20];
             *
             * for (int i = 0; i < 20; i++)
             * {
             *  strHash[i] = (char)hash[i];
             * }
             *
             * string str = new string(strHash);
             *
             * Database.Database.Query("INSERT INTO account(accountID, accountName, password, role, online, banned)VALUES(NULL, 'Username', '" + str + "', 2, 0, 0);");
             *
             * Database.Database.Query("INSERT INTO account(accountID, accountName, password, role, online, banned)VALUES(NULL, 'Username', SHA1('password'), 2, 0, 0);");*/

            Log.Info("Main", "Connection to the DB sucessfull");

            Log.Info("Main", "Generating default cache data");
            Cache.GenerateCache();
            Log.Debug("Main", "Done");

            Log.Info("Main", "Connecting to proxy...");

            proxyConnection = new TCPSocket(ushort.Parse(proxy[0, 1]), false);
            if (proxyConnection.Connect(proxy[0, 0]) == false)
            {
                Log.Error("Main", "Cannot connect to proxy. Halting");
                Database.Database.Stop();
                while (true)
                {
                    ;
                }
            }

            Log.Trace("Main", "Server started");

            while (true)
            {
                Thread.Sleep(1);
                try
                {
                    byte[] data  = new byte[proxyConnection.Available];
                    int    bytes = proxyConnection.Recv(data);

                    if (bytes == -1)
                    {
                        // Proxy is closing, shutdown the node
                        break;
                    }
                    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 is PyObjectData)
                            {
                                PyObjectData info = obj as PyObjectData;

                                if (info.Name == "machoNet.nodeInfo")
                                {
                                    // Update our local info
                                    NodeInfo nodeinfo = new NodeInfo();

                                    if (nodeinfo.Decode(info) == true)
                                    {
                                        nodeID = nodeinfo.nodeID;

                                        Log.Debug("Main", "Found machoNet.nodeInfo, our new node id is " + nodeID.ToString("X4"));
                                        SystemManager.LoadSolarSystems(nodeinfo.solarSystems);
                                    }
                                }
                                else
                                {
                                    // Client packet
                                    PyPacket clientpacket = new PyPacket();

                                    if (clientpacket.Decode(info) == false)
                                    {
                                        Log.Error("Main", "Unknown packet");
                                    }
                                    else
                                    {
                                        // Something similar to Async calls
                                        new Thread(new ParameterizedThreadStart(HandlePacket)).Start(clientpacket);
                                    }
                                }
                            }
                            else if (obj is PyChecksumedStream) // Checksumed packets
                            {
                                PyPacket clientpacket = new PyPacket();

                                if (clientpacket.Decode(obj) == false)
                                {
                                    Log.Error("Main", "Cannot decode packet");
                                }
                                else
                                {
                                    new Thread(new ParameterizedThreadStart(HandlePacket)).Start(clientpacket);
                                }
                            }
                            else if (obj is PyTuple)
                            {
                                // The only tuple packet is the LowLevelVersionExchange
                                LowLevelVersionExchange ex = new LowLevelVersionExchange();

                                if (ex.Decode(obj) == false)
                                {
                                    Log.Error("Main", "LowLevelVersionExchange error");
                                }

                                // Reply with the node LowLevelVersionExchange
                                LowLevelVersionExchange reply = new LowLevelVersionExchange();

                                reply.codename     = Common.Constants.Game.codename;
                                reply.birthday     = Common.Constants.Game.birthday;
                                reply.build        = Common.Constants.Game.build;
                                reply.machoVersion = Common.Constants.Game.machoVersion;
                                reply.version      = Common.Constants.Game.version;
                                reply.region       = Common.Constants.Game.region;

                                Send(reply.Encode(true));
                            }
                            else if (obj is PyObjectEx)
                            {
                                Log.Error("PyObjectEx", PrettyPrinter.Print(obj));
                            }
                            else
                            {
                                Log.Error("Main", PrettyPrinter.Print(obj));
                                Log.Error("Main", "Unhandled packet type");
                            }
                        }
                    }
                }
                catch (Exception)
                {
                }
            }

            /* Code to ADD an account:
             * SHA1 sha1 = SHA1.Create();
             * byte[] hash = sha1.ComputeHash(Encoding.ASCII.GetBytes("password"));
             * char[] strHash = new char[20];
             *
             * for (int i = 0; i < 20; i++)
             * {
             *  strHash[i] = (char)hash[i];
             * }
             *
             * string str = new string(strHash);
             *
             * Database.Database.Query("INSERT INTO account(accountID, accountName, password, role, online, banned)VALUES(NULL, 'Username', '" + str + "', 2, 0, 0);");
             */
        }
Пример #10
0
        static void Main(string[] args)
        {
            Log.Init("evesharp");
            Log.Info("Main", "Starting node...");
            Log.Trace("Database", "Connecting to database...");

            if (Database.Database.Init() == false)
            {
                Log.Error("Main", "Cannot connect to database");
                while (true)
                {
                    ;
                }
            }

            /*
             * DBRowDescriptor descriptor = new DBRowDescriptor();
             *
             * descriptor.AddColumn("itemID", FieldType.I4);
             * descriptor.AddColumn("custominfo", FieldType.Str);
             *
             * PyPackedRow packed = new PyPackedRow(descriptor);
             *
             * packed.SetValue("itemID", new PyInt(500));
             * packed.SetValue("custominfo", new PyString("hello world"));
             *
             * byte[] marshaled = Marshal.Marshal.Process(packed);
             *
             * PyPackedRow unmarshaled = Unmarshal.Process<PyPackedRow>(marshaled);
             *
             * Console.WriteLine(PrettyPrinter.Print(unmarshaled));
             */

            byte[] raw = new byte[] { 1, 0, 55, 1, 22, 33, 0, 33, 25, 33, 14, 0, 0, 25, 45 };

            MemoryStream output = new MemoryStream(raw);
            BinaryReader reader = new BinaryReader(output);

            MemoryStream stream       = new MemoryStream();
            BinaryWriter streamWriter = new BinaryWriter(stream);
            BinaryReader streamReader = new BinaryReader(stream);

            PyPackedRow.ZeroCompress(reader, output, streamWriter);

            byte[] compressed = stream.ToArray();
            stream.Seek(0, SeekOrigin.Begin);

            byte[] uncompress = PyPackedRow.LoadZeroCompressed(streamReader);

            while (true)
            {
                Thread.Sleep(1);
            }

            /*
             * SHA1 sha1 = SHA1.Create();
             * byte[] hash = sha1.ComputeHash(Encoding.ASCII.GetBytes("password"));
             * char[] strHash = new char[20];
             *
             * for (int i = 0; i < 20; i++)
             * {
             *  strHash[i] = (char)hash[i];
             * }
             *
             * string str = new string(strHash);
             *
             * Database.Database.Query("INSERT INTO account(accountID, accountName, password, role, online, banned)VALUES(NULL, 'Username', '" + str + "', 2, 0, 0);");
             */

            Log.Info("Main", "Connection to the DB sucessfull");

            Log.Trace("Main", "Registering services...");

            SvcMgr.AddService(new Services.Network.machoNet());
            SvcMgr.AddService(new Services.Network.alert());
            SvcMgr.AddService(new Services.CacheSvc.objectCaching());

            Log.Info("Main", "Done");
            Log.Info("Main", "Connecting to proxy...");

            proxyConnection = new TCPSocket(ushort.Parse(proxy[0, 1]), false);
            if (proxyConnection.Connect(proxy[0, 0]) == false)
            {
                Log.Error("Main", "Cannot connect to proxy. Halting");
                Database.Database.Stop();
                while (true)
                {
                    ;
                }
            }

            Log.Trace("Main", "Server started");

            while (true)
            {
                Thread.Sleep(1);
                try
                {
                    byte[] data  = new byte[proxyConnection.Available];
                    int    bytes = proxyConnection.Recv(data);

                    if (bytes == -1)
                    {
                        // Proxy is closing, shutdown the node
                        break;
                    }
                    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 is PyObjectData)
                            {
                                PyObjectData info = obj as PyObjectData;

                                if (info.Name == "machoNet.nodeInfo")
                                {
                                    // Update our local info
                                    NodeInfo nodeinfo = new NodeInfo();

                                    if (nodeinfo.Decode(info) == true)
                                    {
                                        nodeID = nodeinfo.nodeID;

                                        SystemManager.LoadSolarSystems(nodeinfo.solarSystems);
                                    }
                                }
                                else
                                {
                                    // Client packet
                                    PyPacket clientpacket = new PyPacket();

                                    if (clientpacket.Decode(info) == false)
                                    {
                                        Log.Error("Main", "Unknown packet");
                                    }
                                    else
                                    {
                                        // Something similar to Async calls
                                        new Thread(new ParameterizedThreadStart(HandlePacket)).Start(clientpacket);
                                    }
                                }
                            }
                            else if (obj is PyChecksumedStream) // Checksumed packets
                            {
                                PyPacket clientpacket = new PyPacket();

                                if (clientpacket.Decode(obj) == false)
                                {
                                    Log.Error("Main", "Cannot decode packet");
                                }
                                else
                                {
                                    new Thread(new ParameterizedThreadStart(HandlePacket)).Start(clientpacket);
                                }
                            }
                            else if (obj is PyTuple)
                            {
                                // The only tuple packet is the LowLevelVersionExchange
                                LowLevelVersionExchange ex = new LowLevelVersionExchange();

                                if (ex.Decode(obj) == false)
                                {
                                    Log.Error("Main", "LowLevelVersionExchange error");
                                }

                                // Reply with the node LowLevelVersionExchange
                                LowLevelVersionExchange reply = new LowLevelVersionExchange();

                                reply.codename     = Common.Constants.Game.codename;
                                reply.birthday     = Common.Constants.Game.birthday;
                                reply.build        = Common.Constants.Game.build;
                                reply.machoVersion = Common.Constants.Game.machoVersion;
                                reply.version      = Common.Constants.Game.version;
                                reply.region       = Common.Constants.Game.region;

                                Send(reply.Encode(true));
                            }
                            else if (obj is PyObjectEx)
                            {
                                Log.Error("PyObjectEx", PrettyPrinter.Print(obj));
                            }
                            else
                            {
                                Log.Error("Main", PrettyPrinter.Print(obj));
                                Log.Error("Main", "Unhandled packet type");
                            }
                        }
                    }
                }
                catch (Exception)
                {
                }
            }

            /* Code to ADD an account:
             * SHA1 sha1 = SHA1.Create();
             * byte[] hash = sha1.ComputeHash(Encoding.ASCII.GetBytes("password"));
             * char[] strHash = new char[20];
             *
             * for (int i = 0; i < 20; i++)
             * {
             *  strHash[i] = (char)hash[i];
             * }
             *
             * string str = new string(strHash);
             *
             * Database.Database.Query("INSERT INTO account(accountID, accountName, password, role, online, banned)VALUES(NULL, 'Username', '" + str + "', 2, 0, 0);");
             */
        }
Пример #11
0
 /// <summary>
 /// Converts the given <paramref name="data"/> to it's byte array representation.
 /// ObjectData are simple representations of Python objects.
 /// These objects are composed by one python string that indicates the type of the object (it's name)
 /// and an argument object that can be any kind of Python type
 ///
 /// The following opcodes are supported
 /// <seealso cref="Opcode.ObjectData" />
 /// </summary>
 /// <param name="writer">Where to write the encoded data to</param>
 /// <param name="data">The value to write</param>
 private static void ProcessObjectData(BinaryWriter writer, PyObjectData data)
 {
     writer.WriteOpcode(Opcode.ObjectData);
     Process(writer, data.Name);
     Process(writer, data.Arguments);
 }
Пример #12
0
        public PyDataType PlaceBid(PyInteger contractID, PyInteger quantity, PyBool forCorp, PyObjectData locationData, CallInformation call)
        {
            using MySqlConnection connection = this.MarketDB.AcquireMarketLock();
            try
            {
                // TODO: SUPPORT PROPER CORP WALLET
                int bidderID = call.Client.EnsureCharacterIsSelected();

                if (forCorp == true)
                {
                    bidderID = call.Client.CorporationID;
                    throw new UserError("Corp bidding is not supported for now!");
                }

                ContractDB.Contract contract = this.DB.GetContract(connection, contractID);

                // ensure the contract is still in progress
                if (contract.Status != ContractStatus.Outstanding)
                {
                    throw new ConAuctionAlreadyClaimed();
                }

                this.DB.GetMaximumBid(connection, contractID, out int maximumBidderID, out int maximumBid);

                // calculate next bid slot
                int nextMinimumBid = maximumBid + (int)Math.Max(0.1 * (double)contract.Price, 1000);

                if (quantity < nextMinimumBid)
                {
                    throw new ConBidTooLow(quantity, nextMinimumBid);
                }

                // take the bid's money off the wallet
                using Wallet bidderWallet = this.WalletManager.AcquireWallet(bidderID, 1000);
                {
                    bidderWallet.EnsureEnoughBalance(quantity);
                    bidderWallet.CreateJournalRecord(
                        MarketReference.ContractAuctionBid, null, null, -quantity
                        );
                }

                // check who we'd outbid and notify them
                this.DB.GetOutbids(connection, contractID, quantity, out List <int> characterIDs, out List <int> corporationIDs);

                OnContractOutbid notification = new OnContractOutbid(contractID);

                foreach (int corporationID in corporationIDs)
                {
                    if (corporationID != bidderID)
                    {
                        this.NotificationManager.NotifyCorporation(corporationID, notification);
                    }
                }

                foreach (int characterID in characterIDs)
                {
                    if (characterID != bidderID)
                    {
                        this.NotificationManager.NotifyCharacter(characterID, notification);
                    }
                }

                // finally place the bid
                ulong bidID = this.DB.PlaceBid(connection, contractID, quantity, bidderID, forCorp);

                // return the money for the player that was the highest bidder
                using Wallet maximumBidderWallet = this.WalletManager.AcquireWallet(maximumBidderID, 1000);
                {
                    maximumBidderWallet.CreateJournalRecord(
                        MarketReference.ContractAuctionBidRefund, null, null, maximumBid, ""
                        );
                }
                return(bidID);
            }
            finally
            {
                this.MarketDB.ReleaseMarketLock(connection);
            }
        }
Пример #13
0
        public PyDataType GetContractList(PyObjectData filtersKeyval, CallInformation call)
        {
            PyDictionary <PyString, PyDataType> filters = KeyVal.ToDictionary(filtersKeyval).GetEnumerable <PyString, PyDataType>();
            PyList <PyInteger> notIssuedByIDs           = null;
            PyList <PyInteger> issuedByIDs = null;

            call.NamedPayload.TryGetValue("startContractID", out PyInteger startContractID);
            int resultsPerPage = call.NamedPayload["num"] as PyInteger;

            filters.TryGetValue("regionID", out PyInteger regionID);
            filters.TryGetValue("stationID", out PyInteger stationID);
            filters.TryGetValue("solarSystemID", out PyInteger solarSystemID);
            filters.TryGetValue("itemTypeID", out PyInteger itemTypeID);
            filters.TryGetValue("assigneeID", out PyInteger assigneeID);
            filters.TryGetValue("itemGroupID", out PyInteger itemGroupID);
            filters.TryGetValue("itemCategoryID", out PyInteger itemCategoryID);
            filters.TryGetValue("priceMax", out PyInteger priceMax);
            filters.TryGetValue("priceMin", out PyInteger priceMin);
            filters.TryGetValue("type", out PyInteger type);
            filters.TryGetValue("description", out PyString description);

            if (priceMax < 0 || priceMin < 0 || priceMax < priceMin)
            {
                throw new ConMinMaxPriceError();
            }

            if (filters.TryGetValue("issuedByIDs", out PyList issuedIDs) == true && issuedIDs is not null)
            {
                issuedByIDs = issuedIDs.GetEnumerable <PyInteger>();
            }
            if (filters.TryGetValue("notIssuedByIDs", out PyList notIssuedIDs) == true && notIssuedIDs is not null)
            {
                notIssuedByIDs = notIssuedIDs.GetEnumerable <PyInteger>();
            }

            // limit the number of results to 100
            if (resultsPerPage > 100)
            {
                resultsPerPage = 100;
            }

            int?locationID = null;

            if (stationID is not null)
            {
                locationID = stationID;
            }
            else if (solarSystemID is not null)
            {
                locationID = solarSystemID;
            }
            else if (regionID is not null)
            {
                locationID = regionID;
            }

            List <int> contractList = this.DB.GetContractList(
                startContractID, resultsPerPage, itemTypeID, notIssuedByIDs, issuedByIDs, assigneeID,
                locationID, itemGroupID, itemCategoryID, priceMax ?? 0, priceMin ?? 0, type, description,
                call.Client.EnsureCharacterIsSelected(), call.Client.CorporationID
                );

            return(KeyVal.FromDictionary(new PyDictionary()
            {
                ["contracts"] = this.DB.GetInformationForContractList(contractList),
                ["bids"] = this.DB.GetBidsForContractList(contractList),
                ["items"] = this.DB.GetItemsForContractList(contractList)
            }
                                         ));
        }
Пример #14
0
        public void ReceiveNodeAsync(IAsyncResult ar)
        {
            try
            {
                AsyncState state = (AsyncState)(ar.AsyncState);

                int bytes = Socket.Socket.EndReceive(ar);

                packetizer.QueuePackets(state.buffer, bytes);
                int p = packetizer.ProcessPackets();

                for (int i = 0; i < p; i++)
                {
                    byte[] packet = packetizer.PopItem();

                    PyObject obj = Unmarshal.Process <PyObject>(packet);

                    if (obj == null)
                    {
                        Log.Debug("Node", "Null packet received");
                        continue;
                    }

                    if ((obj is PyObjectData) == false)
                    {
                        Log.Debug("Node", "Non-valid node packet. Dropping");
                        continue;
                    }

                    PyObjectData item = obj as PyObjectData;

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

                        if (final.Decode(item) == false)
                        {
                            Log.Error("Node", "Cannot decode packet");
                            continue;
                        }

                        if (final.dest.type == PyAddress.AddrType.Client)
                        {
                            ConnectionManager.NotifyClient((int)(final.userID), obj);
                        }
                        else if (final.dest.type == PyAddress.AddrType.Node)
                        {
                            ConnectionManager.NotifyNode((int)(final.dest.typeID), obj);
                        }
                        else if (final.dest.type == PyAddress.AddrType.Broadcast)
                        {
                            Log.Error("Node", "Broadcast packets not supported yet");
                        }
                        // TODO: Handle Broadcast packets
                    }
                    else
                    {
                        Log.Error("Node", string.Format("Wrong packet name: {0}", item.Name));
                    }
                }

                Socket.Socket.BeginReceive(state.buffer, 0, 8192, SocketFlags.None, recvAsync, state);
            }
            catch (ObjectDisposedException)
            {
                Log.Debug("Node", "Disconnected");
                ConnectionManager.RemoveConnection(this);
            }
            catch (SocketException)
            {
                Log.Debug("Node", "Disconnected");
                ConnectionManager.RemoveConnection(this);
            }
            catch (Exception ex)
            {
                Log.Error("Node", "Caught unhandled exception: " + ex.ToString());
            }
        }
Пример #15
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)
                {
                }
            }
        }