Ejemplo n.º 1
0
 /// <summary>
 /// Remove a item from the village task queue
 /// </summary>
 /// <param name="villageID">Which village the task queue belongs to</param>
 /// <param name="task">The item to delete from the task queue</param>
 private void RemoveQueuedTask()
 {
     MarkDeleted = true;
     UpCall.CallStatusUpdate(this, new Travian.StatusChanged()
     {
         ChangedData = Travian.ChangedType.Queue, VillageID = VillageID
     });
 }
Ejemplo n.º 2
0
        public void Action()
        {
            var CV = UpCall.TD.Villages[VillageID];

            if (NextExec >= DateTime.Now)
            {
                return;
            }
            NextExec = DateTime.Now.AddSeconds(rand.Next(150, 300));
            Dictionary <string, string> Postdata = new Dictionary <string, string>()
            {
                { "gid", "15" },
                { "a", VillageID.ToString() },
                { "abriss", Bid.ToString() },
                { "ok", "%E6%8B%86%E6%AF%81" }
            };

            UpCall.PageQuery(VillageID, "build.php", Postdata);

            int lvl = CV.InBuilding[2] != null && CV.InBuilding[2].FinishTime > DateTime.Now ? CV.InBuilding[2].Level : -1;

            if (lvl < 0)
            {
                UpCall.DebugLog("Unknown state: Destroy to -1", DebugLevel.W);
            }
            if (lvl <= 0)
            {
                MarkDeleted  = true;
                UpCall.Dirty = true;
                UpCall.CallStatusUpdate(this, new Travian.StatusChanged()
                {
                    ChangedData = Travian.ChangedType.Queue,
                    VillageID   = VillageID
                });
            }
            UpCall.BuildCount();
        }
Ejemplo n.º 3
0
        public void Action()
        {
            //	当前时刻还未到唤醒时刻
            if (MinimumDelay > 0)
            {
                return;
            }

            if (evade_status == EvadeStatus.NoAtkDetected ||
                evade_status == EvadeStatus.AtkDetected ||
                evade_status == EvadeStatus.TroopsBack)
            {
                CheckAttack();
            }
            else if (evade_status == EvadeStatus.ReadyForEvade)
            {
                DoEvade();
            }
            else if (evade_status == EvadeStatus.Evaded ||
                     evade_status == EvadeStatus.ReadyForBack)
            {
                evade_status = EvadeStatus.ReadyForBack;
                DoTroopsBack();
            }
            else
            {
                evade_status = EvadeStatus.NoAtkDetected;
                MinimumDelay = nMinInterval;
            }

            UpCall.TD.Dirty = true;
            UpCall.CallStatusUpdate(this, new Travian.StatusChanged()
            {
                ChangedData = Travian.ChangedType.Queue, VillageID = VillageID
            });
        }
Ejemplo n.º 4
0
        public void Action()
        {
            var    CV = UpCall.TD.Villages[VillageID];
            int    GID;
            var    Q = this;
            string mat_str, id, c;
            Match  m;
            string result;

            switch (ResearchType)
            {
            case TResearchType.Research:
                if (!CV.Upgrades[Aid].CanResearch)
                {
                    MarkDeleted  = true;
                    UpCall.Dirty = true;
                    UpCall.CallStatusUpdate(this, new Travian.StatusChanged()
                    {
                        ChangedData = Travian.ChangedType.Queue, VillageID = VillageID
                    });
                    return;
                }
                GID    = 22;
                result = UpCall.PageQuery(VillageID, "build.php?gid=" + GID.ToString());
                if (result == null)
                {
                    return;
                }
                mat_str = "'build.php\\?id=(\\d+)&amp;a=" + Aid.ToString() + "&amp;c=([^']*?)'";
                m       = Regex.Match(result, mat_str);
                if (!m.Success)
                {
                    return;
                }
                id     = m.Groups[1].Value;
                c      = m.Groups[2].Value;
                result = UpCall.PageQuery(VillageID, "build.php?id=" + id + "&a=" + Aid.ToString() + "&c=" + c);
                break;

            case TResearchType.UpTroopLevel:
                if (TargetLevel != 0 && CV.Upgrades[Aid].troop_lvl >= TargetLevel || CV.Upgrades[Aid].troop_lvl >= CV.SmithyLevel)
                {
                    MarkDeleted  = true;
                    UpCall.Dirty = true;
                    UpCall.CallStatusUpdate(this, new Travian.StatusChanged()
                    {
                        ChangedData = Travian.ChangedType.Queue, VillageID = VillageID
                    });
                    return;
                }
                GID    = 13;
                result = UpCall.PageQuery(VillageID, "build.php?gid=" + GID.ToString());
                if (result == null)
                {
                    return;
                }
                mat_str = "'build.php\\?id=(\\d+)&amp;a=" + Aid.ToString() + "&amp;c=([^']*?)'";
                m       = Regex.Match(result, mat_str, RegexOptions.Singleline);
                if (!m.Success)
                {
                    return;
                }
                id     = m.Groups[1].Value;
                c      = m.Groups[2].Value;
                result = UpCall.PageQuery(VillageID, "build.php?id=" + id + "&a=" + Aid.ToString() + "&c=" + c);
                break;

            default:
                return;
            }
            UpCall.BuildCount();

            if (TargetLevel == 0 || ResearchType == TResearchType.Research)
            {
                MarkDeleted  = true;
                UpCall.Dirty = true;
                UpCall.CallStatusUpdate(this, new Travian.StatusChanged()
                {
                    ChangedData = Travian.ChangedType.Queue, VillageID = VillageID
                });
            }
            else if (ResearchType == TResearchType.UpTroopLevel)
            {
                if (CV.Upgrades[Aid].troop_lvl >= TargetLevel || CV.Upgrades[Aid].troop_lvl >= CV.SmithyLevel)
                {
                    MarkDeleted  = true;
                    UpCall.Dirty = true;
                    UpCall.CallStatusUpdate(this, new Travian.StatusChanged()
                    {
                        ChangedData = Travian.ChangedType.Queue, VillageID = VillageID
                    });
                }
            }

            UpCall.CallStatusUpdate(this, new Travian.StatusChanged()
            {
                ChangedData = Travian.ChangedType.Research, VillageID = VillageID
            });
        }
Ejemplo n.º 5
0
        private bool FetchAvailGidAndBidWithlvl(TVillage CV, out int gid, out int bid)
        {
            bid = -1;
            gid = 0;

            //	按资源田等级
            int i;
            int minlevel = 10;

            int[] buildpriority   = new int[5];
            bool  bIsCroopsAbove5 = false;

            //	以粮食的最低等级划分判定区域,避免初期粮食过少
            for (i = 1; i <= 18; i++)
            {
                if (!CV.Buildings.ContainsKey(i) || CV.Buildings[i].Gid != 4)
                {
                    continue;
                }
                var tlevel = CV.Buildings[i].Level;
                if (tlevel < minlevel)
                {
                    minlevel = tlevel;
                }
            }

            if (minlevel >= 5)
            {
                bIsCroopsAbove5 = true;
            }

            minlevel = 10;

            //	找到所有资源田的最低等级
            for (i = 1; i <= 18; i++)
            {
                if (!CV.Buildings.ContainsKey(i))
                {
                    continue;
                }

                var tlevel = 0;
                if (bIsCroopsAbove5)
                {
                    tlevel = CV.Buildings[i].Gid != 4 ? CV.Buildings[i].Level : CV.Buildings[i].Level + 1;
                }
                else
                {
                    tlevel = CV.Buildings[i].Level;
                }
                if (tlevel < minlevel)
                {
                    minlevel = tlevel;
                }
            }

            //	找到等级最低资源田的种类和坑号
            int min = 1;

            for (i = 1; i <= 18; i++)
            {
                if (!CV.Buildings.ContainsKey(i))
                {
                    continue;
                }

                var tlevel = 0;
                if (bIsCroopsAbove5)
                {
                    tlevel = CV.Buildings[i].Gid != 4 ? CV.Buildings[i].Level : CV.Buildings[i].Level + 1;
                }
                else
                {
                    tlevel = CV.Buildings[i].Level;
                }
                if (tlevel == minlevel && buildpriority[CV.Buildings[i].Gid] == 0)
                {
                    min = CV.Buildings[i].Gid - 1;
                    buildpriority[CV.Buildings[i].Gid] = i;
                }
            }

            //	如果有多种资源田同级,则按资源的评估比率确定升级的资源田
            for (i = 0; i < 4; i++)
            {
                if (CV.Resource[min].CurrAmount / Travian.resrate[min] >
                    CV.Resource[i].CurrAmount / Travian.resrate[i] &&
                    buildpriority[i + 1] != 0)
                {
                    min = i;
                }
            }
            gid = min + 1;
            bid = buildpriority[gid];

            //	如果最低等级为10级,则查找等级低于10级的粮食
            if (minlevel == 10)
            {
                bool croop = false;
                for (i = 1; i <= 18; i++)
                {
                    if (!CV.Buildings.ContainsKey(i))
                    {
                        continue;
                    }
                    var tlevel = CV.Buildings[i].Level;
                    if (tlevel < 10)
                    {
                        gid   = CV.Buildings[i].Gid;
                        bid   = i;
                        croop = true;
                        break;
                    }
                }

                int finish_cnt = 0;
                for (i = 19; i <= 40; i++)
                {
                    if (!CV.Buildings.ContainsKey(i))
                    {
                        continue;
                    }

                    for (int j = 0; j < Goal.Length; j++)
                    {
                        if (CV.Buildings[i].Gid == Goal[j].gid &&
                            CV.Buildings[i].Level == Goal[j].limit_lvl)
                        {
                            finish_cnt++;
                            break;
                        }
                    }
                }

                //	如果所有资源田都满级了,那么删除掉该任务
                if (croop == false && finish_cnt == Goal.Length && CV.Queue.Contains(this))
                {
                    MarkDeleted     = true;
                    UpCall.TD.Dirty = true;
                    UpCall.CallStatusUpdate(this, new Travian.StatusChanged()
                    {
                        ChangedData = Travian.ChangedType.Queue,
                        VillageID   = VillageID
                    });
                    return(false);
                }
            }

            return(true);
        }
Ejemplo n.º 6
0
		public void Action()
		{
			BuildingQueue Q = this;
			var CV = UpCall.TD.Villages[VillageID];

			if(Q.NextExec >= DateTime.Now)
				return;
			Q.NextExec = DateTime.Now.AddSeconds(60);
			
			int Bid = UpCall.testPossibleNow(VillageID, Q);
			//	-1表示目前无法建造
			if(Bid == -1)
			{
				Q.MarkDeleted = true;
				UpCall.DebugLog("Delete Queue [" + Q.Title + "] because it's impossible to build it.", DebugLevel.W);
				return;
			}
			//	0表示建造该建筑先要造某种别的建筑
			if(Bid != 0)
			{
				UpCall.DebugLog("Queue [" + Q.Title + "] needs Bid=" + Bid.ToString() + " to be extended.", DebugLevel.I);
				Q = new BuildingQueue() { UpCall = UpCall, Bid = Bid, Gid = CV.Buildings[Bid].Gid };
				UpCall.DebugLog("Create Queue [" + Q.Title + "] because it needs to be extended.", DebugLevel.I);
			}

			int bid = Q.Bid;
			int gid = Q.Gid;
			string result;
			result = UpCall.PageQuery(VillageID, "dorf1.php");
			if(result == null)
				return;
			List<int> nMilitaries = new List<int> {13, 14, 19, 20, 21, 22, 29, 30, 31, 32, 33, 36, 37};
			List<int> nResources = new List<int> {5, 6, 7, 8, 9};
			string url = "build.php?id=" + bid.ToString();
			if (nMilitaries.Contains(gid))
			{
				url += "&category=2";
			}
			else if (nResources.Contains(gid))
			{
				url += "&category=3";
			}
			else if (gid == 17)
			{
				url += "&t=0";
			}
			result = UpCall.PageQuery(VillageID, url);
			if(result == null)
				return;
			
			//	m用来解析新建建筑,n用来解析建筑升级
			Match m, n;
			m = Regex.Match(result, "(dorf(\\d)\\.php\\?a=" + gid + "&amp;id=" + bid + "&amp;c=[^\']*?)';\\sreturn");
			n = Regex.Match(result, "(dorf(\\d)\\.php\\?a=" + bid + "&amp;c=[^\']*?)';\\sreturn");
			if(!m.Success && !n.Success)
			{
				// check reason
				/*
				 * <span class="c">已经有建筑在建造中</span>
				 * <div class="c">资源不足</div>
				 * <p class="c">伐木场建造完成</p>
				 * <span class="c">建造所需资源超过仓库容量上限,请先升级你的仓库</span>
				 * <span class="c">粮食产量不足: 需要先建造一个农场</span>
				 * 
				 */
				int RomaNeedCrop = -1;
				//	仓库容量不足的话,先造仓库
				if(gid != 10 && UpCall.GidLang.ContainsKey(10) && Regex.Match(result, "<span class=\"(c|none)\">[^<]*?" + UpCall.GetGidLang(10) + "[^<]*?</span>", RegexOptions.IgnoreCase).Success)
				{
					gid = 10;
					bid = findBuilding(VillageID, gid);
				}
				//	粮食产量不足的话,先造农场
                else if (gid != 11 && UpCall.GidLang.ContainsKey(11) && Regex.Match(result, "<span class=\"(c|none)\">[^<]*?" + UpCall.GetGidLang(11) + "[^<]*?</span>", RegexOptions.IgnoreCase).Success)
				{
					gid = 11;
					bid = findBuilding(VillageID, gid);
				}
                else if (gid != 4 && UpCall.GidLang.ContainsKey(4) && Regex.Match(result, "<span class=\"(c|none)\">[^<]*?" + UpCall.GetGidLang(4) + "[^<]*?</span>", RegexOptions.IgnoreCase).Success)
				{
                	if (UpCall.TD.isRomans && CV.InBuilding[0] != null && Q.Bid > 18)
                	{
                		if (CV.InBuilding[0].Gid != 4)
                			RomaNeedCrop = 1;
                		else if (CV.InBuilding[0].Gid == 4)
                		{
                			RomaNeedCrop = 0;
                			return;
                		}
                		UpCall.DebugLog("Roma NEED Crop rule", DebugLevel.W);
                		Q.NextExec = CV.InBuilding[0].FinishTime.AddSeconds(30);
                	}
                	gid = 4;
                	bid = findBuilding(VillageID, gid);
				}
                else if (result.Contains("<p class=\"(c|none)\">"))
				{
					UpCall.DebugLog("Unexpected status! Report it on the forum! " + Q.Title, DebugLevel.W);
					Q.MarkDeleted = true;
					UpCall.CallStatusUpdate(this, new Travian.StatusChanged() { ChangedData = Travian.ChangedType.Queue, VillageID = VillageID });
					return;
				}
                else if (UpCall.GidLang.ContainsKey(gid) && Regex.Match(result, "<span class=\"(c|none)\">[^<]*?" + UpCall.GetGidLang(gid) + "[^<]*?</span>", RegexOptions.IgnoreCase).Success)
					return;
                else if (result.Contains("<span class=\"(c|none)\">"))
				{
					//Q.Delay = rand.Next(500, 1000);
					// Delay shouldn't happen.
					Q.NextExec = DateTime.Now.AddSeconds(rand.Next(150, 300));
					UpCall.DebugLog("Data not refreshed? Add delay for " + Q.Title, DebugLevel.I);
					return;
				}
				else
				{
					UpCall.PageQuery(VillageID, "dorf1.php");
					UpCall.PageQuery(VillageID, "dorf2.php");
					UpCall.DebugLog("Unknown status! And cause a queue been deleted! " + Q.Title, DebugLevel.W);
					//Q.MarkDeleted = true;
					//UpCall.CallStatusUpdate(this, new Travian.StatusChanged() { ChangedData = Travian.ChangedType.Queue, VillageID = VillageID });
					Q.NextExec = DateTime.Now.AddSeconds(rand.Next(150, 300));
					return;
				}
				
				// 检查资源是否足够
				int timecost;
				if(CV.Buildings.ContainsKey(bid))
					timecost = CV.TimeCost(Buildings.Cost(gid, CV.Buildings[bid].Level + 1));
				else
					timecost = CV.TimeCost(Buildings.Cost(gid, 1));
				if(CV.InBuilding[UpCall.TD.isRomans && bid > 18 ? 1 : 0] != null)
					timecost = Math.Max(timecost, Convert.ToInt32(DateTime.Now.Subtract(CV.InBuilding[UpCall.TD.isRomans && bid > 18 ? 1 : 0].FinishTime).TotalSeconds));
				if(timecost > 0 || RomaNeedCrop == 1)
				{
					UpCall.DebugLog("Need to build but resource not enough so add into queue: " + Q.Title, DebugLevel.I);
					CV.Queue.Insert(0, new BuildingQueue()
					{
						UpCall = UpCall,
						VillageID = VillageID,
						Bid = bid,
						Gid = gid
					});
					UpCall.CallStatusUpdate(this, new Travian.StatusChanged() { ChangedData = Travian.ChangedType.Queue, VillageID = VillageID });

					return;
				}
				result = UpCall.PageQuery(VillageID, "build.php?id=" + bid.ToString());
				if(result == null)
					return;
				m = Regex.Match(result, "(dorf(\\d)\\.php\\?a=" + gid + "&amp;id=" + bid + "&c=[^\']*?)'");
				n = Regex.Match(result, "(dorf(\\d)\\.php\\?a=" + bid + "&amp;c=[^\']*?)'");
				if(!m.Success && !n.Success)
				{
					UpCall.DebugLog("Unknown error on building " + Q.Title, DebugLevel.E);
					Q.MarkDeleted = true;
					UpCall.CallStatusUpdate(this, new Travian.StatusChanged() { ChangedData = Travian.ChangedType.Queue, VillageID = VillageID });
					return;
				}
			}

			// New building
			int qtype = bid < 19 && bid > 0 ? 0 : 1;

			if(CV.Buildings.ContainsKey(bid))
				CV.RB[UpCall.TD.isRomans ? qtype : 0] = new TInBuilding() { ABid = bid, Gid = gid, Level = CV.Buildings[bid].Level };
			else
				CV.RB[UpCall.TD.isRomans ? qtype : 0] = new TInBuilding() { ABid = bid, Gid = gid, Level = 1 };
			
			//	执行建造操作
			string uri;
			if(m.Success)
			{
				uri = m.Groups[1].Value.Replace("amp;", "");
				UpCall.PageQuery(VillageID, uri);
			}
			else
			{
				uri = n.Groups[1].Value.Replace("amp;", "");
				UpCall.PageQuery(VillageID, uri);
			}
			UpCall.BuildCount();

			if(Q.Bid == bid)
				UpCall.DebugLog("Build " + Q.Title, DebugLevel.I);
			else
				UpCall.DebugLog("Build (other) " + Q.Title, DebugLevel.I);
			
			if(Q.Bid == bid)
			{
				if(Q.TargetLevel == 0 || Q.TargetLevel <= CV.Buildings[bid].Level)
				{
					Q.MarkDeleted = true;
					UpCall.CallStatusUpdate(this, new Travian.StatusChanged() { ChangedData = Travian.ChangedType.Queue, VillageID = VillageID });
				}
			}
			UpCall.CallStatusUpdate(this, new Travian.StatusChanged() { ChangedData = Travian.ChangedType.Buildings, VillageID = VillageID });
		}
Ejemplo n.º 7
0
        public void Action()
        {
            if (MinimumDelay > 0)
            {
                return;
            }

            string data = UpCall.CheckBuildingExistAndQuery(VillageID, 16);

            if (data == null)
            {
                MinimumDelay = 60;
                return;
            }

            hero_status = CheckIfHeroHome();
            if (hero_status == -1)
            {
                UpCall.CallStatusUpdate(this, new Travian.StatusChanged()
                {
                    ChangedData = Travian.ChangedType.Queue,
                    VillageID   = VillageID
                });
                UpCall.DebugLog("英雄不属于该村,无法探险!", DebugLevel.II);
                MarkDeleted = true;
                return;
            }
            else if (hero_status == 1)
            {
                UpCall.CallStatusUpdate(this, new Travian.StatusChanged()
                {
                    ChangedData = Travian.ChangedType.Queue,
                    VillageID   = VillageID
                });
                UpCall.DebugLog("英雄目前不在家,等待英雄返回!", DebugLevel.II);
                return;
            }

            bool bAvail = false;
            List <HeroAdventureInfo> InfoList = UpCall.TD.Adv_Sta.HeroAdventures;

            for (int i = 0; i < InfoList.Count; i++)
            {
                TimeSpan ts = CheckDurAvail(InfoList[i].duration);
                if (ts == TimeSpan.MinValue)
                {
                    continue;
                }
                bAvail = true;
                break;
            }

            //	如果当前的探险地方尚未初始化或全部都不合适,则尝试重新抓取
            if (!UpCall.TD.Adv_Sta.bIsHeroAdventureInitialize || !bAvail)
            {
                UpCall.doFetchHeroAdventures(VillageID);
            }

            cur_adv_pt = new TPoint(0, 0);
            int HeroLoc = UpCall.TD.Adv_Sta.HeroLocate;

            for (int i = 0; i < InfoList.Count; i++)
            {
                TimeSpan ts = CheckDurAvail(InfoList[i].duration);
                if (ts == TimeSpan.MinValue)
                {
                    UpCall.DebugLog(
                        "跳过(" + InfoList[i].axis_x + "|" + InfoList[i].axis_y + ")的探险",
                        DebugLevel.II);
                    continue;
                }

                TPoint tp = new TPoint(InfoList[i].axis_x, InfoList[i].axis_y);
                data = UpCall.PageQuery(HeroLoc, "start_adventure.php?from=list&kid=" + tp.Z.ToString());
                if (data == null)
                {
                    continue;
                }
                Match m_test = Regex.Match(data, "type=\"submit\" value=\".*?\" name=\"start\"");
                if (!m_test.Success)
                {
                    continue;
                }

                Dictionary <string, string> PostData = new Dictionary <string, string>();
                MatchCollection             mc       = Regex.Matches(
                    data, "<input type=\"hidden\" name=\"([^\"]*?)\" value=\"([^\"]*?)\" />");
                string key, val;
                foreach (Match m in mc)
                {
                    key           = m.Groups[1].Value;
                    val           = m.Groups[2].Value;
                    PostData[key] = val;
                }
                UpCall.PageQuery(HeroLoc, "start_adventure.php", PostData);
                UpCall.PageQuery(HeroLoc, "build.php?gid=16&tt=1");

                MinimumDelay = Convert.ToInt32(ts.TotalSeconds);
                cur_adv_pt   = tp;
                break;
            }

            if (cur_adv_pt.IsEmpty)
            {
                MinimumDelay = 3600;
                UpCall.DebugLog("探险位置不存在或行程过长", DebugLevel.II);
            }
            else
            {
                UpCall.DebugLog("前往(" + cur_adv_pt.X + "|" + cur_adv_pt.Y + ")探险", DebugLevel.II);
            }
            hero_status = 2;
            UpCall.CallStatusUpdate(this, new Travian.StatusChanged()
            {
                ChangedData = Travian.ChangedType.Queue,
                VillageID   = VillageID
            });
        }