//Usually dev should be call and provide this DB cause can be a risk make all this calls, or you can create other type of method like call specific player maybe import from futbin? //This method will update also clubId cause on GenInvPlayers is not possible know it private static async Task GenInform(IFutClient futClient) { var targetlist = FutManager.InvDb.Where(i => (i.Value is FifaInvPlayer) && (i.Value.CardType == CardType.Gold || i.Value.CardType == CardType.Silver)).Select(i => (FifaInvPlayer)i.Value).ToList(); var total = targetlist.Count(); for (int i = 0; i < total; i++) { _logger.Log("GenInform", "process " + i + "/" + total); try { await futClient.RequestPlayerVariants(targetlist[i].AssetId); } catch (FifaSessionException e) { //when so much call trigger it await futClient.ReSession(); await futClient.RequestPlayerVariants(targetlist[i].AssetId); } } //FutManager.InvDb is updated by it self then just save it using var stream = new MemoryStream(); Serializer.Serialize(stream, FutManager.InvDb); await File.WriteAllBytesAsync("invDb.proto", stream.ToArray()); }
private static async Task WorksProcess(IFutClient futClient) { if (!await IsLogged(futClient)) { return; } //Now You are Logged then can perform other calls //At this point you should be your method to check Watchlist Status and Manage it ... if (NextWatchListCheck < DateTime.UtcNow) { NextWatchListCheck = DateTime.UtcNow.AddMinutes(5); var watchlistData = await futClient.GetWatchList(); WatchList = watchlistData.AuctionInfo; Coins = watchlistData.Credits; return; } //WatchList Worker // rember to apply change on your Watchlist when call methods (example if you call RemoveOutBidFromWatchlist rember to delete on list removed items) //futClient.RemoveOutBidFromWatchlist //futClient.ListItem < First to call It from Watchlist rember to call PriceLimitsByItemId to get price range then rember to add on your List TradePile new item (cause you call update if not expire 5 minutes)(need to cast to FifaAuction), try to Catch FifaStuckException for trade stuck //futClient.SendItemToTradePile < rember to add to TradePile new item, try to Catch F //futClient.PlaceBid < rember to put inside try catch and intercept FifaPermissionDeniedException when somebody is more fast than your or FifaStuckException to detect bid stuck //when you are in watchlist "cycle" cause you bidding rember to update auction status with GetAuctionsStatusInfo(...) //Usually you need to create a list of items to update by default EA will call each sec if expire in less 30 secs, each 5 sec if expire under 60 sec, each 2 minutes if expire under 10 minutes, other each 10 minutes //At this point you should be your method to check Tradepile Status and Manage it ... if (NextTradePileCheck < DateTime.UtcNow) { NextTradePileCheck = DateTime.UtcNow.AddMinutes(5); var tradeData = await futClient.GetTradePile(); TradePile = tradeData.AuctionInfo; Coins = tradeData.Credits; return; } //TradePile Worker //futClient.RemoveSoldFromTradePile < then must call GetTradePile() //futClient.RelistTradePile < catch FifaPermissionDeniedException when happen you need to list one by one, then must call GetTradePile() //futClient.ListItem < catch FifaStuckException for stuck, then must call GetTradePile() }
private static async Task ProcessAccount() { if (!await FutManager.IsFifaSupported(_logger)) { throw new NotImplementedException("New Fifa Code"); } IFutClient futClient = FutManager.CreateNewInstance(_logger); int errorTrigger = 0; while (true) { //Usually all main exception should be catch here ... specific exception like deny when bidding or stuck should be catch in specific method try { await WorksProcess(futClient); errorTrigger = 0; } catch (FifaConfigException ex) { //All exceptions about wrong config like password ... string message = "Config Exception: " + ex.Message; _logger.LogError("Main", message); break; } catch (FifaLogicException ex) { _logger.LogWarning("Main", "Logic Exception: " + ex.Message); errorTrigger++; if (errorTrigger >= 3) { break; } } catch (FifaInternalServerException e) { _logger.LogWarning("Main", "Issue with server task sleep for 10 minutes"); await Task.Delay(10 * 60 * 1000); } catch (FifaSessionExceptionCaptcha e) { _logger.Log("Main", "Session Captcha: " + e.Message); //Must call it when trigger funcaptcha, then you need to login again and solve it, method setup IsLogged false to help you, at this point you can also force people to solve captcha by their self if dont wanna use solver after logout //Remember must be solved only when trigger on GetUserInfo() not here await futClient.LogOut(); } catch (FifaSessionException e) { _logger.LogWarning("Main", "Session: " + e.Message); if (errorTrigger >= 3) { break; } //Usually happen when somebody is logged at same time await futClient.ReSession(); } catch (FifaException e) { _logger.LogError("Main", "FifaException: " + e.Message); errorTrigger++; if (errorTrigger >= 3) { break; } } catch (TaskCanceledException) { //Network Issue? Perfomance Issue? await Task.Delay(10 * 1000); } catch (Exception e) { _logger.LogError("Main", "Exception: " + e.Message); errorTrigger++; if (errorTrigger >= 3) { break; } } int secPause = FutManager.RandomNumber(2 * 10, 4 * 10); await Task.Delay(secPause * 100); } futClient.Dispose(); //Remember to Dispose when finish to use instance to release resources }
private async Task <List <FifaAuctionRestricted> > SearchInMarket(IFutClient futClient, FifaInvBase item, short page, uint maxBuynow = 0, uint maxBid = 0, uint minBid = 0, uint minBuyNow = 0) { //usually need to increase each page and not jump from 0 to 50 for example, but you can do it at your own risk :D //Rember you can BID/BIN only items on Page that you current request, you can not for example store 3 pages than try to bid result on first page or will return error //when you are in Search Page cause you bidding/bin rember to update auctions status with GetAuctionsStatusInfo(...) //Usually you need to create a list of items to update by default EA will call each sec if expire in less 30 secs, each 5 sec if expire under 60 sec, each 2 minutes if expire under 10 minutes, other each 10 minutes //Rember EA cached results for 30 secs with same parameters then if you example try to bin sniping and refreshing page you need to change almost 1 parameter to avoid cached result like increase/decrease price if (page < 1) { throw new ArgumentException("Start Page under 1"); } FifaSearchParameters _searchargs; switch (item.ItemType) { case FifaMarketType.Player: _searchargs = new FifaPlayerSearchParameters() { //ChemistryStyle = targetType, //PreferredPosition = targetType, }; FifaInvPlayer fifaInvPlayer = (FifaInvPlayer)item; //(EnableUnsafeCode) //_searchargs.ResourceId = fifaInvPlayer.Id; //On Web app usually you are not allow to do it //else { _searchargs.ResourceId = fifaInvPlayer.AssetId; ((FifaPlayerSearchParameters)_searchargs).CardType = fifaInvPlayer.CardType != CardType.Special ? CardType.Any : fifaInvPlayer.CardType; } break; case FifaMarketType.PlayersCustom: _searchargs = new FifaPlayerSearchParameters() { /* * CardType = itemPsearch.CardType, * ChemistryStyle = itemPsearch.ChemistryStyle, * League = itemPsearch.LeagueId, * Nation = itemPsearch.NationId, * Team = itemPsearch.TeamId, * PreferredPosition = itemPsearch.PreferredPosition, */ }; break; case FifaMarketType.Contract: _searchargs = new FifaDevelopmentSearchParameters(DevelopmentType.contract); //if (EnableUnsafeCode) //((FifaDevelopmentSearchParameters)_searchargs).DefinitionId = item.Id; //On Web app usually you are not allow to do it break; case FifaMarketType.FitnessCard: _searchargs = new FifaDevelopmentSearchParameters(DevelopmentType.fitness); //if (EnableUnsafeCode) //((FifaDevelopmentSearchParameters)_searchargs).DefinitionId = item.Id; //On Web app usually you are not allow to do it break; case FifaMarketType.HealtCard: _searchargs = new FifaDevelopmentSearchParameters(DevelopmentType.healing); //if (EnableUnsafeCode) //((FifaDevelopmentSearchParameters)_searchargs).DefinitionId = item.Id; //On Web app usually you are not allow to do it break; case FifaMarketType.PlayStyle: _searchargs = new FifaTrainingSearchParameters(TrainingType.playStyle) { ChemistryStyleType = (ChemistryStyleType)item.Id, }; break; case FifaMarketType.Position: _searchargs = new FifaTrainingSearchParameters(TrainingType.position) { PositionChangeType = (PositionChangeType)item.Id, }; break; case FifaMarketType.PlayerTraining: _searchargs = new FifaTrainingSearchParameters(TrainingType.playerTraining); //if (EnableUnsafeCode) //((FifaDevelopmentSearchParameters)_searchargs).DefinitionId = item.Id; //On Web app usually you are not allow to do it break; default: throw new Exception("MarketWorker unknown ItemMarket Type"); } _searchargs.MaxBid = maxBid; _searchargs.MaxBuy = maxBuynow; _searchargs.MinBid = minBid; _searchargs.MinBuy = minBuyNow; _searchargs.Page = page; try { var callresponse = await futClient.Search(_searchargs); return(new List <FifaAuctionRestricted>(callresponse.AuctionInfo)); } catch (FifaStuckException e) { //try to catch 3 times in row before flag stuck return(null); } }
private static async Task <bool> IsLogged(IFutClient futClient) { if (futClient.IsLogged) { return(true); } string fifaEmail = "*****@*****.**"; string fifaPass = "******"; string proxyAddress = null; //"192.168.1.2:8888"; string proxyUser = null; string proxyPass = null; Regex rgx = new Regex("[^a-zA-Z0-9]"); string storageFile = Path.Combine(AssemblyPath, rgx.Replace(fifaEmail, "") + ".storage.bin"); //must be unique for each account string solverApiKey = ""; //Get key on http://api.de-ltd.co.uk/login bool useFunSolverProxy = false; //if true require proxy setup on loggin function ITwoFactorCodeProvider twoFactorCodeProvider = new AppAuthTwoFactorCodeProvider("xxxxxxxxxxxxx"); //You can also use ImapAuthTwoFactorCodeProvider, DisabledTwoFactorCodeProvider, AppAuthTwoFactorCodeProvider or implement a new by your self //Will throw Exception if detect new fifa code, then not need to use FutManager.IsFifaSupported before call it var accountType = await futClient.Loggin(fifaEmail, fifaPass, twoFactorCodeProvider, proxyAddress, proxyUser, proxyPass, storageFile); _logger.Log("IsLogged", "Logged on accountType " + accountType); FifaUserResponse accountInfo = null; try { accountInfo = await futClient.GetUserInfo(); } catch (FifaSessionExceptionCaptcha) { //Need to solve captcha before we can continue //We use futmsolver solver but you can add a new one just implement here ... or you can also stop bot and ask to people to solve in standard app if (useFunSolverProxy) { //Require proxy setup on Loggin function or will return error if (!await futClient.FuncaptchaProxySolver(solverApiKey)) { throw new Exception("too many tenatives"); } } else { //We need to request captcha data before call funcaptcha var captchaData = await futClient.GetCaptchaKey(); string callBack = null; //It try to make max 3 tentatives for (byte t = 0; t < 3; t++) { callBack = await futClient.FuncaptchaSolver(solverApiKey, captchaData.Pk, captchaData.Blob); if (!string.IsNullOrEmpty(callBack)) { break; } } if (string.IsNullOrEmpty(callBack)) { throw new Exception("too many tenatives"); } //need to validate code on EA side bool result = await futClient.ValidateCaptchaKey(callBack); if (!result) { throw new Exception("usually never happen, session expired ?!?"); } } //Call again after captcha solved accountInfo = await futClient.GetUserInfo(); } //0: "NONE" 1: "BLACKLIST" 2: "WHITELIST" 3: "GREYLIST" 100: "MAINTENANCE" if (accountInfo.UserInfo.Feature.Trade == 0) { throw new FifaConfigException("MarketNotUnlocked"); } else if (accountInfo.UserInfo.Feature.Trade == 1) { throw new FifaConfigException("MarketLockedBlack"); } else if (accountInfo.UserInfo.Feature.Trade == 3) { throw new FifaConfigException("MarketLockedGrey"); } Coins = accountInfo.UserInfo.Credits; //Usually you will update credits when call GetTrade/GetWatch //Must Use it cause EA cache data for 5 minutes then you can't ask Each time this data NextTradePileCheck = DateTime.UtcNow.AddMinutes(5); NextWatchListCheck = DateTime.UtcNow.AddMinutes(5); NextUnassignedCheck = DateTime.UtcNow.AddMinutes(5); var liveMessages = await futClient.GetLiveMessage(); //Call only here no other part var unassignedData = await futClient.GetUnassignedItems(); var tradeData = await futClient.GetTradePile(); //You can use Credits inside to update current credit when call it var watchlistData = await futClient.GetWatchList(); //You can use Credits inside to update current credit when call it var activeMessages = await futClient.GetActiveMessage(); //Call only here no other part Unassigned = unassignedData.ItemData; //DuplicateItemIdList should be use to know if you can send player to club TradePile = tradeData.AuctionInfo; WatchList = watchlistData.AuctionInfo; foreach (var message in liveMessages?.MessageList) { _logger.Log("IsLogged", "LiveMessage " + message.Renders.FirstOrDefault(i => i.Name == "bodyText").Value); await Task.Delay(FutManager.RandomNumber(30, 50) * 100); await futClient.CloseLiveMessage(message.MessageId); } foreach (var message in activeMessages?.ActiveMessage) { _logger.Log("IsLogged", "ActiveMessage You have Active Message message[" + message.Message + "] id[" + message.Id + "] rewardType[" + message.RewardType + "] rewardValue[" + message.RewardValue + "]"); await Task.Delay(FutManager.RandomNumber(30, 50) * 100); await futClient.CloseActiveMessage(message.Id); } _logger.Log("IsLogged", "Logged"); return(true); }
public void Setup() { _futClient = new FutClient(); }
public void CreateClient(bool passNullInstance = false) { _requestFactories = new FutRequestFactories(); _futClient = new FutClient(passNullInstance ? null : _requestFactories); }