示例#1
0
        public void Update()
        {
            if (this.timeId.Count == 0)
            {
                return;
            }

            long timeNow = TimeHelper.Now();

            if (timeNow < this.minTime)
            {
                return;
            }

            foreach (KeyValuePair <long, List <long> > kv in this.timeId.GetDictionary())
            {
                long k = kv.Key;
                if (k > timeNow)
                {
                    minTime = k;
                    break;
                }
                this.timeOutTime.Enqueue(k);
            }

            while (this.timeOutTime.Count > 0)
            {
                long time = this.timeOutTime.Dequeue();
                foreach (long timerId in this.timeId[time])
                {
                    this.timeOutTimerIds.Enqueue(timerId);
                }
                this.timeId.Remove(time);
            }

            while (this.timeOutTimerIds.Count > 0)
            {
                long  timerId = this.timeOutTimerIds.Dequeue();
                Timer timer;
                if (!this.timers.TryGetValue(timerId, out timer))
                {
                    continue;
                }
                this.timers.Remove(timerId);
                timer.tcs.SetResult();
            }
        }
示例#2
0
 public override void OnUpdate()
 {
     //只有不是永久Buff的情况下才会执行Update判断
     if (this.BuffData.SustainTime + 1 > 0)
     {
         //Log.Info($"执行持续伤害的Update,当前时间是{TimeHelper.Now()}");
         if (TimeHelper.Now() > MaxLimitTime)
         {
             this.BuffState = BuffState.Finished;
             //Log.Info("持续伤害结束了");
         }
         else if (TimeHelper.Now() > this.m_SelfNextimer)
         {
             ExcuteDamage();
         }
     }
 }
示例#3
0
 public virtual void FixedUpdate()
 {
     if (m_ddWorld != null)
     {
         float deltaTime = m_fixedTimeStep - m_elapsedBetweenFixedFrames;
         int   numSteps  = m_ddWorld.StepSimulation(deltaTime, 1, m_fixedTimeStep);
         m__frameCount              += numSteps;
         m_lastSimulationStepTime    = TimeHelper.Now();
         m_elapsedBetweenFixedFrames = 0f;
         numUpdates = 0;
     }
     //collisions
     if (m_collisionEventHandler != null)
     {
         m_collisionEventHandler.OnPhysicsStep(m_world);
     }
 }
示例#4
0
        public KService(IPEndPoint ipEndPoint)
        {
            this.TimeNow = (uint)TimeHelper.Now();
            this.socket  = new UdpClient(ipEndPoint);

#if SERVER
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                const uint IOC_IN            = 0x80000000;
                const uint IOC_VENDOR        = 0x18000000;
                uint       SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12;
                this.socket.Client.IOControl((int)SIO_UDP_CONNRESET, new[] { Convert.ToByte(false) }, null);
            }
#endif

            this.StartRecv();
        }
示例#5
0
        public ETTask WaitAsync(long time, CancellationToken cancellationToken)
        {
            ETTaskCompletionSource tcs = new ETTaskCompletionSource();
            Timer timer = new Timer {
                Id = IdGenerater.GenerateId(), Time = TimeHelper.Now() + time, tcs = tcs
            };

            this.timers[timer.Id] = timer;
            this.timeId.Add(timer.Time, timer.Id);
            if (timer.Time < this.minTime)
            {
                this.minTime = timer.Time;
            }

            cancellationToken.Register(() => { this.Remove(timer.Id); });
            return(tcs.Task);
        }
示例#6
0
        public Session(AChannel channel)
        {
            this.channel = channel;

            long timeNow = TimeHelper.Now();

            this.LastRecvTime = timeNow;
            this.LastSendTime = timeNow;

            long id = this.Id;

            this.channel.ErrorCallback += (c, e) =>
            {
                OzNetClient.Instance.DispatchClose(this, e);
            };
            this.channel.ReadCallback += OnRead;
        }
示例#7
0
        public void Awake(AChannel aChannel)
        {
            long timeNow = TimeHelper.Now();

            this.LastRecvTime = timeNow;
            this.LastSendTime = timeNow;

            this.channel = aChannel;
            this.requestCallback.Clear();
            long id = this.Id;

            channel.ErrorCallback += (c, e) =>
            {
                this.Network.Remove(id);
            };
            channel.ReadCallback += this.OnRead;
        }
示例#8
0
        public ETTask WaitAsync(long time, ETCancellationToken cancellationToken)
        {
            long tillTime = TimeHelper.Now() + time;

            if (TimeHelper.Now() > tillTime)
            {
                return(ETTask.CompletedTask);
            }

            ETTaskCompletionSource tcs   = new ETTaskCompletionSource();
            OnceWaitTimer          timer = EntityFactory.CreateWithParent <OnceWaitTimer, ETTaskCompletionSource>(this, tcs);

            this.timers[timer.Id] = timer;
            AddToTimeId(tillTime, timer.Id);
            cancellationToken.Register(() => { this.Remove(timer.Id); });
            return(tcs.Task);
        }
示例#9
0
        public void Update()
        {
            if (this.timeId.Count == 0)
            {
                return;
            }

            long timeNow = TimeHelper.Now();

            if (timeNow < this.minTime)
            {
                return;
            }

            this.timeOutTime.Clear();

            foreach (KeyValuePair <long, List <long> > kv in this.timeId.GetDictionary())
            {
                long k = kv.Key;
                if (k > timeNow)
                {
                    minTime = k;
                    break;
                }
                this.timeOutTime.Add(k);
            }

            foreach (long k in this.timeOutTime)
            {
                foreach (long v in this.timeId[k])
                {
                    Timer timer;
                    if (!this.timers.TryGetValue(v, out timer))
                    {
                        continue;
                    }
                    this.timers.Remove(v);
                    timer.tcs.SetResult(true);
                }

                this.timeId.Remove(k);
            }
        }
示例#10
0
        public void OnBeRuler(HttpMessage httpMessage)
        {
            Consensus consensus = Entity.Root.GetComponent <Consensus>();
            WalletKey key       = Wallet.GetWallet().GetCurWallet();

            var  address = key.ToAddress();
            long notice  = 1;

            using (var dbSnapshot = Entity.Root.GetComponent <LevelDBStore>().GetSnapshot(0))
            {
                var account = dbSnapshot.Accounts.Get(address);
                if (account != null)
                {
                    notice = account.nonce + 1;
                }
            }

            BlockSub transfer = new BlockSub();

            transfer.addressIn  = address;
            transfer.addressOut = consensus.consAddress;
            transfer.amount     = "0";
            transfer.nonce      = notice;
            transfer.type       = "contract";

            LuaVMCall luaVMCall = new LuaVMCall();

            luaVMCall.fnName   = "add";
            luaVMCall.args     = new FieldParam[0];
            transfer.data      = luaVMCall.Encode();
            transfer.timestamp = TimeHelper.Now();

            transfer.hash = transfer.ToHash();
            transfer.sign = transfer.ToSign(key);

            var rel = Entity.Root.GetComponent <Rule>().AddTransfer(transfer);

            if (rel == -1)
            {
                OnTransferAsync(transfer);
            }
            httpMessage.result = $"accepted transfer:{transfer.hash}";
        }
示例#11
0
        public async void Test3Async(object o)
        {
            Session session2 = null;

            var accountCount = Wallet.GetWallet().keys.Count;

            while (true)
            {
                Log.Info("Test2Async 200");
                session2 = null;
                for (int ii = 0; ii < 200; ii++)
                {
                    int random1 = RandomHelper.Range(0, accountCount);
                    int random2 = RandomHelper.Range(0, accountCount);
                    while (random1 == random2)
                    {
                        random2 = RandomHelper.Range(0, accountCount);
                    }
                    int random3 = RandomHelper.Range(1, 100);

                    BlockSub transfer = new BlockSub();
                    transfer.type       = "transfer";
                    transfer.addressIn  = Wallet.GetWallet().keys[random1].ToAddress();
                    transfer.addressOut = Wallet.GetWallet().keys[random2].ToAddress();
                    transfer.amount     = random3.ToString();
                    transfer.data       = "";
                    transfer.depend     = "";
                    transfer.nonce      = GetAccountNotice(transfer.addressIn);
                    transfer.timestamp  = TimeHelper.Now();
                    transfer.hash       = transfer.ToHash();
                    transfer.sign       = transfer.ToSign(Wallet.GetWallet().keys[random1]);

                    session2 = await OnTransferAsync2(transfer, session2);

                    while (session2 == null)
                    {
                        session2 = await OnTransferAsync2(transfer, session2);
                    }
                    ;
                }
                await Task.Delay(1000);
            }
        }
示例#12
0
        private async Task RunTask(ActorTask task)
        {
            try
            {
                IResponse response = await task.Run();

                // 如果没找到Actor,重试
                if (response.Error == ErrorCode.ERR_NotFoundActor)
                {
                    this.CancellationTokenSource.Cancel();
                    ++this.failTimes;

                    // 失败10次则清空actor发送队列,返回失败
                    if (this.failTimes > 10)
                    {
                        // 失败直接删除actorproxy
                        Log.Info($"actor send message fail, actorid: {this.Id}");
                        Game.Scene.GetComponent <ActorProxyComponent>().Remove(this.Id);
                        return;
                    }
                    // 等待1s再发送
                    await Game.Scene.GetComponent <TimerComponent>().WaitAsync(1000);

                    int appId = await Game.Scene.GetComponent <LocationProxyComponent>().Get(this.Id);

                    this.Address = Game.Scene.GetComponent <StartConfigComponent>().Get(appId).GetComponent <InnerConfig>().IPEndPoint;
                    this.CancellationTokenSource = new CancellationTokenSource();
                    this.AllowGet();
                    return;
                }

                // 发送成功
                this.LastSendTime = TimeHelper.Now();
                this.failTimes    = 0;

                this.WaitingTasks.Dequeue();
            }
            catch (Exception e)
            {
                Log.Error(e);
            }
        }
示例#13
0
 protected virtual void _InitializePhysicsWorld()
 {
     _isDisposed = false;
     CreatePhysicsWorld(out m_world, out CollisionConf, out Dispatcher, out Broadphase, out constraintSolver, out softBodyWorldInfo);
     if (m_world is DiscreteDynamicsWorld)
     {
         _ddWorld = (DiscreteDynamicsWorld)m_world;
     }
     //Add a BPhysicsWorldLateHelper component to call FixedUpdate
     lateUpdateHelper = Game.Scene.GetComponent <BPhysicsWorldLateHelper>();
     if (lateUpdateHelper == null)
     {
         lateUpdateHelper = Game.Scene.AddComponent <BPhysicsWorldLateHelper>();
     }
     lateUpdateHelper.m_world                  = world;
     lateUpdateHelper.m_ddWorld                = _ddWorld;
     lateUpdateHelper.m_physicsWorld           = this;
     lateUpdateHelper.m__frameCount            = 0;
     lateUpdateHelper.m_lastSimulationStepTime = TimeHelper.Now();
 }
示例#14
0
        public async void Test2Async(object o)
        {
            NodeManager nodeManager = Entity.Root.GetComponent <NodeManager>();

            for (int ii = Wallet.GetWallet().keys.Count; ii < 1000; ii++)
            {
                Wallet.GetWallet().Create();
            }
            Wallet.GetWallet().SaveWallet();

            Log.Info("Test2Async start1");

            Session session2 = null;

            for (int ii = 1; ii < 1000; ii++)
            {
                int random1 = 0;
                int random2 = ii;
                int random3 = 1000;

                BlockSub transfer = new BlockSub();
                transfer.type       = "transfer";
                transfer.addressIn  = Wallet.GetWallet().keys[random1].ToAddress();
                transfer.addressOut = Wallet.GetWallet().keys[random2].ToAddress();
                transfer.amount     = random3.ToString();
                transfer.data       = "";
                transfer.depend     = "";
                transfer.nonce      = GetAccountNotice(transfer.addressIn, false);
                transfer.timestamp  = TimeHelper.Now();
                transfer.hash       = transfer.ToHash();
                transfer.sign       = transfer.ToSign(Wallet.GetWallet().keys[random1]);

                session2 = await OnTransferAsync2(transfer, session2);

                while (session2 == null)
                {
                    session2 = await OnTransferAsync2(transfer, session2);
                }
                ;
            }
        }
示例#15
0
        //从现在起 等待N毫秒后
        public ETTask WaitAsync(long time)
        {
            ETTaskCompletionSource tcs = new ETTaskCompletionSource();
            //创建Timer 并且生成ID 设定触发时间=当前时间+等待的时间 缓存ETTaskCompletionSource对象tcs
            Timer timer = new Timer {
                Id = IdGenerater.GenerateId(), Time = TimeHelper.Now() + time, tcs = tcs
            };

            //管理所有timer对象的字典
            this.timers[timer.Id] = timer;
            //管理所有时间相关的事件 key:时间 value:timerid 通过timerid可以找到以上的Timer对象
            //然后获取它的tcs ...
            this.timeId.Add(timer.Time, timer.Id);
            //这个事件的时间跟当前最近要触发的时间进行比较 如果小于 那么最近要触发的事件是这个 timer.Time
            if (timer.Time < this.minTime)
            {
                //则进行更新最近要触发的time
                this.minTime = timer.Time;
            }
            //返回tcs.Task 而非tcs,所以等待的是其内部的Task对象
            return(tcs.Task);
        }
示例#16
0
        public void Send(ByteStringArray data, ushort opcode)
        {
            if (this.IsDisposed)
            {
                throw new Exception("session已经被Dispose了");
            }
            this.LastSendTime = TimeHelper.Now();

            MemoryStream stream = this.Stream;

            stream.Seek(Packet.MessageIndex, SeekOrigin.Begin);
            stream.SetLength(Packet.MessageIndex);

            Array.Copy(data.data, 0, stream.GetBuffer(), Packet.MessageIndex, data.data.Length);
            stream.SetLength(Packet.MessageIndex + data.data.Length);

            stream.Seek(0, SeekOrigin.Begin);
            opcodeBytes.WriteTo(0, opcode);
            Array.Copy(opcodeBytes, 0, stream.GetBuffer(), 0, opcodeBytes.Length);

            this.Send(stream);
        }
示例#17
0
        // 每10s扫描一次过期的actorproxy进行回收,过期时间是1分钟
        public override async void Start(ActorProxyComponent self)
        {
            List <long> timeoutActorProxyIds = new List <long>();

            while (true)
            {
                await Game.Scene.GetComponent <TimerComponent>().WaitAsync(10000);

                if (self.IsDisposed)
                {
                    return;
                }

                timeoutActorProxyIds.Clear();

                long timeNow = TimeHelper.Now();
                foreach (long id in self.ActorProxys.Keys)
                {
                    ActorProxy actorProxy = self.Get(id);
                    if (actorProxy == null)
                    {
                        continue;
                    }

                    if (timeNow < actorProxy.LastSendTime + 60 * 1000)
                    {
                        continue;
                    }

                    timeoutActorProxyIds.Add(id);
                }

                foreach (long id in timeoutActorProxyIds)
                {
                    self.Remove(id);
                }
            }
        }
示例#18
0
        public void Update()
        {
            if (this.moveTcs == null)
            {
                return;
            }

            Unit unit    = this.GetParent <Unit>();
            long timeNow = TimeHelper.Now();

            if (timeNow - this.StartTime >= this.needTime)
            {
                unit.Position = this.Target;
                ETTaskCompletionSource tcs = this.moveTcs;
                this.moveTcs = null;
                tcs.SetResult();
                return;
            }

            float amount = (timeNow - this.StartTime) * 1f / this.needTime;

            unit.Position = Vector3.Lerp(this.StartPos, this.Target, amount);
        }
        public void FixedUpdate()
        {
            if (moveTcs != null)
            {
                var property_CharacterState = GetParent <Unit>().GetComponent <CharacterStateComponent>();
                if (property_CharacterState.Get(SpecialStateType.CantDoAction))
                {
                    Log.Debug("角色无法行动!");
                    OnMoveEnd();
                    return;
                }

                long timeNow = TimeHelper.Now();
                if (timeNow >= endTime || Vector3.Distance(unit.Position, this.moveTarget) < 0.01f)
                {
                    Log.Debug("行动结束!");
                    OnMoveEnd();
                    return;
                }

                if (moveType == MoveType.Move)
                {
                    float pitch = moveSpeed / baseMoveSpeed;
                    animatorComponent.SetAnimatorSpeed(pitch);
                    animatorComponent.SetBoolValue(CharacterAnim.Run, true);
                    GetParent <Unit>().GetComponent <AudioComponent>().PlayMoveSound(pitch);


                    unit.Rotation = Quaternion.Slerp(unit.Rotation, aimRotation, EventSystem.FixedUpdateTime * 15);
                }

                float amount = (timeNow - this.startTime) * 1f / needTime;

                unit.Position = Vector3.Lerp(this.startPosition, this.moveTarget, amount);
            }
        }
        public ETTask MoveTo(Vector3 target, float speed)
        {
            moveTarget = target;
            float distance = Vector3.Distance(unit.Position, moveTarget);

            if (distance < 0.02f)
            {
                return(ETTask.CompletedTask);
            }

            moveType      = MoveType.Move;
            moveSpeed     = speed;
            moveTcs       = new ETTaskCompletionSource();
            startPosition = unit.Position;
            moveDir       = (moveTarget - unit.Position).normalized;
            aimRotation   = Quaternion.LookRotation(moveDir, Vector3.up);
            startTime     = TimeHelper.Now();
            float time = distance / speed;

            needTime = (long)(time * 1000);
            endTime  = startTime + needTime;

            return(moveTcs.Task);
        }
示例#21
0
        public void Update()
        {
            if (this.timeId.Count == 0)
            {
                return;
            }

            long timeNow = TimeHelper.Now();

            timeOutId.Clear();

            while (this.timeId.Count > 0)
            {
                long k = this.timeId.FirstKey();
                if (k > timeNow)
                {
                    break;
                }
                foreach (long ll in this.timeId[k])
                {
                    this.timeOutId.Add(ll);
                }
                this.timeId.Remove(k);
            }

            foreach (long k in this.timeOutId)
            {
                Timer timer;
                if (!this.timers.TryGetValue(k, out timer))
                {
                    continue;
                }
                this.timers.Remove(k);
                timer.tcs.SetResult(true);
            }
        }
示例#22
0
        //没法准确的在那一刻恢复,但是可以降低调用频率,尤其服务器,每个Update调用太耗了
        public void FixedUpdate()
        {
            if (TimeHelper.Now() - timer.timing >= timer.interval)
            {
                timer.timing += timer.interval;
                NumericComponent numericComponent = this.Entity.GetComponent <NumericComponent>();

                CharacterStateComponent unitStateComponent = this.Entity.GetComponent <CharacterStateComponent>();
                if (!unitStateComponent.Get(SpecialStateType.Die))
                {
                    return;
                }
                if (numericComponent.GetAsFloat(NumericType.HP_RemainPct) < 1.0f)
                {
                    if (unitStateComponent.Get(SpecialStateType.InBattle))
                    {
                        GetHP(numericComponent.GetAsInt(NumericType.HP_Restore));
                    }
                    else
                    {
                        GetHP(Mathf.RoundToInt(numericComponent.GetAsFloat(NumericType.HPMax_Final) * restorePct_NotInBattle));
                    }
                }
                if (numericComponent.GetAsFloat(NumericType.MP_RemainPct) < 1.0f)
                {
                    if (unitStateComponent.Get(SpecialStateType.InBattle))
                    {
                        GetMP(numericComponent.GetAsInt(NumericType.MP_Restore));
                    }
                    else
                    {
                        GetMP(Mathf.RoundToInt(numericComponent.GetAsFloat(NumericType.MPMax_Final) * restorePct_NotInBattle));
                    }
                }
            }
        }
        public void Update()
        {
            if (this.moveTcs == null)
            {
                return;
            }

            Gamer gamer   = this.GetParent <Gamer>();
            long  timeNow = TimeHelper.Now();

            if (timeNow - this.StartTime >= this.needTime)
            {
                gamer.Position = this.Target;
                ETTaskCompletionSource tcs = this.moveTcs;
                this.moveTcs = null;
                tcs.SetResult();
                return;
            }

            float amount = (timeNow - this.StartTime) * 1f / this.needTime;

            //插值 Vector3.Lerp返回已走过的百分比的路径 amount为已走过的百分比
            gamer.Position = Vector3.Lerp(this.StartPos, this.Target, amount);
        }
示例#24
0
 public KService()
 {
     this.TimeNow = (uint)TimeHelper.Now();
     this.socket  = new UdpClient(new IPEndPoint(IPAddress.Any, 0));
     this.StartRecv();
 }
示例#25
0
 public long GetNodeTime()
 {
     return(TimeHelper.Now() + nodeTimeOffset);
 }
示例#26
0
        public async void Run(bool bRun)
        {
            await Task.Delay(1 * 1000);

            List <string> list = JsonHelper.FromJson <List <string> >(Program.jdNode["NodeSessions"].ToString());

            // Get Internet IP
            try
            {
                Session session = await networkInner.Get(NetworkHelper.ToIPEndPoint(list[0]));

                Q2P_IP_INFO qIPNode = new Q2P_IP_INFO();
                R2P_IP_INFO rIPNode = (R2P_IP_INFO)await session.Query(qIPNode, 0.3f);

                networkInner.ipEndPoint = NetworkHelper.ToIPEndPoint(GetIpV4() + ":" + networkInner.ipEndPoint.Port);
                if (rIPNode != null)
                {
                    networkInner.ipEndPoint = NetworkHelper.ToIPEndPoint(rIPNode.address + ":" + networkInner.ipEndPoint.Port);
                }
            }
            catch (Exception)
            {
            }
            Log.Info($"NodeManager  {networkInner.ipEndPoint.ToString()}");
            Log.Info($"NodeSessions {list[0]}");

            //
            Q2P_New_Node new_Node = new Q2P_New_Node();

            new_Node.ActorId    = GetMyNodeId();
            new_Node.address    = Wallet.GetWallet().GetCurWallet().ToAddress();
            new_Node.ipEndPoint = networkInner.ipEndPoint.ToString();

            long state     = 0;
            var  consensus = Entity.Root.GetComponent <Consensus>();

            if (consensus != null)
            {
                state |= consensus.transferShow ? EnumState.transferShow : 0;
                state |= consensus.openSyncFast ? EnumState.openSyncFast : 0;
            }
            state           |= Entity.Root.GetComponentInChild <RelayNetwork>() != null ? EnumState.RelayNetwork : 0;
            new_Node.state   = state;
            new_Node.version = BlockMgr.networkID;

            while (bRun && list.Count > 0)
            {
                try
                {
                    for (int ii = 0; ii < list.Count; ii++)
                    {
                        bool bResponse = false;
                        new_Node.HashCode = StringHelper.HashCode(JsonHelper.ToJson(nodes));
                        Session session = await networkInner.Get(NetworkHelper.ToIPEndPoint(list[ii]));

                        if (session != null && session.IsConnect())
                        {
                            //Log.Debug($"NodeSessions connect " + r2P_New_Node.ActorId);
                            //session.Send(new_Node);

                            long         sendTime     = TimeHelper.Now();
                            R2P_New_Node r2P_New_Node = (R2P_New_Node)await session.Query(new_Node, 3f);

                            if (r2P_New_Node != null)
                            {
                                long timeNow = TimeHelper.Now();
                                nodeTimeOffset = (timeNow - sendTime) / 2 + r2P_New_Node.nodeTime - timeNow;
                                if (!string.IsNullOrEmpty(r2P_New_Node.Nodes))
                                {
                                    nodes = JsonHelper.FromJson <List <NodeData> >(r2P_New_Node.Nodes);
                                }
                                if (!string.IsNullOrEmpty(r2P_New_Node.Message))
                                {
                                    Log.Warning($"NodeSessions: {r2P_New_Node.Message}");
                                }
                                bResponse = true;
                            }
                        }
                        if (bResponse)
                        {
                            break;
                        }
                    }

                    // 等待5秒后关闭连接
                    await Task.Delay(5 * 1000);
                }
                catch (Exception)
                {
                    await Task.Delay(5 * 1000);
                }
            }
        }
示例#27
0
 public ActorMessageSender(Action <IActorResponse> callback)
 {
     this.CreateTime = TimeHelper.Now();
     this.Callback   = callback;
 }
示例#28
0
 public void Awake()
 {
     this.LastSendTime            = TimeHelper.Now();
     this.tcs                     = null;
     this.CancellationTokenSource = new CancellationTokenSource();
 }
示例#29
0
 public void Awake()
 {
     timer          = TimeSpanHelper.GetTimer(this.GetHashCode());
     timer.interval = restoreTimeSpan;
     timer.timing   = TimeHelper.Now();
 }
示例#30
0
        public void ThreadRun(object data)
        {
            System.Threading.Thread.Sleep(1000);

            // check url
            rulerRpc = rulerRpc ?? Entity.Root.Find("SmartxRpc")?.GetComponent <SmartxRpc>()?.GetIPEndPoint();
            if (httpPoolRelay != null && GetHeight(rulerRpc, 5) == 0)
            {
                Log.Error($"rulerRpc: {rulerRpc} can't connect");
                System.Diagnostics.Process.GetCurrentProcess().Kill();
                return;
            }

            LoadTransferFromDB();

            List <TransferHandle>        transfersDel = new List <TransferHandle>();
            Dictionary <string, Account> accounts     = new Dictionary <string, Account>();
            var timePassInfo = new TimePass(15 * 6);

            while (true)
            {
                System.Threading.Thread.Sleep(1000);

                // Query success
                try
                {
                    lock (this)
                    {
                        if (runAction != null)
                        {
                            runAction?.Invoke();
                            runAction = null;
                            SaveTransferToDB();
                        }
                    }

                    if (!timePassInfo.IsPassSet())
                    {
                        continue;
                    }

                    transfersDel.Clear();
                    for (int ii = 0; ii < transfers.Count; ii++)
                    {
                        if (transfers[ii].sendCount <= 5)
                        {
                            if (string.IsNullOrEmpty(transfers[ii].unique))
                            {
                                transfersDel.Add(transfers[ii]);
                                continue;
                            }

                            var transfer = GetUniqueTransfer(rulerRpc, transfers[ii].unique);
                            if (transfer != null)
                            {
                                if (transfer.data == transfers[ii].unique && transfer.height != 0)
                                {
                                    transfers[ii].hash = transfer.hash;
                                    transfersDel.Add(transfers[ii]);
                                }
                            }
                        }
                        else
                        {
                            File.AppendAllText("./TransferBad.csv", JsonHelper.ToJson(transfers[ii]) + "\n", Encoding.UTF8);
                            transfersDel.Add(transfers[ii]);
                        }
                    }

                    using (DbSnapshot snapshot = Entity.Root.GetComponent <Pool>().PoolDBStore.GetSnapshot())
                    {
                        bool remove = transfersDel.Count != 0;
                        // Successfully deleted from table
                        foreach (var it in transfersDel)
                        {
                            if (!string.IsNullOrEmpty(it.unique) && !string.IsNullOrEmpty(it.hash))
                            {
                                snapshot.Add($"unique_{it.unique}", it.hash); // Add to transaction cross reference table
                            }
                            transfers.Remove(it);
                        }
                        if (remove)
                        {
                            snapshot.Commit();
                        }
                    }

                    accounts.Clear();

                    long curHeight = GetHeight(rulerRpc);
                    if (curHeight == 0)
                    {
                        Log.Warning($"rulerRpc: {rulerRpc} can't connect");
                        continue;
                    }

                    // Start a new deal
                    bool bSaveDb = false;
                    for (int ii = transfers.Count - 1; ii >= 0; ii--)
                    {
                        if (transfers[ii].lastHeight < curHeight - 18 && transfers[ii].sendCount <= 5)
                        {
                            transfers[ii].lastHeight = curHeight;
                            transfers[ii].sendCount++;

                            if (BigHelper.Less(transfers[ii].amount, "0", true))
                            {
                                transfers.RemoveAt(ii);
                                continue;
                            }

                            Account account = null;
                            if (!accounts.TryGetValue(transfers[ii].addressIn, out account))
                            {
                                account = GetAccount(rulerRpc, transfers[ii].addressIn);
                                if (account == null)
                                {
                                    continue;
                                }
                                accounts.Add(transfers[ii].addressIn, account);
                            }

                            BlockSub transfer = new BlockSub();
                            transfer.addressIn  = transfers[ii].addressIn;
                            transfer.addressOut = transfers[ii].addressOut;
                            transfer.amount     = transfers[ii].amount;
                            transfer.type       = "transfer";
                            transfer.nonce      = ++account.nonce;
                            transfer.timestamp  = TimeHelper.Now();
                            transfer.data       = transfers[ii].unique;
                            transfer.extend     = new List <string>();
                            //transfer.extend.Add($"deadline:{curHeight + 16}");
                            transfer.extend.Add($"unique");

                            transfer.hash = transfer.ToHash();
                            transfer.sign = transfer.ToSign(Wallet.GetWallet().GetCurWallet());

                            //int rel = Entity.Root.GetComponent<Rule>().AddTransfer(transfer, false);
                            int rel = SendTransfer(rulerRpc, transfer);
                            if (rel == -1)
                            {
                                transfers[ii].sendCount--;
                                continue;
                            }
                            if (rel != 1)
                            {
                                File.AppendAllText("./TransferBad.csv", JsonHelper.ToJson(transfers[ii]) + "\n", Encoding.UTF8);
                                Log.Error($"TransferProcess: aAddTransfer  Error! {rel}");
                                transfers.RemoveAt(ii);
                            }
                            bSaveDb = true;
                        }
                    }
                    if (bSaveDb)
                    {
                        SaveTransferToDB();
                    }
                }
                catch (Exception)
                {
                    Log.Warning($"TransferProcess throw Exception: {rulerRpc}");
                }
            }
        }