您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Check job points and work stats to see if you are able to upgrade to the next position, and display a message at the top of the page.
当前为
// ==UserScript== // @name Torn Starter Job Upgrade Notice // @namespace http://tampermonkey.net/ // @version 1.1 // @description Check job points and work stats to see if you are able to upgrade to the next position, and display a message at the top of the page. // @author Baccy // @icon https://www.google.com/s2/favicons?sz=64&domain=torn.com // @match https://www.torn.com/* // @grant none // ==/UserScript== const APIKey = 'LimitedKey'; let showFalseMessage = false; // Set to true to show a message with your missing stats or job points const jobRequirements = { army: [ { position: 'Private', manual_labor: 50, intelligence: 15, endurance: 20 }, { position: 'Corporal', manual_labor: 120, intelligence: 35, endurance: 50 }, { position: 'Sergeant', manual_labor: 325, intelligence: 60, endurance: 115 }, { position: 'Master Sergeant', manual_labor: 700, intelligence: 160, endurance: 300 }, { position: 'Warrant Officer', manual_labor: 1300, intelligence: 360, endurance: 595 }, { position: 'Lieutenant', manual_labor: 2550, intelligence: 490, endurance: 900 }, { position: 'Major', manual_labor: 4150, intelligence: 600, endurance: 1100 }, { position: 'Colonel', manual_labor: 7500, intelligence: 1350, endurance: 2530 }, { position: 'Brigadier', manual_labor: 10000, intelligence: 2000, endurance: 4000 }, { position: 'General', manual_labor: null, intelligence: null, endurance: null } // Final position ], grocer: [ { position: 'Bag Boy', manual_labor: 30, intelligence: 15, endurance: 50 }, { position: 'Price Labeller', manual_labor: 50, intelligence: 35, endurance: 120 }, { position: 'Cashier', manual_labor: 120, intelligence: 60, endurance: 225 }, { position: 'Food Delivery', manual_labor: 250, intelligence: 200, endurance: 500 }, { position: 'Manager', manual_labor: null, intelligence: null, endurance: null } // Final position ], casino: [ { position: 'Dealer', manual_labor: 35, intelligence: 50, endurance: 120 }, { position: 'Gaming Consultant', manual_labor: 60, intelligence: 115, endurance: 325 }, { position: 'Marketing Manager', manual_labor: 360, intelligence: 595, endurance: 1300 }, { position: 'Revenue Manager', manual_labor: 490, intelligence: 900, endurance: 2550 }, { position: 'Casino Manager', manual_labor: 755, intelligence: 1100, endurance: 4150 }, { position: 'Casino President', manual_labor: null, intelligence: null, endurance: null } // Final position ], medical: [ { position: 'Medical Student', manual_labor: 100, intelligence: 600, endurance: 150 }, { position: 'Houseman', manual_labor: 175, intelligence: 1000, endurance: 275 }, { position: 'Senior Houseman', manual_labor: 300, intelligence: 1500, endurance: 500 }, { position: 'GP', manual_labor: 600, intelligence: 2500, endurance: 1000 }, { position: 'Consultant', manual_labor: 1300, intelligence: 5000, endurance: 2000 }, { position: 'Surgeon', manual_labor: 2600, intelligence: 10000, endurance: 4000 }, { position: 'Brain Surgeon', manual_labor: null, intelligence: null, endurance: null } // Final position ], education: [ { position: 'Recess Supervisor', manual_labor: 300, intelligence: 750, endurance: 500 }, { position: 'Substitute Teacher', manual_labor: 600, intelligence: 1000, endurance: 700 }, { position: 'Elementary Teacher', manual_labor: 1000, intelligence: 1300, endurance: 1000 }, { position: 'Secondary Teacher', manual_labor: 1500, intelligence: 2000, endurance: 1500 }, { position: 'Professor', manual_labor: 1500, intelligence: 3000, endurance: 1500 }, { position: 'Vice Principal', manual_labor: 1500, intelligence: 5000, endurance: 1500 }, { position: 'Principal', manual_labor: null, intelligence: null, endurance: null } // Final position ], law: [ { position: 'Law Student', manual_labor: 1750, intelligence: 2500, endurance: 5000 }, { position: 'Paralegal', manual_labor: 2500, intelligence: 5000, endurance: 7500 }, { position: 'Probate Lawyer', manual_labor: 3500, intelligence: 6500, endurance: 7750 }, { position: 'Trial Lawyer', manual_labor: 4000, intelligence: 7250, endurance: 10000 }, { position: 'Circuit Court Judge', manual_labor: 6000, intelligence: 9000, endurance: 15000 }, { position: 'Federal Judge', manual_labor: null, intelligence: null, endurance: null } // Final position ] }; // Function to check if the user can upgrade to the next job position function checkJobUpgrade(job, currentPosition, jobPoints, workStats) { console.log(`Checking job upgrade for job: ${job}, current position: ${currentPosition}, job points: ${jobPoints}, work stats:`, workStats); const positions = jobRequirements[job.toLowerCase()]; const currentIndex = positions.findIndex(pos => pos.position === currentPosition); // Additional logging for the next position if (currentIndex === -1 || currentIndex >= positions.length - 1) { console.log("User has reached the highest position or job data is incorrect."); return "You have reached the highest position or your job data is incorrect."; } const nextPositionRequirements = positions[currentIndex + 1]; const pointsRequired = (currentIndex + 1) * 5; // Log the next position and its requirements console.log(`Next position: ${positions[currentIndex + 1].position}, Points required: ${pointsRequired}, Requirements:`, nextPositionRequirements); // Check if the user meets the requirements for the next position const canUpgrade = jobPoints >= pointsRequired && workStats.manual_labor >= nextPositionRequirements.manual_labor && workStats.intelligence >= nextPositionRequirements.intelligence && workStats.endurance >= nextPositionRequirements.endurance; if (canUpgrade) { console.log(`User can upgrade to: ${positions[currentIndex + 1].position}`); return `You can upgrade to ${positions[currentIndex + 1].position}!`; } else { console.log(`User cannot upgrade to: ${positions[currentIndex + 1].position}`); if (showFalseMessage) { // Calculate what is lacking for the upgrade const missingStats = []; if (jobPoints < pointsRequired) { missingStats.push(`Job points required: ${pointsRequired} (You have: ${jobPoints})`); } if (workStats.manual_labor < nextPositionRequirements.manual_labor) { missingStats.push(`Manual labor required: ${nextPositionRequirements.manual_labor} (You have: ${workStats.manual_labor})`); } if (workStats.intelligence < nextPositionRequirements.intelligence) { missingStats.push(`Intelligence required: ${nextPositionRequirements.intelligence} (You have: ${workStats.intelligence})`); } if (workStats.endurance < nextPositionRequirements.endurance) { missingStats.push(`Endurance required: ${nextPositionRequirements.endurance} (You have: ${workStats.endurance})`); } // Combine missing stats into a message const missingMessage = `You cannot upgrade to ${positions[currentIndex + 1].position} yet. You are missing:\n${missingStats.join('\n')}`; console.log(missingMessage); return missingMessage; } } } // Function to display the upgrade message after the specified element function displayUpgradeMessage(jobUpgradeMessage) { // Find the container where the message should be inserted const container = document.querySelector('#topHeaderBanner'); if (container) { // Remove any existing message let existingMessage = document.getElementById('job-upgrade-message'); if (existingMessage) { existingMessage.remove(); // Remove it from DOM } // Create a new div to display the job upgrade message const messageDiv = document.createElement('div'); messageDiv.id = 'job-upgrade-message'; messageDiv.innerHTML = jobUpgradeMessage; // Add inline styles to the div messageDiv.style.fontSize = '16px'; messageDiv.style.marginTop = '10px'; messageDiv.style.color = '#ffffff'; // Highlight color messageDiv.style.padding = '10px'; messageDiv.style.backgroundColor = '#1c1b22'; // Dark background messageDiv.style.borderRadius = '5px'; messageDiv.style.lineHeight = '1.5'; messageDiv.style.textAlign = 'center'; // Center the text // Append the new div as a child to the container container.appendChild(messageDiv); } } // Log when API data is being fetched async function fetchAPIData() { console.log("Attempting to fetch data"); try { const workStatsResponse = await fetch(`https://api.torn.com/user/?selections=workstats&key=${APIKey}&comment=StarterJobNotice`); const jobPointsResponse = await fetch(`https://api.torn.com/user/?selections=jobpoints&key=${APIKey}&comment=StarterJobNotice`); const profileResponse = await fetch(`https://api.torn.com/user/?selections=profile&key=${APIKey}&comment=StarterJobNotice`); const workStats = await workStatsResponse.json(); const jobPoints = await jobPointsResponse.json(); const profile = await profileResponse.json(); console.log("Fetched workStats:", workStats); console.log("Fetched jobPoints:", jobPoints); console.log("Fetched profile:", profile); localStorage.setItem('workStats', JSON.stringify(workStats)); localStorage.setItem('jobPoints', JSON.stringify(jobPoints)); localStorage.setItem('profile', JSON.stringify(profile)); localStorage.setItem('lastFetchDate', new Date().toISOString().split('T')[0]); } catch (error) { console.error("Error fetching API data:", error); } } // Function to check if stored data exists and is valid function checkStoredData() { console.log("Checking stored data..."); // Retrieve the stored data from localStorage const workStats = JSON.parse(localStorage.getItem('workStats')); const jobPoints = JSON.parse(localStorage.getItem('jobPoints')); const profile = JSON.parse(localStorage.getItem('profile')); console.log("Retrieved stored data:"); console.log("Work Stats:", workStats); console.log("Job Points:", jobPoints); console.log("Profile:", profile); // Check if the data exists and if there is an error like "Incorrect key" const invalidWorkStats = workStats && workStats.error && workStats.error.code === 2; const invalidJobPoints = jobPoints && jobPoints.error && jobPoints.error.code === 2; const invalidProfile = profile && profile.error && profile.error.code === 2; // Log the validation results console.log("Validation results:"); console.log("Work Stats valid:", !invalidWorkStats); console.log("Job Points valid:", !invalidJobPoints); console.log("Profile valid:", !invalidProfile); // If any data is missing or invalid (contains "Incorrect key" error), fetch the data if (!workStats || !jobPoints || !profile || invalidWorkStats || invalidJobPoints || invalidProfile) { console.log("One or more data items are missing or invalid. Fetching new data..."); fetchAPIData(); } else { console.log("All stored data is valid."); } } // Function to get the last passed 6:30 PM UTC for job updates function getLastJobUpdateTime() { const now = new Date(); const jobUpdateTime = new Date(now); // Set to the latest 6:30 PM UTC jobUpdateTime.setUTCHours(18, 30, 0, 0); // 6:30 PM UTC if (now < jobUpdateTime) { // If the current time is before 6:30 PM today, subtract one day jobUpdateTime.setUTCDate(jobUpdateTime.getUTCDate() - 1); } return jobUpdateTime; } // Function to fetch API data if the last fetch date is older than the last 6:30 PM UTC for job updates async function checkAndFetchAPIData() { const lastFetchDateStr = localStorage.getItem('lastFetchDate'); const lastFetchedJobTime = lastFetchDateStr ? new Date(lastFetchDateStr) : null; const lastScheduledJobUpdateTime = getLastJobUpdateTime(); console.log("Last fetch time:", lastFetchedJobTime); console.log("Last scheduled time (6:30 PM UTC):", lastScheduledJobUpdateTime); if (!lastFetchedJobTime || lastFetchedJobTime < lastScheduledJobUpdateTime) { console.log("Fetching new API data..."); await fetchAPIData(); } else { console.log("No need to fetch data yet."); } } // Function to run on page load function onPageLoad() { console.log("Page loaded. Checking stored data..."); // Check if stored data exists and fetch early if needed checkStoredData(); // Get stored data after ensuring it exists const workStats = JSON.parse(localStorage.getItem('workStats')); const jobPoints = JSON.parse(localStorage.getItem('jobPoints')); const profile = JSON.parse(localStorage.getItem('profile')); console.log("Retrieved stored data:"); console.log("Work Stats:", workStats); console.log("Job Points:", jobPoints); console.log("Profile:", profile); if (workStats && jobPoints && profile) { const job = profile.job.job; const currentPosition = profile.job.position; const jobPointsAvailable = jobPoints.jobpoints.jobs[job.toLowerCase()]; const workStatsData = { manual_labor: workStats.manual_labor, intelligence: workStats.intelligence, endurance: workStats.endurance, }; console.log(`Checking job upgrade for ${job}, current position: ${currentPosition}, available job points: ${jobPointsAvailable}`); // Check if the user can upgrade const upgradeMessage = checkJobUpgrade(job, currentPosition, jobPointsAvailable, workStatsData); if (upgradeMessage) { console.log("Upgrade message found:", upgradeMessage); displayUpgradeMessage(upgradeMessage); } else { console.log("No upgrade available at this time."); } } else { console.log("One or more data items are missing. Work Stats, Job Points, and Profile must all be available."); } } // Check and fetch the API data on page load checkAndFetchAPIData(); onPageLoad();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址