mynameisvasco / futwebapiv2

A FUT 21 javascript injection api written with typescript used to interact with fifa 21 ultimate team webapp. With this library you can build your fifa 21 bot, tool or app.
16 stars 15 forks source link

Error in GetClubItems #5

Closed Federicomang closed 3 years ago

Federicomang commented 3 years ago

Hi, the function getClubItems does not work correctly. The error that is returned to me is the following:

Uncaught TypeError: Cannot read property 'toLowerCase' of undefined at 0x16e6bf.. [as getUrlParams] (ocompiled.js?=218:1) at 0x16e6bf.. [as getClubItems] (ocompiled.js?=218:1) at eval (eval at (ocompiled.js?=218:1), :1:27) at ocompiled.js?=218:1

As parameter in function i pass an instance of MarketSearchOptions, am I wrong or is there something to fix?

Thank you

mynameisvasco commented 3 years ago

Could you please show me your code?

Federicomang commented 3 years ago

Sure,

in the console of the browser i wrote this:

window["options"] = {
  club: -1,
  count: 100,
  defId: [],
  excludeDefIds: [],
  isExactSearch: false,
  league: -1,
  level: "any",
  maskedDefId: 0,
  maxBid: 0,
  maxBuy: 0,
  minBid: 0,
  minBuy: 0,
  nation: -1,
  offset: 0,
  playStyle: -1,
  rarities: [],
  sortBy: "value",
  subtypes: [],
  _acquiredDate: "",
  _category: "any",
  _position: "any",
  _sort: "desc",
  _type: "player",
  _untradeables: "",
  zone: -1
}

window.accessobjects.Club.getClubItems(window["options"])
mynameisvasco commented 3 years ago

The problem is that window.options is not an instance of MarketSearchOptions. You need to construct the object using new keyword.

Federicomang commented 3 years ago

I use your example and in the injector.ts i wrote this:

import * as fut from "../../src/index";

(window as any).fut = fut;
(window as any).api = new fut.App();

i wrote this to expose the MarketSearchOptions class in the browser. After i exec this code with webApp.exec (that use the evaluate of puppeteer to run the code in browser)

try {
  const options = new window.fut.MarketSearchOptions();
   return await window.api.items.getClubItems(options);
} catch(e) {
  return {
          filename: e.fileName,
          line: e.lineNumber,
          stack: e.stack,
          message: e.toString()
  }
}

I tried with another function that use MarketSearchOptions and that give me an error message 461

try {
            const options = new window.fut.MarketSearchOptions();
            options.maxBid = 1000;
            options.maxBuy = 2000;
            options.minBid = 300;
            options.minBuy = 300;
            return await window.api.market.searchTransferMarket(options);
        } catch(e) {
            return {
                filename: e.fileName,
                line: e.lineNumber,
                stack: e.stack,
                message: e.toString()
            }
        }

All the functions that not use MarketSearchOptions work correctly (i tried getTransferPile, getCoins, getPriceRanges)

I'm probably doing something wrong, if so, could you give an example of one of the functions that use MarketSearchOptions, by updating the example already present in the repository?

Thank you very much

mynameisvasco commented 3 years ago

I found the issue. In searchTransferMarket 461 is normal and means that you are sending something wrong to the ea servers. On the other hand, getClubItems is not working because some get methods are missing on MarketSearchOptions, it should be solved with https://github.com/mynameisvasco/futwebapiv2/commit/079a8d562c2d64a6eec6f12a2328c793f8ec870a

Federicomang commented 3 years ago

Hi,

now for getClubItems i have this error

{
  stack: 'TypeError: _0x2ee59a[_0x65f097(...)] is not a function\n' +
    '    at _0x16e6bf.<computed>.<computed> [as getUrlParams] (https://www.ea.com/en-gb/fifa/ultimate-team/web-app/js/ocompiled.js?_=218:1:403886)\n' +
    '    at _0x16e6bf.<computed>.<computed> [as getClubItems] (https://www.ea.com/en-gb/fifa/ultimate-team/web-app/js/ocompiled.js?_=218:1:399576)\n' +
    '    at https://a.origin.com/injector.js:27723:39\n' +
    '    at new Promise (<anonymous>)\n' +
    '    at Items.getClubItems (https://a.origin.com/injector.js:27722:16)\n' +
    '    at <anonymous>:4:43',
  message: 'TypeError: _0x2ee59a[_0x65f097(...)] is not a function'
}

the code is the same as above.

For searchTransferMarket i set bids and the default type of card is player, why is not woking? Could you give an example of correct use of the function? Because i receive every time 461.

Thank you

mynameisvasco commented 3 years ago

Hello, sorry but looks like the fix was not working. Try again with the last commit https://github.com/mynameisvasco/futwebapiv2/commit/1decc83c89014e096318a830cca77d25701a8423

In searchTransferMarket try to use the network tools on the console to see the JSON payload that is being sent.

Federicomang commented 3 years ago

Hello, with the last commit the error of getClubItems is the same as above.

With searchTransferMarket the request that is generated and sent to the server is this:

https://utas.external.s2.fut.ea.com/ut/game/fifa21/transfermarket?num=100&start=0&type=player

but, as I have already said, it gives me error 461. Could you give me a basic example of market research with this function?

Thanks for your help

mynameisvasco commented 3 years ago

Hi sorry, I was doing things the wrong way, the private attributes of MarketSearchOptions must have a function to get them and not a getter. https://github.com/mynameisvasco/futwebapiv2/commit/6b99a970feb7611c7b65d68f3298eb4497c41fa0 should now fix the issue.

About searchTransferMarket, I asked for the JSON payload and not the URL. I am doing the same as you to fetch for the players on the market. Are you setting type="player" manually?

Federicomang commented 3 years ago

Hi,

now the error for getClubItems is this:

{
    "result": {
        "stack": "TypeError: _0x2ee59a[_0x65f097(...)][_0x65f097(...)] is not a function\n    at _0x16e6bf.<computed>.<computed> [as getUrlParams] (https://www.ea.com/en-gb/fifa/ultimate-team/web-app/js/ocompiled.js?_=218:1:402165)\n    at _0x16e6bf.<computed>.<computed> [as getClubItems] (https://www.ea.com/en-gb/fifa/ultimate-team/web-app/js/ocompiled.js?_=218:1:399576)\n    at https://a.origin.com/injector.js:27723:39\n    at new Promise (<anonymous>)\n    at Items.getClubItems (https://a.origin.com/injector.js:27722:16)\n    at <anonymous>:52:43",
        "message": "TypeError: _0x2ee59a[_0x65f097(...)][_0x65f097(...)] is not a function"
    }
}

For searchTransferMarket i wrote this now:

const options = new window.fut.MarketSearchOptions();
options._type = "player";
return await window.api.items.getClubItems(options);

I also tried with this:

const options = new window.fut.MarketSearchOptions();
options.type = "player";
return await window.api.items.getClubItems(options);

And the message i receive now is 460 and not 461

mynameisvasco commented 3 years ago

Hi, I found the problem.

In searchTransferMarket the count attribute cannot be more than 21, and by default, it's 100.

And about the getClubItems, it uses some methods that are associated with UTSearchCriteriaDTO (Web app class) so we cannot use MarketSearchOptions, in order to simplify the whole process we can use UTSearchCriteriaDTO. I created the corresponding interface called IUTSearchCriteriaDTO.

https://github.com/mynameisvasco/futwebapiv2/commit/38de4ca77c7fdd960cf9a99e71de8dd829d5940a

const options = new UTSearchCriteriaDTO()
options.offset = 0;
return await window.api.items.getClubItems(options)

The IUTSearchCriteriaDTO I created is only for type checking, you must instantiate the original UTSearchCriteriaDTO

Federicomang commented 3 years ago

Now getClubItems works! Thanks!

searchTransferMarket goes in error but i tried to remove itemDao and works correctly! Could you check why?

I change searchTransferMarket in Market.ts

  async searchTransferMarket(
    options: IUTSearchCriteriaDTO
  ): Promise<IUTItemEntity[]> {
    return new Promise((resolve, reject) => {
      window.services.Item.itemDao
        .searchTransferMarket(options, 1)
        .observe(undefined, (_: any, obs: any) => {
          if (obs.success) resolve(obs.data.items);
          else reject(obs.error.code);
        });
    });
  }

with

  async searchTransferMarket(
    options: IUTSearchCriteriaDTO
  ): Promise<IUTItemEntity[]> {
    return new Promise((resolve, reject) => {
      window.services.Item
        .searchTransferMarket(options, 1)
        .observe(undefined, (_: any, obs: any) => {
          if (obs.success) resolve(obs.data.items);
          else reject(obs.error.code);
        });
    });
  }

Now both functions works!

mynameisvasco commented 3 years ago

Ok, you can create a pull request, but the intention of using the itemDao is because it skips the caching mechanism, so you would always get updated results.

Federicomang commented 3 years ago

Ok but if use itemDao data.items is undefined because is not data the attribute used but response

I think you need to change

return new Promise((resolve, reject) => {
      window.services.Item.itemDao
        .searchTransferMarket(options, 1)
        .observe(undefined, (_: any, obs: any) => {
          if (obs.success) resolve(obs.data.items);
          else reject(obs.error.code);
        });
    });

with this

return new Promise((resolve, reject) => {
      window.services.Item.itemDao
        .searchTransferMarket(options, 1)
        .observe(undefined, (_: any, obs: any) => {
          if (obs.success) resolve(obs.response.items);
          else reject(obs.error.code);
        });
    });
mynameisvasco commented 3 years ago

Can you check if error also works with your changes?

Federicomang commented 3 years ago

All works

The structure of the variable obs, if we use itemDao, is this:

{
        "error": null,
        "maxAge": 30,
        "response": {
                "items": []
         }
        "retryAfter": 0,
        "status": 200,
        "success": true
    }

I tried to insert a string into options.count and it gave me the error with code 460 as expected

{
        "error": {
                "code": 460,
                "reason": ""
         },
        "maxAge": 0,
        "response": {
                "items": []
         }
        "retryAfter": 0,
        "status": 400,
        "success": false
    }
mynameisvasco commented 3 years ago

Ok let me merge this.