Skip to content

Commit

Permalink
Skinport stuff main functionality done
Browse files Browse the repository at this point in the history
  • Loading branch information
GODrums committed Aug 28, 2023
1 parent 8b06942 commit 3658e8a
Show file tree
Hide file tree
Showing 17 changed files with 345 additions and 70 deletions.
1 change: 1 addition & 0 deletions css/stylesheet.css → css/csfloat_styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
.betterfloat-buffprice:hover .betterfloat-buff-tooltip {
visibility: visible;
opacity: 1;
transition: visibility 0s, opacity 0.5s linear;
}

.betterfloat-buffprice {
Expand Down
1 change: 1 addition & 0 deletions css/popup.css
Original file line number Diff line number Diff line change
Expand Up @@ -228,4 +228,5 @@ input[type='checkbox'] {
color: rgba(255, 255, 255, 0.7);
margin: 5px 20px 5px 0px;
font-weight: 400;
overflow-wrap: break-word;
}
32 changes: 32 additions & 0 deletions css/skinport_styles.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
.betterfloat-buff-tooltip {
/* Positioning the tooltip text */
position: absolute;
z-index: 1;
transform: translate(-16%, 40%);
visibility: hidden;
width: 200px;
background-color: #192733;
color: #fff;
text-align: center;
padding: 8px 10px 8px 10px;
border-radius: 6px;
font-size: 14px;

/* Fade in tooltip */
opacity: 0;
transition: opacity 0.3s;
}

.betterfloat-buffprice {
font-size: 12px;
}

.betterfloat-buffprice:hover .betterfloat-buff-tooltip {
visibility: visible;
opacity: 1;
}

.betterfloat-sale-tag {
font-size: 12px!important;
margin: 1px;
}
13 changes: 13 additions & 0 deletions html/changelog.html
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
<div class="Group">
<div class="VersionHeader">1.4.0</div>
<div class="VersionBox">
<p class="VersionSubHeader">
What's new?
</p>
<ul class="VersionText">
<li><b>FEATURE:</b> First BETA support for skinport.com. Only selected features work for now. Please refer to the corresponding extension settings tab.</li>
<li><b>PRICING:</b> As Steaminventoryhelper changed their CORS policy, requests now have to be proxied through a server. The deployed source code of the server can be found here: https://gist.github.com/GODrums/5b2d24c17c136a1b37acd14b1089933c</li>
<li><b>PRICING:</b> Skinport displays item prices in your local currency. To provide actual accurate exchange rates, the exchangerate.host API is in use. If you want to use Skinport's questionable rates instead, feel free to select it in the options popup. Skinport will always charge in your (local) account currency.</li>
</ul>
</div>
</div>
<div class="Group">
<div class="VersionHeader">1.3.2</div>
<div class="VersionBox">
Expand Down
File renamed without changes.
8 changes: 6 additions & 2 deletions html/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,13 @@
<div class="MainContent"></div>
<footer>
<div class="tabbar">
<button class="tabItem active" data-page="settings.html">
<button class="tabItem active" data-page="csfloat.html">
<img class="tab-icon" src="../public/gear-solid.svg" />
<p>Settings</p>
<p>CSFloat</p>
</button>
<button class="tabItem" data-page="skinport.html">
<img class="tab-icon" src="../public/gear-solid.svg" />
<p>Skinport</p>
</button>
<button class="tabItem" data-page="changelog.html">
<img class="tab-icon" src="../public/file-lines-solid.svg" />
Expand Down
52 changes: 52 additions & 0 deletions html/skinport.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<div class="Group">
<div class="GroupHeader">FEATURES</div>
<div class="GroupElement">
<p class="ElementText">Buff Price Calculations</p>
<input type="checkbox" id="SkinportBuffPrice" name="spBuffPrice" value="spBuffPrice" checked />
</div>
<div class="GroupElement">
<p class="ElementText">Auto-Checkboxes</p>
<input type="checkbox" id="SkinportCheckboxes" name="spCheckBoxes" value="spCheckBoxes" checked />
</div>
</div>
<div class="Group">
<div class="GroupHeader">PRICES</div>
<div class="GroupElementExtended">
<div class="GroupRow">
<p class="ElementText">Buff Price Reference</p>
<select class="ElementDropdownMenu" id="SkinportPriceReference" name="spPriceReference">
<option value="0">Bid</option>
<option value="1" selected>Ask</option>
</select>
</div>
<p class="ElementDescription">
Sets the reference price for difference calculations on item prices.<br />Bid refers to the highest buy order price.<br />Ask refers to the lowest listing price. (Default)
</p>
</div>
<div class="GroupElementExtended">
<div class="GroupRow">
<p class="ElementText">Currency Conversion</p>
<select class="ElementDropdownMenu" id="SkinportCurrencyConversion" name="skinportRates">
<option value="real">Real</option>
<option value="skinport" selected>Skinport</option>
</select>
</div>
<p class="ElementDescription">
Sets the reference rates for the currency conversion (USD -> X). Skinport will nevertheless always charge you in your local currency.. <br />Real refers to the buff-like currency conversion rates. (Default) <br />Skinport refers to the rates used by Skinport, which can vary from Buff rates.
</p>
</div>
<div class="GroupElementExtended">
<div class="GroupRow">
<p class="ElementText">Show Steam Price</p>
<input type="checkbox" id="SkinportSteamPrice" name="spSteamPrice" value="spSteamPrice" />
</div>
<p class="ElementDescription">Show the Steam price of an item in addition to the Buff price.</p>
</div>
<div class="GroupElementExtended">
<div class="GroupRow">
<p class="ElementText">Show Buff Price Difference</p>
<input type="checkbox" id="SkinportInputBuffDifference" name="spBuffDifference" value="spBuffDifference" checked/>
</div>
<p class="ElementDescription">This settings allows to switch between displaying the difference to the Buff price in absolute units and the original difference to the Steam price in percentage.</p>
</div>
</div>
3 changes: 2 additions & 1 deletion manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
{
"matches": ["*://*.csfloat.com/*", "*://*.csgofloat.com/*"],
"js": ["js/csfloat/content_script.js"],
"css": ["css/stylesheet.css"],
"css": ["css/csfloat_styles.css"],
"run_at": "document_end"
},
{
Expand All @@ -24,6 +24,7 @@
{
"matches": ["*://*.skinport.com/*"],
"js": ["js/skinport/content_script.js"],
"css": ["css/skinport_styles.css"],
"run_at": "document_end"
}
],
Expand Down
29 changes: 29 additions & 0 deletions src/@typings/FloatTypes.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ export type ExtensionSettings = {
listingAge: 0 | 1 | 2;
showBuffDifference: boolean;
showTopButton: boolean;
spBuffPrice: boolean;
spCheckBoxes: boolean;
spPriceReference: 0 | 1;
spSteamPrice: boolean;
spBuffDifference: boolean;
skinportRates: "skinport" | "real";
};

export type CSGOTraderMapping = {
Expand Down Expand Up @@ -86,6 +92,29 @@ export module Skinport {
success: boolean;
}

export type UserData = {
country: string;
csrf: string;
currency: string; // e.g. "EUR"
followings: number[];
limits: {
kycTier1PayoutMax: number;
kycTier2PayoutMax: number;
maxOrderValue: number;
minOrderValue: number;
minPayoutValue: number;
minSaleValue: number;
saleFeeReduced: number;
};
locale: string;
message: string | null;
paymentMethods: string[];
rate: 1;
rates: { [target: string]: number }; //currency -> target
requestId: string;
success: boolean;
}

// https://skinport.com/api/home
export type HomeData = {
message: string | null;
Expand Down
5 changes: 5 additions & 0 deletions src/background.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ chrome.runtime.onInstalled.addListener(function (details) {
showBuffDifference: true,
listingAge: 0,
showTopButton: true,
skinportRates: 'real',
spBuffPrice: true,
spCheckBoxes: true,
spPriceReference: 1,
spBuffDifference: true,
});
} else if (details.reason == 'update') {
var thisVersion = chrome.runtime.getManifest().version;
Expand Down
9 changes: 4 additions & 5 deletions src/csfloat/content_script.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,11 @@ import {
getItemPrice,
getPriceMapping,
getWholeHistory,
handleSpecialStickerNames,
loadBuffMapping,
loadMapping,
} from '../mappinghandler';
import { initSettings } from '../util/extensionsettings';
import { parseHTMLString } from '../util/helperfunctions';
import { handleSpecialStickerNames, parseHTMLString } from '../util/helperfunctions';

type PriceResult = {
price_difference: number;
Expand Down Expand Up @@ -253,11 +252,11 @@ async function addItemHistory(container: Element, item: FloatItem) {

const highestContainer = document.createElement('span');
highestContainer.classList.add('betterfloat-history-highest');
highestContainer.textContent = 'High: $' + itemHistory.highest.avg_price;
highestContainer.textContent = 'High: $' + itemHistory.highest.avg_price.toFixed(2);

const lowestContainer = document.createElement('span');
lowestContainer.classList.add('betterfloat-history-lowest');
lowestContainer.textContent = 'Low: $' + itemHistory.lowest.avg_price;
lowestContainer.textContent = 'Low: $' + itemHistory.lowest.avg_price.toFixed(2);

const divider = document.createElement('span');
divider.textContent = ' | ';
Expand Down Expand Up @@ -557,7 +556,7 @@ function createTopButton() {
topButton.classList.add('betterfloat-top-button');
topButton.setAttribute(
'style',
'position: fixed; right: 2rem; bottom: 2rem; z-index: 999; width: 40px; height: 40px; border-radius: 50%; background-color: #004594; border: none; outline: none; cursor: pointer; display: none'
'position: fixed; right: 2rem; bottom: 2rem; z-index: 999; width: 40px; height: 40px; border-radius: 50%; background-color: #004594; border: none; outline: none; cursor: pointer; display: none; transition: visibility 0s, opacity 0.5s linear;'
);
let topButtonIcon = document.createElement('img');
topButtonIcon.setAttribute('src', runtimePublicURL + '/chevron-up-solid.svg');
Expand Down
6 changes: 5 additions & 1 deletion src/eventhandler.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { EventData, HistoryData, ListingData, SellerData, Skinport } from './@typings/FloatTypes';
import { cacheHistory, cacheItems } from './mappinghandler';
import { cacheHistory, cacheItems, cacheSkinportCurrencyRates } from './mappinghandler';

type StallData = {
listings: ListingData[];
Expand All @@ -23,6 +23,10 @@ function processSkinportEvent(eventData: EventData<unknown>) {
console.debug('[BetterFloat] Received data from url: ' + eventData.url + ', data:', eventData.data);
if (eventData.url.includes('api/browse/730')) {
// Skinport.MarketData
} else if (eventData.url.includes('api/data/')) {
// Data from first page load
let data = eventData.data as Skinport.UserData;
cacheSkinportCurrencyRates(data.rates, data.currency);
}
}

Expand Down
58 changes: 47 additions & 11 deletions src/mappinghandler.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { CSGOTraderMapping, HistoryData, ListingData } from './@typings/FloatTypes';
import { CSGOTraderMapping, HistoryData, ListingData, Skinport } from './@typings/FloatTypes';
import { handleSpecialStickerNames } from './util/helperfunctions';

// maps buff_name to buff_id
let buffMapping: { [name: string]: number } = {};
Expand All @@ -9,7 +10,14 @@ let priceMapping: CSGOTraderMapping = {};
let cachedItems: ListingData[] = [];
// history for one item
let cachedHistory: HistoryData[] = [];
// cached steaminventoryhelper responses
let cachedInventoryHelperResponses: { [buff_name: string]: SteaminventoryhelperResponse | null } = {};
// cached currency rates by Skinport: USD -> X
let skinportRatesFromUSD: { [currency: string]: number } = {};
// cached currency rates by exchangerate.host: USD -> X
let realRatesFromUSD: { [currency: string]: number } = {};
let userCurrency = '';


export async function cacheHistory(data: HistoryData[]) {
if (cachedHistory.length > 0) {
Expand All @@ -34,6 +42,21 @@ export async function cacheItems(data: ListingData[]) {
cachedItems = data;
}

export async function cacheSkinportCurrencyRates(data: { [currency: string]: number }, user: string) {
if (Object.keys(skinportRatesFromUSD).length > 0) {
console.debug('[BetterFloat] Currency rates already cached, overwriting old ones: ', skinportRatesFromUSD);
}
skinportRatesFromUSD = data;
userCurrency = user;
}

export async function cacheRealCurrencyRates(data: { [currency: string]: number }) {
if (Object.keys(realRatesFromUSD).length > 0) {
console.debug('[BetterFloat] Real currency rates already cached, overwriting old ones: ', realRatesFromUSD);
}
realRatesFromUSD = data;
}

export async function getWholeHistory() {
let history = cachedHistory;
cachedHistory = [];
Expand Down Expand Up @@ -83,17 +106,30 @@ export async function getItemPrice(buff_name: string): Promise<{ starting_at: nu
};
}

export function handleSpecialStickerNames(name: string): string {
if (name.includes('Ninjas in Pyjamas | Katowice 2015')) {
return 'Sticker | Ninjas in Pyjamas | Katowice 2015';
} else if (name.includes('Vox Eminor | Katowice 2015')) {
return 'Sticker | Vox Eminor | Katowice 2015';
} else if (name.includes('PENTA Sports | Katowice 2015')) {
return 'Sticker | PENTA Sports | Katowice 2015';
} else if (name.indexOf('niko') > -1) {
return name.substring(0, name.lastIndexOf('|')) + ' ' + name.substring(name.lastIndexOf('|'), name.length);
export async function getUserCurrencyRate(rates: "skinport" | "real" = "real") {
if (Object.keys(skinportRatesFromUSD).length == 0) {
await fetchUserData();
}
return name;
if (rates == "real" && Object.keys(realRatesFromUSD).length == 0) {
await fetchCurrencyRates();
}
return rates == "real" ? realRatesFromUSD[userCurrency] : skinportRatesFromUSD[userCurrency];
}

// this endpoint sometimes gets called by Skinport itself and provides the user data
async function fetchUserData() {
await fetch('https://skinport.com/api/data/').then((response) => response.json()).then((data: Skinport.UserData) => {
console.debug('[BetterFloat] Received user data from Skinport manually: ', data)
cacheSkinportCurrencyRates(data.rates, data.currency);
});
}

// fetches currency rates from exchangerate.host, which is a free API which currently allows CORS
async function fetchCurrencyRates() {
await fetch('https://api.exchangerate.host/latest?base=USD').then((response) => response.json()).then((data) => {
console.debug('[BetterFloat] Received currency rates from exchangerate.host: ', data);
cacheRealCurrencyRates(data.rates);
});
}

type SIHRelay = {
Expand Down
Loading

0 comments on commit 3658e8a

Please sign in to comment.