Init
This commit is contained in:
parent
9b79fc57de
commit
f54eb75788
8 changed files with 427 additions and 0 deletions
53
Extension/API.js
Normal file
53
Extension/API.js
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
async function ping(){
|
||||||
|
fetch ('http://127.0.0.1:5180/api/ping')
|
||||||
|
.then(data => {
|
||||||
|
console.log(data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async function setBaseDataHorseAPI(id, basedata) {
|
||||||
|
try {
|
||||||
|
console.log("Setting horse data");
|
||||||
|
console.log("ID:", id); // Log ID to ensure it's received correctly
|
||||||
|
console.log("Basedata:", basedata); // Log the entire horse data to check
|
||||||
|
|
||||||
|
const url = `http://127.0.0.1:5180/api/setHorseBasicData/id=${id}`;
|
||||||
|
|
||||||
|
// Wait for the API call to complete
|
||||||
|
const response = await fetch(url, {
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify(basedata),
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const data = await response; // Wait for the response from the API
|
||||||
|
console.log("API Response:", data); // Log the response from the API
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error setting horse data: " + error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async function getHorseAPI(id) {
|
||||||
|
var horseData;
|
||||||
|
const url = 'http://127.0.0.1:5180/api/getHorseInfo/id=' + id;
|
||||||
|
await fetch(url)
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
horseData = data;
|
||||||
|
});
|
||||||
|
return horseData;
|
||||||
|
}
|
||||||
|
async function setHorsePedigreeAPI(id, pedigreeData)
|
||||||
|
{
|
||||||
|
const url = `http://127.0.0.1:5180/api/setHorsePedigree/id=${id}`;
|
||||||
|
const response = await fetch(url, {
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify(pedigreeData),
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const data = await response;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
BIN
Extension/HR-Collector_Icon.png
Normal file
BIN
Extension/HR-Collector_Icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 43 KiB |
58
Extension/background.js
Normal file
58
Extension/background.js
Normal file
|
|
@ -0,0 +1,58 @@
|
||||||
|
importScripts("./API.js");
|
||||||
|
|
||||||
|
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
||||||
|
if (message.action === "updateHorseData") {
|
||||||
|
updateHorseButton(); // Call the function
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
async function updateHorseButton() {
|
||||||
|
console.log("Updating horse data");
|
||||||
|
|
||||||
|
// Query the active tab
|
||||||
|
chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
|
||||||
|
if (tabs.length === 0) {
|
||||||
|
console.error("No active tab found.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const activeTabId = tabs[0].id;
|
||||||
|
|
||||||
|
// First: Get horse basic data
|
||||||
|
chrome.tabs.sendMessage(
|
||||||
|
activeTabId,
|
||||||
|
{ action: "getHorseBasicData" },
|
||||||
|
async function (response) {
|
||||||
|
if (!response || !response.success) {
|
||||||
|
console.error("Failed to get horse data from content script.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("Horse data received:", response.data);
|
||||||
|
const horseData = response.data;
|
||||||
|
|
||||||
|
// Check if horse exists via API
|
||||||
|
const existingHorse = await getHorseAPI(horseData.id);
|
||||||
|
if (!existingHorse || existingHorse.message === "Horse not found") {
|
||||||
|
console.warn("Horse not found in the API.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update horse data in the API
|
||||||
|
await setBaseDataHorseAPI(horseData.id, horseData);
|
||||||
|
|
||||||
|
// Second: Get horse current data
|
||||||
|
chrome.tabs.sendMessage(activeTabId, { action: "getHorseCurrentData", data: { id: horseData.id } }, function (currentDataResponse)
|
||||||
|
{
|
||||||
|
if (!currentDataResponse) {
|
||||||
|
console.error("Failed to get current horse data.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("Current horse data received:", currentDataResponse);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
89
Extension/content.js
Normal file
89
Extension/content.js
Normal file
|
|
@ -0,0 +1,89 @@
|
||||||
|
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
|
||||||
|
if (request.action === "getHorseBasicData") {
|
||||||
|
try {
|
||||||
|
console.log("Getting horse data");
|
||||||
|
|
||||||
|
const idString = document.querySelector('.right:nth-child(2)').innerText.replace('#', '');
|
||||||
|
// Convert the ID to BigInt
|
||||||
|
const id = BigInt(idString); // Converts to BigInt, equivalent to ulong in C#
|
||||||
|
|
||||||
|
// Convert BigInt to string before sending
|
||||||
|
const idStringForResponse = id.toString(); // Convert to string to prevent serialization issues
|
||||||
|
const horseData = {
|
||||||
|
id: idStringForResponse || "", // Stelle sicher, dass die ID vorhanden ist
|
||||||
|
age: parseInt(document.querySelector('.right:nth-child(6)').innerText, 10) || 0, // Alter muss eine Zahl sein
|
||||||
|
name: document.title.replace(/ - Horse Reality.*$/, '') || "Unknown", // Name darf nicht leer sein
|
||||||
|
gender: document.querySelector('img.icon16')?.alt || "Unknown", // Geschlecht prüfen
|
||||||
|
breed: document.querySelector('.right:nth-child(4)')?.innerText || "Unknown", // Rasse prüfen
|
||||||
|
link: window.location.href || "" // Link sicherstellen
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
console.log("Horse data gathered:", horseData);
|
||||||
|
|
||||||
|
// Sending response back to background script
|
||||||
|
sendResponse({ success: true, data: horseData });
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error gathering horse data: " + error.message);
|
||||||
|
sendResponse({ success: false, message: "Error gathering horse data: " + error.message });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (request.action === "getHorseCurrentData")
|
||||||
|
{
|
||||||
|
console.log("Getting current horse selected tab data");
|
||||||
|
var selectedTab = getTabselText();
|
||||||
|
console.log("Selected tab:", selectedTab);
|
||||||
|
if (selectedTab === "Summary")
|
||||||
|
{
|
||||||
|
var relatedHorses = Array.from(document.querySelectorAll('.pedigree a')).map(link => link.href);
|
||||||
|
var response = setHorsePedigreeAPI(request.data.id, relatedHorses);
|
||||||
|
console.log("Response from API:", response);
|
||||||
|
sendResponse({ success: true, data: response });
|
||||||
|
}
|
||||||
|
else if (selectedTab === "Training")
|
||||||
|
{
|
||||||
|
var training = document.querySelector('.top:nth-child(8)') ? document.querySelector('.top:nth-child(8)').innerText : document.querySelector('.top:nth-child(6)').innerText;
|
||||||
|
var response = setHorseTrainingAPI(request.data.id, training);
|
||||||
|
console.log("Response from API:", response);
|
||||||
|
sendResponse({ success: true, data: response });
|
||||||
|
}
|
||||||
|
else if (selectedTab === "Genetics")
|
||||||
|
{
|
||||||
|
const colorGenetics = Array.from(document.querySelectorAll('.genetic_result')).map(x => x.innerText);
|
||||||
|
const geneticPotential = Array.from(document.querySelectorAll('.genetic_stats'))
|
||||||
|
.map(x => x.innerText.trim())
|
||||||
|
.filter(value => !isNaN(value) && value !== "")
|
||||||
|
.map(value => parseFloat(value));
|
||||||
|
const totalGeneticPotential = (Array.from(document.querySelectorAll('.top div')).find(el => el.innerText.includes('GP'))?.innerText || "").replace("GP total: ", "").trim();
|
||||||
|
|
||||||
|
var response = setHorseGeneticsAPI(request.data.id, colorGenetics);
|
||||||
|
console.log("Response from API:", response);
|
||||||
|
sendResponse({ success: true, data: response });
|
||||||
|
}
|
||||||
|
else if (selectedTab === "Achievements")
|
||||||
|
{
|
||||||
|
var genetics = Array.from(document.querySelectorAll('.genetic_stats')).map(x => x.innerText).filter(text => /poor|below average|average|good|very good/i.test(text));
|
||||||
|
var response = setHorseGeneticsAPI(request.data.id, genetics);
|
||||||
|
console.log("Response from API:", response);
|
||||||
|
}
|
||||||
|
else if (selectedTab === "Health")
|
||||||
|
{
|
||||||
|
var health = [...document.querySelector("#tab_health2 p").innerText.matchAll(/:\s*(\w+)/g)].map(match => match[1]);
|
||||||
|
var response = setHorseHealthAPI(request.data.id, health);
|
||||||
|
console.log("Response from API:", response);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
console.error("Unknown or no tab selected.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true; // This is necessary to allow asynchronous response
|
||||||
|
});
|
||||||
|
function getTabselText() {
|
||||||
|
const tabElement = document.querySelector('div.tabsel');
|
||||||
|
if (tabElement) {
|
||||||
|
return tabElement.textContent.trim();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
72
Extension/horse.js
Normal file
72
Extension/horse.js
Normal file
|
|
@ -0,0 +1,72 @@
|
||||||
|
// Modell für ein Pferd
|
||||||
|
var globalHorse = {
|
||||||
|
// Basic
|
||||||
|
id: null, // ID of the horse
|
||||||
|
age: null, // age of the horse
|
||||||
|
horse_name: null, // name of the horse
|
||||||
|
gender: null, // gender of the horse
|
||||||
|
breed: null, // breed of the horse
|
||||||
|
link: null, // link to the horse's page
|
||||||
|
|
||||||
|
// Summary, Pedigree
|
||||||
|
relatedIds: [], // IDs of related horses
|
||||||
|
// Training
|
||||||
|
training: null, // training of the horse e.g. Basic Training
|
||||||
|
// Genetics
|
||||||
|
GP: 0, // GP of the horse
|
||||||
|
features: {}, // features of the horse e.g. Dressage, Driving, Endurance etc.
|
||||||
|
// Genes
|
||||||
|
Extension: null, // Extension gene of the horse
|
||||||
|
Agouti: null, // Agouti gene of the horse
|
||||||
|
Grey: null, // Grey gene of the horse
|
||||||
|
Cream: null, // Cream gene of the horse
|
||||||
|
Dun: null, // Dun gene of the horse
|
||||||
|
Champagne: null, // Champagne gene of the horse
|
||||||
|
Silver: null, // Silver gene of the horse
|
||||||
|
Mushroom: null, // Mushroom gene of the horse
|
||||||
|
Frame: null, // Frame gene of the horse
|
||||||
|
Appaloosa: null, // Appaloosa gene of the horse
|
||||||
|
PATN1: null, // PATN1 gene of the horse
|
||||||
|
MITF: null, // MITF gene of the horse
|
||||||
|
SW2: null, // SW2 gene of the horse
|
||||||
|
KIT: null, // KIT gene of the horse
|
||||||
|
|
||||||
|
RAB: null, // RAB gene of the horse
|
||||||
|
Seal: null, // Seal gene of the horse
|
||||||
|
Flaxen: null, // Flaxen gene of the horse
|
||||||
|
|
||||||
|
// Achievements
|
||||||
|
conformation: {}, // conformation of the horse e.g. Walk, Trot, Canter, Gallop, Jumping, Dressage
|
||||||
|
shortConformation : null, // Short conformation of the horse (e.g. 12VG)
|
||||||
|
maxShowResult: 0, // max show result of the horse
|
||||||
|
minShowResult: 0, // min show result of the horse
|
||||||
|
maxCompetitionResult: 0, // max competition result of the horse
|
||||||
|
minCompetitionResult: 0, // min competition result of the horse
|
||||||
|
|
||||||
|
// Health
|
||||||
|
fertility: null, // fertility of the horse
|
||||||
|
colicRestance: null, // colic resistance of the horse
|
||||||
|
hoofQuality: null, // hoof quality of the horse
|
||||||
|
backProblems: null, // back problems of the horse
|
||||||
|
respiratoryDisease: null, // respiratory disease of the horse
|
||||||
|
resistanceToLameness: null, // resistance to lameness of the horse
|
||||||
|
};
|
||||||
|
|
||||||
|
function createNewHorse(id, age, horse_name, gender, breed, link) {
|
||||||
|
globalHorse = new globalHorse();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Funktion zum Setzen von Daten
|
||||||
|
function setHorseData(id, age, horse_name, gender, breed, link) {
|
||||||
|
globalHorse.id = id;
|
||||||
|
globalHorse.age = age;
|
||||||
|
globalHorse.horse_name = horse_name;
|
||||||
|
globalHorse.gender = gender;
|
||||||
|
globalHorse.breed = breed;
|
||||||
|
globalHorse.link = link;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getHorseData() {
|
||||||
|
return globalHorse;
|
||||||
|
}
|
||||||
9
Extension/init.html
Normal file
9
Extension/init.html
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<script src="popup.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<p id="status"></p>
|
||||||
|
<button id="downloadHorseButton">Download Horse!</button>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
25
Extension/manifest.json
Normal file
25
Extension/manifest.json
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
{
|
||||||
|
"manifest_version": 3,
|
||||||
|
"name": "Horse Reality Data Downloader",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"permissions": ["tabs", "activeTab", "downloads", "storage"],
|
||||||
|
"background": {
|
||||||
|
"service_worker": "background.js"
|
||||||
|
},
|
||||||
|
"content_scripts": [
|
||||||
|
{
|
||||||
|
"matches": ["https://www.horsereality.com/*"],
|
||||||
|
"js": [
|
||||||
|
"content.js",
|
||||||
|
"ui.js",
|
||||||
|
"API.js"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"host_permissions": [
|
||||||
|
"http://127.0.0.1:5180/*"
|
||||||
|
],
|
||||||
|
"content_security_policy": {
|
||||||
|
"extension_pages": "script-src 'self'; object-src 'self'; connect-src http://127.0.0.1:5180"
|
||||||
|
}
|
||||||
|
}
|
||||||
121
Extension/ui.js
Normal file
121
Extension/ui.js
Normal file
|
|
@ -0,0 +1,121 @@
|
||||||
|
// Warten, bis das DOM vollständig geladen ist
|
||||||
|
document.addEventListener("DOMContentLoaded", function () {
|
||||||
|
// Suche nach dem Element mit der Klasse 'horse_banner'
|
||||||
|
const banner = document.querySelector('.horse_banner');
|
||||||
|
if (banner) {
|
||||||
|
// Erstelle das container div
|
||||||
|
const div = document.createElement('div');
|
||||||
|
div.className = 'collector_ui';
|
||||||
|
Object.assign(div.style, {
|
||||||
|
position: 'absolute',
|
||||||
|
right: '-160px',
|
||||||
|
top: '20px',
|
||||||
|
zIndex: '1',
|
||||||
|
padding: '10px',
|
||||||
|
backgroundColor: '#FFFFFFD9',
|
||||||
|
width: '120px',
|
||||||
|
minHeight: '50px',
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
alignItems: 'flex-start',
|
||||||
|
gap: '10px' // Abstand zwischen Button und Tabelle
|
||||||
|
});
|
||||||
|
|
||||||
|
// Erstelle den Button
|
||||||
|
const updateHorseButton = document.createElement('updateHorseButton');
|
||||||
|
updateHorseButton.textContent = 'Update Horse';
|
||||||
|
Object.assign(updateHorseButton.style, {
|
||||||
|
padding: '10px 15px',
|
||||||
|
backgroundColor: '#ffa200',
|
||||||
|
color: '#fff',
|
||||||
|
border: 'none',
|
||||||
|
borderRadius: '5px',
|
||||||
|
cursor: 'pointer',
|
||||||
|
alignSelf: 'stretch', // Button auf volle Breite dehnen
|
||||||
|
transition: 'background-color 0.3s ease' // Übergang für den Hover-Effekt
|
||||||
|
});
|
||||||
|
updateHorseButton.addEventListener("click", function() {
|
||||||
|
chrome.runtime.sendMessage({ action: "updateHorseData" });
|
||||||
|
});
|
||||||
|
|
||||||
|
// Hover-Effekt hinzufügen
|
||||||
|
updateHorseButton.addEventListener('mouseenter', function () {
|
||||||
|
updateHorseButton.style.backgroundColor = '#bf8700'; // Hover-Farbe
|
||||||
|
});
|
||||||
|
updateHorseButton.addEventListener('mouseleave', function () {
|
||||||
|
updateHorseButton.style.backgroundColor = '#ffa200'; // Originalfarbe
|
||||||
|
});
|
||||||
|
|
||||||
|
// Flex-Container für die Tabelle
|
||||||
|
const table = document.createElement('div');
|
||||||
|
Object.assign(table.style, {
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
width: '100%',
|
||||||
|
gap: '12px' // Abstand zwischen den Zeilen
|
||||||
|
});
|
||||||
|
|
||||||
|
// Beschriftungen und Emoji-Elemente
|
||||||
|
const rows = [
|
||||||
|
{ label: 'Basic', emojiId: 'emojiBasic', emoji: '❌' },
|
||||||
|
{ label: 'Summary', emojiId: 'emojiSummary', emoji: '❌' },
|
||||||
|
{ label: 'Training', emojiId: 'emojiTraining', emoji: '❌' },
|
||||||
|
{ label: 'Genetics', emojiId: 'emojiGenetics', emoji: '❌' },
|
||||||
|
{ label: 'Achievements', emojiId: 'emojiAchievements', emoji: '❌' },
|
||||||
|
{ label: 'Health', emojiId: 'emojiHealth', emoji: '❌' },
|
||||||
|
];
|
||||||
|
|
||||||
|
// Erstelle Zeilen für jede Beschriftung
|
||||||
|
rows.forEach(row => {
|
||||||
|
const rowDiv = document.createElement('div');
|
||||||
|
Object.assign(rowDiv.style, {
|
||||||
|
display: 'flex',
|
||||||
|
justifyContent: 'space-between', // Beschriftung links, Emoji rechts
|
||||||
|
width: '100%'
|
||||||
|
});
|
||||||
|
|
||||||
|
// Linkes Element für die Beschriftung
|
||||||
|
const labelCell = document.createElement('div');
|
||||||
|
labelCell.textContent = row.label;
|
||||||
|
labelCell.style.flex = '1'; // Beschriftung auf der linken Seite
|
||||||
|
|
||||||
|
// Rechtes Element für das Emoji
|
||||||
|
const emojiCell = document.createElement('div');
|
||||||
|
const emojiSpan = document.createElement('span');
|
||||||
|
emojiSpan.id = row.emojiId;
|
||||||
|
emojiSpan.textContent = row.emoji;
|
||||||
|
emojiCell.appendChild(emojiSpan);
|
||||||
|
emojiCell.style.flex = '0'; // Emoji auf der rechten Seite
|
||||||
|
|
||||||
|
// Zeile zur Tabelle hinzufügen
|
||||||
|
rowDiv.appendChild(labelCell);
|
||||||
|
rowDiv.appendChild(emojiCell);
|
||||||
|
table.appendChild(rowDiv);
|
||||||
|
});
|
||||||
|
const infoTextLoaded = document.createElement('p');
|
||||||
|
infoTextLoaded.textContent = '✅ Loaded';
|
||||||
|
infoTextLoaded.justifyContent = 'space-between';
|
||||||
|
infoTextLoaded.width = '100%';
|
||||||
|
const infoTextDynamic = document.createElement('p');
|
||||||
|
infoTextDynamic.textContent = '☑️ Dynamic';
|
||||||
|
infoTextDynamic.justifyContent = 'space-between';
|
||||||
|
infoTextDynamic.width = '100%';
|
||||||
|
const infoTextNeedRefresh = document.createElement('p');
|
||||||
|
infoTextNeedRefresh.textContent = '🔄 Needs Refresh';
|
||||||
|
infoTextNeedRefresh.justifyContent = 'space-between';
|
||||||
|
infoTextNeedRefresh.width = '100%';
|
||||||
|
const infoTextNotLoaded = document.createElement('p');
|
||||||
|
infoTextNotLoaded.textContent = '❌ Not Loaded';
|
||||||
|
infoTextNotLoaded.justifyContent = 'space-between';
|
||||||
|
infoTextNotLoaded.width = '100%';
|
||||||
|
|
||||||
|
// Button oben hinzufügen, dann die Tabelle
|
||||||
|
div.appendChild(updateHorseButton);
|
||||||
|
div.appendChild(table);
|
||||||
|
div.appendChild(infoTextLoaded);
|
||||||
|
div.appendChild(infoTextDynamic);
|
||||||
|
div.appendChild(infoTextNotLoaded);
|
||||||
|
div.appendChild(infoTextNeedRefresh);
|
||||||
|
banner.appendChild(div);
|
||||||
|
}
|
||||||
|
});
|
||||||
Loading…
Reference in a new issue