Diff
checker
टेक्स्ट
टेक्स्ट
छवियां
दस्तावेज़
Excel
फ़ोल्डर्स
Legal
Enterprise
डेस्कटॉप
मूल्य
साइन इन करें
Diffchecker डेस्कटॉप डाउनलोड करें
टेक्स्ट की तुलना करें
दो टेक्स्ट फ़ाइलों के बीच अंतर ढूंढें
उपकरण
इतिहास
रियल-टाइम एडिटर
रिक्त स्थान छिपाएँ
अपरिवर्तित संक्षिप्त करें
लाइन रैप बंद
लेआउट
विभाजित
संयुक्त
परिवर्तन हाइलाइट करें
स्मार्ट
शब्द
अक्षर
टेक्स्ट शैलियां
दिखावट बदलें
सिंटैक्स हाइलाइटिंग
सिंटैक्स चुनें
अनदेखा करें
टेक्स्ट बदलें
पहले अंतर पर जाएँ
इनपुट संपादित करें
Diffchecker Desktop
Diffchecker चलाने का सबसे सुरक्षित तरीका। Diffchecker Desktop ऐप पाएं: आपके diffs कभी आपके कंप्यूटर से बाहर नहीं जाते!
Desktop पाएं
Untitled diff
बनाया गया
9 वर्ष पहले
Diff कभी समाप्त नहीं होता
साफ़
निर्यात करें
शेयर करें
समझाएं
22 हटाए गए
लाइनें
कुल
हटाया गया
अक्षर
कुल
हटाया गया
इस सुविधा का उपयोग जारी रखने के लिए, अपग्रेड करें
Diff
checker
Pro
मूल्य देखें
715 लाइनें
सभी को कॉपी करें
19 जोड़े गए
लाइनें
कुल
जोड़ा गया
अक्षर
कुल
जोड़ा गया
इस सुविधा का उपयोग जारी रखने के लिए, अपग्रेड करें
Diff
checker
Pro
मूल्य देखें
712 लाइनें
सभी को कॉपी करें
"use strict";
"use strict";
var settings = new Store("settings", {
var settings = new Store("settings", {
"preferFriendSummons": true,
"preferFriendSummons": true,
"preferNonFriendSummonsInFavorites": true,
"preferNonFriendSummonsInFavorites": true,
"preferLimitBrokenSummons": true,
"preferLimitBrokenSummons": true,
"preferHighLevelSummons": true,
"preferHighLevelSummons": true,
"notifyOnFullAP": false,
"notifyOnFullAP": false,
"notifyOnFullBP": false,
"notifyOnFullBP": false,
"showSkillCooldowns": true,
"showSkillCooldowns": true,
"showDebuffTimers": true,
"showDebuffTimers": true,
"showBuffTimers": true,
"showBuffTimers": true,
"monitorRaidDebuffs": true,
"monitorRaidDebuffs": true,
"keyboardShortcuts": true,
"keyboardShortcuts": true,
"showBookmarks": true,
"showBookmarks": true,
"preferredSummonElement": "",
"preferredSummonElement": "",
"submenuSize": 1.0,
"submenuSize": 1.0,
"bookmarksSize": 1.0,
"bookmarksSize": 1.0,
"bookmarksMenuSize": 1.0,
"bookmarksMenuSize": 1.0,
"recentQuest": null,
"recentQuest": null,
"showQuickPanels": true,
"showQuickPanels": true,
"showGaugeOverlays": true,
"showGaugeOverlays": true,
"openBookmarksOnClick": false,
"openBookmarksOnClick": false,
"fixJPFontRendering": true,
"fixJPFontRendering": true,
"enableCoOpEnhancements": true,
"enableCoOpEnhancements": true,
"dropdownFix": true,
"dropdownFix": true,
"disableMiddleRightClick": true,
"disableMiddleRightClick": true,
"statusPanel": true,
"statusPanel": true,
"itemsPanel": true,
"itemsPanel": true,
"raidsPanel": false,
"raidsPanel": false,
"clockBrightness": 0.65,
"clockBrightness": 0.65,
"oneClickQuickSummons": true,
"oneClickQuickSummons": true,
"bookmarksInactiveIcon": null,
"bookmarksInactiveIcon": null,
"bookmarksActiveIcon": null,
"bookmarksActiveIcon": null,
"bookmarksIconPadding": 100,
"bookmarksIconPadding": 100,
"horizontalBookmarks": false,
"horizontalBookmarks": false,
"statusPanelBuffs": false,
"statusPanelBuffs": false,
"statusPanelExpiringBuffs": true,
"statusPanelExpiringBuffs": true,
"betterEnglishFont": false,
"betterEnglishFont": false,
"showItemWatchButtons": true,
"showItemWatchButtons": true,
"showPartyNames": true,
"showPartyNames": true,
"filterEnemyTimers": true,
"filterEnemyTimers": true,
"showPerformanceHud": false,
"showPerformanceHud": false,
"showNetworkHud": false,
"showNetworkHud": false,
"showWeaponAttack": true,
"showWeaponAttack": true,
"showSkillActivationIndicator": true,
"showSkillActivationIndicator": true,
"autofillBackupTweets": true,
"autofillBackupTweets": true,
"moveCoOpFooter": true,
"moveCoOpFooter": true,
"largeQuickPanels": false,
"largeQuickPanels": false,
"showPartyHelp": false,
"showPartyHelp": false,
"keepSoundOnBlur": true,
"keepSoundOnBlur": true,
"stuckButtonWorkaround2": true,
"stuckButtonWorkaround2": true,
"showLastActionTimer": true,
"showLastActionTimer": true,
"smartSupports": true,
"smartSupports": true,
"defaultToSmartSupports": false,
"defaultToSmartSupports": false,
"disablePhalanxSticker": true,
"disablePhalanxSticker": true,
"summonOrder": "{}",
"summonOrder": "{}",
"password": "",
"password": "",
"minimumPopupWait": 350,
"minimumPopupWait": 350,
"maximumPopupWait": 1750,
"maximumPopupWait": 1750,
"focusQuickPanels": true,
"focusQuickPanels": true,
"newSkillSystem": true
"newSkillSystem": true
});
});
var failedUpdateMinimumDelay = 10 * 1000;
var failedUpdateMinimumDelay = 10 * 1000;
var minimumUpdateDelay = 60 * 4 * 1000;
var minimumUpdateDelay = 60 * 4 * 1000;
var minimumRaidUpdateDelay = 30 * 1000;
var minimumRaidUpdateDelay = 30 * 1000;
var minimumItemUpdateDelay = 60 * 30 * 1000;
var minimumItemUpdateDelay = 60 * 30 * 1000;
var minimumHaloUpdateDelay = 60 * 30 * 1000;
var minimumHaloUpdateDelay = 60 * 30 * 1000;
var secretKeysByTabId = {};
var secretKeysByTabId = {};
var lastFailure = -1;
var lastFailure = -1;
var users = {};
var users = {};
var lastRaidCodes = {};
var lastRaidCodes = {};
var isDead = true;
var isDead = true;
var isShutdown = false;
var isShutdown = false;
var lastLocation = null;
var lastLocation = null;
var idleRedirectPending = false;
var idleRedirectPending = false;
var lastRedirectTarget = null;
var lastRedirectTarget = null;
chrome.runtime.onMessage.addListener(onRuntimeMessage);
chrome.runtime.onMessage.addListener(onRuntimeMessage);
chrome.alarms.onAlarm.addListener(onAlarm);
chrome.alarms.onAlarm.addListener(onAlarm);
chrome.runtime.onInstalled.addListener(function () {
chrome.runtime.onInstalled.addListener(function () {
var dc = chrome.declarativeContent;
var dc = chrome.declarativeContent;
dc.onPageChanged.removeRules(undefined, function () {
dc.onPageChanged.removeRules(undefined, function () {
dc.onPageChanged.addRules([
dc.onPageChanged.addRules([
{
{
conditions: [
conditions: [
new dc.PageStateMatcher({
new dc.PageStateMatcher({
pageUrl: { hostEquals: 'game.granbluefantasy.jp', schemes: ["https", "http"] },
pageUrl: { hostEquals: 'game.granbluefantasy.jp', schemes: ["https", "http"] },
}),
}),
new dc.PageStateMatcher({
new dc.PageStateMatcher({
pageUrl: { hostEquals: 'gbf.game.mbga.jp', schemes: ["https", "http"] },
pageUrl: { hostEquals: 'gbf.game.mbga.jp', schemes: ["https", "http"] },
})
})
],
],
actions: [new dc.ShowPageAction()]
actions: [new dc.ShowPageAction()]
}
}
]);
]);
});
});
});
});
log("Started");
log("Started");
function getAdjustedSettings() {
function getAdjustedSettings() {
var result = settings.toObject();
var result = settings.toObject();
result.allowDragSelect = false;
result.allowDragSelect = false;
// result.autoSkipToQuestResults = false;
// result.autoSkipToQuestResults = false;
// result.oneClickQuickSummons = false;
// result.oneClickQuickSummons = false;
result.realtimeRaidList = false;
result.realtimeRaidList = false;
// result.raidsPanel = false;
// result.raidsPanel = false;
// result.showQuickPanels = false;
// result.showQuickPanels = false;
result.touchInputSupport = false;
result.touchInputSupport = false;
// Cygamesssssssssssssss
// Cygamesssssssssssssss
result.autofillBackupTweets = false;
result.autofillBackupTweets = false;
// API changes broke this
// API changes broke this
result.detailedUpgradePage = false;
result.detailedUpgradePage = false;
return result;
return result;
}
}
;
;
function log(...args) {
function log(...args) {
args.unshift((new Date()).toLocaleString() + " |");
args.unshift((new Date()).toLocaleString() + " |");
console.log.apply(console, args);
console.log.apply(console, args);
}
}
;
;
function getWatchedItems() {
function getWatchedItems() {
var result = JSON.parse(settings.get("watchedItems") || "[]");
var result = JSON.parse(settings.get("watchedItems") || "[]");
if ((result.length === 1) && (result[0] === null))
if ((result.length === 1) && (result[0] === null))
result = [];
result = [];
var targetCounts = JSON.parse(settings.get("targetItemCounts") || "{}");
var targetCounts = JSON.parse(settings.get("targetItemCounts") || "{}");
कॉपी
कॉपी हुआ
कॉपी
कॉपी हुआ
var itemGroups = JSON.parse(settings.get("itemGroups") || "{}");
return {
return {
items: result,
items: result,
कॉपी
कॉपी हुआ
कॉपी
कॉपी हुआ
counts: targetCounts
counts: targetCounts
,
groups: itemGroups
};
};
}
}
;
;
function setItemWatchTarget(id, count) {
function setItemWatchTarget(id, count) {
var targetCounts = JSON.parse(settings.get("targetItemCounts") || "{}");
var targetCounts = JSON.parse(settings.get("targetItemCounts") || "{}");
targetCounts[id] = count;
targetCounts[id] = count;
settings.set("targetItemCounts", JSON.stringify(targetCounts));
settings.set("targetItemCounts", JSON.stringify(targetCounts));
}
}
;
;
कॉपी
कॉपी हुआ
कॉपी
कॉपी हुआ
function setItemGroup(id, group) {
var itemGroups = JSON.parse(settings.get("itemGroups") || "{}");
if (group!="undefined"){itemGroups[id] = group;}
else{
//hack because it's not an array so can't just be pushed to
var max = JSON.parse(settings.get("itemGroupsNumber") || "0");
var newmax = "" + (parseInt(max)+1);
settings.set("itemGroupsNumber", JSON.stringify(newmax));
itemGroups[id] = newmax;
}
settings.set("itemGroups", JSON.stringify(itemGroups));
}
;
function addWatchedItem(id) {
function addWatchedItem(id) {
var items = getWatchedItems().items;
var items = getWatchedItems().items;
if (items.indexOf(id) >= 0)
if (items.indexOf(id) >= 0)
return items;
return items;
if (!id)
if (!id)
return items;
return items;
items.push(id);
items.push(id);
settings.set("watchedItems", JSON.stringify(items));
settings.set("watchedItems", JSON.stringify(items));
return items;
return items;
}
}
;
;
function removeWatchedItem(id) {
function removeWatchedItem(id) {
var items = getWatchedItems().items;
var items = getWatchedItems().items;
var index = items.indexOf(id);
var index = items.indexOf(id);
if (index < 0)
if (index < 0)
return items;
return items;
items.splice(index, 1);
items.splice(index, 1);
settings.set("watchedItems", JSON.stringify(items));
settings.set("watchedItems", JSON.stringify(items));
return items;
return items;
}
}
;
;
function getFavedSummons() {
function getFavedSummons() {
var result = JSON.parse(settings.get("favedSummons") || "[]");
var result = JSON.parse(settings.get("favedSummons") || "[]");
if ((result.length === 1) && (result[0] === null))
if ((result.length === 1) && (result[0] === null))
result = [];
result = [];
return result;
return result;
}
}
;
;
function addFavedSummon(id) {
function addFavedSummon(id) {
var items = getFavedSummons();
var items = getFavedSummons();
if (items.indexOf(id) >= 0)
if (items.indexOf(id) >= 0)
return items;
return items;
if (!id)
if (!id)
return items;
return items;
items.push(id);
items.push(id);
settings.set("favedSummons", JSON.stringify(items));
settings.set("favedSummons", JSON.stringify(items));
return items;
return items;
}
}
;
;
function removeFavedSummon(id) {
function removeFavedSummon(id) {
var items = getFavedSummons();
var items = getFavedSummons();
var index = items.indexOf(id);
var index = items.indexOf(id);
if (index < 0)
if (index < 0)
return items;
return items;
items.splice(index, 1);
items.splice(index, 1);
settings.set("favedSummons", JSON.stringify(items));
settings.set("favedSummons", JSON.stringify(items));
return items;
return items;
}
}
;
;
function getUserDict(uid) {
function getUserDict(uid) {
var dict = users[uid];
var dict = users[uid];
if (!dict)
if (!dict)
dict = users[uid] = { lastUpdate: [] };
dict = users[uid] = { lastUpdate: [] };
return dict;
return dict;
}
}
;
;
function setUserData(uid, key, data) {
function setUserData(uid, key, data) {
var dict = getUserDict(uid);
var dict = getUserDict(uid);
if (data) {
if (data) {
dict.lastUpdate[key] = Date.now();
dict.lastUpdate[key] = Date.now();
dict[key] = data;
dict[key] = data;
}
}
else {
else {
dict.lastUpdate[key] = 0;
dict.lastUpdate[key] = 0;
dict[key] = null;
dict[key] = null;
}
}
}
}
;
;
function getUserData(uid, key) {
function getUserData(uid, key) {
var dict = getUserDict(uid);
var dict = getUserDict(uid);
return dict[key];
return dict[key];
}
}
;
;
function getLastDataUpdate(uid, key) {
function getLastDataUpdate(uid, key) {
var dict = getUserDict(uid);
var dict = getUserDict(uid);
return dict.lastUpdate[key];
return dict.lastUpdate[key];
}
}
;
;
function formatItemCounters(uid) {
function formatItemCounters(uid) {
var itemCounters = getUserDict(uid).itemCounters;
var itemCounters = getUserDict(uid).itemCounters;
if (!itemCounters)
if (!itemCounters)
return null;
return null;
var counterDict = {};
var counterDict = {};
for (var i = 0, l = itemCounters.length; i < l; i++) {
for (var i = 0, l = itemCounters.length; i < l; i++) {
var item = itemCounters[i];
var item = itemCounters[i];
counterDict[item.item_id] = item;
counterDict[item.item_id] = item;
}
}
return counterDict;
return counterDict;
}
}
;
;
function onRuntimeMessage(msg, sender, sendResponse) {
function onRuntimeMessage(msg, sender, sendResponse) {
if (chrome.runtime.lastError)
if (chrome.runtime.lastError)
log(chrome.runtime.lastError);
log(chrome.runtime.lastError);
var key = msg.type;
var key = msg.type;
var userDict;
var userDict;
if (msg.uid)
if (msg.uid)
userDict = getUserDict(msg.uid);
userDict = getUserDict(msg.uid);
var tabId;
var tabId;
if (sender.tab && sender.tab.id)
if (sender.tab && sender.tab.id)
tabId = sender.tab.id;
tabId = sender.tab.id;
else if (msg.tabId)
else if (msg.tabId)
tabId = msg.tabId;
tabId = msg.tabId;
if (tabId <= 0) {
if (tabId <= 0) {
log("Message has no tab id", key);
log("Message has no tab id", key);
return;
return;
}
}
var senderUrl = sender.url || "";
var senderUrl = sender.url || "";
if ((senderUrl.indexOf("granbluefantasy.jp") >= 0) ||
if ((senderUrl.indexOf("granbluefantasy.jp") >= 0) ||
(senderUrl.indexOf("mbga.jp") >= 0)) {
(senderUrl.indexOf("mbga.jp") >= 0)) {
}
}
else if ((senderUrl.indexOf("chrome-extension://") >= 0) &&
else if ((senderUrl.indexOf("chrome-extension://") >= 0) &&
(senderUrl.indexOf("api.html") >= 0)) {
(senderUrl.indexOf("api.html") >= 0)) {
switch (key) {
switch (key) {
case "apiRequest":
case "apiRequest":
case "getSettings":
case "getSettings":
break;
break;
default:
default:
log("Rejected disallowed API request", msg);
log("Rejected disallowed API request", msg);
return;
return;
}
}
}
}
switch (key) {
switch (key) {
case "apiRequest":
case "apiRequest":
if (!settings.get("webAPI")) {
if (!settings.get("webAPI")) {
log("Rejected API request because API is disabled", msg);
log("Rejected API request because API is disabled", msg);
sendResponse(null);
sendResponse(null);
return;
return;
}
}
log("Processing API request", msg.request.type);
log("Processing API request", msg.request.type);
switch (msg.request.type) {
switch (msg.request.type) {
case "getUserIds":
case "getUserIds":
sendResponse(JSON.stringify(Object.keys(users)));
sendResponse(JSON.stringify(Object.keys(users)));
break;
break;
case "getVersion":
case "getVersion":
sendResponse(chrome.app.getDetails().version);
sendResponse(chrome.app.getDetails().version);
break;
break;
case "tryJoinRaid":
case "tryJoinRaid":
case "getCombatState":
case "getCombatState":
log("Preparing to send api request", msg);
log("Preparing to send api request", msg);
chrome.tabs.query({}, function (tabs) {
chrome.tabs.query({}, function (tabs) {
if (tabs.length === 0) {
if (tabs.length === 0) {
log("Found no granblue tab");
log("Found no granblue tab");
sendResponse({ type: "result", error: "No granblue tab found" });
sendResponse({ type: "result", error: "No granblue tab found" });
return;
return;
}
}
for (var i = 0, l = tabs.length; i < l; i++) {
for (var i = 0, l = tabs.length; i < l; i++) {
var tab = tabs[i];
var tab = tabs[i];
var tabUrl = tab.url;
var tabUrl = tab.url;
if (!tabUrl ||
if (!tabUrl ||
((tabUrl.indexOf("game.granbluefantasy.jp") < 0) &&
((tabUrl.indexOf("game.granbluefantasy.jp") < 0) &&
(tabUrl.indexOf("gbf.game.mbga.jp") < 0))) {
(tabUrl.indexOf("gbf.game.mbga.jp") < 0))) {
continue;
continue;
}
}
log("Sending api request", msg);
log("Sending api request", msg);
actuallySendMessage(msg, tab.id, function (result) {
actuallySendMessage(msg, tab.id, function (result) {
log("Got result for api request");
log("Got result for api request");
sendResponse(result);
sendResponse(result);
});
});
return;
return;
}
}
log("Found no granblue tab");
log("Found no granblue tab");
sendResponse({ type: "result", error: "No granblue tab found" });
sendResponse({ type: "result", error: "No granblue tab found" });
});
});
return true;
return true;
default:
default:
sendResponse({ type: "result", error: "Unknown message" });
sendResponse({ type: "result", error: "Unknown message" });
break;
break;
}
}
break;
break;
case "getUserIds":
case "getUserIds":
sendResponse(JSON.stringify(Object.keys(users)));
sendResponse(JSON.stringify(Object.keys(users)));
break;
break;
case "setPassword":
case "setPassword":
settings.set("password", msg.password);
settings.set("password", msg.password);
break;
break;
case "pleaseInjectStylesheets":
case "pleaseInjectStylesheets":
injectStylesheetsIntoTab(sender);
injectStylesheetsIntoTab(sender);
break;
break;
case "heartbeat":
case "heartbeat":
isDead = false;
isDead = false;
break;
break;
case "cancelSuspend":
case "cancelSuspend":
if (userDict.isSuspended)
if (userDict.isSuspended)
log("Canceling idle/maintenance suspend for " + msg.uid);
log("Canceling idle/maintenance suspend for " + msg.uid);
userDict.isSuspended = false;
userDict.isSuspended = false;
lastFailure = -1;
lastFailure = -1;
break;
break;
case "isShutdown":
case "isShutdown":
sendResponse(isShutdown);
sendResponse(isShutdown);
break;
break;
case "setCompatibility":
case "setCompatibility":
var newState = (msg.state === false);
var newState = (msg.state === false);
if (newState !== isShutdown) {
if (newState !== isShutdown) {
log("Compatibility shutdown state set to", newState);
log("Compatibility shutdown state set to", newState);
isShutdown = newState;
isShutdown = newState;
}
}
break;
break;
case "openNewTab":
case "openNewTab":
chrome.tabs.create({
chrome.tabs.create({
url: msg.url
url: msg.url
});
});
break;
break;
case "getVersion":
case "getVersion":
sendResponse(chrome.app.getDetails().version);
sendResponse(chrome.app.getDetails().version);
break;
break;
case "setRecentCoOpHost":
case "setRecentCoOpHost":
settings.set("recentCoOpHost", msg.data);
settings.set("recentCoOpHost", msg.data);
break;
break;
case "getRecentCoOpHost":
case "getRecentCoOpHost":
sendResponse(settings.get("recentCoOpHost") || null);
sendResponse(settings.get("recentCoOpHost") || null);
break;
break;
case "setCurrentEvent":
case "setCurrentEvent":
if (msg.href !== settings.get("currentEvent"))
if (msg.href !== settings.get("currentEvent"))
log("Event changed to '" + msg.href + "'");
log("Event changed to '" + msg.href + "'");
settings.set("currentEvent", msg.href);
settings.set("currentEvent", msg.href);
break;
break;
case "setCurrentGuildWar":
case "setCurrentGuildWar":
if (msg.href !== settings.get("currentGuildWar"))
if (msg.href !== settings.get("currentGuildWar"))
log("Guild war changed to '" + msg.href + "'");
log("Guild war changed to '" + msg.href + "'");
settings.set("currentGuildWar", msg.href);
settings.set("currentGuildWar", msg.href);
break;
break;
case "getCurrentEvent":
case "getCurrentEvent":
sendResponse(settings.get("currentEvent") || null);
sendResponse(settings.get("currentEvent") || null);
break;
break;
case "getCurrentGuildWar":
case "getCurrentGuildWar":
sendResponse(settings.get("currentGuildWar") || null);
sendResponse(settings.get("currentGuildWar") || null);
break;
break;
case "setRecentQuest":
case "setRecentQuest":
settings.set("recentQuest", msg.url);
settings.set("recentQuest", msg.url);
break;
break;
case "getRecentQuest":
case "getRecentQuest":
sendResponse(settings.get("recentQuest") || null);
sendResponse(settings.get("recentQuest") || null);
break;
break;
case "setLastLocation":
case "setLastLocation":
// FIXME: Track per-tab
// FIXME: Track per-tab
lastLocation = msg.url;
lastLocation = msg.url;
break;
break;
case "setIdleRedirectPending":
case "setIdleRedirectPending":
// FIXME: Track per-tab
// FIXME: Track per-tab
idleRedirectPending = msg.state;
idleRedirectPending = msg.state;
if (msg.url)
if (msg.url)
lastRedirectTarget = msg.url;
lastRedirectTarget = msg.url;
break;
break;
case "getLastLocation":
case "getLastLocation":
sendResponse(lastLocation || null);
sendResponse(lastLocation || null);
break;
break;
case "getIdleRedirectInfo":
case "getIdleRedirectInfo":
if (idleRedirectPending) {
if (idleRedirectPending) {
sendResponse({ pending: true, location: lastLocation, lastRedirectTarget: lastRedirectTarget });
sendResponse({ pending: true, location: lastLocation, lastRedirectTarget: lastRedirectTarget });
}
}
else {
else {
sendResponse({ pending: false });
sendResponse({ pending: false });
}
}
break;
break;
case "getSettings":
case "getSettings":
sendResponse(getAdjustedSettings());
sendResponse(getAdjustedSettings());
break;
break;
case "getRaidCode":
case "getRaidCode":
sendResponse(lastRaidCodes[tabId]);
sendResponse(lastRaidCodes[tabId]);
break;
break;
case "updateRaidCode":
case "updateRaidCode":
lastRaidCodes[tabId] = msg.raidCode;
lastRaidCodes[tabId] = msg.raidCode;
break;
break;
case "getItemCounters":
case "getItemCounters":
return maybeDoUpdate(userDict.nextCounterUpdate, minimumUpdateDelay, formatItemCounters, updateItemCounters, sendResponse, msg.force, tabId, msg.uid);
return maybeDoUpdate(userDict.nextCounterUpdate, minimumUpdateDelay, formatItemCounters, updateItemCounters, sendResponse, msg.force, tabId, msg.uid);
case "updateItemCounters":
case "updateItemCounters":
userDict.nextCounterUpdate = Date.now() + minimumUpdateDelay;
userDict.nextCounterUpdate = Date.now() + minimumUpdateDelay;
userDict.itemCounters = msg.counters;
userDict.itemCounters = msg.counters;
break;
break;
case "invalidateStatus":
case "invalidateStatus":
if (userDict.lastStatus)
if (userDict.lastStatus)
log("Status invalidated");
log("Status invalidated");
userDict.nextStatusUpdate = 0;
userDict.nextStatusUpdate = 0;
userDict.lastStatus = null;
userDict.lastStatus = null;
break;
break;
case "getStatus":
case "getStatus":
var getLastStatus = function (uid) {
var getLastStatus = function (uid) {
var s = getUserDict(uid).lastStatus;
var s = getUserDict(uid).lastStatus;
if (s)
if (s)
fixupStatus(s, uid);
fixupStatus(s, uid);
return s;
return s;
};
};
if (msg.lazy) {
if (msg.lazy) {
var lastStatus = getLastStatus(msg.uid);
var lastStatus = getLastStatus(msg.uid);
if (lastStatus) {
if (lastStatus) {
sendResponse(lastStatus);
sendResponse(lastStatus);
return;
return;
}
}
else {
else {
// log("Lazy status update failed");
// log("Lazy status update failed");
}
}
}
}
return maybeDoUpdate(userDict.nextStatusUpdate, minimumUpdateDelay, getLastStatus, updateStatus, sendResponse, msg.force, tabId, msg.uid);
return maybeDoUpdate(userDict.nextStatusUpdate, minimumUpdateDelay, getLastStatus, updateStatus, sendResponse, msg.force, tabId, msg.uid);
case "updateStatus":
case "updateStatus":
handleNewStatus(msg.status, msg.uid);
handleNewStatus(msg.status, msg.uid);
break;
break;
case "invalidateBuffs":
case "invalidateBuffs":
userDict.nextGuildBuffUpdate = 0;
userDict.nextGuildBuffUpdate = 0;
userDict.nextPersonalBuffUpdate = 0;
userDict.nextPersonalBuffUpdate = 0;
userDict.guildBuffs = null;
userDict.guildBuffs = null;
userDict.personalBuffs = null;
userDict.personalBuffs = null;
log("Buffs invalidated");
log("Buffs invalidated");
break;
break;
case "updateGuildBuffs":
case "updateGuildBuffs":
userDict.lastGuildBuffUpdate = Date.now();
userDict.lastGuildBuffUpdate = Date.now();
userDict.nextGuildBuffUpdate = Date.now() + minimumUpdateDelay;
userDict.nextGuildBuffUpdate = Date.now() + minimumUpdateDelay;
userDict.guildBuffs = msg.buffs;
userDict.guildBuffs = msg.buffs;
break;
break;
case "updatePersonalBuffs":
case "updatePersonalBuffs":
userDict.lastPersonalBuffUpdate = Date.now();
userDict.lastPersonalBuffUpdate = Date.now();
userDict.nextPersonalBuffUpdate = Date.now() + minimumUpdateDelay;
userDict.nextPersonalBuffUpdate = Date.now() + minimumUpdateDelay;
userDict.personalBuffs = msg.buffs;
userDict.personalBuffs = msg.buffs;
break;
break;
case "getNextRankRp":
case "getNextRankRp":
// if not force, don't actually update since this is a heavy call
// if not force, don't actually update since this is a heavy call
if (!msg.force) {
if (!msg.force) {
if (userDict.nextNextRankRpUpdate) {
if (userDict.nextNextRankRpUpdate) {
sendResponse(userDict.nextRankRp);
sendResponse(userDict.nextRankRp);
break;
break;
}
}
sendResponse(null);
sendResponse(null);
break;
break;
}
}
return maybeDoUpdate(userDict.nextNextRankRpUpdate, minimumUpdateDelay, function (uid) { return getUserDict(uid).nextRankRp; }, updateNextRankRp, sendResponse, msg.force, tabId, msg.uid);
return maybeDoUpdate(userDict.nextNextRankRpUpdate, minimumUpdateDelay, function (uid) { return getUserDict(uid).nextRankRp; }, updateNextRankRp, sendResponse, msg.force, tabId, msg.uid);
case "updateNextRankRp":
case "updateNextRankRp":
userDict.nextNextRankRpUpdate = Date.now() + minimumUpdateDelay;
userDict.nextNextRankRpUpdate = Date.now() + minimumUpdateDelay;
userDict.nextRankRp = getRpToNextRank(msg.data);
userDict.nextRankRp = getRpToNextRank(msg.data);
break;
break;
case "getRaids":
case "getRaids":
return maybeDoUpdate(userDict.nextRaidUpdate, minimumRaidUpdateDelay, function (uid) { return getUserDict(uid).lastRaids; }, updateRaids, sendResponse, msg.force, tabId, msg.uid);
return maybeDoUpdate(userDict.nextRaidUpdate, minimumRaidUpdateDelay, function (uid) { return getUserDict(uid).lastRaids; }, updateRaids, sendResponse, msg.force, tabId, msg.uid);
case "invalidateRaids":
case "invalidateRaids":
if (msg.raids) {
if (msg.raids) {
handleNewRaids(msg.raids, msg.uid);
handleNewRaids(msg.raids, msg.uid);
}
}
else {
else {
if (userDict.lastRaids)
if (userDict.lastRaids)
log("Raids invalidated");
log("Raids invalidated");
userDict.nextRaidUpdate = 0;
userDict.nextRaidUpdate = 0;
userDict.lastRaids = null;
userDict.lastRaids = null;
}
}
break;
break;
case "getItems":
case "getItems":
return maybeDoUpdate(userDict.nextItemUpdate, minimumItemUpdateDelay, function (uid) { return getUserDict(uid).lastItems; }, updateItems, sendResponse, msg.force, tabId, msg.uid);
return maybeDoUpdate(userDict.nextItemUpdate, minimumItemUpdateDelay, function (uid) { return getUserDict(uid).lastItems; }, updateItems, sendResponse, msg.force, tabId, msg.uid);
case "invalidateItems":
case "invalidateItems":
if (msg.items) {
if (msg.items) {
handleNewItems(msg.items, msg.uid);
handleNewItems(msg.items, msg.uid);
}
}
else {
else {
if (userDict.lastItems)
if (userDict.lastItems)
log("Items invalidated");
log("Items invalidated");
userDict.nextItemUpdate = 0;
userDict.nextItemUpdate = 0;
userDict.lastItems = null;
userDict.lastItems = null;
}
}
break;
break;
case "getWatchedItems":
case "getWatchedItems":
sendResponse(getWatchedItems());
sendResponse(getWatchedItems());
break;
break;
case "setItemWatchState":
case "setItemWatchState":
if (msg.state)
if (msg.state)
sendResponse(addWatchedItem(msg.id));
sendResponse(addWatchedItem(msg.id));
else
else
sendResponse(removeWatchedItem(msg.id));
sendResponse(removeWatchedItem(msg.id));
break;
break;
case "setItemWatchTarget":
case "setItemWatchTarget":
setItemWatchTarget(msg.id, msg.count);
setItemWatchTarget(msg.id, msg.count);
break;
break;
कॉपी
कॉपी हुआ
कॉपी
कॉपी हुआ
case "setItemGroup":
setItemGroup(msg.id, msg.group);
break;
case "getFavedSummons":
case "getFavedSummons":
sendResponse(getFavedSummons());
sendResponse(getFavedSummons());
break;
break;
case "setSummonFaveState":
case "setSummonFaveState":
if (msg.state)
if (msg.state)
sendResponse(addFavedSummon(msg.id));
sendResponse(addFavedSummon(msg.id));
else
else
sendResponse(removeFavedSummon(msg.id));
sendResponse(removeFavedSummon(msg.id));
break;
break;
case "setSummonOrder":
case "setSummonOrder":
settings.set("summonOrder", msg.data);
settings.set("summonOrder", msg.data);
break;
break;
case "getIsDead":
case "getIsDead":
sendResponse(isDead);
sendResponse(isDead);
break;
break;
case "doGameAjax":
case "doGameAjax":
doGameAjax(msg, tabId, msg.uid, sendResponse);
doGameAjax(msg, tabId, msg.uid, sendResponse);
// retain sendResponse
// retain sendResponse
return true;
return true;
case "doGamePopup":
case "doGamePopup":
case "doGameRedirect":
case "doGameRedirect":
actuallySendMessage(msg, tabId);
actuallySendMessage(msg, tabId);
break;
break;
case "getTabId":
case "getTabId":
sendResponse(tabId);
sendResponse(tabId);
break;
break;
case "getUserIdAndTabId":
case "getUserIdAndTabId":
msg.tabId = tabId;
msg.tabId = tabId;
actuallySendMessage(msg, tabId, sendResponse);
actuallySendMessage(msg, tabId, sendResponse);
return true;
return true;
case "getIsSuspended":
case "getIsSuspended":
sendResponse(!!userDict.isSuspended);
sendResponse(!!userDict.isSuspended);
return true;
return true;
case "recordRewards":
case "recordRewards":
handleQuestRewards(msg);
handleQuestRewards(msg);
break;
break;
case "recordRaidInfo":
case "recordRaidInfo":
handleRaidInfo(msg);
handleRaidInfo(msg);
break;
break;
case "registerSecretKey":
case "registerSecretKey":
secretKeysByTabId[tabId] = msg.key;
secretKeysByTabId[tabId] = msg.key;
break;
break;
case "actionStarted":
case "actionStarted":
userDict.lastActionStartedWhen = msg.when;
userDict.lastActionStartedWhen = msg.when;
userDict.lastActionId = msg.actionId;
userDict.lastActionId = msg.actionId;
broadcastActionTimestamps(msg.uid, userDict);
broadcastActionTimestamps(msg.uid, userDict);
break;
break;
case "actionEnded":
case "actionEnded":
if (msg.succeeded) {
if (msg.succeeded) {
userDict.lastSuccessfulActionStartedWhen =
userDict.lastSuccessfulActionStartedWhen =
userDict.lastActionStartedWhen;
userDict.lastActionStartedWhen;
}
}
if (userDict.lastActionId === msg.actionId) {
if (userDict.lastActionId === msg.actionId) {
if (msg.succeeded) {
if (msg.succeeded) {
userDict.lastSuccessfulActionId =
userDict.lastSuccessfulActionId =
userDict.lastActionId;
userDict.lastActionId;
}
}
else {
else {
userDict.lastActionId = null;
userDict.lastActionId = null;
}
}
}
}
userDict.lastActionEndedWhen = msg.when;
userDict.lastActionEndedWhen = msg.when;
broadcastActionTimestamps(msg.uid, userDict);
broadcastActionTimestamps(msg.uid, userDict);
break;
break;
case "actionCompletedAnimation":
case "actionCompletedAnimation":
// When an action's animation is complete, we disable
// When an action's animation is complete, we disable
// the timer since the lockout is definitely over
// the timer since the lockout is definitely over
if (msg.actionId === userDict.lastActionId) {
if (msg.actionId === userDict.lastActionId) {
userDict.lastActionStartedWhen =
userDict.lastActionStartedWhen =
userDict.lastActionId = null;
userDict.lastActionId = null;
broadcastActionTimestamps(msg.uid, userDict);
broadcastActionTimestamps(msg.uid, userDict);
}
}
break;
break;
case "getLastActionTimestamps":
case "getLastActionTimestamps":
sendResponse(makeActionTimestamps(userDict));
sendResponse(makeActionTimestamps(userDict));
break;
break;
default:
default:
log("Unknown message " + key);
log("Unknown message " + key);
sendResponse({ error: true });
sendResponse({ error: true });
break;
break;
}
}
}
}
;
;
function broadcastActionTimestamps(uid, userDict) {
function broadcastActionTimestamps(uid, userDict) {
var obj = makeActionTimestamps(userDict);
var obj = makeActionTimestamps(userDict);
var msg = {
var msg = {
type: "actionTimestampsChanged",
type: "actionTimestampsChanged",
data: obj,
data: obj,
uid: uid
uid: uid
};
};
chrome.tabs.query(
chrome.tabs.query(
// FIXME: Can we narrow this to granblue tabs without the 'tabs' permission?
// FIXME: Can we narrow this to granblue tabs without the 'tabs' permission?
{}, function (tabs) {
{}, function (tabs) {
if (!tabs)
if (!tabs)
return;
return;
for (var i = 0; i < tabs.length; i++) {
for (var i = 0; i < tabs.length; i++) {
var tab = tabs[i];
var tab = tabs[i];
chrome.tabs.sendMessage(tab.id, msg);
chrome.tabs.sendMessage(tab.id, msg);
if (chrome.runtime.lastError)
if (chrome.runtime.lastError)
log(chrome.runtime.lastError);
log(chrome.runtime.lastError);
}
}
});
});
}
}
;
;
function makeActionTimestamps(userDict) {
function makeActionTimestamps(userDict) {
return {
return {
actionId: userDict.lastActionId,
actionId: userDict.lastActionId,
successfulActionId: userDict.lastSuccessfulActionId,
successfulActionId: userDict.lastSuccessfulActionId,
started: userDict.lastActionStartedWhen,
started: userDict.lastActionStartedWhen,
successfulStarted: userDict.lastSuccessfulActionStartedWhen,
successfulStarted: userDict.lastSuccessfulActionStartedWhen,
ended: userDict.lastActionEndedWhen
ended: userDict.lastActionEndedWhen
};
};
}
}
;
;
function handleQuestRewards(msg) {
function handleQuestRewards(msg) {
var userDict = getUserDict(msg.uid);
var userDict = getUserDict(msg.uid);
if (!userDict.raids)
if (!userDict.raids)
return;
return;
var urlFragment = msg.url.substr(msg.url.lastIndexOf("/") + 1);
var urlFragment = msg.url.substr(msg.url.lastIndexOf("/") + 1);
urlFragment = urlFragment.substr(0, urlFragment.indexOf("?"));
urlFragment = urlFragment.substr(0, urlFragment.indexOf("?"));
var raidId = parseInt(urlFragment);
var raidId = parseInt(urlFragment);
var questId = userDict.raids[raidId];
var questId = userDict.raids[raidId];
}
}
;
;
function handleRaidInfo(msg) {
function handleRaidInfo(msg) {
var userDict = getUserDict(msg.uid);
var userDict = getUserDict(msg.uid);
if (!userDict.raids)
if (!userDict.raids)
userDict.raids = {};
userDict.raids = {};
userDict.raids[msg.raidId] = msg.questId;
userDict.raids[msg.raidId] = msg.questId;
}
}
;
;
function parseTimeInMinutes(text) {
function parseTimeInMinutes(text) {
var parts = text.split(/[\D]+/);
var parts = text.split(/[\D]+/);
var result = 0;
var result = 0;
for (var i = 0, len = Math.min(parts.length, 2); i < len; i++) {
for (var i = 0, len = Math.min(parts.length, 2); i < len; i++) {
if (parts[i].length === 0) {
if (parts[i].length === 0) {
break;
break;
}
}
result = result * 60 + parseInt(parts[i]);
result = result * 60 + parseInt(parts[i]);
}
}
return result;
return result;
}
}
;
;
function estimateValue(truncated, maximum, timeRemaining, elapsedTimeMs, minutesPerUnit) {
function estimateValue(truncated, maximum, timeRemaining, elapsedTimeMs, minutesPerUnit) {
if (truncated >= maximum)
if (truncated >= maximum)
return truncated;
return truncated;
// HACK: Add 59 seconds to the remaining time since they round down the number of minutes
// HACK: Add 59 seconds to the remaining time since they round down the number of minutes
timeRemaining += 59 / 60;
timeRemaining += 59 / 60;
var durationFromFull = maximum * minutesPerUnit;
var durationFromFull = maximum * minutesPerUnit;
timeRemaining = Math.max(0, timeRemaining - (elapsedTimeMs / 60000));
timeRemaining = Math.max(0, timeRemaining - (elapsedTimeMs / 60000));
var fract = (timeRemaining / durationFromFull);
var fract = (timeRemaining / durationFromFull);
fract = Math.max(0.0, Math.min(1.0, fract));
fract = Math.max(0.0, Math.min(1.0, fract));
var estimatedValue = maximum * (1.0 - fract);
var estimatedValue = maximum * (1.0 - fract);
return estimatedValue;
return estimatedValue;
}
}
;
;
function fixupStatus(status, uid) {
function fixupStatus(status, uid) {
if (!status)
if (!status)
return status;
return status;
var userDict = getUserDict(uid);
var userDict = getUserDict(uid);
// FIXME
// FIXME
var lastUpdate = userDict.lastStatusUpdate;
var lastUpdate = userDict.lastStatusUpdate;
status._lastUpdate = lastUpdate;
status._lastUpdate = lastUpdate;
status._now = Date.now();
status._now = Date.now();
var age = (status._now - status._lastUpdate);
var age = (status._now - status._lastUpdate);
status._precise_ap = estimateValue(status.ap, parseInt(status.max_action_point), parseTimeInMinutes(status.action_point_remain), age, 5);
status._precise_ap = estimateValue(status.ap, parseInt(status.max_action_point), parseTimeInMinutes(status.action_point_remain), age, 5);
status._precise_bp = estimateValue(status.bp, parseInt(status.max_battle_point), parseTimeInMinutes(status.battle_point_remain), age, 10);
status._precise_bp = estimateValue(status.bp, parseInt(status.max_battle_point), parseTimeInMinutes(status.battle_point_remain), age, 10);
status.buffs = [];
status.buffs = [];
if (userDict.guildBuffs) {
if (userDict.guildBuffs) {
// FIXME
// FIXME
age = (status._now - userDict.lastGuildBuffUpdate);
age = (status._now - userDict.lastGuildBuffUpdate);
for (var i = 0, l = userDict.guildBuffs.length; i < l; i++) {
for (var i = 0, l = userDict.guildBuffs.length; i < l; i++) {
var gb = userDict.guildBuffs[i];
var gb = userDict.guildBuffs[i];
var timeRemaining = (parseTimeInMinutes(gb.time) * 60 * 1000) - age;
var timeRemaining = (parseTimeInMinutes(gb.time) * 60 * 1000) - age;
if (timeRemaining <= 0)
if (timeRemaining <= 0)
continue;
continue;
status.buffs.push({
status.buffs.push({
comment: gb.comment,
comment: gb.comment,
timeRemaining: timeRemaining,
timeRemaining: timeRemaining,
imageUrl: "http://game-a.granbluefantasy.jp/assets_en/img/sp/assets/item/support/support_" +
imageUrl: "http://game-a.granbluefantasy.jp/assets_en/img/sp/assets/item/support/support_" +
gb.image + "_" + gb.level + ".png"
gb.image + "_" + gb.level + ".png"
});
});
}
}
}
}
if (userDict.personalBuffs) {
if (userDict.personalBuffs) {
// FIXME
// FIXME
age = (status._now - userDict.lastPersonalBuffUpdate);
age = (status._now - userDict.lastPersonalBuffUpdate);
for (var k in userDict.personalBuffs) {
for (var k in userDict.personalBuffs) {
if (!userDict.personalBuffs.hasOwnProperty(k))
if (!userDict.personalBuffs.hasOwnProperty(k))
continue;
continue;
var pb = userDict.personalBuffs[k];
var pb = userDict.personalBuffs[k];
var timeRemaining = (parseTimeInMinutes(pb.remain_time) * 60 * 1000) - age;
var timeRemaining = (parseTimeInMinutes(pb.remain_time) * 60 * 1000) - age;
कॉपी
कॉपी हुआ
कॉपी
कॉपी हुआ
if (timeRemaining <
= 0)
if (timeRemaining <
continue;
status.buffs.push({
comment: pb.name,
timeRemaining: timeRemaining,
imageUrl: "http://game-a.granbluefantasy.jp/assets_en/img/sp/assets/item/support/" +
pb.image_path + "_" + pb.level + ".png"
});
}
}
return status;
}
;
function handleNewStatus(status, uid) {
if (!status) {
log("Failed status update");
return;
}
getUserDict(uid).lastStatus = status;
getUserDict(uid).lastStatusUpdate = Date.now();
getUserDict(uid).nextStatusUpdate = Date.now() + minimumUpdateDelay;
var minutesUntilApRefill = parseTimeInMinutes(status.action_poin
सेव किए गए Diffs
ऑरिजनल टेक्स्ट
फ़ाइल खोलें
"use strict"; var settings = new Store("settings", { "preferFriendSummons": true, "preferNonFriendSummonsInFavorites": true, "preferLimitBrokenSummons": true, "preferHighLevelSummons": true, "notifyOnFullAP": false, "notifyOnFullBP": false, "showSkillCooldowns": true, "showDebuffTimers": true, "showBuffTimers": true, "monitorRaidDebuffs": true, "keyboardShortcuts": true, "showBookmarks": true, "preferredSummonElement": "", "submenuSize": 1.0, "bookmarksSize": 1.0, "bookmarksMenuSize": 1.0, "recentQuest": null, "showQuickPanels": true, "showGaugeOverlays": true, "openBookmarksOnClick": false, "fixJPFontRendering": true, "enableCoOpEnhancements": true, "dropdownFix": true, "disableMiddleRightClick": true, "statusPanel": true, "itemsPanel": true, "raidsPanel": false, "clockBrightness": 0.65, "oneClickQuickSummons": true, "bookmarksInactiveIcon": null, "bookmarksActiveIcon": null, "bookmarksIconPadding": 100, "horizontalBookmarks": false, "statusPanelBuffs": false, "statusPanelExpiringBuffs": true, "betterEnglishFont": false, "showItemWatchButtons": true, "showPartyNames": true, "filterEnemyTimers": true, "showPerformanceHud": false, "showNetworkHud": false, "showWeaponAttack": true, "showSkillActivationIndicator": true, "autofillBackupTweets": true, "moveCoOpFooter": true, "largeQuickPanels": false, "showPartyHelp": false, "keepSoundOnBlur": true, "stuckButtonWorkaround2": true, "showLastActionTimer": true, "smartSupports": true, "defaultToSmartSupports": false, "disablePhalanxSticker": true, "summonOrder": "{}", "password": "", "minimumPopupWait": 350, "maximumPopupWait": 1750, "focusQuickPanels": true, "newSkillSystem": true }); var failedUpdateMinimumDelay = 10 * 1000; var minimumUpdateDelay = 60 * 4 * 1000; var minimumRaidUpdateDelay = 30 * 1000; var minimumItemUpdateDelay = 60 * 30 * 1000; var minimumHaloUpdateDelay = 60 * 30 * 1000; var secretKeysByTabId = {}; var lastFailure = -1; var users = {}; var lastRaidCodes = {}; var isDead = true; var isShutdown = false; var lastLocation = null; var idleRedirectPending = false; var lastRedirectTarget = null; chrome.runtime.onMessage.addListener(onRuntimeMessage); chrome.alarms.onAlarm.addListener(onAlarm); chrome.runtime.onInstalled.addListener(function () { var dc = chrome.declarativeContent; dc.onPageChanged.removeRules(undefined, function () { dc.onPageChanged.addRules([ { conditions: [ new dc.PageStateMatcher({ pageUrl: { hostEquals: 'game.granbluefantasy.jp', schemes: ["https", "http"] }, }), new dc.PageStateMatcher({ pageUrl: { hostEquals: 'gbf.game.mbga.jp', schemes: ["https", "http"] }, }) ], actions: [new dc.ShowPageAction()] } ]); }); }); log("Started"); function getAdjustedSettings() { var result = settings.toObject(); result.allowDragSelect = false; // result.autoSkipToQuestResults = false; // result.oneClickQuickSummons = false; result.realtimeRaidList = false; // result.raidsPanel = false; // result.showQuickPanels = false; result.touchInputSupport = false; // Cygamesssssssssssssss result.autofillBackupTweets = false; // API changes broke this result.detailedUpgradePage = false; return result; } ; function log(...args) { args.unshift((new Date()).toLocaleString() + " |"); console.log.apply(console, args); } ; function getWatchedItems() { var result = JSON.parse(settings.get("watchedItems") || "[]"); if ((result.length === 1) && (result[0] === null)) result = []; var targetCounts = JSON.parse(settings.get("targetItemCounts") || "{}"); return { items: result, counts: targetCounts }; } ; function setItemWatchTarget(id, count) { var targetCounts = JSON.parse(settings.get("targetItemCounts") || "{}"); targetCounts[id] = count; settings.set("targetItemCounts", JSON.stringify(targetCounts)); } ; function addWatchedItem(id) { var items = getWatchedItems().items; if (items.indexOf(id) >= 0) return items; if (!id) return items; items.push(id); settings.set("watchedItems", JSON.stringify(items)); return items; } ; function removeWatchedItem(id) { var items = getWatchedItems().items; var index = items.indexOf(id); if (index < 0) return items; items.splice(index, 1); settings.set("watchedItems", JSON.stringify(items)); return items; } ; function getFavedSummons() { var result = JSON.parse(settings.get("favedSummons") || "[]"); if ((result.length === 1) && (result[0] === null)) result = []; return result; } ; function addFavedSummon(id) { var items = getFavedSummons(); if (items.indexOf(id) >= 0) return items; if (!id) return items; items.push(id); settings.set("favedSummons", JSON.stringify(items)); return items; } ; function removeFavedSummon(id) { var items = getFavedSummons(); var index = items.indexOf(id); if (index < 0) return items; items.splice(index, 1); settings.set("favedSummons", JSON.stringify(items)); return items; } ; function getUserDict(uid) { var dict = users[uid]; if (!dict) dict = users[uid] = { lastUpdate: [] }; return dict; } ; function setUserData(uid, key, data) { var dict = getUserDict(uid); if (data) { dict.lastUpdate[key] = Date.now(); dict[key] = data; } else { dict.lastUpdate[key] = 0; dict[key] = null; } } ; function getUserData(uid, key) { var dict = getUserDict(uid); return dict[key]; } ; function getLastDataUpdate(uid, key) { var dict = getUserDict(uid); return dict.lastUpdate[key]; } ; function formatItemCounters(uid) { var itemCounters = getUserDict(uid).itemCounters; if (!itemCounters) return null; var counterDict = {}; for (var i = 0, l = itemCounters.length; i < l; i++) { var item = itemCounters[i]; counterDict[item.item_id] = item; } return counterDict; } ; function onRuntimeMessage(msg, sender, sendResponse) { if (chrome.runtime.lastError) log(chrome.runtime.lastError); var key = msg.type; var userDict; if (msg.uid) userDict = getUserDict(msg.uid); var tabId; if (sender.tab && sender.tab.id) tabId = sender.tab.id; else if (msg.tabId) tabId = msg.tabId; if (tabId <= 0) { log("Message has no tab id", key); return; } var senderUrl = sender.url || ""; if ((senderUrl.indexOf("granbluefantasy.jp") >= 0) || (senderUrl.indexOf("mbga.jp") >= 0)) { } else if ((senderUrl.indexOf("chrome-extension://") >= 0) && (senderUrl.indexOf("api.html") >= 0)) { switch (key) { case "apiRequest": case "getSettings": break; default: log("Rejected disallowed API request", msg); return; } } switch (key) { case "apiRequest": if (!settings.get("webAPI")) { log("Rejected API request because API is disabled", msg); sendResponse(null); return; } log("Processing API request", msg.request.type); switch (msg.request.type) { case "getUserIds": sendResponse(JSON.stringify(Object.keys(users))); break; case "getVersion": sendResponse(chrome.app.getDetails().version); break; case "tryJoinRaid": case "getCombatState": log("Preparing to send api request", msg); chrome.tabs.query({}, function (tabs) { if (tabs.length === 0) { log("Found no granblue tab"); sendResponse({ type: "result", error: "No granblue tab found" }); return; } for (var i = 0, l = tabs.length; i < l; i++) { var tab = tabs[i]; var tabUrl = tab.url; if (!tabUrl || ((tabUrl.indexOf("game.granbluefantasy.jp") < 0) && (tabUrl.indexOf("gbf.game.mbga.jp") < 0))) { continue; } log("Sending api request", msg); actuallySendMessage(msg, tab.id, function (result) { log("Got result for api request"); sendResponse(result); }); return; } log("Found no granblue tab"); sendResponse({ type: "result", error: "No granblue tab found" }); }); return true; default: sendResponse({ type: "result", error: "Unknown message" }); break; } break; case "getUserIds": sendResponse(JSON.stringify(Object.keys(users))); break; case "setPassword": settings.set("password", msg.password); break; case "pleaseInjectStylesheets": injectStylesheetsIntoTab(sender); break; case "heartbeat": isDead = false; break; case "cancelSuspend": if (userDict.isSuspended) log("Canceling idle/maintenance suspend for " + msg.uid); userDict.isSuspended = false; lastFailure = -1; break; case "isShutdown": sendResponse(isShutdown); break; case "setCompatibility": var newState = (msg.state === false); if (newState !== isShutdown) { log("Compatibility shutdown state set to", newState); isShutdown = newState; } break; case "openNewTab": chrome.tabs.create({ url: msg.url }); break; case "getVersion": sendResponse(chrome.app.getDetails().version); break; case "setRecentCoOpHost": settings.set("recentCoOpHost", msg.data); break; case "getRecentCoOpHost": sendResponse(settings.get("recentCoOpHost") || null); break; case "setCurrentEvent": if (msg.href !== settings.get("currentEvent")) log("Event changed to '" + msg.href + "'"); settings.set("currentEvent", msg.href); break; case "setCurrentGuildWar": if (msg.href !== settings.get("currentGuildWar")) log("Guild war changed to '" + msg.href + "'"); settings.set("currentGuildWar", msg.href); break; case "getCurrentEvent": sendResponse(settings.get("currentEvent") || null); break; case "getCurrentGuildWar": sendResponse(settings.get("currentGuildWar") || null); break; case "setRecentQuest": settings.set("recentQuest", msg.url); break; case "getRecentQuest": sendResponse(settings.get("recentQuest") || null); break; case "setLastLocation": // FIXME: Track per-tab lastLocation = msg.url; break; case "setIdleRedirectPending": // FIXME: Track per-tab idleRedirectPending = msg.state; if (msg.url) lastRedirectTarget = msg.url; break; case "getLastLocation": sendResponse(lastLocation || null); break; case "getIdleRedirectInfo": if (idleRedirectPending) { sendResponse({ pending: true, location: lastLocation, lastRedirectTarget: lastRedirectTarget }); } else { sendResponse({ pending: false }); } break; case "getSettings": sendResponse(getAdjustedSettings()); break; case "getRaidCode": sendResponse(lastRaidCodes[tabId]); break; case "updateRaidCode": lastRaidCodes[tabId] = msg.raidCode; break; case "getItemCounters": return maybeDoUpdate(userDict.nextCounterUpdate, minimumUpdateDelay, formatItemCounters, updateItemCounters, sendResponse, msg.force, tabId, msg.uid); case "updateItemCounters": userDict.nextCounterUpdate = Date.now() + minimumUpdateDelay; userDict.itemCounters = msg.counters; break; case "invalidateStatus": if (userDict.lastStatus) log("Status invalidated"); userDict.nextStatusUpdate = 0; userDict.lastStatus = null; break; case "getStatus": var getLastStatus = function (uid) { var s = getUserDict(uid).lastStatus; if (s) fixupStatus(s, uid); return s; }; if (msg.lazy) { var lastStatus = getLastStatus(msg.uid); if (lastStatus) { sendResponse(lastStatus); return; } else { // log("Lazy status update failed"); } } return maybeDoUpdate(userDict.nextStatusUpdate, minimumUpdateDelay, getLastStatus, updateStatus, sendResponse, msg.force, tabId, msg.uid); case "updateStatus": handleNewStatus(msg.status, msg.uid); break; case "invalidateBuffs": userDict.nextGuildBuffUpdate = 0; userDict.nextPersonalBuffUpdate = 0; userDict.guildBuffs = null; userDict.personalBuffs = null; log("Buffs invalidated"); break; case "updateGuildBuffs": userDict.lastGuildBuffUpdate = Date.now(); userDict.nextGuildBuffUpdate = Date.now() + minimumUpdateDelay; userDict.guildBuffs = msg.buffs; break; case "updatePersonalBuffs": userDict.lastPersonalBuffUpdate = Date.now(); userDict.nextPersonalBuffUpdate = Date.now() + minimumUpdateDelay; userDict.personalBuffs = msg.buffs; break; case "getNextRankRp": // if not force, don't actually update since this is a heavy call if (!msg.force) { if (userDict.nextNextRankRpUpdate) { sendResponse(userDict.nextRankRp); break; } sendResponse(null); break; } return maybeDoUpdate(userDict.nextNextRankRpUpdate, minimumUpdateDelay, function (uid) { return getUserDict(uid).nextRankRp; }, updateNextRankRp, sendResponse, msg.force, tabId, msg.uid); case "updateNextRankRp": userDict.nextNextRankRpUpdate = Date.now() + minimumUpdateDelay; userDict.nextRankRp = getRpToNextRank(msg.data); break; case "getRaids": return maybeDoUpdate(userDict.nextRaidUpdate, minimumRaidUpdateDelay, function (uid) { return getUserDict(uid).lastRaids; }, updateRaids, sendResponse, msg.force, tabId, msg.uid); case "invalidateRaids": if (msg.raids) { handleNewRaids(msg.raids, msg.uid); } else { if (userDict.lastRaids) log("Raids invalidated"); userDict.nextRaidUpdate = 0; userDict.lastRaids = null; } break; case "getItems": return maybeDoUpdate(userDict.nextItemUpdate, minimumItemUpdateDelay, function (uid) { return getUserDict(uid).lastItems; }, updateItems, sendResponse, msg.force, tabId, msg.uid); case "invalidateItems": if (msg.items) { handleNewItems(msg.items, msg.uid); } else { if (userDict.lastItems) log("Items invalidated"); userDict.nextItemUpdate = 0; userDict.lastItems = null; } break; case "getWatchedItems": sendResponse(getWatchedItems()); break; case "setItemWatchState": if (msg.state) sendResponse(addWatchedItem(msg.id)); else sendResponse(removeWatchedItem(msg.id)); break; case "setItemWatchTarget": setItemWatchTarget(msg.id, msg.count); break; case "getFavedSummons": sendResponse(getFavedSummons()); break; case "setSummonFaveState": if (msg.state) sendResponse(addFavedSummon(msg.id)); else sendResponse(removeFavedSummon(msg.id)); break; case "setSummonOrder": settings.set("summonOrder", msg.data); break; case "getIsDead": sendResponse(isDead); break; case "doGameAjax": doGameAjax(msg, tabId, msg.uid, sendResponse); // retain sendResponse return true; case "doGamePopup": case "doGameRedirect": actuallySendMessage(msg, tabId); break; case "getTabId": sendResponse(tabId); break; case "getUserIdAndTabId": msg.tabId = tabId; actuallySendMessage(msg, tabId, sendResponse); return true; case "getIsSuspended": sendResponse(!!userDict.isSuspended); return true; case "recordRewards": handleQuestRewards(msg); break; case "recordRaidInfo": handleRaidInfo(msg); break; case "registerSecretKey": secretKeysByTabId[tabId] = msg.key; break; case "actionStarted": userDict.lastActionStartedWhen = msg.when; userDict.lastActionId = msg.actionId; broadcastActionTimestamps(msg.uid, userDict); break; case "actionEnded": if (msg.succeeded) { userDict.lastSuccessfulActionStartedWhen = userDict.lastActionStartedWhen; } if (userDict.lastActionId === msg.actionId) { if (msg.succeeded) { userDict.lastSuccessfulActionId = userDict.lastActionId; } else { userDict.lastActionId = null; } } userDict.lastActionEndedWhen = msg.when; broadcastActionTimestamps(msg.uid, userDict); break; case "actionCompletedAnimation": // When an action's animation is complete, we disable // the timer since the lockout is definitely over if (msg.actionId === userDict.lastActionId) { userDict.lastActionStartedWhen = userDict.lastActionId = null; broadcastActionTimestamps(msg.uid, userDict); } break; case "getLastActionTimestamps": sendResponse(makeActionTimestamps(userDict)); break; default: log("Unknown message " + key); sendResponse({ error: true }); break; } } ; function broadcastActionTimestamps(uid, userDict) { var obj = makeActionTimestamps(userDict); var msg = { type: "actionTimestampsChanged", data: obj, uid: uid }; chrome.tabs.query( // FIXME: Can we narrow this to granblue tabs without the 'tabs' permission? {}, function (tabs) { if (!tabs) return; for (var i = 0; i < tabs.length; i++) { var tab = tabs[i]; chrome.tabs.sendMessage(tab.id, msg); if (chrome.runtime.lastError) log(chrome.runtime.lastError); } }); } ; function makeActionTimestamps(userDict) { return { actionId: userDict.lastActionId, successfulActionId: userDict.lastSuccessfulActionId, started: userDict.lastActionStartedWhen, successfulStarted: userDict.lastSuccessfulActionStartedWhen, ended: userDict.lastActionEndedWhen }; } ; function handleQuestRewards(msg) { var userDict = getUserDict(msg.uid); if (!userDict.raids) return; var urlFragment = msg.url.substr(msg.url.lastIndexOf("/") + 1); urlFragment = urlFragment.substr(0, urlFragment.indexOf("?")); var raidId = parseInt(urlFragment); var questId = userDict.raids[raidId]; } ; function handleRaidInfo(msg) { var userDict = getUserDict(msg.uid); if (!userDict.raids) userDict.raids = {}; userDict.raids[msg.raidId] = msg.questId; } ; function parseTimeInMinutes(text) { var parts = text.split(/[\D]+/); var result = 0; for (var i = 0, len = Math.min(parts.length, 2); i < len; i++) { if (parts[i].length === 0) { break; } result = result * 60 + parseInt(parts[i]); } return result; } ; function estimateValue(truncated, maximum, timeRemaining, elapsedTimeMs, minutesPerUnit) { if (truncated >= maximum) return truncated; // HACK: Add 59 seconds to the remaining time since they round down the number of minutes timeRemaining += 59 / 60; var durationFromFull = maximum * minutesPerUnit; timeRemaining = Math.max(0, timeRemaining - (elapsedTimeMs / 60000)); var fract = (timeRemaining / durationFromFull); fract = Math.max(0.0, Math.min(1.0, fract)); var estimatedValue = maximum * (1.0 - fract); return estimatedValue; } ; function fixupStatus(status, uid) { if (!status) return status; var userDict = getUserDict(uid); // FIXME var lastUpdate = userDict.lastStatusUpdate; status._lastUpdate = lastUpdate; status._now = Date.now(); var age = (status._now - status._lastUpdate); status._precise_ap = estimateValue(status.ap, parseInt(status.max_action_point), parseTimeInMinutes(status.action_point_remain), age, 5); status._precise_bp = estimateValue(status.bp, parseInt(status.max_battle_point), parseTimeInMinutes(status.battle_point_remain), age, 10); status.buffs = []; if (userDict.guildBuffs) { // FIXME age = (status._now - userDict.lastGuildBuffUpdate); for (var i = 0, l = userDict.guildBuffs.length; i < l; i++) { var gb = userDict.guildBuffs[i]; var timeRemaining = (parseTimeInMinutes(gb.time) * 60 * 1000) - age; if (timeRemaining <= 0) continue; status.buffs.push({ comment: gb.comment, timeRemaining: timeRemaining, imageUrl: "http://game-a.granbluefantasy.jp/assets_en/img/sp/assets/item/support/support_" + gb.image + "_" + gb.level + ".png" }); } } if (userDict.personalBuffs) { // FIXME age = (status._now - userDict.lastPersonalBuffUpdate); for (var k in userDict.personalBuffs) { if (!userDict.personalBuffs.hasOwnProperty(k)) continue; var pb = userDict.personalBuffs[k]; var timeRemaining = (parseTimeInMinutes(pb.remain_time) * 60 * 1000) - age; if (timeRemaining <= 0) continue; status.buffs.push({ comment: pb.name, timeRemaining: timeRemaining, imageUrl: "http://game-a.granbluefantasy.jp/assets_en/img/sp/assets/item/support/" + pb.image_path + "_" + pb.level + ".png" }); } } return status; } ; function handleNewStatus(status, uid) { if (!status) { log("Failed status update"); return; } getUserDict(uid).lastStatus = status; getUserDict(uid).lastStatusUpdate = Date.now(); getUserDict(uid).nextStatusUpdate = Date.now() + minimumUpdateDelay; var minutesUntilApRefill = parseTimeInMinutes(status.action_point_remain); var minutesUntilBpRefill = parseTimeInMinutes(status.battle_point_remain); if ((minutesUntilApRefill > 1) && settings.get("notifyOnFullAP")) chrome.alarms.create("apFull", { delayInMinutes: minutesUntilApRefill + 1 }); else chrome.alarms.clear("apFull"); if ((minutesUntilBpRefill > 1) && settings.get("notifyOnFullBP")) chrome.alarms.create("bpFull", { delayInMinutes: minutesUntilBpRefill + 1 }); else chrome.alarms.clear("bpFull"); // log("ap time", minutesUntilApRefill, "bp time", minutesUntilBpRefill); } ; function maybeDoUpdate(nextTime, minimumUpdateDelay, getValue, doUpdate, sendResponse, force, tabId, uid) { var shouldUpdate = false; var userDict = getUserDict(uid); var now = Date.now(); if (!nextTime) shouldUpdate = true; else if (now >= nextTime) shouldUpdate = true; else if (force) shouldUpdate = true; if ((now - lastFailure) < failedUpdateMinimumDelay) { log("Rate-limiting update due to failure"); shouldUpdate = false; } if (userDict.isSuspended && shouldUpdate) { log("Rejecting update request due to idle timeout"); sendResponse(null); return false; } if (!userDict.inFlightRequests) userDict.inFlightRequests = {}; var requestName = doUpdate.name; var ifr = userDict.inFlightRequests[requestName]; if (ifr) { var elapsed = now - ifr.startedWhen.getTime(); if (elapsed >= 30000) { log("Request of type '" + requestName + "' in-flight since " + ifr.startedWhen.toLocaleString() + "; that's too long, so we're going again anyway."); } else { log("Request of type '" + requestName + "' in-flight since " + ifr.startedWhen.toLocaleString() + "; waiting for it."); ifr.then(function (result) { log("In-flight '" + requestName + "' request completed with value", result); sendResponse(result); }); return true; } } if (shouldUpdate) { var pr = new PromiseResolver(); pr.promise.startedWhen = new Date(); userDict.inFlightRequests[requestName] = pr.promise; doUpdate(tabId, uid, function (_uid) { var response = getValue(_uid); delete userDict.inFlightRequests[requestName]; sendResponse(response); pr.resolve(response); }); return true; } else { sendResponse(getValue(uid)); return false; } } ; function doGameAjax(msg, tabId, uid, callback) { /* if (Math.random() < 0.33) { console.log("Injecting error for request", msg); callback(null, "fake error"); return; } */ actuallySendMessage(msg, tabId, function (bundle) { if (!bundle) { callback({ error: true }, "no response"); return; } var response = bundle[0]; var error = bundle[1]; var url = bundle[2]; if (chrome.runtime.lastError) { isDead = true; log(chrome.runtime.lastError); } else { isDead = false; } if (error) { if (error.indexOf("-- abort") >= 0) { log("xhr aborted", url); } else { log("Error from server", error, url); lastFailure = Date.now(); } } if (typeof (response) === "string") { try { response = JSON.parse(response); } catch (exc) { } } if (isIdleTimeoutRedirect(response)) { handleIdleTimeout(uid); callback({ idleTimeout: true }, error); } else if (isMaintenanceRedirect(response)) { handleMaintenance(uid); callback({ maintenance: true }, error); } else { callback(response, error); } }); } ; function isIdleTimeoutRedirect(jsonBody) { if (jsonBody && jsonBody.redirect && (jsonBody.redirect.indexOf("top") >= 0)) return true; return false; } ; function isMaintenanceRedirect(jsonBody) { if (jsonBody && jsonBody.redirect && (jsonBody.redirect.indexOf("maintenance") >= 0)) return true; return false; } ; function handleIdleTimeout(uid) { log("Idle timeout"); getUserDict(uid).isSuspended = true; lastFailure = Date.now() + 5000; } ; function handleMaintenance(uid) { log("Maintenance"); getUserDict(uid).isSuspended = true; lastFailure = Date.now() + 5000; } ; function updateStatus(tabId, uid, callback) { var msg = { type: "doGameAjax", url: "/user/status" }; // log("Triggering status update"); doGameAjax(msg, tabId, uid, function (result) { getUserDict(uid).nextStatusUpdate = Date.now() + minimumUpdateDelay; if (!result) { log("Status update failed"); callback(uid); } else if (result.idleTimeout) { log("Status update failed: idle timeout"); callback(uid); } else if (result.maintenance) { log("Status update failed: maintenance"); callback(uid); } else { getUserDict(uid).lastStatusUpdate = Date.now(); getUserDict(uid).lastStatus = result.status; // log("Status updated -> ", lastStatus); callback(uid); } }); } ; function getRpToNextRank(data) { data = decodeURIComponent(data); /* Data is of the following form: [garbage] <div class="txt-next-value">Next ###Rankポイント</div> OR (depending on language) <div class="txt-next-value">Next lvl in ### Rank Points</div> [garbage] */ var result = parseInt(data.replace(/^[^]*txt-next-value[\D]+([\d]+)[^]*$/, "$1")); // in case of something unexpected being passed in if (isNaN(result)) { return "?"; } return result; } function updateNextRankRp(tabId, uid, callback) { var msg = { type: "doGameAjax", url: "/profile/content/index/" + uid }; doGameAjax(msg, tabId, uid, function (result) { if (!result) { log("RP to next rank update failed"); callback(uid); } else if (result.idleTimeout) { log("RP to next rank update failed: idle timeout"); callback(uid); } else { getUserDict(uid).lastNextRankRpUpdate = Date.now(); getUserDict(uid).nextNextRankRpUpdate = Date.now() + minimumUpdateDelay; getUserDict(uid).nextRankRp = getRpToNextRank(result.data); callback(uid); } }); } ; function getStrikeTime(data) { data = decodeURIComponent(data); /* Data is of the following form: [garbage] <div class="txt-next-value">Next ###Rankポイント</div> OR (depending on language) <div class="txt-next-value">Next lvl in ### Rank Points</div> [garbage] */ /* var strikeTimes = []; var re = /\<div class="prt\-assault\-guildinfo"\>.*?\<div class="prt\-item\-status"\>(.*?)\<\/div/gms var m; while (m = re.exec(data)) { strikeTimes.push(m[1]); } log(strikeTimes); return strikeTimes; */ } function updateStrikeTime(tabId, uid, callback) { var msg = { type: "doGameAjax", url: "/guild_main/content/index/" }; doGameAjax(msg, tabId, uid, function (result) { if (!result) { log("Strike time update failed"); callback(uid); } else if (result.idleTimeout) { log("Strike time update failed: idle timeout"); callback(uid); } else { getUserDict(uid).lastStrikeTimeUpdate = Date.now(); getUserDict(uid).nextStrikeTimeUpdate = Date.now() + minimumUpdateDelay; getUserDict(uid).strikeTime = getStrikeTime(result.data); callback(uid); } }); } ; function updateItemCounters(tabId, uid, callback) { var msg = { type: "doGameAjax", url: "/item/normal_item_list/1" }; // log("Triggering counter update"); doGameAjax(msg, tabId, uid, function (result) { if (!result) { log("Counter update failed"); getUserDict(uid).nextCounterUpdate = Date.now() + minimumUpdateDelay; callback(uid); } else if (result.idleTimeout) { log("Counter update failed: idle timeout"); getUserDict(uid).nextCounterUpdate = Date.now() + minimumUpdateDelay; callback(uid); } else { getUserDict(uid).lastCounterUpdate = Date.now(); getUserDict(uid).nextCounterUpdate = Date.now() + minimumItemUpdateDelay; getUserDict(uid).itemCounters = result; // log("Counters updated -> ", itemCounters); callback(uid); } }); } ; function onAlarm(alarm) { log("Alarm '" + alarm.name + "' fired"); if (alarm.name.indexOf("Full") >= 0) { var resourceName = alarm.name.replace("Full", "").toUpperCase(); chrome.notifications.create({ type: "basic", iconUrl: "../../icons/active-256.png", title: resourceName + " full", message: "Your Granblue Fantasy " + resourceName + " is full." }); return; } } ; function actuallySendMessage(message, tabId, callback) { // *$!@)%KAKLMRSJ chrome garbage APIs if (tabId) { chrome.tabs.sendMessage(tabId, message, callback); } else { log("No granblue tab found as target for message", message, tabId); } } ; function handleNewRaids(raids, uid) { if (!raids) { log("Failed raid update"); return; } getUserDict(uid).lastRaids = raids; getUserDict(uid).lastRaidUpdate = Date.now(); getUserDict(uid).nextRaidUpdate = Date.now() + minimumRaidUpdateDelay; // log("ap time", minutesUntilApRefill, "bp time", minutesUntilBpRefill); } ; function handleNewItems(items, uid) { if (!items) { log("Failed item update"); return; } getUserDict(uid).lastItems = items; getUserDict(uid).lastItemUpdate = Date.now(); getUserDict(uid).nextItemUpdate = Date.now() + minimumItemUpdateDelay; // log("ap time", minutesUntilApRefill, "bp time", minutesUntilBpRefill); } ; function updateRaids(tabId, uid, callback) { var msg = { type: "doGameAjax", url: "/quest/assist_list/0" }; // log("Triggering status update"); doGameAjax(msg, tabId, uid, function (result) { if (!result) { log("Raid update failed"); callback(uid); } else if (result.idleTimeout) { log("Raid update failed: idle timeout"); lastFailure = Date.now() + 5000; callback(uid); } else if (result.maintenance) { log("Raid update failed: maintenance"); lastFailure = Date.now() + 15000; callback(uid); } else { handleNewRaids(result, uid); callback(uid); } }); } ; function updateItems(tabId, uid, callback) { var msg = { type: "doGameAjax", url: "/item/article_list" }; // log("Triggering status update"); doGameAjax(msg, tabId, uid, function (result) { if (!result) { log("Item update failed"); callback(uid); } else if (result.idleTimeout) { log("Item update failed: idle timeout"); lastFailure = Date.now() + 5000; callback(uid); } else if (result.maintenance) { log("Item update failed: maintenance"); lastFailure = Date.now() + 15000; callback(uid); } else { handleNewItems(result, uid); callback(uid); } }); } ; function injectStylesheetsIntoTab(sender) { var injectStylesheet = function (uri) { var cb = function () { }; chrome.tabs.insertCSS(sender.tab.id, { file: uri, runAt: "document_start" }, cb); }; // log(sender.tab.id, sender.url); var currentSettings = settings.toObject(); injectStylesheet("/content/viramate.css"); injectStylesheet("/css/watch-button.css"); if (currentSettings.condensedUI) injectStylesheet("/css/condensed-ui.css"); if ((navigator.userAgent.indexOf("Chrome/53.0") >= 0) || (navigator.userAgent.indexOf("Chrome/54.0") >= 0) || (navigator.userAgent.indexOf("Chrome/55.0") >= 0) || (navigator.userAgent.indexOf("Chrome/56.0") >= 0) || (navigator.userAgent.indexOf("Chrome/57.0") >= 0) || (navigator.userAgent.indexOf("Chrome/58.0") >= 0)) injectStylesheet("/css/chrome-53.css"); if (currentSettings.betterEnglishFont) { injectStylesheet("/content/lato-woff.css"); injectStylesheet("/css/lato.css"); } if (currentSettings.showGaugeOverlays) injectStylesheet("/content/gauge-overlays.css"); if (currentSettings.showQuickPanels) injectStylesheet("/css/quick-panels.css"); if (currentSettings.moveCoOpFooter) injectStylesheet("/css/move-coop-footer.css"); if (currentSettings.enableCoOpEnhancements) injectStylesheet("/css/coop.css"); if (currentSettings.smartSupports) injectStylesheet("/css/smart-supports.css"); if (currentSettings.singlePageStickers) injectStylesheet("/css/single-page-stickers.css"); if (currentSettings.keyboardShortcuts2) injectStylesheet("/css/keyboard.css"); if (currentSettings.permanentTurnCounter) injectStylesheet("/css/permanent-turn-counter.css"); if (currentSettings.disablePerCharacterOugiSkip) injectStylesheet("/css/per-character-ougi-skip.css"); if (currentSettings.tinySupportSummons) injectStylesheet("/css/tiny-support-summons.css"); if (currentSettings.popupPositionFix) injectStylesheet("/css/popup-position-fix.css"); // chrome.tabs.insertCSS(tabId, {code: "body{border:1px solid red}"}); } ; //# sourceMappingURL=background.js.map
परिवर्तित टेक्स्ट
फ़ाइल खोलें
"use strict"; var settings = new Store("settings", { "preferFriendSummons": true, "preferNonFriendSummonsInFavorites": true, "preferLimitBrokenSummons": true, "preferHighLevelSummons": true, "notifyOnFullAP": false, "notifyOnFullBP": false, "showSkillCooldowns": true, "showDebuffTimers": true, "showBuffTimers": true, "monitorRaidDebuffs": true, "keyboardShortcuts": true, "showBookmarks": true, "preferredSummonElement": "", "submenuSize": 1.0, "bookmarksSize": 1.0, "bookmarksMenuSize": 1.0, "recentQuest": null, "showQuickPanels": true, "showGaugeOverlays": true, "openBookmarksOnClick": false, "fixJPFontRendering": true, "enableCoOpEnhancements": true, "dropdownFix": true, "disableMiddleRightClick": true, "statusPanel": true, "itemsPanel": true, "raidsPanel": false, "clockBrightness": 0.65, "oneClickQuickSummons": true, "bookmarksInactiveIcon": null, "bookmarksActiveIcon": null, "bookmarksIconPadding": 100, "horizontalBookmarks": false, "statusPanelBuffs": false, "statusPanelExpiringBuffs": true, "betterEnglishFont": false, "showItemWatchButtons": true, "showPartyNames": true, "filterEnemyTimers": true, "showPerformanceHud": false, "showNetworkHud": false, "showWeaponAttack": true, "showSkillActivationIndicator": true, "autofillBackupTweets": true, "moveCoOpFooter": true, "largeQuickPanels": false, "showPartyHelp": false, "keepSoundOnBlur": true, "stuckButtonWorkaround2": true, "showLastActionTimer": true, "smartSupports": true, "defaultToSmartSupports": false, "disablePhalanxSticker": true, "summonOrder": "{}", "password": "", "minimumPopupWait": 350, "maximumPopupWait": 1750, "focusQuickPanels": true, "newSkillSystem": true }); var failedUpdateMinimumDelay = 10 * 1000; var minimumUpdateDelay = 60 * 4 * 1000; var minimumRaidUpdateDelay = 30 * 1000; var minimumItemUpdateDelay = 60 * 30 * 1000; var minimumHaloUpdateDelay = 60 * 30 * 1000; var secretKeysByTabId = {}; var lastFailure = -1; var users = {}; var lastRaidCodes = {}; var isDead = true; var isShutdown = false; var lastLocation = null; var idleRedirectPending = false; var lastRedirectTarget = null; chrome.runtime.onMessage.addListener(onRuntimeMessage); chrome.alarms.onAlarm.addListener(onAlarm); chrome.runtime.onInstalled.addListener(function () { var dc = chrome.declarativeContent; dc.onPageChanged.removeRules(undefined, function () { dc.onPageChanged.addRules([ { conditions: [ new dc.PageStateMatcher({ pageUrl: { hostEquals: 'game.granbluefantasy.jp', schemes: ["https", "http"] }, }), new dc.PageStateMatcher({ pageUrl: { hostEquals: 'gbf.game.mbga.jp', schemes: ["https", "http"] }, }) ], actions: [new dc.ShowPageAction()] } ]); }); }); log("Started"); function getAdjustedSettings() { var result = settings.toObject(); result.allowDragSelect = false; // result.autoSkipToQuestResults = false; // result.oneClickQuickSummons = false; result.realtimeRaidList = false; // result.raidsPanel = false; // result.showQuickPanels = false; result.touchInputSupport = false; // Cygamesssssssssssssss result.autofillBackupTweets = false; // API changes broke this result.detailedUpgradePage = false; return result; } ; function log(...args) { args.unshift((new Date()).toLocaleString() + " |"); console.log.apply(console, args); } ; function getWatchedItems() { var result = JSON.parse(settings.get("watchedItems") || "[]"); if ((result.length === 1) && (result[0] === null)) result = []; var targetCounts = JSON.parse(settings.get("targetItemCounts") || "{}"); var itemGroups = JSON.parse(settings.get("itemGroups") || "{}"); return { items: result, counts: targetCounts, groups: itemGroups }; } ; function setItemWatchTarget(id, count) { var targetCounts = JSON.parse(settings.get("targetItemCounts") || "{}"); targetCounts[id] = count; settings.set("targetItemCounts", JSON.stringify(targetCounts)); } ; function setItemGroup(id, group) { var itemGroups = JSON.parse(settings.get("itemGroups") || "{}"); if (group!="undefined"){itemGroups[id] = group;} else{ //hack because it's not an array so can't just be pushed to var max = JSON.parse(settings.get("itemGroupsNumber") || "0"); var newmax = "" + (parseInt(max)+1); settings.set("itemGroupsNumber", JSON.stringify(newmax)); itemGroups[id] = newmax; } settings.set("itemGroups", JSON.stringify(itemGroups)); } ; function addWatchedItem(id) { var items = getWatchedItems().items; if (items.indexOf(id) >= 0) return items; if (!id) return items; items.push(id); settings.set("watchedItems", JSON.stringify(items)); return items; } ; function removeWatchedItem(id) { var items = getWatchedItems().items; var index = items.indexOf(id); if (index < 0) return items; items.splice(index, 1); settings.set("watchedItems", JSON.stringify(items)); return items; } ; function getFavedSummons() { var result = JSON.parse(settings.get("favedSummons") || "[]"); if ((result.length === 1) && (result[0] === null)) result = []; return result; } ; function addFavedSummon(id) { var items = getFavedSummons(); if (items.indexOf(id) >= 0) return items; if (!id) return items; items.push(id); settings.set("favedSummons", JSON.stringify(items)); return items; } ; function removeFavedSummon(id) { var items = getFavedSummons(); var index = items.indexOf(id); if (index < 0) return items; items.splice(index, 1); settings.set("favedSummons", JSON.stringify(items)); return items; } ; function getUserDict(uid) { var dict = users[uid]; if (!dict) dict = users[uid] = { lastUpdate: [] }; return dict; } ; function setUserData(uid, key, data) { var dict = getUserDict(uid); if (data) { dict.lastUpdate[key] = Date.now(); dict[key] = data; } else { dict.lastUpdate[key] = 0; dict[key] = null; } } ; function getUserData(uid, key) { var dict = getUserDict(uid); return dict[key]; } ; function getLastDataUpdate(uid, key) { var dict = getUserDict(uid); return dict.lastUpdate[key]; } ; function formatItemCounters(uid) { var itemCounters = getUserDict(uid).itemCounters; if (!itemCounters) return null; var counterDict = {}; for (var i = 0, l = itemCounters.length; i < l; i++) { var item = itemCounters[i]; counterDict[item.item_id] = item; } return counterDict; } ; function onRuntimeMessage(msg, sender, sendResponse) { if (chrome.runtime.lastError) log(chrome.runtime.lastError); var key = msg.type; var userDict; if (msg.uid) userDict = getUserDict(msg.uid); var tabId; if (sender.tab && sender.tab.id) tabId = sender.tab.id; else if (msg.tabId) tabId = msg.tabId; if (tabId <= 0) { log("Message has no tab id", key); return; } var senderUrl = sender.url || ""; if ((senderUrl.indexOf("granbluefantasy.jp") >= 0) || (senderUrl.indexOf("mbga.jp") >= 0)) { } else if ((senderUrl.indexOf("chrome-extension://") >= 0) && (senderUrl.indexOf("api.html") >= 0)) { switch (key) { case "apiRequest": case "getSettings": break; default: log("Rejected disallowed API request", msg); return; } } switch (key) { case "apiRequest": if (!settings.get("webAPI")) { log("Rejected API request because API is disabled", msg); sendResponse(null); return; } log("Processing API request", msg.request.type); switch (msg.request.type) { case "getUserIds": sendResponse(JSON.stringify(Object.keys(users))); break; case "getVersion": sendResponse(chrome.app.getDetails().version); break; case "tryJoinRaid": case "getCombatState": log("Preparing to send api request", msg); chrome.tabs.query({}, function (tabs) { if (tabs.length === 0) { log("Found no granblue tab"); sendResponse({ type: "result", error: "No granblue tab found" }); return; } for (var i = 0, l = tabs.length; i < l; i++) { var tab = tabs[i]; var tabUrl = tab.url; if (!tabUrl || ((tabUrl.indexOf("game.granbluefantasy.jp") < 0) && (tabUrl.indexOf("gbf.game.mbga.jp") < 0))) { continue; } log("Sending api request", msg); actuallySendMessage(msg, tab.id, function (result) { log("Got result for api request"); sendResponse(result); }); return; } log("Found no granblue tab"); sendResponse({ type: "result", error: "No granblue tab found" }); }); return true; default: sendResponse({ type: "result", error: "Unknown message" }); break; } break; case "getUserIds": sendResponse(JSON.stringify(Object.keys(users))); break; case "setPassword": settings.set("password", msg.password); break; case "pleaseInjectStylesheets": injectStylesheetsIntoTab(sender); break; case "heartbeat": isDead = false; break; case "cancelSuspend": if (userDict.isSuspended) log("Canceling idle/maintenance suspend for " + msg.uid); userDict.isSuspended = false; lastFailure = -1; break; case "isShutdown": sendResponse(isShutdown); break; case "setCompatibility": var newState = (msg.state === false); if (newState !== isShutdown) { log("Compatibility shutdown state set to", newState); isShutdown = newState; } break; case "openNewTab": chrome.tabs.create({ url: msg.url }); break; case "getVersion": sendResponse(chrome.app.getDetails().version); break; case "setRecentCoOpHost": settings.set("recentCoOpHost", msg.data); break; case "getRecentCoOpHost": sendResponse(settings.get("recentCoOpHost") || null); break; case "setCurrentEvent": if (msg.href !== settings.get("currentEvent")) log("Event changed to '" + msg.href + "'"); settings.set("currentEvent", msg.href); break; case "setCurrentGuildWar": if (msg.href !== settings.get("currentGuildWar")) log("Guild war changed to '" + msg.href + "'"); settings.set("currentGuildWar", msg.href); break; case "getCurrentEvent": sendResponse(settings.get("currentEvent") || null); break; case "getCurrentGuildWar": sendResponse(settings.get("currentGuildWar") || null); break; case "setRecentQuest": settings.set("recentQuest", msg.url); break; case "getRecentQuest": sendResponse(settings.get("recentQuest") || null); break; case "setLastLocation": // FIXME: Track per-tab lastLocation = msg.url; break; case "setIdleRedirectPending": // FIXME: Track per-tab idleRedirectPending = msg.state; if (msg.url) lastRedirectTarget = msg.url; break; case "getLastLocation": sendResponse(lastLocation || null); break; case "getIdleRedirectInfo": if (idleRedirectPending) { sendResponse({ pending: true, location: lastLocation, lastRedirectTarget: lastRedirectTarget }); } else { sendResponse({ pending: false }); } break; case "getSettings": sendResponse(getAdjustedSettings()); break; case "getRaidCode": sendResponse(lastRaidCodes[tabId]); break; case "updateRaidCode": lastRaidCodes[tabId] = msg.raidCode; break; case "getItemCounters": return maybeDoUpdate(userDict.nextCounterUpdate, minimumUpdateDelay, formatItemCounters, updateItemCounters, sendResponse, msg.force, tabId, msg.uid); case "updateItemCounters": userDict.nextCounterUpdate = Date.now() + minimumUpdateDelay; userDict.itemCounters = msg.counters; break; case "invalidateStatus": if (userDict.lastStatus) log("Status invalidated"); userDict.nextStatusUpdate = 0; userDict.lastStatus = null; break; case "getStatus": var getLastStatus = function (uid) { var s = getUserDict(uid).lastStatus; if (s) fixupStatus(s, uid); return s; }; if (msg.lazy) { var lastStatus = getLastStatus(msg.uid); if (lastStatus) { sendResponse(lastStatus); return; } else { // log("Lazy status update failed"); } } return maybeDoUpdate(userDict.nextStatusUpdate, minimumUpdateDelay, getLastStatus, updateStatus, sendResponse, msg.force, tabId, msg.uid); case "updateStatus": handleNewStatus(msg.status, msg.uid); break; case "invalidateBuffs": userDict.nextGuildBuffUpdate = 0; userDict.nextPersonalBuffUpdate = 0; userDict.guildBuffs = null; userDict.personalBuffs = null; log("Buffs invalidated"); break; case "updateGuildBuffs": userDict.lastGuildBuffUpdate = Date.now(); userDict.nextGuildBuffUpdate = Date.now() + minimumUpdateDelay; userDict.guildBuffs = msg.buffs; break; case "updatePersonalBuffs": userDict.lastPersonalBuffUpdate = Date.now(); userDict.nextPersonalBuffUpdate = Date.now() + minimumUpdateDelay; userDict.personalBuffs = msg.buffs; break; case "getNextRankRp": // if not force, don't actually update since this is a heavy call if (!msg.force) { if (userDict.nextNextRankRpUpdate) { sendResponse(userDict.nextRankRp); break; } sendResponse(null); break; } return maybeDoUpdate(userDict.nextNextRankRpUpdate, minimumUpdateDelay, function (uid) { return getUserDict(uid).nextRankRp; }, updateNextRankRp, sendResponse, msg.force, tabId, msg.uid); case "updateNextRankRp": userDict.nextNextRankRpUpdate = Date.now() + minimumUpdateDelay; userDict.nextRankRp = getRpToNextRank(msg.data); break; case "getRaids": return maybeDoUpdate(userDict.nextRaidUpdate, minimumRaidUpdateDelay, function (uid) { return getUserDict(uid).lastRaids; }, updateRaids, sendResponse, msg.force, tabId, msg.uid); case "invalidateRaids": if (msg.raids) { handleNewRaids(msg.raids, msg.uid); } else { if (userDict.lastRaids) log("Raids invalidated"); userDict.nextRaidUpdate = 0; userDict.lastRaids = null; } break; case "getItems": return maybeDoUpdate(userDict.nextItemUpdate, minimumItemUpdateDelay, function (uid) { return getUserDict(uid).lastItems; }, updateItems, sendResponse, msg.force, tabId, msg.uid); case "invalidateItems": if (msg.items) { handleNewItems(msg.items, msg.uid); } else { if (userDict.lastItems) log("Items invalidated"); userDict.nextItemUpdate = 0; userDict.lastItems = null; } break; case "getWatchedItems": sendResponse(getWatchedItems()); break; case "setItemWatchState": if (msg.state) sendResponse(addWatchedItem(msg.id)); else sendResponse(removeWatchedItem(msg.id)); break; case "setItemWatchTarget": setItemWatchTarget(msg.id, msg.count); break; case "setItemGroup": setItemGroup(msg.id, msg.group); break; case "getFavedSummons": sendResponse(getFavedSummons()); break; case "setSummonFaveState": if (msg.state) sendResponse(addFavedSummon(msg.id)); else sendResponse(removeFavedSummon(msg.id)); break; case "setSummonOrder": settings.set("summonOrder", msg.data); break; case "getIsDead": sendResponse(isDead); break; case "doGameAjax": doGameAjax(msg, tabId, msg.uid, sendResponse); // retain sendResponse return true; case "doGamePopup": case "doGameRedirect": actuallySendMessage(msg, tabId); break; case "getTabId": sendResponse(tabId); break; case "getUserIdAndTabId": msg.tabId = tabId; actuallySendMessage(msg, tabId, sendResponse); return true; case "getIsSuspended": sendResponse(!!userDict.isSuspended); return true; case "recordRewards": handleQuestRewards(msg); break; case "recordRaidInfo": handleRaidInfo(msg); break; case "registerSecretKey": secretKeysByTabId[tabId] = msg.key; break; case "actionStarted": userDict.lastActionStartedWhen = msg.when; userDict.lastActionId = msg.actionId; broadcastActionTimestamps(msg.uid, userDict); break; case "actionEnded": if (msg.succeeded) { userDict.lastSuccessfulActionStartedWhen = userDict.lastActionStartedWhen; } if (userDict.lastActionId === msg.actionId) { if (msg.succeeded) { userDict.lastSuccessfulActionId = userDict.lastActionId; } else { userDict.lastActionId = null; } } userDict.lastActionEndedWhen = msg.when; broadcastActionTimestamps(msg.uid, userDict); break; case "actionCompletedAnimation": // When an action's animation is complete, we disable // the timer since the lockout is definitely over if (msg.actionId === userDict.lastActionId) { userDict.lastActionStartedWhen = userDict.lastActionId = null; broadcastActionTimestamps(msg.uid, userDict); } break; case "getLastActionTimestamps": sendResponse(makeActionTimestamps(userDict)); break; default: log("Unknown message " + key); sendResponse({ error: true }); break; } } ; function broadcastActionTimestamps(uid, userDict) { var obj = makeActionTimestamps(userDict); var msg = { type: "actionTimestampsChanged", data: obj, uid: uid }; chrome.tabs.query( // FIXME: Can we narrow this to granblue tabs without the 'tabs' permission? {}, function (tabs) { if (!tabs) return; for (var i = 0; i < tabs.length; i++) { var tab = tabs[i]; chrome.tabs.sendMessage(tab.id, msg); if (chrome.runtime.lastError) log(chrome.runtime.lastError); } }); } ; function makeActionTimestamps(userDict) { return { actionId: userDict.lastActionId, successfulActionId: userDict.lastSuccessfulActionId, started: userDict.lastActionStartedWhen, successfulStarted: userDict.lastSuccessfulActionStartedWhen, ended: userDict.lastActionEndedWhen }; } ; function handleQuestRewards(msg) { var userDict = getUserDict(msg.uid); if (!userDict.raids) return; var urlFragment = msg.url.substr(msg.url.lastIndexOf("/") + 1); urlFragment = urlFragment.substr(0, urlFragment.indexOf("?")); var raidId = parseInt(urlFragment); var questId = userDict.raids[raidId]; } ; function handleRaidInfo(msg) { var userDict = getUserDict(msg.uid); if (!userDict.raids) userDict.raids = {}; userDict.raids[msg.raidId] = msg.questId; } ; function parseTimeInMinutes(text) { var parts = text.split(/[\D]+/); var result = 0; for (var i = 0, len = Math.min(parts.length, 2); i < len; i++) { if (parts[i].length === 0) { break; } result = result * 60 + parseInt(parts[i]); } return result; } ; function estimateValue(truncated, maximum, timeRemaining, elapsedTimeMs, minutesPerUnit) { if (truncated >= maximum) return truncated; // HACK: Add 59 seconds to the remaining time since they round down the number of minutes timeRemaining += 59 / 60; var durationFromFull = maximum * minutesPerUnit; timeRemaining = Math.max(0, timeRemaining - (elapsedTimeMs / 60000)); var fract = (timeRemaining / durationFromFull); fract = Math.max(0.0, Math.min(1.0, fract)); var estimatedValue = maximum * (1.0 - fract); return estimatedValue; } ; function fixupStatus(status, uid) { if (!status) return status; var userDict = getUserDict(uid); // FIXME var lastUpdate = userDict.lastStatusUpdate; status._lastUpdate = lastUpdate; status._now = Date.now(); var age = (status._now - status._lastUpdate); status._precise_ap = estimateValue(status.ap, parseInt(status.max_action_point), parseTimeInMinutes(status.action_point_remain), age, 5); status._precise_bp = estimateValue(status.bp, parseInt(status.max_battle_point), parseTimeInMinutes(status.battle_point_remain), age, 10); status.buffs = []; if (userDict.guildBuffs) { // FIXME age = (status._now - userDict.lastGuildBuffUpdate); for (var i = 0, l = userDict.guildBuffs.length; i < l; i++) { var gb = userDict.guildBuffs[i]; var timeRemaining = (parseTimeInMinutes(gb.time) * 60 * 1000) - age; if (timeRemaining <= 0) continue; status.buffs.push({ comment: gb.comment, timeRemaining: timeRemaining, imageUrl: "http://game-a.granbluefantasy.jp/assets_en/img/sp/assets/item/support/support_" + gb.image + "_" + gb.level + ".png" }); } } if (userDict.personalBuffs) { // FIXME age = (status._now - userDict.lastPersonalBuffUpdate); for (var k in userDict.personalBuffs) { if (!userDict.personalBuffs.hasOwnProperty(k)) continue; var pb = userDict.personalBuffs[k]; var timeRemaining = (parseTimeInMinutes(pb.remain_time) * 60 * 1000) - age; if (timeRemaining <= 0) continue; status.buffs.push({ comment: pb.name, timeRemaining: timeRemaining, imageUrl: "http://game-a.granbluefantasy.jp/assets_en/img/sp/assets/item/support/" + pb.image_path + "_" + pb.level + ".png" }); } } return status; } ; function handleNewStatus(status, uid) { if (!status) { log("Failed status update"); return; } getUserDict(uid).lastStatus = status; getUserDict(uid).lastStatusUpdate = Date.now(); getUserDict(uid).nextStatusUpdate = Date.now() + minimumUpdateDelay; var minutesUntilApRefill = parseTimeInMinutes(status.action_point_remain); var minutesUntilBpRefill = parseTimeInMinutes(status.battle_point_remain); if ((minutesUntilApRefill > 1) && settings.get("notifyOnFullAP")) chrome.alarms.create("apFull", { delayInMinutes: minutesUntilApRefill + 1 }); else chrome.alarms.clear("apFull"); if ((minutesUntilBpRefill > 1) && settings.get("notifyOnFullBP")) chrome.alarms.create("bpFull", { delayInMinutes: minutesUntilBpRefill + 1 }); else chrome.alarms.clear("bpFull"); // log("ap time", minutesUntilApRefill, "bp time", minutesUntilBpRefill); } ; function maybeDoUpdate(nextTime, minimumUpdateDelay, getValue, doUpdate, sendResponse, force, tabId, uid) { var shouldUpdate = false; var userDict = getUserDict(uid); var now = Date.now(); if (!nextTime) shouldUpdate = true; else if (now >= nextTime) shouldUpdate = true; else if (force) shouldUpdate = true; if ((now - lastFailure) < failedUpdateMinimumDelay) { log("Rate-limiting update due to failure"); shouldUpdate = false; } if (userDict.isSuspended && shouldUpdate) { log("Rejecting update request due to idle timeout"); sendResponse(null); return false; } if (!userDict.inFlightRequests) userDict.inFlightRequests = {}; var requestName = doUpdate.name; var ifr = userDict.inFlightRequests[requestName]; if (ifr) { var elapsed = now - ifr.startedWhen.getTime(); if (elapsed >= 30000) { log("Request of type '" + requestName + "' in-flight since " + ifr.startedWhen.toLocaleString() + "; that's too long, so we're going again anyway."); } else { log("Request of type '" + requestName + "' in-flight since " + ifr.startedWhen.toLocaleString() + "; waiting for it."); ifr.then(function (result) { log("In-flight '" + requestName + "' request completed with value", result); sendResponse(result); }); return true; } } if (shouldUpdate) { var pr = new PromiseResolver(); pr.promise.startedWhen = new Date(); userDict.inFlightRequests[requestName] = pr.promise; doUpdate(tabId, uid, function (_uid) { var response = getValue(_uid); delete userDict.inFlightRequests[requestName]; sendResponse(response); pr.resolve(response); }); return true; } else { sendResponse(getValue(uid)); return false; } } ; function doGameAjax(msg, tabId, uid, callback) { /* if (Math.random() < 0.33) { console.log("Injecting error for request", msg); callback(null, "fake error"); return; } */ actuallySendMessage(msg, tabId, function (bundle) { if (!bundle) { callback({ error: true }, "no response"); return; } var response = bundle[0]; var error = bundle[1]; var url = bundle[2]; if (chrome.runtime.lastError) { isDead = true; log(chrome.runtime.lastError); } else { isDead = false; } if (error) { if (error.indexOf("-- abort") >= 0) { log("xhr aborted", url); } else { log("Error from server", error, url); lastFailure = Date.now(); } } if (typeof (response) === "string") { try { response = JSON.parse(response); } catch (exc) { } } if (isIdleTimeoutRedirect(response)) { handleIdleTimeout(uid); callback({ idleTimeout: true }, error); } else if (isMaintenanceRedirect(response)) { handleMaintenance(uid); callback({ maintenance: true }, error); } else { callback(response, error); } }); } ; function isIdleTimeoutRedirect(jsonBody) { if (jsonBody && jsonBody.redirect && (jsonBody.redirect.indexOf("top") >= 0)) return true; return false; } ; function isMaintenanceRedirect(jsonBody) { if (jsonBody && jsonBody.redirect && (jsonBody.redirect.indexOf("maintenance") >= 0)) return true; return false; } ; function handleIdleTimeout(uid) { log("Idle timeout"); getUserDict(uid).isSuspended = true; lastFailure = Date.now() + 5000; } ; function handleMaintenance(uid) { log("Maintenance"); getUserDict(uid).isSuspended = true; lastFailure = Date.now() + 5000; } ; function updateStatus(tabId, uid, callback) { var msg = { type: "doGameAjax", url: "/user/status" }; // log("Triggering status update"); doGameAjax(msg, tabId, uid, function (result) { getUserDict(uid).nextStatusUpdate = Date.now() + minimumUpdateDelay; if (!result) { log("Status update failed"); callback(uid); } else if (result.idleTimeout) { log("Status update failed: idle timeout"); callback(uid); } else if (result.maintenance) { log("Status update failed: maintenance"); callback(uid); } else { getUserDict(uid).lastStatusUpdate = Date.now(); getUserDict(uid).lastStatus = result.status; // log("Status updated -> ", lastStatus); callback(uid); } }); } ; function getRpToNextRank(data) { data = decodeURIComponent(data); /* Data is of the following form: [garbage] <div class="txt-next-value">Next ###Rankポイント</div> OR (depending on language) <div class="txt-next-value">Next lvl in ### Rank Points</div> [garbage] */ var result = parseInt(data.replace(/^[^]*txt-next-value[\D]+([\d]+)[^]*$/, "$1")); // in case of something unexpected being passed in if (isNaN(result)) { return "?"; } return result; } function updateNextRankRp(tabId, uid, callback) { var msg = { type: "doGameAjax", url: "/profile/content/index/" + uid }; doGameAjax(msg, tabId, uid, function (result) { if (!result) { log("RP to next rank update failed"); callback(uid); } else if (result.idleTimeout) { log("RP to next rank update failed: idle timeout"); callback(uid); } else { getUserDict(uid).lastNextRankRpUpdate = Date.now(); getUserDict(uid).nextNextRankRpUpdate = Date.now() + minimumUpdateDelay; getUserDict(uid).nextRankRp = getRpToNextRank(result.data); callback(uid); } }); } ; function getStrikeTime(data) { data = decodeURIComponent(data); /* Data is of the following form: [garbage] <div class="txt-next-value">Next ###Rankポイント</div> OR (depending on language) <div class="txt-next-value">Next lvl in ### Rank Points</div> [garbage] */ /* var strikeTimes = []; var re = /\<div class="prt\-assault\-guildinfo"\>.*?\<div class="prt\-item\-status"\>(.*?)\<\/div/gms var m; while (m = re.exec(data)) { strikeTimes.push(m[1]); } log(strikeTimes); return strikeTimes; */ } function updateStrikeTime(tabId, uid, callback) { var msg = { type: "doGameAjax", url: "/guild_main/content/index/" }; doGameAjax(msg, tabId, uid, function (result) { if (!result) { log("Strike time update failed"); callback(uid); } else if (result.idleTimeout) { log("Strike time update failed: idle timeout"); callback(uid); } else { getUserDict(uid).lastStrikeTimeUpdate = Date.now(); getUserDict(uid).nextStrikeTimeUpdate = Date.now() + minimumUpdateDelay; getUserDict(uid).strikeTime = getStrikeTime(result.data); callback(uid); } }); } ; function updateItemCounters(tabId, uid, callback) { var msg = { type: "doGameAjax", url: "/item/normal_item_list/1" }; // log("Triggering counter update"); doGameAjax(msg, tabId, uid, function (result) { if (!result) { log("Counter update failed"); getUserDict(uid).nextCounterUpdate = Date.now() + minimumUpdateDelay; callback(uid); } else if (result.idleTimeout) { log("Counter update failed: idle timeout"); getUserDict(uid).nextCounterUpdate = Date.now() + minimumUpdateDelay; callback(uid); } else { getUserDict(uid).lastCounterUpdate = Date.now(); getUserDict(uid).nextCounterUpdate = Date.now() + minimumItemUpdateDelay; getUserDict(uid).itemCounters = result; // log("Counters updated -> ", itemCounters); callback(uid); } }); } ; function onAlarm(alarm) { log("Alarm '" + alarm.name + "' fired"); if (alarm.name.indexOf("Full") >= 0) { var resourceName = alarm.name.replace("Full", "").toUpperCase(); chrome.notifications.create({ type: "basic", iconUrl: "../../icons/active-256.png", title: resourceName + " full", message: "Your Granblue Fantasy " + resourceName + " is full." }); return; } } ; function actuallySendMessage(message, tabId, callback) { // *$!@)%KAKLMRSJ chrome garbage APIs if (tabId) { chrome.tabs.sendMessage(tabId, message, callback); } else { log("No granblue tab found as target for message", message, tabId); } } ; function handleNewRaids(raids, uid) { if (!raids) { log("Failed raid update"); return; } getUserDict(uid).lastRaids = raids; getUserDict(uid).lastRaidUpdate = Date.now(); getUserDict(uid).nextRaidUpdate = Date.now() + minimumRaidUpdateDelay; // log("ap time", minutesUntilApRefill, "bp time", minutesUntilBpRefill); } ; function handleNewItems(items, uid) { if (!items) { log("Failed item update"); return; } getUserDict(uid).lastItems = items; getUserDict(uid).lastItemUpdate = Date.now(); getUserDict(uid).nextItemUpdate = Date.now() + minimumItemUpdateDelay; // log("ap time", minutesUntilApRefill, "bp time", minutesUntilBpRefill); } ; function updateRaids(tabId, uid, callback) { var msg = { type: "doGameAjax", url: "/quest/assist_list/0" }; // log("Triggering status update"); doGameAjax(msg, tabId, uid, function (result) { if (!result) { log("Raid update failed"); callback(uid); } else if (result.idleTimeout) { log("Raid update failed: idle timeout"); lastFailure = Date.now() + 5000; callback(uid); } else if (result.maintenance) { log("Raid update failed: maintenance"); lastFailure = Date.now() + 15000; callback(uid); } else { handleNewRaids(result, uid); callback(uid); } }); } ; function updateItems(tabId, uid, callback) { var msg = { type: "doGameAjax", url: "/item/article_list" }; // log("Triggering status update"); doGameAjax(msg, tabId, uid, function (result) { if (!result) { log("Item update failed"); callback(uid); } else if (result.idleTimeout) { log("Item update failed: idle timeout"); lastFailure = Date.now() + 5000; callback(uid); } else if (result.maintenance) { log("Item update failed: maintenance"); lastFailure = Date.now() + 15000; callback(uid); } else { handleNewItems(result, uid); callback(uid); } }); } ; function injectStylesheetsIntoTab(sender) { var injectStylesheet = function (uri) { var cb = function () { }; chrome.tabs.insertCSS(sender.tab.id, { file: uri, runAt: "document_start" }, cb); }; // log(sender.tab.id, sender.url); var currentSettings = settings.toObject(); injectStylesheet("/content/viramate.css"); injectStylesheet("/css/watch-button.css"); if (currentSettings.condensedUI) injectStylesheet("/css/condensed-ui.css"); if ((navigator.userAgent.indexOf("Chrome/53.0") >= 0) || (navigator.userAgent.indexOf("Chrome/54.0") >= 0) || (navigator.userAgent.indexOf("Chrome/55.0") >= 0) || (navigator.userAgent.indexOf("Chrome/56.0") >= 0) || (navigator.userAgent.indexOf("Chrome/57.0") >= 0) || (navigator.userAgent.indexOf("Chrome/58.0") >= 0)) injectStylesheet("/css/chrome-53.css"); if (currentSettings.betterEnglishFont) { injectStylesheet("/content/lato-woff.css"); injectStylesheet("/css/lato.css"); } if (currentSettings.showGaugeOverlays) injectStylesheet("/content/gauge-overlays.css"); if (currentSettings.showQuickPanels) injectStylesheet("/css/quick-panels.css"); if (currentSettings.moveCoOpFooter) injectStylesheet("/css/move-coop-footer.css"); if (currentSettings.enableCoOpEnhancements) injectStylesheet("/css/coop.css"); if (currentSettings.smartSupports) injectStylesheet("/css/smart-supports.css"); if (currentSettings.singlePageStickers) injectStylesheet("/css/single-page-stickers.css"); if (currentSettings.keyboardShortcuts2) injectStylesheet("/css/keyboard.css"); if (currentSettings.permanentTurnCounter) injectStylesheet("/css/permanent-turn-counter.css"); if (currentSettings.disablePerCharacterOugiSkip) injectStylesheet("/css/per-character-ougi-skip.css"); if (currentSettings.tinySupportSummons) injectStylesheet("/css/tiny-support-summons.css"); if (currentSettings.popupPositionFix) injectStylesheet("/css/popup-position-fix.css"); // chrome.tabs.insertCSS(tabId, {code: "body{border:1px solid red}"}); } ; //# sourceMappingURL=background.js.map
अंतर खोजें