Skip to content
This repository has been archived by the owner on Apr 22, 2021. It is now read-only.

Commit

Permalink
fix: add button for looking up the player at futbin
Browse files Browse the repository at this point in the history
prevents a previous issue where player links were searched for every player visible on page, which caused rate limiting issues.

fixes #55
  • Loading branch information
Mardaneus86 committed Nov 9, 2017
1 parent b3ed6b5 commit fa09fcd
Show file tree
Hide file tree
Showing 4 changed files with 337 additions and 245 deletions.
137 changes: 137 additions & 0 deletions app/futbin/futbin-player-links.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
/* globals
GM_xmlhttpRequest
gNavManager enums
window $ document
*/
import { BaseScript, Database } from '../core';
import { FutbinSettings } from './settings-entry';

export class FutbinPlayerLinks extends BaseScript {
constructor() {
super(FutbinSettings.id);

const MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
this._observer = new MutationObserver(this._mutationHandler.bind(this));

this._playerPrices = [];
}

activate(state) {
super.activate(state);

const obsConfig = {
childList: true,
characterData: true,
attributes: false,
subtree: true,
};

setTimeout(() => {
this._observer.observe($(document)[0], obsConfig);
}, 0);
}

deactivate(state) {
super.deactivate(state);

$('#futbinPlayerLink').remove();

this._observer.disconnect();
}

_mutationHandler(mutationRecords) {
mutationRecords.forEach(function (mutation) {
if ($(mutation.target).hasClass('DetailView') && $(mutation.target)
.find('.DetailPanel') && mutation.addedNodes.length > 0) {
if ($(mutation.target).find('#futbinPlayerLink').length === 0 && this.getSettings()['show-link-to-player'] === 'true') {
let selectedItem = this._getSelectedItem();

$(mutation.target).find('.DetailPanel ul').append(`<button id="futbinPlayerLink" data-resource-id="${selectedItem.resourceId}" class="list"><span class="btn-text">View on Futbin</span><span class="btn-subtext"></span></button>`);

$('#futbinPlayerLink').bind('click', async () => {
let btn = $('#futbinPlayerLink');
btn.find('.btn-text').html('Searching on Futbin ...');
const futbinLink = await FutbinPlayerLinks._getFutbinPlayerUrl(selectedItem);

selectedItem = this._getSelectedItem();
btn = $('#futbinPlayerLink');
if (btn.data('resource-id') === selectedItem.resourceId) {
if (futbinLink) {
btn.find('.btn-text').html('View on Futbin');
window.open(futbinLink);
} else {
btn.find('.btn-text').html('No exact Futbin player found');
}
}
});
}
}
}, this);
}

static _getFutbinPlayerUrl(item) {
return new Promise((resolve) => {
if (!item._staticData) {
return resolve(null);
}

let futbinPlayerIds = Database.getJson('futbin-player-ids', []);
const futbinPlayer = futbinPlayerIds.find(i => i.id === item.resourceId);
if (futbinPlayer != null) {
return resolve(`https://www.futbin.com/18/player/${futbinPlayer.futbinId}`);
}

const name = `${item._staticData.firstName} ${item._staticData.lastName}`.replace(' ', '+');
const url = `https://www.futbin.com/search?year=18&term=${name}`;
return GM_xmlhttpRequest({
method: 'GET',
url,
onload: (res) => {
if (res.status !== 200) {
return resolve(null);
}
const players = JSON.parse(res.response);
let exactPlayers = players.filter(p =>
parseInt(p.rating, 10) === parseInt(item.rating, 10));
if (exactPlayers.length > 1) {
let version = Object.keys(enums.ItemRareType)[item.rareflag];
if (item.rareflag < 3) {
version = 'normal';
}
exactPlayers = exactPlayers.filter(p =>
p.version.toLowerCase() === version.toLowerCase());
}
if (exactPlayers.length === 1) {
futbinPlayerIds = Database.getJson('futbin-player-ids', []);
if (futbinPlayerIds.find(i => i.id === item.resourceId) == null) {
futbinPlayerIds.push({
id: item.resourceId,
futbinId: exactPlayers[0].id,
});
}
Database.setJson('futbin-player-ids', futbinPlayerIds);
return resolve(`https://www.futbin.com/18/player/${exactPlayers[0].id}`);
}

return resolve(null); // TODO: what should we do if we find more than one?
},
});
});
}

/* eslint-disable class-methods-use-this */
_getSelectedItem() {
if (gNavManager.getCurrentScreenController()._controller._listController) {
return gNavManager.getCurrentScreenController()._controller._listController
.getIterator().current();
}

const current = gNavManager.getCurrentScreenController()._controller._rightController
._currentController._viewmodel.current();

return current._item ? current._item : current;
}
/* eslint-enable class-methods-use-this */
}

new FutbinPlayerLinks(); // eslint-disable-line no-new
182 changes: 182 additions & 0 deletions app/futbin/futbin-prices.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
/* globals
GM_xmlhttpRequest
gNavManager
$
*/

import { utils } from '../../fut';
import { BaseScript } from '../core';
import { FutbinSettings } from './settings-entry';

export class FutbinPrices extends BaseScript {
constructor() {
super(FutbinSettings.id);
}

activate(state) {
super.activate(state);

this._show(state.screenId);
}

onScreenRequest(screenId) {
super.onScreenRequest(screenId);
this._show(screenId);
}

deactivate(state) {
super.deactivate(state);

$('.futbin').remove();

if (this._intervalRunning) {
clearInterval(this._intervalRunning);
}
}

_show(screen) {
const showFutbinPricePages = ['WatchList', 'MyClubSearchFilters', 'UnassignedItems', 'TradePile', 'MyClubSearch', 'SearchResults'];

if (showFutbinPricePages.indexOf(screen) !== -1) {
if (this._intervalRunning) {
clearInterval(this._intervalRunning);
}
this._intervalRunning = setInterval(() => {
if (showFutbinPricePages.indexOf(gNavManager._currentScreen._screenId) === -1) {
if (this._intervalRunning) {
clearInterval(this._intervalRunning);
}
return;
}
const controller = gNavManager.getCurrentScreenController()._controller;

const uiItems = gNavManager.getCurrentScreen().$_root.find('.listFUTItem');

const targetForButton = uiItems.find('.auction');
if (targetForButton !== null) {
targetForButton.show(); // make sure it's always shown (#69)
}

if ($(uiItems[0]).find('.futbin').length > 0) {
return;
}

let listController = null;
if (screen === 'UnassignedItems' || screen === 'WatchList') {
if (!controller ||
!controller._leftController ||
!controller._leftController._view) {
return;
}
listController = controller._leftController;
} else {
if (!controller ||
!controller._listController ||
!controller._listController._view) {
return; // only run if data is available
}
listController = controller._listController;
}

let listrows = null;
if (listController._view._list &&
listController._view._list._listRows &&
listController._view._list._listRows.length > 0) {
listrows = listController._view._list._listRows; // for transfer market and club search
} else if (listController._view._sections &&
listController._view._sections.length > 0) { // for transfer list & trade pile
listController._view._sections.forEach((row) => {
if (row._listRows.length > 0) {
if (listrows == null) {
listrows = row._listRows;
} else {
listrows = listrows.concat(row._listRows);
}
}
});
}

if (listrows === null) {
return;
}

const resourceIdMapping = [];
listrows.forEach((row, index) => {
resourceIdMapping.push({
target: uiItems[index],
playerId: row.data.resourceId,
item: row.data,
});
});

const futbinUrl = `https://www.futbin.com/18/playerPrices?player=&all_versions=${
resourceIdMapping
.map(i => i.playerId)
.filter((current, next) => current !== next)
.join(',')
}`;
GM_xmlhttpRequest({
method: 'GET',
url: futbinUrl,
onload: (res) => {
const futbinData = JSON.parse(res.response);
resourceIdMapping.forEach((item) => {
FutbinPrices._showFutbinPrice(item, futbinData);
});
},
});
}, 1000);
} else {
// no need to search prices on other pages
// reset page
if (this._intervalRunning) {
clearInterval(this._intervalRunning);
}
this._intervalRunning = null;
}
}

static async _showFutbinPrice(item, futbinData) {
if (!futbinData) {
return;
}
const target = $(item.target);
const { playerId } = item;

if (target.find('.player').length === 0) {
// not a player
return;
}

const platform = utils.getPlatform();

if (!futbinData[playerId]) {
return; // futbin data might not be available for this player
}

let targetForButton = null;

if (target.find('.futbin').length > 0) {
return; // futbin price already added to the row
}

const futbinText = 'Futbin BIN';
switch (gNavManager.getCurrentScreen()._screenId) {
case 'UnassignedItems':
case 'TradePile':
case 'MyClubSearch':
case 'WatchList':
$('.secondary.player-stats-data-component').css('float', 'left');
targetForButton = target.find('.auction');
targetForButton.show();
targetForButton.prepend(`<div class="auctionValue futbin"><span class="label">${futbinText}<span class="futbinupdate">(${futbinData[playerId].prices[platform].updated})</span></span><span class="coins value">${futbinData[playerId].prices[platform].LCPrice}</span></div>`);
break;
case 'SearchResults':
targetForButton = target.find('.auctionValue').parent();
targetForButton.prepend(`<div class="auctionValue futbin"><span class="label">${futbinText}<span class="futbinupdate">(${futbinData[playerId].prices[platform].updated})</span></span><span class="coins value">${futbinData[playerId].prices[platform].LCPrice}</span></div>`);
break;
default:
// no need to do anything
}
}
}
Loading

0 comments on commit fa09fcd

Please sign in to comment.