bool SendMail() { msg.From = new MailAddress(From, UpCall.TD.Server, System.Text.Encoding.UTF8); msg.To.Add(To.Join(",")); msg.Subject = string.Format("{0}@{1}", UpCall.TD.Server, UpCall.TD.Username); msg.SubjectEncoding = System.Text.Encoding.UTF8; msg.Body = this.SmsBody; msg.BodyEncoding = System.Text.Encoding.UTF8; msg.IsBodyHtml = false; msg.Priority = MailPriority.High; client.Credentials = new System.Net.NetworkCredential(From, Password); client.Host = this.Host; client.Port = this.Port; client.EnableSsl = this.SSLEnable; //client.SendCompleted += new // SendCompletedEventHandler(SendCompletedCallback); try { //client.SendAsync(msg, msg); client.Send(msg); UpCall.DebugLog("Message sent.", DebugLevel.II); return(true); } catch (System.Net.Mail.SmtpException ex) { UpCall.DebugLog(ex); return(false); } }
private bool SendMail() { MailMessage msg = new MailMessage(); msg.From = new MailAddress(From, UpCall.TD.Server, System.Text.Encoding.UTF8); msg.To.Add(To.Join(",")); msg.Subject = string.Format("{0}@{1}", UpCall.TD.Server, UpCall.TD.Username); msg.SubjectEncoding = System.Text.Encoding.UTF8; msg.Body = this.SmsBody; msg.BodyEncoding = System.Text.Encoding.UTF8; msg.IsBodyHtml = false; msg.Priority = MailPriority.High; SmtpClient client = new SmtpClient(this.Host); client.Credentials = new System.Net.NetworkCredential(From, Password); client.Port = this.Port; client.EnableSsl = this.SSLEnable; try { client.Send(msg); UpCall.DebugLog("Message sent.", DebugLevel.II); return(true); } catch (System.Net.Mail.SmtpException ex) { UpCall.DebugLog(ex); return(false); } }
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 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() { TVillage village = UpCall.TD.Villages[VillageID]; if (!IsValid) { UpCall.DebugLog("Invalid NPC trade task discarded: " + ToString(), DebugLevel.W); RemoveQueuedTask(); return; } if (CountDown > 0) { return; } NpcTradeResult returnCode = doNpcTrade(); switch (returnCode) { case NpcTradeResult.Failure: UpCall.DebugLog("NPC trade task has failed: " + ToString(), DebugLevel.W); RemoveQueuedTask(); return; case NpcTradeResult.Delay: // Wait at least 10 minutes before retrying MinimumDelay = 600; break; case NpcTradeResult.Success: Count++; if (MaxCount != 0 & Count >= MaxCount) { RemoveQueuedTask(); return; } // This is an unfinished multiple NPC trade task, wait at least 1 hr MinimumDelay = 3600; break; } }
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); }
private TResAmount NeedCrop(Data travianData) { return(null); if (NoCrop) { return(null); } if (Distribution == ResourceDistributionType.Uniform || Distribution == ResourceDistributionType.BalanceSource || Distribution == ResourceDistributionType.BalanceSourceTime) { return(null); } if (Distribution == ResourceDistributionType.None && ResourceAmount.Resources[3] <= 0) { return(null); } if (travianData == null || !travianData.Villages.ContainsKey(TargetVillageID) || !travianData.Villages.ContainsKey(VillageID)) { return(null); } TVillage source = travianData.Villages[VillageID]; TVillage destination = travianData.Villages[TargetVillageID]; if (destination.isBuildingInitialized != 2) { return(null); } if (destination.Resource[3].Produce >= 0) { if (UpCall != null) { UpCall.DebugLog("Target Produce >= 0, no need crop rule.", DebugLevel.I); } return(null); } int speed = travianData.MarketSpeed == 0 ? 24 : travianData.MarketSpeed; int timecost = Convert.ToInt32(source.Coord * destination.Coord * 3600 / speed) + 30; int cropcap = destination.Resource[3].CurrAmount + timecost * destination.Resource[3].Produce / 3600; foreach (TMInfo transfer in destination.Market.MarketInfo) { if (transfer.MType == TMType.OtherCome && transfer.FinishTime < DateTime.Now.AddSeconds(timecost)) { cropcap += transfer.CarryAmount.Resources[3]; } } if (cropcap <= 0) { return(new TResAmount(0, 0, 0, ResourceAmount.TotalAmount)); } if (UpCall != null) { UpCall.DebugLog("Target village don't need crop, no need crop rule.", DebugLevel.I); } return(null); }
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 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); }
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"); } }
/// <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); }
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 }); }