private static IEnumerator PerformAction(BgoSessionObject sessionObject, BgoGame game, String actionValue, Dictionary <String, String> overrideData, Action callback) { var postUrl = RemoveCharacterEntities(game.ActionFormSubmitUrl); WWWForm myPostData = new WWWForm(); foreach (var pair in game.ActionForm) { if (pair.Key == "action") { myPostData.AddField("action", actionValue); } else { if (overrideData != null && overrideData.ContainsKey(pair.Key)) { myPostData.AddField(pair.Key, overrideData[pair.Key]); overrideData.Remove(pair.Key); } else { myPostData.AddField(pair.Key, pair.Value); } } } if (overrideData != null) { foreach (var pair in overrideData) { myPostData.AddField(pair.Key, pair.Value); } } var cookieHeaders = myPostData.headers; cookieHeaders.Add("Cookie", "PHPSESSID=" + sessionObject._phpSession + "; identifiant=" + sessionObject._identifiant + "; mot_de_passe=" + sessionObject._motDePasse); //var data = Encoding.UTF8.GetString(myPostData.data); var www = new WWW(BgoBaseUrl + postUrl, myPostData.data, cookieHeaders); yield return(www); if (www.error != null) { Assets.CSharpCode.UI.Util.LogRecorder.Log(www.error); yield break; } var responseText = www.text; BgoPageProvider.FillGameBoard(responseText, game); if (callback != null) { callback(); } }
/// <summary> /// 根据网页内容填充玩家面板 /// </summary> /// <param name="phpSession"></param> /// <param name="game"></param> /// <param name="callback"></param> /// <returns></returns> public static IEnumerator RefreshBoard(String phpSession, BgoGame game, Action callback) { WWWForm myPostData = new WWWForm(); var cookieHeaders = myPostData.headers; cookieHeaders.Add("Cookie", "PHPSESSID=" + phpSession); //var data = Encoding.UTF8.GetString(myPostData.data); var www = new WWW(BgoBaseUrl + "index.php?cnt=202&pl=" + game.GameId + "&nat=" + game.Nat, null, cookieHeaders); yield return(www); if (www.error != null) { Assets.CSharpCode.UI.Util.LogRecorder.Log(www.error); yield break; } var html = www.text; Assets.CSharpCode.UI.Util.LogRecorder.Log("Board page received"); FillGameBoard(html, game); if (callback != null) { callback(); } }
public static IEnumerator PostInternalAction(BgoSessionObject sessionObject, BgoGame game, BgoPlayerAction action, Action <List <PlayerAction> > callback) { switch (action.ActionType) { case PlayerActionType.PlayActionCard: return(Perform2StepAction(sessionObject, game, action.Data[1].ToString(), callback)); case PlayerActionType.BuildWonder: return(Perform2StepAction(sessionObject, game, action.Data[3].ToString(), callback)); default: return(null); } }
/// <summary> /// 获取正在进行的游戏列表,注意这里面也能取到最近完成的比赛 /// </summary> /// <param name="phpSession"></param> /// <param name="callback"></param> /// <returns></returns> public static IEnumerator GameLists(String phpSession, Action <List <BgoGame> > callback) { //http://boardgaming-online.com/index.php?cnt=2 WWWForm myPostData = new WWWForm(); var headers = myPostData.headers; headers.Add("Cookie", "PHPSESSID=" + phpSession); WWW www = new WWW(BgoBaseUrl, null, headers); //UnityWebRequest www = UnityWebRequest.Get(BgoBaseUrl+ "index.php?cnt=2"); //www.SetRequestHeader("Cookie", "PHPSESSID=" + phpSession); yield return(www); if (www.error != null) { Assets.CSharpCode.UI.Util.LogRecorder.Log(www.error); yield break; } var responseText = www.text; List <BgoGame> games = new List <BgoGame>(); //Some logic to extract games var matches = BgoRegexpCollections.ListGamesInMyGamePage.Matches(responseText); foreach (Match match in matches) { BgoGame game = new BgoGame(); game.GameId = match.Groups[1].Value; game.Nat = match.Groups[3].Value; game.Version = "2.0"; game.Name = UTF8Decoder(match.Groups[4].Value); games.Add(game); } if (callback != null) { callback(games); } }
public IEnumerator TakeInternalAction(TtaGame game, PlayerAction action, Action <List <PlayerAction> > callback) { BgoGame bgoGame = game as BgoGame; BgoPlayerAction bgoAction = action as BgoPlayerAction; Action <List <PlayerAction> > callbackDelegate = (actions) => { if (callback != null) { callback(actions); } }; if (bgoAction == null) { LogRecorder.Log("Null Action!"); return(null); } return(BgoPostProvider.PostInternalAction(sessionObject, bgoGame, bgoAction, callbackDelegate)); }
public static void Format(BgoGame game, String html) { //如果当前是EventResolve,那么没有CardRow if (game.CurrentPhase == TtaPhase.EventResolution) { game.PossibleActions.RemoveAll(a => a.ActionType == PlayerActionType.TakeCardFromCardRow); var mc = BgoRegexpCollections.ExtractResolveingEvent.Match(html); var card = Civilopedia.GetCardInfoByName((Age)Enum.Parse(typeof(Age), mc.Groups[2].Value), mc.Groups[1].Value); foreach ( var action in game.PossibleActions.Where(action => action.ActionType == PlayerActionType.Unknown).ToList()) { String bgoStr = action.Data[0].ToString(); String optValue = action.Data[1].ToString(); if (bgoStr == "----- Select an action -----") { continue; } action.ActionType = PlayerActionType.ResolveEventOption; //获得CurrentActionCard action.Data[0] = card; action.Data[1] = bgoStr; action.Data[2] = optValue; } } //Unknown的话 //Data[0]是opt的显示内容,就是文本 //Data[1]是optValue(要传给后端的) foreach ( var action in game.PossibleActions.Where(action => action.ActionType == PlayerActionType.Unknown).ToList()) { String bgoStr = action.Data[0].ToString(); String optValue = action.Data[1].ToString(); if (bgoStr.StartsWith("Increase")) { int foodCost = Convert.ToInt32(bgoStr.CutBetween("(", "F)")); action.ActionType = PlayerActionType.IncreasePopulation; action.Data[0] = bgoStr; action.Data[1] = foodCost; action.Data[2] = optValue; } else if (bgoStr.StartsWith("Build")) { //Build关键字的出现可能有多种情况。包括 //Build Iron (5R) //Build free temple/Build free warrior. //Build 1 stage of Library of Alexandria (1R) //Build 4 stages of Library of Alexandria (1R) if (bgoStr.IndexOf("stage", StringComparison.Ordinal) == 8 || bgoStr.IndexOf("stages", StringComparison.Ordinal) == 8) { //var keyword = bgoStr.Contains("stages") ? "stages" : "stage"; //Build X stage of Y (XR) var resCost = Convert.ToInt32(bgoStr.CutBetween("(", "R)")); var stageCount = Convert.ToInt32(bgoStr.CutBetween("Build ", " stage")); var wonderName = bgoStr.CutBetween("of ", " ("); action.ActionType = PlayerActionType.BuildWonder; action.Data[0] = Civilopedia.GetCardInfoByName(wonderName); action.Data[1] = stageCount; action.Data[2] = resCost; action.Data[3] = optValue; } else if (bgoStr.Contains("(")) { //Building String cardName = bgoStr.CutBetween("Build ", " ("); int resCost = Convert.ToInt32(bgoStr.CutBetween("(", "R)")); action.ActionType = PlayerActionType.BuildBuilding; action.Data[0] = Civilopedia.GetCardInfoByName(cardName); action.Data[1] = resCost; action.Data[2] = optValue; } else { //以Build开头的其他无意义选项 } } else if (bgoStr.StartsWith("Upgrade")) { //Upgrade Agriculture -> Irrigation (2R) var card1 = bgoStr.CutBetween("Upgrade ", " ->"); var card2 = bgoStr.CutBetween("> ", " ("); var resCost = bgoStr.CutBetween("(", "R)"); action.ActionType = PlayerActionType.UpgradeBuilding; action.Data[0] = Civilopedia.GetCardInfoByName(card1); action.Data[1] = Civilopedia.GetCardInfoByName(card2); action.Data[2] = resCost; action.Data[3] = optValue; } else if (bgoStr.StartsWith("Play")) { //Play关键字的出现可能有多种情况。包括 //Play A / Rich Land //Play event Pestilence //Play event Developed Territory II if (bgoStr.Contains("/")) { //Play A / Rich Land var age = bgoStr.CutBetween("Play ", " /"); var cardName = bgoStr.CutAfter("/ "); var card = Civilopedia.GetCardInfoByName((Age)Enum.Parse(typeof(Age), age), cardName); action.ActionType = PlayerActionType.PlayActionCard; action.Internal = IfCardIsInternal(card); action.Data[0] = card; action.Data[1] = optValue; } else if (bgoStr.StartsWith("Play event")) { //Play event Pestilence //Play event Developed Territory II if (bgoStr.EndsWith(" A") || bgoStr.EndsWith(" I") || bgoStr.EndsWith(" II") || bgoStr.EndsWith(" III")) { var conlonySplit = bgoStr.Split(" ".ToCharArray()); var conlonyName = ""; for (var j = 2; j < conlonySplit.Length - 1; j++) { conlonyName += conlonySplit[j] + " "; } var card = Civilopedia.GetCardInfoByName((Age)Enum.Parse(typeof(Age), conlonySplit[conlonySplit.Length]), conlonyName); action.ActionType = PlayerActionType.PlayColony; action.Data[0] = card; action.Data[1] = optValue; } else { //Play event Pestilence var card = Civilopedia.GetCardInfoByName(bgoStr.CutAfter("Play event ")); action.ActionType = PlayerActionType.PlayEvent; action.Data[0] = card; action.Data[1] = optValue; } } } else if (bgoStr.StartsWith("Revolution")) { //Revolution! Change to Constitutional Monarchy (6S) var resCost = Convert.ToInt32(bgoStr.CutBetween("(", "S)")); var card = Civilopedia.GetCardInfoByName(bgoStr.CutBetween("Change to ", " (")); action.ActionType = PlayerActionType.Revolution; action.Data[0] = card; action.Data[1] = resCost; action.Data[2] = optValue; } else if (bgoStr.StartsWith("Elect")) { //Elect leader: Moses //Elect leader: Joan of Arc (for 1 MA) if (!bgoStr.Contains("(")) { var leader = bgoStr.CutAfter(": "); action.ActionType = PlayerActionType.ElectLeader; action.Data[0] = Civilopedia.GetCardInfoByName(leader); action.Data[1] = optValue; } else { //MA elect } } else if (bgoStr.StartsWith("Discover")) { var resCost = Convert.ToInt32(bgoStr.CutBetween("(", "S)")); var card = Civilopedia.GetCardInfoByName(bgoStr.CutBetween("Discover ", " (")); action.ActionType = PlayerActionType.DevelopTechCard; action.Data[0] = card; action.Data[1] = resCost; action.Data[2] = optValue; } else if (bgoStr.StartsWith("Reset Action Phase")) { action.ActionType = PlayerActionType.ResetActionPhase; } else if (bgoStr.StartsWith("Pass political phase")) { action.ActionType = PlayerActionType.PassPoliticalPhase; } else if (bgoStr.StartsWith("End Action Phase")) { action.ActionType = PlayerActionType.EndActionPhase; } else if (bgoStr.StartsWith("Set up new tactics")) { //Set up new tactics: Classic Army action.ActionType = PlayerActionType.SetupTactic; var card = Civilopedia.GetCardInfoByName(bgoStr.CutAfter(": ")); action.Data[0] = card; action.Data[1] = optValue; } else if (bgoStr.StartsWith("Adopt tactics")) { //Adopt tactics: Heavy Cavalry action.ActionType = PlayerActionType.AdoptTactic; var card = Civilopedia.GetCardInfoByName(bgoStr.CutAfter(": ")); action.Data[0] = card; action.Data[1] = optValue; } } //---删除多余 / 一拆多 #region disband/destory var disband = game.PossibleActions.FirstOrDefault( action => action.ActionType == PlayerActionType.Unknown && action.Data[0].ToString() == "Disband / Destroy"); if (disband != null) { //为每个建筑物建立自己的disband/destory game.PossibleActions.Remove(disband); var subDropdown = BgoRegexpCollections.ExtractSubDropDown("unite").Match(html); if (subDropdown.Success) { foreach (Match match in BgoRegexpCollections.ExtractActions.Matches(subDropdown.Groups[1].Value)) { //8;9 A/ Agriculture var optValue = match.Groups[1].Value; var cardName = match.Groups[2].Value; var cardAge = cardName.CutBefore("/"); cardName = cardName.CutAfter("/ "); var card = Civilopedia.GetCardInfoByName((Age)Enum.Parse(typeof(Age), cardAge), cardName); if (card.CardType == CardType.MilitaryTechAirForce || card.CardType == CardType.MilitaryTechArtillery || card.CardType == CardType.MilitaryTechCavalry || card.CardType == CardType.MilitaryTechInfantry) { game.PossibleActions.Add(new BgoPlayerAction() { ActionType = PlayerActionType.Disband, Data = new Dictionary <int, object> { { 0, card }, { 1, disband.Data[1] }, { 2, optValue } } }); } else { game.PossibleActions.Add(new BgoPlayerAction() { ActionType = PlayerActionType.Destory, Data = new Dictionary <int, object> { { 0, card }, { 1, disband.Data[1] }, { 2, optValue } } }); } } } } #endregion #region 侵略一拆多 var aggression = game.PossibleActions.Where( action => action.ActionType == PlayerActionType.Unknown && ( action.Data[0].ToString().EndsWith(" A") || action.Data[0].ToString().EndsWith(" I") || action.Data[0].ToString().EndsWith(" II") || action.Data[0].ToString().EndsWith(" III"))) .ToList(); foreach (var action in aggression) { game.PossibleActions.Remove(action); String bgoStr = action.Data[0].ToString(); String optValue = action.Data[1].ToString(); var cardName = bgoStr.Substring(0, bgoStr.LastIndexOf(" ", StringComparison.Ordinal)); var cardAge = bgoStr.Substring(bgoStr.LastIndexOf(" ", StringComparison.Ordinal) + 1); var card = Civilopedia.GetCardInfoByName( (Age)Enum.Parse(typeof(Age), cardAge) , cardName); var advNum = optValue.CutAfter(";"); var subDropdown = BgoRegexpCollections.ExtractWarAggressionPactTargetList("listeAdversaires" + advNum).Match(html); if (subDropdown.Success) { foreach (Match match in BgoRegexpCollections.ExtractWarAggressionPactTarget.Matches(subDropdown.Groups[1].Value)) { //var childId = match.Groups[1].Value; var childOpt = match.Groups[2].Value; var playername = match.Groups[3].Value.CutBefore(" -"); var maRequired = BgoRegexpCollections.ExtractImage.Matches(match.Groups[4].Value).Count; game.PossibleActions.Add(new BgoPlayerAction { ActionType = PlayerActionType.Aggression, Data = new Dictionary <int, object> { { 0, card }, { 1, playername }, { 2, maRequired }, { 3, optValue }, { 4, "adversaire" + advNum }, { 5, childOpt } } }); } } } #endregion var selectaction = game.PossibleActions.FirstOrDefault( action => action.ActionType == PlayerActionType.Unknown && action.Data[0].ToString() == "----- Select an action -----"); if (selectaction != null) { game.PossibleActions.Remove(selectaction); } }
private static IEnumerator SendTakePutBackCardPostMessage(BgoSessionObject sessionObject, BgoGame game, String postUrl, String idNote, Action callback) { postUrl = RemoveCharacterEntities(postUrl); WWWForm myPostData = new WWWForm(); myPostData.AddField("idNote", idNote); myPostData.AddField("idMsgChat", ""); var cookieHeaders = myPostData.headers; cookieHeaders.Add("Cookie", "PHPSESSID=" + sessionObject._phpSession + "; identifiant=" + sessionObject._identifiant + "; mot_de_passe=" + sessionObject._motDePasse); //var data = Encoding.UTF8.GetString(myPostData.data); var www = new WWW(BgoBaseUrl + postUrl, myPostData.data, cookieHeaders); yield return(www); if (www.error != null) { Assets.CSharpCode.UI.Util.LogRecorder.Log(www.error); yield break; } var responseText = www.text; BgoPageProvider.FillGameBoard(responseText, game); if (callback != null) { callback(); } }
private static IEnumerator Perform2StepAction(BgoSessionObject sessionObject, BgoGame game, String actionValue, Action <List <PlayerAction> > callback) { var postUrl = RemoveCharacterEntities(game.ActionFormSubmitUrl); WWWForm myPostData = new WWWForm(); var actionSp = actionValue.Split(";".ToCharArray()); var idCarte = "0"; foreach (var pair in game.ActionForm) { if (pair.Key == "action") { myPostData.AddField("action", actionValue); } else if (pair.Key == "idCarteAction") { if (actionSp.Length > 1 && actionSp[0] == "12") { idCarte = actionSp[1]; myPostData.AddField("idCarteAction", actionSp[1]); } else { myPostData.AddField("idCarteAction", pair.Value); } } else { myPostData.AddField(pair.Key, pair.Value); } } var cookieHeaders = myPostData.headers; cookieHeaders.Add("Cookie", "PHPSESSID=" + sessionObject._phpSession + "; identifiant=" + sessionObject._identifiant + "; mot_de_passe=" + sessionObject._motDePasse); //var data = Encoding.UTF8.GetString(myPostData.data); var www = new WWW(BgoBaseUrl + postUrl, myPostData.data, cookieHeaders); yield return(www); if (www.error != null) { Assets.CSharpCode.UI.Util.LogRecorder.Log(www.error); yield break; } var responseText = www.text; //Step1 Complete var labelMatches = BgoRegexpCollections.ExtractActionChoice.Matches(responseText); if (labelMatches.Count <= 0) { callback(new List <PlayerAction>()); yield break; } var actions = new List <PlayerAction>(); foreach (Match m in labelMatches) { var msg = m.Groups[2].Value; var optValue = m.Groups[1].Value; BgoPlayerAction pa = new BgoPlayerAction { ActionType = PlayerActionType.Unknown }; pa.Data[0] = msg; pa.Data[1] = optValue; pa.Data[2] = idCarte; actions.Add(pa); } BgoActionFormater.FormatInternalAction(actions, responseText); if (callback != null) { callback(actions); } }
public static IEnumerator PostAction(BgoSessionObject sessionObject, BgoGame game, BgoPlayerAction action, Action callback) { switch (action.ActionType) { //Special function case PlayerActionType.TakeCardFromCardRow: case PlayerActionType.PutBackCard: return(SendTakePutBackCardPostMessage(sessionObject, game, action.Data[3].ToString(), action.Data[2].ToString(), callback)); //----optvalue is [1] case PlayerActionType.ResetActionPhase: case PlayerActionType.PassPoliticalPhase: case PlayerActionType.EndActionPhase: case PlayerActionType.PlayActionCard: case PlayerActionType.ElectLeader: case PlayerActionType.SetupTactic: case PlayerActionType.AdoptTactic: case PlayerActionType.PlayColony: case PlayerActionType.PlayEvent: return(PerformAction(sessionObject, game, action.Data[1].ToString(), callback)); //----optvalue is [2] case PlayerActionType.IncreasePopulation: case PlayerActionType.BuildBuilding: case PlayerActionType.Revolution: case PlayerActionType.ResolveEventOption: case PlayerActionType.DevelopTechCard: return(PerformAction(sessionObject, game, action.Data[2].ToString(), AttachIdCarte(3, action), callback)); //----optvalue is [3] case PlayerActionType.UpgradeBuilding: case PlayerActionType.BuildWonder: return(PerformAction(sessionObject, game, action.Data[3].ToString(), AttachIdCarte(4, action), callback)); //----has additional form case PlayerActionType.Destory: case PlayerActionType.Disband: return(PerformAction(sessionObject, game, action.Data[1].ToString(), new Dictionary <String, String> { { "unite", action.Data[2].ToString() } }, callback)); case PlayerActionType.Aggression: return(PerformAction(sessionObject, game, action.Data[3].ToString(), new Dictionary <String, String> { { action.Data[4].ToString(), action.Data[5].ToString() } }, callback)); //----Unknown case PlayerActionType.Unknown: return(PerformAction(sessionObject, game, action.Data[1].ToString(), callback)); default: return(null); } }
// ReSharper disable once FunctionComplexityOverflow private static void ExtractPlayerNameAndResource(string html, BgoGame game) { var myNameMatch = BgoRegexpCollections.ExtractMyName.Match(html); var myName = myNameMatch.Groups[1].Value.Replace(" ", " "); var matches = BgoRegexpCollections.ExtractPlayerNameAndResource.Matches(html); for (var i = 0; i < matches.Count; i++) { Match mc = matches[i]; var board = game.Boards[i]; board.PlayerName = mc.Groups[1].Value; if (myName.ToLower() == board.PlayerName.ToLower()) { game.MyPlayerIndex = i; } var strCut = mc.Groups[0].Value; var resourceMatches = BgoRegexpCollections.ExtractPlayerNameAndResourceCutResourceOut.Matches(strCut); foreach (Match rmc in resourceMatches) { switch (rmc.Groups[1].Value) { case "Culture": { var cm = BgoRegexpCollections.ExtractPlayerNameAndResourceNormal.Match(rmc.Groups[2].Value); int curr = Convert.ToInt32(cm.Groups[1].Value); int incr = cm.Groups[3].Value == "-" ? 0 : Convert.ToInt32(cm.Groups[3].Value); board.Resource[ResourceType.Culture] = curr; board.Resource[ResourceType.CultureIncrement] = incr; } break; case "Science": { var cm = BgoRegexpCollections.ExtractPlayerNameAndResourceSpecial.Match(rmc.Groups[2].Value); int curr = Convert.ToInt32(cm.Groups[1].Value); int mcurr = cm.Groups[2].Value == "" ? 0 : Convert.ToInt32(cm.Groups[2].Value); int incr = cm.Groups[4].Value == "-" ? 0 : Convert.ToInt32(cm.Groups[4].Value); board.Resource[ResourceType.Science] = curr; board.Resource[ResourceType.ScienceForMilitary] = mcurr; board.Resource[ResourceType.ScienceIncrement] = incr; } break; case "Puissance": { var cm = BgoRegexpCollections.ExtractPlayerNameAndResourceNormal.Match(rmc.Groups[2].Value); int curr = Convert.ToInt32(cm.Groups[1].Value); board.Resource[ResourceType.MilitaryForce] = curr; } break; case "Exploration": { var cm = BgoRegexpCollections.ExtractPlayerNameAndResourceNormal.Match(rmc.Groups[2].Value); int curr = cm.Groups[1].Value == "" ? 0 : Convert.ToInt32(cm.Groups[1].Value); board.Resource[ResourceType.Exploration] = curr; } break; case "HF": { var cms = BgoRegexpCollections.ExtractPlayerNameAndResourceHappy.Matches(rmc.Groups[2].Value); board.Resource[ResourceType.HappyFace] = cms.Count; //cms = BgoRegexpCollections.ExtractPlayerNameAndResourceUnhappy.Matches(rmc.Groups[2].Value); //board.ResourceQuantity[ResourceType.UnhappyFace] = cms.Count; } break; case "Nourriture": { var cm = BgoRegexpCollections.ExtractPlayerNameAndResourceNormal.Match(rmc.Groups[2].Value); int curr = Convert.ToInt32(cm.Groups[1].Value); int incr = cm.Groups[3].Value == "-" ? 0 : Convert.ToInt32(cm.Groups[3].Value); board.Resource[ResourceType.Food] = curr; board.Resource[ResourceType.FoodIncrement] = incr; } break; case "Ressources": { var cm = BgoRegexpCollections.ExtractPlayerNameAndResourceSpecial.Match(rmc.Groups[2].Value); int curr = Convert.ToInt32(cm.Groups[1].Value); int mcurr = cm.Groups[2].Value == "" ? 0 : Convert.ToInt32(cm.Groups[2].Value); int incr = cm.Groups[4].Value == "" ? 0 : Convert.ToInt32(cm.Groups[4].Value); board.Resource[ResourceType.Resource] = curr; board.Resource[ResourceType.ResourceForMilitary] = mcurr; board.Resource[ResourceType.ResourceIncrement] = incr; } break; default: Assets.CSharpCode.UI.Util.LogRecorder.Log("UnknownRMC:" + rmc.Groups[1].Value); break; } } } }
/// <summary> /// 填充面板的帮助方法 /// </summary> /// <param name="html"></param> /// <param name="game"></param> // ReSharper disable once FunctionComplexityOverflow internal static void FillGameBoard(String html, BgoGame game) { //分析用户面板 game.PossibleActions = new List <PlayerAction>(); //解出卡牌列 var matches = BgoRegexpCollections.ExtractCardRow.Matches(html); game.CardRow = new List <CardRowCardInfo>(); foreach (Match mc in matches) { var card = civilopedia.GetCardInfoByName((Age)Enum.Parse(typeof(Age), mc.Groups[5].Value), mc.Groups[6].Value); BgoCardRowCardInfo cardRowCardInfo = new BgoCardRowCardInfo { Card = card, CanPutBack = mc.Groups[4].Value.Contains("carteEnMain"), CanTake = mc.Groups[2].Value != "" && (!mc.Groups[4].Value.Contains("carteEnMain")), CivilActionCost = BgoRegexpCollections.ExtractGovenrmentAndActionPointsMissing.Matches(mc.Groups[8].Value).Count }; //LogRecorder.Log(card.CardName + mc.Groups[2].Value); BgoPlayerAction pa = new BgoPlayerAction { ActionType = PlayerActionType.TakeCardFromCardRow }; pa.Data[0] = cardRowCardInfo; pa.Data[1] = game.CardRow.Count; //Card Row Pos pa.Data[2] = mc.Groups[3].Value; //idNote pa.Data[3] = mc.Groups[2].Value; //PostUrl //能拿能放回去,才能有Action if (cardRowCardInfo.CanPutBack || cardRowCardInfo.CanTake) { game.PossibleActions.Add(pa); } game.CardRow.Add(cardRowCardInfo); } //当前事件 var matchCurrentEvent = BgoRegexpCollections.ExtractCurrentEvent.Match(html); if (matchCurrentEvent.Groups[3].Value == "") { game.CurrentEventAge = (Age)Enum.Parse(typeof(Age), matchCurrentEvent.Groups[5].Value); game.CurrentEventCard = civilopedia.GetCardInfoByName(game.CurrentEventAge, matchCurrentEvent.Groups[6].Value); game.CurrentEventCount = matchCurrentEvent.Groups[7].Value; } else { game.CurrentEventAge = (Age)Enum.Parse(typeof(Age), matchCurrentEvent.Groups[3].Value); game.CurrentEventCard = null; game.CurrentEventCount = matchCurrentEvent.Groups[7].Value; } //未来事件 var matchFutureEvent = BgoRegexpCollections.ExtractFutureEvent.Match(html); if (matchFutureEvent.Groups[1].Value.Length > 4) { game.FutureEventAge = Age.A; game.FutureEventCount = "0"; } else { game.FutureEventAge = (Age)Enum.Parse(typeof(Age), matchFutureEvent.Groups[1].Value); game.FutureEventCount = matchFutureEvent.Groups[2].Value; } //卡牌剩余 var matchCivilRemain = BgoRegexpCollections.ExtractCivilCardRemains.Match(html); game.CivilCardsRemain = Convert.ToInt32(matchCivilRemain.Groups[2].Value); var matchMilitaryRemain = BgoRegexpCollections.ExtractMilitryCardRemains.Match(html); game.MilitaryCardsRemain = Convert.ToInt32(matchMilitaryRemain.Groups[2].Value); //当前阶段 var matchPhase = BgoRegexpCollections.ExtractGamePhase.Match(html); var phase = matchPhase.Groups[1].Value; switch (phase.Trim()) { case "Political Phase": game.CurrentPhase = TtaPhase.PoliticalPhase; break; case "Action Phase": game.CurrentPhase = TtaPhase.ActionPhase; break; case "Event Resolution": game.CurrentPhase = TtaPhase.EventResolution; break; case "Discard Phase": game.CurrentPhase = TtaPhase.DiscardPhase; break; default: game.CurrentPhase = TtaPhase.OtherPhase; break; } //时代和回合 var matchAgeAndRound = BgoRegexpCollections.ExtractAgeAndRound.Match(html); game.CurrentAge = (Age)Enum.Parse(typeof(Age), matchAgeAndRound.Groups[1].Value); game.CurrentRound = Convert.ToInt32(matchAgeAndRound.Groups[2].Value); //可抄袭阵型 var sharedTacticsMatch = BgoRegexpCollections.ExtractSharedTactics.Match(html); game.SharedTactics = new List <CardInfo>(); foreach (Match m in BgoRegexpCollections.ExtractSharedTacticsItem.Matches(sharedTacticsMatch.Groups[1].Value)) { if (m.Groups[1].Value == " ") { continue; } game.SharedTactics.Add(civilopedia.GetCardInfoByName((Age)Enum.Parse(typeof(Age), m.Groups[1].Value), m.Groups[2].Value)); } //拆开玩家面板 matches = BgoRegexpCollections.ExtractPlayerPlate.Matches(html); game.Boards = new List <TtaBoard>(); int plateStart = -1; foreach (Match mc in matches) { if (plateStart != -1) { String plate = html.Substring(plateStart, mc.Index - plateStart); TtaBoard board = new TtaBoard(); game.Boards.Add(board); FillPlayerBoard(board, plate); } plateStart = mc.Index; if (mc.Groups[2].Value != "") { break; } } #region 校准名字和资源 ExtractPlayerNameAndResource(html, game); #endregion //可用行动 var subDropdown = BgoRegexpCollections.ExtractSubDropDown("action").Match(html); if (subDropdown.Success) { matches = BgoRegexpCollections.ExtractActions.Matches(subDropdown.Groups[1].Value); foreach (Match mc in matches) { BgoPlayerAction pa = new BgoPlayerAction { ActionType = PlayerActionType.Unknown }; pa.Data[0] = mc.Groups[2].Value; pa.Data[1] = mc.Groups[1].Value; game.PossibleActions.Add(pa); } Match mSubmitForm = BgoRegexpCollections.ExtractSubmitForm.Match(html); game.ActionForm = new Dictionary <string, string>(); if (mSubmitForm.Success) { game.ActionFormSubmitUrl = mSubmitForm.Groups[1].Value; matches = BgoRegexpCollections.ExtractSubmitFormDetail.Matches(mSubmitForm.Groups[2].Value); foreach (Match mc in matches) { if (mc.Groups[2].Value != "") { game.ActionForm[mc.Groups[2].Value] = ""; } else { game.ActionForm[mc.Groups[4].Value] = mc.Groups[5].Value; } } } } BgoActionFormater.Format((BgoGame)game, html); }