您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Minor improvements to FFlogs and progression tools.
当前为
- // ==UserScript==
- // @name FFProgs
- // @namespace http://tampermonkey.net/
- // @version 0.1.0
- // @description Minor improvements to FFlogs and progression tools.
- // @author You
- // @match https://www.fflogs.com/*
- // @icon https://assets.rpglogs.com/img/ff/favicon.png?v=2
- // @grant none
- // ==/UserScript==
- (function () {
- if (/(^|\.)fflogs\.com$/.test(document.location.hostname) === false) { return; };
- // Helper functions
- function elements(arr) {
- return arr.map(e => document.getElementById(e));
- }
- function addGlobalEventListener(type, selector, callaBack) {
- document.addEventListener(type, e => {
- if (e.target.matches(selector)) callaBack(e);
- })
- }
- function retrieveWindowVariables(variables) {
- const ret = {};
- let scriptContent = "";
- for (let i = 0; i < variables.length; i++) {
- const currVariable = variables[i];
- scriptContent += `if (typeof ${currVariable} !== \"undefined\") $(\"body\").attr(\"tmp_${currVariable}\", JSON.stringify(${currVariable}));\n`
- }
- const script = document.createElement("script");
- script.id = "tmpScript";
- script.appendChild(document.createTextNode(scriptContent));
- (document.body || document.head || document.documentElement).appendChild(script);
- for (let i = 0; i < variables.length; i++) {
- const currVariable = variables[i];
- ret[currVariable] = $.parseJSON($("body").attr(`tmp_${currVariable}`));
- $("body").removeAttr(`tmp_${currVariable}`);
- }
- $("#tmpScript").remove();
- return ret;
- }
- // Easter Egg/Credits
- const characterName = document.querySelector("#character-name > .character-name-link");
- if (characterName) {
- if (characterName.innerHTML === "Chad Bradly") {
- // GIGACHAD
- const characterPortrait = document.getElementById("character-portrait-image");
- characterPortrait.src = "https://c.tenor.com/epNMHGvRyHcAAAAd/gigachad-chad.gif";
- // Adds background to your own page
- const addBackgroundList = ["portrait-and-basics", "character-header-customize-action-box", "update-box"];
- elements(addBackgroundList).forEach((e) => {
- if (e) {
- e.className = "slightly-transparent-box";
- }
- })
- const banner = document.getElementById("character-portrait-box");
- if (banner) {
- banner.style = "background-image: url(\"https://cdn.discordapp.com/attachments/613521566185029642/925189465868218368/ffxiv_dx11_sH6dfhzjue.jpg\");";
- banner.className = "with-banner";
- }
- }
- }
- // Adblock
- const deleteList = ["top-banner", "bottom-banner", "playwire-video-container", "patron-box", "gear-box-ad"];
- elements(deleteList).forEach(e => {
- if (e) {
- e.outerHTML = "";
- }
- });
- // Removes alt-text from item images.
- const imgs = document.getElementsByClassName("gear-img-cell");
- for (let i = 0; i < imgs.length; i++) {
- const img = imgs[i].firstChild;
- if (img) {
- img.alt = "";
- }
- }
- // XIVAnalysis button
- const tabs = document.getElementById("top-level-view-tabs");
- if (tabs) {
- function getReportUrl() {
- const reportURL = document.location.href.split("/reports/")[1];
- const [report, reportInfo] = reportURL.split("#");
- let fight, job;
- if (reportInfo) {
- reportInfo.split("&").forEach((e) => {
- const [key, value] = e.split("=")
- if (key === "fight") {
- fight = value;
- }
- if (fight && key === "source") {
- job = value;
- }
- })
- }
- let url = "https://xivanalysis.com/fflogs";
- [report, fight, job].forEach((urlElement) => {
- if (urlElement) {
- url += `/${urlElement}`;
- }
- });
- return url;
- }
- function refreshAnalysis() {
- const xivanalysisButton = document.getElementById("xivanalysis-tab");
- const url = getReportUrl();
- xivanalysisButton.href = url;
- }
- const url = getReportUrl();
- const xivanalysisButton = document.createElement("a");
- xivanalysisButton.href = url;
- xivanalysisButton.target = "_blank";
- xivanalysisButton.classList.add("big-tab", "view-type-tab");
- xivanalysisButton.id = "xivanalysis-tab";
- const icon = document.createElement("span");
- icon.classList.add("zmdi", "zmdi-time-interval");
- xivanalysisButton.appendChild(icon);
- const text = document.createElement("span");
- text.classList.add("big-tab-text");
- text.innerHTML = "<br>xivanalysis";
- xivanalysisButton.appendChild(text);
- tabs.firstChild.before(xivanalysisButton);
- tabs.addEventListener("click", (e) => { refreshAnalysis(); });
- }
- //Video Player Stuff
- const videoButton = document.querySelector(".replay-video");
- if (videoButton) {
- const streams = {};
- videoButton.addEventListener("click", (e) => {
- const selectVideoButton = document.getElementById("select-video");
- if (selectVideoButton) {
- // Functions for the multistream buttons.
- const videoFrame = document.getElementById("video-frame-inner");
- function showMultistreamFrame() {
- const platform = "youTube"
- const iframe = document.createElement("iframe");
- iframe.id = "player";
- iframe.style = "border: none; width:100%; height: 100%;";
- iframe.allowFullscreen = "1";
- iframe.allow = "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture;";
- iframe.title = "YouTube video player";
- videoFrame.innerHTML = iframe.outerHTML;
- }
- function showMultistreamOptions() {
- const div = document.createElement("div");
- div.style = "text-align: center;";
- const form = document.createElement("form");
- form.style = "margin: 0;";
- form.acceptCharset = "utf-8";
- form.method = "GET";
- form.action = "javascript:void(0);";
- const table = document.createElement("table");
- table.style = "border-collapse: separate; border-spacing: 8px; margin: auto; text-align: left;";
- //Table Infromation
- const infoRow = document.createElement("tr");
- const nameInfo = document.createElement("td");
- const URLInfo = document.createElement("td");
- const offsetInfo = document.createElement("td");
- nameInfo.innerHTML = "Name:";
- URLInfo.innerHTML = "Stream URL:";
- offsetInfo.innerHTML = "Offset:";
- offsetInfo.style = "max-width: 60px;";
- infoRow.append(nameInfo, URLInfo, offsetInfo);
- table.appendChild(infoRow);
- const raidFrames = document.querySelectorAll(".raid-frame-contents");
- const raiders = [];
- raidFrames.forEach((frame) => {
- raiders.push(frame.innerHTML);
- })
- raiders.forEach((person) => {
- const id = person.replace(/ /g, "_");
- const tableRow = document.createElement("tr");
- const nameData = document.createElement("td");
- nameData.innerHTML = person;
- tableRow.appendChild(nameData);
- const streamData = document.createElement("td");
- const streamUrl = document.createElement("input");
- streamUrl.style = "min-width: 260px;"
- streamUrl.type = "text";
- streamUrl.id = `${id}-stream_url`;
- streamUrl.name = `${id}-stream_url`;
- streamUrl.placeholder = "youtube.com/watch?v= or twitch.tv/videos/";
- if (streams[id] && streams[id].url) {
- streamUrl.setAttribute("value", streams[id].url);
- }
- streamUrl.classList.add("url-table-row");
- streamData.appendChild(streamUrl);
- tableRow.appendChild(streamData);
- const offsetData = document.createElement("td");
- const offsetTime = document.createElement("input");
- offsetTime.size = "3";
- offsetTime.id = `${id}-stream_offset`;
- offsetTime.name = `${id}-stream_offset`;
- offsetTime.placeholder = "# in sec";
- if (streams[id] && streams[id].offset) {
- offsetTime.setAttribute("value", streams[id].offset)
- }
- offsetTime.classList.add("url-table-row");
- offsetData.appendChild(offsetTime);
- tableRow.appendChild(offsetData);
- table.appendChild(tableRow);
- })
- form.appendChild(table);
- div.appendChild(form);
- videoFrame.innerHTML = div.outerHTML;
- }
- addGlobalEventListener("input", ".url-table-row", (e) => {
- const [user, action] = e.target.id.split("-");
- const value = e.target.value;
- if (action === "stream_url") {
- if (!streams[user]) streams[user] = {};
- streams[user].url = value;
- }
- if (action === "stream_offset") {
- if (!streams[user]) streams[user] = {};
- streams[user].offset = value;
- }
- })
- // Creates Menu Below Video Player
- const multiStreamOptions = document.getElementById("multistream-options");
- if (!multiStreamOptions) {
- const videoFrameControls = document.getElementById("video-frame-controls");
- const multiStreamO = document.createElement("span");
- multiStreamO.style = "float: right; margin-right: 10px;";
- multiStreamO.id = "multistream-options";
- multiStreamO.classList.add("graph-legend-button");
- multiStreamO.onclick = showMultistreamOptions;
- multiStreamO.innerText = "Multistream options"
- videoFrameControls.appendChild(multiStreamO);
- const multiStreamV = document.createElement("span");
- multiStreamV.style = "margin-right: -1px; float: right;";
- multiStreamV.id = "multistream-view";
- multiStreamV.classList.add("graph-legend-button");
- multiStreamV.onclick = showMultistreamFrame;
- multiStreamV.innerText = "Multistream View";
- videoFrameControls.appendChild(multiStreamV);
- }
- // Save Video URL (OLD)
- selectVideoButton.addEventListener("click", (e) => {
- const windowVariables = retrieveWindowVariables(["videoID", "videoOffset"]);
- if (windowVariables.videoID !== "none") {
- const videoURLInput = document.getElementById("video_url");
- videoURLInput.value = `https://www.youtube.com/watch?v=${windowVariables.videoID}`;
- }
- if (windowVariables.videoOffset) {
- const videoOffsetInput = document.getElementById("video_offset");
- videoOffsetInput.value = windowVariables.videoOffset;
- }
- })
- }
- })
- }
- /*
- Backlog:
- Make youtube/twitch livestream work
- Streams work across multiple fights in one log.
- <- Upload to greasy fork here 0.1.0 ->
- Multiple POV"s depending on selected player.
- Add way to share log viewer and save current streams to a log.
- Doing:
- Make youtube videos work.
- Make Twitch VOD"s work.
- Import/export settings
- Use my Own I frames
- Done:
- Save video inputted into video player,
- Make settings be able to add streams to players
- Save Stream/Offset to session storage on edit for the zones so no need for submit
- */
- })();