Closed bbday closed 8 years ago
did you checked if the PIN event changes if you have a temp BAN?
I don't think so, cause sometime i got temp ban from web ui (fast bid) XD
As I can see it's always the same call right?
it change when you browse from different area: transfert list > search items (each page search) > watchlist
s value is autoincrement for each call. http://nopaste.inside-irc.net/paste/RgPlXdpUW/
It is only affected to watchlist/tradepile/transfermarket?
evey call from web menu: watchlist/tradepile/transfermarket/search/unassigned ...
Ok - Then we can just implement it into every Task in FutClient.cs
Can you help me how to setup fiddler to see these requests? - I just these the "tunnel" packets and my HTTPS decryption is enabled.
There are a lot of tuttorial on google, anyway you need also to add certificate to your machine or fidder can't see encrypted traffic
Surely, but I don't think the problem are the settings of my Fiddler, because it decrypts the whole EA traffic. Only the tunnel to the pin-river seems not be decrypted. You can also provide me a Fiddler file and will implement it to the toolkit.
Can you close the issue or provide a fiddler trace? There is no traffic flow to pin-river.data.ea.com:
On the companion app there is a flow to pin-river.data.ea.com and I plan to implement it:
You can easily see pin events in firebug http://prntscr.com/ae4qsc
I have a very clumsy implantation of it, but not on the toolkit level, and I feel that it helped with bans and other flagging issues.
I cannot find FireBug for Google Chrome :( - If I click on the installation link on their webpage, nothing happens - If you will just send me your Request/Response I can easily add it to the toolkit.
In Chrome you can see under Network http://prntscr.com/ae9bjz, how can I send it to you? Also I'm just coding as a hobby, I don't think my hackish - code is public-worthy but OK. Give me your email, also I did mobile login too, you may want to take a look maybe it helps you.
Thanks! I can see the request now - I don't get why I can't see them with Fiddler. Anyways - How did you implement these requests? Do you have a list of these ids:
fromid: "Transfer List"
toid: "Transfer Targets"
I would bet all but trydis are just hobby developers.
Basically I did a request that takes fromid, toid, menu, status, etc, and then when I call the toolkit, get trade pile for example, after I do a pin request too. Also there is a mobile parameter too, if you'll have that, I could just send you the code.
Request implementation I can easily by my own, but how to call is demanding. It should be done automatically after each request.
I could not do automatically, I don't know the toolkit enough, I did 2 auto request for clear trade pile and send to trade pile but then I give up. I'm just manually calling it after I call LoginAsync for example. Also keep in mind, there is a mobile flag too.
I will to try to implement this tonight and send a pull request.
The request itself is not complicated, quite simple, I just format a string as json by string.format, I'm not even sure I'm sending the right pin requests, in my spaghetti code, but it did helped, I had bans before and I don't remember having any bans since i implemented it but is been only 2-3 weeks.
Yes, but you need to set your sid, nucleus id, the toid and fromid each request. Then you need to know which request you made before.
Do you know for which requests we have PinRequests so far I seen:
What else?
Yes, I set those manually as parameters, here are the headers I'm using maybe it helps.
I'm sending a pin request after each call, after listing a card, removing a card, login, unassigned, etc. As far as I know each call has a pin request.
protected void AddPinHeaders()
{
HttpClient.AddConnectionKeepAliveHeader();
HttpClient.AddRequestHeader("Origin", "https://www.easports.com");
HttpClient.AddRequestHeader("x-ea-taxv", "1.1");
HttpClient.AddRequestHeader("x-ea-game-type", "sku");
AddUserAgent();
HttpClient.AddRequestHeader(HttpHeaders.ContentType, "application/json");
HttpClient.AddRequestHeader("X-Requested-With", "ShockwaveFlash/20.0.0.286");
HttpClient.AddRequestHeader("x-ea-game-id", "fifa16");
AddAcceptHeader("*/*");
AddReferrerHeader("https://www.easports.com/iframe/fut16/bundles/futweb/web/flash/FifaUltimateTeam.swf?cl=155438");
AddAcceptEncodingHeader();
AddAcceptLanguageHeader();
}
protected void AddPinHeadersMobile()
{
HttpClient.AddConnectionKeepAliveHeader();
HttpClient.AddRequestHeader("Origin", "file://");
HttpClient.AddRequestHeader("x-ea-taxv", "1");
HttpClient.AddRequestHeader("CSP", "active");
AddMobileUserAgent();
HttpClient.AddRequestHeader(HttpHeaders.ContentType, "application/json");
AddAcceptHeader("text/plain, */*; q=0.01");
HttpClient.AddRequestHeader("x-ea-game-id-type", "sellid");
HttpClient.AddRequestHeader("x-ea-game-id", "859051");
AddAcceptEncodingHeader();
AddAcceptLanguageHeader();
}
using System.Net.Http;
using System.Threading.Tasks;
using UltimateTeam.Toolkit.Constants;
using UltimateTeam.Toolkit.Models;
namespace UltimateTeam.Toolkit.Requests
{
internal class PinEventRequest : FutRequestBase, IFutRequest<byte>
{
bool mobile = false;
int s = 0;
string fromid = "";
string toid = "";
string menu = "";
string en = "";
bool status = false;
public PinEventRequest(bool _mobile, int _s, string _fromid, string _toid, string _menu, string _en, bool _status)
{
mobile = _mobile;
s = _s;
en = _en;
fromid = _fromid;
toid = _toid;
menu = _menu;
status = _status;
}
public async Task<byte> PerformRequestAsync()
{
string content = status ? string.Format(@"{{""v"":""{12}"",""taxv"":1.1,""tidt"":""sku"",""tid"":""{0}"",""rel"":""prod"",""et"":""client"",""sid"":""{1}"",""plat"":""{2}"",""custom"":{{{11}}},""loc"":""en_GB"",""events"":[{{""core"":{{""pidm"":{{""nucleus"":""{3}""}},""s"":{4},""pid"":""{5}"",""en"":""{13}"",""pidt"":""persona"",""ts_event"":""{6}""}},""{7}"":""{8}"",""type"":""{9}"",""custom"":{{}}}}],""ts_post"":""{10}""}}",
mobile ? "859051" : "FUT16WEB", SessionId, mobile ? "android" : "win", NucleusId, s.ToString(), PersonaId, GetTimeSpecial(), toid, fromid, menu, GetTimeSpecial(), mobile ? "\"networkAccess\":\"W\"" : "", mobile ? "16.2.0.155106" : "v16.0.155438", en) : string.Format(@"{{""v"":""{12}"",""taxv"":1.1,""tidt"":""sku"",""tid"":""{0}"",""rel"":""prod"",""et"":""client"",""sid"":""{1}"",""plat"":""{2}"",""custom"":{{{11}}},""loc"":""en_GB"",""events"":[{{""core"":{{""pidm"":{{""nucleus"":""{3}""}},""s"":{4},""pid"":""{5}"",""en"":""{13}"",""pidt"":""persona"",""ts_event"":""{6}""}},""toid"":""{7}"",""fromid"":""{8}"",""type"":""{9}"",""custom"":{{}}}}],""ts_post"":""{10}""}}",
mobile ? "859051" : "FUT16WEB", SessionId, mobile ? "android" : "win", NucleusId, s.ToString(), PersonaId, GetTimeSpecial(), toid, fromid, menu, GetTimeSpecial(), mobile ? "\"networkAccess\":\"W\"" : "", mobile ? "16.2.0.155106" : "v16.0.155438", en);
if (mobile) { AddPinHeadersMobile(); } else { AddPinHeaders(); }
var tradePileResponseMessage = await HttpClient.PostAsync(string.Format("https://pin-river.data.ea.com/pinEvents"),
new StringContent( content, System.Text.Encoding.UTF8, "application/json"
)
)
.ConfigureAwait(false);
return 0;
}
private static string GetTimeSpecial()
{
return System.DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ss.fffZ");
}
}
}
this is the request
Can you send me the Ids you identified? - I would create a model for the request, because it's better to debug.
Like:
namespace UltimateTeam.Toolkit.Models
{
public class Pin
{
public string Custom { get; set; }
public string Et { get; set; }
public PinEvents PinEvents { get; set; }
public string Loc { get; set; }
public string Plat { get; set; }
public string Rel { get; set; }
public string Sid { get; set; }
public string Taxv { get; set; }
public string Tid { get; set; }
public string Tidt { get; set; }
public string Ts_post { get; set; }
public string V { get; set; }
}
}
etc.
I don't have that my parameters looks something like
currentLocation = "Transfer List"; await utClient.SendPinEventDataAsync(mobileActive, sessionRequests, currentLocation, "Transfer Market Search Results", "menu", "page_view", false);
currentLocation = "Unassigned Items";
await utClient.SendPinEventDataAsync(mobileActive, pinRequests, currentLocation, "Unassigned Items", "menu", "page_view", false);
Yes I'm looking exactly for the IDs like "Transfer Market Search Results", which is set in the variables toid and fromid - The variable menu is always "menu"?
await utClient.SendPinEventDataAsync(mobileActive, pinRequests, "status", "success", "nucleus", "login", true); await utClient.SendPinEventDataAsync(mobileActive, sessionRequests, currentLocation, "Transfer Market Search", "menu", "page_view", false); await utClient.SendPinEventDataAsync(mobileActive, pinRequests, currentLocation, "Transfer List", "menu", "page_view", false); await utClient.SendPinEventDataAsync(mobileActive, pinRequests, currentLocation, "Unassigned Items", "menu", "page_view", false); await utClient.SendPinEventDataAsync(mobileActive, pinRequests, currentLocation, "Transfer Targets", "menu", "page_view", false); await utClient.SendPinEventDataAsync(mobileActive, pinRequests, currentLocation, "Transfer List", "menu", "page_view", false); await utClient.SendPinEventDataAsync(mobileActive, pinRequests, currentLocation, "Transfer Market Search", "menu", "page_view", false); await utClient.SendPinEventDataAsync(mobileActive, pinRequests, currentLocation, "Transfer Market Search Results", "menu", "page_view", false);
I think tha's all I have the current locations names are the same as the 4th parameter, yes, menu except on login.
Nice! Thanks! A few additional questions:
No, no pin for place bid/send to trade-pile, Transfer Market Search before SearchAsync Transfer Market Search Results after
So you would do it like this:
await utClient.SendPinEventDataAsync(mobileActive, pinRequests, currentLocation, "Transfer Market Search", "menu", "page_view", false);
var searchParameters = new PlayerSearchParameters
{
Page = 1,
Level = Level.Gold,
ChemistryStyle = ChemistryStyle.Sniper,
League = League.BarclaysPremierLeague,
Nation = Nation.Norway,
Position = Position.Striker,
Team = Team.ManchesterUnited
};
var searchResponse = await client.SearchAsync(searchParameters);
foreach (var auctionInfo in searchResponse.AuctionInfo)
{
// Handle auction data
}
await utClient.SendPinEventDataAsync(mobileActive, pinRequests, currentLocation, "Transfer Market Search Results", "menu", "page_view", false);
await utClient.SendPinEventDataAsync(mobileActive, sessionRequests, currentLocation, "Transfer Market Search", "menu", "page_view", false); currentLocation = "Transfer Market Search";
results = await utClient.SearchAsync(Parameters);
await utClient.SendPinEventDataAsync(mobileActive, sessionRequests, currentLocation, "Transfer Market Search Results", "menu", "page_view", false); currentLocation = "Transfer Market Search Results";
foreach (var auctionInfo in searchResponse.AuctionInfo) { // Handle auction data }
handle data after in case inside auction info you need to bid/send to tradepile/buy etc.
Ok :+1:
Plus we have:
var purchasedItemsResponse = await client.GetPurchasedItemsAsync(); await utClient.SendPinEventDataAsync(mobileActive, pinRequests, currentLocation, "Unassigned Items", "menu", "page_view", false);
var watchlistResponse = await client.GetWatchlistAsync(); await utClient.SendPinEventDataAsync(mobileActive, pinRequests, currentLocation, "Transfer Targets", "menu", "page_view", false);
var tradePileResponse = await client.GetTradePileAsync(); await utClient.SendPinEventDataAsync(mobileActive, pinRequests, currentLocation, "Transfer List", "menu", "page_view", false);
Right?
var loginFut = await utClient.LoginAsync(........ ); pinRequests = 0; await utClient.SendPinEventDataAsync(mobileActive, pinRequests, "status", "success", "nucleus", "login", true); pinRequests++;
await utClient.SendPinEventDataAsync(mobileActive, pinRequests, currentLocation, "Unassigned Items", "menu", "page_view", false); currentLocation = "Unassigned Items"; pinRequests++; var unassignedList = await utClient.GetPurchasedItemsAsync();
await utClient.SendPinEventDataAsync(mobileActive, pinRequests, currentLocation, "Transfer Targets", "menu", "page_view", false); currentLocation = "Transfer Targets"; pinRequests++; var watchList = await utClient.GetWatchlistAsync();
await utClient.SendPinEventDataAsync(mobileActive, pinRequests, currentLocation, "Transfer List", "menu", "page_view", false); currentLocation = "Transfer List"; pinRequests++; tradePileList = await utClient.GetTradePileAsync();
await utClient.SendPinEventDataAsync(mobileActive, pinRequests, currentLocation, "Unassigned Items", "menu", "page_view", false); currentLocation = "Unassigned Items"; pinRequests++; var unassignedList = await utClient.GetPurchasedItemsAsync();
Ok - We need to count the requests. I don't get it:
Here we send it before:
await utClient.SendPinEventDataAsync(mobileActive, pinRequests, currentLocation, "Unassigned Items", "menu", "page_view", false);
currentLocation = "Unassigned Items";
pinRequests++;
var unassignedList = await utClient.GetPurchasedItemsAsync();
await utClient.SendPinEventDataAsync(mobileActive, pinRequests, currentLocation, "Transfer Targets", "menu", "page_view", false);
currentLocation = "Transfer Targets";
pinRequests++;
var watchList = await utClient.GetWatchlistAsync();
await utClient.SendPinEventDataAsync(mobileActive, pinRequests, currentLocation, "Transfer List", "menu", "page_view", false);
currentLocation = "Transfer List";
pinRequests++;
tradePileList = await utClient.GetTradePileAsync();
await utClient.SendPinEventDataAsync(mobileActive, pinRequests, currentLocation, "Unassigned Items", "menu", "page_view", false);
currentLocation = "Unassigned Items";
pinRequests++;
var unassignedList = await utClient.GetPurchasedItemsAsync();
Here we send it afterwards:
await utClient.SendPinEventDataAsync(mobileActive, sessionRequests, currentLocation, "Transfer Market Search", "menu", "page_view", false);
currentLocation = "Transfer Market Search";
results = await utClient.SearchAsync(Parameters);
await utClient.SendPinEventDataAsync(mobileActive, sessionRequests, currentLocation, "Transfer Market Search Results", "menu", "page_view", false);
currentLocation = "Transfer Market Search Results";
foreach (var auctionInfo in searchResponse.AuctionInfo)
{
// Handle auction data
}
S is the requests number and yes we need to count here are the parameters
Task SendPinEventDataAsync(bool Mobile, int S, string FromID, string ToID, string Menu, string En, bool Status)
return _requestFactories.SendPinEventRequestFactory(Mobile, S, FromID, ToID, Menu, En, Status).PerformRequestAsync();
Yes - Clear, but how about the other question - PinRequests for Watchlist, TradePile and Unassigned Items coming BEFORE the calls and for Transfer Market Search/Transfer Market Search Results they are coming AFTER the calls? Really?
I don't know the internals, I just followed the calls, Transfer Market Search is the search page http://prntscr.com/aeuqo8 I suppose search async goes to that first, and then goes to the results pages.
and then it moves back
if (currentLocation == "Transfer Market Search Results") { //pin data event info await utClient.SendPinEventDataAsync(mobileActive, pinRequests, currentLocation, "Transfer Market Search", "menu", "page_view", false); currentLocation = "Transfer Market Search"; pinRequests++; }
I just tested it - You're right:
For Tradepile, Watchlist and Unassigned Items the PinRequest is called before the i.e. GetWatchlist. For Transfermarket:
PinRequest (Transfer Market Search) Search Player PinRequest (Transfer Market Search Results)
Thanks for sharing your work - I will implement it into a pull request
You welcome, I did the mobile login too some time ago, if you have any questions on that.
Then have a look to my pull request - Maybe you have some comments on it. Would be nice if you know us next time such things, because we did double-work the mobile login :-/
Do you have also the page Ids for mobile pin requests like:
pgid=Hub - Home
nop, sorry.
You are sending the WebApp strings into the companion app right?
pretty much, it didn't occur to me that are different, since all other requests all the same.
By the way - There are a lot of various pin requests I traced:
using System;
using System.IO;
using System.Runtime.Serialization;
namespace UltimateTeam.Toolkit.Models
{
/// <summary>
/// Enumerating Pin Event Ids
/// </summary>
public enum PinEventId
{
[EnumMember(Value = "Home")]
WebApp_Home,
[EnumMember(Value = "Login")]
WebApp_Login,
[EnumMember(Value = "TOTW")]
TOTW,
[EnumMember(Value = "Generations")]
Generations,
[EnumMember(Value = "Unassigned Items")]
WebApp_UnassignedItems,
[EnumMember(Value = "Transfer Targets")]
WebApp_TransferTargets,
[EnumMember(Value = "Transfer List")]
WebApp_TransferList,
[EnumMember(Value = "Transfer Market Search")]
WebApp_TransferMarketSearch,
[EnumMember(Value = "Transfer Market Search Results")]
WebApp_TransferMarketSearchResults,
[EnumMember(Value = "Squad List - My Squads")]
WebApp_SquadList,
[EnumMember(Value = "Squad List - Concept Squads")]
WebApp_ConceptSquadList,
[EnumMember(Value = "Active Squad")]
WebApp_ActiveSquad,
[EnumMember(Value = "Club - Players")]
WebApp_Players,
[EnumMember(Value = "Club - Staff")]
WebApp_Staff,
[EnumMember(Value = "Club - Items")]
WebApp_Items,
[EnumMember(Value = "Club - Consumables")]
WebApp_Consumables,
[EnumMember(Value = "Leaderboards - Main")]
WebApp_Leaderboards,
[EnumMember(Value = "Leaderboards - Match Earnings")]
WebApp_LeaderboardsEarnings,
[EnumMember(Value = "Leaderboards - Transfer Profit")]
WebApp_LeaderboardsTransferProfit,
[EnumMember(Value = "Leaderboards - Club Value")]
WebApp_LeaderboardsClubValue,
[EnumMember(Value = "Leaderboards - Top Squad")]
WebApp_LeaderboardsTopSquad,
[EnumMember(Value = "Store - Main")]
WebApp_MainStore,
[EnumMember(Value = "Store - Gold")]
WebApp_GoldStore,
[EnumMember(Value = "Store - Silver")]
WebApp_SilverStore,
[EnumMember(Value = "Store - Bronze")]
WebApp_BronzeStore,
WebApp_AppOpened,
WebApp_Connect,
WebApp_Connected,
[EnumMember(Value = "Hub - Home")]
CompanionApp_Home,
[EnumMember(Value = "Hub - Squads")]
CompanionApp_HubSquads,
[EnumMember(Value = "Hub - Draft")]
CompanionApp_HubDraft,
[EnumMember(Value = "Hub - Transfers")]
CompanionApp_HubTransfers,
[EnumMember(Value = "Hub - Store")]
CompanionApp_HubStore,
[EnumMember(Value = "Hub - Unassigned")]
CompanionApp_HubUnassigned,
[EnumMember(Value = "Unassigned Items - List View")]
CompanionApp_UnassignedItems,
[EnumMember(Value = "Transfer Targets - List View")]
CompanionApp_TransferTargets,
[EnumMember(Value = "Transfer List - List View")]
CompanionApp_TransferList,
[EnumMember(Value = "Store - Pack Category")]
WebApp_PackCategory,
[EnumMember(Value = "Store - Pack Details")]
WebApp_PackDetails,
[EnumMember(Value = "Club - Players - List View")]
CompanionApp_Players,
[EnumMember(Value = "Club - Players - Detail View")]
CompanionApp_Players_Detailed,
[EnumMember(Value = "Club - Staff - List View")]
CompanionApp_Staff,
[EnumMember(Value = "Club - Staff - Detail View")]
CompanionApp_Staff_Detailed,
[EnumMember(Value = "Club - Club Items - List View")]
CompanionApp_Club,
[EnumMember(Value = "Club - Club - Detail View")]
CompanionApp_Club_Detailed,
[EnumMember(Value = "Club - Club Consumables - List View")]
CompanionApp_Consumables,
[EnumMember(Value = "Club - Club - Detail View")]
CompanionApp_Consumables_Detailed,
[EnumMember(Value = "EASFC - News")]
CompanionApp_EASFC_News,
[EnumMember(Value = "EASFC - News - Preview Squad")]
CompanionApp_EASFC_PreviewSquad,
}
}
@trydis : Could you help me how to call a webrequest within a webrequest:
This is my PinEventRequest:
internal class PinEventRequest : FutRequestBase, IFutRequest<PinResponse>
{
private readonly AppVersion _appVersion;
private readonly string _nucleusId;
private readonly string _personaId;
private readonly string _sessionId;
private readonly string _currentPinEventId;
private readonly string _previousPinEventId;
public PinEventRequest(AppVersion appVersion, string SessionId, string NucleusId, string PersonaId, PinEventId currentPinId, PinEventId previousPinId)
{
_appVersion = appVersion;
_sessionId = SessionId;
_nucleusId = NucleusId;
_personaId = PersonaId;
_currentPinEventId = currentPinId.ToString();
_previousPinEventId = previousPinId.ToString();
}
public async Task<PinResponse> PerformRequestAsync()
{
if (_appVersion == AppVersion.CompanionApp)
{
AddPinHeadersMobile();
}
else if (_appVersion == AppVersion.WebApp)
{
AddPinHeaders();
}
else
{
AddPinHeaders();
}
var pinResponseMessage = await HttpClient.PostAsync(string.Format(Resources.PinRiver), new StringContent(Serialize<Pin>(GeneratePinData())))
.ConfigureAwait(false);
return await Deserialize<PinResponse>(pinResponseMessage);
}
I need to call it in example within this request:
internal class SearchRequest : FutRequestBase, IFutRequest<AuctionResponse>
{
private readonly SearchParameters _searchParameters;
public SearchRequest(SearchParameters searchParameters)
{
searchParameters.ThrowIfNullArgument();
_searchParameters = searchParameters;
}
public async Task<AuctionResponse> PerformRequestAsync()
{
var uriString = string.Format(Resources.FutHome + Resources.TransferMarket + "?start={0}&num={1}",
(_searchParameters.Page - 1) * _searchParameters.PageSize, _searchParameters.PageSize + 1);
_searchParameters.BuildUriString(ref uriString);
AddMethodOverrideHeader(HttpMethod.Get);
AddCommonHeaders();
var searchResponseMessage = await HttpClient
.PostAsync(uriString, new StringContent(" "))
.ConfigureAwait(false);
return await Deserialize<AuctionResponse>(searchResponseMessage);
}
}
}
How can I do this without breaking your concept? Thanks!
@tringler: I've just skimmed though the posts, so forgive me if i've missed some details. Will the PinResponse
be used for anything inside the SearchRequest
?
@trydis No, we just to send the request to fulfil the pin requests like:
public async Task<AuctionResponse> PerformRequestAsync()
{
var uriString = string.Format(Resources.FutHome + Resources.TransferMarket + "?start={0}&num={1}",
(_searchParameters.Page - 1) * _searchParameters.PageSize, _searchParameters.PageSize + 1);
_searchParameters.BuildUriString(ref uriString);
AddMethodOverrideHeader(HttpMethod.Get);
AddCommonHeaders();
//SEND PIN REQUEST HERE
var searchResponseMessage = await HttpClient
.PostAsync(uriString, new StringContent(" "))
.ConfigureAwait(false);
//SEND ANOTHER PIN Request HERE
return await Deserialize<AuctionResponse>(searchResponseMessage);
}
It would be nice to check if the 'PinResponse' is OK, but it's not needed to fulfill. Mostly we need to execute the main request followed by the pin request but sometimes i,e, in case of Searchrequest or Login it's more special. In example of Mobile Login:
Send PIN Request (WebApp_AppOpened)
MobileLogin until the part of /connect/token
Send PIN Request (App_Connect)
MobileLogin after got Session ID
Send PIN Request (WebApp_Connected)
Send PIN Request (CompanionApp_Home)
Try to check EA calls, a new call they added (when browser from Trade Pile to Market Search or Watchlist) to pin-river.data.ea.com called pinevent there is some information about client and page.
Maybe they want kill all bots that don't use it? banwave incomming ...