public void Action() { var CV = UpCall.TD.Villages[VillageID]; UpCall.PageQuery(VillageID, "build.php?gid=24&a=" + ((int)PartyType).ToString()); LastExec = DateTime.Now; if(CV.InBuilding[5] == null || CV.InBuilding[5].FinishTime < DateTime.Now) { // error occurred! retrycount++; if(retrycount > 10) { UpCall.DebugLog("Error on party for several times! Delete the queue!", DebugLevel.W); MarkDeleted = true; } else { UpCall.DebugLog("Error on party! Will retry...", DebugLevel.I); NextExec = DateTime.Now.AddSeconds(rand.Next(500 + retrycount * 20, 800 + retrycount * 30)); } UpCall.Dirty = true; } else { UpCall.BuildCount(); retrycount = 0; } }
/// <summary> /// Wrapper of the real doTransfer function, which /// 1) Verify that the tranfer amount is valid (non-zero) /// 2) Verify that merchant dispatched for the same mission has returned. /// 3) Recalculate the transfer amount for dynamic resource balance /// 4) Verify that the transfer won't overflow the arrival village's warehouse/granary /// 5) Update task status after a successful merchan dispatch /// 6) Remove the task from the village queue when it's no longer valid/needed /// </summary> public void Action() { if (!IsValid) { UpCall.DebugLog("Invalid transfer task discarded: " + Title, DebugLevel.W); this.RemoveQueuedTask(); return; } if (MinimumDelay > 0) { return; } TResAmount toTransfer = new TResAmount(ResourceAmount); if (TargetVillageID != 0 && UpCall.TD.Villages.ContainsKey(TargetVillageID) && UpCall.TD.Villages[TargetVillageID].isBuildingInitialized == 2) { UpCall.PageQuery(TargetVillageID, "build.php?gid=17&t=5"); CalculateResourceAmount(UpCall.TD, VillageID); // check if it's a crop transfer, and crop is seriously needed from target village: if (UpCall.TD.Villages[TargetVillageID].Resource[3].Produce < 0) { var temp = NeedCrop(UpCall.TD); if (temp != null) { UpCall.DebugLog("NeedCrop rule on use. Force crop transfer.", DebugLevel.I); toTransfer = temp; } else if (ExceedTargetCapacity(UpCall.TD)) { return; } } } else { CalculateResourceAmount(UpCall.TD, VillageID); } int timeCost = doTransfer(toTransfer, TargetPos); UpCall.PageQuery(VillageID, "build.php?gid=17&t=5"); if (timeCost >= 0) { var CV = UpCall.TD.Villages[VillageID]; MinimumDelay = Math.Max(MinimumInterval, timeCost * 2 + 30); Count++; if (MaxCount != 0 && Count >= MaxCount) { RemoveQueuedTask(); } } }
private void DoTroopsBack() { string data = UpCall.PageQuery(VillageID, "build.php?gid=16&tt=1"); if (data == null) { MinimumDelay = 0; return; } Match m = Regex.Match(data, "<a href=\"karte\\.php\\?d=" + tpEvadePoint.Z + "\">[^<]*?</a>" + ".*?onclick=\"window\\.location\\.href = \'([^\']*?)\'", RegexOptions.Singleline); if (!m.Success) { evade_status = EvadeStatus.NoAtkDetected; MinimumDelay = nMinInterval; return; } string url = m.Groups[1].Value.Replace("amp;", ""); data = UpCall.PageQuery(VillageID, url); if (data == null) { MinimumDelay = 0; return; } MatchCollection mc = Regex.Matches(data, "<input type=\"hidden\" name=\"([^\"]*?)\" value=\"([^\"]*?)\">"); Dictionary <string, string> postData = new Dictionary <string, string>(); foreach (Match m1 in mc) { postData.Add(m1.Groups[1].Value, m1.Groups[2].Value); } for (int i = 0; i < ReinforceToop.Length; i++) { if (ReinforceToop[i] == 0) { continue; } string troopKey = String.Format("t[{0}]", i + 1); string troopNumber = ReinforceToop[i].ToString(); postData.Add(troopKey, troopNumber); } postData.Add("s1", "ok"); UpCall.PageQuery(VillageID, "build.php", postData); evade_status = EvadeStatus.TroopsBack; MinimumDelay = ReinforceTimeCost + RandomDelay(5, 10); }
TAttacker ParseAttacker(TTInfo troop) { string data = UpCall.PageQuery(VillageID, troop.OwnerVillageUrl, null, true, true); if (string.IsNullOrEmpty(data)) { return(null); } string name = "", ally = ""; int uid = 0, popu = 0; string pattern = "allianz\\.php\\?aid=\\d+\">(.*?)</a></td>" + "[^<]*?</tr>[^<]*?<tr>[^<]*?<th>[^<]*?</th>[^<]*?<td><a href=\"spieler\\.php\\?uid=(\\d+)\">(.*?)</a></td>" + "[^<]*?</tr>[^<]*?<tr>[^<]*?<th>[^<]*?</th>[^<]*?<td>(\\d+)</td>"; Regex reg = new Regex(pattern); Match m = reg.Match(data); if (m.Success) { ally = m.Groups[1].Value; uid = int.Parse(m.Groups[2].Value); name = m.Groups[3].Value; popu = int.Parse(m.Groups[4].Value); } else { return(null); } TPoint point = new TPoint(); point.Z = troop.OwnerVillageZ; TAttacker attacker = new TAttacker { Point = point, Tribe = troop.Tribe, troops = new List <TTInfo>(), VileageName = troop.Owner, Ally = ally, Name = name, Uid = uid, Population = popu, }; return(attacker); }
private void CheckAttack() { var CV = UpCall.TD.Villages[VillageID]; UpCall.PageQuery(VillageID, "build.php?gid=16&tt=1"); latest_toop = null; foreach (TTInfo tt in CV.Troop.Troops) { AnalizeAttacker(tt); } if (latest_toop != null) { int latest_atk_delay = (int)latest_toop.FinishTime.Subtract(DateTime.Now).TotalSeconds; if (latest_atk_delay > nMinInterval + nLeadTime) { MinimumDelay = nMinInterval; evade_status = EvadeStatus.AtkDetected; } else if (latest_atk_delay > nLeadTime && latest_atk_delay <= nMinInterval + nLeadTime) { MinimumDelay = latest_atk_delay - nLeadTime; evade_status = EvadeStatus.ReadyForEvade; } else if (latest_atk_delay > 0 && latest_atk_delay <= nLeadTime) { MinimumDelay = 0; evade_status = EvadeStatus.ReadyForEvade; } else { UpCall.DebugLog("由于出现异常,重置回避攻击检查队列。", DebugLevel.II); latest_toop = null; MinimumDelay = nMinInterval; evade_status = EvadeStatus.NoAtkDetected; } } else { MinimumDelay = nMinInterval; evade_status = EvadeStatus.NoAtkDetected; } }
public void Action() { // 当前时刻还未到唤醒时刻 if (MinimumDelay > 0) { return; } var cv = UpCall.TD.Villages[VillageID]; if (!HasGetAll) { string data = UpCall.PageQuery(VillageID, "build.php?gid=16&tt=1"); InitAttackers(); } foreach (TTInfo tt in cv.Troop.Troops) { AddAtacker(tt); } if (BeAttacked) { AnalizeAttacker(); if (SendMail()) { TotalCount++; this.MinimumDelay = this.MinimumInterval + new Random().Next(60, 300); } else { this.MinimumDelay = new Random().Next(300, 600); } } else { this.MinimumDelay = this.MinimumInterval + new Random().Next(60, 300); } // 延迟时间需要超过最小时间间隔,唤醒时刻到达后才会重新刷新集结点 HasGetAll = !(this.MinimumDelay > this.MinimumInterval); }
public void Action() { if (MinimumDelay > 0) { return; } int page = 1; string link, data; int result = -1; bool mail_sent = false; ClearPMSender(); do { link = "nachrichten.php?&o=0&page=" + page.ToString(); data = UpCall.PageQuery(VillageID, link); result = PMParse(data); if (result == 1) { page++; } if (result != -1 && SendMail() == true && mail_sent == false) { mail_sent = true; } } while (result == 1); if (mail_sent) { TotalCount++; this.MinimumDelay = this.MinimumInterval + new Random().Next(0, 60); } else { this.MinimumDelay = new Random().Next(60, 120); } }
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(); }
public void Action() { if (CountDown > 0) { return; } int key = (UpCall.TD.Tribe - 1) * 10 + Aid; int Gid; Gid = GRt ? AIDMapg[key] : AIDMap[key]; if (GRt && (Aid == 7 || Aid == 8) || Gid == 0) { UpCall.DebugLog("Not appropriate kind of troop to produce, deleted.", DebugLevel.W); MarkDeleted = true; return; } string url = "build.php?gid=" + Gid; if (Gid == 25) { url += "&s=1"; } string data = UpCall.PageQuery(VillageID, url); if (data == null) { return; } if (!data.Contains(string.Format("name=\"t{0}\"", Aid))) { UpCall.DebugLog("Cannot produce this kind of troop before research it.", DebugLevel.W); MarkDeleted = true; return; } /* * id 34 * z 10021 * a 2 * t1 2000 * t3 0 * s1.x 60 * s1.y 16 * s1 ok * <input type="hidden" name="id" value="34"> * <input type="hidden" name="z" value="65535"> * <input type="hidden" name="a" value="2"> * */ string p_a, p_id, p_z; Match m; m = Regex.Match(data, "type=\"hidden\" name=\"id\" value=\"(\\d+?)\""); if (m.Success) { p_id = m.Groups[1].Value; } else { UpCall.DebugLog("Parse id error!", DebugLevel.F); MarkDeleted = true; return; } m = Regex.Match(data, "type=\"hidden\" name=\"z\" value=\"(\\w+?)\""); if (m.Success) { p_z = m.Groups[1].Value; } else { UpCall.DebugLog("Parse z error!", DebugLevel.F); MarkDeleted = true; return; } m = Regex.Match(data, "type=\"hidden\" name=\"a\" value=\"(\\d+?)\""); if (m.Success) { p_a = m.Groups[1].Value; } else { UpCall.DebugLog("Parse a error!", DebugLevel.F); MarkDeleted = true; return; } Dictionary <string, string> PostData = new Dictionary <string, string>(); PostData["id"] = p_id; PostData["z"] = p_z; PostData["a"] = p_a; PostData["s1.x"] = rand.Next(10, 70).ToString(); PostData["s1.y"] = rand.Next(3, 17).ToString(); PostData["s1"] = "ok"; PostData["t" + Aid] = Amount.ToString(); data = UpCall.PageQuery(VillageID, "build.php", PostData); LastExec = DateTime.Now; NextExec = LastExec.AddSeconds(MinimumInterval); Count++; if (MaxCount != 0 && Count >= MaxCount) { MarkDeleted = true; } }
public void Action() { if (CountDown > 0) { return; } if (Targets[TargetID].IsEmpty) { UpCall.DebugLog("Target Is Error!!", DebugLevel.F); MarkDeleted = true; return; } if (Settlers) { var result = UpCall.PageQuery(VillageID, "build.php?id=39&tt=2&z=" + Targets[TargetID].Z.ToString()); if (result == null) { return; } Match m; m = Regex.Match(result, "type=\"submit\" value=\"ok\" name=\"s1\""); if (m.Success) { Dictionary <string, string> PostDataST = new Dictionary <string, string>(); PostDataST["a"] = "1"; PostDataST["s"] = Targets[TargetID].Z.ToString(); PostDataST["id"] = "39"; PostDataST["s1.x"] = rand.Next(40, 70).ToString(); PostDataST["s1.y"] = rand.Next(3, 17).ToString(); PostDataST["s1"] = "ok"; var datast = UpCall.PageQuery(VillageID, "build.php", PostDataST); } else { UpCall.DebugLog("Unable to Settlers", DebugLevel.F); } MarkDeleted = true; return; } List <Dictionary <string, string> > PostDataALL = new List <Dictionary <string, string> >(); for (int w = 0; w < wWaves.Count; w++) { for (int j = 0; j < wWaves[w]; j++) { Dictionary <string, string> PostData = new Dictionary <string, string>(); var data = UpCall.PageQuery(VillageID, "build.php?tt=2&id=39"); Match m10; m10 = Regex.Match(data, "type=\"hidden\" name=\"timestamp\" value=\"([^>]*?)\""); string p_timestamp = m10.Groups[1].Value; Match m11; m11 = Regex.Match(data, "type=\"hidden\" name=\"timestamp_checksum\" value=\"([^>]*?)\""); string p_timestamp_checksum = m11.Groups[1].Value; PostData["timestamp"] = p_timestamp; PostData["timestamp_checksum"] = p_timestamp_checksum; PostData["b"] = "1"; PostData["dname"] = ""; PostData["x"] = Targets[TargetID].X.ToString(); PostData["y"] = Targets[TargetID].Y.ToString(); PostData["s1.x"] = rand.Next(40, 70).ToString(); PostData["s1.y"] = rand.Next(3, 17).ToString(); PostData["s1"] = "ok"; if (Raidtype > 4) { PostData["c"] = "4"; } else { PostData["c"] = Raidtype.ToString(); } for (int i = 1; i < 12; i++) { PostData["t" + i] = wTroops[w].Troops[i - 1].ToString(); } Dictionary <string, string> PostDataF = new Dictionary <string, string>(); var result = UpCall.PageQuery(VillageID, "build.php?tt=2&id=39", PostData); if (result.Contains("<p class=\"error\">")) { UpCall.DebugLog("Target is Error!!", DebugLevel.W); MarkDeleted = true; return; } Match m20; m20 = Regex.Match(result, "type=\"hidden\" name=\"timestamp\" value=\"([^>]*?)\""); string p_timestampF = m20.Groups[1].Value; Match m21; m21 = Regex.Match(result, "type=\"hidden\" name=\"timestamp_checksum\" value=\"([^>]*?)\""); string p_timestamp_checksumF = m21.Groups[1].Value; Match m22; m22 = Regex.Match(result, "type=\"hidden\" name=\"a\" value=\"(\\d+?)\""); string p_aF = m22.Groups[1].Value; PostDataF["timestamp"] = p_timestampF; PostDataF["timestamp_checksum"] = p_timestamp_checksumF; PostDataF["a"] = p_aF; //2 RE,3 Nor,4 Raid, 5 SPY1, 6 SPY2 if (Raidtype > 4) { PostDataF["c"] = "4"; int Tribe = UpCall.TD.Tribe; int spy = Raidtype - 4; PostDataF["spy"] = spy.ToString(); if (Tribe == 3 && wTroops[w].Troops[2] != 0) { PostDataF["t3"] = wTroops[w].Troops[2].ToString(); } else if ((Tribe == 1 || Tribe == 2) && wTroops[w].Troops[3] != 0) { PostDataF["t4"] = wTroops[w].Troops[3].ToString(); } else { UpCall.DebugLog("NO SCOUT TROOPS", DebugLevel.W); MarkDeleted = true; return; } } else { PostDataF["c"] = Raidtype.ToString(); for (int i = 1; i < 12; i++) { PostDataF["t" + i] = wTroops[w].Troops[i - 1].ToString(); } } if (Raidtype == 3 && (wTroops[w].Troops[7] != 0)) { int RP = UpCall.TD.Villages[VillageID].Buildings[39].Level; int tkata = GIDMap[kata]; if (tkata == 0 || RP < 10) { tkata = 99; } PostDataF["kata"] = tkata.ToString(); if ((wTroops[w].Troops[7] >= 20) && (RP == 20)) { int tkata2 = GIDMap[kata2]; PostDataF["kata2"] = tkata2.ToString(); } } PostDataF["kid"] = Targets[TargetID].Z.ToString(); PostDataF["id"] = "39"; PostDataF["s1.x"] = rand.Next(40, 70).ToString(); PostDataF["s1.y"] = rand.Next(3, 17).ToString(); PostDataF["s1"] = "ok"; PostDataALL.Add(PostDataF); } } //POST ALL Attack for (int i = 0; i < PostDataALL.Count; i++) { UpCall.PageQuery(VillageID, "build.php?tt=2&id=39", PostDataALL[i]); } Wave++; if (TargetID == Targets.Count - 1) { MarkDeleted = true; } else { LastExec = DateTime.Now; NextExec = LastExec.AddSeconds(MinimumInterval); TargetID++; } }
/// <summary> /// Trade resource with NPC with 1:1 rate (after paying 3 gold) /// </summary> public NpcTradeResult doNpcTrade() { // Get NPC trade form string result = UpCall.PageQuery(VillageID, "build.php?gid=17&t=3"); if (result == null) { return(NpcTradeResult.Failure); } // Parse capacity and sum Match match = Regex.Match(result, "var summe=(?<summe>\\d+);var max123=(?<max123>\\d+);var max4=(?<max4>\\d+);"); if (!match.Success) { return(NpcTradeResult.Failure); } int sum = Int32.Parse(match.Groups["summe"].Value); // Parse id match = Regex.Match(result, "<input type=\"hidden\" name=\"id\" value=\"(?<id>\\d+)\""); if (!match.Success) { return(NpcTradeResult.Failure); } string id = match.Groups["id"].Value; // Parse c match = Regex.Match(result, "<input type=\"hidden\" name=\"c\" value=\"(?<c>[^>]*?)\""); if (!match.Success) { return(NpcTradeResult.Failure); } string c = match.Groups["c"].Value; // Parse m1[] and m2[] MatchCollection matches = Regex.Matches(result, "<input type=\"hidden\" name=\"m1\\[\\]\" value=\"(?<m1>\\d+)\""); if (matches.Count != 4) { return(NpcTradeResult.Failure); } TResAmount m1 = new TResAmount(new int[matches.Count]); for (int i = 0; i < matches.Count; i++) { m1.Resources[i] = Int32.Parse(matches[i].Groups["m1"].Value); } // Does m1 exceeds threshold? for (int i = 0; i < m1.Resources.Length; i++) { if (m1.Resources[i] < Threshold.Resources[i]) { return(NpcTradeResult.Delay); } } // Compute m2 TResAmount m2 = RedistributeResources(UpCall.TD, VillageID, sum); if (m2 == null) { return(NpcTradeResult.Delay); } // Prepare data Dictionary <string, string> postData = new Dictionary <string, string>(); postData["id"] = id; postData["t"] = "3"; postData["a"] = "6"; postData["c"] = c; StringBuilder sb = new StringBuilder(); for (int i = 0; i < m2.Resources.Length; i++) { if (i > 0) { sb.Append("&"); } sb.AppendFormat("m2[]={0}&m1[]={1}", m2.Resources[i], m1.Resources[i]); } postData["!!!RawData!!!"] = sb.ToString(); // Post form result = UpCall.PageQuery(VillageID, "build.php", postData); if (result == null) { return(NpcTradeResult.Failure); } match = Regex.Match(result, "<b>3</b>[^<]*?</p><script language=\"JavaScript\">var summe="); if (!match.Success) { return(NpcTradeResult.Failure); } UpCall.DebugLog(string.Format("NPC trade {0} -> {1} ({2}) ", m1, m2, VillageID), DebugLevel.I); UpCall.BuildCount(); return(NpcTradeResult.Success); }
/// <summary> /// Dispatch a transportation of a given amount of resource from one village to a given destiantion /// </summary> /// <param name="VillageID">Unique ID of the departure village</param> /// <param name="Amount">Amounts of resources to transport</param> /// <param name="TargetPos">Position of the arrival village</param> /// <returns>Error return minus number. Succeed return single way transfer time cost.</returns> public int doTransfer(TResAmount Amount, TPoint TargetPos) { string result = UpCall.PageQuery(VillageID, "build.php?gid=17&t=5"); if (result == null) { return(-1); } var CV = UpCall.TD.Villages[VillageID]; Dictionary <string, string> PostData = new Dictionary <string, string>(); var m = Regex.Match(result, "name=\"id\" id=\"id\" value=\"(\\d+)\"", RegexOptions.Singleline); if (!m.Success) { return(-1); } PostData["cmd"] = "prepareMarketplace"; PostData["id"] = m.Groups[1].Value; if (result.Contains("Popup(2,5)") && Amount.TotalAmount > CV.Market.SingleCarry * CV.Market.ActiveMerchant) { resumeTime = DateTime.Now.AddSeconds(rand.Next(200 + retrycount * 20, 300 + retrycount * 30)); UpCall.DebugLog("0:00:0?, Will retry...", DebugLevel.I); return(-2); } if (Amount.TotalAmount > CV.Market.SingleCarry * CV.Market.ActiveMerchant) { retrycount++; if (retrycount > 5) { UpCall.DebugLog(string.Format("Transfer cannot go on: MCarry({0}) * MCount({1}) < Amount({2})", CV.Market.SingleCarry, CV.Market.ActiveMerchant, Amount.TotalAmount), DebugLevel.W); return(-2); // Beyond transfer ability } else { UpCall.DebugLog("Error on 'ActiveMerchant'! Will retry...", DebugLevel.I); resumeTime = DateTime.Now.AddSeconds(rand.Next(500 + retrycount * 20, 800 + retrycount * 30)); CV.Market.ActiveMerchant = Math.Min(Amount.TotalAmount / CV.Market.SingleCarry + 1, CV.Market.MaxMerchant); return(-2); } } retrycount = 0; for (int i = 0; i < 4; i++) { PostData["r" + (i + 1).ToString()] = Amount.Resources[i].ToString(); } //cmd=prepareMarketplace&r1=3000&r2=3000&r3=3000&r4=&dname=&x=50&y=105&id=27&t=5&x2=1 PostData["dname"] = ""; PostData["x"] = TargetPos.X.ToString(); PostData["y"] = TargetPos.Y.ToString(); PostData["t"] = "5"; PostData["x2"] = "1"; result = UpCall.PageQuery(VillageID, "ajax.php?cmd=prepareMarketplace", PostData); //cmd=prepareMarketplace&t=5&id=27&a=64846&sz=2788&kid=236746&c=aaa02a&x2=1&r1=3000&r2=3000&r3=3000&r4= if (result == null) { return(-1); } PostData.Clear(); result = result.Replace("\\\"", "\""); result = result.Replace("\\/", "/"); PostData["cmd"] = "prepareMarketplace"; MatchCollection matches = Regex.Matches(result, "name=\"(\\w+)\" id=\"\\w+\" value=\"(\\w+)\""); for (int i = 0; i < matches.Count; i++) { PostData[matches[i].Groups[1].Value] = matches[i].Groups[2].Value; } for (int i = 0; i < 4; i++) { PostData["r" + (i + 1).ToString()] = Amount.Resources[i].ToString(); } m = Regex.Match(result, "<td>([0-9:]{6,})</td>"); if (!m.Success) { return(-1); // Parse error! } int TimeCost = Convert.ToInt32(UpCall.TimeSpanParse(m.Groups[1].Value).TotalSeconds); if (UpCall.TD.MarketSpeed != 0) { // calc market speed var distance = CV.Coord * TargetPos; UpCall.TD.Dirty = true; UpCall.TD.MarketSpeed = Convert.ToInt32(Math.Round(distance * 3600 / TimeCost)); } UpCall.PageQuery(VillageID, "ajax.php?cmd=prepareMarketplace", PostData); UpCall.BuildCount(); // write data into target village if it's my village. foreach (var x in UpCall.TD.Villages) { if (x.Value == CV) { continue; } if (x.Value.Coord == TargetPos) { if (x.Value.isBuildingInitialized == 2) { x.Value.Market.MarketInfo.Add(new TMInfo() { CarryAmount = Amount.Clone(), Coord = CV.Coord, FinishTime = DateTime.Now.AddSeconds(TimeCost), MType = TMType.OtherCome, VillageName = CV.Name }); } break; } } UpCall.DebugLog(string.Format("Transfer {0}({1}) => {2} {3}", CV.Coord.ToString(), VillageID, TargetPos.ToString(), Amount.ToString()), DebugLevel.I); return(TimeCost); }
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+)&a=" + Aid.ToString() + "&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+)&a=" + Aid.ToString() + "&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 }); }
private void DoEvade() { string sendTroopsUrl = String.Format("build.php?id=39&tt=2&z={0}", tpEvadePoint.Z); string sendTroopForm = UpCall.PageQuery(VillageID, sendTroopsUrl); if (sendTroopForm == null || !sendTroopForm.Contains("<form method=\"POST\" name=\"snd\" action=\"build.php?id=39&tt=2\">")) { MinimumDelay = 0; return; } Dictionary <string, string> postData = RaidQueue.GetHiddenInputValues(sendTroopForm); postData.Add("c", "2"); postData.Add("x", tpEvadePoint.X.ToString()); postData.Add("y", tpEvadePoint.Y.ToString()); ReinforceToop = RaidQueue.GetMaxTroops(sendTroopForm); for (int i = 0; i < this.bTroopFilter.Length; i++) { if (bTroopFilter[i]) { continue; } ReinforceToop[i] = 0; } for (int i = 0; i < ReinforceToop.Length; i++) { string troopKey = String.Format("t{0}", i + 1); string troopNumber = ReinforceToop[i] == 0 ? "" : ReinforceToop[i].ToString(); postData.Add(troopKey, troopNumber); } string confirmUrl = "build.php?id=39&tt=2"; string confirmForm = UpCall.PageQuery(this.VillageID, confirmUrl, postData); if (confirmForm == null) { MinimumDelay = 0; return; } Match errorMatch = Regex.Match(confirmForm, "<p class=\"error\">(.+)</span>"); if (errorMatch.Success) { string error = String.Format( "Delete village {0}. Error: {1}", tpEvadePoint, errorMatch.Groups[1].Value); UpCall.DebugLog("部队未能发出,因为:" + error, DebugLevel.W); MinimumDelay = nMinInterval; return; } if (!confirmForm.Contains("<form method=\"post\" action=\"build.php?id=39&tt=2\">")) { MinimumDelay = 0; return; } TimeSpan timeCost = RaidQueue.GetOneWayTimeCost(confirmForm); if (timeCost == TimeSpan.MinValue) { MinimumDelay = nMinInterval; evade_status = EvadeStatus.NoAtkDetected; return; } postData = RaidQueue.GetHiddenInputValues(confirmForm); string result = this.UpCall.PageQuery(this.VillageID, confirmUrl, postData); if (result == null) { MinimumDelay = 0; return; } evade_status = EvadeStatus.Evaded; ReinforceTimeCost = (int)timeCost.TotalSeconds; MinimumDelay = ReinforceTimeCost + RandomDelay(5, 10); TTInfo troopInfo = new TTInfo() { Tribe = UpCall.TD.Tribe, Troops = ReinforceToop }; string message = String.Format( "部队回避 {0} ({1}) => {2} {3}", this.UpCall.TD.Villages[this.VillageID].Coord, this.VillageID, this.tpEvadePoint, troopInfo.FriendlyName); this.UpCall.DebugLog(message, DebugLevel.I); }
private int PMParse(string data) { string strPMTitles = HtmlUtility.GetElement(data, "tbody"); if (strPMTitles == null) { return(-1); } string[] strPMTitleList = HtmlUtility.GetElements(strPMTitles, "tr"); int len = strPMTitleList.Length; int cnt = 0; foreach (string eachPMTitle in strPMTitleList) { Match m = Regex.Match( eachPMTitle, "class=\"status \" title=\"unread\" alt=\"unread\" />"); if (!m.Success) { continue; } m = Regex.Match( eachPMTitle, "<a href=\"spieler\\.php\\?uid=(\\d+)\">([^<]*?)</a>"); if (!m.Success) { continue; } int uid = Convert.ToInt32(m.Groups[1].Value); string name = m.Groups[2].Value; if (!DicPMSender.ContainsKey(uid)) { PMSender sender = new PMSender { _uid = uid, _name = name }; DicPMSender.Add(uid, sender); } m = Regex.Match( eachPMTitle, "<a href=\"(nachrichten\\.php\\?id=\\d+)\">([^<]*?)</a>"); if (!m.Success) { continue; } string link = m.Groups[1].Value; string subject = m.Groups[2].Value.Trim(); m = Regex.Match( eachPMTitle, "<td class=\"dat\">([^<]*?)</td>"); if (!m.Success) { continue; } string date = m.Groups[1].Value; PMInfo info = new PMInfo { _subject = subject, _date = date }; string content = UpCall.PageQuery(VillageID, link); m = Regex.Match(content, @"<div id=""message"">(.+?)</div>", RegexOptions.Singleline); if (!m.Success) { continue; } info._content = m.Groups[1].Value; DicPMSender[uid].PMInfoList.Add(info); cnt++; } if (cnt > 0 && cnt == len) { return(1); } else if (cnt > 0 && cnt < len) { return(0); } else { return(-1); } }
public void Action() { TVillage CV = this.UpCall.TD.Villages[VillageID]; if (this.NextExec >= DateTime.Now) { return; } this.NextExec = DateTime.Now.AddSeconds(50); if (CV.isBuildingInitialized != 2) { return; } int gid, bid; if (AIType == TAIType.Resource) { if (!FetchAvailGidAndBidWithRes(CV, out gid, out bid)) { return; } } else { if (!FetchAvailGidAndBidWithlvl(CV, out gid, out bid)) { return; } } if (!CV.Buildings.ContainsKey(bid)) { return; } int[] costs = Buildings.Cost(gid, CV.Buildings[bid].Level + 1).Resources; int inside_gid, insid_bid; if (FetchAvailInsideBuilding(CV, costs, out inside_gid, out insid_bid)) { gid = inside_gid; bid = insid_bid; } UpCall.DebugLog("AIQueue准备建造 " + DisplayLang.Instance.GetGidLang(gid) + " @" + bid, DebugLevel.II); var BQ = new BuildingQueue() { Bid = bid, Gid = gid, UpCall = UpCall, VillageID = VillageID }; Gid = gid; int cd = BQ.CountDown; if (cd <= 0) { UpCall.DebugLog("AIQueue建筑队列启动!", DebugLevel.II); BQ.Action(); } else { int delay = Math.Min(15 * 60, cd); UpCall.DebugLog("AIQueue建筑队列未能启动,建造该单位尚需等待" + cd + "秒;将于" + delay + "秒后再检查一次。" , DebugLevel.II); this.NextExec = DateTime.Now.AddSeconds(delay); // 为了防止资源未刷新而引起的问题 UpCall.PageQuery(VillageID, "dorf1.php"); } }
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 + "&id=" + bid + "&c=[^\']*?)';\\sreturn"); n = Regex.Match(result, "(dorf(\\d)\\.php\\?a=" + bid + "&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 + "&id=" + bid + "&c=[^\']*?)'"); n = Regex.Match(result, "(dorf(\\d)\\.php\\?a=" + bid + "&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 }); }
private DoRaidResult DoRaid() { if (this.MinimumDelay > 0) { return(DoRaidResult.Postpone); } string sendTroopsUrl = String.Format("build.php?id=39&tt=2&z={0}", this.Targets[this.TargetID].Z); string sendTroopForm = UpCall.PageQuery(this.VillageID, sendTroopsUrl); if (sendTroopForm == null) { return(DoRaidResult.SkipVillage); } if (!sendTroopForm.Contains("<form method=\"post\" name=\"snd\" action=\"build.php?id=39&tt=2\">")) { return(DoRaidResult.SkipVillage); } if (!UpCall.NoAnimals(VillageID, Targets[this.TargetID].X, Targets[this.TargetID].Y)) { UpCall.DebugLog("跳过有野怪的绿洲", DebugLevel.II); return(DoRaidResult.SkipVillage); } Dictionary <string, string> postData = RaidQueue.GetHiddenInputValues(sendTroopForm); postData.Add("c", ((int)this.RaidType).ToString()); postData.Add("x", this.Targets[this.TargetID].X.ToString()); postData.Add("y", this.Targets[this.TargetID].Y.ToString()); int[] maxTroops = RaidQueue.GetMaxTroops(sendTroopForm); for (int i = 0; i < this.Troops.Length; i++) { if (this.Troops[i] > maxTroops[i]) { return(DoRaidResult.SkipVillage); } string troopKey = String.Format("t{0}", i + 1); string troopNumber = this.Troops[i] == 0 ? "" : this.Troops[i].ToString(); postData.Add(troopKey, troopNumber); } string confirmUrl = "build.php?id=39&tt=2"; string confirmForm = UpCall.PageQuery(this.VillageID, confirmUrl, postData); if (confirmForm == null) { return(DoRaidResult.SkipVillage); } Match errorMatch = Regex.Match(confirmForm, "<p class=\"error\">(.+)</p>"); if (errorMatch.Success) { string err_msg = errorMatch.Groups[1].Value; err_msg = err_msg.Replace("<span>", ""); err_msg = err_msg.Replace("</span>", ""); string error = String.Format( "Delete village {0}. Error: {1}", this.Targets[this.TargetID], err_msg); this.UpCall.DebugLog(error, DebugLevel.W); return(DoRaidResult.DeleteVillage); } if (!confirmForm.Contains("<form method=\"post\" action=\"build.php?id=39&tt=2\">")) { return(DoRaidResult.SkipVillage); } TimeSpan timeCost = RaidQueue.GetOneWayTimeCost(confirmForm); if (timeCost == TimeSpan.MinValue) { return(DoRaidResult.SkipVillage); } postData = RaidQueue.GetHiddenInputValues(confirmForm); if (RaidQueue.HasRadioInput("spy", confirmForm)) { postData.Add("spy", ((int)this.SpyOption).ToString()); } string result = this.UpCall.PageQuery(this.VillageID, confirmUrl, postData); if (result == null) { return(DoRaidResult.SkipVillage); } if (!this.MultipeRaids) { this.MinimumDelay = (int)timeCost.TotalSeconds * 2 + this.RandomDelay(30, 180); } TTInfo troopInfo = new TTInfo() { Tribe = this.UpCall.TD.Tribe, Troops = this.Troops }; string message = String.Format( "{0} {1} ({2}) => {3} {4}", this.RaidType, this.UpCall.TD.Villages[this.VillageID].Coord, this.VillageID, this.Targets[this.TargetID], troopInfo.FriendlyName); this.UpCall.DebugLog(message, DebugLevel.I); return(DoRaidResult.Success); }
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 }); }